Files
cursor/plans/第一档提现独立接口_6b3aaf7e.plan.md
ray zhou f71a5c59af ok
2026-05-29 11:21:40 +08:00

163 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: 第一档提现独立接口
overview: 将 Free Credits 第一档免打码提现从 `POST /api/withdraw/apply` 拆出,新增 `POST /api/free-credits/withdraw-first-cash`(与 `keep-first-cash` 并列);普通提现接口保持原样,不再识别 `package_id`
todos:
- id: validator-migrate
content: FreeCreditsValidator 增加 withdraw-first-cash 各支付 sceneWithdrawValidator 移除 *_fc
status: completed
- id: controller-endpoint
content: FreeCreditsController::withdrawFirstCash + 注释更新
status: completed
- id: withdraw-service-split
content: WithdrawService 抽出 public applyFreeCreditsFirstCashapply() 去掉 package_id 分支
status: completed
- id: withdraw-controller-clean
content: WithdrawController::apply 仅保留普通提现校验与文案
status: completed
- id: tests-update
content: 迁移/更新 Validator 与 FreeCreditsFirstCashoutApplyTest 单测
status: completed
isProject: false
---
# 第一档提现独立接口
## 现状
第一档独立提现与**普通钱包提现**共用同一入口:
```mermaid
flowchart LR
client[C端]
withdrawApply["POST /api/withdraw/apply"]
withdrawSvc[WithdrawService::apply]
fcLogic[FreeCreditsLogic::applyFirstCashoutWithdraw]
pay[PayService::apply]
client --> withdrawApply
withdrawApply -->|"package_id > 0"| withdrawSvc
withdrawApply -->|"无 package_id"| withdrawSvc
withdrawSvc --> fcLogic --> pay
```
关键代码:
- [`WithdrawController::apply`](slot_console/app/api/controller/WithdrawController.php)`package_id` 非空时走 `WithdrawValidator::firstCashoutScene`
- [`WithdrawService::apply`](slot_console/app/service/WithdrawService.php) L167168`package_id > 0` 时调用 `applyFreeCreditsFirstCashout` → [`FreeCreditsLogic::applyFirstCashoutWithdraw`](slot_console/app/api/logic/FreeCreditsLogic.php)
- 第一档「保留余额」已是独立接口:`POST /api/free-credits/keep-first-cash`[`FreeCreditsController`](slot_console/app/api/controller/FreeCreditsController.php)
目标形态:
```mermaid
flowchart LR
normal["POST /api/withdraw/apply\namount + 绑卡"]
fcWithdraw["POST /api/free-credits/withdraw-first-cash\npackage_id + 绑卡"]
keep["POST /api/free-credits/keep-first-cash\npackage_id"]
normal --> walletWithdraw[余额/手续费/黑规则]
fcWithdraw --> fcLogic[FreeCreditsLogic]
keep --> walletKeep[freeCreditsFirstCashKeep]
```
## 新接口契约
| 项 | 约定 |
| --- | --- |
| 路径 | `POST /api/free-credits/withdraw-first-cash`Webman 默认路由 → `FreeCreditsController::withdrawFirstCash` |
| 入参 | `package_id`(必填)、`type`1/2/3/6、各支付方式绑卡字段与现 `WithdrawValidator``*_fc` scene 一致)、可选 `pay_net` |
| 成功 `data` | `{ order_id, amount }`(与现第一档走 `withdraw/apply` 的返回一致,**不**改 `buildStatus` |
| 成功 `msg` | 沿用现第一档文案:`Submitted successfully! Your order is under review...` |
| 业务逻辑 | **复用** `FreeCreditsLogic::applyFirstCashoutWithdraw`Pay 回调、`handleFirstCashoutResult`、档位状态机**不变** |
与 [`keep-first-cash`](slot_console/app/api/controller/FreeCreditsController.php) 对称:同属 Free Credits 活动域,第一档二选一:
- **Withdraw** → `POST /api/free-credits/withdraw-first-cash`
- **Keep** → `POST /api/free-credits/keep-first-cash`
## 实现步骤(仅 slot_console
### 1. 新 Controller 方法
文件:[`FreeCreditsController.php`](slot_console/app/api/controller/FreeCreditsController.php)
- 新增 `withdrawFirstCash(Request $request)`
- 校验 → 构建 `WithdrawApplyDTO`(复用现有 DTO`package_id` + 绑卡字段)→ 调用提现编排(见下)
- 更新类注释:第一档提现改指向新路径
### 2. 校验迁移到 FreeCreditsValidator
文件:[`FreeCreditsValidator.php`](slot_console/app/api/validator/FreeCreditsValidator.php)
从 [`WithdrawValidator`](slot_console/app/api/validator/WithdrawValidator.php) **迁入**
- `SCENE_WITHDRAW_FIRST_CASH_CASH` / `_BTC` / `_USDT` / `_PAYPAL`(命名可与原 `*_fc` 对齐或重命名)
- `type``user_name``cash_tag``btc``usdt``paypal_*``email` 等 rule`*_fc` scene 字段集)
- 静态方法 `firstCashoutScene(int $type): string`(原 `firstCashoutScene`
[`WithdrawValidator`](slot_console/app/api/validator/WithdrawValidator.php)**删除** `SCENE_APPLY_*_FC``firstCashoutScene` 及对应 scene 配置。
### 3. 提现编排仍放 WithdrawService绑卡 + 锁)
文件:[`WithdrawService.php`](slot_console/app/service/WithdrawService.php)
- 将现有 `applyFreeCreditsFirstCashout` 提升为 **`public function applyFreeCreditsFirstCash(WithdrawApplyDTO $applyDTO): array`**,内容包含:
- `is_bind_name` 校验
- Redis 防重复提交锁(与 `apply` 相同 key
- `checkBankInfo` + `FreeCreditsLogic::applyFirstCashoutWithdraw`
- [`apply()`](slot_console/app/service/WithdrawService.php)**删除** `if ($applyDTO->package_id > 0)` 分支,仅保留普通提现路径
说明:绑卡逻辑仍在 `WithdrawService` 私有方法中Logic 层不重复实现,避免违反分层「不中转 Service」时仍复用已有绑卡能力。
### 4. 精简 WithdrawController
文件:[`WithdrawController.php`](slot_console/app/api/controller/WithdrawController.php)
- `apply()` 仅按 `type` 选普通 scene`(string) $type`
- 移除 `package_id` 分支与差异化 `msg`
**不对**旧接口传 `package_id` 做拒绝或转发(按你的确认:无需处理)。
### 5. DTO / 字段
[`WithdrawApplyDTO`](slot_console/app/api/dto/request/WithdrawApplyDTO.php)`package_id` 字段可保留供新接口使用;注释改为「仅 free-credits/withdraw-first-cash 使用」。普通 `withdraw/apply` 不再读取该字段。
### 6. 单测与文档注释
| 文件 | 改动 |
| --- | --- |
| [`WithdrawValidatorFreeCreditsTest.php`](slot_console/tests/Unit/WithdrawValidatorFreeCreditsTest.php) | 迁至 `FreeCreditsValidatorWithdrawFirstCashTest`(或合并进 `FreeCreditsValidatorTest`),断言新 scene |
| [`FreeCreditsFirstCashoutApplyTest.php`](slot_console/tests/Integration/FreeCreditsFirstCashoutApplyTest.php) | 改为调用 `WithdrawService::applyFreeCreditsFirstCash`(或经新 Controller harness断言仍是不走余额校验、Pay 失败回滚 ready |
| [`FreeCreditsController.php`](slot_console/app/api/controller/FreeCreditsController.php) / [`FreeCreditsValidator.php`](slot_console/app/api/validator/FreeCreditsValidator.php) | 注释同步新路径 |
运行:
```bash
docker exec -w /app/www/slot/slot_console php82 ./vendor/bin/phpunit \
tests/Unit/FreeCreditsValidatorTest.php \
tests/Unit/WithdrawValidatorFreeCreditsTest.php \
tests/Integration/FreeCreditsFirstCashoutApplyTest.php
```
(迁移后调整具体测试文件名。)
## 不在本次范围
- slot_pwa / gateway 前端改 URL联调时 C 端将 Withdraw 按钮从 `/api/withdraw/apply` 改为 `/api/free-credits/withdraw-first-cash`
- slot_pay / wallet / EventBus 回调逻辑
- `keep-first-cash``claim``status` 行为
## C 端联调要点
第一档 `packages[0].status === 1` 时:
- **Withdraw** → `POST /api/free-credits/withdraw-first-cash` + `package_id` + 支付方式字段
- **Keep** → 现有 `POST /api/free-credits/keep-first-cash`
普通提现页仍用 `POST /api/withdraw/apply``amount` 必填,**不传** `package_id`)。
## 验收
1. 新接口:第一档 ready + 合法绑卡 → 返回 `order_id`/`amount`package → `processing`Pay 失败回滚 `ready`
2. 新接口:非 ready / 无资格 / processing 中 → 业务异常与现逻辑一致
3. `POST /api/withdraw/apply`:仅普通提现;带 `amount` 走余额/手续费校验;**不再**因 `package_id` 进入 Free Credits 分支
4. `keep-first-cash` / `claim` / 提现结果回调回归不受影响
5. 相关单测通过