feat: 完成TikTok短剧管理后台基础功能开发
本次提交搭建了完整的后台管理系统,包含: 1. 登录认证与权限校验体系 2. 工作台、短剧、用户、角色、人员、日志等全业务模块 3. 响应式布局与通用样式组件 4. 菜单动态过滤与路由权限控制 5. 移除了README中冗余的权限管理菜单项
This commit is contained in:
78
src/layout/menu.tsx
Normal file
78
src/layout/menu.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
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: '/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>;
|
||||
}
|
||||
Reference in New Issue
Block a user