46-untitled.md 19 KB

前端执行票 —— 监测点与设备详情卡片化、分类查询与历史折叠

Label: ready-for-agent Category: frontend-execution

来源

承接票37收口时维护者反馈第5条。

范围

  1. 监测点与设备详情面板:能用 KPI、状态卡、时间线、分布图表达的内容,不再以大段纯文字为主;优先复用现有块组件与视觉 token。
  2. 设备卡片中的预警、报警、工单信息增加分类查询/筛选入口,避免长滚动列表查找困难。
  3. 历史条目默认可折叠;每条历史数据可展开查看详情,保留数据时间、状态、来源和关联对象。
  4. 支持空态、加载态、失败态;筛选变化不丢失当前详情上下文,返回/关闭后状态可恢复。
  5. 验收:桌面与窄面板可用;分类切换、折叠/展开、单条详情查看均有明确反馈;不改变后端事实与只读边界。

非目标

  • 不改后端契约;不新增写操作。
  • 不改变地图点位选择、定位和详情路由接缝,只优化消费侧呈现与交互。

进度

  • 2026-10-15 第一轮:已认领 → 已实施(消费侧 4 文件)→ 离线闸门 t46 32/32 + 变异 4/4 → 既有闸门回归全绿。
  • 2026-10-15 第二轮(维护者反馈返工):① 设备详情弃六块长滚动 → 标签页(设备档案默认,最新图片并入该页下方|最新指标|预警信息|报警信息|工单状态),预警/报警每页最多 10 条(上一页/下一页 + 页码);② 状态图例与一张图顶部视觉+词表双对齐(图标登记提为 legendIconFor 单源,详情内 5 处 StatusTag 全部绑定 icon)。t46 扩到 53/53、变异 11/11;18 组离线闸门回归全绿。
  • 2026-10-15 维护者反馈第 3 条(一张图底部管线颜色图例)→ 另建票 48,不在本票范围。
  • 2026-10-15 第三轮(授权后浏览器走查,真实后端 real):CDP 探针 27/27 全过(目标 CBWS202610150001 / 设备 21119740:真实 5 预警/66 报警/7 工单)。KPI 计数条、五页签默认档案+图片并入、第 1/7 页·共 66 条、末页余 6 行到边禁用、66 条默认全收起、分类先筛后翻页码回 1、再点取消、展开四件事、详情 3 标签带图标且色键与顶部报警行 lv1 同源、返回再进零重复取数、480px 无溢出、零 pageerror/console error。证据 verify/artifacts/t46/。
  • 2026-10-15 本票关闭。源码与票据已随提交 2e27b29 推送 origin/master(ChenJZ)。

Status: resolved Type: task Blocked by: Labels: ready-for-agent, wayfinder:task

实施记录(2026-10-15,第一轮)

交付 1:监测点摘要卡片化(范围第 1 条)

  • domain/detailFlow.js 新增 pointDeviceCountsView(detail)(纯函数):点位设备计数 KPI 行(报警/预警/工单处置/正常/离线)。三条纪律:统计整段缺失(statistics.missing 非空)→ 回 null,KPI 条不出现而不是画一排 0(票 16 虚假零值立场,变异 M2 有牙);计数 0 是真实值照画;色键走设备词表(deviceStatusView,不借点位表——票 44 立的边界)。
  • PointDetailCard.vue 第一级重排:身份两行(名称/编码)保留键值行形状(t41 钉住 data-point-code-value 是 <dd>、data-point-device-count 是 <b>,原样保留);状态+原因改状态卡;新增 KPI 计数条(data-point-kpis/data-point-kpi/data-point-kpi-tone,颜色只引用 token)。名称与原因走票 37 的共用省略方法 EllipsisText。

