95 lines
2.5 KiB
React
Raw Normal View History

import { DownOutlined } from "@ant-design/icons";
import { Dropdown, Layout, Menu, message, Space, theme } from "antd";
import { Content, Header } from "antd/es/layout/layout";
import Sider from "antd/es/layout/Sider";
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
2025-06-24 20:08:52 +08:00
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import menuConfig from "../config/menuConfig";
import {
logout,
selectUserName,
selectUserRole,
} from "../features/auth/authSlice";
export default function CommonLayout() {
const location = useLocation();
2025-06-24 20:08:52 +08:00
const naviagte = useNavigate();
const dispatch = useDispatch();
const userName = useSelector(selectUserName);
const [collapsed, setCollapsed] = useState(false);
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
const roles = useSelector(selectUserRole);
const menu = menuConfig.filter(
(item) => !item.roles || item.roles.some((role) => roles.includes(role))
);
const dropDownItems = [
{
key: "logout",
label: "退出登录",
},
];
const handleMenuClick = ({ key }) => {
if (key === "logout") {
dispatch(logout());
message.success("已退出登录");
naviagte("/login");
}
};
return (
<Layout style={{ minHeight: "100vh" }}>
<Sider
collapsible
collapsed={collapsed}
onCollapse={(value) => setCollapsed(value)}
>
<div className="demo-logo-vertical" />
<Menu
theme="dark"
selectedKeys={[location.pathname]}
mode="inline"
items={menu.map((item) => ({
key: item.path,
label: item.label,
icon: React.createElement(item.icon),
}))}
2025-06-24 20:08:52 +08:00
onClick={({ key }) => naviagte(key)}
/>
</Sider>
<Layout>
<Header
style={{ padding: 0, background: colorBgContainer }}
className="flex justify-end"
>
2025-06-25 16:43:40 +08:00
<Dropdown
menu={{ items: dropDownItems, onClick: handleMenuClick }}
className="p-4"
>
<Space>
{userName}
<DownOutlined />
</Space>
</Dropdown>
</Header>
<Content
style={{
margin: "16px 16px",
background: colorBgContainer,
borderRadius: borderRadiusLG,
}}
>
<Outlet />
</Content>
</Layout>
</Layout>
);
}