index.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import React, { useMemo, useEffect, Suspense } from "react";
  2. import { App, Layout } from "antd";
  3. import { useSelector } from "react-redux";
  4. import { Route, Routes, useNavigate, Navigate } from "react-router-dom";
  5. import { Content } from "antd/es/layout/layout";
  6. import { hasToken, getTokenInfo, DageLoading } from "@dage/pc-components";
  7. import store from "@/store";
  8. import { LayoutMenu, LayoutHeader } from "./components";
  9. import { RootState } from "@/store";
  10. import LogoImage from "@/assets/images/logo.png";
  11. import { DEFAULT_ADMIN_MENU, DEFAULT_MENU, DageRouteItem } from "@/router";
  12. import "./index.scss";
  13. const NotFound = React.lazy(() => import("@/components/NotFound"));
  14. export default function CustomLayout() {
  15. const navigate = useNavigate();
  16. const baseStore = useSelector<RootState, RootState["base"]>(
  17. (state) => state.base
  18. );
  19. const menuList = useMemo<DageRouteItem[]>(() => {
  20. return baseStore.userInfo?.user.isAdmin
  21. ? [...DEFAULT_MENU, ...DEFAULT_ADMIN_MENU]
  22. : [...DEFAULT_MENU];
  23. }, [baseStore.userInfo]);
  24. useEffect(() => {
  25. if (!hasToken()) {
  26. navigate("/login", {
  27. replace: true,
  28. });
  29. } else {
  30. store.dispatch({ type: "setUserInfo", payload: getTokenInfo() });
  31. }
  32. }, [navigate]);
  33. return (
  34. <App>
  35. <Layout hasSider className="layout">
  36. {/* 菜单 */}
  37. <Layout.Sider
  38. width={220}
  39. style={{
  40. position: "fixed",
  41. top: 0,
  42. left: 0,
  43. bottom: 0,
  44. background: "#242424",
  45. }}
  46. >
  47. <div className="logo">
  48. <img draggable="false" alt="logo" src={LogoImage} />
  49. </div>
  50. <LayoutMenu
  51. className="layout-menu"
  52. theme="dark"
  53. inlineIndent={20}
  54. menuData={menuList}
  55. />
  56. </Layout.Sider>
  57. <Layout style={{ marginLeft: 220 }}>
  58. {/* 头部 */}
  59. <LayoutHeader menuData={menuList} />
  60. {/* 主体 */}
  61. <Content
  62. style={{
  63. margin: "15px",
  64. overflow: "initial",
  65. position: "relative",
  66. background: "#ffffff",
  67. padding: 20,
  68. borderRadius: 4,
  69. }}
  70. >
  71. <Suspense fallback={<DageLoading />}>
  72. {menuList.length && (
  73. <Routes>
  74. <Route
  75. path="/"
  76. element={
  77. <Navigate to={menuList[0].redirect || menuList[0].path} />
  78. }
  79. />
  80. {renderRoutes(menuList).map((menu) =>
  81. menu.redirect ? (
  82. <Route
  83. key={menu.path}
  84. path={menu.path}
  85. element={<Navigate replace to={menu.redirect} />}
  86. />
  87. ) : (
  88. <Route
  89. key={menu.path}
  90. path={menu.path}
  91. Component={menu.Component}
  92. />
  93. )
  94. )}
  95. <Route path="*" Component={NotFound} />
  96. </Routes>
  97. )}
  98. </Suspense>
  99. </Content>
  100. </Layout>
  101. </Layout>
  102. </App>
  103. );
  104. }
  105. function renderRoutes(routes: DageRouteItem[]) {
  106. function deep(v: DageRouteItem[]) {
  107. const stack: DageRouteItem[] = [];
  108. v.forEach((item) => {
  109. const { children = [], ...rest } = item;
  110. stack.push(rest);
  111. if (!!children.length) {
  112. stack.push(...deep(children));
  113. }
  114. });
  115. return stack;
  116. }
  117. return deep(routes);
  118. }