npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@duxiaoma/design-rbac

v1.0.2

Published

基于 Vue3 + ant-design-vue 的 RBAC 权限组件库(资源目录 / 资源节点 / 资源行为 / 部门角色 / 用户授权)

Readme

@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。