63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
|
|
"""统一响应模型。
|
|||
|
|
|
|||
|
|
所有接口响应体形如 `{code, message, data}`(PROJECT_STANDARDS 第 3 节)。
|
|||
|
|
分页响应字段为 `list/total/pageNum/pageSize`(同规范第 14 节)。
|
|||
|
|
|
|||
|
|
字段名采用驼峰(规范约定)而 Python 属性用蛇形(语言惯例),
|
|||
|
|
两者通过 pydantic 的 alias 映射,序列化时输出驼峰。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|||
|
|
|
|||
|
|
from app.core.constants import CODE_SUCCESS
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ApiResponse[T](BaseModel):
|
|||
|
|
"""统一响应包装。泛型参数为 `data` 的类型。"""
|
|||
|
|
|
|||
|
|
code: int = Field(default=CODE_SUCCESS, description="状态码,与 HTTP 状态码一致")
|
|||
|
|
message: str = Field(default="success", description="提示信息")
|
|||
|
|
data: T | None = Field(default=None, description="业务数据")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def ok[T](data: T | None = None, message: str = "success") -> ApiResponse[T]:
|
|||
|
|
"""构造成功响应。
|
|||
|
|
|
|||
|
|
统一出口便于日后调整成功码或附加字段时只改一处。
|
|||
|
|
"""
|
|||
|
|
return ApiResponse(code=CODE_SUCCESS, message=message, data=data)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class PageResult[T](BaseModel):
|
|||
|
|
"""分页结果。
|
|||
|
|
|
|||
|
|
Python 侧使用蛇形属性名,序列化后输出规范要求的驼峰字段名。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
model_config = ConfigDict(populate_by_name=True)
|
|||
|
|
|
|||
|
|
records: list[T] = Field(
|
|||
|
|
default_factory=list, alias="list", serialization_alias="list", description="当前页数据"
|
|||
|
|
)
|
|||
|
|
total: int = Field(default=0, description="总记录数")
|
|||
|
|
page_num: int = Field(
|
|||
|
|
default=1, alias="pageNum", serialization_alias="pageNum", description="当前页码"
|
|||
|
|
)
|
|||
|
|
page_size: int = Field(
|
|||
|
|
default=10, alias="pageSize", serialization_alias="pageSize", description="每页条数"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class PageQuery(BaseModel):
|
|||
|
|
"""分页查询入参基类。业务查询参数继承本类扩展。"""
|
|||
|
|
|
|||
|
|
model_config = ConfigDict(populate_by_name=True)
|
|||
|
|
|
|||
|
|
page_num: int = Field(default=1, ge=1, alias="pageNum", description="页码,从 1 开始")
|
|||
|
|
page_size: int = Field(default=10, ge=1, le=200, alias="pageSize", description="每页条数")
|
|||
|
|
|
|||
|
|
@property
|
|||
|
|
def offset(self) -> int:
|
|||
|
|
"""转换为 SQL OFFSET。"""
|
|||
|
|
return (self.page_num - 1) * self.page_size
|