Files
zcglxt/backend_new/app/core/response.py

153 lines
3.9 KiB
Python

"""
统一响应封装模块
"""
from typing import Any, Generic, TypeVar, Optional, List
from pydantic import BaseModel, Field
from datetime import datetime
# 泛型类型变量
T = TypeVar("T")
class ResponseModel(BaseModel, Generic[T]):
"""统一响应模型"""
code: int = Field(default=200, description="响应状态码")
message: str = Field(default="success", description="响应消息")
data: Optional[T] = Field(default=None, description="响应数据")
timestamp: int = Field(default_factory=lambda: int(datetime.now().timestamp()), description="时间戳")
@classmethod
def success(cls, data: Optional[T] = None, message: str = "success") -> "ResponseModel[T]":
"""
成功响应
Args:
data: 响应数据
message: 响应消息
Returns:
ResponseModel: 响应对象
"""
return cls(code=200, message=message, data=data)
@classmethod
def error(
cls,
code: int,
message: str,
data: Optional[T] = None
) -> "ResponseModel[T]":
"""
错误响应
Args:
code: 错误码
message: 错误消息
data: 附加数据
Returns:
ResponseModel: 响应对象
"""
return cls(code=code, message=message, data=data)
class PaginationMeta(BaseModel):
"""分页元数据"""
total: int = Field(..., description="总记录数")
page: int = Field(..., ge=1, description="当前页码")
page_size: int = Field(..., ge=1, le=100, description="每页记录数")
total_pages: int = Field(..., ge=0, description="总页数")
class PaginatedResponse(BaseModel, Generic[T]):
"""分页响应模型"""
total: int = Field(..., description="总记录数")
page: int = Field(..., ge=1, description="当前页码")
page_size: int = Field(..., ge=1, description="每页记录数")
total_pages: int = Field(..., ge=0, description="总页数")
items: List[T] = Field(default_factory=list, description="数据列表")
class ValidationError(BaseModel):
"""验证错误详情"""
field: str = Field(..., description="字段名")
message: str = Field(..., description="错误消息")
class ErrorResponse(BaseModel):
"""错误响应模型"""
code: int = Field(..., description="错误码")
message: str = Field(..., description="错误消息")
errors: Optional[List[ValidationError]] = Field(default=None, description="错误详情列表")
timestamp: int = Field(default_factory=lambda: int(datetime.now().timestamp()), description="时间戳")
def success_response(data: Any = None, message: str = "success") -> dict:
"""
生成成功响应
Args:
data: 响应数据
message: 响应消息
Returns:
dict: 响应字典
"""
return ResponseModel.success(data=data, message=message).model_dump()
def error_response(code: int, message: str, errors: Optional[List[dict]] = None) -> dict:
"""
生成错误响应
Args:
code: 错误码
message: 错误消息
errors: 错误详情列表
Returns:
dict: 响应字典
"""
error_data = ErrorResponse(
code=code,
message=message,
errors=[ValidationError(**e) for e in errors] if errors else None
)
return error_data.model_dump()
def paginated_response(
items: List[Any],
total: int,
page: int,
page_size: int
) -> dict:
"""
生成分页响应
Args:
items: 数据列表
total: 总记录数
page: 当前页码
page_size: 每页记录数
Returns:
dict: 响应字典
"""
total_pages = (total + page_size - 1) // page_size if page_size > 0 else 0
response = PaginatedResponse(
total=total,
page=page,
page_size=page_size,
total_pages=total_pages,
items=items
)
return success_response(data=response.model_dump())