Files
cursor/plans/free_credits_release_902566c9.plan.md
2026-05-21 18:16:26 +08:00

12 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
free credits release 为“首充前免费余额定格与分档释放”准备开发方案,按钱包账务、充值提现事件、客户端 API、后台配置统计分阶段落地。重点遵循现有后端分层规则避免把业务编排错误地下沉到 Service。
id content status
confirm-wallet-fields 按已确认口径使用 deposit_balance + withdraw_balance 作为免费余额 completed
id content status
design-schema 设计独立 Free Credits 活动主表、档位明细表、流水关联和旧活动 ID 关联 completed
id content status
implement-console-core 在 slot_console 实现活动领域模型、定格、解锁、Claim 和状态查询 Logic pending
id content status
wire-recharge 接入 slot_pay/slot_console 充值成功链路并保证首充定格幂等 completed
id content status
wire-cashout 实现第一档独立提现订单和回调状态同步 completed
id content status
add-console-apis 补充大厅状态、活动入口、后台配置统计相关 API completed
id content status
test-acceptance 按需求文档核心规则和账务验收补测试/联调用例 completed
false

首充前免费余额定格与分档释放开发准备

目标范围

本次需求核心实现应以后端账务和状态机为主,前端展示依赖新增/扩展 API。主要涉及

已有统一活动管理表可作为关联来源:

  • s_common.s_recharge_gift_config:现有充值赠送活动主表。
  • recharge_gift_player:现有充值赠送活动参与玩家表。

本需求不直接复用这两张表承载 Free Credits 账务状态,采用独立 Free Credits 表设计,并保留与旧活动 ID 的关联,避免把“首充前免费余额定格”与已有充值赠送活动规则混在同一张参与表里。

数据表 DDL 草案

金额字段建议沿用现有活动表中的 _qf 口径,按千分位整数保存,避免小数精度问题。

CREATE TABLE `free_credits_player` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `activity_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '关联 s_recharge_gift_config.id',
  `uid` bigint unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
  `source` varchar(64) NOT NULL DEFAULT '' COMMENT '渠道',
  `model_id` int unsigned NOT NULL DEFAULT '0' COMMENT '游戏模型ID',
  `home_withdraw_unlocked` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '首页Withdraw是否已解锁 0否 1是',
  `frozen_amount_qf` bigint unsigned NOT NULL DEFAULT '0' COMMENT '首充时定格金额,千分位',
  `first_cash_amount_qf` bigint unsigned NOT NULL DEFAULT '0' COMMENT '第一档免打码提现金额,千分位',
  `first_recharge_order_id` varchar(64) NOT NULL DEFAULT '' COMMENT '触发定格的首笔充值订单号',
  `first_recharge_time` datetime DEFAULT NULL COMMENT '首笔充值成功时间',
  `first_cashout_order_id` varchar(64) NOT NULL DEFAULT '' COMMENT '第一档独立提现订单号',
  `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '主状态 0未开始 1首页已解锁 2已定格 3待充值解锁 4第一档可提现 5第一档提现中 6第一档已提现 7后续释放中 10全部完成',
  `completed_time` datetime DEFAULT NULL COMMENT '全部完成时间',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_activity_uid` (`activity_id`,`uid`),
  KEY `idx_uid` (`uid`),
  KEY `idx_activity_status` (`activity_id`,`status`),
  KEY `idx_first_recharge_order` (`first_recharge_order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Free Credits用户活动主表';
