createReactivePermission
基于响应式系统的权限管理函数,支持角色切换时的自动权限更新。
函数签名
typescript
function createReactivePermission(
config: PermissionConfig,
deps: PermissionDeps
): PermissionInstance
interface PermissionConfig {
/** 默认角色 */
defaultRole: string
/** 所有权限定义 */
permissions: Permission[]
/** 所有角色定义 */
roles: Role[]
/** 是否严格模式(检查未定义的权限时抛出错误) */
strict?: boolean
}
interface PermissionDeps {
/** 创建响应式对象 */
createReactive: CreateReactive
/** 控制台日志函数 */
log: (...args: any[]) => void
/** 控制台警告函数 */
warn: (...args: any[]) => void
}
interface Permission {
/** 权限代码 */
code: string
/** 权限名称 */
name: string
/** 权限描述 */
description?: string
}
interface Role {
/** 角色代码 */
code: string
/** 角色名称 */
name: string
/** 角色拥有的权限代码列表 */
permissions: string[]
/** 角色描述 */
description?: string
}前置依赖
依赖参数
| 参数名 | 类型 | 说明 |
|---|---|---|
deps.createReactive | CreateReactive | 创建响应式对象的函数,用于实现角色切换的自动更新 |
deps.log | (...args: any[]) => void | 日志输出函数,用于记录角色切换等操作 |
deps.warn | (...args: any[]) => void | 警告输出函数,用于记录权限检查警告信息 |
环境要求
- createReactive: 需要先导入
createReactive函数
bash
# 确保已安装相关依赖
npm install shared参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
config | PermissionConfig | 是 | 权限配置对象 |
config.defaultRole | string | 是 | 默认角色代码 |
config.permissions | Permission[] | 是 | 所有权限定义列表 |
config.roles | Role[] | 是 | 所有角色定义列表 |
config.strict | boolean | 否 | 是否启用严格模式,默认 false |
deps | PermissionDeps | 是 | 环境依赖,包含响应式函数和日志函数 |
返回值
| 类型 | 说明 |
|---|---|
PermissionInstance | 权限管理实例,包含权限检查和角色管理方法 |
工作原理
- 响应式状态管理:使用
createReactive创建响应式的角色状态 - 权限检查:根据当前角色的权限列表进行权限验证
- 多种检查模式:支持单个权限、全部权限(AND)、任一权限(OR)的检查
- 订阅通知:角色变化时自动通知所有订阅者
- 动态管理:支持运行时添加角色和权限
- 严格模式:可选的权限定义检查,避免检查未定义的权限
核心特性:
- 角色切换时所有权限检查自动更新
- 灵活的权限检查方式(单个/全部/任一)
- 支持动态添加角色和权限
- 响应式订阅机制
- 可选的严格模式
异常
| 错误类型 | 触发条件 | 错误信息 |
|---|---|---|
Error | 缺少默认角色 | defaultRole is required |
Error | 角色列表为空 | roles is required and cannot be empty |
Error | 默认角色不存在 | Default role "xxx" not found in roles |
完整示例
typescript
import { createReactivePermission } from 'zcw-shared/reactive/createReactivePermission'
import { createReactive } from 'zcw-shared/reactive/createReactive'
// 创建权限管理实例
const permission = createReactivePermission({
defaultRole: 'user',
permissions: [
{ code: 'user.view', name: '查看用户', description: '查看用户列表和详情' },
{ code: 'user.create', name: '创建用户', description: '创建新用户' },
{ code: 'user.edit', name: '编辑用户', description: '编辑用户信息' },
{ code: 'user.delete', name: '删除用户', description: '删除用户账户' },
{ code: 'post.view', name: '查看文章', description: '查看文章列表' },
{ code: 'post.create', name: '创建文章', description: '创建新文章' },
{ code: 'post.edit', name: '编辑文章', description: '编辑文章内容' },
{ code: 'post.delete', name: '删除文章', description: '删除文章' },
{ code: 'post.publish', name: '发布文章', description: '发布文章' }
],
roles: [
{
code: 'guest',
name: '访客',
description: '未登录用户',
permissions: ['post.view']
},
{
code: 'user',
name: '普通用户',
description: '已注册的普通用户',
permissions: ['user.view', 'post.view', 'post.create']
},
{
code: 'editor',
name: '编辑',
description: '内容编辑',
permissions: ['user.view', 'post.view', 'post.create', 'post.edit', 'post.publish']
},
{
code: 'admin',
name: '管理员',
description: '系统管理员',
permissions: ['user.view', 'user.create', 'user.edit', 'user.delete', 'post.view', 'post.create', 'post.edit', 'post.delete', 'post.publish']
}
],
strict: true
}, {
createReactive,
log: console.log,
warn: console.warn
})
// 单个权限检查
console.log(permission.hasPermission('user.view')) // true
console.log(permission.hasPermission('user.edit')) // false
// 多个权限检查 (AND)
console.log(permission.hasAllPermissions(['user.view', 'post.create'])) // true
console.log(permission.hasAllPermissions(['user.view', 'user.edit'])) // false
// 多个权限检查 (OR)
console.log(permission.hasAnyPermission(['user.edit', 'post.create'])) // true
console.log(permission.hasAnyPermission(['user.edit', 'user.delete'])) // false
// 切换角色
permission.setRole('admin')
console.log(permission.hasPermission('user.edit')) // true
console.log(permission.hasPermission('user.delete')) // true
// 订阅角色变化
const unsubscribe = permission.subscribe(() => {
console.log('角色已切换到:', permission.currentRole)
// 更新 UI 显示
updateUI()
})
// 获取当前角色信息
const currentRole = permission.getCurrentRole()
console.log(currentRole?.name) // 管理员
console.log(currentRole?.permissions) // ['user.view', 'user.create', ...]
// 获取当前角色的所有权限对象
const currentPermissions = permission.getCurrentPermissions()
console.log(currentPermissions) // [{ code: 'user.view', name: '查看用户' }, ...]
// 动态添加角色
permission.addRole({
code: 'moderator',
name: '版主',
description: '内容审核',
permissions: ['post.view', 'post.edit', 'post.delete']
})
// 动态添加权限
permission.addPermission({
code: 'comment.moderate',
name: '审核评论',
description: '审核和管理评论'
})
// 为角色添加权限
permission.addPermissionToRole('moderator', 'comment.moderate')
// 从角色移除权限
permission.removePermissionFromRole('moderator', 'post.delete')
// 检查角色是否存在
console.log(permission.hasRole('moderator')) // true
// 获取所有角色
const allRoles = permission.getRoles()
console.log(allRoles) // [{ code: 'guest', ... }, { code: 'user', ... }, ...]
// 获取所有权限
const allPermissions = permission.getPermissions()
console.log(allPermissions) // [{ code: 'user.view', ... }, { code: 'user.create', ... }, ...]
// 清理订阅
unsubscribe()实际应用场景
Vue 组件中使用
typescript
import { createReactivePermission } from 'zcw-shared/reactive/createReactivePermission'
import { createReactive } from 'zcw-shared/reactive/createReactive'
import { ref, computed } from 'vue'
const permission = createReactivePermission(config, {
createReactive,
log: console.log,
warn: console.warn
})
export default {
setup() {
const currentRole = ref(permission.currentRole)
// 订阅角色变化
permission.subscribe(() => {
currentRole.value = permission.currentRole
})
// 计算属性
const canEdit = computed(() => permission.hasPermission('post.edit'))
const canDelete = computed(() => permission.hasPermission('post.delete'))
return {
currentRole,
canEdit,
canDelete,
hasPermission: permission.hasPermission,
setRole: permission.setRole
}
}
}React Hook 中使用
typescript
function usePermission() {
const [currentRole, setCurrentRole] = useState(permission.currentRole)
useEffect(() => {
const unsubscribe = permission.subscribe(() => {
setCurrentRole(permission.currentRole)
})
return unsubscribe
}, [])
return {
currentRole,
hasPermission: permission.hasPermission,
hasAllPermissions: permission.hasAllPermissions,
hasAnyPermission: permission.hasAnyPermission,
setRole: permission.setRole
}
}路由守卫
typescript
// Vue Router 守卫
router.beforeEach((to, from, next) => {
const requiredPermissions = to.meta.permissions as string[]
if (requiredPermissions && requiredPermissions.length > 0) {
if (permission.hasAllPermissions(requiredPermissions)) {
next()
} else {
next('/403') // 无权限,跳转到 403 页面
}
} else {
next()
}
})UI 条件渲染
vue
<template>
<div>
<!-- 单个权限检查 -->
<button v-if="permission.hasPermission('user.create')">
创建用户
</button>
<!-- 多个权限检查 (AND) -->
<button v-if="permission.hasAllPermissions(['post.edit', 'post.publish'])">
编辑并发布
</button>
<!-- 多个权限检查 (OR) -->
<button v-if="permission.hasAnyPermission(['post.edit', 'post.delete'])">
管理文章
</button>
<!-- 角色切换 -->
<select v-model="permission.currentRole">
<option v-for="role in permission.getRoles()" :key="role.code" :value="role.code">
{{ role.name }}
</option>
</select>
</div>
</template>高级用法
自定义权限检查函数
typescript
// 基于资源的权限检查
function canAccessResource(resourceType: string, action: string): boolean {
const permissionCode = `${resourceType}.${action}`
return permission.hasPermission(permissionCode)
}
// 使用示例
if (canAccessResource('user', 'edit')) {
// 允许编辑用户
}权限组合
typescript
// 定义权限组
const ADMIN_PERMISSIONS = [
'user.view', 'user.create', 'user.edit', 'user.delete',
'post.view', 'post.create', 'post.edit', 'post.delete', 'post.publish'
]
const EDITOR_PERMISSIONS = [
'post.view', 'post.create', 'post.edit', 'post.publish'
]
// 检查是否具有管理员权限组
function isAdmin(): boolean {
return permission.hasAllPermissions(ADMIN_PERMISSIONS)
}
// 检查是否具有编辑权限组
function isEditor(): boolean {
return permission.hasAllPermissions(EDITOR_PERMISSIONS)
}权限继承
typescript
// 定义角色层级
const ROLE_HIERARCHY = {
guest: [],
user: ['guest'],
editor: ['user'],
admin: ['editor']
}
// 扩展角色权限(继承父角色权限)
function extendRolePermissions(role: Role, allRoles: Role[]): string[] {
const permissions = [...role.permissions]
const parents = ROLE_HIERARCHY[role.code as keyof typeof ROLE_HIERARCHY] || []
parents.forEach(parentCode => {
const parentRole = allRoles.find(r => r.code === parentCode)
if (parentRole) {
permissions.push(...extendRolePermissions(parentRole, allRoles))
}
})
return [...new Set(permissions)] // 去重
}动态权限加载
typescript
// 从服务器加载权限配置
async function loadPermissionsFromServer() {
const response = await fetch('/api/permissions')
const data = await response.json()
// 添加新权限
data.permissions.forEach((p: Permission) => {
permission.addPermission(p)
})
// 添加新角色
data.roles.forEach((r: Role) => {
permission.addRole(r)
})
}
// 根据用户信息设置角色
async function setupUserPermissions(userId: string) {
const response = await fetch(`/api/users/${userId}/role`)
const { roleCode } = await response.json()
permission.setRole(roleCode)
}基于响应式系统的权限管理解决方案,让权限控制变得简单而高效!