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);