"""统一响应格式""" 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) }