Bläddra i källkod

refactor: 权限下拉重构

lanjianrong 5 år sedan
förälder
incheckning
e6a945f84e

+ 16 - 11
src/pages/Customer/Business/index.jsx

@@ -1,5 +1,5 @@
 import React, { useState, useEffect, useRef } from 'react'
-import { connect, useModel } from 'umi'
+import { connect } from 'umi'
 import { getBusinessList } from '@/services/customer'
 import ProTable from '@ant-design/pro-table'
 import consts from '@/consts'
@@ -10,17 +10,19 @@ import { useModal } from '@/components/Modal'
 import { useTableScroll } from '@/hooks/useAutoTable'
 import CompanyDetail from '../Company/components/CompanyDetail'
 import { Funnel } from '@ant-design/charts'
+import PermSelect from '../Company/components/PermSelect'
+import { PermDataTypeEunm } from '../Company/components/PermSelect'
 
 const Business = ({ dispatch, groupList, shouldUpdate, loading }) => {
   const tRef = useRef(null)
   const { toggleDrawer, setDrawerProps } = useModal()
   const [state, setState] = useState({
     orderIds: [],
-    params: { businessGroupId: null },
+    params: { businessGroupId: null, dataPermission: 'oneself', staffIds: null },
     funnelData: []
   })
 
-  const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
+  // const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
 
   useEffect(() => {
     if (!groupList) {
@@ -133,6 +135,16 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading }) => {
     conversionTag: false
   }
   const { getScrollRef, redoHeight } = useTableScroll(columns)
+
+  // 处理权限Select下拉组件OnChange事件
+  const handlePermChange = ({ staffIds = [], dataPermission }) => {
+    if (staffIds?.length) {
+      setState({ ...state, params: { ...state.params, staffIds, dataPermission: null } })
+      return
+    }
+    setState({ ...state, params: { ...state.params, staffIds: null, dataPermission } })
+  }
+
   return (
     <div className="h-full w-full flex flex-row justify-between">
       <div className="h-full w-3/20 rounded-4px shadow-card">
@@ -191,14 +203,7 @@ const Business = ({ dispatch, groupList, shouldUpdate, loading }) => {
                 }
               }}
               headerTitle={
-                <Select
-                  defaultValue="oneself"
-                  dropdownMatchSelectWidth={false}
-                  onChange={e => {
-                    setState({ ...state, params: { ...state.params, dataPermission: e } })
-                  }}
-                  options={permData?.customer || []}
-                />
+                <PermSelect onConfirm={handlePermChange} dataType={PermDataTypeEunm.CUSTOMER} />
               }
               search={false}
               toolbar={{

+ 18 - 17
src/pages/Customer/Client/index.jsx

@@ -2,7 +2,7 @@ import ContactDetail from '@/pages/Customer/Client/components/ClientDetail'
 import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import AddContact from '@/pages/Customer/Client/components/AddClient'
 import ProTable from '@ant-design/pro-table'
-import { Input, Button, message, Tooltip, Select } from 'antd'
+import { Input, Button, message, Tooltip } from 'antd'
 import { connect, useModel } from 'umi'
 import React, { useEffect, useState, useRef, useMemo } from 'react'
 import consts from '@/consts'
@@ -21,6 +21,8 @@ import { apiAddClient, queryClient } from '@/services/customer'
 import { apiBatchLink } from '@/services/customer'
 import styles from './index.less'
 import { refactorSortField } from '@/utils/utils'
+import PermSelect from '../Company/components/PermSelect'
+import { PermDataTypeEunm } from '../Company/components/PermSelect'
 
 const Client = props => {
   const { toggleDrawer, setDrawerProps } = useModal()
@@ -89,7 +91,7 @@ const Client = props => {
   }
 
   const [state, setState] = useState({
-    params: { dataPermission: 'oneself' },
+    params: { dataPermission: 'oneself', staffIds: null },
     id: '',
     orderIds: []
   })
@@ -460,6 +462,15 @@ const Client = props => {
     refreshData()
   }
 
+  // 处理权限Select下拉组件OnChange事件
+  const handlePermChange = ({ staffIds = [], dataPermission }) => {
+    if (staffIds?.length) {
+      setState({ ...state, params: { ...state.params, staffIds, dataPermission: null } })
+      return
+    }
+    setState({ ...state, params: { ...state.params, staffIds: null, dataPermission } })
+  }
+
   const renderTableAlert = ({ selectedRowKeys }) => {
     return (
       <div className="flex flex-row">
@@ -556,18 +567,15 @@ const Client = props => {
                 style={{ width: '300px' }}
                 allowClear={true}
                 placeholder={`在${
-                  permData?.customer?.find(item => item.value === state.params.dataPermission)
-                    ?.label
+                  permData[PermDataTypeEunm.CUSTOMER]?.find(
+                    item => item.value === state.params.dataPermission
+                  )?.label || '自定义'
                 }下搜索`}
                 onSearch={handleSearch}
               />
             </Tooltip>
           ),
-          // search: {
-          //   allowClear: true,
-          //   onSearch: handleSearch,
-          //   placeholder: '输入联系人、客户名称、电话邮箱等'
-          // },
+
           actions: [
             <LazyCascader
               key="lazyCascader"
@@ -581,14 +589,7 @@ const Client = props => {
           ]
         }}
         headerTitle={
-          <Select
-            defaultValue="oneself"
-            dropdownMatchSelectWidth={false}
-            onChange={e => {
-              setState({ ...state, params: { ...state.params, dataPermission: e } })
-            }}
-            options={permData?.customer || []}
-          />
+          <PermSelect onConfirm={handlePermChange} dataType={PermDataTypeEunm.CUSTOMER} />
         }
         onLoadingChange={loadingStatus => {
           loadingStatus && redoHeight()

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

@@ -1,6 +1,6 @@
 /* eslint-disable no-underscore-dangle */
 /* eslint-disable consistent-return */
-import { Button, Transfer, Tree } from 'antd'
+import { Button, message, Transfer, Tree } from 'antd'
 import React, { useMemo, useState, useEffect } from 'react'
 import styles from './ConnectCompany/index.less'
 import { DeleteOutlined } from '@ant-design/icons'
@@ -206,6 +206,7 @@ const CustomPerm = ({ onConfirm }) => {
         <Transfer
           showSearch
           oneWay={true}
+          titles={['部门栏', '目标栏']}
           className="h-full"
           render={item => item.title}
           onSearch={handleOnSearch}
@@ -328,11 +329,15 @@ const CustomPerm = ({ onConfirm }) => {
         <Button className="mr-4" onClick={closeModal}>
           取消
         </Button>
+
         <Button
           type="primary"
           onClick={() => {
+            if (!state.targetKeys.length) {
+              return message.warning('目标栏尚未有员工,操作无效')
+            }
             if (onConfirm) {
-              onConfirm(state.targetKeys)
+              onConfirm({ staffIds: state.targetKeys, dataPermission: null })
             }
             closeModal()
           }}>

+ 37 - 0
src/pages/Customer/Company/components/PermSelect.jsx

@@ -0,0 +1,37 @@
+import { useModal } from '@/components/Modal'
+import { useModel } from 'umi'
+import { Select } from 'antd'
+import CustomPerm from './CustomPerm'
+
+export const PermDataTypeEunm = {
+  CUSTOMER: 'customer',
+  PRODUCT: 'product',
+  HR: 'hr',
+  WORKBENCH: 'workbench'
+}
+
+const PermSelect = ({ dataType, onConfirm }) => {
+  const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
+  const { toggleModal, setModalProps } = useModal()
+  return (
+    <Select
+      defaultValue="oneself"
+      dropdownMatchSelectWidth={false}
+      onChange={e => {
+        if (e === 'custom') {
+          setModalProps({
+            width: '60vw',
+            modalRender: () => <CustomPerm onConfirm={onConfirm} />,
+            onCancel: toggleModal
+          })
+          toggleModal()
+          return
+        }
+        onConfirm({ staffIds: null, dataPermission: e })
+      }}
+      options={[...(permData[dataType] || []), { value: 'custom', label: '自定义' }]}
+    />
+  )
+}
+
+export default PermSelect

+ 18 - 29
src/pages/Customer/Company/index.jsx

@@ -1,7 +1,7 @@
 import React, { useState, useEffect, useRef, useMemo } from 'react'
 import ProTable from '@ant-design/pro-table'
 import { useTableScroll } from '@/hooks/useAutoTable'
-import { Input, Button, message, Select, Tooltip } from 'antd'
+import { Input, Button, message, Tooltip } from 'antd'
 import { connect, useModel } from 'umi'
 import consts from '@/consts'
 import { queryCompany, apiAddCompany } from '@/services/customer'
@@ -16,7 +16,8 @@ import { Add, Down, Check } from '@icon-park/react'
 import { apiBatchLink } from '@/services/customer'
 import styles from './index.less'
 import { refactorSortField } from '@/utils/utils'
-import CustomPerm from './components/CustomPerm'
+import PermSelect from './components/PermSelect'
+import { PermDataTypeEunm } from './components/PermSelect'
 
 const Company = props => {
   const {
@@ -31,7 +32,7 @@ const Company = props => {
 
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
 
-  const { toggleDrawer, setDrawerProps, toggleModal, setModalProps } = useModal()
+  const { toggleDrawer, setDrawerProps } = useModal()
   const tRef = useRef(null)
   const [selectKeys, setSelectKeys] = useState([])
 
@@ -78,7 +79,7 @@ const Company = props => {
 
   const [state, setState] = useState({
     id: '',
-    params: { dataPermission: 'oneself' },
+    params: { dataPermission: 'oneself', staffIds: null },
     visible: false,
     orderIds: []
   })
@@ -379,6 +380,15 @@ const Company = props => {
     refreshData()
   }
 
+  // 处理权限Select下拉组件OnChange事件
+  const handlePermChange = ({ staffIds = [], dataPermission }) => {
+    if (staffIds?.length) {
+      setState({ ...state, params: { ...state.params, staffIds, dataPermission: null } })
+      return
+    }
+    setState({ ...state, params: { ...state.params, staffIds: null, dataPermission } })
+  }
+
   const renderTableAlert = ({ selectedRowKeys }) => {
     return (
       <div className="flex flex-row">
@@ -466,8 +476,9 @@ const Company = props => {
                 style={{ width: '300px' }}
                 allowClear={true}
                 placeholder={`在${
-                  permData?.customer?.find(item => item.value === state.params.dataPermission)
-                    ?.label
+                  permData[PermDataTypeEunm.CUSTOMER]?.find(
+                    item => item.value === state.params.dataPermission
+                  )?.label || '自定义'
                 }下搜索`}
                 onSearch={handleSearch}
               />
@@ -486,29 +497,7 @@ const Company = props => {
           ]
         }}
         headerTitle={
-          <Select
-            defaultValue="oneself"
-            dropdownMatchSelectWidth={false}
-            onChange={e => {
-              if (e === 'custom') {
-                setModalProps({
-                  width: '60vw',
-                  modalRender: () => (
-                    <CustomPerm
-                      onConfirm={staffIds =>
-                        setState({ ...state, params: { ...state.params, staffIds } })
-                      }
-                    />
-                  ),
-                  onCancel: toggleModal
-                })
-                toggleModal()
-                return
-              }
-              setState({ ...state, params: { ...state.params, dataPermission: e, staffIds: null } })
-            }}
-            options={[...(permData?.customer || []), { value: 'custom', label: '自定义' }]}
-          />
+          <PermSelect onConfirm={handlePermChange} dataType={PermDataTypeEunm.CUSTOMER} />
         }
         rowSelection={{
           onChange: hanleRowSelectChange,

+ 23 - 18
src/pages/Product/Lock/Lockstore/index.jsx

@@ -12,6 +12,8 @@ import { useTableScroll } from '@/hooks/useAutoTable'
 import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import { refactorSortField } from '@/utils/utils'
 import ReceiveLock from './components/ReceiveLock'
+import PermSelect from '@/pages/Customer/Company/components/PermSelect'
+import { PermDataTypeEunm } from '@/pages/Customer/Company/components/PermSelect'
 
 // 渲染产品标签
 export const ProductLabel = ({ data }) => {
@@ -74,7 +76,7 @@ const LockStore = ({ prodList = [], dispatch }) => {
   }
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
   const [state, setState] = useState({
-    params: { dataPermission: 'oneself' },
+    params: { dataPermission: 'oneself', staffIds: null },
     data: [],
     totalOld: 0, // 待接收锁总数
     id: ''
@@ -235,25 +237,19 @@ const LockStore = ({ prodList = [], dispatch }) => {
   ]
   const { getScrollRef, redoHeight } = useTableScroll(columns, selectKeys)
 
+  // 处理权限Select下拉组件OnChange事件
+  const handlePermChange = ({ staffIds = [], dataPermission }) => {
+    if (staffIds?.length) {
+      setState({ ...state, params: { ...state.params, staffIds, dataPermission: null } })
+      return
+    }
+    setState({ ...state, params: { ...state.params, staffIds: null, dataPermission } })
+  }
+
   return (
     <ProTable
       rowKey={record => record.id}
       search={false}
-      headerTitle={
-        <>
-          <Select
-            defaultValue="oneself"
-            dropdownMatchSelectWidth={false}
-            onChange={e => {
-              setState({ ...state, params: { ...state.params, dataPermission: e } })
-            }}
-            options={permData?.product || []}
-          />
-          <Button type="primary" className="ml-4" onClick={() => showReceiveLockModal()}>
-            待接收锁 ({state.totalOld})
-          </Button>
-        </>
-      }
       bordered
       params={state.params}
       columns={columns}
@@ -274,6 +270,14 @@ const LockStore = ({ prodList = [], dispatch }) => {
         }
       }}
       scroll={getScrollRef}
+      headerTitle={
+        <>
+          <PermSelect onConfirm={handlePermChange} dataType={PermDataTypeEunm.PRODUCT} />
+          <Button type="primary" className="ml-4" onClick={() => showReceiveLockModal()}>
+            待接收锁 ({state.totalOld})
+          </Button>
+        </>
+      }
       toolbar={{
         search: (
           <Tooltip placement="bottom" title="输入软件锁号">
@@ -281,7 +285,9 @@ const LockStore = ({ prodList = [], dispatch }) => {
               style={{ width: '300px' }}
               allowClear={true}
               placeholder={`在${
-                permData?.product?.find(item => item.value === state.params.dataPermission)?.label
+                permData[PermDataTypeEunm.PRODUCT]?.find(
+                  item => item.value === state.params.dataPermission
+                )?.label || '自定义'
               }下搜索`}
               onSearch={handleSearch}
             />
@@ -317,7 +323,6 @@ const LockStore = ({ prodList = [], dispatch }) => {
         ]
       }}
     />
-    // {/* <Locks onClose={hideDrawer} visible={state.visible} onCreate={onCreate} id={state.id} /> */}
   )
 }
 

+ 150 - 0
src/pages/workbench/Dashboard/components/RatioPanels.jsx

@@ -0,0 +1,150 @@
+import React from 'react'
+import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
+import { Button } from 'antd'
+import ProTable from '@ant-design/pro-table'
+import { useDispatch } from 'umi'
+import CustomModal from '@/components/Modal/src/components/CustomModal'
+import { queryRatioPanelsList } from '@/services/dashboard'
+import consts from '@/consts'
+
+const dataTypeEunm = {
+  0: 'client',
+  1: 'customer',
+  2: 'business'
+}
+
+const RatioPanels = ({ dataType }) => {
+  const dispatch = useDispatch()
+  const closeModal = () => {
+    dispatch({
+      type: 'single/changeModal'
+    })
+  }
+  const columnsMap = {
+    0: [
+      {
+        dataIndex: 'clientName',
+        title: '联系人名称'
+      },
+      {
+        dataIndex: 'companyName',
+        title: '客户名称'
+      },
+      {
+        dataIndex: 'districtName',
+        title: '地区'
+      },
+      {
+        dataIndex: 'phone',
+        title: '手机'
+      },
+      {
+        dataIndex: 'email',
+        title: '邮箱'
+      },
+      {
+        dataIndex: 'qq',
+        title: 'QQ'
+      },
+      {
+        dataIndex: 'createTime',
+        title: '创建时间'
+      }
+    ],
+    1: [
+      {
+        dataIndex: 'companyName',
+        title: '客户名称'
+      },
+      {
+        dataIndex: 'districtName',
+        title: '地区'
+      },
+      {
+        dataIndex: 'nature',
+        title: '客户性质'
+      },
+      {
+        dataIndex: 'phone',
+        title: '客户电话'
+      },
+      {
+        dataIndex: 'createTime',
+        title: '创建时间'
+      }
+    ],
+    2: [
+      {
+        dataIndex: 'name',
+        title: '商机名称'
+      },
+      {
+        dataIndex: 'customerName',
+        title: '客户名称'
+      },
+      {
+        dataIndex: 'businessStatusName',
+        title: '商机状态'
+      },
+      {
+        dataIndex: 'price',
+        title: '商机金额'
+      },
+      {
+        dataIndex: 'createTime',
+        title: '创建时间'
+      }
+    ]
+    // 3: [
+    //   {
+    //     dataIndex: '',
+    //     title: '栏目'
+    //   },
+    //   {
+    //     dataIndex: '',
+    //     title: '类型'
+    //   },
+    //   {
+    //     dataIndex: '',
+    //     title: '服务时间'
+    //   },
+    //   {
+    //     dataIndex: '',
+    //     title: '服务内容'
+    //   }
+    // ]
+  }
+  return (
+    <CustomModal title="卡片详情">
+      <div className="mx-4">
+        <ProTable
+          size="small"
+          pagination={{ defaultPageSize: 10 }}
+          rowKey={record => record.id}
+          scroll={{ y: 400 }}
+          columns={columnsMap[dataType]}
+          params={{ dataType }}
+          request={async params => {
+            const { code = -1, data } = await queryRatioPanelsList(params)
+            return {
+              data: data[dataTypeEunm[dataType]],
+              success: code === consts.RET_CODE.SUCCESS,
+              total: data.total
+            }
+          }}
+          search={false}
+          toolBarRender={false}
+        />
+      </div>
+      <div className={styles.modalFooter}>
+        <div className="text-right">
+          <Button type="button" onClick={closeModal}>
+            关闭
+          </Button>
+        </div>
+      </div>
+    </CustomModal>
+  )
+}
+
+export default RatioPanels

+ 1 - 0
src/pages/workbench/Dashboard/components/ReminderList.jsx

@@ -160,6 +160,7 @@ const ReminderList = props => {
           rowKey={record => record.id}
           columns={dataMap[dataType].columns}
           params={{ dataType, reminderCyclical }}
+          scroll={{ y: 400 }}
           request={async params => {
             const { code = -1, data } = await queryReminderList({ ...params })
             return {

+ 1 - 3
src/pages/workbench/Dashboard/consts.js

@@ -52,9 +52,7 @@ export const cyclicalOp = [
 ]
 
 export const cardTypeMap = {
-  CLIENT: {
-    key: 'client'
-  }, // 联系人
+  CLIENT: 0, // 联系人
   COMPANY: 1, // 客户
   BUSINESS: 2, // 商机
   SERVICE: 3 // 服务记录

+ 18 - 4
src/pages/workbench/Dashboard/index.jsx

@@ -9,8 +9,9 @@ import { queryDashboard } from '@/services/dashboard'
 import ReminderList from './components/ReminderList'
 import LeaderBoard from './components/LeaderBoard'
 import SoftLeaderboard from './components/SoftLeaderboard'
-import { cyclicalOp } from './consts'
+import { cardTypeMap, cyclicalOp } from './consts'
 import BusinessChar from './components/BusinessChar'
+import RatioPanels from './components/RatioPanels'
 
 const Dashboard = () => {
   const timer = useRef(null)
@@ -40,6 +41,15 @@ const Dashboard = () => {
     })
     toggleModal()
   }
+  // 展示卡片详情
+  const handleRatioCard = dataType => {
+    setModalProps({
+      width: '90vw',
+      modalRender: () => <RatioPanels dataType={dataType} />,
+      onCancel: () => toggleModal()
+    })
+    toggleModal()
+  }
   const initData = async payload => {
     if (timer.current) clearTimeout(timer.current)
     const {
@@ -219,7 +229,9 @@ const Dashboard = () => {
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
-                <Row>
+                <Row
+                  className="cursor-pointer"
+                  onClick={() => handleRatioCard(cardTypeMap.COMPANY)}>
                   <Col span={6}>
                     <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <City size="26" fill="#fff" />
@@ -255,7 +267,7 @@ const Dashboard = () => {
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
-                <Row>
+                <Row className="cursor-pointer" onClick={() => handleRatioCard(cardTypeMap.CLIENT)}>
                   <Col span={6}>
                     <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <AddressBook size="26" fill="#fff" />
@@ -290,7 +302,9 @@ const Dashboard = () => {
               {state.loading ? (
                 <Skeleton active avatar />
               ) : (
-                <Row>
+                <Row
+                  className="cursor-pointer"
+                  onClick={() => handleRatioCard(cardTypeMap.BUSINESS)}>
                   <Col span={6}>
                     <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
                       <Finance size="26" fill="#fff" />

+ 8 - 2
src/services/dashboard.js

@@ -6,10 +6,9 @@ import request from '@/basic/utils/request'
  * @returns 结果集
  */
 export async function queryDashboard(payload) {
-  const data = await request.get('/dashboard/list', {
+  return request.get('/dashboard/list', {
     params: { ...payload }
   })
-  return data
 }
 
 /** 获得提醒列表数据 */
@@ -19,3 +18,10 @@ export async function queryReminderList(payload) {
   })
   return data
 }
+
+/** 获得环比数据列表 */
+export async function queryRatioPanelsList(params) {
+  return request.get('/dashboard/ratioPanels', {
+    params
+  })
+}

+ 2 - 2
src/services/lock.js

@@ -2,8 +2,8 @@ import request from '@/basic/utils/request'
 
 /** 请求客户列表 */
 export async function queryLock(params) {
-  return request('/software/list', {
-    params
+  return request.post('/software/list', {
+    data: params
   })
 }