fbef15ba7e
- 合并为单一初始全量迁移,覆盖 users/user_devices/user_points/point_batches/point_transactions/point_recharge_orders - 去掉所有 ForeignKey 约束(业务层软删除,不依赖数据库级联) - 去掉不必要的索引,仅保留 Unique 约束自带索引 - 修复 mjk_users.id 为 UUID 类型(非 String(36)) - 修复 user_device.last_active_at 时区类型一致性(添加 timezone=True)
61 lines
1.4 KiB
Python
61 lines
1.4 KiB
Python
"""
|
|
积分批次表
|
|
==========
|
|
|
|
每笔充值产生一个批次,记录初始积分、剩余积分、过期时间。
|
|
|
|
消费时按过期时间升序扣减(FIFO,先充先用)。
|
|
"""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, String
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import BaseModelBigInt
|
|
|
|
|
|
class PointBatch(BaseModelBigInt):
|
|
"""积分批次"""
|
|
|
|
__tablename__ = "mjk_point_batches"
|
|
|
|
user_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
nullable=False,
|
|
comment="用户 ID",
|
|
)
|
|
|
|
amount: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="初始积分",
|
|
)
|
|
|
|
remaining: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="剩余可用积分(扣除冻结后)",
|
|
)
|
|
|
|
frozen: Mapped[int] = mapped_column(
|
|
default=0,
|
|
nullable=False,
|
|
comment="已冻结积分(预扣未结算)",
|
|
)
|
|
|
|
expired_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
comment="过期时间(created_at + 180 天)",
|
|
)
|
|
|
|
source: Mapped[str] = mapped_column(
|
|
String(32),
|
|
default="wxpay",
|
|
nullable=False,
|
|
comment="来源:wxpay / invite / gift / compensation",
|
|
)
|