"""通用分页与过滤工具,供各 API 路由复用。""" from typing import Generic, TypeVar from fastapi import Query from pydantic import BaseModel, computed_field T = TypeVar("T") class PaginationParams: """依赖注入式分页参数(可直接用于 Depends)。""" def __init__( self, page: int = Query(1, ge=1, description="页码,从 1 开始"), page_size: int = Query(20, ge=1, le=100, description="每页条数"), ): self.page = page self.page_size = page_size @property def offset(self) -> int: return (self.page - 1) * self.page_size @property def limit(self) -> int: return self.page_size class PaginatedResponse(BaseModel, Generic[T]): """通用分页响应结构。""" items: list[T] total: int page: int page_size: int @computed_field # type: ignore[misc] @property def total_pages(self) -> int: if self.page_size == 0: return 0 import math return math.ceil(self.total / self.page_size) model_config = {"from_attributes": True}