File size: 2,832 Bytes
954be92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1891530
954be92
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
数据模型定义
使用 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