Files
dashboard/.qoder/repowiki/zh/content/核心功能模块/型号管理.md
T

382 lines
18 KiB
Markdown
Raw Normal View History

2026-06-30 14:46:52 +08:00
# 型号管理
<cite>
**本文引用的文件**
- [Model.js](file://backend/src/models/Model.js)
- [Brand.js](file://backend/src/models/Brand.js)
- [model.js](file://backend/src/validators/model.js)
- [models.js](file://backend/src/routes/models.js)
- [measurementStorage.js](file://backend/src/services/measurementStorage.js)
- [eqCacheStorage.js](file://backend/src/services/eqCacheStorage.js)
- [curveClient.js](file://backend/src/services/curveClient.js)
- [index.vue](file://frontend/src/views/model/index.vue)
- [model.js](file://frontend/src/api/model.js)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕“型号管理”功能进行系统性说明,涵盖型号的 CRUD 操作、技术规格管理、测量数据存储与检索、以及与品牌模型的一对一关联关系。文档基于实际代码库实现,提供接口调用流程、数据验证规则、存储策略与常见问题的解决方案,并给出面向初学者与高级开发者的分层解读。
## 项目结构
型号管理功能由前端视图、API 客户端与后端路由/模型/服务共同组成,形成“前端交互—HTTP 请求—后端路由—数据模型—外部存储”的完整链路。
```mermaid
graph TB
FE["前端视图<br/>frontend/src/views/model/index.vue"] --> API["API 客户端<br/>frontend/src/api/model.js"]
API --> ROUTER["后端路由<br/>backend/src/routes/models.js"]
ROUTER --> MODEL["型号模型<br/>backend/src/models/Model.js"]
ROUTER --> VALIDATOR["型号验证器<br/>backend/src/validators/model.js"]
ROUTER --> MSVC["频响存储服务<br/>backend/src/services/measurementStorage.js"]
ROUTER --> ESVC["EQ 缓存服务<br/>backend/src/services/eqCacheStorage.js"]
ROUTER --> CSVC["曲线校验服务<br/>backend/src/services/curveClient.js"]
ROUTER --> BRAND["品牌模型<br/>backend/src/models/Brand.js"]
```
图表来源
- [index.vue:1-1226](file://frontend/src/views/model/index.vue#L1-L1226)
- [model.js:1-151](file://frontend/src/api/model.js#L1-L151)
- [models.js:1-569](file://backend/src/routes/models.js#L1-L569)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [measurementStorage.js:1-115](file://backend/src/services/measurementStorage.js#L1-L115)
- [eqCacheStorage.js:1-73](file://backend/src/services/eqCacheStorage.js#L1-L73)
- [curveClient.js:1-147](file://backend/src/services/curveClient.js#L1-L147)
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
章节来源
- [index.vue:1-1226](file://frontend/src/views/model/index.vue#L1-L1226)
- [model.js:1-151](file://frontend/src/api/model.js#L1-L151)
- [models.js:1-569](file://backend/src/routes/models.js#L1-L569)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [measurementStorage.js:1-115](file://backend/src/services/measurementStorage.js#L1-L115)
- [eqCacheStorage.js:1-73](file://backend/src/services/eqCacheStorage.js#L1-L73)
- [curveClient.js:1-147](file://backend/src/services/curveClient.js#L1-L147)
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
## 核心组件
- 型号模型:定义型号的数据结构与约束,包括品牌名称、型号名称、形式、阻抗、来源、EQ 键等字段。
- 品牌模型:与型号存在一对一关联,型号通过品牌名称进行关联。
- 型号验证器:使用 Zod 对创建/更新请求体进行严格校验。
- 型号路由:提供列表查询、详情查看、新增、更新、删除、搜索推送、频响 CSV 查看、EQ 缓存查看等接口。
- 测量存储服务:负责将频响 CSV/文本文件上传至 S3,并支持按路径键读取。
- EQ 缓存服务:通过 Redis 提供型号 EQ 数据的哈希字段列表与具体值读取。
- 曲线校验服务:对接外部曲线 API,校验型号的 parametric_eq 数据有效性。
章节来源
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [models.js:133-566](file://backend/src/routes/models.js#L133-L566)
- [measurementStorage.js:1-115](file://backend/src/services/measurementStorage.js#L1-L115)
- [eqCacheStorage.js:1-73](file://backend/src/services/eqCacheStorage.js#L1-L73)
- [curveClient.js:1-147](file://backend/src/services/curveClient.js#L1-L147)
## 架构总览
型号管理的端到端流程如下:
- 前端通过 API 客户端发起请求,后端路由接收并进行鉴权与参数校验。
- 路由根据业务逻辑调用模型层与服务层,完成数据库读写、外部存储交互与第三方校验。
- 前端渲染结果,支持批量推送至搜索引擎、查看频响 CSV、查看 EQ 缓存等。
```mermaid
sequenceDiagram
participant U as "用户"
participant FE as "前端视图"
participant API as "API 客户端"
participant RT as "后端路由(models.js)"
participant MD as "型号模型(Model.js)"
participant MS as "频响存储(measurementStorage.js)"
participant ES as "EQ 缓存(eqCacheStorage.js)"
participant CS as "曲线校验(curveClient.js)"
U->>FE : 打开型号页面
FE->>API : 发起列表/详情/新增/更新/删除请求
API->>RT : HTTP 请求
alt 查询列表/详情
RT->>MD : 读取数据库
MD-->>RT : 返回数据
else 新增/更新
RT->>MD : 写入数据库
MD-->>RT : 返回新记录
opt 上传频响文件
RT->>MS : 上传CSV/文本至S3
MS-->>RT : 返回S3 Key
end
else 删除
RT->>ES : 从搜索引擎删除文档
RT->>MD : 删除数据库记录
end
RT-->>API : 返回响应
API-->>FE : 渲染结果
```
图表来源
- [models.js:133-566](file://backend/src/routes/models.js#L133-L566)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [measurementStorage.js:61-108](file://backend/src/services/measurementStorage.js#L61-L108)
- [eqCacheStorage.js:24-66](file://backend/src/services/eqCacheStorage.js#L24-L66)
- [curveClient.js:81-138](file://backend/src/services/curveClient.js#L81-L138)
- [index.vue:714-1063](file://frontend/src/views/model/index.vue#L714-L1063)
- [model.js:13-151](file://frontend/src/api/model.js#L13-L151)
## 详细组件分析
### 型号数据模型与品牌关联
- 型号模型包含主键、品牌名称、型号名称、形式、阻抗、来源、EQ 键、创建时间等字段。
- 品牌模型包含主键与唯一约束的品牌名称。
- 关联关系:前端在新增型号时会检查品牌是否存在,若不存在则自动创建;后端在新增/更新时也通过品牌名称进行一致性校验。
```mermaid
erDiagram
BRAND {
int id PK
string name UK
}
MODEL {
int id PK
string brand_name
string name
string form
string rig
string source
string eq_key
datetime create_at
}
BRAND ||--o{ MODEL : "拥有多个型号"
```
图表来源
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
章节来源
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
### 型号验证器与参数规范
- 创建验证器:要求品牌名称与型号名称非空且长度不超过 100;其他字段可选且可为空。
- 更新验证器:允许部分字段可选更新,其余规则与创建一致。
- 返回值:验证通过后进入业务流程,失败则返回错误信息。
章节来源
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
### 型号 CRUD 与查询接口
- 列表查询:支持按品牌名称、型号名称模糊过滤,支持按 id 或创建时间排序,支持分页与跳过。
- 详情查看:按 id 获取单条型号信息。
- 新增:支持上传频响文件(CSV/TXT/JSON),自动转换 TXT 为 CSV;若存在同品牌同型号则拒绝重复创建。
- 更新:支持部分字段更新;若上传新文件,需提供来源与形式字段;更新后写入数据库并可重新上传频响文件。
- 删除:删除前尝试从搜索引擎删除文档,再删除数据库记录。
章节来源
- [models.js:133-566](file://backend/src/routes/models.js#L133-L566)
### 技术规格管理
- 形式字段:支持入耳式、头戴式、耳塞式等枚举值映射。
- 阻抗字段:用于记录典型阻抗值。
- 来源字段:标识型号数据来源(如 Eafonyoung)。
- EQ 键字段:用于关联 EQ 缓存的键名。
章节来源
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [index.vue:226-250](file://frontend/src/views/model/index.vue#L226-L250)
### 测量数据存储与检索
- 文件类型:支持 CSV、TXT、JSONTXT 将被转换为 CSV。
- 上传流程:后端接收 multipart/form-data,校验扩展名,必要时转换格式,然后上传至 S3。
- 下载流程:仅对特定来源(如 Eafonyoung)开放,需具备形式字段以定位 S3 Key。
- S3 Key 构造规则:按来源、形式、品牌首字母与品牌+型号文件名组织路径。
```mermaid
flowchart TD
Start(["上传入口"]) --> CheckExt["校验文件扩展名"]
CheckExt --> ExtOK{"扩展名有效?"}
ExtOK --> |否| ErrExt["返回错误:不支持的文件格式"]
ExtOK --> |是| Convert["如为TXT则转换为CSV"]
Convert --> BuildKey["构建S3 Key"]
BuildKey --> Put["上传至S3"]
Put --> Done(["完成"])
ErrExt --> Done
```
图表来源
- [models.js:59-68](file://backend/src/routes/models.js#L59-L68)
- [models.js:307-335](file://backend/src/routes/models.js#L307-L335)
- [measurementStorage.js:48-79](file://backend/src/services/measurementStorage.js#L48-L79)
章节来源
- [models.js:59-68](file://backend/src/routes/models.js#L59-L68)
- [models.js:307-335](file://backend/src/routes/models.js#L307-L335)
- [measurementStorage.js:48-79](file://backend/src/services/measurementStorage.js#L48-L79)
### EQ 缓存与频响 CSV 查看
- EQ 缓存:通过 Redis 哈希存储型号的 EQ 数据,提供字段列表与单字段值读取。
- 频响 CSV:仅对特定来源开放,按来源、形式、品牌、型号拼接 S3 Key 并读取内容。
章节来源
- [models.js:183-278](file://backend/src/routes/models.js#L183-L278)
- [eqCacheStorage.js:24-66](file://backend/src/services/eqCacheStorage.js#L24-L66)
- [measurementStorage.js:87-108](file://backend/src/services/measurementStorage.js#L87-L108)
### 搜索引擎推送与校验
- 校验:对选中型号调用曲线校验服务,确保 parametric_eq 结构有效。
- 推送:将型号文档推送到搜索引擎,支持批量与进度反馈。
```mermaid
sequenceDiagram
participant FE as "前端"
participant API as "API 客户端"
participant RT as "后端路由(models.js)"
participant CS as "曲线校验(curveClient.js)"
FE->>API : 选择型号并点击推送
API->>RT : POST /models/push-to-search/validate
loop 对每个型号
RT->>CS : fetchAndValidateCurve(brand,name,form)
CS-->>RT : [ok, reason]
end
alt 全部通过
API->>RT : POST /models/push-to-search
RT-->>API : 返回推送结果
else 部分失败
RT-->>API : 返回错误列表
end
```
图表来源
- [models.js:466-514](file://backend/src/routes/models.js#L466-L514)
- [models.js:516-566](file://backend/src/routes/models.js#L516-L566)
- [curveClient.js:81-138](file://backend/src/services/curveClient.js#L81-L138)
- [index.vue:1117-1220](file://frontend/src/views/model/index.vue#L1117-L1220)
章节来源
- [models.js:466-514](file://backend/src/routes/models.js#L466-L514)
- [models.js:516-566](file://backend/src/routes/models.js#L516-L566)
- [curveClient.js:81-138](file://backend/src/services/curveClient.js#L81-L138)
- [index.vue:1117-1220](file://frontend/src/views/model/index.vue#L1117-L1220)
### 前端交互与使用示例
- 列表查询:支持品牌名称与型号名称模糊搜索、排序与分页。
- 详情查看:点击更多操作可查看推送状态、EQ 缓存、CSV 内容。
- 参数配置:新增/编辑对话框支持品牌选择、型号输入、形式、阻抗、来源与频响文件上传。
- 批量推送:勾选多条后执行推送流程,包含校验与进度提示。
章节来源
- [index.vue:1-1226](file://frontend/src/views/model/index.vue#L1-L1226)
- [model.js:1-151](file://frontend/src/api/model.js#L1-L151)
## 依赖关系分析
- 前端依赖:Element Plus 组件库、Vue 3、axios 请求封装。
- 后端依赖:Express 路由、Sequelize ORM、Zod 验证、Multer 文件上传、Axios 第三方调用、AWS SDK S3 访问、Redis 客户端。
- 外部服务:Meilisearch(搜索引擎)、Luxsin 曲线 API、S3 存储。
```mermaid
graph LR
FE["前端(index.vue)"] --> API["API(model.js)"]
API --> RT["路由(models.js)"]
RT --> MD["模型(Model.js)"]
RT --> VAL["验证器(model.js)"]
RT --> MS["S3(measurementStorage.js)"]
RT --> ES["Redis(eqCacheStorage.js)"]
RT --> CS["曲线(curveClient.js)"]
RT --> BR["品牌(Brand.js)"]
```
图表来源
- [index.vue:1-1226](file://frontend/src/views/model/index.vue#L1-L1226)
- [model.js:1-151](file://frontend/src/api/model.js#L1-L151)
- [models.js:1-569](file://backend/src/routes/models.js#L1-L569)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [measurementStorage.js:1-115](file://backend/src/services/measurementStorage.js#L1-L115)
- [eqCacheStorage.js:1-73](file://backend/src/services/eqCacheStorage.js#L1-L73)
- [curveClient.js:1-147](file://backend/src/services/curveClient.js#L1-L147)
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
章节来源
- [index.vue:1-1226](file://frontend/src/views/model/index.vue#L1-L1226)
- [model.js:1-151](file://frontend/src/api/model.js#L1-L151)
- [models.js:1-569](file://backend/src/routes/models.js#L1-L569)
- [Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
- [model.js:1-22](file://backend/src/validators/model.js#L1-L22)
- [measurementStorage.js:1-115](file://backend/src/services/measurementStorage.js#L1-L115)
- [eqCacheStorage.js:1-73](file://backend/src/services/eqCacheStorage.js#L1-L73)
- [curveClient.js:1-147](file://backend/src/services/curveClient.js#L1-L147)
- [Brand.js:1-23](file://backend/src/models/Brand.js#L1-L23)
## 性能考虑
- 分页与排序:列表查询支持分页与排序,建议前端设置合理页大小与排序字段,避免一次性加载过多数据。
- 文件上传:上传 TXT 时会进行转换,建议控制文件大小与格式,减少不必要的转换开销。
- 搜索推送:批量推送包含校验步骤,建议分批处理并监控进度,避免超时。
- 缓存与存储:EQ 缓存通过 Redis 快速读取字段列表,避免大对象传输;S3 读取采用流式读取,注意网络抖动与超时配置。
## 故障排查指南
- 参数验证失败
- 现象:创建/更新返回参数错误。
- 排查:检查品牌名称与型号名称长度、必填字段是否缺失;确认前端表单规则与后端验证器一致。
- 参考
- [model.js:3-19](file://backend/src/validators/model.js#L3-L19)
- [models.js:307-361](file://backend/src/routes/models.js#L307-L361)
- 重复型号
- 现象:新增时报“该品牌下型号名称已存在”。
- 排查:确认数据库中是否已存在相同品牌+型号组合;更新时注意品牌与型号变更后的冲突检测。
- 参考
- [models.js:312-317](file://backend/src/routes/models.js#L312-L317)
- [models.js:380-388](file://backend/src/routes/models.js#L380-L388)
- 不支持的文件格式
- 现象:上传文件返回“不支持的文件格式”。
- 排查:确认扩展名为 CSV/TXT/JSONTXT 会被转换为 CSV。
- 参考
- [models.js:320-325](file://backend/src/routes/models.js#L320-L325)
- [models.js:59-68](file://backend/src/routes/models.js#L59-L68)
- S3 读取失败
- 现象:查看 CSV 时提示“S3 上未找到该型号的频响文件”或读取失败。
- 排查:确认来源为 Eafonyoung、具备形式字段、S3 Key 构造正确;检查桶权限与区域配置。
- 参考
- [models.js:255-258](file://backend/src/routes/models.js#L255-L258)
- [measurementStorage.js:87-108](file://backend/src/services/measurementStorage.js#L87-L108)
- 推送失败
- 现象:推送至搜索引擎失败或校验未通过。
- 排查:检查型号的佩戴方式是否为入耳式或头戴式;确认曲线接口可用与响应格式正确。
- 参考
- [models.js:466-514](file://backend/src/routes/models.js#L466-L514)
- [curveClient.js:81-138](file://backend/src/services/curveClient.js#L81-L138)
章节来源
- [model.js:3-19](file://backend/src/validators/model.js#L3-L19)
- [models.js:312-317](file://backend/src/routes/models.js#L312-L317)
- [models.js:320-325](file://backend/src/routes/models.js#L320-L325)
- [models.js:255-258](file://backend/src/routes/models.js#L255-L258)
- [measurementStorage.js:87-108](file://backend/src/services/measurementStorage.js#L87-L108)
- [models.js:466-514](file://backend/src/routes/models.js#L466-L514)
- [curveClient.js:81-138](file://backend/src/services/curveClient.js#L81-L138)
## 结论
型号管理功能通过清晰的前后端职责划分与严格的参数验证,实现了从基础 CRUD 到技术规格管理、测量数据存储与搜索引擎推送的完整闭环。借助 Redis 与 S3 的高效读写能力,以及第三方曲线校验服务,系统在保证数据一致性的同时提升了用户体验与可维护性。建议在生产环境中进一步完善日志与监控,优化批量推送的并发与重试策略,并持续关注外部依赖的稳定性。
## 附录
- 常用接口清单
- 列表查询:GET /api/models/
- 详情查看:GET /api/models/:id
- 新增:POST /api/models/
- 更新:PUT /api/models/:id
- 删除:DELETE /api/models/:id
- 查看 EQ 缓存:GET /api/models/:id/eq-cache
- 查看 EQ 缓存字段:GET /api/models/:id/eq-cache/field?key=...
- 查看搜索引擎推送:GET /api/models/:id/meilisearch
- 查看频响 CSVGET /api/models/:id/measurement
- 校验推送:POST /api/models/push-to-search/validate
- 推送:POST /api/models/push-to-search
章节来源
- [models.js:133-566](file://backend/src/routes/models.js#L133-L566)
- [model.js:13-151](file://frontend/src/api/model.js#L13-L151)