|
@@ -0,0 +1,294 @@
|
|
|
|
|
+<!-- DSH-IDEMPOTENCY-KEY: scope-industry-filter-coverage-v1 -->
|
|
|
|
|
+<!-- parentKey: 00 -->
|
|
|
|
|
+<!-- created: 2026-10-19T06:05:37.799Z -->
|
|
|
|
|
+# 前端执行票 —— 「当前范围」与「行业」筛选生效面审计与补齐(事件族仅预警分析收 district;管线片区由编码前缀推导)
|
|
|
|
|
+
|
|
|
|
|
+## Question
|
|
|
|
|
+
|
|
|
|
|
+维护者 2026-10-19 反馈第 8 条:上方菜单栏「当前范围」(全部/城南/城北/太常/未分区)**没有影响到场景及物体的筛选及部分 UI 中的信息筛选**;行业也需一并检查。
|
|
|
|
|
+
|
|
|
|
|
+**核查结论(2026-10-19 读代码 + 只读接口):部分真实缺陷,需按接缝逐条补齐。** 已接线与未接线的现状:
|
|
|
|
|
+
|
|
|
|
|
+**行业(较完整,存在 1 处缺口)**
|
|
|
|
|
+- 已接线:`map-snapshot`(`services/mapApi.js`)、基础设施(`infrastructureApi`)、概览(`overviewApi`)、监测(`monitoringApi`)、事件(`eventApi`/`warningResponseApi`)、管线图层(`pipeNetworkStore.setIndustry`)。
|
|
|
|
|
+- 缺口:**管线几何只吃行业、不吃片区**(`domain/pipeNetwork.js` 第 288 行 `districtApplied: false`,且注释说明「片区只筛设施点位与统计」)。这是仓内**已知并已如实标注**的边界,不是静默漏筛。
|
|
|
|
|
+
|
|
|
|
|
+**片区(缺口较多)**
|
|
|
|
|
+- 已接线:`map-snapshot`、基础设施、概览、监测分布。
|
|
|
|
|
+- **缺口 1(严重)**:事件族**完全没有 district 入参**——`services/eventApi.js` 的 `fetchCurrentEvents` 无 `district`;`services/warningResponseApi.js` 的 `rangeParams` 也无 `district`。后端 `filters.district` 字段存在(实测响应里有),但前端从不传。
|
|
|
|
|
+- **缺口 2**:`CockpitShell.vue` 的 `watch(scope)`(第 1804-1810 行)只重载 `infrastructureStore`/`overviewStore`/`monitoringStore` + `refreshMapForFilters`,**不重载 `eventStore`**——切片区后预警处置四块面板完全不刷新。
|
|
|
|
|
+- **缺口 3**:管线几何与构件图层不随片区变化(同上 `districtApplied:false`)。
|
|
|
|
|
+- **缺口 4**:`overviewStore.loadPanels({ scope })` 实际只覆盖部分面板(代码注释「概览只有运行监测那块收行业入参(另两块不收)」),需核实片区是否同样只覆盖一块。
|
|
|
|
|
+
|
|
|
|
|
+## Acceptance
|
|
|
|
|
+
|
|
|
|
|
+- **先做完整审计再改**:逐面板列出「当前范围/行业」是否进入请求参数、是否进入本地图层筛选,产出对照表写进票面(含后端是否支持该参数)。后端不支持的参数**不得前端伪造筛选**,也不得静默忽略——要在界面如实说明。
|
|
|
|
|
+- 补齐事件族的片区入参(后端 `filters.district` 已存在);`watch(scope)` 补 `eventStore` 重载并回第 1 页。
|
|
|
|
|
+- 管线/构件图层的片区能力:若后端几何接口支持 district → 接线;不支持 → 沿用 `districtApplied:false` 的**如实说明**并记录后端契约缺口(另开后端票,不在本票伪造)。
|
|
|
|
|
+- 审计结论若发现某面板「片区/行业」本就不适用(如纯聚合口径),在票面登记理由,**不强行加筛选**。
|
|
|
|
|
+- 补充闸门:筛选参数进查询串可断言;切范围/行业后受影响的 store 都有重载;未接线的面板有可见说明。
|
|
|
|
|
+- 闸门 + 变异打红;按 AGENTS.md 跳过 build/dev/浏览器验证。
|
|
|
|
|
+
|
|
|
|
|
+## Context
|
|
|
|
|
+
|
|
|
|
|
+- 代码:`CockpitShell.vue`(`watch(scope)`/`watch(industry)`/`refreshMapForFilters`)、`services/eventApi.js`、`services/warningResponseApi.js`、`stores/eventStore.js`、`domain/pipeNetwork.js`(`districtApplied`)、`stores/pipeNetworkStore.js`、各 `*Api.js`。
|
|
|
|
|
+- 既有裁定:票 18/20(窨井作为第四行业接线)、票 24(管线几何图层)、票 37(deviceType 全局筛选)。
|
|
|
|
|
+- 后端只读接口:`http://192.168.110.96:8301/api/cockpit/v1/**`,`filters.district` 字段已在响应中,可作联调依据。
|
|
|
|
|
+
|
|
|
|
|
+## Related spec
|
|
|
|
|
+
|
|
|
|
|
+[`../specs/2026-10-18-global-list-pagination.md`](../specs/2026-10-18-global-list-pagination.md)(本票不涉分页,属同批维护者反馈)
|
|
|
|
|
+
|
|
|
|
|
+## 进度
|
|
|
|
|
+
|
|
|
|
|
+<!-- 做到哪一步了,在这里一行一行记 -->
|
|
|
|
|
+
|
|
|
|
|
+- [x] 认领(Assignees: agent;阻塞票 #59 已关闭,本票处于 frontier)+ 读全(正文 / 评论(空)/ 标签 wayfinder:task / 父 00 / 阻塞边 #59)
|
|
|
|
|
+- [x] 先查后做:**逐端点实测**代替读代码猜测(见下方对照表;探针脚本与载荷落盘 `verify/artifacts/t67/`)
|
|
|
|
|
+- [x] 审计对照表成稿(本票正文下方),并据它纠正票面两条前提(见 Answer「票面前提的两处纠正」)
|
|
|
|
|
+- [x] 实施:预警分析接片区;`watch(scope)` 补 `eventStore` 重载并回第 1 页;未接线面板补可见口径说明;管线图层的片区落点上屏
|
|
|
|
|
+- [x] 新增闸门 [t67-filter-caliber.mjs](../verify/t67-filter-caliber.mjs) **77/77** + 变异 [t67-mutations.mjs](../verify/t67-mutations.mjs) **14/14** 打红并按字节还原
|
|
|
|
|
+- [x] 实施期间并行在制的票 05–08 落地了概览四端点重做(旧三端点退役)⇒ 复查并更新:概览四块的口径说明改按**规格 §1「四端点不收入参」**书写(新端点在本机后端实测 404、无实测定性),审计表与结论同步改写,闸门 A7/A8 改钉新导出
|
|
|
|
|
+- [x] 回归:t61 39 / t65b 14 / t66 22 / t68 17 / t62 51 / t63 23 / t64 61 / t75 18 / t39 24 / t40 17 / t43 23 / t46 54 / t48 33 / t50 15 / t51 20 / t54 24 / t55 5 / t59 37 / t60 42 / t27 8 / t16 / t45 35 / t13 50 / t14-event-detail 44 / t09 38 全绿;更正后补验管线相关:t24-pipe-layer 18 / t24-pipe-layer-flow 17 / t48-pipe-color-legend 33 / t22-pipeline-rendering 12 全绿
|
|
|
|
|
+- [x] 后端契约缺口另立 [票 77](77-untitled.md)(本票不伪造筛选)
|
|
|
|
|
+- [x] **2026-10-23 维护者更正:管线有片区可分**(编码 = 片区+行业+时间编码)⇒ 重开重做 §十:`pipeNetwork.js` 按编码前缀推导片区、图层真按片区裁剪、说明改口;E 组 18 项重写、变异 14 条(新增前缀错位/推不出对象被静默保留两条)
|
|
|
|
|
+- [x] 真实载荷复核(`geom-none.json`):6762 条前缀推导与 `name` 片区词 **100% 一致零反例**;燃气∩太常 586 = 编码 (TC,RQ) 计数 586(三路交叉);现网无 CB/城北
|
|
|
|
|
+- [x] **2026-10-23 真机复验失败排查**:根因=dev server 转译缓存给浏览器发了**旧版** `pipeNetworkStore`(无 `setScope`)→ `watch(scope)` 第 5 步抛错 → 后面的 `refreshMapForFilters` 永不执行(面板刷了、一张图不刷);处置=touch 模块强制重转译,复验点击后 `map-snapshot?...&district=0` 且场景计数真的变(§十一)
|
|
|
|
|
+- [x] 顺带修 `domain/deviceMetricSources.js` 的 `deviceMetricKind(null)` 崩溃(档案分区 EMPTY 时打断设备详情聚合,真机控制台反复出现)
|
|
|
|
|
+- [x] 收口(本票 resolved)
|
|
|
|
|
+
|
|
|
|
|
+Status: resolved
|
|
|
|
|
+Assignees: agent
|
|
|
|
|
+Type: task
|
|
|
|
|
+Blocked by: #59(已关闭)
|
|
|
|
|
+Labels: wayfinder:task
|
|
|
|
|
+
|
|
|
|
|
+## Comments
|
|
|
|
|
+
|
|
|
|
|
+### local — 2026-10-22 开工与调查说明
|
|
|
|
|
+
|
|
|
|
|
+**已查阅范围(一句话结论 / 路径)**
|
|
|
|
|
+- 本票正文 / 评论(空)/ 标签 wayfinder:task / 父图 00 / 阻塞边 #59(已关闭)⇒ **无 needs-triage**,按执行票推进。
|
|
|
|
|
+- 代码:CockpitShell.vue(`watch(scope)`/`watch(industry)`/`refreshMapForFilters`/`panelViewOf`)、domain/{pipeNetwork, panelViews, panelCatalog, filterOptions, eventList, warningResponsePanels, monitoringPanels, infrastructurePanels, overviewPanels}.js、services/{mapApi, infrastructureApi, monitoringApi, overviewApi, eventApi, warningResponseApi, pipeLayerService}.js、stores/{eventStore, infrastructureStore, monitoringStore, overviewStore, pipeNetworkStore, mapStore}.js。
|
|
|
|
|
+- 既有裁定:票 12(district 契约)、票 24(几何图层)、票 37(deviceType 全局筛选)、票 56/64(面板口径说明的折叠摘要接缝与 `data-*` 断言面)、票 61/62(页码条件键纪律)、票 63/65(下属面板与工单端点)。
|
|
|
|
|
+- 仓内既有笔记够不够用:**不够**——票面记的「后端 `filters.district` 字段存在(实测响应里有)」只对**一个**端点成立,其余端点收不收这个参数必须**逐端点实测**才能定;仓内没有这份逐端点台账。因此按 `/research` 的替代做法做了**只读探针实测**(不查外网,查的是本仓自己的后端),脚本与原始载荷落盘 `verify/artifacts/t67/`,结论回填本票。
|
|
|
|
|
+
|
|
|
|
|
+**探针方法与判据(避免"看起来筛了"的假绿)**
|
|
|
|
|
+- 判据一:非法值 `district=99` / `industry=NOT_A_REAL_INDUSTRY` 是否 **400**(说明后端真的读并校验该参数)。
|
|
|
|
|
+- 判据二:`district=0` 与 `district=1` 的响应**逐字段比对**是否真的不同(排除 `requestId`/`updatedAt`/`serverUpdatedAt`/`range.start|end`/`freshness.ageSeconds` 这类随挂钟变的字段)。
|
|
|
|
|
+- 只凭"响应里有 filters 字段"会判错:`/events/current` 的 `filters` 只有 `{mode, level, industry, status}`,根本没有片区;而 `/events/multidimensional-analysis` 的 `filters` 里有 `district` / `districtName` 且真的过滤。
|
|
|
|
|
+
|
|
|
|
|
+收口见 ## Answer。
|
|
|
|
|
+
|
|
|
|
|
+## Answer
|
|
|
|
|
+
|
|
|
|
|
+**已实施并关闭(2026-10-22;2026-10-23 按维护者更正重做管线片区,见 §十)。按 AGENTS.md 跳过 build/dev/preview 与浏览器验证。**
|
|
|
|
|
+
|
|
|
|
|
+### 一、审计对照表(本票的第一交付物)
|
|
|
|
|
+
|
|
|
|
|
+判据见上(400 + 逐字段比对)。"前端现状"= 本票开工前的代码实际行为。
|
|
|
|
|
+
|
|
|
|
|
+| 面板 / 图层 | panelId | 数据端点 | **片区** 后端 | **片区** 前端 | **行业** 后端 | **行业** 前端 |
|
|
|
|
|
+|---|---|---|---|---|---|---|
|
|
|
|
|
+| 一张图·监测点 | — | `/map-snapshot` | ✅ 收且过滤 | ✅ 已接(`refreshMapForFilters`) | ✅ | ✅ |
|
|
|
|
|
+| 管线 / 构件几何 | — | `/infrastructure/geometry` | ⚠️ 端点不收,但**编码前缀里有片区**(片区+行业+时间编码) | ✅ **本地按编码前缀裁剪**(§十 更正) | ❌ 不收(**properties 有 industry**) | ✅ 本地裁剪 |
|
|
|
|
|
+| 基础设施·基础档案 | `archive` | `/infrastructure/base-archives` | ✅ | ✅ | ✅ | ✅ |
|
|
|
|
|
+| 基础设施·运行信息 | `operation` | `/infrastructure/operating-information` | ❌ 忽略 | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 基础设施·管理信息 | `management` | `/infrastructure/management-information` | ✅ | ✅ | ✅ | ✅ |
|
|
|
|
|
+| 基础设施·应急保障 | `emergency` | `/infrastructure/emergency-support` | ❌ 忽略 | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 运行监测·监测概览 | `monitoringOverview` | `/monitoring/overview` | ❌ 忽略 | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 运行监测·监测分布 | `monitoringDistribution` | `/monitoring/distribution` | ✅ | ✅ | ✅ | ✅ |
|
|
|
|
|
+| 运行监测·运行概况 | `operationOverview` | `/monitoring/situation` | ❌ 忽略 | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 运行监测·点位台账 | `monitoringPointLedger` | 同上(共用一次取数) | ✅ | ✅ | ✅ | ✅ |
|
|
|
|
|
+| 预警处置·当前预警 | `currentEvents` | `/events/current` | ❌ **忽略** | ❌(且旧版整条旁路) | ✅ | ✅ |
|
|
|
|
|
+| 预警处置·历史分析 | `historyAnalysis` | `/events/history-analysis` | ❌ **忽略** | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 预警处置·预警效率 | `responseEfficiency` | `/events/handling-efficiency` | ❌ **忽略** | ❌ | ✅ | ✅ |
|
|
|
|
|
+| 预警处置·当前工单列表 | 块 | `/work-orders` | ❌ 忽略 | ❌ | ❌ **忽略** | ❌ |
|
|
|
|
|
+| 预警处置·预警分析 | `eventAnalysis` | `/events/multidimensional-analysis` | ✅ **收且过滤** | ❌ **本票补上** | ✅ | ✅ |
|
|
|
|
|
+| 概览·感知设备 | `perceptionDevices` | `/overview/perception` | ❌ 不收入参(规格) | ❌ | ❌ 不收入参(规格) | ❌ |
|
|
|
|
|
+| 概览·基础设施 | `pipeNetwork` | `/overview/pipe-network` | ❌ 不收入参(规格) | ❌ | ❌ 不收入参(规格) | ❌ |
|
|
|
|
|
+| 概览·预警研判 | `warningStudy` | `/overview/warning-study` | ❌ 不收入参(规格) | ❌ | ❌ 不收入参(规格) | ❌ |
|
|
|
|
|
+| 概览·报警处置 | `alarmDisposal` | `/overview/alarm-disposal` | ❌ 不收入参(规格) | ❌ | ❌ 不收入参(规格) | ❌ |
|
|
|
|
|
+
|
|
|
|
|
+> **概览四块这一栏的依据强度与别处不同,如实标出来**:票 05–08(并行在制)在本票实施期间把概览数据源从旧三端点(`/overview/infrastructure`、`/overview/monitoring`、`/overview/warning-settings`)换成了四个新端点,而这四个新端点**在本机后端尚未部署(实测一律 404)**,没法用"非法值 400 / 0-1 响应不同"那套判据。所以它们的"不收入参"依据是**前端实现 + 规格 §1**,不是实测。旧三端点时期是实测过的(`/overview/infrastructure` 任何入参都不变、`/overview/monitoring` 收行业、`/overview/warning-settings` 只收窗口)。端点上线后按 `verify/artifacts/t67/` 复跑升级证据,登记在票 77。
|
|
|
|
|
+
|
|
|
|
|
+**行业面结论:前端已经接满"后端收"的全部端点**(原始审计里"行业较完整、存在 1 处缺口"成立,且那 1 处 = 管线片区,不是行业)。行业缺口只有**后端不收**的四处,本票不伪造、能上屏的都已说明:`/work-orders`(实测不认行业 → 工单列表页脚说明)、概览四块(四个端点不收入参 → 四块面板各一句口径说明);另两处(旧 `/overview/infrastructure`、`/overview/warning-settings`)随概览重做已退役,其继任者归票 77 复核。
|
|
|
|
|
+
|
|
|
|
|
+**片区面结论:不是前端漏接,而是后端覆盖参差**——真收片区的只有 5 个端点(`map-snapshot`、`base-archives`、`management-information`、`monitoring-distribution`、`multidimensional-analysis`),其余 7 个事件/监测端点**完全不认**该参数,概览四块则是端点根本不收入参。
|
|
|
|
|
+
|
|
|
|
|
+**唯一的例外是管线几何**:端点也不收片区,但片区信息**在设施编码里**(片区+行业+时间编码),所以前端能按编码前缀本地裁剪 —— 这条本票起初判错(只看 properties 有没有片区字段),由维护者 2026-10-23 更正,见 §十。
|
|
|
|
|
+
|
|
|
|
|
+### 二、票面前提的两处纠正(实测推翻,写进票面以免后人沿错路)
|
|
|
|
|
+
|
|
|
|
|
+1. **"事件族完全没有 district 入参,后端 `filters.district` 字段存在"** —— 只对**预警分析**那一个端点成立。`/events/current`、`/events/history-analysis`、`/events/handling-efficiency` 实测**不读**该参数(非法值照 200、0/1 响应逐字节相同,响应 `filters` 里也没有片区字段)。所以"补齐事件族片区入参"不可能靠前端补齐,只能:**把真收的那一块接上**(预警分析),其余**如实说明 + 开后端票**(票 77)。
|
|
|
|
|
+2. **"管线/构件图层沿用 `districtApplied:false` 的如实说明"** —— 那句话此前**只写在注释里**:`districtApplied` 全仓只有 3 处引用(领域函数、store 的 EMPTY 常量、注释),**没有任何界面消费点**。也就是说用户从来没看到过这条"如实说明"。本票把它做成真的可见说明(见下)。
|
|
|
|
|
+
|
|
|
|
|
+### 三、改动(5 个源文件 + 2 个组件)
|
|
|
|
|
+
|
|
|
|
|
+| 文件 | 改动 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| [domain/filterCaliber.js](../../../src/modules/cockpit/domain/filterCaliber.js) **新增** | 筛选生效面的**单一措辞来源**:`SCOPE_FILTER_LABEL`/`INDUSTRY_FILTER_LABEL`、`DISTRICT_GAPS`(11 块)、`INDUSTRY_GAPS`(5 处:工单列表 + 概览四块)、`districtGap()`/`industryGap()`、`PIPE_DISTRICT_NOTE`、`withFilterCaliber()`。文件头把逐端点实测结论写死,便于下次复用 |
|
|
|
|
|
+| [domain/panelViews.js](../../../src/modules/cockpit/domain/panelViews.js) | `panelView()` 出口统一 `withFilterCaliber(...)` —— 口径说明挂在**注册表这一处**,面板新增/改名不会漏(也省掉 11 处重复代码) |
|
|
|
|
|
+| [services/warningResponseApi.js](../../../src/modules/cockpit/services/warningResponseApi.js) | `fetchAggregated` 增 `hooks.acceptsDistrict`;**只有** `fetchEventAnalysis` 打开。多窗(90 天)路径的每个窗都带 |
|
|
|
|
|
+| [stores/eventStore.js](../../../src/modules/cockpit/stores/eventStore.js) | `CONDITION_KEYS` 与 `conditionSnapshot()` 补 `scope` ⇒ 换片区时三个页码一起回第 1 页,定时刷新不复位 |
|
|
|
|
|
+| [CockpitShell.vue](../../../src/modules/cockpit/CockpitShell.vue) | ① `watch(scope)` 补 `eventStore.loadPanels({ mode, scope })`;② `refreshCurrentModePanels()` 的预警处置分支补 `scope`;③ 状态详情里新增 `data-pipe-district-note`(渲染 `PIPE_DISTRICT_NOTE`) |
|
|
|
|
|
+| [domain/eventList.js](../../../src/modules/cockpit/domain/eventList.js) | `currentEventsView()` 增 `gap`(当前预警不在 panelViews 注册表里,走自己的视图) |
|
|
|
|
|
+| [components/EventListPane.vue](../../../src/modules/cockpit/components/EventListPane.vue) | 渲染 `data-panel-gap`(与 PanelBlocks 同一个断言钩子) |
|
|
|
|
|
+| [domain/warningResponsePanels.js](../../../src/modules/cockpit/domain/warningResponsePanels.js) | 工单列表块的 `pageNote` 追加行业缺口句(`industryGap('workOrderList')`) |
|
|
|
|
|
+| [domain/pipeNetwork.js](../../../src/modules/cockpit/domain/pipeNetwork.js) **§十 更正** | 新增 `PIPE_DISTRICT_PREFIX`(CN=0 城南 / CB=1 城北 / TC=2 太常)与 `pipeDistrictOf()`;`toPipeNetwork()` 每条对象带 `district`;`filterPipeNetwork()` 吃 `filters.scope`,返回 `districtApplied`(全域 false)与 `districtUnresolvedCount`(编码推不出片区、被排除的可上图对象数) |
|
|
|
|
|
+| [stores/pipeNetworkStore.js](../../../src/modules/cockpit/stores/pipeNetworkStore.js) **§十 更正** | 新增 `scope` 状态与 `setScope()`;`filtered` 同时吃行业与片区;`load()` 收 `scope` |
|
|
|
|
|
+
|
|
|
|
|
+**没改**:`mapStore`/`monitoringStore`/`infrastructureStore`/`overviewStore`(片区接线原本就通);任何后端代码;`pipeLayerService.js`(几何仍是一次全量取回,片区在本地裁剪 —— 与行业同一条纪律)。
|
|
|
|
|
+
|
|
|
|
|
+### 四、用户实际看到的两句话(折叠摘要里)
|
|
|
|
|
+
|
|
|
|
|
+**每块"不随当前范围变"的面板**(11 块,措辞按端点分化,例如当前预警):
|
|
|
|
|
+
|
|
|
|
|
+> 「当前范围」不作用于本面板:后端该端点未提供片区入参(当前事件端点实测下发该参数也不生效),本表始终列出全部片区
|
|
|
|
|
+
|
|
|
|
|
+**一张图的状态详情里**(管线/构件,§十 更正后的措辞):
|
|
|
|
|
+
|
|
|
|
|
+> 「当前范围」按设施编码规则(片区 + 行业 + 时间编码)作用到管线与构件图层:几何数据本身没有片区字段,片区是从编码前缀推出来的;编码推不出片区的对象(阀门、窨井等少量构件)在按片区查看时不显示,选「未分区」才看得到它们
|
|
|
|
|
+
|
|
|
|
|
+**概览四块**(同样在折叠摘要里,凭据是规格而非实测,见上表注):
|
|
|
|
|
+
|
|
|
|
|
+> 「当前范围」不作用于本面板:概览四块的数据端点按规格不收入参(不收片区),本面板读数始终为全域
|
|
|
|
|
+>
|
|
|
|
|
+> 「行业」不作用于本面板:概览四块的数据端点按规格不收入参,本面板读数始终为全部行业
|
|
|
|
|
+
|
|
|
|
|
+**报警效率的工单列表**(页脚口径行):
|
|
|
|
|
+
|
|
|
|
|
+> 「行业」不作用于本工单列表:后端工单端点未提供行业入参,列表始终列出全部行业的工单(上方分布仍按行业统计)
|
|
|
|
|
+
|
|
|
|
|
+### 五、验收自查(对抗式,逐条对 Acceptance)
|
|
|
|
|
+
|
|
|
|
|
+1. ✅ **先做完整审计再改,产出对照表(含后端是否支持)** —— 见上方第一张表;支撑证据是**逐端点实测**(不是读代码猜),脚本 `probe-district.sh` / `probe-geometry-and-industry.sh` / `diff-district.py` 与全部原始载荷在 `verify/artifacts/t67/`,可原样复跑。
|
|
|
|
|
+2. ✅ **补齐事件族片区入参(后端已存在的那处)** —— 预警分析接上 `district`(A1/A2/A3 逐片区取值 + 全域不传 + 90 天多窗每窗都带);**三个不认该参数的端点一个都不传**(A4/F1 反向钉住)。这是票面前提被实测纠正后的诚实版本:能接的接上,接不了的不伪造。
|
|
|
|
|
+3. ✅ **`watch(scope)` 补 `eventStore` 重载并回第 1 页** —— C1(源码接线)+ B2(行为:三个页码都回 1,且请求带新片区);B3 钉住"同条件重取不复位"(条文 6 的反面,别把定时刷新也复位)。
|
|
|
|
|
+4. ✅ **管线/构件的片区能力** —— **本票起初判错、已按维护者更正重做(§十)**:几何 properties 确实没有片区字段(R3 用落盘载荷复算 6766 feature 证实),但设施编码是「片区+行业+时间编码」,片区**能推出来** ⇒ 改为本地按编码前缀裁剪(E 组逐条钉住:推导与名称 100% 一致、四个片区取值、推不出片区的对象如实计数、行业×片区正交)。说明同步改口(不再是「不作用于」)。
|
|
|
|
|
+5. ✅ **本就不适用的面板登记理由、不强行加筛选** —— 概览四块登记片区 + 行业两条缺口说明,**依据强度单独标注**(四个新端点在本机后端未部署、实测 404 ⇒ 依据是规格 §1 与前端实现,不是实测;见上表注与 `verify/artifacts/t67/overview-endpoints-not-deployed.md`)。纯聚合口径的面板(监测分布的状态饼图是全局未筛口径)保持原样,未强加筛选。
|
|
|
|
|
+6. ✅ **补充闸门三条** —— ① 参数进查询串可断言:A 组 9 项(含"该带的带上"与"不该带的不许带"两个方向);② 切范围/行业后受影响的 store 都有重载:B 组行为 + C 组外壳接线;③ 未接线的面板有可见说明:D 组 38 项(逐块 + 全注册表正向普查 + 反向普查 + SSR 真的进 DOM)。
|
|
|
|
|
+7. ✅ **闸门 + 变异打红** —— t67 **77/77**;变异 **14/14**(M1 分析丢 district、M2 当前事件伪造 district、M3 scope 不进条件键、M4 watch 丢 eventStore、M5/M11 删缺口、M6 缺口里塞接口字段名、**M7 片区恒不生效、M8 管线说明写回「不作用于」、M13 编码前缀映射错位、M14 推不出片区的对象被静默保留**、M9 刷新漏传 scope、M10 删工单行业缺口、M12 注册表绕过口径出口),每条点名打红指定断言并按字节还原。
|
|
|
|
|
+
|
|
|
|
|
+### 六、闸门设计里两条值得记住的判据
|
|
|
|
|
+
|
|
|
|
|
+- **"响应里有 filters 字段"不是证据,非法值 400 才是**:`/events/current` 的 `filters` 里压根没有片区字段,而票面当初就是被"实测响应里有 district"误导成"后端都支持"。闸门 R 组因此固化了双判据(400 + 逐字段比对),并**排除随挂钟变的字段**(`requestId`/`updatedAt`/`serverUpdatedAt`/`range.start|end`,还有 `/infrastructure/operating-information` 指标的 `freshness.ageSeconds`)—— 不排除的话,这些端点会被误判成"按片区过滤了"。
|
|
|
|
|
+- **口径说明要正向普查,不能只查你改过的面板**:D0c 以 `implementedPanelIds()` 为准,要求**每个**已实现面板要么有片区缺口、要么属于已接线集合 —— 将来新增面板漏写说明会立刻红。这与票 56 把"说明字段是否有消费点"做成机制是同一条路子。
|
|
|
|
|
+- **"字段里没有"不等于"数据里没有"**(§十 记的第二次同类翻车):我先后两次同一个毛病 —— 一次把"响应里有 `filters` 字段"当成"后端支持",一次把"properties 里没有片区字段"当成"片区不可得"。两次都是**只看一个信号就下结论**。E1b 现在用「编码前缀 × `name` 里的片区词」两路独立信号交叉复核(6762/6762、零反例),E7 再加一路(燃气∩太常 586 与编码 (TC,RQ) 计数相等)—— 判据至少两路,才配叫证据。
|
|
|
|
|
+
|
|
|
|
|
+### 七、后端契约缺口(不在本票伪造)
|
|
|
|
|
+
|
|
|
|
|
+另立 [票 77:后端执行票 —— 片区/行业筛选的端点覆盖缺口](77-untitled.md):事件族三端点补 `district`、`/work-orders` 补 `industry`、概览四新端点上线时定参数面。部署后按 `verify/artifacts/t67/` 的同一套探针复跑即可验收。
|
|
|
|
|
+
|
|
|
|
|
+**几何读模型的片区归属已降级为"锦上添花"**(§十 更正):前端已能按设施编码前缀推出片区并据此裁剪图层,
|
|
|
|
|
+所以"几何必须补片区字段"不再是阻塞项;若后端将来直接下发 `district`/`location`,前端改 `pipeDistrictOf` 一处即可。
|
|
|
|
|
+
|
|
|
|
|
+### 八、既有红如实留档(与本票 diff 零交集)
|
|
|
|
|
+
|
|
|
|
|
+| 闸门 | 现状 | 根因(有据) |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| t56-panel-summary-disclosure | 整脚本导入失败 | 它 import `MONITORING_FAULT_GAP`/`monitoringSummaryPanel`,而 `domain/overviewPanels.js` 在**并行在制的概览重构(票 02)**里已移除这些导出:`git show HEAD:` 该文件有,工作树没有;**本票未修改该文件** |
|
|
|
|
|
+| t38-infrastructure-panel-adjustments | 整脚本导入失败 | 同上,缺 `infrastructureSummaryPanel` |
|
|
|
|
|
+| t44-distribution-ranking | 整脚本导入失败 | 同上,缺 `alertSettingsPanel` |
|
|
|
|
|
+| t15-time-district | 断言期异常(`operationOverviewPanel` 的 list 块 rows 为空) | 运行概况已按票 62 的追加需求改成读 `monitoringOverview.devices`(`extra`),该脚本仍按旧形状直接调面板函数;**本票未修改 `monitoringPanels.js`,且该断言不经过 `panelViews`** |
|
|
|
|
|
+| t14-final-walkthrough | puppeteer `spawn EPERM` | 浏览器脚本;本机沙箱边界 + AGENTS.md 禁止浏览器验证 |
|
|
|
|
|
+
|
|
|
|
|
+按仓内成例**不半修**这些闸门。
|
|
|
|
|
+
|
|
|
|
|
+### 九、下一步
|
|
|
|
|
+
|
|
|
|
|
+- 真实环境走查(片区/行业在四模式下的观感、说明文案的折叠摘要是否易读)归[票 18](18-frontend-real-integration-gate.md) 联调窗口。
|
|
|
|
|
+- 后端票 77 落地后,前端只需把 `filterCaliber.js` 里对应条目的措辞删掉、把参数接上(`acceptsDistrict` 打开),闸门 D 组的正向普查会自动要求更新。
|
|
|
|
|
+- **改动未提交**:工作树混有大量并行在制品(概览重构、城市体块、场景图标等 20+ 文件),本票 9 个文件需按票 33/36/37 纪律单独裁剪入库。
|
|
|
|
|
+
|
|
|
|
|
+### 十、更正(2026-10-23):管线**有**片区可分,本票 §二/§四 的"不作用于管线"作废
|
|
|
|
|
+
|
|
|
|
|
+**维护者原话**:管线编码 `network_code` 的组成规则就是「**片区 + 行业 + 时间编码**」
|
|
|
|
|
+(如 `TCRQ202609080001` = 太常·燃气管),另外 `location` 字段作为位置描述也描述了管线信息
|
|
|
|
|
+(如那段太常燃气管的 `location` 是「太常|燃气管线」)。
|
|
|
|
|
+
|
|
|
|
|
+**我错在哪**:§二 第 2 条只查了「几何 properties 里有没有片区字段」,没有就下结论"不可本地筛"——
|
|
|
|
|
+把**字段里没有**当成了**数据里没有**。这跟本票 §六 批评的那条错误(把"响应里有个 filters 字段"
|
|
|
|
|
+当成"后端支持")是同一类毛病:**只看一个信号就下判断**。片区信息一直在编码前两位里。
|
|
|
|
|
+
|
|
|
|
|
+**用真实载荷复核(`verify/artifacts/t67/geom-none.json`,6766 feature)**
|
|
|
|
|
+
|
|
|
|
|
+| 检验 | 结果 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| code 两字母前缀分布 | TC **4116**、CN **2646**、GD 1、YL 3 |
|
|
|
|
|
+| 前缀 × `name` 里的片区词(**两个独立信号**) | TC → 4116/4116 含「太常」;CN → 2646/2646 含「城南」;**零反例** |
|
|
|
|
|
+| 前缀 + 行业字母 | TC/CN 各带 RQ(燃气)/WS(供水)/YS(雨水)/GC(管沟),与「片区+行业+时间」规则吻合 |
|
|
|
|
|
+| 三路交叉独立验证 | 燃气∩太常 = `586`,与编码里 (TC,RQ) 计数 **586** 完全相等 |
|
|
|
|
|
+| `location` 字段 | 几何 properties **里没有这个键**(只有 source/sourceId/code/name/industry/typeCode/networkType/networkLevel/pointType/networkId/diameter/remark/sourceCoordinates/coordinateValidation*)⇒ 片区只能靠编码前缀,不靠 location |
|
|
|
|
|
+| 推不出片区的对象 | 4 个(`GD-001` 阀门、`YL-YJ-001/002/003` 窨井,用的是另一套编码);其中 3 个本来就在「无地图位置」拦下清单(blocked)里,只有 `YL-YJ-003` 是可上图对象 |
|
|
|
|
|
+
|
|
|
|
|
+**实现(`domain/pipeNetwork.js` / `stores/pipeNetworkStore.js` / `CockpitShell.vue`)**
|
|
|
|
|
+- `PIPE_DISTRICT_PREFIX = { CN: 0, CB: 1, TC: 2 }`(与 `filterOptions.DISTRICT_CODES` 的后端片区编码同值)+
|
|
|
|
|
+ `pipeDistrictOf(code)`:只认「两位片区字母 + 两位行业字母」的正式形状,认不出回 `null`(不猜)。
|
|
|
|
|
+- `toPipeNetwork()` 每条 pipe/component/blocked 都带 `district`;
|
|
|
|
|
+ `filterPipeNetwork(network, { industry, scope })` 现在**真的按片区裁剪**,并返回
|
|
|
|
|
+ `districtApplied`(全域 false/具体片区 true)与 `districtUnresolvedCount`(被排除的可上图对象数)。
|
|
|
|
|
+- 「未分区」的语义=**编码推不出片区的那批对象**(与后端 `district=null` 同一读法);
|
|
|
|
|
+ 选具体片区时它们被排除并计数 —— 不硬塞进某个片区,也不静默留在结果里。
|
|
|
|
|
+- 几何仍是**一次全量取回**、片区在本地裁剪(与行业同一条纪律:切换即时、不重新发请求)。
|
|
|
|
|
+
|
|
|
|
|
+**两条如实标注**
|
|
|
|
|
+1. **片区仍是前端推导,不是后端筛选**:几何端点实测仍**不收** `district`(`district=0/1` 响应逐字节相同、非法值 99 也不 400),
|
|
|
|
|
+ 所以界面上的措辞改成「按设施编码规则作用到管线图层……片区是从编码前缀推出来的」,
|
|
|
|
|
+ 而不是含糊地说"片区已生效"。
|
|
|
|
|
+2. **`CB = 城北` 已由维护者 2026-10-23 确认**(此前我按拼音推定、标注"可推翻",现已落定):
|
|
|
|
|
+ 现网 6766 条几何里**一条 `CB` 都没有** —— 选「城北」时管线为空,是编码里没有、不是没有管线。
|
|
|
|
|
+
|
|
|
|
|
+**票 77 相应调整**:几何端点补片区字段从"前端等着用"降级为"锦上添花"——前端已能工作;
|
|
|
|
|
+若后端将来直接下发 `district`/`location`,前端只改 `pipeDistrictOf` 一处(闸门 E1 会用落盘载荷复核前缀与名称的一致性)。
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+### 十一、真机复验失败 → 根因与修复(2026-10-23,维护者实测「按钮不起作用」)
|
|
|
|
|
+
|
|
|
|
|
+**现象**:维护者在 `http://127.0.0.1:8000/#/cockpit` 点「当前范围」按钮,界面毫无变化。
|
|
|
|
|
+
|
|
|
|
|
+**取证**(Chrome DevTools 协议只读取证,未改页面):
|
|
|
|
|
+1. 点「城南」后 **4 个面板确实带上了片区**(`monitoring/distribution?district=0`、
|
|
|
|
|
+ `events/multidimensional-analysis?...&district=0`、`infrastructure/base-archives?district=0`、
|
|
|
|
|
+ `management-information?district=0`)—— 说明点击→store→watch 这一段是通的;
|
|
|
|
|
+2. 但**一张图一条 `map-snapshot` 请求都没发**;
|
|
|
|
|
+3. 控制台里有:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+TypeError: pipeNetworkStore.setScope is not a function
|
|
|
|
|
+ at CockpitShell.vue:1442 (watcher callback)
|
|
|
|
|
+[Vue warn]: Unhandled error during execution of watcher callback
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**根因(两级)**
|
|
|
|
|
+- **直接原因**:我这次给 `pipeNetworkStore` 新加的 `setScope` 在**浏览器拿到的模块里不存在**。
|
|
|
|
|
+ 实测证明是 dev server 的**转译缓存**给旧版:同一 URL 直接取回,`return {...}` 里没有 `setScope`;
|
|
|
|
|
+ 加 `?t=999999` 强制重取就正常。dev server 的 mtime 失效没跟上(Windows 上常见),
|
|
|
|
|
+ **硬刷新也救不回来**(浏览器刷新不会让 Vite 重新转译),只能 `touch` 文件或重启 dev server。
|
|
|
|
|
+- **放大原因**:`watch(scope)` 里 6 个联动是一串**同一个回调**,第 5 个 `pipeNetworkStore.setScope(next)`
|
|
|
|
|
+ 一抛错,**排在它后面的 `refreshMapForFilters` 就永远不执行** —— 于是「面板刷了、一张图不刷」,
|
|
|
|
|
+ 而界面上没有任何提示(只有控制台 warn)。这正是「筛了但没生效」的最隐蔽形态。
|
|
|
|
|
+
|
|
|
|
|
+**修复与复验**
|
|
|
|
|
+1. `touch` 我改过的模块强制 Vite 重新转译(已用 `curl` 逐文件核对服务端返回的是新版)。
|
|
|
|
|
+2. 复验(同一页面、只读取证):
|
|
|
|
|
+ - 点「城南」→ `map-snapshot?page=1&pageSize=2&district=0`(第 1 页起全部带 `district=0`);
|
|
|
|
|
+ - 一张图状态带真的变了:**太常** 报警0/预警1/工单0/正常0/离线0 ↔ **全域** 报警1/预警1/工单5/正常1/离线2;
|
|
|
|
|
+ - 基础设施「基础档案」在太常下读数为 `设施总数 0 处`(设施档案没有片区来源,全部落未分区 —— 票 68 记过的既知事实,不是缺陷)。
|
|
|
|
|
+
|
|
|
|
|
+**顺带修掉一个真实缺陷**(`domain/deviceMetricSources.js`,committed 代码、非本票引入):
|
|
|
|
|
+`deviceMetricKind(archive = {})` 的默认值只在**未传**时生效,而 `fetchEquipmentDetailAggregate` 在档案分区为 EMPTY 时
|
|
|
|
|
+显式传 `null` → `archive.type` 抛 `TypeError`,**整条设备详情聚合被打断**(真机控制台反复出现该异常)。
|
|
|
|
|
+改为函数内 `const source = archive || {}` 收口;复验:刷新后控制台 error 归零。
|
|
|
|
|
+
|
|
|
|
|
+**留给运维/开发的一条纪律(写进票面,避免重复踩)**
|
|
|
|
|
+> 改了 `stores/*.js`、`services/*.js` 这类**纯 JS 模块**后,dev server 可能仍把旧转译结果发给浏览器
|
|
|
|
|
+> (`.vue` 有 HMR 边界会换,纯 JS 不会)。表现是「新增的 store 方法 is not a function」,
|
|
|
|
|
+> 而且**浏览器硬刷新也无效**。处置:`touch` 该文件(或重启 dev server),再刷新页面。
|
|
|
|
|
+
|
|
|
|
|
+**观察(不在本票处理)**:`MAP_SUMMARY_PAGE_SIZE = 2`(2026-09-18 为演示渐进加载而设,注释写明)。
|
|
|
|
|
+真实数据下每切一次筛选会连翻几十到上千次 `map-snapshot`(本次实测一次筛选 40+ 请求)。
|
|
|
|
|
+演示无碍,**真实投用前应调回后端默认 500**,否则既是性能问题也像"卡住不动"。
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|