Преглед на файлове

数据字典/编号规则

shaogen1995 преди 4 месеца
родител
ревизия
27fdb7f0c5

+ 4 - 4
README.md

@@ -1,12 +1,12 @@
-1.用 yarn
+1.npm 有问题的话试试用 yarn
 
 2.测试堡垒机存放目录
-227/data/data/guangdong_guangzhou_zhongda_zhongliuyiyuan_data
+227/data/data/museum_yiwu_cms_data
 
 3.蓝湖地址
-https://lanhuapp.com/web/#/item/project/detailDetach?pid=80948489-b74b-4a80-ad55-af0100d0f72f&tid=de3e5e3e-a489-4b19-862a-7c87ce113467&see=all&project_id=80948489-b74b-4a80-ad55-af0100d0f72f&image_id=81dcc2d5-c5f0-4111-8771-e8b110de9524&fromEditor=true&type=image
+https://lanhuapp.com/web/#/item/project/product?tid=de3e5e3e-a489-4b19-862a-7c87ce113467&pid=a2168b1b-1ece-477c-a597-db484cea40c4&image_id=13b4ac78-2989-488d-b27e-382ef8edb596&docId=13b4ac78-2989-488d-b27e-382ef8edb596&docType=axure&versionId=57474e72-6d0c-4e34-96a0-ba3b390ee4c7&pageId=17aeaf597f6d461e8d02a23cb341f035&parentId=6c25bfdb-a8f7-4462-981a-e8dd72b9a86f
 
 4.测试域名
-https://sit-zhongliuyiyuan.4dage.com
+https://sit-yiwubwg.4dage.com
 接口地址在后面拼接:/api/doc.html#/home
 测试网址在后面拼接:/backstage

+ 210 - 210
src/pages/Layout/data.ts

