|
@@ -0,0 +1,289 @@
|
|
|
+import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import { Button, Input, Modal, Popconfirm, Table, Tooltip } from "antd";
|
|
|
+import { BZ2AgeType } from "@/types";
|
|
|
+// 表格拖动排序-----------------
|
|
|
+import { DndProvider, useDrag, useDrop } from "react-dnd";
|
|
|
+import { HTML5Backend } from "react-dnd-html5-backend";
|
|
|
+import { ExclamationCircleFilled } from "@ant-design/icons";
|
|
|
+import {
|
|
|
+ BZ2_APIaddAge,
|
|
|
+ BZ2_APIageDel,
|
|
|
+ BZ2_APIsort,
|
|
|
+} from "@/store/action/BZ2Qhistory";
|
|
|
+import { MessageFu } from "@/utils/message";
|
|
|
+import classNames from "classnames";
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ data: BZ2AgeType[];
|
|
|
+ closeFu: () => void;
|
|
|
+ addFu: () => void;
|
|
|
+};
|
|
|
+
|
|
|
+function AgePage({ data, closeFu, addFu }: Props) {
|
|
|
+ // 表格拖动排序
|
|
|
+ interface DraggableBodyRowProps
|
|
|
+ extends React.HTMLAttributes<HTMLTableRowElement> {
|
|
|
+ index: number;
|
|
|
+ moveRow: (dragIndex: number, hoverIndex: number) => void;
|
|
|
+ }
|
|
|
+
|
|
|
+ const type = "DraggableBodyRow";
|
|
|
+
|
|
|
+ const DraggableBodyRow = useCallback(
|
|
|
+ ({
|
|
|
+ index,
|
|
|
+ moveRow,
|
|
|
+ className,
|
|
|
+ style,
|
|
|
+ ...restProps
|
|
|
+ }: DraggableBodyRowProps) => {
|
|
|
+ // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
|
+ const ref = useRef<HTMLTableRowElement>(null);
|
|
|
+ // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
|
+ const [{ isOver, dropClassName }, drop] = useDrop({
|
|
|
+ accept: type,
|
|
|
+ collect: (monitor) => {
|
|
|
+ const { index: dragIndex } = monitor.getItem() || {};
|
|
|
+ if (dragIndex === index) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ isOver: monitor.isOver(),
|
|
|
+ dropClassName:
|
|
|
+ dragIndex < index ? " drop-over-downward" : " drop-over-upward",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ drop: (item: { index: number }) => {
|
|
|
+ if (moveRow) moveRow(item.index, index);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
|
+ const [, drag] = useDrag({
|
|
|
+ type,
|
|
|
+ item: { index },
|
|
|
+ collect: (monitor) => ({
|
|
|
+ isDragging: monitor.isDragging(),
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ drop(drag(ref));
|
|
|
+
|
|
|
+ return (
|
|
|
+ <tr
|
|
|
+ ref={ref}
|
|
|
+ className={`${className}${isOver ? dropClassName : ""}`}
|
|
|
+ style={{ cursor: "move", ...style }}
|
|
|
+ {...restProps}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ },
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ const components = {
|
|
|
+ body: {
|
|
|
+ row: DraggableBodyRow,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ const moveRow = useCallback(
|
|
|
+ async (dragIndex: number, hoverIndex: number) => {
|
|
|
+ if (dragIndex === hoverIndex) return;
|
|
|
+ // 交互位置-之前的id
|
|
|
+ const beforeId = data[dragIndex].id;
|
|
|
+ const afterId = data[hoverIndex].id;
|
|
|
+ // console.log("交换位置", beforeId, afterId);
|
|
|
+ const res = await BZ2_APIsort(beforeId, afterId);
|
|
|
+
|
|
|
+ if (res.code === 0) addFu();
|
|
|
+ },
|
|
|
+ [addFu, data]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 点击删除
|
|
|
+ const delTableFu = useCallback(
|
|
|
+ async (id: number) => {
|
|
|
+ const res = await BZ2_APIageDel(id);
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success("删除成功!");
|
|
|
+ addFu();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [addFu]
|
|
|
+ );
|
|
|
+
|
|
|
+ const columns = useMemo(() => {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ width: 100,
|
|
|
+ title: (
|
|
|
+ <div className="moveTit">
|
|
|
+ 序号
|
|
|
+ <Tooltip title="按住鼠标可拖动表格调整顺序">
|
|
|
+ <div className="inco" hidden={data.length < 2}>
|
|
|
+ <ExclamationCircleFilled />
|
|
|
+ </div>
|
|
|
+ </Tooltip>
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ render: (_1: any, _2: any, index: number) => index + 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "专题名称",
|
|
|
+ dataIndex: "name",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "操作",
|
|
|
+ render: (item: BZ2AgeType) => (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ size="small"
|
|
|
+ type="text"
|
|
|
+ onClick={() =>
|
|
|
+ setAddInfo({ name: item.name, id: item.id, oldName: item.name })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ 编辑
|
|
|
+ </Button>
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => delTableFu(item.id)}
|
|
|
+ >
|
|
|
+ <Button size="small" type="text" danger>
|
|
|
+ 删除
|
|
|
+ </Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </>
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }, [data.length, delTableFu]);
|
|
|
+
|
|
|
+ // 点击新增和编辑
|
|
|
+ const [addInfo, setAddInfo] = useState({ name: "", id: 0, oldName: "" });
|
|
|
+
|
|
|
+ const addNameChange = useCallback(
|
|
|
+ (val: string) => {
|
|
|
+ setAddInfo({
|
|
|
+ id: addInfo.id,
|
|
|
+ oldName: addInfo.oldName,
|
|
|
+ name: val.replace(/\s+/g, ""),
|
|
|
+ });
|
|
|
+ },
|
|
|
+ [addInfo.id, addInfo.oldName]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 点击提交
|
|
|
+ const nameBtnOk = useCallback(async () => {
|
|
|
+ if (addInfo.name === "") return MessageFu.warning("不能为空!");
|
|
|
+
|
|
|
+ const obj = {
|
|
|
+ id: addInfo.id > 0 ? addInfo.id : null,
|
|
|
+ type: "age",
|
|
|
+ name: addInfo.name,
|
|
|
+ };
|
|
|
+
|
|
|
+ const res = await BZ2_APIaddAge(obj);
|
|
|
+
|
|
|
+ if (res.code === 0) {
|
|
|
+ addFu();
|
|
|
+ MessageFu.success(addInfo.id > 0 ? "编辑成功!" : "新增成功!");
|
|
|
+ setAddInfo({ name: "", id: 0, oldName: "" });
|
|
|
+ }
|
|
|
+ }, [addFu, addInfo.id, addInfo.name]);
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ wrapClassName={styles.AgePage}
|
|
|
+ destroyOnClose
|
|
|
+ open={true}
|
|
|
+ title="年代专题设置"
|
|
|
+ footer={
|
|
|
+ [] // 设置footer为空,去掉 取消 确定默认按钮
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div className="AgePageMain">
|
|
|
+ {/* 新增按钮 */}
|
|
|
+ <div className="ageAddBtn">
|
|
|
+ <Button
|
|
|
+ type="primary"
|
|
|
+ onClick={() => {
|
|
|
+ if (data.length >= 10)
|
|
|
+ return MessageFu.warning("最多支持10条数据!");
|
|
|
+ setAddInfo({ name: "", id: -1, oldName: "" });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ 新增
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 表格主体 */}
|
|
|
+ <div className="tableBox">
|
|
|
+ <DndProvider backend={HTML5Backend}>
|
|
|
+ <Table
|
|
|
+ scroll={{ y: 470 }}
|
|
|
+ columns={columns}
|
|
|
+ dataSource={data}
|
|
|
+ components={components}
|
|
|
+ rowKey="id"
|
|
|
+ pagination={false}
|
|
|
+ onRow={(_, index) => {
|
|
|
+ const attr = {
|
|
|
+ index,
|
|
|
+ moveRow,
|
|
|
+ };
|
|
|
+ return attr as React.HTMLAttributes<any>;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </DndProvider>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="ageBtn">
|
|
|
+ <Button onClick={closeFu}>关闭</Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 点击新增从右侧出来的弹窗 */}
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "ageRightBox",
|
|
|
+ addInfo.id ? "ageRightBoxShow" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ <div className="ageRightBoxmain" hidden={addInfo.id === 0}>
|
|
|
+ <div className="ageRtit">
|
|
|
+ {addInfo.id > 0 ? `编辑 ${addInfo.oldName}` : "新增"}
|
|
|
+ </div>
|
|
|
+ <Input
|
|
|
+ maxLength={20}
|
|
|
+ showCount
|
|
|
+ placeholder="请输入专题名称"
|
|
|
+ value={addInfo.name}
|
|
|
+ onChange={(e) => addNameChange(e.target.value)}
|
|
|
+ />
|
|
|
+
|
|
|
+ <div className="ageRbtn">
|
|
|
+ <Button type="primary" onClick={nameBtnOk}>
|
|
|
+ 提交
|
|
|
+ </Button>
|
|
|
+  
|
|
|
+ <Popconfirm
|
|
|
+ title="放弃编辑后,信息将不会保存!"
|
|
|
+ okText="放弃"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setAddInfo({ name: "", id: 0, oldName: "" })}
|
|
|
+ >
|
|
|
+ <Button>取消</Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoAgePage = React.memo(AgePage);
|
|
|
+
|
|
|
+export default MemoAgePage;
|