Просмотр исходного кода

Merge branch 'dev' of http://192.168.1.41:3000/outaozhen/cldV2react into dev

outaozhen 4 лет назад
Родитель
Сommit
546509a301
49 измененных файлов с 1613 добавлено и 1757 удалено
  1. 1 1
      package.json
  2. 2 13
      src/app.tsx
  3. 12 0
      src/components/ModalStore/README.md
  4. 49 0
      src/components/ModalStore/index.tsx
  5. 190 0
      src/components/ModalStore/src/CreateProvider.tsx
  6. 17 0
      src/components/ModalStore/src/context.ts
  7. 4 0
      src/components/ModalStore/src/index.ts
  8. 1 1
      src/global.less
  9. 52 44
      src/pages/Customer/Business/components/AddBusiness.jsx
  10. 59 50
      src/pages/Customer/Business/components/BusinessDetail/index.jsx
  11. 12 24
      src/pages/Customer/Business/components/ChangeStaff/index.jsx
  12. 25 31
      src/pages/Customer/Business/index.jsx
  13. 136 152
      src/pages/Customer/Client/components/AddClient/index.jsx
  14. 65 65
      src/pages/Customer/Client/components/ClientDetail/AddRecord.jsx
  15. 25 35
      src/pages/Customer/Client/components/ClientDetail/TabList.jsx
  16. 73 62
      src/pages/Customer/Client/components/ClientDetail/index.jsx
  17. 17 17
      src/pages/Customer/Client/components/ConnectClient/index.jsx
  18. 27 47
      src/pages/Customer/Client/index.jsx
  19. 95 73
      src/pages/Customer/Company/components/AddCompany/index.jsx
  20. 10 30
      src/pages/Customer/Company/components/ChangeCompany/index.jsx
  21. 6 4
      src/pages/Customer/Company/components/CompanyDetail/SyncClient.jsx
  22. 51 74
      src/pages/Customer/Company/components/CompanyDetail/TabList.jsx
  23. 78 70
      src/pages/Customer/Company/components/CompanyDetail/index.jsx
  24. 24 17
      src/pages/Customer/Company/components/ConnectCompany/index.jsx
  25. 2 4
      src/pages/Customer/Company/components/ConnectCompany/index.less
  26. 31 34
      src/pages/Customer/Company/components/CustomPerm.jsx
  27. 9 17
      src/pages/Customer/Company/components/PermSelect.tsx
  28. 31 32
      src/pages/Customer/Company/index.jsx
  29. 18 18
      src/pages/Hr/Employee/components/EmployeeDetail/index.jsx
  30. 14 16
      src/pages/Hr/Employee/components/StaffModal/index.jsx
  31. 4 17
      src/pages/Hr/Employee/index.jsx
  32. 72 87
      src/pages/Product/Cloud/components/Detail/index.jsx
  33. 13 11
      src/pages/Product/Cloud/index.jsx
  34. 31 38
      src/pages/Product/Lock/LockStore/components/ChangeClient/index.jsx
  35. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/Form.jsx
  36. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/LowerList.jsx
  37. 59 65
      src/pages/Product/Lock/LockStore/components/LocksDetail/LockModal.jsx
  38. 24 84
      src/pages/Product/Lock/LockStore/components/LocksDetail/TabList.jsx
  39. 0 0
      src/pages/Product/Lock/LockStore/components/LockDetail/consts.js
  40. 113 0
      src/pages/Product/Lock/LockStore/components/LockDetail/index.jsx
  41. 0 120
      src/pages/Product/Lock/LockStore/components/LocksDetail/index.jsx
  42. 0 29
      src/pages/Product/Lock/LockStore/components/LocksDetail/index.less
  43. 8 7
      src/pages/Product/Lock/LockStore/components/ReceiveLock.jsx
  44. 20 19
      src/pages/Product/Lock/LockStore/components/SoftwareDetail/index.jsx
  45. 24 128
      src/pages/Product/Lock/LockStore/index.jsx
  46. 45 95
      src/pages/Workbench/Dashboard/components/RatioPanels.jsx
  47. 28 90
      src/pages/Workbench/Dashboard/components/ReminderList.jsx
  48. 1 1
      src/pages/Workbench/Dashboard/components/SoftLeaderboard.jsx
  49. 35 35
      src/pages/Workbench/Dashboard/index.jsx

+ 1 - 1
package.json

@@ -57,7 +57,7 @@
     "@icon-park/react": "^1.3.3",
     "@umijs/route-utils": "^1.0.33",
     "ahooks": "^2.10.0",
-    "antd": "4.18.2",
+    "antd": "4.18.5",
     "antd-img-crop": "^3.16.0",
     "classnames": "^2.2.6",
     "crypto-js": "^4.0.0",

+ 2 - 13
src/app.tsx

@@ -3,20 +3,15 @@ import { history } from 'umi'
 import RightContent from '@/components/RightContent'
 import { message, notification } from 'antd'
 import logo from '../public/logo.svg'
-import BasicModal, { BasicDrawer } from '@/components/Modal'
 import { getToken } from '@/utils/auth'
 import { tryChangeWorkStatus } from './components/RightContent/Book'
 import { getAuthCache, setAuthCache } from './utils/auth'
 import { LAYOUT_COLLAPSED_KEY } from './utils/cache/cacheEnum'
 import consts from './consts'
+import ModalStore from './components/ModalStore'
 
 const loginPath = '/user/login'
 
