Files
vue3-element-admin/src/store/modules/permission.ts
haoxr c68479e3bb refactor: 路由代码优化和完善注释
Former-commit-id: 859d3b74927b032ad265170d6e6ffd821b3fa0d3
2023-02-11 10:41:07 +08:00

100 lines
2.7 KiB
TypeScript

import { RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia';
import { constantRoutes } from '@/router';
import { store } from '@/store';
import { listRoutes } from '@/api/menu';
const modules = import.meta.glob('../../views/**/**.vue');
const Layout = () => import('@/layout/index.vue');
/**
* Use meta.role to determine if the current user has permission
*
* @param roles 用户角色集合
* @param route 路由
* @returns
*/
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
if (route.meta && route.meta.roles) {
// 角色【超级管理员】拥有所有权限,忽略校验
if (roles.includes('ROOT')) {
return true;
}
return roles.some(role => {
if (route.meta?.roles !== undefined) {
return (route.meta.roles as string[]).includes(role);
}
});
}
return false;
};
/**
* 递归过滤有权限的异步(动态)路由
*
* @param routes 接口返回的异步(动态)路由
* @param roles 用户角色集合
* @returns 返回用户有权限的异步(动态)路由
*/
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
const asyncRoutes: RouteRecordRaw[] = [];
routes.forEach(route => {
const tmpRoute = { ...route }; // ES6扩展运算符复制新对象
// 判断用户(角色)是否有该路由的访问权限
if (hasPermission(roles, tmpRoute)) {
if (tmpRoute.component?.toString() == 'Layout') {
tmpRoute.component = Layout;
console.log();
} else {
const component = modules[`../../views/${tmpRoute.component}.vue`];
if (component) {
tmpRoute.component = component;
} else {
tmpRoute.component = modules[`../../views/error-page/404.vue`];
}
}
if (tmpRoute.children) {
tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles);
}
asyncRoutes.push(tmpRoute);
}
});
return asyncRoutes;
};
// setup
export const usePermissionStore = defineStore('permission', () => {
// state
const routes = ref<RouteRecordRaw[]>([]);
// actions
function setRoutes(newRoutes: RouteRecordRaw[]) {
routes.value = constantRoutes.concat(newRoutes);
}
function generateRoutes(roles: string[]) {
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
listRoutes()
.then(({ data: asyncRoutes }) => {
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
setRoutes(accessedRoutes);
resolve(accessedRoutes);
})
.catch(error => {
reject(error);
});
});
}
return { routes, setRoutes, generateRoutes };
});
// 非setup
export function usePermissionStoreHook() {
return usePermissionStore(store);
}