release: v0.17.0
GitHub Pages / build (push) Canceled after 0s
GitHub Pages / deploy (push) Canceled after 0s
Docker image / meta (push) Successful in 24s
Docs Docker image / meta (push) Successful in 7s
Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 59s
Docs Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 30s
Docker image / merge (push) Canceled after 0s
Docs Docker image / merge (push) Canceled after 0s
Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Docs Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s

This commit is contained in:
Qiufeng
2026-08-19 22:09:49 +08:00
parent 9414048f9d
commit 84e9e7bff5
469 changed files with 19997 additions and 39561 deletions
+115
View File
@@ -0,0 +1,115 @@
import React, { memo, useState } from 'react';
import { useNavigate, useLocation } 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 MenuLogo from './MenuLogo';
import Style from './Menu.module.less';
const { SubMenu, MenuItem, HeadMenu } = Menu;
interface IMenuProps {
showLogo?: boolean;
showOperation?: boolean;
}
const renderMenuItems = (menu: IRouter[], parentPath = '') => {
const navigate = useNavigate();
return menu.map((item) => {
const { children, meta, path } = item;
if (!meta || meta?.hidden === true) {
// 无meta信息 或 hidden == true,路由不显示为菜单
return null;
}
const { Icon, title, single } = meta;
const routerPath = resolve(parentPath, path);
if (!children || children.length === 0) {
return (
<MenuItem
key={routerPath}
value={routerPath}
icon={Icon ? <Icon /> : undefined}
onClick={() => navigate(routerPath)}
>
{title}
</MenuItem>
);
}
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 (
<MenuItem
key={singlePath}
value={singlePath}
icon={Icon ? <Icon /> : undefined}
onClick={() => navigate(singlePath)}
>
{title}
</MenuItem>
);
}
}
return (
<SubMenu key={routerPath} value={routerPath} title={title} icon={Icon ? <Icon /> : undefined}>
{renderMenuItems(children, routerPath)}
</SubMenu>
);
});
};
/**
* 顶部菜单
*/
export const HeaderMenu = memo(() => {
const globalState = useAppSelector(selectGlobal);
const location = useLocation();
const [active, setActive] = useState<MenuValue>(location.pathname); // todo
return (
<HeadMenu
expandType='popup'
style={{ marginBottom: 20 }}
value={active}
theme={globalState.theme}
onChange={(v) => setActive(v)}
>
{renderMenuItems(router)}
</HeadMenu>
);
});
/**
* 左侧菜单
*/
export default memo((props: IMenuProps) => {
const location = useLocation();
const globalState = useAppSelector(selectGlobal);
const { version } = globalState;
const bottomText = globalState.collapsed ? version : `元境幻生管理台 ${version}`;
return (
<Menu
width='232px'
style={{ flexShrink: 0, height: '100%' }}
className={Style.menuPanel2}
value={location.pathname}
theme={globalState.theme}
collapsed={globalState.collapsed}
operations={props.showOperation ? <div className={Style.menuTip}>{bottomText}</div> : undefined}
logo={props.showLogo ? <MenuLogo collapsed={globalState.collapsed} /> : undefined}
>
{renderMenuItems(router)}
</Menu>
);
});