This commit is contained in:
ray zhou
2026-05-29 19:26:16 +08:00
parent ad623aad91
commit 225fb2bd28
7 changed files with 330 additions and 47 deletions

View File

@@ -1,22 +1,22 @@
---
name: 首充剩余分档规则
overview: 将 Free Credits剩余金额(定格额 第一档 $20」从固定 package_amount 均分,改为 10/20/30/50/100 元阶梯瀑布拆分;后续档解锁为「累计充值 ≥ 每档门槛(标准档=面额−$1;尾档 unlock 按大单位整向下取整,如 15340qf→15000qf
overview: 将 Free Credits 剩余金额改为 10/20/30/50/100 瀑布分档;后续档解锁为「每档独立的新增累计充值」(自上一档解锁后重新计数,非终身 totalR 一刀切);尾档 unlock 按大单位整向下取整。
todos:
- id: split-algorithm
content: 实现 buildReleasePackages 瀑布拆分,替换 splitReleasePackageAmounts + createPackages
status: pending
status: completed
- id: db-unlock-qf
content: free_credits_package 增 unlock_recharge_qfinstall.sql + 迁移脚本
status: pending
content: package 增 unlock_recharge_qf本档所需新增累计充值player 增 recharge_baseline_qf迁移脚本
status: completed
- id: advance-unlock
content: advanceByRecharge 按累计充值+unlock_recharge_qf 解锁;存量 unlock=0 回退旧逻辑
status: pending
content: advanceByRecharge 用 (totalRbaseline)≥unlock 逐档解锁并重置 baseline存量回退旧逻辑
status: completed
- id: admin-config
content: 废弃 package_amount/subsequent_min 后台必填;更新 ActivityValidate
status: pending
status: completed
- id: tests-docs
content: 单测/集成测 + 需求文档 §5.7/5.8 更新
status: pending
status: completed
isProject: false
---
@@ -38,14 +38,16 @@ isProject: false
按顺序「吃掉」剩余金额(瀑布式,非按总额选一档):
| 阶段 | 单档面额 | 本阶段最多档数 | 累计充值解锁门槛(每档 |
|------|---------|---------------|------------------------|
| 1 | $10 | 3 | ≥ $9 |
| 2 | $20 | 5 | ≥ $19 |
| 3 | $30 | 10 | ≥ $29 |
| 4 | $50 | 10 | ≥ $49 |
| 5 | $100 | 直到剩余 < $100 | ≥ $99 |
| 6 | 尾档 | 剩余 < $100 的余额,**一整档**`amount_qf` 可为小数大单位,如 $15.34 | **累计充值门槛 = 面额按大单位整数向下取整**(见下) |
| 阶段 | 单档面额 | 本阶段最多档数 | 本档所需**新增**累计充值(自上一档解锁后起算 |
|------|---------|---------------|------------------------------------------|
| 1 | $10 | 3 | 每档再充 ≥ $9 |
| 2 | $20 | 5 | 每档再充 ≥ $19 |
| 3 | $30 | 10 | 每档再充 ≥ $29 |
| 4 | $50 | 10 | 每档再充 ≥ $49 |
| 5 | $100 | 直到剩余 < $100 | 每档再充 ≥ $99 |
| 6 | 尾档 | 剩余 < $100 的一整档 | 再充 ≥ **面额整元向下取整**(见下) |
**重要**:表中金额为「每一档单独重新累计」的充值要求,**不是**钱包终身 `totalRecharge` 达到该绝对值。上一档变为 `ready` 后,充值计数归零,从当前 `totalRecharge` 重新累计下一档。
金额在代码中为 **千分位整数qf**$10 → `10000`
@@ -70,7 +72,7 @@ unlock_recharge_qf = intdiv(amount_qf, 1000) * 1000 // 去掉 qf 余数,等
| amount_qf小单位/千分位) | 档位展示面额 | unlock_recharge_qf累计充值门槛 |
|-------------------------|-------------|-----------------------------------|
| `15340` | $15.34 | `15000`$15非 $15.34 |
| `15340` | $15.34 | `15000`本档需**新增**累计充 $15非 $15.34 |
| `8500` | $8.50 | `8000`$8 |
| `10000` | $10.00 | `10000`$10 |
@@ -108,31 +110,58 @@ public static function buildReleasePackages(int $leftAmountQf): array
`createPackages()` 改为遍历上述结构写入 `free_credits_package`,不再读 `package_amount` 配置。
### 2. 库表:每档解锁门槛
### 2. 库表:本档门槛 + 充值基线
[`free_credits_package`](slot_console/db/install.sql) 当前无解锁门槛字段。建议新增:
**`free_credits_package`** 新增:
```sql
unlock_recharge_qf bigint unsigned NOT NULL DEFAULT 0 COMMENT '解锁本档所需累计真实充值,千分位'
unlock_recharge_qf bigint unsigned NOT NULL DEFAULT 0
COMMENT '解锁本档所需新增累计真实充值(千分位),自上一档解锁后起算'
```
- 定格写入时一并落库
- **存量用户**(默认策略):已有行 `unlock_recharge_qf=0` 时,`advanceByRecharge` 回退旧逻辑(`subsequent_min_recharge` + 单笔充值),避免行为突变
- **新定格**:一律写入新门槛
**`free_credits_player`** 新增:
(若产品确认「存量也迁移」,另做一次性 SQL/脚本按 player 重算 package 行 — 需单独评估已解锁/已领取档。)
```sql
recharge_baseline_qf bigint unsigned NOT NULL DEFAULT 0
COMMENT '后续档计数起点wallet.totalRecharge 快照(千分位)'
```
### 3. 解锁逻辑(`advanceByRecharge`
- 定格时:写入各档 `unlock_recharge_qf``recharge_baseline_qf = 定格时 wallet.totalRecharge`(首笔 release 档从定格后**新增**充值开始计
- **存量**grandfather`unlock_recharge_qf=0` 的包仍走旧逻辑(单笔 `subsequent_min_recharge`
后续 release 档变更:
### 3. 解锁逻辑(`advanceByRecharge`)— 每档「新的」累计充值
第一档(免打码提现)**不变**:仍用终身 `totalRecharge >= recharge_unlock_amount`(默认 $50
后续 release 档:
```text
incrementalRecharge = wallet.totalRecharge - player.recharge_baseline_qf
若 incrementalRecharge >= nextPackage.unlock_recharge_qf → 解锁该档为 ready
→ recharge_baseline_qf = wallet.totalRecharge // 下一档重新累计
```
循环至多 `max_unlock_per_recharge` 次(同一笔充值回调内可连续解锁多档,但每解锁一档都会 **重置 baseline**,故单笔 $27 通常只够解锁一档 $9 档)。
| 项 | 旧 | 新 |
|----|----|-----|
| 条件 | `rechargeAmount >= subsequent_min` | `totalRecharge >= package.unlock_recharge_qf` |
| 顺序 | 仍按 `package_no` 逐档 | 不变 |
| 单笔上限 | `max_unlock_per_recharge` | **保留**(大额充值仍最多解锁 N 档) |
| 条件 | 本笔 `rechargeAmount >= subsequent_min` | `(totalR - baseline) >= unlock_recharge_qf` |
| 计数范围 | 单笔 | **档间新增累计**(解锁后 baseline 前移) |
| 顺序 | `package_no` 升序 | 不变 |
第一档逻辑不变(仍用 `recharge_unlock_amount`,默认 $50
```mermaid
sequenceDiagram
participant Wallet
participant Logic
participant Player
Wallet->>Logic: totalRecharge=50000
Note over Player: baseline=41000
Logic->>Logic: incremental=9000 >= unlock 9000
Logic->>Player: baseline=50000
Note over Logic: 下一档需再新增累计充值
```
**与「领取 Claim」**Claim 仍要求档位 `ready`;解锁条件只影响何时变 `ready`,不改变 Claim 入账逻辑。
### 4. 配置与后台
@@ -154,7 +183,10 @@ unlock_recharge_qf bigint unsigned NOT NULL DEFAULT 0 COMMENT '解锁本档所
集成测 [`FreeCreditsFirstRechargeFreezeTest`](slot_console/tests/Integration/FreeCreditsFirstRechargeFreezeTest.php) 断言 package 行数与金额。
解锁:在 harness 中 mock `totalRecharge`,验证 `unlock_recharge_qf` 达标后变 `ready`
解锁单测(增量累计):
- baseline=41000totalR=50000unlock=9000 → 解锁baseline 更新为 50000
- 同上后再充到 59000 → 第二档 unlock=9000 可解锁;一笔 50000→59000 只够第二档若 baseline 已重置
- 尾档 unlock=15000amount=15340需新增累计 15000非 15340
### 7. 文档