From 097a3fabea5d5a6c5f57e9417159ecc661e45f7f Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Sat, 29 Jun 2024 15:22:24 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20:recycle:=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=8E=A5=E5=8F=A3=E7=A7=BB=E9=99=A4=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=8F=82=E6=95=B0=EF=BC=8C=E5=90=8E=E7=AB=AF=E4=BB=8E?= =?UTF-8?q?token=E8=A7=A3=E6=9E=90=E8=A7=92=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/menu.ts | 11 +++-- src/plugins/permission.ts | 73 ++++++++++++++++++--------------- src/store/modules/permission.ts | 4 +- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/api/menu.ts b/src/api/menu.ts index 528aff7e..4fff728f 100644 --- a/src/api/menu.ts +++ b/src/api/menu.ts @@ -4,16 +4,15 @@ const MENU_BASE_URL = "/api/v1/menus"; class MenuAPI { /** - * 获取路由列表 + * 获取当前用户的路由列表 + *

+ * 无需传入角色,后端解析token获取角色自行判断是否拥有路由的权限 * * @returns 路由列表 */ - static getRoutes(roles: string[]) { - const queryParams = roles - .map((role) => `roles=${encodeURIComponent(role)}`) - .join("&"); + static getRoutes() { return request({ - url: `${MENU_BASE_URL}/routes?${queryParams}`, + url: `${MENU_BASE_URL}/routes`, method: "get", }); } diff --git a/src/plugins/permission.ts b/src/plugins/permission.ts index e3bc46ff..f658a7ef 100644 --- a/src/plugins/permission.ts +++ b/src/plugins/permission.ts @@ -1,8 +1,13 @@ -import router from "@/router"; -import { useUserStore, usePermissionStore } from "@/store"; +import { + NavigationGuardNext, + RouteLocationNormalized, + RouteRecordRaw, +} from "vue-router"; + import NProgress from "@/utils/nprogress"; -import { RouteRecordRaw } from "vue-router"; import { TOKEN_KEY } from "@/enums/CacheEnum"; +import router from "@/router"; +import { usePermissionStore, useUserStore } from "@/store"; export function setupPermission() { // 白名单路由 @@ -11,19 +16,21 @@ export function setupPermission() { router.beforeEach(async (to, from, next) => { NProgress.start(); const hasToken = localStorage.getItem(TOKEN_KEY); + if (hasToken) { if (to.path === "/login") { - // 如果已登录,跳转首页 + // 如果已登录,跳转到首页 next({ path: "/" }); NProgress.done(); } else { const userStore = useUserStore(); const hasRoles = userStore.user.roles && userStore.user.roles.length > 0; + if (hasRoles) { - // 未匹配到任何路由,跳转404 + // 如果未匹配到任何路由,跳转到404页面 if (to.matched.length === 0) { - from.name ? next({ name: from.name }) : next("/404"); + next(from.name ? { name: from.name } : "/404"); } else { // 如果路由参数中有 title,覆盖路由元信息中的 title const title = @@ -31,45 +38,32 @@ export function setupPermission() { if (title) { to.meta.title = title; } - next(); } } else { const permissionStore = usePermissionStore(); try { - const { roles } = await userStore.getUserInfo(); - const accessRoutes = await permissionStore.generateRoutes(roles); - accessRoutes.forEach((route: RouteRecordRaw) => { - router.addRoute(route); - }); + await userStore.getUserInfo(); + const dynamicRoutes = await permissionStore.generateRoutes(); + dynamicRoutes.forEach((route: RouteRecordRaw) => + router.addRoute(route) + ); next({ ...to, replace: true }); } catch (error) { - // 移除 token 并跳转登录页 + // 移除 token 并重定向到登录页,携带当前页面路由作为跳转参数 await userStore.resetToken(); - // 重定向到登录页,并携带当前页面路由和参数,作为登录成功后跳转的页面 - const params = new URLSearchParams( - to.query as Record - ); - const queryString = params.toString(); - const redirect = queryString - ? `${to.path}?${queryString}` - : to.path; - next(`/login?redirect=${encodeURIComponent(redirect)}`); + redirectToLogin(to, next); NProgress.done(); } } } } else { // 未登录 - if (whiteList.indexOf(to.path) !== -1) { - // 在白名单,直接进入 - next(); + if (whiteList.includes(to.path)) { + next(); // 在白名单,直接进入 } else { // 不在白名单,重定向到登录页 - const params = new URLSearchParams(to.query as Record); - const queryString = params.toString(); - const redirect = queryString ? `${to.path}?${queryString}` : to.path; - next(`/login?redirect=${encodeURIComponent(redirect)}`); + redirectToLogin(to, next); NProgress.done(); } } @@ -80,20 +74,31 @@ export function setupPermission() { }); } -// 是否有权限 +/** 重定向到登录页 */ +function redirectToLogin( + to: RouteLocationNormalized, + next: NavigationGuardNext +) { + const params = new URLSearchParams(to.query as Record); + 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().user; - //「超级管理员」拥有所有的按钮权限 + + // 超级管理员 拥有所有权限 if (type === "button" && roles.includes("ROOT")) { return true; } + const auths = type === "button" ? perms : roles; return typeof value === "string" ? auths.includes(value) - : auths.some((perm) => { - return value.includes(perm); - }); + : value.some((perm) => auths.includes(perm)); } diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 5549e1a5..b756cab9 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -19,9 +19,9 @@ export const usePermissionStore = defineStore("permission", () => { /** * 生成动态路由 */ - function generateRoutes(roles: string[]) { + function generateRoutes() { return new Promise((resolve, reject) => { - MenuAPI.getRoutes(roles) + MenuAPI.getRoutes() .then((data) => { const dynamicRoutes = transformRoutes(data); routes.value = constantRoutes.concat(dynamicRoutes);