04e467e433
后端: - 微信回调 db.commit 失败仍返回 SUCCESS,避免无限重试 - recharge() 加 order_id 幂等保护,防重复充值 - time_expire 使用北京时间(UTC+8),修复时区 bug - 充值档位后端配置化(points-config.yaml + /recharge-options API) - 代码审查 20 项修复(认证加固、扣费顺序、错误响应、状态同步等) 前端: - 充值弹窗:自动轮询 + 【我已支付】手动兜底 - 二维码倒计时显示,过期后遮罩 + 刷新按钮 - 充值档位从后端动态加载 - 去掉 select/qrcode 弹窗标题,金额红色突出显示 - 全项目命名统一(视频生成/压制成片/配音合成/声音复刻等) - Modal 关闭按钮独立于 title 显示
92 lines
2.2 KiB
Python
92 lines
2.2 KiB
Python
"""
|
|
积分流水表
|
|
==========
|
|
|
|
记录每一笔积分变动,用于审计和对账。
|
|
|
|
变动类型:
|
|
- recharge:充值
|
|
- consume:消费(AI 调用)
|
|
- expire:过期
|
|
- refund:返还(预扣后失败或实际少于预估)
|
|
"""
|
|
|
|
import uuid
|
|
|
|
from sqlalchemy import BigInteger, String, Text
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import BaseModelBigInt
|
|
|
|
|
|
class PointTransaction(BaseModelBigInt):
|
|
"""积分流水"""
|
|
|
|
__tablename__ = "mjk_point_transactions"
|
|
|
|
user_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
nullable=False,
|
|
comment="用户 ID",
|
|
)
|
|
|
|
type: Mapped[str] = mapped_column(
|
|
String(20),
|
|
nullable=False,
|
|
comment="变动类型:recharge / consume / expire / refund",
|
|
)
|
|
|
|
amount: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="变动数量(正数)",
|
|
)
|
|
|
|
balance_before: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="变动前总余额",
|
|
)
|
|
|
|
balance_after: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="变动后总余额",
|
|
)
|
|
|
|
source_type: Mapped[str | None] = mapped_column(
|
|
String(32),
|
|
nullable=True,
|
|
comment="消费来源类型:script / polish / voice_clone / tts / video",
|
|
)
|
|
|
|
source_id: Mapped[str | None] = mapped_column(
|
|
String(64),
|
|
nullable=True,
|
|
comment="关联的任务 ID 或订单 ID",
|
|
)
|
|
|
|
batch_id: Mapped[int | None] = mapped_column(
|
|
BigInteger,
|
|
nullable=True,
|
|
comment="关联的积分批次 ID(消费时记录从哪个批次扣)",
|
|
)
|
|
|
|
duration: Mapped[float | None] = mapped_column(
|
|
nullable=True,
|
|
comment="时长(秒),按秒计费业务记录",
|
|
)
|
|
|
|
category: Mapped[str | None] = mapped_column(
|
|
String(32),
|
|
nullable=True,
|
|
comment="业务分类:脚本生成 / 配音合成 / 视频生成 / 压制成片 / 字幕烧录 / 封面设计 / 充值",
|
|
)
|
|
|
|
description: Mapped[str | None] = mapped_column(
|
|
Text,
|
|
nullable=True,
|
|
comment="描述",
|
|
)
|