Переглянути джерело

feat: Merge branch '7.18' into dev 编号规则设置

outaozhen 3 роки тому
батько
коміт
0adeafd8d0

+ 5 - 0
config/routes.ts

@@ -133,6 +133,11 @@ const routes: MenuDataItem[] = [
         component: './Business/Inventory'
       },
       {
+        path: 'rules',
+        name: 'rules',
+        component: './Business/RulesSet'
+      },
+      {
         path: 'process',
         name: 'process',
         access: 'authRouteFilter',

+ 3 - 2
package.json

@@ -49,10 +49,11 @@
     "antd": "4.20.7",
     "array-move": "^4.0.0",
     "classnames": "^2.2.6",
-    "dayjs": "^1.10.7",
+    "dayjs": "^1.11.3",
     "lodash": "^4.17.11",
     "omit.js": "^2.0.2",
     "rc-menu": "^9.0.13",
+    "rc-tween-one": "^3.0.6",
     "rc-util": "^5.14.0",
     "react": "18.1.0",
     "react-copy-to-clipboard": "^5.1.0",
@@ -67,9 +68,9 @@
     "babel-plugin-import": "^1.13.5",
     "compression-webpack-plugin": "^10.0.0",
     "cross-env": "^7.0.0",
+    "eslint": "^8.17.0",
     "husky": "^8.0.0",
     "lint-staged": "^10.0.0",
-    "eslint": "^8.17.0",
     "prettier": "^2.6.1",
     "stylelint": "^14.9.0",
     "typescript": "^4.7.3",

Різницю між файлами не показано, бо вона завелика
+ 5775 - 1908
pnpm-lock.yaml


+ 1 - 0
src/locales/zh-CN/menu.ts

@@ -27,6 +27,7 @@ export default {
   'menu.institutions.staff': '人员管理',
   'menu.institutions.restrict': '限制登录',
   'menu.business': '业务审批设置',
+  'menu.business.rules': '编号规则设置',
   'menu.business.inventory': '审核资料清单模板',
   'menu.business.process': '流程用户设置',
   'menu.institutions.company.company-list': '单位列表',

+ 310 - 0
src/pages/Business/RulesSet/index.tsx

@@ -0,0 +1,310 @@
+import { PageContainer } from '@ant-design/pro-layout'
+import { Button, Col, Form, Input, InputNumber, message, Row, Select, Tabs, Tag } from 'antd'
+import React, { useEffect, useState } from 'react'
+import { TweenOneGroup } from 'rc-tween-one'
+import { createUid, dayjsFormat } from '@/utils/util'
+import { queryRuleCodeList, updateRuleCode } from '@/services/api/business'
+import { useRequest } from '@umijs/max'
+
+const { TabPane } = Tabs
+const { Option } = Select
+const contentHeight = document.body.clientHeight - 122
+
+const connectorOption = [
+  { label: '无', value: '' },
+  { label: '-', value: '-' },
+  { label: '_', value: '_' }
+]
+
+export enum ruleOptionEunm {
+  REVIEWTYPE = '1',
+  YEAR = '2',
+  MONTH = '3',
+  NUMBER = '4',
+  TEXT = '5'
+}
+interface iTags {
+  ruleArr: ruleOption[]
+  setRuleArr: (arr: ruleOption[]) => void
+}
+
+const RenderTags: React.FC<iTags> = ({ ruleArr, setRuleArr }) => {
+  const handleClose = (removedTag: ruleOption) => {
+    const tags = ruleArr.filter(tag => tag.pid !== removedTag.pid)
+    setRuleArr(tags)
+  }
+  return (
+    <div>
+      <TweenOneGroup
+        enter={{
+          scale: 0.8,
+          opacity: 0,
+          type: 'from',
+          duration: 100
+        }}
+        leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
+        appear={false}>
+        {ruleArr.map((tag, idx) => {
+          return (
+            <span key={idx} style={{ display: 'inline-block' }}>
+              {tag?.label ? (
+                <Tag
+                  closable
+                  onClose={(e: MouseEvent) => {
+                    e.preventDefault()
+                    handleClose(tag)
+                  }}>
+                  {tag.label}
+                </Tag>
+              ) : null}
+            </span>
+          )
+        })}
+      </TweenOneGroup>
+    </div>
+  )
+}
+
+const RulesSet = () => {
+  const [form] = Form.useForm()
+  const [state, setState] = useState({
+    ruleTypeValue: ruleOptionEunm.REVIEWTYPE,
+    tabId: 'yuS',
+    connector: '-'
+  })
+
+  const [ruleArr, setRuleArr] = useState<ruleOption[]>([])
+
+  // 处理自动位数编号 -> 联动起始编号
+  const digitHandler = (value: any) => {
+    if (value) {
+      const length = form.getFieldValue('digits')
+      const code = parseInt(form.getFieldValue('autoCode'))
+      const newCode = (Array(length).join('0') + code).slice(-length)
+      form.setFieldsValue({ autoCode: newCode })
+    }
+  }
+
+  const { run: tryRuleCode } = useRequest(() => queryRuleCodeList({ tab: state.tabId }), {
+    manual: true,
+    onSuccess: result => {
+      setRuleArr(result.rules)
+      setState({ ...state, connector: result.connector })
+    }
+  })
+
+  const { run: tryUpdateRuleCode } = useRequest(updateRuleCode, {
+    manual: true,
+    onSuccess: () => {
+      message.success('规则更改成功')
+      tryRuleCode()
+    }
+  })
+
+  useEffect(() => {
+    if (state.ruleTypeValue === ruleOptionEunm.NUMBER) {
+      form.setFieldsValue({ ruleType: ruleOptionEunm.NUMBER, digits: '5', autoCode: '00001', ruleText: '' })
+    }
+  }, [state.ruleTypeValue])
+
+  // 只需首次加载执行一次
+  useEffect(() => {
+    function fectTryRuleCode() {
+      if (state.tabId === 'yuS') {
+        tryRuleCode()
+      }
+    }
+    fectTryRuleCode()
+  }, [])
+
+  // 添加规则
+  const ruleHandel = () => {
+    switch (state.ruleTypeValue) {
+      case ruleOptionEunm.REVIEWTYPE:
+        setRuleArr([
+          ...ruleArr,
+          {
+            type: 'approvalType',
+            value: form.getFieldValue('approvalType'),
+            label: '审核类型',
+            pid: createUid()
+          }
+        ])
+        break
+      case ruleOptionEunm.YEAR:
+        setRuleArr([
+          ...ruleArr,
+          {
+            type: 'currentYear',
+            value: dayjsFormat(new Date(), 'YYYY'),
+            label: '当前年份',
+            pid: createUid()
+          }
+        ])
+        break
+      case ruleOptionEunm.MONTH:
+        setRuleArr([
+          ...ruleArr,
+          {
+            type: 'currentMonth',
+            value: dayjsFormat(new Date(), 'M'),
+            label: '当前月份',
+            pid: createUid()
+          }
+        ])
+        break
+      case ruleOptionEunm.NUMBER:
+        setRuleArr([
+          ...ruleArr,
+          {
+            type: 'autoCode',
+            value: form.getFieldValue('autoCode'),
+            label: '自动编号',
+            pid: createUid()
+          }
+        ])
+        break
+      default:
+        setRuleArr([
+          ...ruleArr,
+          {
+            type: 'fixedText',
+            value: form.getFieldValue('fixedText'),
+            label: '固定文本',
+            pid: createUid()
+          }
+        ])
+        break
+    }
+  }
+  return (
+    <PageContainer title={false}>
+      <div className="p-4 bg-white" style={{ height: `${contentHeight}px` }}>
+        <div className="flex justify-between w-full pb-2 border-b border-[bg-[#00ffcc]]">
+          <div className="text-xl">编号规则设置</div>
+          <div>
+            <Button
+              type="primary"
+              onClick={() => {
+                tryUpdateRuleCode({
+                  tab: state.tabId,
+                  rules: ruleArr.map(item => ({
+                    rule: item.type,
+                    value: item.value,
+                    label: item.label,
+                    pid: item.pid
+                  })),
+                  connector: state.connector
+                })
+              }}>
+              保存
+            </Button>
+          </div>
+        </div>
+        <Form
+          form={form}
+          initialValues={{
+            approvalType: '01',
+            Connector: state.connector,
+            ruleType: ruleOptionEunm.REVIEWTYPE
+          }}>
+          <Tabs
+            defaultActiveKey="yuS"
+            onChange={key => {
+              setState({
+                ...state,
+                tabId: key
+              })
+            }}>
+            <TabPane key="yuS" tab="预算">
+              <Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 24 }} label="编号预览">
+                {ruleArr.map(item => item?.value).join(state.connector)}
+              </Form.Item>
+              <Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 24 }} label="编号规则">
+                <div className="w-full min-h-32px border-1 border-[#d9d9d9] border-solid rounded-2px py-1 px-3">
+                  <RenderTags ruleArr={ruleArr} setRuleArr={setRuleArr} />
+                </div>
+              </Form.Item>
+              <Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 5 }} label="连接符" name="Connector">
+                <Select
+                  options={connectorOption}
+                  onSelect={value =>
+                    setState({
+                      ...state,
+                      connector: value
+                    })
+                  }
+                />
+              </Form.Item>
+              <Row>
+                <Col span={8}>
+                  <Form.Item labelCol={{ span: 9 }} wrapperCol={{ span: 24 }} label="规则" name="ruleType">
+                    <Select
+                      onSelect={value =>
+                        setState({
+                          ...state,
+                          ruleTypeValue: value
+                        })
+                      }>
+                      <Option value="0">请选择</Option>
+                      <Option value="1">审核类型</Option>
+                      <Option value="2">当前年份</Option>
+                      <Option value="3">当前月份</Option>
+                      <Option value="4">自动编号</Option>
+                      <Option value="5">固定文本</Option>
+                    </Select>
+                  </Form.Item>
+                </Col>
+                <Col span={16}>
+                  <div className="flex">
+                    <div className="px-2">
+                      <Form.Item
+                        label="类型"
+                        name="approvalType"
+                        hidden={state.ruleTypeValue === ruleOptionEunm.REVIEWTYPE ? false : true}>
+                        <Select style={{ width: 180 }}>
+                          <Option value="01">预算</Option>
+                        </Select>
+                      </Form.Item>
+                    </div>
+                    <div className="pr-2">
+                      <Form.Item
+                        label="数位"
+                        name="digits"
+                        hidden={state.ruleTypeValue === ruleOptionEunm.NUMBER ? false : true}>
+                        <InputNumber style={{ width: 180 }} min={1} onChange={value => digitHandler(value)} />
+                      </Form.Item>
+                    </div>
+                    <div className="pr-2">
+                      <Form.Item
+                        label="规则"
+                        name="fixedText"
+                        hidden={state.ruleTypeValue === ruleOptionEunm.TEXT ? false : true}>
+                        <Input style={{ width: 180 }} />
+                      </Form.Item>
+                    </div>
+                    <div className="pr-2">
+                      <Form.Item
+                        label="起始编号"
+                        name="autoCode"
+                        hidden={state.ruleTypeValue === ruleOptionEunm.NUMBER ? false : true}>
+                        <Input type="number" style={{ width: 180 }} />
+                      </Form.Item>
+                    </div>
+                    <div>
+                      <Button type="primary" ghost onClick={() => ruleHandel()}>
+                        添加
+                      </Button>
+                    </div>
+                  </div>
+                </Col>
+              </Row>
+            </TabPane>
+          </Tabs>
+        </Form>
+      </div>
+    </PageContainer>
+  )
+}
+
+export default RulesSet

