Browse Source

feat: 调整cld2后台

lanjianrong 4 years ago
parent
commit
0af26d8ea1

+ 2 - 1
package.json

@@ -61,6 +61,7 @@
     "lodash": "^4.17.11",
     "moment": "^2.25.3",
     "omit.js": "^2.0.2",
+    "rc-queue-anim": "^1.8.5",
     "react": "^17.0.0",
     "react-dev-inspector": "^1.1.1",
     "react-dom": "^17.0.0",
@@ -107,7 +108,7 @@
     "stylelint": "^13.0.0",
     "typescript": "^4.2.2",
     "windicss": "3.0.12",
-    "windicss-webpack-plugin": "0.6.1"
+    "windicss-webpack-plugin": "1.0.0"
   },
   "engines": {
     "node": ">=10.0.0"

+ 34 - 25
src/pages/Role/System/components/ConnectModal/index.tsx

@@ -3,7 +3,8 @@ import { Button, Input, message, Modal } from 'antd'
 import React, { useState, useRef, useEffect } from 'react'
 import { addRoleStaff, fetchStaffList } from '@/services/user/api'
 import './index.less'
-import { useDebounceFn } from 'ahooks'
+import QueueAnim from 'rc-queue-anim'
+import { LoadingOutlined, MoreOutlined } from '@ant-design/icons'
 
 interface ConnectModalProps {
   title: string
@@ -47,10 +48,14 @@ const ConnectModal: React.FC<ConnectModalProps> = ({ title, dataId, onSelect })
       refreshDeps: [searchVal]
     }
   )
-  const { run } = useDebounceFn((value: string) => setSearchVal(value))
-  const handleSearch = () => {
-    run()
+
+  const handleSearch = (value: string) => {
+    setSearchVal(value)
+    setTimeout(() => {
+      tryQueryStaffList()
+    }, 250)
   }
+
   const { list = [] }: { list: API.StaffItem[] } = data || {}
   useEffect(() => {
     if (visible) {
@@ -59,8 +64,6 @@ const ConnectModal: React.FC<ConnectModalProps> = ({ title, dataId, onSelect })
   }, [visible])
 
   const itemSelectHandler = (staffId: string) => {
-    console.log('staffId', staffId, 'dataId', dataId)
-
     tryAddRoleStaff({ id: dataId, staffId })
     if (onSelect) {
       onSelect()
@@ -83,27 +86,33 @@ const ConnectModal: React.FC<ConnectModalProps> = ({ title, dataId, onSelect })
             onPressEnter={e => handleSearch(e.currentTarget.value)}
             style={{ width: '95%' }}></Input.Search>
         }>
-        <div ref={containerRef} className="h-60vh overflow-y-auto modal-content">
-          {list.map(item => (
-            <div className="card" key={item.staffId}>
-              <div className="w-4/3 flex justify-between">
-                <span className="w-1/5">{item.username}</span>
-                <span className="w-2/5">{item.phone}</span>
-                <span className="w-1/5">{item.position}</span>
-                <span className="w-1/5">{item.category}</span>
+        <div ref={containerRef} className="h-60vh overflow-y-auto overflow-x-hidden modal-content">
+          <QueueAnim>
+            {list.map(item => (
+              <div className="card" key={item.staffId}>
+                <div className="w-4/3 flex justify-between">
+                  <span className="w-1/5">{item.username}</span>
+                  <span className="w-2/5">{item.phone}</span>
+                  <span className="w-1/5">{item.position}</span>
+                  <span className="w-1/5">{item.category}</span>
+                </div>
+                <div className="w-1/4 flex justify-end">
+                  <span className="btn-outline" onClick={() => itemSelectHandler(item.staffId)}>
+                    选择ta
+                  </span>
+                </div>
               </div>
-              <div className="w-1/4 flex justify-end">
-                <span className="btn-outline" onClick={() => itemSelectHandler(item.staffId)}>
-                  选择ta
-                </span>
-              </div>
-            </div>
-          ))}
-          {noMore && <span>数据已全部加载完毕</span>}
+            ))}
+          </QueueAnim>
+          {noMore && <div className="text-center text-gray-400">已到底部</div>}
           {!noMore && (
-            <button type="button" onClick={loadMore} disabled={loadingMore}>
-              {loadingMore ? 'Loading more...' : 'Click to load more'}
-            </button>
+            <div className="text-center mt-3 cursor-pointer">
+              {loadingMore ? (
+                <LoadingOutlined />
+              ) : (
+                <MoreOutlined rotate={90} style={{ fontSize: 24 }} onClick={loadMore} />
+              )}
+            </div>
           )}
         </div>
       </Modal>

+ 30 - 13
src/pages/Role/System/components/RoleMenu/roleMenu.tsx

@@ -3,7 +3,7 @@ import { PlusOutlined, DownOutlined } from '@ant-design/icons'
 import { Button, message, Popover } from 'antd'
 import './index.less'
 import { useRequest } from 'umi'
-import { createRoleWithMenuId, fetchRoleListByMenuId } from '@/services/user/api'
+import { createRoleWithMenuId, fetchRoleListByMenuId, deleteRole } from '@/services/user/api'
 import { ModalForm, ProFormText } from '@ant-design/pro-form'
 
 type RoleMenuProps = {
@@ -12,6 +12,7 @@ type RoleMenuProps = {
 }
 
 const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect }) => {
+  const [activeId, setActiveId] = useState('')
   const [menuRoles, setMenuRoles] = useState<API.MenuRoleItem[]>([])
   const { run: tryFetchMenuRoles } = useRequest((id: string) => fetchRoleListByMenuId(id), {
     manual: true,
@@ -20,6 +21,20 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect }) => {
     }
   })
 
+  const { run: tryDeleteRole } = useRequest(
+    (id: string) => {
+      if (activeId === id) {
+        setActiveId('')
+      }
+      deleteRole({ id })
+    },
+    {
+      manual: true,
+      onSuccess: async () => {
+        await tryFetchMenuRoles()
+      }
+    }
+  )
   const { run: tryAddRole } = useRequest(
     (params: API.CreateRoleParams) => createRoleWithMenuId(params),
     {
@@ -32,7 +47,6 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect }) => {
   useEffect(() => {
     tryFetchMenuRoles(menuId)
   }, [])
-  const [activeId, setActiveId] = useState('')
 
   const handleItemClick = (id: string) => {
     setActiveId(id)
@@ -41,16 +55,6 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect }) => {
     }
   }
 
