65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
"""统一响应格式"""
|
|
from typing import Any, Generic, Optional, TypeVar, List
|
|
from pydantic import BaseModel, Field
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
class ResponseModel(BaseModel, Generic[T]):
|
|
"""通用响应格式"""
|
|
code: int = 200
|
|
message: str = "success"
|
|
data: Optional[T] = None
|
|
timestamp: int = 0
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class PageResult(BaseModel, Generic[T]):
|
|
"""分页响应格式"""
|
|
items: List[T] = Field(default_factory=list, serialization_alias="list")
|
|
total: int = 0
|
|
page: int = 1
|
|
pageSize: int = 10
|
|
totalPages: int = 0
|
|
|
|
|
|
def success_response(data: Any = None, message: str = "success") -> dict:
|
|
"""成功响应"""
|
|
from datetime import datetime
|
|
return {
|
|
"code": 200,
|
|
"message": message,
|
|
"data": data,
|
|
"timestamp": int(datetime.now().timestamp() * 1000)
|
|
}
|
|
|
|
|
|
def format_api_error_message(exc: Exception, *, fallback: str = "操作失败") -> str:
|
|
"""将 HTTP/SQLAlchemy 等异常转为可展示的错误文案(避免 str([]) 空列表)。"""
|
|
if isinstance(exc, PermissionError):
|
|
return str(exc) or fallback
|
|
status_code = getattr(exc, "status_code", None)
|
|
if status_code is not None:
|
|
detail = getattr(exc, "detail", None)
|
|
if isinstance(detail, str) and detail.strip():
|
|
return detail
|
|
if detail not in (None, "", []):
|
|
return str(detail)
|
|
msg = str(exc).strip()
|
|
if msg and msg != "[]":
|
|
return msg
|
|
return fallback
|
|
|
|
|
|
def error_response(code: int = 400, message: str = "error", data: Any = None) -> dict:
|
|
"""错误响应"""
|
|
from datetime import datetime
|
|
return {
|
|
"code": code,
|
|
"message": message,
|
|
"data": data,
|
|
"timestamp": int(datetime.now().timestamp() * 1000)
|
|
}
|