Sfoglia il codice sorgente

feat: 后台人员管理+后台功能角色设置相关

fix: 去除重复的权限设置
outaozhen 2 anni fa
parent
commit
4fb55e057a

+ 6 - 0
config/routes.ts

@@ -262,6 +262,12 @@ const routes: Route[] = [
         name: BackstagePermission.VIEW_SYSTEM_ADMIN_SETTING,
         access: 'authRouteFilter',
         component: './System/Admin'
+      },
+      {
+        path: 'account',
+        name: BackstagePermission.VIEW_SYSTEM_ACCOUNT,
+        access: 'authRouteFilter',
+        component: './System/Account'
       }
     ]
   },

+ 3 - 1
src/enums/access.ts

@@ -98,5 +98,7 @@ export enum BackstagePermission {
   /** 后台权限设置-查看信息 */
   VIEW_BACK_PERMISSION_ROLE = 'viewBackPermissionRole',
   /** 系统设置-查看管理员 */
-  VIEW_SYSTEM_ADMIN_SETTING = 'viewSystemAdminSetting'
+  VIEW_SYSTEM_ADMIN_SETTING = 'viewSystemAdminSetting',
+  /** 后台人员管理- */
+  VIEW_SYSTEM_ACCOUNT = 'viewSystemAccount'
 }

+ 1 - 0
src/locales/zh-CN/menu.ts

@@ -48,5 +48,6 @@ export default {
   'menu.system': '系统管理',
   'menu.system.setting': '系统设置',
   'menu.system.viewSystemAdminSetting': '管理员',
+  'menu.system.viewSystemAccount': '后台人员管理',
   'menu.schema.test': '测试'
 }

+ 62 - 0
src/pages/Permission/BackRole/components/ConnectModal/index.tsx

@@ -0,0 +1,62 @@
+import { fetchRoleBgStaffListByRoleId, linkRoleBgAccount } from '@/services/permission'
+import { PlusOutlined } from '@ant-design/icons'
+import { ModalForm, ProFormSelect } from '@ant-design/pro-form'
+import { Button, message } from 'antd'
+import { useEffect, useRef, useState } from 'react'
+import type { ProFormInstance } from '@ant-design/pro-form'
+import { useRequest } from '@umijs/max'
+
+const ConnectModal = ({ dataId, onReload }) => {
+  const formRef = useRef<ProFormInstance>(null)
+  const [menuRoles, setMenuRoles] = useState([])
+  const { run: tryGetRoleBgStaffList } = useRequest(
+    (params: { roleID: string; search?: string }) =>
+      fetchRoleBgStaffListByRoleId({ pageNo: 1, pageSize: 214000, ...params }),
+    {
+      manual: true,
+      onSuccess: result => {
+        setMenuRoles(result.items)
+      }
+    }
+  )
+  const { run: tryConnectRoleBgAccount } = useRequest(
+    (params: API.LinkAccountParams) => linkRoleBgAccount(params),
+    {
+      manual: true,
+      onSuccess: async () => {
+        await onReload()
+      }
+    }
+  )
+  useEffect(() => {
+    tryGetRoleBgStaffList()
+  }, [])
+  return (
+    <ModalForm
+      formRef={formRef}
+      title="添加用户"
+      width="30%"
+      onVisibleChange={visible => !visible && formRef.current?.resetFields()}
+      layout="horizontal"
+      trigger={
+        <Button size="small" type="primary" ghost>
+          <PlusOutlined />
+          添加用户
+        </Button>
+      }
+      onFinish={async values => {
+        await tryConnectRoleBgAccount({ ...values, ID: dataId })
+        message.success('添加成功')
+        return true
+      }}>
+      <ProFormSelect
+        label="角色名称"
+        name="accountIDs"
+        className="w-full"
+        options={menuRoles?.map(item => ({ value: item.ID, label: item.name }))}
+      />
+    </ModalForm>
+  )
+}
+
+export default ConnectModal

+ 17 - 23
src/pages/Permission/BackRole/components/PermTabs/index.tsx

@@ -2,7 +2,7 @@ import { useState } from 'react'
 import { useRequest } from '@umijs/max'
 import { RoleType } from '../RoleLeftMenu'
 import { Card, Checkbox, Button, message, Spin, Affix } from 'antd'
-import { queryRoleDetailByID, setRolePermission } from '@/services/permission'
+import { queryRoleBgDetailByID, setRoleBgPermission } from '@/services/permission'
 import { BackstagePermission } from '@/enums/access'
 
 import './index.less'
