From 8aa1f313af60ed03cb79a1bee475af6d93a130f3 Mon Sep 17 00:00:00 2001 From: meowrain Date: Sat, 15 Nov 2025 20:11:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(access):=20=E5=AE=9E=E7=8E=B0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E7=94=A8=E6=88=B7=E8=A7=92=E8=89=B2=E7=9A=84=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加权限检查功能,包括用户角色定义、路由元信息扩展和权限验证逻辑 重构路由配置和用户存储,支持动态菜单过滤 更新构建配置以支持类型声明生成 --- package.json | 4 ++- src/access/checkAccess.ts | 37 +++++++++++++++++++++++ src/access/index.ts | 6 ++++ src/components/GlobalHeader.vue | 53 ++++++++++++++++++++++----------- src/router/index.ts | 21 ++++++++++--- src/store/index.ts | 0 src/store/types.d.ts | 5 ++++ src/store/user.ts | 27 +++++++++++++++-- src/types/router.d.ts | 12 ++++++++ tsconfig.app.json | 3 ++ 10 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 src/access/checkAccess.ts create mode 100644 src/access/index.ts delete mode 100644 src/store/index.ts create mode 100644 src/store/types.d.ts create mode 100644 src/types/router.d.ts diff --git a/package.json b/package.json index 67def2f..d4377cb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "build": "vue-tsc -b && vite build --mode dev", "build:prod": "vue-tsc -b && vite build --mode prod", "preview": "vite preview", - "lint": "eslint . --ext .ts,.vue" + "lint": "eslint . --ext .ts,.vue", + "type-check": "vue-tsc --noEmit", + "build:types": "vue-tsc --declaration --emitDeclarationOnly" }, "dependencies": { "@arco-design/web-vue": "^2.57.0", diff --git a/src/access/checkAccess.ts b/src/access/checkAccess.ts new file mode 100644 index 0000000..048e126 --- /dev/null +++ b/src/access/checkAccess.ts @@ -0,0 +1,37 @@ +import type { LoginUesr } from "../store/types"; +import ACCESS_ENUM from "./accessEnum"; + +/** + * 检查当前用户是否拥有权限 + * @param loginUser 登录的用户信息 + * @param needAccess 需要的权限 + * @returns {boolean} + */ +const checkAccess = ( + loginUser: LoginUesr, + needAccess = ACCESS_ENUM.NOT_LOGIN +): boolean => { + // 获取当前登录用户具有的权限 + const loginUserAccess = loginUser?.userRole ?? ACCESS_ENUM.NOT_LOGIN; + // 对比权限是否足够 + // 如果需要的权限是随便是个人都能访问 + if (needAccess === ACCESS_ENUM.NOT_LOGIN) { + return true; + } + // 如果用户登录才能访问 + if (needAccess === ACCESS_ENUM.USER) { + if (loginUserAccess !== ACCESS_ENUM.NOT_LOGIN) { + return false; + } + } + // 如果需要管理员权限 + if (needAccess === ACCESS_ENUM.ADMIN) { + // 如果不为管理员 + if (loginUserAccess !== ACCESS_ENUM.ADMIN) { + return false; + } + } + // 如果说啥都不符合,那还说啥了,直接拒了 + return false; +}; +export default checkAccess; diff --git a/src/access/index.ts b/src/access/index.ts new file mode 100644 index 0000000..c981526 --- /dev/null +++ b/src/access/index.ts @@ -0,0 +1,6 @@ +import router from "../router/router"; +import { useUserStore } from "../store/user"; +import ACCESS_ENUM from "./accessEnum"; +import checkAccess from "./checkAccess"; + + diff --git a/src/components/GlobalHeader.vue b/src/components/GlobalHeader.vue index b30cc02..9acf94c 100644 --- a/src/components/GlobalHeader.vue +++ b/src/components/GlobalHeader.vue @@ -1,9 +1,16 @@ \ No newline at end of file + diff --git a/src/router/index.ts b/src/router/index.ts index dd3d81d..efa13fd 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,8 +1,21 @@ -import type {RouteRecordRaw} from "vue-router"; +import type { RouteRecordRaw } from "vue-router"; import HomeView from "../views/HomeView.vue"; import AboutView from "../views/AboutView.vue"; - +import ACCESS_ENUM from "../access/accessEnum"; +/** + * 路由配置 + */ export const routes: Array = [ - {path: "/home", name: "HomeView", component: HomeView}, - {path: "/about", name: "AboutView", component: AboutView}, + { + path: "/home", + name: "HomeView", + component: HomeView, + meta: { hideInMenu: false, access: ACCESS_ENUM.NOT_LOGIN }, + }, + { + path: "/about", + name: "AboutView", + component: AboutView, + meta: { hideInMenu: false, access: ACCESS_ENUM.NOT_LOGIN }, + }, ]; diff --git a/src/store/index.ts b/src/store/index.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/store/types.d.ts b/src/store/types.d.ts new file mode 100644 index 0000000..c2277ea --- /dev/null +++ b/src/store/types.d.ts @@ -0,0 +1,5 @@ + +export interface LoginUesr { + userName: string; + userRole?: string; +} \ No newline at end of file diff --git a/src/store/user.ts b/src/store/user.ts index 9e2715f..922c7af 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,11 +1,34 @@ import { defineStore } from "pinia"; import ACCESS_ENUM from "../access/accessEnum"; +import type { LoginUesr } from "../store/types"; +/** + * + */ export const useUserStore = defineStore("user", { state: () => ({ loginUser: { userName: "未登录", userRole: ACCESS_ENUM.NOT_LOGIN, - }, + } as LoginUesr, }), - actions: {}, + actions: { + // 获取登录用户 + async getLoginUser() { + try { + // 从后端获取当前登录用户信息 + + }catch(e) { + console.error("获取登录用户失败", e); + // 网络错误情况也视为未登录 + this.loginUser = { + ...this.loginUser, + userRole: ACCESS_ENUM.NOT_LOGIN, + }; + } + }, + // 手动更新用户状态 + updateUserLoginStatus(user: LoginUesr) { + this.loginUser = user; + } + }, }); diff --git a/src/types/router.d.ts b/src/types/router.d.ts new file mode 100644 index 0000000..7e9834c --- /dev/null +++ b/src/types/router.d.ts @@ -0,0 +1,12 @@ +// src/types/router.d.ts +import 'vue-router'; // 让 TypeScript 知道 vue-router 模块的类型定义 + +/** + * 路由元信息 + */ +declare module 'vue-router' { + interface RouteMeta { + hideInMenu?: boolean; + access?: string; + } +} \ No newline at end of file diff --git a/tsconfig.app.json b/tsconfig.app.json index 62042bf..b32ebbf 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,6 +1,9 @@ { "extends": "@vue/tsconfig/tsconfig.dom.json", "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": false, + "declarationDir": "./dist/types", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "types": [ "vite/client"