import React, { memo, useState } from 'react'; import { useNavigate, useLocation, NavigateFunction } from 'react-router-dom'; import { Menu, MenuValue } from 'tdesign-react'; import router, { IRouter } from 'router'; import { resolve } from 'utils/path'; import { useAppSelector } from 'modules/store'; import { selectGlobal } from 'modules/global'; import { selectUser } from 'modules/user'; import MenuLogo from './MenuLogo'; import Style from './Menu.module.less'; const { SubMenu, MenuItem, HeadMenu } = Menu; interface IMenuProps { showLogo?: boolean; showOperation?: boolean; } // 纯函数:递归渲染菜单(不在递归/循环内调用 Hook) const renderMenuItems = (menu: IRouter[], navigate: NavigateFunction, isAdmin: boolean, parentPath = '') => { return menu.map((item) => { const { children, meta, path } = item; if (!meta || meta?.hidden === true) { return null; } if (meta.admin && !isAdmin) { // 平台管理菜单仅 admin 角色可见 return null; } const { Icon, title, single } = meta; const routerPath = resolve(parentPath, path); if (!children || children.length === 0) { return ( : undefined} onClick={() => navigate(routerPath)} > {title} ); } if (single && children?.length > 0) { const firstChild = children[0]; if (firstChild?.meta && !firstChild?.meta?.hidden) { const { Icon, title } = meta; const singlePath = resolve(resolve(parentPath, path), firstChild.path); return ( : undefined} onClick={() => navigate(singlePath)} > {title} ); } } return ( : undefined}> {renderMenuItems(children, navigate, isAdmin, routerPath)} ); }); }; /** * 顶部菜单 */ export const HeaderMenu = memo(() => { const globalState = useAppSelector(selectGlobal); const location = useLocation(); const navigate = useNavigate(); const userState = useAppSelector(selectUser); const isAdmin = userState.userInfo?.role === 'admin'; const [active, setActive] = useState(location.pathname); // todo return ( setActive(v)} > {renderMenuItems(router, navigate, isAdmin)} ); }); /** * 左侧菜单 */ export default memo((props: IMenuProps) => { const location = useLocation(); const navigate = useNavigate(); const globalState = useAppSelector(selectGlobal); const userState = useAppSelector(selectUser); const isAdmin = userState.userInfo?.role === 'admin'; const { version } = globalState; const bottomText = globalState.collapsed ? version : 'EveryPublish ' + version; return ( {bottomText} : undefined} logo={props.showLogo ? : undefined} > {renderMenuItems(router, navigate, isAdmin)} ); });