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

150 lines
4.4 KiB
TypeScript
Raw Normal View History

2025-08-05 01:57:49 +00:00
import {
2025-08-05 08:54:53 +00:00
AppstoreOutlined,
LogoutOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
UserOutlined,
2025-08-05 01:57:49 +00:00
} from '@ant-design/icons';
2025-08-05 08:54:53 +00:00
import { Avatar, Button, Dropdown, Layout, Menu, message } from 'antd';
import React, { useEffect, useState } from 'react';
import { history, Outlet, useLocation } from 'umi';
2025-08-06 10:06:10 +00:00
import { ConfigProvider } from 'antd';
import zhCN from 'antd/lib/locale/zh_CN';
2025-08-05 01:57:49 +00:00
import './index.less';
const { Header, Sider, Content } = Layout;
const MainLayout: React.FC = () => {
2025-08-05 08:54:53 +00:00
const [collapsed, setCollapsed] = useState(false);
const [username, setUsername] = useState('');
const [selectedKey, setSelectedKey] = useState('images'); // 添加选中状态
2025-08-05 08:54:53 +00:00
const location = useLocation();
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
useEffect(() => {
// 检查登录状态
const isLoggedIn = localStorage.getItem('isLoggedIn');
const currentUsername = localStorage.getItem('username');
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
if (!isLoggedIn) {
message.error('请先登录!');
history.push('/login');
return;
}
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
setUsername(currentUsername || '');
setSelectedKey(getSelectedKeyFromPath(location.pathname));
2025-08-05 08:54:53 +00:00
}, []);
2025-08-05 01:57:49 +00:00
// 监听路由变化,更新选中菜单
useEffect(() => {
setSelectedKey(getSelectedKeyFromPath(location.pathname));
}, [location.pathname]);
const getSelectedKeyFromPath = (path: string) => {
if (path.startsWith('/userList')) return 'userList';
if (path.startsWith('/terminal')) return 'terminal';
if (path.startsWith('/images')) return 'images';
if (path.startsWith('/profile')) return 'profile';
2025-08-29 09:51:17 +00:00
if (path.startsWith('/network')) return 'network';
if (path.startsWith('/storage')) return 'storage';
return 'images'; // 默认选中镜像列表
};
const handleMenuClick = (item: any) => {
// 更新选中状态
setSelectedKey(item.key);
// 使用路由导航
history.push(`/${item.key}`);
};
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
const handleLogout = () => {
localStorage.removeItem('isLoggedIn');
localStorage.removeItem('username');
message.success('已退出登录');
history.push('/login');
};
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
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>
);
2025-08-05 01:57:49 +00:00
2025-08-05 08:54:53 +00:00
return (
2025-08-06 10:06:10 +00:00
<ConfigProvider locale={zhCN}>
2025-08-13 08:34:32 +00:00
<Layout className="main-layout">
<Sider
trigger={null}
collapsible
collapsed={collapsed}
className="main-sider"
2025-08-05 08:54:53 +00:00
>
2025-08-14 09:23:11 +00:00
<div className="logo">{!collapsed && <span>NEXSPACE</span>}</div>
2025-08-13 08:34:32 +00:00
<Menu
theme="dark"
mode="inline"
selectedKeys={[selectedKey]}
onClick={handleMenuClick}
>
<Menu.Item key="terminal" icon={<AppstoreOutlined />}>
</Menu.Item>
<Menu.Item key="userList" icon={<AppstoreOutlined />}>
</Menu.Item>
<Menu.Item key="images" icon={<AppstoreOutlined />}>
2025-08-29 09:51:17 +00:00
</Menu.Item>
<Menu.Item key="network" icon={<AppstoreOutlined />}>
</Menu.Item>
<Menu.Item key="storage" icon={<AppstoreOutlined />}>
2025-08-13 08:34:32 +00:00
</Menu.Item>
<Menu.Item key="profile" icon={<UserOutlined />}>
</Menu.Item>
</Menu>
</Sider>
2025-08-05 01:57:49 +00:00
2025-08-13 08:34:32 +00:00
<Layout>
<Header className="main-header">
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
onClick={() => setCollapsed(!collapsed)}
className="trigger"
/>
2025-08-05 01:57:49 +00:00
2025-08-13 08:34:32 +00:00
<div className="header-right">
<span className="welcome-text">{username}</span>
<Dropdown overlay={userMenu} placement="bottomRight">
<Avatar icon={<UserOutlined />} className="user-avatar" />
</Dropdown>
</div>
</Header>
2025-08-05 01:57:49 +00:00
2025-08-13 08:34:32 +00:00
<Content
className="main-content"
style={{ height: 'calc(100vh - 64px)', overflow: 'auto' }}
>
2025-08-13 08:34:32 +00:00
<Outlet />
</Content>
</Layout>
2025-08-05 08:54:53 +00:00
</Layout>
2025-08-06 10:06:10 +00:00
</ConfigProvider>
2025-08-05 08:54:53 +00:00
);
2025-08-05 01:57:49 +00:00
};
export default MainLayout;