|
@@ -1,5 +1,13 @@
|
|
-import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react";
|
|
|
|
-import { Modal, Collapse, message, Empty } from "antd";
|
|
|
|
|
|
+import {
|
|
|
|
+ forwardRef,
|
|
|
|
+ Key,
|
|
|
|
+ useEffect,
|
|
|
|
+ useImperativeHandle,
|
|
|
|
+ useMemo,
|
|
|
|
+ useState,
|
|
|
|
+} from "react";
|
|
|
|
+import { Modal, Collapse, Empty, Steps, Result, Button, Spin } from "antd";
|
|
|
|
+import { ProTable } from "@ant-design/pro-components";
|
|
import DiffTable from "./DiffTable";
|
|
import DiffTable from "./DiffTable";
|
|
import { useModel, useRequest } from "umi";
|
|
import { useModel, useRequest } from "umi";
|
|
import { PushDataModelTable } from "@/api/dataModel";
|
|
import { PushDataModelTable } from "@/api/dataModel";
|
|
@@ -7,16 +15,36 @@ import { GetAllDesignTables } from "@/api";
|
|
import { TableItemType } from "@/type";
|
|
import { TableItemType } from "@/type";
|
|
import NoData from "@/assets/no-data.png";
|
|
import NoData from "@/assets/no-data.png";
|
|
|
|
|
|
-export default forwardRef(function SyncModal(props: {onPush: () => void}, ref) {
|
|
|
|
|
|
+export default forwardRef(function SyncModal(
|
|
|
|
+ props: { onPush: () => void },
|
|
|
|
+ ref
|
|
|
|
+) {
|
|
const [open, setOpen] = useState(false);
|
|
const [open, setOpen] = useState(false);
|
|
const { project } = useModel("erModel");
|
|
const { project } = useModel("erModel");
|
|
const { data, loading, run } = useRequest(GetAllDesignTables, {
|
|
const { data, loading, run } = useRequest(GetAllDesignTables, {
|
|
manual: true,
|
|
manual: true,
|
|
});
|
|
});
|
|
const [tableList, setTableList] = useState<TableItemType[]>(project?.tables);
|
|
const [tableList, setTableList] = useState<TableItemType[]>(project?.tables);
|
|
|
|
+ const [step, setStep] = useState(0);
|
|
|
|
+
|
|
|
|
+ // 选中需要同步的表
|
|
|
|
+ const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);
|
|
|
|
+ const [selectedRows, setSelectedRows] = useState<any[]>([]);
|
|
|
|
+ const [okLoading, setOkLoading] = useState(false);
|
|
|
|
+ const [resultStatus, setResultStatus] = useState<"success" | "error">(
|
|
|
|
+ "success"
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ if (step === 0 && tableList.length) {
|
|
|
|
+ setSelectedRowKeys(tableList.map((item) => item.table.id));
|
|
|
|
+ setSelectedRows(tableList);
|
|
|
|
+ }
|
|
|
|
+ }, [tableList, step]);
|
|
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
useImperativeHandle(ref, () => ({
|
|
open: () => {
|
|
open: () => {
|
|
|
|
+ setStep(0);
|
|
setOpen(true);
|
|
setOpen(true);
|
|
run();
|
|
run();
|
|
},
|
|
},
|
|
@@ -34,7 +62,7 @@ export default forwardRef(function SyncModal(props: {onPush: () => void}, ref) {
|
|
dataTable: any;
|
|
dataTable: any;
|
|
}[] = [];
|
|
}[] = [];
|
|
const tables = data?.result?.appBusinessTables || [];
|
|
const tables = data?.result?.appBusinessTables || [];
|
|
- tableList.forEach((tableItem) => {
|
|
|
|
|
|
+ selectedRows.forEach((tableItem) => {
|
|
const dataTable = tables.find(
|
|
const dataTable = tables.find(
|
|
(item: any) =>
|
|
(item: any) =>
|
|
item.schemaName === tableItem.table.schemaName ||
|
|
item.schemaName === tableItem.table.schemaName ||
|
|
@@ -49,35 +77,187 @@ export default forwardRef(function SyncModal(props: {onPush: () => void}, ref) {
|
|
});
|
|
});
|
|
|
|
|
|
return list;
|
|
return list;
|
|
- }, [tableList, data]);
|
|
|
|
|
|
+ }, [selectedRows, data]);
|
|
|
|
|
|
|
|
+ // 差异对比更新当前模型数据
|
|
const handleUpdateTable = (tableItem: TableItemType) => {
|
|
const handleUpdateTable = (tableItem: TableItemType) => {
|
|
- setTableList(
|
|
|
|
- tableList.map((item) =>
|
|
|
|
|
|
+ setSelectedRows(
|
|
|
|
+ selectedRows.map((item) =>
|
|
item.table.id === tableItem.table.id ? tableItem : item
|
|
item.table.id === tableItem.table.id ? tableItem : item
|
|
)
|
|
)
|
|
);
|
|
);
|
|
- }
|
|
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const Step1Comp = () => {
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <ProTable
|
|
|
|
+ title={() => "请选择需要推送的表"}
|
|
|
|
+ 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 (
|
|
|
|
+ <>
|
|
|
|
+ <div className="text-14px font-bold m-y-12px">
|
|
|
|
+ 提示:共选择了
|
|
|
|
+ <span className="color-green">{selectedRows.length}</span>
|
|
|
|
+ 张表格数据。
|
|
|
|
+ {existTableList.length ? (
|
|
|
|
+ <>
|
|
|
|
+ 其中有
|
|
|
|
+ <span className="color-#faad14">{existTableList.length}</span>
|
|
|
|
+ 张表存在相同的编码或别名,可对比确认后提交。
|
|
|
|
+ </>
|
|
|
|
+ ) : null}
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <Collapse
|
|
|
|
+ items={list.map((item) => {
|
|
|
|
+ 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: (
|
|
|
|
+ <span
|
|
|
|
+ style={{
|
|
|
|
+ color: existTable ? "#faad14" : "",
|
|
|
|
+ }}
|
|
|
|
+ >{`${table.schemaName}${name ? `(${name})` : ""}`}</span>
|
|
|
|
+ ),
|
|
|
|
+ children: (
|
|
|
|
+ <DiffTable
|
|
|
|
+ sourceTable={item}
|
|
|
|
+ targetTableId={existTable?.dataTable?.id}
|
|
|
|
+ onChange={handleUpdateTable}
|
|
|
|
+ />
|
|
|
|
+ ),
|
|
|
|
+ };
|
|
|
|
+ })}
|
|
|
|
+ />
|
|
|
|
+ </>
|
|
|
|
+ );
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const Step3Comp = () => {
|
|
|
|
+ return (
|
|
|
|
+ <div className="flex justify-center items-center h-full">
|
|
|
|
+ {okLoading ? (
|
|
|
|
+ <Spin spinning={okLoading} tip="正在同步数据...">
|
|
|
|
+ <div className="w-500px h-full"></div>
|
|
|
|
+ </Spin>
|
|
|
|
+ ) : (
|
|
|
|
+ <>
|
|
|
|
+ {resultStatus === "success" ? (
|
|
|
|
+ <Result
|
|
|
|
+ status="success"
|
|
|
|
+ title="数据同步完成!"
|
|
|
|
+ subTitle="请查看数据表的数据信息"
|
|
|
|
+ />
|
|
|
|
+ ) : (
|
|
|
|
+ <Result
|
|
|
|
+ status="error"
|
|
|
|
+ title="数据同步失败!"
|
|
|
|
+ subTitle="请检查数据表的数据信息"
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ </>
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ );
|
|
|
|
+ };
|
|
|
|
|
|
- const [okLoading, setOkLoading] = useState(false);
|
|
|
|
const handleSubmit = async () => {
|
|
const handleSubmit = async () => {
|
|
|
|
+ setStep(2);
|
|
try {
|
|
try {
|
|
setOkLoading(true);
|
|
setOkLoading(true);
|
|
- await PushDataModelTable(tableList);
|
|
|
|
- message.success("同步推送完成");
|
|
|
|
|
|
+ await PushDataModelTable(selectedRows);
|
|
|
|
+ // message.success("同步推送完成");
|
|
|
|
+ setResultStatus("success");
|
|
setOpen(false);
|
|
setOpen(false);
|
|
props.onPush?.();
|
|
props.onPush?.();
|
|
|
|
+ } catch (err) {
|
|
|
|
+ setResultStatus("error");
|
|
} finally {
|
|
} finally {
|
|
setOkLoading(false);
|
|
setOkLoading(false);
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ };
|
|
|
|
|
|
return (
|
|
return (
|
|
<Modal
|
|
<Modal
|
|
title="数据同步推送"
|
|
title="数据同步推送"
|
|
width={"100%"}
|
|
width={"100%"}
|
|
open={open}
|
|
open={open}
|
|
- okText="同步"
|
|
|
|
loading={loading}
|
|
loading={loading}
|
|
style={{
|
|
style={{
|
|
top: 10,
|
|
top: 10,
|
|
@@ -91,55 +271,67 @@ export default forwardRef(function SyncModal(props: {onPush: () => void}, ref) {
|
|
}}
|
|
}}
|
|
okButtonProps={{
|
|
okButtonProps={{
|
|
loading: okLoading,
|
|
loading: okLoading,
|
|
- disabled: !tableList.length
|
|
|
|
|
|
+ disabled: !selectedRows.length,
|
|
}}
|
|
}}
|
|
onCancel={() => setOpen(false)}
|
|
onCancel={() => setOpen(false)}
|
|
- onOk={handleSubmit}
|
|
|
|
- >
|
|
|
|
- <div className="text-14px font-bold m-y-12px">
|
|
|
|
- 提示:将当前模型表推送至数据表,一共
|
|
|
|
- <span className="color-green">{tableList.length}</span>
|
|
|
|
- 张表格数据。
|
|
|
|
- {existTableList.length ? (
|
|
|
|
|
|
+ footer={(_, { CancelBtn }) => {
|
|
|
|
+ return (
|
|
<>
|
|
<>
|
|
- 其中有<span className="color-#faad14">{existTableList.length}</span>
|
|
|
|
- 张表存在相同的编码或别名,可对比确认后提交。
|
|
|
|
|
|
+ <CancelBtn />
|
|
|
|
+ {step === 0 && (
|
|
|
|
+ <Button
|
|
|
|
+ type="primary"
|
|
|
|
+ disabled={!selectedRows.length}
|
|
|
|
+ onClick={() => setStep(step + 1)}
|
|
|
|
+ >
|
|
|
|
+ 下一步
|
|
|
|
+ </Button>
|
|
|
|
+ )}
|
|
|
|
+ {step > 0 && (
|
|
|
|
+ <Button onClick={() => setStep(step - 1)}>上一步</Button>
|
|
|
|
+ )}
|
|
|
|
+ {step === 1 && (
|
|
|
|
+ <Button type="primary" onClick={handleSubmit}>
|
|
|
|
+ 开始同步
|
|
|
|
+ </Button>
|
|
|
|
+ )}
|
|
</>
|
|
</>
|
|
- ) : null}
|
|
|
|
|
|
+ );
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <div className="h-full flex flex-col overflow-hidden">
|
|
|
|
+ <div className="py-12px px-30px">
|
|
|
|
+ <Steps
|
|
|
|
+ current={step}
|
|
|
|
+ progressDot
|
|
|
|
+ items={[
|
|
|
|
+ {
|
|
|
|
+ title: "选择数据表",
|
|
|
|
+ description: "选择需要同步的表",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ title: "差异对比",
|
|
|
|
+ description: "数据模型与数据表进行对比",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ title: "推送",
|
|
|
|
+ description: "推送到数据表",
|
|
|
|
+ },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div className="flex-1 overflow-auto">
|
|
|
|
+ {step === 0 && <Step1Comp />}
|
|
|
|
+ {step === 1 && <Step2Comp />}
|
|
|
|
+ {step === 2 && <Step3Comp />}
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- <Collapse
|
|
|
|
- items={tableList.map((item) => {
|
|
|
|
- const { table } = item;
|
|
|
|
- const name = table.langNameList?.find(
|
|
|
|
- (item) => item.name === "zh-CN"
|
|
|
|
- )?.value;
|
|
|
|
- const existTable = existTableList.find(
|
|
|
|
- (item) => item.modelTable.table.id === table.id
|
|
|
|
- );
|
|
|
|
- return {
|
|
|
|
- key: table.id,
|
|
|
|
- label: (
|
|
|
|
- <span
|
|
|
|
- style={{
|
|
|
|
- color: existTable
|
|
|
|
- ? "#faad14"
|
|
|
|
- : "",
|
|
|
|
- }}
|
|
|
|
- >{`${table.schemaName}${name ? `(${name})` : ""}`}</span>
|
|
|
|
- ),
|
|
|
|
- children: (
|
|
|
|
- <DiffTable
|
|
|
|
- sourceTable={item}
|
|
|
|
- targetTableId={existTable?.dataTable?.id}
|
|
|
|
- onChange={handleUpdateTable}
|
|
|
|
- />
|
|
|
|
- ),
|
|
|
|
- };
|
|
|
|
- })}
|
|
|
|
- />
|
|
|
|
- {
|
|
|
|
- !tableList.length && <Empty image={NoData} description="当前模型表为空,请添加后再进行同步!"/>
|
|
|
|
- }
|
|
|
|
|
|
+ {!tableList.length && (
|
|
|
|
+ <Empty
|
|
|
|
+ image={NoData}
|
|
|
|
+ description="当前模型表为空,请添加后再进行同步!"
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
</Modal>
|
|
</Modal>
|
|
);
|
|
);
|
|
});
|
|
});
|