# 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
1

# NPM 包安装

npm i -S darkm-module-admin
1

# 配置文件

{
  "Db": {
    "Modules": [
      {
        "Name": "Admin",
        "Database": "Nm_Admin",
        "Prefix": ""
      }
    ]
  },
  "Admin": {
    // 是否开启审计功能
    "Auditing": true,
    // 是否开启权限验证
    "PermissionValidate": true
  },
  "Upload": {
    // 文件上传路径
    "UploadPath": "/upload",
    // 临时文件路径
    "TempPath": "/temp"
  }
}
1
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
1

# 权限编码规则

格式: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
{
    // ...
}
1
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);
}
1
2
3
4
5
6
7

适用场景: 字典下拉列表、公共数据查询等

# 3. 匿名即可访问

使用 [AllowAnonymous] 特性标记,无需登录。

[HttpPost]
[AllowAnonymous]  // ← 匿名访问
[DisableAuditing]
[Description("登录")]
public async Task<IResultModel> Login([FromBody]LoginModel model)
{
    // ...
}
1
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);
        }
    }
}
1
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"
  }
}
1
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
1
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>
1
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>
1
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>
1
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>
1
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>
1
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>
1
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)
1
2
3
4
5
6
7

# 2. v-model 双向绑定

所有选择器组件都支持 v-model 双向绑定:

<!-- 推荐用法 -->
<account-select v-model="accountId" />

<!-- 等价于 -->
<account-select 
  :value="accountId" 
  @input="accountId = $event" 
/>
1
2
3
4
5
6
7
8

# 3. 级联选择

多个选择器可以级联使用:

<template>
  <div>
    <role-select v-model="roleId" />
    <account-select v-model="accountId" :roleId="roleId" />
  </div>
</template>
1
2
3
4
5
6

# 4. 缓存机制

大部分选择器组件支持前端缓存:

// 缓存配置
data() {
  return {
    clientCacheKey: 'select-cache-admin-account',
    //clientCacheTime: 60, // 缓存时长(秒)
  }
}
1
2
3
4
5
6
7

# 5. 数据格式

所有组件返回的数据格式:

  • 单选: 返回 ID(String/Number)
  • 多选: 返回 ID 数组(Array)
  • change 事件: 返回 (value, data),data 为完整对象

# 📊 审计日志系统

# 审计配置

{
  "Admin": {
    "Auditing": true  // 开启审计
  }
}
1
2
3
4
5

# 审计内容

内容 说明
操作人 执行操作的用户 ID 和名称
操作时间 操作发生的时间
操作类型 新增/修改/删除/查询
操作模块 所属模块名称
操作方法 具体操作方法
请求参数 传入的参数信息
返回结果 操作结果
执行时长 操作耗时
IP 地址 操作者 IP
浏览器信息 User-Agent

# 禁用审计

某些敏感操作(如登录)需要禁用审计:

[HttpPost]
[AllowAnonymous]
[DisableAuditing]  // ← 禁用审计
[Description("登录")]
public async Task<IResultModel> Login([FromBody]LoginModel model)
{
    // ...
}
1
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);
}
1
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);
}
1
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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 🔍 常见问题

# 1. 权限验证不生效

问题: 未授权用户仍能访问接口

解决:

# 检查配置
cat appsettings.json | grep PermissionValidate

# 检查控制器是否继承 ModuleController
# 检查是否有 [PermissionValidate] 特性

# 检查权限是否已分配给角色
# 检查角色是否已分配给用户
1
2
3
4
5
6
7
8

# 2. 菜单不显示

问题: 登录后菜单为空

解决:

  1. 检查菜单是否已添加
  2. 检查菜单是否已分配给角色
  3. 检查用户是否有该角色
  4. 清除浏览器缓存后重新登录

# 3. 按钮不显示

问题: 页面正常但按钮不显示

解决:

// 检查 page.js 中的 buttons 配置
this.buttons = {
  add: {
    code: 'asset_add',
    permissions: ['asset_add_post']  // ← 确保权限编码正确
  }
}

// 检查权限是否已分配
1
2
3
4
5
6
7
8
9

# 4. 审计日志未记录

问题: 操作后没有审计日志

解决:

# 检查审计配置
cat appsettings.json | grep Auditing

# 检查是否被 [DisableAuditing] 禁用
# 检查 AuditLog 表是否正常
1
2
3
4
5

# 📚 相关文档


# 🔗 参考链接


最后更新: 2022-08-07