13-event-list-and-mode-switch.md 7.4 KB

13: 事件列表与预警/报警切换

What to build: 提供预警/报警分段切换和只读事件列表。事件等级颜色与点位状态色分离,事件通过设备编码关联设备位置。

Blocked by: 11

Status: resolved Labels: ready-for-agent

  • 预警与报警可切换,列表字段和状态标签同步变化。
  • 事件列表默认展示最新 10-15 条。
  • 事件等级使用 1-4 级颜色,并有文字辅助。
  • 事件不创建独立地图标记。
  • 不判断预警真伪或误报。
  • 有事件适配和切换状态单测。

进度:100%

已完成并关闭。 逻辑闸门 49/49 + 真机走查 15/15(维护者授权后执行);手动验证维护者亦已通过。

交付物

  • domain/eventList.js(新):跨设备 /events/current(CockpitCurrentEventsResponse) 的契约适配 + 切换视图 + 事件列表行。
    • toCurrentEvents() / toEventItem() / toEventSection():envelope、内部分区、 EventItem → 领域行(等级、状态、量值、设备编码、坐标校验留给票 14);
    • eventListSwitchView(mode):唯一的切换视图 —— 字段标签(预警编号/报警编号) 与状态标签名(预警状态/报警状态)从同一个对象取,切换必然一起变(验收第 1 条 是结构性保证,不是两边各自小心);
    • eventLevelTag(level):走 statusTones.js 的 LEVEL_TAGS(lv1..lv4 + '1级'..'4级'), 与点位状态色(pointStatus.js)分离是结构性的;认不出的等级落中性灰 + 文字,不猜;
    • latestEventRows():默认取最新 12 条(DEFAULT_EVENT_LIMIT,落在验收「10-15 条」区间), 排序口径照抄后端 eventOrdering()(eventTime 倒序、同时间 eventNo 升序);
    • eventStatusText():状态直译已知取值(ACTIVE/PENDING/PROCESSING/HANDLING), 认不出的回原码(数据值照原样显示,与 CODE_TEXT 同一立场)—— 只呈现后端判断, 不替后端裁决真伪。
  • services/eventApi.js(新):fetchCurrentEvents({ mode, industry, level, status, ... }) 拼 /events/current 查询串 → 04 统一出口 → 收成一个分区;mode 只认 WARNING/ALARM (后端对认不出的值 400),industry 经 filterOptions.industryQuery() 映射。
  • stores/eventStore.js(新):共享切换状态(mode 默认 WARNING)+ currentEvents 分区
    • token 竞态收口(快速切预警→报警→预警只让最后一次落进分区)。 切换状态在 store 而不是组件:票 19 要求四块面板读同一个当前族。
  • components/EventListPane.vue(新):可复用面板内容 —— 预警/报警分段按钮 + 只读事件 表格(等级 StatusTag 带文字、状态文本、时间、量值、设备)。挂载在预警处置模式的 currentEvents 面板(CockpitShell.vue 增加该分支,注册在 t05 守卫面)。
  • mocks/contractMocks.js:新增 /events/current 跨设备样例(预警/报警各 14 条, 等级 1-4 全覆盖),按 mode 真过滤(切换真的换内容),排序/分页/内部分区照后端语义, 非法 mode 抛错。字段名照后端 CockpitCurrentEventsResponse。
  • verify/t13-event-list.mjs(新,49 项逻辑闸门)、 verify/t13-event-list-walkthrough.mjs(新,真机走查脚本,待授权执行)。

与票 19 的分工(都在票面上写明了)

本票交付「事件列表 + 预警/报警切换」积木并在 currentEvents 面板落一个可见挂载点; 票 19(预警处置模式面板,阻塞于 13 + 16)在其上做四面板组合、工单状态与设备定位, 并复用同一个 eventStore.setMode()(四面板切换状态共享)。

验证

逻辑闸门 49/49(node .scratch/cockpit-shell-panel-layout/verify/t13-event-list.mjs), 十段覆盖:契约适配 / 切换视图同步 / 等级配色 / 默认条数 / 事件不建标记(静态守卫)/ 不判断真伪(静态守卫)/ store 取数切换竞态 / mock 真过滤 / 页面组件静态守卫 / 视图行形状。

回归全绿:t01 / t04 / t05(守卫面已扩到本票三个新文件)227/227 / t06 / t07 / t08 / t09 / t10 / t11 / t12 / t17 / t18 / t21 / t21-view / t29 / t30。

变异测试确认守卫有牙(每一条都验证过会变红/崩溃): B2/G3 切换同步、D2/G1/G2/H3 默认条数、F1 不判断真伪、G4 竞态 token、 E1/I3/I4 静态守卫(地图服务 import / fetch / service import)、D5 视图行形状 (撤销 eventRowView 转换后 D5 直接崩溃 —— 视图行形状是硬依赖)。

对抗式自查抓到的真 bug

currentEventsView() 第一版把领域行(toEventItem 的结果)直接交给组件, 而组件要的是视图行(eventRowView:level.tone/statusText/quantity)—— 逻辑闸门只数行数抓不到(假绿),真机走查才会红。已修复:rows 一律 latestEventRows(items).map(eventRowView),并新增 D5 视图行形状断言。 这正是票 12 的教训「能加载 ≠ 能渲染」的又一例。

真机走查与收口(维护者授权后执行,15/15)

维护者授权 + 已起 yarn dev(8000)+ 手动验证通过后执行:

 node .scratch/cockpit-shell-panel-layout/verify/t13-event-list-walkthrough.mjs

三组 15/15(内容从 DOM 读,证明界面真画出来了而不是 store 里有值):

  • A 预警(7 项):预警处置模式下当前预警面板画出事件列表;默认预警 (WARNING 按钮按下、表头「预警编号/预警状态」、行码 WRN-*);每行等级=色键+文字 (如 1级@lv1);恰好 12 条 + 「仅展示最新 12 条 · 共 14 条」;面板零写操作按钮; 无页面错误。
  • B 切报警(4 项):点报警按钮 → 表头同步变「报警编号/报警状态」(不再有 「预警编号」);行内容换成 ALM-*;切换前后地图点位数 2 → 2 不变(事件不建独立标记)。
  • C 空样例(4 项):只让 /events/current 走 empty → 「当前没有事件」、不画假行、 分段切换仍在、无页面错误。

走查脚本第一轮 14/15 抓到两个断言自身的假绿/误判(不是产品 bug),已修并复验: ① A6 把分段切换按钮(data-event-switch,视图切换不是业务写操作)误算进 「写操作按钮」→ 改为排除切换按钮后 0;② B4 用 getPointMarkers().length 取点数, 而该句柄返回 { markers, onMap } 对象 → length 恒 undefined、undefined !== null 恒真,B4 是弱绿(取不到也绿)→ 改读 onMap(取不到给 null、断言 !== null), 修后证据从 undefined → undefined 变为真实的 2 → 2。

Answer

事件列表与预警/报警切换落地:跨设备 /events/current 的契约适配、 共享切换状态(eventStore.mode,票 19 四面板复用)与只读事件列表组件。 字段标签与状态标签从同一个切换视图取(同步变化是结构保证)、等级 1-4 色带文字 (statusTones 的 LEVEL_TAGS,与点位状态色分离)、默认展示最新 12 条、 事件不建独立地图标记(只带设备编码供票 14 回联)、不判断预警真伪或误报 (后端契约就没有准确率/误报字段)。逻辑闸门 49/49 + 变异测试有牙 + 真机走查 15/15 (含手动验证)+ 全量回归绿。