@@ -23,7 +23,7 @@ const filterPermission = (permission: string[]) => {
 const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
   const [permission, setPermission] = useState([])
 
-  const { loading } = useRequest(() => queryRoleDetailByID({ ID }), {
+  const { loading } = useRequest(() => queryRoleBgDetailByID({ ID }), {
     refreshDeps: [ID],
     onSuccess: ({ backstagePermission = [] } = {}) => {
       setPermission(filterPermission(backstagePermission))
@@ -31,8 +31,8 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
     onError: e => console.log(e)
   })
 
-  const { run: trySetRolePermission, loading: submitStauts } = useRequest(
-    (params: API.RolePermissionParams) => setRolePermission(params),
+  const { run: trySetRoleBgPermission, loading: submitStauts } = useRequest(
+    (params: API.RolePermissionParams) => setRoleBgPermission(params),
     {
       manual: true,
       onSuccess: () => {
@@ -53,7 +53,7 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
       ID,
       frontPermission: filterPermission(permission)
     }
-    trySetRolePermission(params)
+    trySetRoleBgPermission(params)
   }
 
   return (
@@ -265,18 +265,6 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
                 </div>
               </div>
               <div>
-                <h4 className="pt-3">流程用户配置</h4>
-                <div className="my-2">
-                  <Checkbox
-                    onChange={e =>
-                      handleBackOnchange(e.target.checked, BackstagePermission.VIEW_INVENTORY_TEMPLATE)
-                    }
-                    checked={permission.includes(BackstagePermission.VIEW_INVENTORY_TEMPLATE)}>
-                    查看流程用户
-                  </Checkbox>
-                </div>
-              </div>
-              <div>
                 <h4 className="pt-3">业务编号配置</h4>
                 <div className="my-2">
                   <Checkbox
@@ -393,12 +381,18 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
                     checked={permission.includes(BackstagePermission.VIEW_SYSTEM_ADMIN_SETTING)}>
                     查看信息
                   </Checkbox>
-                  {/* <Checkbox
-                    onChange={e => handleBackOnchange(e.target.checked, 'editBa9')}
-                    checked={permission.includes('updatePsw')}
-                    >
-                    编辑信息
-                  </Checkbox> */}
+                </div>
+              </div>
+              <div>
+                <h4>后台人员管理</h4>
+                <div className="my-2">
+                  <Checkbox
+                    onChange={e =>
+                      handleBackOnchange(e.target.checked, BackstagePermission.VIEW_SYSTEM_ACCOUNT)
+                    }
+                    checked={permission.includes(BackstagePermission.VIEW_SYSTEM_ACCOUNT)}>
+                    查看信息
+                  </Checkbox>
                 </div>
               </div>
             </Card>

+ 9 - 9
src/pages/Permission/BackRole/components/RoleLeftMenu/index.tsx

@@ -1,4 +1,4 @@
-import { addRoleMenu, delRoleMenuByRoleID, updateRoleMenu } from '@/services/permission'
+import { addRoleBgMenu, delRoleBgMenuByRoleID, updateRoleBgMenu } from '@/services/permission'
 import { isNullOrUnDef } from '@/utils/is'
 import { DeleteOutlined, FormOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
 import { ModalForm, ProFormText } from '@ant-design/pro-form'
@@ -33,15 +33,15 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
   const formRef = useRef<ProFormInstance>(null)
   const [activeID, setActiveID] = useState<Nullable<string>>(null)
 
-  const { run: tryAddRole } = useRequest((params: API.CreateRoleParams) => addRoleMenu(params), {
+  const { run: tryAddRoleBg } = useRequest((params: API.CreateRoleParams) => addRoleBgMenu(params), {
     manual: true,
     onSuccess: () => {
       onReloadStaff()
     }
   })
 
-  const { run: tryUpdateRole } = useRequest(
-    (params: Partial<API.UpdateRoleParams>) => updateRoleMenu(params),
+  const { run: tryUpdateRoleBg } = useRequest(
+    (params: Partial<API.UpdateRoleParams>) => updateRoleBgMenu(params),
     {
       manual: true,
       onSuccess: () => {
@@ -51,7 +51,7 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
     }
   )
 
-  const { run: tryDelRole } = useRequest((ID: string) => delRoleMenuByRoleID({ ID }), {
+  const { run: tryDelRoleBg } = useRequest((ID: string) => delRoleBgMenuByRoleID({ ID }), {
     manual: true,
     onSuccess: () => {
       message.success('删除成功')
@@ -65,7 +65,7 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
   ) => {
     const val = e.currentTarget.value || e.currentTarget.nodeValue
     if (val !== oldTitle) {
-      await tryUpdateRole({ ID, name: val })
+      await tryUpdateRoleBg({ ID, name: val })
     }
     setActiveID(null)
   }
@@ -75,7 +75,7 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
       // 系统管理员,系统用户不能删除、编辑
       const newItem = {
         ...item,
-        title: [RoleType.SYSTEM, RoleType.SYSTEM_NORMAL].includes(item.roleType) ? (
+        title: [RoleType.SYSTEM].includes(item.roleType) ? (
           <span className="department-node py-1">{item.title}</span>
         ) : (
           <div className="department-node py-1">
@@ -99,7 +99,7 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
                 title="确认删除吗?"
                 onText="确认"
                 cancelText="取消"
-                onConfirm={() => tryDelRole(item.key)}
+                onConfirm={() => tryDelRoleBg(item.key)}
                 icon={<QuestionCircleOutlined style={{ color: 'red' }} />}>
                 <DeleteOutlined
                   onClick={() => {
@@ -138,7 +138,7 @@ const RoleLeftMenu: React.FC<RoleLeftMenuProps> = ({
             </Button>
           }
           onFinish={async values => {
-            await tryAddRole(values)
+            await tryAddRoleBg(values)
             message.success('添加成功')
             return true
           }}>

+ 17 - 17
src/pages/Permission/BackRole/index.tsx

@@ -1,4 +1,4 @@
-import { fetchRoleList, unLinkRoleAccount, fetchRoleStaffListByRoleId } from '@/services/permission'
+import { fetchRoleBgList, unLinkRoleBgAccount, fetchRoleBgStaffListByRoleId } from '@/services/permission'
 import { DeleteOutlined } from '@ant-design/icons'
 import { PageContainer } from '@ant-design/pro-layout'
 import { Input, message, Popconfirm, Table, Tabs } from 'antd'
@@ -7,7 +7,7 @@ import { useRequest } from '@umijs/max'
 import RoleLeftMenu, { RoleType } from './components/RoleLeftMenu'
 import PermTabs from './components/PermTabs'
 import type { ColumnsType } from 'antd/lib/table'
-import ConnectModal from '../FrontRole/components/ConnectModal'
+import ConnectModal from './components/ConnectModal'
 const { TabPane } = Tabs
 
 const Role = () => {
@@ -19,9 +19,9 @@ const Role = () => {
   })
 
   const [menuRoles, setMenuRoles] = useState([])
-  const { run: tryGetRoleStaffList, loading: staffListLoading } = useRequest(
+  const { run: tryGetRoleBgStaffList, loading: staffListLoading } = useRequest(
     (params: { roleID: string; search?: string }) =>
-      fetchRoleStaffListByRoleId({ pageNo: 1, pageSize: 214000, ...params }),
+      fetchRoleBgStaffListByRoleId({ pageNo: 1, pageSize: 214000, ...params }),
     {
       manual: true,
       onSuccess: result => {
@@ -29,13 +29,13 @@ const Role = () => {
       }
     }
   )
-  const { run: tryUnLinkRoleAccount } = useRequest(
-    (params: API.LinkAccountParams) => unLinkRoleAccount(params),
+  const { run: tryUnLinkRoleBgAccount } = useRequest(
+    (params: API.LinkAccountParams) => unLinkRoleBgAccount(params),
     {
       manual: true,
       onSuccess: async () => {
         message.success('移除成功')
-        await tryGetRoleStaffList({ roleID: state.currentRoleID })
+        await tryGetRoleBgStaffList({ roleID: state.currentRoleID })
       }
     }
   )
@@ -43,10 +43,10 @@ const Role = () => {
   const onSelect = (currentRoleID: string, roleType: string) => {
     if (state.currentRoleID === currentRoleID) return
     setState({ ...state, currentRoleID, roleType })
-    tryGetRoleStaffList({ roleID: currentRoleID })
+    tryGetRoleBgStaffList({ roleID: currentRoleID })
   }
 
-  const { run: tryFetchRoleListByMenu } = useRequest(fetchRoleList, {
+  const { run: tryFetchRoleBgListByMenu } = useRequest(fetchRoleBgList, {
     onSuccess: result => {
       setMenuRoles(
         result.map(item => ({
@@ -64,7 +64,7 @@ const Role = () => {
     if (state.roleStaff.length) {
       return message.warning('请先移除该角色下的所有用户')
     }
-    tryDelRole(ID)
+    tryDelRoleBg(ID)
   }
   const columns: ColumnsType<API.MenuByRoleIdItem> = [
     {
@@ -78,7 +78,7 @@ const Role = () => {
       width: '15%'
     },
     {
-      title: '企事业名称',
+      title: '业务主体',
       dataIndex: 'institutionID',
       width: '35%',
       render: (_, record) => record.institution?.name
@@ -88,13 +88,13 @@ const Role = () => {
       dataIndex: 'operation',
       width: '10%',
       render: (_, record) =>
-        ![RoleType.SYSTEM, RoleType.SYSTEM_NORMAL].includes(state.roleType) && (
+        ![RoleType.SYSTEM].includes(state.roleType) && (
           <Popconfirm
             title="确定移除吗?"
             okText="确定"
             cancelText="取消"
             onConfirm={() => {
-              tryUnLinkRoleAccount({ ID: state.currentRoleID, accountID: record.ID })
+              tryUnLinkRoleBgAccount({ ID: state.currentRoleID, accountID: record.ID })
             }}>
             <span className="text-hex-fd3995 cursor-pointer hover:text-hex-e7026e">
               <DeleteOutlined />
@@ -114,7 +114,7 @@ const Role = () => {
           onSelect={onSelect}
           menuRoles={menuRoles}
           showDelIcon={!state.roleStaff.length}
-          onReloadStaff={() => tryFetchRoleListByMenu()}
+          onReloadStaff={() => tryFetchRoleBgListByMenu()}
           delRoleValidFn={delRoleValidFn}
         />
         <div className="w-6/7 ml-8 bg-white p-4 rounded-20px relative">
@@ -124,12 +124,12 @@ const Role = () => {
                 <div className="flex items-center children:mx-1">
                   <Input.Search
                     placeholder="请输入账号或姓名"
-                    onSearch={value => tryGetRoleStaffList({ roleID: state.currentRoleID, search: value })}
+                    onSearch={value => tryGetRoleBgStaffList({ roleID: state.currentRoleID, search: value })}
                   />
                   {state.currentRoleID && state.roleType !== RoleType.SYSTEM && (
                     <ConnectModal
                       dataId={state.currentRoleID}
-                      onReload={() => tryGetRoleStaffList({ roleID: state.currentRoleID })}
+                      onReload={() => tryGetRoleBgStaffList({ roleID: state.currentRoleID })}
                     />
                   )}
                 </div>
@@ -145,7 +145,7 @@ const Role = () => {
                   y: document.body.clientHeight - (285 + wrapHeight)
                 }}
                 dataSource={state.roleStaff}
-                rowKey={row => row.id}
+                rowKey={row => row.ID}
               />
             </TabPane>
             <TabPane tab="功能权限" key="2">

+ 498 - 0
src/pages/Permission/Role/components/PermTabs/index.tsx

@@ -0,0 +1,498 @@
+import { Card, Tabs, Checkbox, Button, message, Spin } from 'antd'
+import React, { useState } from 'react'
+import { queryRoleDetailByID, setRolePermission } from '@/services/permission'
+import { useRequest } from '@umijs/max'
+import { RoleType } from '../RoleLeftMenu'
+import './index.less'
+const { TabPane } = Tabs
+
+type PermTabsProps = {
+  currentPermData: {
+    ID: string
+    roleType: RoleType
+  }
+}
+export enum OperationType {
+  FRONT = 'front', // 前台
+  BACKSTAGE = 'backstage' // 后台
+}
+const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID, roleType } }) => {
+  const [state, setState] = useState({
+    frontPermission: [], // 前台权限
+    backstagePermission: [] // 后台权限
+  })
+
+  const { loading } = useRequest(() => queryRoleDetailByID({ ID }), {
+    refreshDeps: [ID],
+    onSuccess: ({ frontPermission = [], backstagePermission = [] } = {}) => {
+      setState({ ...state, frontPermission, backstagePermission })
+    },
+    onError: e => console.log(e)
+  })
+
+  const { run: trySetRolePermission, loading: submitStauts } = useRequest(
+    (params: API.SetRolePermissionParams) => setRolePermission(params),
+    {
+      manual: true,
+      onSuccess: () => {
+        message.success('设置成功')
+      }
+    }
+  )
+  const handleFrontOnchange = (checked: boolean, perm: string) => {
+    if (checked) {
+      setState({ ...state, frontPermission: [...state.frontPermission, perm] })
+    } else {
+      setState({ ...state, frontPermission: state.frontPermission.filter(item => item !== perm) })
+    }
+  }
+  const handleBackOnchange = (checked: boolean, perm: string) => {
+    if (checked) {
+      setState({ ...state, backstagePermission: [...state.backstagePermission, perm] })
+    } else {
+      setState({
+        ...state,
+        backstagePermission: state.backstagePermission.filter(item => item !== perm)
+      })
+    }
+  }
+  const handleSubmitFront = () => {
+    trySetRolePermission({
+      ID,
+      operation: OperationType.FRONT,
+      frontPermission: state.frontPermission
+    })
+  }
+
+  const handleSubmitBackstage = () => {
+    trySetRolePermission({
+      ID,
+      operation: OperationType.BACKSTAGE,
+      backstagePermission: state.backstagePermission
+    })
+  }
+
+  return (
+    <div>
+      <Tabs type="card">
+        <TabPane tab="前台" key="3" className="tab-height overflow-y-auto">
+          <Spin spinning={loading}>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="待办列表">
+                <div>
+                  {/* <h4>我的项目</h4> */}
+                  <div className="my-2">
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'todo')} disabled>
+                      已办待办
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="项目列表">
+                <div>
+                  <h4>我的项目</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'viewProject')}
+                      checked={state.frontPermission.includes('viewProject')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      查看项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'addProject')}
+                      checked={state.frontPermission.includes('addProject')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      新建项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'editProject')}
+                      checked={state.frontPermission.includes('editProject')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      编辑项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'exportProject')}
+                      checked={state.frontPermission.includes('exportProject')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      导出项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'delProject')}
+                      checked={state.frontPermission.includes('delProject')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      删除项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'report')}
+                      checked={state.frontPermission.includes('report')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      项目上报(审批模板)
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'report1')}
+                      checked={state.frontPermission.includes('report1')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      项目上报(自由流程)
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">我参与的项目</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      disabled={roleType === RoleType.SYSTEM}
+                      checked={state.frontPermission.includes('viewParticipatingProject')}
+                      onChange={e => handleFrontOnchange(e.target.checked, 'viewParticipatingProject')}>
+                      查看项目
+                    </Checkbox>
+                    <Checkbox
+                      disabled={roleType === RoleType.SYSTEM}
+                      checked={state.frontPermission.includes('saveIndex')}
+                      onChange={e => handleFrontOnchange(e.target.checked, 'saveIndex')}>
+                      指标入库
+                    </Checkbox>
+                    <Checkbox
+                      disabled={roleType === RoleType.SYSTEM}
+                      checked={state.frontPermission.includes('exportParticipatingProject')}
+                      onChange={e => handleFrontOnchange(e.target.checked, 'exportParticipatingProject')}>
+                      导出
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">全部项目</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleFrontOnchange(e.target.checked, 'viewAllProjects')}
+                      checked={state.frontPermission.includes('viewAllProjects')}
+                      disabled={roleType === RoleType.SYSTEM}>
+                      查看项目
+                    </Checkbox>
+                    <Checkbox
+                      disabled={roleType === RoleType.SYSTEM}
+                      checked={state.frontPermission.includes('saveIndexAll')}
+                      onChange={e => handleFrontOnchange(e.target.checked, 'saveIndexAll')}>
+                      指标入库
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">指标库</h4>
+                  <div className="my-2">
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'section')} disabled>
+                      区间对数
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="个人设置">
+                <div>
+                  <h4>基本设置</h4>
+                  <div className="my-2">
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'edit')} disabled>
+                      编辑
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">企事业信息</h4>
+                  <div className="my-2">
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'access2')} disabled>
+                      查看
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">安全设置</h4>
+                  <div className="my-2">
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'phone')} disabled>
+                      手机绑定
+                    </Checkbox>
+                    <Checkbox onChange={e => handleFrontOnchange(e.target.checked, 'password')} disabled>
+                      密码修改
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+          </Spin>
+          <Button type="primary" onClick={handleSubmitFront} loading={submitStauts}>
+            提交
+          </Button>
+        </TabPane>
+        <TabPane tab="后台" key="4" className="tab-height overflow-y-auto">
+          <Spin spinning={loading}>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="项目审批设置">
+                <div>
+                  <h4>项目管理</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewManagement')}
+                      checked={state.backstagePermission.includes('viewManagement')}>
+                      查看项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'addBa1')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      新建项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa1')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑项目
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'bindBa1')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      绑定角色
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'deployBa1')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      流程配置
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">审批流程模板</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewVerification')}
+                      checked={state.backstagePermission.includes('viewVerification')}>
+                      查看流程
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'addBa2')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      新建流程
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa2')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑流程
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="企事业单位">
+                <div>
+                  <h4>单位管理</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewCompany')}
+                      checked={state.backstagePermission.includes('viewCompany')}>
+                      查看单位
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'addBa4')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      新建单位
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'staff')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      人员管理
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'organizational')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      组织管理
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'deploy')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      单位设置
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">人员管理</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewStaff')}
+                      checked={state.backstagePermission.includes('viewStaff')}>
+                      查看人员
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa5')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑人员
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">限制登录</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewRestrict')}
+                      checked={state.backstagePermission.includes('viewRestrict')}>
+                      查看人员
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa5')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑人员
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="业务审批设置">
+                {/* <div>
+                  <h4>业务管理</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewBusiness')}
+                      checked={state.backstagePermission.includes('viewBusiness')}>
+                      查看信息
+                    </Checkbox>
+                  </div>
+                </div> */}
+                <div>
+                  <h4 className="pt-3">流程用户配置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewProcess')}
+                      checked={state.backstagePermission.includes('viewProcess')}>
+                      查看信息
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">资料清单配置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewInventory')}
+                      checked={state.backstagePermission.includes('viewInventory')}>
+                      查看信息
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="表单设置">
+                <div>
+                  <h4>基础数据设置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewBase')}
+                      checked={state.backstagePermission.includes('viewBase')}>
+                      查看项目信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa6')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑项目信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa6')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      查看企事业单位信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa6')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑企事业单位信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa6')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      查看人员信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa6')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑人员信息
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">数据源设置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewOption')}
+                      checked={state.backstagePermission.includes('viewOption')}>
+                      查看信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa7')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑信息
+                    </Checkbox>
+                  </div>
+                </div>
+                <div>
+                  <h4 className="pt-3">预算业务表单设置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewBudget')}
+                      checked={state.backstagePermission.includes('viewBudget')}>
+                      查看信息
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+            <div className="shadow-md mb-4">
+              <Card size="small" type="inner" title="系统管理">
+                <div>
+                  <h4>管理员设置</h4>
+                  <div className="my-2">
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'viewAdmin')}
+                      checked={state.backstagePermission.includes('viewAdmin')}>
+                      查看信息
+                    </Checkbox>
+                    <Checkbox
+                      onChange={e => handleBackOnchange(e.target.checked, 'editBa9')}
+                      checked={state.backstagePermission.includes('updatePsw')}
+                      disabled>
+                      编辑信息
+                    </Checkbox>
+                  </div>
+                </div>
+              </Card>
+            </div>
+          </Spin>
+          <Button type="primary" onClick={handleSubmitBackstage} loading={submitStauts}>
+            提交
+          </Button>
+        </TabPane>
+      </Tabs>
+      {/* <Affix offsetBottom={10}>
+        <Button type="primary" onClick={handleSubmit} loading={submitStauts}>
+          提交
+        </Button>
+      </Affix> */}
+    </div>
+  )
+}
+
+export default PermTabs

+ 230 - 0
src/pages/System/Account/index.tsx

@@ -0,0 +1,230 @@
+import {
+  addAccountBg,
+  delAccountBg,
+  fetchRoleBgList,
+  fetchRoleBgStaffListByRoleId,
+  updateAccountBg
+} from '@/services/permission'
+import consts from '@/utils/consts'
+import { PageContainer } from '@ant-design/pro-layout'
+import ProTable from '@ant-design/pro-table'
+import { Button, Form, Input, message, Modal } from 'antd'
+import React, { useEffect, useRef, useState } from 'react'
+import { ModalForm, ProFormRadio, ProFormSelect, ProFormText } from '@ant-design/pro-form'
+import { useRequest } from '@umijs/max'
+import classNames from 'classnames'
+export enum ModalType {
+  ADD,
+  UPDATE
+}
+
+const Account: React.FC = () => {
+  const tRef = useRef<ActionType>(null)
+  const formRef = useRef<ProFormInstance>(null)
+  const [state, setState] = useState({
+    params: {},
+    visible: false,
+    modalType: 'add',
+    modalVisible: false
+  })
+  const [menuRoles, setMenuRoles] = useState([])
+  const { run: tryFetchRoleBgListByMenu } = useRequest(fetchRoleBgList, {
+    onSuccess: result => {
+      setMenuRoles(result)
+    }
+  })
+  const { run: tryAddAccountBgRole } = useRequest(addAccountBg, {
+    manual: true,
+    onSuccess: () => {
+      message.success('添加成功')
+      tRef.current?.reload()
+    }
+  })
+
+  const { run: tryUpdateAccountBgRole } = useRequest(updateAccountBg, {
+    manual: true,
+    onSuccess: () => {
+      message.success('编辑成功')
+      tRef.current?.reload()
+    }
+  })
+
+  const { run: tryDelAccountBgRole } = useRequest(delAccountBg, {
+    manual: true,
+    onSuccess: () => {
+      message.success('删除成功')
+      tRef.current?.reload()
+    }
+  })
+
+  const handleDel = (ID: string) => {
+    Modal.confirm({
+      title: '删除',
+      content: (
+        <div>
+          <div>确认删除该行数据?</div>
+        </div>
+      ),
+      okButtonProps: {
+        danger: true
+      },
+      onOk: () => tryDelAccountBgRole({ ID })
+    })
+  }
+  useEffect(() => {
+    tryFetchRoleBgListByMenu()
+  }, [])
+  const columns: ProColumnType<API.InstitutionRoleParams>[] = [
+    {
+      dataIndex: 'account',
+      title: '账号',
+      // align: 'center',
+      onHeaderCell: () => ({ style: { textAlign: 'center' } })
+    },
+    {
+      dataIndex: 'name',
+      title: '姓名',
+      onHeaderCell: () => ({ style: { textAlign: 'center' } })
+    },
+    {
+      title: '状态',
+      dataIndex: 'enable',
+      render: text => (
+        <div className="flex items-center">
+          <span
+            className={classNames('w-3 h-3 rounded-1/2 inline-flex', text ? 'bg-green-500' : 'bg-red-500')}
+          />
+          <span className="ml-1">{text ? '启用' : '停用'}</span>
+        </div>
+      )
+    },
+    {
+      dataIndex: 'opreate',
+      title: '操作',
+      onHeaderCell: () => ({ style: { textAlign: 'center' } }),
+      render: (_, record) => (
+        <div className="divide-x divide-bg-gray-400 flex flex-row justify-center">
+          <span
+            className="pr-2 text-primary cursor-pointer hover:text-hex-967bbd"
+            onClick={() => {
+              setTimeout(() => {
+                formRef.current?.setFieldsValue({ ...record })
+              }, 80)
+              setState({
+                ...state,
+                modalType: ModalType.UPDATE,
+                modalVisible: true,
+                ID: record.ID,
+                name: record.name,
+                enable: record.enable
+              })
+            }}>
+            编辑
+          </span>
+          <span
+            className={'pl-2 text-red-500 cursor-pointer hover:text-red-600'}
+            onClick={() => handleDel(record.ID)}>
+            删除
+          </span>
+        </div>
+      )
+    }
+  ]
+  return (
+    <PageContainer title={false}>
+      <div className="h-full w-full flex flex-row">
+        <div className="w-full h-full bg-white">
+          <ProTable
+            rowKey="ID"
+            actionRef={tRef}
+            columns={columns}
+            search={false}
+            scroll={{ y: document.body.clientHeight - 315 }}
+            request={async params => {
+              const { code = -1, data: { items = [], total = 0 } = {} } = await fetchRoleBgStaffListByRoleId({
+                ...params
+              })
+              return {
+                data: items,
+                success: code === consts.RET_CODE.SUCCESS,
+                total
+              }
+            }}
+            toolbar={{
+              actions: [
+                <>
+                  <Button
+                    type="primary"
+                    key="add_flow_btn"
+                    onClick={() => {
+                      setState({
+                        ...state,
+                        modalType: ModalType.ADD,
+                        modalVisible: true
+                      })
+                    }}>
+                    添加人员
+                  </Button>
+                </>
+              ]
+            }}
+          />
+          <ModalForm
+            visible={state.modalVisible}
+            isKeyPressSubmit
+            layout="horizontal"
+            labelCol={{ span: 4 }}
+            modalProps={{
+              width: '30%'
+            }}
+            onVisibleChange={visible => {
+              setState({ ...state, modalVisible: visible })
+              setTimeout(() => {
+                if (!visible) formRef.current?.resetFields()
+              }, 80)
+            }}
+            initialValues={{ enable: true }}
+            title={`${state.modalType === ModalType.ADD ? '添加' : '编辑'}人员`}
+            formRef={formRef}
+            onFinish={async values => {
+              try {
+                if (state.modalType === ModalType.ADD) {
+                  await tryAddAccountBgRole(values)
+                } else {
+                  await tryUpdateAccountBgRole({ ...values, ID: state.ID })
+                }
+                tRef.current?.reload()
+                return true
+              } catch (error) {
+                message.error(error)
+                return false
+              }
+            }}>
+            <ProFormText name="account" label="账号" rules={[{ required: true, message: '请输入' }]} />
+            <ProFormText name="name" label="名称" rules={[{ required: true, message: '请输入' }]} />
+            <Form.Item label="密码" name="password" rules={[{ required: true, message: '请输入' }]}>
+              <Input.Password placeholder="请输入" />
+            </Form.Item>
+            <ProFormSelect
+              label="角色"
+              name="roleIDs"
+              className="w-full"
+              options={menuRoles?.map(item => ({ value: item.ID, label: item.name }))}
+            />
+            <ProFormRadio.Group
+              options={[
+                { label: '启用', value: true },
+                { label: '停用', value: false }
+              ]}
+              name="enable"
+              label="状态"
+              rules={[{ required: true, message: '请选择' }]}
+            />
+          </ModalForm>
+        </div>
+      </div>
+    </PageContainer>
+  )
+}
+
+export default Account

+ 8 - 0
src/services/api/typings.d.ts

@@ -432,4 +432,12 @@ declare namespace API {
     }
     businessType?: string
   }
+
+  type AccountBgParams = {
+    name: string
+    account: string
+    password: string
+    roleIDs: string
+    enable: boolean
+  }
 }

+ 89 - 0
src/services/permission.ts

@@ -7,6 +7,13 @@ export async function fetchRoleList(params: API.RoleListParams) {
   })
 }
 
+/** 获取单菜单下的后台角色列表 */
+export async function fetchRoleBgList(params: API.RoleListParams) {
+  return request<API.MenuRoleItem[]>('/RoleBg/list', {
+    params
+  })
+}
+
 /** 新增菜单下角色 */
 export async function addRoleMenu(params: API.CreateRoleParams) {
   return request('/role/add', {
@@ -15,6 +22,14 @@ export async function addRoleMenu(params: API.CreateRoleParams) {
   })
 }
 
+/** 新增菜单下后台角色 */
+export async function addRoleBgMenu(params: API.CreateRoleParams) {
+  return request('/RoleBg/add', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 编辑菜单下角色 */
 export async function updateRoleMenu(params: Partial<API.UpdateRoleParams>) {
   return request('/role/update', {
@@ -23,6 +38,14 @@ export async function updateRoleMenu(params: Partial<API.UpdateRoleParams>) {
   })
 }
 
+/** 编辑菜单下后台角色 */
+export async function updateRoleBgMenu(params: Partial<API.UpdateRoleParams>) {
+  return request('/RoleBg/update', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 删除菜单下角色 */
 export async function delRoleMenuByRoleID(params: API.DelRoleParams) {
   return request('/role/delete', {
@@ -31,6 +54,14 @@ export async function delRoleMenuByRoleID(params: API.DelRoleParams) {
   })
 }
 
+/** 删除菜单下后台角色 */
+export async function delRoleBgMenuByRoleID(params: API.DelRoleParams) {
+  return request('/RoleBg/delete', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 获取角色下员工列表 */
 export async function fetchRoleStaffListByRoleId(params) {
   return request<API.MenuByRoleIdItem[]>('/account/list', {
@@ -39,6 +70,35 @@ export async function fetchRoleStaffListByRoleId(params) {
   })
 }
 
+/** 获取后台账号列表 */
+export async function fetchRoleBgStaffListByRoleId(params) {
+  return request<API.MenuByRoleIdItem[]>('/AccountBg/list', { params })
+}
+
+/** 新增后台账号 */
+export async function addAccountBg(params: API.AccountBgParams) {
+  return request('/AccountBg/add', {
+    method: 'POST',
+    data: params
+  })
+}
+
+/** 编辑后台账号 */
+export async function updateAccountBg(params: API.AccountBgParams) {
+  return request('/AccountBg/update', {
+    method: 'POST',
+    data: params
+  })
+}
+
+/** 删除后台账号 */
+export async function delAccountBg(params: API.DelRoleParams) {
+  return request('/AccountBg/delete', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 角色下关联账号 */
 export async function linkRoleAccount(params: API.LinkAccountParams) {
   return request('/role/link/account', {
@@ -47,6 +107,14 @@ export async function linkRoleAccount(params: API.LinkAccountParams) {
   })
 }
 
+/** 后台角色下关联账号 */
+export async function linkRoleBgAccount(params: API.LinkAccountParams) {
+  return request('/RoleBg/link/account', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 角色下移除账号 */
 export async function unLinkRoleAccount(params: API.LinkAccountParams) {
   return request('/role/unlink/account', {
@@ -55,6 +123,14 @@ export async function unLinkRoleAccount(params: API.LinkAccountParams) {
   })
 }
 
+/** 后台角色下移除账号 */
+export async function unLinkRoleBgAccount(params: API.LinkAccountParams) {
+  return request('/RoleBg/unlink/account', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 角色下设置权限 */
 export async function setRolePermission(params: API.SetRolePermissionParams) {
   return request('/role/set/permission', {
@@ -63,7 +139,20 @@ export async function setRolePermission(params: API.SetRolePermissionParams) {
   })
 }
 
+/** 角色下设置后台权限 */
+export async function setRoleBgPermission(params: API.SetRolePermissionParams) {
+  return request('/RoleBg/set/permission', {
+    method: 'POST',
+    data: params
+  })
+}
+
 /** 获取角色详情 */
 export async function queryRoleDetailByID(params: { ID: string }) {
   return request('/role/detail', { params })
 }
+
+/** 获取后台角色详情 */
+export async function queryRoleBgDetailByID(params: { ID: string }) {
+  return request('/RoleBg/detail', { params })
+}