-  const content = (
-    <div className="popoverList">
-      <ul>
-        <li>复制</li>
-        <li>粘贴</li>
-        <li className="text-red-500">删除</li>
-      </ul>
-    </div>
-  )
-
   return (
     <div className="h-full w-max-234px rounded-4px roleMenu">
       <div className="p-4 border-b-1 border-solid border-black border-opacity-10 bg-[#f7f9fa] flex justify-around items-center">
@@ -86,7 +90,20 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect }) => {
               ].join(' ')}
               onClick={() => handleItemClick(item.id)}>
               <span>{item.name}</span>
-              <Popover placement="bottomRight" content={content} trigger="click">
+              <Popover
+                placement="bottomRight"
+                content={
+                  <div className="popoverList">
+                    <ul>
+                      <li>复制</li>
+                      <li>粘贴</li>
+                      <li className="text-red-500" onClick={() => tryDeleteRole(item.id)}>
+                        删除
+                      </li>
+                    </ul>
+                  </div>
+                }
+                trigger="click">
                 <DownOutlined />
               </Popover>
             </li>

+ 61 - 44
src/pages/Role/System/index.tsx

@@ -1,40 +1,47 @@
 import { useModel, useRequest } from 'umi'
 import Icon from '@/components/IconPark'
 import ProForm, { ProFormCheckbox, ProFormDependency, ProFormSwitch } from '@ant-design/pro-form'
-import { Table, Tabs } from 'antd'
+import { message, Table, Tabs } from 'antd'
 import React, { useMemo, useState, useEffect } from 'react'
 import RoleMenu from './components/RoleMenu/roleMenu'
-import { fetchRoleStaffListByRoleId } from '@/services/user/api'
+import { fetchRoleStaffListByRoleId, updateRolePermission } from '@/services/user/api'
 import type { ColumnsType } from 'antd/lib/table'
 import ConnectModal from './components/ConnectModal'
+import { formatPermission } from '@/utils/utils'
 
