from pydantic import BaseModel, EmailStr from typing import Optional, List from datetime import datetime from app.models.models import MembershipType, AccountStatus, KeyStatus # ========== 账号相关 ========== class AccountBase(BaseModel): email: str access_token: str refresh_token: Optional[str] = None workos_session_token: Optional[str] = None membership_type: MembershipType = MembershipType.PRO remark: Optional[str] = None class AccountCreate(AccountBase): pass class AccountUpdate(BaseModel): email: Optional[str] = None access_token: Optional[str] = None refresh_token: Optional[str] = None workos_session_token: Optional[str] = None membership_type: Optional[MembershipType] = None status: Optional[AccountStatus] = None remark: Optional[str] = None class AccountResponse(AccountBase): id: int status: AccountStatus usage_count: int last_used_at: Optional[datetime] = None current_key_id: Optional[int] = None created_at: datetime updated_at: datetime class Config: from_attributes = True class AccountImport(BaseModel): """批量导入账号""" accounts: List[AccountCreate] # ========== 外部系统批量上传 ========== class ExternalAccountItem(BaseModel): """外部系统上传的账号项""" email: str access_token: str refresh_token: Optional[str] = None workos_session_token: Optional[str] = None membership_type: Optional[str] = "free" # free/pro, 默认free(auto账号) remark: Optional[str] = None class ExternalBatchUpload(BaseModel): """外部系统批量上传请求""" accounts: List[ExternalAccountItem] update_existing: bool = True # 是否更新已存在的账号 class ExternalBatchResponse(BaseModel): """外部系统批量上传响应""" success: bool total: int created: int updated: int failed: int errors: List[str] = [] # ========== 激活码相关 ========== class KeyBase(BaseModel): membership_type: MembershipType = MembershipType.PRO # pro=高级模型, free=无限auto quota: int = 500 # 总额度 (仅Pro有效) valid_days: int = 30 # 有效天数,0表示永久 (仅Auto有效) max_devices: int = 2 # 最大设备数 remark: Optional[str] = None class KeyCreate(KeyBase): key: Optional[str] = None # 不提供则自动生成 count: int = 1 # 批量生成数量 class KeyUpdate(BaseModel): membership_type: Optional[MembershipType] = None quota: Optional[int] = None valid_days: Optional[int] = None max_devices: Optional[int] = None status: Optional[KeyStatus] = None remark: Optional[str] = None class KeyAddQuota(BaseModel): """叠加额度(只加额度不加时间)""" add_quota: int class KeyResponse(BaseModel): id: int key: str status: KeyStatus membership_type: MembershipType quota: int quota_used: int quota_remaining: Optional[int] = None # 剩余额度(计算字段) valid_days: int first_activated_at: Optional[datetime] = None expire_at: Optional[datetime] = None max_devices: int switch_count: int last_switch_at: Optional[datetime] = None current_account_id: Optional[int] = None remark: Optional[str] = None created_at: datetime updated_at: datetime class Config: from_attributes = True # ========== 客户端 API 相关 ========== class VerifyKeyRequest(BaseModel): key: str device_id: Optional[str] = None # 设备标识 class VerifyKeyResponse(BaseModel): success: bool message: Optional[str] = None error: Optional[str] = None # 成功时返回 email: Optional[str] = None accessToken: Optional[str] = None refreshToken: Optional[str] = None WorkosCursorSessionToken: Optional[str] = None membership_type: Optional[str] = None # 额度信息 quota: Optional[int] = None # 总额度 quotaUsed: Optional[int] = None # 已用额度 quotaRemaining: Optional[int] = None # 剩余额度 quotaCost: Optional[int] = None # 每次换号消耗 expireDate: Optional[str] = None class SwitchAccountRequest(BaseModel): key: str device_id: Optional[str] = None # 设备标识 class SwitchAccountResponse(BaseModel): success: bool message: Optional[str] = None error: Optional[str] = None email: Optional[str] = None accessToken: Optional[str] = None refreshToken: Optional[str] = None WorkosCursorSessionToken: Optional[str] = None membership_type: Optional[str] = None # 额度信息 quotaUsed: Optional[int] = None quotaRemaining: Optional[int] = None # ========== 统计相关 ========== class DashboardStats(BaseModel): total_accounts: int active_accounts: int pro_accounts: int total_keys: int active_keys: int today_usage: int # ========== 认证相关 ========== class Token(BaseModel): access_token: str token_type: str = "bearer" class LoginRequest(BaseModel): username: str password: str # ========== 全局设置相关 ========== class GlobalSettingsResponse(BaseModel): """全局设置响应""" # Auto密钥设置 auto_switch_interval_minutes: int = 20 # 换号最小间隔(分钟) auto_max_switches_per_day: int = 50 # 每天最大换号次数 # Pro密钥设置 pro_quota_cost: int = 50 # 每次换号扣除额度 class GlobalSettingsUpdate(BaseModel): """更新全局设置""" auto_switch_interval_minutes: Optional[int] = None auto_max_switches_per_day: Optional[int] = None pro_quota_cost: Optional[int] = None # ========== 批量操作相关 ========== class BatchExtendRequest(BaseModel): """批量延长请求""" key_ids: List[int] # 激活码ID列表 extend_days: int = 0 # 延长天数(Auto和Pro都可用) add_quota: int = 0 # 增加额度(仅Pro有效) class BatchExtendResponse(BaseModel): """批量延长响应""" success: int failed: int errors: List[str] = []