from datetime import datetime from typing import Literal, Optional from pydantic import BaseModel, Field class PaymentConfigResponse(BaseModel): payment_enabled: bool demo_mode: bool unit_price: float min_slots: int max_slots: int channels: list[str] wechat_available: bool alipay_available: bool class CreatePaymentOrderRequest(BaseModel): slots: int = Field(ge=1, le=100) channel: Literal["wechat", "alipay"] class PaymentOrderResponse(BaseModel): order_no: str channel: str slots: int amount_fen: int amount_yuan: float status: str qr_code: Optional[str] = None pay_url: Optional[str] = None paid_at: Optional[datetime] = None expires_at: Optional[datetime] = None created_at: Optional[datetime] = None demo_mode: bool = False class PaymentOrderListItem(BaseModel): id: int order_no: str user_id: int username: Optional[str] = None display_name: Optional[str] = None channel: str slots: int amount_fen: int amount_yuan: float status: str trade_no: Optional[str] = None is_demo: bool = False paid_at: Optional[datetime] = None created_at: datetime class PaymentOrderListResponse(BaseModel): items: list[PaymentOrderListItem] total: int page: int page_size: int paid_count: int = 0 paid_amount_yuan: float = 0 class AdminUpdateOrderStatusRequest(BaseModel): status: Literal["pending", "paid", "expired", "cancelled", "refunded"] class MessageResponse(BaseModel): message: str