import React, { useEffect, useState } from 'react'; import { Table, Button, Modal, Form, Input, Space, message, Switch, Select, TreeSelect, Tooltip, InputNumber } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons'; import * as AntdIcons from '@ant-design/icons'; import { getMenuTree, createMenu, updateMenu, deleteMenu } from './service'; import IconSelect from '@/components/IconSelect'; const MenuPage: React.FC = () => { const [menus, setMenus] = useState([]); const [menuTreeData, setMenuTreeData] = useState([]); const [modalVisible, setModalVisible] = useState(false); const [iconSelectVisible, setIconSelectVisible] = useState(false); const [editingMenu, setEditingMenu] = useState(null); const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const fetchData = async () => { try { setLoading(true); const [menuList, treeData] = await Promise.all([ getMenuTree(), getMenuTreeWithoutButtons() ]); setMenus(menuList); setMenuTreeData(treeData); } catch (error) { console.error('获取菜单列表失败:', error); message.error('获取菜单列表失败'); } finally { setLoading(false); } }; useEffect(() => { fetchData(); }, []); const getIcon = (iconName: string | undefined) => { if (!iconName) return null; const iconKey = `${iconName.charAt(0).toUpperCase() + iconName.slice(1)}Outlined`; const IconComponent = (AntdIcons as any)[iconKey]; return IconComponent ? : null; }; const handleAdd = () => { setEditingMenu(null); form.resetFields(); form.setFieldsValue({ type: MenuTypeEnum.MENU, sort: 0, hidden: false, enabled: true }); setModalVisible(true); }; const handleEdit = (record: MenuDTO) => { setEditingMenu(record); form.setFieldsValue({ ...record, parentId: record.parentId === 0 ? undefined : record.parentId }); setModalVisible(true); }; const handleDelete = async (id: number) => { Modal.confirm({ title: '确认删除', content: '确定要删除这个菜单吗?', onOk: async () => { try { await deleteMenu(id); message.success('删除成功'); fetchData(); } catch (error) { message.error('删除失败'); } }, }); }; const handleSubmit = async () => { try { const values = await form.validateFields(); const submitData = { ...values, parentId: values.parentId || 0 }; if (editingMenu) { await updateMenu(editingMenu.id, submitData); message.success('更新成功'); } else { await createMenu(submitData); message.success('创建成功'); } setModalVisible(false); fetchData(); } catch (error) { message.error('操作失败'); } }; const getTreeSelectData = (menus: MenuDTO[]) => { const treeData = menus.map(menu => ({ title: menu.name, value: menu.id, children: menu.children?.map(child => ({ title: child.name, value: child.id, disabled: editingMenu?.id === child.id })) })); return treeData; }; const columns = [ { title: '菜单名称', dataIndex: 'name', key: 'name', width: '200px', }, { title: '类型', dataIndex: 'type', key: 'type', width: '100px', render: (type: MenuTypeEnum) => MenuTypeNames[type], }, { title: '权限标识', dataIndex: 'permission', key: 'permission', width: '150px', }, { title: '路由地址', dataIndex: 'path', key: 'path', width: '150px', }, { title: '组件路径', dataIndex: 'component', key: 'component', width: '150px', }, { title: '排序', dataIndex: 'sort', key: 'sort', width: '80px', }, { title: '状态', dataIndex: 'enabled', key: 'enabled', width: '80px', render: (enabled: boolean) => ( ), }, { title: '操作', key: 'action', width: '150px', render: (_: any, record: MenuDTO) => ( ), }, ]; return (
setModalVisible(false)} width={600} destroyOnClose >
上级菜单 } > {form.getFieldValue('type') !== MenuTypeEnum.BUTTON && ( <> 路由地址 } rules={[{ required: true, message: '请输入路由地址' }]} > 组件路径 } rules={[{ required: true, message: '请输入组件路径' }]} > setIconSelectVisible(true)} suffix={form.getFieldValue('icon') && getIcon(form.getFieldValue('icon'))} /> )} {form.getFieldValue('type') === MenuTypeEnum.BUTTON && ( 权限标识 } rules={[{ required: true, message: '请输入权限标识' }]} > )}
setIconSelectVisible(false)} value={form.getFieldValue('icon')} onChange={value => { form.setFieldValue('icon', value); setIconSelectVisible(false); }} /> ); }; export default MenuPage;