| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- import { Outlet, useNavigate, useLocation } from 'react-router-dom'
- import { Layout as AntLayout, Menu, Avatar, Dropdown, message } from 'antd'
- import {
- DashboardOutlined,
- UserOutlined,
- AppstoreOutlined,
- KeyOutlined,
- FileTextOutlined,
- LogoutOutlined,
- SettingOutlined,
- BellOutlined,
- DatabaseOutlined,
- CloudDownloadOutlined,
- } from '@ant-design/icons'
- import { useAuthStore } from '../store/authStore'
- import type { MenuProps } from 'antd'
- const { Header, Sider, Content } = AntLayout
- const menuItems: MenuProps['items'] = [
- {
- key: '/dashboard',
- icon: <DashboardOutlined />,
- label: '仪表盘',
- },
- {
- key: '/admins',
- icon: <UserOutlined />,
- label: '管理员管理',
- },
- {
- key: '/users',
- icon: <UserOutlined />,
- label: '用户管理',
- },
- {
- key: '/software',
- icon: <AppstoreOutlined />,
- label: '软件管理',
- },
- {
- key: '/cards',
- icon: <KeyOutlined />,
- label: '卡密管理',
- },
- {
- key: '/keys',
- icon: <SettingOutlined />,
- label: '密钥管理',
- },
- {
- key: '/logs',
- icon: <FileTextOutlined />,
- label: '日志管理',
- },
- {
- key: '/announcements',
- icon: <BellOutlined />,
- label: '公告管理',
- },
- {
- key: '/system-config',
- icon: <DatabaseOutlined />,
- label: '系统配置',
- },
- {
- key: '/client-versions',
- icon: <CloudDownloadOutlined />,
- label: '客户端版本',
- },
- ]
- export default function Layout() {
- const navigate = useNavigate()
- const location = useLocation()
- const { logout, adminInfo } = useAuthStore()
- const handleMenuClick = ({ key }: { key: string }) => {
- navigate(key)
- }
- const handleLogout = async () => {
- try {
- await logout()
- navigate('/login')
- message.success('退出登录成功')
- } catch (error) {
- message.error('退出登录失败')
- }
- }
- const userMenuItems: MenuProps['items'] = [
- {
- key: 'logout',
- icon: <LogoutOutlined />,
- label: '退出登录',
- onClick: handleLogout,
- },
- ]
- return (
- <AntLayout style={{ minHeight: '100vh' }}>
- <Header
- style={{
- padding: '0 24px',
- display: 'flex',
- justifyContent: 'space-between',
- alignItems: 'center',
- background: '#ffffff',
- borderBottom: '1px solid #f0f0f0',
- boxShadow: '0 1px 4px rgba(0, 0, 0, 0.06)',
- }}
- >
- <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
- <img
- src="/logo.png"
- alt="游铛铛"
- style={{
- height: '48px',
- width: 'auto',
- }}
- />
- <span style={{ fontSize: 18, fontWeight: 600, color: 'rgba(0, 0, 0, 0.85)' }}>
- 游铛铛管理端
- </span>
- </div>
- <Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
- <div style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8 }}>
- <Avatar src="/avatar.jpg" />
- <span>{adminInfo?.real_name || adminInfo?.username || '管理员'}</span>
- </div>
- </Dropdown>
- </Header>
- {/* 主区域:左侧菜单 + 右侧内容 */}
- <AntLayout>
- <Sider
- width={200}
- theme="light"
- style={{
- borderRight: '1px solid #f0f0f0',
- background: '#ffffff',
- }}
- >
- <Menu
- className="sider-menu"
- mode="inline"
- selectedKeys={[location.pathname]}
- items={menuItems}
- onClick={handleMenuClick}
- style={{
- border: 'none',
- padding: '16px 0',
- }}
- />
- </Sider>
- <Content
- style={{
- margin: '24px',
- background: '#ffffff',
- padding: '24px',
- borderRadius: '8px',
- boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
- minHeight: 'calc(100vh - 112px)',
- }}
- >
- <Outlet />
- </Content>
- </AntLayout>
- </AntLayout>
- )
- }
|