Files
dashboard/.qoder/repowiki/zh/content/后端API文档/OTA固件API.md
T
2026-06-30 14:46:52 +08:00

388 lines
15 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.
# OTA固件API
<cite>
**本文引用的文件**
- [backend/src/routes/ota.js](file://backend/src/routes/ota.js)
- [backend/src/models/Ota.js](file://backend/src/models/Ota.js)
- [backend/src/services/otaStorage.js](file://backend/src/services/otaStorage.js)
- [backend/src/validators/ota.js](file://backend/src/validators/ota.js)
- [backend/src/utils/response.js](file://backend/src/utils/response.js)
- [backend/src/middleware/auth.js](file://backend/src/middleware/auth.js)
- [backend/src/config/env.js](file://backend/src/config/env.js)
- [frontend/src/api/ota.js](file://frontend/src/api/ota.js)
- [frontend/src/views/ota/index.vue](file://frontend/src/views/ota/index.vue)
- [backend/package.json](file://backend/package.json)
- [frontend/package.json](file://frontend/package.json)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为OTA固件管理API的完整RESTful接口文档,涵盖固件版本管理的HTTP方法、URL模式、请求/响应格式以及文件上传处理流程。内容包括:
- 固件版本列表查询、详情获取、创建、更新、删除接口
- 设备端“最新版本检查”接口
- 文件上传(Luxsin-X8上传至S3Luxsin-X9保存到本地目录)
- 存储服务配置与使用示例
- 固件版本比较、强制更新策略与兼容性检查机制
- 下载链接生成、版本升级通知与错误处理实现指南
## 项目结构
后端采用Express + Sequelize + MySQL架构,前端基于Vue3 + Element Plus。OTA相关逻辑集中在路由、模型、服务层与验证器中,并通过统一响应封装返回。
```mermaid
graph TB
subgraph "前端"
FE_API["前端API模块<br/>frontend/src/api/ota.js"]
FE_VIEW["OTA页面视图<br/>frontend/src/views/ota/index.vue"]
end
subgraph "后端"
ROUTER["OTA路由<br/>backend/src/routes/ota.js"]
AUTH["认证中间件<br/>backend/src/middleware/auth.js"]
RESP["统一响应封装<br/>backend/src/utils/response.js"]
VALID["参数校验<br/>backend/src/validators/ota.js"]
MODEL["数据库模型<br/>backend/src/models/Ota.js"]
STORE["存储服务<br/>backend/src/services/otaStorage.js"]
ENV["环境配置<br/>backend/src/config/env.js"]
end
FE_API --> ROUTER
FE_VIEW --> FE_API
ROUTER --> AUTH
ROUTER --> VALID
ROUTER --> MODEL
ROUTER --> STORE
ROUTER --> RESP
STORE --> ENV
```
图表来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
章节来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
## 核心组件
- 路由层:定义所有OTA相关HTTP接口,包含设备端“最新版本检查”和后台管理接口。
- 认证中间件:保护后台接口,要求Bearer Token。
- 参数校验:使用Zod对创建/更新请求体进行严格校验。
- 数据模型:Sequelize定义的OTA表结构,包含版本号、MD5、强制更新、定向灰度、时间窗口等字段。
- 存储服务:根据设备型号选择不同存储路径(S3或本地),并生成公开下载链接。
- 响应封装:统一封装成功/错误/无数据三类响应格式。
章节来源
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
- [backend/src/services/otaStorage.js:1-113](file://backend/src/services/otaStorage.js#L1-L113)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
## 架构总览
OTA接口分为两类:
- 设备端调用:无需登录,用于查询最新可升级版本。
- 后台管理:需登录,用于维护OTA版本列表、上传升级包、查看/编辑/删除。
```mermaid
sequenceDiagram
participant Device as "设备端"
participant Router as "OTA路由"
participant Model as "数据库模型"
participant Logger as "日志"
Device->>Router : GET /api/ota/latest/check?currentVerCode&model&hw
Router->>Model : 查询 verCode > 当前版本且状态可用
alt 找到更高版本
Model-->>Router : 返回最高版本记录
Router-->>Device : 成功响应含下载URL、MD5、是否强制等
else 无更高版本
Router-->>Device : 无数据响应
end
Router->>Logger : 记录查询结果
```
图表来源
- [backend/src/routes/ota.js:68-102](file://backend/src/routes/ota.js#L68-L102)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
## 详细组件分析
### 设备端“最新版本检查”
- 方法与路径:GET /api/ota/latest/check
- 请求参数:
- currentVerCode: 当前设备版本号(整数)
- model: 设备型号(如 Luxsin-X8/X9
- hw: 可选硬件版本号(整数)
- 响应:
- 成功:返回最高可用版本记录(含URL、MD5、是否强制更新、定向/灰度等)
- 无数据:表示无更高可用版本
- 兼容性与策略:
- 仅查询状态为可用且版本号大于当前版本的记录
- 支持按硬件版本过滤
- 强制更新字段用于客户端决定是否强制升级
章节来源
- [backend/src/routes/ota.js:68-102](file://backend/src/routes/ota.js#L68-L102)
### 后台管理接口(需登录)
#### 获取OTA版本列表
- 方法与路径:GET /api/ota/
- 查询参数:
- skip: 跳过条数(默认0
- limit: 每页数量(默认100,最大1000)
- verCode: 精确匹配版本号
- verName: 模糊匹配版本名称
- model: 模糊匹配设备型号
- status: 状态(0/1
- 响应:分页数据(items、total、skip、limit
章节来源
- [backend/src/routes/ota.js:107-143](file://backend/src/routes/ota.js#L107-L143)
#### 获取指定OTA详情
- 方法与路径:GET /api/ota/:ota_id
- 路径参数:ota_id(整数)
- 响应:单条记录或无数据
章节来源
- [backend/src/routes/ota.js:145-160](file://backend/src/routes/ota.js#L145-L160)
#### 创建OTA版本
- 方法与路径:POST /api/ota/
- 请求体字段(必填/可选见校验规则):
- verCode: 整数(唯一性约束:同model下不可重复)
- verName: 字符串(1~20
- url: 字符串(下载地址或上传后生成的URL)
- md5: 32位十六进制字符串
- force: 0/1(默认0
- desc: 描述(可空)
- model: 设备型号(可空)
- hw: 硬件版本号(默认0
- target: 是否定向(0/1,默认0
- beta: 是否灰度(0/1,默认0
- startTime/endTime: 时间字符串(可空)
- status: 状态(0/1,默认1
- 响应:创建成功的记录
章节来源
- [backend/src/routes/ota.js:162-194](file://backend/src/routes/ota.js#L162-L194)
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
#### 更新OTA版本
- 方法与路径:PUT /api/ota/:ota_id
- 请求体字段:同创建接口(部分字段可为空表示不更新)
- 响应:更新后的记录
- 注意:
- 若更新版本号或设备型号,需保证新的组合在同model下唯一
- 日期字段会自动转换为Date类型
章节来源
- [backend/src/routes/ota.js:196-247](file://backend/src/routes/ota.js#L196-L247)
- [backend/src/validators/ota.js:19-33](file://backend/src/validators/ota.js#L19-L33)
#### 删除OTA版本
- 方法与路径:DELETE /api/ota/:ota_id
- 响应:删除成功消息
章节来源
- [backend/src/routes/ota.js:249-268](file://backend/src/routes/ota.js#L249-L268)
### 文件上传与存储
#### 接口:上传升级包
- 方法与路径:POST /api/ota/upload-package
- 请求头:Content-Type: multipart/form-data
- 表单字段:
- package_file: 二进制文件
- model: 设备型号(仅支持 Luxsin-X8 或 Luxsin-X9
- 响应:
- 成功:返回md5、filename、urlX8同时返回s3_key
- 错误:返回错误信息(如未配置S3、上传失败、不支持的设备型号等)
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "OTA路由"
participant Store as "存储服务"
participant S3 as "S3客户端"
participant FS as "本地文件系统"
Client->>Router : POST /api/ota/upload-package
Router->>Store : readUploadContentAndMd5(buffer)
alt model == Luxsin-X9
Store->>FS : 写入本地文件并生成URL
FS-->>Store : 返回保存名与URL
else model == Luxsin-X8
Store->>S3 : 上传对象并生成URL
S3-->>Store : 返回保存名、URL与S3 Key
end
Store-->>Router : {md5, filename, url[, s3_key]}
Router-->>Client : 成功响应
```
图表来源
- [backend/src/routes/ota.js:24-66](file://backend/src/routes/ota.js#L24-L66)
- [backend/src/services/otaStorage.js:46-103](file://backend/src/services/otaStorage.js#L46-L103)
#### 存储策略与配置
- 设备型号支持:Luxsin-X8、Luxsin-X9
- 存储方式:
- X8:上传至S3,生成公开访问URL
- X9:写入本地目录,生成公开访问URL
- 关键环境变量(来自存储服务):
- OTA_UPLOAD_DIR:本地上传根目录(开发默认临时目录,生产默认/data/projects/source
- AWS_REGION/AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYS3区域与凭证(无凭证时走IAM角色)
- AWS_S3_OTA_BUCKETS3存储桶名称
- OTA_X8_PUBLIC_BASEX8公开URL基础路径
- OTA_X9_URL_BASEX9公开URL基础路径
章节来源
- [backend/src/services/otaStorage.js:12-25](file://backend/src/services/otaStorage.js#L12-L25)
- [backend/src/services/otaStorage.js:51-103](file://backend/src/services/otaStorage.js#L51-L103)
### 前端集成与使用示例
- 前端API模块提供:
- 列表、详情、创建、更新、删除、上传包等方法
- OTA页面视图:
- 支持搜索(版本名、设备型号、状态、版本号)
- 分页与表格展示
- 上传升级包(X8/X9)并回填URL与MD5
- 表单校验与提交
章节来源
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
## 依赖关系分析
```mermaid
classDiagram
class OtaRoute {
+GET "/api/ota/"
+GET "/api/ota/ : ota_id"
+POST "/api/ota/"
+PUT "/api/ota/ : ota_id"
+DELETE "/api/ota/ : ota_id"
+POST "/api/ota/upload-package"
+GET "/api/ota/latest/check"
}
class AuthMiddleware {
+authMiddleware()
}
class ApiResponse {
+success(data,msg)
+error(msg,code)
+noData(msg)
}
class OtaValidator {
+OtaCreateSchema
+OtaUpdateSchema
}
class OtaModel {
+verCode : int
+verName : string
+url : string
+md5 : string
+force : smallint
+desc : string
+model : string
+hw : int
+target : smallint
+beta : smallint
+startTime : date
+endTime : date
+status : smallint
}
class OtaStorage {
+readUploadContentAndMd5()
+saveX9PackageLocal()
+uploadX8PackageToS3()
}
OtaRoute --> AuthMiddleware : "保护后台接口"
OtaRoute --> OtaValidator : "参数校验"
OtaRoute --> OtaModel : "读写数据库"
OtaRoute --> OtaStorage : "文件上传"
OtaRoute --> ApiResponse : "统一响应"
```
图表来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
- [backend/src/services/otaStorage.js:1-113](file://backend/src/services/otaStorage.js#L1-L113)
## 性能考量
- 列表查询限制每页最大1000条,避免一次性返回过多数据。
- “最新版本检查”接口按verCode降序查询第一条,索引建议:
- 在verCode、model、status上建立复合索引以提升查询效率。
- 文件上传使用内存存储(multer.memoryStorage),大文件可能影响内存占用,建议:
- 控制上传文件大小与超时时间(前端已设置较长超时)。
- 对于X8大文件,优先考虑流式上传或分片上传策略(当前实现为一次性上传)。
[本节为通用性能建议,不直接分析具体文件]
## 故障排查指南
- 认证失败(401):
- 检查请求头Authorization是否为Bearer Token
- 确认Token未过期
- 参数校验失败:
- 按照Zod校验规则修正请求体字段(长度、类型、取值范围)
- 版本冲突:
- 创建/更新时若verCode与model组合重复,会返回“该版本已存在”
- S3上传失败:
- 检查AWS_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY与AWS_S3_OTA_BUCKET配置
- 确认S3权限与存储桶存在
- 无可用版本:
- 设备端查询不到更高版本时返回“无数据”,确认目标设备型号、硬件版本与状态
章节来源
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
- [backend/src/routes/ota.js:174-181](file://backend/src/routes/ota.js#L174-L181)
- [backend/src/services/otaStorage.js:72-103](file://backend/src/services/otaStorage.js#L72-L103)
## 结论
本OTA固件API提供了完善的版本管理能力,支持设备端“最新版本检查”与后台管理功能,结合S3与本地存储策略满足不同设备型号的升级包分发需求。通过严格的参数校验与统一响应封装,提升了接口的稳定性与易用性。建议在生产环境中完善索引、优化大文件上传策略,并加强S3权限与监控告警。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 统一响应格式
- 成功:code=1,msg为成功信息,data为返回数据
- 错误:code=0msg为错误信息,data=null
- 无数据:code=2msg为提示信息,data=null
章节来源
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
### 设备端版本比较与强制更新策略
- 版本比较:仅返回verCode大于当前版本且状态为可用的最高版本
- 强制更新:由force字段控制,客户端据此决定是否强制升级
- 定向/灰度:target/beta字段可用于控制发布范围
章节来源
- [backend/src/routes/ota.js:77-89](file://backend/src/routes/ota.js#L77-L89)
- [backend/src/models/Ota.js:33-66](file://backend/src/models/Ota.js#L33-L66)
### 前端调用示例(参考)
- 列表查询:传入skip、limit、verName、model、status、verCode
- 上传包:构造FormData,包含package_file与model,设置Content-Type为multipart/form-data
- 提交表单:根据设备型号决定是否需要先上传包再填写URL/MD5
章节来源
- [frontend/src/api/ota.js:13-67](file://frontend/src/api/ota.js#L13-L67)
- [frontend/src/views/ota/index.vue:420-449](file://frontend/src/views/ota/index.vue#L420-L449)