@@ -2,198 +2,198 @@ import { RouterType, RouterTypeRow } from '@/types'
 import React from 'react'
 
 const tabLeftArr: RouterType = [
-  {
-    id: 1,
-    name: '工作台',
-    son: [
-      {
-        id: 100,
-        name: '数据统计',
-        path: '/',
-        Com: React.lazy(() => import('../A_workbench/A1dataSta'))
-      },
-      {
-        id: 101,
-        name: '业务中心',
-        path: '/business',
-        Com: React.lazy(() => import('../A_workbench/A2business'))
-      },
-      {
-        id: 102,
-        name: '流程管理',
-        path: '/flow',
-        Com: React.lazy(() => import('../A_workbench/A3flow'))
-      }
-    ]
-  },
-  {
-    id: 2,
-    name: '入藏管理',
-    son: [
-      {
-        id: 103,
-        name: '藏品征集',
-        path: '/collect',
-        Com: React.lazy(() => import('../B_enterTibet/B1collect'))
-      },
-      {
-        id: 104,
-        name: '藏品鉴定',
-        path: '/identify',
-        Com: React.lazy(() => import('../B_enterTibet/B2identify'))
-      },
-      {
-        id: 105,
-        name: '藏品入馆',
-        path: '/entering',
-        Com: React.lazy(() => import('../B_enterTibet/B3entering'))
-      },
-      {
-        id: 106,
-        name: '藏品入藏',
-        path: '/enterTibet',
-        Com: React.lazy(() => import('../B_enterTibet/B4enterTibet'))
-      }
-    ]
-  },
-  {
-    id: 3,
-    name: '藏品管理',
-    son: [
-      {
-        id: 107,
-        name: '藏品总账',
-        path: '/ledger',
-        Com: React.lazy(() => import('../C_goodsManage/C1ledger'))
-      },
-      {
-        id: 108,
-        name: '藏品附件',
-        path: '/files',
-        Com: React.lazy(() => import('../C_goodsManage/C2files'))
-      },
-      {
-        id: 109,
-        name: '藏品关注',
-        path: '/focus',
-        Com: React.lazy(() => import('../C_goodsManage/C3focus'))
-      },
-      {
-        id: 110,
-        name: '藏品导入',
-        path: '/import',
-        Com: React.lazy(() => import('../C_goodsManage/C4import'))
-      },
-      {
-        id: 111,
-        name: '藏品登记',
-        path: '/register',
-        Com: React.lazy(() => import('../C_goodsManage/C5register'))
-      },
-      {
-        id: 112,
-        name: '藏品编辑',
-        path: '/edit',
-        Com: React.lazy(() => import('../C_goodsManage/C6edit'))
-      },
-      {
-        id: 113,
-        name: '藏品删除',
-        path: '/delete',
-        Com: React.lazy(() => import('../C_goodsManage/C7delete'))
-      },
-      {
-        id: 114,
-        name: '回收站',
-        path: '/recycleBin',
-        Com: React.lazy(() => import('../C_goodsManage/C8recycleBin'))
-      }
-    ]
-  },
+  // {
+  //   id: 1,
+  //   name: '工作台',
+  //   son: [
+  //     {
+  //       id: 100,
+  //       name: '数据统计',
+  //       path: '/',
+  //       Com: React.lazy(() => import('../A_workbench/A1dataSta'))
+  //     },
+  //     {
+  //       id: 101,
+  //       name: '业务中心',
+  //       path: '/business',
+  //       Com: React.lazy(() => import('../A_workbench/A2business'))
+  //     },
+  //     {
+  //       id: 102,
+  //       name: '流程管理',
+  //       path: '/flow',
+  //       Com: React.lazy(() => import('../A_workbench/A3flow'))
+  //     }
+  //   ]
+  // },
+  // {
+  //   id: 2,
+  //   name: '入藏管理',
+  //   son: [
+  //     {
+  //       id: 103,
+  //       name: '藏品征集',
+  //       path: '/collect',
+  //       Com: React.lazy(() => import('../B_enterTibet/B1collect'))
+  //     },
+  //     {
+  //       id: 104,
+  //       name: '藏品鉴定',
+  //       path: '/identify',
+  //       Com: React.lazy(() => import('../B_enterTibet/B2identify'))
+  //     },
+  //     {
+  //       id: 105,
+  //       name: '藏品入馆',
+  //       path: '/entering',
+  //       Com: React.lazy(() => import('../B_enterTibet/B3entering'))
+  //     },
+  //     {
+  //       id: 106,
+  //       name: '藏品入藏',
+  //       path: '/enterTibet',
+  //       Com: React.lazy(() => import('../B_enterTibet/B4enterTibet'))
+  //     }
+  //   ]
+  // },
+  // {
+  //   id: 3,
+  //   name: '藏品管理',
+  //   son: [
+  //     {
+  //       id: 107,
+  //       name: '藏品总账',
+  //       path: '/ledger',
+  //       Com: React.lazy(() => import('../C_goodsManage/C1ledger'))
+  //     },
+  //     {
+  //       id: 108,
+  //       name: '藏品附件',
+  //       path: '/files',
+  //       Com: React.lazy(() => import('../C_goodsManage/C2files'))
+  //     },
+  //     {
+  //       id: 109,
+  //       name: '藏品关注',
+  //       path: '/focus',
+  //       Com: React.lazy(() => import('../C_goodsManage/C3focus'))
+  //     },
+  //     {
+  //       id: 110,
+  //       name: '藏品导入',
+  //       path: '/import',
+  //       Com: React.lazy(() => import('../C_goodsManage/C4import'))
+  //     },
+  //     {
+  //       id: 111,
+  //       name: '藏品登记',
+  //       path: '/register',
+  //       Com: React.lazy(() => import('../C_goodsManage/C5register'))
+  //     },
+  //     {
+  //       id: 112,
+  //       name: '藏品编辑',
+  //       path: '/edit',
+  //       Com: React.lazy(() => import('../C_goodsManage/C6edit'))
+  //     },
+  //     {
+  //       id: 113,
+  //       name: '藏品删除',
+  //       path: '/delete',
+  //       Com: React.lazy(() => import('../C_goodsManage/C7delete'))
+  //     },
+  //     {
+  //       id: 114,
+  //       name: '回收站',
+  //       path: '/recycleBin',
+  //       Com: React.lazy(() => import('../C_goodsManage/C8recycleBin'))
+  //     }
+  //   ]
+  // },
   {
     id: 4,
     name: '库存管理',
     son: [
-      {
-        id: 100,
-        name: '库房管理',
-        path: '/storage',
-        Com: React.lazy(() => import('../D_storeManage/D1storage'))
-      },
+      // {
+      //   id: 100,
+      //   name: '库房管理',
+      //   path: '/storage',
+      //   Com: React.lazy(() => import('../D_storeManage/D1storage'))
+      // },
       {
         id: 101,
         name: '库房设置',
         path: '/storSet',
         Com: React.lazy(() => import('../D_storeManage/D2storSet'))
-      },
-      {
-        id: 103,
-        name: '人员出入库',
-        path: '/staff',
-        Com: React.lazy(() => import('../D_storeManage/D3staff'))
-      },
-      {
-        id: 104,
-        name: '入库',
-        path: '/impStor',
-        Com: React.lazy(() => import('../D_storeManage/D4impStor'))
-      },
-      {
-        id: 105,
-        name: '移库',
-        path: '/moveStor',
-        Com: React.lazy(() => import('../D_storeManage/D5moveStor'))
-      },
-      {
-        id: 106,
-        name: '出库',
-        path: '/putsStor',
-        Com: React.lazy(() => import('../D_storeManage/D6putsStor'))
-      },
-      {
-        id: 107,
-        name: '盘点',
-        path: '/check',
-        Com: React.lazy(() => import('../D_storeManage/D7check'))
-      },
-      {
-        id: 108,
-        name: '注销',
-        path: '/cancel',
-        Com: React.lazy(() => import('../D_storeManage/D8cancel'))
-      }
-    ]
-  },
-  {
-    id: 5,
-    name: '藏品保管',
-    son: [
-      {
-        id: 100,
-        name: '事故登记',
-        path: '/accident',
-        Com: React.lazy(() => import('../E_goodsStorage/E1accident'))
-      },
-      {
-        id: 101,
-        name: '残损登记',
-        path: '/damaged',
-        Com: React.lazy(() => import('../E_goodsStorage/E2damaged'))
-      },
-      {
-        id: 102,
-        name: '现状登记',
-        path: '/actuality',
-        Com: React.lazy(() => import('../E_goodsStorage/E3actuality'))
-      },
-      {
-        id: 103,
-        name: '修复登记',
-        path: '/repair',
-        Com: React.lazy(() => import('../E_goodsStorage/E4repair'))
       }
+      // {
+      //   id: 103,
+      //   name: '人员出入库',
+      //   path: '/staff',
+      //   Com: React.lazy(() => import('../D_storeManage/D3staff'))
+      // },
+      // {
+      //   id: 104,
+      //   name: '入库',
+      //   path: '/impStor',
+      //   Com: React.lazy(() => import('../D_storeManage/D4impStor'))
+      // },
+      // {
+      //   id: 105,
+      //   name: '移库',
+      //   path: '/moveStor',
+      //   Com: React.lazy(() => import('../D_storeManage/D5moveStor'))
+      // },
+      // {
+      //   id: 106,
+      //   name: '出库',
+      //   path: '/putsStor',
+      //   Com: React.lazy(() => import('../D_storeManage/D6putsStor'))
+      // },
+      // {
+      //   id: 107,
+      //   name: '盘点',
+      //   path: '/check',
+      //   Com: React.lazy(() => import('../D_storeManage/D7check'))
+      // },
+      // {
+      //   id: 108,
+      //   name: '注销',
+      //   path: '/cancel',
+      //   Com: React.lazy(() => import('../D_storeManage/D8cancel'))
+      // }
     ]
   },
+  // {
+  //   id: 5,
+  //   name: '藏品保管',
+  //   son: [
+  //     {
+  //       id: 100,
+  //       name: '事故登记',
+  //       path: '/accident',
+  //       Com: React.lazy(() => import('../E_goodsStorage/E1accident'))
+  //     },
+  //     {
+  //       id: 101,
+  //       name: '残损登记',
+  //       path: '/damaged',
+  //       Com: React.lazy(() => import('../E_goodsStorage/E2damaged'))
+  //     },
+  //     {
+  //       id: 102,
+  //       name: '现状登记',
+  //       path: '/actuality',
+  //       Com: React.lazy(() => import('../E_goodsStorage/E3actuality'))
+  //     },
+  //     {
+  //       id: 103,
+  //       name: '修复登记',
+  //       path: '/repair',
+  //       Com: React.lazy(() => import('../E_goodsStorage/E4repair'))
+  //     }
+  //   ]
+  // },
   // 待完善-展览管理
   {
     id: 7,
@@ -210,37 +210,37 @@ const tabLeftArr: RouterType = [
         name: '编号规则',
         path: '/numRule',
         Com: React.lazy(() => import('../Z_system/Z2numRule'))
-      },
-      {
-        id: 102,
-        name: '流程设置',
-        path: '/flowSet',
-        Com: React.lazy(() => import('../Z_system/Z3flowSet'))
-      },
-      {
-        id: 103,
-        name: '组织管理',
-        path: '/organization',
-        Com: React.lazy(() => import('../Z_system/Z4organization'))
-      },
-      {
-        id: 9900,
-        name: '角色管理',
-        path: '/role',
-        Com: React.lazy(() => import('../Z_system/Z5role'))
-      },
-      {
-        id: 106,
-        name: '用户管理',
-        path: '/user',
-        Com: React.lazy(() => import('../Z_system/Z6user'))
-      },
-      {
-        id: 9901,
-        name: '系统日志',
-        path: '/log',
-        Com: React.lazy(() => import('../Z_system/Z7log'))
       }
+      // {
+      //   id: 102,
+      //   name: '流程设置',
+      //   path: '/flowSet',
+      //   Com: React.lazy(() => import('../Z_system/Z3flowSet'))
+      // },
+      // {
+      //   id: 103,
+      //   name: '组织管理',
+      //   path: '/organization',
+      //   Com: React.lazy(() => import('../Z_system/Z4organization'))
+      // },
+      // {
+      //   id: 9900,
+      //   name: '角色管理',
+      //   path: '/role',
+      //   Com: React.lazy(() => import('../Z_system/Z5role'))
+      // },
+      // {
+      //   id: 106,
+      //   name: '用户管理',
+      //   path: '/user',
+      //   Com: React.lazy(() => import('../Z_system/Z6user'))
+      // },
+      // {
+      //   id: 9901,
+      //   name: '系统日志',
+      //   path: '/log',
+      //   Com: React.lazy(() => import('../Z_system/Z7log'))
+      // }
     ]
   }
 ]

