Files
backend/.qoder/repowiki/zh/content/API参考/档案API/档案API.md

336 lines
13 KiB
Markdown
Raw Normal View History

# 档案API
<cite>
**本文引用的文件**
- [routes.go](file://internal/handler/routes.go)
- [profile_handler.go](file://internal/handler/profile_handler.go)
- [profile_service.go](file://internal/service/profile_service.go)
- [profile_repository.go](file://internal/repository/profile_repository.go)
- [common.go](file://internal/types/common.go)
- [response.go](file://internal/model/response.go)
- [profile.go](file://internal/model/profile.go)
- [texture.go](file://internal/model/texture.go)
- [texture_service.go](file://internal/service/texture_service.go)
- [texture_repository.go](file://internal/repository/texture_repository.go)
- [postgres.go](file://pkg/database/postgres.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向开发者与集成方系统化梳理“档案API”的设计与使用方法覆盖以下能力
- 档案的创建、查询、更新、删除与“活跃档案”设置
- 公开获取档案详情与需要认证的档案管理端点
- 档案与Minecraft用户UUID的关系、活跃档案的概念
- 档案列表的获取方式
- 完整的API使用示例包括创建档案的请求体结构与获取档案详情的响应格式
- 档案与材质之间的关系
## 项目结构
档案API位于路由组 `/api/v1/profile` 下,采用“公开路由 + 认证路由”的分层设计:
- 公开路由通过档案UUID获取档案详情
- 认证路由需要携带JWT令牌支持创建、查询列表、更新、删除、设置活跃档案
```mermaid
graph TB
subgraph "路由组 /api/v1/profile"
A["GET /:uuid<br/>公开:获取档案详情"]
subgraph "认证组"
B["POST /<br/>创建档案"]
C["GET /<br/>获取我的档案列表"]
D["PUT /:uuid<br/>更新档案"]
E["DELETE /:uuid<br/>删除档案"]
F["POST /:uuid/activate<br/>设置活跃档案"]
end
end
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
## 核心组件
- 路由注册:集中于路由文件,定义公开与认证端点
- 处理器profile_handler 负责鉴权、参数解析、调用服务层并返回统一响应
- 服务层profile_service 实现业务规则如创建档案时生成UUID与RSA私钥、设置活跃状态、权限校验等
- 仓储层profile_repository 封装数据库操作(增删改查、统计、事务)
- 类型与模型types 中定义请求/响应结构model 中定义档案与材质模型及响应结构
- 数据库通过GORM连接PostgreSQL统一日志与连接池配置
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [profile_service.go](file://internal/service/profile_service.go#L1-L253)
- [profile_repository.go](file://internal/repository/profile_repository.go#L1-L200)
- [common.go](file://internal/types/common.go#L81-L207)
- [response.go](file://internal/model/response.go#L1-L86)
- [profile.go](file://internal/model/profile.go#L1-L64)
- [texture.go](file://internal/model/texture.go#L1-L77)
- [postgres.go](file://pkg/database/postgres.go#L1-L74)
## 架构总览
档案API遵循经典的三层架构HTTP路由 -> 处理器 -> 服务 -> 仓储 -> 数据库。认证中间件确保仅持有有效令牌的用户可访问受保护端点。
```mermaid
graph TB
Client["客户端"] --> R["Gin 路由<br/>/api/v1/profile"]
R --> M["认证中间件"]
M --> H["处理器<br/>profile_handler"]
H --> S["服务层<br/>profile_service"]
S --> Repo["仓储层<br/>profile_repository"]
Repo --> DB["数据库<br/>PostgreSQL(GORM)"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [profile_service.go](file://internal/service/profile_service.go#L1-L253)
- [profile_repository.go](file://internal/repository/profile_repository.go#L1-L200)
- [postgres.go](file://pkg/database/postgres.go#L1-L74)
## 详细组件分析
### 路由与端点
- 公开端点
- GET /api/v1/profile/:uuid根据UUID获取档案详情
- 认证端点
- POST /api/v1/profile创建档案
- GET /api/v1/profile获取当前用户的所有档案列表
- PUT /api/v1/profile/:uuid更新档案可更新角色名、皮肤ID、披风ID
- DELETE /api/v1/profile/:uuid删除档案
- POST /api/v1/profile/:uuid/activate设置活跃档案同时将该用户其他档案设为非活跃
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
### 处理器与鉴权
- 认证中间件所有认证端点均使用认证中间件从上下文提取user_id
- 参数绑定使用Gin的ShouldBindJSON进行请求体校验
- 统一响应:使用统一响应结构,错误码与消息标准化
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [response.go](file://internal/model/response.go#L1-L86)
### 服务层业务规则
- 创建档案
- 校验用户存在且状态正常
- 校验角色名唯一
- 生成UUID与RSA私钥PEM格式
- 默认设置为活跃档案,并将该用户其他档案设为非活跃
- 更新档案
- 校验档案归属(仅档案所属用户可更新)
- 校验新角色名唯一
- 支持更新角色名、皮肤ID、披风ID
- 删除档案
- 校验档案归属
- 设置活跃档案
- 校验档案归属
- 使用事务将该用户其他档案设为非活跃,再将目标档案设为活跃
- 同步更新最后使用时间
- 档案数量限制
- 通过服务层检查当前用户档案数量是否超过上限
章节来源
- [profile_service.go](file://internal/service/profile_service.go#L1-L253)
### 仓储层与数据库
- 查询
- FindProfileByUUID按UUID查询并预加载皮肤与披风
- FindProfilesByUserID按用户ID查询并预加载皮肤与披风按创建时间倒序
- FindProfileByName按角色名查询
- 更新
- UpdateProfile、UpdateProfileFields
- 删除
- DeleteProfile按UUID删除
- 统计
- CountProfilesByUserID
- 活跃状态
- SetActiveProfile事务内将该用户其他档案设为非活跃再将目标档案设为活跃
- 最后使用时间
- UpdateProfileLastUsedAt
章节来源
- [profile_repository.go](file://internal/repository/profile_repository.go#L1-L200)
### 模型与类型
- 档案模型
- 字段UUID、用户ID、角色名、皮肤ID、披风ID、活跃状态、最后使用时间、创建/更新时间
- 关联User、Skin(Texture)、Cape(Texture)
- 档案响应结构
- ProfileResponse包含UUID、角色名、textures皮肤/披风)、活跃状态、最后使用时间、创建时间
- ProfileTexturesData包含SKIN与CAPE两个可选字段
- ProfileTexture包含URL与可选metadata如模型类型
- 请求/响应类型
- CreateProfileRequestname必填1-16字符
- UpdateProfileRequestname可选、skin_id可选、cape_id可选
- ProfileInfo用于列表与详情的统一返回字段
章节来源
- [profile.go](file://internal/model/profile.go#L1-L64)
- [common.go](file://internal/types/common.go#L81-L207)
### 档案与材质的关系
- 档案可关联两种材质皮肤SkinID与披风CapeID
- 材质模型包含类型SKIN/CAPE、URL、哈希、大小、公开状态等
- 服务层与仓储层均支持对材质的创建、查询、更新、删除、收藏等操作但这些属于独立的材质API范畴
章节来源
- [profile.go](file://internal/model/profile.go#L1-L64)
- [texture.go](file://internal/model/texture.go#L1-L77)
- [texture_service.go](file://internal/service/texture_service.go#L1-L252)
- [texture_repository.go](file://internal/repository/texture_repository.go#L1-L232)
### API使用示例
- 创建档案
- 方法与路径POST /api/v1/profile
- 认证需要JWT
- 请求体结构CreateProfileRequest
- name字符串必填长度1-16
- 成功响应返回ProfileInfo包含UUID、用户ID、角色名、皮肤ID、披风ID、活跃状态、最后使用时间、创建/更新时间)
- 常见错误400参数错误/达到档案数量上限、401未授权、500服务器错误
- 获取我的档案列表
- 方法与路径GET /api/v1/profile
- 认证需要JWT
- 成功响应数组元素为ProfileInfo
- 获取档案详情
- 方法与路径GET /api/v1/profile/{uuid}
- 认证公开端点无需JWT
- 成功响应ProfileInfo
- 更新档案
- 方法与路径PUT /api/v1/profile/{uuid}
- 认证需要JWT
- 请求体结构UpdateProfileRequest
- name字符串可选长度1-16
- skin_id整数可选
- cape_id整数可选
- 成功响应ProfileInfo
- 删除档案
- 方法与路径DELETE /api/v1/profile/{uuid}
- 认证需要JWT
- 成功响应:{"message":"删除成功"}
- 设置活跃档案
- 方法与路径POST /api/v1/profile/{uuid}/activate
- 认证需要JWT
- 成功响应:{"message":"设置成功"}
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [common.go](file://internal/types/common.go#L81-L207)
- [response.go](file://internal/model/response.go#L1-L86)
### 活跃档案概念
- 每个用户在同一时刻只能有一个“活跃档案”
- 当创建新档案或切换活跃档案时,系统会将该用户其他档案设为非活跃
- 设置活跃档案会同步更新最后使用时间
章节来源
- [profile_service.go](file://internal/service/profile_service.go#L1-L253)
- [profile_repository.go](file://internal/repository/profile_repository.go#L89-L117)
### 档案列表获取方式
- 通过认证端点 GET /api/v1/profile 获取当前用户的所有档案
- 返回顺序按创建时间倒序
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L95-L151)
- [profile_service.go](file://internal/service/profile_service.go#L83-L90)
- [profile_repository.go](file://internal/repository/profile_repository.go#L44-L57)
### 档案与Minecraft用户UUID的关系
- 档案模型包含UUID字段用于标识Minecraft角色
- 档案与用户通过user_id关联
- 公开端点通过UUID获取档案详情不涉及用户身份
章节来源
- [profile.go](file://internal/model/profile.go#L1-L64)
- [routes.go](file://internal/handler/routes.go#L63-L79)
## 依赖分析
- 路由到处理器:路由文件注册各端点,处理器负责鉴权与参数解析
- 处理器到服务:处理器调用服务层实现业务逻辑
- 服务到仓储:服务层封装业务规则并委托仓储层执行数据库操作
- 仓储到数据库仓储层通过GORM访问PostgreSQL
```mermaid
graph LR
Routes["routes.go"] --> Handler["profile_handler.go"]
Handler --> Service["profile_service.go"]
Service --> Repo["profile_repository.go"]
Repo --> DB["postgres.go"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [profile_service.go](file://internal/service/profile_service.go#L1-L253)
- [profile_repository.go](file://internal/repository/profile_repository.go#L1-L200)
- [postgres.go](file://pkg/database/postgres.go#L1-L74)
## 性能考虑
- 预加载策略查询档案时预加载皮肤与披风减少N+1查询风险
- 分页与排序:列表查询按创建时间倒序,避免全量扫描
- 事务一致性:设置活跃档案使用事务,保证原子性
- 连接池:数据库连接池配置合理,建议结合实际负载调整
章节来源
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L57)
- [profile_service.go](file://internal/service/profile_service.go#L161-L188)
- [postgres.go](file://pkg/database/postgres.go#L1-L74)
## 故障排查指南
- 未授权
- 现象返回401
- 排查确认JWT是否正确传递与有效
- 参数错误
- 现象返回400
- 排查:检查请求体字段是否符合长度与类型要求
- 无权操作
- 现象返回403
- 排查:确认操作的档案是否属于当前用户
- 资源不存在
- 现象返回404
- 排查确认UUID是否正确、档案是否被删除
- 达到上限
- 现象返回400
- 排查:检查当前用户档案数量与系统限制
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L1-L399)
- [response.go](file://internal/model/response.go#L1-L86)
## 结论
档案API以清晰的公开/认证分层设计结合严格的鉴权与参数校验提供了完整的Minecraft角色档案生命周期管理能力。通过服务层的业务规则与仓储层的事务保障系统在一致性与扩展性方面具备良好基础。建议在生产环境中配合限流、缓存与监控进一步优化性能与稳定性。
## 附录
### API端点一览
- 公开
- GET /api/v1/profile/:uuid
- 认证
- POST /api/v1/profile
- GET /api/v1/profile
- PUT /api/v1/profile/:uuid
- DELETE /api/v1/profile/:uuid
- POST /api/v1/profile/:uuid/activate
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)