PayrollManagementSystem/backend/app/core/response.py

63 lines
2.2 KiB
Python
Raw Normal View History

"""统一响应模型。
所有接口响应体形如 `{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