1. 新增数据管理页面,支持查看数据概览、短剧/剧集指标和同步记录 2. 新增短剧详情页,支持查看短剧信息、管理剧集和上传视频 3. 新增菜单配置项,添加数据管理入口 4. 扩展API类型定义,新增剧集、上传任务、数据统计等类型 5. 修复timestamp类型为数字类型,新增短剧额外字段 6. 为页面布局添加统一的page-stack样式类 7. 新增短剧详情路由,优化短剧列表页跳转逻辑
80 lines
2.5 KiB
TypeScript
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>;
|
|
}
|