From 81d7b213b80bbf873d32caa4629f53228c7eb5de Mon Sep 17 00:00:00 2001 From: yexb <553699424@qq.com> Date: Thu, 14 May 2026 15:30:25 +0800 Subject: [PATCH] =?UTF-8?q?steady:=20=E5=A2=9E=E5=8A=A0=E8=B6=8B=E5=8A=BF?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E8=AE=BE=E8=AE=A1=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...026-05-14-steady-data-view-trend-design.md | 392 ++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-14-steady-data-view-trend-design.md diff --git a/docs/superpowers/specs/2026-05-14-steady-data-view-trend-design.md b/docs/superpowers/specs/2026-05-14-steady-data-view-trend-design.md new file mode 100644 index 0000000..b783642 --- /dev/null +++ b/docs/superpowers/specs/2026-05-14-steady-data-view-trend-design.md @@ -0,0 +1,392 @@ +# steady-DataView 稳态历史趋势设计方案 + +## 目标 + +在 `steady/steady-DataView` 中新增稳态历史趋势查看能力,用于展示 InfluxDB 中的稳态数据历史趋势图。数据结构与 `tools/add-data` 中的 13 张 `data_*` 表字段保持一致,但查询数据源改为 InfluxDB 时序库。 + +本方案只设计后端接口、查询模型、页面交互和性能策略,不包含代码实现。 + +## 当前上下文 + +- `steady-DataView` 当前已有 `/steady/data-view/page`、`/detail`、`/templates`,主要面向 MySQL 稳态数据分页、详情和模板查询。 +- `tools/add-data` 已维护 13 张稳态数据表定义,字段包含基础字段 `TIMEID`、`LINEID`、`PHASIC_TYPE`、`QUALITYFLAG`,以及业务值字段和 `_MAX`、`_MIN`、`_CP95` 等统计字段。 +- `tools/add-ledger` 已提供台账树能力,层级固定为:工程 -> 项目 -> 设备 -> 监测点。 +- `tools/wave-tool` 已有趋势图点位返回结构,可参考 `points`、`sampled`、`displayPointCount` 等概念。 + +## 总体方案 + +新增趋势查看能力时,`steady-DataView` 负责统一编排: + +1. 从 `add-ledger` 复用台账层级,生成趋势页面左侧监测点设备树。 +2. 从稳态指标目录生成指标树,指标范围覆盖电压、电流、频率、谐波、功率、闪变。 +3. 将页面选择的监测点、指标、相别、统计类型、时间范围转换成 InfluxDB 查询。 +4. 返回趋势图可直接消费的多序列点位数据。 +5. 按天和分桶粒度动态加载,避免大范围一次性返回明细点。 + +保留现有分页和详情接口,不在本次设计中移除。 + +## 左侧设备树 + +页面左侧展示台账监测点设备树,口径参照 `add-ledger`: + +```text +工程(设备数 / 监测点数) + 项目(设备数 / 监测点数) + 设备(监测点数) + 监测点 +``` + +数量统计口径: + +- 台账节点:`cs_ledger.State = 1` +- 设备:`cs_equipment_delivery.run_status <> 0` +- 监测点:`cs_line.status = 1` +- 设备数:当前节点下有效设备数量 +- 监测点数:当前节点下有效监测点数量 + +建议新增趋势专用接口: + +```text +GET /steady/data-view/ledger-tree +``` + +返回字段: + +```json +{ + "id": "project-001", + "parentId": "engineering-001", + "name": "10kV一号站", + "level": 1, + "sort": 0, + "deviceCount": 4, + "lineCount": 28, + "selectable": false, + "children": [] +} +``` + +节点选择规则: + +- 监测点节点可直接作为趋势查询的 `lineId`。 +- 设备节点选中时,等价于选中其下全部有效监测点。 +- 工程、项目节点选中时,等价于选中其下全部有效监测点,但需要做数量限制。 +- 搜索设备名或监测点名时,应保留完整父级路径,避免返回孤立节点。 + +## 指标树 + +新增趋势指标树接口: + +```text +GET /steady/data-view/indicator-tree +``` + +指标分组沿用用户提供的结构: + +- 电压趋势 +- 电流趋势 +- 频率趋势 +- 谐波趋势 +- 功率趋势 +- 闪变趋势 + +后端不直接散落前端 JS 节点,而是维护统一指标目录。每个叶子指标建议包含: + +```json +{ + "indicatorCode": "V_RMS", + "name": "相电压有效值", + "groupCode": "VOLTAGE", + "tableName": "data_v", + "baseFields": ["RMS"], + "phaseCodes": ["A", "B", "C"], + "supportStats": ["AVG", "MAX", "MIN", "CP95"], + "harmonic": false, + "harmonicOrderStart": null, + "harmonicOrderEnd": null, + "unit": "V" +} +``` + +普通指标通过 `baseFields` 映射到 InfluxDB field。谐波指标通过 `fieldPrefix + harmonicOrder + statSuffix` 生成字段,如 `V_5`、`V_5_MAX`、`V_5_MIN`、`V_5_CP95`。 + +## InfluxDB 配置 + +InfluxDB 连接做成配置项,不在代码中写死。 + +```yaml +steady: + influxdb: + url: http://192.168.1.103:18086 + database: pqsbase + username: admin + password: ${STEADY_INFLUXDB_PASSWORD:} + ssl: false + connect-timeout-ms: 5000 + read-timeout-ms: 30000 +``` + +本地密码可配置为 `123456`,但不建议提交明文密码到仓库配置文件。 + +从截图判断当前更接近 InfluxDB 1.x 连接方式,查询方案优先按 InfluxQL 设计。如实际为 InfluxDB 2.x,需要将 `database` 改为 `bucket/org/token` 模型。 + +## InfluxDB 数据模型 + +建议保持与 `add-data` 表结构一致: + +- measurement:沿用表名,如 `data_v`、`data_i`、`data_harmrate_v` +- time:InfluxDB 内置时间,等价原 `TIMEID` +- tag:`LINEID`、`PHASIC_TYPE`、`QUALITYFLAG` +- field:沿用原业务字段,如 `RMS`、`RMS_MAX`、`RMS_MIN`、`RMS_CP95` + +查询时必须使用 `AddDataTableRegistry` 或趋势指标目录做 measurement 和 field 白名单校验,禁止前端传任意表名或字段名直接拼接查询。 + +## 趋势查询接口 + +建议新增: + +```text +POST /steady/data-view/trend/query +POST /steady/data-view/trend/day +POST /steady/data-view/trend/summary +``` + +`trend/query` 用于首次查询,返回图表元数据、首屏数据和可加载日期范围。 + +`trend/day` 用于按天动态加载。前端切换日期、拖动缩放或需要补齐某天数据时调用。 + +请求示例: + +```json +{ + "lineIds": ["line-001"], + "indicatorCodes": ["V_RMS", "FREQ"], + "statTypes": ["AVG", "MAX", "MIN", "CP95"], + "phases": ["A", "B", "C"], + "timeStart": "2026-05-01 00:00:00", + "timeEnd": "2026-05-01 23:59:59", + "bucket": "10m", + "qualityFlag": 1 +} +``` + +返回示例: + +```json +{ + "sampled": true, + "bucket": "10m", + "sourcePointCount": 86400, + "displayPointCount": 144, + "series": [ + { + "seriesKey": "line-001|V_RMS|A|AVG", + "lineId": "line-001", + "lineName": "进线一", + "indicatorCode": "V_RMS", + "indicatorName": "相电压有效值", + "phase": "A", + "statType": "AVG", + "unit": "V", + "points": [ + { + "time": "2026-05-01 00:00:00", + "value": 220.1 + } + ] + } + ] +} +``` + +`trend/summary` 返回当前查询范围或当前可视窗口内的统计值: + +```json +{ + "items": [ + { + "seriesKey": "line-001|V_RMS|A", + "max": 232.1, + "avg": 220.4, + "min": 214.8, + "cp95": 228.7 + } + ] +} +``` + +## 统计口径 + +统计类型包括: + +- `MAX`:最大值 +- `AVG`:平均值 +- `MIN`:最小值 +- `CP95`:95% 概率大值 + +优先读取已有统计字段: + +- `AVG` 读取基础字段,如 `RMS`、`FREQ`、`V_5` +- `MAX` 读取 `_MAX` 字段 +- `MIN` 读取 `_MIN` 字段 +- `CP95` 读取 `_CP95` 字段 + +如果某些表没有独立统计字段,如部分闪变和波动字段,则接口应在指标目录中标明不支持的统计类型,前端禁用对应选项。仅在明确需要时才使用 InfluxDB 动态聚合兜底。 + +## 查询模式限制 + +支持两种主要查询模式: + +1. 一个监测点,多指标 +2. 多个监测点,一个指标 + +为了保证图表可读性和查询效率,建议限制: + +- 普通趋势:最多 8 个监测点或 8 个指标。 +- 多监测点查询时,默认只允许 1 个指标。 +- 单监测点查询时,可选择多个指标。 +- 单次序列数量建议不超过 24 条,超过时提示缩小监测点、指标、相别或统计类型范围。 + +## 谐波展示方案 + +谐波类包含 2~50 次谐波,不适合一次性全部画趋势线。建议拆成三种展示: + +1. 趋势图模式 + - 用户选择谐波类型后,再选择 1 到 6 个谐波次数。 + - 只展示被选次数随时间变化。 + - 适合观察 3、5、7、11、13 次等重点谐波。 + +2. 谐波谱模式 + - 用户在趋势图上选中某个时间点。 + - 展示该时刻 2~50 次谐波柱状图。 + - 适合查看单个时刻的谐波分布。 + +3. TopN 模式 + - 后端按当前时间范围统计每个谐波次数的 `MAX` 或 `CP95`。 + - 默认返回 Top 10。 + - 适合快速定位主要谐波次数。 + +谐波趋势默认禁止直接加载 2~50 全部次数。必须指定 `harmonicOrders` 或使用 `topN`。 + +## 按天动态加载 + +前端首次查询时只加载当前可视范围或默认第一天数据。用户滚动、缩放、切换日期时按天请求。 + +后端按时间范围自动给出建议 bucket: + +- 范围小于 6 小时:`1m` +- 6 小时到 1 天:`5m` 或 `10m` +- 1 天到 7 天:按天加载,每天 `10m` 或 `30m` +- 大于 7 天:优先按天加载摘要,进入某天后再加载细节 + +接口返回 `sampled`、`sourcePointCount`、`displayPointCount`,前端可提示当前是否已下采样。 + +## 缓存策略 + +建议增加短期查询缓存,缓存 key 包含: + +```text +lineIds + indicatorCodes + phases + statTypes + day + bucket + qualityFlag +``` + +缓存粒度以单日为主,避免一个大时间范围缓存过大。缓存只用于趋势点位,不缓存配置密码和连接对象以外的敏感信息。 + +## 页面布局 + +推荐布局: + +```text +顶部:时间范围 / 相别 / 统计类型 / 查询 / 重置 + +左侧: + 台账监测点树 + - 工程、项目、设备、监测点 + - 显示设备数、监测点数 + - 支持搜索与勾选 + +左侧下方或中左: + 稳态指标树 + - 电压趋势 + - 电流趋势 + - 频率趋势 + - 谐波趋势 + - 功率趋势 + - 闪变趋势 + +中间: + 趋势图 + - 折线图 + - 图例开关 + - tooltip + - 缩放联动 + - 按天动态加载 + +右侧: + 当前范围统计 + - 最大值 + - 平均值 + - 最小值 + - CP95 +``` + +谐波类指标被选中时,趋势图上方增加: + +- 谐波次数选择器 +- 趋势 / 谱图 / TopN 切换 + +## 后端模块划分 + +建议在 `steady-DataView` 中按职责拆分: + +- `SteadyDataViewLedgerController`:趋势页面台账树 +- `SteadyDataViewIndicatorController`:指标树 +- `SteadyDataViewTrendController`:趋势查询、按天加载、统计摘要 +- `SteadyDataViewLedgerService`:复用 add-ledger 口径生成带数量的树 +- `SteadyDataViewIndicatorService`:维护指标目录和字段映射 +- `SteadyDataViewTrendService`:参数校验、查询编排、结果组装 +- `SteadyInfluxQueryComponent`:InfluxDB 查询封装 +- `SteadyTrendFieldResolver`:指标到 measurement/field 的白名单转换 + +保留现有 `SteadyDataViewController` 的分页、详情、模板职责,不继续把所有新接口堆到一个大 Controller。 + +## 验证方式 + +方案落地后,默认验证不执行 Maven 构建,除非用户明确要求。 + +建议检查: + +1. 配置检查:InfluxDB 配置项可被 Spring Boot 读取,密码未硬编码提交。 +2. 指标映射检查:所有指标都能解析到合法 measurement 和 field。 +3. 台账树检查:设备数、监测点数与 add-ledger 有效数据口径一致。 +4. 查询限制检查:超出监测点、指标、谐波次数限制时返回明确提示。 +5. 查询语句检查:InfluxDB 查询必须带时间范围、`LINEID` 和必要 tag 条件。 +6. 趋势返回检查:返回 series、points、统计摘要结构稳定,前端可直接绘图。 +7. 谐波检查:趋势模式不默认返回 2~50 全部次数,谱图和 TopN 按独立接口或模式返回。 + +## 分期建议 + +第一期: + +- InfluxDB 可配置连接 +- 台账监测点树,包含设备数和监测点数 +- 稳态指标树 +- 普通指标趋势查询 +- 最大值、平均值、最小值、CP95 +- 按天动态加载 +- 谐波趋势支持手动选择次数 + +第二期: + +- 谐波谱图 +- 谐波 TopN +- 查询缓存优化 +- 大范围摘要视图 +- 前端交互细节优化 + +## 待确认事项 + +1. InfluxDB 版本是否确定为 1.x。 +2. 生产环境 InfluxDB measurement 是否完全沿用 `data_*` 表名。 +3. `QUALITYFLAG` 在 InfluxDB 中是否作为 tag 保存。 +4. 谐波相角、间谐波等字段命名是否与 `add-data` 当前 SQL 完全一致。 +5. 前端是否已有可复用的 ECharts 趋势图组件,还是只参考 waveform 返回结构重新接入。