添加 uipro,更新 wiki

This commit is contained in:
eafonyang
2026-07-10 11:25:45 +08:00
parent 6bb39e9172
commit f88ff46427
163 changed files with 30244 additions and 151 deletions
@@ -15,6 +15,13 @@
- [frontend/package.json](file://frontend/package.json)
</cite>
## 更新摘要
**变更内容**
- 版本唯一性约束从'verCode + model'升级为'verCode + model + beta',支持同一设备型号下存在多个不同beta状态的版本
- 在创建/更新接口中新增对beta字段的支持,允许设置灰度发布状态
- 前端新增beta筛选功能,支持按灰度状态过滤版本列表
- 实现基于(model, beta)组合的最新版本标识显示逻辑
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
@@ -30,11 +37,12 @@
## 简介
本文件为OTA固件管理API的完整RESTful接口文档,涵盖固件版本管理的HTTP方法、URL模式、请求/响应格式以及文件上传处理流程。内容包括:
- 固件版本列表查询、详情获取、创建、更新、删除接口
- 设备端最新版本检查接口
- 设备端"最新版本检查"接口
- 文件上传(Luxsin-X8上传至S3Luxsin-X9保存到本地目录)
- 存储服务配置与使用示例
- 固件版本比较、强制更新策略与兼容性检查机制
- 下载链接生成、版本升级通知与错误处理实现指南
- **新增**:Beta版本支持与灰度发布管理功能
## 项目结构
后端采用Express + Sequelize + MySQL架构,前端基于Vue3 + Element Plus。OTA相关逻辑集中在路由、模型、服务层与验证器中,并通过统一响应封装返回。
@@ -65,20 +73,20 @@ STORE --> ENV
```
图表来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
- [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)
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
章节来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
- [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)
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
## 核心组件
- 路由层:定义所有OTA相关HTTP接口,包含设备端最新版本检查和后台管理接口。
- 路由层:定义所有OTA相关HTTP接口,包含设备端"最新版本检查"和后台管理接口。
- 认证中间件:保护后台接口,要求Bearer Token。
- 参数校验:使用Zod对创建/更新请求体进行严格校验。
- 数据模型:Sequelize定义的OTA表结构,包含版本号、MD5、强制更新、定向灰度、时间窗口等字段。
- 参数校验:使用Zod对创建/更新请求体进行严格校验,支持beta字段验证
- 数据模型:Sequelize定义的OTA表结构,包含版本号、MD5、强制更新、定向灰度、时间窗口等字段**新增beta字段支持**
- 存储服务:根据设备型号选择不同存储路径(S3或本地),并生成公开下载链接。
- 响应封装:统一封装成功/错误/无数据三类响应格式。
@@ -117,7 +125,7 @@ Router->>Logger : 记录查询结果
## 详细组件分析
### 设备端最新版本检查
### 设备端"最新版本检查"
- 方法与路径:GET /api/ota/latest/check
- 请求参数:
- currentVerCode: 当前设备版本号(整数)
@@ -145,10 +153,13 @@ Router->>Logger : 记录查询结果
- verName: 模糊匹配版本名称
- model: 模糊匹配设备型号
- status: 状态(0/1
- **beta: 灰度状态筛选(0/1**
- 响应:分页数据(items、total、skip、limit
**更新** 新增beta参数支持,可按灰度状态筛选版本列表
章节来源
- [backend/src/routes/ota.js:107-143](file://backend/src/routes/ota.js#L107-L143)
- [backend/src/routes/ota.js:107-145](file://backend/src/routes/ota.js#L107-L145)
#### 获取指定OTA详情
- 方法与路径:GET /api/ota/:ota_id
@@ -156,12 +167,12 @@ Router->>Logger : 记录查询结果
- 响应:单条记录或无数据
章节来源
- [backend/src/routes/ota.js:145-160](file://backend/src/routes/ota.js#L145-L160)
- [backend/src/routes/ota.js:147-162](file://backend/src/routes/ota.js#L147-L162)
#### 创建OTA版本
- 方法与路径:POST /api/ota/
- 请求体字段(必填/可选见校验规则):
- verCode: 整数(唯一性约束:同model下不可重复)
- verCode: 整数(**唯一性约束:同model+beta下不可重复**
- verName: 字符串(1~20
- url: 字符串(下载地址或上传后生成的URL)
- md5: 32位十六进制字符串
@@ -170,13 +181,15 @@ Router->>Logger : 记录查询结果
- model: 设备型号(可空)
- hw: 硬件版本号(默认0
- target: 是否定向(0/1,默认0
- beta: 是否灰度(0/1,默认0
- **beta: 是否灰度(0/1,默认0**
- startTime/endTime: 时间字符串(可空)
- status: 状态(0/1,默认1
- 响应:创建成功的记录
**更新** 版本唯一性约束已更新为'verCode + model + beta'组合,允许同一设备型号下存在多个不同beta状态的版本
章节来源
- [backend/src/routes/ota.js:162-194](file://backend/src/routes/ota.js#L162-L194)
- [backend/src/routes/ota.js:164-196](file://backend/src/routes/ota.js#L164-L196)
- [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)
@@ -185,11 +198,13 @@ Router->>Logger : 记录查询结果
- 请求体字段:同创建接口(部分字段可为空表示不更新)
- 响应:更新后的记录
- 注意:
- 若更新版本号设备型号,需保证新的组合在同model下唯一
- **若更新版本号设备型号或灰度状态,需保证新的组合在同model+beta下唯一**
- 日期字段会自动转换为Date类型
**更新** 版本冲突检查逻辑已更新,现在考虑beta字段参与唯一性验证
章节来源
- [backend/src/routes/ota.js:196-247](file://backend/src/routes/ota.js#L196-L247)
- [backend/src/routes/ota.js:198-250](file://backend/src/routes/ota.js#L198-L250)
- [backend/src/validators/ota.js:19-33](file://backend/src/validators/ota.js#L19-L33)
#### 删除OTA版本
@@ -197,7 +212,7 @@ Router->>Logger : 记录查询结果
- 响应:删除成功消息
章节来源
- [backend/src/routes/ota.js:249-268](file://backend/src/routes/ota.js#L249-L268)
- [backend/src/routes/ota.js:252-271](file://backend/src/routes/ota.js#L252-L271)
### 文件上传与存储
@@ -255,14 +270,18 @@ Router-->>Client : 成功响应
- 前端API模块提供:
- 列表、详情、创建、更新、删除、上传包等方法
- OTA页面视图:
- 支持搜索(版本名、设备型号、状态、版本号)
- 支持搜索(版本名、设备型号、状态、版本号、**灰度状态**
- 分页与表格展示
- **新增beta筛选下拉框,支持按灰度状态过滤**
- **实现基于(model, beta)组合的最新版本标识显示**
- 上传升级包(X8/X9)并回填URL与MD5
- 表单校验与提交
**更新** 前端新增beta筛选功能和智能最新版本标识显示逻辑
章节来源
- [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)
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
## 依赖关系分析
@@ -317,7 +336,7 @@ OtaRoute --> ApiResponse : "统一响应"
```
图表来源
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
- [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)
@@ -326,13 +345,14 @@ OtaRoute --> ApiResponse : "统一响应"
## 性能考量
- 列表查询限制每页最大1000条,避免一次性返回过多数据。
- 最新版本检查接口按verCode降序查询第一条,索引建议:
- "最新版本检查"接口按verCode降序查询第一条,索引建议:
- 在verCode、model、status上建立复合索引以提升查询效率。
- **建议增加beta字段的索引以优化灰度版本筛选查询**。
- 文件上传使用内存存储(multer.memoryStorage),大文件可能影响内存占用,建议:
- 控制上传文件大小与超时时间(前端已设置较长超时)。
- 对于X8大文件,优先考虑流式上传或分片上传策略(当前实现为一次性上传)。
[本节为通用性能建议,不直接分析具体文件]
**更新** 建议为beta字段添加数据库索引以优化灰度版本筛选性能
## 故障排查指南
- 认证失败(401):
@@ -340,24 +360,28 @@ OtaRoute --> ApiResponse : "统一响应"
- 确认Token未过期
- 参数校验失败:
- 按照Zod校验规则修正请求体字段(长度、类型、取值范围)
- 版本冲突:
- 创建/更新时若verCodemodel组合重复,会返回该版本已存在
- **版本冲突**
- **创建/更新时若verCodemodel和beta组合重复,会返回"该版本已存在(相同版本+灰度状态)"**
- **确保在同一设备型号和灰度状态下版本号的唯一性**
- S3上传失败:
- 检查AWS_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY与AWS_S3_OTA_BUCKET配置
- 确认S3权限与存储桶存在
- 无可用版本:
- 设备端查询不到更高版本时返回无数据,确认目标设备型号、硬件版本与状态
- 设备端查询不到更高版本时返回"无数据",确认目标设备型号、硬件版本与状态
**更新** 版本冲突错误信息已更新,明确说明需要检查verCode + model + beta组合的唯一性
章节来源
- [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/routes/ota.js:176-183](file://backend/src/routes/ota.js#L176-L183)
- [backend/src/routes/ota.js:223-231](file://backend/src/routes/ota.js#L223-L231)
- [backend/src/services/otaStorage.js:72-103](file://backend/src/services/otaStorage.js#L72-L103)
## 结论
本OTA固件API提供了完善的版本管理能力,支持设备端最新版本检查与后台管理功能,结合S3与本地存储策略满足不同设备型号的升级包分发需求。通过严格的参数校验与统一响应封装,提升了接口的稳定性与易用性。建议在生产环境中完善索引、优化大文件上传策略,并加强S3权限与监控告警。
本OTA固件API提供了完善的版本管理能力,支持设备端"最新版本检查"与后台管理功能,结合S3与本地存储策略满足不同设备型号的升级包分发需求。**新增的beta版本支持功能使得系统能够管理同一设备型号下的多个灰度版本,提升了版本发布的灵活性和可控性**。通过严格的参数校验与统一响应封装,提升了接口的稳定性与易用性。建议在生产环境中完善索引、优化大文件上传策略,并加强S3权限与监控告警。
[本节为总结性内容,不直接分析具体文件]
**更新** 系统现已支持完整的灰度发布管理,允许在同一设备型号下并行管理稳定版和测试版固件。
## 附录
@@ -373,16 +397,38 @@ OtaRoute --> ApiResponse : "统一响应"
- 版本比较:仅返回verCode大于当前版本且状态为可用的最高版本
- 强制更新:由force字段控制,客户端据此决定是否强制升级
- 定向/灰度:target/beta字段可用于控制发布范围
- **新版本管理**:系统支持同一设备型号下存在多个不同beta状态的版本,每个(beta, model)组合都有独立的最新版本标识
**更新** 最新版本标识逻辑已更新,现在基于(model, beta)组合来计算和显示latest标签
章节来源
- [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)
- [frontend/src/views/ota/index.vue:428-443](file://frontend/src/views/ota/index.vue#L428-L443)
### 前端调用示例(参考)
- 列表查询:传入skip、limit、verName、model、status、verCode
- 列表查询:传入skip、limit、verName、model、status、verCode、**beta**
- 上传包:构造FormData,包含package_file与model,设置Content-Type为multipart/form-data
- 提交表单:根据设备型号决定是否需要先上传包再填写URL/MD5
- **beta筛选**:在searchForm中添加beta字段,值为0或1进行灰度状态筛选
**更新** 前端API调用示例已更新,包含beta参数的使用方法
章节来源
- [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)
- [frontend/src/views/ota/index.vue:412-418](file://frontend/src/views/ota/index.vue#L412-L418)
- [frontend/src/views/ota/index.vue:597-599](file://frontend/src/views/ota/index.vue#L597-L599)
### Beta版本管理特性
- **版本唯一性**:同一设备型号下,相同版本号但不同beta状态的版本可以共存
- **灰度发布**:通过beta字段控制版本是否为灰度版本(0=否,1=是)
- **智能标识**:前端自动计算并显示每个(model, beta)组合下的最新版本标签
- **筛选功能**:支持按beta状态筛选版本列表,便于管理不同发布阶段的版本
**新增** Beta版本管理功能的详细说明
章节来源
- [backend/src/routes/ota.js:176-183](file://backend/src/routes/ota.js#L176-L183)
- [backend/src/routes/ota.js:218-231](file://backend/src/routes/ota.js#L218-L231)
- [frontend/src/views/ota/index.vue:428-443](file://frontend/src/views/ota/index.vue#L428-L443)
- [frontend/src/views/ota/index.vue:35-45](file://frontend/src/views/ota/index.vue#L35-L45)
@@ -12,15 +12,15 @@
- [backend/src/routes/ota.js](file://backend/src/routes/ota.js)
- [backend/src/services/squiglink.js](file://backend/src/services/squiglink.js)
- [frontend/src/views/model/components/ModelFormDialog.vue](file://frontend/src/views/model/components/ModelFormDialog.vue)
- [backend/src/services/measurementStorage.js](file://backend/src/services/measurementStorage.js)
</cite>
## 更新摘要
**变更内容**
- 新增squig.link外部URL数据源抓取功能
- 增强模型创建/更新流程支持外部频响数据源
- 添加squiglink_csv字段支持直接上传CSV内容
- 新增squiglink-fetch接口用于从外部URL获取频响数据
- 前端ModelFormDialog组件集成squig.link导入功能
- 新增测量文件S3自动迁移功能,当更新型号的路径相关字段时自动迁移现有CSV文件
- 增强型号更新接口的智能文件处理逻辑
- 实现S3服务端文件复制与删除操作,确保数据一致性
- 优化型号管理流程,减少手动文件干预需求
## 目录
1. [简介](#简介)
@@ -34,16 +34,16 @@
9. [结论](#结论)
## 简介
本文件为型号管理API的详细RESTful API文档,覆盖型号的CRUD操作、查询筛选与排序、数据验证规则,以及与OTA固件的一对多关联关系与级联操作。文档同时提供前端调用示例与后端实现细节,帮助开发者快速集成与维护。**最新更新**:新增squig.link外部数据源支持,增强模型创建/更新流程以支持外部URL数据源
本文件为型号管理API的详细RESTful API文档,覆盖型号的CRUD操作、查询筛选与排序、数据验证规则,以及与OTA固件的一对多关联关系与级联操作。文档同时提供前端调用示例与后端实现细节,帮助开发者快速集成与维护。**最新更新**:新增squig.link外部数据源支持及测量文件S3自动迁移功能,显著提升型号数据管理的自动化程度和数据一致性保障
## 项目结构
型号管理API位于后端Express应用中,采用模块化设计:
- 路由层:集中于 models.js,提供型号的增删改查、搜索推送、频响文件处理、**squig.link数据抓取**等接口
- 路由层:集中于 models.js,提供型号的增删改查、搜索推送、频响文件处理、**squig.link数据抓取**、**S3文件自动迁移**等接口
- 模型层:Model.js 定义数据库表结构
- 验证层:model.js 使用Zod进行请求体验证
- 工具层:response.js 统一响应格式
- 中间件:auth.js 提供鉴权保护
- **服务层**squiglink.js 提供squig.link外部数据源抓取服务
- **服务层**squiglink.js 提供squig.link外部数据源抓取服务measurementStorage.js 提供S3存储与文件迁移服务
- 前端封装:frontend/src/api/model.js 提供HTTP调用封装
- **前端组件**ModelFormDialog.vue 集成squig.link导入功能
@@ -55,11 +55,13 @@ R --> V["验证层<br/>backend/src/validators/model.js"]
R --> U["工具层<br/>backend/src/utils/response.js"]
R --> A["中间件<br/>backend/src/middleware/auth.js"]
R --> S["服务层<br/>backend/src/services/squiglink.js"]
R --> MS["存储服务<br/>backend/src/services/measurementStorage.js"]
R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
MS -. 存储 .-> S3["S3对象存储"]
```
**图表来源**
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
@@ -67,10 +69,11 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
- [frontend/src/api/model.js:1-165](file://frontend/src/api/model.js#L1-L165)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
- [frontend/src/views/model/components/ModelFormDialog.vue:1-555](file://frontend/src/views/model/components/ModelFormDialog.vue#L1-L555)
**章节来源**
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
@@ -78,15 +81,17 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
- [frontend/src/api/model.js:1-165](file://frontend/src/api/model.js#L1-L165)
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
- [frontend/src/views/model/components/ModelFormDialog.vue:1-555](file://frontend/src/views/model/components/ModelFormDialog.vue#L1-L555)
## 核心组件
- 路由控制器:models.js 提供型号的列表查询、详情获取、创建、更新、删除、搜索推送、频响文件上传与查询、**squig.link数据抓取**等接口
- 路由控制器:models.js 提供型号的列表查询、详情获取、创建、更新、删除、搜索推送、频响文件处理、**squig.link数据抓取**、**S3文件自动迁移**等接口
- 数据模型:Model.js 定义型号字段及约束
- 请求验证:model.js 使用Zod Schema进行创建/更新的输入校验
- 统一响应:response.js 提供统一的响应结构
- 鉴权中间件:auth.js 实现Bearer Token鉴权
- **squig.link服务**squiglink.js 提供外部数据源抓取功能
- **S3存储服务**measurementStorage.js 提供文件上传、下载、迁移等存储服务
- 前端封装:frontend/src/api/model.js 提供HTTP调用封装
- **前端组件**ModelFormDialog.vue 集成squig.link导入功能
@@ -97,11 +102,12 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
- [frontend/src/api/model.js:13-165](file://frontend/src/api/model.js#L13-L165)
- [frontend/src/views/model/components/ModelFormDialog.vue:158-464](file://frontend/src/views/model/components/ModelFormDialog.vue#L158-L464)
## 架构概览
型号管理API采用分层架构,路由层负责HTTP协议与参数解析,模型层负责数据持久化,验证层确保输入合法性,工具层统一输出格式,中间件提供安全控制,**服务层提供外部数据源集成**。
型号管理API采用分层架构,路由层负责HTTP协议与参数解析,模型层负责数据持久化,验证层确保输入合法性,工具层统一输出格式,中间件提供安全控制,**服务层提供外部数据源集成与S3存储管理**。
```mermaid
sequenceDiagram
@@ -110,6 +116,7 @@ participant R as "路由(models.js)"
participant V as "验证(model.js)"
participant M as "模型(Model.js)"
participant S as "服务(squiglink.js)"
participant MS as "存储服务(measurementStorage.js)"
participant U as "响应(response.js)"
participant A as "鉴权(auth.js)"
C->>R : "HTTP请求"
@@ -119,6 +126,8 @@ R->>V : "请求体验证"
V-->>R : "验证结果"
R->>S : "外部数据源抓取可选"
S-->>R : "抓取结果"
R->>MS : "S3文件操作(上传/迁移)"
MS-->>R : "操作结果"
R->>M : "数据库操作"
M-->>R : "结果"
R->>U : "封装响应"
@@ -130,6 +139,7 @@ U-->>C : "统一响应"
- [backend/src/validators/model.js:3-19](file://backend/src/validators/model.js#L3-L19)
- [backend/src/models/Model.js:4-50](file://backend/src/models/Model.js#L4-L50)
- [backend/src/services/squiglink.js:261-310](file://backend/src/services/squiglink.js#L261-L310)
- [backend/src/services/measurementStorage.js:116-157](file://backend/src/services/measurementStorage.js#L116-L157)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
@@ -240,11 +250,14 @@ datetime create_at
- 路径参数:model_id(整数)
- 表单字段:同创建,支持部分字段更新(传入'null'表示保持原值)
- 文件处理:同创建,若上传需提供source与form
- **智能文件迁移**:当未上传新文件且路径相关字段(source、form、brand_name、name)发生变更时,系统自动将现有CSV文件从旧路径迁移到新路径
- 成功响应:更新后的型号信息
- 异常响应:未找到、重复、格式不支持、通用错误
**新增** 智能S3文件自动迁移功能,确保数据一致性与完整性
**章节来源**
- [backend/src/routes/models.js:439-526](file://backend/src/routes/models.js#L439-L526)
- [backend/src/routes/models.js:439-535](file://backend/src/routes/models.js#L439-L535)
- [backend/src/validators/model.js:12-19](file://backend/src/validators/model.js#L12-L19)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
@@ -260,7 +273,7 @@ datetime create_at
- 异常响应:未找到、Meilisearch删除失败、通用错误
**章节来源**
- [backend/src/routes/models.js:528-554](file://backend/src/routes/models.js#L528-L554)
- [backend/src/routes/models.js:537-563](file://backend/src/routes/models.js#L537-L563)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
@@ -309,7 +322,7 @@ string model
- 输出:推送成功数量、任务ID与推送数据
**章节来源**
- [backend/src/routes/models.js:556-656](file://backend/src/routes/models.js#L556-L656)
- [backend/src/routes/models.js:565-665](file://backend/src/routes/models.js#L565-L665)
### 频响文件上传与查询
- 上传:POST /api/models/multipart/form-data),支持TXT自动转换为CSV**新增squiglink_csv字段**
@@ -362,15 +375,65 @@ string model
**新增** 完整的squig.link外部数据源支持
**章节来源**
- [backend/src/routes/models.js:307-369](file://backend/src/routes/models.js#L307-L369)
- [backend/src/routes/models.js:307-369](file://backend/src/routes/models.js#L307-369)
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
- [frontend/src/views/model/components/ModelFormDialog.vue:158-464](file://frontend/src/views/model/components/ModelFormDialog.vue#L158-L464)
### S3文件自动迁移功能
#### 智能文件迁移机制
- **触发条件**:更新型号时未上传新文件且路径相关字段发生变更
- **路径字段**:source(来源)、form(佩戴方式)、brand_name(品牌名)、name(型号名)
- **迁移策略**:服务端直接复制后删除,无需下载再上传
- **原子操作**:复制成功后才删除旧文件,确保数据完整性
#### S3存储服务功能
- **文件路径构建**autoeq/measurements/{source}/data/{form}/{brandFirstChar}/{brand model}.csv
- **上传服务**uploadMeasurementToS3 - 支持CSV文件上传到S3
- **读取服务**getMeasurementFromS3 - 从S3读取CSV文件内容
- **迁移服务**moveMeasurementOnS3 - 实现S3文件的智能迁移
- **路径生成**buildMeasurementKey - 根据参数生成标准S3 Key
#### 迁移流程详解
```mermaid
flowchart TD
A[更新型号请求] --> B{是否上传新文件?}
B --> |是| C[上传新文件到S3]
B --> |否| D{路径字段是否变更?}
D --> |否| E[直接更新数据库]
D --> |是| F[计算新旧S3路径]
F --> G{路径是否相同?}
G --> |是| H[跳过迁移]
G --> |否| I[执行S3复制操作]
I --> J[复制成功后删除旧文件]
J --> K[更新数据库]
C --> L[返回成功响应]
E --> L
H --> L
K --> L
```
**图表来源**
- [backend/src/routes/models.js:502-509](file://backend/src/routes/models.js#L502-L509)
- [backend/src/services/measurementStorage.js:116-157](file://backend/src/services/measurementStorage.js#L116-L157)
#### 错误处理与日志记录
- **文件不存在**:跳过迁移并记录日志,不影响更新操作
- **网络异常**:抛出明确错误信息,便于问题排查
- **权限问题**:详细的错误描述,指导权限配置
- **路径冲突**:自动检测路径变化,避免不必要的操作
**新增** 完整的S3文件自动迁移功能,提升数据管理自动化水平
**章节来源**
- [backend/src/routes/models.js:502-509](file://backend/src/routes/models.js#L502-L509)
- [backend/src/services/measurementStorage.js:110-165](file://backend/src/services/measurementStorage.js#L110-L165)
## 依赖分析
- 路由依赖:models.js 依赖Model模型、Zod验证器、响应工具、鉴权中间件,并与Meilisearch、S3服务交互,**新增squiglink服务依赖**
- 路由依赖:models.js 依赖Model模型、Zod验证器、响应工具、鉴权中间件,并与Meilisearch、S3服务交互,**新增squiglink服务依赖与measurementStorage服务依赖**
- 模型依赖:Model.js 依赖Sequelize ORM
- 前端依赖:frontend/src/api/model.js 依赖通用请求封装
- **服务依赖**squiglink.js 依赖axios、logger,提供外部数据源抓取功能
- **服务依赖**squiglink.js 依赖axios、logger,提供外部数据源抓取功能measurementStorage.js 依赖AWS SDK、logger,提供S3存储服务
```mermaid
graph LR
@@ -379,21 +442,24 @@ R --> V["model.js(Zod)"]
R --> U["response.js"]
R --> A["auth.js"]
R --> S["squiglink.js"]
R --> MS["measurementStorage.js"]
R -. 外部 .-> MS["Meilisearch"]
R -. 外部 .-> S3["S3存储"]
S -. 外部 .-> SL["squig.link"]
MS -. 外部 .-> AWS["AWS SDK"]
```
**图表来源**
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
**章节来源**
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
## 性能考虑
- 分页限制:列表查询limit上限为1000,避免一次性返回过多数据
@@ -402,6 +468,8 @@ S -. 外部 .-> SL["squig.link"]
- 验证前置:使用Zod在进入数据库操作前完成字段校验,减少无效请求
- **squig.link抓取超时**:设置15秒超时,避免外部服务影响系统性能
- **squigsites.json缓存**1小时TTL减少对外部服务的频繁请求
- **S3迁移优化**:服务端直接复制,避免网络传输开销,提高迁移效率
- **路径变更检测**:智能判断是否需要迁移,避免不必要的S3操作
## 故障排除指南
- 401 未登录/无效凭证:检查Authorization头是否为Bearer Token且有效
@@ -412,6 +480,8 @@ S -. 外部 .-> SL["squig.link"]
- Meilisearch异常:检查服务连通性与API密钥
- **squig.link抓取失败**:检查share_url格式、网络连通性、目标站点可用性
- **squig.link文件下载失败**:确认文件存在、权限正确、支持的文件后缀
- **S3迁移失败**:检查AWS凭证配置、S3 Bucket权限、网络连接状态
- **文件路径错误**:确认source、form、brand_name、name字段值符合规范
**章节来源**
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
@@ -419,6 +489,7 @@ S -. 外部 .-> SL["squig.link"]
- [backend/src/routes/models.js:322-325](file://backend/src/routes/models.js#L322-L325)
- [backend/src/routes/models.js:450-455](file://backend/src/routes/models.js#L450-L455)
- [backend/src/services/squiglink.js:33-47](file://backend/src/services/squiglink.js#L33-L47)
- [backend/src/services/measurementStorage.js:149-156](file://backend/src/services/measurementStorage.js#L149-L156)
## 结论
型号管理API提供了完善的CRUD能力、灵活的查询过滤与排序、严格的输入验证、以及与搜索与存储系统的集成。**最新更新**:新增squig.link外部数据源支持,显著提升了型号数据的获取效率和准确性。结合OTA模型的关联关系,可支撑从型号到固件升级的完整业务闭环。建议在生产环境中关注分页与超时配置、文件上传性能与安全策略、**squig.link抓取的超时与缓存策略**,并在删除型号前做好OTA关联清理。
型号管理API提供了完善的CRUD能力、灵活的查询过滤与排序、严格的输入验证、以及与搜索与存储系统的集成。**最新更新**:新增squig.link外部数据源支持及测量文件S3自动迁移功能,显著提升了型号数据的获取效率和数据一致性保障。智能文件迁移机制确保了在更新型号路径相关字段时,现有CSV文件能够自动迁移到新路径,无需人工干预。结合OTA模型的关联关系,可支撑从型号到固件升级的完整业务闭环。建议在生产环境中关注分页与超时配置、文件上传性能与安全策略、**squig.link抓取的超时与缓存策略**、**S3迁移的性能监控与错误处理**,并在删除型号前做好OTA关联清理。