Procházet zdrojové kódy

fix: 调整数据权限

lanjianrong před 5 roky
rodič
revize
db8158c06b

+ 4 - 9
src/components/Table/src/BasicTable.tsx

@@ -1,13 +1,12 @@
 /* eslint-disable react-hooks/rules-of-hooks */
 /* eslint-disable no-param-reassign */
-import { PERMISSION_SELECT_KEY } from '@/utils/cache/cacheEnum'
 import PermSelect from '@/pages/Customer/Company/components/PermSelect'
 import { TABLE_COLUMNS_MAP, ColumnStateEnum } from '@/utils/cache/cacheEnum'
 import { isNullOrUnDef } from '@/utils/is'
 import type { ColumnsState } from '@ant-design/pro-table'
 import ProTable from '@ant-design/pro-table'
 import { useModel } from 'umi'
-import { getAuthCache, setAuthCache } from '@/utils/auth'
+import { getAuthCache, getPermAuthCache, setAuthCache } from '@/utils/auth'
 import React, { useRef, useState, useLayoutEffect, useMemo } from 'react'
 import { useMount } from 'ahooks'
 import { useTableScroll } from './hooks/useTableScroll'
@@ -68,19 +67,15 @@ const BasicTable: {
   } = useModel('@@initialState')
   // 如果数据权限不存在,就不渲染
   if (isNullOrUnDef(permData)) return null
-  // const [columns] = useState(originalColumns)
-  const permAuthCache = getAuthCache(PERMISSION_SELECT_KEY)
-  let defaultpermAuthCache = 'oneself'
-  if (permAuthCache && permAuthCache[mainMenuType]) {
-    defaultpermAuthCache = permAuthCache[mainMenuType]
-  }
+
+  const [defaultPermAuthCache, defaultStaffIds] = getPermAuthCache(mainMenuType)
   const tableElRef = useRef<HTMLElement>(null)
 
   const [state, setState] = useState({
     selectKeysRef: null,
     sizeRef: 'middle',
     columnsStateMap: columnsStateMap || {},
-    params: { staffIds: null, dataPermission: defaultpermAuthCache },
+    params: { staffIds: defaultStaffIds, dataPermission: defaultPermAuthCache },
     dataSource: null
   })
 

+ 5 - 2
src/pages/Customer/Client/index.jsx

@@ -21,6 +21,7 @@ import styles from './index.less'
 import { refactorSortField } from '@/utils/utils'
 import { PermDataTypeEunm } from '../Company/components/PermSelect'
 import BasicTable from '@/components/Table'
+import { getPermAuthCache } from '@/utils/auth'
 
 const Client = props => {
   const { toggleDrawer, setDrawerProps } = useModal()
@@ -88,6 +89,7 @@ const Client = props => {
     orderIds: []
   })
 
