2026-10-18-global-list-pagination.md 18 KB

驾驶舱长列表统一分页规范(2026-10-18)

来源:票 57(维护者 2026-10-17 反馈 5)。上位规格:2026-10-17-monitoring-feedback.md §5。

目标与适用判据

凡可能包含表格或卡片列表、且新增数据会无限拉长页面的区域,统一分页行为:

  • 每页最多 10 条(PAGE_SIZE = 10),前端展示窗口恒 ≤10 条;
  • 控件三件:上一页、下一页、页码直达;只有一页时不画任何控件;
  • 先筛选/分类,后分页;条件变化回第 1 页;总数不由当前页反推。

排除(不是条目清单,或数量契约有界,详见盘点表):聚合图表(柱/环/堆叠/趋势/饼/维度柱)、KPI 行、键值行块、一张图顶部状态栏图例、地图重叠聚合 fan(渲染层)、契约有界小清单(管理信息片区×行业明细、预警分析重点识别)、地图摘要点位装载(渐进保护,见三分法)。

统一行为(规范条文)

  1. 页大小:PAGE_SIZE = 10。任何接入区域的展示窗口每页 ≤10 条。
  2. 控件:上一页|页码|下一页 + 计数行「第 X/Y 页 · 共 N 条」。页码直达=页码按钮:当前页不可点并标 aria-current="page";总页数 >7 时收缩为「1 … c−1 c c+1 … Y」窗口(恒含首末页与省略号)。
  3. 禁用态:到边按钮 disabled 且保留占位(按钮消失会让计数行跳动,读起来像出错——票 46 既有语义)。
  4. 一页不画控件:pageCount <= 1 时整个 pager 不渲染(短列表不多出两个死按钮)。
  5. 筛选先于分页:分类 chips、全局筛选(行业/片区/设备类型/点位状态/范围)、模式切换(预警↔报警)、设备·点位切换、时间范围变化,都先作用于集合或请求参数,再分页。
  6. 复位规则:上述任何条件变化 → 页码回第 1 页。新鲜度/定时刷新不复位页码(用户停在第 3 页时,周期刷新不得把人弹回第 1 页);数据变少导致页码越界时由分页函数夹回最后一页。
  7. 总数口径:服务端分页读响应 pagination.total;前端集合分页读过滤后集合长度;渐进装载用「已装载 M · 共 N」双口径。任何区域不得用「当前页 × 页大小」反推总数。
  8. 态语义(沿用既有分区词汇,不另造一套):
    • 加载:正在取数…(分区 pending 语义);翻页请求进行中保持旧内容或同一占位,不闪空白;
    • 空态:「真没有」与「条件下没有」分文案(当前没有记录 vs 当前分类下没有记录(换一个分类或点「全部」));
    • 失败:分区 FAILED/UNAVAILABLE 占位 + 分区状态标签;渐进装载下一批失败不回滚已装载内容(台账既有语义);
    • 竞态:沿用各 store 既有 token/纪元纪律;翻页请求迟到即作废,不落进新页码。
  9. 无障碍:pager role="group" + aria-label="「列表名」分页";页码当前项 aria-current="page";计数行是随页码更新的文本。
  10. 文案纪律:不把后端 page/pageSize 参数名暴露到界面文案(上位规格 §5 原文);只说「页」「条」。
  11. 单源:翻页窗口计算只有一份(domain/pagination.js,自 equipmentDetailView.pagedRows 升格,HISTORY_PAGE_SIZE/pagedRows 原名保留导出兼容),pager 控件只有一份(PagerNav.vue)。禁止任何组件重写翻页算术或另画一套 pager。

三分法:服务端 / 前端集合 / 渐进装载

  • 服务端页码分页(翻页即请求,page+pageSize=10 进查询串): 预警处置·当前事件表(/events/current);预警处置·历史事件单窗范围(/events/history-analysis 近 7 天;逐事件行与 page/pageSize 契约为票 61 连同后端一并补齐)。
  • 前端集合分页(数据已一次装载,pager 只切窗口、零请求): 设备详情预警/报警/工单状态;点位摘要设备卡片与关联设备图层清单;运行概况设备台账(票 62 追加需求:原「异常设备清单」已撤下);基础设施·运行信息指标列表(票 64 补入,原误列排除);历史事件多窗合并范围(近 30/90 天——historyWindows 分窗合并后不存在「全局页」,回退已加载合并集合分页并在页脚如实说明;跨窗全局分页仍不在本图范围,需要时必须另立后端票重画契约)。
  • 渐进装载 + 页码 UI(数据链路保持自动渐进,界面只对已装载集合翻页): 监测点台账——装载与一张图点位数据同款自动渐进链(条件变化 → 新快照 → 自动连翻到 settled,沿用快照 token 与纪元纪律);UI 面板对已装载集合做统一页码分页(10/页、页码直达)。票 62 已落地:装载链在 domain/ledgerLoader.js,页大小由后端默认值决定(前端不硬编码),snapshotAt 由后端回显、缺失即停链;「加载下一页」按钮退役。
  • 排除:地图摘要点位装载保持自动渐进、无列表 UI(票 14/23 契约,不得误改为页码分页)。

