123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import React, {
- useMemo,
- useEffect,
- useState,
- useCallback,
- Suspense,
- } from "react";
- import { App, Layout, message } from "antd";
- import { useSelector } from "react-redux";
- import {
- Route,
- Routes,
- useNavigate,
- useLocation,
- Navigate,
- } from "react-router-dom";
- import { Content } from "antd/es/layout/layout";
- import { hasToken, getTokenInfo } from "@/utils";
- import store from "@/store";
- import { LayoutSider, LayoutHeader } from "./components";
- import { RootState } from "@/store";
- import { RouteType } from "./types";
- import { DEFAULT_ADMIN_MENU, DEFAULT_MENU } from "./constants";
- import "./index.scss";
- import { MemoSpinLoding } from "@/components";
- import { isNaN } from "lodash";
- const NotFound = React.lazy(() => import("@/components/NotFound"));
- export default function CustomLayout() {
- const navigate = useNavigate();
- const location = useLocation();
- const [activeMenuKey, setActiveMenuKey] = useState("/");
- const baseStore = useSelector<RootState, RootState["base"]>(
- (state) => state.base
- );
- const menuList = useMemo<RouteType[]>(() => {
- const list = baseStore.userInfo?.user.isAdmin
- ? [...DEFAULT_MENU, ...DEFAULT_ADMIN_MENU]
- : [...DEFAULT_MENU];
- function deep(v: RouteType[], parent?: RouteType) {
- const stack: RouteType[] = [];
- v.forEach((item) => {
- const { child = [], ...rest } = item;
- if (!!parent) {
- rest.key = parent.key + rest.key;
- rest.parent = {
- key: parent.key,
- label: parent.label,
- };
- }
- stack.push(rest);
- if (!!child.length) {
- stack.push(...deep(child, item));
- }
- });
- return stack;
- }
- return deep(list);
- }, [baseStore.userInfo]);
- const [curMenu, setCurMenu] = useState<null | RouteType>(null);
- useEffect(() => {
- if (!hasToken()) {
- message.open({
- type: "warning",
- content: "登录失效!",
- duration: 4,
- });
- navigate("/login", {
- replace: true,
- });
- } else {
- store.dispatch({ type: "setUserInfo", payload: getTokenInfo() });
- }
- }, [navigate]);
- /**
- * 初始化菜单选中状态
- */
- const getActiveMenu = useCallback(() => {
- const split = location.pathname.split("/").slice(1);
- const pMenu = "/" + split[0];
- if (split.length > 1) {
- const pathname = split
- .map((i) => (!isNaN(Number(i)) ? ":id" : i))
- .join("/");
- setCurMenu(menuList.find((i) => i.key === `/${pathname}`) as RouteType);
- } else {
- setCurMenu(menuList.find((i) => i.key === pMenu) as RouteType);
- }
- setActiveMenuKey(pMenu);
- }, [location, menuList]);
- useEffect(() => {
- getActiveMenu();
- }, [getActiveMenu]);
- const handleMenu = useCallback(
- (item: Partial<RouteType>) => {
- const path = item?.key as string;
- setActiveMenuKey(path);
- navigate(path);
- },
- [setActiveMenuKey, navigate]
- );
- return (
- <App>
- <Layout hasSider className="layout">
- {/* 菜单 */}
- <LayoutSider
- selectedKeys={[activeMenuKey]}
- items={menuList.filter((i) => !i.hide)}
- onClick={handleMenu}
- />
- <Layout style={{ marginLeft: 220 }}>
- {/* 头部 */}
- <LayoutHeader menu={curMenu} />
- {/* 主体 */}
- <Content
- style={{
- margin: "15px",
- overflow: "initial",
- position: "relative",
- background: "#ffffff",
- padding: 20,
- borderRadius: 4,
- }}
- >
- <Suspense fallback={<MemoSpinLoding />}>
- <Routes>
- <Route path="/" element={<Navigate to="/weapon" />} />
- {menuList.map((menu) => (
- <Route
- key={menu.key}
- path={menu.key}
- Component={menu.component}
- />
- ))}
- <Route path="*" Component={NotFound} />
- </Routes>
- </Suspense>
- </Content>
- </Layout>
- </Layout>
- </App>
- );
- }
|