--- name: status 接口字段精简 overview: 对照需求文档精简 C 端 status/claim 响应字段,并将所有金额由千分位(qf)转为大单位(与全站 getNumberFormat 一致);innerapi 仍返回 qf 全量。 todos: - id: package-list-for-client content: FreeCreditsPackageModel::listForClient() 返回精简字段,amount 经 getNumberFormat 转大单位 status: completed - id: slim-build-status content: buildStatus 去掉 activity_id;顶层金额与 packages 均转大单位 status: completed - id: format-first-cashout-amount content: firstCashout 响应 data.amount 同步转大单位(Pay 入参仍用 qf) status: completed - id: update-controller-phpdoc content: 更新 FreeCreditsController PHPDoc:金额为展示单位 float,非千分位 status: completed - id: client-status-test content: 单测断言字段白名单及 78500 qf → 78.5 等大单位转换 status: completed isProject: false --- # Free Credits status 接口字段精简 ## 结论 **可以且应该精简。** 当前 [`buildStatus()`](slot_console/app/api/logic/FreeCreditsLogic.php) 直接 `toArray()` 透出库表列,超出需求文档中 C 端 UI 所需信息;[`activity_id`](slot_console/app/api/logic/FreeCreditsLogic.php) 仅用于后台/内部关联,C 端无展示或交互用途。 你已确认: - **只做删减**,不新增 `total_deposit`(累计充值进度由 C 端从钱包侧获取)。 - **金额转大单位**:C 端接口不再返回千分位整数,统一转为展示金额(与 [`AgentController::formatAmountToFloat`](slot_console/app/api/controller/AgentController.php)、[`CommonFn::getNumberFormat`](slot_lib/src/common/CommonFn.php) 一致,默认 `moneyFormat=1000`、`moneyDot=2`,如 qf `78500` → `78.5`)。 --- ## 需求文档 vs 当前响应 需求文档([首充前免费余额定格与分档释放需求文档.md](docs/requirements/首充前免费余额定格与分档释放需求文档.md))描述的是 **UI 行为**,未定义 JSON 契约,但可反推 C 端必需数据: | UI 场景(文档章节) | C 端需要的数据 | | --- | --- | | 是否展示活动(`status === -1` 隐藏) | `status` | | 首页 Withdraw 是否曾达赢取门槛(§5.2、§7) | `home_withdraw_unlocked` | | 池总额 / 入口副标题「$78.50 pending」(§6.3–6.6、§9.3、§14.2) | `frozen_amount` | | 问号弹窗 / 第一档金额(§8、§10) | `first_cash_amount`、`recharge_unlock_amount` | | 档位列表 Withdraw / Unlock / Claim / Claimed(§9.3、§10–12) | `packages[]`:`id`、`package_type`、`amount`、`status` | | 发起 claim / 第一档提现(现有 API) | `packages[].id` → POST `package_id` | **当前多出的字段:** - 顶层:`activity_id`(`recharge_gift_config.id`,仅 innerapi/编排用) - `packages[]` 全表列:`player_id`、`activity_id`、`uid`、`withdraw_order_id`、`claim_biz_id`、`unlocked_time`、`claimed_time`、`completed_time`、`create_time`、`update_time` - `package_no` 可保留(便于调试与稳定排序展示),也可仅靠数组顺序;建议 **保留**(成本低、与 DB 序号一致) **命名与单位:** packages 字段由 `amount_qf` 改为 **`amount`**;顶层与各档 **`amount` 均为大单位 float**(非 qf),C 端可直接用于 `$78.50` 类文案,无需再 `/1000`。 --- ## 目标响应契约(C 端) ```json { "status": 4, "home_withdraw_unlocked": 1, "frozen_amount": 78.5, "first_cash_amount": 20, "recharge_unlock_amount": 50, "packages": [ { "id": 101, "package_no": 1, "package_type": 1, "amount": 20, "status": 1 } ] } ``` `status === -1` 时仍仅 `{ "status": -1 }`(与现逻辑一致)。 **转换规则(实现):** ```php // 与全站 C 端金额一致;qf 为库表 / 内部逻辑整数 private function formatClientAmount(int $amountQf): float { return (float) CommonFn::getNumberFormat($amountQf); } ``` - 应用于:`frozen_amount`、`first_cash_amount`、`recharge_unlock_amount`、`packages[].amount`。 - **`firstCashout` 成功响应** `data.amount` 同样转大单位;调用 Pay / 钱包时仍传 qf,仅 JSON 对外转换。 - **innerapi / 单测写库** 仍使用 `_qf` 整数,不在 DB 层改单位。 --- ## 实现方案 ```mermaid flowchart LR statusApi[status_claim_firstCashout] buildStatus[buildStatus] clientDto[toClientStatusDto] modelFull[listByPlayerId_toArray] innerapi[innerapi_list] statusApi --> buildStatus --> clientDto buildStatus --> modelFull innerapi --> modelFull ``` 1. **Logic 层统一转换**([`FreeCreditsLogic`](slot_console/app/api/logic/FreeCreditsLogic.php)) - 新增 `formatClientAmount(int $amountQf): float`(封装 `CommonFn::getNumberFormat`)。 - 供 `buildStatus`、`listForClient`(或 Model 回调)、`firstCashout` 响应共用。 2. **Model 层 C 端 packages**([`FreeCreditsPackageModel`](slot_console/app/model/common/FreeCreditsPackageModel.php)) - 新增 `listForClient(int $playerId, callable $formatAmount): array` 或 Logic 内 `array_map`:只输出 `id`、`package_no`、`package_type`、`amount`(大单位)、`status`。 - 保留 `listByPlayerId()` 供 innerapi、dev、集成测试。 3. **收口 DTO**(`buildStatus`) - 去掉 `activity_id`。 - 顶层三金额字段经 `formatClientAmount`;`packages` 用 `listForClient`。 - `status()`、`claim()` 经 `buildStatus` 返回,结构一致。 4. **firstCashout 响应** - `return ['order_id' => ..., 'amount' => $this->formatClientAmount($package->amount_qf)]`。 5. **更新文档**([`FreeCreditsController`](slot_console/app/api/controller/FreeCreditsController.php) PHPDoc) - 删除「千分位整数、展示时除以 1000」描述;改为「金额为大单位 float,精度见 `moneyDot`」。 6. **单测** - 新增 `FreeCreditsClientStatusTest`:字段白名单 + `78500` qf → `78.5` 转换断言。 7. **不改动** - [`innerapi/controller/FreeCreditsController`](slot_console/app/innerapi/controller/FreeCreditsController.php) 仍返回全量 `toArray()`。 - `FreeCreditsFreezeDev` 等内部工具继续用 `listByPlayerId`。 --- ## 字段对照表(精简前后) | 字段 | 精简前 | 精简后 | 说明 | | --- | --- | --- | --- | | `activity_id` | 有 | **删** | C 端不需要 | | `status` | 有 | 有 | 主状态机 | | `home_withdraw_unlocked` | 有 | 有 | §5.2 | | `frozen_amount` | qf 整数 | **float 大单位** | 如 78.5 | | `first_cash_amount` | qf 整数 | **float 大单位** | 如 20 | | `recharge_unlock_amount` | qf 整数 | **float 大单位** | 如 50 | | `packages[].id` | 有 | 有 | claim/cashout | | `packages[].package_no` | 有 | 有 | 序号展示 | | `packages[].package_type` | 有 | 有 | 1=提现档 2=领取档 | | `packages[].amount` | `amount_qf`(qf) | `amount`(**float 大单位**) | 重命名 + 转换 | | `firstCashout.data.amount` | qf | **float 大单位** | 与 status 一致 | | `packages[].status` | 有 | 有 | UI 状态 | | `packages[].player_id/uid/...` | 有 | **删** | 内部字段 | | `packages[].withdraw_order_id` 等 | 有 | **删** | 轮询靠主 `status` + package `status` | --- ## 风险与协调 - **Breaking change**:C 端需改为直接使用大单位金额(不再 `/1000`);删除 `activity_id`、`amount_qf` 及 packages 审计字段。 - **精度**:与 `ShareConfigService::moneyDot` / `moneyFormat` 绑定,勿手写 `/1000`,避免与 VIP/钱包接口不一致。 - **累计充值进度**:不纳入本次接口;C 端继续从钱包统计接口取(钱包侧金额亦通常为大单位)。