-// 重新构建MenuData,解决重定向没有权限的路由
-// const generateMenu = (menuData, permission) => menuData.map(menu => {
-
-// })
-
 export async function getInitialState() {
   // 如果是登录页面,不执行
   const fetchUserInfo = async () => {
@@ -108,13 +103,7 @@ export const layout = ({ initialState, setInitialState }) => {
       //   permData && setInitialState({ ...initialState, permData })
       // }
     },
-    childrenRender: children => (
-      <>
-        {children}
-        <BasicDrawer />
-        <BasicModal />
-      </>
-    ),
+    childrenRender: children => <ModalStore>{children}</ModalStore>,
     // links: [
     //   <div className="ant-menu-title-content">
     //     <AddressBook theme="outline" className="anticon" />

+ 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 创建上下文中使用堆栈管理弹窗,即可实现无限嵌套且层级叠加不冲突的弹窗/抽屉。

+ 49 - 0
src/components/ModalStore/index.tsx

@@ -0,0 +1,49 @@
+import React from 'react'
+import { createModalHook, ModalStore } from './src'
+import ClientDetail 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'
+import ReceiveLock from '@/pages/Product/Lock/LockStore/components/ReceiveLock'
+import CustomPerm from '@/pages/Customer/Company/components/CustomPerm'
+
+const modalMap = {
+  M_CLIENT_ADD: AddClient, // 添加客户弹窗
+  M_COMPANY_ADD: AddCompany, // 添加单位弹窗
+  M_BUSINESS_ADD: AddBusiness, // 添加商机弹窗
+  D_CLIENT_DETAIL: ClientDetail, // 客户详情抽屉
+  D_COMPANY_DETAIL: CompanyDetail, // 单位详情抽屉
+  D_BUSINESS_DETAIL: BusinessDetail, // 商机详情抽屉
+  M_CONNECT_CLIENT: ConnectClient, // 关联客户弹窗
+  M_CONNECT_COMPANY: ConnectCompany, // 关联单位弹窗
+  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, // 操作锁库弹窗
+  M_RECEIVE_LOCK: ReceiveLock, // 接受锁库弹窗
+  M_CUSTOM_PERM: CustomPerm // 自定义数据权限弹窗
+}
+
+export const useModal = createModalHook<typeof modalMap>()
+
+export default ({ children }: { children: React.ReactChildren }) => (
+  <ModalStore modalMap={modalMap} destroyOnClose="afterClose">
+    {children}
+  </ModalStore>
+)

+ 190 - 0
src/components/ModalStore/src/CreateProvider.tsx

@@ -0,0 +1,190 @@
+import { message } from 'antd'
+import type { CSSProperties } from 'react'
+import React from 'react'
+import { ModalContext } from './context'
+export interface ModalFullConfig<T = any> {
+  destroyOnClose?: boolean | string
+  visiblePropName?: string
+  // onClosePropName?: string
+  component: React.ComponentType<T>
+}
+
+export type ModalConfig<T = any> = ModalFullConfig<T> | React.ComponentType<T>
+
+export type ModalConfigMap = Record<string, ModalConfig>
+
+export interface ModalStoreProps extends Omit<ModalFullConfig, 'component'> {
+  children: React.ReactNode
+  modalMap: ModalConfigMap
+}
+
+export interface ModalItem extends Record<string, any> {
+  key: string
+}
+
+export interface ModalStoreState {
+  currentModal: ModalItem[]
+}
+
+class ModalStore extends React.Component<ModalStoreProps, ModalStoreState> {
+  constructor(props: ModalStoreProps) {
+    super(props)
+    this.state = {
+      currentModal: []
+    }
+  }
+
+  // 获取modal的config
+  private getModalConfig(key: string) {
+    const { modalMap = {}, visiblePropName = 'visible' } = this.props
+    const componentKey = key.split('@')?.[0]
+    let config = modalMap[componentKey]
+    if (typeof config === 'function') config = { component: config }
+    let onClosePropName = 'onCancel'
+    let destroyOnClose = 'afterClose'
+    if (componentKey.startsWith('D')) {
+      onClosePropName = 'onClose'
+      destroyOnClose = 'afterVisibleChange'
+    }
+
+    return { visiblePropName, onClosePropName, destroyOnClose, config }
+  }
+
+  private setModalState(fn: (prev: ModalItem[]) => ModalItem[]) {
+    this.setState(prev => ({ currentModal: fn(prev.currentModal) }))
+  }
+
+  private getCloseFunction(key: string, cb?: (...args: any[]) => void) {
+    return (...args: any[]) => {
+      const { visiblePropName } = this.getModalConfig(key)
+      this.setModalState(prev => {
+        return prev.map(item => {
+          if (item.key === key) {
+            return { ...item, [visiblePropName]: false }
+          }
+          return item
+        })
+      })
+      if (typeof cb === 'function') {
+        cb(...args)
+      }
+    }
+  }
+
+  private getDestroyFunction(key: string, cb?: (...args: any[]) => void) {
+    return (...args: any[]) => {
+      this.setModalState(prev => prev.filter(v => v.key !== key))
+      if (typeof cb === 'function') {
+        cb(...args)
+      }
+    }
+  }
+
+  private push = (key: string, state: any) => {
+    // eslint-disable-next-line no-param-reassign
+    key = state?.dataId ? `${key}@${state?.dataId}` : key
+    const { visiblePropName, onClosePropName, destroyOnClose } = this.getModalConfig(key)
+
+    this.setModalState(prevModals => {
+      const defaultProps: any = {
+        [visiblePropName]: key.startsWith('D') ? false : true,
+        [onClosePropName]: this.getCloseFunction(key, state?.[onClosePropName])
+      }
+
+      if (destroyOnClose) {
+        const prop = typeof destroyOnClose === 'string' ? destroyOnClose : onClosePropName
+
+        defaultProps[prop] =
+          destroyOnClose === 'afterVisibleChange'
+            ? (visible: boolean) => !visible && this.getDestroyFunction(key)()
+            : this.getDestroyFunction(key)
+      }
+
+      const newModal = {
+        ...state,
+        ...defaultProps,
+        key
+      }
+      // console.log(key)
+
+      const nextModals = prevModals.slice()
+
+      const index = nextModals.findIndex(item => item.key === key)
+
+      if (index !== -1) {
+        if (key.startsWith('D')) {
+          message.warning('当前窗口正在运行中,请勿重复打开')
+          return prevModals
+        }
+        nextModals.splice(index, 1)
+      }
+      nextModals.push(newModal)
+
+      return nextModals
+    })
+    if (key.startsWith('D')) {
+      // 利用事件循环,先让dom元素渲染出来再使其展示动画(否则可能导致抽屉无动画直接出现)
+      setTimeout(() => {
+        this.setModalState(prevModals =>
+          prevModals.map(item => {
+            if (item.key === key) {
+              return { ...item, visible: true }
+            }
+            return item
+          })
+        )
+      }, 0)
+    }
+  }
+
+  private renderModal = (item: ModalItem) => {
+    const { config } = this.getModalConfig(item.key)
+    const nodeProps = this.renderMaskProps(item)
+    if (config) {
+      // 弹窗
+      if ('component' in config) {
+        return React.createElement(config.component, nodeProps)
+      }
+      // 抽屉
+      return React.createElement(config, nodeProps)
+    }
+    return null
+  }
+
+  private renderMaskProps = (item: ModalItem) => {
+    // 没有dataId 不是抽屉
+    if (!item.dataId) return item
+    const drawerStore = this.state.currentModal
+      .filter(modal => modal.dataId)
+      .map(modal => modal.dataId)
+    const len = drawerStore.length
+    if (len === 1) return item
+    // 抽屉至少2个
+    const currentIdx = drawerStore.findIndex(modal => modal === item.dataId)
+    if (currentIdx === 0) return item
+    if (currentIdx > 0) {
+      // 大于0说明是第二或以上的抽屉了
+      console.log(len, currentIdx)
+
+      return {
+        ...item,
+        maskStyle: { opacity: 0, animation: 'none' } as CSSProperties
+        // style: { transform: `translateX(-${(len - currentIdx) * 10}px)` }
+      }
+    }
+    return item
+  }
+  render() {
+    const { currentModal } = this.state
+    const { children } = this.props
+
+    return (
+      <ModalContext.Provider value={this.push}>
+        {children}
+        {currentModal.map(this.renderModal)}
+      </ModalContext.Provider>
+    )
+  }
+}
+
+export default ModalStore

+ 17 - 0
src/components/ModalStore/src/context.ts

@@ -0,0 +1,17 @@
+import React from 'react'
+import type { ModalConfigMap, ModalConfig } from './CreateProvider'
+
+type ReturnModalState<T> = T extends ModalConfig<infer P> ? Partial<P> : T
+
+export type ModalDispatch<T extends ModalConfigMap = any> = <K extends keyof T & string>(
+  key: K,
+  state: ReturnModalState<T[K]>
+) => void
+
+export const ModalContext = React.createContext<ModalDispatch<any>>(() => {})
+
+// export const useModal = () => React.useContext(ModalContext)
+
+export function createModalHook<T extends ModalConfigMap>() {
+  return () => React.useContext<ModalDispatch<T>>(ModalContext)
+}

+ 4 - 0
src/components/ModalStore/src/index.ts

@@ -0,0 +1,4 @@
+import { ModalContext, createModalHook } from './context'
+import ModalStore from './CreateProvider'
+
+export { ModalStore, ModalContext, createModalHook }

+ 1 - 1
src/global.less

@@ -192,7 +192,7 @@ input:-webkit-autofill:active {
   color: unset;
 }
 
-.my-drawer.ant-drawer-open {
+.zh-drawer.ant-drawer-open {
   // width: 100% !important; // mask: false
   @media (min-width: 992px) {
     > .ant-drawer-content-wrapper {

+ 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>
               ]
             }}
           />

+ 136 - 152
src/pages/Customer/Client/components/AddClient/index.jsx

@@ -1,26 +1,26 @@
-import React, { useRef, useState, 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 { ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form'
-import { Plus } from '@icon-park/react'
 import { useDispatch, connect } from 'umi'
 import { ChangeCompMap } from '@/pages/Customer/Company/components/ChangeCompany'
-import ModalDragForm from '@/components/Modal/src/components/ModalDragForm'
 import { isNullOrUnDef } from '@/utils/is'
 import TelephoneFormItem from './TelephoneFormItem'
+import { validateEnum } from '@/pages/Customer/Company/components/AddCompany/CompanyFormItem'
 
 const AddClient = props => {
   const {
+    onCancel,
     reload,
     onConfirm,
-    buttonProps,
     dataId,
     dataType,
-    btnTitle = '客户',
     defaultValues,
-    sourceList
+    sourceList,
+    ...resetModalProps
   } = props
-  const formRef = useRef(null)
+
+  const [formRef] = Form.useForm()
   const layout = {
     layout: 'horizontal',
     labelCol: { flex: '100px' }
@@ -37,178 +37,162 @@ const AddClient = props => {
   }, [])
 
   const handleChange = changedValues => {
-    // const clientName = formRef.current?.getFieldValue('clientName')
     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 clientName = formRef.current?.getFieldValue('clientName')
-    // if (clientName) {
-    //   const clientNameNum = clientName.split('')
-    //   const [firstName, ...lastName] = clientNameNum
-    //   const nameAfter = `(${lastName.join('')})`
-    //   const newClientName = `${firstName + nameAfter}工`
-    //   formRef.current?.setFieldsValue({ niceName: newClientName })
-    // } else if (!formRef.current?.getFieldValue('qq')) {
-    //   const emailNum = qq.value
-    //   const newEmail = `${emailNum}@qq.com`
-    //   formRef.current?.setFieldsValue({ email: newEmail })
-    // }
   }
+
+  const handleOnOk = () => {
+    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)
+        }
+      })
+  }
+
   return (
-    <ModalDragForm
-      {...layout}
-      formRef={formRef}
-      modalProps={{ zIndex: 1003, getContainer: false }}
+    <Modal
+      {...resetModalProps}
+      onCancel={onCancel}
+      width="43vw"
       title="添加客户"
-      onVisibleChange={visible => {
-        if (visible) {
-          formRef.current?.setFieldsValue({ ...defaultValues })
-        }
-      }}
-      onValuesChange={handleChange}
-      trigger={
-        <Button type="primary" {...buttonProps} className="mr-1">
-          <Plus className="mr-1" />
-          {btnTitle}
-        </Button>
-      }
-      submitter={{
-        render: ({ submit }, defaultDoms) => [
-          ...defaultDoms,
-          dataId ? (
+      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 = {}
                 if (dataType === ChangeCompMap.BUSINESS.key) {
                   values.businessId = dataId
                 }
-                formRef.current && formRef.current.setFieldsValue(values)
-                submit()
-              }}>
+                formRef?.setFieldsValue(values)
+                handleOnOk()
+              }}
+            >
               添加并关联
             </Button>
-          ) : null
-        ]
-      }}
-      onFinish={async values => {
-        await onConfirm(values)
-        formRef.current?.resetFields()
-        setValidStatusFtl('')
-        !isNullOrUnDef(reload) && reload()
-        return true
-      }}>
-      {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
-      <ProFormText
-        name="clientName"
-        label="姓名"
-        placeholder="请输入客户名称"
-        rules={[{ required: true, message: '请输入姓名' }]}
-      />
-      <Form.Item
-        label="客户地区"
-        name="districtIds"
-        rules={[{ required: true, message: '请选择地区' }]}>
-        <LazyCascader showFooter={true} />
-      </Form.Item>
-      <Row>
-        <Col span={12}>
-          <ProFormSelect
-            name="gender"
-            label="性别"
-            placeholder=""
-            rules={[{ message: '请选择性别' }]}
-            options={[
-              { label: '男', value: '男' },
-              { label: '女', value: '女' }
-            ]}
-          />
-          <ProFormText label="部门" name="department" placeholder="" />
+          ) : null}
+        </div>
+      }
+    >
+      <Form {...layout} form={formRef} onValuesChange={handleChange} initialValues={defaultValues}>
+        {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
+        <ProFormText
+          name="clientName"
+          label="姓名"
+          placeholder="请输入客户名称"
+          rules={[{ required: true, message: '请输入姓名' }]}
+        />
+        <Form.Item
+          label="客户地区"
+          name="districtIds"
+          rules={[{ required: true, message: '请选择地区' }]}
+        >
+          <LazyCascader showFooter={true} />
+        </Form.Item>
+        <Row>
+          <Col span={12}>
+            <ProFormSelect
+              name="gender"
+              label="性别"
+              placeholder=""
+              rules={[{ message: '请选择性别' }]}
+              options={[
+                { label: '男', value: '男' },
+                { label: '女', value: '女' }
+              ]}
+            />
+            <ProFormText label="部门" name="department" placeholder="" />
 
-          <Form.Item
-            label="手机"
-            name="telephone"
-            validateStatus={validStatusFtl}
-            hasFeedback
-            rules={[{ required: true, message: '请输入手机号码' }]}>
-            <TelephoneFormItem validateFn={status => setValidStatusFtl(status)} />
-          </Form.Item>
-          <ProFormText
-            label="电话"
-            name="phone"
-            rules={[{ message: '请输入电话/座机号' }]}
-            placeholder=""
-          />
-        </Col>
-        <Col span={12}>
-          <ProFormText label="昵称" name="niceName" placeholder="" />
-          {/* <ProFormDependency name={['clientName']}>
-            {({ clientName, newClientName }) => {
-              if (!clientName === false) {
-                const clientNameNum = clientName.split('')
-                const [firstName, ...lastName] = clientNameNum
-                const nameAfter = `(${lastName.join('')})`
-                // eslint-disable-next-line no-param-reassign
-                newClientName = `${firstName + nameAfter}工`
-              }
-              return (
-                <ProFormText
-                  label="昵称"
-                  name="niceName"
-                  placeholder=""
-                  value={`${newClientName || ''}`}
-                />
-              )
-            }}
-          </ProFormDependency> */}
-          <ProFormText label="职位" name="position" placeholder="" />
-          <ProFormText label="QQ" name="qq" placeholder="" />
-          <ProFormText label="邮箱" name="email" placeholder="" />
-        </Col>
-      </Row>
-      <Row>
-        <Col span={12}>
-          <ProFormText label="办公室" name="office" placeholder="" />
-        </Col>
-        <Col span={12}>
-          <ProFormSelect
-            name="sourceId"
-            label="来源"
-            placeholder=""
-            rules={[{ message: '来源' }]}
-            options={sourceList}
-          />
-        </Col>
-      </Row>
-      <Row>
-        <Col span={12}>
-          <ProFormText label="客户地址" name="address" placeholder="" />
-          <ProFormText label="客户地标" name="landmarks" placeholder="" />
-        </Col>
-        <Col span={12}>
-          <ProFormText label="客户乘车" name="ride" placeholder="" />
-          <ProFormText label="客户住宿" name="stay" placeholder="" />
-        </Col>
-      </Row>
+            <Form.Item
+              label="手机"
+              name="telephone"
+              validateStatus={validStatusFtl}
+              hasFeedback
+              rules={[{ required: true, message: '请输入手机号码' }]}
+            >
+              <TelephoneFormItem validateFn={status => setValidStatusFtl(status)} />
+            </Form.Item>
+            <ProFormText
+              label="电话"
+              name="phone"
+              rules={[{ message: '请输入电话/座机号' }]}
+              placeholder=""
+            />
+          </Col>
+          <Col span={12}>
+            <ProFormText label="昵称" name="niceName" placeholder="" />
+            <ProFormText label="职位" name="position" placeholder="" />
+            <ProFormText label="QQ" name="qq" placeholder="" />
+            <ProFormText label="邮箱" name="email" placeholder="" />
+          </Col>
+        </Row>
+        <Row>
+          <Col span={12}>
+            <ProFormText label="办公室" name="office" placeholder="" />
+          </Col>
+          <Col span={12}>
+            <ProFormSelect
+              name="sourceId"
+              label="来源"
+              placeholder=""
+              rules={[{ message: '来源' }]}
+              options={sourceList}
+            />
+          </Col>
+        </Row>
+        <Row>
+          <Col span={12}>
+            <ProFormText label="客户地址" name="address" placeholder="" />
+            <ProFormText label="客户地标" name="landmarks" placeholder="" />
+          </Col>
+          <Col span={12}>
+            <ProFormText label="客户乘车" name="ride" placeholder="" />
+            <ProFormText label="客户住宿" name="stay" placeholder="" />
+          </Col>
+        </Row>
 
-      <ProFormTextArea label="备注" name="mark" placeholder="" />
-    </ModalDragForm>
+        <ProFormTextArea label="备注" name="mark" placeholder="" />
+      </Form>
+    </Modal>
   )
 }
 

