f0746d06db
- 删除 novalon 前端 src/ 下所有文件 - 从 gym-manage 复制前端 src/ 完整目录树 - 替换 gym-manage-api → novalon-manage-api - 替换 gym_system → manage_system - 无 gym 残留引用
211 lines
5.4 KiB
TypeScript
211 lines
5.4 KiB
TypeScript
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<string, MenuItem>()
|
|
const rootMenus: MenuItem[] = []
|
|
|
|
const componentToPathMap: Record<string, string> = {
|
|
'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<string, string> = {
|
|
'系统管理': '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
|
|
}
|
|
}
|
|
}
|
|
})
|