From 0288e975dc32b7ed58f81fa881a6d11d8a4c36e8 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Tue, 19 Nov 2024 13:02:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20:sparkles:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9D=83=E9=99=90=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=EF=BC=8C=E5=B7=A5=E4=BD=9C=E5=8F=B0=E6=A8=A1=E5=9D=97=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=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 --- src/api/system/user.ts | 4 +- src/directive/index.ts | 10 +++++ src/directive/permission/index.ts | 69 +++++++++++++++++++++++++++++++ src/main.ts | 4 +- src/pages/work/index.vue | 22 ++++------ src/plugins/index.ts | 9 ++++ src/store/modules/user.ts | 4 +- 7 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 src/directive/index.ts create mode 100644 src/directive/permission/index.ts create mode 100644 src/plugins/index.ts diff --git a/src/api/system/user.ts b/src/api/system/user.ts index bd1c15f..f70a4db 100644 --- a/src/api/system/user.ts +++ b/src/api/system/user.ts @@ -153,10 +153,10 @@ export interface UserInfo { avatar?: string; /** 角色 */ - roles: string[]; + roles?: string[]; /** 权限 */ - perms: string[]; + perms?: string[]; } /** diff --git a/src/directive/index.ts b/src/directive/index.ts new file mode 100644 index 0000000..72de857 --- /dev/null +++ b/src/directive/index.ts @@ -0,0 +1,10 @@ +import type { App } from "vue"; + +import { hasPerm, hasRole } from "./permission"; + +// 全局注册 directive +export function setupDirective(app: App) { + // 使 v-hasPerm 在所有组件中都可用 + app.directive("hasPerm", hasPerm); + app.directive("hasRole", hasRole); +} diff --git a/src/directive/permission/index.ts b/src/directive/permission/index.ts new file mode 100644 index 0000000..cdeb15c --- /dev/null +++ b/src/directive/permission/index.ts @@ -0,0 +1,69 @@ +import type { Directive, DirectiveBinding } from "vue"; + +import { useUserStore } from "@/store"; + +/** + * 按钮权限 + */ +export const hasPerm: Directive = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + const requiredPerms = binding.value; + + console.log("requiredPerms", requiredPerms); + if (!requiredPerms) { + return; + } + + // 校验传入的权限值是否合法 + if (!requiredPerms || (typeof requiredPerms !== "string" && !Array.isArray(requiredPerms))) { + throw new Error( + "需要提供权限标识!例如:v-has-perm=\"'sys:user:add'\" 或 v-has-perm=\"['sys:user:add', 'sys:user:edit']\"" + ); + } + + const { roles = [], perms = [] } = useUserStore().userInfo || {}; + + // 超级管理员拥有所有权限 + if (roles?.includes("ROOT")) { + return; + } + + // 检查权限 + const hasAuth = Array.isArray(requiredPerms) + ? requiredPerms.some((perm) => perms.includes(perm)) + : perms.includes(requiredPerms); + + // 如果没有权限,移除该元素 + if (!hasAuth && el.parentNode) { + el.parentNode.removeChild(el); + } + }, +}; + +/** + * 角色权限指令 + */ +export const hasRole: Directive = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + const requiredRoles = binding.value; + + // 校验传入的角色值是否合法 + if (!requiredRoles || (typeof requiredRoles !== "string" && !Array.isArray(requiredRoles))) { + throw new Error( + "需要提供角色标识!例如:v-has-role=\"'ADMIN'\" 或 v-has-role=\"['ADMIN', 'TEST']\"" + ); + } + + const { roles = [] } = useUserStore().userInfo || {}; + + // 检查是否有对应角色权限 + const hasAuth = Array.isArray(requiredRoles) + ? requiredRoles.some((role) => roles.includes(role)) + : roles.includes(requiredRoles); + + // 如果没有权限,移除元素 + if (!hasAuth && el.parentNode) { + el.parentNode.removeChild(el); + } + }, +}; diff --git a/src/main.ts b/src/main.ts index a9353bc..5763cc7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,7 @@ import { createSSRApp } from "vue"; import App from "./App.vue"; +import setupPlugins from "@/plugins"; + import "uno.css"; import { setupStore } from "@/store"; @@ -8,7 +10,7 @@ export function createApp() { const app = createSSRApp(App); setupStore(app); - + app.use(setupPlugins); return { app, }; diff --git a/src/pages/work/index.vue b/src/pages/work/index.vue index 03b9e17..313dc88 100644 --- a/src/pages/work/index.vue +++ b/src/pages/work/index.vue @@ -6,6 +6,7 @@ ) { + // 自定义指令(directive) + setupDirective(app); + }, +}; diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index f12d133..952b0d8 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -4,7 +4,7 @@ import UserAPI, { type UserInfo } from "@/api/system/user"; import { setToken, getUserInfo, setUserInfo, clearAll } from "@/utils/cache"; export const useUserStore = defineStore("user", () => { - const userInfo = ref(getUserInfo()); + const userInfo = ref(getUserInfo()); // 登录 const login = (data: LoginFormData) => { @@ -45,7 +45,7 @@ export const useUserStore = defineStore("user", () => { console.error("登出失败", error); } finally { clearAll(); // 清除本地的 token 和用户信息缓存 - userInfo.value = null; // 清空用户信息 + userInfo.value = undefined; // 清空用户信息 } };