+ 213 - 0
src/pages/Z_system/Z1dict/Z1add.tsx

@@ -0,0 +1,213 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Cascader, Form, FormInstance, Input, InputNumber, Modal } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { MessageFu } from '@/utils/message'
+import { TypeZ1dict } from './type'
+import { Z1_APIgetInfo, Z1_APIsave } from '@/store/action/Z1dict'
+
+export type Z1AddInfoType = {
+  id: string
+  txt: '新增' | '编辑'
+  acInfo: TypeZ1dict
+}
+
+type Props = {
+  addInfo: Z1AddInfoType
+  addFu: () => void
+  closeFu: () => void
+}
+
+function Z1add({ addInfo, addFu, closeFu }: Props) {
+  const { dictList: treeData } = useSelector((state: RootState) => state.Z1dict)
+
+  // 级联选择器改变的时候 筛选当前级联的 信息出来
+  const [acCardInfo, setAcCardInfo] = useState({} as TypeZ1dict)
+  const [parentIdArr, setParentIdArr] = useState<string[] | null>(null)
+
+  // useEffect(() => {
+  //   console.log(acCardInfo, parentIdArr)
+  // }, [acCardInfo, parentIdArr])
+
+  const saveIdsRef = useRef<string[]>([])
+
+  useEffect(() => {
+    setAcCardInfo(addInfo.acInfo)
+
+    let ids: string[] | null = addInfo.acInfo.id ? [addInfo.acInfo.id] : null
+    if (addInfo.acInfo.ancestor) ids = [...addInfo.acInfo.ancestor.split(','), addInfo.acInfo.id]
+
+    let idsRes = ids
+    if (ids && ids.length >= 1 && addInfo.txt === '编辑') {
+      ids.pop()
+    }
+
+    if (idsRes) {
+      // 保存的时候需要补前面3个级别
+      saveIdsRef.current = idsRes.filter((v, i) => i <= 2)
+      // 去掉0和前2级
+      idsRes = idsRes.filter((v, i) => i > 2)
+    }
+
+    // console.log(123, idsRes)
+
+    setParentIdArr(idsRes)
+  }, [addInfo.acInfo, addInfo.txt])
+
+  const cardChange = useCallback((aa: any, bb: any) => {
+    setParentIdArr(aa)
+
+    if (bb && bb.length) setAcCardInfo(bb[bb.length - 1])
+    else setAcCardInfo({} as TypeZ1dict)
+  }, [])
+
+  const getInfoFu = useCallback(async (id: string) => {
+    const res = await Z1_APIgetInfo(id)
+    if (res.code === 0) {
+      FormBoxRef.current?.setFieldsValue({
+        ...res.data
+      })
+    }
+  }, [])
+  useEffect(() => {
+    if (addInfo.txt === '编辑') getInfoFu(addInfo.id)
+    else {
+      FormBoxRef.current?.setFieldsValue({
+        sort: 999
+      })
+    }
+  }, [addInfo.id, addInfo.txt, getInfoFu])
+
+  // 设置表单初始数据(区分编辑和新增)
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    // return MessageFu.warning("有表单不符号规则!");
+  }, [])
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      let ancestor = ''
+      let parentId: string | null = null
+
+      if (parentIdArr && parentIdArr.length >= 5 && addInfo.txt === '新增')
+        return MessageFu.warning('最多支持五级!')
+
+      if (acCardInfo) parentId = addInfo.txt === '编辑' ? acCardInfo.parentId : acCardInfo.id
+      if (parentIdArr && parentId) {
+        let arrTemp = [...saveIdsRef.current, ...parentIdArr.filter(v => v !== addInfo.id)]
+        ancestor = arrTemp.join(',')
+      }
+
+      // 新增并且没有父级
+      if (addInfo.txt === '新增' && !parentId && !ancestor) {
+        parentId = saveIdsRef.current[saveIdsRef.current.length - 1]
+        ancestor = saveIdsRef.current.join(',')
+        // console.log(123, parentId, ancestor)
+      }
+
+      // let level = 1
+      // if (parentIdArr) {
+      //   level = addInfo.txt === '新增' ? acCardInfo.level + 1 : acCardInfo.level
+      // }
+      const obj = {
+        ...values,
+        id: addInfo.txt === '编辑' ? addInfo.id : null,
+        ancestor,
+        // level,
+        parentId
+      }
+      // console.log(123, obj)
+      // if (1 + 1 === 2) {
+      //   return
+      // }
+
+      const res = await Z1_APIsave(obj)
+
+      if (res.code === 0) {
+        MessageFu.success(addInfo.txt + '成功!')
+        addFu()
+        closeFu()
+      }
+    },
+    [acCardInfo, addFu, addInfo.id, addInfo.txt, closeFu, parentIdArr]
+  )
+  return (
+    <Modal
+      wrapClassName={styles.Z1add}
+      open={true}
+      title={addInfo.txt}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='Z1aMain'>
+        <Form
+          scrollToFirstError={true}
+          ref={FormBoxRef}
+          name='basic'
+          labelCol={{ span: 3 }}
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete='off'
+        >
+          <div className='fromRow'>
+            <div className='fromRowll'>上级字典:</div>
+            <div className='fromRowrr'>
+              <Cascader
+                style={{ width: 658 }}
+                disabled={addInfo.txt === '编辑'}
+                changeOnSelect
+                fieldNames={{ label: 'name', value: 'id', children: 'children' }}
+                options={treeData}
+                placeholder={addInfo.txt === '编辑' ? '空' : '请选择'}
+                value={parentIdArr ? [...parentIdArr] : []}
+                onChange={cardChange}
+              />
+            </div>
+          </div>
+
+          <Form.Item
+            label='字典值'
+            name='name'
+            rules={[{ required: true, message: '请输入字典值!' }]}
+            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
+          >
+            <Input maxLength={30} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          <div className='fromRow2'>
+            <Form.Item
+              label='排序值'
+              name='sort'
+              rules={[{ required: true, message: '请输入排序值!' }]}
+            >
+              <InputNumber min={1} max={999} precision={0} placeholder='请输入' />
+            </Form.Item>
+            <div className='fromRowTit'>
+              请输入1~999的数字。数字越小,排序越靠前。数字相同时,更新发布的内容排在前面
+            </div>
+          </div>
+
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+            <Button type='primary' htmlType='submit'>
+              提交
+            </Button>
+            &emsp;
+            <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoZ1add = React.memo(Z1add)
+
+export default MemoZ1add

+ 32 - 0
src/pages/Z_system/Z1dict/data.ts

@@ -0,0 +1,32 @@
+import { TypeZ1dict } from './type'
+
+// 把所有的字典,只保留前面2级,给下拉框筛选
+export const Z1toTowFu = (data: TypeZ1dict[]) => {
+  return data.map(item => ({
+    ...item,
+    children: item.children?.map(child => ({
+      ...child,
+      children: undefined // 移除第三层子级
+    }))
+  }))
+}
+
+// 通过id获取 树的obj
+export const treeResIdFu = (list: any, id: string) => {
+  // 每次进来使用find遍历一次
+  let res = list.find((item: any) => item.id === id)
+
+  if (res) {
+    return res
+  } else {
+    for (let i = 0; i < list.length; i++) {
+      if (list[i].children instanceof Array && list[i].children.length > 0) {
+        res = treeResIdFu(list[i].children, id)
+
+        if (res) return res
+      }
+    }
+
+    return null
+  }
+}

+ 104 - 0
src/pages/Z_system/Z1dict/index.module.scss

@@ -1,4 +1,108 @@
 .Z1dict {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 24px;
   :global {
+    .Z1top {
+      display: flex;
+      justify-content: space-between;
+      .Z1topll {
+        display: flex;
+        align-items: center;
+      }
+    }
+    .Z1main {
+      margin-top: 20px;
+      height: calc(100% - 30px);
+      display: flex;
+      justify-content: space-between;
+      .Z1m1ll {
+        width: 70%;
+        overflow-y: auto;
+        .site-tree-search-value {
+          color: red;
+          font-weight: 700;
+        }
+        .ant-tree {
+          min-height: 100%;
+          padding: 10px;
+        }
+      }
+      .Z1m1rr {
+        width: calc(30% - 24px);
+        padding: 20px;
+        .Z1mr1 {
+          font-weight: 700;
+          color: var(--themeColor);
+          font-size: 24px;
+        }
+        .Z1mr2 {
+          margin: 20px 0 40px;
+          .ant-btn {
+            font-size: 24px;
+            height: 46px;
+          }
+        }
+
+        .Z1mr3 {
+          display: flex;
+          font-size: 20px;
+          margin-bottom: 30px;
+          .Z1mr3ll {
+            width: 100px;
+            text-align: right;
+            font-weight: 700;
+          }
+          .Z1mr3rr {
+            width: calc(100% - 100px);
+          }
+        }
+      }
+    }
+  }
+}
+
+// 新增弹窗页面
+.Z1add {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+    }
+
+    .Z1aMain {
+      padding-top: 15px;
+      .fromRow2 {
+        position: relative;
+
+        .fromRowTit {
+          position: absolute;
+          left: 200px;
+          top: 5px;
+          color: #999;
+          font-size: 12px;
+        }
+      }
+      .fromRow {
+        display: flex;
+        align-items: center;
+        margin-bottom: 24px;
+        .fromRowll {
+          width: 94px;
+          text-align: right;
+          position: relative;
+        }
+        .fromRowrr {
+          width: calc(100% - 94px);
+        }
+      }
+    }
   }
 }