+ 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>
   )

+ 73 - 62
src/pages/Customer/Client/components/ClientDetail/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 } from 'react'
 import ContanctForm from './Form.jsx'
 import ContanctTabList from './TabList.jsx'
@@ -9,9 +9,17 @@ import { connect } from 'umi'
 import { Up, Down } from '@icon-park/react'
 import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
 
-const ContactDetail = props => {
-  const { dispatch, updateKey = 'client', refresh, visible, dataId = '', orderIds = [] } = props
-  const shouldUpdate = refresh[updateKey] || false
+const ClientDetail = props => {
+  const {
+    refresh,
+    visible,
+    dispatch,
+    updateKey = 'client',
+    dataId = '',
+    orderIds = [],
+    ...resetDrawerProps
+  } = props
+  const shouldUpdate = refresh?.[updateKey] || false
   const [state, setState] = useState({
     loading: false,
     client: {},
@@ -48,66 +56,69 @@ const ContactDetail = props => {
   }, [visible])
 
   return (
-    <Spin spinning={state.loading}>
-      <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>
+    <Drawer {...resetDrawerProps} visible={visible} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <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">
+                <ContanctForm client={state.client} updateKey={updateKey} />
               </div>
-            ) : null}
-            <div className="sheet-left-panel pr-4">
-              <ContanctForm client={state.client} updateKey={updateKey} />
-            </div>
-          </Col>
-          <Col
-            span={15}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 15 }}
-            // xl={{ span: 15 }}
-            className="sheet-box-right">
-            <ContanctTabList
-              clientId={state.client.id}
-              software={state.software}
-              updateKey={updateKey}
-            />
-            <ContanctLowerList log={state.log} servicelist={state.serviceLog} />
-          </Col>
-        </Row>
-      </div>
-    </Spin>
+            </Col>
+            <Col
+              span={15}
+              // sm={{ span: 24 }}
+              // md={{ span: 24 }}
+              // lg={{ span: 15 }}
+              // xl={{ span: 15 }}
+              className="sheet-box-right"
+            >
+              <ContanctTabList
+                clientId={state.client.id}
+                software={state.software}
+                updateKey={updateKey}
+              />
+              <ContanctLowerList log={state.log} servicelist={state.serviceLog} />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
   )
 }
 
