Bläddra i källkod

feat: 添加新增模型弹窗

liaojiaxing 3 månader sedan
förälder
incheckning
170b672531

BIN
apps/er-designer/src/assets/image/default.png


+ 63 - 0
apps/er-designer/src/components/AddModel.tsx

@@ -0,0 +1,63 @@
+import React from "react";
+import { Modal, Input, Form, message } from "antd";
+import { SaveDataModel } from "@/api";
+import { TableType } from "@/enum";
+
+export default React.forwardRef(function AddModel(
+  props: { onChange?: () => {} },
+  ref
+) {
+  const [open, setOpen] = React.useState(false);
+  const [form] = Form.useForm();
+  const type = React.useRef<TableType>();
+  React.useImperativeHandle(ref, () => {
+    return {
+      open: (tableType: TableType) => {
+        type.current = tableType;
+        setOpen(true);
+        form.resetFields();
+      },
+      close: () => {
+        setOpen(false);
+      },
+    };
+  });
+
+  const handleSubmit = () => {
+    form.validateFields().then(async (values) => {
+      console.log(values, message);
+      await SaveDataModel({
+        ...values,
+        type: type.current,
+      });
+      message.success("创建成功");
+      props.onChange?.();
+      setOpen(false);
+    });
+  };
+
+  return (
+    <Modal
+      open={open}
+      width={440}
+      title="创建模型"
+      onCancel={() => setOpen(false)}
+      onOk={handleSubmit}
+    >
+      <Form layout="vertical" form={form}>
+        <Form.Item
+          label="模型名称"
+          name="name"
+          rules={[
+            { required: true, message: "请输入模型名称,长度50以内!", max: 50 },
+          ]}
+        >
+          <Input placeholder="请输入模型名称" />
+        </Form.Item>
+        <Form.Item name="description" label="模型描述">
+          <Input.TextArea placeholder="请输入模型描述" />
+        </Form.Item>
+      </Form>
+    </Modal>
+  );
+});

+ 10 - 5
apps/er-designer/src/models/erModel.tsx

@@ -6,7 +6,7 @@ import { Snapline } from "@antv/x6-plugin-snapline";
 import { Keyboard } from "@antv/x6-plugin-keyboard";
 import { Export } from "@antv/x6-plugin-export";
 import { Selection } from "@antv/x6-plugin-selection";
-import { GetAllDesignTables } from "@/api";
+import { SaveDataModel } from "@/api";
 import { useRequest } from "umi";
 import { useFullscreen } from "ahooks";
 import { throttle } from "lodash-es";
@@ -43,13 +43,13 @@ export default function erModel() {
   });
   const [project, setProjectInfo] = useState<ProjectInfo>({
     id: "1",
-    name: "项目1",
+    name: "新建模型",
     directory: "",
     type: 3,
-    description: "模型描述",
+    description: "",
     isTemplate: false,
-    industry: "互联网",
-    publishStatus: "未发布",
+    industry: "",
+    publishStatus: "",
     tables: [],
     relations: [],
     topicAreas: [],
@@ -115,6 +115,11 @@ export default function erModel() {
         }
       }
     }
