Bläddra i källkod

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

outaozhen 4 år sedan
förälder
incheckning
636f9af062
25 ändrade filer med 358 tillägg och 107 borttagningar
  1. 3 2
      src/components/LazyCascader/LazyCascader.jsx
  2. 13 4
      src/models/district.js
  3. 11 4
      src/pages/Customer/Business/components/BusinessDetail/Form.jsx
  4. 3 2
      src/pages/Customer/Business/components/BusinessDetail/Step/index.jsx
  5. 17 11
      src/pages/Customer/Business/components/BusinessDetail/TabList.jsx
  6. 14 3
      src/pages/Customer/Business/components/BusinessDetail/index.jsx
  7. 0 1
      src/pages/Customer/Business/index.jsx
  8. 110 0
      src/pages/Customer/Client/components/AddClient/TelephoneFormItem.jsx
  9. 33 17
      src/pages/Customer/Client/components/AddClient/index.jsx
  10. 15 3
      src/pages/Customer/Client/components/ClientDetail/Form.jsx
  11. 33 16
      src/pages/Customer/Company/components/AddCompany/CompanyFormItem.jsx
  12. 23 3
      src/pages/Customer/Company/components/AddCompany/index.jsx
  13. 8 2
      src/pages/Customer/Company/components/ChangeCompany/index.jsx
  14. 6 3
      src/pages/Customer/Company/components/CompanyDetail/TabList.jsx
  15. 7 2
      src/pages/Customer/Company/components/ConnectCompany/index.jsx
  16. 5 3
      src/pages/Hr/Employee/index.jsx
  17. 2 1
      src/pages/workbench/Dashboard/components/BusinessChar.jsx
  18. 2 1
      src/pages/workbench/Dashboard/components/LeaderBoard.jsx
  19. 1 1
      src/pages/workbench/Dashboard/components/RatioPanels.jsx
  20. 6 3
      src/pages/workbench/Dashboard/components/ReminderList.jsx
  21. 2 1
      src/pages/workbench/Dashboard/components/SoftLeaderboard.jsx
  22. 0 0
      src/pages/Workbench/Dashboard/consts.js
  23. 44 22
      src/pages/workbench/Dashboard/index.jsx
  24. 0 0
      src/pages/Workbench/Dashboard/index.less
  25. 0 2
      src/utils/ws.ts

+ 3 - 2
src/components/LazyCascader/LazyCascader.jsx

@@ -125,7 +125,8 @@ const CLazyCascader = props => {
                       item.value.map(v => v.id),
                       item.value
                     )
-                  }>
+                  }
+                >
                   <Tag>{item.name}</Tag>
                 </div>
               ))}
@@ -139,7 +140,7 @@ const CLazyCascader = props => {
   const handleOnPopupVisibleChange = e => {
     setVisible(e)
     // 检测value是为了防止在Form里面的自定义级联组件失效
-    // TODOS 自定义FormItem组件需要接受value以及onChange事件
+    // TODO: 自定义FormItem组件需要接受value以及onChange事件
     if (value && !e && cValue === defaultValue) {
       triggerChange(null)
     }

+ 13 - 4
src/models/district.js

@@ -20,14 +20,23 @@ export default {
         })
       }
     },
