scheme.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import json
  2. from datetime import datetime
  3. from pathlib import Path
  4. from typing import Optional, Dict, Any, List
  5. from pydantic import BaseModel, field_validator
  6. from enum import Enum
  7. class ImageType(str, Enum):
  8. front_face = "front_face"
  9. back_face = "back_face"
  10. front_edge = "front_edge"
  11. back_edge = "back_edge"
  12. class CardType(str, Enum):
  13. pokemon = "pokemon"
  14. basketball = "basketball"
  15. baseball = "baseball"
  16. # 用于指定要更新哪个结果图片路径的枚举
  17. class ResultImagePathType(str, Enum):
  18. detection = "detection"
  19. modified = "modified"
  20. # 用于排序的
  21. class SortBy(str, Enum): # NEW
  22. card_name = "card_name"
  23. created_at = "created_at"
  24. updated_at = "updated_at"
  25. detection_score = "detection_score"
  26. modified_score = "modified_score"
  27. class SortOrder(str, Enum): # NEW
  28. asc = "ASC"
  29. desc = "DESC"
  30. # "图片类型和计算分数分数类型映射表"
  31. IMAGE_TYPE_TO_SCORE_TYPE = {
  32. "front_face": "front_face",
  33. "back_face": "back_face",
  34. "front_edge": "front_corner_edge",
  35. "back_edge": "back_corner_edge",
  36. }
  37. # --- Pydantic 数据模型 ---
  38. class CardImageResponse(BaseModel):
  39. """用于API响应的图片数据模型 (主键为 id)"""
  40. id: int
  41. card_id: int
  42. image_type: str
  43. image_name: Optional[str] = None
  44. image_path: str
  45. detection_image_path: Optional[str] = None
  46. modified_image_path: Optional[str] = None
  47. detection_json: Dict[str, Any]
  48. modified_json: Optional[Dict[str, Any]] = None
  49. is_edited: bool
  50. created_at: datetime
  51. updated_at: datetime
  52. class Config:
  53. from_attributes = True
  54. @field_validator('detection_json', 'modified_json', mode='before')
  55. @classmethod
  56. def parse_json_string(cls, v):
  57. if v is None:
  58. return None
  59. if isinstance(v, str):
  60. try:
  61. return json.loads(v)
  62. except json.JSONDecodeError:
  63. raise ValueError("Invalid JSON string in database")
  64. return v
  65. class CardDetailResponse(BaseModel):
  66. """用于响应单个卡牌详细信息的模型 (主键为 id)"""
  67. id: int
  68. id_prev: Optional[int] = None
  69. id_next: Optional[int] = None
  70. card_name: Optional[str] = None
  71. created_at: datetime
  72. updated_at: datetime
  73. card_type: str
  74. is_edited: bool
  75. detection_score: Optional[float] = None
  76. modified_score: Optional[float] = None
  77. detection_score_detail: Optional[Dict[str, Any]] = None
  78. modified_score_detail: Optional[Dict[str, Any]] = None
  79. images: List[CardImageResponse] = []
  80. class Config:
  81. from_attributes = True
  82. class ImageJsonPairResponse(BaseModel):
  83. """用于获取单个图片两个JSON数据的响应模型 (主键为 id)"""
  84. id: int
  85. detection_json: Dict[str, Any]
  86. modified_json: Optional[Dict[str, Any]] = None
  87. class Config:
  88. from_attributes = True
  89. @field_validator('detection_json', 'modified_json', mode='before')
  90. @classmethod
  91. def parse_json_string(cls, v):
  92. if v is None:
  93. return None
  94. if isinstance(v, str):
  95. try:
  96. return json.loads(v)
  97. except json.JSONDecodeError:
  98. raise ValueError("Invalid JSON string in database")
  99. return v
  100. class CardImageInListResponse(BaseModel):
  101. """为卡牌列表接口定义的简化版图片响应模型"""
  102. id: int
  103. image_type: str
  104. image_path: str
  105. detection_image_path: Optional[str] = None
  106. modified_image_path: Optional[str] = None
  107. class Config:
  108. from_attributes = True
  109. class CardListDetailResponse(BaseModel):
  110. """为新的卡牌列表接口定义的响应模型"""
  111. id: int
  112. card_name: Optional[str] = None
  113. card_type: str
  114. detection_score: Optional[float] = None
  115. modified_score: Optional[float] = None
  116. is_edited: bool
  117. created_at: datetime
  118. updated_at: datetime
  119. image_path_list: Dict[str, Optional[str]] = {}
  120. detection_image_path_list: Dict[str, Optional[str]] = {}
  121. modified_image_path_list: Dict[str, Optional[str]] = {}
  122. class Config:
  123. from_attributes = True