可正常启用

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

View File

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