From 7cca4064782ced1a09cd2840a225824f4d39c6d9 Mon Sep 17 00:00:00 2001 From: WindowBird <13870814+windows-bird@user.noreply.gitee.com> Date: Wed, 26 Nov 2025 17:47:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=83=E9=99=90=E5=B8=B8=E9=87=8F=E5=92=8Cno?= =?UTF-8?q?rmalize=E6=9D=83=E9=99=90=E5=88=97=E8=A1=A8=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=8A=BD=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- directives/permission.js | 160 ++++++++++++++++----------------------- store/user.js | 18 +---- utils/permission.js | 17 +++++ 3 files changed, 85 insertions(+), 110 deletions(-) create mode 100644 utils/permission.js diff --git a/directives/permission.js b/directives/permission.js index 2357601..050d740 100644 --- a/directives/permission.js +++ b/directives/permission.js @@ -1,123 +1,97 @@ import { useUserStore } from '@/store/user' - -const ADMIN_ROLES = ['admin', 'sys_admin'] - -const normalizePermissionList = (permissions) => { - if (!permissions) return [] - if (Array.isArray(permissions)) return permissions.filter(Boolean) - if (typeof permissions === 'object') { - return Object.keys(permissions).filter(key => !!permissions[key]) - } - if (typeof permissions === 'string') { - return permissions - .split(',') - .map((perm) => perm.trim()) - .filter(Boolean) - - - - - - - - - - - } - return [] -} +import { ADMIN_ROLES, normalizePermissions } from '@/utils/permission' const resolveRequiredPermissions = (value) => { - if (!value) return [] - if (Array.isArray(value)) return value.filter(Boolean) - if (typeof value === 'string') { - return value - .split(',') - .map((item) => item.trim()) - .filter(Boolean) - } - return [] + if (!value) return [] + if (Array.isArray(value)) return value.filter(Boolean) + if (typeof value === 'string') { + return value + .split(',') + .map((item) => item.trim()) + .filter(Boolean) + } + return [] } const evaluatePermission = (userStore, requiredPermissions, modifiers = {}) => { - if (!userStore) return false - const { requireAll = modifiers.all } = modifiers - const permissionsToCheck = resolveRequiredPermissions(requiredPermissions) - if (permissionsToCheck.length === 0) return true + if (!userStore) return false + const {requireAll = modifiers.all} = modifiers + const permissionsToCheck = resolveRequiredPermissions(requiredPermissions) + if (permissionsToCheck.length === 0) return true - const userInfo = userStore.userInfo - const userRoles = userInfo?.roles || [] - const isAdmin = Array.isArray(userRoles) && userRoles.some((role) => ADMIN_ROLES.includes(role)) - if (isAdmin) return true + const userInfo = userStore.userInfo + const userRoles = userInfo?.roles || [] + const isAdmin = Array.isArray(userRoles) && userRoles.some((role) => ADMIN_ROLES.includes(role)) + if (isAdmin) return true - const userPermissions = normalizePermissionList(userInfo?.permissions) - if (userPermissions.length === 0) return false + const userPermissions = normalizePermissions(userInfo?.permissions) + if (userPermissions.length === 0) return false - if (requireAll) { - return permissionsToCheck.every((permission) => userPermissions.includes(permission)) - } + if (requireAll) { + return permissionsToCheck.every((permission) => userPermissions.includes(permission)) + } - return permissionsToCheck.some((permission) => userPermissions.includes(permission)) + return permissionsToCheck.some((permission) => userPermissions.includes(permission)) } const getUserStore = (binding, vnode) => { - const piniaInstance = - binding?.instance?.proxy?.$pinia || - binding?.instance?.appContext?.app?.$pinia || - vnode?.context?.$pinia || - binding?.instance?.appContext?.appContext?.provides?.pinia + const piniaInstance = + binding?.instance?.proxy?.$pinia || + binding?.instance?.appContext?.app?.$pinia || + vnode?.context?.$pinia || + binding?.instance?.appContext?.appContext?.provides?.pinia - try { - if (piniaInstance) { - return useUserStore(piniaInstance) + try { + if (piniaInstance) { + return useUserStore(piniaInstance) + } + return useUserStore() + } catch (error) { + console.warn('[v-permission] failed to access pinia instance:', error) + return null } - return useUserStore() - } catch (error) { - console.warn('[v-permission] failed to access pinia instance:', error) - return null - } } const toggleElementVisibility = (el, shouldShow) => { - if (shouldShow) { - el.style.display = el.__vOriginalDisplay || '' - } else { - if (el.style.display !== 'none') { - el.__vOriginalDisplay = el.style.display + if (shouldShow) { + el.style.display = el.__vOriginalDisplay || '' + } else { + if (el.style.display !== 'none') { + el.__vOriginalDisplay = el.style.display + } + el.style.display = 'none' } - el.style.display = 'none' - } - el.__vPermissionVisible = shouldShow + el.__vPermissionVisible = shouldShow } const handleDirective = (el, binding, vnode) => { - const userStore = getUserStore(binding, vnode) - const shouldShow = evaluatePermission(userStore, binding.value, binding.modifiers) - toggleElementVisibility(el, shouldShow) + const userStore = getUserStore(binding, vnode) + const shouldShow = evaluatePermission(userStore, binding.value, binding.modifiers) + toggleElementVisibility(el, shouldShow) } export const registerPermissionDirective = (appOrVue) => { - if (!appOrVue) return + if (!appOrVue) return - const directiveConfig = { - mounted: handleDirective, - updated: handleDirective, - beforeMount: handleDirective, - beforeUpdate: handleDirective - } + const directiveConfig = { + mounted: handleDirective, + updated: handleDirective, + beforeMount: handleDirective, + beforeUpdate: handleDirective + } - if (typeof appOrVue.directive === 'function') { - // Vue3 - appOrVue.directive('permission', directiveConfig) - } else if (typeof appOrVue.prototype?.directive === 'function' || typeof appOrVue.directive === 'function') { - // Vue2 global Vue constructor - const VueCtor = appOrVue.prototype?.constructor || appOrVue - VueCtor.directive('permission', { - inserted: handleDirective, - update: handleDirective, - componentUpdated: handleDirective - }) - } + if (typeof appOrVue.directive === 'function') { + // Vue3 + appOrVue.directive('permission', directiveConfig) + } else if (typeof appOrVue.prototype?.directive === 'function' || typeof appOrVue.directive === 'function') { + // Vue2 global Vue constructor + const VueCtor = appOrVue.prototype?.constructor || appOrVue + VueCtor.directive('permission', { + inserted: handleDirective, + update: handleDirective, + componentUpdated: handleDirective + }) + } } export default registerPermissionDirective diff --git a/store/user.js b/store/user.js index 943c788..eb114cd 100644 --- a/store/user.js +++ b/store/user.js @@ -1,21 +1,5 @@ import { defineStore } from 'pinia' - -const ADMIN_ROLES = ['admin', 'sys_admin'] - -const normalizePermissions = (permissions) => { - if (!permissions) return [] - if (Array.isArray(permissions)) return permissions.filter(Boolean) - if (typeof permissions === 'object') { - return Object.keys(permissions).filter(key => !!permissions[key]) - } - if (typeof permissions === 'string') { - return permissions - .split(',') - .map((perm) => perm.trim()) - .filter(Boolean) - } - return [] -} +import { ADMIN_ROLES, normalizePermissions } from '@/utils/permission' /** * 用户信息 Store diff --git a/utils/permission.js b/utils/permission.js new file mode 100644 index 0000000..8062951 --- /dev/null +++ b/utils/permission.js @@ -0,0 +1,17 @@ +export const ADMIN_ROLES = ['admin', 'sys_admin'] + +export const normalizePermissions = (permissions) => { + if (!permissions) return [] + if (Array.isArray(permissions)) return permissions.filter(Boolean) + if (typeof permissions === 'object') { + return Object.values(permissions).filter((perm) => !!perm) + } + if (typeof permissions === 'string') { + return permissions + .split(',') + .map((perm) => perm.trim()) + .filter(Boolean) + } + return [] +} +