+ 230 - 2
src/pages/Z_system/Z1dict/index.tsx

@@ -1,10 +1,238 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useState } from 'react'
 import styles from './index.module.scss'
+import { useDispatch, useSelector } from 'react-redux'
+import { Z1_APIdel, Z1_APIgetDict } from '@/store/action/Z1dict'
+import { RootState } from '@/store'
+import { Button, Cascader, Input, Tree, TreeDataNode } from 'antd'
+import { treeResIdFu, Z1toTowFu } from './data'
+import { TypeZ1dict } from './type'
+import Z1add, { Z1AddInfoType } from './Z1add'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { MessageFu } from '@/utils/message'
+
 function Z1dict() {
+  const dispatch = useDispatch()
+
+  useEffect(() => {
+    dispatch(Z1_APIgetDict())
+  }, [dispatch])
+
+  // 级联改变
+  const [topId, setTopId] = useState(['10000', '12000'])
+
+  useEffect(() => {
+    if (topId && topId.length)
+      dispatch(
+        Z1_APIgetDict(topId[1], data => {
+          if (data && data.length) setAcShu(data[0].id)
+        })
+      )
+  }, [dispatch, topId])
+
+  const onChange = useCallback((value: any) => {
+    // console.log('级联改变', value)
+    setTopId(value)
+  }, [])
+
+  const { dictAll, dictList: treeDataTemp } = useSelector((state: RootState) => state.Z1dict)
+
+  // 点击重置
+  const resetFu = useCallback(
+    (flag: boolean) => {
+      // 重置 flag为true
+      // 新增和编辑 为false
+      if (flag) {
+        setTopId(['10000', '12000'])
+      } else dispatch(Z1_APIgetDict(topId[1]))
+
+      setValue('')
+    },
+    [dispatch, topId]
+  )
+
+  // 当前选中的树节点ID
+  const [acShu, setAcShu] = useState('0')
+
+  // 点击树节点
+  const onSelect = (id: any) => {
+    // console.log('点击树节点', id)
+
+    if (id[0]) setAcShu(id[0])
+  }
+
+  const [value, setValue] = useState('')
+
+  const valueChange = useCallback((val: string) => {
+    setValue(val)
+  }, [])
+
+  // 搜索高亮
+  const treeData = useMemo(() => {
+    const loop = (dataTemp: any[]): TreeDataNode[] => {
+      const data = dataTemp || []
+
+      return data.map(item => {
+        const strTitle = ((item.num ? item.num + ' ' : '') + item.name) as string
+
+        const index = strTitle.indexOf(value)
+
+        const beforeStr = strTitle.substring(0, index)
+        const afterStr = strTitle.slice(index + value.length)
+        const title =
+          index > -1 ? (
+            <span key={item.id}>
+              {beforeStr}
+              <span className='site-tree-search-value'>{value}</span>
+              {afterStr}
+            </span>
+          ) : (
+            <span key={item.id}>{strTitle}</span>
+          )
+        if (item.children) {
+          return { title, key: item.id, children: loop(item.children) }
+        }
+        return {
+          title,
+          key: item.id
+        }
+      })
+    }
+
+    return loop(treeDataTemp)
+  }, [treeDataTemp, value])
+
+  // 右侧信息
+  const rightData = useMemo(() => {
+    let obj = {} as TypeZ1dict
+    if (treeDataTemp && treeDataTemp.length) obj = treeResIdFu(treeDataTemp, acShu)
+
+    return obj || {}
+  }, [acShu, treeDataTemp])
+
+  // 点击新增和编辑
+  const [addInfo, setAddInfo] = useState({} as Z1AddInfoType)
+
+  const addSonFu = useCallback(
+    (id: string) => {
+      setAddInfo({
+        id,
+        txt: id === '-1' ? '新增' : '编辑',
+        acInfo: rightData
+      })
+    },
+    [rightData]
+  )
+
+  // 点击删除
+  const delTree = useCallback(
+    async (id: string) => {
+      const res = await Z1_APIdel(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功!')
+        resetFu(false)
+      }
+    },
+    [resetFu]
+  )
+
   return (
     <div className={styles.Z1dict}>
       <div className='pageTitle'>数据字典</div>
-      <p>待开发</p>
+      {/* 顶部 */}
+      <div className='Z1top'>
+        <div className='Z1topll'>
+          {dictAll.length ? (
+            <Cascader
+              style={{ width: 240 }}
+              value={topId}
+              options={Z1toTowFu(dictAll)}
+              fieldNames={{ label: 'name', value: 'id', children: 'children' }}
+              onChange={onChange}
+            />
+          ) : (
+            <div style={{ width: 240 }}></div>
+          )}
+          &emsp;
+          <Input
+            style={{ width: 240 }}
+            placeholder='请输入字典值'
+            maxLength={30}
+            value={value}
+            onChange={e => valueChange(e.target.value)}
+          />
+        </div>
+        <div className='Z1toprr'>
+          <Button
+            type='primary'
+            onClick={() => setAddInfo({ id: '-1', txt: '新增', acInfo: rightData })}
+          >
+            新增
+          </Button>
+          &emsp;
+          <Button onClick={() => resetFu(true)}>重置</Button>
+        </div>
+      </div>
+      {/* 主体 */}
+      <div className='Z1main'>
+        <div className='Z1m1ll'>
+          {treeDataTemp && treeDataTemp.length ? (
+            <Tree
+              // 默认全部展开
+              defaultExpandAll={true}
+              // 数据
+              treeData={treeData}
+              // 自定义字段
+              // fieldNames={{ title: 'name', key: 'id', children: 'children' }}
+              // 选中
+              selectedKeys={[acShu]}
+              // 点击
+              onSelect={onSelect}
+            />
+          ) : null}
+        </div>
+        <div className='Z1m1rr'>
+          {rightData.id ? (
+            <>
+              <div className='Z1mr1'>操作</div>
+              <div className='Z1mr2'>
+                <Button type='text' onClick={() => addSonFu(rightData.id)}>
+                  编辑
+                </Button>
+                &emsp;
+                <MyPopconfirm txtK='删除' onConfirm={() => delTree(rightData.id)} />
+              </div>
+
+              {/* <div className='Z1mr3'>
+                <div className='Z1mr3ll'>id:</div>
+                <div className='Z1mr3rr'>{rightData.id}</div>
+              </div> */}
+
+              <div className='Z1mr3'>
+                <div className='Z1mr3ll'>字典值:</div>
+                <div className='Z1mr3rr'>{rightData.name}</div>
+              </div>
+
+              <div className='Z1mr3'>
+                <div className='Z1mr3ll'>层级:</div>
+                <div className='Z1mr3rr'>{rightData.level - 2}</div>
+              </div>
+
+              <div className='Z1mr3'>
+                <div className='Z1mr3ll'>排序值:</div>
+                <div className='Z1mr3rr'>{rightData.sort}</div>
+              </div>
+            </>
+          ) : null}
+        </div>
+      </div>
+      {/* 新增/编辑页面 中图法分类 */}
+      {addInfo.id ? (
+        <Z1add
+          addInfo={addInfo}
+          addFu={() => resetFu(false)}
+          closeFu={() => setAddInfo({} as Z1AddInfoType)}
+        />
+      ) : null}
     </div>
   )
 }

