vdi/web-fe/src/components/Guide/Layout/index.tsx

118 lines
3.7 KiB
TypeScript
Raw Normal View History

2025-08-05 01:57:49 +00:00
import React, { useState, useEffect } from 'react';
import { Layout, Menu, Button, Avatar, Dropdown, message } from 'antd';
import {
AppstoreOutlined,
UserOutlined,
LogoutOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
} from '@ant-design/icons';
import { history, useLocation, Outlet } from 'umi';
import './index.less';
const { Header, Sider, Content } = Layout;
const MainLayout: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [username, setUsername] = useState('');
const location = useLocation();
useEffect(() => {
// 检查登录状态
const isLoggedIn = localStorage.getItem('isLoggedIn');
const currentUsername = localStorage.getItem('username');
if (!isLoggedIn) {
message.error('请先登录!');
history.push('/login');
return;
}
setUsername(currentUsername || '');
}, []);
const handleMenuClick = (key: string) => {
// 使用路由导航
history.push(`/${key}`);
};
const handleLogout = () => {
localStorage.removeItem('isLoggedIn');
localStorage.removeItem('username');
message.success('已退出登录');
history.push('/login');
};
const userMenu = (
<Menu>
<Menu.Item key="profile" icon={<UserOutlined />} onClick={() => history.push('/profile')}>
</Menu.Item>
<Menu.Divider />
<Menu.Item key="logout" icon={<LogoutOutlined />} onClick={handleLogout}>
退
</Menu.Item>
</Menu>
);
// 根据当前路径确定选中的菜单项
const getSelectedKey = () => {
const path = location.pathname;
if (path === '/images') return 'images';
if (path === '/profile') return 'profile';
return 'images'; // 默认选中镜像列表
};
return (
<Layout className="main-layout">
<Sider
trigger={null}
collapsible
collapsed={collapsed}
className="main-sider"
>
<div className="logo">
{!collapsed && <span>VDI </span>}
</div>
<Menu
theme="dark"
mode="inline"
selectedKeys={[getSelectedKey()]}
onClick={({ key }) => handleMenuClick(key)}
>
<Menu.Item key="images" icon={<AppstoreOutlined />}>
</Menu.Item>
<Menu.Item key="profile" icon={<UserOutlined />}>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header className="main-header">
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
onClick={() => setCollapsed(!collapsed)}
className="trigger"
/>
<div className="header-right">
<span className="welcome-text">{username}</span>
<Dropdown overlay={userMenu} placement="bottomRight">
<Avatar icon={<UserOutlined />} className="user-avatar" />
</Dropdown>
</div>
</Header>
<Content className="main-content">
<Outlet />
</Content>
</Layout>
</Layout>
);
};
export default MainLayout;