# OTA固件API **本文引用的文件** - [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) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件为OTA固件管理API的完整RESTful接口文档,涵盖固件版本管理的HTTP方法、URL模式、请求/响应格式以及文件上传处理流程。内容包括: - 固件版本列表查询、详情获取、创建、更新、删除接口 - 设备端“最新版本检查”接口 - 文件上传(Luxsin-X8上传至S3,Luxsin-X9保存到本地目录) - 存储服务配置与使用示例 - 固件版本比较、强制更新策略与兼容性检查机制 - 下载链接生成、版本升级通知与错误处理实现指南 ## 项目结构 后端采用Express + Sequelize + MySQL架构,前端基于Vue3 + Element Plus。OTA相关逻辑集中在路由、模型、服务层与验证器中,并通过统一响应封装返回。 ```mermaid graph TB subgraph "前端" FE_API["前端API模块
frontend/src/api/ota.js"] FE_VIEW["OTA页面视图
frontend/src/views/ota/index.vue"] end subgraph "后端" ROUTER["OTA路由
backend/src/routes/ota.js"] AUTH["认证中间件
backend/src/middleware/auth.js"] RESP["统一响应封装
backend/src/utils/response.js"] VALID["参数校验
backend/src/validators/ota.js"] MODEL["数据库模型
backend/src/models/Ota.js"] STORE["存储服务
backend/src/services/otaStorage.js"] ENV["环境配置
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、url;X8同时返回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_KEY:S3区域与凭证(无凭证时走IAM角色) - AWS_S3_OTA_BUCKET:S3存储桶名称 - OTA_X8_PUBLIC_BASE:X8公开URL基础路径 - OTA_X9_URL_BASE:X9公开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=0,msg为错误信息,data=null - 无数据:code=2,msg为提示信息,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)