提供基本前后端骨架
This commit is contained in:
102
app/schemas/base.py
Normal file
102
app/schemas/base.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
基础 Schema 定义
|
||||
|
||||
定义通用的响应模式和基础配置。
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Generic, TypeVar
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
DataT = TypeVar("DataT")
|
||||
|
||||
|
||||
class BaseSchema(BaseModel):
|
||||
"""基础 Schema 配置"""
|
||||
|
||||
model_config = ConfigDict(
|
||||
from_attributes=True, # 支持从 ORM 对象创建
|
||||
populate_by_name=True, # 支持字段别名
|
||||
str_strip_whitespace=True, # 自动去除字符串首尾空白
|
||||
)
|
||||
|
||||
|
||||
class TimestampMixin(BaseModel):
|
||||
"""时间戳混入"""
|
||||
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class APIResponse(BaseModel, Generic[DataT]):
|
||||
"""统一 API 响应格式"""
|
||||
|
||||
success: bool = True
|
||||
message: str = "操作成功"
|
||||
data: DataT | None = None
|
||||
|
||||
@classmethod
|
||||
def ok(cls, data: DataT | None = None, message: str = "操作成功") -> "APIResponse[DataT]":
|
||||
"""成功响应"""
|
||||
return cls(success=True, message=message, data=data)
|
||||
|
||||
@classmethod
|
||||
def error(cls, message: str = "操作失败", data: DataT | None = None) -> "APIResponse[DataT]":
|
||||
"""错误响应"""
|
||||
return cls(success=False, message=message, data=data)
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
"""错误响应"""
|
||||
|
||||
success: bool = False
|
||||
message: str
|
||||
code: str
|
||||
details: dict[str, Any] = {}
|
||||
|
||||
|
||||
class PaginationParams(BaseModel):
|
||||
"""分页参数"""
|
||||
|
||||
page: int = 1
|
||||
page_size: int = 20
|
||||
|
||||
@property
|
||||
def offset(self) -> int:
|
||||
"""计算偏移量"""
|
||||
return (self.page - 1) * self.page_size
|
||||
|
||||
@property
|
||||
def limit(self) -> int:
|
||||
"""获取限制数量"""
|
||||
return self.page_size
|
||||
|
||||
|
||||
class PaginatedResponse(BaseModel, Generic[DataT]):
|
||||
"""分页响应"""
|
||||
|
||||
items: list[DataT]
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
total_pages: int
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
items: list[DataT],
|
||||
total: int,
|
||||
page: int,
|
||||
page_size: int,
|
||||
) -> "PaginatedResponse[DataT]":
|
||||
"""创建分页响应"""
|
||||
total_pages = (total + page_size - 1) // page_size if page_size > 0 else 0
|
||||
return cls(
|
||||
items=items,
|
||||
total=total,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
total_pages=total_pages,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user