@duxiaoma/design-rbac

基于 Vue3 + ant-design-vue 的 RBAC 权限组件库(资源目录 / 资源节点 / 资源行为 / 部门角色 / 用户授权)
362
Install
npm install @duxiaoma/design-rbac
Latest Version:1.0.2
Vue:3
License:ISC
Last Updated:Oct 19, 2026
Links: Gitee  ·  npm
Maintainer: xm_npm

@duxiaoma/design-rbac

基于 Vue 3 + ant-design-vue v4 + @duxiaoma/adm-vue3 的 RBAC(基于角色的权限控制)业务组件库,内置关系图可视化配置,开箱即用。提供四大业务页面:资源行为管理、资源权限管理、部门角色管理、用户授权管理,并对外导出权限判断方法 isHasPower。

后端接口的入参 / 反参明细见同目录 INTE.md,本文档只介绍组件库的接入与配置。


一、功能特性

  • 资源行为管理:资源行为枚举(查看 / 新增 / 修改 / 删除 / 导入 / 导出等内置行为 + 自定义行为)的分页查询与维护。
  • 资源权限管理:以关系图管理「资源目录 → 资源节点 → 资源行为」三级资源树,右键节点即可新增 / 编辑 / 删除 / 授权。
  • 部门角色管理:以关系图管理「组织 → 部门角色」树,支持角色维护与角色资源授权。
  • 用户授权管理:用户池分页检索,对用户批量授权资源行为、批量分配部门角色,支持单用户回显。
  • 宿主无关设计:接口地址、前缀、HTTP 方法、请求实例全部可配置 / 可注入,不绑定任何后端框架。
  • 细粒度权限控制:通过 options.power 传入当前用户权限码,控制每个操作入口的显示 / 禁用;同时导出纯函数 isHasPower 供宿主项目在菜单、路由、按钮等场景复用。

二、环境要求

组件库以下列依赖作为 peerDependencies,由宿主项目提供(不重复打包):

依赖 版本要求 说明
vue ^3.5.0 Vue 3
ant-design-vue ^4.2.0 UI 组件库,宿主需已全局注册或可自行解析其组件
@duxiaoma/adm-vue3 ^1.0.3 团队基础组件库(CTable / CTitle / useTable 等)

其余运行时依赖(relation-graph、lodash、@ant-design/icons-vue)已在 dependencies 中声明,安装本包时会自动安装。


三、安装与引入

3.1 安装

pnpm add @duxiaoma/design-rbac
# 或
npm i @duxiaoma/design-rbac

3.2 引入样式

组件样式与逻辑分离,必须在入口文件(如 main.ts)中手动引入一次:

import '@duxiaoma/design-rbac/style.css'

关系图(relation-graph)的样式随其包内联注入,无需额外引入。

3.3 全量注册

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import DesignRbac from '@duxiaoma/design-rbac'
import '@duxiaoma/design-rbac/style.css'

const app = createApp(App)
app.use(DesignRbac) // 全局注册 GraphAction / GraphResources / GraphRole / GraphUser
app.mount('#app')

3.4 按需引入(推荐)

支持局部注册,也支持 app.use(单个组件):

// 方式一:SFC 中直接引入使用
import {
  GraphResources,
  GraphRole,
  GraphAction,
  GraphUser
} from '@duxiaoma/design-rbac'
// 方式二:单独全局注册某个组件
import { GraphResources } from '@duxiaoma/design-rbac'
app.use(GraphResources)

四、组件与配置

4.1 组件一览

组件名 页面标题 说明
GraphAction 资源行为列表 资源行为枚举的分页查询、新增、编辑、删除
GraphResources 资源权限管理 资源目录 / 资源节点关系图,右键维护目录与节点、配置行为
GraphRole 部门角色管理 组织 / 部门角色关系图,右键维护角色并为角色授权资源
GraphUser 用户授权管理 用户池列表,批量授权资源行为 / 部门角色

4.2 通用 Props

四个组件的 Props 完全一致:

Prop 类型 必填 说明
options IOptions 否 组件配置项(接口地址、前缀、方法、权限码、表格、弹窗等)
requestFc (config) => Promise<any> 是 宿主注入的请求方法,组件所有接口都经它发出

