60-untitled.md 12 KB

前端执行票 —— 统一分页批次二:点位摘要两级清单(设备卡片、关联设备图层清单)

Question

按 全局分页规范 落地批次二:PointDetailCard.vue 两个全量直渲清单接入共享 pager——「设备卡片」(data-device-cards,详情端点 devices[])与「关联设备图层清单」(data-device-layer-list,票 42 的快照 deviceCodes 全量保留)。前端集合分页,每页 10 条、页码直达/前后页,两清单各自独立页码;换点位/设备时复位。

Acceptance

  • 两清单每页 ≤10 条、pageCount <= 1 不画控件、到边禁用保占位。
  • 票 42 口径不变:关联设备清单数据仍保留全部编码(含待确认),分页只是窗口化渲染;互斥归类(已上图/无地图位置/模式隐藏/待确认)与差额可追溯不受影响。
  • 换点位/设备/返回第一级时页码复位;数据刷新(freshness tick)不复位,越界夹回。
  • 空态文案沿用既有(「该监测点当前没有关联设备」等);新增闸门 + 变异打红;既有相关闸门按成例改写后全绿。

Context

共享 pager 由批次一提供(domain/pagination.js + PagerNav.vue)。教训复用:票 43(稳定标量键);票 42(清单总数只认当前快照、每台设备恰好落一类)。

Related spec

../specs/2026-10-18-global-list-pagination.md