+ 10 - 0
src/pages/Z_system/Z1dict/type.d.ts

@@ -0,0 +1,10 @@
+export type TypeZ1dict = {
+  id: string
+  parentId: string
+  sort: number
+  name: string
+  description: any
+  ancestor: string
+  level: number
+  children?: TypeZ1dict[]
+}

+ 99 - 0
src/pages/Z_system/Z2numRule/Z2edit.tsx

@@ -0,0 +1,99 @@
+import React, { useCallback, useEffect, useRef } from 'react'
+import styles from './index.module.scss'
+import { Button, Form, FormInstance, Input, Modal, Select } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { TypeZ2list } from './type'
+import { Z2editSelectDate, Z2editSelectlength } from './data'
+import { Z2_APIsave } from '@/store/action/Z2numRule'
+import { MessageFu } from '@/utils/message'
+
+type Props = {
+  editObj: TypeZ2list
+  editFu: () => void
+  closeFu: () => void
+}
+
+function Z2edit({ editObj, editFu, closeFu }: Props) {
+  useEffect(() => {
+    FormBoxRef.current?.setFieldsValue(editObj)
+  }, [editObj])
+
+  // 设置表单ref
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    // return MessageFu.warning("有表单不符号规则!");
+  }, [])
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      const obj = { ...values, id: editObj.id }
+      const res = await Z2_APIsave(obj)
+      if (res.code === 0) {
+        MessageFu.success('编辑成功')
+        editFu()
+        closeFu()
+      }
+    },
+    [closeFu, editFu, editObj.id]
+  )
+
+  return (
+    <Modal
+      wrapClassName={styles.Z2edit}
+      open={true}
+      title='编辑'
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='Z2aMain'>
+        <Form
+          scrollToFirstError={true}
+          ref={FormBoxRef}
+          name='basic'
+          labelCol={{ span: 3 }}
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete='off'
+        >
+          <Form.Item label='编号类型' name='name'>
+            <Input maxLength={30} disabled />
+          </Form.Item>
+
+          <Form.Item
+            label='前缀'
+            name='prefix'
+            rules={[{ pattern: /^[A-Z0-9]*$/, message: '请输入大写英文字母或数字' }]}
+          >
+            <Input maxLength={6} showCount placeholder='请输入大写英文字母或数字' />
+          </Form.Item>
+
+          <Form.Item label='日期方式' name='dateType'>
+            <Select options={Z2editSelectDate} />
+          </Form.Item>
+
+          <Form.Item label='流水号位数' name='length' rules={[{ required: true, message: '' }]}>
+            <Select options={Z2editSelectlength} />
+          </Form.Item>
+
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+            <Button type='primary' htmlType='submit'>
+              提交
+            </Button>
+            &emsp;
+            <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoZ2edit = React.memo(Z2edit)
+
+export default MemoZ2edit

+ 16 - 0
src/pages/Z_system/Z2numRule/data.ts

@@ -0,0 +1,16 @@
+export const Z2editSelectDate = [
+  { value: '', label: '无' },
+  { value: 'yyyyMMdd', label: 'yyyyMMdd' },
+  { value: 'yyMMdd', label: 'yyMMdd' },
+  { value: 'MMdd', label: 'MMdd' }
+]
+
+export const Z2editSelectlength = [
+  { value: 2, label: 2 },
+  { value: 3, label: 3 },
+  { value: 4, label: 4 },
+  { value: 5, label: 5 },
+  { value: 6, label: 6 },
+  { value: 7, label: 7 },
+  { value: 8, label: 8 }
+]

+ 35 - 0
src/pages/Z_system/Z2numRule/index.module.scss

@@ -1,4 +1,39 @@
 .Z2numRule {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 24px;
   :global {
+    .Z2top {
+      display: flex;
+      justify-content: space-between;
+    }
+    .Z2tableBox {
+      border-radius: 10px;
+      overflow: hidden;
+      margin-top: 15px;
+      height: calc(100% - 25px);
+      background-color: #fff;
+    }
+  }
+}
+
+// 编辑弹窗页面
+.Z2edit {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+    }
+
+    .Z2aMain {
+      padding-top: 15px;
+    }
   }
 }

