|
@@ -1,6 +1,6 @@
|
|
|
-import React, { useState, useEffect } from 'react'
|
|
|
-import { PlusOutlined, DownOutlined } from '@ant-design/icons'
|
|
|
-import { Button, message, Popconfirm, Popover, Input, Switch } from 'antd'
|
|
|
+import React, { useState, useEffect, useRef } from 'react'
|
|
|
+import { PlusOutlined, InfoCircleOutlined, FormOutlined, DeleteOutlined } from '@ant-design/icons'
|
|
|
+import { Button, message, Popconfirm, Switch, Tooltip } from 'antd'
|
|
|
import { useRequest } from 'umi'
|
|
|
import {
|
|
|
createRoleWithMenuId,
|
|
@@ -8,25 +8,44 @@ import {
|
|
|
deleteRole,
|
|
|
updateStaff
|
|
|
} from '@/services/user/api'
|
|
|
+import type { ProFormInstance } from '@ant-design/pro-form'
|
|
|
import { ModalForm, ProFormText } from '@ant-design/pro-form'
|
|
|
import classNames from 'classnames'
|
|
|
-
|
|
|
+import styles from './index.less'
|
|
|
type RoleMenuProps = {
|
|
|
menuId: string
|
|
|
onSelect?: (id: string) => void
|
|
|
itemCount?: number
|
|
|
}
|
|
|
-
|
|
|
+enum ModalType {
|
|
|
+ ADD,
|
|
|
+ UPDATE
|
|
|
+}
|
|
|
+type RoleMenuState = {
|
|
|
+ menuRoles: API.MenuRoleItem[]
|
|
|
+ activeId: Nullable<string>
|
|
|
+ visible: boolean
|
|
|
+ modalType: ModalType
|
|
|
+ defaultMenuData: Nullable<{ id: string; name: string }>
|
|
|
+}
|
|
|
const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
|
|
|
- const [state, setState] = useState({
|
|
|
- value: ''
|
|
|
+ const formRef = useRef<ProFormInstance>(null)
|
|
|
+ const [state, setState] = useState<RoleMenuState>({
|
|
|
+ menuRoles: [],
|
|
|
+ activeId: null,
|
|
|
+ visible: false,
|
|
|
+ modalType: ModalType.ADD,
|
|
|
+ defaultMenuData: null
|
|
|
})
|
|
|
- const [activeId, setActiveId] = useState('')
|
|
|
- const [menuRoles, setMenuRoles] = useState<API.MenuRoleItem[]>([])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ formRef.current?.setFieldsValue({ ...state.defaultMenuData })
|
|
|
+ }, [state.defaultMenuData])
|
|
|
+
|
|
|
const { run: tryFetchMenuRoles } = useRequest((id: string) => fetchRoleListByMenuId(id), {
|
|
|
manual: true,
|
|
|
onSuccess: result => {
|
|
|
- setMenuRoles(result)
|
|
|
+ setState({ ...state, menuRoles: result })
|
|
|
}
|
|
|
})
|
|
|
|
|
@@ -44,25 +63,13 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
|
|
|
}
|
|
|
}
|
|
|
)
|
|
|
- const { run: tryUpdateStaff } = useRequest(
|
|
|
- (id: string, name: string) => {
|
|
|
- if (activeId === id) {
|
|
|
- setActiveId('')
|
|
|
- }
|
|
|
- return updateStaff({ id, name })
|
|
|
- },
|
|
|
- {
|
|
|
- manual: true,
|
|
|
- onSuccess: () => {
|
|
|
- message.success('修改成功')
|
|
|
- tryFetchMenuRoles(menuId)
|
|
|
- }
|
|
|
+ const { run: tryUpdateStaff } = useRequest(updateStaff, {
|
|
|
+ manual: true,
|
|
|
+ onSuccess: () => {
|
|
|
+ message.success('修改成功')
|
|
|
+ tryFetchMenuRoles(menuId)
|
|
|
}
|
|
|
- )
|
|
|
-
|
|
|
- const onChangeName = value => {
|
|
|
- setState({ ...state, name: value })
|
|
|
- }
|
|
|
+ })
|
|
|
|
|
|
const { run: tryAddRole } = useRequest(
|
|
|
(params: API.CreateRoleParams) => createRoleWithMenuId(params),
|
|
@@ -70,6 +77,7 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
|
|
|
manual: true,
|
|
|
onSuccess: () => {
|
|
|
tryFetchMenuRoles(menuId)
|
|
|
+ message.success('添加成功')
|
|
|
}
|
|
|
}
|
|
|
)
|
|
@@ -78,19 +86,30 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
|
|
|
}, [])
|
|
|
|
|
|
const handleItemClick = (id: string) => {
|
|
|
- setActiveId(id)
|
|
|
+ setState({ ...state, activeId: id })
|
|
|
if (onSelect) {
|
|
|
onSelect(id)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const handleEditIconClick = (id: string, text: string) => {
|
|
|
+ setState({
|
|
|
+ ...state,
|
|
|
+ visible: true,
|
|
|
+ modalType: ModalType.UPDATE,
|
|
|
+ defaultMenuData: { id, name: text }
|
|
|
+ })
|
|
|
+ }
|
|
|
return (
|
|
|
<div className="h-full w-max-234px rounded-4px">
|
|
|
- <div className="p-4 border-b-1 border-solid border-black border-opacity-10 bg-[#f7f9fa] flex items-center justify-around">
|
|
|
+ <div className="p-4 border-b-1 border-solid border-black border-opacity-10 bg-hex-f7f9fa flex items-center justify-around">
|
|
|
<span className="text-[0.9375rem]">角色列表</span>
|
|
|
|
|
|
<ModalForm<{ name: string; backstageMenuId: string }>
|
|
|
- title="添加新的角色"
|
|
|
+ visible={state.visible}
|
|
|
+ formRef={formRef}
|
|
|
+ onVisibleChange={visible => setState({ ...state, visible })}
|
|
|
+ title={state.modalType === ModalType.ADD ? '添加新的角色' : '更新角色'}
|
|
|
width="500px"
|
|
|
layout="horizontal"
|
|
|
trigger={
|
|
@@ -100,68 +119,68 @@ const RoleMenu: React.FC<RoleMenuProps> = ({ menuId, onSelect, itemCount }) => {
|
|
|
</Button>
|
|
|
}
|
|
|
onFinish={async values => {
|
|
|
- await tryAddRole(values)
|
|
|
- message.success('添加成功')
|
|
|
+ if (state.modalType === ModalType.ADD) {
|
|
|
+ await tryAddRole(values)
|
|
|
+ } else {
|
|
|
+ console.log(values)
|
|
|
+
|
|
|
+ await tryUpdateStaff(values)
|
|
|
+ }
|
|
|
return true
|
|
|
}}
|
|
|
initialValues={{ backstageMenuId: menuId }}>
|
|
|
<ProFormText name="backstageMenuId" hidden />
|
|
|
+ <ProFormText name="id" hidden />
|
|
|
<ProFormText
|
|
|
name="name"
|
|
|
label="名称"
|
|
|
placeholder="请输入角色名称"
|
|
|
rules={[{ required: true, message: '请输入角色名' }]}
|
|
|
/>
|
|
|
- <Switch onChange={checked => {}} />
|
|
|
+ {state.modalType === ModalType.ADD ? (
|
|
|
+ <>
|
|
|
+ <Switch onChange={checked => {}} />
|
|
|
+ <span className="mx-2">复制角色</span>
|
|
|
+ <Tooltip title="该操作允许复制其他栏目的角色并且将所绑定的用户一并复制">
|
|
|
+ <InfoCircleOutlined />
|
|
|
+ </Tooltip>
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
</ModalForm>
|
|
|
</div>
|
|
|
<div className="p-4 bg-white" style={{ height: 'calc(100% - 1rem*2 - 20px)' }}>
|
|
|
<ul className="p-0 m-0 list-none text-primary flex flex-col flex-1">
|
|
|
- {menuRoles.map(item => (
|
|
|
+ {state.menuRoles.map(item => (
|
|
|
<li
|
|
|
key={item.id}
|
|
|
- className={classNames('flex justify-between items-center py-2 px-5 cursor-pointer', {
|
|
|
- 'scale-up-center': item.id === activeId
|
|
|
- })}
|
|
|
- onClick={() => handleItemClick(item.id)}>
|
|
|
- <span>{item.name}</span>
|
|
|
- <Popover
|
|
|
- placement="bottomRight"
|
|
|
- content={
|
|
|
- <div className="popoverList">
|
|
|
- <ul>
|
|
|
- <Popconfirm
|
|
|
- title={
|
|
|
- <Input
|
|
|
- placeholder="角色名称"
|
|
|
- name="name"
|
|
|
- onChange={e => onChangeName(e.currentTarget.value)}
|
|
|
- />
|
|
|
- }
|
|
|
- okText="确认"
|
|
|
- cancelText="取消"
|
|
|
- onConfirm={() => tryUpdateStaff(item.id, state.name)}
|
|
|
- icon="">
|
|
|
- <li>编辑</li>
|
|
|
- </Popconfirm>
|
|
|
- <Popconfirm
|
|
|
- title="确认删除吗?"
|
|
|
- okText="确认"
|
|
|
- cancelText="取消"
|
|
|
- onConfirm={() => {
|
|
|
- if (itemCount && itemCount !== 0) {
|
|
|
- return message.warning('请先移除已经关联的员工')
|
|
|
- }
|
|
|
- return tryDeleteRole(item.id)
|
|
|
- }}>
|
|
|
- <li className="text-red-500">删除</li>
|
|
|
- </Popconfirm>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- }
|
|
|
- trigger="click">
|
|
|
- <DownOutlined />
|
|
|
- </Popover>
|
|
|
+ className={classNames(
|
|
|
+ 'flex justify-between items-center py-2 px-5 cursor-pointer',
|
|
|
+ {
|
|
|
+ 'scale-up-center': item.id === state.activeId
|
|
|
+ },
|
|
|
+ styles.node
|
|
|
+ )}>
|
|
|
+ <div className={styles.title} onClick={() => handleItemClick(item.id)}>
|
|
|
+ {item.name}
|
|
|
+ </div>
|
|
|
+ <div className={styles.extra}>
|
|
|
+ <FormOutlined
|
|
|
+ className="pr-2"
|
|
|
+ onClick={() => handleEditIconClick(item.id, item.name)}
|
|
|
+ />
|
|
|
+ <Popconfirm
|
|
|
+ title="确认删除吗?"
|
|
|
+ okText="确认"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => {
|
|
|
+ if (itemCount && itemCount !== 0) {
|
|
|
+ return message.warning('请先移除已经关联的员工')
|
|
|
+ }
|
|
|
+ return tryDeleteRole(item.id)
|
|
|
+ }}>
|
|
|
+ <DeleteOutlined />
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
</li>
|
|
|
))}
|
|
|
</ul>
|