-const System: React.FC = () => {
+const System = () => {
   const { TabPane } = Tabs
 
   const columns: ColumnsType<API.RoleStaffListItem> = [
     {
       title: '用户',
-      dataIndex: 'username'
+      dataIndex: 'username',
+      width: '15%'
     },
     {
       title: '手机',
-      dataIndex: 'phone'
+      dataIndex: 'phone',
+      width: '20%'
     },
     {
       title: '部门',
-      dataIndex: 'departmentName'
+      dataIndex: 'departmentName',
+      width: '20%'
     },
     {
       title: '岗位',
-      dataIndex: 'position'
+      dataIndex: 'position',
+      width: '15%'
     },
     {
       title: '角色',
-      dataIndex: 'age'
+      dataIndex: 'age',
+      width: '20%'
     },
     {
       title: '操作',
       dataIndex: 'opreate',
+      width: '20%',
       render: () => (
         <span className="hover:text-hex-e7026e">
           <Icon type="delete" fill="#fd3995" />
@@ -48,7 +55,7 @@ const System: React.FC = () => {
     return initialState?.menuList?.find(item => item.name === '系统管理')?.id
   }, initialState.menuList)
 
-  const [state, setState] = useState<{ id: string; roleStaff: API.RoleStaffListItem[] }>({
+  const [state, setState] = useState({
     id: '',
     roleStaff: []
   })
@@ -75,6 +82,7 @@ const System: React.FC = () => {
     <div className="h-full w-full flex flex-row">
       <RoleMenu menuId={menuId} onSelect={onSelect} />
       <div className="w-max-3/4">
+        <div></div>
         <div className="ml-8 bg-white p-4 shadow-md shadow-hex-3e2c5a relative">
           <div className="absolute right-4 top-4 z-100">
             {state.id && (
@@ -94,8 +102,15 @@ const System: React.FC = () => {
               />
             </TabPane>
             <TabPane tab="角色权限" key="2">
-              <ProForm layout="horizontal" initialValues={{ staff: ['1', '2'] }}>
-                <ProFormSwitch
+              {state.id && (
+                <ProForm
+                  layout="horizontal"
+                  onFinish={async values => {
+                    const newValues = formatPermission(values)
+                    await updateRolePermission({ permission: [newValues], id: state.id })
+                    message.success('设置成功')
+                  }}>
+                  {/* <ProFormSwitch
                   name="showHome"
                   label={
                     <span className="flex items-center">
@@ -103,39 +118,40 @@ const System: React.FC = () => {
                       后台首页
                     </span>
                   }
-                />
+                /> */}
 
-                <ProFormSwitch
-                  name="showAuth"
-                  label={
-                    <span className="flex items-center">
-                      <Icon
-                        type="every-user"
-                        className="mr-1"
-                        className="flex items-baseline mr-1"
+                  <ProFormSwitch
+                    name="showSystem"
+                    label={
+                      <span className="flex items-center">
+                        <Icon
+                          type="every-user"
+                          className="mr-1"
+                          className="flex items-baseline mr-1"
+                        />
+                        角色权限管理
+                      </span>
+                    }
+                  />
+                  <ProFormDependency name={['showSystem']}>
+                    {({ showSystem }) => (
+                      <ProFormCheckbox.Group
+                        wrapperCol={{ offset: 1 }}
+                        // initialValue={}
+                        name="system"
+                        options={[
+                          { value: 'system', label: '系统管理', disabled: !showSystem },
+                          { value: 'customer', label: '客户', disabled: !showSystem }
+                          // { value: '3', label: '产品', disabled: !showAuth },
+                          // { value: '4', label: '开票合同', disabled: !showAuth },
+                          // { value: '5', label: '考勤', disabled: !showAuth },
+                          // { value: '6', label: '人资', disabled: !showAuth },
+                          // { value: '7', label: '财务费用', disabled: !showAuth }
+                        ]}
                       />
-                      角色权限管理
-                    </span>
-                  }
-                />
-                <ProFormDependency name={['showAuth']}>
-                  {({ showAuth }) => (
-                    <ProFormCheckbox.Group
-                      wrapperCol={{ offset: 1 }}
-                      name="staff"
-                      options={[
-                        { value: '1', label: '系统管理', disabled: !showAuth },
-                        { value: '2', label: '客户', disabled: !showAuth },
-                        { value: '3', label: '产品', disabled: !showAuth },
-                        { value: '4', label: '开票合同', disabled: !showAuth },
-                        { value: '5', label: '考勤', disabled: !showAuth },
-                        { value: '6', label: '人资', disabled: !showAuth },
-                        { value: '7', label: '财务费用', disabled: !showAuth }
-                      ]}
-                    />
-                  )}
-                </ProFormDependency>
-                <ProFormSwitch
+                    )}
+                  </ProFormDependency>
+                  {/* <ProFormSwitch
                   name="showAudit"
                   label={
                     <span className="flex items-center">
@@ -187,8 +203,9 @@ const System: React.FC = () => {
                       ]}
                     />
                   )}
-                </ProFormDependency>
-              </ProForm>
+                </ProFormDependency> */}
+                </ProForm>
+              )}
             </TabPane>
           </Tabs>
         </div>

+ 17 - 0
src/services/user/api.ts

@@ -73,6 +73,15 @@ export async function addRoleStaff(params: API.AddRoleStaffParams) {
     data: params
   })
 }
+
+/** 角色下更新权限 */
+export async function updateRolePermission(params: API.UpdateRolePermissionParams) {
+  return request('/role/permission/save', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 获取员工列表 */
 export async function fetchStaffList(params: API.GetStaffListParams) {
   return request<API.StaffItem[]>('/api/staff/list', {
@@ -80,3 +89,11 @@ export async function fetchStaffList(params: API.GetStaffListParams) {
     prefix: ''
   })
 }
+
+/** 删除角色 */
+export async function deleteRole({ id }: { id: string }) {
+  return request('/role/delete', {
+    method: 'POST',
+    data: { id }
+  })
+}

+ 5 - 0
src/services/user/typings.d.ts

@@ -163,4 +163,9 @@ declare namespace API {
     id: string
     staffId: string
   }
+
+  type UpdateRolePermissionParams = {
+    id: string
+    permission: any[]
+  }
 }

+ 13 - 0
src/utils/utils.ts

@@ -19,3 +19,16 @@ export const isAntDesignProOrDev = (): boolean => {
   }
   return isAntDesignPro()
 }
+
+export const formatPermission = (values: any) => {
+  const newValues = { ...values }
+  // eslint-disable-next-line no-restricted-syntax
+  for (const key in newValues) {
+    if (Object.prototype.hasOwnProperty.call(values, key)) {
+      if (key.indexOf('show') !== -1) {
+        delete newValues[key]
+      }
+    }
+  }
+  return newValues
+}