import request from '@/utils/request' import { MenuStatus } from '@/constants/status' export interface RawMenuItem { id: string createBy: string | null updateBy: string | null createdAt: string updatedAt: string deletedAt: string | null menuName: string parentId: string orderNum: number menuType: 'M' | 'C' | 'F' perms: string | null component: string | null status: number children: RawMenuItem[] } export interface MenuItem { id: number name: string path: string icon: string component: string parentId: number sort: number type: 'directory' | 'menu' | 'button' permission: string status: MenuStatus visible: boolean children?: MenuItem[] createdAt: string updatedAt: string } const menuTypeMap: Record = { M: 'directory', C: 'menu', F: 'button', } function normalizeMenuItem(raw: RawMenuItem): MenuItem { const permission = raw.perms || '' return { id: Number(raw.id), name: raw.menuName, path: buildPath(raw), icon: inferIcon(raw), component: raw.component || '', parentId: Number(raw.parentId), sort: raw.orderNum, type: menuTypeMap[raw.menuType] || 'menu', permission, status: raw.status as MenuStatus, visible: true, children: raw.children?.map(normalizeMenuItem) || [], createdAt: raw.createdAt, updatedAt: raw.updatedAt, } } function buildPath(raw: RawMenuItem): string { if (raw.menuType === 'M') return '' if (raw.menuType === 'F') return '' const perm = raw.perms || '' const pathMap: Record = { 'system:user:list': '/users', 'system:role:list': '/roles', 'system:menu:list': '/menus', 'system:dept:list': '/sys/dept', 'system:dict:list': '/dict', 'system:config:list': '/sys/config', 'system:notice:list': '/notice', 'system:file:list': '/files', 'audit:login:list': '/loginlog', 'audit:login-log:list': '/loginlog', 'audit:operation:list': '/oplog', 'audit:operation-log:list': '/oplog', 'audit:exception:list': '/exceptionlog', 'audit:exception-log:list': '/exceptionlog', 'monitor:online:list': '/monitor/online', 'monitor:job:list': '/monitor/job', 'monitor:data:list': '/monitor/data', 'monitor:server:list': '/monitor/server', 'monitor:cache:list': '/monitor/cache', } return pathMap[perm] || '' } function inferIcon(raw: RawMenuItem): string { const perm = raw.perms || '' const iconMap: Record = { 'system:user:list': 'user', 'system:role:list': 'role', 'system:menu:list': 'menu', 'system:dept:list': 'menu', 'system:dict:list': 'dict', 'system:config:list': 'config', 'system:notice:list': 'notice', 'system:file:list': 'file', 'audit:login:list': 'loginlog', 'audit:login-log:list': 'loginlog', 'audit:operation:list': 'oplog', 'audit:operation-log:list': 'oplog', 'audit:exception:list': 'exceptionlog', 'audit:exception-log:list': 'exceptionlog', 'monitor:online:list': 'user', 'monitor:job:list': 'menu', 'monitor:data:list': 'config', 'monitor:server:list': 'config', 'monitor:cache:list': 'config', } return iconMap[perm] || '' } export interface CreateMenuRequest { name: string path?: string icon?: string component?: string parentId: number sort: number type: 'directory' | 'menu' | 'button' permission?: string status?: MenuStatus visible?: boolean } export interface UpdateMenuRequest { name?: string path?: string icon?: string component?: string parentId?: number sort?: number type?: 'directory' | 'menu' | 'button' permission?: string status?: MenuStatus visible?: boolean } export const menuApi = { getAll: async (): Promise => { const res = await request.get('/menus') const raw = (res as unknown as RawMenuItem[]) return Array.isArray(raw) ? raw.map(normalizeMenuItem) : [] }, getById: async (id: number): Promise => { const res = await request.get(`/menus/${id}`) return normalizeMenuItem(res as unknown as RawMenuItem) }, getTree: async (): Promise => { const res = await request.get('/menus/tree') const raw = (res as unknown as RawMenuItem[]) return Array.isArray(raw) ? raw.map(normalizeMenuItem) : [] }, create: (data: CreateMenuRequest) => request.post('/menus', data), update: (id: number, data: UpdateMenuRequest) => request.put(`/menus/${id}`, data), delete: (id: number) => request.delete(`/menus/${id}`), }