Procházet zdrojové kódy

feat: 完善字段变量选择

liaojiaxing před 3 měsíci
rodič
revize
5785a61757

+ 90 - 0
apps/er-designer/src/components/ColumnVariableModal.tsx

@@ -0,0 +1,90 @@
+import React, { useMemo, useRef, useState } from "react";
+import { Collapse, Modal, Table } from "antd";
+import { useRequest, useModel } from "umi";
+import { ColumnItem } from "@/type";
+export default function VariableModal(props: {
+  /**
+   * 触发节点
+   */
+  trigger: JSX.Element;
+  /**
+   * 确认
+   */
+  onOk: (code: string) => void;
+}) {
+  const [open, setOpen] = React.useState(false);
+  const [selectedRowKeys, setSelectedRowKeys] = React.useState<React.Key[]>([]);
+  const { project } = useModel("erModel");
+  const [variable, setVariable] = useState('');
+
+  const triggerDom = React.cloneElement(props.trigger, {
+    ...props.trigger.props,
+    onClick: () => {
+      setSelectedRowKeys([]);
+      setVariable('');
+      setOpen(true);
+    },
+  });
+  const handleSelected = (tableAliasName: string, keys: React.Key[], rows: any[]) => {
+    console.log(rows, rows?.[0]?.schemaName)
+    setSelectedRowKeys(keys);
+    setVariable(rows?.[0]?.schemaName ? `<%${tableAliasName}.${rows?.[0]?.schemaName}%>` : '');
+  };
+
+  const handleOk = () => {
+    props.onOk(variable);
+    setOpen(false);
+  };
+
+  return (
+    <>
+      <Modal
+        width={880}
+        open={open}
+        title="请选择"
+        onCancel={() => setOpen(false)}
+        onOk={handleOk}
+        okButtonProps={{
+          disabled: !variable
+        }}
+      >
+        <div>当前选择:<span>{variable}</span></div>
+        <Collapse
+          items={project.tables.map((item) => {
+            const { table, tableColumnList } = item;
+            const name = table.langNameList?.find(
+              (item) => item.name === "zh-CN"
+            )?.value;
+            return {
+              key: table.id,
+              label: `${table.aliasName}${name ? `(${name})` : ""}`,
+              children: (
+                <Table
+                  rowKey={"id"}
+                  pagination={false}
+                  dataSource={tableColumnList}
+                  rowSelection={{
+                    type: "radio",
+                    selectedRowKeys,
+                    onChange: (keys, selectedRows) => {
+                      handleSelected(table.aliasName, keys, selectedRows);
+                    },
+                  }}
+                  columns={[
+                    { title: "字段代码", dataIndex: "name" },
+                    { title: "字段名称", dataIndex: "type" },
+                    { title: "字段类型", dataIndex: "type" },
+                    { title: "字段长度", dataIndex: "type" },
+                    { title: "是否必填", dataIndex: "type" },
+                    { title: "需求描述", dataIndex: "type" },
+                  ]}
+                />
+              ),
+            };
+          })}
+        ></Collapse>
+      </Modal>
+      {triggerDom}
+    </>
+  );
+}

+ 22 - 6
apps/er-designer/src/components/TableEdit.tsx