4.3 options 配置项

interface IOptions {
  /** 接口 url 映射,仅需传需要覆盖的 key,会与内置默认地址合并 */
  apis?: Record<string, string>
  /** 接口 url 前缀,默认 '/api/component/rbac' */
  apiPrefix?: string
  /** 各操作对应的 HTTP 方法,默认 { add: 'post', del: 'delete', modify: 'put', check: 'get' } */
  apisMode?: Partial<{ add: string; del: string; modify: string; check: string }>
  /** 当前登录用户的权限码数组,控制组件内操作入口的显示 / 禁用,见第五章 */
  power?: string[]
  /** 列表页表格配置(当前对 GraphUser 生效) */
  listConfig?: Partial<{
    emptyTxt: string      // 无数据文本,默认 '--'
    resetSearch: boolean  // 点击重置后是否自动查询,默认 false
    pagAlign: string      // 分页栏对齐方式,默认 'center'
    tipLen: number        // 归属组织列悬浮提示前的最大长度,默认 12
  }>
  /** 弹窗是否垂直居中,默认 false */
  centered?: boolean
}

4.4 requestFc 请求方法注入

组件内部统一调用 requestApi(url, params, method),并按下列规则组装后交给 requestFc:

  • 请求地址:apiPrefix + url
  • GET 请求:参数放在 params(query);其余方法参数放在 data(body)
  • 固定请求头:Content-Type: application/json;charset=utf-8

因此 requestFc 收到的配置对象与 axios 的请求配置完全兼容,宿主只需返回后端响应体({ code, message, data })即可:

// api/rbac.ts
import axios from 'axios'
import type { App } from 'vue'

const request = axios.create({ timeout: 15000 })

// 请求拦截器:按需携带 token
request.interceptors.request.use((config) => {
  config.headers.Authorization = `Bearer ${localStorage.getItem('token') ?? ''}`
  return config
})

/**
 * 组件库请求方法
 * 组件判断成功的口径是响应体 code === 200,请确保 resolve 的是后端响应体而不是 AxiosResponse
 */
export const requestFc = async (config: any) => {
  const { data } = await request(config)
  return data
}

4.5 完整使用示例

<!-- views/rbac/resources.vue -->
<template>
  <GraphResources :options="options" :request-fc="requestFc" />
</template>

<script setup lang="ts">
import { GraphResources } from '@duxiaoma/design-rbac'
import { requestFc } from '@/api/rbac'
import { useUserStore } from '@/store/user'

const userStore = useUserStore()

const options = {
  // 后端前缀与默认值一致时可省略
  apiPrefix: '/api/component/rbac',
  // 仅需覆盖与默认值不同的接口
  apis: {
    // resourceTree: '/custom/resource_tree'
  },
  // 当前用户权限码(一般取自登录态 / 用户信息接口)
  power: userStore.power,
  centered: true
}
</script>

四个页面分别挂载到不同路由即可:

import {
  GraphAction,
  GraphResources,
  GraphRole,
  GraphUser
} from '@duxiaoma/design-rbac'

const routes = [
  { path: '/rbac/action', component: GraphAction },
  { path: '/rbac/resources', component: GraphResources },
  { path: '/rbac/role', component: GraphRole },
  { path: '/rbac/user', component: GraphUser }
]

记得给每个路由组件通过 props 或模板传入 options 与 requestFc(可在外层包一层布局组件统一传递)。

4.6 内置接口地址(options.apis)

默认前缀 apiPrefix = '/api/component/rbac',下表为内置相对地址,宿主可按 key 整体覆盖:

