diff --git a/admin/src/layout.tsx b/admin/src/layout.tsx index df28729..e8ca930 100644 --- a/admin/src/layout.tsx +++ b/admin/src/layout.tsx @@ -1,24 +1,24 @@ -import React, { useState, useMemo, useRef, useEffect } from 'react'; -import { Switch, Route, Redirect, useHistory } from 'react-router-dom'; -import { Layout, Menu, Breadcrumb, Spin } from '@arco-design/web-react'; +import React, {useState, useMemo, useRef, useEffect} from 'react'; +import {Switch, Route, Redirect, useHistory} from 'react-router-dom'; +import {Layout, Menu, Breadcrumb, Spin} from '@arco-design/web-react'; import cs from 'classnames'; import { - IconMenuFold, - IconMenuUnfold, - IconSettings, - IconList, IconDashboard, + IconMenuFold, + IconMenuUnfold, + IconSettings, + IconList, IconDashboard, } from '@arco-design/web-react/icon'; import qs from 'query-string'; import NProgress from 'nprogress'; import Navbar from './components/NavBar'; import Footer from './components/Footer'; -import useRoute, { IRoute } from '@/routes'; -import { isArray } from './utils/is'; +import useRoute, {IRoute} from '@/routes'; +import {isArray} from './utils/is'; import useLocale from './utils/useLocale'; import getUrlParams from './utils/getUrlParams'; import lazyload from './utils/lazyload'; import styles from './style/layout.module.less'; -import { useStore } from '@/store'; +import {useStore} from '@/store'; const MenuItem = Menu.Item; const SubMenu = Menu.SubMenu; @@ -27,241 +27,247 @@ const Sider = Layout.Sider; const Content = Layout.Content; function getFlattenRoutes(routes) { - const mod = import.meta.glob('./pages/**/[a-z[]*.tsx'); - const res = []; - function travel(_routes) { - _routes.forEach((route) => { - if (route.key && !route.children) { - route.component = lazyload(mod[`./pages/${route.key}/index.tsx`]); - res.push(route); - } else if (isArray(route.children) && route.children.length) { - travel(route.children); - } - }); - } - travel(routes); - return res; + const mod = import.meta.glob('./pages/**/[a-z[]*.tsx'); + const res = []; + + function travel(_routes) { + _routes.forEach((route) => { + if (route.key && !route.children) { + try { + route.component = lazyload(mod[`./pages/${route.key}/index.tsx`]); + res.push(route); + } catch (error) { + console.error(`cannot found /pages/${route.key}/index.tsx`) + } + } else if (isArray(route.children) && route.children.length) { + travel(route.children); + } + }); + } + + travel(routes); + return res; } function PageLayout() { - const urlParams = getUrlParams(); - const history = useHistory(); - const pathname = history.location.pathname; - const currentComponent = qs.parseUrl(pathname).url.slice(1); - const locale = useLocale(); - const store = useStore() - const {settings,userInfo,userLoading} = store - const [routes, defaultRoute] = useRoute(userInfo?.menus); + const urlParams = getUrlParams(); + const history = useHistory(); + const pathname = history.location.pathname; + const currentComponent = qs.parseUrl(pathname).url.slice(1); + const locale = useLocale(); + const store = useStore() + const {settings, userInfo, userLoading} = store + const [routes, defaultRoute] = useRoute(userInfo?.menus); - const defaultSelectedKeys = [currentComponent || defaultRoute]; - const paths = (currentComponent || defaultRoute).split('/'); - const defaultOpenKeys = paths.slice(0, paths.length - 1); + const defaultSelectedKeys = [currentComponent || defaultRoute]; + const paths = (currentComponent || defaultRoute).split('/'); + const defaultOpenKeys = paths.slice(0, paths.length - 1); - const [breadcrumb, setBreadCrumb] = useState([]); - const [collapsed, setCollapsed] = useState(false); - const [selectedKeys, setSelectedKeys] = - useState(defaultSelectedKeys); - const [openKeys, setOpenKeys] = useState(defaultOpenKeys); + const [breadcrumb, setBreadCrumb] = useState([]); + const [collapsed, setCollapsed] = useState(false); + const [selectedKeys, setSelectedKeys] = + useState(defaultSelectedKeys); + const [openKeys, setOpenKeys] = useState(defaultOpenKeys); - const routeMap = useRef>(new Map()); - const menuMap = useRef< - Map - >(new Map()); + const routeMap = useRef>(new Map()); + const menuMap = useRef< + Map + >(new Map()); - const navbarHeight = 60; - const menuWidth = collapsed ? 48 : settings.menuWidth; + const navbarHeight = 60; + const menuWidth = collapsed ? 48 : settings.menuWidth; - const showNavbar = settings.navbar && urlParams.navbar !== false; - const showMenu = settings.menu && urlParams.menu !== false; - const showFooter = settings.footer && urlParams.footer !== false; + const showNavbar = settings.navbar && urlParams.navbar !== false; + const showMenu = settings.menu && urlParams.menu !== false; + const showFooter = settings.footer && urlParams.footer !== false; - const flattenRoutes = useMemo(() => getFlattenRoutes(routes) || [], [routes]); + const flattenRoutes = useMemo(() => getFlattenRoutes(routes) || [], [routes]); - function onClickMenuItem(key) { - const currentRoute = flattenRoutes.find((r) => r.key === key); - const component = currentRoute.component; - const preload = component.preload(); - NProgress.start(); - preload.then(() => { - history.push(currentRoute.path ? currentRoute.path : `/${key}`); - NProgress.done(); - }); - } + function onClickMenuItem(key) { + const currentRoute = flattenRoutes.find((r) => r.key === key); + const component = currentRoute.component; + const preload = component.preload(); + NProgress.start(); + preload.then(() => { + history.push(currentRoute.path ? currentRoute.path : `/${key}`); + NProgress.done(); + }); + } - function toggleCollapse() { - setCollapsed((collapsed) => !collapsed); - } + function toggleCollapse() { + setCollapsed((collapsed) => !collapsed); + } - const paddingLeft = showMenu ? { paddingLeft: menuWidth } : {}; - const paddingTop = showNavbar ? { paddingTop: navbarHeight } : {}; - const paddingStyle = { ...paddingLeft, ...paddingTop }; + const paddingLeft = showMenu ? {paddingLeft: menuWidth} : {}; + const paddingTop = showNavbar ? {paddingTop: navbarHeight} : {}; + const paddingStyle = {...paddingLeft, ...paddingTop}; - function renderRoutes(locale) { - routeMap.current.clear(); - return function travel(_routes: IRoute[], level, parentNode = []) { - return _routes.map((route) => { - const { breadcrumb = true, ignore } = route; - const iconDom = getIconFromKey(route.key); - const titleDom = ( - <> - {iconDom} {locale[route.name] || route.name} - - ); + function renderRoutes(locale) { + routeMap.current.clear(); + return function travel(_routes: IRoute[], level, parentNode = []) { + return _routes.map((route) => { + const {breadcrumb = true, ignore} = route; + const iconDom = getIconFromKey(route.key); + const titleDom = ( + <> + {iconDom} {locale[route.name] || route.name} + + ); - routeMap.current.set( - `/${route.key}`, - breadcrumb ? [...parentNode, route.name] : [] - ); + routeMap.current.set( + `/${route.key}`, + breadcrumb ? [...parentNode, route.name] : [] + ); - const visibleChildren = (route.children || []).filter((child) => { - const { ignore, breadcrumb = true } = child; - if (ignore || route.ignore) { - routeMap.current.set( - `/${child.key}`, - breadcrumb ? [...parentNode, route.name, child.name] : [] - ); - } + const visibleChildren = (route.children || []).filter((child) => { + const {ignore, breadcrumb = true} = child; + if (ignore || route.ignore) { + routeMap.current.set( + `/${child.key}`, + breadcrumb ? [...parentNode, route.name, child.name] : [] + ); + } - return !ignore; - }); + return !ignore; + }); - if (ignore) { - return ''; - } - if (visibleChildren.length) { - menuMap.current.set(route.key, { subMenu: true }); - return ( - - {travel(visibleChildren, level + 1, [...parentNode, route.name])} - - ); - } - menuMap.current.set(route.key, { menuItem: true }); - return {titleDom}; - }); - }; - } + if (ignore) { + return ''; + } + if (visibleChildren.length) { + menuMap.current.set(route.key, {subMenu: true}); + return ( + + {travel(visibleChildren, level + 1, [...parentNode, route.name])} + + ); + } + menuMap.current.set(route.key, {menuItem: true}); + return {titleDom}; + }); + }; + } - function updateMenuStatus() { - const pathKeys = pathname.split('/'); - const newSelectedKeys: string[] = []; - const newOpenKeys: string[] = [...openKeys]; - while (pathKeys.length > 0) { - const currentRouteKey = pathKeys.join('/'); - const menuKey = currentRouteKey.replace(/^\//, ''); - const menuType = menuMap.current.get(menuKey); - if (menuType && menuType.menuItem) { - newSelectedKeys.push(menuKey); - } - if (menuType && menuType.subMenu && !openKeys.includes(menuKey)) { - newOpenKeys.push(menuKey); - } - pathKeys.pop(); - } - setSelectedKeys(newSelectedKeys); - setOpenKeys(newOpenKeys); - } + function updateMenuStatus() { + const pathKeys = pathname.split('/'); + const newSelectedKeys: string[] = []; + const newOpenKeys: string[] = [...openKeys]; + while (pathKeys.length > 0) { + const currentRouteKey = pathKeys.join('/'); + const menuKey = currentRouteKey.replace(/^\//, ''); + const menuType = menuMap.current.get(menuKey); + if (menuType && menuType.menuItem) { + newSelectedKeys.push(menuKey); + } + if (menuType && menuType.subMenu && !openKeys.includes(menuKey)) { + newOpenKeys.push(menuKey); + } + pathKeys.pop(); + } + setSelectedKeys(newSelectedKeys); + setOpenKeys(newOpenKeys); + } - function getIconFromKey(key) { - switch (key) { - case 'role': - return ; - case 'user': - return ; - default: - return ; - } - } + function getIconFromKey(key) { + switch (key) { + case 'role': + return ; + case 'user': + return ; + default: + return ; + } + } - useEffect(() => { - const routeConfig = routeMap.current.get(pathname); - const _breadcrumb = routeConfig || [] - setBreadCrumb([getIconFromKey(paths[0]),..._breadcrumb]); - updateMenuStatus(); - }, [pathname,userLoading]); + useEffect(() => { + const routeConfig = routeMap.current.get(pathname); + const _breadcrumb = routeConfig || [] + setBreadCrumb([getIconFromKey(paths[0]), ..._breadcrumb]); + updateMenuStatus(); + }, [pathname, userLoading]); - return ( - -
- -
- {userLoading ? ( - - ) : ( - - {showMenu && ( - -
- { - setOpenKeys(openKeys); - }} - > - {renderRoutes(locale)(routes, 1)} - -
-
- {collapsed ? : } -
-
- )} - -
- {!!breadcrumb.length && ( -
- - {breadcrumb.map((node, index) => ( - - {typeof node === 'string' ? locale[node] || node : node} - - ))} - -
- )} - - - {flattenRoutes.map((route, index) => { - return ( - - ); - })} - - - - import('./pages/exception/403'))} - /> - - -
- {showFooter &&