Browse Source

feat: 添加表单校验封装

liaojiaxing 4 months ago
parent
commit
d32996e0c3

+ 4 - 1
apps/er-designer/src/models/erModel.tsx

@@ -37,7 +37,10 @@ export default function erModel() {
   const historyRef = useRef<ProjectInfo[]>([]);
   const activeIndex = useRef(0);
   const [_isFullscreen, { enterFullscreen, exitFullscreen }] = useFullscreen(document.body);
-  const [playModeEnable, setPlayModeEnable] = useState(false);
+  const [playModeEnable, setPlayModeEnable] = useSessionStorageState('playModeEnable', {
+    defaultValue: false,
+    listenStorageChange: true
+  });
   const [project, setProjectInfo] = useState<ProjectInfo>({
     id: "1",
     name: "项目1",

+ 57 - 32
apps/er-designer/src/pages/detail/components/AddTable.tsx

@@ -4,8 +4,9 @@ import LangInput from "@/components/LangInput";
 import LangInputTextarea from "@/components/LangInputTextarea";
 import { TableType } from "@/enum";
 import { createTable } from "@/utils";
-import { TableItemType, ViewTable } from "@/type";
+import { TableItemType } from "@/type";
 import { useSearchParams } from "umi";
+import { validateTableCode, validateAliasName } from "@/utils/validator";
 
 export default forwardRef(function AddTable(
   props: {
@@ -32,7 +33,7 @@ export default forwardRef(function AddTable(
   }));
 
   const [form] = Form.useForm();
-  const [formModel, setFormModel] = useState<TableItemType['table']>();
+  const [formModel, setFormModel] = useState<TableItemType["table"]>();
 
   const items: TabsProps["items"] = [
     {
@@ -43,7 +44,24 @@ export default forwardRef(function AddTable(
           <Form labelCol={{ span: 8 }} form={form}>
             <Row gutter={16}>
               <Col span={12}>
-                <Form.Item label="表类型">
+                <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={
@@ -55,38 +73,41 @@ export default forwardRef(function AddTable(
                   />
                 </Form.Item>
               </Col>
+            </Row>
+            <Row gutter={16}>
               <Col span={12}>
-                <Form.Item label="编码">
+                <Form.Item
+                  label="别名"
+                  name="aliasName"
+                  rules={[
+                    { required: true, message: "请输入别名" },
+                    validateAliasName,
+                  ]}
+                  tooltip="包含字母、数字, 必须小写字母开头! 如:userinfo"
+                >
                   <Input
                     placeholder="请输入"
-                    value={formModel?.schemaName}
-                    onChange={(e) => handleChange("schemaName", e.target.value)}
+                    value={formModel?.aliasName}
+                    onChange={(e) => handleChange("aliasName", e.target.value)}
                   />
                 </Form.Item>
               </Col>
-            </Row>
-            <Row gutter={16}>
               <Col span={12}>
-                <Form.Item label="表名">
+                <Form.Item label="表名" name="langNameList">
                   <LangInput
                     value={formModel?.langNameList}
                     onChange={(lang) => handleChange("langNameList", lang)}
                   />
                 </Form.Item>
               </Col>
-              <Col span={12}>
-                <Form.Item label="别名">
-                  <Input
-                    placeholder="请输入"
-                    value={formModel?.aliasName}
-                    onChange={(e) => handleChange("aliasName", e.target.value)}
-                  />
-                </Form.Item>
-              </Col>
             </Row>
             <Row gutter={16}>
               <Col span={24}>
-                <Form.Item label="描述" labelCol={{ span: 4 }}>
+                <Form.Item
+                  label="描述"
+                  labelCol={{ span: 4 }}
+                  name="langDescriptionList"
+                >
                   <LangInputTextarea
                     value={formModel?.langDescriptionList}
                     onChange={(lang) =>
@@ -114,21 +135,25 @@ export default forwardRef(function AddTable(
   ];
 
   const handleChange = (key: string, value: any) => {
-    formModel && setFormModel({
-      ...formModel,
-      [key]: value
-    });
+    formModel &&
+      setFormModel({
+        ...formModel,
+        [key]: value,
+      });
   };
   const handleOk = () => {
-    form.validateFields().then((values) => {
-      if(tableItemRef.current && formModel) {
-        props.onChange({
-          ...tableItemRef.current,
-          table: formModel
-        })
-      }
-      setOpen(false);
-    });
+    // 新建
+    if (tabActiveKey === "1") {
+      form.validateFields().then(() => {
+        if (tableItemRef.current && formModel) {
+          props.onChange({
+            ...tableItemRef.current,
+            table: formModel,
+          });
+        }
+        setOpen(false);
+      });
+    }
   };
 
   return (

+ 13 - 5
apps/er-designer/src/pages/detail/index.tsx

@@ -1,4 +1,4 @@
-import React, { useMemo, useRef, useState } from "react";
+import React, { useEffect, useMemo, useRef, useState } from "react";
 import { Layout, Menu, Button, Descriptions, Input, Tooltip, Empty } from "antd";
 import type { DescriptionsProps, MenuProps } from "antd";
 import { PlusOutlined, SearchOutlined } from "@ant-design/icons";
@@ -12,11 +12,15 @@ import { TableItemType } from "@/type";
 const { Content, Header } = Layout;
 export default function index() {
   const [active, setActive] = useState(0);
-  const [showNavigator, setShowNavigator] = useState(false);
+  const [showNavigator, setShowNavigator] = useState(true);
   const addTableRef = useRef<{open: () => void}>();
-  const { project } = useModel("erModel");
+  const { project, setProject, setPlayModeEnable } = useModel("erModel");
   const [searchKeyword, setSearchKeyword] = useState("");
 
+  useEffect(() => {
+    setPlayModeEnable(true);
+  }, [project]);
+
   const descItems: DescriptionsProps["items"] = [
     {
       key: "1",
@@ -65,9 +69,10 @@ export default function index() {
     }[] = [];
 
     tables.forEach((item) => {
+      const name = item.table.langNameList?.find((item) => item.name === "zh-CN")?.value;
       const newItem = {
         key: item.table.id,
-        label: item.table.langNameList?.find((item) => item.label === "zh-CN")?.value,
+        label: item.table.schemaName + `${name ? `(${name})}` : ''}`,
         icon: <i className="iconfont icon-biaogebeifen" />,
         children: []
       };
@@ -84,7 +89,10 @@ export default function index() {
   }, [project]);
 
   const handleAddTable = (tableItem: TableItemType) => {
-    
+    setProject({
+      ...project,
+      tables: [...project.tables, tableItem]
+    })
   }
 
   const extra = (

+ 63 - 0
apps/er-designer/src/utils/validator.ts

@@ -0,0 +1,63 @@
+import type { FormRule } from "antd";
+/**
+ * @description 验证表编码
+ */
+export const validateTableCode: FormRule = {
+  validateTrigger: ["onChange", "onBlur"],
+  validator: (
+    _rule: any,
+    value: string,
+  ): Promise<void> | void => {
+    // 小写字母开头,可以有数字,下划线,字母,且必须包含下划线
+    const regex = /^[a-z][a-z0-9_]*_[a-zA-Z0-9_]*$/;
+    if (value.length >= 50) {
+      return Promise.reject(new Error("编码长度不能超过50"));
+    }
+    if (!regex.test(value)) {
+      return Promise.reject(new Error("编码只能包含字母、下划线、数字, 必须小写字母开头,且必须有下划线!"));
+    }
+    return Promise.resolve();
+  },
+};
+
+/**
+ * @description 验证字段编码
+ */
+export const validateColumnCode: FormRule = {
+  validateTrigger: ["onChange", "onBlur"],
+  validator: (
+    _rule: any,
+    value: string,
+  ): Promise<void> | void => {
+    // 小写字母开头,可以有数字,下划线,字母,且必须包含下划线
+    const regex = /^[a-z][a-z0-9_]*$/;
+    if (value.length >= 50) {
+      return Promise.reject(new Error("编码长度不能超过50"));
+    }
+    if (!regex.test(value)) {
+      return Promise.reject(new Error("编码只能包含字母和数字, 必须小写字母开头!"));
+    }
+    return Promise.resolve();
+  },
+};
+
+/**
+ * @description 校验别名
+ */
+export const validateAliasName: FormRule = {
+  validateTrigger: ["onChange", "onBlur"],
+  validator: (
+    _rule: any,
+    value: string,
+  ): Promise<void> | void => {
+    // 小写字母开头,可以有数字,下划线,字母,且必须包含下划线
+    const regex = /^[a-z][a-zA-Z0-9_]*$/;
+    if (value.length >= 50) {
+      return Promise.reject(new Error("别名长度不能超过50"));
+    }
+    if (!regex.test(value)) {
+      return Promise.reject(new Error("别名只能包含字母和数字, 必须小写字母开头!"));
+    }
+    return Promise.resolve();
+  },
+};