Files
huang eaa70ac255 feat: 实现 RBAC 权限系统和数据权限控制 (004-rbac-data-permission)
主要功能:
- 实现完整的 RBAC 权限系统(账号、角色、权限的多对多关联)
- 基于 owner_id + shop_id 的自动数据权限过滤
- 使用 PostgreSQL WITH RECURSIVE 查询下级账号
- Redis 缓存优化下级账号查询性能(30分钟过期)
- 支持多租户数据隔离和层级权限管理

技术实现:
- 新增 Account、Role、Permission 模型及关联关系表
- 实现 GORM Scopes 自动应用数据权限过滤
- 添加数据库迁移脚本(000002_rbac_data_permission、000003_add_owner_id_shop_id)
- 完善错误码定义(1010-1027 为 RBAC 相关错误)
- 重构 main.go 采用函数拆分提高可读性

测试覆盖:
- 添加 Account、Role、Permission 的集成测试
- 添加数据权限过滤的单元测试和集成测试
- 添加下级账号查询和缓存的单元测试
- 添加 API 回归测试确保向后兼容

文档更新:
- 更新 README.md 添加 RBAC 功能说明
- 更新 CLAUDE.md 添加技术栈和开发原则
- 添加 docs/004-rbac-data-permission/ 功能总结和使用指南

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:44:06 +08:00

483 lines
13 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: Permission Management API
description: RBAC 权限管理接口 - 支持权限的创建、查询、更新、删除,支持层级关系
version: 1.0.0
servers:
- url: http://localhost:8080/api/v1
description: Development server
tags:
- name: permissions
description: 权限管理
paths:
/permissions:
post:
summary: 创建权限
description: 创建新权限,支持层级关系(通过 parent_id
tags:
- permissions
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePermissionRequest'
responses:
'200':
description: 创建成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/PermissionResponse'
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
get:
summary: 查询权限列表
description: 分页查询权限列表,支持按类型和父权限过滤
tags:
- permissions
parameters:
- name: page
in: query
description: 页码(从 1 开始)
schema:
type: integer
default: 1
minimum: 1
- name: page_size
in: query
description: 每页大小
schema:
type: integer
default: 20
minimum: 1
maximum: 100
- name: perm_type
in: query
description: 权限类型过滤1=菜单, 2=按钮)
schema:
type: integer
enum: [1, 2]
- name: parent_id
in: query
description: 父权限 ID 过滤(查询指定权限的子权限)
schema:
type: integer
- name: status
in: query
description: 状态过滤0=禁用, 1=启用)
schema:
type: integer
enum: [0, 1]
responses:
'200':
description: 查询成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/ListPermissionsResponse'
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
/permissions/{id}:
get:
summary: 查询权限详情
description: 根据 ID 查询权限详情
tags:
- permissions
parameters:
- name: id
in: path
required: true
description: 权限 ID
schema:
type: integer
responses:
'200':
description: 查询成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/PermissionResponse'
'404':
description: 权限不存在
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
put:
summary: 更新权限
description: 更新权限信息
tags:
- permissions
parameters:
- name: id
in: path
required: true
description: 权限 ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdatePermissionRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/PermissionResponse'
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'404':
description: 权限不存在
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
delete:
summary: 删除权限
description: 软删除权限,设置 deleted_at 字段
tags:
- permissions
parameters:
- name: id
in: path
required: true
description: 权限 ID
schema:
type: integer
responses:
'200':
description: 删除成功
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'404':
description: 权限不存在
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
/permissions/tree:
get:
summary: 查询权限树
description: 查询完整的权限层级树结构(菜单和按钮的层级关系)
tags:
- permissions
responses:
'200':
description: 查询成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/PermissionTreeNode'
'500':
description: 服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
components:
schemas:
ApiResponse:
type: object
required:
- code
- message
- timestamp
properties:
code:
type: integer
description: 错误码0 表示成功1xxx 表示客户端错误2xxx 表示服务端错误)
example: 0
message:
type: string
description: 响应消息
example: success
data:
type: object
description: 响应数据
timestamp:
type: string
format: date-time
description: 响应时间戳ISO 8601 格式)
example: "2025-11-18T15:30:00Z"
CreatePermissionRequest:
type: object
required:
- perm_name
- perm_code
- perm_type
properties:
perm_name:
type: string
maxLength: 50
description: 权限名称
example: 用户管理
perm_code:
type: string
maxLength: 100
pattern: '^[a-z]+:[a-z]+$'
description: 权限编码格式module:action如 user:create
example: user:create
perm_type:
type: integer
enum: [1, 2]
description: 权限类型1=菜单, 2=按钮)
example: 1
url:
type: string
maxLength: 255
description: URL 路径(菜单权限必填,按钮权限可选)
example: /admin/users
parent_id:
type: integer
nullable: true
description: 上级权限 ID顶级权限为 null
example: null
sort:
type: integer
default: 0
description: 排序序号(数字越小越靠前)
example: 1
status:
type: integer
enum: [0, 1]
default: 1
description: 状态0=禁用, 1=启用)
example: 1
UpdatePermissionRequest:
type: object
properties:
perm_name:
type: string
maxLength: 50
description: 权限名称(可选更新)
example: 用户管理模块
perm_code:
type: string
maxLength: 100
pattern: '^[a-z]+:[a-z]+$'
description: 权限编码(可选更新)
example: user:manage
url:
type: string
maxLength: 255
description: URL 路径(可选更新)
example: /admin/users/manage
sort:
type: integer
description: 排序序号(可选更新)
example: 2
status:
type: integer
enum: [0, 1]
description: 状态(可选更新)
example: 0
PermissionResponse:
type: object
properties:
id:
type: integer
description: 权限 ID
example: 1
perm_name:
type: string
description: 权限名称
example: 用户管理
perm_code:
type: string
description: 权限编码
example: user:create
perm_type:
type: integer
description: 权限类型1=菜单, 2=按钮)
example: 1
url:
type: string
description: URL 路径
example: /admin/users
parent_id:
type: integer
nullable: true
description: 上级权限 ID
example: null
sort:
type: integer
description: 排序序号
example: 1
status:
type: integer
description: 状态0=禁用, 1=启用)
example: 1
creator:
type: integer
description: 创建人 ID
example: 1
updater:
type: integer
description: 更新人 ID
example: 1
created_at:
type: string
format: date-time
description: 创建时间
example: "2025-11-18T10:00:00Z"
updated_at:
type: string
format: date-time
description: 更新时间
example: "2025-11-18T10:00:00Z"
ListPermissionsResponse:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/PermissionResponse'
total:
type: integer
description: 总记录数
example: 80
page:
type: integer
description: 当前页码
example: 1
page_size:
type: integer
description: 每页大小
example: 20
PermissionTreeNode:
type: object
description: 权限树节点(包含子权限)
properties:
id:
type: integer
description: 权限 ID
example: 1
perm_name:
type: string
description: 权限名称
example: 系统管理
perm_code:
type: string
description: 权限编码
example: system:manage
perm_type:
type: integer
description: 权限类型1=菜单, 2=按钮)
example: 1
url:
type: string
description: URL 路径
example: /admin/system
sort:
type: integer
description: 排序序号
example: 1
status:
type: integer
description: 状态0=禁用, 1=启用)
example: 1
children:
type: array
description: 子权限列表
items:
$ref: '#/components/schemas/PermissionTreeNode'
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- BearerAuth: []