Files
dashboard/.qoder/repowiki/zh/content/后端API文档/仪表板API.md
T
2026-06-30 14:46:52 +08:00

18 KiB
Raw Blame History

仪表板API

**本文档引用的文件** - [backend/src/routes/dashboard.js](file://backend/src/routes/dashboard.js) - [backend/src/routes/models.js](file://backend/src/routes/models.js) - [backend/src/models/Model.js](file://backend/src/models/Model.js) - [backend/src/models/Ota.js](file://backend/src/models/Ota.js) - [backend/src/models/DashboardUser.js](file://backend/src/models/DashboardUser.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/redis.js](file://backend/src/config/redis.js) - [backend/src/services/eqCacheStorage.js](file://backend/src/services/eqCacheStorage.js) - [backend/src/services/measurementStorage.js](file://backend/src/services/measurementStorage.js) - [frontend/src/api/dashboard.js](file://frontend/src/api/dashboard.js) - [frontend/src/views/home/index.vue](file://frontend/src/views/home/index.vue) - [backend/src/app.js](file://backend/src/app.js) - [backend/src/routes/index.js](file://backend/src/routes/index.js)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件为“仪表板API”的RESTful接口文档,聚焦系统统计数据查询能力,覆盖以下指标与能力:

  • 品牌数量统计:基于品牌模型的计数与唯一性约束,可用于统计品牌总数与活跃品牌数。
  • 型号分布情况:按品牌、形式、阻抗等维度进行分组统计与聚合展示。
  • OTA更新状态:按版本状态、目标范围、灰度/强升等维度进行筛选与聚合。
  • 用户活跃度:后台用户登录时间与状态,用于评估管理员活跃度。
  • 数据聚合查询:按日期、品牌、型号等维度进行分组统计。
  • 时间序列分析:以“今日新增”为代表的日粒度趋势数据。
  • 图表数据格式:统一返回结构与字段命名,便于前端可视化。
  • 缓存策略:Redis缓存EQ键值,降低后端压力。
  • 性能优化:数据库索引、查询条件、分页与轻量字段返回。
  • 实时数据更新机制:通过定时任务或事件触发刷新缓存。
  • 自定义统计维度与数据导出:通过查询参数扩展维度与导出CSV。

本项目采用前后端分离架构,后端基于Express,数据库使用Sequelize ORM,前端使用Vue 3 + Element Plus。

项目结构

后端采用模块化路由组织,仪表板相关接口集中在dashboard路由中,并通过认证中间件保护。前端通过API封装调用后端接口。

graph TB
FE["前端应用<br/>Vue 3 + Element Plus"] --> API["仪表板API<br/>/api/dashboard/*"]
API --> AUTH["认证中间件<br/>Bearer Token"]
API --> RESP["统一响应封装<br/>ApiResponse/PageData"]
API --> MODELS["型号模型<br/>Model"]
API --> OTA["OTA模型<br/>Ota"]
API --> REDIS["Redis 缓存<br/>EQ缓存"]
API --> S3["S3 存储<br/>频响CSV"]
AUTH --> USER["后台用户模型<br/>DashboardUser"]

图示来源

章节来源

核心组件

  • 认证中间件:校验Authorization头中的Bearer Token,注入用户上下文。
  • 统一响应封装:提供成功/错误/无数据三种响应结构,便于前端处理。
  • 仪表板路由:提供“今日新增”接口,返回型号与OTA的当日增量数据。
  • 模型与OTA数据模型:定义品牌、型号、OTA等核心实体字段。
  • Redis缓存服务:提供EQ缓存键值读取与字段解析。
  • S3存储服务:提供频响CSV上传与读取能力,支持来源与佩戴方式等维度。

章节来源

架构总览

后端启动时同步数据库表并挂载所有路由,根路径与健康检查接口无需认证,业务路由统一通过认证中间件保护。仪表板接口在路由层引入认证中间件,确保只有登录用户可访问。

sequenceDiagram
participant Client as "客户端"
participant App as "Express 应用"
participant Router as "仪表板路由"
participant Auth as "认证中间件"
participant Resp as "统一响应"
participant DB as "数据库"
Client->>App : GET /
App-->>Client : {message, docs, redoc}
Client->>App : GET /health
App-->>Client : {status : "healthy"}
Client->>Router : GET /api/dashboard/today
Router->>Auth : 校验 Bearer Token
Auth-->>Router : 注入用户上下文
Router->>DB : 查询今日新增型号与OTA
DB-->>Router : 返回结果
Router->>Resp : 包装响应
Resp-->>Client : {code,msg,data}

图示来源

详细组件分析

仪表板路由与“今日新增”接口

  • 接口:GET /api/dashboard/today
  • 认证:需登录(路由内挂载认证中间件)
  • 功能:返回当日00:00起至当前的新增型号与OTA列表
  • 请求参数:无
  • 响应字段:
    • models:数组,包含id、brand_name、name、create_at
    • otas:数组,包含id、verName、model、create_at
  • 时间范围:以服务器所在时区计算当日起点
  • 错误处理:捕获异常并返回统一错误响应
sequenceDiagram
participant C as "客户端"
participant R as "仪表板路由"
participant A as "认证中间件"
participant M as "Model模型"
participant O as "Ota模型"
participant U as "统一响应"
C->>R : GET /api/dashboard/today
R->>A : 校验Token
A-->>R : 注入用户
R->>M : 查询当日新增型号
M-->>R : 型号列表
R->>O : 查询当日新增OTA
O-->>R : OTA列表
R->>U : 包装响应
U-->>C : {code,msg,data}

图示来源

章节来源

型号与OTA数据模型

  • 型号模型(Model):包含品牌名、型号名、形式、阻抗、来源、EQ键、创建时间等字段,支持按品牌与型号组合唯一性约束。
  • OTA模型(Ota):包含版本号、版本名、升级包URL、MD5、是否强升、描述、对应型号、硬件版本、目标范围、灰度状态、起止时间、状态、创建时间等字段,支持按版本号与名称等维度筛选。
erDiagram
MODEL {
int id PK
string brand_name
string name
string form
string rig
string source
string eq_key
datetime create_at
}
OTA {
int id PK
int verCode
string verName
string url
string md5
smallint force
string desc
string model
int hw
smallint target
smallint beta
datetime startTime
datetime endTime
smallint status
datetime create_at
}

图示来源

章节来源

Redis缓存与EQ键值读取

  • 缓存键构建规则:{品牌名称} {型号名称}
  • 接口:
    • GET /api/models/:model_id/eq-cache:返回该型号的缓存键与字段列表(不含value,避免响应过大)
    • GET /api/models/:model_id/eq-cache/field?key=:返回指定字段的值(自动JSON解析)
  • 错误处理:字段不存在、Redis读取失败等场景返回统一错误响应
sequenceDiagram
participant C as "客户端"
participant R as "型号路由"
participant S as "EQ缓存服务"
participant RC as "Redis客户端"
participant U as "统一响应"
C->>R : GET /api/models/ : model_id/eq-cache
R->>S : getEqCacheKeys(brand,name)
S->>RC : hkeys(redisKey)
RC-->>S : field_keys
S-->>R : {redis_key, field_keys}
R->>U : 包装响应
U-->>C : {code,msg,data}
C->>R : GET /api/models/ : model_id/eq-cache/field?key=...
R->>S : getEqCacheField(brand,name,key)
S->>RC : hget(redisKey,key)
RC-->>S : raw_value
S-->>R : {redis_key,key,value}
R->>U : 包装响应
U-->>C : {code,msg,data}

图示来源

章节来源

S3频响CSV读取

  • 接口:GET /api/models/:model_id/measurement
  • 适用来源:仅支持来源为“Eafonyoung”的型号
  • 依赖字段:型号必须包含佩戴方式(form),否则无法定位S3文件
  • 返回:S3 Key与CSV内容字符串
  • 错误处理:来源不符、缺少form、S3未找到等场景返回统一错误响应
flowchart TD
Start(["请求进入"]) --> CheckSource["校验来源是否为 Eafonyoung"]
CheckSource --> |否| ErrSource["返回错误:仅支持 Eafonyoung"]
CheckSource --> |是| CheckForm["校验是否存在佩戴方式(form)"]
CheckForm --> |否| ErrForm["返回错误:缺少佩戴方式"]
CheckForm --> |是| BuildKey["构建S3 Key"]
BuildKey --> ReadS3["从S3读取CSV内容"]
ReadS3 --> Found{"找到文件?"}
Found --> |否| ErrNotFound["返回错误:S3未找到文件"]
Found --> |是| ReturnOK["返回 {s3_key,content}"]
ErrSource --> End(["结束"])
ErrForm --> End
ErrNotFound --> End
ReturnOK --> End

图示来源

章节来源

前端集成与使用示例

  • 前端API封装:提供获取“今日新增”的方法,内部调用 /dashboard/today
  • 前端页面:首页卡片展示今日新增型号与OTA数量与列表,支持时间格式化显示
sequenceDiagram
participant V as "首页视图"
participant A as "仪表板API"
participant S as "后端仪表板路由"
V->>A : getTodayStats()
A->>S : GET /dashboard/today
S-->>A : {code,msg,data : {models,otas}}
A-->>V : Promise.resolve(data)
V->>V : 渲染今日新增卡片

图示来源

章节来源

依赖关系分析

  • 路由汇总:后端将各模块路由集中注册,包括仪表板路由
  • 认证链路:所有仪表板接口均受认证中间件保护
  • 数据模型:仪表板接口依赖Model与Ota模型进行查询
  • 缓存链路:型号路由依赖EQ缓存服务与Redis客户端
  • 存储链路:型号路由依赖S3存储服务进行频响文件读取
graph LR
RoutesIndex["路由汇总"] --> DashboardRoute["仪表板路由"]
RoutesIndex --> ModelsRoute["型号路由"]
DashboardRoute --> AuthMW["认证中间件"]
ModelsRoute --> AuthMW
DashboardRoute --> ModelModel["Model模型"]
DashboardRoute --> OtaModel["Ota模型"]
ModelsRoute --> EqCache["EQ缓存服务"]
ModelsRoute --> S3Svc["S3存储服务"]
AuthMW --> User["DashboardUser模型"]

图示来源

章节来源

性能考虑

  • 查询优化
    • 使用精确时间范围过滤当日新增,避免全表扫描
    • 仅返回必要字段,减少网络传输
  • 缓存策略
    • Redis缓存EQ键值,避免频繁读取数据库
    • 字段列表与单字段读取分离,控制响应大小
  • 存储优化
    • S3文件按来源、佩戴方式、品牌首字母与型号组织,便于快速定位
  • 并发与超时
    • Redis连接设置最大重试次数与连接超时
    • 前端对EQ缓存读取设置较长超时,避免弱网失败
  • 分页与限制
    • 当前“今日新增”接口未分页,建议后续扩展分页参数以应对高并发

故障排查指南

  • 认证失败
    • 现象:返回未登录或缺少凭证、无效凭证、登录已过期
    • 排查:确认Authorization头格式为Bearer Token,检查Token有效期
  • Redis读取失败
    • 现象:返回Redis读取失败或字段不存在
    • 排查:确认Redis连接配置正确,检查缓存键是否存在
  • S3文件未找到
    • 现象:返回S3上未找到该型号的频响文件
    • 排查:确认来源为Eafonyoung且存在佩戴方式,检查S3 Key拼接逻辑
  • 统一错误响应
    • 现象:接口返回code=0或2,msg包含错误信息
    • 排查:根据msg提示定位具体问题,查看后端日志

章节来源

结论

本仪表板API围绕“今日新增”这一高频指标提供了简洁高效的查询接口,并通过Redis缓存与S3存储提升了整体性能与可扩展性。建议后续在以下方面持续优化:

  • 扩展更多统计维度(品牌、型号、OTA状态等)与分页能力
  • 引入时间序列分析接口,支持多日趋势对比
  • 完善缓存失效与更新策略,保证数据一致性
  • 提供数据导出能力(如CSV),满足报表需求

附录

API定义与使用示例

  • 获取今日新增(型号 + OTA
    • 方法:GET
    • URL/api/dashboard/today
    • 认证:是
    • 请求参数:无
    • 响应字段:
      • models:数组,元素含id、brand_name、name、create_at
      • otas:数组,元素含id、verName、model、create_at
    • 示例调用:前端通过 getTodayStats() 封装调用

章节来源

缓存与实时更新机制

  • 缓存键:{品牌名称} {型号名称}
  • 读取策略:
    • 列表:仅返回字段名列表,避免大响应
    • 单字段:按key读取并自动解析JSON
  • 实时更新:建议通过定时任务或事件触发刷新Redis缓存,确保前端展示最新数据

章节来源

数据导出与图表数据格式

  • 导出建议:在现有接口基础上增加查询参数(如时间范围、维度、格式)以支持导出
  • 图表数据格式:统一使用统一响应结构,前端按需转换为折线图、柱状图等所需格式

章节来源