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

feat: 人资更换上司相关组件

outaozhen преди 5 години
родител
ревизия
b57007f493

+ 46 - 3
src/pages/Staff/Employee/components/ChangeSupervisor/index.jsx

@@ -1,10 +1,53 @@
 import React from 'react'
-import styles from '@/pages/customer/Contact/components/ChangeCompany/index.less'
+import { LinkOne, Switch } from '@icon-park/react'
+import { useModal } from '@/components/Modal'
+import { Card, Tooltip } from 'antd'
+import consts from '@/basic/consts'
+import { useDispatch } from 'dva'
+import StaffModal from '@/pages/staff/Employee/components/StaffModal'
+import styles from './index.less'
 
-const ChangeSupervisor = () => {
+const ChangeSupervisor = props => {
+  const dispatch = useDispatch()
+  const { toggleModal, setModalProps } = useModal()
+  const {
+    dataSource: { staffId, clientId, staffName }
+  } = props
+  const refreshClient = () => {
+    dispatch({
+      type: 'refresh/commitAction',
+      payload: 'stafflist'
+    })
+  }
+  const handleConnectStaff = () => {
+    setModalProps({
+      width: '60vw',
+      modalRender: node => <StaffModal onSelect={refreshClient} node={node} clientId={clientId} />,
+      onCancel: () => toggleModal()
+    })
+    toggleModal()
+  }
+  const normalValueRender = (
+    <Card size="small">
+      <div className="flex justify-between">
+        <div className={styles.nameContent}>{staffName}</div>
+        <div className="w-30px">
+          <Tooltip
+            placement="right"
+            title="更换上司"
+            className="ml-5px"
+            onClick={handleConnectStaff}>
+            <span className={styles.switchIcon}>
+              <Switch />
+            </span>
+          </Tooltip>
+        </div>
+      </div>
+    </Card>
+  )
   return (
     <div className={styles.companyInput}>
-      <span>更换上司</span>
+      {staffId === consts.ENCRYPTION_ZERO && normalValueRender}
     </div>
   )
 }

+ 54 - 0
src/pages/Staff/Employee/components/ChangeSupervisor/index.less

@@ -0,0 +1,54 @@
+.companyInput {
+  padding: 8px 12px 6px;
+  color: @primary-color;
+  background: #f7f7f7;
+  border: 1px solid #f7f7f7;
+  &:hover {
+    background: #f2f2f2;
+    border-color: #f2f2f2;
+  }
+  :global(.ant-card-small > .ant-card-body) {
+    padding: 0.5rem;
+  }
+  .notCompanyContent {
+    cursor: pointer;
+    &:hover {
+      color: #967bbd;
+    }
+  }
+  .nameContent {
+    color: @primary-color;
+    cursor: pointer;
+    &:hover {
+      color: #967bbd;
+    }
+  }
+  .unlinkIcon {
+    padding: 0 3px;
+    color: #fd3995;
+    line-height: 1.15rem;
+    border: 1px solid #fd3995;
+    border-radius: 0.25rem;
+    cursor: pointer;
+    &:hover {
+      color: #ffffff;
+      background-color: #fd3995;
+      border-color: #fd3995;
+      transition: all 0.2s ease-in-out;
+    }
+  }
+  .switchIcon {
+    padding: 0 3px;
+    color: #886ab5;
+    line-height: 1.15rem;
+    border: 1px solid #886ab5;
+    border-radius: 0.25rem;
+    cursor: pointer;
+    &:hover {
+      color: #ffffff;
+      background-color: #886ab5;
+      border-color: #886ab5;
+      transition: all 0.2s ease-in-out;
+    }
+  }
+}

+ 9 - 0
src/pages/Staff/Employee/components/EmployeeDetail/EmployeeForm.jsx

@@ -1,9 +1,16 @@
 import React from 'react'
 import { Col, Row } from 'antd'
 import EditableForm from '@/components/EditableForm'
+import ChangeSupervisor from '@/pages/staff/Employee/components/ChangeSupervisor'
 
 const EmployeeForm = props => {
   const { staff } = props
+  const changeCopInputData = {
+    staffName: staff.username,
+    staffId: staff.staffId,
+    clientName: staff.clientName,
+    clientId: staff.id
+  }
   const columns = [
     {
       dataIndex: 'jobNumber',
@@ -24,6 +31,8 @@ const EmployeeForm = props => {
     {
       dataIndex: 'departmentName',
       label: '部门上司',
+      editCellType: 'custom',
+      customCell: <ChangeSupervisor dataSource={changeCopInputData} />,
       span: 24
     },
     {

+ 0 - 1
src/pages/Staff/Employee/components/EmployeeDetail/EmployeeLowerList.jsx

@@ -10,7 +10,6 @@ const EmployeeLowerList = () => {
         <Tabs>
           <TabPane tab="软件锁" key="软件锁">
             <div className="sheet-right-panel">目前功能暂时不开放</div>
-            <StaffModal />
           </TabPane>
         </Tabs>
       </div>

+ 67 - 16
src/pages/Staff/Employee/components/StaffModal/index.jsx

@@ -1,12 +1,60 @@
-import React, { useState } from 'react'
+import React, { useState, useEffect, useRef } from 'react'
 import { Input, Button, Spin } from 'antd'
-import styles from './index.less'
+import consts from '@/basic/consts'
+import { useDispatch } from 'dva'
+import { useDebounceFn } from 'ahooks'
 import { SearchOutlined, CloseOutlined } from '@ant-design/icons'
+import { queryStaff } from '@/services/staff'
+import styles from './index.less'
 
 const StaffModal = () => {
+  const scrollRef = useRef()
+  const dispatch = useDispatch()
   const [state, setState] = useState({
-    loading: false
+    loading: true,
+    list: [],
+    page: 1,
+    size: 10,
+    total: 0
   })
+  const initData = async params => {
+    const { data: { list, total } = { list: [], total: 0 }, code = -1 } = await queryStaff(params)
+    if (code === consts.RET_CODE.SUCCESS) {
+      if (params?.page === 1) {
+        // 请求的是第一页
+        setState({ ...state, list, total, loading: false })
+      } else {
+        setState({ ...state, list: state.list.concat(list), total, loading: false })
+      }
+    }
+  }
+
+  useEffect(() => {
+    initData({ page: 1, size: 10 })
+  }, [])
+  const onChange = e => {
+    const { value = '' } = e.target || e.currentTarget
+    initData({ search: value, page: state.page, size: state.size })
+  }
+
+  const { run: handleInputChange } = useDebounceFn(onChange)
+
+  const closeModal = () => {
+    dispatch({
+      type: 'single/changeModal'
+    })
+  }
+
+  const handleListScroll = () => {
+    // 未滚动到底部
+    if (
+      scrollRef.current.scrollHeight - scrollRef.current.clientHeight <=
+      scrollRef.current.scrollTop
+    ) {
+      // 已到底部
+      initData({ page: state.page + 1, size: state.size })
+    }
+  }
   return (
     <div className={['ant-modal-content', styles.modalContainer].join(' ')}>
       <div className={styles.modalHeader}>
@@ -14,24 +62,27 @@ const StaffModal = () => {
           prefix={<SearchOutlined />}
           className={styles.inputSearch}
           placeholder="输入员工名称搜索"
+          onClick={handleInputChange}
         />
         <span className={styles.closeIcon}>
-          <CloseOutlined />
+          <CloseOutlined onClick={closeModal} />
         </span>
       </div>
-      <div className={styles.modalContent}>
+      <div className={styles.modalContent} ref={scrollRef} onScroll={handleListScroll}>
         <Spin spinning={state.loading}>
-          <div className={styles.card}>
-            <span className="w-1/6">张三</span>
-            <span className="w-1/6">总部</span>
-            <span className="w-1/6">测试</span>
-            <span className="w-1/2 zh-justify-between">
-              <span>15800000001</span>
-              <Button type="primary" size="small">
-                关联
-              </Button>
-            </span>
-          </div>
+          {state.list.map(item => (
+            <div key={item.id} className={styles.card}>
+              <span className="w-1/6">{item.username}</span>
+              <span className="w-1/6">{item.departmentName}</span>
+              <span className="w-1/6">{item.position}</span>
+              <span className="w-1/2 zh-justify-between">
+                <span>{item.emergencyContacts}</span>
+                <Button type="primary" size="small">
+                  关联
+                </Button>
+              </span>
+            </div>
+          ))}
         </Spin>
       </div>
     </div>

+ 10 - 0
src/services/staff.js

@@ -21,3 +21,13 @@ export async function apiStaffDetail(id) {
   const data = await request('/staff/detail', { params })
   return data
 }
+
+/**
+ * 员工更换上司
+ * @param {*} payload
+ * @returns
+ */
+export async function apiChangeSupervisor(payload) {
+  const data = await request.post('/staff/change/supervisor', { data: { ...payload } })
+  return data
+}