Files
vue3-element-admin/src/plugins/permission.ts
2025-12-11 21:19:02 +08:00

83 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { RouteRecordRaw } from "vue-router";
import NProgress from "@/utils/nprogress";
import router from "@/router";
import { usePermissionStore, useUserStore } from "@/store";
import { useTenantStoreHook } from "@/store/modules/tenant-store";
export function setupPermission() {
const whiteList = ["/login"];
router.beforeEach(async (to, from, next) => {
NProgress.start();
try {
const isLoggedIn = useUserStore().isLoggedIn();
// 未登录处理
if (!isLoggedIn) {
if (whiteList.includes(to.path)) {
next();
} else {
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`);
NProgress.done();
}
return;
}
// 已登录登录页重定向
if (to.path === "/login") {
next({ path: "/" });
return;
}
const permissionStore = usePermissionStore();
const userStore = useUserStore();
// 动态路由生成
if (!permissionStore.isRouteGenerated) {
if (!userStore.userInfo?.roles?.length) {
await userStore.getUserInfo();
}
// 登录成功后,尝试获取租户列表和当前租户信息(如果启用多租户)
// 最小侵入:如果接口失败,不影响正常流程(可能是单租户模式)
const tenantStore = useTenantStoreHook();
// 由 tenantStore 内部自行判断前端多租户开关VITE_APP_TENANT_ENABLED
await tenantStore.prepareTenantContextAfterLogin();
const dynamicRoutes = await permissionStore.generateRoutes();
dynamicRoutes.forEach((route: RouteRecordRaw) => {
router.addRoute(route);
});
next({ ...to, replace: true });
return;
}
// 路由404检查
if (to.matched.length === 0) {
next("/404");
return;
}
// 动态标题设置
const title = (to.params.title as string) || (to.query.title as string);
if (title) {
to.meta.title = title;
}
next();
} catch (error) {
// 错误处理:重置状态并跳转登录
console.error("Route guard error:", error);
await useUserStore().resetAllState();
next("/login");
NProgress.done();
}
});
router.afterEach(() => {
NProgress.done();
});
}