维护者裁定(2026-10-18;2026-10-19 追加第 3 条)

  1. 监测点台账:监测点数据保持自动渐进式加载(与地图中点位数据的加载方式一致),但 UI 页面中要能翻页——「加载下一页监测点」按钮随之退役。
  2. 事件清单:走服务端页码分页(翻页带 page 参数发请求);多窗合并范围的回退规则见三分法。
  3. 验收与走查以真实数据为准,不为演示扩写 mock 样例(票 64 引出):mock 样例数据量小 ⇒ 某些接入区域在 mock 下不足一页、按条文 4 正确地不画控件,这是预期行为而非缺陷,不得为此把 mock 样例补到 >10 条(扩了也没有演示价值,真实数据才是验收口径)。多页与边界行为一律在闸门里用真实载荷或合成载荷证明(往闸门灌数据 ≠ 改 mock 样例:票 62 的 mock 判据、票 64 的 t64 V 组都是这条路);真实观感归票 18 联调窗口。批次二~五执行票同样适用。

全仓盘点

区域 代码接缝 数据源 · 现状 目标 批次
设备详情 · 预警信息 / 报警信息 EquipmentDetailSections.vue(data-event-list)、domain/equipmentDetailView.js 设备详情聚合两分区;已每页 10、先分类后翻、一页无控件 迁共享 pager,补页码直达 一
设备详情 · 工单状态 同上(data-work-order-list) 设备详情聚合 workOrders;全量直渲 前端集合分页 10/页 一
预警处置 · 当前事件表 EventListPane.vue(data-event-table)、stores/eventStore.js /events/current(后端默认 100、上限 1000);前端砍最新 12 条 服务端页码分页(pageSize=10);mode/筛选/范围变化回第 1 页 三
预警处置 · 历史事件 domain/warningResponsePanels.js historyAnalysisPanel(PanelBlocks list 块) /events/history-analysis 分窗合并;events.slice(0,12) 单窗(近 7 天)服务端分页;多窗(近 30/90 天)合并集合分页 + 页脚如实说明 三
运行概况 · 设备台账(原「异常设备清单」) domain/monitoringPanels.js operationOverview(list 块) /monitoring/overview 的 devices[](票 62 追加需求;行数 ≡ counts.equipmentCount) 前端集合分页 10/页(页脚报设备台数) 四 ✅
运行监测 · 监测点台账 domain/monitoringPanels.js monitoringPointLedger、stores/monitoringStore.js loadMoreLedger、PanelBlocks data-ledger-more /monitoring/distribution 服务端分页 + 快照 token(票 23);「加载下一页」每次追加后端一页 ≈500 卡 装载保持自动渐进(同地图链路);UI 对已装载集合页码分页 10/页;按钮退役 四
点位摘要 · 设备卡片 PointDetailCard.vue(data-device-cards) 设备详情端点 devices[];全量直渲 前端集合分页 10/页 二
点位摘要 · 关联设备图层清单 PointDetailCard.vue(data-device-layer-list,票 42) 地图快照 deviceCodes,保留全部编码(含待确认) 前端集合分页 10/页(数据仍保留全部,窗口化渲染;互斥归类与差额口径不变) 二
基础设施 · 运行信息指标列表 domain/infrastructurePanels.js operationPanel → listBlock('运行指标', …, { paginate: true, pageScope }) /infrastructure/operating-information 一次回全部行业指标;实测 6772 条(供水 2497/排水 3576/燃气 699),响应 2.3 MB;原全量直渲、块标题「指标占位」与实际内容不符 前端集合分页 10/页(本票 57 曾误列为排除项,2026-10-19 由维护者反馈纠正);块标题改为如实说法 —— 已由票 64 落地 五 ✅
基础设施 · 管理信息片区×行业明细 managementPanel(list 块) districtIndustry[],实测 9 行,组合数契约有界(片区×行业) 排除(有界小清单,实测 <10) —
基础设施 · 应急保障三段 domain/infrastructurePanels.js emergencySectionBlock(list 块) /infrastructure/emergency-support 三段 items;2026-10-22 实测 0+20+9=29 条(防护目标 20 条已超一页) 前端集合分页 10/页(一页时无控件)——已由票 63 落地 五 ✅
预警分析 · 重点识别 eventAnalysisPanel(list 块) 后端聚合重点,数量少 排除 —
一张图 · 地图摘要点位装载 stores/mapStore.js、domain/mapSummary.js /map/snapshot 快照自动链 排除:保持自动渐进装载,不改页码 —
其余 图表块(bars/donut/stacked/trend/pie/dimbars)、KPI、键值行、状态栏图例、地图重叠聚合 fan 非条目清单 排除 —

