Files
backend/.qoder/repowiki/zh/content/API参考/档案API/详情查询.md
lan a4b6c5011e
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
chore(git): 更新.gitignore以忽略新的本地文件
2025-11-30 08:33:17 +08:00

299 lines
14 KiB
Markdown
Raw 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.

# 详情查询
<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)
- [profile.go](file://internal/model/profile.go)
- [texture.go](file://internal/model/texture.go)
- [response.go](file://internal/model/response.go)
- [common.go](file://internal/types/common.go)
- [postgres.go](file://pkg/database/postgres.go)
- [yggdrasil_handler.go](file://internal/handler/yggdrasil_handler.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
## 简介
本文件面向“详情查询”API聚焦 GET /api/v1/profile/:uuid 端点。该接口为公开路由无需认证即可访问用于根据Minecraft用户UUID获取档案的公开信息。响应体包含档案UUID、用户名、创建时间、最后使用时间、活跃状态以及关联的皮肤和披风信息若存在。该接口在Minecraft客户端通过Yggdrasil协议连接服务器时可被用于查询玩家档案信息以支持皮肤/披风展示等场景。
## 项目结构
围绕“详情查询”API的关键文件组织如下
- 路由注册:在路由层定义公开的 GET /api/v1/profile/:uuid并将其挂载到 v1 分组下。
- 处理器:实现 GetProfile 处理函数,负责参数解析、调用服务层、构造统一响应。
- 服务层:封装业务逻辑,调用仓库层进行数据查询。
- 仓库层基于GORM执行数据库查询预加载皮肤/披风关联。
- 模型与类型:定义档案模型、响应结构、纹理类型等。
- 数据库PostgreSQL驱动与连接池配置。
```mermaid
graph TB
subgraph "路由层"
R["routes.go<br/>注册 /api/v1/profile/:uuid"]
end
subgraph "处理器层"
H["profile_handler.go<br/>GetProfile 处理函数"]
end
subgraph "服务层"
S["profile_service.go<br/>GetProfileByUUID"]
end
subgraph "仓库层"
REPO["profile_repository.go<br/>FindProfileByUUID"]
end
subgraph "模型与类型"
M["profile.go<br/>Profile/ProfileResponse"]
T["texture.go<br/>Texture"]
RESP["response.go<br/>统一响应结构"]
TYPES["common.go<br/>ProfileInfo"]
end
subgraph "数据库"
DB["postgres.go<br/>PostgreSQL 连接与配置"]
end
R --> H
H --> S
S --> REPO
REPO --> DB
H --> RESP
S --> M
REPO --> M
M --> T
H --> TYPES
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [profile.go](file://internal/model/profile.go#L7-L24)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [response.go](file://internal/model/response.go#L1-L86)
- [common.go](file://internal/types/common.go#L154-L165)
- [postgres.go](file://pkg/database/postgres.go#L13-L74)
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
## 核心组件
- 路由层:在 v1 分组下注册 GET /api/v1/profile/:uuid明确该端点为公开路由无需JWT认证。
- 处理器层GetProfile 从路径参数读取 uuid调用服务层查询档案构造统一响应。
- 服务层GetProfileByUUID 调用仓库层查询档案;若未找到返回“档案不存在”错误。
- 仓库层FindProfileByUUID 使用 uuid 条件查询,并预加载 Skin 和 Cape 关联。
- 模型与类型Profile 定义档案字段及关联ProfileResponse 为对外响应结构ProfileInfo 为处理器侧返回结构Texture 定义材质模型及其索引字段。
- 统一响应response.go 提供统一的 Response/Error 结构,便于前后端约定。
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [profile.go](file://internal/model/profile.go#L7-L24)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [response.go](file://internal/model/response.go#L1-L86)
- [common.go](file://internal/types/common.go#L154-L165)
## 架构总览
下面的序列图展示了客户端调用 GET /api/v1/profile/:uuid 的典型流程以及与Yggdrasil协议的集成场景。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "Gin 路由"
participant Handler as "GetProfile 处理器"
participant Service as "profile_service.GetProfileByUUID"
participant Repo as "profile_repository.FindProfileByUUID"
participant DB as "PostgreSQL"
Client->>Router : "GET /api/v1/profile/ : uuid"
Router->>Handler : "路由分发"
Handler->>Service : "GetProfileByUUID(uuid)"
Service->>Repo : "FindProfileByUUID(uuid)"
Repo->>DB : "SELECT ... WHERE uuid=?<br/>并预加载 Skin/Cape"
DB-->>Repo : "Profile 记录"
Repo-->>Service : "Profile 对象"
Service-->>Handler : "Profile 对象"
Handler-->>Client : "200 + 统一响应体"
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [postgres.go](file://pkg/database/postgres.go#L13-L74)
## 详细组件分析
### 接口定义与行为
- 路由:公开端点 GET /api/v1/profile/:uuid无需认证。
- 请求参数:路径参数 uuidMinecraft档案UUID
- 成功响应:返回统一响应结构,包含档案基本信息与关联皮肤/披风信息。
- 错误响应当档案不存在时返回404。
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [response.go](file://internal/model/response.go#L1-L86)
### 响应数据结构
- 响应体字段(对外):
- uuid档案UUID
- nameMinecraft角色名
- textures包含皮肤与披风信息的对象
- SKIN皮肤信息可选
- url皮肤图片地址
- metadata元数据可选
- model皮肤模型slim 或 classic
- CAPE披风信息可选
- url披风图片地址
- metadata元数据可选
- is_active是否为活跃档案
- last_used_at最后使用时间可选
- created_at创建时间
- updated_at更新时间
- 处理器侧返回结构ProfileInfo
- uuid、user_id、name、skin_id、cape_id、is_active、last_used_at、created_at、updated_at
章节来源
- [profile.go](file://internal/model/profile.go#L31-L57)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [common.go](file://internal/types/common.go#L154-L165)
### 查询流程与错误码
- 正常流程:处理器读取 uuid -> 服务层查询 -> 仓库层查询并预加载关联 -> 返回统一响应。
- 错误码:
- 404档案不存在
- 500服务器内部错误数据库异常、服务层错误等
```mermaid
flowchart TD
Start(["进入 GetProfile"]) --> Parse["解析路径参数 uuid"]
Parse --> Query["调用服务层 GetProfileByUUID"]
Query --> RepoCall["仓库层 FindProfileByUUID(uuid)"]
RepoCall --> Found{"找到记录?"}
Found --> |是| BuildResp["组装响应含 textures"]
Found --> |否| NotFound["返回 404 档案不存在"]
BuildResp --> Ok["返回 200 + 统一响应"]
NotFound --> End(["结束"])
Ok --> End
```
图表来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [response.go](file://internal/model/response.go#L1-L86)
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [response.go](file://internal/model/response.go#L1-L86)
### 与Yggdrasil协议的集成场景
- 在Minecraft客户端连接服务器时可通过Yggdrasil的会话服务器端点获取玩家档案信息从而展示皮肤/披风。
- 该端点与Yggdrasil的会话服务器端点存在语义上的互补前者为公开档案详情查询后者为认证后的会话信息查询。
- 典型调用链:客户端 -> 服务器Yggdrasil-> 本系统 GetProfileByUUID公开详情查询
章节来源
- [yggdrasil_handler.go](file://internal/handler/yggdrasil_handler.go#L426-L440)
## 依赖分析
- 路由层依赖 Gin 路由注册,将公开端点挂载至 v1 分组。
- 处理器层依赖服务层与统一响应结构。
- 服务层依赖仓库层与数据库连接。
- 仓库层依赖 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"]
Handler --> Resp["response.go"]
Service --> Model["profile.go"]
Repo --> Model
Model --> Texture["texture.go"]
Handler --> Types["common.go"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [postgres.go](file://pkg/database/postgres.go#L13-L74)
- [profile.go](file://internal/model/profile.go#L7-L24)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [response.go](file://internal/model/response.go#L1-L86)
- [common.go](file://internal/types/common.go#L154-L165)
章节来源
- [routes.go](file://internal/handler/routes.go#L63-L79)
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [postgres.go](file://pkg/database/postgres.go#L13-L74)
- [profile.go](file://internal/model/profile.go#L7-L24)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [response.go](file://internal/model/response.go#L1-L86)
- [common.go](file://internal/types/common.go#L154-L165)
## 性能考量
- 数据库索引与查询优化
- Profile 表的 uuid 字段为主键,查询命中主键索引,具备高效率。
- Profile 表的 name 字段具有唯一索引,有助于去重与唯一性约束。
- Profile 表的 user_id 字段具有普通索引,有利于按用户维度查询。
- Profile 表的 is_active 字段具有索引,便于筛选活跃档案。
- Texture 表的 hash 字段具有唯一索引,有利于快速定位材质。
- Texture 表的 uploader_id、is_public、favorite_count、download_count 等字段具有索引,便于检索与排序。
- 关联预加载
- 仓库层在查询档案时使用预加载Preload加载 Skin 与 Cape减少 N+1 查询风险,提升响应速度。
- 数据库连接池
- PostgreSQL 驱动初始化时配置了连接池参数(最大空闲连接、最大打开连接、连接最大生命周期),有助于并发场景下的稳定性与吞吐量。
- 缓存建议
- 对高频查询的档案详情可引入缓存如Redis以进一步降低数据库压力。
- 缓存键可采用 profile:{uuid},并设置合理过期时间(如几分钟)。
- 日志与监控
- 处理器层记录错误日志,便于定位慢查询与异常。
- 建议增加指标埋点如QPS、P95/P99延迟、错误率以便持续优化。
章节来源
- [profile_repository.go](file://internal/repository/profile_repository.go#L19-L31)
- [profile.go](file://internal/model/profile.go#L7-L24)
- [texture.go](file://internal/model/texture.go#L16-L35)
- [postgres.go](file://pkg/database/postgres.go#L13-L74)
## 故障排查指南
- 404 档案不存在
- 现象:请求返回 404消息提示“档案不存在”。
- 排查:确认 uuid 是否正确;检查数据库中是否存在该 uuid 的档案记录。
- 500 服务器内部错误
- 现象:请求返回 500消息提示服务层或仓库层错误。
- 排查:查看处理器层日志;检查数据库连接与连接池配置;确认 GORM 查询是否报错。
- 响应缺少皮肤/披风信息
- 现象textures 字段为空或部分缺失。
- 排查:确认档案是否绑定了皮肤/披风;检查关联表是否存在有效记录;确认仓库层预加载是否生效。
- Yggdrasil集成问题
- 现象:客户端无法显示皮肤/披风。
- 排查确认客户端调用的Yggdrasil端点与本系统公开详情查询端点是否一致核对响应结构与字段命名是否匹配。
章节来源
- [profile_handler.go](file://internal/handler/profile_handler.go#L153-L195)
- [profile_service.go](file://internal/service/profile_service.go#L71-L81)
- [response.go](file://internal/model/response.go#L1-L86)
## 结论
GET /api/v1/profile/:uuid 作为公开端点提供了基于Minecraft档案UUID的详情查询能力。其架构清晰、职责分明路由层公开、处理器层编排、服务层封装、仓库层持久化、模型层定义。响应体包含档案基础信息与皮肤/披风信息满足客户端在Yggdrasil协议下的集成需求。通过合理的数据库索引、关联预加载与连接池配置可在高并发场景下保持稳定与高效。建议结合缓存与监控体系持续优化查询性能与用户体验。