重构数据权限模型并清理旧RBAC代码
核心变更: - 数据权限过滤从基于账号层级改为基于用户类型的多策略过滤 - 移除 AccountStore 中的 GetSubordinateIDs 等旧方法 - 重构认证中间件,支持 enterprise_id 和 customer_id - 更新 GORM Callback,根据用户类型自动选择过滤策略(代理/企业/个人客户) - 更新所有集成测试以适配新的 API 签名 - 添加功能总结文档和 OpenSpec 归档 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
44
README.md
44
README.md
@@ -19,7 +19,7 @@
|
||||
- **统一错误处理**:全局 ErrorHandler 统一处理所有 API 错误,返回一致的 JSON 格式(包含错误码、消息、时间戳);Panic 自动恢复防止服务崩溃;错误分类处理(客户端 4xx、服务端 5xx)和日志级别控制;敏感信息自动脱敏保护
|
||||
- **数据持久化**:GORM + PostgreSQL 集成,提供完整的 CRUD 操作、事务支持和数据库迁移能力
|
||||
- **异步任务处理**:Asynq 任务队列集成,支持任务提交、后台执行、自动重试和幂等性保障,实现邮件发送、数据同步等异步任务
|
||||
- **RBAC 权限系统**:完整的基于角色的访问控制,支持账号、角色、权限的多对多关联和层级关系;基于 owner_id + shop_id 的自动数据权限过滤,实现多租户数据隔离;使用 PostgreSQL WITH RECURSIVE 查询下级账号并通过 Redis 缓存优化性能(详见 [功能总结](docs/004-rbac-data-permission/功能总结.md) 和 [使用指南](docs/004-rbac-data-permission/使用指南.md))
|
||||
- **RBAC 权限系统**:完整的基于角色的访问控制,支持账号、角色、权限的多对多关联和层级关系;基于店铺层级的自动数据权限过滤,实现多租户数据隔离;使用 PostgreSQL WITH RECURSIVE 查询下级店铺并通过 Redis 缓存优化性能(详见 [功能总结](docs/004-rbac-data-permission/功能总结.md) 和 [使用指南](docs/004-rbac-data-permission/使用指南.md))
|
||||
- **生命周期管理**:物联网卡/号卡的开卡、激活、停机、复机、销户
|
||||
- **代理商体系**:层级管理和分佣结算
|
||||
- **批量同步**:卡状态、实名状态、流量使用情况
|
||||
@@ -51,8 +51,9 @@
|
||||
### 核心设计决策
|
||||
|
||||
- **层级关系在店铺之间维护**:代理上下级关系通过 `Shop.parent_id` 维护,而非账号之间
|
||||
- **数据权限基于店铺归属**:数据过滤使用 `shop_id IN (当前店铺及下级店铺)`,不是 `owner_id`
|
||||
- **数据权限基于店铺归属**:数据过滤使用 `shop_id IN (当前店铺及下级店铺)`
|
||||
- **递归查询+Redis缓存**:使用 `GetSubordinateShopIDs()` 递归查询下级店铺ID,结果缓存30分钟
|
||||
- **GORM 自动过滤**:通过 GORM Callback 自动应用数据权限过滤,无需在每个查询手动添加条件
|
||||
- **禁止外键约束**:遵循项目原则,表之间通过ID字段关联,关联查询在代码层显式执行
|
||||
- **GORM字段显式命名**:所有模型字段必须显式指定 `gorm:"column:field_name"` 标签
|
||||
|
||||
@@ -100,6 +101,45 @@ tb_account (账号表 - 已修改)
|
||||
- [设计文档](openspec/changes/add-user-organization-model/design.md)
|
||||
- [提案文档](openspec/changes/add-user-organization-model/proposal.md)
|
||||
|
||||
## 数据权限模型
|
||||
|
||||
系统采用基于用户类型的自动数据权限过滤策略,通过 GORM Callback 自动应用,无需在每个查询中手动添加过滤条件。
|
||||
|
||||
### 过滤规则
|
||||
|
||||
| 用户类型 | 过滤策略 | 示例 |
|
||||
|---------|---------|------|
|
||||
| 超级管理员(Super Admin) | 跳过过滤,查看所有数据 | - |
|
||||
| 平台用户(Platform) | 跳过过滤,查看所有数据 | - |
|
||||
| 代理账号(Agent) | 基于店铺层级过滤 | `WHERE shop_id IN (当前店铺及下级店铺)` |
|
||||
| 企业账号(Enterprise) | 基于企业归属过滤 | `WHERE enterprise_id = 当前企业ID` |
|
||||
| 个人客户(Personal Customer) | 基于创建者过滤 | `WHERE creator = 当前用户ID` |
|
||||
|
||||
### 工作机制
|
||||
|
||||
1. **认证中间件**设置完整用户上下文(`UserContextInfo`)到 `context` 中
|
||||
2. **GORM Callback**在每次查询前自动注入过滤条件
|
||||
3. **递归查询 + 缓存**:代理用户的下级店铺 ID 通过 `GetSubordinateShopIDs()` 递归查询,结果缓存 30 分钟
|
||||
4. **跳过过滤**:特殊场景(如统计、后台任务)可使用 `SkipDataPermission(ctx)` 绕过过滤
|
||||
|
||||
### 使用示例
|
||||
|
||||
```go
|
||||
// 1. 认证后 context 已自动包含用户信息
|
||||
ctx := c.UserContext()
|
||||
|
||||
// 2. 所有 Store 层查询自动应用数据权限过滤
|
||||
orders, err := orderStore.List(ctx) // 自动过滤为当前用户可见的订单
|
||||
|
||||
// 3. 需要查询所有数据时,显式跳过过滤
|
||||
ctx = gorm.SkipDataPermission(ctx)
|
||||
allOrders, err := orderStore.List(ctx) // 查询所有订单(仅限特殊场景)
|
||||
```
|
||||
|
||||
详细说明参见:
|
||||
- [数据权限清理总结](docs/remove-legacy-rbac-cleanup/清理总结.md)
|
||||
- [RBAC 权限使用指南](docs/004-rbac-data-permission/使用指南.md)
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user