+ 87 - 2
src/pages/Z_system/Z2numRule/index.tsx

@@ -1,10 +1,95 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
+import { Button, Input } from 'antd'
+import { useDispatch, useSelector } from 'react-redux'
+import { Z2_APIgetList } from '@/store/action/Z2numRule'
+import MyTable from '@/components/MyTable'
+import { RootState } from '@/store'
+import { TypeZ2list } from './type'
+import { Z2tableC } from '@/utils/tableData'
+import Z2edit from './Z2edit'
+
 function Z2numRule() {
+  const dispatch = useDispatch()
+
+  const [value, setValue] = useState('')
+  const valueRef = useRef('')
+
+  const getListFu = useCallback(() => {
+    dispatch(Z2_APIgetList(valueRef.current))
+  }, [dispatch])
+
+  useEffect(() => {
+    getListFu()
+  }, [getListFu])
+
+  // 点击重置
+  const resetFu = useCallback(() => {
+    setValue('')
+    valueRef.current = ''
+    getListFu()
+  }, [getListFu])
+
+  // 从仓库中获取表格数据
+  const tableList = useSelector((state: RootState) => state.Z2numRule.tableList)
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: TypeZ2list) => {
+          return (
+            <Button size='small' type='text' onClick={() => setEditObj(item)}>
+              编辑
+            </Button>
+          )
+        }
+      }
+    ]
+  }, [])
+
+  // 点击编辑
+  const [editObj, setEditObj] = useState({} as TypeZ2list)
+
   return (
     <div className={styles.Z2numRule}>
       <div className='pageTitle'>编号规则</div>
-      <p>待开发</p>
+      {/* 顶部 */}
+      <div className='Z2top'>
+        <div className='Z2topll'>
+          <Input
+            placeholder='请输入编号类型'
+            value={value}
+            onChange={e => {
+              const val = e.target.value.trim()
+              valueRef.current = val
+              setValue(val)
+            }}
+            maxLength={10}
+          />
+        </div>
+        <div className='Z2toprr'>
+          <Button type='primary' onClick={getListFu}>
+            查询
+          </Button>
+          &emsp;
+          <Button onClick={resetFu}>重置</Button>
+        </div>
+      </div>
+      {/* 表格 */}
+      <div className='Z2tableBox'>
+        <MyTable
+          yHeight={680}
+          list={tableList}
+          columnsTemp={Z2tableC}
+          lastBtn={tableLastBtn}
+          pagingInfo={false}
+        />
+      </div>
+
+      {editObj.id ? (
+        <Z2edit editObj={editObj} editFu={getListFu} closeFu={() => setEditObj({} as TypeZ2list)} />
+      ) : null}
     </div>
   )
 }

