可正常启用

This commit is contained in:
戚辰先生 2024-12-01 15:02:46 +08:00
parent 74cb4a3255
commit 3a6c6ad9ab
2 changed files with 115 additions and 101 deletions

View File

@ -88,10 +88,10 @@ const DepartmentPage: React.FC = () => {
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 60,
title: '部门名称',
dataIndex: 'name',
key: 'name',
width: 250,
fixed: 'left' as FixedType,
sorter: true
},
@ -99,26 +99,9 @@ const DepartmentPage: React.FC = () => {
title: '部门编码',
dataIndex: 'code',
key: 'code',
width: 100,
width: 120,
sorter: true
},
{
title: '部门名称',
dataIndex: 'name',
key: 'name',
width: 150,
sorter: true
},
{
title: '上级部门',
dataIndex: 'parentId',
key: 'parentId',
width: 150,
render: (parentId: number) => {
const parent = departments.find(dept => dept.id === parentId);
return parent?.name || '-';
}
},
{
title: '部门描述',
dataIndex: 'description',
@ -189,12 +172,14 @@ const DepartmentPage: React.FC = () => {
<Table
loading={loading}
columns={columns}
dataSource={departments}
dataSource={departmentTree}
rowKey="id"
scroll={{x: 1500}}
pagination={pagination}
scroll={{x: 1200}}
pagination={false}
size="middle"
bordered
defaultExpandAllRows
indentSize={24}
/>
<Modal

View File

@ -5,7 +5,7 @@ import type { TablePaginationConfig } from 'antd/es/table';
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
import { getMenuTree } from './service';
import type { MenuResponse } from './types';
import { MenuTypeEnum, MenuTypeNames } from './types';
import { MenuTypeEnum } from './types';
import IconSelect from '@/components/IconSelect';
import { useTableData } from '@/hooks/useTableData';
import * as AntdIcons from '@ant-design/icons';
@ -13,7 +13,6 @@ import * as AntdIcons from '@ant-design/icons';
const MenuPage: React.FC = () => {
const {
list: menus,
pagination,
loading,
loadData: fetchMenus,
handleCreate,
@ -24,16 +23,21 @@ const MenuPage: React.FC = () => {
baseUrl: '/api/v1/menu'
},
defaultParams: {
sortField: 'createTime',
sortOrder: 'descend'
sortField: 'sort',
sortOrder: 'asc'
}
});
const [modalVisible, setModalVisible] = useState(false);
const [iconSelectVisible, setIconSelectVisible] = useState(false);
const [editingMenu, setEditingMenu] = useState<MenuResponse | null>(null);
const [menuTree, setMenuTree] = useState<MenuResponse[]>([]);
const [iconSelectVisible, setIconSelectVisible] = useState(false);
const [form] = Form.useForm();
useEffect(() => {
getMenuTree().then(menus => setMenuTree(menus));
}, []);
const handleAdd = () => {
setEditingMenu(null);
form.resetFields();
@ -135,26 +139,85 @@ const MenuPage: React.FC = () => {
return Icon ? <Icon /> : null;
};
const treeData = buildMenuTree(menus).map(menu => ({
key: menu.id,
title: (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>
<Space>
{menu.type === MenuTypeEnum.DIRECTORY ? <FolderOutlined /> :
menu.type === MenuTypeEnum.MENU ? <MenuOutlined /> :
<ToolOutlined />}
<span>{menu.name}</span>
{menu.icon && getIcon(menu.icon)}
</Space>
<Space size={8}>
const columns = [
{
title: '菜单名称',
dataIndex: 'name',
key: 'name',
width: 250,
fixed: 'left' as FixedType,
sorter: true
},
{
title: '图标',
dataIndex: 'icon',
key: 'icon',
width: 80,
render: (icon: string) => getIcon(icon)
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
width: 100,
render: (type: MenuTypeEnum) => {
const typeMap = {
[MenuTypeEnum.DIRECTORY]: '目录',
[MenuTypeEnum.MENU]: '菜单',
[MenuTypeEnum.BUTTON]: '按钮'
};
return typeMap[type];
}
},
{
title: '路由地址',
dataIndex: 'path',
key: 'path',
width: 200,
ellipsis: true
},
{
title: '组件路径',
dataIndex: 'component',
key: 'component',
width: 200,
ellipsis: true
},
{
title: '权限标识',
dataIndex: 'permission',
key: 'permission',
width: 150,
ellipsis: true
},
{
title: '排序',
dataIndex: 'sort',
key: 'sort',
width: 80,
sorter: true
},
{
title: '状态',
dataIndex: 'enabled',
key: 'enabled',
width: 80,
render: (enabled: boolean) => (
<Switch checked={enabled} disabled size="small"/>
)
},
{
title: '操作',
key: 'action',
width: 160,
fixed: 'right' as FixedType,
render: (_: any, record: MenuResponse) => (
<Space size={0}>
<Button
type="link"
size="small"
icon={<EditOutlined />}
onClick={(e) => {
e.stopPropagation();
handleEdit(menu);
}}
icon={<EditOutlined/>}
onClick={() => handleEdit(record)}
>
</Button>
@ -162,70 +225,36 @@ const MenuPage: React.FC = () => {
type="link"
size="small"
danger
icon={<DeleteOutlined />}
onClick={(e) => {
e.stopPropagation();
handleDelete(menu.id);
}}
icon={<DeleteOutlined/>}
onClick={() => handleDelete(record.id)}
disabled={record.children?.length > 0}
>
</Button>
</Space>
</div>
),
children: menu.children?.map(child => ({
key: child.id,
title: (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>
<Space>
{child.type === MenuTypeEnum.DIRECTORY ? <FolderOutlined /> :
child.type === MenuTypeEnum.MENU ? <MenuOutlined /> :
<ToolOutlined />}
<span>{child.name}</span>
{child.icon && getIcon(child.icon)}
</Space>
<Space size={8}>
<Button
type="link"
size="small"
icon={<EditOutlined />}
onClick={(e) => {
e.stopPropagation();
handleEdit(child);
}}
>
</Button>
<Button
type="link"
size="small"
danger
icon={<DeleteOutlined />}
onClick={(e) => {
e.stopPropagation();
handleDelete(child.id);
}}
>
</Button>
</Space>
</div>
)
}))
}));
}
];
return (
<div style={{ padding: '24px' }}>
<div style={{ marginBottom: 16 }}>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
<div style={{padding: '24px'}}>
<div style={{marginBottom: 16}}>
<Button type="primary" icon={<PlusOutlined/>} onClick={handleAdd}>
</Button>
</div>
<Tree
showLine={{ showLeafIcon: false }}
defaultExpandAll
treeData={treeData}
<Table
loading={loading}
columns={columns}
dataSource={menuTree}
rowKey="id"
scroll={{x: 1500}}
pagination={false}
size="middle"
bordered
defaultExpandAllRows
indentSize={24}
/>
<Modal
@ -320,7 +349,7 @@ const MenuPage: React.FC = () => {
name="sort"
label="显示排序"
tooltip="值越大排序越靠后,默认为当前最大值+10"
rules={[{ required: true, message: '请输显示排序' }]}
rules={[{ required: true, message: '请输显示排序' }]}
>
<InputNumber
style={{ width: '100%' }}