Files
cursor/plans/首充第一档金额下限_43e84a69.plan.md
ray zhou f71a5c59af ok
2026-05-29 11:21:40 +08:00

5.6 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
首充第一档金额下限 首充定格时,第一档金额应至少为活动配置 `ext_config.first_cash_amount`(千分位),不能仅按 `balanceBeforeQf` 用 `min` 压到低于配置;同步调整 `handleFreeCreditInit` 的定格基数与 `calcFirstCashAmount` 公式,并更新单测。
id content status
fix-calc-first-cash 修改 FreeCreditsLogic::calcFirstCashAmount 为至少 ext_config.first_cash_amount completed
id content status
update-unit-tests 更新 FreeCreditsLogicAmountTest 与 handleFreeCreditInit 相关单测 completed
id content status
verify-integration 按需跑 FreeCreditsFirstRechargeFreezeTest 验证落库第一档金额 completed
false

首充定格:第一档金额不低于配置

问题

handleFreeCreditInit 当前:

$frozenAmount = max($balanceBeforeQf, 0);

定格总额仍用入账前余额(正确),但第一档金额在 freezeFirstRecharge 里走:

$firstCashAmount = self::calcFirstCashAmount($frozenAmount, $this->configAmount($config, 'first_cash_amount', ...));
// calcFirstCashAmount = min(frozen, configured)

定格额 < 配置免打码额 时,第一档会变成定格额本身(例如池内 $6、配置 $20 → 第一档 $6与「第一档最少给 ext_config.first_cash_amount」不符。

单测 FreeCreditsLogicAmountTest'定格小于配置' => [30, 20, 20] 已按「至少配置值」写期望,与实现 不一致min(30,20)=20 碰巧相等,但 frozen=15, config=20 会得到 15

目标行为

字段 规则
定格总额 frozen_amount_qf 仍为入账前免费余额 balance_before_qf(需求 §5.3强行抬到配置
第一档金额 first_cash_amount_qf / package_no=1.amount_qf max(min(定格额, 配置), 配置) → 等价于 至少为配置值:定格 ≥ 配置时取配置上限;定格 < 配置时仍记 配置值(运营承诺的档位面额)
flowchart LR
  event[free_credit_init] --> init[handleFreeCreditInit]
  init --> freeze[freezeFirstRecharge]
  freeze --> frozen["frozen = balanceBefore"]
  freeze --> first["firstCash = max(min(frozen, cfg), cfg)"]

边界说明:若定格额实际小于配置,玩家可提现金额仍受池内 package.amount_qf 与钱包冻结额约束;本次按你的要求把 落库第一档金额 抬到配置下限,与需求文档 §5.6「定格 < $20 → 第一档 = 定格额」存在冲突——以你本次口径为准;若需「可提现 ≤ 定格」再单独加提现校验。

实现(仅 slot_console

1. 修改 calcFirstCashAmount

文件:FreeCreditsLogic.php

public static function calcFirstCashAmount(int $frozenAmount, int $configuredFirstCash): int
{
    return max(min($frozenAmount, $configuredFirstCash), $configuredFirstCash);
}
  • 注释改为:第一档面额不低于配置,且不超过定格总额与配置上限。
  • 逻辑上等价于 return $configuredFirstCash(当 configuredFirstCash > 0);保留 min(frozen, …) 形式便于日后若配置为 0 时回退。

2. handleFreeCreditInit 显式读配置(可选但建议)

在同文件 handleFreeCreditInit 内,在调用 freezeFirstRecharge 前读取一次配置(便于日志/后续扩展;定格额仍用 balanceBeforeQf

$configuredFirstCash = $this->configAmount($config, 'first_cash_amount', self::DEFAULT_FIRST_CASH);
$frozenAmount = max($balanceBeforeQf, 0);
// 不把 frozenAmount 改成 max(balanceBefore, configuredFirstCash),避免改变定格总额语义

若你希望 尝试多冻 到配置下限,可另议;当前计划 只改第一档金额公式,不改定格总额。

3. 单测

文件 改动
FreeCreditsLogicAmountTest.php 修正/补充:[15, 20, 20](定格小于配置 → 第一档仍为 20保留 [100, 20, 20]
FreeCreditsHandleFreeCreditInitTest.php 增加用例:balanceBefore=15000first_cash_amount_qf=20000Harness 落库后 first_cash_amount_qf / 第一档 amount_qf 为 20000若 Harness 走完整 freezeFirstRecharge 需开 DB 或扩展 Harness 断言)
集成测 FreeCreditsFirstRechargeFreezeTest 当 DB 活动配置 first_cash_amount_qf=20000balanceBefore < 20000 时断言 player.first_cash_amount_qf === 20000

运行Docker

docker exec -w /app/www/slot/slot_console php82 ./vendor/bin/phpunit \
  --filter 'FreeCreditsLogicAmountTest|FreeCreditsHandleFreeCreditInitTest'

不改动的部分

  • wallet maybeSendFreeCreditInit:仍 balance_before_qf > 0 即发事件。
  • 定格扣款金额:仍 freeCreditsFreeze(frozenAmount)frozenAmountbalanceBefore 为准(经 freezeFirstRechargemin(…, wallet.balance) 封顶)。
  • 解锁第一档:仍用 recharge_unlock_amount 配置,与本次无关。

风险

  • 定格 < 配置时,first_cash_amount_qf > 实际可冻余额C 端可能展示 $20 但池内不足;提现/保留时需依赖现有 package.amount_qf 与钱包校验,必要时后续在 applyFirstCashoutWithdraw 增加 amount_qf <= frozen 断言。