+ 12 - 0
src/pages/Z_system/Z2numRule/type.d.ts

@@ -0,0 +1,12 @@
+export type TypeZ2list = {
+  createTime: string
+  creatorName: string
+  dateType: string
+  id: number
+  isEdit: number
+  length: number
+  name: string
+  prefix: string
+  type: string
+  updateTime: string
+}

+ 39 - 0
src/store/action/Z1dict.ts

@@ -0,0 +1,39 @@
+import http from '@/utils/http'
+import { AppDispatch } from '..'
+import { TypeZ1dict } from '@/pages/Z_system/Z1dict/type'
+/**
+ * 获取对应表格列表(传id就是列表,从第三级开始)
+ */
+export const Z1_APIgetDict = (id?: string, backFu?: (data: TypeZ1dict[]) => void): any => {
+  return async (dispatch: AppDispatch) => {
+    let url = 'cms/dict/getTree'
+    if (id) url = url + `?parentId=${id}`
+    const res = await http.get(url)
+    if (res.code === 0) {
+      const caseStr = id ? 'Z1/getList' : 'Z1/getDictAll'
+      dispatch({ type: caseStr, payload: res.data })
+      backFu && backFu(res.data)
+    }
+  }
+}
+
+/**
+ * 获取详情
+ */
+export const Z1_APIgetInfo = (id: string) => {
+  return http.get(`cms/dict/detail/${id}`)
+}
+
+/**
+ * 新增、编辑
+ */
+export const Z1_APIsave = (data: any) => {
+  return http.post('cms/dict/save', data)
+}
+
+/**
+ * 删除
+ */
+export const Z1_APIdel = (id: string) => {
+  return http.get(`cms/dict/remove/${id}`)
+}

