336 lines
13 KiB
Markdown
336 lines
13 KiB
Markdown
|
|
# 档案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(如模型类型)
|
|||
|
|
- 请求/响应类型
|
|||
|
|
- CreateProfileRequest:name(必填,1-16字符)
|
|||
|
|
- UpdateProfileRequest:name(可选)、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)
|