交付 2:预警/报警/工单分类查询(范围第 2 条)

  • domain/equipmentDetailView.js 新增分类视图函数(全纯函数):categoryChips(rows, order)(首项恒「全部」+真实计数;0 计数的词表项不出现;词表外分类不静默丢、排已知项之后)、filterByCategory(rows, key)(空键=全部原样返回同一引用;认不出的键回空数组——回全量就是"筛了个寂寞",变异 M1 有牙)、categoryNote(生效时回显「当前分类:X(再点同一项取消)」,票 37 typeNote 同立场)。
  • 分类词表全部复用单源:事件等级走票 13 eventList.js 的 eventLevelTag(1–4 级 + 未知),工单状态走 workOrder.js 字典 0–7(WORK_ORDER_CATEGORY_ORDER 直接展开自 WORK_ORDER_STATES);认不出的等级/状态码落 level:unknown/state:unknown「等级未知/状态未知」,不并进任何真实语义(变异 M4 有牙)。
  • eventRows/workOrderRows 增补视图字段(categoryKey/categoryLabel/timeText/type/deviceCode/deviceName/source)——都是既有领域字段的改名/复用,零新后端字段。
  • EquipmentDetailSections.vue:预警/报警/工单三块共用同一条 chip 条(一组绑定只写一处,data-category-bar/data-category-chip/aria-pressed/is-active);分类是组件本地视图状态(categories = ref({})):不发请求、不动 selection、不进 filterStore——它是「这一屏怎么看」,不是全局数据条件(票面非目标「不改变后端事实与只读边界」)。换设备(watch(deviceCode))分类归空:A 的条件不挂到 B 上。

交付 3:历史条目默认折叠 + 展开详情(范围第 3 条)

  • 预警/报警/工单条目改 <details data-history-item>(无 open=默认折叠;原生键盘可达、展开态自带反馈),summary 一行给折叠读法:名称/状态名 + 等级 + 状态 + 短读时间(shortEventTime 单源)+ 编码 + 量值/关联标记。
  • 展开后 eventDetailRows/workOrderDetailRows 出详情行:数据时间、状态、来源、关联对象四件事始终保留(缺值给占位符——变异 M3 有牙:把必选项也按"没值就丢"处理会被 C1 抓住);可选行(编码/等级/量值/位置/说明)有值才画,不铺一排 — 噪音。工单 实际结案 必留(折叠行本来就显示「结案 —」,展开后消失是前后矛盾)。
  • 票 12 的接缝逐字保留:v-if="trackOfOrder(order)" / v-else-if="timeline.hasContent" / :path-only="!timeline.hasContent"(t12 F9 守卫钉住),时间线仍挂在每张工单自己的卡里。

