09-point-status-legend.md 6.6 KB

09: 点位状态图例与标记

What to build: 将后端解析后的监测点状态渲染为地图标记、颜色和图例。前端不重算点位状态,不把事件等级色混用为点位状态色。

Blocked by: 08

Status: resolved Labels: ready-for-agent

  • 监测点标记按后端返回状态渲染。
  • 正常、预警、报警、处置中工单、离线/无关联设备状态均可表达。
  • 每种颜色都有文字或形状辅助,不单独依赖颜色。
  • 地图图例与标记状态一致。
  • 有状态到视觉表现的单测。

进度:100%

已完成并关闭(2026-09-18)。 逻辑闸门 38/38、真机走查 28/28;回归 16 个既有闸门全绿 (t01 20/20、t04 9/9、t05 179/179 + 10/10、t06、t07 39/39 + 20/20、t08 44/44 + 16/16、 t21 9/9 + 10/10、t28 7/7、t29 6/6、t30 7/7)。

交付物

  • 新增 src/modules/cockpit/domain/pointStatus.js:状态 → 视觉表现的唯一一张表。 六个后端状态(ALARM/WARNING/WORK_ORDER/NORMAL/OFFLINE/EMPTY,标签与优先级逐字照抄后端 CockpitMonitoringPointStatus)各带 色键 + 形状 + 文字;另有 UNKNOWN(状态未发布) 与 UNASSOCIATED(无关联设备)两条。地图标记、地图图例、markerSvg() 图片都从这一张表取, 所以「图例与标记一致」是结构性的,不靠两边各自小心。
  • services/cesiumEngine.js 新增点位标记层:CustomDataSource('cockpit-point-markers') + billboard(形状 SVG data URL、CLAMP_TO_GROUND 贴地形)。引擎层只认 shape/tone,不认识业务状态名。
  • services/mapService.js 新增 syncPointMarkersForSummary() / getPointMarkerState() / clearPointMarkers();语义色从 .cockpit-shell 的计算样式读 --lv1..--neutral, 域层与引擎零色值(票 06 的单一口径)。
  • components/MapCanvas.vue:地图图例换成点位状态图例(8 行,每行形状 + 文字 + 计数), 标记随分页批次增量重画;StatusTag 增可选 shape 道具(不传仍是票 06 的圆点)。
  • mocks/contractMocks.js:新增 point-statuses 场景(六态 + 未关联设备 + 一个前端不认识的状态, 全部可上图)。默认样例一个字节未动,所以票 07/08 的走查数字(2,4,5 / 可上图 2 · 不上图 3)原样成立。

两个只有真机才暴露的 bug(都是视觉探针抓到的,走查当时反而绿)

  1. Cesium 的 DataSourceCollection.add() 是异步的(Promise.resolve(ds).then() 里才 push)。 同一 tick 内「先写后读」会建出两个数据源:写进未注册的 A,再从新建的空 B 读回 0 个。 症状极具迷惑性——模块计数与 dataset 都说 8,组件渲染却是「点位标记 0」, 而晚一点的 DEV 把手调用(A 已注册)又读回 8,同一页面两套答案。 修法:WeakMap 按 viewer 缓存数据源实例。
  2. 补画重试封顶 10 秒:引擎冷启动(动态拉 Cesium 分包 + 地形/影像)比装载器慢, 超时后第一批点位再也没画上,只有用户点「加载下一页」才会重新触发。 修法:退出判据改成引擎终态(ready/failed/disabled/unavailable),不再是"试够次数就放弃"。

第 2 条同时暴露了走查的盲区:它一路在点分页按钮,所以永远能画出标记。 为此新增走查块 H:一次都不点,只等引擎 ready,要求标记自己出现。

对抗式复验(每条断言都确认过能变红,不是恒真)

  • 把 toneColors() 改成恒返回一个颜色 → C2/C3 红(第一版 C2 比的是"图片是否不同",而图片里含形状, 所以它当时假绿 25/25;已改成把颜色从 SVG 里单独抠出来比,并要求逐个等于 token 实测值)。
  • 把图例截成 5 行(标记仍 8 个)→ D2/D3/G1/H2 红。
  • 把 StatusTag 的形状去掉 → D4/D6/D7 红。
  • 把所有状态折叠成 NORMAL → B1/B2/B3/B5/C4/C7/D3/D5 红。

口径说明(供后续票对齐)

  • 票面写「处置中工单」,后端枚举的 label 是「工单处置」;本票用后端的词,避免前端另造一套业务词汇。
  • 「离线」与「无设备」同为中性灰,靠形状区分(空心圆 vs 空心方块),并各自带文字。 > 2026-10-08 就地修订(由蓝湖素材替换票 05 Q22=1 裁定):正式素材替换后,「无设备」不再使用 hollowSquare 几何形状,改为「镂空徽标母版 T_MarkPoint_White + 降饱和降亮度 + 不使用内层图标(Q25=C),并保留文字标签「无设备」」。本行原「空心方块」口径被取代;本票其余口径(六态、优先级、色键、颜色不是唯一线索)不变。
  • 地图标记设了 disableDepthTestDistance: Infinity:状态点不因地形/建筑遮挡而消失(大屏值守优先)。 若将来要"被楼挡住",改这一处即可。
  • 地图上原来的事件四级图例已移除(票 09 正文明确不许混用)。事件等级图例归票 13/19; 票 14「事件定位」要把事件画到地图上时,需自己带一份事件图例,不要直接复用点位状态那 8 行。

后续关联监测设备图层的图例口径(决策地图票 05,非本票已交付功能)

本票八行图例继续只解释默认摘要的监测点状态与未关联设备;新增的关联监测设备临时图层应有独立设备图例,且设备图例只计当前模式实际绘制的设备。data-map-markers* 与“点位标记”数仍只计当前模式可见的摘要标记,不计设备图层;摘要分页总数不混入关联设备。该图层及模式筛选的实现由后续规格负责,本票原有图例验收与完成记录保留。参见决策地图票 05。

遗留

  • 点位聚合(CONTEXT.md「点位聚合」/ ADR 0002)不在本票验收内:同一位置多点目前各画各的, 没有聚合与展开。本票只保证状态词表与图例一致。
  • 地图标记的点击选中归票 10(entity.id 已按 point|<kind>|<code> 建好,可直接拾取)。

Answer

点位状态 → 视觉表现收成一张表(domain/pointStatus.js),地图标记与地图图例同源于它; 前端只渲染后端 pointStatus,认不出的状态如实落「状态未发布」而不猜成正常; 每个状态同时有形状、色键与文字,颜色不是唯一线索;事件等级色不再出现在地图图例上。