+
+    // 提交服务器
+    if(!isInit) {
+      SaveDataModel(project);
+    }
   };
 
   useEffect(() => {

+ 73 - 130
apps/er-designer/src/pages/home/All.tsx

@@ -1,5 +1,5 @@
 import React, { useEffect, useMemo, useRef, useState } from "react";
-import { ProTable, PageContainer } from "@ant-design/pro-components";
+import { ProTable, PageContainer, } from "@ant-design/pro-components";
 import {
   Card,
   Col,
@@ -14,31 +14,23 @@ import {
   Dropdown,
   message,
   TreeDataNode,
-  Tag,
   Tooltip,
+  Form,
 } from "antd";
 import type { MenuProps } from "antd";
-import { Icon, useRequest } from "umi";
+import { useRequest } from "umi";
 import {
   AppstoreOutlined,
   MenuOutlined,
   MoreOutlined,
+  PlusOutlined,
 } from "@ant-design/icons";
-import {
-  FlowchartMindMapList,
-  AddFolder,
-  EditFolder,
-  DeleteFolder,
-  Move,
-  Copy,
-  GetAllFolders,
-} from "@/api/systemDesigner";
+import { GetDataModelList } from "@/api";
 import ProjectCard from "./ProjectCard";
-import { graphOptions } from "./data";
-import { GraphType } from "@/enum";
 import DragItem from "./DragItem";
 import DropItem from "./DropItem";
-import { createNew, listToTree } from "@/utils";
+import { TableType } from "@/enum";
+import AddModel from "@/components/AddModel";
 
 type BreadcrumbItem = {
   title: React.ReactNode;
@@ -49,16 +41,17 @@ type BreadcrumbItem = {
 export default function All({
   onChangeCurrentFolder,
   updateKey,
+  type,
 }: {
   onChangeCurrentFolder: (id: string) => void;
   updateKey: number;
+  type: TableType;
 }) {
   const [display, setDisplay] = useState("card");
   const [folderData, setFolderData] = useState<any[]>([]);
   const [dataSource, setDataSource] = useState<any[]>([]);
   const [total, setTotal] = useState(0);
   const [searchName, setSearchName] = useState("");
-  const [graphType, setGraphType] = useState<GraphType | "">("");
   const [currentPage, setCurrentPage] = useState(1);
   const [pageSize, setPageSize] = useState(12);
   const [open, setOpen] = useState(false);
@@ -67,37 +60,27 @@ export default function All({
   const moveSource = useRef<{ id: string; type: "folder" | "chart" }>();
   const [folderList, setFolderList] = useState<any[]>([]);
   const [selectFolder, setSelectFolder] = useState("");
+  const addModelRef = useRef<{open: (type: TableType) => void}>();
 
-  const { loading, run, refresh } = useRequest(FlowchartMindMapList, {
+  const { loading, run, refresh } = useRequest(GetDataModelList, {
     defaultParams: [
       {
-        currentPage,
-        pageSize,
-        filters: [
-          {
-            name: "name",
-            value: searchName,
-          },
-          {
-            name: "folderId",
-            value: currentFolder.current,
-          },
-        ],
+        name: '1'
       },
     ],
     onSuccess: (res) => {
       const result = res?.result || {};
-      setDataSource(result?.pageList?.model || []);
-      setFolderData(result?.folders || []);
-      setTotal(result?.pageList?.totalCount || 0);
-    },
+      setDataSource(result);
+      // setFolderData(result?.folders || []);
+      setTotal(result.length || 0);
+    }
   });
 
-  const { refresh: refreshFolderAll } = useRequest(GetAllFolders, {
-    onSuccess: (res) => {
-      setFolderList(res?.result || []);
-    },
-  });
+  // const { refresh: refreshFolderAll } = useRequest(GetAllFolders, {
+  //   onSuccess: (res) => {
+  //     setFolderList(res?.result || []);
+  //   },
+  // });
 
   useEffect(() => {
     updateKey && getData(1, pageSize);
@@ -123,7 +106,7 @@ export default function All({
     {
       title: (
         <span className="ant-breadcrumb-link">
-          <a>我的文件</a>
+          <a>{type === TableType.BusinessTable ? '业务表' : '流程表'}</a>
         </span>
       ),
       index: 0,
@@ -138,26 +121,11 @@ export default function All({
     useState<BreadcrumbItem[]>(defultData);
   const breadcrumbDataRef = useRef<BreadcrumbItem[]>(breadcrumbData);
 
-  const getData = (page: number, pageSize: number, type?: GraphType | "") => {
+  const getData = (page: number, pageSize: number, type?: string) => {
     setCurrentPage(page);
     setPageSize(pageSize);
     run({
-      currentPage: page,
-      pageSize: pageSize,
-      filters: [
-        {
-          name: "searchText",
-          value: searchName,
-        },
-        {
-          name: "folderId",
-          value: currentFolder.current,
-        },
-        {
-          name: "type",
-          value: type !== undefined ? type : graphType,
-        },
-      ],
+      name: '1'
     });
   };
 
@@ -189,7 +157,6 @@ export default function All({
   // 构建文件夹树
   const folderTreeData = useMemo((): TreeDataNode[] => {
     return [
-      listToTree(
         folderList.map((item) => {
           return {
             ...item,
@@ -204,7 +171,7 @@ export default function All({
             ),
             icon: <FolderIcon />,
           };
-        }),
+        },
         root
       ),
     ] as unknown as TreeDataNode[];
@@ -230,10 +197,10 @@ export default function All({
             />
           ),
           onOk: async () => {
-            await AddFolder({
-              parentId: currentFolder.current,
-              name,
-            });
+            // await AddFolder({
+            //   parentId: currentFolder.current,
+            //   name,
+            // });
             message.success("添加成功");
             refresh();
           },
@@ -245,7 +212,7 @@ export default function All({
       label: <span className="ml-4px">添加模型</span>,
       // icon: <Icon icon="local:flow" width="22px" />,
       onClick: async () => {
-        await createNew(GraphType.flowchart, currentFolder.current);
+        // await createNew(GraphType.flowchart, currentFolder.current);
         getData(1, pageSize);
       },
     },
@@ -285,12 +252,6 @@ export default function All({
     getData(1, pageSize);
   };
 
-  // 搜索图形类型
-  const setSearchGraphType = (type: GraphType | "") => {
-    setGraphType(type);
-    getData(1, pageSize, type);
-  };
-
   const handleOpenFolderModal = (id: string, type: "folder" | "chart") => {
     moveSource.current = {
       id,
@@ -310,34 +271,34 @@ export default function All({
   const handleMove = (targetFolderId: string) => {
     if (!moveSource.current || targetFolderId === moveSource.current?.id)
       return;
-    Move({
-      fileType: moveSource.current.type,
-      fileId: moveSource.current.id,
-      targetFolderId,
-    }).then(() => {
-      message.success("移动成功");
-      refresh();
-      setOpen(false);
-    });
+    // Move({
+    //   fileType: moveSource.current.type,
+    //   fileId: moveSource.current.id,
+    //   targetFolderId,
+    // }).then(() => {
+    //   message.success("移动成功");
+    //   refresh();
+    //   setOpen(false);
+    // });
     if (moveSource.current?.type === "folder") {
-      refreshFolderAll();
+      // refreshFolderAll();
     }
   };
 
   const handleCopy = (targetFolderId: string) => {
     if (!moveSource.current || targetFolderId === moveSource.current?.id)
       return;
-    Copy({
-      fileType: moveSource.current.type,
-      fileId: moveSource.current.id,
-      targetFolderId,
-    }).then(() => {
-      message.success("复制成功");
-      refresh();
-      setOpen(false);
-    });
+    // Copy({
+    //   fileType: moveSource.current.type,
+    //   fileId: moveSource.current.id,
+    //   targetFolderId,
+    // }).then(() => {
+    //   message.success("复制成功");
+    //   refresh();
+    //   setOpen(false);
+    // });
     if (moveSource.current?.type === "folder") {
-      refreshFolderAll();
+      // refreshFolderAll();
     }
   };
 
@@ -354,7 +315,17 @@ export default function All({
       >
         <div className="flex justify-between items-center m-b-12px">
           <Breadcrumb items={breadcrumbData} />
-          <div className="right flex gap-12px">
+          <AddModel ref={addModelRef}/>
+          <div className="right flex items-center gap-12px">
+            <Button
+              type="primary"
+              icon={<PlusOutlined />}
+              onClick={() => {
+                addModelRef.current?.open(type)
+              }}
+            >
+              新建项目
+            </Button>
             <Input
               placeholder="搜索文件"
               prefix={<i className="iconfont icon-chazhao" />}
@@ -364,34 +335,6 @@ export default function All({
               }}
               onPressEnter={handleSearch}
             />
-            <span>
-              {graphType ? (
-                <Tag
-                  color="#108ee9"
-                  closable
-                  onClose={() => setSearchGraphType("")}
-                >
-                  {graphOptions.find((item) => item.value === graphType)?.label}
-                </Tag>
-              ) : (
-                <Dropdown
-                  menu={{
-                    items: graphOptions.map((item) => {
-                      return {
-                        key: item.key,
-                        label: item.label,
-                        value: item.value,
-                        onClick: () => {
-                          setSearchGraphType(item.value);
-                        },
-                      };
-                    }),
-                  }}
-                >
-                  <Button icon={<i className="iconfont icon-shaixuan" />} />
-                </Dropdown>
-              )}
-            </span>
             <span>
               <Tooltip title={display === "card" ? "列表模式" : "卡片模式"}>
                 <Button
@@ -477,12 +420,12 @@ export default function All({
                                                     />
                                                   ),
                                                   onOk: async () => {
-                                                    await EditFolder({
-                                                      id: item.id,
-                                                      name,
-                                                    });
-                                                    refresh();
-                                                    refreshFolderAll;
+                                                    // await EditFolder({
+                                                    //   id: item.id,
+                                                    //   name,
+                                                    // });
+                                                    // refresh();
+                                                    // refreshFolderAll;
                                                     message.success(
                                                       "重命名成功"
                                                     );
@@ -509,12 +452,12 @@ export default function All({
                                                   content: "确定删除该文件夹?",
                                                   centered: true,
                                                   onOk: async () => {
-                                                    await DeleteFolder({
-                                                      id: item.id,
-                                                    });
-                                                    message.success("删除成功");
-                                                    refresh();
-                                                    refreshFolderAll();
+                                                    // await DeleteFolder({
+                                                    //   id: item.id,
+                                                    // });
+                                                    // message.success("删除成功");
+                                                    // refresh();
+                                                    // refreshFolderAll();
                                                   },
                                                 });
                                               },

+ 6 - 7
apps/er-designer/src/pages/home/ProjectCard.tsx

@@ -1,8 +1,6 @@
 import React, { useEffect, useState } from "react";
 import { Card, Dropdown, Modal, Input, message } from "antd";
-import defaultFlowImg from "@/assets/image/flow.png";
-import defaultMindImg from "@/assets/image/mindmap.png";
-// import { DeleteGraph, EditGraph } from "@/api/systemDesigner";
+import defaultImg from "@/assets/image/default.png"
 import { GetFile } from "@/api";
 
 export default function ProjectCard({
@@ -49,7 +47,7 @@ export default function ProjectCard({
             border: "solid 1px #f5f5f5",
           }}
           src={
-            coverImg
+            coverImg || defaultImg
           }
         />
       }
@@ -126,11 +124,12 @@ export default function ProjectCard({
       )}
       <Card.Meta
         title={
-          <span>
-            {record.name}
+          <span className="flex items-center justify-between">
+            <span className="flex-1 tru ">{record.name}</span>
+            <span className="text-12px font-normal color-#999">更新于:{record.updateTime}</span>
           </span>
         }
-        description={`更新于: ${record.updatedTime}`}
+        description={`${record.description}`}
       />
     </Card>
   );

+ 31 - 9
apps/er-designer/src/pages/home/index.tsx

@@ -4,9 +4,10 @@ import { css } from "@emotion/css";
 import { Space, Button, ConfigProvider, Popover } from "antd";
 import React, { useMemo, useRef, useState } from "react";
 import { Icon } from "umi";
-// import All from "./All";
+import All from "./All";
 import Collect from "./Collect";
 import Template from "./Template";
+import { TableType } from "@/enum";
 
 export default () => {
   const currentFolder = useRef("root");
@@ -74,16 +75,24 @@ export default () => {
     currentFolder.current = id;
   };
 
-  const [pathname, setPathname] = useState("/all");
+  const [pathname, setPathname] = useState("/all/business");
   const routes = [
     {
       path: "/all",
-      name: "全部",
+      name: "数据模型",
       icon: <i className="iconfont icon-xitong" />,
-      component: (
-        // <All onChangeCurrentFolder={handleChangeFolder} updateKey={updateKey} />
-        <div></div>
-      ),
+      children: [
+        {
+          path: "/all/business",
+          name: "业务模型",
+          component: <All onChangeCurrentFolder={handleChangeFolder} updateKey={updateKey} type={TableType.BusinessTable} />
+        },
+        {
+          path: "/all/flow",
+          name: "流程模型",
+          component: <All onChangeCurrentFolder={handleChangeFolder} updateKey={updateKey} type={TableType.FlowTable} />
+        },
+      ]
     },
     {
       path: "/recently",
@@ -107,7 +116,20 @@ export default () => {
 
   const content = useMemo(() => {
     currentFolder.current = "root";
-    return routes.find((item) => item.path === pathname)?.component;
+    let comp: React.ReactNode;
+    routes.forEach(item => {
+      if (item.path === pathname) {
+        comp = item.component;
+      }
+      if (item.children) {
+        item.children.forEach(child => {
+          if (child.path === pathname) {
+            comp = child.component;
+          }
+        })
+      }
+    });
+    return comp;
   }, [pathname, updateKey]);
 
   return (
@@ -121,7 +143,7 @@ export default () => {
       <ProLayout
         headerTitleRender={() => null}
         logo={false}
-        title={"系统设计"}
+        title={"数据模型"}
         location={{ pathname }}
         route={{
           routes,

+ 2 - 0
apps/er-designer/src/type.d.ts

@@ -145,6 +145,8 @@ export interface ProjectInfo {
   name: string;
   // 文件夹
   directory: string;
+  // 封面
+  coverImage?: string;
   // 模型类型
   type: number; // 2 流程 3 业务表
   // 创建时间