+ 16 - 0
src/services/api/business.ts

@@ -54,3 +54,19 @@ export async function moveTemplate(params: { ID: string; moveID: string }) {
     data: params
   })
 }
+
+/** 编号规则生成器查询详情 */
+export async function queryRuleCodeList(params: { tab: string }) {
+  return request('/RuleCode/list', {
+    method: 'GET',
+    params
+  })
+}
+
+/** 编号规则生成器保存编号 */
+export async function updateRuleCode(params: API.RuleCodeUpdateParams) {
+  return request('/RuleCode/update', {
+    method: 'POST',
+    data: params
+  })
+}

+ 5 - 0
src/services/api/typings.d.ts

@@ -414,4 +414,9 @@ declare namespace API {
     institutionID: string
     accountID: string
   }
+
+  type RuleCodeUpdateParams = {
+    tab: string
+    rules: any[]
+  }
 }

+ 14 - 0
src/utils/util.ts

@@ -1,5 +1,7 @@
 import type { TableColumnType } from 'antd'
+import dayjs from 'dayjs'
 
+// eslint-disable-next-line no-promise-executor-return
 export const delay = (ms?: number | undefined) => new Promise(res => setTimeout(res, ms))
 
 /**
@@ -33,3 +35,15 @@ export function generateColumns(c: TableColumnType, s: any, f?: string | string[
   }
   return nC
 }
+
+/**
+ * 日期格式化
+ * @param format - 格式
+ */
+export const dayjsFormat = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
+  if (date === '0001-01-01 00:00:00' || !date) return ''
+  return dayjs(date).format(format)
+}
+
+// 可控长度的随机数拼接时间戳成产唯一id
+export const createUid = () => URL.createObjectURL(new Blob()).substr(-36)