19 KiB
19 KiB
后端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)目录
简介
本项目为“耳机品牌与型号管理平台”的后端 RESTful API,采用 Node.js + Express 构建,提供认证系统、品牌管理、型号管理、OTA 固件、用户管理以及分享码日志等完整能力。系统通过统一响应体封装、JWT 认证中间件、Sequelize 数据库访问层与多处外部服务集成(S3、Meilisearch、AWS SDK),形成模块化、可扩展的 API 体系。
- 版本信息:后端版本 1.0.0
- 默认端口:8083(可通过环境变量覆盖)
- 健康检查:GET /health
- 在线文档:Swagger UI 与 ReDoc(根路径与健康检查接口提供文档入口)
章节来源
项目结构
后端采用按功能域划分的路由组织方式,入口文件加载中间件、数据库与路由,随后启动服务并进行数据库同步与初始化任务。
graph TB
A["入口应用<br/>backend/src/app.js"] --> B["CORS/BodyLimit 中间件"]
A --> C["路由注册<br/>backend/src/routes/index.js"]
C --> D["认证路由<br/>backend/src/routes/auth.js"]
C --> E["品牌路由<br/>backend/src/routes/brands.js"]
C --> F["型号路由<br/>backend/src/routes/models.js"]
C --> G["OTA 路由<br/>backend/src/routes/ota.js"]
C --> H["分享码日志路由<br/>backend/src/routes/shareCodeLogs.js"]
C --> I["用户路由<br/>backend/src/routes/users.js"]
C --> J["仪表盘路由<br/>backend/src/routes/dashboard.js"]
A --> K["数据库同步与启动"]
图表来源
章节来源
核心组件
- 统一响应体封装:ApiResponse 提供 success/error/noData 三类标准响应,便于前端统一处理。
- 认证中间件:基于 Bearer Token 的 JWT 校验,支持超级管理员权限拦截。
- 密码处理:PBKDF2 加盐哈希,安全存储用户口令。
- 数据库访问:Sequelize ORM,配合各模型完成 CRUD 与查询统计。
- 外部服务集成:S3 存储频响文件、Meilisearch 搜索索引、AWS SDK、Redis 缓存等。
章节来源
- backend/src/utils/response.js:1-25
- backend/src/middleware/auth.js:1-36
- backend/src/utils/password.js:1-37
- backend/src/models/index.js:1-8
架构总览
系统整体交互流程如下:
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}
图表来源
详细组件分析
认证系统 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
- backend/src/utils/password.js:16-34
- backend/src/middleware/auth.js:3-26
品牌管理 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
- 成功响应:删除结果
- 错误:不存在;内部错误
章节来源
型号管理 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
- 错误:连接失败;内部错误
章节来源
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 配置/上传失败;内部错误
章节来源
用户管理 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
- 成功响应:删除结果
- 错误:不可删除当前登录账号;最后一位超级管理员不可删除;内部错误
章节来源
分享码日志 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
- 错误:内部错误
章节来源
仪表盘 API(需登录)
- 今日新增
- 方法与路径:GET /api/dashboard/today
- 成功响应:models[], otas[](当日新增)
- 错误:内部错误
章节来源
依赖关系分析
- 入口应用加载路由汇总并启动服务,路由按功能域拆分,降低耦合度。
- 认证中间件贯穿多路由,统一鉴权;超级管理员中间件仅用于用户管理。
- 响应封装统一返回结构,便于前端与监控系统消费。
- 多处外部服务调用(S3、Meilisearch、AWS SDK、Redis)通过独立服务模块抽象,便于替换与测试。
graph LR
App["入口应用<br/>app.js"] --> RIndex["路由汇总<br/>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
- backend/src/routes/index.js:4-10
- backend/src/middleware/auth.js:1-36
- backend/src/utils/jwt.js:1-28
- backend/src/utils/password.js:1-37
- backend/src/utils/response.js:1-25
章节来源
性能考量
- 分页与上限:列表接口统一支持 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
- backend/src/utils/password.js:16-34
- backend/src/routes/models.js:89-128
- backend/src/routes/ota.js:37-66
结论
本 API 体系以模块化路由为核心,结合统一响应体、JWT 认证与外部服务集成,提供了从认证到品牌/型号/OTA/用户/日志的完整能力。通过严格的参数校验、分页与上限控制、以及对外部服务的容错设计,系统具备良好的可维护性与扩展性。建议在生产环境中完善 CORS 限制、速率限制、审计日志与监控告警机制。
[本节为总结性内容,不直接分析具体文件]
附录
认证与安全
- 认证方式:Bearer Token(JWT)
- Token 有效期:12 小时
- 密码策略:PBKDF2 加盐哈希,迭代次数与长度配置见密码工具
- 权限控制:超级管理员仅限用户管理相关接口
章节来源
- backend/src/utils/jwt.js:3-25
- backend/src/utils/password.js:6-34
- backend/src/middleware/auth.js:28-33
速率限制与版本
- 速率限制:未内置全局限流中间件,建议在网关或反向代理层配置
- 版本:后端版本 1.0.0
章节来源
常见用例与最佳实践
- 品牌管理:先查询列表/模糊搜索,再执行新增/更新/删除
- 型号管理:上传频响文件时同时提供 source 与 form 字段;使用校验接口预检后再推送至搜索
- OTA 管理:先上传升级包并获取下载地址/MD5,再创建 OTA 记录;设备端通过最新版本检查接口获取可用升级
- 用户管理:确保至少保留一位超级管理员;变更权限时注意最后一位管理员保护
[本节为通用指导,不直接分析具体文件]
调试工具与监控
- 在线文档:启动后访问根路径或健康检查接口查看 Swagger UI 与 ReDoc
- 日志:Winston 输出,建议接入集中式日志系统
- 监控:对关键接口(登录、OTA 最新版本检查、型号上传)埋点与告警
章节来源
已弃用功能与迁移指南
- 项目说明文档未提及明确的弃用接口;若后续出现弃用,请关注版本变更与迁移说明
- 建议:在升级前备份数据库与外部服务数据,逐步替换服务模块并验证接口行为
章节来源