feat(ota): 增强设备管理与OTA功能模块
- 新增OTA固件升级处理器,支持固件升级请求及黑名单过滤 - 引入设备持久化仓储,支持设备信息上报与活动记录 - 扩展数据模型,新增UserDevice与UserActive,支持设备版本跟踪 - 实现Redis到MySQL的异步数据同步任务 - 更新路由配置,集成新的API端点以支持OTA功能 - 优化架构图,反映新增的数据流与处理流程
This commit is contained in:
@@ -7,8 +7,10 @@
|
||||
- [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/handler/ota.go](file://internal/handler/ota.go)
|
||||
- [internal/repository/brand.go](file://internal/repository/brand.go)
|
||||
- [internal/repository/model.go](file://internal/repository/model.go)
|
||||
- [internal/repository/ota.go](file://internal/repository/ota.go)
|
||||
- [internal/response/response.go](file://internal/response/response.go)
|
||||
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
|
||||
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
||||
@@ -20,16 +22,21 @@
|
||||
- [internal/middleware/request_id.go](file://internal/middleware/request_id.go)
|
||||
- [internal/model/brand.go](file://internal/model/brand.go)
|
||||
- [internal/model/model.go](file://internal/model/model.go)
|
||||
- [internal/model/ota.go](file://internal/model/ota.go)
|
||||
- [internal/cache/brand_cache.go](file://internal/cache/brand_cache.go)
|
||||
- [internal/cache/model_cache.go](file://internal/cache/model_cache.go)
|
||||
- [sql/ota.sql](file://sql/ota.sql)
|
||||
- [sql/black_list.sql](file://sql/black_list.sql)
|
||||
- [sql/ota_target_device.sql](file://sql/ota_target_device.sql)
|
||||
</cite>
|
||||
|
||||
## 更新摘要
|
||||
**变更内容**
|
||||
- 更新依赖注入模式:所有处理器现在通过构造函数接收依赖项实例
|
||||
- 新增仓储层依赖:BrandHandler 和 ModelHandler 现在依赖仓储实例而非直接数据库连接
|
||||
- 更新路由装配:路由在启动时集中装配依赖并传递给处理器
|
||||
- 简化处理器实现:移除了对全局数据库连接的直接依赖
|
||||
- 新增OTA固件升级处理功能:引入OTAHandler组件,支持固件升级请求处理、黑名单过滤、目标设备分布和版本选择等OTA固件升级能力
|
||||
- 新增OTA仓储层:OTARepository提供完整的OTA数据访问能力,包括最新版本查询、黑名单检查、定向设备匹配等功能
|
||||
- 新增OTA数据模型:包含OTA、BlackList、OTATargetDevice三种数据结构,支持完整的OTA升级流程
|
||||
- 新增数据库表结构:ota、black_list、ota_target_device三张表,支撑OTA功能的数据存储需求
|
||||
- 更新路由集成:OTA功能已集成到/audio路由组中,提供/api/v1/audio/ota端点
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
@@ -45,10 +52,10 @@
|
||||
11. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向 Luxsin 应用 API 的业务处理器模块,系统性梳理各处理器的职责、接口设计与实现细节,覆盖 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler 与 HealthHandler。文档重点阐述新的依赖注入模式、错误处理机制、响应格式化策略,以及与 Gin 框架的集成方式;并通过流程图与类图展示处理器间的协作关系与数据流转过程,帮助初学者快速上手,同时为高级开发者提供深入的技术参考。
|
||||
本文件面向 Luxsin 应用 API 的业务处理器模块,系统性梳理各处理器的职责、接口设计与实现细节,覆盖 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler、HealthHandler 和新增的 OTAHandler。文档重点阐述新的依赖注入模式、错误处理机制、响应格式化策略,以及与 Gin 框架的集成方式;并通过流程图与类图展示处理器间的协作关系与数据流转过程,帮助初学者快速上手,同时为高级开发者提供深入的技术参考。
|
||||
|
||||
## 项目结构
|
||||
业务处理器位于 internal/handler 目录,采用依赖注入模式,围绕"控制器-仓储-搜索-缓存-响应"的分层组织,配合中间件与路由装配,形成清晰的控制流与依赖注入入口。
|
||||
业务处理器位于 internal/handler 目录,采用依赖注入模式,围绕"控制器-仓储-搜索-缓存-响应"的分层组织,配合中间件与路由装配,形成清晰的控制流与依赖注入入口。新增的OTA功能通过独立的处理器、仓储层和数据模型实现完整的固件升级能力。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
@@ -67,12 +74,19 @@ BRAND["internal/handler/brand.go<br/>NewBrandHandler(brandRepo, log)"]
|
||||
MODEL["internal/handler/model.go<br/>NewModelHandler(modelRepo, log)"]
|
||||
MODELLIST["internal/handler/model_list.go<br/>NewModelListHandler(searchClient, log)"]
|
||||
DEVICE["internal/handler/device.go<br/>NewDeviceHandler(redis, log)"]
|
||||
OTA["internal/handler/ota.go<br/>NewOTAHandler(otaRepo, log)"]
|
||||
end
|
||||
subgraph "仓储层"
|
||||
BRANDREPO["internal/repository/brand.go<br/>BrandRepository"]
|
||||
MODELREPO["internal/repository/model.go<br/>ModelRepository"]
|
||||
OTAREPO["internal/repository/ota.go<br/>OTARepository"]
|
||||
end
|
||||
subgraph "基础设施"
|
||||
RESP["internal/response/response.go<br/>统一响应体"]
|
||||
ENCODE["pkg/encode/base64.go<br/>自定义Base64编码"]
|
||||
SEARCH["internal/search/meilisearch.go<br/>Meilisearch客户端"]
|
||||
CACHE["internal/cache/*<br/>Redis缓存"]
|
||||
DB["MySQL 数据库<br/>ota, black_list, ota_target_device 表"]
|
||||
end
|
||||
MAIN --> ROUTER
|
||||
ROUTER --> CORS
|
||||
@@ -83,10 +97,18 @@ ROUTER --> BRAND
|
||||
ROUTER --> MODEL
|
||||
ROUTER --> MODELLIST
|
||||
ROUTER --> DEVICE
|
||||
ROUTER --> OTA
|
||||
BRAND --> BRANDREPO
|
||||
MODEL --> MODELREPO
|
||||
OTA --> OTAREPO
|
||||
BRANDREPO --> DB
|
||||
MODELREPO --> DB
|
||||
OTAREPO --> DB
|
||||
BRAND --> RESP
|
||||
MODEL --> RESP
|
||||
MODELLIST --> RESP
|
||||
DEVICE --> RESP
|
||||
OTA --> RESP
|
||||
MODELLIST --> SEARCH
|
||||
BRAND --> CACHE
|
||||
MODEL --> CACHE
|
||||
@@ -96,17 +118,18 @@ MODELLIST --> ENCODE
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101)
|
||||
- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52)
|
||||
- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
- [internal/handler/health.go:10](file://internal/handler/health.go#L10)
|
||||
- [internal/handler/brand.go:18](file://internal/handler/brand.go#L18)
|
||||
- [internal/handler/model.go:18](file://internal/handler/model.go#L18)
|
||||
- [internal/handler/model_list.go:19](file://internal/handler/model_list.go#L19)
|
||||
- [internal/handler/device.go:19](file://internal/handler/device.go#L19)
|
||||
- [internal/handler/ota.go:19](file://internal/handler/ota.go#L19)
|
||||
|
||||
**章节来源**
|
||||
- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52)
|
||||
- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108)
|
||||
|
||||
## 核心组件
|
||||
- **健康检查处理器**:提供轻量级健康状态返回,便于外部探活与编排。
|
||||
@@ -114,6 +137,7 @@ MODELLIST --> ENCODE
|
||||
- **型号查询处理器**:按品牌或型号关键字查询型号列表,现在依赖 ModelRepository 实例。
|
||||
- **型号检索处理器**:基于 Meilisearch 执行全文检索,依赖搜索客户端实例。
|
||||
- **设备上报处理器**:接收设备信息(MAC、型号、版本、来源 IP),依赖 Redis 客户端。
|
||||
- **OTA固件升级处理器**:处理固件升级请求,支持黑名单过滤、目标设备分布和版本选择等OTA固件升级能力。
|
||||
|
||||
**章节来源**
|
||||
- [internal/handler/health.go:8-19](file://internal/handler/health.go#L8-L19)
|
||||
@@ -121,9 +145,10 @@ MODELLIST --> ENCODE
|
||||
- [internal/handler/model.go:13-23](file://internal/handler/model.go#L13-L23)
|
||||
- [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/ota.go:14-21](file://internal/handler/ota.go#L14-L21)
|
||||
|
||||
## 架构总览
|
||||
下图展示从请求进入至响应返回的关键路径,以及处理器与仓储、搜索、缓存、日志等组件的交互,体现了完整的依赖注入架构。
|
||||
下图展示从请求进入至响应返回的关键路径,以及处理器与仓储、搜索、缓存、日志等组件的交互,体现了完整的依赖注入架构。新增的OTA功能通过独立的处理流程支持复杂的固件升级场景。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -131,8 +156,7 @@ participant C as "客户端"
|
||||
participant R as "Gin 路由"
|
||||
participant H as "业务处理器"
|
||||
participant REPO as "仓储层"
|
||||
participant S as "Meilisearch"
|
||||
participant RC as "Redis"
|
||||
participant DB as "MySQL数据库"
|
||||
participant L as "Zap 日志"
|
||||
C->>R : "HTTP 请求"
|
||||
R->>H : "匹配到处理器并调用"
|
||||
@@ -140,24 +164,37 @@ alt "品牌/型号查询"
|
||||
H->>REPO : "List(ctx, filters)"
|
||||
REPO-->>H : "结果集"
|
||||
else "型号检索"
|
||||
H->>S : "ModelList(ctx, key, count)"
|
||||
S-->>H : "命中结果"
|
||||
H->>DB : "Meilisearch查询"
|
||||
DB-->>H : "命中结果"
|
||||
else "设备上报"
|
||||
H->>RC : "HSet(ctx, key, mac, json)"
|
||||
RC-->>H : "OK 或错误"
|
||||
H->>DB : "Redis HSet(ctx, key, mac, json)"
|
||||
DB-->>H : "OK 或错误"
|
||||
else "OTA固件升级"
|
||||
H->>REPO : "GetLatestOTA(ctx, model, hw, beta)"
|
||||
REPO->>DB : "查询最新OTA记录"
|
||||
DB-->>REPO : "OTA记录"
|
||||
REPO-->>H : "OTA记录"
|
||||
H->>REPO : "IsInBlackList(ctx, otaID, mac)"
|
||||
REPO->>DB : "检查黑名单"
|
||||
DB-->>REPO : "命中/未命中"
|
||||
H->>REPO : "FindTargetDevice(ctx, otaID, mac)"
|
||||
REPO->>DB : "检查定向设备"
|
||||
DB-->>REPO : "匹配/不匹配"
|
||||
end
|
||||
H->>L : "记录日志/错误"
|
||||
H-->>C : "JSON 或自定义Base64响应"
|
||||
H-->>C : "JSON 响应"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [internal/router/router.go:32-36](file://internal/router/router.go#L32-L36)
|
||||
- [internal/router/router.go:45-52](file://internal/router/router.go#L45-L52)
|
||||
- [internal/handler/brand.go:29](file://internal/handler/brand.go#L29)
|
||||
- [internal/handler/model.go:30](file://internal/handler/model.go#L30)
|
||||
- [internal/handler/model_list.go:37](file://internal/handler/model_list.go#L37)
|
||||
- [internal/handler/device.go:71](file://internal/handler/device.go#L71)
|
||||
- [internal/handler/ota.go:57-131](file://internal/handler/ota.go#L57-L131)
|
||||
- [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52)
|
||||
- [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79)
|
||||
- [internal/repository/ota.go:20-158](file://internal/repository/ota.go#L20-L158)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
|
||||
## 详细组件分析
|
||||
@@ -173,7 +210,7 @@ H-->>C : "JSON 或自定义Base64响应"
|
||||
**章节来源**
|
||||
- [internal/handler/health.go:8-19](file://internal/handler/health.go#L8-L19)
|
||||
- [internal/response/response.go:15-21](file://internal/response/response.go#L15-L21)
|
||||
- [internal/router/router.go:40](file://internal/router/router.go#L40)
|
||||
- [internal/router/router.go:42](file://internal/router/router.go#L42)
|
||||
|
||||
### 品牌处理器(BrandHandler)
|
||||
- **职责**:根据品牌名称模糊查询品牌列表。
|
||||
@@ -365,6 +402,62 @@ RespOK --> End
|
||||
**章节来源**
|
||||
- [internal/handler/device.go:14-85](file://internal/handler/device.go#L14-L85)
|
||||
|
||||
### OTA固件升级处理器(OTAHandler)
|
||||
- **职责**:处理固件升级请求,支持黑名单过滤、目标设备分布和版本选择等OTA固件升级能力。
|
||||
- **输入参数**:
|
||||
- 查询字符串:model(必填)
|
||||
- 查询字符串:hw(必填)
|
||||
- 查询字符串:mac(可选)
|
||||
- 查询字符串:beta(可选,默认0)
|
||||
- **处理流程**:
|
||||
1. 参数校验:验证model和hw参数,解析beta参数
|
||||
2. 查询最新OTA记录:按model+hw+beta+status=1查询最新一条OTA记录
|
||||
3. 黑名单检查:检查mac是否在指定ota_id的黑名单中
|
||||
4. 定向升级检查:如果是定向升级,检查mac是否在定向设备列表中
|
||||
5. 版本选择:根据检查结果返回合适的OTA版本
|
||||
- **错误处理**:
|
||||
- 参数校验失败返回统一错误
|
||||
- 数据库查询失败记录错误并返回统一内部错误
|
||||
- 黑名单或定向设备检查失败返回统一内部错误
|
||||
- **数据模型**:OTA、BlackList、OTATargetDevice
|
||||
- **依赖注入**:通过 NewOTAHandler 构造函数注入 OTARepository 和 zap.Logger
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入 GetOTA"]) --> ParseParams["解析参数 model/hw/mac/beta"]
|
||||
ParseParams --> Validate{"参数校验通过?"}
|
||||
Validate -- 否 --> RespBadReq["返回BadRequest错误"]
|
||||
Validate -- 是 --> QueryLatest["查询最新OTA记录"]
|
||||
QueryLatest --> QueryOK{"查询成功?"}
|
||||
QueryOK -- 否 --> RespInternal["返回InternalError"]
|
||||
QueryOK -- 是 --> CheckBlackList["检查黑名单"]
|
||||
CheckBlackList --> InBlackList{"命中黑名单?"}
|
||||
InBlackList -- 是 --> QueryNotInBlack["查询不在黑名单中的最新OTA"]
|
||||
QueryNotInBlack --> BlackListOK{"查询成功?"}
|
||||
BlackListOK -- 否 --> RespInternal
|
||||
BlackListOK -- 是 --> ReturnOTA["返回OTA记录"]
|
||||
InBlackList -- 否 --> CheckTarget{"是否定向升级?"}
|
||||
CheckTarget -- 否 --> ReturnOTA
|
||||
CheckTarget -- 是 --> CheckTargetDevice["检查定向设备"]
|
||||
CheckTargetDevice --> TargetHit{"定向命中?"}
|
||||
TargetHit -- 是 --> ReturnOTA
|
||||
TargetHit -- 否 --> QueryNotTarget["查询非定向最新OTA"]
|
||||
QueryNotTarget --> NotTargetOK{"查询成功?"}
|
||||
NotTargetOK -- 否 --> RespInternal
|
||||
NotTargetOK -- 是 --> ReturnOTA
|
||||
ReturnOTA --> End(["结束"])
|
||||
RespBadReq --> End
|
||||
RespInternal --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [internal/handler/ota.go:25-132](file://internal/handler/ota.go#L25-L132)
|
||||
|
||||
**章节来源**
|
||||
- [internal/handler/ota.go:14-132](file://internal/handler/ota.go#L14-L132)
|
||||
- [internal/repository/ota.go:20-158](file://internal/repository/ota.go#L20-L158)
|
||||
- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42)
|
||||
|
||||
## 依赖注入模式详解
|
||||
|
||||
### 依赖注入架构
|
||||
@@ -381,16 +474,18 @@ ROUTER --> BRANCACHE["cache.BrandCache<br/>品牌缓存"]
|
||||
ROUTER --> MODELCACHE["cache.ModelCache<br/>型号缓存"]
|
||||
ROUTER --> BRANDREPO["repository.NewBrandRepository()<br/>品牌仓储"]
|
||||
ROUTER --> MODELREPO["repository.NewModelRepository()<br/>型号仓储"]
|
||||
ROUTER --> OTAREPO["repository.NewOTARepository()<br/>OTA仓储"]
|
||||
ROUTER --> HEALTH["handler.NewHealthHandler()<br/>健康检查处理器"]
|
||||
ROUTER --> BRAND["handler.NewBrandHandler()<br/>品牌处理器"]
|
||||
ROUTER --> MODEL["handler.NewModelHandler()<br/>型号处理器"]
|
||||
ROUTER --> MODELLIST["handler.NewModelListHandler()<br/>型号检索处理器"]
|
||||
ROUTER --> DEVICE["handler.NewDeviceHandler()<br/>设备上报处理器"]
|
||||
ROUTER --> OTA["handler.NewOTAHandler()<br/>OTA固件升级处理器"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [cmd/server/main.go:53-69](file://cmd/server/main.go#L53-L69)
|
||||
- [internal/router/router.go:16-36](file://internal/router/router.go#L16-L36)
|
||||
- [cmd/server/main.go:77](file://cmd/server/main.go#L77)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
|
||||
### 依赖注入优势
|
||||
- **测试友好**:可以轻松注入模拟对象进行单元测试
|
||||
@@ -399,7 +494,7 @@ ROUTER --> DEVICE["handler.NewDeviceHandler()<br/>设备上报处理器"]
|
||||
- **生命周期管理**:依赖项的创建和销毁由路由集中管理
|
||||
|
||||
### 仓储层依赖
|
||||
BrandRepository 和 ModelRepository 现在接收 Redis 缓存实例作为依赖:
|
||||
BrandRepository、ModelRepository 和 OTARepository 现在接收相应的依赖:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
@@ -419,6 +514,15 @@ class ModelRepository {
|
||||
+ ListByBrandFromDB(ctx, brandName) : "[]Model,error"
|
||||
+ ListByModelFromDB(ctx, modelName) : "[]Model,error"
|
||||
}
|
||||
class OTARepository {
|
||||
- db : "sql.DB"
|
||||
+ NewOTARepository(db) : "OTARepository"
|
||||
+ GetLatestOTA(ctx, modelVal, hw, beta) : "OTA,error"
|
||||
+ GetLatestOTANotInBlackList(ctx, modelVal, hw, beta, mac) : "OTA,error"
|
||||
+ GetLatestOTANotTarget(ctx, modelVal, hw, beta) : "OTA,error"
|
||||
+ IsInBlackList(ctx, otaID, mac) : "bool,error"
|
||||
+ FindTargetDevice(ctx, otaID, mac) : "OTATargetDevice,error"
|
||||
}
|
||||
class BrandCache {
|
||||
- rdb : "redis.Client"
|
||||
+ NewBrandCache(rdb) : "BrandCache"
|
||||
@@ -435,17 +539,19 @@ class ModelCache {
|
||||
}
|
||||
BrandRepository --> BrandCache : "依赖注入"
|
||||
ModelRepository --> ModelCache : "依赖注入"
|
||||
OTARepository --> DB : "依赖注入"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21)
|
||||
- [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21)
|
||||
- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17)
|
||||
- [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24)
|
||||
- [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25)
|
||||
|
||||
**章节来源**
|
||||
- [internal/router/router.go:16-36](file://internal/router/router.go#L16-L36)
|
||||
- [cmd/server/main.go:53-69](file://cmd/server/main.go#L53-L69)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
- [cmd/server/main.go:77](file://cmd/server/main.go#L77)
|
||||
|
||||
## 依赖分析
|
||||
- **依赖注入模式**:
|
||||
@@ -454,6 +560,7 @@ ModelRepository --> ModelCache : "依赖注入"
|
||||
- **组件耦合**:
|
||||
- 处理器与仓储之间为单向依赖,职责清晰。
|
||||
- 搜索与缓存作为外部服务,通过客户端封装接入。
|
||||
- OTA处理器与数据库直接交互,提供完整的OTA数据访问能力。
|
||||
- **可能的循环依赖**:
|
||||
- 当前结构未见循环导入,符合 Go 包管理最佳实践。
|
||||
|
||||
@@ -465,37 +572,42 @@ ROUTER --> BRAND["brand.go"]
|
||||
ROUTER --> MODEL["model.go"]
|
||||
ROUTER --> MODELLIST["model_list.go"]
|
||||
ROUTER --> DEVICE["device.go"]
|
||||
ROUTER --> OTA["ota.go"]
|
||||
BRAND --> BREPO["repository/brand.go"]
|
||||
MODEL --> MREPO["repository/model.go"]
|
||||
MODELLIST --> SEARCH["search/meilisearch.go"]
|
||||
DEVICE --> REDIS["Redis 客户端"]
|
||||
OTA --> OTAREPO["repository/ota.go"]
|
||||
BRAND --> BREPO
|
||||
BREPO --> BCACHE["cache/brand_cache.go"]
|
||||
MODEL --> MREPO
|
||||
MREPO --> MCACHE["cache/model_cache.go"]
|
||||
OTA --> OTAREPO
|
||||
OTAREPO --> DB["MySQL数据库"]
|
||||
BRAND --> ENCODE["pkg/encode/base64.go"]
|
||||
MODEL --> ENCODE
|
||||
MODELLIST --> ENCODE
|
||||
OTA --> ENCODE
|
||||
ALL["各处理器"] --> RESP["internal/response/response.go"]
|
||||
ALL --> LOG["zap.Logger"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [cmd/server/main.go:67-70](file://cmd/server/main.go#L67-L70)
|
||||
- [internal/router/router.go:27-36](file://internal/router/router.go#L27-L36)
|
||||
- [cmd/server/main.go:77](file://cmd/server/main.go#L77)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
- [internal/handler/brand.go:18](file://internal/handler/brand.go#L18)
|
||||
- [internal/handler/model.go:18](file://internal/handler/model.go#L18)
|
||||
- [internal/handler/model_list.go:19](file://internal/handler/model_list.go#L19)
|
||||
- [internal/handler/device.go:19](file://internal/handler/device.go#L19)
|
||||
- [internal/handler/ota.go:19](file://internal/handler/ota.go#L19)
|
||||
- [internal/repository/brand.go:19](file://internal/repository/brand.go#L19)
|
||||
- [internal/repository/model.go:19](file://internal/repository/model.go#L19)
|
||||
- [internal/repository/ota.go:15](file://internal/repository/ota.go#L15)
|
||||
- [internal/search/meilisearch.go:17](file://internal/search/meilisearch.go#L17)
|
||||
- [pkg/encode/base64.go:8](file://pkg/encode/base64.go#L8)
|
||||
- [internal/response/response.go:9](file://internal/response/response.go#L9)
|
||||
|
||||
**章节来源**
|
||||
- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52)
|
||||
- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101)
|
||||
- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56)
|
||||
- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108)
|
||||
|
||||
## 性能考虑
|
||||
- **响应体积优化**
|
||||
@@ -503,11 +615,15 @@ ALL --> LOG["zap.Logger"]
|
||||
- 检索处理器对 count 进行上限控制,避免超大数据量返回。
|
||||
- **数据库查询**
|
||||
- 品牌与型号查询均使用 ORDER BY 与 LIKE,建议在数据库侧建立合适索引以提升模糊查询性能。
|
||||
- OTA查询涉及多表关联,建议在ota表的model、hw、beta、status字段建立复合索引。
|
||||
- 仓储层现在支持缓存降级,当缓存不可用时自动回退到数据库查询。
|
||||
- **搜索与缓存**
|
||||
- Meilisearch 适合全文检索,建议合理设置属性检索范围与分页大小。
|
||||
- Redis 写入为单键 HSet,具备良好吞吐能力;建议评估内存占用与持久化策略。
|
||||
- 缓存层现在支持全量缓存和按品牌缓存两种策略,提升查询性能。
|
||||
- **OTA查询优化**
|
||||
- OTA查询流程涉及多次数据库查询,建议在黑名单表和定向设备表建立适当的索引。
|
||||
- 可以考虑缓存常用的OTA查询结果,减少数据库压力。
|
||||
- **中间件与日志**
|
||||
- 开启 Recovery、CORS、Logger、RequestID 中间件,有助于可观测性与稳定性;注意日志级别与输出频率对性能的影响。
|
||||
- **并发安全**
|
||||
@@ -517,6 +633,7 @@ ALL --> LOG["zap.Logger"]
|
||||
- 在生产环境启用 Release 模式,降低框架开销。
|
||||
- 对外部依赖(数据库、搜索、缓存)增加超时与重试策略,提升鲁棒性。
|
||||
- 利用缓存预热机制,在应用启动时加载常用数据到缓存。
|
||||
- OTA查询流程复杂,建议添加适当的超时控制和错误重试机制。
|
||||
|
||||
## 故障排查指南
|
||||
- **健康检查失败**
|
||||
@@ -532,6 +649,11 @@ ALL --> LOG["zap.Logger"]
|
||||
- **设备上报异常**
|
||||
- 校验必填参数 mac 与 model 是否传入。
|
||||
- 关注"marshal device info failed"与"redis hset failed"的错误日志。
|
||||
- **OTA固件升级异常**
|
||||
- 校验必填参数 model、hw 是否传入且格式正确。
|
||||
- 关注"query ota failed"、"check black list failed"、"check target device failed"等错误日志。
|
||||
- 检查数据库连接,确认ota、black_list、ota_target_device表存在且结构正确。
|
||||
- 验证OTA状态、硬件版本号、灰度标识等字段是否符合预期。
|
||||
- **依赖注入相关问题**
|
||||
- 确认所有处理器都通过构造函数正确注入了依赖项。
|
||||
- 检查路由装配顺序,确保依赖项在处理器之前创建。
|
||||
@@ -546,12 +668,13 @@ ALL --> LOG["zap.Logger"]
|
||||
- [internal/handler/model.go:31-35](file://internal/handler/model.go#L31-L35)
|
||||
- [internal/handler/model_list.go:38-42](file://internal/handler/model_list.go#L38-L42)
|
||||
- [internal/handler/device.go:61-78](file://internal/handler/device.go#L61-L78)
|
||||
- [internal/handler/ota.go:58-94](file://internal/handler/ota.go#L58-L94)
|
||||
- [internal/response/response.go:15-36](file://internal/response/response.go#L15-L36)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31)
|
||||
|
||||
## 结论
|
||||
本处理器模块采用全新的依赖注入模式,通过构造函数注入依赖项,实现了更好的解耦和可测试性。通过统一响应体与自定义 Base64 编码实现灵活的输出策略,结合 Gin 中间件与外部服务(数据库、Meilisearch、Redis)形成稳定高效的业务处理链路。新的架构模式简化了处理器实现,提升了代码质量,建议在生产环境中进一步完善超时与重试、索引优化与缓存策略,持续提升性能与可靠性。
|
||||
本处理器模块采用全新的依赖注入模式,通过构造函数注入依赖项,实现了更好的解耦和可测试性。通过统一响应体与自定义 Base64 编码实现灵活的输出策略,结合 Gin 中间件与外部服务(数据库、Meilisearch、Redis)形成稳定高效的业务处理链路。新增的OTA固件升级功能提供了完整的固件升级能力,包括黑名单过滤、目标设备分布和版本选择等特性。新的架构模式简化了处理器实现,提升了代码质量,建议在生产环境中进一步完善超时与重试、索引优化与缓存策略,持续提升性能与可靠性。
|
||||
|
||||
## 附录
|
||||
- **路由与处理器映射**
|
||||
@@ -560,20 +683,36 @@ ALL --> LOG["zap.Logger"]
|
||||
- /audio/getModel -> ModelHandler.GetModel
|
||||
- /audio/modelList -> ModelListHandler.ModelList
|
||||
- /audio/reportDevInfo -> DeviceHandler.ReportDevInfo
|
||||
- /audio/ota -> OTAHandler.GetOTA
|
||||
- **依赖注入示例**
|
||||
- 品牌处理器:BrandHandler.NewBrandHandler(brandRepo, log)
|
||||
- 型号处理器:ModelHandler.NewModelHandler(modelRepo, log)
|
||||
- 型号检索处理器:ModelListHandler.NewModelListHandler(searchClient, log)
|
||||
- 设备上报处理器:DeviceHandler.NewDeviceHandler(redis, log)
|
||||
- OTA固件升级处理器:OTAHandler.NewOTAHandler(otaRepo, log)
|
||||
- **OTA查询参数说明**
|
||||
- model:设备型号(必填)
|
||||
- hw:硬件版本号(必填)
|
||||
- mac:设备MAC地址(可选)
|
||||
- beta:灰度标识(可选,默认0)
|
||||
- **OTA数据模型字段**
|
||||
- OTA:id、verCode、verName、url、md5、force、desc、model、hw、target、beta、pawVerCode、pawVerName、pawUrl、pawMd5、startTime、endTime、status
|
||||
- BlackList:id、ota_id、mac、create_at
|
||||
- OTATargetDevice:id、ota_id、mac_addr、type、create_at
|
||||
- **数据库表结构**
|
||||
- ota表:存储OTA固件升级记录
|
||||
- black_list表:存储OTA黑名单
|
||||
- ota_target_device表:存储OTA定向设备
|
||||
- **常用调用示例(路径引用)**
|
||||
- 品牌查询:[internal/handler/brand.go:25](file://internal/handler/brand.go#L25)
|
||||
- 型号查询:[internal/handler/model.go:25](file://internal/handler/model.go#L25)
|
||||
- 型号检索:[internal/handler/model_list.go:26](file://internal/handler/model_list.go#L26)
|
||||
- 设备上报:[internal/handler/device.go:26](file://internal/handler/device.go#L26)
|
||||
- OTA固件升级:[internal/handler/ota.go:25](file://internal/handler/ota.go#L25)
|
||||
- 健康检查:[internal/handler/health.go:14](file://internal/handler/health.go#L14)
|
||||
- **配置与启动**
|
||||
- 配置加载与环境变量:[internal/config/config.go:18-64](file://internal/config/config.go#L18-L64)
|
||||
- 服务器启动与优雅关闭:[cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101)
|
||||
- 服务器启动与优雅关闭:[cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108)
|
||||
- **中间件**
|
||||
- CORS:[internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21)
|
||||
- Logger:[internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
@@ -581,4 +720,9 @@ ALL --> LOG["zap.Logger"]
|
||||
- **缓存策略**
|
||||
- 品牌缓存:brand:all 键,30分钟TTL
|
||||
- 型号缓存:model:brand:{brand} 和 model:all 键,30分钟TTL
|
||||
- 启动时预热缓存,提升首次查询性能
|
||||
- 启动时预热缓存,提升首次查询性能
|
||||
- **OTA查询流程**
|
||||
- 最新OTA查询:按model+hw+beta+status=1排序取第一条
|
||||
- 黑名单检查:检查mac是否在指定ota_id的黑名单中
|
||||
- 定向设备检查:检查mac是否在指定ota_id的定向设备列表中
|
||||
- 版本选择:根据检查结果返回合适的OTA版本
|
||||
Reference in New Issue
Block a user