# Admin 权限管理模块
Admin 模块是 DarkM 框架的核心基础模块,实现了基于 RBAC(Role-Based Access Control)的权限管理系统。所有需要权限管理的项目都必须安装此模块。
# 📋 模块概述
| 属性 | 说明 |
|---|---|
| 模块名称 | Admin(权限管理) |
| 模块类型 | 基础模块 |
| 依赖关系 | 无依赖(其他模块依赖它) |
| 必需性 | 所有管理系统必需 |
| Git 仓库 | framework/darkm/darkm (opens new window) |
# 🎯 核心功能
# 功能清单
| 功能 | 说明 | 重要性 |
|---|---|---|
| 账户管理 | 用户账户的增删改查 | ⭐⭐⭐⭐⭐ |
| 角色管理 | 角色定义和权限分配 | ⭐⭐⭐⭐⭐ |
| 菜单管理 | 系统菜单配置 | ⭐⭐⭐⭐⭐ |
| 权限管理 | 接口权限定义和授权 | ⭐⭐⭐⭐⭐ |
| 按钮权限 | 细化到按钮级别的权限控制 | ⭐⭐⭐⭐ |
| 审计日志 | 详细的操作日志记录 | ⭐⭐⭐⭐ |
| 配置管理 | 系统配置项管理 | ⭐⭐⭐⭐ |
| 数据权限 | 数据范围控制 | ⭐⭐⭐ |
# 📦 安装配置
# NuGet 包安装
Install-Package DarkM.Module.Admin.Web -Version 1.0.2
# NPM 包安装
npm i -S darkm-module-admin
# 配置文件
{
"Db": {
"Modules": [
{
"Name": "Admin",
"Database": "Nm_Admin",
"Prefix": ""
}
]
},
"Admin": {
// 是否开启审计功能
"Auditing": true,
// 是否开启权限验证
"PermissionValidate": true
},
"Upload": {
// 文件上传路径
"UploadPath": "/upload",
// 临时文件路径
"TempPath": "/temp"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
配置说明:
| 配置项 | 说明 | 默认值 |
|---|---|---|
Auditing | 是否开启审计日志 | true |
PermissionValidate | 是否开启权限验证 | true |
UploadPath | 文件上传路径 | /upload |
TempPath | 临时文件路径 | /temp |
# 🗄️ 数据库表结构
# 核心表
| 表名 | 说明 | 主键 |
|---|---|---|
Account | 账户表 | Id (Guid) |
Role | 角色表 | Id (Guid) |
Permission | 权限表 | Id (int) |
Menu | 菜单表 | Id (int) |
Config | 配置项表 | Id (int) |
AuditLog | 审计日志表 | Id (long) |
# 关联表
| 表名 | 说明 |
|---|---|
AccountRole | 账户 - 角色关联 |
RolePermission | 角色 - 权限关联 |
RoleMenu | 角色 - 菜单关联 |
# 🔐 权限系统设计
# 什么是权限?
在 DarkM 框架中,权限就是接口,即 Controller 中的每一个 Action。
权限 = Controller + Action + HttpMethod
# 权限编码规则
格式:Area_Controller_Action_HttpMethod
| 部分 | 说明 | 示例 |
|---|---|---|
| Area | 区域/模块编码 | Admin |
| Controller | 控制器名称 | Config |
| Action | 操作方法 | Query |
| HttpMethod | 请求方式 | Get |
示例: admin_config_query_get
# 权限访问级别
# 1. 需要授权才能访问(默认)
所有继承自 ModuleController 的控制器默认都需要授权。
// 模块控制器基类
[Area("Admin")]
public abstract class ModuleController : ControllerAbstract
{
// ...
}
// ControllerAbstract 包含权限验证特性
[PermissionValidate]
public abstract class ControllerAbstract : ControllerBase
{
// ...
}
2
3
4
5
6
7
8
9
10
11
12
13
# 2. 登录即可访问
使用 [Common] 特性标记,只需登录无需特定权限。
[HttpGet]
[Description("下拉列表")]
[Common] // ← 登录即可访问
public Task<IResultModel> Select(string group, string code)
{
return _service.Select(group, code);
}
2
3
4
5
6
7
适用场景: 字典下拉列表、公共数据查询等
# 3. 匿名即可访问
使用 [AllowAnonymous] 特性标记,无需登录。
[HttpPost]
[AllowAnonymous] // ← 匿名访问
[DisableAuditing]
[Description("登录")]
public async Task<IResultModel> Login([FromBody]LoginModel model)
{
// ...
}
2
3
4
5
6
7
8
适用场景: 登录接口、获取系统配置等
# 🎨 权限配置示例
# Controller 定义
using System.ComponentModel;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using DarkM.Lib.Auth.Web.Attributes;
using DarkM.Lib.Utils.Core.Result;
namespace DarkM.Module.Admin.Web.Controllers
{
[Description("配置项管理")] // ← 控制器说明
public class ConfigController : ModuleController
{
private readonly IConfigService _service;
public ConfigController(IConfigService service)
{
_service = service;
}
[HttpGet]
[Description("查询")] // ← Action 说明
public async Task<IResultModel> Query([FromQuery]ConfigQueryModel model)
{
return await _service.Query(model);
}
[HttpPost]
[Description("添加")]
public Task<IResultModel> Add(ConfigAddModel model)
{
return _service.Add(model);
}
[HttpPut]
[Description("修改")]
public Task<IResultModel> Update(ConfigUpdateModel model)
{
return _service.Update(model);
}
[HttpDelete]
[Description("删除")]
public Task<IResultModel> Delete([BindRequired]int id)
{
return _service.Delete(id);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 权限解析结果
上述 Controller 解析后生成以下权限:
| 权限编码 | 说明 | 访问级别 |
|---|---|---|
admin_config_query_get | 配置项管理 - 查询 | 需授权 |
admin_config_add_post | 配置项管理 - 添加 | 需授权 |
admin_config_update_put | 配置项管理 - 修改 | 需授权 |
admin_config_delete_delete | 配置项管理 - 删除 | 需授权 |
# 🖥️ 前端组件说明
# NPM 包信息
{
"name": "darkm-module-admin",
"version": "1.5.0-beta-2.0",
"code": "admin",
"title": "权限管理",
"dependencies": {
"darkm-skins-classics": "^1.5.0-beta-2.0",
"darkm-ui": "^1.5.0-beta-2.0"
}
}
2
3
4
5
6
7
8
9
10
# 组件目录结构
src/Admin/UI/module-admin/
├── src/
│ ├── views/ # 页面组件
│ │ ├── account/ # 账户管理
│ │ ├── role/ # 角色管理
│ │ ├── menu/ # 菜单管理
│ │ ├── permission/ # 权限管理
│ │ ├── group/ # 分组管理
│ │ ├── config/ # 配置管理
│ │ ├── auditLog/ # 审计日志
│ │ └── loginLog/ # 登录日志
│ └── components/ # 通用组件
│ ├── account-select/ # 账户选择器
│ ├── account-search-select/ # 账户搜索选择器
│ ├── role-select/ # 角色选择器
│ ├── group-select/ # 分组选择器
│ ├── module-select/ # 模块选择器
│ ├── enum-select/ # 枚举选择器
│ └── ...
└── package.json
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 📦 通用组件详解
# 1. AccountSelect 账户选择器
组件路径: components/account-select
功能: 下拉选择账户,支持按类型、状态、角色、分组筛选
使用示例:
<template>
<account-select
v-model="accountId"
:type="[0, 1]"
:status="[1]"
:roleId="roleId"
/>
</template>
<script>
import { components } from 'darkm-module-admin'
const { AccountSelect } = components
export default {
components: { AccountSelect },
data() {
return {
accountId: '',
roleId: 'xxx'
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String | 否 | - | 选中的账户 ID(v-model) |
type | Array | 否 | [] | 账户类型筛选(0:系统、1:普通、2:外部等) |
status | Array | 否 | [] | 状态筛选(0:未激活、1:正常、2:禁用、3:注销) |
roleId | Array | 否 | [] | 角色 ID 筛选 |
roleCode | Array | 否 | [] | 角色编码筛选 |
groupId | Array | 否 | [] | 分组 ID 筛选 |
groupCode | Array | 否 | [] | 分组编码筛选 |
codeKey | Boolean | 否 | false | 是否使用编码作为 key |
disabled | Boolean | 否 | false | 是否禁用 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String) | 选中值变化时触发(v-model) |
change | (value: String, data: Object) | 选中值变化时触发,返回完整数据 |
特点:
- ✅ 支持缓存(clientCacheKey: 'select-cache-admin-account')
- ✅ 支持多种筛选条件
- ✅ 支持多选类型和状态
# 2. AccountSearchSelect 账户搜索选择器
组件路径: components/account-search-select
功能: 弹窗式账户搜索选择,支持高级查询、多选、批量绑定
使用示例:
<template>
<account-search-select
v-model="accountIds"
:roleId="roleId"
:groupId="groupId"
@success="handleSuccess"
/>
</template>
<script>
import { components } from 'darkm-module-admin'
const { AccountSearchSelect } = components
export default {
components: { AccountSearchSelect },
data() {
return {
accountIds: [],
roleId: 'xxx',
groupId: 'xxx'
}
},
methods: {
handleSuccess(data) {
console.log('绑定成功:', data)
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String/Number | 否 | - | 选中的账户 ID(v-model) |
type | Number/String | 否 | - | 账户类型筛选 |
roleId | Number/String | 否 | - | 角色 ID(用于批量绑定) |
groupId | Number/String | 否 | - | 分组 ID(用于批量绑定) |
disabled | Boolean | 否 | false | 是否禁用 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String) | 选中值变化时触发 |
success | (data: Object) | 批量绑定成功后触发 |
功能特点:
- ✅ 高级查询:支持登录名、名称、类型、状态、手机号、邮箱查询
- ✅ 角色筛选:按角色筛选账户
- ✅ 分组筛选:按分组筛选账户
- ✅ 多选支持:支持批量选择账户
- ✅ 批量绑定:支持批量绑定到角色或分组
- ✅ 双击选择:双击行快速选择
- ✅ 信息显示:显示角色、分组、状态、登录时间等
查询条件:
| 条件 | 类型 | 说明 |
|---|---|---|
| 登录名 | 文本 | 模糊匹配 |
| 名称 | 文本 | 模糊匹配 |
| 类型 | 枚举 | AccountType |
| 状态 | 枚举 | AccountStatus |
| 手机号 | 文本 | 模糊匹配 |
| 邮箱 | 文本 | 模糊匹配 |
| 角色 | 选择器 | 按角色筛选 |
| 分组 | 选择器 | 按分组筛选 |
# 3. RoleSelect 角色选择器
组件路径: components/role-select
功能: 下拉选择角色
使用示例:
<template>
<role-select v-model="roleId" />
</template>
<script>
import { components } from 'darkm-module-admin'
const { RoleSelect } = components
export default {
components: { RoleSelect },
data() {
return {
roleId: ''
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String | 否 | - | 选中的角色 ID(v-model) |
disabled | Boolean | 否 | false | 是否禁用 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String) | 选中值变化时触发(v-model) |
change | (value: String, data: Object) | 选中值变化时触发,返回完整数据 |
特点:
- ✅ 支持缓存(clientCacheKey: 'select-cache-admin-role')
- ✅ 简单下拉选择
# 4. GroupSelect 分组选择器
组件路径: components/group-select
功能: 下拉选择分组
使用示例:
<template>
<group-select v-model="groupId" />
</template>
<script>
import { components } from 'darkm-module-admin'
const { GroupSelect } = components
export default {
components: { GroupSelect },
data() {
return {
groupId: ''
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String | 否 | - | 选中的分组 ID(v-model) |
disabled | Boolean | 否 | false | 是否禁用 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String) | 选中值变化时触发(v-model) |
change | (value: String, data: Object) | 选中值变化时触发,返回完整数据 |
特点:
- ✅ 支持缓存(clientCacheKey: 'select-cache-admin-group')
- ✅ 简单下拉选择
# 5. ModuleSelect 模块选择器
组件路径: components/module-select
功能: 下拉选择模块
使用示例:
<template>
<module-select v-model="moduleId" />
</template>
<script>
import { components } from 'darkm-module-admin'
const { ModuleSelect } = components
export default {
components: { ModuleSelect },
data() {
return {
moduleId: ''
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String | 否 | - | 选中的模块 ID(v-model) |
disabled | Boolean | 否 | false | 是否禁用 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String) | 选中值变化时触发(v-model) |
change | (value: String, data: Object) | 选中值变化时触发,返回完整数据 |
特点:
- ✅ 支持缓存(clientCacheKey: 'select-cache-admin-module')
- ✅ 简单下拉选择
# 6. EnumSelect 枚举选择器
组件路径: components/enum-select
功能: 下拉选择枚举值,支持动态加载枚举
使用示例:
<template>
<enum-select
v-model="accountType"
module-code="admin"
enum-name="AccountType"
/>
</template>
<script>
import { components } from 'darkm-module-admin'
const { EnumSelect } = components
export default {
components: { EnumSelect },
data() {
return {
accountType: ''
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Props 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | String/Number | 否 | - | 选中的枚举值(v-model) |
moduleCode | String | 是 | - | 模块编码 |
enumName | String | 是 | - | 枚举名称 |
libName | String | 否 | - | 所在库名称 |
disabled | Boolean | 否 | false | 是否禁用 |
clearable | Boolean | 否 | true | 是否可清空 |
Events 事件:
| 事件名 | 参数 | 说明 |
|---|---|---|
input | (value: String/Number) | 选中值变化时触发 |
change | (value: String/Number, data: Object) | 选中值变化时触发 |
特点:
- ✅ 支持缓存(key 包含 enumName、moduleCode、libName)
- ✅ 支持跨模块枚举
- ✅ 支持库级别枚举
# 📋 组件使用注意事项
# 1. 组件引入方式
// 方式一:引入单个组件
import { components } from 'darkm-module-admin'
const { AccountSelect, RoleSelect } = components
// 方式二:全局注册
import Admin from 'darkm-module-admin'
Vue.use(Admin)
2
3
4
5
6
7
# 2. v-model 双向绑定
所有选择器组件都支持 v-model 双向绑定:
<!-- 推荐用法 -->
<account-select v-model="accountId" />
<!-- 等价于 -->
<account-select
:value="accountId"
@input="accountId = $event"
/>
2
3
4
5
6
7
8
# 3. 级联选择
多个选择器可以级联使用:
<template>
<div>
<role-select v-model="roleId" />
<account-select v-model="accountId" :roleId="roleId" />
</div>
</template>
2
3
4
5
6
# 4. 缓存机制
大部分选择器组件支持前端缓存:
// 缓存配置
data() {
return {
clientCacheKey: 'select-cache-admin-account',
//clientCacheTime: 60, // 缓存时长(秒)
}
}
2
3
4
5
6
7
# 5. 数据格式
所有组件返回的数据格式:
- 单选: 返回 ID(String/Number)
- 多选: 返回 ID 数组(Array)
- change 事件: 返回
(value, data),data 为完整对象
# 📊 审计日志系统
# 审计配置
{
"Admin": {
"Auditing": true // 开启审计
}
}
2
3
4
5
# 审计内容
| 内容 | 说明 |
|---|---|
| 操作人 | 执行操作的用户 ID 和名称 |
| 操作时间 | 操作发生的时间 |
| 操作类型 | 新增/修改/删除/查询 |
| 操作模块 | 所属模块名称 |
| 操作方法 | 具体操作方法 |
| 请求参数 | 传入的参数信息 |
| 返回结果 | 操作结果 |
| 执行时长 | 操作耗时 |
| IP 地址 | 操作者 IP |
| 浏览器信息 | User-Agent |
# 禁用审计
某些敏感操作(如登录)需要禁用审计:
[HttpPost]
[AllowAnonymous]
[DisableAuditing] // ← 禁用审计
[Description("登录")]
public async Task<IResultModel> Login([FromBody]LoginModel model)
{
// ...
}
2
3
4
5
6
7
8
# 🔧 核心服务接口
# IAccountService(账户服务)
public interface IAccountService
{
// 查询账户列表
Task<IResultModel> Query(AccountQueryModel model);
// 添加账户
Task<IResultModel> Add(AccountAddModel model);
// 修改账户
Task<IResultModel> Update(AccountUpdateModel model);
// 删除账户
Task<IResultModel> Delete(int id);
// 重置密码
Task<IResultModel> ResetPassword(int id);
// 修改状态
Task<IResultModel> UpdateStatus(int id, int status);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# IRoleService(角色服务)
public interface IRoleService
{
// 查询角色列表
Task<IResultModel> Query(RoleQueryModel model);
// 添加角色
Task<IResultModel> Add(RoleAddModel model);
// 修改角色
Task<IResultModel> Update(RoleUpdateModel model);
// 分配权限
Task<IResultModel> AssignPermissions(RolePermissionModel model);
// 分配菜单
Task<IResultModel> AssignMenus(RoleMenuModel model);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# IMenuService(菜单服务)
public interface IMenuService
{
// 获取菜单树
Task<IResultModel> GetTree();
// 添加菜单
Task<IResultModel> Add(MenuAddModel model);
// 修改菜单
Task<IResultModel> Update(MenuUpdateModel model);
// 删除菜单
Task<IResultModel> Delete(int id);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 🔍 常见问题
# 1. 权限验证不生效
问题: 未授权用户仍能访问接口
解决:
# 检查配置
cat appsettings.json | grep PermissionValidate
# 检查控制器是否继承 ModuleController
# 检查是否有 [PermissionValidate] 特性
# 检查权限是否已分配给角色
# 检查角色是否已分配给用户
2
3
4
5
6
7
8
# 2. 菜单不显示
问题: 登录后菜单为空
解决:
- 检查菜单是否已添加
- 检查菜单是否已分配给角色
- 检查用户是否有该角色
- 清除浏览器缓存后重新登录
# 3. 按钮不显示
问题: 页面正常但按钮不显示
解决:
// 检查 page.js 中的 buttons 配置
this.buttons = {
add: {
code: 'asset_add',
permissions: ['asset_add_post'] // ← 确保权限编码正确
}
}
// 检查权限是否已分配
2
3
4
5
6
7
8
9
# 4. 审计日志未记录
问题: 操作后没有审计日志
解决:
# 检查审计配置
cat appsettings.json | grep Auditing
# 检查是否被 [DisableAuditing] 禁用
# 检查 AuditLog 表是否正常
2
3
4
5
# 📚 相关文档
# 🔗 参考链接
最后更新: 2022-08-07
← Q&A 01_通用模块 (Common) →