-export default connect(({ refresh, single }) => ({
-  visible: single.drawer.visible,
+export default connect(({ refresh }) => ({
   refresh
-}))(ContactDetail)
+}))(ClientDetail)

+ 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>
   )
 }
 

+ 27 - 47
src/pages/Customer/Client/index.jsx

@@ -1,11 +1,7 @@
-import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
-import AddClient from '@/pages/Customer/Client/components/AddClient'
 import { Input, Button, message, Tooltip } from 'antd'
 import { connect, useModel } from 'umi'
 import React, { useEffect, useState, useRef, useMemo } from 'react'
 import consts from '@/consts'
-import { useModal } from '@/components/Modal'
 import LazyCascader, { formatValues } from '@/components/LazyCascader'
 import PersonLabel from '../Company/components/PersonLabel'
 import {
@@ -22,9 +18,11 @@ import { PermDataTypeEunm } from '../Company/components/PermSelect'
 import BasicTable from '@/components/Table'
 import { getPermAuthCache } from '@/utils/auth'
 // import FilterCascader from '@/components/Table/src/components/FilterCascader'
-
+import { useModal } from '@/components/ModalStore'
+import { Plus } from '@icon-park/react'
 const Client = props => {
-  const { toggleDrawer, setDrawerProps } = useModal()
+  const dispatchModal = useModal()
+  // const { toggleDrawer, setDrawerProps } = useModal()
   const {
     personTagColorMap,
     teamTagColorMap,
@@ -109,6 +107,7 @@ const Client = props => {
   }
 
   const [defaultPermAuthCache] = getPermAuthCache(PermDataTypeEunm.CUSTOMER)
+
   // 重置到默认值,包括表单
   const initData = () => {
     tRef.current?.reset()
@@ -126,43 +125,10 @@ const Client = props => {
       message.success(msg)
       initData()
     }
-  }
-
-  // 展示drawer
-  const showDrawer = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <ContactDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
-  }
-
-  // 展示单位
-  const showDrawerComapny = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh'
-        // overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={id} orderIds={state.orderIds} />
-    })
-    toggleDrawer()
+    return code === consts.RET_CODE.SUCCESS
   }
 
   const columns = [
-    // {
-    //   title: '关键字',
-    //   dataIndex: 'search',
-    //   hideInTable: true,
-    //   search: false
-    // },
     {
       title: '客户',
       dataIndex: 'clientName',
@@ -171,7 +137,9 @@ const Client = props => {
       fixed: 'left',
       render: (clientName, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
+          onClick={() =>
+            dispatchModal('D_CLIENT_DETAIL', { dataId: record.id, orderIds: state.orderIds })
+          }
           className="text-primary cursor-pointer hover:text-[#967bbd]"
         >
           {clientName}
@@ -189,7 +157,12 @@ const Client = props => {
       render: (companyName, record) =>
         record.companyId !== consts.ENCRYPTION_ZERO ? (
           <span
-            onClick={() => showDrawerComapny(record.companyId)}
+            onClick={() =>
+              dispatchModal('D_COMPANY_DETAIL', {
+                dataId: record.companyId,
+                orderIds: state.orderIds
+              })
+            }
             className="text-primary cursor-pointer hover:text-[#967bbd]"
           >
             {companyName}
@@ -605,12 +578,19 @@ const Client = props => {
               showFooter={true}
               className="hover:bg-[rgba(0,0,0,0.1)]"
             />,
-            <AddClient
-              modalProps={{ zIndex: 1050 }}
-              onConfirm={handleAddClient}
+            <Button
+              type="primary"
               key="addClientBtn"
-              reload={() => tRef.current?.reload()}
-            />
+              onClick={() =>
+                dispatchModal('M_CLIENT_ADD', {
+                  onConfirm: handleAddClient,
+                  reload: () => tRef.current?.reload()
+                })
+              }
+            >
+              <Plus className="mr-1" />
+              客户
+            </Button>
           ]
         }}
         columnsStateMap={columnsStateMap}

+ 95 - 73
src/pages/Customer/Company/components/AddCompany/index.jsx

@@ -1,24 +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 } from '@ant-design/pro-form'
-import { Plus } from '@icon-park/react'
 import { connect } from 'umi'
 import { ChangeCompMap } from '../ChangeCompany'
-import ModalDragForm from '@/components/Modal/src/components/ModalDragForm'
 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' }
@@ -32,7 +34,7 @@ const AddCompanyModal = ({
           payload: defaultValue.districtIds
         })
       }
-      formRef.current.setFieldsValue(defaultValue)
+      formRef?.setFieldsValue(defaultValue)
     }
     const getNatures = () => {
       dispatch({
@@ -41,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 (
-    <ModalDragForm
-      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 = {}
@@ -64,64 +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>
-    </ModalDragForm>
+    >
+      <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>
   )
 }
 

+ 10 - 30
src/pages/Customer/Company/components/ChangeCompany/index.jsx

@@ -1,13 +1,12 @@
-import { useModal } from '@/components/Modal'
+// import { useModal } from '@/components/Modal'
 import { LinkOne, LinkInterrupt, Switch } from '@icon-park/react'
 import { Card, Modal, Tooltip } from 'antd'
 import React from 'react'
 import styles from './index.less'
-import SearchModal from '@/pages/Customer/Company/components/ConnectCompany'
 import { apiDelCustomer } from '@/services/customer'
 import { useDispatch } from 'dva'
 import consts from '@/consts'
-import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
+import { useModal } from '@/components/ModalStore'
 
 export const ChangeCompMap = {
   CLIENT: {
@@ -25,7 +24,7 @@ export const ChangeCompMap = {
 }
 const ChangeCompanyInput = props => {
   const dispatch = useDispatch()
-  const { toggleModal, setModalProps, toggleDrawer, setDrawerProps } = useModal()
+  const dispatchModal = useModal()
   const {
     dataSource: {
       customerId,
@@ -47,20 +46,12 @@ const ChangeCompanyInput = props => {
     })
   }
   const handleConnectCustomer = () => {
-    setModalProps({
-      zIndex: 1002,
-      width: '60vw',
-      modalRender: () => (
-        <SearchModal
-          onSelect={refreshClient}
-          dataId={dataId}
-          preUrl={actionPayload}
-          defaultAddibleValue={defaultValue}
-        />
-      ),
-      onCancel: () => toggleModal()
+    dispatchModal('M_CONNECT_COMPANY', {
+      onSelect: refreshClient,
+      dataId,
+      preUrl: actionPayload,
+      defaultAddibleValue: defaultValue
     })
-    toggleModal(true)
   }
   const notValueRender = showConnectIcon && (
     <div onClick={handleConnectCustomer} className={styles.notCompanyContent}>
@@ -71,7 +62,6 @@ const ChangeCompanyInput = props => {
 
   const removeCustomer = () => {
     Modal.confirm({
-      zIndex: 1002,
       title: '确认移除',
       content: (
         <p>
@@ -88,19 +78,9 @@ const ChangeCompanyInput = props => {
   }
 
   const handleCompanyClick = () => {
-    toggleDrawer()
-    setDrawerProps({
-      zIndex: 1001,
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <CompanyDetail dataId={customerId} />
-    })
-    toggleDrawer()
+    dispatchModal('D_COMPANY_DETAIL', { dataId: customerId })
   }
+
   const normalValueRender = (
     <Card size="small">
       <div className="flex justify-between">

+ 6 - 4
src/pages/Customer/Company/components/CompanyDetail/SyncClient.jsx

@@ -93,24 +93,26 @@ const SyncClient = ({ customer, client }) => {
         ghost
         type="primary"
         loading={loading}
-        onClick={() => setState({ ...state, visible: true, loading: true })}>
+        onClick={() => setState({ ...state, visible: true, loading: true })}
+      >
         <Copy theme="two-tone" fill={['#333', '#886ab5']} />
         <span className="ml-1">同步地址信息</span>
         {/* <div className="flex items-center justify-center">
         </div> */}
       </Button>
       <Modal
-        zIndex={1003}
         width="70%"
         title={`同步 ${customer.companyName} 信息`}
         // getContainer={false}
         visible={visible}
         onCancel={() => setState({ ...state, visible: false, loading: false })}
-        onOk={handleOnConfirm}>
+        onOk={handleOnConfirm}
+      >
         <div className="rounded-3 p-4 mb-2 pt-0">
           <Checkbox.Group
             defaultValue={checkValues}
-            onChange={e => setState({ ...state, checkValues: e })}>
+            onChange={e => setState({ ...state, checkValues: e })}
+          >
             <div className="flex flex-nowrap">
               <Checkbox value="district">
                 <div className="w-100px text-left">地区</div>

+ 51 - 74
src/pages/Customer/Company/components/CompanyDetail/TabList.jsx

@@ -1,26 +1,23 @@
 /* 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 } from 'antd'
+import { Tabs, message, Dropdown, Menu, Typography, Button } from 'antd'
 import { Table } from '@arco-design/web-react'
 import '@arco-design/web-react/dist/css/arco.css'
 import styles from './index.less'
-import AddContact from '@/pages/Customer/Client/components/AddClient'
 import { apiAddClient, apiAddCustomerService, updateClient } from '@/services/customer'
 import { formatValues } from '@/components/LazyCascader'
 import consts from '@/consts'
 import ProTable from '@ant-design/pro-table'
-import { useModal } from '@/components/Modal'
 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'
 import { DownOutlined } from '@ant-design/icons'
 import { ProductLabel } from '@/pages/Product/Lock/LockStore/index'
-// import VirtualTable from '@/components/Table/src/VirtualTable'
+import { useModal } from '@/components/ModalStore'
+import { Plus } from '@icon-park/react'
+const { Text } = Typography
 
 const CompanyTabList = ({
   initData,
@@ -32,62 +29,15 @@ const CompanyTabList = ({
   updateKey
 }) => {
   const dispatch = useDispatch()
-  const { toggleDrawer, setDrawerProps } = useModal()
+  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,
@@ -157,10 +107,7 @@ const CompanyTabList = ({
           value: item
         }))
       ),
-      onFilter: (value, item) => item.department === value,
-      onFilterDropdownVisibleChange: visible => {
-        console.log(visible)
-      }
+      onFilter: (value, item) => item.department === value
     },
     {
       title: '姓名',
@@ -171,7 +118,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>
@@ -213,7 +163,13 @@ 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
@@ -229,7 +185,7 @@ const CompanyTabList = ({
               {clientName}
             </span>
           )}
-        </>
+        </span>
       )
     },
     {
@@ -309,8 +265,19 @@ const CompanyTabList = ({
       width: 185,
       render: (text, record) => (
         <span
+<<<<<<< HEAD
+          onClick={() => showDrawerBusiness(record.id)}
+          className="text-primary cursor-pointer hover:text-[#967bbd]">
+=======
+<<<<<<< HEAD
+          onClick={() => dispatchModal('D_BUSINESS_DETAIL', { dataId: record.id })}
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
+=======
           onClick={() => showDrawerBusiness(record.id)}
           className="text-primary cursor-pointer hover:text-[#967bbd]">
+>>>>>>> 6b1c324... fix: 客户、单位抽屉表格宽度的调整
+>>>>>>> 4bb3d4dec0c6c298c57baf1d23b6189be6e0ae15
           {text}
         </span>
       )
@@ -435,17 +402,27 @@ const CompanyTabList = ({
         </Tabs>
       </div>
       <div className="sheet-btns pl-15px pt-15px flex items-center">
-        <AddContact
-          onConfirm={handleAddClient}
-          buttonProps={{ size: 'small', ghost: 'true' }}
-          defaultValues={{
-            districtIds: customer.districtIds,
-            stay: customer.stay,
-            ride: customer.ride,
-            address: customer.address,
-            landmarks: customer.landmarks
-          }}
-        />
+        <Button
+          type="primary"
+          className="mr-1"
+          size="small"
+          ghost
+          onClick={() =>
+            dispatchModal('M_CLIENT_ADD', {
+              onConfirm: handleAddClient,
+              defaultValues: {
+                districtIds: customer.districtIds,
+                stay: customer.stay,
+                ride: customer.ride,
+                address: customer.address,
+                landmarks: customer.landmarks
+              }
+            })
+          }
+        >
+          <Plus className="mr-1" />
+          客户
+        </Button>
         <AddRecord onConfirm={handleAddCustomerService} />
         <SyncClient customer={customer} client={client.client} />
       </div>

+ 78 - 70
src/pages/Customer/Company/components/CompanyDetail/index.jsx

@@ -1,5 +1,5 @@
 import React, { useState, useEffect } from 'react'
-import { Row, Col, Spin, Tooltip } from 'antd'
+import { Row, Col, Spin, Tooltip, Drawer } from 'antd'
 import consts from '@/consts'
 import { apiCompanyDetail } from '@/services/customer'
 import CompanyForm from './Form'
@@ -10,8 +10,16 @@ import { Up, Down } from '@icon-park/react'
 import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
 
 const CompanyDetail = props => {
-  const { dispatch, updateKey = 'company', refresh, visible, dataId = '', orderIds = [] } = props
-  const shouldUpdate = refresh[updateKey] || false
+  const {
+    visible,
+    dispatch,
+    updateKey = 'company',
+    dataId = '',
+    orderIds = [],
+    refresh,
+    ...resetDrawerProps
+  } = props
+  const shouldUpdate = refresh?.[updateKey] || false
   const [state, setState] = useState({
     loading: false,
     customer: {},
@@ -45,75 +53,75 @@ const CompanyDetail = props => {
     visible && initData(dataId)
   }, [visible])
   return (
-    <Spin spinning={state.loading}>
-      <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}
+    <Drawer {...resetDrawerProps} visible={visible} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <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">
-              <CompanyForm customer={state.customer} updateKey={updateKey} />
-            </div>
-          </Col>
-          <Col
-            span={15}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 15 }}
-            // xl={{ span: 15 }}
-            flex={{ flexDirection: 'column' }}
-            className="sheet-box-right">
-            <CompanyTabList
-              updateKey={updateKey}
-              initData={initData}
-              customerId={flipConsts.curId}
-              software={state.software}
-              client={state.client}
-              customer={state.customer}
-              business={state.business}
-            />
-            <CompanyLowerList log={state.log} servicelist={state.serviceLog} />
-          </Col>
-        </Row>
-      </div>
-    </Spin>
+              <div className="sheet-left-panel pr-4">
+                <CompanyForm customer={state.customer} updateKey={updateKey} />
+              </div>
+            </Col>
+            <Col
+              span={15}
+              // sm={{ span: 24 }}
+              // md={{ span: 24 }}
+              // lg={{ span: 15 }}
+              // xl={{ span: 15 }}
+              flex={{ flexDirection: 'column' }}
+              className="sheet-box-right"
+            >
+              <CompanyTabList
+                updateKey={updateKey}
+                initData={initData}
+                customerId={flipConsts.curId}
+                software={state.software}
+                client={state.client}
+                customer={state.customer}
+                business={state.business}
+              />
+              <CompanyLowerList log={state.log} servicelist={state.serviceLog} />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
   )
 }
 
-// export default index
-export default connect(({ refresh, single }) => ({
-  refresh,
-  visible: single.drawer.visible
-  // departments: staff.departments,
-  // departmentsMap: staff.departmentsMap
+export default connect(({ refresh }) => ({
+  refresh
 }))(CompanyDetail)

+ 24 - 17
src/pages/Customer/Company/components/ConnectCompany/index.jsx

@@ -1,19 +1,24 @@
-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 './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'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
 
-const ConnectCompany = ({ 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,
@@ -54,11 +59,6 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
   }
 
   const { run: handleInputChange } = useDebounceFn(onChange)
-  const closeModal = () => {
-    dispatch({
-      type: 'single/changeModal'
-    })
-  }
 
   const addConfirm = async values => {
     const payload = formatValues(values)
@@ -67,7 +67,7 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
       if (Object.hasOwnProperty.call(values, `${preUrl}Id`)) {
         message.success('新增成功并且绑定成功')
         onSelect(values.companyName)
-        closeModal()
+        onCancel()
       } else {
         message.success(msg)
         initData()
@@ -80,7 +80,7 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
     const { code = -1 } = await apiChangeCustomer(preUrl, { id: dataId, customerId })
     if (code === consts.RET_CODE.SUCCESS) {
       onSelect()
-      closeModal()
+      onCancel()
     }
   }
 
@@ -102,7 +102,10 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
   }
 
   return (
-    <CustomModal
+    <Modal
+      {...resetModalProps}
+      onCancel={onCancel}
+      width="60vw"
       title={
         <Input
           prefix={<SearchOutlined />}
@@ -110,12 +113,15 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
           placeholder="输入单位名称搜索"
           onChange={handleInputChange}
         />
-      }>
+      }
+      footer={false}
+    >
       <div
         className={styles.modalContent}
         ref={scrollRef}
         onScroll={handleListScroll}
-        style={{ paddingBottom: 0 }}>
+        style={{ paddingBottom: 0 }}
+      >
         <Spin spinning={state.laoding}>
           {state.customer.map(item => (
             <div key={item.id} className={styles.card}>
@@ -126,7 +132,8 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
                   title="确认关联ta"
                   onConfirm={() => connectCustomer(item.id)}
                   okText="确认"
-                  cancelText="取消">
+                  cancelText="取消"
+                >
                   <Button type="primary" size="small">
                     关联
                   </Button>
@@ -147,7 +154,7 @@ const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
           />
         </div>
       )}
-    </CustomModal>
+    </Modal>
   )
 }
 

+ 2 - 4
src/pages/Customer/Company/components/ConnectCompany/index.less

@@ -3,11 +3,9 @@
 }
 
 .modalContent {
-  height: 63vh;
   max-height: 63vh;
-  padding: 1.5rem;
+  padding: 0;
   overflow-y: auto;
-  border-bottom: 1px solid #dee2e6;
   :global(.ant-transfer-operation > .ant-btn) {
     height: 20rem;
     padding: 0 5px;
@@ -38,7 +36,7 @@
 }
 
 .modalFooter {
-  padding: 1rem;
+  padding: 1rem 1rem 0 1rem;
 }
 
 .removeTreeSwitcher {

+ 31 - 34
src/pages/Customer/Company/components/CustomPerm.jsx

@@ -1,15 +1,11 @@
-/* eslint-disable no-underscore-dangle */
-/* eslint-disable consistent-return */
-import { Button, message, Transfer, Tree } from 'antd'
+import { Button, message, Modal, Transfer, Tree } from 'antd'
 import React, { useMemo, useState, useEffect } from 'react'
 import styles from './ConnectCompany/index.less'
 import { DeleteOutlined } from '@ant-design/icons'
 import consts from '@/basic/consts'
-import { useDispatch } from 'umi'
 import { queryDepartmentStaffList } from '@/services/hr'
 import { useWindowSizeFn } from '@/hooks/event/useWindomSizeFn'
 import { isEmpty, isNull, isNullOrUnDef } from '@/utils/is'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
 
 const isChecked = (selectedKeys, eventKey) => selectedKeys.includes(eventKey)
 
@@ -41,7 +37,7 @@ const generateTree = (treeNodes = [], checkedKeys = []) =>
     return node
   })
 
-const CustomPerm = ({ onConfirm, defaultValues = [] }) => {
+const CustomPerm = ({ onConfirm, defaultValues = [], onCancel, ...resetModalProps }) => {
   const [state, setState] = useState({
     dataSource: [],
     leftTargetId: null,
@@ -89,12 +85,6 @@ const CustomPerm = ({ onConfirm, defaultValues = [] }) => {
     const height = calcTreeHeight()
     setState({ ...state, height })
   })
-  const dispatch = useDispatch()
-  const closeModal = () => {
-    dispatch({
-      type: 'single/changeModal'
-    })
-  }
 
   const handleOnSearch = (direction, value) => {
     const targetNode = state.transferDataSource.find(item => item.title.indexOf(value) > -1)
@@ -201,7 +191,34 @@ const CustomPerm = ({ onConfirm, defaultValues = [] }) => {
     return []
   }, [state.leftTargetId, state.treeKeys.length, state.targetKeys.length])
   return (
-    <CustomModal title="自定义展示数据">
+    <Modal
+      {...resetModalProps}
+      onCancel={onCancel}
+      width="60vw"
+      title="自定义展示数据"
+      footer={
+        <>
+          <Button className="mr-4" onClick={onCancel}>
+            取消
+          </Button>
+
+          <Button
+            type="primary"
+            onClick={() => {
+              if (!state.targetKeys.length) {
+                return message.warning('目标栏尚未有员工,操作无效')
+              }
+              if (onConfirm) {
+                onConfirm({ staffIds: state.targetKeys, dataPermission: 'custom' })
+              }
+              onCancel()
+            }}
+          >
+            确定
+          </Button>
+        </>
+      }
+    >
       <div className={styles.modalContent}>
         <Transfer
           showSearch
@@ -338,27 +355,7 @@ const CustomPerm = ({ onConfirm, defaultValues = [] }) => {
           }}
         </Transfer>
       </div>
-      <div className={[styles.modalFooter, 'text-right'].join(' ')}>
-        <Button className="mr-4" onClick={closeModal}>
-          取消
-        </Button>
-
-        <Button
-          type="primary"
-          onClick={() => {
-            if (!state.targetKeys.length) {
-              return message.warning('目标栏尚未有员工,操作无效')
-            }
-            if (onConfirm) {
-              onConfirm({ staffIds: state.targetKeys, dataPermission: 'custom' })
-            }
-            closeModal()
-          }}
-        >
-          确定
-        </Button>
-      </div>
-    </CustomModal>
+    </Modal>
   )
 }
 

+ 9 - 17
src/pages/Customer/Company/components/PermSelect.tsx

@@ -1,13 +1,12 @@
-import { useModal } from '@/components/Modal'
 import { useModel } from 'umi'
 import { Button, Dropdown, Menu } from 'antd'
-import CustomPerm from './CustomPerm'
 import { getPermAuthCache, setAuthCache } from '@/utils/auth'
 import { PERMISSION_SELECT_KEY } from '@/utils/cache/cacheEnum'
 import type { SelectProps } from 'antd'
 import type { MainMenuKeyEnum } from '@/utils/cache/cacheEnum'
 import { DownOutlined } from '@ant-design/icons'
 import { useState } from 'react'
+import { useModal } from '@/components/ModalStore'
 
 export const PermDataTypeEunm = {
   CUSTOMER: 'customer',
@@ -21,8 +20,8 @@ interface PermSelectProps extends SelectProps {
 }
 
 const PermSelect: React.FC<PermSelectProps> = ({ dataType, onConfirm }) => {
+  const dispatchModal = useModal()
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
-  const { toggleModal, setModalProps } = useModal()
   const options = [...(permData[dataType] || [])]
   const [defaultValue, defaultStaffIds, permAuthCache] = getPermAuthCache(dataType)
 
@@ -34,21 +33,14 @@ const PermSelect: React.FC<PermSelectProps> = ({ dataType, onConfirm }) => {
 
   const handleOnChange = e => {
     if (e === 'custom') {
-      setModalProps({
-        width: '60vw',
-        modalRender: () => (
-          <CustomPerm
-            defaultValues={state.staffIds || []}
-            onConfirm={({ staffIds, dataPermission }) => {
-              setState({ ...state, staffIds, currKey: e })
-              onConfirm({ staffIds, dataPermission })
-              setAuthCache(PERMISSION_SELECT_KEY, { ...permAuthCache, [dataType]: staffIds })
-            }}
-          />
-        ),
-        onCancel: () => toggleModal()
+      dispatchModal('M_CUSTOM_PERM', {
+        defaultValues: state.staffIds || [],
+        onConfirm: ({ staffIds, dataPermission }) => {
+          setState({ ...state, staffIds, currKey: e })
+          onConfirm({ staffIds, dataPermission })
+          setAuthCache(PERMISSION_SELECT_KEY, { ...permAuthCache, [dataType]: staffIds })
+        }
       })
-      toggleModal()
 
       return
     }

+ 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>
   )
 }
 

+ 4 - 17
src/pages/Hr/Employee/index.jsx

@@ -1,16 +1,16 @@
 import React, { useState } from 'react'
 import consts from '@/consts'
 import { Button, Popconfirm, message } from 'antd'
-import { useModal } from '@/components/Modal'
 import RoleMenu from '@/pages/Hr/Employee/components/RoleMenu'
 import { queryStaff } from '@/services/staff'
-import EmployeeDetail from '@/pages/Hr/Employee/components/EmployeeDetail'
 import { delDepartment } from '@/services/hr'
 import { connect, useAccess } from 'umi'
 import BasicTable from '@/components/Table'
+import { useModal } from '@/components/ModalStore'
 
 const Employee = props => {
   const { dispatch } = props
+  const dispatchModal = useModal()
   const [state, setState] = useState({
     params: { id: '0' }
   })
@@ -19,20 +19,7 @@ const Employee = props => {
       type: 'staff/fetchDepartments'
     })
   }
-  const { toggleDrawer, setDrawerProps } = useModal()
-  // 展示员工详情
-  const showDrawer = id => {
-    setDrawerProps({
-      closable: true,
-      onClose: () => toggleDrawer(),
-      bodyStyle: {
-        height: '100vh',
-        overflowY: 'hidden'
-      },
-      children: <EmployeeDetail dataId={id} />
-    })
-    toggleDrawer()
-  }
+
   const columns = [
     {
       title: '工号',
@@ -47,7 +34,7 @@ const Employee = props => {
       width: 50,
       render: (username, record) => (
         <span
-          onClick={() => showDrawer(record.id)}
+          onClick={() => dispatchModal('D_EMPLOYEE_DETAIL', { dataId: record.id })}
           className="text-primary cursor-pointer hover:text-[#967bbd]"
         >
           {username}

+ 72 - 87
src/pages/Product/Cloud/components/Detail/index.jsx

@@ -1,17 +1,16 @@
 import React, { useState, useEffect } from 'react'
-import { Row, Col, Button, Tooltip, Spin, Modal } from 'antd'
+import { Row, Col, Button, Tooltip, Spin, Modal, Drawer } from 'antd'
 import { LinkOne, LinkInterrupt } from '@icon-park/react'
 import { connect } from 'umi'
-import { useModal } from '@/components/Modal'
 import consts from '@/consts'
 import Form from './Form'
 import ClientDetail from '@/pages/Customer/Client/components/ClientDetail/Form'
 import LowerList from './LowerList'
 import TabList from './TabList'
-import ConnectClient from '@/pages/Customer/Client/components/ConnectClient'
 import { apiRoadpricingDetail, apiRoadPricingUnLinkClient } from '@/services/product'
+import { useModal } from '@/components/ModalStore'
 
-const Detail = props => {
+const CloudDetail = props => {
   const {
     dispatch,
     updateKey = 'cloud',
@@ -19,10 +18,11 @@ const Detail = props => {
     visible,
     dataId = '',
     projectType,
-    filterTag = true
+    filterTag = true,
+    ...resetDrawerProps
   } = props
-  const { toggleModal, setModalProps } = useModal()
-  const shouldUpdate = refresh[updateKey] || false
+  const dispatchModal = useModal()
+  const shouldUpdate = refresh?.[updateKey] || false
   const refreshClient = () => {
     dispatch({
       type: 'refresh/commitAction',
@@ -54,21 +54,13 @@ const Detail = props => {
     }
   }
   const handleConnectClient = () => {
-    setModalProps({
-      zIndex: 1002,
-      width: '60vw',
-      modalRender: () => (
-        <ConnectClient
-          onSelect={refreshClient}
-          dataId={state.cloudUser.ssoId}
-          preUrl="RoadPricing"
-          showFooter={false}
-          otherParams={{ projectType }}
-        />
-      ),
-      onCancel: () => toggleModal()
+    dispatchModal('M_CONNECT_CLIENT', {
+      onSelect: refreshClient,
+      dataId: state.cloudUser.ssoId,
+      preUrl: 'RoadPricing',
+      showFooter: false,
+      otherParams: { projectType }
     })
-    toggleModal(true)
   }
   // 移除cld客户
   const pricingUnLinkClient = clientId => {
@@ -97,75 +89,68 @@ const Detail = props => {
   useEffect(() => {
     visible && initData(dataId)
   }, [visible])
+
   return (
-    <Spin spinning={state.loading}>
-      <div className="sheet-box">
-        <Row>
-          <Col
-            span={9}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 9 }}
-            // xl={{ span: 9 }}
-            className="sheet-box-left"
-          >
-            <div className="sheet-left-panel pr-4">
-              <Form cloudUser={state.cloudUser} updateKey={updateKey} projectType={projectType} />
-              {state.cloudUser.cld?.clientId ? (
-                <>
-                  <div className="mt-4">
-                    <ClientDetail client={state.client} filterTag={filterTag} />
-                  </div>
+    <Drawer {...resetDrawerProps} visible={visible} className="zh-drawer">
+      <Spin spinning={state.loading}>
+        <div className="sheet-box">
+          <Row>
+            <Col span={9} className="sheet-box-left">
+              <div className="sheet-left-panel pr-4">
+                <Form cloudUser={state.cloudUser} updateKey={updateKey} projectType={projectType} />
+                {state.cloudUser.cld?.clientId ? (
+                  <>
+                    <div className="mt-4">
+                      <ClientDetail client={state.client} filterTag={filterTag} />
+                    </div>
+                    <div className="text-center mt-6">
+                      <Tooltip placement="right" title="移除CLD客户">
+                        <Button
+                          type="primary"
+                          ghost
+                          size="small"
+                          onClick={() => {
+                            pricingUnLinkClient(state.cloudUser.cld?.clientId)
+                          }}>
+                          <LinkInterrupt size="14" />
+                          <span className="ml-5px">移除CLD客户</span>
+                        </Button>
+                      </Tooltip>
+                    </div>
+                  </>
+                ) : (
                   <div className="text-center mt-6">
-                    <Tooltip placement="right" title="移除CLD客户">
-                      <Button
-                        type="primary"
-                        ghost
-                        size="small"
-                        onClick={() => {
-                          pricingUnLinkClient(state.cloudUser.cld?.clientId)
-                        }}
-                      >
-                        <LinkInterrupt size="14" />
-                        <span className="ml-5px">移除CLD客户</span>
-                      </Button>
-                    </Tooltip>
+                    <Button type="primary" ghost size="small" onClick={handleConnectClient}>
+                      <LinkOne size="14" />
+                      <span className="ml-5px">关联CLD客户</span>
+                    </Button>
                   </div>
-                </>
-              ) : (
-                <div className="text-center mt-6">
-                  <Button type="primary" ghost size="small" onClick={handleConnectClient}>
-                    <LinkOne size="14" />
-                    <span className="ml-5px">关联CLD客户</span>
-                  </Button>
-                </div>
-              )}
-            </div>
-          </Col>
-          <Col
-            span={15}
-            // sm={{ span: 24 }}
-            // md={{ span: 24 }}
-            // lg={{ span: 15 }}
-            // xl={{ span: 15 }}
-            flex={{ flexDirection: 'column' }}
-            className="sheet-box-right"
-          >
-            <TabList
-              compilationList={state.compilationList}
-              cloudUser={state.cloudUser}
-              projectType={projectType}
-              ssoId={state.cloudUser.ssoId}
-            />
-            <LowerList log={state.log} serviceLog={state.serviceLog} />
-          </Col>
-        </Row>
-      </div>
-    </Spin>
+                )}
+              </div>
+            </Col>
+            <Col
+              span={15}
+              // sm={{ span: 24 }}
+              // md={{ span: 24 }}
+              // lg={{ span: 15 }}
+              // xl={{ span: 15 }}
+              flex={{ flexDirection: 'column' }}
+              className="sheet-box-right">
+              <TabList
+                compilationList={state.compilationList}
+                cloudUser={state.cloudUser}
+                projectType={projectType}
+                ssoId={state.cloudUser.ssoId}
+              />
+              <LowerList log={state.log} serviceLog={state.serviceLog} />
+            </Col>
+          </Row>
+        </div>
+      </Spin>
+    </Drawer>
   )
 }
 
-export default connect(({ refresh, single }) => ({
-  refresh,
-  visible: single.drawer.visible
-}))(Detail)
+export default connect(({ refresh }) => ({
+  refresh
+}))(CloudDetail)

+ 13 - 11
src/pages/Product/Cloud/index.jsx

@@ -75,11 +75,12 @@ const Cloud = () => {
       dataIndex: 'mobile',
       key: 'mobile',
       fixed: 'left',
-      width: 80,
+      width: 110,
       render: (text, record) => (
         <span
           onClick={() => showDrawerRoadpricing(record.ssoId)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {text}
         </span>
       )
@@ -89,7 +90,7 @@ const Cloud = () => {
       dataIndex: 'username',
       key: 'username',
       ellipsis: true,
-      width: 60,
+      width: 100,
       search: false
     },
     {
@@ -97,7 +98,7 @@ const Cloud = () => {
       dataIndex: 'real_name',
       key: 'real_name',
       ellipsis: true,
-      width: 60,
+      width: 100,
       search: false
     },
     {
@@ -105,14 +106,14 @@ const Cloud = () => {
       dataIndex: 'qq',
       key: 'qq',
       ellipsis: true,
-      width: 60
+      width: 110
     },
     {
       title: '企业名称',
       dataIndex: 'company',
       key: 'company',
       ellipsis: true,
-      width: 100
+      width: 150
     },
     {
       title: 'CLD客户',
@@ -127,7 +128,7 @@ const Cloud = () => {
       dataIndex: 'customerName',
       key: 'customerName',
       ellipsis: true,
-      width: 100,
+      width: 150,
       renderText: (_, record) => record.cld?.customerName
     },
     {
@@ -160,7 +161,8 @@ const Cloud = () => {
                       )
                   )}
                 </div>
-              }>
+              }
+            >
               {record.all_online_times}
             </Tooltip>
           )
@@ -174,7 +176,7 @@ const Cloud = () => {
       key: 'latestUsed',
       filters: true,
       filterMultiple: false,
-      width: 80,
+      width: 120,
       valueEnum: compilation.reduce((prev, curr) => {
         const obj = { ...prev }
         if (curr._id) {
@@ -200,7 +202,7 @@ const Cloud = () => {
         return obj
       }, {}),
       filterMultiple: false,
-      width: 50
+      width: 80
     },
     {
       title: '注册时间',
@@ -208,7 +210,7 @@ const Cloud = () => {
       key: 'create_time',
       sorter: true,
       ellipsis: true,
-      width: 60,
+      width: 150,
       renderText: text => dayjsFormat(text, 'YYYY-MM-DD HH:mm')
     },
     {

+ 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


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

@@ -0,0 +1,113 @@
+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,
+    dispatch,
+    dataId = '',
+    refresh,
+    orderIds = [],
+    updateKey = 'software',
+    ...resetDrawerProps
+  } = props
+  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} 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;
-      }
-    }
-  }
-}

+ 8 - 7
src/pages/Product/Lock/LockStore/components/ReceiveLock.jsx

@@ -1,14 +1,12 @@
-import { Button, Input, message } from 'antd'
+import { Button, Input, message, Modal } from 'antd'
 import React, { useState, useRef } from 'react'
 import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
 import consts from '@/basic/consts'
 import { apiReceiveOldLock, queryOldLockList } from '@/services/product'
 import { ProductLabel } from '../index'
 import ProTable from '@ant-design/pro-table'
-import CustomModal from '@/components/Modal/src/components/CustomModal'
-// import { Attention } from '@icon-park/react'
 
-const ReceiveLock = ({ refresh }) => {
+const ReceiveLock = ({ refresh, ...resetModalProps }) => {
   const tRef = useRef()
   const [tParams, setParams] = useState({
     search: null
@@ -52,7 +50,10 @@ const ReceiveLock = ({ refresh }) => {
     setParams({ ...tParams, search: val })
   }
   return (
-    <CustomModal
+    <Modal
+      width="50vw"
+      {...resetModalProps}
+      bodyStyle={{ padding: '24px 24px 0' }}
       title={
         <div className="flex items-center justify-between">
           <span>
@@ -62,7 +63,7 @@ const ReceiveLock = ({ refresh }) => {
             </Tooltip> */}
           </span>
           <Input.Search
-            style={{ width: '300px' }}
+            style={{ width: '300px', marginRight: '50px' }}
             placeholder="输入锁号/产品进行搜索"
             allowClear
             onSearch={handleOnSearch}
@@ -91,7 +92,7 @@ const ReceiveLock = ({ refresh }) => {
           }}
         />
       </div>
-    </CustomModal>
+    </Modal>
   )
 }
 

+ 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

+ 24 - 128
src/pages/Product/Lock/LockStore/index.jsx

@@ -1,21 +1,14 @@
 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 +28,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,27 +48,11 @@ 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()
   }
-  const showReceiveLockModal = () => {
-    setModalProps({
-      width: '60vw',
-      modalRender: () => <ReceiveLock refresh={refreshData} />,
-      onCancel: () => toggleModal()
-    })
-    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 +81,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 +89,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 +207,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 +222,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 +237,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>
       )
@@ -368,14 +269,6 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
     }
   }
 
-  // const dropDownMenClick = ({ key }) => {
-  //   if (key === '1') {
-  //     showReceiveLockModal()
-  //   } else {
-  //     showReceiveNewLockModal()
-  //   }
-  // }
-
   const [defaultPermAuthCache] = getPermAuthCache(PermDataTypeEunm.PRODUCT)
   return (
     <BasicTable
@@ -421,7 +314,10 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
         //   </Button>
         // </Dropdown>
         state.totalOld ? (
-          <Button type="primary" onClick={showReceiveLockModal}>
+          <Button
+            type="primary"
+            onClick={() => dispatchModal('M_RECEIVE_LOCK', { refresh: refreshData })}
+          >
             接收旧锁({state.totalOld})
           </Button>
         ) : null

+ 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_COMPANY_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>个,服务