import { createRouter, createWebHashHistory } from "vue-router"; import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from "vue-router"; import routes from "./routes"; import { useDefaultStore } from "@/store"; import { UserRoleEnum } from "@/types"; const router = createRouter({ history: createWebHashHistory(), routes, }); /** * 当前角色是否可访问目标路由(meta.roles 未声明 = 登录即可访问)。 * 供路由守卫与 App.vue 角色落定后的复核共用。 */ export function isRouteAllowed( route: RouteLocationNormalizedLoaded | RouteRecordRaw, role: UserRoleEnum ): boolean { const roles = (route.meta?.roles ?? null) as UserRoleEnum[] | null; return !roles || roles.length === 0 || roles.includes(role); } /** * 路由守卫(防止直接敲 URL 绕过菜单): * - 角色未落定(roleLoaded=false,首次导航早于 App.vue 的 GetUserScope)时放行, * 由 App.vue 在角色落定后调用本守卫的复核逻辑重定向; * - 角色已落定后按 meta.roles 校验,不满足重定向 /no-auth。 */ router.beforeEach(to => { if (to.path === "/no-auth") { return true; } const store = useDefaultStore(); if (!store.roleLoaded) { return true; } if (!isRouteAllowed(to, store.userRole)) { return { path: "/no-auth", replace: true }; } return true; }); export default router;