Files
2026-07-09 14:24:46 +08:00

3.0 KiB
Raw Permalink Blame History

coin_account — 金币 + 现金余额快照

模型 app/models/wallet.py · 仓库 app/repositories/wallet.py · 接口 wallet-account · ← 索引 · 总览

一用户一行的余额快照,App「资产卡 / 钱包」读它展示。每次余额变动都另写一笔流水(coin_transaction / cash_transaction)并记 balance_after,出问题逐笔回溯。user_id 既是主键也是外键(一对一)。详见 总览 §四 资金模型

用在哪 / 增删改查

  • C(插入):get_or_create_account 懒建 —— 用户第一次发生金币动作(签到/任务/看广告/admin 发币/兑换/提现)时建一行空账户(全 0)。从未发生过金币动作的用户没有这行(读接口按 0 兜底)。
  • U(更新):几乎所有钱相关动作都更新它 —— 发金币(签到/任务/看广告/admin)coin_balance += 、兑现金 coin_balance = / cash_balance_cents += 、发起提现 cash_balance_cents = (带条件原子 UPDATE 防超额)、提现退款 cash_balance_cents +=
  • D:无。
  • R:GET /wallet/account(钱包余额卡)、admin 用户 360 概览。

字段

类型 约束 / 默认 说明(取值 / join)
user_id Integer PK + FK→user.id 用户(一用户一行);既是主键也是外键
coin_balance Integer NOT NULL, default 0 当前金币余额(个数);= 历次 coin_transaction.amount 之和
cash_balance_cents Integer NOT NULL, default 0 当前现金余额(分,金币兑换账本);= 历次 cash_transaction.amount_cents 之和
invite_cash_balance_cents Integer NOT NULL, default 0 当前邀请奖励金余额(分,与现金物理隔离的第二本现金账);= 历次 invite_cash_transaction.amount_cents 之和。好友比价并下单发奖入账(#113),source=invite_cash 提现出账(#121)
total_coin_earned Integer NOT NULL, default 0 累计赚取金币(只增不减,仅正向 grant 累加),用于"历史总收益"展示
updated_at DateTime(tz) server_default now(), onupdate now() 最后更新时间

关系 / Join Key

  • user_iduser.id(一对一)。
  • coin_transaction / cash_transaction 无外键直连,靠 user_id 关联;快照 = 流水累加值,流水的 balance_after* 应等于当时的快照余额(对账依据)。

索引与约束

  • PK user_id(同时是 FK→user.id)。

注意

  • 唯一发金币入口 wallet.grant_coins:更新本表 + 写 coin_transaction,不 commit,由调用方同事务提交(发币与业务记录原子化)。邀请奖励金同款:唯一变动入口 wallet.grant_invite_cash(更新 invite_cash_balance_cents + 写 invite_cash_transaction)。
  • 扣现金用 UPDATE ... WHERE <对应余额列> >= amount 原子条件扣减(按提现 sourcecash_balance_centsinvite_cash_balance_cents),并发/重试不会超额。