分类:bug。终态:ready-for-agent(诊断完成、规格已 resolved、根因与代码路径已钉牢,可直接实施)。历史实施真实(37/37 逻辑+19/19 变异+真机走查),重开缺陷是刷新/快照失效生命周期,非原实施虚假。同编码坐标/状态重绘缺口已随整体验收修复(ead3944,t48-linkage-invariants 通过),勿重复。
选中监测点(设备层已上图)后:
SNAPSHOT_EXPIRED(快照失效):装载器进 expired 相位,但 batchUpdatedAt 不变 → 外壳撤层监听永不触发 → 旧设备层永不撤下,持续误读为当前范围数据。objects 监听+计划指纹会让设备层重建(重找部分生效);但详情缓存不重载(跨端点不同版风险提示常驻)、无「完整加载仍找不到→关闭详情并说明原因」核对、无「暂隐+顶栏待核对」状态——规格 14:86 要求的重载链未实现。刷新按钮路径(applyFilters→refresh 同链)、快照失效路径、以及刷新后的详情一致性。不涉及:同编码重绘(已修)、翻页闪烁(正常)、关闭/换点(正常)、初始加载(正常)。
?scenario=device-layer),确认设备层已上图。data-map-devices 仍非 0(根因 ①)。SNAPSHOT_EXPIRED → 相位 expired 后 data-map-devices 仍非 0(根因 ②)。| # | 根因 | 位置 | 置信度 |
|---|---|---|---|
| ① | 刷新窗口:loader.refresh() 内部立即清空,但 store 的 summary.value 只在 await 首页返回后更新;外壳监听 batchUpdatedAt 在那之前不触发 |
mapStore.js:153(await loader.refresh())+ CockpitShell.vue 快照监听 |
高(已确认) |
| ② | 快照失效:expireMapSummary 不改 batchUpdatedAt → 撤层监听去重判据不变 → 永不触发 |
mapSummary.js:expireMapSummary + CockpitShell.vue:syncDeviceLayerForSnapshot 去重 |
高(已确认) |
| ③ | 重载链缺失:详情仅在用户重点且缓存无明确答复时重载;无快照变更驱动的"逐页重找→找到重载详情→完整找不到才关闭"核对;invalidateForSnapshot 清空后立即按调用时刻摘要重算(生产路径调用时摘要已新,此处修正先前审查的定性:不是独立缺陷,真正缺口是 ①② 与本条的链) |
detailStore.js:openSelection + deviceLayerStore.js:invalidateForSnapshot + 规格对照 |
高(缺失已确认;原"旧摘要重绘"定性修正为中低) |
batchUpdatedAt 判据解耦,或监听 phase 变化)(根因 ②)。维护者对 ❓ Q1 回复按规格:完整实现规格 14:86 核对链。交付:
domain/mapSummary.js:装载器维护本快照全页对象键索引(换快照即重置;每页合并后全量记入,护栏截断不影响),新增 hasObject(kind, code) —— 存在性判定覆盖所有已取页,合并态护栏不作缺席证据(规格明写)。stores/mapStore.js:refreshing 信号(刷新链发起即亮、收口即灭)+ hasSnapshotObject() 出口。stores/detailStore.js:reloadPointDetail(pointCode) —— 强制重取点位摘要(不查「已答过」缓存),刻意不动 selection(保留选择身份与详情层级)。stores/deviceLayerStore.js:suspendForSnapshot() —— 撤下旧设备图层但不按当前(旧)摘要立即重算;图层挂起至新快照首页或核对链恢复。CockpitShell.vue:三个监听(刷新发起 → 挂起+清收场提示+待核对;expired 相位 → 挂起;settled → 核对收口)+ reconcileSnapshotSelection()(找到→强制重载详情;完整加载找不到→关闭详情并顶栏说明;失败/失效→保持待核对可重试)+ 顶栏 data-snapshot-pending / data-snapshot-absent 提示(关闭入口由既有 data-anchor-hidden chip 保留)。证据:verify/t42-refresh-lifecycle.mjs 29/29(真实 store + 注入 fetch:refreshing 发起/收口、expired 相位、全页索引含跨页/重置、强制重载计数与层级保留、挂起不重算;外壳静态守卫钉住三个监听/核对函数/chip)。相邻 19 组闸门复跑,本票范围全绿。
三处红为并发会话在途改动、与本票无关(据实记录):① pointAnchor.js 他票面板宽度修改(t41 D6 裁切断言随之过期,归该票同步);② cesiumEngine syncAssociatedDevices 被地图文字工作加入 markerEntityIndex,t45 连续性脚本的 vm 沙箱未同步;③ t05 D1-overviewStore 裸字段(他票,先前已记录)。
扩展恢复后在 real 页面完成全链复验(网络日志 + DOM + 截图):
page=1 不带 token(开新快照),第 2–8 页全部携带新锁定 snapshotAt、全部 200——分页 token 链路无 400(整体验收修的信封在真实页持续生效);GET /monitoring-points/GS001 由核对链强制重取(规格「找到即重新加载」在真实页触发);详情面板存活、身份完整;t42-refresh-lifecycle B1–B8(模板+监听+store 行为)钉住,A1 断言「发起即亮」为确定性证据;本票验收全部满足(历史 9 条 + 重开的规格 14:86 核对链),resolved 关闭;父地图 gist 已追加。
Type: implementation Status: resolved Blocked by: 41 Labels: ready-for-agent
按规格 14 接入选中监测点后的关联监测设备临时图层。地图摘要继续只包含监测点与未关联设备;关联设备不写回摘要序列、分页、默认图例或摘要计数。地图点击和台账选择都从同一监测点选择语义启动设备加载,并与点位定位并行;设备数据到达即可渲染,不等待相机动画结束。
后端 #69 已发布:有 snapshotAt 时详情与地图共享同一快照;设备编码集合以地图快照 deviceCodes 为准,坐标只认设备自身 longitude/latitude/coordinateValidation.renderable。无坐标、非法、未校验、归属不明、详情失败或当前快照不一致的设备继续出现在清单中,并显示待确认/不可用原因,禁止复制监测点坐标或人工偏移。现网 UNVERIFIED_COORDINATE 的正式边界是清单-only。
UNVERIFIED_COORDINATE/renderable=false 时只显示清单及原因,不用临时样例冒称正式设备已能上图。deviceCode 和所属 monitoringPointCode,不冒充 pointCode。snapshotAt 翻页不重建或闪烁设备图层;快照查找逐页进行,第一页没有不能判定点位不存在。deviceCodes;详情独有/快照独有设备分别标记不一致或待确认,不静默丢弃。ALARM/WARNING,未知状态待确认。已完成并关闭。 逻辑闸门 37/37、变异测试 19/19 全部打红、真机走查已执行(见下), 全量零依赖闸门回归绿。
domain/deviceLayer.js(新):集合分类(六类互斥:drawn/no-location/hidden/pending/
inconsistent/unavailable)、快照生命周期(总数只认当前快照去重 deviceCodes;
快照独有→待确认、详情独有→不一致且禁止上图)、互斥计数与独立图例、跨端点风险提示。stores/deviceLayerStore.js(新):合成点。它读 mapStore 的当前快照 deviceCodes(总数依据)
与 detailStore 的 devices[](状态与设备级坐标),按 domain 判定后交地图服务。
两侧都不为自己长出对方(票 10 的 F4、票 02 的层次纪律)。services/cesiumEngine.js:syncAssociatedDevices / readAssociatedDevices /
clearAssociatedDevices / pickDeviceMarkerAt / hasDeviceMarker +
独立数据源 cockpit-associated-device-markers(与摘要 cockpit-point-markers 分开)。services/mapService.js:syncAssociatedDevices / clearAssociatedDevices /
getAssociatedDeviceState + 宿主读数 data-map-devices(-plan)(与摘要 data-map-markers* 分开)。domain/pointDetail.js:设备卡片带出设备级坐标与校验(后端 #69 已交付)。pointSelection.js:统一选择入口在打开详情前先出一次设备计划(不等详情、不等镜头)。CockpitShell.vue:四类订阅(选择 / 详情到达 / 快照变化 / 一级模式)+ 卸载拆监听与复位。components/PointDetailCard.vue:关联设备清单(保留全部、每行标注互斥归类)+ 独立图例。UNVERIFIED_COORDINATE/renderable=false);
新增 device-layer 受控有效坐标样例(两台设备带自身有效坐标,且地图 deviceCodes
与详情 devices[] 一致)。verify/t42-device-layer.mjs(37/37)+ 变异 19/19 全部打红。deviceCodes,不拿详情统计或卡片数冒充 —— 详情不携地图快照的
snapshotAt、还可能复用缓存,两边可能不同版。所以「快照独有」与「详情独有」必须分开:
前者待确认、后者标不一致且禁止上图,两边都不静默丢弃。coordinateValidation.renderable(票 07 的唯一判据):
前端不重算经纬度范围、绝不用监测点坐标代替设备坐标、不人工偏移(CONTEXT.md 明令禁止)。
现网无可信校核源 → 正式边界是清单-only,本票照抄这个边界。本机 @puppeteer/browsers 是空目录(票 37 记录的既有环境缺陷),故按票 36/37/41 成例
改用 DSH 自带浏览器真实驱动(yarn dev @8000,真实 public/cockpit/config.json)。
修掉的缺陷:UI 把「清单行数」当成了「关联总数」。 真机读数暴露:总数显示 2 而当前快照
只有 1 台设备 —— 多出来的是「详情独有」那一行(规格明确它不计入总数)。
修:store 单独持有 total(=当前快照去重 deviceCodes 条数),与 rows.length 分开;
界面两个数都显示且各有明确含义。已补断言 B1b-total-is-not-row-count 钉住。
实测证据(真实浏览器,与验收逐条对应):
onMap=2),实体 id 形如
device|MP-001|EQ-001,属性同时带 deviceCode + monitoringPointCode、不含 pointCode
(不冒充监测点);摘要标记仍为 2(data-map-markers=2)、设备另计(data-map-devices=2)。UNVERIFIED_COORDINATE/renderable=false →
清单保留并标 no-location、引擎 0 台、总数 1、清单 2 行(inconsistent 那行不计入总数、
不上图)、跨端点风险提示出现、摘要标记仍 2。onMap=0、计划清空、宿主读数归零,而摘要标记仍 2(互不牵连)。pointCode 正确),A 的不残留。pickDeviceMarkerAt() 只认本图层带 deviceCode 的实体并回身份;
设备优先于监测点(票 15 的优先级)。未覆盖项(如实记录):走查时浏览器标签 document.hidden===true,rAF 被冻结、Cesium 不渲染
(票 37/41 记过同一环境事实),因此依赖渲染的 scene.pick 在本次环境下连监测点标记也拾不到
(已用"连 pointHit 也为 null"的对照确认是环境而非本票缺陷)——「真实鼠标点设备点」这条
双向联动入口的走查归票 43(它正是双向对应的实现票,且 pickDeviceMarkerAt() 的接缝已就位)。
建议维护者在前台标签页复跑一次以补该条观感。
shape 由调用方给,默认 circle)与 14px 尺寸(小于监测点的 18px),不实现状态词表。domain/modeLayerPlan.js)与图例合成。本票只实现
单点位的模式可见性(isVisibleInMode),不做全图矩阵。零依赖逻辑闸门全绿(t01/t03/t04/t05 254/t06/t07 39/t08 44/t09/t10 57/t11/t12/t13/
t14/t15/t16/t17/t18 71/t19/t21/t21-view/t29/t30/t36/t37/t38/t39/t41 46/t42 37)。
两处红与本票无关:① t28-fill-container.mjs 需 puppeteer,而本机 @puppeteer/browsers 是空目录
(既有环境缺陷);② 某次运行中 t05 的 C8-real-attaches-credential 一度红 —— 经核实是并发会话
正在改 services/cockpitApi.js / mapApi.js(本票改动清单里没有这两个文件),随后复跑已恢复绿。
按 AGENTS.md:本会话未跑 build(真机走查是维护者本轮明确要求才执行的)。
43(面板与三维设备点双向对应)、44(设备位置符号与状态词表)、46(模式图层计划)
均已解除阻塞,可并行。整体验收审查:刷新等待首屏期间旧设备层仍在;快照失效未改变batchUpdatedAt时不撤层;缺重找点位、强制重取详情及完整找不到后关闭链。另同编码坐标/状态未重绘已在整体验收当前工作区修复(t48-linkage-invariants),尚待提交与真实样本回验。当前票因刷新生命周期未满足重新打开,先诊断再实施。
This was generated by AI during triage.
分类:bug|终态:ready-for-agent(needs-triage 已摘除)。
已确认(代码核验 + 规格 14:86 原文对照):
ead3944,t48-linkage-invariants 通过),勿重复。batchUpdatedAt 监听不触发 → 旧设备层存活,违背规格"先撤下"。expireMapSummary,batchUpdatedAt 不变 → 撤层监听永不触发 → 旧层永不撤下。objects 监听让设备层在后续页重建(部分生效),但详情不重载、无收场核对。原审查"撤下后从旧摘要重绘"定性修正——生产路径调用时摘要已新,非独立缺陷。最小复现: 打开 ?scenario=device-layer 设备层 → 刷新(窗口期旧层存活)→ mock 第 2 页 SNAPSHOT_EXPIRED(失效后旧层仍上图)→ 刷新后点位移页/移除(详情不重载/永不关闭)。
实施方向与详细根因表: 见票面「进度(2026-10-13 诊断)」节;证据 verify/artifacts/t48/acceptance-status.md。
❓ Q1(待拍板,不阻塞标签流转): 修复范围按规格 14:86 完整实现核对链,还是先只修 ①② 时序缺口、核对链另立子票?➡️ 推荐:按规格完整实现(规格已 resolved,核对链是本票验收第 4 条的字面要求;拆出会让整体验收 48 的第 2 条仍差一块)。回复后按选定范围实施,标签维持 ready-for-agent。