@@ -17,6 +17,7 @@ import {
 import LangInput from "./LangInput";
 import { validateColumnCode } from "@/utils/validator";
 import VariableModal from "./VariableModal";
+import ColumnVariableModal from "./ColumnVariableModal";
 import { FormInstance } from "antd/lib";
 import {
   DownloadOutlined,
@@ -36,7 +37,9 @@ export default function TableEdit(props: {
     props.data
   );
   const boxRef = React.useRef<HTMLDivElement>(null);
-  const importResultRef = React.useRef<{open: (data: any[], columns: readonly ColumnItem[]) => void}>();
+  const importResultRef = React.useRef<{
+    open: (data: any[], columns: readonly ColumnItem[]) => void;
+  }>();
 
   useEffect(() => {
     props.onChange?.(dataSource);
@@ -70,9 +73,18 @@ export default function TableEdit(props: {
             }
             onOk={(val) => onChange?.(val)}
           />
-          <Button size="small" style={{ width: 40, fontSize: 12 }} type="text">
-            +字段
-          </Button>
+          <ColumnVariableModal
+            trigger={
+              <Button
+                size="small"
+                style={{ width: 40, fontSize: 12 }}
+                type="text"
+              >
+                +字段
+              </Button>
+            }
+            onOk={(val) => onChange?.(val)}
+          />
         </div>
       </div>
     );
@@ -334,11 +346,15 @@ export default function TableEdit(props: {
 
   const handleChangeColumn = (list: ColumnItem[]) => {
     setDataSource(list);
-  }
+  };
 
   return (
     <div className="w-full h-full overflow-auto" ref={boxRef}>
-      <ImportResultModal ref={importResultRef} tableId={props?.tableId} onChange={handleChangeColumn} />
+      <ImportResultModal
+        ref={importResultRef}
+        tableId={props?.tableId}
+        onChange={handleChangeColumn}
+      />
       <EditableProTable
         columns={columns}
         rowKey="id"

+ 68 - 34
apps/er-designer/src/pages/er/components/ColumnItem.tsx

@@ -17,6 +17,8 @@ import { useSortable } from "@dnd-kit/sortable";
 import { CSS } from "@dnd-kit/utilities";
 import LangInput from "@/components/LangInput";
 import { DataType } from "@/enum";
+import VariableModal from "@/components/VariableModal";
+import ColumnVariableModal from "@/components/ColumnVariableModal";
 
 export default function ColumnItem({
   column,
@@ -181,13 +183,45 @@ export default function ColumnItem({
                 </Col>
                 <Col span={12}>
                   <Form.Item label="默认值">
-                    <Input
-                      className="w-full"
-                      placeholder="默认值"
-                      disabled={column.isPreDefined}
-                      value={column.defaultValue}
-                      onChange={(e) => onChange("defaultValue", e.target.value)}
-                    />
+                    <div>
+                      <Input
+                        className="w-full"
+                        placeholder="默认值"
+                        disabled={column.isPreDefined}
+                        value={column.defaultValue}
+                        onChange={(e) =>
+                          onChange("defaultValue", e.target.value)
+                        }
+                      />
+                    </div>
+                    {!column.isPreDefined && (
+                      <div>
+                        <VariableModal
+                          trigger={
+                            <Button
+                              size="small"
+                              style={{ width: 40, fontSize: 12 }}
+                              type="text"
+                            >
+                              +变量
+                            </Button>
+                          }
+                          onOk={(val) => onChange("defaultValue", val)}
+                        />
+                        <ColumnVariableModal
+                          trigger={
+                            <Button
+                              size="small"
+                              style={{ width: 40, fontSize: 12 }}
+                              type="text"
+                            >
+                              +字段
+                            </Button>
+                          }
+                          onOk={(val) => onChange("defaultValue", val)}
+                        />
+                      </div>
+                    )}
                   </Form.Item>
                 </Col>
               </Row>
@@ -209,33 +243,33 @@ export default function ColumnItem({
               )}
               {column.type === DataType.Decimal && (
                 <Row gutter={8}>
-                <Col span={12}>
-                  <Form.Item label="总长度">
-                    <InputNumber
-                      placeholder="请输入"
-                      min={0}
-                      step={1}
-                      className="w-full"
-                      disabled={column.isPreDefined}
-                      value={column.precision}
-                      onChange={(num) => onChange("precision", num)}
-                    />
-                  </Form.Item>
-                </Col>
-                <Col span={12}>
-                  <Form.Item label="小数位数">
-                    <InputNumber
-                      placeholder="请输入"
-                      min={0}
-                      step={1}
-                      className="w-full"
-                      disabled={column.isPreDefined}
-                      value={column.scale}
-                      onChange={(num) => onChange("scale", num)}
-                    />
-                  </Form.Item>
-                </Col>
-              </Row>
+                  <Col span={12}>
+                    <Form.Item label="总长度">
+                      <InputNumber
+                        placeholder="请输入"
+                        min={0}
+                        step={1}
+                        className="w-full"
+                        disabled={column.isPreDefined}
+                        value={column.precision}
+                        onChange={(num) => onChange("precision", num)}
+                      />
+                    </Form.Item>
+                  </Col>
+                  <Col span={12}>
+                    <Form.Item label="小数位数">
+                      <InputNumber
+                        placeholder="请输入"
+                        min={0}
+                        step={1}
+                        className="w-full"
+                        disabled={column.isPreDefined}
+                        value={column.scale}
+                        onChange={(num) => onChange("scale", num)}
+                      />
+                    </Form.Item>
+                  </Col>
+                </Row>
               )}
               <Row>
                 <Col span={24}>

+ 1 - 0
package.json

@@ -59,6 +59,7 @@
     "antd": "^5.23.0",
     "axios": "^1.7.7",
     "dayjs": "^1.11.13",
+    "html2canvas": "^1.4.1",
     "insert-css": "^2.0.0",
     "lodash-es": "^4.17.21",
     "react-draggable": "^4.4.6",

+ 34 - 0
pnpm-lock.yaml

@@ -131,6 +131,9 @@ importers:
       dayjs:
         specifier: ^1.11.13
         version: 1.11.13
+      html2canvas:
+        specifier: ^1.4.1
+        version: 1.4.1
       insert-css:
         specifier: ^2.0.0
         version: 2.0.0
@@ -6182,6 +6185,11 @@ packages:
     resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
     dev: false
 
+  /base64-arraybuffer@1.0.2:
+    resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
+    engines: {node: '>= 0.6.0'}
+    dev: false
+
   /base64-js@1.5.1:
     resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
 
@@ -6941,6 +6949,12 @@ packages:
       postcss-selector-parser: 6.1.2
     dev: false
 
+  /css-line-break@2.1.0:
+    resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
+    dependencies:
+      utrie: 1.0.2
+    dev: false
+
   /css-loader@6.7.1(webpack@5.94.0):
     resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==}
     engines: {node: '>= 12.13.0'}
@@ -9278,6 +9292,14 @@ packages:
       webpack: 5.94.0(esbuild@0.23.1)
     dev: false
 
+  /html2canvas@1.4.1:
+    resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      css-line-break: 2.1.0
+      text-segmentation: 1.0.3
+    dev: false
+
   /htmlparser2@6.1.0:
     resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
     dependencies:
@@ -13986,6 +14008,12 @@ packages:
       minimatch: 3.1.2
     dev: false
 
+  /text-segmentation@1.0.3:
+    resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
+    dependencies:
+      utrie: 1.0.2
+    dev: false
+
   /text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
 
@@ -14603,6 +14631,12 @@ packages:
     engines: {node: '>= 0.4.0'}
     dev: false
 
+  /utrie@1.0.2:
+    resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
+    dependencies:
+      base64-arraybuffer: 1.0.2
+    dev: false
+
   /v8-compile-cache-lib@3.0.1:
     resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
     dev: true