Blocked by: #31
Type: task Status: resolved Label: ready-for-agent Category: frontend-execution
票 18 真实联调与真人走查第 1、4 项(2026-10-10):地图上监测点、设备、设施、管道全部没有正确显示。
CockpitShell.vue 构造 modeLayerPlan 时恒传 facilities: null、pipelines: null,因此设施与管线图层在任何模式都处于「未就绪」降级态,cesiumEngine 只有 PIPELINE_SOURCE 常量与查找逻辑,没有创建管线数据源的写入路径。water_source_info / water_plant_info / pump_station(water_supply) / pipe_network_base(network_type='2') / water_user_info,控制器路由为 /waterSupply/gis/map/features(需 waterSupply:gis:map 权限),几何为两点 LineString,且只做非空检查、不做范围与零坐标校核。coordinateValidation 均为 UNVERIFIED / renderable=false,按契约不得上图。这是「没有显示」的一个独立且正确的成因,与图层接线问题必须分开处理。1001,真实管网表 5268 条(成因归后端执行票 20)。modeLayerPlan,并补齐引擎侧管线数据源的写入与渲染路径(含按行业/片区/模式过滤)。浏览器实测:主场景内设施点位与管线按真实几何绘制,切换行业/片区/模式时图层正确显隐;无合法坐标的对象出现在「无地图位置」清单并给出原因;设施总数与后端真实口径一致。
发现于票 18;依赖后端执行票 20(设施映射);坐标校核来源缺失需另行排期。
票面现状事实 2 只看了供水侧,不够。一手核实(后端源码 E:\pipe-ner-server + 真实只读探测):
Cockpit*Controller 无一产出几何;/api/cockpit/v1/map-snapshot 实测返回顶层键为 requestId, apiVersion, readOnly, page, pageSize, snapshotAt, total, batchUpdatedAt, complete, monitoringPoints, unassociatedEquipment, coordinateValidation, mapFilter —— 无设施、无管线。/infrastructure/base-archives 只有聚合统计。WaterSupplyGisMapController 与 gasbasic/GisController,都在 /api/cockpit/v1/** 之外。GET /waterSupply/gis/map/features → HTTP 200 但业务 code=401 认证失败。ADR 0005 明文「免鉴权范围不扩展到后端其他业务路径」,故前端复用它会直接违反鉴权决策。| 行业 | 管线几何 | 构件属性 |
| --- | --- | --- |
| 燃气 | pipe_network_base 每条仅 2 端点直线段 | ✅ gas_pipe_point(经纬度 + pointType=阀门/调压/计量/阴极保护/弯头/三通/其它 + networkId) |
| 供水 | 同为 2 端点直线段(996 条) | ❌ |
| 排水 | 同为 2 端点直线段(3735 条) | ⚠️ drainage.domain.PipeNetworkInfo(管线/管点/排口),未见构件类型 |
| 窨井 | 无管线;ManholeBase 有经纬度 | ❌ |
规模:5268 条(燃气 537 / 供水 996 / 排水 3735),管线总长 67.6 km。管段之间没有共享端点拓扑——「角/支管构件」无法从几何推断,只能用燃气 gas_pipe_point.pointType 的真实属性落位。
| 问题 | 裁定 |
|---|---|
| 几何权威读取路径 | 新开后端驾驶舱几何读模型,不在前端复用业务 GIS 端点 → 已建 票 30,并接为本票 Blocked by: #30 |
| 跨行业覆盖 | 燃气出全套构件(管段 + 阀门/弯头/三通,取自真实 pointType);供水/排水只画真实 2 点直线段;窨井按真实经纬度落点;哪个行业没数据就如实说没数据 |
| 渲染层 | Cesium。实测 src/modules/cockpit 一行 three/Tres 都没有,地图栈 100% Cesium;规模仅数百段,两引擎均无性能压力,而管线贴地与地形/影像/3D Tiles 正确遮挡是 Cesium 原生能力。Three.js 的优势要到上万级管段 + PBR 才兑现,引入却要新建第二个场景与整套相机/地形/拾取对齐层 |
| 建模方式 | 按管点数据程序化生成管线模型,构件分四类:样条管道 / 角管道(弯头)/ 阀门管道 / 支管管道(三通) |
附带发现:ADR 0005 中「Three.js 只在选中的重点管段或构件上增强」在代码里根本没有实现(src/modules/cockpit 零 three/Tres 引用),属纸面设想。选 Cesium 则该 ADR 无需修订。
另一会话正实时编辑 services/cesiumEngine.js 与 domain/overlapDevices.js(内容为重叠聚合标签/光环动效,属票 45/47 域)。故本轮管线图层另起模块(domain/pipeNetwork.js + services/pipeLayerService.js + 引擎侧独立文件),从 MapCanvas.vue 平行挂载,不改 cesiumEngine.js 一个字,也不提交那两个文件。
cb4a5cb)| 文件 | 作用 |
|---|---|
domain/pipeNetwork.js |
纯判定层:契约转换、构件分类、管径→线宽分档、行业筛选、坐标准入 |
services/cesiumPipeLayer.js |
Cesium 渲染层:写 cockpit-pipelines 数据源,管段贴地折线 + 构件符号;upsert 不全量重建 |
services/pipeLayerService.js |
取数:读 /map-facilities(票 30 新建),收成分区 |
stores/pipeNetworkStore.js |
状态:与 mapStore 分开持有,行业切换本地裁剪不重发请求 |
mocks/contractMocks.js |
几何样例:燃气全套构件、供排水直线段、窨井点位,外加三类「不得上图」 |
CockpitShell.vue |
接线:不再传 facilities/pipelines: null;几何随共享分区启动 |
关键实现取舍:数据源名沿用引擎已有的 cockpit-pipelines,于是 cesiumEngine.js 里现成的 pipelineSource(viewer) 直接可用——引擎文件一个字未改,常量值两边一致(等并发会话落地后合并为单一来源)。构件先以可辨识符号 + 中文标签表达,glTF 预制构件实例化需素材库,仓库暂无管线素材,不拿临时符号冒充"已建成的管道模型"。
在 public/cockpit/config.json 临时切到 dataSource: mock(该文件 gitignored,验完已还原为 real),起 yarn dev + 浏览器实测。这只能验证渲染路径与显隐,真实几何仍待票 30。
mock-pipe-layer-rendered.png):橙=燃气、蓝=供水、紫=排水三条管段按真实几何贴地绘制;构件符号各带中文标签——阀门(红)、弯头(黄)、三通(绿)、窨井(灰),以及未建模类型调压(黄,保留后端原文,未被猜成已知类别)。verify/t24-pipe-layer.mjs 16/16 通过:四类构件分类、多段路径保留、未建模类型保留后端原文、三类坐标纪律(未校验/零坐标/缺经度)一律拦下且带中文原因、点数不足不补点、行业筛选、管径分档。verify/t24-pipe-layer-flow.mjs 17/17 通过:mock → 契约 → pipeLayerService → pipeNetworkStore → modeLayerPlan 形状整条链路;空场景、空态、取数失败;设施/管线并入「无地图位置」总览后的徽标与清单自洽;四个一级模式 + 引导态 + 未知模式回落下的管线/设施图层显隐(验收第 2 条中可离线验证的部分已覆盖)。coordinateOverview 扩展后 loaded.total 漏加设施的不可图数(11 ≠ 11+3)。由 G2 的 total === renderable + blocked 不变式当场转红,已修。t46-mode-layer-plan、t04-config、t05-adapter(283)、t07-coordinate(39)、t08-map-summary(44)、t48-real-envelope 全绿。3f12751)补链路回归时发现取数失败会被显示成「这里没有管线」:
pipeNetworkStore 原先在失败时交出空数组 [],而 modeLayerPlan.planNonPointLayers 用 hasArray() 判定就绪——于是几何请求失败(未配地址、端点不存在、后端 500)时,图层状态仍是 ready,界面不会出现「管线数据未就绪」说明。这正是本项目明令禁止的那类谎报(infrastructureApi.js 里已有同一陷阱的注释:「把一次读取失败说成这里本来就没有危险源——那是撒谎」)。
修复:facilities/pipelines 改为取数成功(含真实为空)才交数组,失败或未取过一律交 null,由计划如实降级为 degraded 并给出说明。t24-pipe-layer-flow 的 F9 锁定该行为。
对抗式自查逐项核对验收,发现设施总数口径在三个后端端点间不一致(只读实测 2026-10-12):
| 端点 | totals.facilityCount |
行业拆分 |
|---|---|---|
/infrastructure/base-archives |
5278 | 燃气 537 / 供水 1004 / 排水 3737 / 窨井 0 |
/overview/infrastructure |
5276 | 燃气 537 / 供水 1004 / 排水 3735 / 窨井 0 |
/infrastructure/management-information |
5273 | 片区×行业视图 |
三者各自内部自洽(5278 = 537+1004+3737;5276 = 537+1004+3735),差异收敛到排水 2 条,说明三套服务对同一张 pipe_network_base 各自遍历、各自定口径。
之所以真机上肉眼可见:overviewStore 设计上就把两个端点并成一张卡片(总数与行业构成取 /overview/infrastructure,片区分布取 /infrastructure/base-archives),口径一不一致,同一张卡片上就并列出现「设施总数 5276」与「片区分布 未分区 5278」。
前端没有绕过:任选一个数字显示等于把后端缺陷藏起来,违反本项目「不静默」纪律。故如实立 票 31 并接为本票 Blocked by: #31。
票 30、31 已收口,本轮对齐真实契约后完成真机验收。
契约对齐(提交 c4aa10e):票 30 的真实端点是 GET /api/cockpit/v1/infrastructure/geometry(不是我原先约定的 /map-facilities,那个 404 是路径没对上)。实测真实形状并逐项对齐:
| 差异 | 原约定 | 真实契约 | 处置 |
|---|---|---|---|
| 路径 | /map-facilities |
/infrastructure/geometry |
改常量 |
| feature 判别 | 自定 kind 字段 |
标准 GeoJSON,无 kind |
改按 geometry.type 判;geometry:null 时按 typeCode 判 |
pointType |
中文(阀门/弯头/三通) | 实测英文 valve |
两侧词表都认 |
coverage |
自定 4 行 geometryAvailable |
9 行三态(AVAILABLE/EMPTY/UNAVAILABLE + reason) |
按行归并、缺口如实记 gaps |
| 非法坐标 | 保留几何但 renderable:false |
geometry: null,原值在 sourceCoordinates |
由既有守卫拦下 |
| 新增 reason | — | OUTSIDE_PRIMARY_AREA(后端 8013a207 改为主场景区自动准入) |
已有专属文案 |
真机验收(real 模式,2026-10-12 20:54,浏览器实测):
real-geometry-rendered.png);断言面 data-map-pipes="5268"、data-map-pipe-components="1"。遗留(不阻塞本票收口):
services/mapService.js / components/MapCanvas.vue 两处桥接改动仍未提交——同文件含并发会话的在制品(对方已提交票 25/47 等)。我的桥接经本轮真机验证确实生效(data-map-pipes 就是它写进去的),归属清楚,待对方收工后单独提交。districtApplied:false。mapService.js / MapCanvas.vue 两处桥接。按用户指派认领。本轮先做诊断(范围第 1 项「权威读取路径」是决策点,需 grilling 澄清)。已确认:阻塞项票 20 已关闭 → 本票当前可做;无 needs-triage。并行风险:另一会话正在实时编辑 src/modules/cockpit/services/cesiumEngine.js 与 domain/overlapDevices.js(内容为重叠聚合标签/光环动效,属票 45/47 域),与本票设施/管线图层不重叠,但其未提交改动本轮不碰、不提交。