import { useEffect, useRef, useState } from 'react'; import { Drawer, Form, Input, InputNumber, Radio, Switch, TreeSelect, Button, Space, Row, Col, Card } from 'antd'; import type { DefaultOptionType } from 'antd/es/select'; import { App } from 'antd'; import { getMenu, getMenuList, createMenu, updateMenu } from '@/api/system/menu'; import type { SystemMenu } from '@/api/system/menu'; import { useTranslation } from 'react-i18next'; const DEFAULT_FORM = { type: 1, status: 0, visible: true, keepAlive: true, sort: 0 }; /** Build tree-select data from flat menu list */ function buildMenuTreeSelect(list: SystemMenu[]): DefaultOptionType[] { const map = new Map(); const roots: DefaultOptionType[] = []; for (const item of list) { map.set(item.id!, { value: item.id, title: item.name, children: [], }); } for (const item of list) { const node = map.get(item.id!)!; if (item.parentId === 0 || !map.has(item.parentId)) { roots.push(node); } else { map.get(item.parentId)!.children.push(node); } } return roots; } interface MenuDrawerProps { open: boolean; id: number | null; onSuccess: () => void; onClose: () => void; } const MenuDrawer: React.FC = ({ open, id, onSuccess, onClose }) => { const { t } = useTranslation('system/menu'); const { t: tc } = useTranslation('common'); const { message } = App.useApp(); const [form] = Form.useForm(); const [confirmLoading, setConfirmLoading] = useState(false); const [menuTree, setMenuTree] = useState([]); // 保留服务端原始字段,避免编辑时丢掉未在表单里出现的字段 const originData = useRef>({}); const menuType = Form.useWatch('type', form); const isEdit = id != null; useEffect(() => { if (open) { form.resetFields(); originData.current = {}; getMenuList().then(({ data }) => setMenuTree(buildMenuTreeSelect(data))).catch(() => { }); if (id) { getMenu(id).then(({ data }) => { originData.current = { ...data }; form.setFieldsValue(data); }).catch(() => { }); } else { form.setFieldsValue(DEFAULT_FORM); } } }, [open, id, form]); const handleOk = async () => { let values: SystemMenu; try { values = await form.validateFields(); } catch { return; } setConfirmLoading(true); try { const payload = { ...originData.current, ...values, ...(id != null ? { id } : {}) } as SystemMenu; if (isEdit) { await updateMenu(payload); message.success(tc('success')); } else { await createMenu(payload); message.success(tc('success')); } onSuccess(); } finally { setConfirmLoading(false); } }; return ( } >
{t('typeDir')} {t('typeMenu')} {t('typeButton')} {menuType !== 3 && ( )} {menuType === 2 && ( )} {tc('enable')} {tc('disable')} {(menuType !== 3 || menuType === 2) && ( {menuType !== 3 && ( )} {menuType === 2 && ( )} )}
); }; export default MenuDrawer;