0
点赞
收藏
分享

微信扫一扫

Vue element admin 直接输入path 权限过滤

菜单权限
store\modules\permisstion.ts -> generateRoutes()

按钮权限
directive\permission\index.ts

路由权限
plugins\permission.ts

permission.ts 修改如下

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", "/datav"];

  const constantPathList = ["/redirect", "/dashboard", "/401", "/404", "/profile", "/myNotice"];

  router.beforeEach(async (to, from, next) => {
    // 开始进度条
    NProgress.start();

    const isLogin = !!getAccessToken(); // 判断是否登录
    if (isLogin) {
      if (to.path === "/login") {
        // 已登录,访问登录页,跳转到首页
        next({ path: "/" });
      } else {
        const permissionStore = usePermissionStore();
        //console.log("permissionStore", permissionStore);
        // 判断路由是否加载完成
        if (permissionStore.isRoutesLoaded) {
          if (to.matched.length === 0) {
            // 路由未匹配,跳转到404
            console.log("Route 加载完成后,路由未匹配 => ", to.path);
            next("/404");
          } else if (whiteList.includes(to.path)) {
            console.log("Route 加载完成后,白名单 => ", to.path);
            next();
          } else {
            const routeExists = constantPathList.some((path) => to.path.includes(path));
            if (!routeExists) {
              //有权限的 + 白名单 = 可访问
              //console.log("Route 加载【后】 => ", to.path);
              permissionCheck(permissionStore, to, next);
            }
            // 动态设置页面标题
            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();
            const routeExists = constantPathList.some((path) => to.path.includes(path));
            if (!routeExists) {
              //有权限的 + 白名单 = 可访问
              //console.log("Route 加载【前】 => ", to.path);
              permissionCheck(permissionStore, to, next);
            }

            // console.log("dynamicRoutes", dynamicRoutes);
            // console.log("router", router);
            dynamicRoutes.forEach((route: RouteRecordRaw) => {
              //console.log("route", route);
              router.addRoute(route);
            });
            // console.log("router", router);
            // console.log("to", to);
            next({ ...to, replace: true });
          } catch (error) {
            console.error(error);
            // 路由加载失败,重置 token 并重定向到登录页
            await useUserStore().clearUserData();
            redirectToLogin(to, next);
            NProgress.done();
          }
        }
      }
    } else {
      // 未登录,判断是否在白名单中
      if (whiteList.includes(to.path)) {
        next();
      } else {
        // 不在白名单,重定向到登录页
        redirectToLogin(to, next);
        NProgress.done();
      }
    }
  });

  // 后置守卫,保证每次路由跳转结束时关闭进度条
  router.afterEach(() => {
    NProgress.done();
  });
}

function permissionCheck(permissionStore: any, to: any, next: NavigationGuardNext) {
  console.log("permissionStore.routes", permissionStore.routes);
  let found = false;
  permissionStore.routes.forEach((route: RouteRecordRaw) => {
    console.log("permissionStore.route", route.path);
    if (to.path.includes(route.path) && route.path != "/") {
      console.log("to.path => ", to.path);
      console.log("route.path => ", route.path);
      found = true;
    }
  });
  if (!found) {
    console.log("无权 => ", to.path);
    next("/401");
  }
}

// 重定向到登录页
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));
}

console.log("to", to.path);
let found = false;
permissionStore.routes.forEach((route: RouteRecordRaw) => {
  console.log("permissionStore.route", route.path);
  if (route.path.includes(to.path)) {
    found = true;
  }
});

if (!found) {
  next("/404");
}

不能用 some 优化,优化后值就变少了

console.log("to", to.path);
const routeExists = permissionStore.routes.some((route: RouteRecordRaw) => {
  console.log("permissionStore.route", route.path);
  return route.path.includes(to.path);
});

if (!routeExists) {
  next("/404");
}


举报

相关推荐

0 条评论