# 后端API文档 **本文引用的文件** - [backend/src/app.js](file://backend/src/app.js) - [backend/src/routes/index.js](file://backend/src/routes/index.js) - [backend/src/routes/auth.js](file://backend/src/routes/auth.js) - [backend/src/routes/brands.js](file://backend/src/routes/brands.js) - [backend/src/routes/models.js](file://backend/src/routes/models.js) - [backend/src/routes/ota.js](file://backend/src/routes/ota.js) - [backend/src/routes/shareCodeLogs.js](file://backend/src/routes/shareCodeLogs.js) - [backend/src/routes/users.js](file://backend/src/routes/users.js) - [backend/src/routes/dashboard.js](file://backend/src/routes/dashboard.js) - [backend/src/middleware/auth.js](file://backend/src/middleware/auth.js) - [backend/src/utils/jwt.js](file://backend/src/utils/jwt.js) - [backend/src/utils/password.js](file://backend/src/utils/password.js) - [backend/src/utils/response.js](file://backend/src/utils/response.js) - [backend/src/models/index.js](file://backend/src/models/index.js) - [backend/package.json](file://backend/package.json) - [backend/README.md](file://backend/README.md) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本项目为“耳机品牌与型号管理平台”的后端 RESTful API,采用 Node.js + Express 构建,提供认证系统、品牌管理、型号管理、OTA 固件、用户管理以及分享码日志等完整能力。系统通过统一响应体封装、JWT 认证中间件、Sequelize 数据库访问层与多处外部服务集成(S3、Meilisearch、AWS SDK),形成模块化、可扩展的 API 体系。 - 版本信息:后端版本 1.0.0 - 默认端口:8083(可通过环境变量覆盖) - 健康检查:GET /health - 在线文档:Swagger UI 与 ReDoc(根路径与健康检查接口提供文档入口) **章节来源** - [backend/src/app.js:1-60](file://backend/src/app.js#L1-L60) - [backend/README.md:61-66](file://backend/README.md#L61-L66) ## 项目结构 后端采用按功能域划分的路由组织方式,入口文件加载中间件、数据库与路由,随后启动服务并进行数据库同步与初始化任务。 ```mermaid graph TB A["入口应用
backend/src/app.js"] --> B["CORS/BodyLimit 中间件"] A --> C["路由注册
backend/src/routes/index.js"] C --> D["认证路由
backend/src/routes/auth.js"] C --> E["品牌路由
backend/src/routes/brands.js"] C --> F["型号路由
backend/src/routes/models.js"] C --> G["OTA 路由
backend/src/routes/ota.js"] C --> H["分享码日志路由
backend/src/routes/shareCodeLogs.js"] C --> I["用户路由
backend/src/routes/users.js"] C --> J["仪表盘路由
backend/src/routes/dashboard.js"] A --> K["数据库同步与启动"] ``` **图表来源** - [backend/src/app.js:14-37](file://backend/src/app.js#L14-L37) - [backend/src/routes/index.js:1-13](file://backend/src/routes/index.js#L1-L13) **章节来源** - [backend/src/app.js:14-37](file://backend/src/app.js#L14-L37) - [backend/src/routes/index.js:1-13](file://backend/src/routes/index.js#L1-L13) ## 核心组件 - 统一响应体封装:ApiResponse 提供 success/error/noData 三类标准响应,便于前端统一处理。 - 认证中间件:基于 Bearer Token 的 JWT 校验,支持超级管理员权限拦截。 - 密码处理:PBKDF2 加盐哈希,安全存储用户口令。 - 数据库访问:Sequelize ORM,配合各模型完成 CRUD 与查询统计。 - 外部服务集成:S3 存储频响文件、Meilisearch 搜索索引、AWS SDK、Redis 缓存等。 **章节来源** - [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/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37) - [backend/src/models/index.js:1-8](file://backend/src/models/index.js#L1-L8) ## 架构总览 系统整体交互流程如下: ```mermaid sequenceDiagram participant Client as "客户端" participant Auth as "认证路由" participant JWT as "JWT 工具" participant User as "用户模型" participant Resp as "统一响应" Client->>Auth : POST /api/auth/login Auth->>User : 查询用户并校验状态 Auth->>JWT : 生成访问令牌 JWT-->>Auth : 访问令牌 Auth-->>Resp : 包装响应 Resp-->>Client : {code,msg,data} Client->>Auth : GET /api/auth/me Auth->>JWT : 解析并校验令牌 JWT-->>Auth : 用户负载 Auth->>User : 查询用户详情 Auth-->>Resp : 包装响应 Resp-->>Client : {code,msg,data} ``` **图表来源** - [backend/src/routes/auth.js:24-77](file://backend/src/routes/auth.js#L24-L77) - [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26) - [backend/src/utils/jwt.js:7-21](file://backend/src/utils/jwt.js#L7-L21) ## 详细组件分析 ### 认证系统 API - 登录 - 方法与路径:POST /api/auth/login - 请求体:username, password - 成功响应:access_token, token_type, expires_in, user - 错误:用户名或密码为空;用户不存在或状态异常;口令错误;内部错误 - 安全:口令使用 PBKDF2 校验;登录成功更新最近登录时间 - 当前用户 - 方法与路径:GET /api/auth/me - 认证:Bearer Token - 成功响应:用户信息字典 - 错误:未登录/凭证无效/账号不存在或禁用 - 修改密码 - 方法与路径:PUT /api/auth/password - 认证:Bearer Token - 请求体:old_password, new_password(≥6位) - 成功响应:操作结果提示 - 错误:缺少参数;原密码错误;内部错误 **章节来源** - [backend/src/routes/auth.js:24-109](file://backend/src/routes/auth.js#L24-L109) - [backend/src/utils/password.js:16-34](file://backend/src/utils/password.js#L16-L34) - [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26) ### 品牌管理 API - 列表查询 - 方法与路径:GET /api/brands/ - 查询参数:skip, limit(≤1000), name(模糊) - 成功响应:items[{id,name}], total, skip, limit - 错误:内部错误 - 单条查询 - 方法与路径:GET /api/brands/:brand_id - 成功响应:{id,name} 或 noData - 错误:内部错误 - 新增 - 方法与路径:POST /api/brands/ - 请求体:name - 成功响应:{id,name} - 错误:名称为空;已存在;内部错误 - 更新 - 方法与路径:PUT /api/brands/:brand_id - 请求体:name - 成功响应:{id,name} - 错误:名称为空;已存在;内部错误 - 删除 - 方法与路径:DELETE /api/brands/:brand_id - 成功响应:删除结果 - 错误:不存在;内部错误 **章节来源** - [backend/src/routes/brands.js:14-144](file://backend/src/routes/brands.js#L14-L144) ### 型号管理 API - 列表查询 - 方法与路径:GET /api/models/ - 查询参数:skip, limit(≤1000), brand_name(模糊), name(模糊), sort_by(id/create_at), sort_order(asc/desc) - 成功响应:items[{id,brand_name,name,form,rig,source,eq_key,create_at}], total, skip, limit - 错误:内部错误 - EQ 缓存键列表 - 方法与路径:GET /api/models/:model_id/eq-cache - 成功响应:{redis_key, field_keys} - 错误:内部错误 - EQ 缓存字段值 - 方法与路径:GET /api/models/:model_id/eq-cache/field?key=... - 查询参数:key - 成功响应:字段值 - 错误:缺少 key;内部错误 - Meilisearch 推送状态 - 方法与路径:GET /api/models/:model_id/meilisearch - 成功响应:{pushed:boolean, document|null} - 错误:内部错误 - 频响 CSV 查看(仅 Eafonyoung) - 方法与路径:GET /api/models/:model_id/measurement - 成功响应:{s3_key,content} - 错误:来源非 Eafonyoung;缺少佩戴方式;内部错误 - 单条查询 - 方法与路径:GET /api/models/:model_id - 成功响应:{id,brand_name,name,form,rig,source,eq_key,create_at} - 错误:不存在;内部错误 - 新增(支持频响文件上传) - 方法与路径:POST /api/models/ - 请求体:multipart/form-data,字段包括 brand_name, name, form, rig, source, eq_key,以及 measurement_file(.csv/.txt/.json) - 成功响应:新建型号对象 - 错误:重复;格式不支持;S3 上传失败;内部错误 - 更新(支持频响文件上传) - 方法与路径:PUT /api/models/:model_id - 请求体:multipart/form-data,字段包括 brand_name, name, form, rig, source, eq_key,以及 measurement_file - 成功响应:更新后型号对象 - 错误:重复;格式不支持;缺少来源/形式;S3 上传失败;内部错误 - 删除 - 方法与路径:DELETE /api/models/:model_id - 成功响应:删除结果 - 错误:不存在;Meilisearch 删除失败;内部错误 - 推送到搜索(校验) - 方法与路径:POST /api/models/push-to-search/validate - 请求体:model_ids[] - 成功响应:validated_count 或包含错误明细 - 错误:内部错误 - 推送到搜索 - 方法与路径:POST /api/models/push-to-search - 请求体:model_ids[] - 成功响应:pushed_count, task_uid, models - 错误:连接失败;内部错误 **章节来源** - [backend/src/routes/models.js:133-566](file://backend/src/routes/models.js#L133-L566) ### OTA 固件 API - 设备端最新版本检查(无需登录) - 方法与路径:GET /api/ota/latest/check - 查询参数:currentVerCode, model, hw(可选) - 成功响应:最新 OTA 对象或 noData - 错误:内部错误 - 列表查询(需登录) - 方法与路径:GET /api/ota/ - 查询参数:skip, limit(≤1000), verCode, verName(模糊), model, status - 成功响应:items[], total, skip, limit - 错误:内部错误 - 单条查询(需登录) - 方法与路径:GET /api/ota/:ota_id - 成功响应:OTA 对象 - 错误:不存在;内部错误 - 新增(需登录) - 方法与路径:POST /api/ota/ - 请求体:verCode, verName, url, md5, force, desc, model, hw, target, beta, startTime, endTime, status - 成功响应:创建后的 OTA 对象 - 错误:版本已存在;字段校验失败;内部错误 - 更新(需登录) - 方法与路径:PUT /api/ota/:ota_id - 请求体:同上(可部分字段) - 成功响应:更新后的 OTA 对象 - 错误:版本冲突;字段校验失败;内部错误 - 删除(需登录) - 方法与路径:DELETE /api/ota/:ota_id - 成功响应:删除结果 - 错误:不存在;内部错误 - 升级包上传(需登录) - 方法与路径:POST /api/ota/upload-package - 请求体:multipart/form-data,字段 model(X8/X9),package_file - 成功响应:md5, filename, url, s3_key(如适用) - 错误:不支持的设备;文件缺失;S3 配置/上传失败;内部错误 **章节来源** - [backend/src/routes/ota.js:68-268](file://backend/src/routes/ota.js#L68-L268) ### 用户管理 API(超级管理员) - 列表查询(需登录且超级管理员) - 方法与路径:GET /api/users/ - 查询参数:skip, limit(≤1000), username(模糊) - 成功响应:items[], total, skip, limit - 错误:内部错误 - 新增(需登录且超级管理员) - 方法与路径:POST /api/users/ - 请求体:username(≤64), password(≥6), is_super_admin(布尔) - 成功响应:用户对象 - 错误:用户名为空/过长/已存在;密码过短;内部错误 - 更新(需登录且超级管理员) - 方法与路径:PUT /api/users/:user_id - 请求体:status(0/1), is_super_admin(布尔), password(≥6可选) - 成功响应:用户对象 - 错误:状态非法;最后一位超级管理员不可降权/禁用;密码过短;内部错误 - 删除(需登录且超级管理员) - 方法与路径:DELETE /api/users/:user_id - 成功响应:删除结果 - 错误:不可删除当前登录账号;最后一位超级管理员不可删除;内部错误 **章节来源** - [backend/src/routes/users.js:35-177](file://backend/src/routes/users.js#L35-L177) ### 分享码日志 API(需登录) - 查询 - 方法与路径:GET /api/share-code/logs - 查询参数:skip, limit(≤1000), mac_addr(模糊), share_code(模糊), action(import/export), ip_addr(模糊), start_at,end_at, sort_by(id/create_at), sort_order(asc/desc) - 成功响应:items[{id,mac_addr,share_code,action,ip_addr,eq_data,expire_at,create_at}], total, skip, limit - 错误:内部错误 **章节来源** - [backend/src/routes/shareCodeLogs.js:14-84](file://backend/src/routes/shareCodeLogs.js#L14-L84) ### 仪表盘 API(需登录) - 今日新增 - 方法与路径:GET /api/dashboard/today - 成功响应:models[], otas[](当日新增) - 错误:内部错误 **章节来源** - [backend/src/routes/dashboard.js:19-63](file://backend/src/routes/dashboard.js#L19-L63) ## 依赖关系分析 - 入口应用加载路由汇总并启动服务,路由按功能域拆分,降低耦合度。 - 认证中间件贯穿多路由,统一鉴权;超级管理员中间件仅用于用户管理。 - 响应封装统一返回结构,便于前端与监控系统消费。 - 多处外部服务调用(S3、Meilisearch、AWS SDK、Redis)通过独立服务模块抽象,便于替换与测试。 ```mermaid graph LR App["入口应用
app.js"] --> RIndex["路由汇总
routes/index.js"] RIndex --> RAuth["认证路由"] RIndex --> RBrands["品牌路由"] RIndex --> RModels["型号路由"] RIndex --> ROta["OTA 路由"] RIndex --> RShare["分享码日志路由"] RIndex --> RUsers["用户路由"] RIndex --> RDash["仪表盘路由"] RAuth --> JWT["JWT 工具"] RAuth --> Pwd["密码工具"] RAuth --> UResp["统一响应"] RModels --> S3["S3 存储服务"] RModels --> MS["Meilisearch"] RModels --> Eq["EQ 缓存服务"] ROta --> OtaStore["OTA 存储服务"] ROta --> OtaVal["OTA 校验器"] RUsers --> UResp RBrands --> UResp RShare --> UResp RDash --> UResp ``` **图表来源** - [backend/src/app.js:10-37](file://backend/src/app.js#L10-L37) - [backend/src/routes/index.js:4-10](file://backend/src/routes/index.js#L4-L10) - [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36) - [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28) - [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37) - [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25) **章节来源** - [backend/src/app.js:10-37](file://backend/src/app.js#L10-L37) - [backend/src/routes/index.js:4-10](file://backend/src/routes/index.js#L4-L10) ## 性能考量 - 分页与上限:列表接口统一支持 skip/limit,最大限制为 1000,避免一次性返回过多数据。 - 查询过滤:品牌/型号/OTA/日志均支持多字段模糊匹配与范围筛选,建议结合索引与分页使用。 - 文件上传:型号频响文件采用内存存储(multer.memoryStorage),注意控制文件大小与并发量;S3 上传失败时需重试与告警。 - 外部服务超时:Meilisearch 请求设置超时,避免阻塞主流程;OTA 最新版本检查对设备端开放,减少不必要的鉴权开销。 - 缓存与索引:EQ 缓存与 Meilisearch 索引提升读取性能,写入时需保证一致性与幂等。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 认证失败 - 现象:401 未登录/无效凭证/登录过期 - 排查:确认 Authorization 头是否为 Bearer Token;检查 JWT_SECRET 是否正确;确认用户状态正常 - 密码错误 - 现象:登录/改密返回错误 - 排查:确认旧密码正确;新密码长度≥6;PBKDF2 校验逻辑 - 资源不存在 - 现象:noData 或 404 类似响应 - 排查:确认 ID/名称是否存在;品牌/型号/OTA/日志是否被删除 - 外部服务异常 - 现象:S3/Meilisearch/AWS SDK 调用失败 - 排查:检查配置项(S3 凭证、Meilisearch 地址与密钥);网络连通性;超时与重试策略 - 日志与监控 - 建议:开启 Winston 日志输出;结合统一响应体与错误码定位问题;对高频接口增加指标埋点 **章节来源** - [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26) - [backend/src/utils/password.js:16-34](file://backend/src/utils/password.js#L16-L34) - [backend/src/routes/models.js:89-128](file://backend/src/routes/models.js#L89-L128) - [backend/src/routes/ota.js:37-66](file://backend/src/routes/ota.js#L37-L66) ## 结论 本 API 体系以模块化路由为核心,结合统一响应体、JWT 认证与外部服务集成,提供了从认证到品牌/型号/OTA/用户/日志的完整能力。通过严格的参数校验、分页与上限控制、以及对外部服务的容错设计,系统具备良好的可维护性与扩展性。建议在生产环境中完善 CORS 限制、速率限制、审计日志与监控告警机制。 [本节为总结性内容,不直接分析具体文件] ## 附录 ### 认证与安全 - 认证方式:Bearer Token(JWT) - Token 有效期:12 小时 - 密码策略:PBKDF2 加盐哈希,迭代次数与长度配置见密码工具 - 权限控制:超级管理员仅限用户管理相关接口 **章节来源** - [backend/src/utils/jwt.js:3-25](file://backend/src/utils/jwt.js#L3-L25) - [backend/src/utils/password.js:6-34](file://backend/src/utils/password.js#L6-L34) - [backend/src/middleware/auth.js:28-33](file://backend/src/middleware/auth.js#L28-L33) ### 速率限制与版本 - 速率限制:未内置全局限流中间件,建议在网关或反向代理层配置 - 版本:后端版本 1.0.0 **章节来源** - [backend/package.json:1-29](file://backend/package.json#L1-L29) ### 常见用例与最佳实践 - 品牌管理:先查询列表/模糊搜索,再执行新增/更新/删除 - 型号管理:上传频响文件时同时提供 source 与 form 字段;使用校验接口预检后再推送至搜索 - OTA 管理:先上传升级包并获取下载地址/MD5,再创建 OTA 记录;设备端通过最新版本检查接口获取可用升级 - 用户管理:确保至少保留一位超级管理员;变更权限时注意最后一位管理员保护 [本节为通用指导,不直接分析具体文件] ### 调试工具与监控 - 在线文档:启动后访问根路径或健康检查接口查看 Swagger UI 与 ReDoc - 日志:Winston 输出,建议接入集中式日志系统 - 监控:对关键接口(登录、OTA 最新版本检查、型号上传)埋点与告警 **章节来源** - [backend/src/app.js:23-34](file://backend/src/app.js#L23-L34) ### 已弃用功能与迁移指南 - 项目说明文档未提及明确的弃用接口;若后续出现弃用,请关注版本变更与迁移说明 - 建议:在升级前备份数据库与外部服务数据,逐步替换服务模块并验证接口行为 **章节来源** - [backend/README.md:1-99](file://backend/README.md#L1-L99)