lanjianrong před 4 roky
rodič
revize
f56d834a02
36 změnil soubory, kde provedl 927 přidání a 1215 odebrání
  1. 12 0
      src/components/ModalStore/README.md
  2. 27 2
      src/components/ModalStore/index.tsx
  3. 13 4
      src/components/ModalStore/src/CreateProvider.tsx
  4. 52 44
      src/pages/Customer/Business/components/AddBusiness.jsx
  5. 59 50
      src/pages/Customer/Business/components/BusinessDetail/index.jsx
  6. 12 24
      src/pages/Customer/Business/components/ChangeStaff/index.jsx
  7. 25 31
      src/pages/Customer/Business/index.jsx
  8. 42 30
      src/pages/Customer/Client/components/AddClient/index.jsx
  9. 65 65
      src/pages/Customer/Client/components/ClientDetail/AddRecord.jsx
  10. 25 35
      src/pages/Customer/Client/components/ClientDetail/TabList.jsx
  11. 3 2
      src/pages/Customer/Client/components/ClientDetail/index.jsx
  12. 17 17
      src/pages/Customer/Client/components/ConnectClient/index.jsx
  13. 1 0
      src/pages/Customer/Client/index.jsx
  14. 93 74
      src/pages/Customer/Company/components/AddCompany/index.jsx
  15. 0 1
      src/pages/Customer/Company/components/ChangeCompany/index.jsx
  16. 18 71
      src/pages/Customer/Company/components/CompanyDetail/TabList.jsx
  17. 9 2
      src/pages/Customer/Company/components/CompanyDetail/index.jsx
  18. 12 11
      src/pages/Customer/Company/components/ConnectCompany/index.jsx
  19. 31 32
      src/pages/Customer/Company/index.jsx
  20. 18 18
      src/pages/Hr/Employee/components/EmployeeDetail/index.jsx
  21. 14 16
      src/pages/Hr/Employee/components/StaffModal/index.jsx
  22. 31 38
      src/pages/Product/Lock/LockStore/components/ChangeClient/index.jsx
  23. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/Form.jsx
  24. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/LowerList.jsx
  25. 59 65
      src/pages/Product/Lock/LockStore/components/LocksDetail/LockModal.jsx
  26. 24 84
      src/pages/Product/Lock/LockStore/components/LocksDetail/TabList.jsx
  27. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/consts.js
  28. 116 0
      src/pages/Product/Lock/LockStore/components/LockDetail/index.jsx
  29. 0 120
      src/pages/Product/Lock/LockStore/components/LocksDetail/index.jsx
  30. 0 29
      src/pages/Product/Lock/LockStore/components/LocksDetail/index.less
  31. 20 19
      src/pages/Product/Lock/LockStore/components/SoftwareDetail/index.jsx
  32. 20 110
      src/pages/Product/Lock/LockStore/index.jsx
  33. 45 95
      src/pages/Workbench/Dashboard/components/RatioPanels.jsx
  34. 28 90
      src/pages/Workbench/Dashboard/components/ReminderList.jsx
  35. 1 1
      src/pages/Workbench/Dashboard/components/SoftLeaderboard.jsx
  36. 35 35
      src/pages/Workbench/Dashboard/index.jsx

+ 12 - 0
src/components/ModalStore/README.md

@@ -0,0 +1,12 @@
+## ModalStore 用于集中管理抽屉以及弹窗
+
+### 使用方法:
+
+1. 在 modalMap 中引入对应的 Modal/Drawer 组件,key 格式: 弹窗(M_ADD_CLIENT)、抽屉(D_CLIENT_DETAIL), 该组件默认接收 visible、onCancel(弹窗)/onClose(抽屉)。
+2. destroyOnClose 控制弹窗/抽屉是否在关闭后销毁掉组件。
+
+### 封装原因:
+
+1. cld2 中存在大量需要共用的弹窗以及弹窗,如果每个调用的地方都要重复嵌套一次,且逻辑基本一样,会造成业务代码臃肿、不健康,长期下去技术债务也无法弥补。
+2. 由于第一次封装使用了单例模式,所有抽屉和弹窗各共用了一个实例导致了后期耗费比较大的成本去适配 Modal 和 Drawer 的层级(zIndex)兼容且最终效果来看也未能满足一开始要实现的效果。
+3. 由 React.createContext 创建上下文中使用堆栈管理弹窗,即可实现无限嵌套且层级叠加不冲突的弹窗/抽屉。

+ 27 - 2
src/components/ModalStore/index.tsx

@@ -4,16 +4,41 @@ import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
 import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import ConnectCompany from '@/pages/Customer/Company/components/ConnectCompany'
 import AddClient from '@/pages/Customer/Client/components/AddClient'
+import AddCompany from '@/pages/Customer/Company/components/AddCompany'
+import EmployeeDetail from '@/pages/Hr/Employee/components/EmployeeDetail'
+import StaffModal from '@/pages/Hr/Employee/components/StaffModal'
+import AddBusiness from '@/pages/Customer/Business/components/AddBusiness'
+import BusinessDetail from '@/pages/Customer/Business/components/BusinessDetail'
+import ReminderList from '@/pages/Workbench/Dashboard/components/ReminderList'
+import RatioPanels from '@/pages/Workbench/Dashboard/components/RatioPanels'
+import SoftwareDetail from '@/pages/Product/Lock/LockStore/components/SoftwareDetail'
+import AddRecord from '@/pages/Customer/Client/components/ClientDetail/AddRecord'
+import OpreateLock from '@/pages/Product/Lock/LockStore/components/LockDetail/OpreateLock'
+import LockDetail from '@/pages/Product/Lock/LockStore/components/LockDetail'
+import ConnectClient from '@/pages/Customer/Client/components/ConnectClient'
 
 const modalMap = {
+  M_CLIENT_ADD: AddClient, // 添加客户弹窗
+  M_COMPANY_ADD: AddCompany, // 添加单位弹窗
+  M_BUSINESS_ADD: AddBusiness, // 添加商机弹窗
   D_CLIENT_DETAIL: ContactDetail, // 客户详情抽屉
   D_COMPANY_DETAIL: CompanyDetail, // 单位详情抽屉
+  D_BUSINESS_DETAIL: BusinessDetail, // 商机详情抽屉
+  M_CONNECT_CLIENT: ConnectClient, // 关联客户弹窗
   M_CONNECT_COMPANY: ConnectCompany, // 关联单位弹窗
-  M_CLIENT_ADD: AddClient // 添加客户弹窗
+  D_EMPLOYEE_DETAIL: EmployeeDetail, // 部门与员工详情抽屉
+  M_CONNECT_STAFF: StaffModal, // 关联员工弹窗
+  M_REMINDER_LIST: ReminderList, // 仪表盘提醒列表弹窗
+  M_RATIO_PANELS: RatioPanels, // 仪表盘环比数据弹窗
+  D_LOCK_DETAIL: LockDetail, // 锁库详情抽屉
+  D_SOFTWARE_DETAIL: SoftwareDetail, // 软件锁详情抽屉
+  M_ADD_RECORD: AddRecord, // 添加服务记录
+  M_OPREATE_LOCK: OpreateLock // 操作锁库弹窗
 }
 
 export const useModal = createModalHook<typeof modalMap>()