+ 23 - 0
src/store/action/Z2numRule.ts

@@ -0,0 +1,23 @@
+import http from '@/utils/http'
+import { AppDispatch } from '..'
+
+/**
+ * 编码规则-获取列表
+ */
+export const Z2_APIgetList = (name: string): any => {
+  return async (dispatch: AppDispatch) => {
+    let url = 'cms/number/getList'
+    if (name) url += `?name=${name}`
+    const res = await http.get(url)
+    if (res.code === 0) {
+      dispatch({ type: 'Z2/getList', payload: res.data })
+    }
+  }
+}
+
+/**
+ * 点击编辑
+ */
+export const Z2_APIsave = (data: any) => {
+  return http.post('cms/number/edit', data)
+}

+ 34 - 0
src/store/reducer/Z1dict.ts

@@ -0,0 +1,34 @@
+import { TypeZ1dict } from '@/pages/Z_system/Z1dict/type'
+
+// 初始化状态
+const initState = {
+  // 所有字典数据
+  dictAll: [] as TypeZ1dict[],
+  // 列表展示的数据
+  dictList: [] as TypeZ1dict[]
+}
+
+// 定义 action 类型
+type Props =
+  | {
+      type: 'Z1/getDictAll'
+      payload: TypeZ1dict[]
+    }
+  | {
+      type: 'Z1/getList'
+      payload: TypeZ1dict[]
+    }
+
+// reducer
+export default function userReducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取字典数据
+    case 'Z1/getDictAll':
+      return { ...state, dictAll: action.payload }
+    // 获取展示的数据
+    case 'Z1/getList':
+      return { ...state, dictList: action.payload }
+    default:
+      return state
+  }
+}

+ 25 - 0
src/store/reducer/Z2numRule.ts

@@ -0,0 +1,25 @@
+import { TypeZ2list } from '@/pages/Z_system/Z2numRule/type'
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableList: [] as TypeZ2list[]
+}
+
+// 定义 action 类型
+type Props = {
+  type: 'Z2/getList'
+  payload: TypeZ2list[]
+}
+
+// reducer
+export default function userReducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取列表数据
+    case 'Z2/getList':
+      return { ...state, tableList: action.payload }
+
+    default:
+      return state
+  }
+}

+ 4 - 1
src/store/reducer/index.ts

@@ -3,13 +3,16 @@ import { combineReducers } from 'redux'
 
 // 导入 登录 模块的 reducer
 import A0Layout from './layout'
-
+import Z1dict from './Z1dict'
+import Z2numRule from './Z2numRule'
 import Z6user from './Z6user'
 import Z7log from './Z7log'
 
 // 合并 reducer
 const rootReducer = combineReducers({
   A0Layout,
+  Z1dict,
+  Z2numRule,
   Z6user,
   Z7log
 })

+ 7 - 0
src/utils/tableData.ts

@@ -14,6 +14,13 @@
 //     ["text", "创建日期",'description', 50,A],
 //   ];
 
+export const Z2tableC = [
+  ['txt', '编号类型', 'name'],
+  ['txt', '前缀', 'prefix'],
+  ['txt', '日期方式', 'dateType'],
+  ['txt', '起始流水编号', 'length']
+]
+
 export const Z6tableC = [
   ['txt', '用户名', 'userName'],
   ['txtChange', '角色', 'isAdmin', { 1: '管理员', 0: '普通成员' }],