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 [] +} +