import { defineStore } from 'pinia' import request from '@/utils/request' export interface MenuItem { id: string name: string path: string icon?: string parentId?: string sort: number children?: MenuItem[] } interface BackendMenuItem { id: string menuName: string parentId: string orderNum: number menuType: string perms?: string component?: string status: number children?: BackendMenuItem[] } function transformMenuData(backendMenus: BackendMenuItem[]): MenuItem[] { const menuMap = new Map() const rootMenus: MenuItem[] = [] const componentToPathMap: Record = { 'system/user/index': '/users', 'system/role/index': '/roles', 'system/menu/index': '/menus', 'system/dict/index': '/dict', 'system/config/index': '/sys/config', 'system/notice/index': '/notice', 'system/file/index': '/files', 'audit/operation/index': '/oplog', 'audit/login/index': '/loginlog', 'audit/exception/index': '/exceptionlog', } const filteredMenus = backendMenus.filter(menu => menu.menuType !== 'F') filteredMenus.forEach(menu => { const menuItem: MenuItem = { id: menu.id, name: menu.menuName, path: menu.component ? (componentToPathMap[menu.component] || `/${menu.component.replace('/index', '').replace('system/', '')}`) : '', icon: getMenuIcon(menu.menuName), parentId: menu.parentId === '0' ? undefined : menu.parentId, sort: menu.orderNum } menuMap.set(menu.id, menuItem) }) filteredMenus.forEach(menu => { const menuItem = menuMap.get(menu.id)! if (menu.parentId === '0') { rootMenus.push(menuItem) } else { const parentMenu = menuMap.get(menu.parentId) if (parentMenu) { if (!parentMenu.children) { parentMenu.children = [] } parentMenu.children.push(menuItem) } } }) rootMenus.forEach(menu => { if (menu.children) { menu.children.sort((a, b) => a.sort - b.sort) } }) return rootMenus.sort((a, b) => a.sort - b.sort) } function getMenuIcon(menuName: string): string { const iconMap: Record = { '系统管理': 'Setting', '审计日志': 'Document', '系统监控': 'Monitor', '用户管理': 'User', '角色管理': 'UserFilled', '菜单管理': 'Menu', '字典管理': 'Collection', '参数配置': 'Tools', '通知公告': 'Bell', '文件管理': 'Folder', '操作日志': 'Document', '登录日志': 'Document', '异常日志': 'Warning' } return iconMap[menuName] || 'Document' } interface PermissionState { roles: string[] permissions: string[] menus: MenuItem[] loaded: boolean } export const usePermissionStore = defineStore('permission', { state: (): PermissionState => ({ roles: [], permissions: [], menus: [], loaded: false }), getters: { hasRole: (state) => (role: string | string[]) => { if (Array.isArray(role)) { return role.some(r => state.roles.includes(r)) } return state.roles.includes(role) }, hasPermission: (state) => (permission: string | string[]) => { if (Array.isArray(permission)) { return permission.some(p => state.permissions.includes(p)) } return state.permissions.includes(permission) } }, actions: { setPermissionData(data: { roles: string[] permissions: string[] menus: MenuItem[] }) { this.roles = data.roles this.permissions = data.permissions this.menus = data.menus this.loaded = true this.saveToStorage() }, clearPermissionData() { this.roles = [] this.permissions = [] this.menus = [] this.loaded = false localStorage.removeItem('permission') }, saveToStorage() { const data = { roles: this.roles, permissions: this.permissions, menus: this.menus } localStorage.setItem('permission', JSON.stringify(data)) }, initFromStorage() { const stored = localStorage.getItem('permission') if (stored) { try { const data = JSON.parse(stored) this.roles = data.roles || [] this.permissions = data.permissions || [] this.menus = data.menus || [] this.loaded = true } catch (error) { console.error('从 localStorage 恢复权限数据失败:', error) } } }, async fetchUserMenus() { try { const res: any = await request.get('/menus') if (res && Array.isArray(res)) { const transformedMenus = transformMenuData(res) const permissions: string[] = [] const extractPermissions = (menus: BackendMenuItem[]) => { menus.forEach(menu => { if (menu.perms) { permissions.push(menu.perms) } if (menu.children && menu.children.length > 0) { extractPermissions(menu.children) } }) } extractPermissions(res) this.setPermissionData({ roles: JSON.parse(localStorage.getItem('roles') || '[]'), permissions: permissions, menus: transformedMenus }) } } catch (error) { console.error('获取用户菜单失败:', error) throw error } } } })