交付 4:状态与边界(范围第 4/5 条)

  • 空/加载/失败态:六分区独立成败语义一字未动(SectionStateTag + sectionPlaceholder + 整包失败分支),分类过滤只作用于「有内容」分支的行。
  • 筛选不丢上下文:分类是本地状态,切换不发请求、不改 selection;返回/关闭仍走既有 detailStore 路径(t10/t41 绿)。
  • 只读边界:组件零 fetch、零接口路径、零 .sort(、零后端裸字段/原因码(t05/t10/t11 + 本票 E5–E7 守卫)。

实施记录(2026-10-15,第二轮:维护者反馈返工)

维护者 2026-10-15 三条反馈:① 设备详情弃用「浏览器式文档切换」(六块竖排长滚动),改标签页 设备档案(默认,图片归此页)|最新指标|预警信息|报警信息|工单状态,预警/报警列表每页最多 10 项;② 点位摘要与设备详情的状态图例没有与一张图顶部图例对齐;③ 一张图正下方持久显示管线颜色图例。经确认 ①② 在本票内返工,③ 另建票 48。

交付 5:设备详情改标签页(返工第 1 条)

  • domain/equipmentDetailView.js 新增页签计划:EQUIPMENT_TABS(五页,顺序即界面顺序,archive 页的 sections = ['archive','latestImage'])、DEFAULT_EQUIPMENT_TAB = 'archive'、panelsForTab()、tabCount()。渲染计划仍是六块独立分区(EQUIPMENT_SECTION_PANELS 长度不变,latestImage 加 mergedInto: 'archive' 标归属)——标签页只改呈现归属,不合并任何分区的数据与成败(t11 D1/D9 的独立性判据原样成立)。
  • EquipmentDetailSections.vue:role="tablist" 页签条 + 只渲染 activePanels;页签上挂条数(预警/报警/工单有,档案/指标回空串——0 会被读成"档案有 0 条");换设备时页签复位到默认页。
  • 图片按维护者选定的形态放在档案键值行下方(沿用既有点击放大 dialog、加载失败与"后端未提供"三条分支,图片分区自己的成败仍独立显示)。

交付 6:预警/报警分页(返工第 1 条后半)

  • pagedRows(rows, page, pageSize = 10)(纯函数):HISTORY_PAGE_SIZE = 10;返回 rows/page/pageCount/total/from/to/hasPrev/hasNext。三条边界都收在 domain 可断言处:越界页码夹回合法页(回空表就是拿页码 bug 冒充"没有数据",变异 M5 有牙)、空表算 1 页、不排序不改序(只在已过滤序列上切窗口,票 10/11 立场)。
  • 控件:上一页/下一页 + 「第 N/M 页 · 共 X 条」;到边的按钮置灰但保留占位(消失会让页码行跳动,读起来像出错);只有一页时整条控件不出现。
  • 换分类时页码回第 1 页(停在第 3 页看新结果集会直接显示"没有记录")。工单块不分页(维护者原话只点名预警、报警;工单条目自带时间线,切页会打断阅读)。

交付 7:状态图例与一张图顶部对齐(返工第 2 条,口径=视觉+词表双统一)

  • 图标登记提为单源接缝:domain/pointStatus.js 里原先内联在 legendVisuals() 的 iconOf 表改成模块级 LEGEND_ICON_BY_KEY + 导出 legendIconFor(key);legendVisuals() 自己经它取值(顶部状态栏消费路径不变,t09 38/38 仍绿)。
  • 详情侧接入:statusView() / deviceStatusView() 返回值新增 icon 字段(点位走点位表、设备走设备表,只借图标登记、不借状态语义 —— 票 44 的两表边界由 H3 断言守住)。PointDetailCard.vue 内全部 5 处 StatusTag 绑定 :icon(点位状态卡、设备卡片、关联设备清单命中行/未命中行、设备详情表头)。
  • StatusTag.vue 加可选 icon prop:不传 = 票 06 原外观(事件列表等既有调用点零变化);传了则图标与形状/圆点同 currentColor,与顶部状态栏同一档弱发光。
  • 词表口径:点位侧本就直接消费 legendVisuals() 的同一张表(八桶含 EMPTY 无设备 / UNASSOCIATED 无关联设备),设备侧维持票 44 裁定的独立平行表(设备五态无 EMPTY)—— 这是既有决策,返工未推翻;若要把设备状态也并进八桶词表,属于词表口径变更,需另立决策票。
  • 修掉一个真缺陷:legendIconFor 第一版用 table[key] || '',toString/__proto__ 这类继承键会命中原型方法并被当图标名带出屏(sectionState.js 的 owns 注释记过同一课)。改成 hasOwnProperty 判定,H5 断言 + 变异 M7 钉住。

过程记录(第二轮)

  • E10 断言逮到漏绑:写完后跑 t46,「详情卡内每个 StatusTag 都绑定 icon」判红 —— 设备详情表头那一处漏了。守卫按绑定判(不是"文件里出现过 icon 字样"),所以漏一处就红,这正是本仓第五次踩"守卫比它要守的东西宽"之前先立住的形状。
  • 具名 import 拼错:把 EVENT_CATEGORY_ORDER 误写成 EQUIPMENT_CATEGORY_ORDER,文本正则守卫全绿(字样都在文件里),只有真的加载 .vue 的 t41 SSR 闸门炸出来。据此新增 E11/E11b/E11c 三条:拿 domain 模块的命名空间判"import 的名字是否真实导出",并与清单双向核对(多一个没登记的名字、或清单里的名字没被 import,都判红)。变异 M8/M8b 分别用「t46 自己也 import 的名字改名」(闸门崩溃式抓住)与「只有组件 import 的名字改名」(E11 断言转红)把这条判据本身验穿。
  • 变异脚本对「崩溃」与「断言转红」分列记录(CAUGHT-BY-CRASH),不把加载失败混算成某条断言有牙,也不误记成假绿。

验收对照(第二轮更新)

  1. 离线闸门:t46-detail-cards-history.mjs 53/53(A chips/过滤、B 分类键单源、C 展开四件事、D KPI 不画假 0、F 页签计划、G 分页边界、H 图例对齐、E 静态守卫按绑定判 + import 按真实导出判);t46-mutations.mjs 变异 11/11 全部抓住(M1 认不出回全量 / M2 缺统计画 0 / M3 必留行丢失 / M4 未知等级猜成 1 级 / M5 越界页码不夹回 / M6 图片未并入档案页 / M7 图标登记吃继承键 / M8+M8b 导出改名 / M9 页签次序打乱 / M10 状态视图丢图标),还原逐字节校验。
  2. 既有闸门回归(18 组,全绿):t05 282/283(唯一红 D1-stores/overviewStore.js 为 HEAD 级既有失败,本票未动该文件)、t09 38/38、t10 57/57、t11 61/61、t12 52/52、t41 SSR 9/9、t43 40/40 + t43 图表 20/20、t44 47/47 + t44 普查 103/103、t15 11/11、t16-stores/t16-alarm-order、t22、t23、t27、t42、t50 30/30。
  3. 浏览器走查:未执行(AGENTS.md:未获明确要求不跑 dev/走查)。入口 http://127.0.0.1:8000/#/cockpit;判据:
    • 设备详情打开后默认停在「设备档案」页,档案键值行下方出现图片区;页签条上预警/报警/工单带条数;
    • 预警/报警条目数 >10 时出现「上一页/下一页 · 第 N/M 页」,翻到末页取余数,单页设备不出现分页控件;
    • 分类 chips 先筛后翻,换分类回第 1 页;
    • 点位状态卡、设备卡片、关联设备清单、设备详情表头的状态标签都带图标,且与一张图顶部状态栏同形同色同字;
    • 换设备页签/分类/页码全部复位;返回/关闭不重复取数;窄面板(420px 浮层)下页签与 chips 换行不溢出。

改动文件与入库裁剪清单(两轮合计)

domain/detailFlow.js(+pointDeviceCountsView;statusView/deviceStatusView 带 icon)、domain/equipmentDetailView.js(+分类/详情视图函数、页签计划、pagedRows;行视图补字段)、domain/pointStatus.js(图标登记提为 legendIconFor 单源 + hasOwnProperty 收口)、components/StatusTag.vue(+可选 icon prop 与样式)、components/PointDetailCard.vue(第一级卡片化 + 5 处状态标签接图标)、components/EquipmentDetailSections.vue(chip 条 + 折叠 + 展开详情 + 标签页 + 分页)、verify/t46-detail-cards-history.mjs、verify/t46-mutations.mjs。工作树混有并行在制品(CockpitShell/MapCanvas/mapService/PipeEnhancement 族等),入库须按票 33/36/37 纪律单独裁剪本票 hunks。

Comments

local — 2026-10-15T04:53:26.109Z

实施完成(2026-10-15):① 监测点摘要卡片化(状态卡 + 设备计数 KPI 条,pointDeviceCountsView 纯函数,统计缺失不画假 0);② 预警/报警按等级、工单按状态字典 0–7 出分类 chips(词表全部复用单源 eventLevelTag/WORK_ORDER_STATES;再点取消;生效回显 categoryNote);③ 历史条目默认折叠(details 无 open),展开保留数据时间/状态/来源/关联对象四件事;④ 分类为组件本地视图状态:不发请求、不动 selection、换设备归空;六分区独立成败与票 12 时间线接缝逐字保留。离线闸门 t46 32/32、变异 4/4 打红(含沙箱管道陷阱的过程记录);t10/t11/t12/t15/t41/t43/t44/t50 回归全绿;t05 唯一红为 HEAD 级既有(overviewStore,本票未动)。改动未提交(工作树混有并行在制品,按裁剪清单单独摘取)。浏览器走查(验收第 5 条)按 AGENTS.md 未自动执行,票面留判据——票保持 open。

local — 2026-10-15T07:13:57.909Z

返工完成(2026-10-15 第二轮,维护者反馈第 1/2 条):① 设备详情弃六块竖排长滚动,改标签页(设备档案=默认页且最新图片并入其键值行下方|最新指标|预警信息|报警信息|工单状态),页签带条数;预警/报警每页最多 10 条(上一页/下一页+「第 N/M 页 · 共 X 条」,越界页码夹回、单页不出现控件、换分类回第 1 页;工单不分页——原话只点名预警报警且工单条目自带时间线);② 状态图例与一张图顶部对齐(口径=视觉+词表双统一):图标登记从 legendVisuals 内联表提为 pointStatus 的 legendIconFor 单源,statusView/deviceStatusView 带 icon,StatusTag 加可选 icon prop,详情卡内 5 处状态标签全绑定;设备侧仍走票 44 的独立平行表(只借图标登记不借状态语义)。渲染计划仍六块独立分区(t11 D1/D9 不破)。过程:E10 断言逮到表头漏绑 icon;具名 import 拼错(EVENT→EQUIPMENT_CATEGORY_ORDER)文本守卫全绿、t41 SSR 才炸 → 新增 E11/E11b/E11c 按真实导出+双向清单判,M8/M8b 验穿;legendIconFor 第一版吃继承键(toString)改 hasOwnProperty。t46 53/53、变异 11/11;18 组离线闸门回归全绿。第 3 条(一张图底部管线颜色图例)另建票 48。改动仍未提交;浏览器走查按 AGENTS.md 未自动执行,票面留判据——票保持 open。

local — 2026-10-15T09:49:14.842Z

浏览器走查完成并关闭(2026-10-15 第三轮,维护者授权,真实后端 real)。方式:一次性 CDP 探针(本仓票 26/33/36 手法;地图标记是 Cesium 实体,交互式会话点不到,且并行会话写 src 会触发 vite 整页重载——进入路径做成可重入、交互+读数合并进单个页内 evaluate 原子块)。目标 CBWS202610150001(唯一报警点,顶部状态栏「报警」筛选孤立出来 → setCameraFocus 飞近 → 真鼠标点票 47 DOM overlay 标记内部 SVG)/ 设备 21119740(真实 5 预警/66 报警/7 工单)。27/27 全过:① 点位摘要=状态卡+KPI 计数条(ALARM=1:lv1…真 0 照画),t41 钉住的 dd/b 形状原样;② 五页签默认档案、图片并入档案页(sections=archive,latestImage)、页签条数 5/66/7;③ 报警第 1/7 页·共 66 条、每页 10 行、末页余 6 行、到边按钮禁用、66 条默认全收起;④ chips all=66/4级=66、点分类后页码回第 1 页、回显「当前分类:4级(再点同一项取消)」、再点取消恢复全量;⑤ 展开一条报警见 数据时间/状态/来源/关联设备/编码/等级/量值/位置,值全非空白;⑥ 顶部状态栏 8 行全带图标、详情内 3 个状态标签全带图标且色键 lv1 与顶部报警行同源;⑦ 返回再进同一设备零重复取数(detail-aggregate 0→0)、视图回默认页签;⑧ 480px 窄面板 tabs/aside/body/chips 溢出量全 0;Z 应用侧零 pageerror、零 console error。证据 verify/artifacts/t46/(探针脚本 + 5 张截图 + walkthrough-result.json)。走查中修掉探针自身两处误判(顶部图例图标类名选择器错、C3 空集合 every 恒真需连行数一起判),非应用缺陷。源码提交 2e27b29 已推送 origin/master(ChenJZ)。本票关闭。

Answer