key 默认地址 说明
resourceTree /resource_tree 资源树(tag: rt/uar/aar)
foldDetail /resource_fold/detail 资源目录详情
foldAdd /resource_fold/add 新增资源目录
foldModify /resource_fold/update 编辑资源目录
foldDel /resource_fold/delete 删除资源目录
nodeDetail /resource/detail 资源节点详情
nodeAdd /resource/add 新增资源节点
nodeModify /resource/update 编辑资源节点
nodeDel /resource/delete 删除资源节点
actionList /resource_action_list 资源行为分页列表
actionAdd /resource_action/add 新增资源行为
actionDetail /resource_action/detail 资源行为详情
actionModify /resource_action/update 编辑资源行为
actionDel /resource_action/delete 删除资源行为
enum /get_enum RBAC 枚举(资源类型 / 行为 / 目录树 / 组织树)
userList /user_pool 用户池分页查询
userAuth /user_auth_resource/list 查询用户已授权资源(回显)
userAuthResource /user_auth_resource/add 用户资源授权
userAssemble /user_auth_assemble/list 查询用户所属部门角色(回显)
userAuthAssemble /user_auth_assemble/add 用户部门角色授权
roleTree /assemble_tree 部门角色树(tag: at/uaa)
roleDetail /assemble/detail 部门角色详情
roleAdd /assemble/add 新增部门角色
roleDel /assemble/delete 删除部门角色
roleModify /assemble/update 编辑部门角色
roleResourceCheck /assemble_auth_resource/list 查询角色已授权资源(回显)
roleAuthResource /assemble_auth_resource/add 角色资源授权

HTTP 方法默认映射 apisMode:

操作 方法 用途
check GET tree / detail / list 等查询
add POST 各类新增
modify PUT 编辑、授权提交
del DELETE 各类删除

五、权限控制与 isHasPower

5.1 组件内权限码(options.power)

把当前登录用户的权限码数组传给 options.power 后,组件会自动控制操作入口:

所属页面 权限码 控制的操作
资源权限管理 resource:fold:insert 新增资源目录
resource:fold:update 编辑资源目录
resource:fold:delete 删除资源目录
resource:node:insert 新增资源权限(节点)
resource:node:update 编辑资源权限
resource:node:delete 删除资源权限
资源行为管理 resource:action:insert 新增资源行为
resource:action:update 编辑资源行为
resource:action:delete 删除资源行为
部门角色管理 assemble:data:insert 新增部门角色
assemble:data:update 编辑部门角色
assemble:data:delete 删除部门角色
assemble:auth:update 授权资源权限
用户授权管理 user:auth_resource:update 授权资源权限
user:auth_assemble:update 授权部门角色

规则说明:

  • power 为空(未传 / 空数组)时,所有操作入口默认隐藏或禁用,请务必在接入权限后传入真实权限码;
  • 权限数组中包含超级管理员通配码 admin:auth:action 时,拥有全部操作权限;
  • 权限码通常由宿主登录态 / 用户信息接口返回,组件只负责消费。

5.2 对外导出的 isHasPower

权限判断逻辑同时以纯函数形式对外导出,宿主项目可在菜单导航、路由守卫、页面按钮等任意场景复用,保证全系统口径一致。

import { isHasPower } from '@duxiaoma/design-rbac'

/**
 * @param power    后端返回的权限数组
 * @param needType 需要查询的某个权限码
 */
function isHasPower(power?: string[] | null, needType?: string | null): boolean

判定规则:

  1. power 为空 → 返回 false(用户没有任何权限);
  2. needType 为空 → 返回 true(菜单导航中未配置权限码的菜单默认显示;页面内操作入口则必须配置权限码);
  3. power 命中 needType,或包含超管码 admin:auth:action → 返回 true,否则 false。

使用示例:

import { isHasPower } from '@duxiaoma/design-rbac'

// 假设这是后端返回的当前用户权限数组
const power = ['resource:node:insert', 'resource:node:update']

// 1. 页面按钮 / 操作判断
isHasPower(power, 'resource:node:insert') // true
isHasPower(power, 'resource:node:delete') // false
isHasPower([], 'resource:node:insert') // false:没有任何权限
isHasPower(power, '') // true:未配置权限码的入口默认显示
isHasPower(['admin:auth:action'], 'resource:node:delete') // true:超管放行
// 2. 路由守卫中控制菜单 / 页面访问
import { isHasPower } from '@duxiaoma/design-rbac'

router.beforeEach((to) => {
  // to.meta.power 为该页面要求的权限码;未配置 meta.power 的路由默认放行
  if (to.meta.power && !isHasPower(userStore.power, to.meta.power as string)) {
    return '/403'
  }
  return true
})
<!-- 3. 菜单 / 按钮渲染(配合 v-if) -->
<template>
  <a-button v-if="isHasPower(power, 'user:auth_resource:update')">
    授权资源权限
  </a-button>