-export default ({ children }) => (
+
+export default ({ children }: { children: React.ReactChildren }) => (
   <ModalStore modalMap={modalMap} destroyOnClose="afterClose">
     {children}
   </ModalStore>

+ 13 - 4
src/components/ModalStore/src/CreateProvider.tsx

@@ -35,10 +35,15 @@ class ModalStore extends React.Component<ModalStoreProps, ModalStoreState> {
 
   // 获取modal的config
   private getModalConfig(key: string) {
-    const { modalMap = {}, visiblePropName = 'visible', destroyOnClose = true } = this.props
+    const { modalMap = {}, visiblePropName = 'visible' } = this.props
     let config = modalMap[key]
     if (typeof config === 'function') config = { component: config }
-    const onClosePropName = key.startsWith('M') ? 'onCancel' : 'onClose'
+    let onClosePropName = 'onCancel'
+    let destroyOnClose = 'afterClose'
+    if (key.startsWith('D')) {
+      onClosePropName = 'onClose'
+      destroyOnClose = 'afterVisibleChange'
+    }
 
     return { visiblePropName, onClosePropName, destroyOnClose, config }
   }
@@ -79,12 +84,16 @@ class ModalStore extends React.Component<ModalStoreProps, ModalStoreState> {
     this.setModalState(prevModals => {
       const defaultProps: any = {
         [visiblePropName]: true,
-        [onClosePropName]: this.getCloseFunction(key, state[onClosePropName])
+        [onClosePropName]: this.getCloseFunction(key, state?.[onClosePropName])
       }
 
       if (destroyOnClose) {
         const prop = typeof destroyOnClose === 'string' ? destroyOnClose : onClosePropName
-        defaultProps[prop] = this.getDestroyFunction(key)
+
+        defaultProps[prop] =
+          destroyOnClose === 'afterVisibleChange'
+            ? (visible: boolean) => !visible && this.getDestroyFunction(key)()
+            : this.getDestroyFunction(key)
       }
       const newModal = { ...state, ...defaultProps, key }
       const nextModals = prevModals.slice()

+ 52 - 44
src/pages/Customer/Business/components/AddBusiness.jsx

@@ -1,49 +1,56 @@
 import { ProFormDatePicker, ProFormSelect, ProFormText } from '@ant-design/pro-form'
-import { Button, Row, Col, message } from 'antd'
-import { Plus } from '@icon-park/react'
-import React, { useRef } from 'react'
+import { Button, Row, Col, Modal, Form } from 'antd'
 import { connect } from 'umi'
 import { addBusiness } from '@/services/customer'
-import ModalDragForm from '@/components/Modal/src/components/ModalDragForm'
 import { isNullOrUnDef } from '@/utils/is'
+import consts from '@/consts'
 
 const AddBusiness = props => {
-  const formRef = useRef(null)
-  const { groupList = [], reload } = props
+  const [formRef] = Form.useForm()
+  const { visible, onCancel, groupList = [], reload } = props
   const layout = {
     layout: 'horizontal',
     labelCol: { flex: '100px' }
   }
-  return (
-    <ModalDragForm
-      {...layout}
-      formRef={formRef}
-      trigger={
-        <Button type="primary" className="flex items-center">
-          <Plus className="mr-1" />
-          商机
-        </Button>
+
+  const handleOnOk = () => {
+    formRef?.validateFields().then(async values => {
+      const { code = -1 } = await addBusiness(values)
+      if (code === consts.RET_CODE.SUCCESS) {
+        !isNullOrUnDef(reload) && reload()
+        formRef.current?.resetFields()
+        setTimeout(() => {
+          onCancel()
+        }, 80)
       }
+    })
+  }
+  return (
+    <Modal
       title="添加商机"
-      onFinish={async values => {
-        try {
-          await addBusiness(values)
-          formRef.current?.resetFields()
-          !isNullOrUnDef(reload) && reload()
-          return true
-        } catch (error) {
-          message.error('添加失败,请重试')
-          return false
-        }
-      }}>
-      <ProFormText name="name" label="商机名称" required />
-      <ProFormSelect
-        fieldProps={{ options: groupList }}
-        name="businessGroupId"
-        label="商机状态组"
-        required
-      />
-      {/* <Col span={12}>
+      width="43vw"
+      visible={visible}
+      onCancel={onCancel}
+      footer={
+        <div>
+          <Button type="default" className="mr-2" onClick={onCancel}>
+            取消
+          </Button>
+          <Button type="primary" onClick={handleOnOk}>
+            确认
+          </Button>
+        </div>
+      }
+    >
+      <Form {...layout} form={formRef}>
+        <ProFormText name="name" label="商机名称" required />
+        <ProFormSelect
+          fieldProps={{ options: groupList }}
+          name="businessGroupId"
+          label="商机状态组"
+          required
+        />
+        {/* <Col span={12}>
           <ProFormDependency name={['businessGroupId']}>
             {({ businessGroupId }) => (
               <ProFormSelect
@@ -59,16 +66,17 @@ const AddBusiness = props => {
             )}
           </ProFormDependency>
         </Col> */}
-      <Row>
-        <Col span={12}>
-          <ProFormText name="price" label="商机金额(元)" required />
-        </Col>
-        <Col span={12}>
-          <ProFormDatePicker name="finalTime" label="预计成交" required />
-        </Col>
-      </Row>
-      <ProFormText name="remark" label="备注" />
-    </ModalDragForm>
+        <Row>
+          <Col span={12}>
+            <ProFormText name="price" label="商机金额(元)" required />
+          </Col>
+          <Col span={12}>
+            <ProFormDatePicker name="finalTime" label="预计成交" required />
+          </Col>
+        </Row>
+        <ProFormText name="remark" label="备注" />
+      </Form>
+    </Modal>
   )
 }
 

+ 59 - 50
src/pages/Customer/Business/components/BusinessDetail/index.jsx

@@ -1,4 +1,4 @@
-import { Row, Col, Spin, Tooltip } from 'antd'
+import { Row, Col, Spin, Tooltip, Drawer } from 'antd'
 import React, { useState, useEffect, useMemo } from 'react'
 import Form from './Form'
 import TabList from './TabList'
@@ -12,7 +12,15 @@ import './index.less'
 
 const Detail = props => {
   const { initialState } = useModel('@@initialState')
-  const { dispatch, updateKey = 'business', refresh, visible, dataId = '', orderIds = [] } = props
+  const {
+    visible,
+    onClose,
+    dispatch,
+    updateKey = 'business',
+    refresh,
+    dataId = '',
+    orderIds = []
+  } = props
   const shouldUpdate = refresh[updateKey] || false
   const [state, setState] = useState({
     loading: false,
@@ -64,59 +72,60 @@ const Detail = props => {
   }, [visible])
 
   return (
-    <Spin spinning={state.loading}>
-      <div className="sheet-box">
-        <Row>
-          <Col span={10} className="sheet-box-left">
-            {orderIds.length ? (
-              <div className="mb-3">
-                <Tooltip title="上一条记录">
-                  <Up
-                    fill={flipConsts.disableUpBtn ? '#BDBDBE' : '#886ab5'}
-                    size="20"
-                    onClick={() => flipFn(FlipOverEnum.UP)}
-                    className={[
-                      flipConsts.disableUpBtn ? 'cursor-not-allowed' : 'cursor-pointer'
-                    ].join(' ')}
-                  />
-                </Tooltip>
-                <Tooltip title="下一条记录">
-                  <Down
-                    fill={flipConsts.disableDownBtn ? '#BDBDBE' : '#886ab5'}
-                    size="20"
-                    onClick={() => flipFn(FlipOverEnum.DOWN)}
-                    className={[
-                      flipConsts.disableDownBtn ? 'cursor-not-allowed' : 'cursor-pointer',
-                      'ml-1'
-                    ].join(' ')}
-                  />
-                </Tooltip>
+    <Drawer visible={visible} onClose={onClose} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <div className="sheet-box">
+          <Row>
+            <Col span={10} className="sheet-box-left">
+              {orderIds.length ? (
+                <div className="mb-3">
+                  <Tooltip title="上一条记录">
+                    <Up
+                      fill={flipConsts.disableUpBtn ? '#BDBDBE' : '#886ab5'}
+                      size="20"
+                      onClick={() => flipFn(FlipOverEnum.UP)}
+                      className={[
+                        flipConsts.disableUpBtn ? 'cursor-not-allowed' : 'cursor-pointer'
+                      ].join(' ')}
+                    />
+                  </Tooltip>
+                  <Tooltip title="下一条记录">
+                    <Down
+                      fill={flipConsts.disableDownBtn ? '#BDBDBE' : '#886ab5'}
+                      size="20"
+                      onClick={() => flipFn(FlipOverEnum.DOWN)}
+                      className={[
+                        flipConsts.disableDownBtn ? 'cursor-not-allowed' : 'cursor-pointer',
+                        'ml-1'
+                      ].join(' ')}
+                    />
+                  </Tooltip>
+                </div>
+              ) : null}
+              <div className="sheet-left-panel pr-15px">
+                <Form
+                  isOwner={isOwner}
+                  business={state.business}
+                  groupStatus={state.groupStatus}
+                  updateKey={updateKey}
+                />
               </div>
-            ) : null}
-            <div className="sheet-left-panel pr-15px">
-              <Form
+            </Col>
+            <Col span={14} className="sheet-box-right">
+              <TabList
+                businessId={state.business.id}
+                clientList={state.linkClient.client}
                 isOwner={isOwner}
-                business={state.business}
-                groupStatus={state.groupStatus}
-                updateKey={updateKey}
               />
-            </div>
-          </Col>
-          <Col span={14} className="sheet-box-right">
-            <TabList
-              businessId={state.business.id}
-              clientList={state.linkClient.client}
-              isOwner={isOwner}
-            />
-            <LowerList log={state.log} serviceLog={state.serviceLog} />
-          </Col>
-        </Row>
-      </div>
-    </Spin>
+              <LowerList log={state.log} serviceLog={state.serviceLog} />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
   )
 }
 
-export default connect(({ refresh, single }) => ({
-  visible: single.drawer.visible,
+export default connect(({ refresh }) => ({
   refresh
 }))(Detail)

+ 12 - 24
src/pages/Customer/Business/components/ChangeStaff/index.jsx

@@ -1,33 +1,30 @@
 import React from 'react'
-import { useModal } from '@/components/Modal'
 import { LinkOne, Switch } from '@icon-park/react'
 import { Card, Tooltip } from 'antd'
 import { useDispatch } from 'dva'
 import consts from '@/consts'
-import StaffModal from '@/pages/Hr/Employee/components/StaffModal'
 import styles from './index.less'
-import EmployeeDetail from '@/pages/Hr/Employee/components/EmployeeDetail'
+import { useModal } from '@/components/ModalStore'
 
 const ChangeStaff = props => {
   const dispatch = useDispatch()
-  const { toggleModal, setModalProps, toggleDrawer, setDrawerProps } = useModal()
-  const { text = '', dataId, responsibleId, actionPayload } = props.dataSource
+  const dispatchModal = useModal()
+  const { text = '', dataId, responsibleId, actionPayload = 'business' } = props?.dataSource || {}
   const refreshClient = () => {
     dispatch({
       type: 'refresh/commitAction',
       payload: actionPayload
     })
   }
+
   const handleConnectCustomer = () => {
-    setModalProps({
-      width: '60vw',
-      modalRender: () => (
-        <StaffModal onSelect={refreshClient} id={dataId} postUrl="/business/change/responsible" />
-      ),
-      onCancel: () => toggleModal()
+    dispatchModal('M_CONNECT_STAFF', {
+      onSelect: refreshClient,
+      id: dataId,
+      postUrl: '/business/change/responsible'
     })
-    toggleModal()
   }
+
   const notValueRender = (
     <div onClick={handleConnectCustomer} className={styles.notBusinessContent}>
       <LinkOne size="14" />
@@ -36,17 +33,7 @@ const ChangeStaff = props => {
   )
 
   const handleCompanyClick = () => {
-    toggleDrawer()
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <EmployeeDetail dataId={dataId} />
-    })
-    toggleDrawer()
+    dispatchModal('D_EMPLOYEE_DETAIL', { dataId })
   }
   const normalValueRender = (
     <Card size="small">
@@ -59,7 +46,8 @@ const ChangeStaff = props => {
             placement="right"
             title="更换负责人"
             className="ml-5px"
-            onClick={handleConnectCustomer}>
+            onClick={handleConnectCustomer}
+          >
             <span className={styles.switchIcon}>
               <Switch />
             </span>

+ 25 - 31
src/pages/Customer/Business/index.jsx

@@ -2,21 +2,19 @@ import React, { useState, useEffect, useRef, useMemo } from 'react'
 import { connect, useModel } from 'umi'
 import { getBusinessList } from '@/services/customer'
 import consts from '@/consts'
-import { Select, Tooltip, Input } from 'antd'
-import AddBusiness from './components/AddBusiness'
-import Detail from './components/BusinessDetail'
-import { useModal } from '@/components/Modal'
-import CompanyDetail from '../Company/components/CompanyDetail'
+import { Select, Tooltip, Input, Button } from 'antd'
 import { Funnel } from '@ant-design/charts'
 import BasicTable from '@/components/Table'
 import { getAuthCache, getPermAuthCache, setAuthCache } from '@/utils/auth'
 import { PermDataTypeEunm } from '@/pages/Customer/Company/components/PermSelect'
 import { BUSINESS_GROUP_KEY } from '@/utils/cache/cacheEnum'
+import { Plus } from '@icon-park/react'
+import { useModal } from '@/components/ModalStore'
 
 const Business = ({ dispatch, groupList, shouldUpdate, loading, refreshGroupList }) => {
   const [defaultPermAuthCache, defaultStaffIds] = getPermAuthCache(PermDataTypeEunm.CUSTOMER)
+  const dispatchModal = useModal()
   const tRef = useRef(null)
-  const { toggleDrawer, setDrawerProps } = useModal()
   const defaultGroupId = getAuthCache(BUSINESS_GROUP_KEY) || null
   const [state, setState] = useState({
     orderIds: [],
@@ -70,24 +68,6 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading, refreshGroupList
     }
   }, [loading, shouldUpdate])
 
-  // 展示drawer
-  const showDrawer = (id, isCompany = false) => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: isCompany ? (
-        <CompanyDetail dataId={id} />
-      ) : (
-        <Detail dataId={id} orderIds={state.orderIds} group={groupList} />
-      )
-    })
-    toggleDrawer()
-  }
-
   const columns = [
     {
       dataIndex: 'name',
@@ -95,7 +75,13 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading, refreshGroupList
       width: '10%',
       render: (text, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
+          onClick={() =>
+            dispatchModal('D_BUSINESS_DETAIL', {
+              dataId: record.id,
+              orderIds: state.orderIds,
+              group: groupList
+            })
+          }
           className="text-primary cursor-pointer hover:text-hex-967bbd"
         >
           {text}
@@ -109,7 +95,7 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading, refreshGroupList
       render: (text, record) =>
         record.customerId && (
           <span
-            onClick={() => showDrawer(record.customerId, true)}
+            onClick={() => dispatchModal('D_COMPANY_DETAIL', { dataId: record.customerId })}
             className="text-primary cursor-pointer hover:text-hex-967bbd"
           >
             {text}
@@ -237,11 +223,19 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading, refreshGroupList
                 </Tooltip>
               ),
               actions: [
-                <AddBusiness
-                  key="add"
-                  groupList={state.groupList}
-                  reload={() => tRef.current?.reload()}
-                />
+                <Button
+                  type="primary"
+                  className="flex items-center"
+                  onClick={() =>
+                    dispatchModal('M_BUSINESS_ADD', {
+                      groupList: state.groupList,
+                      reload: () => tRef.current?.reload()
+                    })
+                  }
+                >
+                  <Plus className="mr-1" />
+                  商机
+                </Button>
               ]
             }}
           />

+ 42 - 30
src/pages/Customer/Client/components/AddClient/index.jsx

@@ -1,4 +1,4 @@
-import React, { useRef, useState, useEffect } from 'react'
+import React, { useState, useEffect } from 'react'
 import { Form, Row, Col, Button, Modal } from 'antd'
 import LazyCascader from '@/components/LazyCascader'
 import { ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form'
@@ -6,13 +6,21 @@ import { useDispatch, connect } from 'umi'
 import { ChangeCompMap } from '@/pages/Customer/Company/components/ChangeCompany'
 import { isNullOrUnDef } from '@/utils/is'
 import TelephoneFormItem from './TelephoneFormItem'
-import consts from '@/consts'
+import { validateEnum } from '@/pages/Customer/Company/components/AddCompany/CompanyFormItem'
 
 const AddClient = props => {
-  const { visible, onCancel, reload, onConfirm, dataId, dataType, defaultValues, sourceList } =
-    props
+  const {
+    onCancel,
+    reload,
+    onConfirm,
+    dataId,
+    dataType,
+    defaultValues,
+    sourceList,
+    ...resetModalProps
+  } = props
 
-  const formRef = useRef(null)
+  const [formRef] = Form.useForm()
   const layout = {
     layout: 'horizontal',
     labelCol: { flex: '100px' }
@@ -32,45 +40,54 @@ const AddClient = props => {
     if (!changedValues) return
     if ('clientName' in changedValues) {
       if (!changedValues.clientName || changedValues.clientName?.length === 1) {
-        formRef.current?.setFieldsValue({ niceName: '' })
+        formRef?.setFieldsValue({ niceName: '' })
         return
       }
       const [lastName, ...firstName] = changedValues.clientName.split('')
       const newClientName = `${lastName}(${firstName.join('')})工:`
-      formRef.current?.setFieldsValue({ niceName: newClientName })
+      formRef?.setFieldsValue({ niceName: newClientName })
     }
     if ('qq' in changedValues) {
       if (!changedValues.qq) {
-        formRef.current?.setFieldsValue({ email: '' })
+        formRef?.setFieldsValue({ email: '' })
         return
       }
-      formRef.current?.setFieldsValue({ email: `${changedValues.qq}@qq.com` })
+      formRef?.setFieldsValue({ email: `${changedValues.qq}@qq.com` })
     }
   }
 
   const handleOnOk = () => {
-    formRef.current?.validateFields().then(async values => {
-      try {
-        await onConfirm(values)
-        if (code === consts.RET_CODE.SUCCESS) {
-          formRef.current?.resetFields()
-          setValidStatusFtl('')
-          !isNullOrUnDef(reload) && reload()
-          onCancel()
+    formRef
+      ?.validateFields()
+      .then(async values => {
+        try {
+          const success = await onConfirm(values)
+          if (success) {
+            !isNullOrUnDef(reload) && reload()
+            formRef?.resetFields()
+            setTimeout(() => {
+              setValidStatusFtl('')
+              onCancel()
+            }, 80)
+          }
+        } catch (error) {}
+      })
+      .catch(({ values }) => {
+        if ('telephone' in values && !values.telephone) {
+          setValidStatusFtl(validateEnum.Error)
         }
-      } catch (error) {}
-    })
+      })
   }
 
   return (
     <Modal
-      width="42vw"
-      visible={visible}
+      {...resetModalProps}
       onCancel={onCancel}
+      width="43vw"
       title="添加客户"
       footer={
         <div>
-          <Button type="default" className="ml-2" onClick={onCancel}>
+          <Button type="default" className="mr-2" onClick={onCancel}>
             取消
           </Button>
           <Button type="primary" onClick={handleOnOk}>
@@ -79,14 +96,14 @@ const AddClient = props => {
           {dataId ? (
             <Button
               type="primary"
-              key="2"
+              className="ml-2"
               onClick={() => {
                 setShowDataItem(true)
                 const values = {}
                 if (dataType === ChangeCompMap.BUSINESS.key) {
                   values.businessId = dataId
                 }
-                formRef.current?.setFieldsValue(values)
+                formRef?.setFieldsValue(values)
                 handleOnOk()
               }}
             >
@@ -96,12 +113,7 @@ const AddClient = props => {
         </div>
       }
     >
-      <Form
-        {...layout}
-        formRef={formRef}
-        onValuesChange={handleChange}
-        initialValues={defaultValues}
-      >
+      <Form {...layout} form={formRef} onValuesChange={handleChange} initialValues={defaultValues}>
         {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
         <ProFormText
           name="clientName"

+ 65 - 65
src/pages/Customer/Client/components/ClientDetail/AddRecord.jsx

@@ -1,14 +1,12 @@
-import React, { useRef, useState } from 'react'
-import { Form, Button, Radio, DatePicker, Switch } from 'antd'
+import React, { useState } from 'react'
+import { Form, Radio, DatePicker, Switch, Modal } from 'antd'
 import { dayjsFormat } from '@/utils/utils'
-import { Plus } from '@icon-park/react'
 import dayjs from 'dayjs'
-import ModalDragForm from '@/components/Modal/src/components/ModalDragForm'
 import { ProFormTextArea } from '@ant-design/pro-form'
 
 const AddRecord = props => {
-  const formRef = useRef(null)
-  const { onConfirm } = props
+  const [formRef] = Form.useForm()
+  const { onConfirm, ...resetModalProps } = props
   const [showExtraItem, setShowExtraItem] = useState(false)
 
   const onChange = value => {
@@ -20,67 +18,69 @@ const AddRecord = props => {
   }
 
   return (
-    <ModalDragForm
-      modalProps={{ zIndex: 1003, getContainer: false }}
-      layout="vertical"
+    <Modal
+      {...resetModalProps}
       title="添加服务记录"
-      formRef={formRef}
-      onVisibleChange={e => !e && onChange(e)}
-      trigger={
-        <Button type="primary" ghost size="small" className="mr-1">
-          <Plus className="mr-1" /> 添加服务记录
-        </Button>
-      }
-      onFinish={async values => {
-        const newVal = { ...values }
-        formRef.current?.resetFields()
-        if (values.date) {
-          newVal.date = dayjsFormat(values.date, 'YYYY-MM-DD')
-        }
-        if (values.remindTime) {
-          newVal.remindTime = dayjsFormat(values.remindTime, 'YYYY-MM-DD')
-        }
-        await onConfirm(newVal)
+      onOk={() => {
+        formRef?.validateFields().then(async values => {
+          const newVal = { ...values }
+          formRef.current?.resetFields()
+          if (values.date) {
+            newVal.date = dayjsFormat(values.date, 'YYYY-MM-DD')
+          }
+          if (values.remindTime) {
+            newVal.remindTime = dayjsFormat(values.remindTime, 'YYYY-MM-DD')
+          }
+          const isSuccess = await onConfirm(newVal)
+          isSuccess && resetModalProps.onCancel()
+        })
+      }}
+    >
+      <Form layout="vertical" form={formRef}>
+        <Form.Item
+          name="status"
+          label="服务类型"
+          rules={[{ required: true, message: '请选择类型' }]}
+        >
+          <Radio.Group>
+            <Radio value={1}>上门服务</Radio>
+            <Radio value={2}>电话拜访</Radio>
+            <Radio value={3}>其他事项</Radio>
+            <Radio value={4}>在线服务</Radio>
+          </Radio.Group>
+        </Form.Item>
+        <Form.Item
+          name="date"
+          label="服务日期"
+          initialValue={dayjs(new Date())}
+          rules={[{ required: true, message: '请选择服务日期' }]}
+        >
+          <DatePicker style={{ width: '100%' }} />
+        </Form.Item>
+        <ProFormTextArea
+          name="mark"
+          label="内容"
+          rules={[{ required: true, message: '请输入服务内容' }]}
+        />
 
-        return true
-      }}>
-      <Form.Item name="status" label="服务类型" rules={[{ required: true, message: '请选择类型' }]}>
-        <Radio.Group>
-          <Radio value={1}>上门服务</Radio>
-          <Radio value={2}>电话拜访</Radio>
-          <Radio value={3}>其他事项</Radio>
-          <Radio value={4}>在线服务</Radio>
-        </Radio.Group>
-      </Form.Item>
-      <Form.Item
-        name="date"
-        label="服务日期"
-        initialValue={dayjs(new Date())}
-        rules={[{ required: true, message: '请选择服务日期' }]}>
-        <DatePicker style={{ width: '100%' }} />
-      </Form.Item>
-      <ProFormTextArea
-        name="mark"
-        label="内容"
-        rules={[{ required: true, message: '请输入服务内容' }]}
-      />
-
-      <div className="pb-5">
-        <Switch onChange={onChange} checked={showExtraItem} />
-        <span className="ml-2">添加备忘录</span>
-      </div>
-      {showExtraItem ? (
-        <>
-          <Form.Item
-            name="remindTime"
-            label="备忘日期"
-            rules={[{ required: true, message: '请选择备忘日期' }]}>
-            <DatePicker style={{ width: '100%' }} disabledDate={disabledDate} />
-          </Form.Item>
-          <ProFormTextArea name="remarks" label="备忘内容" />
-        </>
-      ) : null}
-    </ModalDragForm>
+        <div className="pb-5">
+          <Switch onChange={onChange} checked={showExtraItem} />
+          <span className="ml-2">添加备忘录</span>
+        </div>
+        {showExtraItem ? (
+          <>
+            <Form.Item
+              name="remindTime"
+              label="备忘日期"
+              rules={[{ required: true, message: '请选择备忘日期' }]}
+            >
+              <DatePicker style={{ width: '100%' }} disabledDate={disabledDate} />
+            </Form.Item>
+            <ProFormTextArea name="remarks" label="备忘内容" />
+          </>
+        ) : null}
+      </Form>
+    </Modal>
   )
 }
 

+ 25 - 35
src/pages/Customer/Client/components/ClientDetail/TabList.jsx

@@ -1,65 +1,47 @@
-import { message, Tabs, Typography } from 'antd'
+import { Button, message, Tabs, Typography } from 'antd'
 import React, { useEffect, useState, useRef } from 'react'
 import consts from '@/consts'
 import { apiAddService } from '@/services/customer'
-import LocksDetail from '@/pages/Product/Lock/LockStore/components/LocksDetail'
-import { useModal } from '@/components/Modal'
-import AddRecord from './AddRecord'
 import { useDispatch } from 'dva'
 import ProTable from '@ant-design/pro-table'
 import { renderBadge } from '@/pages/Workbench/Dashboard/components/RatioPanels'
 import { longleSellStatusNum, longlePreserveStatusNum } from '@/pages/Product/Lock/LockStore/index'
 import { ProductLabel } from '@/pages/Product/Lock/LockStore/index'
+import { useModal } from '@/components/ModalStore'
+import { Plus } from '@icon-park/react'
 
 const ContanctTabList = ({ clientId, software }) => {
-  // console.log(clientId)
   const { Text } = Typography
   const dispatch = useDispatch()
-  const { toggleDrawer, setDrawerProps } = useModal()
+  const dispatchModal = useModal()
   const [state, setState] = useState({
     params: {},
     visible: false
   })
   const [clientHeight] = useState((document.body.clientHeight - 48 - 92 - 64 - 120) / 2)
   const tRef = useRef()
-  // 展示软件锁drawer
-  const showLongleDrawer = id => {
-    toggleDrawer()
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <LocksDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
+
   const columns = [
     {
       title: '锁号',
       dataIndex: 'keyNum',
       width: 90,
       render: (clientName, record) => (
-        <>
+        <span
+          onClick={() => dispatchModal('D_LOCK_DETAIL', { dataId: record.id })}
+          className={[
+            'cursor-pointer hover:text-hex-967bbd',
+            record.preserveStatus === 3 ? null : 'text-primary'
+          ].join(' ')}
+        >
           {record.preserveStatus === 3 ? (
             <Text delete type="secondary">
-              <span
-                onClick={() => showLongleDrawer(record.id)}
-                className="cursor-pointer hover:text-hex-967bbd">
-                {clientName}
-              </span>
+              {clientName}
             </Text>
           ) : (
-            <span
-              onClick={() => showLongleDrawer(record.id)}
-              className="text-primary cursor-pointer hover:text-hex-967bbd">
-              {clientName}
-            </span>
+            clientName
           )}
-        </>
+        </span>
       )
     },
     {
@@ -151,7 +133,7 @@ const ContanctTabList = ({ clientId, software }) => {
       type: 'refresh/commitAction',
       payload: 'client'
     })
-    // await initData()
+    return code === consts.RET_CODE.SUCCESS
   }
   useEffect(() => {
     setState({ ...state, params: { ...state.params, clientId } })
@@ -192,7 +174,15 @@ const ContanctTabList = ({ clientId, software }) => {
         </Tabs>
       </div>
       <div className="sheet-btns pl-15px pt-15px :not-first:ml-1">
-        <AddRecord onConfirm={handleAddService} />
+        <Button
+          type="primary"
+          ghost
+          size="small"
+          className="mr-1"
+          onClick={() => dispatchModal('M_ADD_RECORD', { onConfirm: handleAddService })}
+        >
+          <Plus className="mr-1" /> 添加服务记录
+        </Button>
       </div>
     </div>
   )

+ 3 - 2
src/pages/Customer/Client/components/ClientDetail/index.jsx

@@ -17,7 +17,8 @@ const ContactDetail = props => {
     dispatch,
     updateKey = 'client',
     dataId = '',
-    orderIds = []
+    orderIds = [],
+    ...resetDrawerProps
   } = props
   const shouldUpdate = refresh[updateKey] || false
   const [state, setState] = useState({
@@ -56,7 +57,7 @@ const ContactDetail = props => {
   }, [visible])
 
   return (
-    <Drawer visible={visible} onClose={onClose} className="zh-drawer">
+    <Drawer {...resetDrawerProps} visible={visible} onClose={onClose} className="zh-drawer">
       <Spin spinning={state.loading}>
         <div className="sheet-box">
           <Row>

+ 17 - 17
src/pages/Customer/Client/components/ConnectClient/index.jsx

@@ -1,23 +1,22 @@
-import { Input, Button, Spin, message, Popconfirm } from 'antd'
+import { Input, Button, Spin, message, Popconfirm, Modal } from 'antd'
 import React, { useState, useEffect, useRef } from 'react'
 import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
 import { SearchOutlined } from '@ant-design/icons'
 import { useDebounceFn } from 'ahooks'
-import { useDispatch } from 'dva'
 import { apiAddClient, apiChangeClient, queryClient } from '@/services/customer'
 import consts from '@/basic/consts'
 import { formatValues } from '@/components/LazyCascader'
 import AddClient from '../AddClient'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
 
 const ConnectClient = ({
+  onCancel,
   dataId,
   onSelect,
   preUrl = 'client',
   showFooter = true,
-  otherParams = {}
+  otherParams = {},
+  ...resetModalProps
 }) => {
-  const dispatch = useDispatch()
   const scrollRef = useRef()
   const [state, setState] = useState({
     laoding: true,
@@ -60,11 +59,6 @@ const ConnectClient = ({
   }
 
   const { run: handleInputChange } = useDebounceFn(onChange)
-  const closeModal = () => {
-    dispatch({
-      type: 'single/changeModal'
-    })
-  }
 
   const addConfirm = async values => {
     const payload = formatValues(values)
@@ -73,7 +67,7 @@ const ConnectClient = ({
       if (Object.hasOwnProperty.call(values, `${preUrl}Id`)) {
         message.success('新增成功并且绑定成功')
         onSelect(values.name)
-        closeModal()
+        onCancel()
       } else {
         message.success(msg)
         initData()
@@ -87,7 +81,7 @@ const ConnectClient = ({
     if (code === consts.RET_CODE.SUCCESS) {
       // message.success('关联成功')
       onSelect()
-      closeModal()
+      onCancel()
     }
   }
 
@@ -108,7 +102,10 @@ const ConnectClient = ({
   }
 
   return (
-    <CustomModal
+    <Modal
+      {...resetModalProps}
+      onCancel={onCancel}
+      width="50vw"
       title={
         <Input
           prefix={<SearchOutlined />}
@@ -116,12 +113,14 @@ const ConnectClient = ({
           placeholder="输入客户名称搜索"
           onChange={handleInputChange}
         />
-      }>
+      }
+    >
       <div
         className={styles.modalContent}
         ref={scrollRef}
         onScroll={handleListScroll}
-        style={{ paddingBottom: 0 }}>
+        style={{ paddingBottom: 0 }}
+      >
         <Spin spinning={state.laoding}>
           {state.client.map(item => (
             <div key={item.id} className={styles.card}>
@@ -134,7 +133,8 @@ const ConnectClient = ({
                   title="确认选择ta"
                   onConfirm={() => connectClient(item.id)}
                   okText="确认"
-                  cancelText="取消">
+                  cancelText="取消"
+                >
                   <Button type="primary" size="small">
                     选择ta
                   </Button>
@@ -156,7 +156,7 @@ const ConnectClient = ({
           />
         </div>
       ) : null}
-    </CustomModal>
+    </Modal>
   )
 }
 

+ 1 - 0
src/pages/Customer/Client/index.jsx

@@ -125,6 +125,7 @@ const Client = props => {
       message.success(msg)
       initData()
     }
+    return code === consts.RET_CODE.SUCCESS
   }
 
   const columns = [

+ 93 - 74
src/pages/Customer/Company/components/AddCompany/index.jsx

@@ -1,23 +1,26 @@
-import React, { useState, useRef, useEffect } from 'react'
-import { Form, Row, Col, Button } from 'antd'
+import React, { useState, useEffect } from 'react'
+import { Form, Row, Col, Button, Modal } from 'antd'
 import LazyCascader from '@/components/LazyCascader'
-import { ProFormText, ProFormCheckbox, ProFormTextArea, ModalForm } from '@ant-design/pro-form'
-import { Plus } from '@icon-park/react'
+import { ProFormText, ProFormCheckbox, ProFormTextArea } from '@ant-design/pro-form'
 import { connect } from 'umi'
 import { ChangeCompMap } from '../ChangeCompany'
 import { isNullOrUnDef } from '@/utils/is'
 import CompanyFormItem from './CompanyFormItem'
-
+import { validateEnum } from './CompanyFormItem'
 const AddCompanyModal = ({
+  onCancel,
   reload,
   dataId,
   dataType,
   onConfirm,
   dispatch,
   natures,
-  defaultValue
+  defaultValue,
+  ...resetModalProps
 }) => {
-  const formRef = useRef()
+  const [formRef] = Form.useForm()
+  const [showDataItem, setShowDataItem] = useState(false)
+
   const layout = {
     layout: 'horizontal',
     labelCol: { flex: '100px' }
@@ -31,7 +34,7 @@ const AddCompanyModal = ({
           payload: defaultValue.districtIds
         })
       }
-      formRef.current.setFieldsValue(defaultValue)
+      formRef?.setFieldsValue(defaultValue)
     }
     const getNatures = () => {
       dispatch({
@@ -40,20 +43,47 @@ const AddCompanyModal = ({
     }
     !natures.length && getNatures()
   }, [])
-  const [showDataItem, setShowDataItem] = useState(false)
+
+  const handleOnOk = () => {
+    formRef
+      ?.validateFields()
+      .then(async values => {
+        try {
+          const successs = await onConfirm(values)
+          if (successs) {
+            !isNullOrUnDef(reload) && reload()
+            formRef?.resetFields()
+            setTimeout(() => {
+              setValidStatusFcn('')
+              onCancel()
+            }, 80)
+          }
+        } catch (error) {}
+      })
+      .catch(({ values }) => {
+        if ('companyName' in values && !values.companyName) {
+          setValidStatusFcn(validateEnum.Error)
+        }
+      })
+  }
   return (
-    <ModalForm
-      // modalProps={{ zIndex: 1003, getContainer: false }}
-      formRef={formRef}
+    <Modal
+      {...resetModalProps}
+      onCancel={onCancel}
       title="添加新单位"
-      {...layout}
-      submitter={{
-        render: ({ submit }, defaultDoms) => [
-          ...defaultDoms,
-          dataId ? (
+      width="43vw"
+      footer={
+        <div>
+          <Button type="default" className="mr-2" onClick={onCancel}>
+            取消
+          </Button>
+          <Button type="primary" onClick={handleOnOk}>
+            确认
+          </Button>
+          {dataId ? (
             <Button
               type="primary"
-              key="2"
+              className="ml-2"
               onClick={() => {
                 setShowDataItem(true)
                 const values = {}
@@ -63,68 +93,57 @@ const AddCompanyModal = ({
                 if (dataType === ChangeCompMap.BUSINESS.key) {
                   values.businessId = dataId
                 }
-                formRef.current && formRef.current.setFieldsValue(values)
-                submit()
+                formRef && formRef.setFieldsValue(values)
+                handleOnOk()
               }}
             >
               添加并关联
             </Button>
-          ) : null
-        ]
-      }}
-      trigger={
-        <Button type="primary">
-          <Plus className="mr-1" />
-          单位
-        </Button>
+          ) : null}
+        </div>
       }
-      onFinish={async values => {
-        await onConfirm(values)
-        formRef.current?.resetFields()
-        setValidStatusFcn('')
-        !isNullOrUnDef(reload) && reload()
-        return true
-      }}
     >
-      <Form.Item
-        name="companyName"
-        label="单位名称"
-        validateStatus={validStatusFcn}
-        hasFeedback
-        rules={[{ required: true, message: '请输入单位全称' }]}
-      >
-        <CompanyFormItem validateFn={status => setValidStatusFcn(status)} />
-      </Form.Item>
-      {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
-      <Form.Item
-        name="districtIds"
-        label="单位地区"
-        rules={[{ required: true, message: '请选择地区' }]}
-      >
-        <LazyCascader showFooter={true} />
-      </Form.Item>
-      <ProFormText
-        name="phone"
-        label="单位电话"
-        placeholder="请输入单位电话"
-        rules={[{ required: true, message: '请输入单位电话' }]}
-      />
-      <ProFormCheckbox.Group name="natureIds" label="单位性质" options={natures} />
-      <ProFormText name="address" label="单位地址" placeholder="" />
-      <Row>
-        <Col span={12}>
-          <ProFormText name="mail" label="单位邮箱" placeholder="" />
-          {/* <ProFormText name="fax" label="单位传真" placeholder="" /> */}
-          <ProFormText name="ride" label="乘车路线" placeholder="" />
-          <ProFormText name="stay" label="参考住宿" placeholder="" />
-        </Col>
-        <Col span={12}>
-          <ProFormText name="webservice" label="网址" placeholder="" />
-          <ProFormText name="landmarks" label="地标建筑" placeholder="" />
-          <ProFormTextArea name="remarks" label="备注" placeholder="" />
-        </Col>
-      </Row>
-    </ModalForm>
+      <Form {...layout} form={formRef}>
+        <Form.Item
+          name="companyName"
+          label="单位名称"
+          validateStatus={validStatusFcn}
+          hasFeedback
+          rules={[{ required: true, message: '请输入单位全称' }]}
+        >
+          <CompanyFormItem validateFn={status => setValidStatusFcn(status)} />
+        </Form.Item>
+        {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
+        <Form.Item
+          name="districtIds"
+          label="单位地区"
+          rules={[{ required: true, message: '请选择地区' }]}
+        >
+          <LazyCascader showFooter={true} />
+        </Form.Item>
+        <ProFormText
+          name="phone"
+          label="单位电话"
+          placeholder="请输入单位电话"
+          rules={[{ required: true, message: '请输入单位电话' }]}
+        />
+        <ProFormCheckbox.Group name="natureIds" label="单位性质" options={natures} />
+        <ProFormText name="address" label="单位地址" placeholder="" />
+        <Row>
+          <Col span={12}>
+            <ProFormText name="mail" label="单位邮箱" placeholder="" />
+            {/* <ProFormText name="fax" label="单位传真" placeholder="" /> */}
+            <ProFormText name="ride" label="乘车路线" placeholder="" />
+            <ProFormText name="stay" label="参考住宿" placeholder="" />
+          </Col>
+          <Col span={12}>
+            <ProFormText name="webservice" label="网址" placeholder="" />
+            <ProFormText name="landmarks" label="地标建筑" placeholder="" />
+            <ProFormTextArea name="remarks" label="备注" placeholder="" />
+          </Col>
+        </Row>
+      </Form>
+    </Modal>
   )
 }
 

+ 0 - 1
src/pages/Customer/Company/components/ChangeCompany/index.jsx

@@ -62,7 +62,6 @@ const ChangeCompanyInput = props => {
 
   const removeCustomer = () => {
     Modal.confirm({
-      zIndex: 1002,
       title: '确认移除',
       content: (
         <p>

+ 18 - 71
src/pages/Customer/Company/components/CompanyDetail/TabList.jsx

@@ -1,6 +1,4 @@
 /* eslint-disable no-dupe-keys */
-import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
-import LocksDetail from '@/pages/Product/Lock/LockStore/components/LocksDetail'
 import React, { useRef, useState } from 'react'
 import { Tabs, message, Dropdown, Menu, Typography, Button } from 'antd'
 import { Table } from '@arco-design/web-react'
@@ -12,7 +10,6 @@ import consts from '@/consts'
 import ProTable from '@ant-design/pro-table'
 import { useDispatch } from 'umi'
 import AddRecord from '@/pages/Customer/Client/components/ClientDetail/AddRecord'
-import Detail from '@/pages/Customer/Business/components/BusinessDetail'
 import SyncClient from './SyncClient'
 import { longleSellStatusNum, longlePreserveStatusNum } from '@/pages/Product/Lock/LockStore/index'
 import { renderBadge } from '@/pages/Workbench/Dashboard/components/RatioPanels'
@@ -20,6 +17,7 @@ import { DownOutlined } from '@ant-design/icons'
 import { ProductLabel } from '@/pages/Product/Lock/LockStore/index'
 import { useModal } from '@/components/ModalStore'
 import { Plus } from '@icon-park/react'
+const { Text } = Typography
 
 const CompanyTabList = ({
   initData,
@@ -34,59 +32,12 @@ const CompanyTabList = ({
   const dispatchModal = useModal()
   const { TabPane } = Tabs
   const tRef = useRef(null)
-  const { Text } = Typography
   const [state, setState] = useState({
     params: {},
     visible: false
   })
   const [clientHeight] = useState((document.body.clientHeight - 48 - 92 - 64 - 120) / 2)
-  // console.log(clientHeight)
-  // 展示drawer
-  const showDrawer = id => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <ContactDetail dataId={id} />
-    })
-    toggleDrawer(true)
-  }
-  // 展示软件锁drawer
-  const showLongleDrawer = id => {
-    toggleDrawer()
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <LocksDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer(true)
-  }
-  // 展示商机详情
-  const showDrawerBusiness = (id, isCompany = false) => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: isCompany ? (
-        <CompanyDetail dataId={id} />
-      ) : (
-        <Detail dataId={id} orderIds={state.orderIds} />
-      )
-    })
-    toggleDrawer(true)
-  }
+
   const changePriority = async (key, clientId) => {
     const { code = -1 } = await updateClient({
       id: clientId,
@@ -158,10 +109,7 @@ const CompanyTabList = ({
           value: item
         }))
       ),
-      onFilter: (value, item) => item.department === value,
-      onFilterDropdownVisibleChange: visible => {
-        console.log(visible)
-      }
+      onFilter: (value, item) => item.department === value
     },
     {
       title: '姓名',
@@ -172,7 +120,10 @@ const CompanyTabList = ({
       },
       render: (clientName, record) => (
         <div className="text-primary hover:text-[#967bbd] line-clamp-1">
-          <span onClick={() => showDrawer(record.id)} className="cursor-pointer ">
+          <span
+            onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.id })}
+            className="cursor-pointer "
+          >
             {clientName}
           </span>
         </div>
@@ -214,25 +165,21 @@ const CompanyTabList = ({
       dataIndex: 'keyNum',
       width: 90,
       render: (clientName, record) => (
-        <>
+        <span
+          onClick={() => dispatchModal('D_LOCK_DETAIL', { dataId: record.id })}
+          className={[
+            'cursor-pointer hover:text-hex-967bbd',
+            record.preserveStatus === 3 ? null : 'text-primary'
+          ].join(' ')}
+        >
           {record.preserveStatus === 3 ? (
             <Text delete type="secondary">
-              <span
-                onClick={() => showLongleDrawer(record.id)}
-                className="cursor-pointer hover:text-hex-967bbd"
-              >
-                {clientName}
-              </span>
+              {clientName}
             </Text>
           ) : (
-            <span
-              onClick={() => showLongleDrawer(record.id)}
-              className="text-primary cursor-pointer hover:text-hex-967bbd"
-            >
-              {clientName}
-            </span>
+            clientName
           )}
-        </>
+        </span>
       )
     },
     {
@@ -312,7 +259,7 @@ const CompanyTabList = ({
       width: 185,
       render: (text, record) => (
         <span
-          onClick={() => showDrawerBusiness(record.id)}
+          onClick={() => dispatchModal('D_BUSINESS_DETAIL', { dataId: record.id })}
           className="text-primary cursor-pointer hover:text-[#967bbd]"
         >
           {text}

+ 9 - 2
src/pages/Customer/Company/components/CompanyDetail/index.jsx

@@ -10,7 +10,14 @@ import { Up, Down } from '@icon-park/react'
 import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
 
 const CompanyDetail = props => {
-  const { visible, onClose, dispatch, updateKey = 'company', dataId = '', orderIds = [] } = props
+  const {
+    visible,
+    dispatch,
+    updateKey = 'company',
+    dataId = '',
+    orderIds = [],
+    ...resetDrawerProps
+  } = props
   const { [updateKey]: shouldUpdate = false } = useStore()?.getState()?.refresh
   const [state, setState] = useState({
     loading: false,
@@ -45,7 +52,7 @@ const CompanyDetail = props => {
     visible && initData(dataId)
   }, [visible])
   return (
-    <Drawer visible={visible} onClose={onClose} className="zh-drawer">
+    <Drawer {...resetDrawerProps} visible={visible} className="zh-drawer">
       <Spin spinning={state.loading}>
         <div className="sheet-box">
           <Row>

+ 12 - 11
src/pages/Customer/Company/components/ConnectCompany/index.jsx

@@ -3,16 +3,22 @@ import React, { useState, useEffect, useRef } from 'react'
 import styles from './index.less'
 import { SearchOutlined } from '@ant-design/icons'
 import { useDebounceFn } from 'ahooks'
-import { useDispatch, useAccess } from 'umi'
+import { useAccess } from 'umi'
 import AddCompany from '@/pages/Customer/Company/components/AddCompany'
 import { createCustomer, queryCustomers } from '@/services/customer'
 import consts from '@/basic/consts'
 import { formatValues } from '@/components/LazyCascader'
 import { apiChangeCustomer } from '@/services/customer'
 
-const ConnectCompany = ({ visible, onCancel, dataId, onSelect, preUrl, defaultAddibleValue }) => {
+const ConnectCompany = ({
+  onCancel,
+  dataId,
+  onSelect,
+  preUrl,
+  defaultAddibleValue,
+  ...resetModalProps
+}) => {
   const hasAddPerm = useAccess()?.validatePermByType('company_add')
-  const dispatch = useDispatch()
   const scrollRef = useRef()
   const [state, setState] = useState({
     laoding: true,
@@ -53,11 +59,6 @@ const ConnectCompany = ({ visible, onCancel, dataId, onSelect, preUrl, defaultAd
   }
 
   const { run: handleInputChange } = useDebounceFn(onChange)
-  const closeModal = () => {
-    dispatch({
-      type: 'single/changeModal'
-    })
-  }
 
   const addConfirm = async values => {
     const payload = formatValues(values)
@@ -66,7 +67,7 @@ const ConnectCompany = ({ visible, onCancel, dataId, onSelect, preUrl, defaultAd
       if (Object.hasOwnProperty.call(values, `${preUrl}Id`)) {
         message.success('新增成功并且绑定成功')
         onSelect(values.companyName)
-        closeModal()
+        onCancel()
       } else {
         message.success(msg)
         initData()
@@ -79,7 +80,7 @@ const ConnectCompany = ({ visible, onCancel, dataId, onSelect, preUrl, defaultAd
     const { code = -1 } = await apiChangeCustomer(preUrl, { id: dataId, customerId })
     if (code === consts.RET_CODE.SUCCESS) {
       onSelect()
-      closeModal()
+      onCancel()
     }
   }
 
@@ -102,7 +103,7 @@ const ConnectCompany = ({ visible, onCancel, dataId, onSelect, preUrl, defaultAd
 
   return (
     <Modal
-      visible={visible}
+      {...resetModalProps}
       onCancel={onCancel}
       width="60vw"
       title={

+ 31 - 32
src/pages/Customer/Company/index.jsx

@@ -3,19 +3,17 @@ import { Input, Button, message, Tooltip } from 'antd'
 import { connect, useModel, useAccess } from 'umi'
 import consts from '@/consts'
 import { queryCompany, apiAddCompany } from '@/services/customer'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
-import AddCompany from '@/pages/Customer/Company/components/AddCompany'
-import { useModal } from '@/components/Modal'
 import LazyCascader, { formatValues } from '@/components/LazyCascader'
 import PersonLabel from './components/PersonLabel'
 import { TagTypeEnum, TagDataTypeEnum, LabelModeType } from './components/PersonLabel/const'
-import { Add, Down, Check } from '@icon-park/react'
+import { Add, Down, Check, Plus } from '@icon-park/react'
 import { apiBatchLink } from '@/services/customer'
 import styles from './index.less'
 import { generateFilterField, generateSortField } from '@/utils/utils'
 import { PermDataTypeEunm } from './components/PermSelect'
 import BasicTable from '@/components/Table'
 import { getPermAuthCache } from '@/utils/auth'
+import { useModal } from '@/components/ModalStore'
 // import FilterCascader from '@/components/Table/src/components/FilterCascader'
 
 const Company = props => {
@@ -33,7 +31,6 @@ const Company = props => {
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
 
   const hasAddPerm = useAccess()?.validatePermByType('company_add')
-  const { toggleDrawer, setDrawerProps } = useModal()
   const tRef = useRef(null)
 
   const [tagState, setTagState] = useState({
@@ -46,6 +43,7 @@ const Company = props => {
     orderIds: []
   })
 
+  const dispatchModal = useModal()
   useEffect(() => {
     if (!personTags.length) {
       dispatch({
@@ -130,6 +128,7 @@ const Company = props => {
       message.success('新增成功')
       initData()
     }
+    return code === consts.RET_CODE.SUCCESS
   }
   const handleSearch = value => {
     tRef.current.reloadAndRest()
@@ -142,20 +141,6 @@ const Company = props => {
     setState({ ...state, params: { ...state.params, province, city, area } })
   }
 
-  // 展示drawer
-  const showDrawer = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-
   const columns = [
     {
       title: '单位名称',
@@ -165,11 +150,14 @@ const Company = props => {
       fixed: 'left',
       search: false,
       sorter: true,
-      render: (companyName, record) => (
+      render: (text, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
-          {companyName}
+          onClick={() =>
+            dispatchModal('D_COMPANY_DETAIL', { dataId: record.id, orderIds: state.orderIds })
+          }
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
+          {text}
         </span>
       )
     },
@@ -214,7 +202,8 @@ const Company = props => {
             tagType={TagTypeEnum.PERSONTAG}
             tagColumn={TagDataTypeEnum.COMPANY}
             checkCallBack={refreshData}
-            modeType={LabelModeType.column}>
+            modeType={LabelModeType.column}
+          >
             <Add theme="filled" size="20" fill="#868e96" className="cursor-pointer" />
           </PersonLabel>
         </div>
@@ -245,7 +234,8 @@ const Company = props => {
             tagType={TagTypeEnum.TEAMTAG}
             tagColumn={TagDataTypeEnum.COMPANY}
             checkCallBack={refreshData}
-            modeType={LabelModeType.column}>
+            modeType={LabelModeType.column}
+          >
             <Add theme="filled" size="20" fill="#868e96" className="cursor-pointer" />
           </PersonLabel>
         </div>
@@ -413,7 +403,8 @@ const Company = props => {
             tagType={TagTypeEnum.PERSONTAG}
             tagColumn={TagDataTypeEnum.COMPANY}
             checkCallBack={toolbarOptionsChange}
-            modeType={LabelModeType.toolbar}>
+            modeType={LabelModeType.toolbar}
+          >
             {tagState.tagIds.length ? (
               <Button>
                 {tagState.tagIds.map(item => (
@@ -438,7 +429,8 @@ const Company = props => {
             tagType={TagTypeEnum.TEAMTAG}
             tagColumn={TagDataTypeEnum.COMPANY}
             checkCallBack={toolbarOptionsChange}
-            modeType={LabelModeType.toolbar}>
+            modeType={LabelModeType.toolbar}
+          >
             {tagState.tagCooperationIds.length ? (
               <Button>
                 {tagState.tagCooperationIds.map(item => (
@@ -514,11 +506,18 @@ const Company = props => {
               bordered={false}
             />,
             hasAddPerm && (
-              <AddCompany
-                onConfirm={handleAddCompany}
-                key="addCompanyBtn"
-                reload={() => tRef.current?.reload()}
-              />
+              <Button
+                type="primary"
+                onClick={() =>
+                  dispatchModal('M_COMPANY_ADD', {
+                    onConfirm: handleAddCompany,
+                    reload: () => tRef.current?.reload()
+                  })
+                }
+              >
+                <Plus className="mr-1" />
+                单位
+              </Button>
             )
           ]
         }}

+ 18 - 18
src/pages/Hr/Employee/components/EmployeeDetail/index.jsx

@@ -1,5 +1,5 @@
 import React, { useState, useEffect } from 'react'
-import { Col, Row } from 'antd'
+import { Col, Drawer, Row } from 'antd'
 import consts from '@/consts'
 import { connect } from 'umi'
 import EmployeeForm from './Form.jsx'
@@ -8,7 +8,7 @@ import EmployeeTabList from './TabList.jsx'
 import { apiStaffDetail } from '@/services/staff'
 
 const EmployeeDetail = props => {
-  const { dispatch, shouldUpdate, visible, dataId = '' } = props
+  const { visible, onClose, dispatch, shouldUpdate, dataId = '' } = props
   const [state, setState] = useState({
     loading: false,
     staff: {},
@@ -37,24 +37,24 @@ const EmployeeDetail = props => {
     visible && initData(dataId)
   }, [visible])
   return (
-    <div className="sheet-box">
-      <Row>
-        <Col span={12} className="sheet-box-left">
-          <div className="sheet-left-panel pr-4">
-            <EmployeeForm staff={state.staff} />
-          </div>
-        </Col>
-        <Col span={12} className="sheet-box-right">
-          <EmployeeLowerList />
-          <EmployeeTabList log={state.log} />
-        </Col>
-      </Row>
-    </div>
+    <Drawer visible={visible} onClose={onClose} className="zh-drawer">
+      <div className="sheet-box">
+        <Row>
+          <Col span={12} className="sheet-box-left">
+            <div className="sheet-left-panel pr-4">
+              <EmployeeForm staff={state.staff} />
+            </div>
+          </Col>
+          <Col span={12} className="sheet-box-right">
+            <EmployeeLowerList />
+            <EmployeeTabList log={state.log} />
+          </Col>
+        </Row>
+      </div>
+    </Drawer>
   )
 }
 
-// export default EmployeeDetail
-export default connect(({ refresh, single }) => ({
-  visible: single.drawer.visible,
+export default connect(({ refresh }) => ({
   shouldUpdate: refresh.stafflist
 }))(EmployeeDetail)

+ 14 - 16
src/pages/Hr/Employee/components/StaffModal/index.jsx

@@ -1,16 +1,13 @@
 import React, { useState, useEffect, useRef } from 'react'
-import { Input, Button, Spin } from 'antd'
+import { Input, Button, Spin, Modal } from 'antd'
 import consts from '@/basic/consts'
-import { useDispatch } from 'dva'
 import { useDebounceFn } from 'ahooks'
 import { SearchOutlined } from '@ant-design/icons'
 import { queryStaff, apiChangeSupervisor } from '@/services/staff'
 import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
 
-const StaffModal = ({ id, onSelect, postUrl }) => {
+const StaffModal = ({ visible, onCancel, id, onSelect, postUrl }) => {
   const scrollRef = useRef()
-  const dispatch = useDispatch()
   const [state, setState] = useState({
     loading: true,
     list: [],
@@ -52,18 +49,14 @@ const StaffModal = ({ id, onSelect, postUrl }) => {
 
   const { run: handleInputChange } = useDebounceFn(onChange)
 
-  const closeModal = () => {
-    dispatch({
-      type: 'single/changeModal'
-    })
-  }
-
   // 关联上司
   const connectStaff = async dataId => {
     const { code = -1 } = await apiChangeSupervisor(postUrl, { id, dataId })
     if (code === consts.RET_CODE.SUCCESS) {
       onSelect()
-      closeModal()
+      setTimeout(() => {
+        onCancel()
+      }, 80)
     }
   }
 
@@ -83,7 +76,10 @@ const StaffModal = ({ id, onSelect, postUrl }) => {
     }
   }
   return (
-    <CustomModal
+    <Modal
+      visible={visible}
+      onCancel={onCancel}
+      width="43vw"
       title={
         <Input
           prefix={<SearchOutlined />}
@@ -91,12 +87,14 @@ const StaffModal = ({ id, onSelect, postUrl }) => {
           placeholder="输入员工名称搜索"
           onChange={handleInputChange}
         />
-      }>
+      }
+    >
       <div
         className={styles.modalContent}
         ref={scrollRef}
         onScroll={handleListScroll}
-        style={{ paddingBottom: 0 }}>
+        style={{ paddingBottom: 0 }}
+      >
         <Spin spinning={state.loading}>
           {state.list.map(item => (
             <div key={item.id} className={styles.card}>
@@ -114,7 +112,7 @@ const StaffModal = ({ id, onSelect, postUrl }) => {
         </Spin>
         {state.noMore && <div className="text-center text-gray-400 my-4">已到底部</div>}
       </div>
-    </CustomModal>
+    </Modal>
   )
 }
 

+ 31 - 38
src/pages/Product/Lock/LockStore/components/ChangeClient/index.jsx

@@ -1,65 +1,51 @@
 import React from 'react'
 import { Switch, LinkOne } from '@icon-park/react'
-import { useModal } from '@/components/Modal'
 import { Card, Tooltip } from 'antd'
 import consts from '@/basic/consts'
 import { useDispatch } from 'dva'
 import { isEmpty, isNullOrUnDef } from '@/utils/is'
-import ConnectClient from '@/pages/Customer/Client/components/ConnectClient'
-import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
 import styles from './index.less'
+import { useModal } from '@/components/ModalStore'
 
-const ChangeClient = props => {
+const ChangeClient = ({
+  dataSource: { clientName = '', longleId, clientId, actionPayload }
+} = {}) => {
+  const dispatchModal = useModal()
   const dispatch = useDispatch()
-  const { toggleModal, setModalProps, toggleDrawer, setDrawerProps } = useModal()
-  const { clientName = '', longleId, clientId, actionPayload } = props.dataSource
   if (isNullOrUnDef(clientName) || isEmpty(clientName)) return null
+
   const refreshClient = () => {
     dispatch({
       type: 'refresh/commitAction',
       payload: actionPayload
     })
   }
-  const handleConnectCustomer = () => {
-    setModalProps({
-      zIndex: 1002,
-      width: '60vw',
-      modalRender: () => (
-        <ConnectClient
-          onSelect={refreshClient}
-          dataId={longleId}
-          preUrl={actionPayload}
-          showFooter={false}
-        />
-      ),
-      onCancel: () => toggleModal()
-    })
-    toggleModal(true)
-  }
+
   const notValueRender = (
-    <div onClick={handleConnectCustomer} className={styles.notCompanyContent}>
+    <div
+      onClick={() =>
+        dispatchModal('M_CONNECT_CLIENT', {
+          onSelect: refreshClient,
+          dataId: longleId,
+          preUrl: actionPayload,
+          showFooter: false
+        })
+      }
+      className={styles.notCompanyContent}
+    >
       <LinkOne size="14" />
       <span className="ml-5px">关联客户</span>
     </div>
   )
-  const handleCompanyClick = () => {
-    toggleDrawer()
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <ContactDetail dataId={clientId} />
-    })
-    toggleDrawer()
-  }
+
   const normalValueRender = (
     <Card size="small">
       <div className="flex justify-between">
         {/* <div className={styles.nameContent} onClick={handleCompanyClick}> */}
-        <div className={styles.nameContent} onClick={handleCompanyClick}>
+        <div
+          className={styles.nameContent}
+          onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: clientId })}
+        >
           {clientName}
         </div>
         <div className="max-w-55px">
@@ -67,7 +53,14 @@ const ChangeClient = props => {
             placement="right"
             title="更换客户"
             className="ml-5px"
-            onClick={handleConnectCustomer}
+            onClick={() =>
+              dispatchModal('M_CONNECT_CLIENT', {
+                onSelect: refreshClient,
+                dataId: longleId,
+                preUrl: actionPayload,
+                showFooter: false
+              })
+            }
           >
             <span className={styles.switchIcon}>
               <Switch />

src/pages/Product/Lock/LockStore/components/LocksDetail/Form.jsx → src/pages/Product/Lock/LockStore/components/LockDetail/Form.jsx


src/pages/Product/Lock/LockStore/components/LocksDetail/LowerList.jsx → src/pages/Product/Lock/LockStore/components/LockDetail/LowerList.jsx


+ 59 - 65
src/pages/Product/Lock/LockStore/components/LocksDetail/LockModal.jsx

@@ -1,6 +1,5 @@
 import React, { useState, useEffect, useRef } from 'react'
 import { Modal, Form, Select, Input, Spin, Button, Radio, Popconfirm, message } from 'antd'
-import styles from './index.less'
 import { SearchOutlined } from '@ant-design/icons'
 import { queryClient } from '@/services/customer'
 import { queryLock } from '@/services/product'
@@ -8,9 +7,8 @@ import consts from '@/basic/consts'
 import { useDebounceFn } from 'ahooks'
 import { apiSoftwareAddLonglelog, apiReceiveLock } from '@/services/product'
 import { useDispatch, connect } from 'umi'
-// import { createUid } from '@/utils/utils'
-// import DragIniter from '@/components/Modal/src/components/DragIniter'
 import { ProFormTextArea } from '@ant-design/pro-form'
+import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
 
 export const lockTypeEnum = {
   REMARK: 0, // 备注
@@ -20,32 +18,32 @@ export const lockTypeEnum = {
   RECEIVE: 5, // 接收
   SALE: 6
 }
+const modalTitleEnum = {
+  1: '升级软件锁',
+  0: '备注信息',
+  3: '确认收回',
+  5: '确认接收'
+}
+const placeholderEnum = {
+  6: '搜索客户(姓名、手机、QQ、公司名称)',
+  2: '输入新锁号'
+}
 
-const LockModal = props => {
-  const modalTitleEnum = {
-    1: '升级软件锁',
-    0: '备注信息',
-    3: '确认收回',
-    5: '确认接收'
-  }
-  const placeholderEnum = {
-    6: '搜索客户(姓名、手机、QQ、公司名称)',
-    2: '输入新锁号'
-  }
-  const [form] = Form.useForm()
-  const dispatch = useDispatch()
-  const scrollRef = useRef()
+const OpreateLock = props => {
   const {
-    visible,
-    onCancel,
     onConfirm,
+    onCancel,
     loading,
     type,
     longleId,
     keyNum,
     prodList,
-    upgradeProduct
+    upgradeProduct,
+    ...resetModalProps
   } = props
+  const [form] = Form.useForm()
+  const dispatch = useDispatch()
+  const scrollRef = useRef()
   const layout = {
     layout: 'vertical'
   }
@@ -133,7 +131,7 @@ const LockModal = props => {
 
   const { run: handleInputChange } = useDebounceFn(onChange)
   useEffect(() => {
-    if (visible) {
+    if (resetModalProps.visible) {
       if (type === lockTypeEnum.CHANGE) {
         initData({ current: 1, pageSize: 10 })
         return
@@ -147,18 +145,17 @@ const LockModal = props => {
         form.setFieldsValue({ longleId })
       }
     }
-  }, [visible, type])
+  }, [resetModalProps.visible, type])
 
   const handleonOk = () => {
     form.validateFields().then(async values => {
-      // console.log('values', values)
       if (type === lockTypeEnum.RECEIVE) {
         const { code = -1 } = await apiReceiveLock({
           longleId
         })
         if (code === consts.RET_CODE.SUCCESS) {
           message.success('接收成功')
-          onCancel()
+          resetModalProps.onCancel()
         }
       } else {
         onConfirm({ ...values, preserveStatus: type })
@@ -239,7 +236,8 @@ const LockModal = props => {
 
   return (
     <Modal
-      getContainer={false}
+      onCancel={onCancel}
+      {...resetModalProps}
       title={
         modalTitleEnum[type] ?? (
           <Input
@@ -251,9 +249,6 @@ const LockModal = props => {
           />
         )
       }
-      visible={visible}
-      confirmLoading={loading}
-      onCancel={onCancel}
       width={800}
       footer={
         type !== lockTypeEnum.UPDATE &&
@@ -269,7 +264,8 @@ const LockModal = props => {
             </Button>
           </div>
         )
-      }>
+      }
+    >
       {type === lockTypeEnum.SALE ? (
         <div className="text-center mb-6">
           <Radio.Group value={state.sellStatus} buttonStyle="solid" onChange={checkGroupOnChange}>
@@ -284,7 +280,8 @@ const LockModal = props => {
           className={styles.modalContainer}
           ref={scrollRef}
           onScroll={handleListScroll}
-          style={{ paddingBottom: 0 }}>
+          style={{ paddingBottom: 0 }}
+        >
           <div className={styles.modalContent}>
             <Spin spinning={state.loading}>
               {type === lockTypeEnum.SALE &&
@@ -299,7 +296,8 @@ const LockModal = props => {
                         title="确认选择ta"
                         onConfirm={() => connectClient(item.id)}
                         okText="确认"
-                        cancelText="取消">
+                        cancelText="取消"
+                      >
                         <Button type="primary" size="small">
                           选择ta
                         </Button>
@@ -317,7 +315,8 @@ const LockModal = props => {
                         title="确认选择ta"
                         onConfirm={() => connectLongle(item.id)}
                         okText="确认"
-                        cancelText="取消">
+                        cancelText="取消"
+                      >
                         <Button type="primary" size="small">
                           更换
                         </Button>
@@ -333,41 +332,36 @@ const LockModal = props => {
 
       <Form {...layout} form={form}>
         {type === lockTypeEnum.UPDATE ? (
-          <>
-            <Form.Item
-              name="product"
-              label="新增产品"
-              required
-              rules={[
-                () => ({
-                  validator(_, value) {
-                    if (!value) {
-                      return Promise.reject(new Error('请选择产品'))
-                    }
-                    // 表示该产品已升级
-                    if (value && upgradeProduct.includes(value)) {
-                      return Promise.reject(new Error('该产品已存在,无法升级'))
-                    }
-                    return Promise.resolve(value)
+          <Form.Item
+            name="product"
+            label="新增产品"
+            required
+            rules={[
+              () => ({
+                validator(_, value) {
+                  if (!value) {
+                    return Promise.reject(new Error('请选择产品'))
                   }
-                })
-              ]}>
-              <Select
-                placeholder="请选择产品"
-                onDropdownVisibleChange={async e => {
-                  e && !prodList?.length && (await fetchSoftProducts())
-                }}
-                options={prodList.map(item => ({ value: item.title }))}
-              />
-            </Form.Item>
-          </>
+                  // 表示该产品已升级
+                  if (value && upgradeProduct.includes(value)) {
+                    return Promise.reject(new Error('该产品已存在,无法升级'))
+                  }
+                  return Promise.resolve(value)
+                }
+              })
+            ]}
+          >
+            <Select
+              placeholder="请选择产品"
+              onDropdownVisibleChange={async e => {
+                e && !prodList?.length && (await fetchSoftProducts())
+              }}
+              options={prodList.map(item => ({ value: item.title }))}
+            />
+          </Form.Item>
         ) : null}
 
-        {type === lockTypeEnum.REMARK ? (
-          <>
-            <ProFormTextArea name="mark" label="备注" />
-          </>
-        ) : null}
+        {type === lockTypeEnum.REMARK ? <ProFormTextArea name="mark" label="备注" /> : null}
 
         {type === lockTypeEnum.RECOVER || type === lockTypeEnum.RECEIVE ? (
           <>
@@ -397,4 +391,4 @@ const LockModal = props => {
 
 export default connect(({ lock }) => ({
   prodList: lock.prodList
-}))(LockModal)
+}))(OpreateLock)

+ 24 - 84
src/pages/Product/Lock/LockStore/components/LocksDetail/TabList.jsx

@@ -4,40 +4,20 @@ import { dayjsFormat } from '@/utils/utils'
 import consts from '@/consts'
 import { apiSoftwareAddLonglelog, apiDelLonglelog } from '@/services/product'
 import { ProductLabel } from '@/pages/Product/Lock/LockStore'
-import LockModal, { lockTypeEnum } from './LockModal'
-import ClientDetail from '@/pages/Customer/Client/components/ClientDetail'
-import LocksDetail from '@/pages/Product/Lock/LockStore/components/LocksDetail'
+import { lockTypeEnum } from './OpreateLock'
 import { servicelogEnum, showProductsStatus, showNewLongleStatus, showMarkStatus } from './consts'
 import { useDispatch, useAccess } from 'umi'
-import { useModal } from '@/components/Modal'
+import { useModal } from '@/components/ModalStore'
 
 const LockTabList = props => {
   const {
-    // longleLog,
-    // longleId,
-    // keyNum,
-    // clientId,
-    // logStatus,
-    // upgradeProduct,
-    // logStockStatus,
-    // logSellStatus,
-    longle: {
-      id: longleId,
-      keyNum,
-      // clientId,
-      status,
-      stockStatus,
-      sellStatus,
-      preserveStatus
-    } = {},
+    longle: { id: longleId, keyNum, status, stockStatus, sellStatus, preserveStatus } = {},
     longleLog,
     upgradeProduct,
     updateKey
   } = props
   const hasAddPerm = useAccess()?.validatePermByType('lockstore_delete_record')
-  // 双重解构
-  // const { longleId, keyNum, clientId, status, stockStatus, sellStatus } = props.longle
-  const { toggleDrawer, setDrawerProps } = useModal()
+  const dispatchModal = useModal()
   const dispatch = useDispatch()
   const { TabPane } = Tabs
 
@@ -48,7 +28,6 @@ const LockTabList = props => {
   })
 
   const handleAddLonglelog = async values => {
-    // console.log(values)
     setAddLonglelog({ ...addLonglelog, loading: true })
     const { code = -1 } = await apiSoftwareAddLonglelog({
       ...values,
@@ -66,41 +45,15 @@ const LockTabList = props => {
     }
   }
 
-  const handleClientClick = clientId => {
-    toggleDrawer()
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <ClientDetail dataId={clientId} />
-    })
-    toggleDrawer()
-  }
-
   // 点击新软件锁详情
   const showLongleClick = newLongleId => {
-    // console.log(newLongleId)
-    toggleDrawer()
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <LocksDetail dataId={newLongleId} />
-    })
+    dispatchModal('D_LOCK_DETAIL', { dataId: newLongleId })
     setTimeout(() => {
       dispatch({
         type: 'refresh/commitAction',
         payload: updateKey
       })
     }, 0)
-    toggleDrawer(true)
   }
 
   const renderNewLog = longleService => {
@@ -153,6 +106,17 @@ const LockTabList = props => {
     }
   }
 
+  const openLockModal = type => {
+    dispatchModal('M_OPREATE_LOCK', {
+      type,
+      onConfirm: handleAddLonglelog,
+      keyNum,
+      upgradeProduct,
+      longleId,
+      logStatus: status
+    })
+  }
+
   return (
     <div>
       <div className="pl-4">
@@ -173,7 +137,9 @@ const LockTabList = props => {
                         {servicelogEnum[item.status]}{' '}
                         <span
                           className="textPurple text-hex-967bbd cursor-pointer"
-                          onClick={() => handleClientClick(item.clientId)}
+                          onClick={() =>
+                            dispatchModal('D_CLIENT_DETAIL', { dataId: item.clientId })
+                          }
                         >
                           {item.status !== 6 ? <>{item.client}</> : null}
                         </span>
@@ -221,9 +187,7 @@ const LockTabList = props => {
             ghost
             size="small"
             className="mr-3px"
-            onClick={() =>
-              setAddLonglelog({ ...setAddLonglelog, visible: true, type: lockTypeEnum.RECEIVE })
-            }
+            onClick={() => openLockModal(lockTypeEnum.RECEIVE)}
           >
             接收
           </Button>
@@ -234,9 +198,7 @@ const LockTabList = props => {
             ghost
             size="small"
             className="mr-3px"
-            onClick={() =>
-              setAddLonglelog({ ...setAddLonglelog, visible: true, type: lockTypeEnum.SALE })
-            }
+            onClick={() => openLockModal(lockTypeEnum.SALE)}
           >
             借销赠
           </Button>
@@ -258,13 +220,7 @@ const LockTabList = props => {
             ghost
             size="small"
             className="mr-1"
-            onClick={() =>
-              setAddLonglelog({
-                ...setAddLonglelog,
-                visible: true,
-                type: lockTypeEnum.CHANGE
-              })
-            }
+            onClick={() => openLockModal(lockTypeEnum.CHANGE)}
           >
             更换
           </Button>
@@ -275,9 +231,7 @@ const LockTabList = props => {
             ghost
             size="small"
             className="mr-1"
-            onClick={() =>
-              setAddLonglelog({ ...setAddLonglelog, visible: true, type: lockTypeEnum.RECOVER })
-            }
+            onClick={() => openLockModal(lockTypeEnum.RECOVER)}
           >
             收回
           </Button>
@@ -286,24 +240,10 @@ const LockTabList = props => {
           type="primary"
           ghost
           size="small"
-          onClick={() =>
-            setAddLonglelog({ ...setAddLonglelog, visible: true, type: lockTypeEnum.REMARK })
-          }
+          onClick={() => openLockModal(lockTypeEnum.REMARK)}
         >
           备注
         </Button>
-
-        <LockModal
-          onConfirm={handleAddLonglelog}
-          loading={addLonglelog.loading}
-          visible={addLonglelog.visible}
-          onCancel={() => setAddLonglelog({ ...addLonglelog, visible: false })}
-          type={addLonglelog.type}
-          keyNum={keyNum}
-          upgradeProduct={upgradeProduct}
-          longleId={longleId}
-          logStatus={status}
-        />
       </div>
     </div>
   )

src/pages/Product/Lock/LockStore/components/LocksDetail/consts.js → src/pages/Product/Lock/LockStore/components/LockDetail/consts.js


+ 116 - 0
src/pages/Product/Lock/LockStore/components/LockDetail/index.jsx

@@ -0,0 +1,116 @@
+import React, { useState, useEffect } from 'react'
+import { Row, Col, Tooltip, Drawer, Spin } from 'antd'
+import consts from '@/consts'
+import { apiSoftwareDetail } from '@/services/product'
+import LockForm from './Form'
+import LockLowerList from './LowerList'
+import LockTabList from './TabList'
+import { connect } from 'umi'
+import { Down, Up } from '@icon-park/react'
+import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
+
+const LockDetail = props => {
+  const {
+    visible,
+    onClose,
+    dispatch,
+    dataId = '',
+    refresh,
+    orderIds = [],
+    updateKey = 'software',
+    ...resetDrawerProps
+  } = props
+  console.log(resetDrawerProps)
+  const shouldUpdate = refresh[updateKey] || false
+
+  const [state, setState] = useState({
+    loading: false,
+    longle: {},
+    log: [],
+    total: 0,
+    longleLog: []
+  })
+
+  const initData = async id => {
+    setState({ ...state, loading: true })
+    const {
+      data: { longle = {}, log = [], longleLog = [] } = { longle: {}, longleLog: [] },
+      code = -1
+    } = await apiSoftwareDetail({ id })
+    if (code === consts.RET_CODE.SUCCESS) {
+      if (shouldUpdate) {
+        dispatch({
+          type: 'refresh/commitAction',
+          payload: updateKey
+        })
+      }
+      setState({ ...state, longle, log, longleLog, loading: false })
+    }
+  }
+  useEffect(() => {
+    if (shouldUpdate) {
+      initData(dataId)
+    }
+  }, [shouldUpdate])
+  useEffect(() => {
+    if (visible) {
+      initData(dataId)
+    }
+  }, [visible])
+
+  const { flipFn, flipConsts } = useFlipOver(initData, dataId, orderIds)
+
+  return (
+    <Drawer {...resetDrawerProps} visible={visible} onClose={onClose} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <div className="sheet-box">
+          <Row>
+            <Col span={9} className="sheet-box-left">
+              {orderIds.length ? (
+                <div className="mb-3">
+                  <Tooltip title="上一条记录">
+                    <Up
+                      fill={flipConsts.disableUpBtn ? '#BDBDBE' : '#886ab5'}
+                      size="20"
+                      onClick={() => flipFn(FlipOverEnum.UP)}
+                      className={[
+                        flipConsts.disableUpBtn ? 'cursor-not-allowed' : 'cursor-pointer'
+                      ].join(' ')}
+                    />
+                  </Tooltip>
+                  <Tooltip title="下一条记录">
+                    <Down
+                      fill={flipConsts.disableDownBtn ? '#BDBDBE' : '#886ab5'}
+                      size="20"
+                      onClick={() => flipFn(FlipOverEnum.DOWN)}
+                      className={[
+                        flipConsts.disableDownBtn ? 'cursor-not-allowed' : 'cursor-pointer',
+                        'ml-1'
+                      ].join(' ')}
+                    />
+                  </Tooltip>
+                </div>
+              ) : null}
+              <div className="sheet-left-panel pr-4">
+                <LockForm longle={state.longle} />
+              </div>
+            </Col>
+            <Col span={15} className="sheet-box-right">
+              <LockTabList
+                longleLog={state.longleLog}
+                longle={state.longle}
+                upgradeProduct={state.longle.product?.split('+') || []}
+                updateKey={updateKey}
+              />
+              <LockLowerList log={state.log} />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
+  )
+}
+
+export default connect(({ refresh }) => ({
+  refresh
+}))(LockDetail)

+ 0 - 120
src/pages/Product/Lock/LockStore/components/LocksDetail/index.jsx

@@ -1,120 +0,0 @@
-import React, { useState, useEffect } from 'react'
-import { Row, Col, Tooltip } from 'antd'
-import consts from '@/consts'
-import { apiSoftwareDetail } from '@/services/product'
-import LockForm from './Form.jsx'
-import LockLowerList from './LowerList'
-import LockTabList from './TabList'
-import { connect } from 'umi'
-import { Down, Up } from '@icon-park/react'
-import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
-
-const Index = props => {
-  const { dispatch, visible, dataId = '', refresh, orderIds = [], updateKey = 'software' } = props
-  const shouldUpdate = refresh[updateKey] || false
-  const [state, setState] = useState({
-    longle: {},
-    log: [],
-    total: 0,
-    longleLog: []
-  })
-  const initData = async id => {
-    const {
-      data: { longle = {}, log = [], longleLog = [] } = { longle: {}, longleLog: [] },
-      code = -1
-    } = await apiSoftwareDetail({ id })
-    if (code === consts.RET_CODE.SUCCESS) {
-      if (shouldUpdate) {
-        dispatch({
-          type: 'refresh/commitAction',
-          payload: updateKey
-        })
-      }
-      setState({ ...state, longle, log, longleLog })
-    }
-  }
-  useEffect(() => {
-    if (shouldUpdate) {
-      initData(dataId)
-    }
-  }, [shouldUpdate])
-  useEffect(() => {
-    if (visible) {
-      initData(dataId)
-    }
-  }, [visible])
-
-  const { flipFn, flipConsts } = useFlipOver(initData, dataId, orderIds)
-
-  return (
-    <div>
-      <div className="sheet-box">
-        <Row>
-          <Col
-            span={9}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 9 }}
-            // xl={{ span: 9 }}
-            className="sheet-box-left">
-            {orderIds.length ? (
-              <div className="mb-3">
-                <Tooltip title="上一条记录">
-                  <Up
-                    fill={flipConsts.disableUpBtn ? '#BDBDBE' : '#886ab5'}
-                    size="20"
-                    onClick={() => flipFn(FlipOverEnum.UP)}
-                    className={[
-                      flipConsts.disableUpBtn ? 'cursor-not-allowed' : 'cursor-pointer'
-                    ].join(' ')}
-                  />
-                </Tooltip>
-                <Tooltip title="下一条记录">
-                  <Down
-                    fill={flipConsts.disableDownBtn ? '#BDBDBE' : '#886ab5'}
-                    size="20"
-                    onClick={() => flipFn(FlipOverEnum.DOWN)}
-                    className={[
-                      flipConsts.disableDownBtn ? 'cursor-not-allowed' : 'cursor-pointer',
-                      'ml-1'
-                    ].join(' ')}
-                  />
-                </Tooltip>
-              </div>
-            ) : null}
-            <div className="sheet-left-panel pr-4">
-              <LockForm longle={state.longle} />
-            </div>
-          </Col>
-          <Col
-            span={15}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 15 }}
-            // xl={{ span: 15 }}
-            className="sheet-box-right">
-            <LockTabList
-              longleLog={state.longleLog}
-              longle={state.longle}
-              upgradeProduct={state.longle.product?.split('+') || []}
-              // clientId={state.longle.clientId}
-              // keyNum={state.longle.keyNum}
-              // upgradeProduct={state.longle.product?.split('+') || []}
-              // logStatus={state.longle.status}
-              // logStockStatus={state.longle.stockStatus}
-              // logSellStatus={state.longle.sellStatus}
-              updateKey={updateKey}
-            />
-            <LockLowerList log={state.log} />
-          </Col>
-        </Row>
-      </div>
-    </div>
-  )
-}
-
-// export default Index
-export default connect(({ refresh, single }) => ({
-  refresh,
-  visible: single.drawer.visible
-}))(Index)

+ 0 - 29
src/pages/Product/Lock/LockStore/components/LocksDetail/index.less

@@ -1,29 +0,0 @@
-.inputSearch {
-  width: 95%;
-}
-.modalContainer {
-  height: 53vh;
-  max-height: 53vh;
-  overflow-y: auto;
-  .modalHeader {
-    position: relative;
-    padding: 1.5rem;
-  }
-  .modalContent {
-    .card {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      padding: 1rem;
-      word-wrap: break-word;
-      background-color: #ffffff;
-      background-clip: border-box;
-      border: 1px solid rgba(0, 0, 0, 0.08);
-      border-radius: 4px;
-      box-shadow: 0 0 13px 0 rgb(74 53 107 / 8%) !important;
-      &:not(:last-of-type) {
-        margin-bottom: 1rem;
-      }
-    }
-  }
-}

+ 20 - 19
src/pages/Product/Lock/LockStore/components/SoftwareDetail/index.jsx

@@ -1,14 +1,13 @@
 import React, { useState, useEffect } from 'react'
-import { Row, Col } from 'antd'
+import { Row, Col, Drawer, Spin } from 'antd'
 import consts from '@/consts'
 import { apiStaffDetail } from '@/services/staff'
 import StaffDetail from './StaffDetail'
 import TabList from './TabList'
 import LowerList from './LowerList'
-import { connect } from 'umi'
 
 const SoftwareDetail = props => {
-  const { visible, dataId = '' } = props
+  const { visible, dataId = '', ...resetDrawerProps } = props
   const [state, setState] = useState({
     loading: false,
     staff: {},
@@ -28,22 +27,24 @@ const SoftwareDetail = props => {
     visible && initData(dataId)
   }, [visible])
   return (
-    <div className="sheet-box">
-      <Row>
-        <Col span={12} className="sheet-box-left">
-          <div className="sheet-left-panel pr-4">
-            <StaffDetail staff={state.staff} />
-          </div>
-        </Col>
-        <Col span={12} className="sheet-box-right">
-          <LowerList />
-          <TabList />
-        </Col>
-      </Row>
-    </div>
+    <Drawer {...resetDrawerProps} visible={visible} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <div className="sheet-box">
+          <Row>
+            <Col span={12} className="sheet-box-left">
+              <div className="sheet-left-panel pr-4">
+                <StaffDetail staff={state.staff} />
+              </div>
+            </Col>
+            <Col span={12} className="sheet-box-right">
+              <LowerList />
+              <TabList />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
   )
 }
 
-export default connect(({ single }) => ({
-  visible: single.drawer.visible
-}))(SoftwareDetail)
+export default SoftwareDetail

+ 20 - 110
src/pages/Product/Lock/LockStore/index.jsx

@@ -1,21 +1,15 @@
 import React, { useEffect, useState, useRef } from 'react'
 import { Tag, Tooltip, Input, Button } from 'antd'
 import consts from '@/consts'
-import { useModel, connect } from 'umi'
+import { connect, useModel } from 'umi'
 import { queryLock } from '@/services/product'
-import LocksDetail from '@/pages/Product/Lock/LockStore/components/LocksDetail'
-import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
-import SoftwareDetail from '@/pages/Product/Lock/LockStore/components/SoftwareDetail'
-import { useModal } from '@/components/Modal'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import { generateSortField } from '@/utils/utils'
 import ReceiveLock from './components/ReceiveLock'
-// import ReceiveNewLock from './components/ReceiveNewLock'
 import { PermDataTypeEunm } from '@/pages/Customer/Company/components/PermSelect'
 import BasicTable from '@/components/Table'
 import { getPermAuthCache } from '@/utils/auth'
 import FilterDatePicker from '@/components/Table/src/components/FilterDatePicker'
-// import { DownOutlined } from '@ant-design/icons'
+import { useModal } from '@/components/ModalStore'
 
 // 渲染产品标签
 export const ProductLabel = ({ data }) => {
@@ -35,36 +29,6 @@ export const ProductLabel = ({ data }) => {
   )
 }
 
-// const longleStatusNum = {
-//   1: {
-//     text: '生成'
-//   },
-//   2: {
-//     text: '接收'
-//   },
-//   3: {
-//     text: '借出'
-//   },
-//   4: {
-//     text: '销售'
-//   },
-//   5: {
-//     text: '升级'
-//   },
-//   6: {
-//     text: '更换'
-//   },
-//   7: {
-//     text: '收回'
-//   },
-//   8: {
-//     text: '备注'
-//   },
-//   9: {
-//     text: '赠送'
-//   }
-// }
-
 // 出库状态
 const longleStockStatusNum = {
   1: { text: '生成' },
@@ -85,8 +49,7 @@ export const longlePreserveStatusNum = {
 
 const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
   const tRef = useRef()
-  const { toggleDrawer, setDrawerProps, toggleModal, setModalProps } = useModal()
-  // 刷新
+  const dispatchModal = useModal()
   const refreshData = () => {
     tRef.current?.reload()
   }
@@ -98,14 +61,7 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
     })
     toggleModal()
   }
-  // const showReceiveNewLockModal = () => {
-  //   setModalProps({
-  //     width: '60vw',
-  //     modalRender: () => <ReceiveNewLock refresh={refreshData} />,
-  //     onCancel: () => toggleModal()
-  //   })
-  //   toggleModal()
-  // }
+
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
   const [state, setState] = useState({
     data: [],
@@ -134,60 +90,6 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
     }
   }, [shouldUpdate])
 
-  // 展示drawer
-  const showDrawer = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <LocksDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-  // 展示DrawerClient
-  const showDrawerClient = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <ContactDetail dataId={id} />
-    })
-    toggleDrawer()
-  }
-  // 展示DrawerResponsible
-  const showDrawerResponsible = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <SoftwareDetail dataId={id} />
-    })
-    toggleDrawer()
-  }
-
-  // 展示单位详情抽屉
-  const showCompanyDrawer = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={id} updateKey="longle" />
-    })
-    toggleDrawer()
-  }
-
   const columns = [
     {
       title: '锁号',
@@ -196,8 +98,11 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
       fixed: 'left',
       render: (keyNum, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() =>
+            dispatchModal('D_LOCK_DETAIL', { dataId: record.id, orderIds: state.orderIds })
+          }
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {keyNum}
         </span>
       )
@@ -311,8 +216,9 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
       width: 150,
       render: (text, record) => (
         <span
-          onClick={() => showDrawerClient(record.clientId)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.clientId })}
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {text}
         </span>
       )
@@ -325,8 +231,11 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
       width: 300,
       render: (text, record) => (
         <span
-          onClick={() => showCompanyDrawer(record.customerId)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() =>
+            dispatchModal('D_COMPANY_DETAIL', { dataId: record.customerId, updateKey: 'longle' })
+          }
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {text}
         </span>
       )
@@ -337,8 +246,9 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
       width: 80,
       render: (text, record) => (
         <span
-          onClick={() => showDrawerResponsible(record.responsibleId)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() => dispatchModal('D_SOFTWARE_DETAIL', { dataId: record.responsibleId })}
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {text}
         </span>
       )

+ 45 - 95
src/pages/Workbench/Dashboard/components/RatioPanels.jsx

@@ -1,14 +1,11 @@
 import React, { useState } from 'react'
 import ProTable from '@ant-design/pro-table'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
 import { queryRatioPanelsList, queryServiceRatioPanelsList } from '@/services/dashboard'
 import consts from '@/consts'
 import { servicelogEnum } from '@/pages/Customer/Company/components/CompanyDetail/LowerList'
-import ClientDetail from '@/pages/Customer/Client/components/ClientDetail'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import { cardTypeMap } from '../consts'
-import { useModal } from '@/components/Modal'
-import { Badge } from 'antd'
+import { Badge, Modal } from 'antd'
+import { useModal } from '@/components/ModalStore'
 
 const dataTypeEunm = {
   0: {
@@ -44,37 +41,23 @@ export const renderBadge = (count, active = false) => {
 }
 
 /** 服务环比数据Tab切换表格 */
-const ServiceRatioPanels = ({ staffIds, cyclical, dataPermission }) => {
-  const { toggleDrawer, setDrawerProps } = useModal()
+const ServiceRatioPanels = ({ dispatchModal, staffIds, cyclical, dataPermission }) => {
   const activeKeyMap = {
     0: { key: 'clientName', title: '客户', id: 'clientId' },
     1: { key: 'customerName', title: '单位', id: 'customerId' },
     2: { key: 'businessName', title: '商机', id: 'businessId' }
   }
   const [state, setState] = useState({
-    orderIds: [],
     activeKey: '0',
     total: 0
   })
   const showDrawer = id => {
-    let children = null
     if (state.activeKey === '0') {
-      children = <ClientDetail dataId={id} orderIds={state.orderIds} />
+      dispatchModal('D_CLIENT_DETAIL', { dataId: id })
     }
     if (state.activeKey === '1') {
-      children = <CompanyDetail dataId={id} orderIds={state.orderIds} />
+      dispatchModal('D_COMPANY_DETAIL', { dataId: id })
     }
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children
-    })
-    toggleDrawer()
   }
   const columns = [
     {
@@ -178,38 +161,8 @@ const ServiceRatioPanels = ({ staffIds, cyclical, dataPermission }) => {
   )
 }
 
-const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission }) => {
-  const { toggleDrawer, setDrawerProps } = useModal()
-  const state = {
-    orderIds: []
-  }
-  const showDrawer = id => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <ClientDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-  // 展示单位
-  const showDrawerComapny = id => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
+const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission, ...resetModalProps }) => {
+  const dispatchModal = useModal()
   const columnsMap = {
     0: [
       {
@@ -218,7 +171,7 @@ const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission }) => {
         width: '10%',
         render: (clientName, record) => (
           <span
-            onClick={() => showDrawer(record.id)}
+            onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.id })}
             className="text-primary cursor-pointer hover:text-[#967bbd]"
           >
             {clientName}
@@ -233,7 +186,7 @@ const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission }) => {
         render: (companyName, record) => (
           <span
             className="text-primary cursor-pointer hover:text-[#967bbd]"
-            onClick={() => showDrawerComapny(record.companyId)}
+            onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.companyId })}
           >
             {companyName}
           </span>
@@ -284,7 +237,7 @@ const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission }) => {
         width: '16%',
         render: (companyName, record) => (
           <span
-            onClick={() => showDrawerComapny(record.id)}
+            onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.id })}
             className="text-primary cursor-pointer hover:text-[#967bbd]"
           >
             {companyName}
@@ -363,46 +316,43 @@ const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission }) => {
   }
 
   return (
-    <CustomModal title={`卡片详情(${dataTypeEunm[dataType].title})`}>
-      <div className="pb-4">
-        {dataType === cardTypeMap.SERVICE ? (
-          <ServiceRatioPanels
-            cyclical={retioCyclical}
-            dataPermission={dataPermission}
-            staffIds={staffIds}
+    <Modal
+      {...resetModalProps}
+      title={`卡片详情(${dataTypeEunm[dataType].title})`}
+      footer={false}
+      width="90vw"
+    >
+      {dataType === cardTypeMap.SERVICE ? (
+        <ServiceRatioPanels
+          dispatchModal={dispatchModal}
+          cyclical={retioCyclical}
+          dataPermission={dataPermission}
+          staffIds={staffIds}
+        />
+      ) : (
+        <div className="mx-4">
+          <ProTable
+            size="small"
+            bordered={true}
+            pagination={{ defaultPageSize: 10 }}
+            rowKey={record => record.id}
+            scroll={{ y: 400 }}
+            columns={columnsMap[dataType]}
+            params={{ dataType, dataPermission, cyclical: retioCyclical, staffIds }}
+            request={async params => {
+              const { code = -1, data } = await queryRatioPanelsList(params)
+              return {
+                data: data[dataTypeEunm[dataType].key],
+                success: code === consts.RET_CODE.SUCCESS,
+                total: data.total
+              }
+            }}
+            search={false}
+            toolBarRender={false}
           />
-        ) : (
-          <div className="mx-4">
-            <ProTable
-              size="small"
-              bordered={true}
-              pagination={{ defaultPageSize: 10 }}
-              rowKey={record => record.id}
-              scroll={{ y: 400 }}
-              columns={columnsMap[dataType]}
-              params={{ dataType, dataPermission, cyclical: retioCyclical, staffIds }}
-              request={async params => {
-                const { code = -1, data } = await queryRatioPanelsList(params)
-                return {
-                  data: data[dataTypeEunm[dataType].key],
-                  success: code === consts.RET_CODE.SUCCESS,
-                  total: data.total
-                }
-              }}
-              search={false}
-              toolBarRender={false}
-            />
-          </div>
-        )}
-      </div>
-      {/* <div className={styles.modalFooter}>
-        <div className="text-right">
-          <Button type="button" onClick={closeModal}>
-            关闭
-          </Button>
         </div>
-      </div> */}
-    </CustomModal>
+      )}
+    </Modal>
   )
 }
 

+ 28 - 90
src/pages/Workbench/Dashboard/components/ReminderList.jsx

@@ -1,71 +1,13 @@
-import React, { useState } from 'react'
 import consts from '@/consts'
-import { connect } from 'umi'
 import ProTable from '@ant-design/pro-table'
-import { useModal } from '@/components/Modal'
 import { queryReminderList } from '@/services/dashboard'
-// import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
-import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
-import Detail from '@/pages/Customer/Business/components/BusinessDetail'
-
+import { useModal } from '@/components/ModalStore'
+import { Modal } from 'antd'
 const ReminderList = props => {
-  // const dispatch = useDispatch()
-  const { dataType, reminderCyclical } = props
-  const { toggleDrawer, setDrawerProps } = useModal()
-  const [state] = useState({
-    orderIds: []
-  })
-  // const [state, setState] = useState({
-  //   params: { dataType, reminderCyclical }
-  // })
-  // 展示客户
-  const showDrawer = id => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <ContactDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-  // 展示单位
-  const showDrawerComapny = id => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-  // 展示商机详情
-  const showDrawerBusiness = (id, isCompany = false) => {
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: isCompany ? (
-        <CompanyDetail dataId={id} />
-      ) : (
-        <Detail dataId={id} orderIds={state.orderIds} />
-      )
-    })
-    toggleDrawer()
-  }
+  const { dataType, reminderCyclical, ...resetModalProps } = props
+
+  const dispatchModal = useModal()
+
   const clientColumns = [
     {
       title: '客户名称',
@@ -74,8 +16,9 @@ const ReminderList = props => {
       width: '10%',
       render: (clientName, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.id })}
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {clientName}
         </span>
       )
@@ -87,8 +30,14 @@ const ReminderList = props => {
       ellipsis: true,
       render: (companyName, record) => (
         <span
-          onClick={() => showDrawerComapny(record.companyId)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() =>
+            dispatchModal('D_COMPANY_DETAIL', {
+              dataId: record.companyId,
+              orderIds: state.orderIds
+            })
+          }
+          className="text-primary cursor-pointer hover:text-hex-967bbd"
+        >
           {companyName}
         </span>
       )
@@ -139,8 +88,9 @@ const ReminderList = props => {
       ellipsis: true,
       render: (companyName, record) => (
         <span
-          onClick={() => showDrawerComapny(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() => dispatchModal('D_COMPANY_DETAIL', { dataId: record.id })}
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {companyName}
         </span>
       )
@@ -191,8 +141,11 @@ const ReminderList = props => {
       ellipsis: true,
       render: (text, record) => (
         <span
-          onClick={() => showDrawerBusiness(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          onClick={() =>
+            dispatchModal('D_BUSINESS_DETAIL', { dataId: record.id, orderIds: state.orderIds })
+          }
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {text}
         </span>
       )
@@ -249,14 +202,8 @@ const ReminderList = props => {
     2: { title: '商机' }
   }
 
-  // const closeModal = () => {
-  //   dispatch({
-  //     type: 'single/changeModal'
-  //   })
-  // }
-
   return (
-    <CustomModal title={titleMap[dataType].title}>
+    <Modal {...resetModalProps} title={titleMap[dataType].title} width="90vw" footer={false}>
       <div className="mx-4">
         <ProTable
           size="small"
@@ -278,17 +225,8 @@ const ReminderList = props => {
           toolBarRender={false}
         />
       </div>
-      {/* <div className={styles.modalFooter}>
-        <div className="text-right">
-          <Button type="button" onClick={closeModal}>
-            关闭
-          </Button>
-        </div>
-      </div> */}
-    </CustomModal>
+    </Modal>
   )
 }
 
-export default connect(({ single }) => ({
-  visible: single.drawer.visible
-}))(ReminderList)
+export default ReminderList

+ 1 - 1
src/pages/Workbench/Dashboard/components/SoftLeaderboard.jsx

@@ -23,7 +23,7 @@ const SoftLeaderboard = ({ loading = false, productLeaderBoard = [] }) => {
         valueType: 'indexBorder',
         align: 'center',
         width: '20%',
-        render: (_, record, index) =>
+        render: (_, __, index) =>
           index + 1 <= 3 ? <Iconfont type="icon-trophy" className={colorMap[index + 1]} /> : ''
       },
       {

+ 35 - 35
src/pages/Workbench/Dashboard/index.jsx

@@ -4,21 +4,19 @@ import { Row, Col, Select, Card, Skeleton, TreeSelect } from 'antd'
 import { AddressBook, City, Comment } from '@icon-park/react'
 import consts from '@/consts'
 import { connect, useModel } from 'umi'
-import { useModal } from '@/components/Modal'
 import { queryDashboard } from '@/services/dashboard'
 import { queryStaff } from '@/services/staff'
-import ReminderList from './components/ReminderList'
 import LeaderBoard from './components/LeaderBoard'
 import SoftLeaderboard from './components/SoftLeaderboard'
 import { cardTypeMap, cyclicalOp } from './consts'
 // import BusinessChar from './components/BusinessChar'
-import RatioPanels from './components/RatioPanels'
 import PermSelect, { PermDataTypeEunm } from '@/pages/Customer/Company/components/PermSelect'
 import { getAuthCache, getPermAuthCache, setAuthCache } from '@/utils/auth'
 import { WORKBENCH_CYCLICAL_KEY } from '@/utils/cache/cacheEnum'
 import styles from './index.less'
 import { isDevMode } from '@/utils/env'
 import { isMobile } from '@/utils/is'
+import { useModal } from '@/components/ModalStore'
 
 const Dashboard = ({ dispatch, departments = [] }) => {
   const { initialState: { currentUser } = { currentUser: {} } } = useModel('@@initialState')
@@ -54,31 +52,20 @@ const Dashboard = ({ dispatch, departments = [] }) => {
     }
   })
 
-  const { toggleModal, setModalProps } = useModal()
+  const dispatchModal = useModal()
+
   // 展示服务弹窗详情
   const handleReminderList = (dataType, reminderCyclical) => {
-    setModalProps({
-      width: '90vw',
-      modalRender: () => <ReminderList dataType={dataType} reminderCyclical={reminderCyclical} />,
-      onCancel: () => toggleModal()
-    })
-    toggleModal()
+    dispatchModal('M_REMINDER_LIST', { dataType, reminderCyclical })
   }
   // 展示卡片详情
   const handleRatioCard = dataType => {
-    setModalProps({
-      width: '90vw',
-      modalRender: () => (
-        <RatioPanels
-          dataType={dataType}
-          staffIds={state.params.staffIds}
-          retioCyclical={state.params.cyclical}
-          dataPermission={state.params.dataPermission}
-        />
-      ),
-      onCancel: () => toggleModal()
+    dispatchModal('M_RATIO_PANELS', {
+      dataType,
+      staffIds: state.params.staffIds,
+      retioCyclical: state.params.cyclical,
+      dataPermission: state.params.dataPermission
     })
-    toggleModal()
   }
 
   // dataPermission-all 拉取部门下员工列表
@@ -200,7 +187,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, '7day')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -211,7 +199,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, '15day')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -222,7 +211,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, '30day')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -233,7 +223,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, '3month')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -244,7 +235,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, '6month')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -255,7 +247,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
       render: (name, record) => (
         <span
           onClick={() => handleReminderList(record.type, 'reminder')}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {name}
         </span>
       )
@@ -362,7 +355,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
                     'relative',
                     'cursor-pointer',
                     state.selectId === item.id ? styles.imgBg : styles.paddingBg
-                  ].join(' ')}>
+                  ].join(' ')}
+                >
                   <img
                     className="w-full max-w-30px h-30px border rounded-30px"
                     src={
@@ -400,7 +394,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
                           state.clientChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.clientChainRatio.percentage}
                       </span>
                     </div>
@@ -422,7 +417,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
               ) : (
                 <Row
                   className="cursor-pointer"
-                  onClick={() => handleRatioCard(cardTypeMap.COMPANY)}>
+                  onClick={() => handleRatioCard(cardTypeMap.COMPANY)}
+                >
                   <Col span={6}>
                     <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <City size="26" fill="#fff" />
@@ -437,7 +433,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
                           state.customerChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.customerChainRatio.percentage}
                       </span>
                     </div>
@@ -498,7 +495,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
               ) : (
                 <Row
                   onClick={() => handleRatioCard(cardTypeMap.SERVICE)}
-                  className="cursor-pointer">
+                  className="cursor-pointer"
+                >
                   <Col span={6}>
                     <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <Comment size="26" fill="#fff" />
@@ -513,7 +511,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
                           state.serviceLogChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.serviceLogChainRatio.percentage}
                       </span>
                     </div>
@@ -547,7 +546,8 @@ const Dashboard = ({ dispatch, departments = [] }) => {
               title="数据汇总"
               className="shadow-card"
               bodyStyle={{ padding: state.loading ? '24px' : 0 }}
-              loading={state.loading}>
+              loading={state.loading}
+            >
               <ul>
                 <li className="px-12px py-16px border-b-1">
                   新增客户<b className="px-1">{state.aggregation.clientCount}</b>个,服务