This commit is contained in:
yml2213
2026-07-20 14:58:57 +08:00
commit 45db0aa4b9
50 changed files with 5861 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
import { useMemo, useState } from 'react'
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
import {
Layout,
Menu,
theme,
Dropdown,
Space,
Typography,
Avatar,
} from 'antd'
import {
DashboardOutlined,
SkinOutlined,
ShoppingOutlined,
TeamOutlined,
UserOutlined,
LogoutOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
} from '@ant-design/icons'
import { useAuth } from '../store/auth'
import type { MenuProps } from 'antd'
const { Header, Sider, Content } = Layout
export default function MainLayout() {
const [collapsed, setCollapsed] = useState(false)
const { user, logout, isAdmin } = useAuth()
const navigate = useNavigate()
const location = useLocation()
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken()
const menuItems: MenuProps['items'] = useMemo(() => {
const items: MenuProps['items'] = [
{ key: '/', icon: <DashboardOutlined />, label: '数据概览' },
{ key: '/skins', icon: <SkinOutlined />, label: '皮肤商品' },
{ key: '/orders', icon: <ShoppingOutlined />, label: '订单管理' },
]
if (isAdmin) {
items.push({ key: '/distributors', icon: <TeamOutlined />, label: '分销商' })
}
return items
}, [isAdmin])
const userMenu: MenuProps['items'] = [
{
key: 'logout',
icon: <LogoutOutlined />,
label: '退出登录',
onClick: () => {
logout()
navigate('/login')
},
},
]
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider trigger={null} collapsible collapsed={collapsed} theme="dark">
<div
style={{
height: 64,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#fff',
fontWeight: 700,
fontSize: collapsed ? 14 : 16,
letterSpacing: 1,
}}
>
{collapsed ? '皮肤' : '皮肤分销系统'}
</div>
<Menu
theme="dark"
mode="inline"
selectedKeys={[location.pathname === '/' ? '/' : `/${location.pathname.split('/')[1]}`]}
items={menuItems}
onClick={({ key }) => navigate(key)}
/>
</Sider>
<Layout>
<Header
style={{
padding: '0 24px',
background: colorBgContainer,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<span
style={{ fontSize: 18, cursor: 'pointer' }}
onClick={() => setCollapsed(!collapsed)}
>
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</span>
<Dropdown menu={{ items: userMenu }}>
<Space style={{ cursor: 'pointer' }}>
<Avatar size="small" icon={<UserOutlined />} />
<Typography.Text>
{user?.nickname || user?.username}
{isAdmin ? '(管理员)' : '(分销商)'}
</Typography.Text>
</Space>
</Dropdown>
</Header>
<Content style={{ margin: 24 }}>
<div
style={{
padding: 24,
minHeight: 360,
background: colorBgContainer,
borderRadius: borderRadiusLG,
}}
>
<Outlet />
</div>
</Content>
</Layout>
</Layout>
)
}