跳页(维护者 2026-10-19 追加)

页码直达按钮之外,pager 还必须提供输入框跳页:

  • 一个数字输入框 + 「跳转」按钮(或 Enter 提交),输入目标页号后直接跳到该页;
  • 输入非数字/0/超出 pageCount 时夹回合法范围(1..pageCount),不报错、不发请求、不清空列表;
  • 输入框占位提示当前页(placeholder = 当前页),aria-label="跳转到指定页";
  • 总页数 ≤1 时整块 pager(含输入框)不渲染,与本规范第 4 条一致;
  • 跳页与「上一页/下一页/页码」共用同一个翻页出口,不新增第二套页码状态。

实施批次

每批一张执行票(本票只收口规范与盘点,不实施):

  • 批次一:共享分页基建(domain/pagination.js + PagerNav.vue,含页码直达与输入框跳页)+ 设备详情三清单接入(预警/报警迁移、工单状态新接入)。
  • 批次二:点位摘要两级清单(设备卡片、关联设备图层清单)分页。
  • 批次三:预警处置事件清单服务端页码分页(当前事件表 + 历史事件单窗/多窗规则 + mock 同构)。
  • 批次四:运行监测(运行概况设备台账前端集合分页;监测点台账自动渐进装载链 + 页码 UI、撤「加载下一页」按钮)。
  • 批次五:基础设施运行信息指标列表(6772 条,最高优先)✅ 票 64 + 应急保障三段接入(PanelBlocks list 块路径收尾)✅ 票 63。

执行票:见票 57 正文(批次五已按 2026-10-19 维护者反馈扩为两张:运行信息指标列表 + 应急保障)。

非目标

  • 不改后端只读契约与快照 token 语义(票 23);地图渐进装载不改页码。
  • 不改排序口径(「前端不重排」立场不变;服务端分页按后端返回序渲染)。
  • 不给聚合图表、KPI、键值行与契约有界小清单加分页。
  • 按 AGENTS.md,实施票默认跳过 build/dev/浏览器验证,除非维护者当次明确授权。