进度

  • 认领(Assignees: Qoder;阻塞票 #59 已关闭,处于 frontier)
  • 读票全(正文/评论/标签/认领/父 00/阻塞边 #59)+ 规范 + 票 59 成例 + 既有闸门断言面
  • 调查:仓内资料足以回答,未新开 research 笔记;两处票面未写死的分叉已向维护者裁定(未命中子清单分页 / 不画计数行),记在开工说明评论
  • 实施:PagerNav.vue 新增 showCount(默认 true,既有消费方零改动);PointDetailCard.vue 三清单接共享 pager + pages 稳定标量键 + 复位 watch
  • 新增闸门 t60-point-detail-lists.mjs 42/42 + 变异 t60-mutations.mjs 10/10 打红并按字节还原
  • 回归全绿:t59 37/37 + 变异 13/13、t46 54/54 + 变异 12/12、t10 57/57、t41 SSR 9/9、t42 39/39、t43 40/40、t44 47/47、并行票 64 61/61
  • 规范「修订记录」补两条当次裁定(口径只留一份)
  • 收口(本票 resolved)

Status: resolved Assignees: Qoder Type: task Blocked by: #59(已关闭) Labels: wayfinder:task

Comments

  • 批次二开工说明 + 维护者当次两条裁定(见本票 Answer 的「两条当次裁定」节;已读资料路径与一句话结论逐条记在该评论)。

local — 2026-10-20T16:51:39.623Z

(收口时正文整篇替换误覆盖此条,补回以保留 provenance)已读资料与一句话结论:

  • 规范 specs/2026-10-18-global-list-pagination.md — 条文 2/3/4/6/7/11 + 三分法「前端集合」明列本票两清单。
  • 票 59 Answer — 共享件已就位:domain/pagination.js(pagedRows/pageWindow/clampPage)+ PagerNav.vue(受控、唯一 @page 出口携带绝对页码);接线成例 = pages 组件本地状态 + pagedOf() + gotoPage(),复位在组件 watch。
  • components/PointDetailCard.vue、stores/deviceLayerStore.js、domain/detailFlow.js — 设备卡片读 pointData.devices[];关联清单读 store rows(保留全部编码),总数读 total(只认当前快照 deviceCodes),归类/图例读 counts/legend,票 14 未命中行读 placement === 'unmatched'。
  • 既有闸门/走查断言面:t42 B1b(总数 ≠ 清单行数)、t43 F9(卡片与清单 hover/select 绑定)、t44 F7/F10/F12、t46 E5/E6/E7b/E8、t59 S7/C 组、t18/t44/t45 走查探针(data-device-layer-row/data-device-more 读行)。 调查结论:仓内既有资料足以回答本次全部问题,未新开 research 笔记。两条票面未写死分叉已向维护者裁定(见 Answer「两条当次裁定」)。

Answer

已实施、闸门 + 变异闭环并关闭(2026-10-19)。按 AGENTS.md 跳过 build/dev/浏览器验证。

交付物

文件 内容
src/modules/cockpit/components/PointDetailCard.vue 三个清单接入共享 pager:「设备卡片」(data-device-cards,详情端点 devices[])、「关联设备图层清单」(data-device-layer-list,命中子集)、「未命中设备清单」(票 14 展开子清单,当次裁定 1)。窗口行 pagedCards/pagedLayerRows/pagedUnmatchedRows 全部经 pagedOf() → domain/pagination.js 的 pagedRows(条文 11 单源,组件零 Math.*/零 .slice();页码是视图本地状态 pages = { cards, layer, unmatched }(稳定标量键,票 43 教训),唯一出口 gotoPage(key, target);复位 watch 的 getter 收成一个标量字符串 `${pointCode}
src/modules/cockpit/components/PagerNav.vue 新增 showCount prop(Boolean,默认 true):计数行是唯一受它门控的块(v-if="showCount"),前后页/页码直达/跳页能力不受影响。批次一既有消费方(设备详情三清单)不传该 prop ⇒ 形态逐字不变
.scratch/.../specs/2026-10-18-global-list-pagination.md 「修订记录」追加票 60 两条当次裁定(规范是唯一口径来源,不在别处另写第二份)

两条当次裁定(票面未写死,已向维护者确认后按此实施)

  1. 票 14 的「另有 N 台 · 未命中当前筛选」展开子清单同样 ≤10/页,第三套独立页码。 规范判据一视同仁(可能拉长页面就分页);pageCount<=1 时共享层自己 v-if 掉 ⇒ 常态界面零新增控件。「另有 N 台」的 N 仍读全量 unmatchedDeviceRows.length(data-device-more-count 不变),差额可追溯是票 14 的口径。
  2. 本组件三处 pager 不画计数行(:show-count="false")。理由:上方已各有权威总数——设备卡片侧是 KPI「设备合计」(读后端统计),关联清单侧是标题「总数 X 台(已上图 Y)」(只认当前快照);再并排放一个「共 N 条」(窗口口径)就是并排的第二个总数,且窗口条数 ≠ 快照总数正是票 42 明写的「总数 ≠ 清单行数」。

实施中途的一次自我纠正:pager 容器在 <ul> 里必须是 <li>(否则 HTML 非法),而普通 <li> 在 PagerNav 不渲染时会留一条空行 —— 用 .point-detail__pager { display: contents } 收口,不在组件里重复判 pageCount>1(那条规则仍只在共享层有一份)。复位 watch 第一版写成数组 getter,会让「重进同一点位」(selection 换新对象、标量同值)假复位,按票 43 教训改成标量字符串。

票 42 口径未动的证明(不是声明,是断言)

分页只发生在渲染窗口:store.rows 仍是全量 27 行、total 仍是快照口径 27(15 命中 + 12 未命中)、counts 互斥归类之和仍 = 全量、legend 合计仍 = 全量;标题的两个数与图例的绑定一字未动。闸门 K 组五条逐条钉住(K1/K1b/K2/K3/K4),并有变异 M5「标题总数改读窗口条数 → K2 转红」证明它抓得住。

验证

  • 新增闸门 t60-point-detail-lists.mjs 42/42:真实链路灌数(mock 传输 + mapStore.advance + detailStore.openPoint + deviceLayerStore.syncForSelection({filterActive:true})),渲染用 Vue 自定义渲染器在纯对象树上跑真实 patch(票 64 成例,不引 jsdom)。
    • R 组:每页 ≤10、点页码 2 逐条对编码(画的是第 11–20 台)、两清单页码互相独立、末页只画余数、到边 disabled 且节点仍在、上一页走同一出口;data-device-card 续全局下标(第 2 页是 10..19 —— 走查/探针按「第 N 台」取数,翻页不得让它每页都从 0 数)。
    • T 组:折叠钮文案仍报全量 12 台、展开后 ≤10、第三套独立 pager、翻末页只画余数、不牵连前两处。
    • K 组:票 42 口径(见上)。
    • Z 组(条文 5/6 正反两半):数据刷新不复位(还停第 2 页)、跳 999 夹回最后一页且画的是余数、同点位重进不误复位、换点位回第 1 页、短列表(2 条)三处控件都不画、返回第一级复位、空态文案与「空清单不画控件」。
    • S 组:showCount 默认 true、计数行是唯一受控块、EquipmentDetailSections 不传 show-count(既有计数行保留)、三处都 :show-count="false"、三处共用唯一出口、单源一条委托、复位键是标量、标题总数与归类仍读 store。
    • C 组:三份 .vue 用 @vue/compiler-sfc 真实编译过(票 41/59 教训:拼错的绑定只有加载层判得出)。
  • 变异闸 t60-mutations.mjs 10/10 打红并按字节还原:M1 卡片下标退回页内 0 起 / M2 关联清单退回全量直渲 / M3 未命中退回全量展开 / M4 差额读数改读窗口 / M5 标题总数改读窗口条数 / M6 showCount 默认改 false(批次一形态回归)/ M7 组件重长翻页算术 / M8 翻页多开一个出口 / M9 换点位不再复位 / M10 复位触发器退回数组 getter。
  • 既有闸门「无需改写即全绿」(本票未动任何既有判据,如实记):t59 37/37 + 变异 13/13、t46 54/54 + 变异 12/12、t10 57/57、t41 SSR 9/9、t42 39/39、t43 40/40、t44 47/47、并行票 64 61/61。t59 的 S7(计数行措辞)之所以仍绿,正因为 showCount 默认 true。t11/t05 的崩溃与本票无关:改动前后同点位、同行号失败(t11:527、t05:343,均在详情静态守卫之前),属并行在制品既有红。
  • 浏览器走查探针面逐条预判(真机复验归票 18/17 联调窗口):t45 W4(rows === 2)与 t44(DEVICE_CODES 2 台)都落在 ≤10 场景;t44 的行同源断言读的是引擎计划 getAssociatedDevices().plan(store 全量),不是 DOM 窗口;t18 D2e(moreCount === '1'、展开含 EQ-001)在未命中 1 条时 pageCount=1 ⇒ 不画控件、行仍在;t10/t11/t12 点 [data-device-card="0"] 在第 1 页仍存在。没有一条既有走查判据需要因本票改写(多页场景的真实证据归票 18 走查窗口)。

验收对照

  1. ✅ 每页 ≤10(R1/R2/T2)、一页不画控件(Z4b/Z6b)、到边禁用保占位(R5/R10)。
  2. ✅ 票 42 口径不变(K1/K1b/K2/K3/K4 + 变异 M4/M5);数据仍保留全部编码含待确认,分页只窗口化渲染。
  3. ✅ 复位与保持(Z1 刷新不复位、Z2 越界夹回、Z3 同点位重进不误复位、Z4 换点位、Z5 返回第一级)。
  4. ✅ 空态文案沿用既有(Z6 + S9);新增闸门 + 变异打红;既有闸门无需改写即全绿。
  5. ✅ 单源:翻页算术与控件各只有一份(S4/S5/S6 + 变异 M7/M8)。
  6. ✅ 按 AGENTS.md 跳过 build/dev/浏览器验证。

状态与下一步

批次二收口。两点如实留档:① 改动未提交(工作树混有票 46/50/51/64 等并行在制品;本票足迹只有 components/PointDetailCard.vue、components/PagerNav.vue 两份源文件 + verify/t60-*.mjs 两份脚本 + 规范修订记录,入库须按票 33/36/37 纪律单独裁剪);② 浏览器/真机验收按项目规则未执行,归票 18/17 联调窗口(≥10 台设备的点位复验建议用 data-point-pager="cards|layer|unmatched" 三处包装面取数)。

后续批次(票 61–68)仍按批次一的共享件接入,无需再改本票两份源文件;唯一例外:若某消费方也需要「上方已有权威总数、不画计数行」,复用本票的 show-count(判据已写进规范修订记录,不要再在组件里另写第二份 pageCount 判断)。