Files
2026-05-27 18:07:55 +08:00

513 lines
27 KiB
Markdown
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.
# 核心模块
<cite>
**本文引用的文件**
- [cmd/server/main.go](file://cmd/server/main.go)
- [internal/router/router.go](file://internal/router/router.go)
- [internal/config/config.go](file://internal/config/config.go)
- [internal/database/mysql.go](file://internal/database/mysql.go)
- [internal/cache/redis.go](file://internal/cache/redis.go)
- [internal/handler/brand.go](file://internal/handler/brand.go)
- [internal/handler/model.go](file://internal/handler/model.go)
- [internal/handler/model_list.go](file://internal/handler/model_list.go)
- [internal/handler/device.go](file://internal/handler/device.go)
- [internal/handler/health.go](file://internal/handler/health.go)
- [internal/repository/brand.go](file://internal/repository/brand.go)
- [internal/repository/model.go](file://internal/repository/model.go)
- [internal/model/brand.go](file://internal/model/brand.go)
- [internal/model/model.go](file://internal/model/model.go)
- [internal/response/response.go](file://internal/response/response.go)
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕 Luxsin 应用 API 的核心模块进行系统化文档化,重点覆盖以下方面:
- 业务处理器(Handler):负责接收请求、解析参数、调用仓库层、封装统一响应。
- 数据访问层(Repository):负责与数据库交互,执行查询与扫描逻辑。
- 数据模型(Model):定义持久化与对外传输的数据结构。
- 统一响应(Response):规范 HTTP 响应体格式,提供便捷的构造方法。
- 依赖注入与启动流程:从配置加载到服务启动、中间件装配、路由注册与资源管理。
- 错误处理与日志记录:在各层中的一致性错误处理与可观测性。
- 扩展最佳实践:如何新增模块、如何复用编码器、如何接入缓存与搜索引擎。
- 性能优化与并发安全:连接池、超时控制、上下文传播、Redis 并发安全。
## 项目结构
项目采用分层与按功能域组织的结构:
- cmd/server:应用入口,负责配置加载、外部依赖初始化、HTTP 服务器启动与优雅关闭。
- internal/config:集中式配置加载与校验。
- internal/database:数据库连接与连接池配置。
- internal/cacheRedis 客户端初始化。
- internal/search:搜索引擎客户端封装。
- internal/router:路由注册与中间件装配。
- internal/handler:业务处理器,面向具体 API 路由。
- internal/repository:数据访问层,封装 SQL 查询。
- internal/model:领域模型与传输模型。
- internal/response:统一响应体封装。
- pkg/*:通用工具包(如编码器、日志)。
```mermaid
graph TB
subgraph "入口与配置"
MAIN["cmd/server/main.go<br/>应用入口"]
CFG["internal/config/config.go<br/>配置加载"]
end
subgraph "基础设施"
DB["internal/database/mysql.go<br/>MySQL 连接与池"]
RDS["internal/cache/redis.go<br/>Redis 客户端"]
SRCH["internal/search/meilisearch.go<br/>搜索引擎客户端"]
LOG["pkg/logger/logger.go<br/>日志"]
end
subgraph "服务编排"
RT["internal/router/router.go<br/>路由与中间件"]
end
subgraph "业务层"
H_BRAND["internal/handler/brand.go<br/>品牌处理器"]
H_MODEL["internal/handler/model.go<br/>型号处理器"]
H_MLIST["internal/handler/model_list.go<br/>型号搜索处理器"]
H_DEV["internal/handler/device.go<br/>设备上报处理器"]
H_HEALTH["internal/handler/health.go<br/>健康检查处理器"]
end
subgraph "数据访问与模型"
REPO_BRAND["internal/repository/brand.go<br/>品牌仓库"]
REPO_MODEL["internal/repository/model.go<br/>型号仓库"]
MODEL_BRAND["internal/model/brand.go<br/>品牌模型"]
MODEL_MODEL["internal/model/model.go<br/>型号模型"]
RESP["internal/response/response.go<br/>统一响应"]
ENC["pkg/encode/base64.go<br/>Base64 编码器"]
end
MAIN --> CFG
MAIN --> DB
MAIN --> RDS
MAIN --> SRCH
MAIN --> LOG
MAIN --> RT
RT --> H_HEALTH
RT --> H_BRAND
RT --> H_MODEL
RT --> H_MLIST
RT --> H_DEV
H_BRAND --> REPO_BRAND
H_MODEL --> REPO_MODEL
H_MLIST --> SRCH
H_DEV --> RDS
REPO_BRAND --> DB
REPO_MODEL --> DB
H_BRAND --> RESP
H_MODEL --> RESP
H_MLIST --> RESP
H_HEALTH --> RESP
H_BRAND --> ENC
H_MODEL --> ENC
H_MLIST --> ENC
```
图表来源
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
- [internal/config/config.go:18-64](file://internal/config/config.go#L18-L64)
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
章节来源
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
## 核心组件
本节聚焦 Handler、Repository、Model、Response 四大核心模块的职责、协作方式与实现要点。
- Handler(业务处理器)
- 职责:解析请求参数、调用仓库或外部服务、封装统一响应;必要时进行参数校验与基础编码处理。
- 典型实现位置:
- 品牌列表:[internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
- 型号列表:[internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
- 型号搜索:[internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
- 设备上报:[internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
- 健康检查:[internal/handler/health.go:14-18](file://internal/handler/health.go#L14-L18)
- Repository(数据访问层)
- 职责:封装 SQL 查询、参数拼装、结果扫描与错误包装;支持上下文传播与超时控制。
- 典型实现位置:
- 品牌仓库:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50)
- 型号仓库:[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
- Model(数据模型)
- 职责:定义数据库字段映射与 JSON 序列化字段名;可选字段使用指针以区分空值与缺省。
- 典型实现位置:
- 品牌模型:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- 型号模型:[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
- Response(统一响应)
- 职责:统一响应体结构与常用状态构造方法,保证前后端契约一致。
- 典型实现位置:
- 统一响应:[internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
章节来源
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
## 架构总览
下图展示从请求进入至响应返回的关键路径,以及各层之间的依赖关系与调用方向。
```mermaid
sequenceDiagram
participant C as "客户端"
participant G as "Gin 路由<br/>internal/router/router.go"
participant H as "业务处理器<br/>internal/handler/*"
participant R as "仓库层<br/>internal/repository/*"
participant DB as "数据库<br/>internal/database/mysql.go"
participant S as "搜索引擎<br/>internal/search/meilisearch.go"
participant RC as "Redis<br/>internal/cache/redis.go"
participant RESP as "统一响应<br/>internal/response/response.go"
C->>G : "HTTP 请求"
G->>H : "匹配路由并调用处理器"
alt "品牌/型号列表"
H->>R : "调用仓库查询"
R->>DB : "执行 SQL 查询"
DB-->>R : "返回结果集"
R-->>H : "返回模型切片"
else "型号搜索"
H->>S : "调用搜索引擎"
S-->>H : "返回搜索结果"
else "设备上报"
H->>RC : "写入 Redis Hash"
RC-->>H : "返回写入结果"
end
H->>RESP : "构造统一响应"
RESP-->>C : "HTTP 响应"
```
图表来源
- [internal/router/router.go:21-38](file://internal/router/router.go#L21-L38)
- [internal/handler/brand.go:30-35](file://internal/handler/brand.go#L30-L35)
- [internal/handler/model.go:31-36](file://internal/handler/model.go#L31-L36)
- [internal/handler/model_list.go:37-42](file://internal/handler/model_list.go#L37-L42)
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
- [internal/repository/brand.go:31-35](file://internal/repository/brand.go#L31-L35)
- [internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46)
- [internal/response/response.go:15-21](file://internal/response/response.go#L15-L21)
## 详细组件分析
### Handler 层
- 品牌处理器(BrandHandler
- 关键点:读取查询参数、调用仓库、错误日志与统一错误响应、可选 Base64 响应。
- 参考路径:[internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
- 型号处理器(ModelHandler
- 关键点:多条件查询(品牌/名称模糊)、上下文传播、统一响应与错误处理。
- 参考路径:[internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
- 型号搜索处理器(ModelListHandler
- 关键点:搜索引擎客户端调用、count 参数限制、统一响应。
- 参考路径:[internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
- 设备上报处理器(DeviceHandler
- 关键点:参数校验、日志记录、Redis Hash 写入、错误处理。
- 参考路径:[internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
- 健康检查处理器(HealthHandler
- 关键点:简单响应,使用统一响应体。
- 参考路径:[internal/handler/health.go:14-18](file://internal/handler/health.go#L14-L18)
```mermaid
classDiagram
class BrandHandler {
-repo : BrandRepository
-log : Logger
+GetBrand(c)
}
class ModelHandler {
-repo : ModelRepository
-log : Logger
+GetModel(c)
}
class ModelListHandler {
-search : SearchClient
-log : Logger
+ModelList(c)
}
class DeviceHandler {
-redis : RedisClient
-log : Logger
+ReportDevInfo(c)
}
class HealthHandler {
+Check(c)
}
BrandHandler --> BrandRepository : "依赖"
ModelHandler --> ModelRepository : "依赖"
ModelListHandler --> SearchClient : "依赖"
DeviceHandler --> RedisClient : "依赖"
```
图表来源
- [internal/handler/brand.go:14-24](file://internal/handler/brand.go#L14-L24)
- [internal/handler/model.go:14-24](file://internal/handler/model.go#L14-L24)
- [internal/handler/model_list.go:14-24](file://internal/handler/model_list.go#L14-L24)
- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24)
- [internal/handler/health.go:8-12](file://internal/handler/health.go#L8-L12)
章节来源
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
### Repository 层
- 品牌仓库(BrandRepository
- 关键点:条件查询、排序、结果扫描。
- 参考路径:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50)
- 型号仓库(ModelRepository
- 关键点:多条件拼装、LIKE 模糊匹配、NullString 处理、上下文传播。
- 参考路径:[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
```mermaid
classDiagram
class BrandRepository {
-db : sql.DB
+List(ctx, brandName) []Brand
}
class ModelRepository {
-db : sql.DB
+List(ctx, brandName, modelName) []Model
}
class Brand {
+id : int
+name : string
}
class Model {
+id : int
+brandName : string
+name : string
+form : *string
+rig : *string
+source : *string
+eqKey : *string
+createAt : time
}
BrandRepository --> Brand : "返回"
ModelRepository --> Model : "返回"
```
图表来源
- [internal/repository/brand.go:12-50](file://internal/repository/brand.go#L12-L50)
- [internal/repository/model.go:12-94](file://internal/repository/model.go#L12-L94)
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
章节来源
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
### Model 层
- 品牌模型(Brand
- 字段:id、name
- 参考路径:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- 型号模型(Model
- 字段:id、brandName、name、form、rig、source、eqKey、createAt(可选字段使用指针)
- 参考路径:[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
章节来源
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
### Response 层
- 统一响应体(Body
- 字段:code、message、data
- 方法:OK、Fail、BadRequest、InternalError
- 参考路径:[internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
```mermaid
flowchart TD
Start(["进入处理器"]) --> Build["构造响应体<br/>OK/Fail/BadRequest/InternalError"]
Build --> Send["通过 Gin 写入 HTTP 响应"]
Send --> End(["完成"])
```
图表来源
- [internal/response/response.go:15-36](file://internal/response/response.go#L15-L36)
章节来源
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
### 编码与日志
- Base64 编码器(pkg/encode/base64.go
- 用途:在处理器中对响应进行 Base64 编码后输出字符串。
- 使用场景:品牌与型号列表的可选 Base64 输出。
- 参考路径:[internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44)[internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)[internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
- 日志(pkg/logger/logger.go
- 用途:全局日志初始化与结构化日志记录。
- 参考路径:[cmd/server/main.go:32-36](file://cmd/server/main.go#L32-L36)[internal/handler/brand.go:32-34](file://internal/handler/brand.go#L32-L34)[internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)[internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)[internal/handler/device.go:47-49](file://internal/handler/device.go#L47-L49)[internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
章节来源
- [internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44)
- [internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)
- [internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
- [cmd/server/main.go:32-36](file://cmd/server/main.go#L32-L36)
- [internal/handler/brand.go:32-34](file://internal/handler/brand.go#L32-L34)
- [internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
- [internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
- [internal/handler/device.go:47-49](file://internal/handler/device.go#L47-L49)
- [internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
## 依赖分析
- 启动与依赖注入
- 配置加载:[internal/config/config.go:18-64](file://internal/config/config.go#L18-L64)
- 数据库连接与池:[internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
- Redis 客户端:[internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
- 路由与中间件:[internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
- 入口程序:[cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
- 处理器与仓库的依赖
- 品牌处理器依赖品牌仓库:[internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23) → [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
- 型号处理器依赖型号仓库:[internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23) → [internal/repository/model.go:16](file://internal/repository/model.go#L16)
- 型号搜索处理器依赖搜索引擎客户端:[internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23) → [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
- 设备上报处理器依赖 Redis 客户端:[internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23) → [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
```mermaid
graph LR
MAIN["cmd/server/main.go"] --> CFG["internal/config/config.go"]
MAIN --> DB["internal/database/mysql.go"]
MAIN --> RDS["internal/cache/redis.go"]
MAIN --> RT["internal/router/router.go"]
RT --> H_BRAND["internal/handler/brand.go"]
RT --> H_MODEL["internal/handler/model.go"]
RT --> H_MLIST["internal/handler/model_list.go"]
RT --> H_DEV["internal/handler/device.go"]
H_BRAND --> REPO_BRAND["internal/repository/brand.go"]
H_MODEL --> REPO_MODEL["internal/repository/model.go"]
H_MLIST --> SRCH["internal/search/meilisearch.go"]
H_DEV --> RDS
REPO_BRAND --> DB
REPO_MODEL --> DB
```
图表来源
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
- [internal/router/router.go:21-38](file://internal/router/router.go#L21-L38)
- [internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23)
- [internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23)
- [internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23)
- [internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23)
- [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
- [internal/repository/model.go:16](file://internal/repository/model.go#L16)
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
章节来源
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
- [internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23)
- [internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23)
- [internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23)
- [internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23)
- [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
- [internal/repository/model.go:16](file://internal/repository/model.go#L16)
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
## 性能考量
- 数据库连接与池
- 最大并发连接数、最大空闲连接数、连接生命周期设置,有助于避免连接争用与资源泄漏。
- 参考路径:[internal/database/mysql.go:33-35](file://internal/database/mysql.go#L33-L35)
- 上下文与超时
- 仓库层使用 QueryContext 与 PingContext,确保超时控制与取消传播。
- 参考路径:[internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46)[internal/database/mysql.go:37-43](file://internal/database/mysql.go#L37-L43)
- Redis 并发安全
- 单个 Redis 客户端实例在 Go 中是并发安全的,可在多个 goroutine 中共享。
- 参考路径:[internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
- 响应体积与 Base64
- 对于大列表响应,可启用 Base64 输出以减少传输体积,但会增加 CPU 开销。
- 参考路径:[internal/handler/brand.go:37-44](file://internal/handler/branch.go#L37-L44)[internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)[internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
- 搜索性能
- 搜索结果数量限制(count)可有效控制响应规模,避免过量数据传输。
- 参考路径:[internal/handler/model_list.go:30-35](file://internal/handler/model_list.go#L30-L35)
章节来源
- [internal/database/mysql.go:33-35](file://internal/database/mysql.go#L33-L35)
- [internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46)
- [internal/database/mysql.go:37-43](file://internal/database/mysql.go#L37-L43)
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
- [internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44)
- [internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)
- [internal/handler/model_list.go:30-35](file://internal/handler/model_list.go#L30-L35)
- [internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
## 故障排查指南
- 常见错误类型与处理
- 数据库查询失败:在仓库层包装错误并在处理器记录日志与返回统一错误响应。
- 参考路径:[internal/repository/model.go:43-44](file://internal/repository/model.go#L43-L44)[internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
- 编码失败:在处理器捕获编码错误并返回统一错误响应。
- 参考路径:[internal/handler/brand.go:40-43](file://internal/handler/brand.go#L40-L43)[internal/handler/model.go:40-43](file://internal/handler/model.go#L40-L43)
- Redis 写入失败:记录错误并返回统一错误响应。
- 参考路径:[internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
- 搜索失败:记录错误并返回统一错误响应。
- 参考路径:[internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
- 日志定位
- 使用结构化日志记录关键上下文(如远程 IP、时间戳),便于问题追踪。
- 参考路径:[internal/handler/device.go:47-50](file://internal/handler/device.go#L47-L50)
章节来源
- [internal/repository/model.go:43-44](file://internal/repository/model.go#L43-L44)
- [internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
- [internal/handler/brand.go:40-43](file://internal/handler/brand.go#L40-L43)
- [internal/handler/model.go:40-43](file://internal/handler/model.go#L40-L43)
- [internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
- [internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
- [internal/handler/device.go:47-50](file://internal/handler/device.go#L47-L50)
## 结论
本项目通过清晰的分层与职责分离,实现了可维护、可扩展且具备良好性能特征的 API 服务:
- Handler 专注于业务编排与响应封装;
- Repository 将数据访问细节抽象化;
- Model 明确数据契约;
- Response 提供统一的对外接口;
- 配合中间件、日志与统一错误处理,形成完整的可观测与可诊断体系;
- 在数据库连接池、上下文超时、Redis 并发安全与可选 Base64 响应等方面体现了工程化细节。
## 附录
- 扩展新模块的最佳实践
- 新增处理器:在 internal/handler 下创建处理器文件,定义结构体与依赖注入函数,实现业务方法并调用仓库或外部服务。
- 参考路径:[internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24)[internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24)
- 新增仓库:在 internal/repository 下创建仓库文件,实现查询方法、参数拼装与结果扫描,使用上下文与错误包装。
- 参考路径:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50)[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
- 新增模型:在 internal/model 下定义结构体,注意可选字段使用指针;在仓库扫描函数中正确映射 NullString。
- 参考路径:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)[internal/repository/model.go:63-86](file://internal/repository/model.go#L63-L86)
- 统一响应:优先使用 internal/response 提供的方法,保持前后端一致性。
- 参考路径:[internal/response/response.go:15-36](file://internal/response/response.go#L15-L36)
- 参数与编码:利用 pkg/encode/base64.go 实现可选的 Base64 响应;在处理器中进行必要的参数校验与日志记录。
- 参考路径:[internal/handler/brand.go:27-29](file://internal/handler/brand.go#L27-L29)[internal/handler/model.go:27-29](file://internal/handler/model.go#L27-L29)[internal/handler/model_list.go:26-28](file://internal/handler/model_list.go#L26-L28)[pkg/encode/base64.go](file://pkg/encode/base64.go)
- 资源管理:在入口程序中集中初始化外部依赖(数据库、Redis、搜索引擎),并在退出时优雅关闭。
- 参考路径:[cmd/server/main.go:38-62](file://cmd/server/main.go#L38-L62)[cmd/server/main.go:87-94](file://cmd/server/main.go#L87-L94)