Files
meijiaka-zy/python-api/app/schemas/common.py
T

79 lines
2.1 KiB
Python

"""
通用响应格式 Schema
==================
与前端 ApiResponse<T> 保持一致:
{ code: number; data: T; message: string }
"""
from typing import Any, Generic, TypeVar
from pydantic import BaseModel, Field
T = TypeVar("T")
class ApiResponse(BaseModel, Generic[T]):
"""
统一 API 响应格式
Attributes:
code: HTTP 状态码(200 表示成功)
data: 响应数据(泛型)
message: 提示信息
"""
code: int = Field(default=200, description="状态码,200 表示成功")
data: T | None = Field(default=None, description="响应数据")
message: str = Field(default="success", description="提示信息")
class Config:
json_schema_extra = {
"example": {
"code": 200,
"data": {},
"message": "success",
}
}
class PaginatedData(BaseModel, Generic[T]):
"""分页数据包装"""
items: list[T] = Field(description="数据列表")
total: int = Field(description="总数")
page: int = Field(description="当前页码")
page_size: int = Field(description="每页数量")
has_more: bool = Field(description="是否有更多")
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
class ApiErrorResponse(BaseModel):
"""错误响应格式"""
code: int = Field(description="错误码")
message: str = Field(description="错误信息")
detail: dict[str, Any] | None = Field(default=None, description="详细错误信息")
def success_response(data: T | None = None, message: str = "success") -> ApiResponse[T]:
"""构造成功响应"""
return ApiResponse(code=200, data=data, message=message)
def error_response(
code: int, message: str, detail: dict[str, Any] | None = None
) -> ApiErrorResponse:
"""构造错误响应"""
return ApiErrorResponse(code=code, message=message, detail=detail)