# 28: 后端执行票 —— 无关联设备监测点被静默丢弃(计数不对称) Type: task Status: ready-for-agent Label: ready-for-agent Category: backend-execution ## 来源 票 18 真实联调实测(2026-10-10 16:15)+ 用户反馈「监测点没有获取到正确的接口,后端一共有六个未关联设备的监测点」。 ## 口径决策(维护者裁定:方案 A,2026-10-10) **采用方案 A**:无关联设备的监测点是**合法监测点**,按其真实 `EMPTY`(无设备)状态**计入总数与状态分布**,不得静默丢弃。 依据:`CONTEXT.md` 的「点位状态」把「无关联设备 / 无设备」列为六个合法状态之一。既然该状态是合法点位状态,无关联设备的点位就不该从统计中消失;否则界面显示「监测点 0 个」是对真实台账的误报。 (未采用的方案 B:按点位自身计 1 记入 `excluded` 新增的「无类型点位」计数,界面仍显示 0 个。裁定为 B 会继续让合法点位不可见,不采纳。) ## 现象 后端确有 **6 个监测点**(`GS001`/`GS002`/`PS001`/`PS002`/`RQ001`/`RQ002`,均 `pointStatus=EMPTY`、`deviceCodes=[]`、无关联设备),但运行监测模式的两个端点都报 0: | 端点 | 监测点数 | | --- | --- | | `GET /map-snapshot` | **6**(正确返回) | | `GET /monitoring/overview` | **0** | | `GET /monitoring/distribution` | **0**(`pagination.total=0`,`pointStatusDistribution.EMPTY=0`) | **静默丢弃**:`excluded` 里 `unknownTypeCount=0`、`typeKindMismatchCount=0`、`invalidCoordinateCount=7`(仅 7 台未关联设备),**6 个监测点既未计入总数,也未计入任何排除计数**,完全消失。 自相矛盾之处:后端自己在 `map-snapshot` 已判定这 6 个点位为 `EMPTY`,而 `monitoring/distribution` 的 `EMPTY` 桶却是 0。 补充事实:这 6 个点位**有真实经纬度**(如 `GS001` 为 `110.399876, 28.458287`),只是缺可信坐标校核来源而 `renderable=false`。因此它们「可统计、暂不上图」是两件独立的事,不应互相阻断。 ## 根因(已定位到行) `CockpitMonitoringDistributionService` 点位循环(约 258–270 行): ```java String mismatch = classify(type); List devices = safeDevices(point.getDevices()); if (mismatch != null) { int amount = devices.size(); // ← 这 6 个点位 devices.size() = 0 if (UNKNOWN_TYPE.equals(mismatch)) { unknownTypeCount += amount; // ← 加 0,等于没记录 } ... continue; // ← 被丢弃 } ``` 这 6 个点位无关联设备,`typeCode` 不可推导而 `mismatch != null`,于是进入排除分支;**但排除计数按「设备数」累加,而它们设备数为 0**,所以既没进 marker 列表,也没进任何 excluded 桶。 对比同文件设备循环(约 326–334 行):设备走同样分支时是 `unknownTypeCount += 1`(按设备自身计 1)。**点位按设备数计、设备按自身计,两侧口径不对称**,无设备点位因此被抹掉。 连锁效应:`hasResolved = !deviceCodes.isEmpty()`(约 444 行),而 `deviceCodes` 只在坐标校验通过后收集;坐标未校验 → `freshness=EMPTY / NO_RESOLVED_DEVICES`,把「设备坐标未校验」误报成「无设备」。 适配器层(`BusinessCockpitMonitoringDistributionAdapter`)**正确**构建了这 6 个点位,丢失发生在 Service 层。 ## 范围 1. **按方案 A 落实口径**:无关联设备的点位按 `EMPTY` 计入 `monitoring/distribution` 的状态分布与 `pagination.total`;不得因设备数为 0 而丢弃。 2. 坐标未校验与「无设备」是两件事:**统计不因坐标未校验而排除**,只是不上图。坐标校验只作用于「能否上图」,不得影响「是否计入统计」。 3. 修正排除计数口径:点位按点位本身计(或显式区分「无类型点位」计数),消除点位/设备两侧不对称。 4. 修正 `hasResolved` / `NO_RESOLVED_DEVICES` 语义:区分「确实无设备」与「设备坐标未校验」。 5. `monitoring/overview` 的 `monitoringPointCount` 同源核对:修复后应与 `map-snapshot` 的监测点数一致(6)。 6. 补契约测试:无关联设备点位必须可见(计入 `EMPTY` 桶),且统计不受坐标未校验影响。 ## 验收 真实环境复验:`monitoring/overview` 的 `monitoringPointCount` = 6 且与 `map-snapshot` 一致;`monitoring/distribution` 的 `EMPTY` 桶 = 6、`pagination.total` ≥ 6;`excluded` 各计数之和与「总数 − 纳入数」可对账(6 个点位不再凭空消失);`NO_RESOLVED_DEVICES` 不再误报。编译 + `Cockpit*Test` 全绿 + 提交推送。 ## 关联 发现于票 18;与 [票 20](20-20-0-1.md)(管网编码漏计)同族——均为「未分类对象被静默丢弃而非如实计数」。坐标未校验导致的不可上图属另一问题,归 [票 24](24-24.md)。