-    *fetchWithValues({ payload = [] }, { call, put, select }) {
-      const provinceId = payload[0] //
-      const cityId = payload[1]
+    *fetchWithValues({ payload = [] }, { call, put, select, take }) {
+      const provinceId = payload[0] // 省id
+      const cityId = payload[1] // 市id
+
+      const originalData = yield select(state => state.district.data)
+
+      // TODO: 省级数据初始化
+      if (!originalData?.length) {
+        yield put({ type: 'fetch' })
+        yield take('fetch/@@end') // 直到监听到b结束才继续执行
+      }
+
       const currProvince = yield select(state =>
         state.district.data.find(item => item.id === provinceId)
       )
       // 判断市的数据是否拉取过了
-      if (currProvince && (!currProvince.children || !currProvince.children.length)) {
+      if (currProvince && !currProvince.children?.length) {
         const { code = -1, data = [] } = yield call(queryDistrict, { parentId: provinceId })
         if (code === consts.RET_CODE.SUCCESS) {
           const response = yield call(queryDistrict, { parentId: cityId })

+ 11 - 4
src/pages/Customer/Business/components/BusinessDetail/Form.jsx

@@ -8,7 +8,7 @@ import ChangeCompanyInput, {
 import Step from './Step/index'
 
 const Form = props => {
-  const { business, groupStatus, updateKey } = props
+  const { business, groupStatus, updateKey, isOwner } = props
 
   const isEnd = useMemo(() => {
     return groupStatus.findIndex(item => item.endProcess && item.selected) !== -1
@@ -39,7 +39,9 @@ const Form = props => {
       dataIndex: 'customerId',
       label: '单位名称',
       editCellType: 'custom',
-      customCell: <ChangeCompanyInput dataSource={changeCopInputData} editable={!isEnd} />,
+      customCell: (
+        <ChangeCompanyInput dataSource={changeCopInputData} editable={!isOwner ? false : !isEnd} />
+      ),
       span: 24
     },
     {
@@ -81,14 +83,19 @@ const Form = props => {
           <h2 className="text-2xl pb-4">{business.name}</h2>
         </Col>
         <Col span={2} />
-        <Step statusId={business.businessStatusId} id={business.id} groupStatus={groupStatus} />
+        <Step
+          statusId={business.businessStatusId}
+          id={business.id}
+          groupStatus={groupStatus}
+          isOwner={isOwner}
+        />
       </Row>
       <EditableForm
         dataSource={business}
         columns={columns}
         tartgetUrl="/business/update"
         type={updateKey}
-        editable={!isEnd}
+        editable={!isOwner ? false : !isEnd}
       />
     </div>
   )

+ 3 - 2
src/pages/Customer/Business/components/BusinessDetail/Step/index.jsx

@@ -7,7 +7,7 @@ import { changeGroupStatus } from '@/services/customer'
 import { CloseOne, SmilingFaceWithSquintingEyes } from '@icon-park/react'
 import { MinusCircleOutlined, DownOutlined } from '@ant-design/icons'
 
-const Step = ({ id, statusId, groupStatus = [] }) => {
+const Step = ({ id, statusId, groupStatus = [], isOwner }) => {
   const dispatch = useDispatch()
   const { run: tryChangeStatus } = useRequest(params => changeGroupStatus(params), {
     manual: true,
@@ -97,6 +97,7 @@ const Step = ({ id, statusId, groupStatus = [] }) => {
         >
           <div
             onClick={() => {
+              if (!isOwner) return
               if (!op.isEnd) {
                 if (idx < op.selectedItemIdx) {
                   return
@@ -163,7 +164,7 @@ const Step = ({ id, statusId, groupStatus = [] }) => {
               {stateMap[op.otherItems[op.endItemIdx].key].text}
             </>
           ) : (
-            <Dropdown overlay={menu}>
+            <Dropdown overlay={isOwner ? menu : ''}>
               <div>
                 <span className="mr-1">结束</span>
                 <DownOutlined />

+ 17 - 11
src/pages/Customer/Business/components/BusinessDetail/TabList.jsx

@@ -11,7 +11,7 @@ import { ChangeCompMap } from '@/pages/Customer/Company/components/ChangeCompany
 import { useModal } from '@/components/Modal'
 import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
 
-const ContanctTabList = ({ businessId, clientList }) => {
+const ContanctTabList = ({ businessId, clientList, isOwner }) => {
   const { toggleModal, setModalProps, toggleDrawer, setDrawerProps } = useModal()
   const dispatch = useDispatch()
   const [state, setState] = useState({
@@ -47,7 +47,8 @@ const ContanctTabList = ({ businessId, clientList }) => {
       render: (clientName, record) => (
         <span
           onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {clientName}
         </span>
       )
@@ -128,15 +129,20 @@ const ContanctTabList = ({ businessId, clientList }) => {
         </Tabs>
       </div>
       <div className="sheet-btns pl-15px pt-15px">
-        <AddRecord onConfirm={handleAddService} />
-        <Button
-          type="primary"
-          ghost
-          size="small"
-          className="mr-1"
-          onClick={() => showConnectClientModal()}>
-          <Plus className="mr-1" /> 客户
-        </Button>
+        {isOwner && (
+          <>
+            <AddRecord onConfirm={handleAddService} />
+            <Button
+              type="primary"
+              ghost
+              size="small"
+              className="mr-1"
+              onClick={() => showConnectClientModal()}
+            >
+              <Plus className="mr-1" /> 客户
+            </Button>
+          </>
+        )}
       </div>
     </div>
   )

+ 14 - 3
src/pages/Customer/Business/components/BusinessDetail/index.jsx

@@ -1,16 +1,17 @@
 import { Row, Col, Spin, Tooltip } from 'antd'
-import React, { useState, useEffect } from 'react'
+import React, { useState, useEffect, useMemo } from 'react'
 import Form from './Form'
 import TabList from './TabList'
 import LowerList from './LowerList'
 import { getBusinessDetailById } from '@/services/customer'
 import consts from '@/consts'
-import { connect } from 'umi'
+import { connect, useModel } from 'umi'
 import { Up, Down } from '@icon-park/react'
 import { FlipOverEnum, useFlipOver } from '@/hooks/web/useFlipOver'
 import './index.less'
 
 const Detail = props => {
+  const { initialState } = useModel('@@initialState')
   const { dispatch, updateKey = 'business', refresh, visible, dataId = '', orderIds = [] } = props
   const shouldUpdate = refresh[updateKey] || false
   const [state, setState] = useState({
@@ -22,6 +23,11 @@ const Detail = props => {
     linkClient: {} // 关联的客户
   })
 
+  const isOwner = useMemo(() => {
+    const { staffId } = initialState.currentUser || {}
+    return state.business.staffId === staffId
+  }, [state.business.businessStatusId])
+
   const initData = async id => {
     setState({ ...state, loading: true })
     const {
@@ -89,6 +95,7 @@ const Detail = props => {
             ) : null}
             <div className="sheet-left-panel pr-15px">
               <Form
+                isOwner={isOwner}
                 business={state.business}
                 groupStatus={state.groupStatus}
                 updateKey={updateKey}
@@ -96,7 +103,11 @@ const Detail = props => {
             </div>
           </Col>
           <Col span={14} className="sheet-box-right">
-            <TabList businessId={state.business.id} clientList={state.linkClient.client} />
+            <TabList
+              businessId={state.business.id}
+              clientList={state.linkClient.client}
+              isOwner={isOwner}
+            />
             <LowerList log={state.log} serviceLog={state.serviceLog} />
           </Col>
         </Row>

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

@@ -30,7 +30,6 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading }) => {
 
   const funnelData = useMemo(() => {
     if (!groupList) return null
-    console.log('111', state.params.businessGroupId)
     return groupList
       .find(item => item.value === state.params.businessGroupId)
       ?.items?.filter(item => !item.endProcess)

+ 110 - 0
src/pages/Customer/Client/components/AddClient/TelephoneFormItem.jsx

@@ -0,0 +1,110 @@
+import { useModal } from '@/components/Modal'
+import consts from '@/consts'
+import { queryClient } from '@/services/customer'
+import { useDebounceFn } from 'ahooks'
+import { Input, Alert, Popover } from 'antd'
+import ClientDetail from '../ClientDetail'
+import { useState } from 'react'
+import { validateEnum } from '@/pages/Customer/Company/components/AddCompany/CompanyFormItem'
+
+const TelephoneFormItem = ({ value, onChange, validateFn }) => {
+  const { toggleDrawer, setDrawerProps } = useModal()
+  const [state, setState] = useState({
+    inputVal: value,
+    visible: false,
+    list: null
+  })
+  const triggerChange = changedValue => {
+    onChange?.(changedValue)
+  }
+
+  const queryList = async search => {
+    if (!search) return
+    const { code = -1, data } = await queryClient({ current: 1, pageSize: 20, search })
+    if (code === consts.RET_CODE.SUCCESS) {
+      const { client = [] } = data
+      setState({ ...state, list: client })
+      if (client?.length) {
+        validateFn(validateEnum.Warning)
+      } else {
+        validateFn(validateEnum.Success)
+      }
+    }
+  }
+
+  const { run: handleQueryList, cancel: cancelQuerying } = useDebounceFn(queryList, { wait: 600 })
+
+  const handleOnInputChange = async e => {
+    const val = e.target.value || ''
+    if (!val) {
+      cancelQuerying()
+      setState({ ...state, inputVal: val, list: null, visible: false })
+      validateFn(validateEnum.Error)
+    } else {
+      setState({ ...state, inputVal: val })
+      validateFn(validateEnum.Validating)
+      handleQueryList(val)
+    }
+    triggerChange(val)
+  }
+
+  const showClientDrawer = id => {
+    setDrawerProps({
+      zIndex: 1004,
+      closable: true,
+      onClose: () => toggleDrawer(),
+      bodyStyle: {
+        height: '100vh'
+      },
+      children: <ClientDetail dataId={id} />
+    })
+    toggleDrawer(true)
+  }
+
+  const { visible, list, inputVal } = state
+  return (
+    <Popover
+      zIndex={1003}
+      placement="bottom"
+      visible={list && list.length && visible}
+      onVisibleChange={e => setState({ ...state, visible: e })}
+      title={
+        <Alert
+          message="已存在相同手机号码,请确认是否继续添加"
+          type="warning"
+          style={{ padding: '5px', margin: '10px 0' }}
+        />
+      }
+      trigger="click"
+      content={
+        <ul className="list-none">
+          {list?.map(item => {
+            return (
+              <p key={item.id}>
+                <span
+                  className="text-primary cursor-pointer hover:text-hex-967bbd"
+                  onClick={() => showClientDrawer(item.id)}
+                >
+                  {item.clientName}
+                </span>
+                <span className="mx-1">/</span>
+                <span>{item.districtName?.replaceAll(' / ', ',')}</span>
+              </p>
+            )
+          })}
+        </ul>
+      }
+    >
+      <Input
+        type="text"
+        autoComplete="false"
+        value={inputVal}
+        placeholder="请输入手机号码"
+        onChange={handleOnInputChange}
+        className="company-input"
+      />
+    </Popover>
+  )
+}
+
+export default TelephoneFormItem

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

@@ -6,6 +6,7 @@ import { Plus } from '@icon-park/react'
 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'
 
 const AddClient = props => {
   const {
@@ -23,7 +24,7 @@ const AddClient = props => {
     labelCol: { flex: '100px' }
   }
   const [showDataItem, setShowDataItem] = useState(false)
-
+  const [validStatusFtl, setValidStatusFtl] = useState('')
   return (
     <ModalDragForm
       {...layout}
@@ -56,7 +57,8 @@ const AddClient = props => {
                 }
                 formRef.current && formRef.current.setFieldsValue(values)
                 submit()
-              }}>
+              }}
+            >
               添加并关联
             </Button>
           ) : null
@@ -67,17 +69,20 @@ const AddClient = props => {
         formRef.current?.resetFields()
         !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: '请选择地区' }]}>
+        rules={[{ required: true, message: '请选择地区' }]}
+      >
         <LazyCascader showFooter={true} />
       </Form.Item>
       <Row>
@@ -85,39 +90,50 @@ const AddClient = props => {
           <ProFormSelect
             name="gender"
             label="性别"
+            placeholder=""
             rules={[{ message: '请选择性别' }]}
             options={[
               { label: '男', value: '男' },
               { label: '女', value: '女' }
             ]}
           />
-          <ProFormText label="部门" name="department" />
-          <ProFormText
+          <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=""
           />
-          <ProFormText label="电话" name="phone" rules={[{ message: '请输入电话/座机号' }]} />
         </Col>
         <Col span={12}>
-          <ProFormText label="昵称" name="niceName" />
-          <ProFormText label="职位" name="position" />
-          <ProFormText label="QQ" name="qq" />
-          <ProFormText label="邮箱" name="email" />
+          <ProFormText label="昵称" name="niceName" placeholder="" />
+          <ProFormText label="职位" name="position" placeholder="" />
+          <ProFormText label="QQ" name="qq" placeholder="" />
+          <ProFormText label="邮箱" name="email" placeholder="" />
         </Col>
       </Row>
-      <ProFormText label="办公室" name="office" />
+      <ProFormText label="办公室" name="office" placeholder="" />
       <Row>
         <Col span={12}>
-          <ProFormText label="客户地址" name="address" />
-          <ProFormText label="客户地标" name="landmarks" />
+          <ProFormText label="客户地址" name="address" placeholder="" />
+          <ProFormText label="客户地标" name="landmarks" placeholder="" />
         </Col>
         <Col span={12}>
-          <ProFormText label="客户乘车" name="ride" />
-          <ProFormText label="客户住宿" name="stay" />
+          <ProFormText label="客户乘车" name="ride" placeholder="" />
+          <ProFormText label="客户住宿" name="stay" placeholder="" />
         </Col>
       </Row>
-      <ProFormTextArea label="备注" name="mark" />
+      <ProFormTextArea label="备注" name="mark" placeholder="" />
     </ModalDragForm>
   )
 }

+ 15 - 3
src/pages/Customer/Client/components/ClientDetail/Form.jsx

@@ -50,6 +50,14 @@ const ContanctForm = props => {
     }
   }, [])
 
+  const defaultCompanyValue = {
+    districtIds: client.districtIds,
+    address: client.address,
+    ride: client.ride,
+    stay: client.stay,
+    landmarks: client.landmarks
+  }
+
   const columns = useMemo(() => {
     const pColumns = [
       {
@@ -67,7 +75,9 @@ const ContanctForm = props => {
         dataIndex: 'companyName',
         label: '单位名称',
         editCellType: 'custom',
-        customCell: <ChangeCompanyInput dataSource={changeCopInputData} />,
+        customCell: (
+          <ChangeCompanyInput dataSource={changeCopInputData} defaultValue={defaultCompanyValue} />
+        ),
         span: 24
       },
       {
@@ -175,7 +185,8 @@ const ContanctForm = props => {
                 tagType={TagTypeEnum.PERSONTAG}
                 tagColumn={TagDataTypeEnum.CLIENT}
                 checkCallBack={refreshClient}
-                modeType={LabelModeType.column}>
+                modeType={LabelModeType.column}
+              >
                 <Add theme="filled" size="20" fill="#868e96" className="cursor-pointer" />
               </PersonLabel>
             </div>
@@ -202,7 +213,8 @@ const ContanctForm = props => {
                 tagType={TagTypeEnum.TEAMTAG}
                 tagColumn={TagDataTypeEnum.CLIENT}
                 checkCallBack={refreshClient}
-                modeType={LabelModeType.column}>
+                modeType={LabelModeType.column}
+              >
                 <Add theme="filled" size="20" fill="#868e96" className="cursor-pointer" />
               </PersonLabel>
             </div>

+ 33 - 16
src/pages/Customer/Company/components/AddCompany/CompanyFormItem.jsx

@@ -6,7 +6,13 @@ import { Input, Alert, Popover } from 'antd'
 import CompanyDetail from '../CompanyDetail'
 import { useState } from 'react'
 
-const CompanyFormItem = ({ value, onChange }) => {
+export const validateEnum = {
+  Success: 'success',
+  Warning: 'warning',
+  Error: 'error',
+  Validating: 'validating'
+}
+const CompanyFormItem = ({ value, onChange, validateFn }) => {
   // const ref = useRef(null)
   const { toggleDrawer, setDrawerProps } = useModal()
   const [state, setState] = useState({
@@ -19,29 +25,38 @@ const CompanyFormItem = ({ value, onChange }) => {
   }
 
   const queryList = async search => {
-    if (!search) {
-      setState({ ...state, list: null })
-      return
-    }
-    const { code = -1, data } = await queryCompany({ current: 1, pageSize: 999, search })
+    if (!search) return
+    const { code = -1, data } = await queryCompany({ current: 1, pageSize: 20, search })
     if (code === consts.RET_CODE.SUCCESS) {
       const { customer = [] } = data
       setState({ ...state, list: customer })
+      if (customer?.length) {
+        validateFn(validateEnum.Warning)
+      } else {
+        validateFn(validateEnum.Success)
+      }
     }
   }
 
-  const { run: handleQueryList } = useDebounceFn(queryList, { wait: 500 })
+  const { run: handleQueryList, cancel: cancelQuerying } = useDebounceFn(queryList, { wait: 600 })
 
   const handleOnInputChange = async e => {
     const val = e.target.value || ''
-    setState({ ...state, inputVal: val })
-    await handleQueryList(val)
+    if (!val) {
+      cancelQuerying()
+      setState({ ...state, inputVal: val, list: null, visible: false })
+      validateFn(validateEnum.Error)
+    } else {
+      setState({ ...state, inputVal: val })
+      validateFn(validateEnum.Validating)
+      handleQueryList(val)
+    }
     triggerChange(val)
   }
 
   const showCompanyDrawer = id => {
     setDrawerProps({
-      zIndex: 1003,
+      zIndex: 1004,
       closable: true,
       onClose: () => toggleDrawer(),
       bodyStyle: {
@@ -55,13 +70,13 @@ const CompanyFormItem = ({ value, onChange }) => {
   const { visible, list, inputVal } = state
   return (
     <Popover
-      zIndex={1004}
+      zIndex={1003}
       placement="bottom"
-      visible={visible && list && list.length}
+      visible={list && list.length && visible}
       onVisibleChange={e => setState({ ...state, visible: e })}
       title={
         <Alert
-          message="已存在同名单位, 请确认是否继续添加"
+          message="已存在同名单位请确认是否继续添加"
           type="warning"
           style={{ padding: '5px', margin: '10px 0' }}
         />
@@ -74,7 +89,8 @@ const CompanyFormItem = ({ value, onChange }) => {
               <p key={item.id}>
                 <span
                   className="text-primary cursor-pointer hover:text-hex-967bbd"
-                  onClick={() => showCompanyDrawer(item.id)}>
+                  onClick={() => showCompanyDrawer(item.id)}
+                >
                   {item.companyName}
                 </span>
                 <span className="mx-1">/</span>
@@ -83,13 +99,14 @@ const CompanyFormItem = ({ value, onChange }) => {
             )
           })}
         </ul>
-      }>
+      }
+    >
       <Input
         type="text"
         autoComplete="false"
         value={inputVal}
+        placeholder="请输入单位全称"
         onChange={handleOnInputChange}
-        className="company-input"
       />
     </Popover>
   )

+ 23 - 3
src/pages/Customer/Company/components/AddCompany/index.jsx

@@ -9,13 +9,31 @@ import ModalDragForm from '@/components/Modal/src/components/ModalDragForm'
 import { isNullOrUnDef } from '@/utils/is'
 import CompanyFormItem from './CompanyFormItem'
 
-const AddCompanyModal = ({ reload, dataId, dataType, onConfirm, dispatch, natures }) => {
+const AddCompanyModal = ({
+  reload,
+  dataId,
+  dataType,
+  onConfirm,
+  dispatch,
+  natures,
+  defaultValue
+}) => {
   const formRef = useRef()
   const layout = {
     layout: 'horizontal',
     labelCol: { flex: '100px' }
   }
+  const [validStatusFcn, setValidStatusFcn] = useState('')
   useEffect(() => {
+    if (defaultValue) {
+      if (defaultValue.districtIds && defaultValue.districtIds?.length > 1) {
+        dispatch({
+          type: 'district/fetchWithValues',
+          payload: defaultValue.districtIds
+        })
+      }
+      formRef.current.setFieldsValue(defaultValue)
+    }
     const getNatures = () => {
       dispatch({
         type: 'company/fetchNatures'
@@ -64,6 +82,7 @@ const AddCompanyModal = ({ reload, dataId, dataType, onConfirm, dispatch, nature
       onFinish={async values => {
         await onConfirm(values)
         formRef.current?.resetFields()
+        setValidStatusFcn('')
         !isNullOrUnDef(reload) && reload()
         return true
       }}
@@ -71,10 +90,11 @@ const AddCompanyModal = ({ reload, dataId, dataType, onConfirm, dispatch, nature
       <Form.Item
         name="companyName"
         label="单位名称"
-        placeholder="请输入单位全称"
+        validateStatus={validStatusFcn}
+        hasFeedback
         rules={[{ required: true, message: '请输入单位全称' }]}
       >
-        <CompanyFormItem />
+        <CompanyFormItem validateFn={status => setValidStatusFcn(status)} />
       </Form.Item>
       {showDataItem ? <ProFormText name={`${dataType}Id`} hidden /> : null}
       <Form.Item

+ 8 - 2
src/pages/Customer/Company/components/ChangeCompany/index.jsx

@@ -31,6 +31,7 @@ const ChangeCompanyInput = props => {
       actionPayload = ChangeCompMap.CLIENT.key,
       title = '客户'
     },
+    defaultValue,
     editable = true
   } = props
   const refreshClient = () => {
@@ -43,8 +44,13 @@ const ChangeCompanyInput = props => {
     setModalProps({
       zIndex: 1002,
       width: '60vw',
-      modalRender: node => (
-        <SearchModal onSelect={refreshClient} node={node} dataId={dataId} preUrl={actionPayload} />
+      modalRender: () => (
+        <SearchModal
+          onSelect={refreshClient}
+          dataId={dataId}
+          preUrl={actionPayload}
+          defaultAddibleValue={defaultValue}
+        />
       ),
       onCancel: () => toggleModal()
     })

+ 6 - 3
src/pages/Customer/Company/components/CompanyDetail/TabList.jsx

@@ -13,6 +13,7 @@ import AddRecord from '@/pages/Customer/Client/components/ClientDetail/AddRecord
 import Detail from '@/pages/Customer/Business/components/BusinessDetail'
 import SyncClient from './SyncClient'
 import { longleSellStatusNum } from '@/pages/Product/Lock/LockStore/index'
+import { renderBadge } from '@/pages/Workbench/Dashboard/components/RatioPanels'
 
 const CompanyTabList = ({ initData, customerId, client, software, customer, business }) => {
   const dispatch = useDispatch()
@@ -134,7 +135,8 @@ const CompanyTabList = ({ initData, customerId, client, software, customer, busi
       render: (clientName, record) => (
         <span
           onClick={() => showLongleDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {clientName}
         </span>
       )
@@ -166,7 +168,8 @@ const CompanyTabList = ({ initData, customerId, client, software, customer, busi
       render: (text, record) => (
         <span
           onClick={() => showDrawerBusiness(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {text}
         </span>
       )
@@ -231,7 +234,7 @@ const CompanyTabList = ({ initData, customerId, client, software, customer, busi
     <div>
       <div className="pl-15px">
         <Tabs>
-          <TabPane tab="客户" key="客户">
+          <TabPane tab={<span>客户{renderBadge(client.total, true)}</span>} key="客户">
             <div className="sheet-right-panel" ref={tRef}>
               <ProTable
                 size="small"

+ 7 - 2
src/pages/Customer/Company/components/ConnectCompany/index.jsx

@@ -11,7 +11,7 @@ import { formatValues } from '@/components/LazyCascader'
 import { apiChangeCustomer } from '@/services/customer'
 import CustomModal from '@/components/Modal/src/components/CustomModal'
 
-const ConnectCompany = ({ dataId, onSelect, preUrl }) => {
+const ConnectCompany = ({ dataId, onSelect, preUrl, defaultAddibleValue }) => {
   const hasAddPerm = useAccess()?.validatePermByType('company_add')
   const dispatch = useDispatch()
   const scrollRef = useRef()
@@ -134,7 +134,12 @@ const ConnectCompany = ({ dataId, onSelect, preUrl }) => {
       </div>
       {hasAddPerm && (
         <div className={styles.modalFooter}>
-          <AddCompany onConfirm={addConfirm} dataId={dataId} dataType={preUrl} />
+          <AddCompany
+            onConfirm={addConfirm}
+            dataId={dataId}
+            dataType={preUrl}
+            defaultValue={defaultAddibleValue}
+          />
         </div>
       )}
     </CustomModal>

+ 5 - 3
src/pages/Hr/Employee/index.jsx

@@ -48,7 +48,8 @@ const Employee = props => {
       render: (username, record) => (
         <span
           onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {username}
         </span>
       )
@@ -113,7 +114,7 @@ const Employee = props => {
   return (
     <div className="h-full w-full flex flex-row">
       <RoleMenu onSelect={onSelect} />
-      <div className="w-max-3/4">
+      <div className="w-full">
         <div className="ml-8 shadow-hex-3e2c5a">
           {/* <div className="absolute right-33 top-3 z-100">
             {hasPerm && state.params.id && (
@@ -155,7 +156,8 @@ const Employee = props => {
                         onText="确认"
                         cancelText="取消"
                         // onConfirm={() => console.log(state.params.id)}
-                        onConfirm={() => handleDelDepartment(state.params.id)}>
+                        onConfirm={() => handleDelDepartment(state.params.id)}
+                      >
                         <Button danger size="small">
                           删除部门
                         </Button>

+ 2 - 1
src/pages/workbench/Dashboard/components/BusinessChar.jsx

@@ -77,7 +77,8 @@ const BusinessChar = props => {
             ) : null}
           </div>
         </div>
-      }>
+      }
+    >
       {char && thread && <DualAxes {...config} />}
     </Card>
   )

+ 2 - 1
src/pages/workbench/Dashboard/components/LeaderBoard.jsx

@@ -110,7 +110,8 @@ const LeaderBoard = ({ loading = false, dataList = [] }) => {
       <Option value="回款金额">回款金额</Option> */}
           </Select>
         </div>
-      }>
+      }
+    >
       <div className="text-center border border-x-0 p-2">{opMap[activeOp]}排行榜</div>
       <ProTable
         border={true}

+ 1 - 1
src/pages/workbench/Dashboard/components/RatioPanels.jsx

@@ -29,7 +29,7 @@ const dataTypeEunm = {
   }
 }
 
-const renderBadge = (count, active = false) => {
+export const renderBadge = (count, active = false) => {
   return active ? (
     <Badge
       count={count}

+ 6 - 3
src/pages/workbench/Dashboard/components/ReminderList.jsx

@@ -75,7 +75,8 @@ const ReminderList = props => {
       render: (clientName, record) => (
         <span
           onClick={() => showDrawer(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {clientName}
         </span>
       )
@@ -127,7 +128,8 @@ const ReminderList = props => {
       render: (companyName, record) => (
         <span
           onClick={() => showDrawerComapny(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {companyName}
         </span>
       )
@@ -179,7 +181,8 @@ const ReminderList = props => {
       render: (text, record) => (
         <span
           onClick={() => showDrawerBusiness(record.id)}
-          className="text-primary cursor-pointer hover:text-[#967bbd]">
+          className="text-primary cursor-pointer hover:text-[#967bbd]"
+        >
           {text}
         </span>
       )

+ 2 - 1
src/pages/workbench/Dashboard/components/SoftLeaderboard.jsx

@@ -81,7 +81,8 @@ const SoftLeaderboard = ({ loading = false, productLeaderBoard = [] }) => {
             <Option value="soft">软件锁</Option>
           </Select>
         </div>
-      }>
+      }
+    >
       <div className="text-center border border-x-0 p-2">{opMap[activeOp]}排行榜</div>
       <div className="">
         <ProTable

src/pages/workbench/Dashboard/consts.js → src/pages/Workbench/Dashboard/consts.js


+ 44 - 22
src/pages/workbench/Dashboard/index.jsx

@@ -147,7 +147,8 @@ const Dashboard = () => {
       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>
       )
@@ -158,7 +159,8 @@ const Dashboard = () => {
       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>
       )
@@ -169,7 +171,8 @@ const Dashboard = () => {
       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>
       )
@@ -180,7 +183,8 @@ const Dashboard = () => {
       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>
       )
@@ -191,7 +195,8 @@ const Dashboard = () => {
       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>
       )
@@ -202,7 +207,8 @@ const Dashboard = () => {
       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>
       )
@@ -277,7 +283,8 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 6 }}
-            xl={{ span: 6 }}>
+            xl={{ span: 6 }}
+          >
             <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
               {state.loading ? (
                 <Skeleton active avatar />
@@ -297,7 +304,8 @@ const Dashboard = () => {
                           state.clientChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.clientChainRatio.percentage}
                       </span>
                     </div>
@@ -317,14 +325,16 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 6 }}
-            xl={{ span: 6 }}>
+            xl={{ span: 6 }}
+          >
             <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
                 <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" />
@@ -339,7 +349,8 @@ const Dashboard = () => {
                           state.customerChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.customerChainRatio.percentage}
                       </span>
                     </div>
@@ -360,14 +371,16 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 6 }}
-            xl={{ span: 6 }}>
+            xl={{ span: 6 }}
+          >
             <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
                 <Row
                   className="cursor-pointer"
-                  onClick={() => handleRatioCard(cardTypeMap.BUSINESS)}>
+                  onClick={() => handleRatioCard(cardTypeMap.BUSINESS)}
+                >
                   <Col span={6}>
                     <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <Finance size="26" fill="#fff" />
@@ -382,7 +395,8 @@ const Dashboard = () => {
                           state.businessChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.businessChainRatio.percentage}
                       </span>
                     </div>
@@ -403,14 +417,16 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 6 }}
-            xl={{ span: 6 }}>
+            xl={{ span: 6 }}
+          >
             <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
                 <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" />
@@ -425,7 +441,8 @@ const Dashboard = () => {
                           state.serviceLogChainRatio.percentage.startsWith('-')
                             ? 'text-green-500'
                             : 'text-red-500'
-                        ].join(' ')}>
+                        ].join(' ')}
+                      >
                         {state.serviceLogChainRatio.percentage}
                       </span>
                     </div>
@@ -450,7 +467,8 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 16 }}
-            xl={{ span: 16 }}>
+            xl={{ span: 16 }}
+          >
             <BusinessChar
               loading={state.loading}
               data={state.businessChar}
@@ -463,13 +481,15 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 8 }}
-            xl={{ span: 8 }}>
+            xl={{ span: 8 }}
+          >
             <Card
               headStyle={{ padding: '0 12px' }}
               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>个,服务
@@ -497,7 +517,8 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 12 }}
-            xl={{ span: 12 }}>
+            xl={{ span: 12 }}
+          >
             <LeaderBoard dataList={state.leaderboard} loading={state.loading} />
           </Col>
           <Col
@@ -505,7 +526,8 @@ const Dashboard = () => {
             sm={{ span: 24 }}
             md={{ span: 24 }}
             lg={{ span: 12 }}
-            xl={{ span: 12 }}>
+            xl={{ span: 12 }}
+          >
             <SoftLeaderboard
               productLeaderBoard={state.productLeaderBoard}
               loading={state.loading}

src/pages/workbench/Dashboard/index.less → src/pages/Workbench/Dashboard/index.less


+ 0 - 2
src/utils/ws.ts

@@ -45,8 +45,6 @@ class Ws {
 
   // 初始化socket,一般在应用启动时初始化一次就好了,或者需要更换wsUrl
   public init(uid: string, uri: string, opts?: Options) {
-    console.log('id', uid)
-
     this.uid = uid
     this.uri = uri
     this.opts = opts