123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- import {
- forwardRef,
- useImperativeHandle,
- useMemo,
- useRef,
- useState,
- } from "react";
- import {
- Col,
- Form,
- Input,
- message,
- Modal,
- Row,
- Select,
- Tabs,
- TabsProps,
- } from "antd";
- import LangInput from "@/components/LangInput";
- import LangInputTextarea from "@/components/LangInputTextarea";
- import { TableType } from "@/enum";
- import { createColumn, createTable } from "@/utils";
- import { TableItemType } from "@/type";
- import { useModel, useRequest } from "umi";
- import {
- GetAllDesignTables,
- GetAllBusinessTableColumns,
- GetBusinessTablesByTableId,
- ListLangByKey,
- } from "@/api";
- import { validateTableCode, validateAliasName } from "@/utils/validator";
- import { pick } from "lodash-es";
- import CustomColorPicker from "@/components/CustomColorPicker";
- export default forwardRef(function AddTable(
- props: {
- onChange: (tables: TableItemType[]) => void;
- },
- ref
- ) {
- const [open, setOpen] = useState(false);
- const tableItemRef = useRef<TableItemType>();
- const { project, graph } = useModel("erModel");
- const [tabActiveKey, setTabActiveKey] = useState("1");
- const [form] = Form.useForm();
- const [form1] = Form.useForm();
- const [formModel, setFormModel] = useState<TableItemType["table"]>();
- const [hideAddTab, setHideAddTab] = useState(false);
- const [color, setColor] = useState<string>();
- useImperativeHandle(ref, () => ({
- open: () => {
- // 获取当前模型类型
- tableItemRef.current = createTable(project.type, project.id);
- setFormModel(tableItemRef.current.table);
- setOpen(true);
- setColor(undefined);
- },
- openImportMode: () => {
- setTabActiveKey("2");
- run();
- setHideAddTab(true);
- setOpen(true);
- },
- close: () => {
- setOpen(false);
- },
- }));
- const { data, loading, run } = useRequest(() => GetAllDesignTables(), {
- manual: true,
- });
- const tableOptions = useMemo(() => {
- const options =
- data?.result?.appBusinessTables
- ?.filter(
- (item: any) =>
- // 过滤当前数据表类型及存在相同schemaName、aliasName的表
- item?.type == project?.type
- // && !project.tables.find(
- // (tableItem) =>
- // tableItem.table.schemaName === item.schemaName ||
- // tableItem.table.aliasName === item.aliasName
- // )
- )
- ?.map((item: any) => {
- // 判断是否存在已引入的表
- const hasTable = project.tables.find(
- (tableItem: TableItemType) =>
- tableItem.table.schemaName === item.schemaName ||
- tableItem.table.aliasName === item.aliasName
- );
- return {
- label: `${item?.schemaName}(${item.name})`,
- value: item?.id,
- disabled: hasTable,
- };
- }) || [];
- return options;
- }, [data]);
- const items: TabsProps["items"] = [
- {
- key: "1",
- label: `新建`,
- children: (
- <div>
- <Form labelCol={{ span: 8 }} form={form}>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item
- label="编码"
- name="schemaName"
- rules={[
- { required: true, message: "请输入编码" },
- validateTableCode,
- ]}
- tooltip="包含字母、下划线、数字, 必须小写字母开头,且必须有下划线! 如:user_info"
- >
- <Input
- placeholder="请输入"
- value={formModel?.schemaName}
- onChange={(e) => handleChange("schemaName", e.target.value)}
- />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item label="表类型" name="type">
- <Input
- placeholder="请输入"
- value={
- formModel?.type == TableType.BusinessTable
- ? "业务表"
- : "视图表"
- }
- disabled
- />
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item
- label="别名"
- name="aliasName"
- rules={[
- { required: true, message: "请输入别名" },
- validateAliasName,
- ]}
- tooltip="包含字母、数字, 必须小写字母开头! 如:userinfo"
- >
- <Input
- placeholder="请输入"
- value={formModel?.aliasName}
- onChange={(e) => handleChange("aliasName", e.target.value)}
- />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item label="表名" name="langNameList">
- <LangInput
- value={formModel?.langNameList}
- onChange={(lang) => handleChange("langNameList", lang)}
- />
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={24}>
- <Form.Item
- label="描述"
- labelCol={{ span: 4 }}
- name="langDescriptionList"
- >
- <LangInputTextarea
- value={formModel?.langDescriptionList}
- onChange={(lang) =>
- handleChange("langDescriptionList", lang)
- }
- />
- </Form.Item>
- </Col>
- </Row>
- </Form>
- </div>
- ),
- },
- {
- key: "2",
- label: `引入`,
- children: (
- <div>
- <Form labelCol={{ span: 4 }} form={form1}>
- <Form.Item
- label="选择表"
- name="table"
- rules={[{ required: true, message: "请选择表" }]}
- >
- <Select
- mode="multiple"
- placeholder="请选择"
- loading={loading}
- options={tableOptions}
- />
- </Form.Item>
- <Form.Item label="颜色" name="color">
- <CustomColorPicker onChange={setColor}>
- {color ? (
- <div
- className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none cursor-pointer shadow-inner"
- style={{ background: color || "#eee" }}
- ></div>
- ) : (
- <span className="bg-#eee px-5px py-3px rounded-4px cursor-pointer text-12px text-#666">
- 随机生成,点击可选择颜色
- </span>
- )}
- </CustomColorPicker>
- </Form.Item>
- </Form>
- </div>
- ),
- },
- ];
- const handleChange = (key: string, value: any) => {
- formModel &&
- setFormModel({
- ...formModel,
- [key]: value,
- });
- };
- // 获取引入的表转换成模型表
- const getNewTableByTable = async (
- tableData: any,
- columns: any[],
- tableOther: Record<string, any> = {}
- ): Promise<TableItemType> => {
- const newTable = createTable(project.type, project.id);
- const langKeyList: string[] = [];
- if (tableData.langName) {
- langKeyList.push(tableData.langName);
- }
- if (tableData.langDescription) {
- langKeyList.push(tableData.langDescription);
- }
- columns.forEach((item) => {
- if (item.langName) {
- langKeyList.push(item.langName);
- }
- });
- // 获取全部多语言数据
- const langList = await Promise.all(
- [...new Set(langKeyList)].map((key) =>
- ListLangByKey({ key }).then((res) => res.result)
- )
- );
- const langName = langList.find((item) => item.key === tableData.langName);
- const descName = langList.find(
- (item) => item.key === tableData.langDescription
- );
- return {
- isTable: true,
- // 表格数据
- table: {
- ...newTable.table,
- ...pick(tableData, ["schemaName", "aliasName", "isDeleted"]),
- langNameList: [
- { name: "zh-CN", value: langName?.["zh-CN"] || "" },
- { name: "en", value: langName?.["en"] || "" },
- ],
- langDescriptionList: [
- { name: "zh-CN", value: descName?.["zh-CN"] || "" },
- { name: "en", value: descName?.["en"] || "" },
- ],
- ...tableOther,
- },
- // 字段数据
- tableColumnList: columns.map((item) => {
- const column = createColumn(newTable.table.id);
- const langName = langList.find((lang) => lang.key === item.langName);
- return {
- ...column,
- ...pick(item, Object.keys(column)),
- langNameList: [
- { name: "zh-CN", value: langName?.["zh-CN"] || "" },
- { name: "en", value: langName?.["en"] || "" },
- ],
- };
- }),
- };
- };
- const [loadingColumns, setLoadingColumns] = useState(false);
- const handleOk = () => {
- // 新建
- if (tabActiveKey === "1") {
- form.validateFields().then(() => {
- if (tableItemRef.current && formModel) {
- props.onChange([
- {
- ...tableItemRef.current,
- table: formModel,
- },
- ]);
- }
- form.resetFields();
- setOpen(false);
- });
- }
- // 引入
- if (tabActiveKey === "2") {
- form1.validateFields().then(async () => {
- // 加载表格字段
- const values = form1.getFieldsValue();
- try {
- setLoadingColumns(true);
- const requestList = values.table.map((tableId: string) => [
- GetBusinessTablesByTableId(tableId),
- GetAllBusinessTableColumns({
- currentPage: 1,
- pageSize: 2000,
- orderByProperty: "isPreDefined DESC, DisplayOrder",
- Ascending: true,
- totalPage: 1,
- totalCount: 1,
- filters: [
- {
- name: "BusinessTableId",
- value: tableId,
- },
- ],
- }),
- ]);
- if (requestList.length === 0) {
- message.error("请选择要引入的表");
- return;
- }
- const resArr = await Promise.allSettled(
- (requestList as Promise<any>[]).flat(1)
- );
- const tableMap: Record<string, any> = {};
- resArr.forEach((res) => {
- if (res.status === "fulfilled") {
- const value = res.value?.result;
- // 表格数据
- if (Array.isArray(value) && value[0]) {
- tableMap[value[0].id] = {
- table: value[0],
- tableColumnList: [],
- };
- } else {
- // 字段数据
- const model = res.value?.result?.model;
- const tableId = model?.[0]?.businessTableId;
- if (tableId) {
- if (tableMap[tableId]) {
- tableMap[tableId].tableColumnList = model;
- } else {
- tableMap[tableId] = {
- table: {},
- tableColumnList: model,
- };
- }
- }
- }
- }
- });
- const rect = graph?.getAllCellsBBox();
- // 计算起始位置 默认往最后加
- const startY = (rect?.height || 0) + (rect?.y || 0) + 20;
- const result = Object.keys(tableMap).map(async (key, index) => {
- const table = await getNewTableByTable(
- tableMap[key].table,
- tableMap[key].tableColumnList
- );
- table.table.style.y = startY;
- table.table.style.x =
- 100 + index * (project.setting.tableWidth + 20);
- if (color) {
- table.table.style.color = color;
- }
- return table;
- });
- const newTables = await Promise.all(result);
- props.onChange(newTables);
- form1.resetFields();
- setOpen(false);
- } catch (err) {
- console.error(err);
- message.warning("引入失败");
- } finally {
- setLoadingColumns(false);
- }
- });
- }
- };
- const handleChangeTableActiveKey = (key: string) => {
- setTabActiveKey(key);
- if (key === "2") {
- run();
- }
- };
- return (
- <Modal
- open={open}
- title="添加表"
- okText={loadingColumns ? "加载中..." : "确定"}
- cancelText="取消"
- onCancel={() => setOpen(false)}
- onOk={handleOk}
- okButtonProps={{
- loading: loadingColumns,
- }}
- >
- <Tabs
- items={items.filter((item) => (hideAddTab ? item.key === "2" : true))}
- activeKey={tabActiveKey}
- onChange={handleChangeTableActiveKey}
- />
- </Modal>
- );
- });
|