Files
meijiaka-zy/python-api/app/models/point_transaction.py
T
小鱼开发 04e467e433 feat(points): 积分系统收尾 + 充值弹窗改造 + 命名统一
后端:
- 微信回调 db.commit 失败仍返回 SUCCESS,避免无限重试
- recharge() 加 order_id 幂等保护,防重复充值
- time_expire 使用北京时间(UTC+8),修复时区 bug
- 充值档位后端配置化(points-config.yaml + /recharge-options API)
- 代码审查 20 项修复(认证加固、扣费顺序、错误响应、状态同步等)

前端:
- 充值弹窗:自动轮询 + 【我已支付】手动兜底
- 二维码倒计时显示,过期后遮罩 + 刷新按钮
- 充值档位从后端动态加载
- 去掉 select/qrcode 弹窗标题,金额红色突出显示
- 全项目命名统一(视频生成/压制成片/配音合成/声音复刻等)
- Modal 关闭按钮独立于 title 显示
2026-05-09 21:29:35 +08:00

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="描述",
)