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([]); // actions function setRoutes(newRoutes: RouteRecordRaw[]) { routes.value = constantRoutes.concat(newRoutes); } /** * 生成动态路由 * * @param roles 用户角色集合 * @returns */ function generateRoutes(roles: string[]) { return new Promise((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); }