This commit is contained in:
2025-08-20 00:42:01 +08:00
commit 06bb5439b4
73 changed files with 30196 additions and 0 deletions

View File

@ -0,0 +1,175 @@
import React, { useState } from 'react';
import {
Layout as AntLayout,
Menu,
Button,
Avatar,
Dropdown,
Typography,
Space,
MenuProps,
} from 'antd';
import {
MenuFoldOutlined,
MenuUnfoldOutlined,
UserOutlined,
TeamOutlined,
SafetyOutlined,
AppstoreOutlined,
LogoutOutlined,
SettingOutlined,
DashboardOutlined,
} from '@ant-design/icons';
import { useAuth } from '../hooks/useAuth';
import { useNavigate, useLocation, Outlet } from 'react-router-dom';
const { Header, Sider, Content } = AntLayout;
const { Title } = Typography;
const Layout: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const { user, logout } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const menuItems = [
{
key: '/dashboard',
icon: React.createElement(DashboardOutlined),
label: '仪表盘',
},
{
key: '/users',
icon: React.createElement(UserOutlined),
label: '用户管理',
},
{
key: '/roles',
icon: React.createElement(TeamOutlined),
label: '角色管理',
},
{
key: '/permissions',
icon: React.createElement(SafetyOutlined),
label: '权限管理',
},
{
key: '/menus',
icon: React.createElement(AppstoreOutlined),
label: '菜单管理',
},
];
const handleMenuClick = ({ key }: { key: string }) => {
navigate(key);
};
const handleLogout = () => {
logout();
navigate('/login');
};
const userMenuItems: MenuProps['items'] = [
{
key: 'profile',
icon: React.createElement(SettingOutlined),
label: '个人设置',
onClick: () => navigate('/profile'),
},
{
type: 'divider',
},
{
key: 'logout',
icon: React.createElement(LogoutOutlined),
label: '退出登录',
onClick: handleLogout,
},
];
return (
<AntLayout style={{ minHeight: '100vh' }}>
<Sider
trigger={null}
collapsible
collapsed={collapsed}
style={{
background: '#fff',
boxShadow: '2px 0 8px rgba(0,0,0,0.15)',
}}
>
<div
style={{
height: 64,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderBottom: '1px solid #f0f0f0',
}}
>
{!collapsed ? (
<Title level={3} style={{ margin: 0, color: '#1890ff' }}>
UAdmin
</Title>
) : (
<Title level={3} style={{ margin: 0, color: '#1890ff' }}>
U
</Title>
)}
</div>
<Menu
mode="inline"
selectedKeys={[location.pathname]}
items={menuItems}
onClick={handleMenuClick}
style={{ border: 'none' }}
/>
</Sider>
<AntLayout>
<Header
style={{
padding: '0 16px',
background: '#fff',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
}}
>
<Button
type="text"
icon={collapsed ? React.createElement(MenuUnfoldOutlined) : React.createElement(MenuFoldOutlined)}
onClick={() => setCollapsed(!collapsed)}
style={{
fontSize: '16px',
width: 64,
height: 64,
}}
/>
<Space>
<span>{user?.username}</span>
<Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
<Avatar
style={{ backgroundColor: '#1890ff', cursor: 'pointer' }}
icon={React.createElement(UserOutlined)}
/>
</Dropdown>
</Space>
</Header>
<Content
style={{
margin: '16px',
padding: '24px',
background: '#fff',
borderRadius: '8px',
minHeight: 'calc(100vh - 112px)',
}}
>
<Outlet />
</Content>
</AntLayout>
</AntLayout>
);
};
export default Layout;