145 lines
3.4 KiB
TypeScript
145 lines
3.4 KiB
TypeScript
import { FC } from 'react';
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
import {
|
|
TeamOutlined,
|
|
UserOutlined,
|
|
DesktopOutlined,
|
|
HomeOutlined,
|
|
} from '@ant-design/icons';
|
|
import type { MenuProps } from 'antd';
|
|
import { Breadcrumb, Layout, Menu, theme } from 'antd';
|
|
import { AppRouter, routes, routeName } from './router';
|
|
import PageFooter from './components/PageFooter';
|
|
|
|
const { Content, Sider } = Layout;
|
|
|
|
type MenuItem = Required<MenuProps>['items'][number];
|
|
|
|
type KeyRouterMap = Map<React.Key, string>;
|
|
|
|
const keyRouterMap: KeyRouterMap = new Map();
|
|
|
|
function getItem(
|
|
label: React.ReactNode,
|
|
key: React.Key,
|
|
icon?: React.ReactNode,
|
|
children?: MenuItem[],
|
|
): MenuItem {
|
|
return {
|
|
key,
|
|
icon,
|
|
children,
|
|
label,
|
|
} as MenuItem;
|
|
}
|
|
|
|
function defMenu(
|
|
label: React.ReactNode,
|
|
key: React.Key,
|
|
icon: React.ReactNode,
|
|
path: string,
|
|
): MenuItem {
|
|
keyRouterMap.set(key, path);
|
|
return getItem(label, key, icon);
|
|
}
|
|
|
|
function defRootMenu(
|
|
label: React.ReactNode,
|
|
key: React.Key,
|
|
icon: React.ReactNode,
|
|
children: MenuItem[],
|
|
): MenuItem {
|
|
return getItem(label, key, icon, children);
|
|
}
|
|
|
|
function defSubMenu(
|
|
label: React.ReactNode,
|
|
key: React.Key,
|
|
path: string,
|
|
): MenuItem {
|
|
keyRouterMap.set(key, path);
|
|
return getItem(label, key);
|
|
}
|
|
|
|
const items: MenuItem[] = [
|
|
defMenu('主页', 'mainpage', <DesktopOutlined />, routes.main),
|
|
defRootMenu('主席团管理', 'sub1', <UserOutlined />, [
|
|
defSubMenu('排班表管理', '1', routes.admin.dutyTable),
|
|
defSubMenu('值班信息管理', '2', routes.admin.dutyInfo),
|
|
]),
|
|
defRootMenu('值班组长', 'sub2', <TeamOutlined />, [
|
|
defSubMenu('值班总结', '4', '/duty/conclusion'),
|
|
]),
|
|
defMenu('关于我们', 'aboutpage', <UserOutlined />, routes.about),
|
|
];
|
|
|
|
interface BreadcrumbItem {
|
|
href: string;
|
|
title: JSX.Element;
|
|
}
|
|
|
|
const AppLayout: FC<{ router: JSX.Element }> = (props) => {
|
|
const { colorBgContainer, borderRadiusLG } = theme.getDesignToken();
|
|
const navigate = useNavigate();
|
|
|
|
const location = useLocation();
|
|
const pathArray = location.pathname.split('/');
|
|
const currentRouteItems: BreadcrumbItem[] = [
|
|
{
|
|
href: '/',
|
|
title: <HomeOutlined />,
|
|
},
|
|
];
|
|
|
|
for (var i = 1; i < pathArray.length; i++) {
|
|
currentRouteItems.push({
|
|
href: '',
|
|
title: <span>{routeName.get(pathArray[i])}</span>,
|
|
});
|
|
}
|
|
|
|
return (
|
|
<Layout style={{ minHeight: '100vh' }}>
|
|
<Sider>
|
|
<div className='demo-logo-vertical' />
|
|
<Menu
|
|
theme='dark'
|
|
defaultSelectedKeys={['1']}
|
|
mode='inline'
|
|
items={items}
|
|
onClick={(info: { key: React.Key }) => {
|
|
console.log('path', keyRouterMap.get(info.key));
|
|
navigate(keyRouterMap.get(info.key) || '/');
|
|
}}
|
|
/>
|
|
</Sider>
|
|
<Layout>
|
|
<Content style={{ margin: '0 16px' }}>
|
|
<Breadcrumb style={{ margin: '16px 0' }} items={currentRouteItems} />
|
|
<div
|
|
style={{
|
|
padding: 24,
|
|
minHeight: 360,
|
|
background: colorBgContainer,
|
|
borderRadius: borderRadiusLG,
|
|
}}
|
|
>
|
|
<div>{props.router}</div>
|
|
</div>
|
|
</Content>
|
|
<PageFooter />
|
|
</Layout>
|
|
</Layout>
|
|
);
|
|
};
|
|
|
|
const App: FC = () => {
|
|
return (
|
|
<div className='app'>
|
|
<AppLayout router={<AppRouter />} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default App;
|