"""基础响应模式""" from typing import Generic, TypeVar, Optional, Any, List from pydantic import BaseModel, Field from datetime import datetime DataT = TypeVar("DataT") class ResponseModel(BaseModel, Generic[DataT]): """ 统一响应格式模型 """ code: int = Field(default=200, description="响应状态码") message: str = Field(default="success", description="响应消息") data: Optional[DataT] = Field(default=None, description="响应数据") request_id: Optional[str] = Field(default=None, description="请求ID") class BaseSchema(BaseModel): """基础模式""" class Config: from_attributes = True # Pydantic V2 json_encoders = {datetime: lambda v: v.isoformat()} class TimestampMixin(BaseModel): """时间戳混入""" created_at: datetime updated_at: datetime class IDMixin(BaseModel): """ID混入""" id: int class PaginationParams(BaseModel): """分页参数""" page: int = Field(default=1, ge=1, description="页码") page_size: int = Field(default=20, ge=1, le=100, description="每页数量") @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[DataT]): """分页响应模型""" items: list[DataT] = Field(default_factory=list, description="数据列表") total: int = Field(default=0, description="总数量") page: int = Field(default=1, description="当前页码") page_size: int = Field(default=20, description="每页数量") pages: int = Field(default=1, description="总页数") @classmethod def create(cls, items: list[DataT], total: int, page: int, page_size: int): """创建分页响应""" pages = (total + page_size - 1) // page_size if page_size > 0 else 1 return cls( items=items, total=total, page=page, page_size=page_size, pages=pages )