CREATE TABLE `free_credits_package` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `player_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'free_credits_player.id',
  `activity_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '关联 s_recharge_gift_config.id',
  `uid` bigint unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
  `package_no` int unsigned NOT NULL DEFAULT '0' COMMENT '档位序号从1开始',
  `package_type` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '档位类型 1第一档免打码提现 2后续释放档',
  `amount_qf` bigint unsigned NOT NULL DEFAULT '0' COMMENT '档位金额,千分位',
  `status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '档位状态 0锁定 1可操作 2处理中 3已完成 4失败 5风控拒绝',
  `withdraw_order_id` varchar(64) NOT NULL DEFAULT '' COMMENT '第一档提现订单号',
  `claim_biz_id` varchar(64) NOT NULL DEFAULT '' COMMENT '后续档Claim入账幂等业务号',
  `unlocked_time` datetime DEFAULT NULL COMMENT '解锁时间',
  `claimed_time` datetime DEFAULT NULL COMMENT '领取时间',
  `completed_time` datetime DEFAULT NULL COMMENT '完成时间',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_player_package` (`player_id`,`package_no`),
  UNIQUE KEY `uniq_claim_biz` (`claim_biz_id`),
  KEY `idx_uid_status` (`uid`,`status`),
  KEY `idx_activity_status` (`activity_id`,`status`),
  KEY `idx_withdraw_order` (`withdraw_order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Free Credits档位明细表';

建议数据流

flowchart TD
  preDepositUser["未首充用户"] --> winThreshold["免费余额曾达到门槛"]
  winThreshold --> homeUnlocked["首页 Withdraw 解锁"]
  preDepositUser --> firstRecharge["任意入口首笔真实充值成功"]
  firstRecharge --> freezeFreeCredits["定格当前免费余额"]
  freezeFreeCredits --> freeCreditsPool["slot_console 保存 Free Credits Pool 与档位"]
  firstRecharge --> walletTotalRecharge["查询钱包累计充值总额"]
  walletTotalRecharge --> firstReady["累计充值满门槛释放第一档"]
  firstReady --> firstCashout["第一档独立提现"]
  firstCashout --> laterPackages["后续档位按充值解锁"]
  laterPackages --> claimToWallet["Claim 入 Deposit Balance"]
  claimToWallet --> y1Task["创建 Y1 流水任务"]

后端落地方案

  1. slot_console 新增独立 Free Credits 活动领域模型。

    • 新增用户池主表,保存 activity_iduid、定格金额、首充订单、主状态、首页解锁标记、完成时间等;主表不保存累计充值。
    • 新增档位明细表,一档一行,保存序号、类型、金额、状态、关联提现单/Claim 流水、解锁/完成时间。
    • activity_id 关联现有 s_common.s_recharge_gift_config 或后台活动配置 ID但 Free Credits 的进度、档位和账务状态不写入 recharge_gift_player
    • 表归属按 slot_console 现有业务库和活动模块规范处理;slot_wallet 不新增 Free Credits 活动表。
  2. slot_console 增加 Logic 编排定格、解锁、Claim。

    • Controller 只做请求接收、Validate、DTO、统一响应。
    • Validate 处理参数必填/类型/枚举。
    • DTO 只承载已校验字段。
    • Logic 负责首充定格、查询钱包累计充值总额、档位状态流转、事务和幂等。
    • Model 负责查询/写入和状态条件更新。
    • Service 仅用于已有公共能力,如调用钱包原子 API、配置读取、外部系统封装不新增单纯转发 Service。
    • 调用 slot_wallet 时只请求余额变更、钱包流水、入 Deposit Balance、创建 Y1 任务等钱包能力,不把活动状态写入钱包服务。
  3. 接入充值成功链路。

    • 现有充值成功链路在 /Users/ray/Documents/project/www/slot/slot_pay/app/command/EventRecharge.php 调用钱包充值入账。
    • 充值成功后由 slot_pay 或事件消费者通知 slot_console,由 slot_console 判断是否首笔真实充值并触发定格。
    • 定格需要调用 slot_wallet 原子能力扣减当前免费余额并写钱包流水,再由 slot_console 落 Free Credits Pool 和档位。
    • 第一档门槛通过调用钱包查询用户累计充值总额判断;slot_console 主表不保存累计充值,也不新增充值事件明细表。
  4. 实现第一档独立提现。

    • 第一档不进入普通钱包余额,创建独立提现订单类型 free_credit_first_cashout
    • 需要在 slot_pay 的提现订单模型/实体中支持新订单类型,提现处理中防重复,成功/失败/拒绝回写档位状态。
    • 第一档提现成功后关闭首页状态条,但活动入口保留到所有档位完成。
  5. 实现后续档位解锁和 Claim。

    • 后续每笔符合条件真实充值最多解锁下一档,按配置控制最小充值金额和每笔最多解锁档数。
    • Claim 由 slot_console 校验档位状态和顺序后,调用 slot_wallet 将档位金额入 Deposit Balance,创建 Deposit Lot 和 Y1 Wager Task。
    • slot_console 负责 Claim 幂等和档位状态流转;slot_wallet 负责钱包入账幂等和流水一致性。失败时档位保持 ready,重复点击不能重复入账。
  6. 增加客户端查询与操作 API。

  7. 增加后台配置与统计。

    • 配置项优先绑定到现有统一活动管理的活动 IDFree Credits 专属配置包括活动开关、首笔赢取门槛、充值解锁门槛、免打码提现额、拆分金额、后续最小充值、每笔最多解锁档数、Y1 倍数、Banner。
    • 统计项:定格人数、完成提现人数、全部完成人数、定格总金额、已提现金额、已领取金额、待释放金额。
    • 筛选排序按文档要求实现。

已确认口径

  • 免费余额 = deposit_balance + withdraw_balance,即钱包余额。
  • 第一档不需要流水,完全绕开普通可提现余额计算。
  • 第一档解锁通过充值成功异步通知驱动,并调用钱包查询累计充值总额判断是否达到门槛。
  • Free Credits 定格逻辑以独立活动配置为准。
  • 客户端 UI 由前端人员处理,本仓库不包含对应页面代码。

关键风险与需确认点

  • 文档中的 Deposite Balance / Deposite Lot 建议统一确认是否为历史命名还是拼写问题。

建议开发顺序

  1. 先实现 slot_console 活动数据模型、配置读取、状态机和只读查询接口。
  2. 梳理并补齐 slot_wallet 需要暴露的钱包原子能力,包括查询累计充值总额、冻结/扣减免费余额、入 Deposit Balance、创建 Y1 任务和幂等流水。
  3. 接入充值成功链路,完成 slot_payslot_console 的事件通知、首充定格和调用钱包累计充值总额解锁第一档。
  4. 实现第一档独立提现链路和提现回调到 slot_console 的状态同步。
  5. 实现后续档位解锁、Claim 调用钱包入账和 Y1 流水任务创建。
  6. slot_console 大厅/活动入口接口、后台统计、客户端 UI、文案、埋点和验收用例。