Type: implementation Status: resolved Blocked by: 42 Labels: ready-for-agent
按规格 15 实现面板设备卡片与三维设备点的双向 hover/选中/拾取联动。选中反应使用外环、放大和连接监测点标记中心的引线,不使用颜色抢占设备状态语义;hover 是瞬态轻放大/卡片高亮,不叠加选中外环和引线。设备点使用独立 pickDeviceMarkerAt() 身份,设备点优先于监测点,未关联设备既有拾取链路不变。
map.locate.device;同点位设备 A→B 只换中心不重飞;返回点位级回点位视角但监测点仍保持选中。data-map-device-picked、data-map-panel-selection、data-map-device-hovered,不破坏 data-map-picked。已完成并关闭。 逻辑闸门 40/40、变异测试 26/26 全部打红、真机走查已执行(见下), 全量零依赖闸门回归绿。
domain/deviceCorrespondence.js(新):反应档位(selected/hovered/dimmed/normal,
互斥且优先级正确)、镜头联动三段(device-tier/center-only/point-tier)、
拾取优先级(resolvePickOrder:设备优先、监测点兜底)、引线退化(重合不画)、
反应量(scale/alpha/ring,不含颜色)。services/cesiumEngine.js:applyDeviceReactions(逐实体写 scale/alpha/outline)、
syncDeviceLead/clearDeviceLead(设备点到监测点标记中心的归属引线)、pickDeviceMarkerForHover。services/mapService.js:syncDeviceReactions / syncDeviceLeadForSelection /
setSelectedDevice / setHoveredDevice / hoverDeviceAt / onDeviceHover /
pickDeviceOrPointAt(优先链)/ setPanelSelectionLevel / clearDeviceSelection /
getDeviceCorrespondenceState;宿主新增三个可断言字段;hover 节流 60ms。stores/deviceLayerStore.js:selectedDevice/hoveredDevice/dimming +
selectDevice(含镜头联动)/ hoverDevice / backToPointLevel / noteLevel。components/PointDetailCard.vue:设备卡片与设备清单都接上 hover/选中(data-device-selected/
-hovered 供走查读)。components/MapCanvas.vue:三维 hover → 面板高亮;三维点设备 → 选中并进设备级。CockpitShell.vue:层级字段写入 + 层级对照同步 + 设备把手。verify/t43-device-correspondence.mjs(40/40)+ 变异 26/26 全部打红。color 字段都没有(有断言钉住)。本机 @puppeteer/browsers 是空目录(既有环境缺陷),故按票 36/37/41/42 成例
改用 DSH 自带浏览器真实驱动(yarn dev @8000)。
修掉的缺陷:设备选中态有「两套真相」。 我原先把 setSelectedDevice 直接暴露到 DEV 把手,
真机走查暴露:直接调服务层后 store 的 selectedDevice 仍读空串 —— 界面(面板高亮)与引擎
(三维强化)对"选中了谁"给出两个答案。修法:服务层不再暴露直写选中态的函数,
按票 41 的 publishPointSelectionHandle 成例,由外壳把 store 的方法递给 DEV 把手
(publishDeviceSelectionHandle);走查驱动的是"用户那条路径"。已补断言 F14 钉住。
实测证据(真实浏览器,与验收逐条对应):
data-map-device-picked=EQ-001、detailLevel=equipment、detailDevice=EQ-001;
store 与服务层读数一致(store === service === 'EQ-001',修复前 store 为空串)。EQ-002 时 data-map-device-hovered=EQ-002 而
data-map-device-picked 保持 EQ-001。data-map-panel-selection 随详情层级变化(point ↔ equipment)——
注意 Vue 的 watch 是异步(flush: 'pre'),同步读到的仍是上一拍的值(已确认下一拍一致)。equipment → point、监测点仍选中(pointCode=MP-001)、设备选中清空。applyDeviceReactions 对两台实体各写一次(返回 written=2)。未覆盖项(如实记录):走查标签 document.hidden===true(rAF 冻结、Cesium 不渲染),
所以「真实鼠标 hover 三维设备点 → 面板高亮」与「真实鼠标点设备点」这两条的画面观感
未能逐帧验证(票 42 已记录同一环境事实:该环境下连监测点标记的 scene.pick 也拾不到)。
这两条的判定与接线已由 t43 闸门覆盖(拾取优先级 D 段、hover/选中接线 F 段、反应量 B 段),
真实观感建议维护者在前台标签页复跑,或由票 48 的整体验收一并覆盖。
scale/alpha/outline,
不碰形状与色键(shape 仍由调用方给)。isVisibleInMode 继续生效)。零依赖逻辑闸门全绿(t01/t03/t05/t06/t07 39/t08/t09/t10 57/t11/t12/t13/t14/t15/t16/t17/
t18 71/t19/t21/t21-view/t29/t30/t36/t37/t38/t39/t41/t42 37/t43 40)。
三处红与本票无关:① t28-fill-container.mjs 需 puppeteer(既有环境缺陷);
② t04-config.mjs 的「页面与组件不该硬编码后端地址」与 ③ t20-overview-panels.mjs 的 D3
—— 两条都指向 services/cockpitApi.js,而该文件并发会话(票 20)正在改,
不在本票改动清单里(git status 可核)。
按 AGENTS.md:本会话未跑 build(真机走查是维护者本轮明确要求才执行的)。
45(重叠设备聚合与展开)、46(模式图层计划)、47(状态特效)的依赖已就绪;
45 仍需 42/43/44/46 全绿后才可claim。