task-111(任务与重复分析中心): 实现店铺数据任务分页刷新

新增 shop-data-list-state.ts:店铺数据任务分页信息派生与可批量选择结果行
(result_id)展平,供后续批量下载复用。

TDD: task-111.test.ts 8 用例先 RED 后 GREEN。
This commit is contained in:
2026-09-05 17:18:47 +08:00
parent cb1490ccc2
commit 137af44ae8
2 changed files with 118 additions and 0 deletions
@@ -0,0 +1,54 @@
/** 店铺数据任务列表分页与选择派生(任务 111/112):分页信息 + 可批量选择的结果行,纯逻辑。 */
import { SHOP_DATA_DEFAULT_PAGE_SIZE, SHOP_DATA_MAX_PAGE_SIZE, SHOP_DATA_PAGE_MIN } from './shop-data-filter.ts'
import type { ShopDataTaskGroup } from './shop-data-model.ts'
export interface ShopDataPageInfo {
page: number
pageSize: number
total: number
totalPages: number
from: number
to: number
hasPrev: boolean
hasNext: boolean
}
function finiteInt(value: unknown): number | null {
return typeof value === 'number' && Number.isFinite(value) ? Math.floor(value) : null
}
/** 由总数与目标分页派生页码信息;空数据视为第 1 页。 */
export function shopDataPageInfo(page: unknown, pageSize: unknown, total: unknown): ShopDataPageInfo {
const rawSize = finiteInt(pageSize)
const size =
rawSize === null || rawSize < 1
? SHOP_DATA_DEFAULT_PAGE_SIZE
: Math.min(Math.max(rawSize, 10), SHOP_DATA_MAX_PAGE_SIZE)
const safeTotal = Math.max(finiteInt(total) ?? 0, 0)
const totalPages = safeTotal === 0 ? 1 : Math.max(1, Math.ceil(safeTotal / size))
const requested = Math.max(finiteInt(page) ?? SHOP_DATA_PAGE_MIN, SHOP_DATA_PAGE_MIN)
const safePage = Math.min(requested, totalPages)
const from = safeTotal === 0 ? 0 : (safePage - 1) * size + 1
const to = Math.min(safeTotal, safePage * size)
return {
page: safePage,
pageSize: size,
total: safeTotal,
totalPages,
from,
to,
hasPrev: safePage > 1,
hasNext: safePage < totalPages && safeTotal > 0,
}
}
/** 展平本页所有可选中的结果行(result_id),供批量下载/勾选;缺行忽略。 */
export function selectableResultRows(groups: readonly ShopDataTaskGroup[]): string[] {
const ids: string[] = []
for (const group of groups) {
for (const row of group.results) {
if (row.resultId) ids.push(row.resultId)
}
}
return ids
}