You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
5.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
Pydantic Schemas - 请求/响应数据验证
"""
from datetime import datetime
from typing import Optional, List
from pydantic import BaseModel, Field, EmailStr
# ==================== 通用响应 ====================
class ResponseBase(BaseModel):
"""基础响应"""
code: int = 0
message: str = "success"
class ResponseData(ResponseBase):
"""带数据的响应"""
data: Optional[dict] = None
class ResponseList(ResponseBase):
"""带列表的响应"""
data: List[dict] = []
total: int = 0
page: int = 1
page_size: int = 10
# ==================== 认证相关 ====================
class LoginRequest(BaseModel):
"""登录请求"""
username: str = Field(..., min_length=3, max_length=50)
password: str = Field(..., min_length=6)
class TokenResponse(BaseModel):
"""令牌响应"""
access_token: str
refresh_token: str
token_type: str = "Bearer"
expires_in: int = 3600
class RefreshTokenRequest(BaseModel):
"""刷新令牌请求"""
refresh_token: str
# ==================== 用户相关 ====================
class UserBase(BaseModel):
"""用户基础信息"""
username: str = Field(..., min_length=3, max_length=50)
email: Optional[EmailStr] = None
class UserCreate(UserBase):
"""创建用户"""
password: str = Field(..., min_length=6)
class UserResponse(UserBase):
"""用户响应"""
id: int
role: str
is_active: bool
created_at: datetime
class Config:
from_attributes = True
class UserUpdate(BaseModel):
"""更新用户"""
email: Optional[EmailStr] = None
password: Optional[str] = Field(None, min_length=6)
# ==================== K 线数据相关 ====================
class KlineRequest(BaseModel):
"""K 线数据查询请求"""
symbol: str = Field(..., description="品种代码,如 IF2406")
period: str = Field(..., description="周期,如 1m, 5m, 1h, 1d")
start: datetime
end: datetime
class KlineDataItem(BaseModel):
"""单条 K 线数据"""
time: datetime
open: float
high: float
low: float
close: float
volume: int
amount: Optional[float] = None
open_interest: Optional[int] = None
class KlineResponse(ResponseBase):
"""K 线数据响应"""
data: List[KlineDataItem] = []
symbol: str
period: str
# ==================== 实时行情相关 ====================
class RealtimeQuoteItem(BaseModel):
"""实时行情数据"""
time: datetime
symbol: str
last_price: float
open_price: Optional[float] = None
high_price: Optional[float] = None
low_price: Optional[float] = None
prev_close: Optional[float] = None
volume: Optional[int] = None
amount: Optional[float] = None
bid_price_1: Optional[float] = None
bid_volume_1: Optional[int] = None
ask_price_1: Optional[float] = None
ask_volume_1: Optional[int] = None
position: Optional[int] = None
change_percent: Optional[float] = None # 涨跌幅
class SubscribeRequest(BaseModel):
"""订阅请求"""
symbols: List[str] = Field(..., description="品种代码列表")
class UnsubscribeRequest(BaseModel):
"""取消订阅请求"""
symbols: List[str] = Field(..., description="品种代码列表")
# ==================== 告警相关 ====================
class AlertBase(BaseModel):
"""告警基础信息"""
symbol: str = Field(..., description="品种代码")
condition_type: str = Field(..., description="条件类型greater_than, less_than, equals")
condition_value: float = Field(..., description="条件值")
alert_type: str = Field(default="price", description="告警类型price, percent_change")
class AlertCreate(AlertBase):
"""创建告警"""
pass
class AlertResponse(AlertBase):
"""告警响应"""
id: int
user_id: int
status: str
triggered_at: Optional[datetime] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class AlertUpdate(BaseModel):
"""更新告警"""
condition_value: Optional[float] = None
status: Optional[str] = None
# ==================== 订阅相关 ====================
class SubscriptionBase(BaseModel):
"""订阅基础信息"""
symbol: str = Field(..., description="品种代码")
period: Optional[str] = Field(None, description="周期")
subscription_type: str = Field(default="kline", description="订阅类型kline, realtime")
class SubscriptionCreate(SubscriptionBase):
"""创建订阅"""
pass
class SubscriptionResponse(SubscriptionBase):
"""订阅响应"""
id: int
user_id: int
is_active: bool
created_at: datetime
class Config:
from_attributes = True
# ==================== API Key 相关 ====================
class APIKeyCreate(BaseModel):
"""创建 API Key"""
name: Optional[str] = None
permissions: Optional[List[str]] = None
expires_days: Optional[int] = None # 过期天数
class APIKeyResponse(BaseModel):
"""API Key 响应"""
id: int
name: Optional[str]
key: str # 仅创建时返回
permissions: Optional[List[str]]
expires_at: Optional[datetime]
is_active: bool
created_at: datetime
class Config:
from_attributes = True
# ==================== 分页参数 ====================
class PageParams(BaseModel):
"""分页参数"""
page: int = Field(1, ge=1)
page_size: int = Field(10, ge=1, le=100)