"""计费域:watch_records / point_transactions / recharge_orders / recharge_packages""" from datetime import date, datetime from decimal import Decimal from sqlalchemy import Date, DateTime, Index, Numeric, SmallInteger, String, func from sqlalchemy.dialects.mysql import BIGINT, INTEGER from sqlalchemy.orm import Mapped, mapped_column from app.models.base import Base class WatchRecord(Base): __tablename__ = "watch_records" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) subject_type: Mapped[int] = mapped_column(SmallInteger, comment="1用户 2游客") subject_id: Mapped[str] = mapped_column(String(64), comment="user_id或device_id") video_id: Mapped[int] = mapped_column(BIGINT(unsigned=True)) watch_date: Mapped[date] = mapped_column(Date) cost_type: Mapped[int] = mapped_column(SmallInteger, comment="0免费 1积分 2会员 3本人") cost_points: Mapped[int] = mapped_column(default=0) watch_duration: Mapped[int] = mapped_column(default=0, comment="秒") position: Mapped[int] = mapped_column(default=0, comment="最后播放进度(秒),续播用") created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) __table_args__ = ( Index("uk_dedup", "subject_type", "subject_id", "video_id", "watch_date", unique=True), Index("idx_subject", "subject_type", "subject_id", "created_at"), ) class PointTransaction(Base): __tablename__ = "point_transactions" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(BIGINT(unsigned=True)) change_amount: Mapped[int] = mapped_column(comment="正增负减") balance_after: Mapped[int] = mapped_column() biz_type: Mapped[int] = mapped_column( SmallInteger, comment="1充值 2观看 3评论奖励 4会员 5赠送 6调整 7扣回 8推荐奖励" ) biz_id: Mapped[str] = mapped_column(String(64), default="") remark: Mapped[str] = mapped_column(String(200), default="") created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) __table_args__ = ( Index("idx_user_created", "user_id", "created_at"), Index("idx_biz", "biz_type", "biz_id"), ) class RechargeOrder(Base): __tablename__ = "recharge_orders" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) order_no: Mapped[str] = mapped_column(String(32), unique=True) user_id: Mapped[int] = mapped_column(BIGINT(unsigned=True)) amount_fen: Mapped[int] = mapped_column(comment="人民币金额(分)") points: Mapped[int] = mapped_column(comment="应到账积分") pay_method: Mapped[int] = mapped_column(SmallInteger, comment="1支付宝 2微信 3USDT") status: Mapped[int] = mapped_column(SmallInteger, default=0, comment="0待支付 1已支付 2已关闭 3已退款") third_trade_no: Mapped[str | None] = mapped_column(String(64), unique=True) usdt_amount: Mapped[Decimal | None] = mapped_column(Numeric(18, 6)) usdt_rate: Mapped[Decimal | None] = mapped_column(Numeric(10, 4)) paid_at: Mapped[datetime | None] = mapped_column(DateTime) expire_at: Mapped[datetime] = mapped_column(DateTime) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) __table_args__ = (Index("idx_user_status", "user_id", "status"),) class RechargePackage(Base): """充值套餐档位(管理后台实时可配)""" __tablename__ = "recharge_packages" id: Mapped[int] = mapped_column(INTEGER(unsigned=True), primary_key=True, autoincrement=True) amount_yuan: Mapped[int] = mapped_column() points: Mapped[int] = mapped_column(comment="基础积分=金额x汇率") bonus_points: Mapped[int] = mapped_column(default=0) sort: Mapped[int] = mapped_column(default=0) status: Mapped[int] = mapped_column(SmallInteger, default=1, comment="1上架 0下架") created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now())