diff --git a/src/directives/index.ts b/src/directives/index.ts index 4aca441..b096eda 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1,7 +1,8 @@ import { App } from "vue"; -import antiShake from "@/directives/modules/anti-shake"; -import throttle from "@/directives/modules/throttle"; -import custom from "@/directives/modules/custom"; +import antiShake from "@/directives/modules/global/anti-shake"; +import throttle from "@/directives/modules/global/throttle"; +import custom from "@/directives/modules/global/custom"; +import hasPerm from "@/directives/modules/permission/has-perm"; // 定义安装函数 // install 函数是一个对象中的方法,其作用是将一系列指令对象安装到 Vue 应用实例中,它自带两个参数:app 和 options @@ -13,6 +14,7 @@ const directives = { app.directive("antiShake", antiShake); app.directive("throttle", throttle); app.directive("custom", custom); + app.directive("hasPerm", hasPerm); } }; diff --git a/src/directives/modules/anti-shake.ts b/src/directives/modules/global/anti-shake.ts similarity index 100% rename from src/directives/modules/anti-shake.ts rename to src/directives/modules/global/anti-shake.ts diff --git a/src/directives/modules/custom.ts b/src/directives/modules/global/custom.ts similarity index 100% rename from src/directives/modules/custom.ts rename to src/directives/modules/global/custom.ts diff --git a/src/directives/modules/throttle.ts b/src/directives/modules/global/throttle.ts similarity index 100% rename from src/directives/modules/throttle.ts rename to src/directives/modules/global/throttle.ts diff --git a/src/directives/modules/permission/has-perm.ts b/src/directives/modules/permission/has-perm.ts new file mode 100644 index 0000000..47457e1 --- /dev/null +++ b/src/directives/modules/permission/has-perm.ts @@ -0,0 +1,57 @@ +import { Directive } from "vue"; +import { useUserInfoStore } from "@/store/modules/user-info"; + +/** + * 检测指令绑定值是否为空 + * @param value 指令绑定值 + * @returns {Array} 指令绑定值数组 + */ +const bindingValueEmpty = (value: unknown): Array => { + // 处理未定义或空值情况 + if (!value) throw new Error("v-permission 指令需要配置权限标识"); + + // 标准化为数组格式 + // 如果 value 是一个数组,则直接返回该数组 + // 如果 value 不是数组,则将其转换为包含单个字符串元素的数组 + return Array.isArray(value) ? (value as string[]) : [String(value)]; +}; + +/** + * 检查自定义指令权限 + * @param {HTMLElement} el dom元素 + * @param {unknown} bindingValue 指令绑定值 + */ +const checkPermissions = (el: HTMLElement, bindingValue: unknown) => { + try { + // 检测自定义指令并转化为数组格式 + const requiredPermissions = bindingValueEmpty(bindingValue); + + // 超级管理员标识 + const all_permission = "*:*:*"; + + // 获取用户权限标识-Array[string] + let { permissions } = useUserInfoStore().account; + + // 如果是超级管理员则放行 + if (permissions.includes(all_permission)) return; + + const hasPermissions = requiredPermissions.some((perm: string) => permissions.includes(perm)); + + // 无权限、父节点存在时 + if (!hasPermissions && el.parentNode) { + // 则删除当前子节点 + el.parentNode.removeChild(el); + } + } catch (error) { + console.error(`权限指令错误: ${error}`); + // 删除当前节点 + if (el.parentNode) el.parentNode.removeChild(el); + } +}; + +const hasPerm: Directive = { + mounted: (el, binding) => checkPermissions(el, binding.value), + updated: (el, binding) => checkPermissions(el, binding.value) +}; + +export default hasPerm; diff --git a/src/mock/_data/system_menu.ts b/src/mock/_data/system_menu.ts index 606e495..97df870 100644 --- a/src/mock/_data/system_menu.ts +++ b/src/mock/_data/system_menu.ts @@ -1474,7 +1474,7 @@ export const permissionData = [ hide: false, disable: false, roles: ["admin", "common"], - permission: "common:btn:delete", + permission: "common:btn:add", sort: 1, type: 3 } @@ -1487,7 +1487,7 @@ export const permissionData = [ hide: false, disable: false, roles: ["admin", "common"], - permission: "common:btn:delete", + permission: "common:btn:edit", sort: 2, type: 3 } diff --git a/src/views/permission/test1/test1.vue b/src/views/permission/test1/test1.vue index 73bdc99..b80c66d 100644 --- a/src/views/permission/test1/test1.vue +++ b/src/views/permission/test1/test1.vue @@ -13,11 +13,33 @@ 当前页面角色权限
- - 新增 - 编辑 - 删除 - + + + + + + + 权限按钮: + 新增 + 编辑 + 删除 + + + +
+ + + + + + + 权限按钮: + 新增 + 编辑 + 删除 + + + @@ -30,7 +52,18 @@ let userInfoStore = useUserInfoStore(); let { account } = storeToRefs(userInfoStore); const permissions = computed(() => JSON.stringify(account.value.permissions, null)); const pageRule = computed(() => JSON.stringify(route.meta.roles, null)); -console.log("权限数据", account.value); + +let sysBtn = ` + 新增 + 编辑 + 删除 +`; + +let commonBtn = ` + 新增 + 编辑 + 删除 +`; diff --git a/src/views/permission/test2/test2.vue b/src/views/permission/test2/test2.vue index c8c3681..7077d3a 100644 --- a/src/views/permission/test2/test2.vue +++ b/src/views/permission/test2/test2.vue @@ -2,22 +2,44 @@
- 当前页面为 + 当前页面 超级管理员 - 权限页面, - 普通角色 - 无法查看 + 和 + 普通角色 + 都可以查看 当前用户权限 - + 当前页面角色权限
- - 新增 - 编辑 - 删除 - + + + + + + + 权限按钮: + 新增 + 编辑 + 删除 + + + +
+ + + + + + + 权限按钮: + 新增 + 编辑 + 删除 + + +
@@ -28,9 +50,20 @@ import { useUserInfoStore } from "@/store/modules/user-info"; const route = useRoute(); let userInfoStore = useUserInfoStore(); let { account } = storeToRefs(userInfoStore); -const userPermissions = computed(() => JSON.stringify(account.value.permissions, null)); +const permissions = computed(() => JSON.stringify(account.value.permissions, null)); const pageRule = computed(() => JSON.stringify(route.meta.roles, null)); -console.log("权限数据", account.value); + +let sysBtn = ` + 新增 + 编辑 + 删除 +`; + +let commonBtn = ` + 新增 + 编辑 + 删除 +`;