""" 模型数据传输对象定义(新表结构) """ from datetime import datetime from typing import Any, Generic, List, Optional, TypeVar from decimal import Decimal from pydantic import BaseModel, ConfigDict T = TypeVar("T") class ModelPriceNewResponse(BaseModel): """单条价格记录响应""" id: int label: str tier_min: Optional[Decimal] = None tier_max: Optional[Decimal] = None tier_unit: Optional[str] = None input_price_original: Decimal output_price_original: Decimal discount_rate: Decimal discount_label: Optional[str] = None # 如 "1折"、"5折" input_price_discounted: Decimal output_price_discounted: Decimal currency: str = "CNY" unit: str display_multiplier: int = 1000000 model_config = ConfigDict(from_attributes=True) class ModelResponse(BaseModel): """模型详情响应""" id: int model_code: str display_name: Optional[str] = None img: Optional[str] = None tag1: Optional[str] = None tag2: Optional[str] = None description: Optional[str] = None custom_description: Optional[str] = None keywords: Optional[str] = None display_tags: Optional[List[str]] = None input_modalities: Optional[List[str]] = None output_modalities: Optional[List[str]] = None features: Optional[Any] = None rate_limits: Optional[Any] = None tool_call_prices: Optional[Any] = None categories: List[int] = [] category: Optional[int] = None # 兼容字段,取 categories[0] supplier: str is_featured: bool = False is_search: bool = False is_thinking: bool = False is_api_enabled: bool = False is_show_enabled: bool = True source_url: Optional[str] = None crawled_at: Optional[datetime] = None created_at: datetime updated_at: datetime # 前端兼容字段 title: Optional[str] = None # = model_code name: Optional[str] = None # = display_name keyword: Optional[str] = None # = keywords model_config = ConfigDict(from_attributes=True) class ModelListResponse(BaseModel): """模型列表响应(含价格)""" id: int model_code: str display_name: Optional[str] = None img: Optional[str] = None tag1: Optional[str] = None tag2: Optional[str] = None description: Optional[str] = None custom_description: Optional[str] = None keywords: Optional[str] = None display_tags: Optional[List[str]] = None categories: List[int] = [] category: Optional[int] = None # 兼容字段,取 categories[0] supplier: str is_featured: bool = False is_search: bool = False is_thinking: bool = False is_api_enabled: bool = False is_show_enabled: bool = True created_at: datetime updated_at: datetime # 前端兼容字段(旧字段名映射) title: Optional[str] = None # = model_code name: Optional[str] = None # = display_name keyword: Optional[str] = None # = keywords # 价格列表(is_active=true 的所有记录) prices: List[ModelPriceNewResponse] = [] model_config = ConfigDict(from_attributes=True) class PaginatedResponse(BaseModel, Generic[T]): """分页响应""" total: int page: int page_size: int items: List[T] class ApiResponse(BaseModel, Generic[T]): """统一API响应""" code: int message: str data: Optional[T] = None class KeywordsResponse(BaseModel): keywords: List[str] class FeaturedModelsResponse(BaseModel): items: List[ModelListResponse] class ModelPricingResponse(BaseModel): """模型定价信息(用于 /pricing/{model_code} 端点)""" model_code: str display_name: Optional[str] = None description: Optional[str] = None custom_description: Optional[str] = None features: Optional[Any] = None rate_limits: Optional[Any] = None tool_call_prices: Optional[Any] = None display_tags: Optional[List[str]] = None input_modalities: Optional[List[str]] = None output_modalities: Optional[List[str]] = None categories: List[int] = [] source_keys: Optional[List[str]] = None normalized_keys: Optional[List[str]] = None is_api_enabled: bool = False prices: List[ModelPriceNewResponse] = []