import json from datetime import datetime from pathlib import Path from typing import Optional, Dict, Any, List from pydantic import BaseModel, field_validator from enum import Enum class ImageType(str, Enum): front_face = "front_face" back_face = "back_face" front_edge = "front_edge" back_edge = "back_edge" class CardType(str, Enum): pokemon = "pokemon" basketball = "basketball" baseball = "baseball" # 用于指定要更新哪个结果图片路径的枚举 class ResultImagePathType(str, Enum): detection = "detection" modified = "modified" # 用于排序的 class SortBy(str, Enum): # NEW card_name = "card_name" created_at = "created_at" updated_at = "updated_at" detection_score = "detection_score" modified_score = "modified_score" class SortOrder(str, Enum): # NEW asc = "ASC" desc = "DESC" # "图片类型和计算分数分数类型映射表" IMAGE_TYPE_TO_SCORE_TYPE = { "front_face": "front_face", "back_face": "back_face", "front_edge": "front_corner_edge", "back_edge": "back_corner_edge", } # --- Pydantic 数据模型 --- class CardImageResponse(BaseModel): """用于API响应的图片数据模型 (主键为 id)""" id: int card_id: int image_type: str image_name: Optional[str] = None image_path: str detection_image_path: Optional[str] = None modified_image_path: Optional[str] = None detection_json: Dict[str, Any] modified_json: Optional[Dict[str, Any]] = None is_edited: bool created_at: datetime updated_at: datetime 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 CardDetailResponse(BaseModel): """用于响应单个卡牌详细信息的模型 (主键为 id)""" id: int card_name: Optional[str] = None created_at: datetime updated_at: datetime card_type: str is_edited: bool detection_score: Optional[float] = None modified_score: Optional[float] = None detection_score_detail: Optional[Dict[str, Any]] = None modified_score_detail: Optional[Dict[str, Any]] = None images: List[CardImageResponse] = [] class Config: from_attributes = True class ImageJsonPairResponse(BaseModel): """用于获取单个图片两个JSON数据的响应模型 (主键为 id)""" id: int 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 CardImageInListResponse(BaseModel): """为卡牌列表接口定义的简化版图片响应模型""" id: int image_type: str image_path: str detection_image_path: Optional[str] = None modified_image_path: Optional[str] = None class Config: from_attributes = True class CardListDetailResponse(BaseModel): """为新的卡牌列表接口定义的响应模型""" id: int card_name: Optional[str] = None card_type: str detection_score: Optional[float] = None modified_score: Optional[float] = None is_edited: bool created_at: datetime updated_at: datetime image_path_list: Dict[str, Optional[str]] = {} detection_image_path_list: Dict[str, Optional[str]] = {} modified_image_path_list: Dict[str, Optional[str]] = {} class Config: from_attributes = True