Files
cyh-tk-admin/src/layout/menu.tsx
zhxiao1124 a691db573c feat: 新增数据管理页面与短剧详情页,完善接口类型与菜单配置
1.  新增数据管理页面,支持查看数据概览、短剧/剧集指标和同步记录
2.  新增短剧详情页,支持查看短剧信息、管理剧集和上传视频
3.  新增菜单配置项,添加数据管理入口
4.  扩展API类型定义,新增剧集、上传任务、数据统计等类型
5.  修复timestamp类型为数字类型,新增短剧额外字段
6.  为页面布局添加统一的page-stack样式类
7.  新增短剧详情路由,优化短剧列表页跳转逻辑
2026-07-01 16:35:57 +08:00

80 lines
2.5 KiB
TypeScript

import type { ReactNode } from 'react';
import { Menu } from '@arco-design/web-react';
import {
IconApps,
IconDashboard,
IconFile,
IconSettings,
IconUser,
IconVideoCamera,
} from '@arco-design/web-react/icon';
import type { AdminProfile } from '../api/types';
import { hasPermissions } from '../utils/permission';
export type MenuConfig = {
key: string;
label: string;
icon?: ReactNode;
requiredPermissions?: string[];
children?: MenuConfig[];
};
export const SYSTEM_MENU_KEY = '/system';
export const menuItems: MenuConfig[] = [
{ key: '/dashboard', label: '工作台', icon: <IconDashboard /> },
{ key: '/dramas', label: '短剧管理', icon: <IconVideoCamera />, requiredPermissions: ['drama:read'] },
{ key: '/data', label: '数据管理', icon: <IconApps />, requiredPermissions: ['data:read'] },
{ key: '/users', label: '用户管理', icon: <IconUser />, requiredPermissions: ['user:read'] },
{
key: SYSTEM_MENU_KEY,
label: '系统管理',
icon: <IconSettings />,
children: [
{ key: '/roles', label: '角色管理', icon: <IconApps />, requiredPermissions: ['role:read'] },
{ key: '/personnel', label: '人员管理', icon: <IconUser />, requiredPermissions: ['admin-user:read'] },
{ key: '/profile', label: '个人中心', icon: <IconUser /> },
{ key: '/logs', label: '日志管理', icon: <IconFile />, requiredPermissions: ['log:read'] },
],
},
];
export function filterMenuItems(items: MenuConfig[], profile: AdminProfile | null): MenuConfig[] {
return items
.map((item) => {
if (item.children) {
const children = filterMenuItems(item.children, profile);
return children.length ? { ...item, children } : null;
}
return hasPermissions(profile, item.requiredPermissions) ? item : null;
})
.filter((item): item is MenuConfig => Boolean(item));
}
export function findCurrentMenu(pathname: string) {
for (const item of menuItems) {
if (item.children) {
const child = item.children.find((childItem) => pathname.startsWith(childItem.key));
if (child) {
return { item: child, parent: item };
}
}
if (pathname.startsWith(item.key)) {
return { item };
}
}
return undefined;
}
export function renderMenuItem(item: MenuConfig) {
if (item.children) {
return (
<Menu.SubMenu key={item.key} title={<span>{item.icon}{item.label}</span>}>
{item.children.map((child) => renderMenuItem(child))}
</Menu.SubMenu>
);
}
return <Menu.Item key={item.key}>{item.icon}{item.label}</Menu.Item>;
}