</template>

组件内部的操作入口判断同样基于该方法(已自动绑定 options.power),无需在使用组件时重复调用。


六、后端约定

  • 统一响应体:{ code: 200, message: 'success', data, timestamp },组件以 code === 200 判定成功;
  • 分页响应:data = { list: [], page: { total, current, page_size } };
  • 每个操作都是独立 URL + 独立 HTTP 方法,请求体中没有 op 字段;
  • 授权类接口(用户资源授权、用户角色授权、角色资源授权)均为整体替换语义,提交时需带上最终完整勾选结果,传空数组即清空;
  • 树节点的 checked / indeterminate(半选)由后端根据下级状态推导,前端在授权弹窗中负责级联勾选与回显。

完整的 27 个接口入参 / 反参说明、枚举字典与注意事项,请参阅 INTE.md。


七、目录结构

src/
├── index.ts                  # 包入口:组件 install、类型与 isHasPower 导出
├── action/                   # 【组件】GraphAction 资源行为管理
│   ├── index.vue
│   └── components/           #   ActionEdit、TopForm
├── resources/                # 【组件】GraphResources 资源权限管理(目录 + 节点)
│   ├── index.vue、base.vue
│   └── components/           #   FoldEdit、NodeEdit(FirstForm/SecondForm)
├── role/                     # 【组件】GraphRole 部门角色管理
│   ├── index.vue、base.vue
│   └── components/           #   Resource、RoleEdit
├── user/                     # 【组件】GraphUser 用户授权管理
│   ├── index.vue
│   └── components/           #   OrgDialog、Resource、Role、TopForm
├── _components/              # 跨模块公共组件:Explain、SeeksRelationGraph
├── _config/                  # api(默认接口地址)/ columns / index(前缀、方法、tips)/ rules
├── _hooks/                   # use-api(配置合并 + 请求 + 权限)、use-graph(关系图级联勾选)
├── _utils/                   # 通用工具方法:isHasPower
├── _types/                   # 全部 TS 类型
└── _style/                   # config.less + index.less

八、本地开发与构建

pnpm install        # 安装依赖
pnpm type-check     # vue-tsc 类型检查
pnpm build          # 构建产物(es / cjs / umd + 类型声明 + style.css)
pnpm publish        # 发布前会自动执行 pnpm build(prepublishOnly)

构建产物:

产物 路径
ES Module dist/es/index.mjs
CommonJS dist/lib/index.cjs
UMD dist/umd/design-rbac.umd.js
类型声明 dist/types/index.d.ts
样式 dist/style/index.css(即包导出的 @duxiaoma/design-rbac/style.css)

vue、ant-design-vue、@duxiaoma/adm-vue3、relation-graph、lodash、@ant-design/icons-vue 均已 external,由宿主项目提供,不会重复打包。


九、常见问题

  1. 关系图 / 按钮没有样式? 确认已在入口引入 import '@duxiaoma/design-rbac/style.css',且宿主项目已引入 ant-design-vue 的样式(v4 组件自带 css-in-js,通常无需额外引入)。

  2. 接口请求地址不对 / 方法不对? 通过 options.apiPrefix 覆盖前缀,通过 options.apis 按 key 覆盖单个地址,通过 options.apisMode 覆盖增删改查对应的 HTTP 方法。

  3. 操作按钮全部置灰或右键菜单不显示? 新口径下 options.power 为空时默认禁用所有操作入口;请传入当前用户的真实权限码,超管传入 admin:auth:action。

  4. requestFc 报错或列表不刷新? 确保 requestFc resolve 的是后端响应体本身(包含 code / data 字段),而不是 axios 的 AxiosResponse;成功状态码需为 200。

Related Packages

@duxiaoma/adm-vue3

基于 Vue3 + ant-design-vue 的业务组件库

864
com-angel-authorization

Framework-agnostic user permission toolkit for React and Vue

7,496
@composy/permission-vue

LDesign 权限系统 Vue 3 适配层 / Vue 3 adapter for @composy/permission-core

0
@pureadmin/components

pureadmin components

4,706

Version History

Version Released Vue License
1.0.2 ^3.5.0 ISC
1.0.1 ^3.5.0 ISC
1.0.0 ^3.5.0 ISC