index.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { fetchRoleBgList, unLinkRoleBgAccount, fetchRoleBgStaffListByRoleId } from '@/services/permission'
  2. import { DeleteOutlined } from '@ant-design/icons'
  3. import { PageContainer } from '@ant-design/pro-layout'
  4. import { Input, message, Popconfirm, Table, Tabs } from 'antd'
  5. import { useState } from 'react'
  6. import { useRequest } from '@umijs/max'
  7. import RoleLeftMenu, { RoleType } from './components/RoleLeftMenu'
  8. import PermTabs from './components/PermTabs'
  9. import type { ColumnsType } from 'antd/lib/table'
  10. import ConnectModal from './components/ConnectModal'
  11. const { TabPane } = Tabs
  12. const Role = () => {
  13. const [state, setState] = useState({
  14. activeTab: '1',
  15. currentRoleID: null,
  16. roleType: '',
  17. roleStaff: []
  18. })
  19. const [menuRoles, setMenuRoles] = useState([])
  20. const { run: tryGetRoleBgStaffList, loading: staffListLoading } = useRequest(
  21. (params: { roleID: string; search?: string }) =>
  22. fetchRoleBgStaffListByRoleId({ pageNo: 1, pageSize: 214000, ...params }),
  23. {
  24. manual: true,
  25. onSuccess: result => {
  26. setState({ ...state, roleStaff: result.items })
  27. }
  28. }
  29. )
  30. const { run: tryUnLinkRoleBgAccount } = useRequest(
  31. (params: API.LinkAccountParams) => unLinkRoleBgAccount(params),
  32. {
  33. manual: true,
  34. onSuccess: async () => {
  35. message.success('移除成功')
  36. await tryGetRoleBgStaffList({ roleID: state.currentRoleID })
  37. }
  38. }
  39. )
  40. const onSelect = (currentRoleID: string, roleType: string) => {
  41. if (state.currentRoleID === currentRoleID) return
  42. setState({ ...state, currentRoleID, roleType })
  43. tryGetRoleBgStaffList({ roleID: currentRoleID })
  44. }
  45. const { run: tryFetchRoleBgListByMenu } = useRequest(fetchRoleBgList, {
  46. onSuccess: result => {
  47. setMenuRoles(
  48. result.map(item => ({
  49. key: item.ID,
  50. title: item.name,
  51. roleType: item.roleType
  52. }))
  53. )
  54. result?.length && onSelect?.(state.currentRoleID ?? result[0]?.ID, result[0]?.roleType)
  55. }
  56. })
  57. const delRoleValidFn = (ID: string) => {
  58. if (state.roleStaff.length) {
  59. return message.warning('请先移除该角色下的所有用户')
  60. }
  61. tryDelRoleBg(ID)
  62. }
  63. const columns: ColumnsType<API.MenuByRoleIdItem> = [
  64. {
  65. title: '账号',
  66. dataIndex: 'account',
  67. width: '15%'
  68. },
  69. {
  70. title: '姓名',
  71. dataIndex: 'name',
  72. width: '15%'
  73. },
  74. {
  75. title: '业务主体',
  76. dataIndex: 'institutionID',
  77. width: '35%',
  78. render: (_, record) => record.institution?.name
  79. },
  80. {
  81. title: '操作',
  82. dataIndex: 'operation',
  83. width: '10%',
  84. render: (_, record) =>
  85. ![RoleType.SYSTEM].includes(state.roleType) && (
  86. <Popconfirm
  87. title="确定移除吗?"
  88. okText="确定"
  89. cancelText="取消"
  90. onConfirm={() => {
  91. tryUnLinkRoleBgAccount({ ID: state.currentRoleID, accountID: record.ID })
  92. }}>
  93. <span className="text-hex-fd3995 cursor-pointer hover:text-hex-e7026e">
  94. <DeleteOutlined />
  95. </span>
  96. </Popconfirm>
  97. )
  98. }
  99. ]
  100. const wrapHeight = document.querySelector('.ant-pro-page-container-warp')?.clientHeight || 0
  101. return (
  102. <PageContainer title={false}>
  103. <div className="h-full w-full flex flex-row">
  104. <RoleLeftMenu
  105. defaultActiveRole={state.currentRoleID ?? menuRoles[0]?.ID}
  106. onSelect={onSelect}
  107. menuRoles={menuRoles}
  108. showDelIcon={!state.roleStaff.length}
  109. onReloadStaff={() => tryFetchRoleBgListByMenu()}
  110. delRoleValidFn={delRoleValidFn}
  111. />
  112. <div className="w-6/7 ml-8 bg-white p-4 rounded-20px relative">
  113. <Tabs
  114. tabBarExtraContent={{
  115. right: state.activeTab === '1' && (
  116. <div className="flex items-center children:mx-1">
  117. <Input.Search
  118. placeholder="请输入账号或姓名"
  119. onSearch={value => tryGetRoleBgStaffList({ roleID: state.currentRoleID, search: value })}
  120. />
  121. {state.currentRoleID && state.roleType !== RoleType.SYSTEM && (
  122. <ConnectModal
  123. dataId={state.currentRoleID}
  124. onReload={() => tryGetRoleBgStaffList({ roleID: state.currentRoleID })}
  125. />
  126. )}
  127. </div>
  128. )
  129. }}
  130. defaultActiveKey="1"
  131. onChange={key => setState({ ...state, activeTab: key })}>
  132. <TabPane tab="用户列表" key="1">
  133. <Table<API.RoleStaffItem>
  134. loading={staffListLoading}
  135. columns={columns}
  136. scroll={{
  137. y: document.body.clientHeight - (285 + wrapHeight)
  138. }}
  139. dataSource={state.roleStaff}
  140. rowKey={row => row.ID}
  141. />
  142. </TabPane>
  143. <TabPane tab="功能权限" key="2">
  144. <PermTabs
  145. currentPermData={{
  146. ID: state.currentRoleID,
  147. roleType: state.roleType
  148. }}
  149. />
  150. </TabPane>
  151. </Tabs>
  152. </div>
  153. </div>
  154. </PageContainer>
  155. )
  156. }
  157. export default Role