import { forwardRef, Key, useEffect, useImperativeHandle, useMemo, useState, } from "react"; import { Modal, Collapse, Empty, Steps, Result, Button, Spin, Form, TreeSelect, Tabs, message, } from "antd"; import { ProTable } from "@ant-design/pro-components"; import DiffTable from "./DiffTable"; import { useModel, useRequest } from "umi"; import { PushDataModelTable, GetCanUseTableList } from "@/api/dataModel"; import { GetAllDesignTables, SaveDataModel, ImportFromBusinessTables, } from "@/api"; import { TableItemType } from "@/type"; import NoData from "@/assets/no-data.png"; import CustomColorPicker from "./CustomColorPicker"; import { pick, set } from "lodash-es"; export default forwardRef(function SyncModal( props: { onPush: () => void }, ref ) { const [open, setOpen] = useState(false); const { project } = useModel("erModel"); const [color, setColor] = useState(); const { data, loading, run } = useRequest(GetAllDesignTables, { manual: true, }); const [tableList, setTableList] = useState(project?.tables); const [step, setStep] = useState(0); const [tabActiveKey, setTabActiveKey] = useState("1"); // 选中需要同步的表 const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRows, setSelectedRows] = useState([]); const [okLoading, setOkLoading] = useState(false); const [resultStatus, setResultStatus] = useState<"success" | "error">( "success" ); const [importTables, setImportTables] = useState([]); useEffect(() => { if (step === 0 && tableList.length) { setSelectedRowKeys(tableList.map((item) => item.table.id)); setSelectedRows(tableList); } }, [tableList, step]); useImperativeHandle(ref, () => ({ open: () => { setTabActiveKey("1"); setColor(undefined); setStep(0); setOpen(true); run(); run1({ type: project.type }); }, close: () => setOpen(false), })); useEffect(() => { setTableList(project.tables); }, [project.tables]); useEffect(() => { setStep(0); }, [tabActiveKey]); const { data: data1, loading: loading1, run: run1, } = useRequest(GetCanUseTableList, { manual: true, }); // 可引入表列表 const treeData = useMemo(() => { const tableMap: Record = {}; data1?.result ?.filter( (item: any) => // 过滤当前数据表类型及存在相同schemaName、aliasName的表 item?.type == project?.type // && !project.tables.find( // (tableItem) => // tableItem.table.schemaName === item.schemaName || // tableItem.table.aliasName === item.aliasName // ) ) ?.forEach((item: any) => { // 判断是否存在已引入的表 const hasTable = project.tables.find( (tableItem: TableItemType) => tableItem.table.schemaName === item.schemaName || tableItem.table.aliasName === item.aliasName ); const option = { key: item.id, title: `${item?.schemaName}(${item.name})`, value: item?.id, disabled: hasTable, selectable: !item.parentBusinessTableId, }; // 子表 if (item.parentBusinessTableId) { if (tableMap[item.parentBusinessTableId]) { tableMap[item.parentBusinessTableId].children.push(option); } else { tableMap[item.parentBusinessTableId] = { children: [option], }; } } else { // 主表 if (tableMap[item.id]) { tableMap[item.id] = { ...tableMap[item.id], ...option, }; } else { tableMap[item.id] = { ...option, children: [], }; } } return; }); return Object.keys(tableMap).map((key) => tableMap[key]); }, [data1]); // 已存在的数据表 const existTableList = useMemo(() => { const list: { modelTable: TableItemType; dataTable: any; }[] = []; const tables = data?.result?.appBusinessTables || []; selectedRows.forEach((tableItem) => { const dataTable = tables.find( (item: any) => item.id === tableItem.table?.businessTableId // item.schemaName === tableItem.table.schemaName || // item.aliasName === tableItem.table.aliasName ); if (dataTable) { list.push({ modelTable: tableItem, dataTable, }); } }); return list; }, [selectedRows, data]); // 差异对比更新当前模型数据 const handleUpdateTable = (tableItem: TableItemType) => { setSelectedRows( selectedRows.map((item) => item.table.id === tableItem.table.id ? tableItem : item ) ); }; const Step1Comp = () => { return ( <> "请选择模型表"} dataSource={tableList.map((item) => item.table)} rowKey="id" search={false} pagination={false} options={false} size="small" rowSelection={{ selectedRowKeys, onChange(selectedRowKeys) { setSelectedRowKeys(selectedRowKeys); setSelectedRows( tableList.filter((item) => selectedRowKeys.includes(item.table.id) ) ); }, }} columns={[ { title: "类型", dataIndex: "type", valueType: "select", valueEnum: { 3: "业务表", 2: "流程表", }, }, { title: "编码", dataIndex: "schemaName", valueType: "text", }, { title: "别名", dataIndex: "aliasName", valueType: "text", }, { title: "名称", dataIndex: "langNameList", render: (_, record) => { return ( record.langNameList?.find( (item: any) => item.name === "zh-CN" )?.value || "-" ); }, }, { title: "描述", dataIndex: "langDescriptionList", render: (_, record) => { return ( record?.langDescriptionList?.find( (item: any) => item.name === "zh-CN" )?.value || "-" ); }, }, ]} /> ); }; const Step2Comp = () => { const list = selectedRows.filter(({ table }) => existTableList.find((item) => item.modelTable.table.id === table.id) ); return ( <>
提示:共选择了 {selectedRows.length} 张表格数据。 {existTableList.length ? ( <> 其中有 {existTableList.length} 张表已存在,可对比调整差异后开始操作。 ) : null}
{ const { table } = item; const name = table.langNameList?.find( (item: any) => item.name === "zh-CN" )?.value; const existTable = existTableList.find( (item) => item.modelTable.table.id === table.id ); return { key: table.id, label: ( {`${table.schemaName}${name ? `(${name})` : ""}`} ), children: ( ), }; })} /> ); }; const Step3Comp = () => { return (
{okLoading ? (
) : ( <> {resultStatus === "success" ? ( ) : ( )} )}
); }; const handlePush = async () => { setStep(2); try { setOkLoading(true); await PushDataModelTable(selectedRows); // message.success("同步推送完成"); setResultStatus("success"); } catch (err) { setResultStatus("error"); } finally { setOkLoading(false); } }; const handlePull = async () => { setOkLoading(true); try { // 1、更新原有表的数据 const tableIds = selectedRows.map(({ table }) => table.id); await SaveDataModel({ erDataModel: { ...project, tables: project.tables.map((item) => { if (tableIds.includes(item.table.id)) { return ( selectedRows.find((t) => t.table.id === item.table.id) || item ); } return item; }), }, }); } catch (err) { console.log(err); message.error("拉取失败"); setResultStatus("error"); } // 2、添加引入数据 try { const businessTables = data1?.result ?.filter((item: any) => importTables?.includes(item.id)) ?.map((item: any) => { return pick(item, [ "aliasName", "schemaName", "id", "parentBusinessTableId", ]); }) || []; if (!businessTables.length) { setResultStatus("success"); setStep(2); return; } await ImportFromBusinessTables({ dataModelId: project.id, color, businessTables, }); } catch (err) { console.log(err); message.error("引入失败"); setResultStatus("error"); } finally { setOkLoading(false); setStep(2); } }; const handleDone = () => { setOpen(false); props.onPush?.(); }; return ( setOpen(false)} footer={(_, { CancelBtn }) => { return ( <> {step === 0 && ( )} {step > 0 && ( )} {step === 2 && resultStatus === "success" && ( )} {step === 1 && tabActiveKey === "1" && ( )} {step === 1 && tabActiveKey === "2" && ( )} ); }} >
{step === 0 && ( <>
{ setImportTables(value); }} /> {color ? (
) : ( 随机生成,点击可选择颜色 )}
)} {step === 1 && } {step === 2 && } ), }, { key: "2", label: "推送", children: (
{step === 0 && } {step === 1 && } {step === 2 && }
), }, ]} /> {!tableList.length && ( )}
); });