""" 数据模型定义 使用 Pydantic 进行数据验证 """ from pydantic import BaseModel, Field from typing import Dict, Optional from datetime import datetime # ============== API 响应模型 ============== class ExchangeRateAPIResponse(BaseModel): """外部 API 原始响应模型""" result: str documentation: Optional[str] = None terms_of_use: Optional[str] = None time_last_update_unix: int time_last_update_utc: str time_next_update_unix: int time_next_update_utc: str base_code: str conversion_rates: Dict[str, float] # ============== 缓存数据模型 ============== class CachedRates(BaseModel): """缓存的汇率数据""" base_code: str rates: Dict[str, float] last_update_unix: int last_update_utc: str next_update_utc: str cached_at: datetime = Field(default_factory=datetime.now) # ============== API 请求/响应模型 ============== class RatesResponse(BaseModel): """获取所有汇率的响应""" success: bool base_currency: str rates: Dict[str, float] last_update: str cached_at: str currencies_count: int class CurrencyRateResponse(BaseModel): """获取单个货币汇率的响应""" success: bool base_currency: str currency: str rate: float class ConvertRequest(BaseModel): """汇率换算请求""" from_currency: str = Field(..., min_length=3, max_length=3, description="源货币代码") to_currency: str = Field(..., min_length=3, max_length=3, description="目标货币代码") amount: float = Field(..., gt=0, description="换算金额") class ConvertResponse(BaseModel): """汇率换算响应""" success: bool from_currency: str to_currency: str amount: float result: float rate: float reverse_rate: float class BatchConvertRequest(BaseModel): """批量换算请求""" base_currency: str = Field(..., min_length=3, max_length=3, description="基准货币代码") amount: float = Field(..., gt=0, description="换算金额") class BatchConvertResponse(BaseModel): """批量换算响应""" success: bool base_currency: str amount: float conversions: Dict[str, float] class CurrencyInfo(BaseModel): """货币信息""" code: str name: str name_cn: str symbol: Optional[str] = None class CurrenciesResponse(BaseModel): """货币列表响应""" success: bool currencies: list[CurrencyInfo] class ServiceStatusResponse(BaseModel): """服务状态响应""" status: str cache_valid: bool last_update: Optional[str] = None currencies_count: int api_keys_count: int update_interval_seconds: int class ErrorResponse(BaseModel): """错误响应""" success: bool = False error: str detail: Optional[str] = None