修订记录

  • 2026-10-18 首版(票 57)。
  • 2026-10-19 维护者 8 条反馈后的纠正:① 补齐「输入框跳页」要求;② 撤销运行信息指标列表的排除——实测 6772 条 / 2.3 MB,改列入批次五(原判断基于代码推断"单行业指标条数契约有界",被真实数据证伪);③ 应急保障盘点点亮实测量(8+0+20=28);④ 管理信息实测 9 行,维持排除并补实测依据。
  • 2026-10-19 票 64 收口时的追加裁定(见「维护者裁定」第 3 条):验收以真实数据为准,不为演示扩写 mock 样例;mock 下不足一页不画控件是预期行为,多页行为归闸门用真实/合成载荷证明。
  • 2026-10-19 票 60(批次二)维护者当次两条裁定:① 点位摘要里票 14 的「另有 N 台 · 未命中当前筛选」展开子清单同样 ≤10/页、独立第三套页码(判据一视同仁:它可能拉长页面;「另有 N 台」的 N 仍报全量,差额可追溯不变);② 计数行(条文 2/9)在 PointDetailCard 的三处 pager 一律省略——PagerNav 新增 show-count 开关(默认 true,批次一既有消费方形态不变);该组件上方已各有权威总数(设备合计 KPI 读后端统计;清单标题「总数 X 台(已上图 Y)」只认当前快照),并排再画「共 N 条」就成了窗口口径的第二个总数。
  • 2026-10-21 票 61(批次三)落地与两条当次裁定:① 三分法的「历史事件单窗 = 服务端页码」此前只有前端假设、真实契约不支持(/events/history-analysis 只回小时桶、无逐事件行、也不接 page/pageSize)——维护者裁定本票连同后端一起完成:该端点新增 events[](形状与 events/current 的 EventItem 同构)与 pagination,接 page/pageSize(默认 1/100、上限 1000)。前端的服务端页码分页因此有真实契约可依。② 多窗合并范围的窗口数如实报:historyWindows 在「起止差恰为 30/90 天」时会切出毫秒级尾窗(实测 30 天 = 2 窗、90 天 = 4 窗),页脚口径写实际窗数(已合并 N 个时间窗 · 已加载 M 条),不写死 3、也不伪造全局页码;页码归属键(pageScope)用请求侧范围键(后端回显 range.type=TREND_WINDOW 不能当预设范围用)。
  • 2026-10-22 票 62(批次四)落地与三条当次裁定:① 渐进装载的页大小不归前端定——台账装载链查询串不带 pageSize,由后端契约默认值说了算(前端硬编码 500 就是第二份口径,后端改默认值时前端会悄悄要错页);装载器只在响应里读回它用于读数。② 快照 token 只认响应回显——/monitoring/distribution 此前 page>1 强制要 snapshotAt 却从不回显(前端只能猜时间戳),维护者裁定本票连同后端补齐回显(data.snapshotAt,与 map-snapshot 同形);装载器缺 token 时停链报 snapshot-token-missing,绝不拿猜的值去换 400。③ 周期刷新不重放全链(票 33 教训):台账已 settled 时,新鲜度 tick 走 reuseLedgerSnapshot() 一个请求都不发;未 settled 且未失败才补完剩余批次——「定时刷新不复位页码」(条文 6)在渐进装载上的对应形态就是「不重放、不重置已装载集合」。另记:「加载下一页监测点」按钮与 ledger-more 接缝随本票退役,台账的「还有没有下一批」由页脚 已装载 M · 共 N 条(含未关联设备) 如实说明。
  • 2026-10-22 票 62 追加需求(维护者当日二次裁定):运行概况展示设备台账,不展示异常设备清单。原状:运行概况借用 /monitoring/situation 的 abnormalEquipment[] 画「异常设备清单」——那张清单只装 WARNING/ALARM/EXPIRED/OFFLINE 四态设备(实测 8 台),不是台账、条数也与设备总数对不上。维护者要求按真实数据展示9 台监测设备的台账。裁定:后端 /monitoring/overview 回出逐设备 devices[](该服务 build() 里本就组装了 selectedDevices,只用于算 createdAt 与 counts.equipmentCount,未回响应);前端运行概况改读这一份。口径纪律:台账行数恒等于 counts.equipmentCount(同一次遍历产出,不是第二个口径),筛选生效时两者同步收窄;每行 deviceCode/deviceName/deviceType{code,name}/industry/monitoringState/monitoringPointCode/sampledAt/createdAt,缺值一律 null(不拿编码冒充名称、不填 0);异常口径不丢(指标状态分布、预警/报警趋势、离线说明仍在),只是不再拿它当台账。分页口径不变:前端集合分页 10/页、页码直达,一页不画控件。
  • 2026-10-22 票 63(批次五)落地与两条当次记录:① 应急保障三段(危险源/防护目标/应急资源)接前端集合分页,三段共用 emergencySectionBlock 一处声明 ⇒ 行为一致、不各写一份;各自独立页码:pageScope = 段码|条数|段状态(标量键;条数也入键 ⇒ 换类别导致集合变短时页码槽跟着换、越界自然回第 1 页)。实测校准:2026-10-22 线上 protectionTargets 20 条(两页,此前一屏 20 张卡)、emergencyResources 9 条、hazardSources 0 条(EMPTY),totalObjectCount = 29 —— 与本规范首版记的「8+0+20=28」略有出入(现网增长,totals 口径随之变),分页必要性因此由真实数据直接证明,不必再靠 mock 灌数就「有没有增长空间」这一点争论。② mock 静态样例仍不扩面(维护者 2026-10-19 裁定第 3 条):contractMocks 的三段合计仅 4 条(1/1/2)⇒ 按条文 4 正确地不画控件,这是预期行为;多页行为由 t63 闸门用真实量级载荷(0/20/9)证明。排除项(管理信息「片区 × 行业明细」、预警分析「重点识别」)未顺手接入,t63 的 S4 守卫钉住这条边界。