157 lines
6.1 KiB
Markdown
157 lines
6.1 KiB
Markdown
---
|
||
name: C端 status 响应补全
|
||
overview: 完成 Free Credits 定格状态接口 C 端响应:packages 精简与 status 映射(Model 已改)、banner_image、首笔提现成功广播 broadcast(真实 Top10 + 不足补假数据),并同步单测与文档。
|
||
todos:
|
||
- id: add-banner-image
|
||
content: 在 buildConfigClientFields / buildStatus / buildPreEnrollmentStatus 返回 banner_image
|
||
status: completed
|
||
- id: add-broadcast-list
|
||
content: 实现 broadcast 列表(真实首档 completed Top10 + 假数据补齐至 10 条)
|
||
status: completed
|
||
- id: finish-packages-docs
|
||
content: 更新 FreeCreditsController PHPDoc(packages、banner_image、broadcast)
|
||
status: completed
|
||
- id: update-unit-tests
|
||
content: 调整 FreeCreditsClientStatusTest / Harness;补充 banner_image、status 映射、broadcast 用例
|
||
status: completed
|
||
- id: run-phpunit
|
||
content: php82 容器跑 FreeCreditsClientStatusTest 验证
|
||
status: completed
|
||
isProject: false
|
||
---
|
||
|
||
# C 端定格 status 响应补全
|
||
|
||
## 当前进度
|
||
|
||
[FreeCreditsPackageModel.php](slot_console/app/model/common/FreeCreditsPackageModel.php) **已完成**:
|
||
- `mapStatusForClient()`:DB status 4/5 → 3
|
||
- `listForClient()`:仅返回 `id`、`amount`、`status`
|
||
|
||
**待完成**:`banner_image`、`broadcast`、Logic/Controller 文档、单测。
|
||
|
||
## 1. `banner_image`(活动 Banner)
|
||
|
||
配置:`ext_config.banner_image`([activity/edit.vue](backend/slot_admin_vue/src/views/game/activity/edit.vue))
|
||
|
||
在 [FreeCreditsLogic.php](slot_console/app/api/logic/FreeCreditsLogic.php) 的 `buildConfigClientFields()` 增加 `banner_image`,`buildStatus()` / `buildPreEnrollmentStatus()` 透传;`status=-1` 仍仅 `{ status: -1 }`。
|
||
|
||
## 2. `broadcast`(首笔提现成功最近 10 人)
|
||
|
||
对齐需求文档 [§13 广播模块](docs/requirements/首充前免费余额定格与分档释放需求文档.md):弹窗展示最近 10 条;用户本次明确要求 **仅首笔提现成功**(非后续 claim)。
|
||
|
||
### 2.1 顶层字段
|
||
|
||
- 字段名:**`broadcast`**(`array`,固定长度 **10**)
|
||
- 每项结构:
|
||
|
||
```json
|
||
{ "username": "U1***3", "amount": 20.0 }
|
||
```
|
||
|
||
| 子字段 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `username` | string | 脱敏账号,展示用 |
|
||
| `amount` | float | 该用户首笔免打码提现金额(展示大单位) |
|
||
|
||
C 端文案示例:`🎉 U1***3 just cashed out $20.00`(前端拼接,接口只给结构化数据)。
|
||
|
||
### 2.2 真实数据查询
|
||
|
||
在 [FreeCreditsPackageModel.php](slot_console/app/model/common/FreeCreditsPackageModel.php) 新增查询方法(仅查库,不做脱敏):
|
||
|
||
```php
|
||
public static function listRecentFirstCashoutCompleted(int $activityId, int $limit = 10): array
|
||
```
|
||
|
||
条件:
|
||
- `activity_id = ?`
|
||
- `package_type = TYPE_FIRST_CASH(1)`
|
||
- `status = STATUS_COMPLETED(3)`
|
||
- `ORDER BY completed_time DESC`(`completed_time` 为空则 fallback `update_time`)
|
||
- `LIMIT 10`
|
||
|
||
返回行至少含:`uid`、`amount_qf`。
|
||
|
||
### 2.3 组装与脱敏(Logic)
|
||
|
||
在 [FreeCreditsLogic.php](slot_console/app/api/logic/FreeCreditsLogic.php) 新增 `buildBroadcastList(?Model $config): array`:
|
||
|
||
1. 有 `activity_id` 时查真实记录,逐条:
|
||
- `amount` = `formatClientAmount(amount_qf)`
|
||
- `username` = `maskDisplayName(account)`:`UserService::getUserInfoEntity($uid)->account`,规则与 [GameLatestLogic::username()](slot_console/app/napi/logic/GameLatestLogic.php) 一致:`substr(0,2) + '***' + substr(-1)`;account 为空时用 `strval(uid)` 再脱敏
|
||
2. 若真实条数 `< 10`,用 **`buildFakeBroadcastItems($need, $config)`** 补齐:
|
||
- `amount`:取当前活动 `first_cash_amount`(`configAmount` + `formatClientAmount`),可在 ±10% 内随机浮动(整数分位),避免 10 条完全相同
|
||
- `username`:随机生成 `U` + 5–8 位数字再脱敏(勿与真实 uid 重复)
|
||
3. 合并后 **截断/保证恰好 10 条**(真实在前,假数据在后)
|
||
|
||
在 `buildStatus()` / `buildPreEnrollmentStatus()` 增加:
|
||
|
||
```php
|
||
'broadcast' => $this->buildBroadcastList($config),
|
||
```
|
||
|
||
`status=-1` 不返回 `broadcast`。
|
||
|
||
### 2.4 分层说明
|
||
|
||
- **Model**:只负责按条件查最近 N 条首档 completed
|
||
- **Logic**:脱敏、金额格式化、假数据补齐(业务展示规则,不抽到 Service)
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
pkgTable[free_credits_package]
|
||
modelQuery[listRecentFirstCashoutCompleted]
|
||
logicBuild[buildBroadcastList]
|
||
fakePad[buildFakeBroadcastItems]
|
||
statusAPI["status data.broadcast"]
|
||
pkgTable --> modelQuery --> logicBuild
|
||
logicBuild --> fakePad --> statusAPI
|
||
```
|
||
|
||
## 3. packages 文档收尾
|
||
|
||
[FreeCreditsController.php](slot_console/app/api/controller/FreeCreditsController.php):`packages` 项为 `id`、`amount`、`status(0–3)`;补充 `banner_image`、`broadcast`。
|
||
|
||
## 4. 单测
|
||
|
||
[FreeCreditsClientStatusTest.php](slot_console/tests/Unit/FreeCreditsClientStatusTest.php):
|
||
|
||
| 项 | 调整 |
|
||
|---|---|
|
||
| `PLAYER_TOP_KEYS` | 增加 `banner_image`、`broadcast`;**移除** `first_cash_amount`(与当前 `buildStatus` 一致) |
|
||
| `PACKAGE_KEYS` | `['id','amount','status']` |
|
||
| 新增 | `testMapStatusForClientMapsFailedAndRejected` |
|
||
| 新增 | `testBuildStatusIncludesBannerImageFromExtConfig` |
|
||
| 新增 | `testBuildBroadcastAlwaysReturnsTenItems`:harness 注入空真实列表,断言 `count(broadcast)==10`、每项含 `username`/`amount` |
|
||
|
||
[FreeCreditsLogicHarness.php](slot_console/tests/Support/FreeCreditsLogicHarness.php):可覆写 `buildBroadcastList` 或注入 Model 查询结果,避免单测连库。
|
||
|
||
## 5. 验证
|
||
|
||
```bash
|
||
docker exec -w /app/www/slot/slot_console php82 ./vendor/bin/phpunit tests/Unit/FreeCreditsClientStatusTest.php
|
||
```
|
||
|
||
## 响应示例(status≥0)
|
||
|
||
```json
|
||
{
|
||
"status": 2,
|
||
"frozen_amount": 78.5,
|
||
"win_threshold": 50.0,
|
||
"recharge_unlock_amount": 50.0,
|
||
"help": "...",
|
||
"banner_image": "https://cdn.example.com/xxx.png",
|
||
"broadcast": [
|
||
{ "username": "U1***3", "amount": 20.0 },
|
||
{ "username": "U9***2", "amount": 20.0 }
|
||
],
|
||
"packages": [
|
||
{ "id": 101, "amount": 20.0, "status": 1 }
|
||
]
|
||
}
|
||
```
|
||
|
||
注:`broadcast` 数组长度恒为 10;示例仅展示 2 条。
|