长城汽车软件包管理平台
whychdw
2025-04-26 be81587ef4c7a1711884d7ca8f27cbf85e2d7558
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import type { NavigationGuardNext, RouteLocationNormalized, RouteRecordRaw } from "vue-router";
import NProgress from "@/utils/nprogress";
import { getAccessToken } from "@/utils/auth";
import router from "@/router";
import { usePermissionStore, useUserStore } from "@/store";
 
export function setupPermission() {
  // 白名单路由
  const whiteList = ["/login"];
 
  router.beforeEach(async (to, from, next) => {
    NProgress.start();
 
    const isLogin = !!getAccessToken(); // 判断是否登录
    if (isLogin) {
      if (to.path === "/login") {
        // 已登录,访问登录页,跳转到首页
        next({ path: "/" });
      } else {
        const permissionStore = usePermissionStore();
        // 判断路由是否加载完成
        if (permissionStore.isRoutesLoaded) {
          if (to.matched.length === 0) {
            // 路由未匹配,跳转到404
            next("/404");
          } else {
            // 动态设置页面标题
            const title = (to.params.title as string) || (to.query.title as string);
            if (title) {
              to.meta.title = title;
            }
            next();
          }
        } else {
          try {
            // 生成动态路由
            const dynamicRoutes = await permissionStore.generateRoutes();
            dynamicRoutes.forEach((route: RouteRecordRaw) => router.addRoute(route));
            next({ ...to, replace: true });
          } catch (error) {
            console.error(error);
            // 路由加载失败,重置 token 并重定向到登录页
            await useUserStore().clearSessionAndCache();
            redirectToLogin(to, next);
            NProgress.done();
          }
        }
      }
    } else {
      // 未登录,判断是否在白名单中
      if (whiteList.includes(to.path)) {
        next();
      } else {
        // 不在白名单,重定向到登录页
        redirectToLogin(to, next);
        NProgress.done();
      }
    }
  });
 
  // 后置守卫,保证每次路由跳转结束时关闭进度条
  router.afterEach(() => {
    NProgress.done();
  });
}
 
// 重定向到登录页
function redirectToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) {
  const params = new URLSearchParams(to.query as Record<string, string>);
  const queryString = params.toString();
  const redirect = queryString ? `${to.path}?${queryString}` : to.path;
  next(`/login?redirect=${encodeURIComponent(redirect)}`);
}
 
/** 判断是否有权限 */
export function hasAuth(value: string | string[], type: "button" | "role" = "button") {
  const { roles, perms } = useUserStore().userInfo;
 
  // 超级管理员 拥有所有权限
  if (type === "button" && roles.includes("ROOT")) {
    return true;
  }
 
  const auths = type === "button" ? perms : roles;
  return typeof value === "string"
    ? auths.includes(value)
    : value.some((perm) => auths.includes(perm));
}