+  const [defaultPermAuthCache] = getPermAuthCache(PermDataTypeEunm.CUSTOMER)
   // 重置到默认值,包括表单
   const initData = () => {
     tRef.current?.reset()
@@ -561,8 +563,8 @@ const Client = props => {
                 allowClear={true}
                 placeholder={`在${
                   permData[PermDataTypeEunm.CUSTOMER]?.find(
-                    item => item.value === state.params.dataPermission
-                  )?.label || '自定义'
+                    item => item.value === defaultPermAuthCache
+                  )?.label
                 }下搜索`}
                 onSearch={handleSearch}
               />
@@ -579,6 +581,7 @@ const Client = props => {
               className="hover:bg-[rgba(0,0,0,0.1)]"
             />,
             <AddClient
+              modalProps={{ zIndex: 1050 }}
               onConfirm={handleAddClient}
               key="addClientBtn"
               reload={() => tRef.current?.reload()}

+ 63 - 61
src/pages/Customer/Company/components/CompanyDetail/SyncClient.jsx

@@ -85,72 +85,74 @@ const SyncClient = ({ customer, client }) => {
   const { checkValues, visible } = state
   return (
     <>
-      <Button size="small" onClick={() => setState({ ...state, visible: true })}>
+      <Button
+        size="small"
+        ghost
+        type="primary"
+        onClick={() => setState({ ...state, visible: true })}>
         <div className="flex items-center justify-center">
           <Copy theme="two-tone" fill={['#333', '#535A5D']} />
           <span className="ml-1">同步地址信息</span>
         </div>
       </Button>
-      {visible ? (
-        <Modal
-          width="70%"
-          title={`同步 ${customer.companyName} 信息`}
-          getContainer={false}
-          visible={visible}
-          onCancel={() => setState({ ...state, visible: false })}
-          onOk={handleOnConfirm}>
-          <div className="rounded-3 p-4 mb-2">
-            <Checkbox.Group
-              defaultValue={checkValues}
-              onChange={e => setState({ ...state, checkValues: e })}>
-              <div className="flex flex-nowrap">
-                <Checkbox value="district">
-                  <div className="w-100px text-left">地区</div>
-                </Checkbox>
-                <div>{customer.districtName?.replaceAll(' / ', ',')}</div>
-              </div>
-              <div className="flex flex-nowrap">
-                <Checkbox value="address">
-                  <div className="w-100px text-left">地址</div>
-                </Checkbox>
-                <div>{customer.address}</div>
-              </div>
-              <div className="flex flex-nowrap">
-                <Checkbox value="ride">
-                  <div className="w-100px text-left">乘车路线</div>
-                </Checkbox>
-                <div>{customer.ride}</div>
-              </div>
-              <div className="flex flex-nowrap">
-                <Checkbox value="landmarks">
-                  <div className="w-100px text-left">地标建筑</div>
-                </Checkbox>
-                <div>{customer.landmarks}</div>
-              </div>
-              <div className="flex flex-nowrap">
-                <Checkbox value="stay">
-                  <div className="w-100px text-left">参考住宿</div>
-                </Checkbox>
-                <div>{customer.stay}</div>
-              </div>
-            </Checkbox.Group>
-          </div>
-          <ProTable
-            search={false}
-            rowKey="id"
-            toolBarRender={false}
-            size="small"
-            columns={columns}
-            dataSource={client}
-            bordered
-            scroll={{ y: 400 }}
-            pagination={false}
-            rowSelection={{
-              onChange: selectedRowKeys => setState({ ...state, selectedKeys: selectedRowKeys })
-            }}
-          />
-        </Modal>
-      ) : null}
+      <Modal
+        width="70%"
+        title={`同步 ${customer.companyName} 信息`}
+        getContainer={false}
+        visible={visible}
+        onCancel={() => setState({ ...state, visible: false })}
+        onOk={handleOnConfirm}>
+        <div className="rounded-3 p-4 mb-2 pt-0">
+          <Checkbox.Group
+            defaultValue={checkValues}
+            onChange={e => setState({ ...state, checkValues: e })}>
+            <div className="flex flex-nowrap">
+              <Checkbox value="district">
+                <div className="w-100px text-left">地区</div>
+              </Checkbox>
+              <div>{customer.districtName?.replaceAll(' / ', ',')}</div>
+            </div>
+            <div className="flex flex-nowrap">
+              <Checkbox value="address">
+                <div className="w-100px text-left">地址</div>
+              </Checkbox>
+              <div>{customer.address}</div>
+            </div>
+            <div className="flex flex-nowrap">
+              <Checkbox value="ride">
+                <div className="w-100px text-left">乘车路线</div>
+              </Checkbox>
+              <div>{customer.ride}</div>
+            </div>
+            <div className="flex flex-nowrap">
+              <Checkbox value="landmarks">
+                <div className="w-100px text-left">地标建筑</div>
+              </Checkbox>
+              <div>{customer.landmarks}</div>
+            </div>
+            <div className="flex flex-nowrap">
+              <Checkbox value="stay">
+                <div className="w-100px text-left">参考住宿</div>
+              </Checkbox>
+              <div>{customer.stay}</div>
+            </div>
+          </Checkbox.Group>
+        </div>
+        <ProTable
+          search={false}
+          rowKey="id"
+          toolBarRender={false}
+          size="small"
+          columns={columns}
+          dataSource={client}
+          bordered
+          scroll={{ y: 400 }}
+          pagination={false}
+          rowSelection={{
+            onChange: selectedRowKeys => setState({ ...state, selectedKeys: selectedRowKeys })
+          }}
+        />
+      </Modal>
     </>
   )
 }

+ 1 - 1
src/pages/Customer/Company/components/CustomPerm.jsx

@@ -348,7 +348,7 @@ const CustomPerm = ({ onConfirm, defaultValues = [] }) => {
               return message.warning('目标栏尚未有员工,操作无效')
             }
             if (onConfirm) {
-              onConfirm({ staffIds: state.targetKeys, dataPermission: null })
+              onConfirm({ staffIds: state.targetKeys, dataPermission: 'custom' })
             }
             closeModal()
           }}>

+ 7 - 11
src/pages/Customer/Company/components/PermSelect.tsx

@@ -2,7 +2,7 @@ import { useModal } from '@/components/Modal'
 import { useModel } from 'umi'
 import { Button, Dropdown, Menu } from 'antd'
 import CustomPerm from './CustomPerm'
-import { getAuthCache, setAuthCache } from '@/utils/auth'
+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'
@@ -23,22 +23,15 @@ interface PermSelectProps extends SelectProps {
 const PermSelect: React.FC<PermSelectProps> = ({ dataType, onConfirm }) => {
   const { initialState: { permData } = { permData: {} } } = useModel('@@initialState')
   const { toggleModal, setModalProps } = useModal()
-  let defaultValue = 'oneself'
   const options = [...(permData[dataType] || [])]
-  const permAuthCache = getAuthCache(PERMISSION_SELECT_KEY)
-
-  if (permAuthCache && permAuthCache[dataType]) {
-    defaultValue = permAuthCache[dataType]
-  }
-
+  const [defaultValue, defaultStaffIds] = getPermAuthCache(dataType)
   const [state, setState] = useState({
     currKey: defaultValue,
-    staffIds: [],
+    staffIds: defaultStaffIds,
     showSetting: false
   })
 
   const handleOnChange = e => {
-    setState({ ...state, currKey: e })
     if (e === 'custom') {
       setModalProps({
         width: '60vw',
@@ -46,16 +39,19 @@ const PermSelect: React.FC<PermSelectProps> = ({ dataType, onConfirm }) => {
           <CustomPerm
             defaultValues={state.staffIds}
             onConfirm={({ staffIds, dataPermission }) => {
-              setState({ ...state, staffIds, showSetting: true })
+              setState({ ...state, staffIds, currKey: e })
               onConfirm({ staffIds, dataPermission })
+              setAuthCache(PERMISSION_SELECT_KEY, { ...permAuthCache, [dataType]: staffIds })
             }}
           />
         ),
         onCancel: () => toggleModal()
       })
       toggleModal()
+
       return
     }
+    setState({ ...state, currKey: e })
     onConfirm({ staffIds: null, dataPermission: e })
     setAuthCache(PERMISSION_SELECT_KEY, { ...permAuthCache, [dataType]: e })
     // 将setting icon隐藏,非自定义option下不显示

+ 5 - 2
src/pages/Customer/Company/index.jsx

@@ -16,6 +16,7 @@ import styles from './index.less'
 import { refactorSortField } from '@/utils/utils'
 import { PermDataTypeEunm } from './components/PermSelect'
 import BasicTable from '@/components/Table'
+import { getPermAuthCache } from '@/utils/auth'
 
 const Company = props => {
   const {
@@ -386,6 +387,8 @@ const Company = props => {
     requestSuccess && refreshData()
   }
 
+  const [defaultPermAuthCache] = getPermAuthCache(PermDataTypeEunm.CUSTOMER)
+
   const renderTableAlert = ({ selectedRowKeys }) => {
     return (
       <div className="flex flex-row">
@@ -475,8 +478,8 @@ const Company = props => {
                 allowClear={true}
                 placeholder={`在${
                   permData[PermDataTypeEunm.CUSTOMER]?.find(
-                    item => item.value === state.params.dataPermission
-                  )?.label || '自定义'
+                    item => item.value === defaultPermAuthCache
+                  )?.label
                 }下搜索`}
                 onSearch={handleSearch}
               />

+ 0 - 1
src/pages/Hr/Employee/index.jsx

@@ -129,7 +129,6 @@ const Employee = props => {
           </div>
           {state.params.id && (
             <BasicTable
-              mainMenuType="hr"
               columnStateType="EMPLOYEE"
               params={{ departmentId: state.params.id }}
               rowKey={record => record.id}

+ 28 - 4
src/pages/Product/Lock/Lockstore/components/ReceiveLock.jsx

@@ -1,15 +1,18 @@
-import { Button, message } from 'antd'
-import React, { useRef } from 'react'
+import { Button, Input, message } 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/lock'
 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 tRef = useRef()
-
+  const [tParams, setParams] = useState({
+    search: null
+  })
   const receiveLongle = async (name, id) => {
     const { code = -1 } = await apiReceiveOldLock({ id })
     if (code === consts.RET_CODE.SUCCESS) {
@@ -45,16 +48,37 @@ const ReceiveLock = ({ refresh }) => {
     }
   ]
 
+  const handleOnSearch = val => {
+    setParams({ ...tParams, search: val })
+  }
   return (
-    <CustomModal title="以下锁为系统升级前未接收的锁,请及时接收;新系统生成的锁,将在列表中按“本部门”展示。">
+    <CustomModal
+      title={
+        <div className="flex items-center justify-between">
+          <span>
+            以下锁为系统升级前未接收的锁,请及时接收。
+            {/* <Tooltip title="新系统生成的锁,将在列表中按“本部门”展示。">
+              <Attention theme="outline" fill="#333" />
+            </Tooltip> */}
+          </span>
+          <Input.Search
+            style={{ width: '300px' }}
+            placeholder="输入锁号/产品进行搜索"
+            allowClear
+            onSearch={handleOnSearch}
+          />
+        </div>
+      }>
       <div className={styles.modalContent}>
         <ProTable
           rowKey={record => record.id}
           columns={columns}
           actionRef={tRef}
+          params={tParams}
           toolBarRender={false}
           search={false}
           bordered={true}
+          scroll={{ y: 460 }}
           request={async params => {
             const { data: { longle, total } = { longle: [], total: 0 }, code = -1 } =
               await queryOldLockList(params)

+ 25 - 5
src/pages/Product/Lock/Lockstore/components/ReceiveNewLock.jsx

@@ -1,5 +1,5 @@
-import { Button, message } from 'antd'
-import React, { useRef } from 'react'
+import { Button, Input, message } from 'antd'
+import React, { useRef, useState } from 'react'
 import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
 import consts from '@/basic/consts'
 import { apiReceiveLock, queryReceiveList } from '@/services/lock'
@@ -10,6 +10,9 @@ import CustomModal from '@/components/Modal/src/components/CustomModal'
 const ReceiveNewLock = ({ refresh }) => {
   const tRef = useRef()
 
+  const [tParams, setParams] = useState({
+    search: null
+  })
   const receiveLongle = async (name, id) => {
     const { code = -1 } = await apiReceiveLock({ id })
     if (code === consts.RET_CODE.SUCCESS) {
@@ -45,19 +48,36 @@ const ReceiveNewLock = ({ refresh }) => {
     }
   ]
 
+  const handleOnSearch = val => {
+    setParams({ ...tParams, search: val })
+  }
+
   return (
-    <CustomModal title="新系统生成的锁,将在列表中按“本部门”展示。">
+    <CustomModal
+      title={
+        <div className="flex flex-nowrap items-center justify-between">
+          "新系统生成的锁,将在列表中按“本部门”展示。"
+          <Input.Search
+            style={{ width: '300px' }}
+            placeholder="输入锁号/产品进行搜索"
+            allowClear
+            onSearch={handleOnSearch}
+          />
+        </div>
+      }>
       <div className={styles.modalContent}>
         <ProTable
           rowKey={record => record.id}
+          params={tParams}
           columns={columns}
           actionRef={tRef}
           toolBarRender={false}
           search={false}
           bordered={true}
-          request={async params => {
+          scroll={{ y: 460 }}
+          request={async (params, _, filter) => {
             const { data: { longle, total } = { longle: [], total: 0 }, code = -1 } =
-              await queryReceiveList(params)
+              await queryReceiveList({ ...params, ...filter })
             return {
               data: longle,
               success: code === consts.RET_CODE.SUCCESS,

+ 40 - 22
src/pages/Product/Lock/Lockstore/index.jsx

@@ -10,9 +10,11 @@ import { useModal } from '@/components/Modal'
 import CompanyDetail from '@/pages/Customer/Company/components/CompanyDetail'
 import { refactorSortField } from '@/utils/utils'
 import ReceiveLock from './components/ReceiveLock'
-import ReceiveNewLock from './components/ReceiveNewLock'
+// import ReceiveNewLock from './components/ReceiveNewLock'
 import { PermDataTypeEunm } from '@/pages/Customer/Company/components/PermSelect'
 import BasicTable from '@/components/Table'
+import { getPermAuthCache } from '@/utils/auth'
+// import { DownOutlined } from '@ant-design/icons'
 
 // 渲染产品标签
 export const ProductLabel = ({ data }) => {
@@ -95,14 +97,14 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
     })
     toggleModal()
   }
-  const showReceiveNewLockModal = () => {
-    setModalProps({
-      width: '60vw',
-      modalRender: () => <ReceiveNewLock 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({
     params: { dataPermission: 'oneself', staffIds: null },
@@ -348,6 +350,15 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
     }
   }
 
+  // const dropDownMenClick = ({ key }) => {
+  //   if (key === '1') {
+  //     showReceiveLockModal()
+  //   } else {
+  //     showReceiveNewLockModal()
+  //   }
+  // }
+
+  const [defaultPermAuthCache] = getPermAuthCache(PermDataTypeEunm.PRODUCT)
   return (
     <BasicTable
       rowKey={record => record.id}
@@ -377,18 +388,25 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
       }}
       columnsStateMap={columnsStateMap}
       headerTitle={
-        <>
-          {state.totalOld ? (
-            <Button type="primary" className="ml-4" onClick={() => showReceiveLockModal()}>
-              待接收锁 ({state.totalOld})
-            </Button>
-          ) : null}
-          {state.totalNew ? (
-            <Button type="primary" className="ml-4" onClick={() => showReceiveNewLockModal()}>
-              待接收新锁 ({state.totalNew})
-            </Button>
-          ) : null}
-        </>
+        // <Dropdown
+        //   trigger="click"
+        //   overlay={
+        //     <Menu onClick={dropDownMenClick}>
+        //       {state.totalOld ? <Menu.Item key="1">接收旧锁</Menu.Item> : null}
+
+        //       {state.totalNew ? <Menu.Item key="2">接收新锁</Menu.Item> : null}
+        //     </Menu>
+        //   }>
+        //   <Button>
+        //     接收锁
+        //     <DownOutlined />
+        //   </Button>
+        // </Dropdown>
+        state.totalOld ? (
+          <Button type="primary" onClick={showReceiveLockModal}>
+            接收旧锁({state.totalOld})
+          </Button>
+        ) : null
       }
       toolbar={{
         search: (
@@ -398,7 +416,7 @@ const LockStore = ({ prodList = [], dispatch, shouldUpdate }) => {
               allowClear={true}
               placeholder={`在${
                 permData[PermDataTypeEunm.PRODUCT]?.find(
-                  item => item.value === state.params.dataPermission
+                  item => item.value === defaultPermAuthCache
                 )?.label || '自定义'
               }下搜索`}
               onSearch={handleSearch}

+ 3 - 0
src/types/typing.d.ts

@@ -17,8 +17,11 @@ import type { LabelTooltipType } from 'antd/lib/form/FormItemLabel'
 import type { SortOrder } from 'antd/lib/table/interface'
 import type { ProFieldEmptyText } from '@ant-design/pro-field'
 import type { Bordered } from '@ant-design/pro-table/lib/typing'
+import type { ReactNode } from 'react-router/node_modules/@types/react'
 
 export type BasicTableProps<T, U extends ParamsType, ValueType = 'text'> = {
+  /** @name 配置search栏tooltip的title属性 */
+  searchTooptip?: boolean | string | ReactNode
   /** @name 启用列可伸缩功能 */
   resizable?: boolean
   /** @type 枚举表中的菜单常量 */

+ 29 - 1
src/utils/auth/index.ts

@@ -2,7 +2,13 @@
 
 import { Persistent, BasicKeys } from '@/utils/cache/persistent'
 import projectSetting from '@/settings/projectSetting'
-import { TOKEN_KEY, CacheTypeEnum } from '@/utils/cache/cacheEnum'
+import {
+  TOKEN_KEY,
+  CacheTypeEnum,
+  PERMISSION_SELECT_KEY,
+  MainMenuKeyEnum
+} from '@/utils/cache/cacheEnum'
+import { isArray } from '../is'
 
 const { permissionCacheType } = projectSetting
 const isLocal = permissionCacheType === CacheTypeEnum.LOCAL
@@ -25,3 +31,25 @@ export function clearAuthCache(immediate = true) {
   const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession
   return fn(immediate)
 }
+
+export function getPermAuthCache(dataType?: MainMenuKeyEnum) {
+  if (!dataType) return [null, null]
+  let defaultValue = 'oneself',
+    defaultStaffIds = null
+  const permAuthCache = getAuthCache(PERMISSION_SELECT_KEY)
+  if (permAuthCache && permAuthCache[dataType]) {
+    if (isArray(permAuthCache[dataType])) {
+      // 防止类型为custom但staffIds为空数组的情况
+      if (!permAuthCache[dataType].length) {
+        defaultValue = 'oneself'
+        defaultStaffIds = null
+      } else {
+        defaultValue = 'custom'
+        defaultStaffIds = permAuthCache[dataType]
+      }
+    } else {
+      defaultValue = permAuthCache[dataType]
+    }
+  }
+  return [defaultValue, defaultStaffIds]
+}

+ 1 - 1
src/utils/cache/persistent.ts

@@ -19,7 +19,7 @@ import { pick, omit } from 'lodash-es'
 interface BasicStore {
   [TOKEN_KEY]: string | null | undefined
   [CASCADER_HISTORY_KEY]: { key: string; value: string[]; label: string }[] | null | underfined
-  [PERMISSION_SELECT_KEY]: { [key in MAIN_MENU_KEY]: string } | null | underfined
+  [PERMISSION_SELECT_KEY]: { [key in MAIN_MENU_KEY]: string | string[] } | null | underfined
   [TABLE_COLUMNS_MAP]: { [key in MAIN_MENU_KEY]: Record<string, ColumnsState> } | null | underfined
   [WORKBENCH_CYCLICAL_KEY]: string
 }

+ 1 - 1
src/utils/is.ts

@@ -28,7 +28,7 @@ export function isString(val: unknown): val is string {
   return is(val, 'String')
 }
 
-export function isArray(val: any): val is Array<any> {
+export function isArray(val: any): val is any[] {
   return val && Array.isArray(val)
 }