diff --git a/frontend/src/components/AppLayout.tsx b/frontend/src/components/AppLayout.tsx new file mode 100644 index 0000000..4db998a --- /dev/null +++ b/frontend/src/components/AppLayout.tsx @@ -0,0 +1,194 @@ +import { useState } from 'react'; +import { Outlet, useNavigate, useLocation } from 'react-router-dom'; +import { + Layout, + Menu, + Avatar, + Dropdown, + Space, + Typography, + Tag, + theme, +} from 'antd'; +import { + DashboardOutlined, + ProjectOutlined, + CheckSquareOutlined, + RobotOutlined, + AuditOutlined, + LogoutOutlined, + MenuFoldOutlined, + MenuUnfoldOutlined, + UserOutlined, +} from '@ant-design/icons'; +import type { MenuProps } from 'antd'; +import { useAuthStore } from '@/stores/auth'; +import type { UserRole } from '@/types'; + +const { Header, Sider, Content } = Layout; +const { Text } = Typography; + +const roleLabels: Record = { + super_admin: '超级管理员', + tenant_admin: '租户管理员', + project_manager: '项目经理', + reviewer: '审核员', + worker: '执行者', +}; + +const roleColors: Record = { + super_admin: 'red', + tenant_admin: 'orange', + project_manager: 'blue', + reviewer: 'purple', + worker: 'green', +}; + +const menuItems: MenuProps['items'] = [ + { + key: '/dashboard', + icon: , + label: '仪表盘', + }, + { + key: '/projects', + icon: , + label: '项目管理', + }, + { + key: '/tasks', + icon: , + label: '任务管理', + }, + { + key: '/workers', + icon: , + label: 'AI 工作者', + }, + { + key: '/reviews', + icon: , + label: '审核管理', + }, +]; + +export default function AppLayout() { + const [collapsed, setCollapsed] = useState(false); + const navigate = useNavigate(); + const location = useLocation(); + const { user, logout } = useAuthStore(); + + const handleMenuClick: MenuProps['onClick'] = ({ key }) => { + navigate(key); + }; + + const handleLogout = () => { + logout(); + navigate('/login'); + }; + + const userMenuItems: MenuProps['items'] = [ + { + key: 'user-info', + label: ( + + {user?.username} + {user?.email} + + ), + disabled: true, + }, + { type: 'divider' }, + { + key: 'logout', + icon: , + label: '退出登录', + onClick: handleLogout, + }, + ]; + + const selectedKey = '/' + location.pathname.split('/')[1]; + + return ( + + +
+ {collapsed ? 'AI' : 'AI Worker 平台'} +
+ + + +
+
setCollapsed(!collapsed)} + > + {collapsed ? : } +
+ + + } style={{ backgroundColor: '#1677ff' }} /> + {user?.username || '用户'} + {user?.role && ( + {roleLabels[user.role]} + )} + + +
+ + + +
+ + ); +}