task-61(ASIN 数据中心): 定义共享分页和筛选类型

新增 src/pages/asin/asin-filter.ts 纯共享层:AsinListParams 分页+keyword/username/日期区间/
groupId/国家筛选,normalizeAsinPageParams 钳制页码页大小并校验 ISO 日期,toAsinPageQuery
序列化 snake_case(仅下发非空),镜像 DedupeTotalDataController.page 参数契约。
8 用例全过,443 单测 + build 绿。
This commit is contained in:
2026-09-05 15:26:42 +08:00
parent 8e5fc00945
commit 53b4cb52f3
2 changed files with 168 additions and 0 deletions
@@ -0,0 +1,81 @@
/** ASIN 数据中心共享分页/筛选类型(任务 61):与 Java 各列表接口(snake)对齐,纯逻辑。 */
export const ASIN_PAGE_DEFAULT_SIZE = 15
export const ASIN_PAGE_MIN_PAGE = 1
export const ASIN_PAGE_MAX_SIZE = 200
/** ISO 日期(yyyy-MM-dd)或空。 */
export function validIsoDateOrUndefined(value: unknown): string | undefined {
if (typeof value !== 'string') return undefined
const text = value.trim()
return /^\d{4}-\d{2}-\d{2}$/.test(text) ? text : undefined
}
/** ASIN 中心列表页共享筛选/分页状态。 */
export interface AsinListParams {
page: number
pageSize: number
/** 值/商品模糊关键字。 */
keyword?: string
/** 上传用户名模糊搜索。 */
username?: string
startDate?: string
endDate?: string
groupId?: number | null
/** 国家代码(如 DE、UK)。 */
country?: string
}
/** 序列化到 Java 分页接口的查询参数(snake_case)。 */
export interface AsinPageQuery {
page: number
page_size: number
keyword?: string
username?: string
start_date?: string
end_date?: string
group_id?: number
country?: string
}
function finiteInt(value: unknown): number | null {
return typeof value === 'number' && Number.isFinite(value) ? Math.floor(value) : null
}
/** 归一化共享分页/筛选:页码下限 1、页大小 1..上限,空条件视为无筛选。 */
export function normalizeAsinPageParams(raw: Partial<AsinListParams>): AsinListParams {
const page = Math.max(finiteInt(raw.page) ?? ASIN_PAGE_MIN_PAGE, ASIN_PAGE_MIN_PAGE)
const rawSize = finiteInt(raw.pageSize)
const pageSize =
rawSize === null || rawSize < ASIN_PAGE_MIN_PAGE
? ASIN_PAGE_DEFAULT_SIZE
: Math.min(rawSize, ASIN_PAGE_MAX_SIZE)
const textOrUndefined = (value: unknown) =>
typeof value === 'string' && value.trim() ? value.trim() : undefined
const keyword = textOrUndefined(raw.keyword)
const username = textOrUndefined(raw.username)
const country = textOrUndefined(raw.country)
const groupId = finiteInt(raw.groupId)
return {
page,
pageSize,
keyword,
username,
startDate: validIsoDateOrUndefined(raw.startDate),
endDate: validIsoDateOrUndefined(raw.endDate),
groupId: groupId === null || groupId < 1 ? null : groupId,
country,
}
}
/** 前端状态 → Java 查询参数;仅下发非空字段。 */
export function toAsinPageQuery(params: AsinListParams): AsinPageQuery {
const query: AsinPageQuery = { page: params.page, page_size: params.pageSize }
if (params.keyword) query.keyword = params.keyword
if (params.username) query.username = params.username
if (params.startDate) query.start_date = params.startDate
if (params.endDate) query.end_date = params.endDate
if (params.groupId != null) query.group_id = params.groupId
if (params.country) query.country = params.country
return query
}