# 20: 后端执行票 —— 管网编码 0/1 映射与设备边界设施类型命名空间 Type: task Status: claimed Label: ready-for-agent Category: backend-execution ## 来源 票 18 真实数据口径核对(2026-10-10),并由真人走查第 4 项佐证(界面设施总数 1001,实际 5268)。 ## 状态 **已认领(2026-10-10),诊断中**。阻塞依赖无(票 12/13 已 resolved,后端契约基座就绪)。 诊断手段:只读源码核实(`E:\pipe-ner-server` @ `origin/master`)+ 真实库只读探针(凭据经环境变量注入,探针放 `%TEMP%` 用完即删)+ 联调环境 `http://192.168.110.96:8301` 实测。 ## 现象 1. **管网数字编码漏计**:业务 GIS 既有规则为 `pipe_network_base.network_type` `0=燃气 / 1=排水 / 2=供水`(见 `zksy-admin` 的 GIS 控制器)。但基础档案、管理信息、运行信息、总体概览四个适配器只兼容 `2=供水`、`3=燃气` 与行业文字,`0`/`1` 被直接跳过。真实分组 `0=537、1=3735、2=996` → **4272 条管网未进入任何正式统计**。因过滤发生在适配器内,响应 `excluded=0` 不能作为完整性证据。 2. **设施类型命名空间误用**:设备边界只用 `equipment_type`(监测设备类型)建字典,却用同一编码去解释设施 `network_type`,导致真实 3735 条排水设施被标为「供水设备 / WATER_SUPPLY」、996 条供水设施被标为「排水设备 / DRAINAGE」。 3. **概览强制置空**:`overview/infrastructure` 把所有管网设施行业置 `null`,正式行业统计只得到 `8`(水厂 3 + 供水泵站 5),`excluded.unknownTypeCount=5268`。 ## 诊断(2026-10-10) 诊断手段:只读源码核实 + 真实库只读探针(凭据走环境变量、探针放 `%TEMP%` 用完即删)。 ### 后端基线 | 项 | 值 | | --- | --- | | 仓库 / 分支 / 提交 | `origin/master` / `master` / `d8a6b03`(票 13 收口后的基线) | | 联调环境 | `http://192.168.110.96:8301` 可达 | ### 数据事实(真实库实测) | 项 | 实测值 | | --- | --- | | `pipe_network_base.network_type` 分布 | `0`=537、`1`=3735、`2`=996,**总数 5268**(与票面声称一致) | | 权威编码规则 | `GisController.getPipeLines` L43 注释与分支:**`0`=燃气、`1`=排水、`2`=供水**(另兼容 `gas/drainage/water` 等历史串) | | `equipment_type` 主键命名空间 | id=`1`→**供水设备**、id=`2`→**排水设备**、id=`3`→燃气设备(parent 均为 0) | | `network_type="3"` 实际存在? | **不存在**(分布仅 `0/1/2`);且生产代码无任何 `setNetworkType` 写入路径 | ### 现象逐条核实(票面三个现象均成立) **现象 1 — 管网数字编码漏计(4272 条丢失)**:三处**各自复制**的映射函数都只认 `2`/`3` 与中文串,遇到 `0`/`1` 返回 `null`,调用方随即 `continue` 静默丢弃: | 位置 | 函数 | 缺 `0`/`1` 的后果 | | --- | --- | --- | | `BusinessCockpitInfrastructureBaseArchivesAdapter.pipeType` L149 | 返回 `WATER_PIPE`/`GAS_PIPE`/`DRAINAGE_PIPE` | `addPipes` L123 `typeCode==null` → `continue`,5268 条只剩 996 条进入响应 | | `BusinessCockpitInfrastructureManagementInformationAdapter.pipeIndustry` L154 | 返回行业码 | 4272 条 `industry=null` | | `BusinessCockpitInfrastructureOperatingInformationAdapter.pipeIndustry` L191 | 返回行业码 | 4272 条 `industry=null` | 三份逻辑重复且同源同错——这正是「单一权威来源」要消除的对象。 **现象 2 — 命名空间碰撞(类型名与行业系统性错位)**:`BusinessCockpitDeviceBoundaryAdapter` L85 把**原始 `network_type`** 当作设施类型码上报,服务层 `mapFacility` L78 用 `types.get(...)` 去查 **`equipment_type` 字典**。两套编码数值域重叠而语义不同,于是: | `network_type` | 真实含义 | 误查 `equipment_type` | 对外结果 | | --- | --- | --- | --- | | `1` | 排水(**3735 条**) | id=1 = 供水设备 | 被标「供水设备 / WATER_SUPPLY」 | | `2` | 供水(**996 条**) | id=2 = 排水设备 | 被标「排水设备 / DRAINAGE」 | | `0` | 燃气(537 条) | 无 id=0 | 类型解析失败 → `UNKNOWN_TYPE` | 适配器类注释 L29-30 声称「管网设施 `network_type` 是自由文本、与 `equipment_type.id` 无对应关系」——**该前提为假**:它不是自由文本,而是有权威编码的字段;「无对应关系」被误实现为「透传原始码」,结果不是隔离而是碰撞。 **现象 3 — 概览强制置空**:`BusinessCockpitOverviewInfrastructureAdapter` L123 构造设施 `SourceType(code, name, industry, drainageScope, objectKind)` 时传 `industry=null, drainageScope=null`,5268 条管网全部落入非正式范围,正式行业统计只剩水厂 3 + 泵站 5。 ### 修复方向(单一权威来源) 新增单源持有**管网命名空间**的类型码 / 中文名 / 行业,四处适配器共用;设备边界的设施类型改用该命名空间(不再借用 `equipment_type` 主键),未识别值仍显式 `null` 计入 `UNKNOWN_TYPE`,不静默丢弃。 ## 待裁定问题 1. **设备边界的设施类型身份如何表示**(命名空间如何隔离)。 2. **旧映射 `"3"`→燃气 如何处置**(真实库无此值,且它与 `equipment_type.id=3=燃气设备` 高度疑似同源混淆产物)。 ## 范围 1. 建立管网设施类型与行业的**单一权威来源**,与既有 GIS 规则一致,覆盖 `0/1/2` 与历史字符串。 2. 修正基础档案、管理信息、运行信息、总体概览四个适配器的映射与行业归属,不再静默 `continue`。 3. 修正设备边界的设施类型解析:设施不得借用监测设备类型字典。 4. 保留口径差异说明:`base-archives`(水厂/泵站/管网/排水工程设施)与 `management`(窨井/管网/水源地)本属不同对象域,但两者都必须包含全部管网。 5. 补契约测试:四行业管网各自计数正确、`0/1/2` 不再丢失、跨端点管网总量一致。 ## 验收 真实环境复验:`base-archives` 管网计数应覆盖 `537+3735+996`;概览不再把管网整体排除;设备边界设施类型名称与行业正确。编译 + `Cockpit*Test` 全绿 + 提交推送 + 基线卡片更新。 ## 关联 发现于票 18;与票 25 后端契约缺口台账同源,需回写。 ## 进度 Status: ready-for-agent Type: task Blocked by: Labels: ready-for-agent, backend-execution, wayfinder:task ## Comments ## Answer