42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
import { Type } from 'class-transformer';
|
|
import { IsInt, IsOptional, Max, Min } from 'class-validator';
|
|
|
|
/** 契约 data-models.md §1:列表接口统一分页参数 */
|
|
export class PageQueryDto {
|
|
@IsOptional()
|
|
@Type(() => Number)
|
|
@IsInt()
|
|
@Min(1)
|
|
page: number = 1;
|
|
|
|
@IsOptional()
|
|
@Type(() => Number)
|
|
@IsInt()
|
|
@Min(1)
|
|
@Max(200)
|
|
pageSize: number = 20;
|
|
|
|
get skip(): number {
|
|
return (this.page - 1) * this.pageSize;
|
|
}
|
|
}
|
|
|
|
export interface Paged<T> {
|
|
items: T[];
|
|
total: number;
|
|
page: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
export function toPaged<T>(items: T[], total: number, query: { page: number; pageSize: number }): Paged<T> {
|
|
return { items, total, page: query.page, pageSize: query.pageSize };
|
|
}
|
|
|
|
/** 规范化分页参数(用于非 DTO 校验路径,如内部调用) */
|
|
export function normalizePaging(page?: number, pageSize?: number, maxPageSize = 200): { page: number; pageSize: number; skip: number } {
|
|
const p = Number.isFinite(page) && (page as number) >= 1 ? Math.floor(page as number) : 1;
|
|
const rawSize = Number.isFinite(pageSize) ? Math.floor(pageSize as number) : 20;
|
|
const size = Math.min(Math.max(rawSize, 1), maxPageSize);
|
|
return { page: p, pageSize: size, skip: (p - 1) * size };
|
|
}
|