index.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import React, { useState, useEffect } from 'react'
  2. import { PlusOutlined, DownOutlined } from '@ant-design/icons'
  3. import { Button, message, Popconfirm, Popover, Input } from 'antd'
  4. import { useRequest } from 'umi'
  5. import {
  6. createRoleWithMenuId,
  7. fetchRoleListByMenuId,
  8. deleteRole,
  9. updateStaff
  10. } from '@/services/user/api'
  11. import { ModalForm, ProFormText } from '@ant-design/pro-form'
  12. type RoleMenuProps = {
  13. menuId: string
  14. onSelect?: (id: string) => void
  15. itemCount?: number
  16. }
  17. const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
  18. const [state, setState] = useState({
  19. value: ''
  20. })
  21. const [activeId, setActiveId] = useState('')
  22. const [menuRoles, setMenuRoles] = useState<API.MenuRoleItem[]>([])
  23. const { run: tryFetchMenuRoles } = useRequest((id: string) => fetchRoleListByMenuId(id), {
  24. manual: true,
  25. onSuccess: result => {
  26. setMenuRoles(result)
  27. }
  28. })
  29. const { run: tryDeleteRole } = useRequest(
  30. (id: string) => {
  31. if (activeId === id) {
  32. setActiveId('')
  33. }
  34. return deleteRole({ id })
  35. },
  36. {
  37. manual: true,
  38. onSuccess: () => {
  39. tryFetchMenuRoles(menuId)
  40. }
  41. }
  42. )
  43. const { run: tryUpdateStaff } = useRequest(
  44. (id: string, name: string) => {
  45. if (activeId === id) {
  46. setActiveId('')
  47. }
  48. return updateStaff({ id, name })
  49. },
  50. {
  51. manual: true,
  52. onSuccess: () => {
  53. message.success('修改成功')
  54. tryFetchMenuRoles(menuId)
  55. }
  56. }
  57. )
  58. const onChangeName = value => {
  59. setState({ ...state, name: value })
  60. }
  61. const { run: tryAddRole } = useRequest(
  62. (params: API.CreateRoleParams) => createRoleWithMenuId(params),
  63. {
  64. manual: true,
  65. onSuccess: () => {
  66. tryFetchMenuRoles(menuId)
  67. }
  68. }
  69. )
  70. useEffect(() => {
  71. tryFetchMenuRoles(menuId)
  72. }, [])
  73. const handleItemClick = (id: string) => {
  74. setActiveId(id)
  75. if (onSelect) {
  76. onSelect(id)
  77. }
  78. }
  79. return (
  80. <div className="h-full w-max-234px rounded-4px">
  81. <div className="p-4 border-b-1 border-solid border-black border-opacity-10 bg-[#f7f9fa] flex items-center justify-around">
  82. <span className="text-[0.9375rem]">角色列表</span>
  83. <ModalForm<{ name: string; backstageMenuId: string }>
  84. title="添加新的角色"
  85. width="500px"
  86. trigger={
  87. <Button size="small" type="primary" ghost>
  88. <PlusOutlined />
  89. 创建角色
  90. </Button>
  91. }
  92. onFinish={async values => {
  93. await tryAddRole(values)
  94. message.success('添加成功')
  95. return true
  96. }}
  97. initialValues={{ backstageMenuId: menuId }}>
  98. <ProFormText name="backstageMenuId" hidden />
  99. <ProFormText name="name" rules={[{ required: true, message: '请输入角色名' }]} />
  100. </ModalForm>
  101. </div>
  102. <div className="p-4 bg-white" style={{ height: 'calc(100% - 1rem*2 - 20px)' }}>
  103. <ul className="p-0 m-0 list-none text-primary flex flex-col flex-1">
  104. {menuRoles.map(item => (
  105. <li
  106. key={item.id}
  107. className={[
  108. 'flex justify-between items-center py-2 px-5 cursor-pointer',
  109. item.id === activeId ? 'scale-up-center' : ''
  110. ].join(' ')}
  111. onClick={() => handleItemClick(item.id)}>
  112. <span>{item.name}</span>
  113. <Popover
  114. placement="bottomRight"
  115. content={
  116. <div className="popoverList">
  117. <ul>
  118. <Popconfirm
  119. title={
  120. <Input
  121. placeholder="角色名称"
  122. name="name"
  123. onChange={e => onChangeName(e.currentTarget.value)}
  124. />
  125. }
  126. okText="确认"
  127. cancelText="取消"
  128. onConfirm={() => tryUpdateStaff(item.id, state.name)}
  129. icon="">
  130. <li>编辑</li>
  131. </Popconfirm>
  132. <Popconfirm
  133. title="确认删除吗?"
  134. okText="确认"
  135. cancelText="取消"
  136. onConfirm={() => {
  137. if (itemCount && itemCount !== 0) {
  138. return message.warning('请先移除已经关联的员工')
  139. }
  140. return tryDeleteRole(item.id)
  141. }}>
  142. <li className="text-red-500">删除</li>
  143. </Popconfirm>
  144. </ul>
  145. </div>
  146. }
  147. trigger="click">
  148. <DownOutlined />
  149. </Popover>
  150. </li>
  151. ))}
  152. </ul>
  153. </div>
  154. </div>
  155. )
  156. }
  157. export default RoleMenu