""" 积分系统 Schema =============== """ from datetime import datetime from pydantic import BaseModel, ConfigDict, Field # ── 余额查询 ────────────────────────────────────────── class PointBalanceResponse(BaseModel): """积分余额响应""" balance: int = Field(description="当前积分余额(允许欠费为负)") total_recharged: int = Field(description="累计充值") total_consumed: int = Field(description="累计消费") total_expired: int = Field(description="累计过期") # ── 流水记录 ────────────────────────────────────────── class PointTransactionItem(BaseModel): """单条流水记录""" model_config = ConfigDict(from_attributes=True) id: int type: str = Field(description="recharge / consume / expire / refund") amount: int balance_before: int balance_after: int source_type: str | None = Field(None, description="消费来源类型") source_id: str | None = Field(None, description="消费来源业务 ID") duration: float | None = Field(None, description="时长(秒),按秒计费业务记录") category: str | None = Field( None, description="业务分类:脚本生成 / 配音合成 / 视频生成 / 压制成片 / 字幕烧录 / 封面设计 / 充值", ) description: str | None = None created_at: datetime class PointTransactionListResponse(BaseModel): """流水列表响应""" items: list[PointTransactionItem] total: int skip: int limit: int # ── 充值 ────────────────────────────────────────────── class RechargeRequest(BaseModel): """充值请求""" points: int = Field(gt=0, description="充值积分数量") amount_rmb: int = Field(gt=0, description="支付金额(分)") class RechargeResponse(BaseModel): """充值响应(微信支付预下单 - Native 扫码)""" order_id: int points: int amount_rmb: int # Native 支付二维码链接,前端用此生成二维码供用户微信扫描 code_url: str | None = None # 二维码过期时间(ISO 格式),前端据此显示倒计时 expire_at: str | None = None # ── 积分预估 ────────────────────────────────────────── class CostEstimateResponse(BaseModel): """积分预估响应""" source_type: str estimated_points: int = Field(description="预估上限积分(执行业务前检查用)") actual_points: int = Field(description="按传入参数计算的实际积分") # ── 充值订单 ────────────────────────────────────────── class RechargeOrderItem(BaseModel): """充值订单记录""" model_config = ConfigDict(from_attributes=True) id: int points: int amount_rmb: int status: str created_at: datetime paid_at: datetime | None = None class RechargeOrderListResponse(BaseModel): """充值订单列表""" items: list[RechargeOrderItem] total: int skip: int limit: int # ── 消费扣费 ────────────────────────────────────────── class ConsumeRequest(BaseModel): """消费扣费请求(供前端/Rust 层调用)""" points: int = Field(gt=0, description="消耗积分数量") source_type: str = Field( description="消费来源类型,如 compose / subtitle_burn / cover_design / video" ) source_id: str = Field(description="消费来源业务 ID") description: str | None = Field(default=None, description="消费描述") allow_negative: bool = Field( default=False, description="是否允许扣费后余额为负(不确定消耗场景用)" )