import json from datetime import datetime from pathlib import Path from typing import Optional, Dict, Any, List from pydantic import BaseModel, field_validator # --- Pydantic 数据模型 --- class CardImageResponse(BaseModel): """用于API响应的图片数据模型 (主键为 id)""" id: int card_id: int image_type: str image_name: Optional[str] = None image_path: str detection_json: Dict[str, Any] modified_json: Optional[Dict[str, Any]] = None created_at: datetime updated_at: datetime class Config: from_attributes = True @field_validator('image_path', mode='before') @classmethod def format_image_path(cls, v:str): """将绝对文件路径转换为 'Data/filename.jpg' 格式的相对URL路径""" if not isinstance(v, str) or not v: return v p = Path(v) relative_path = f"{p.parent.name}/{p.name}" return relative_path @field_validator('detection_json', 'modified_json', mode='before') @classmethod def parse_json_string(cls, v): if v is None: return None if isinstance(v, str): try: return json.loads(v) except json.JSONDecodeError: raise ValueError("Invalid JSON string in database") return v class CardDetailResponse(BaseModel): """用于响应单个卡牌详细信息的模型 (主键为 id)""" id: int card_name: Optional[str] = None created_at: datetime updated_at: datetime images: List[CardImageResponse] = [] class Config: from_attributes = True class ImageJsonPairResponse(BaseModel): """用于获取单个图片两个JSON数据的响应模型 (主键为 id)""" id: int # 原 image_id detection_json: Dict[str, Any] modified_json: Optional[Dict[str, Any]] = None class Config: from_attributes = True @field_validator('detection_json', 'modified_json', mode='before') @classmethod def parse_json_string(cls, v): if v is None: return None if isinstance(v, str): try: return json.loads(v) except json.JSONDecodeError: raise ValueError("Invalid JSON string in database") return v class CardListDetailResponse(BaseModel): """为新的卡牌列表接口定义的响应模型 (主键为 id)""" id: int # 原 card_id card_name: Optional[str] = None created_at: datetime updated_at: datetime class Config: from_attributes = True