"""bx 原系统 API 响应包装(code=0 / msg / data.rows),与门户 success_response 分离。""" from datetime import date, datetime from typing import Annotated, Generic, List, Optional, TypeVar from pydantic import BaseModel, ConfigDict, PlainSerializer from pydantic.alias_generators import to_camel T = TypeVar("T") def _dt_to_str(v: Optional[datetime]) -> Optional[str]: if v is None: return None return v.strftime("%Y-%m-%d %H:%M:%S") def _date_to_str(v: Optional[date]) -> Optional[str]: if v is None: return None return v.strftime("%Y-%m-%d") DatetimeToStr = Annotated[datetime, PlainSerializer(_dt_to_str, return_type=str)] OptDatetimeToStr = Annotated[Optional[datetime], PlainSerializer(_dt_to_str, return_type=Optional[str])] DateToStr = Annotated[date, PlainSerializer(_date_to_str, return_type=str)] OptDateToStr = Annotated[Optional[date], PlainSerializer(_date_to_str, return_type=Optional[str])] class PagedQuery(BaseModel): model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel) page: int = 1 page_size: int = 10 class ApiResponse(BaseModel, Generic[T]): code: int = 0 msg: str = "success" data: Optional[T] = None class PagedData(BaseModel, Generic[T]): model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel) rows: List[T] total: int page: int page_size: int class PagedResponse(BaseModel, Generic[T]): code: int = 0 msg: str = "success" data: Optional[PagedData[T]] = None