import { RouteRecordRaw } from "vue-router"; import { defineStore } from "pinia"; import { constantRoutes } from "@/router"; import { store } from "@/store"; const modules = import.meta.glob("../../views/**/**.vue"); // 不同角色,不同首页 const Layout = () => import("@/layout/school.vue"); const Admin = () => import("@/layout/admin.vue"); // 角色【后台管理员】拥有的权限路由 const schoolRoutes: RouteRecordRaw[] = JSON.parse( JSON.stringify([ { path: "/", component: "AdminIndex", redirect: "/area", children: [ { path: "area", component: "area/index", meta: { title: "区域级数据看板", icon: "homepage", keepAlive: true }, }, ], }, ]) ); // 角色【学校负责人】拥有的权限路由 const adminRoutes: RouteRecordRaw[] = JSON.parse( JSON.stringify([ { path: "/", component: "SchoolIndex", redirect: "/dashboard", children: [ { path: "dashboard", component: "dashboard", meta: { title: "数据看板", icon: "homepage", keepAlive: true }, }, { path: "class", component: "class", meta: { title: "班级管理", icon: "menu", keepAlive: true }, }, { path: "teacher", component: "teacher", meta: { title: "教师管理", icon: "menu", keepAlive: true }, }, { path: "student", component: "student", meta: { title: "学生管理", icon: "menu", keepAlive: true }, }, { path: "equipment", component: "equipment", meta: { title: "设备管理", icon: "menu", keepAlive: true }, }, { path: "training", component: "training", meta: { title: "训练管理", icon: "menu", keepAlive: true }, }, { path: "board", component: "board", meta: { title: "测评数据看板", icon: "menu", keepAlive: true }, }, ], }, ]) ); /** * 递归过滤有权限的异步(动态)路由 * * @param routes 接口返回的异步(动态)路由 * @param roles 用户角色集合 * @returns 返回用户有权限的异步(动态)路由 */ const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => { const asyncRoutes: RouteRecordRaw[] = []; routes.forEach((route) => { const tmpRoute = { ...route }; // ES6扩展运算符复制新对象 if (tmpRoute.component?.toString() == "SchoolIndex") { tmpRoute.component = Layout; console.log("SchoolIndex"); } else if (tmpRoute.component?.toString() == "AdminIndex") { console.log("AdminIndex"); } else { const component = modules[`../../views/${tmpRoute.component}/index.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) => { // 角色【后台管理员】拥有权限 if (roles.includes("ADMIN")) { // 根据角色获取有访问权限的路由 const accessedRoutes = filterAsyncRoutes(adminRoutes, roles); setRoutes(accessedRoutes); resolve(accessedRoutes); } // 角色【学校负责人】拥有权限 else if (roles.includes("SCHOOL")) { const accessedRoutes = filterAsyncRoutes(schoolRoutes, roles); setRoutes(accessedRoutes); resolve(accessedRoutes); } else { reject("没有访问权限"); } }); } return { routes, setRoutes, generateRoutes }; }); // 非setup export function usePermissionStoreHook() { return usePermissionStore(store); }