import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import { App, Dropdown, Form, Input, Modal, Space, theme } from 'antd'; import { DashboardOutlined, HomeOutlined, ControlOutlined, BellOutlined, VideoCameraOutlined, FileTextOutlined, BookOutlined, ProfileOutlined, ExperimentOutlined, ShoppingOutlined, SettingOutlined, LogoutOutlined, UserOutlined, ThunderboltOutlined, ApiOutlined, ControlOutlined as ControlOutlinedIcon, KeyOutlined, } from '@ant-design/icons'; import { ProLayout } from '@ant-design/pro-components'; import { useState } from 'react'; import { authService } from '../services/auth'; const menuData = [ { path: '/dashboard', name: '仪表盘', icon: , permission: 'dashboard:view' }, { path: '/houses', name: '蚕房管理', icon: , permission: 'room:read' }, { path: '/devices', name: '设备管理', icon: , permission: 'device:read' }, { path: '/energy', name: '能耗管理', icon: , permission: 'energy:view' }, { path: '/control', name: '设备控制', icon: , permission: 'device:control' }, { path: '/ir', name: '红外遥控', icon: , permission: 'device:control' }, { path: '/thresholds', name: '阈值配置', icon: , permission: 'threshold:read' }, { path: '/alerts', name: '告警中心', icon: , permission: 'alarm:read' }, { path: '/videos', name: '视频监控', icon: , permission: 'video:read' }, { path: '/logs', name: '控制日志', icon: , permission: 'log:read' }, { path: '/knowledge', name: '知识库', icon: , permission: 'knowledge:read' }, { path: '/batches', name: '批次管理', icon: , permission: 'batch:read' }, { path: '/lamp-tests', name: 'LAMP 检测', icon: , permission: 'lamp:read' }, { path: '/consumables', name: '耗材管理', icon: , permission: 'consumable:read' }, ]; // 角色中文名 const roleNames: Record = { admin: '管理员', operator: '操作员', viewer: '查看者', farmer: '养殖员', }; export const BasicLayout = () => { const location = useLocation(); const navigate = useNavigate(); const { message } = App.useApp(); const { token: { colorBgContainer, borderRadiusLG }, } = theme.useToken(); const [pwdOpen, setPwdOpen] = useState(false); const [pwdForm] = Form.useForm<{ oldPassword: string; newPassword: string; confirm: string }>(); const [pwdLoading, setPwdLoading] = useState(false); const handleChangePassword = async () => { const v = await pwdForm.validateFields(); if (v.newPassword !== v.confirm) { message.error('两次输入的新密码不一致'); return; } setPwdLoading(true); try { await authService.changePassword({ oldPassword: v.oldPassword, newPassword: v.newPassword }); message.success('密码修改成功,请重新登录'); setPwdOpen(false); pwdForm.resetFields(); await authService.logout(); navigate('/login'); } catch (err: any) { const msg = err?.response?.data?.error || '密码修改失败'; message.error(typeof msg === 'string' ? msg : '密码修改失败'); } finally { setPwdLoading(false); } }; return ( (
item.path && navigate(item.path)} style={{ cursor: 'pointer' }} > {dom}
)} menuDataRender={() => menuData.filter((m) => authService.hasPermission(m.permission))} location={{ pathname: location.pathname }} headerTitleRender={(logo, title) => ( navigate('/dashboard')}> {logo}{title} )} avatarProps={{ icon: , size: 'small', title: (() => { const user = authService.getUser(); return user ? `${user.username}(${roleNames[user.role ?? ''] ?? user.role})` : 'admin'; })(), render: (_, dom) => ( , label: '修改密码' }, { type: 'divider' }, { key: 'logout', icon: , label: '退出登录' }, ], onClick: async ({ key }) => { if (key === 'logout') { await authService.logout(); navigate('/login'); } else if (key === 'changePassword') { pwdForm.resetFields(); setPwdOpen(true); } }, }} > {dom} ), }} >
setPwdOpen(false)} onOk={handleChangePassword} confirmLoading={pwdLoading} okText="提交" cancelText="取消" >
); };