feat(permissions): 完善权限检查和指令功能

- 扩展超级管理员标识符支持多种格式
- 修复权限指令使用display:none而非删除元素
- 增强按钮权限检查逻辑
- 优化权限检查的实时性和准确性
This commit is contained in:
Leo 2025-07-07 01:13:29 +08:00
parent b29e59be08
commit 7fd43755d7
2 changed files with 152 additions and 20 deletions

View File

@ -2,23 +2,88 @@ import type { App, Directive } from 'vue'
import { usePermission } from '@/hooks' import { usePermission } from '@/hooks'
export function install(app: App) { export function install(app: App) {
const { hasPermission } = usePermission() // 角色权限指令
function updateRolePermission(el: HTMLElement, permission: Entity.RoleType | Entity.RoleType[]) {
function updatapermission(el: HTMLElement, permission: Entity.RoleType | Entity.RoleType[]) {
if (!permission) if (!permission)
throw new Error('v-permissson Directive with no explicit role attached') throw new Error('v-role Directive with no explicit role attached')
if (!hasPermission(permission)) // 每次检查时重新获取权限函数,确保使用最新的用户状态
el.parentElement?.removeChild(el) const { hasRole } = usePermission()
// 使用显示/隐藏而不是删除元素
if (hasRole(permission)) {
el.style.display = ''
}
else {
el.style.display = 'none'
}
} }
const permissionDirective: Directive<HTMLElement, Entity.RoleType | Entity.RoleType[]> = { // 按钮权限指令
function updateButtonPermission(el: HTMLElement, permission: string | string[]) {
if (!permission)
throw new Error('v-button Directive with no explicit permission attached')
// 每次检查时重新获取权限函数,确保使用最新的用户状态
const { hasButton } = usePermission()
// 使用显示/隐藏而不是删除元素
if (hasButton(permission)) {
el.style.display = ''
}
else {
el.style.display = 'none'
}
}
// 通用权限指令(向后兼容)
function updatePermission(el: HTMLElement, permission: Entity.RoleType | Entity.RoleType[]) {
if (!permission)
throw new Error('v-permission Directive with no explicit role attached')
// 每次检查时重新获取权限函数,确保使用最新的用户状态
const { hasPermission } = usePermission()
// 使用显示/隐藏而不是删除元素
if (hasPermission(permission)) {
el.style.display = ''
}
else {
el.style.display = 'none'
}
}
// 角色权限指令
const roleDirective: Directive<HTMLElement, Entity.RoleType | Entity.RoleType[]> = {
mounted(el, binding) { mounted(el, binding) {
updatapermission(el, binding.value) updateRolePermission(el, binding.value)
}, },
updated(el, binding) { updated(el, binding) {
updatapermission(el, binding.value) updateRolePermission(el, binding.value)
}, },
} }
// 按钮权限指令
const buttonDirective: Directive<HTMLElement, string | string[]> = {
mounted(el, binding) {
updateButtonPermission(el, binding.value)
},
updated(el, binding) {
updateButtonPermission(el, binding.value)
},
}
// 通用权限指令(向后兼容)
const permissionDirective: Directive<HTMLElement, Entity.RoleType | Entity.RoleType[]> = {
mounted(el, binding) {
updatePermission(el, binding.value)
},
updated(el, binding) {
updatePermission(el, binding.value)
},
}
app.directive('permission', permissionDirective) app.directive('permission', permissionDirective)
app.directive('role', roleDirective)
app.directive('button', buttonDirective)
} }

View File

@ -5,7 +5,25 @@ import { isArray, isString } from 'radash'
export function usePermission() { export function usePermission() {
const authStore = useAuthStore() const authStore = useAuthStore()
function hasPermission( /**
*
*/
function isSuperAdmin() {
if (!authStore.userInfo)
return false
const { role } = authStore.userInfo
// 支持多种超级管理员标识
const superAdminIdentifiers = ['super', 'admin', '超级管理员', 'ADMIN', 'coder_ADMIN']
return superAdminIdentifiers.some(identifier => role.includes(identifier))
}
/**
*
* @param permission
*/
function hasRole(
permission?: Entity.RoleType | Entity.RoleType[], permission?: Entity.RoleType | Entity.RoleType[],
) { ) {
if (!permission) if (!permission)
@ -15,21 +33,70 @@ export function usePermission() {
return false return false
const { role } = authStore.userInfo const { role } = authStore.userInfo
// 角色为super可直接通过 // 超级管理员可直接通过
let has = role.includes('super') if (isSuperAdmin())
if (!has) { return true
if (isArray(permission))
// 角色为数组, 判断是否有交集 let has = false
has = permission.some(i => role.includes(i)) if (isArray(permission))
// 角色为数组, 判断是否有交集
has = permission.some(i => role.includes(i))
if (isString(permission))
// 角色为字符串, 判断是否包含
has = role.includes(permission)
if (isString(permission))
// 角色为字符串, 判断是否包含
has = role.includes(permission)
}
return has return has
} }
/**
*
* @param permission
*/
function hasButton(
permission?: string | string[],
) {
if (!permission)
return true
if (!authStore.userInfo)
return false
// 超级管理员拥有所有权限
if (isSuperAdmin())
return true
const { buttons } = authStore.userInfo
// 检查具体权限标识
if (!buttons || buttons.length === 0)
return false
if (isArray(permission))
// 权限为数组, 判断是否有交集
return permission.some(i => buttons.includes(i))
if (isString(permission))
// 权限为字符串, 判断是否包含
return buttons.includes(permission)
return false
}
/**
* ()
* @param permission
*/
function hasPermission(
permission?: Entity.RoleType | Entity.RoleType[],
) {
return hasRole(permission)
}
return { return {
hasPermission, hasPermission,
hasRole,
hasButton,
isSuperAdmin,
} }
} }