2022-12-05 23:01:12 +08:00

194 lines
4.4 KiB
TypeScript

import { defineStore } from 'pinia'
import { Permission } from '/admin/types/permission'
import { MenuType } from '/admin/enum/app'
import { Menu } from '/admin/types/Menu'
import { constantRoutes } from '/admin/router'
import { RouteRecordRaw } from 'vue-router'
interface Permissions {
menus: Menu[]
asyncMenus: Menu[]
permissions: Permission[]
menuPathMap: Map<string, string>
}
export const usePermissionsStore = defineStore('PermissionsStore', {
state: (): Permissions => {
return {
menus: [],
asyncMenus: [],
permissions: [],
menuPathMap: new Map(),
}
},
/**
* get
*/
getters: {
getMenus(): Menu[] {
return this.menus
},
getAsyncMenus(): Menu[] {
return this.asyncMenus
},
getPermissions(): Permission[] {
return this.permissions
},
getMenuPathMap(): Map<string, string> {
return this.menuPathMap
},
},
/**
* actions
*/
actions: {
/**
* generate async menus
* @param permissions
* @param force
* @returns
*/
getAsyncMenusFrom(permissions: Permission[], force: boolean = false): Menu[] {
// 如果非强制获取并且 menu 有值,直接返回
if (!force && this.asyncMenus.length > 0) {
return this.asyncMenus
}
const menus: Permission[] = []
permissions.forEach(permission => {
if (permission.type === MenuType.PAGE_TYPE) {
menus.push(permission)
}
// set map
this.menuPathMap.set(permission.route, permission.title)
})
this.setAsyncMenus(this.getAsnycMenus(menus))
return this.asyncMenus
},
/**
* get menus
* @param permissions
* @param force
* @returns
*/
getMenusFrom(permissions: Permission[], force: boolean = false): Menu[] {
// 如果非强制获取并且 menu 有值,直接返回
if (!force && this.menus.length > 0) {
return this.menus
}
const asyncMenus = this.getAsyncMenusFrom(permissions, force)
this.setMenus(asyncMenus)
return this.menus
},
/**
* set menus
*
* @param menus
*/
setMenus(menus: Menu[]) {
this.menus = this.transformRoutesToMenus(constantRoutes).concat(menus)
},
setAsyncMenus(menus: Menu[]) {
this.asyncMenus = menus
},
/**
* 生成 Menus
*
* @param permissions
* @param parentId
* @param path
* @returns
*/
getAsnycMenus(permissions: Permission[], parentId: number = 0, path: string = ''): Menu[] {
const menus: Menu[] = []
permissions.forEach(permission => {
if (permission.parent_id === parentId) {
// menu
const menu: Menu = Object.assign({
path: this.resoulveRoutePath(permission.route, path),
name: permission.module + '_' + permission.permission_mark,
redirect: permission.redirect,
meta: Object.assign({ title: permission.title, icon: permission.icon, hidden: permission.hidden, is_inner: permission.is_inner }),
})
// child menu
const children = this.getAsnycMenus(permissions, permission.id, menu.path)
if (children.length > 0) {
menu.children = children
}
menus.push(menu)
}
})
return menus
},
/**
* transform routes to menus
* @param routes
* @param path
* @returns
*/
transformRoutesToMenus(routes: Menu[] | Array<RouteRecordRaw>, path: string = ''): Menu[] {
const menus: Menu[] = []
routes.forEach(route => {
if (route.meta?.hidden) {
return false
}
const menu: Menu = Object.assign({
path: this.resoulveRoutePath(route.path, path),
name: route.name,
meta: route.meta,
component: route.component,
})
if (route.children?.length) {
menu.children = this.transformRoutesToMenus(route.children, menu.path)
}
menus.push(menu)
})
return menus
},
/**
* resoulve route path
* @param route
* @param path
* @returns
*/
resoulveRoutePath(route: string, path: string): string {
if (path.length) {
return (path + (route.indexOf('/') === -1 ? '/' : '') + route).replace(/\/$/g, '')
}
// 去除尾部的 /
return route.replace(/\/$/g, '')
},
},
})