107 lines
5.6 KiB
Markdown
107 lines
5.6 KiB
Markdown
---
|
||
name: 首充第一档金额下限
|
||
overview: 首充定格时,第一档金额应至少为活动配置 `ext_config.first_cash_amount`(千分位),不能仅按 `balanceBeforeQf` 用 `min` 压到低于配置;同步调整 `handleFreeCreditInit` 的定格基数与 `calcFirstCashAmount` 公式,并更新单测。
|
||
todos:
|
||
- id: fix-calc-first-cash
|
||
content: 修改 FreeCreditsLogic::calcFirstCashAmount 为至少 ext_config.first_cash_amount
|
||
status: completed
|
||
- id: update-unit-tests
|
||
content: 更新 FreeCreditsLogicAmountTest 与 handleFreeCreditInit 相关单测
|
||
status: completed
|
||
- id: verify-integration
|
||
content: 按需跑 FreeCreditsFirstRechargeFreezeTest 验证落库第一档金额
|
||
status: completed
|
||
isProject: false
|
||
---
|
||
|
||
# 首充定格:第一档金额不低于配置
|
||
|
||
## 问题
|
||
|
||
[`handleFreeCreditInit`](slot_console/app/api/logic/FreeCreditsLogic.php) 当前:
|
||
|
||
```php
|
||
$frozenAmount = max($balanceBeforeQf, 0);
|
||
```
|
||
|
||
定格总额仍用入账前余额(正确),但第一档金额在 [`freezeFirstRecharge`](slot_console/app/api/logic/FreeCreditsLogic.php) 里走:
|
||
|
||
```php
|
||
$firstCashAmount = self::calcFirstCashAmount($frozenAmount, $this->configAmount($config, 'first_cash_amount', ...));
|
||
// calcFirstCashAmount = min(frozen, configured)
|
||
```
|
||
|
||
当 **定格额 < 配置免打码额** 时,第一档会变成定格额本身(例如池内 $6、配置 $20 → 第一档 $6),与「第一档最少给 `ext_config.first_cash_amount`」不符。
|
||
|
||
单测 [`FreeCreditsLogicAmountTest`](slot_console/tests/Unit/FreeCreditsLogicAmountTest.php) 里 `'定格小于配置' => [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(定格额, 配置), 配置)` → 等价于 **至少为配置值**:定格 ≥ 配置时取配置上限;定格 < 配置时仍记 **配置值**(运营承诺的档位面额) |
|
||
|
||
```mermaid
|
||
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`](slot_console/app/api/logic/FreeCreditsLogic.php)
|
||
|
||
```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`**):
|
||
|
||
```php
|
||
$configuredFirstCash = $this->configAmount($config, 'first_cash_amount', self::DEFAULT_FIRST_CASH);
|
||
$frozenAmount = max($balanceBeforeQf, 0);
|
||
// 不把 frozenAmount 改成 max(balanceBefore, configuredFirstCash),避免改变定格总额语义
|
||
```
|
||
|
||
若你希望 **尝试多冻** 到配置下限,可另议;当前计划 **只改第一档金额公式**,不改定格总额。
|
||
|
||
### 3. 单测
|
||
|
||
| 文件 | 改动 |
|
||
|------|------|
|
||
| [`FreeCreditsLogicAmountTest.php`](slot_console/tests/Unit/FreeCreditsLogicAmountTest.php) | 修正/补充:`[15, 20, 20]`(定格小于配置 → 第一档仍为 20);保留 `[100, 20, 20]` |
|
||
| [`FreeCreditsHandleFreeCreditInitTest.php`](slot_console/tests/Unit/FreeCreditsHandleFreeCreditInitTest.php) | 增加用例:`balanceBefore=15000`、`first_cash_amount_qf=20000` 时,Harness 落库后 `first_cash_amount_qf` / 第一档 `amount_qf` 为 20000(若 Harness 走完整 `freezeFirstRecharge` 需开 DB 或扩展 Harness 断言) |
|
||
| 集成测 [`FreeCreditsFirstRechargeFreezeTest`](slot_console/tests/Integration/FreeCreditsFirstRechargeFreezeTest.php) | 当 DB 活动配置 `first_cash_amount_qf=20000` 且 `balanceBefore < 20000` 时断言 `player.first_cash_amount_qf === 20000` |
|
||
|
||
运行(Docker):
|
||
|
||
```bash
|
||
docker exec -w /app/www/slot/slot_console php82 ./vendor/bin/phpunit \
|
||
--filter 'FreeCreditsLogicAmountTest|FreeCreditsHandleFreeCreditInitTest'
|
||
```
|
||
|
||
## 不改动的部分
|
||
|
||
- **wallet** `maybeSendFreeCreditInit`:仍 `balance_before_qf > 0` 即发事件。
|
||
- **定格扣款金额**:仍 `freeCreditsFreeze(frozenAmount)`,`frozenAmount` 以 `balanceBefore` 为准(经 `freezeFirstRecharge` 内 `min(…, wallet.balance)` 封顶)。
|
||
- **解锁第一档**:仍用 `recharge_unlock_amount` 配置,与本次无关。
|
||
|
||
## 风险
|
||
|
||
- 定格 < 配置时,`first_cash_amount_qf` > 实际可冻余额:C 端可能展示 $20 但池内不足;提现/保留时需依赖现有 `package.amount_qf` 与钱包校验,必要时后续在 `applyFirstCashoutWithdraw` 增加 `amount_qf <= frozen` 断言。
|