137 lines
5.8 KiB
Markdown
137 lines
5.8 KiB
Markdown
---
|
||
name: toBalance 清零分析
|
||
overview: 产品要求 To Balance 后客户端仍展示领取金额。推荐**保留 my_amount_qf 清零**(进度已兑现),在 status 接口对已提取用户用 cashout_record 回填 myAmountDisplay;并禁止已提取用户继续 Spin 污染状态。
|
||
todos:
|
||
- id: build-state-withdrawn-display
|
||
content: buildStateEntity:playerStatus=已提取时,myAmountDisplay 取自 lucky_reward_cashout_record.amount_qf(大单位)
|
||
status: completed
|
||
- id: block-spin-after-withdrawn
|
||
content: executeManualSpin:status=已提取时拒绝 Spin(防 status/my_amount 被改回可提取)
|
||
status: completed
|
||
- id: keep-zero-my-amount
|
||
content: toBalance 事务内保留 my_amount_qf=0 + status=已提取(不改删除清零逻辑)
|
||
status: completed
|
||
- id: sync-docs-yapi
|
||
content: 更新 lucky_reward_api.md、04 需求 §7、YApi
|
||
status: completed
|
||
isProject: false
|
||
---
|
||
|
||
# To Balance 后展示领取金额 — 方案(迭代)
|
||
|
||
## 产品诉求(新增)
|
||
|
||
客户端 To Balance **成功之后**,仍要在活动页展示**领取时的金额**(含刷新 status、再次进入活动,不能只靠 toBalance 响应本地缓存)。
|
||
|
||
当前问题:`toBalance` 把 `my_amount_qf = 0` 后,`POST /api/lucky-reward/status` 的 `myAmountDisplay` 变为 `0.00`,客户端无法继续展示 $10.00 等已领取金额。
|
||
|
||
---
|
||
|
||
## 推荐方案:库内清零 + status 展示回填(推荐)
|
||
|
||
**不改为「不清零 my_amount_qf」**,而是区分「活动进度」与「展示金额」:
|
||
|
||
| 层 | 行为 |
|
||
| --- | --- |
|
||
| DB `my_amount_qf` | **继续清零** — 表示本轮可 Spin 累积的进度已兑现,避免尾差/Spin 叠加 |
|
||
| DB `status` | **已提取(3)** — 客户端据此隐藏 To Balance 按钮 |
|
||
| status 响应 `myAmountDisplay` | **已提取时**从 [`LuckyRewardCashoutRecordModel::findSuccessByUidAndCycle`](slot_console/app/model/common/LuckyRewardCashoutRecordModel.php) 读 `amount_qf`,经 `formatAmountDisplay()` 返回 |
|
||
|
||
改动点:[`LuckyRewardLogic::buildStateEntity()`](slot_console/app/api/logic/LuckyRewardLogic.php)(约 788–806 行)
|
||
|
||
```php
|
||
// 伪代码
|
||
if ($hasOpenedBox && (int)$activityPlayer->status === STATUS_WITHDRAWN) {
|
||
$cashout = LuckyRewardCashoutRecordModel::findSuccessByUidAndCycle($uid, $cycleId);
|
||
$myAmountQf = $cashout !== null ? (int)$cashout->amount_qf : 0;
|
||
} else {
|
||
$myAmountQf = $hasOpenedBox ? (int)$activityPlayer->my_amount_qf : 0;
|
||
}
|
||
```
|
||
|
||
展示值为**实际入账金额**(`floor(my_amount/10)*10` 后的值),与 toBalance 响应 `amountDisplay` 一致,语义正确。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
toBalance[toBalance 成功] --> zero["my_amount_qf=0\nstatus=已提取"]
|
||
zero --> cashoutRow[cashout_record 保留 amount_qf]
|
||
cashoutRow --> statusPoll[客户端调 status]
|
||
statusPoll --> display["myAmountDisplay=提取金额\nplayerStatus=3"]
|
||
```
|
||
|
||
---
|
||
|
||
## 备选方案:取消清零(不推荐单独使用)
|
||
|
||
删除 `my_amount_qf = 0` 一行,status 直接读库内 `my_amount_qf` 即可展示。
|
||
|
||
**缺点**(见原分析):
|
||
|
||
- 尾差残留(转入 floor 后库内仍 > 转入额)
|
||
- 提取后若还有 Spin,[`executeManualSpin`](slot_console/app/api/logic/LuckyRewardLogic.php) 会改 `my_amount_qf` / 把 `status` 改回可提取(2)
|
||
- 与需求文档 §7「my_amount 本笔归零」不一致
|
||
|
||
若走此方案,**必须**同步加 Spin 拦截,否则状态机会脏。
|
||
|
||
---
|
||
|
||
## 必须配套:已提取用户禁止 Spin
|
||
|
||
无论是否清零,[`executeManualSpin()`](slot_console/app/api/logic/LuckyRewardLogic.php) 当前**不校验** `STATUS_WITHDRAWN`。提取后若 `spin_available > 0`(邀请 Spin 等),仍可能:
|
||
|
||
- 增加 `my_amount_qf`
|
||
- 把 `status` 从 3 改回 2
|
||
|
||
建议在 Spin 入口增加:
|
||
|
||
```php
|
||
if ((int)$activityPlayer->status === LuckyRewardPlayerModel::STATUS_WITHDRAWN) {
|
||
throw new BusinessException('Already withdrawn this cycle');
|
||
}
|
||
```
|
||
|
||
资金安全仍由 `cashout_record` 幂等保证;此拦截主要为**状态一致 + 展示正确**。
|
||
|
||
---
|
||
|
||
## 客户端约定(无需新字段)
|
||
|
||
沿用现有 [`LuckyRewardStateEntity`](slot_console/app/entity/luckyReward/LuckyRewardStateEntity.php):
|
||
|
||
- `playerStatus === 3`(已提取)→ 隐藏 To Balance / 展示「已领取」态
|
||
- `myAmountDisplay` → 仍展示进度条/金额数字(提取后由服务端回填为领取金额)
|
||
- toBalance 当场成功仍可用响应 `amountDisplay`;之后以 status 为准
|
||
|
||
**不新增** `withdrawnAmountDisplay` 字段,除非客户端希望区分「当前可提进度」与「历史已提」——当前产品只需展示领取金额,复用 `myAmountDisplay` 即可。
|
||
|
||
---
|
||
|
||
## 需求文档调整
|
||
|
||
[`04_slot_console_活动主流程方案.md`](docs/requirements/lucky_rewards/04_slot_console_活动主流程方案.md) §7 第 6 步建议改为:
|
||
|
||
> 成功:写 cashout_record;`player.status=已提取`、**`my_amount_qf` 归零(进度清空)**;**status 接口对已提取用户 `myAmountDisplay` 取 cashout_record.amount_qf 展示**。
|
||
|
||
---
|
||
|
||
## 实施范围(待你确认后执行)
|
||
|
||
| 文件 | 改动 |
|
||
| --- | --- |
|
||
| [`LuckyRewardLogic.php`](slot_console/app/api/logic/LuckyRewardLogic.php) | `buildStateEntity` 已提取回填;`executeManualSpin` 拦截已提取 |
|
||
| 集成测 | 新增/扩展:toBalance 后 status 的 `myAmountDisplay` 等于提取额 |
|
||
| [`lucky_reward_api.md`](slot_console/doc/lucky_reward_api.md) + YApi #554/#561 | status 字段说明:已提取时 myAmountDisplay 含义 |
|
||
| 需求 §7 | 与实现对齐 |
|
||
|
||
**不改动**:`toBalance` 内 `my_amount_qf = 0`(保留)。
|
||
|
||
---
|
||
|
||
## 原分析问题答复(更新结论)
|
||
|
||
| 问题 | 更新结论 |
|
||
| --- | --- |
|
||
| 必须清零吗? | **库内建议继续清零**;展示不清零,改由 status 回填 |
|
||
| 不清零唯一目的「展示金额」? | **否**;用 cashout_record 回填更干净 |
|
||
| 重复打款? | 仍靠 cashout_record,与是否清零无关 |
|