Files
cursor/projects/Users-ray-Documents-project-www-slot-backend/agent-transcripts/acc31887-b2c2-4094-8e2b-e942aa1121d3/acc31887-b2c2-4094-8e2b-e942aa1121d3.jsonl
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

25 lines
29 KiB
JSON
Raw 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.

{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n\"后续档瀑布拆分 + 每档新增累计充值解锁\" 这个需求你做完了没?\n</user_query>"}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"正在核对「后续档瀑布拆分 + 每档新增累计充值解锁」需求的计划与代码实现状态。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/.cursor/plans/首充剩余分档规则_509262bd.plan.md"}},{"type":"tool_use","name":"Grep","input":{"pattern":"瀑布|累计充值|unlock|waterfall","glob":"**/*.{php,vue,ts,js,md}","head_limit":50}},{"type":"tool_use","name":"Grep","input":{"pattern":"首充|firstRecharge|first_recharge|remainingTier","glob":"**/*.{php,vue,ts}","head_limit":40}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"计划里 todos 已全部标为 completed正在核对核心实现与 git 状态。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/app/api/logic/FreeCreditsLogic.php","offset":36,"limit":120}},{"type":"tool_use","name":"Grep","input":{"pattern":"buildReleasePackages|advanceByRecharge|recharge_baseline_qf|unlock_recharge_qf|splitReleasePackageAmounts","glob":"**/*","path":"/Users/ray/Documents/project/www/slot/slot_console"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*free_credits*","target_directory":"/Users/ray/Documents/project/www/slot/slot_console"}},{"type":"tool_use","name":"Shell","input":{"command":"cd /Users/ray/Documents/project/www/slot/slot_console && git log --oneline -10 && echo \"---\" && git status -sb && echo \"---\" && git diff --stat HEAD 2>/dev/null | head -30","description":"Check slot_console git history and status"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console","pattern":"advanceByRecharge|recharge_baseline|tryUnlockRelease|unlock_recharge"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/migrate_free_credits_release_tiers.sql"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/tests/Unit/FreeCreditsLogicAmountTest.php"}},{"type":"tool_use","name":"Shell","input":{"command":"cd /Users/ray/Documents/project/www/slot/backend && git status -sb 2>/dev/null; git diff --stat HEAD -- slot_admin/app/game/validate/ActivityValidate.php slot_admin_vue/src/views/game/activity/edit.vue 2>/dev/null | head -20","description":"Check slot_admin changes for this feature"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Shell","input":{"command":"cd /Users/ray/Documents/project/www/slot/slot_console && git log --oneline --all --grep=\"瀑布\\|release_tier\\|unlock_recharge\" -5 2>/dev/null; cd /Users/ray/Documents/project/www/slot/docs && git status -sb 2>/dev/null | head -5; cd /Users/ray/Documents/project/www/slot/backend/slot_admin && git status -sb 2>/dev/null | head -10","description":"Check commits and status across repos"}},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":760,"path":"/Users/ray/Documents/project/www/slot/slot_console/app/api/logic/FreeCreditsLogic.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/tests/Unit/FreeCreditsAdvanceUnlockTest.php"}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/tests/Integration","pattern":"buildReleasePackages|58500|unlock_recharge"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/tests/Integration/FreeCreditsFirstRechargeFreezeTest.php"}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/backend","pattern":"package_amount|subsequent_min|瀑布"}},{"type":"tool_use","name":"Read","input":{"limit":50,"offset":838,"path":"/Users/ray/Documents/project/www/slot/slot_console/app/api/logic/FreeCreditsLogic.php"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":50,"offset":65,"path":"/Users/ray/Documents/project/www/slot/backend/slot_admin/app/game/validate/ActivityValidate.php"}},{"type":"tool_use","name":"Shell","input":{"command":"cd /Users/ray/Documents/project/www/slot/slot_console && git diff --stat && echo \"=== backend ===\" && cd /Users/ray/Documents/project/www/slot/backend/slot_admin 2>/dev/null && git status -sb 2>/dev/null || ls /Users/ray/Documents/project/www/slot/backend/","description":"Check uncommitted diff stats across repos"}},{"type":"tool_use","name":"Shell","input":{"command":"docker exec -w /app/www/slot/slot_console php82 ./vendor/bin/phpunit tests/Unit/FreeCreditsLogicAmountTest.php tests/Unit/FreeCreditsAdvanceUnlockTest.php 2>&1","description":"Run Free Credits unit tests in Docker","block_until_ms":60000}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Shell","input":{"command":"cd /Users/ray/Documents/project/www/slot/backend/slot_admin_vue && git status -sb 2>/dev/null; cd /Users/ray/Documents/project/www/slot/docs && git status -sb 2>/dev/null; cd /Users/ray/Documents/project/www/slot/slot_console && git log -1 --oneline main 2>/dev/null && git log -1 --oneline fix/upActivity 2>/dev/null","description":"Check vue/docs git status and branch tips"}},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":240,"path":"/Users/ray/Documents/project/www/slot/docs/requirements/首充前免费余额定格与分档释放需求文档.md"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"**结论:核心代码已写完,单测通过,但还没交付完成** — 改动仍在 `fix/upActivity` 分支的工作区,未 commit / merge数据库迁移也尚未上线执行。\n\n## 已完成(代码 + 单测)\n\n计划 [`首充剩余分档规则_509262bd.plan.md`](/Users/ray/.cursor/plans/首充剩余分档规则_509262bd.plan.md) 里的 5 项 todo 在实现层面都已落地:\n\n| 模块 | 状态 |\n|------|------|\n| 瀑布拆分 `buildReleasePackages()` | 已实现 |\n| 尾档整元取整 `calcTailUnlockRechargeQf()` | 已实现 |\n| 解锁逻辑 `(totalR - baseline) >= unlock` | 已实现,含存量 `unlock_recharge_qf=0` 回退 |\n| DB 字段 + 迁移脚本 | `install.sql` 已改,另有 `migrate_free_credits_release_tiers.sql` |\n| 后台废弃 `package_amount` / `subsequent_min` | `ActivityValidate` + admin Vue 已改 |\n| 需求文档 §5.7 / §5.8 | 已更新 |\n| 单测 | 21 个用例全部 PASS |\n\n核心实现见 [`slot_console/app/api/logic/FreeCreditsLogic.php`](slot_console/app/api/logic/FreeCreditsLogic.php)\n\n```98:131:slot_console/app/api/logic/FreeCreditsLogic.php\n public static function buildReleasePackages(int $leftAmountQf): array\n {\n // ... 10/20/30/50/100 瀑布 + 尾档\n }\n```\n\n```841:866:slot_console/app/api/logic/FreeCreditsLogic.php\n private function tryUnlockReleasePackageByRecharge(...): bool\n {\n // incrementalRecharge = totalRecharge - recharge_baseline_qf\n // unlock 后 baseline 前移\n }\n```\n\n## 未完成(交付层面)\n\n当前 **3 个仓库都有未提交改动**,都在 `fix/upActivity`\n\n**slot_console**+216 / -47 行) \n- `FreeCreditsLogic.php`、Model、`install.sql`、单测 \n- 未跟踪:`db/migrate_free_credits_release_tiers.sql`、`tests/Unit/FreeCreditsAdvanceUnlockTest.php`\n\n**backend/slot_admin** \n- `ActivityValidate.php``package_amount` / `subsequent_min` 改为可选)\n\n**backend/slot_admin_vue** \n- `activity/edit.vue`、`activity/index.vue`(废弃提示 + 瀑布说明)\n\n**main 分支** 上还没有这次功能的 merge commit**线上 DB 也还没跑迁移**。\n\n## 可选项(计划里标为非必须)\n\n- C 端 `status` 接口返回 `unlock_recharge_amount` — **未做**\n- 集成测断言具体瀑布档位数/金额 — 现有集成测只验「有 release 档」,未验 `$58.50 → 5 档` 这类明细\n\n---\n\n**一句话**:业务逻辑和单测都好了,但还没 commit、PR、merge、跑迁移所以**不能算正式上线完成**。需要的话我可以帮你整理 commit 清单、PR 描述和上线步骤(含迁移执行顺序)。\n\n[REDACTED]"}]}}
{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n帮我写一份这个需求的部署文档呗\n</user_query>"}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"正在收集迁移脚本、配置与上线依赖,以便编写准确的部署文档。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/migrate_free_credits_release_tiers.sql"}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/install.sql","pattern":"free_credits","-A":3}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console","pattern":"handleRecharge|advanceByRecharge|free_credit","glob":"**/*.{php,php}","head_limit":30}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/config/free_credits.php"}}]}}
{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n中断了吗\n</user_query>"}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"是的,上次读取被中断了。正在重新收集信息并继续编写部署文档。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/migrate_free_credits_release_tiers.sql"}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/install.sql","pattern":"free_credits","-A":2}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/deploy*.md","target_directory":"/Users/ray/Documents/project/www/slot/docs"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/db/install.sql","offset":36,"limit":45}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*","target_directory":"/Users/ray/Documents/project/www/slot/docs"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"上次确实中断了(工具读取超时)。信息已重新收集完毕,正在生成部署文档。\n\n[REDACTED]"},{"type":"tool_use","name":"CreatePlan","input":{"name":"Free Credits 部署文档","overview":"为「后续档瀑布拆分 + 每档新增累计充值解锁」编写上线部署文档,覆盖 DB 迁移、服务发布顺序、存量兼容、验收与回滚。","plan":"# Free Credits 瀑布分档 — 部署文档\n\n## 1. 变更摘要\n\n| 项 | 说明 |\n|---|---|\n| 需求 | 首充定格后,剩余金额按 10/20/30/50/100 瀑布拆分;后续档按「每档新增累计充值」解锁 |\n| 影响服务 | **slot_console**(核心)、**slot_admin** + **slot_admin_vue**(后台配置文案/校验) |\n| 不影响 | slot_wallet定格/冻结/Claim、slot_pay第一档提现、第一档 $20 / 累计 $50 解锁规则 |\n| 分支 | `fix/upActivity`(待 merge |\n\n---\n\n## 2. 发布前检查\n\n- [ ] 代码已 merge 到目标分支并通过 CI\n- [ ] 单测已通过:\n ```bash\n docker exec -w /app/www/slot/slot_console php82 \\\n ./vendor/bin/phpunit tests/Unit/FreeCreditsLogicAmountTest.php \\\n tests/Unit/FreeCreditsAdvanceUnlockTest.php\n ```\n- [ ] 确认线上是否存在**在途 Free Credits 用户**(已定格、未完成全部档位)\n- [ ] 与产品确认:存量用户走 grandfather`unlock_recharge_qf=0` 仍用旧单笔解锁规则)\n\n---\n\n## 3. 数据库迁移(必须先于代码)\n\n**库**`s_common` \n**脚本**[`slot_console/db/migrate_free_credits_release_tiers.sql`](slot_console/db/migrate_free_credits_release_tiers.sql)\n\n```sql\nALTER TABLE s_common.free_credits_package\n ADD COLUMN unlock_recharge_qf bigint unsigned NOT NULL DEFAULT 0\n COMMENT '解锁本档所需新增累计真实充值(千分位),自上一档解锁后起算'\n AFTER amount_qf;\n\nALTER TABLE s_common.free_credits_player\n ADD COLUMN recharge_baseline_qf bigint unsigned NOT NULL DEFAULT 0\n COMMENT '后续档计数起点wallet.totalRecharge 快照(千分位)'\n AFTER first_cash_amount_qf;\n```\n\n### 3.1 执行方式\n\n```bash\n# 示例:容器内 MySQL\ndocker exec -i goMysql mysql -uroot -p<password> < migrate_free_credits_release_tiers.sql\n```\n\n### 3.2 迁移后校验\n\n```sql\n-- 列存在且默认 0\nSHOW COLUMNS FROM s_common.free_credits_package LIKE 'unlock_recharge_qf';\nSHOW COLUMNS FROM s_common.free_credits_player LIKE 'recharge_baseline_qf';\n\n-- 存量数据应为 0旧规则兼容\nSELECT COUNT(*) FROM s_common.free_credits_package WHERE unlock_recharge_qf != 0;\n-- 上线前应为 0新定格用户上线后才会有非 0 值\n```\n\n### 3.3 注意事项\n\n- **先 DDL、后发代码**:新代码会读写 `unlock_recharge_qf` / `recharge_baseline_qf`;缺列会导致定格/解锁失败\n- 新装环境直接用 [`slot_console/db/install.sql`](slot_console/db/install.sql)(已含两列)\n- 迁移**幂等**:若列已存在会报错,勿重复执行;可用 `information_schema` 先查再执行\n\n---\n\n## 4. 代码发布顺序\n\n```mermaid\nflowchart LR\n db[1_DB迁移]\n console[2_slot_console]\n admin[3_slot_admin]\n vue[4_slot_admin_vue]\n db --> console --> admin --> vue\n```\n\n| 顺序 | 仓库 | 变更要点 |\n|---|---|---|\n| 1 | DB | 执行 §3 迁移 |\n| 2 | **slot_console** | `FreeCreditsLogic` 瀑布拆分 + 增量解锁Model`install.sql` |\n| 3 | **slot_admin** | `ActivityValidate::checkFreeCreditsExt` — `package_amount` / `subsequent_min_recharge` 改为可选 |\n| 4 | **slot_admin_vue** | 活动编辑页废弃提示列表页展示「10/20/30/50/100 瀑布」 |\n\n**无需重启/发布**slot_wallet、slot_pay、slot_pwa本次无接口字段变更C 端 `unlock_recharge_amount` 为可选增强,未做)\n\n---\n\n## 5. 存量用户兼容Grandfather\n\n| 用户类型 | 拆分规则 | 解锁规则 |\n|---|---|---|\n| **上线前已定格** | 保持原档位行不变 | `unlock_recharge_qf=0` → 仍按 `subsequent_min_recharge` **单笔**解锁 |\n| **上线后新定格** | `buildReleasePackages()` 瀑布拆分 | 按 `unlock_recharge_qf` + `recharge_baseline_qf` 增量累计解锁 |\n\n无需对存量数据做 backfill。 \n若运营希望存量也切新规则需单独产品决策 + 数据修复脚本(**不在本次范围**)。\n\n---\n\n## 6. 上线后验收\n\n### 6.1 新用户定格(核心)\n\n1. 测试账号:注册 → 赢取门槛 → 首充定格(如定格 $78.50,第一档 $20\n2. 查库:\n ```sql\n SELECT package_no, amount_qf, unlock_recharge_qf, status\n FROM s_common.free_credits_package\n WHERE player_id = ?\n ORDER BY package_no;\n ```\n3. 期望 release 档:`10000×3, 20000, 8500`unlock`9000, 9000, 9000, 19000, 8000`\n4. 查 player`recharge_baseline_qf` = 定格时 wallet 累计充值\n\n### 6.2 解锁链路\n\n1. 累计充满 $50 → 第一档变 ready规则未变\n2. 第一档解锁后 `recharge_baseline_qf` 更新为当前 totalR\n3. 再新增累计 $9 → 第一个 $10 release 档变 readybaseline 再次前移\n4. 尾档:面额 $8.50 时 unlock 为 $88000 qf\n\n### 6.3 后台\n\n- 新建/编辑 Free Credits 活动:可不填「解锁拆分金额」「后续解锁最小充值」\n- 活动列表显示「分档规则: 10/20/30/50/100 瀑布(新定格)」\n\n### 6.4 回归\n\n- 存量用户(`unlock_recharge_qf=0`)单笔充值解锁仍正常\n- Claim 入账、第一档提现、金额守恒 `sum(release) = frozen - first_cash` 不变\n\n---\n\n## 7. 回滚方案\n\n| 场景 | 操作 |\n|---|---|\n| **代码有问题、DB 已迁移** | 回滚 slot_console 到上一版本;**保留 DB 新列**(默认 0旧代码忽略即可 |\n| **仅后台有问题** | 单独回滚 slot_admin / slot_admin_vue |\n| **误发新代码但未迁移** | 立即补跑 §3 迁移,或回滚代码 |\n\n**不建议** DROP 新列(除非确认无新定格用户且已回滚代码)。\n\n---\n\n## 8. 监控与告警\n\n上线后关注\n\n- slot_console 日志Free Credits 定格失败、解锁异常\n- 业务指标:新定格用户的 package 行数分布(应与瀑布规则一致,不再全是 $10 均分)\n- 客诉:「再充多少解锁下一档」— 当前 C 端未返回 `unlock_recharge_amount`,需 help 文案说明\n\n---\n\n## 9. 相关文档\n\n- 需求:[`docs/requirements/首充前免费余额定格与分档释放需求文档.md`](docs/requirements/首充前免费余额定格与分档释放需求文档.md) §5.7、§5.8\n- 实现计划:[首充剩余分档规则](/Users/ray/.cursor/plans/首充剩余分档规则_509262bd.plan.md)\n\n---\n\n## 10. 建议落盘路径(确认后可写入)\n\n`docs/deploy/FreeCredits瀑布分档上线.md`\n","todos":[{"id":"write-deploy-md","content":"确认后将本文档写入 docs/deploy/FreeCredits瀑布分档上线.md"},{"id":"commit-and-pr","content":"slot_console / slot_admin / slot_admin_vue 提交并提 PR merge"},{"id":"run-db-migrate","content":"各环境先执行 migrate_free_credits_release_tiers.sql 再发 console"},{"id":"post-deploy-verify","content":"按 §6 验收新定格 + 存量 grandfather + 后台配置"}]}}]}}
{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n部署文档放到slot_console/doc文件夹下面\n</user_query>"}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"正在将部署文档路径更新为 `slot_console/doc`。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/.cursor/plans/free_credits_部署文档_149ece64.plan.md"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*","target_directory":"/Users/ray/Documents/project/www/slot/slot_console/doc"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/doc/首充前免费余额定格与分档释放需求部署说明.md","limit":40}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"StrReplace","input":{"path":"/Users/ray/.cursor/plans/free_credits_部署文档_149ece64.plan.md","old_string":" - id: write-deploy-md\n content: 确认后将本文档写入 docs/deploy/FreeCredits瀑布分档上线.md\n status: pending","new_string":" - id: write-deploy-md\n content: 确认后将本文档写入 slot_console/doc/FreeCredits瀑布分档部署说明.md\n status: pending"}},{"type":"tool_use","name":"StrReplace","input":{"path":"/Users/ray/.cursor/plans/free_credits_部署文档_149ece64.plan.md","old_string":"## 10. 建议落盘路径(确认后可写入)\n\n`docs/deploy/FreeCredits瀑布分档上线.md`","new_string":"## 10. 落盘路径\n\n[`slot_console/doc/FreeCredits瀑布分档部署说明.md`](slot_console/doc/FreeCredits瀑布分档部署说明.md)\n\n同目录已有 [`slot_console/doc/首充前免费余额定格与分档释放需求部署说明.md`](slot_console/doc/首充前免费余额定格与分档释放需求部署说明.md)(首版上线 checklist本文档专述**瀑布分档 + 增量解锁**增量变更,二者并存。"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"已更新计划,部署文档落盘路径改为:\n\n**[`slot_console/doc/FreeCredits瀑布分档部署说明.md`](slot_console/doc/FreeCredits瀑布分档部署说明.md)**\n\n说明\n- `slot_console/doc/` 下已有 [`首充前免费余额定格与分档释放需求部署说明.md`](slot_console/doc/首充前免费余额定格与分档释放需求部署说明.md)(首版上线 checklist\n- 新文档专述本次「瀑布分档 + 增量解锁」增量变更,与旧文档并存,不覆盖\n\n当前仍是 plan 阶段,文件还没写入仓库。需要我执行时,说一声「写入 doc」或「execute」我会把完整部署文档落到 `slot_console/doc/` 下。\n\n[REDACTED]"}]}}
{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n执行\n</user_query>"}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"正在将部署文档写入 `slot_console/doc/`。\n\n[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/.cursor/plans/free_credits_部署文档_149ece64.plan.md"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Write","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/doc/FreeCredits瀑布分档部署说明.md","contents":"# Free Credits 瀑布分档 — 部署说明\n\n> 本文档描述「后续档瀑布拆分 + 每档新增累计充值解锁」增量上线步骤。 \n> 首版 Free Credits 上线 checklist 见同目录 [`首充前免费余额定格与分档释放需求部署说明.md`](首充前免费余额定格与分档释放需求部署说明.md)。\n\n---\n\n## 1. 变更摘要\n\n| 项 | 说明 |\n|---|---|\n| 需求 | 首充定格后,剩余金额按 10/20/30/50/100 瀑布拆分;后续档按「每档新增累计充值」解锁 |\n| 影响服务 | **slot_console**(核心)、**slot_admin** + **slot_admin_vue**(后台配置文案/校验) |\n| 不影响 | slot_wallet定格/冻结/Claim、slot_pay第一档提现、第一档 $20 / 累计 $50 解锁规则 |\n| 分支 | `fix/upActivity`(待 merge |\n\n---\n\n## 2. 发布前检查\n\n- [ ] 代码已 merge 到目标分支并通过 CI\n- [ ] 单测已通过:\n\n```bash\ndocker exec -w /app/www/slot/slot_console php82 \\\n ./vendor/bin/phpunit tests/Unit/FreeCreditsLogicAmountTest.php \\\n tests/Unit/FreeCreditsAdvanceUnlockTest.php\n```\n\n- [ ] 确认线上是否存在**在途 Free Credits 用户**(已定格、未完成全部档位)\n- [ ] 与产品确认:存量用户走 grandfather`unlock_recharge_qf=0` 仍用旧单笔解锁规则)\n\n---\n\n## 3. 数据库迁移(必须先于代码)\n\n**库**`s_common` \n**脚本**[`db/migrate_free_credits_release_tiers.sql`](../db/migrate_free_credits_release_tiers.sql)\n\n```sql\nALTER TABLE s_common.free_credits_package\n ADD COLUMN unlock_recharge_qf bigint unsigned NOT NULL DEFAULT 0\n COMMENT '解锁本档所需新增累计真实充值(千分位),自上一档解锁后起算'\n AFTER amount_qf;\n\nALTER TABLE s_common.free_credits_player\n ADD COLUMN recharge_baseline_qf bigint unsigned NOT NULL DEFAULT 0\n COMMENT '后续档计数起点wallet.totalRecharge 快照(千分位)'\n AFTER first_cash_amount_qf;\n```\n\n### 3.1 执行方式\n\n```bash\n# 在 slot_console 目录下执行示例Docker MySQL\ndocker exec -i goMysql mysql -uroot -p<password> \\\n < /app/www/slot/slot_console/db/migrate_free_credits_release_tiers.sql\n```\n\n### 3.2 迁移后校验\n\n```sql\n-- 列存在且默认 0\nSHOW COLUMNS FROM s_common.free_credits_package LIKE 'unlock_recharge_qf';\nSHOW COLUMNS FROM s_common.free_credits_player LIKE 'recharge_baseline_qf';\n\n-- 存量数据应为 0旧规则兼容\nSELECT COUNT(*) FROM s_common.free_credits_package WHERE unlock_recharge_qf != 0;\n-- 上线前应为 0新定格用户上线后才会有非 0 值\n```\n\n### 3.3 注意事项\n\n- **先 DDL、后发代码**:新代码会读写 `unlock_recharge_qf` / `recharge_baseline_qf`;缺列会导致定格/解锁失败\n- 新装环境直接用 [`db/install.sql`](../db/install.sql)(已含两列)\n- 迁移**非幂等**:若列已存在会报错,勿重复执行;可用 `information_schema` 先查再执行\n\n---\n\n## 4. 代码发布顺序\n\n```mermaid\nflowchart LR\n db[1_DB迁移]\n console[2_slot_console]\n admin[3_slot_admin]\n vue[4_slot_admin_vue]\n db --> console --> admin --> vue\n```\n\n| 顺序 | 仓库 | 变更要点 |\n|---|---|---|\n| 1 | DB | 执行 §3 迁移 |\n| 2 | **slot_console** | `FreeCreditsLogic` 瀑布拆分 + 增量解锁Model`install.sql` |\n| 3 | **slot_admin** | `ActivityValidate::checkFreeCreditsExt` — `package_amount` / `subsequent_min_recharge` 改为可选 |\n| 4 | **slot_admin_vue** | 活动编辑页废弃提示列表页展示「10/20/30/50/100 瀑布」 |\n\n**无需重启/发布**slot_wallet、slot_pay、slot_pwa本次无接口字段变更C 端 `unlock_recharge_amount` 为可选增强,未做)\n\n---\n\n## 5. 存量用户兼容Grandfather\n\n| 用户类型 | 拆分规则 | 解锁规则 |\n|---|---|---|\n| **上线前已定格** | 保持原档位行不变 | `unlock_recharge_qf=0` → 仍按 `subsequent_min_recharge` **单笔**解锁 |\n| **上线后新定格** | `buildReleasePackages()` 瀑布拆分 | 按 `unlock_recharge_qf` + `recharge_baseline_qf` 增量累计解锁 |\n\n无需对存量数据做 backfill。 \n若运营希望存量也切新规则需单独产品决策 + 数据修复脚本(**不在本次范围**)。\n\n---\n\n## 6. 上线后验收\n\n### 6.1 新用户定格(核心)\n\n1. 测试账号:注册 → 赢取门槛 → 首充定格(如定格 $78.50,第一档 $20\n2. 查库:\n\n```sql\nSELECT package_no, amount_qf, unlock_recharge_qf, status\nFROM s_common.free_credits_package\nWHERE player_id = ?\nORDER BY package_no;\n```\n\n3. 期望 release 档:`10000×3, 20000, 8500`unlock`9000, 9000, 9000, 19000, 8000`\n4. 查 player`recharge_baseline_qf` = 定格时 wallet 累计充值\n\n### 6.2 解锁链路\n\n1. 累计充满 $50 → 第一档变 ready规则未变\n2. 第一档解锁后 `recharge_baseline_qf` 更新为当前 totalR\n3. 再新增累计 $9 → 第一个 $10 release 档变 readybaseline 再次前移\n4. 尾档:面额 $8.50 时 unlock 为 $88000 qf\n\n### 6.3 后台\n\n- 新建/编辑 Free Credits 活动:可不填「解锁拆分金额」「后续解锁最小充值」\n- 活动列表显示「分档规则: 10/20/30/50/100 瀑布(新定格)」\n\n### 6.4 回归\n\n- 存量用户(`unlock_recharge_qf=0`)单笔充值解锁仍正常\n- Claim 入账、第一档提现、金额守恒 `sum(release) = frozen - first_cash` 不变\n\n---\n\n## 7. 回滚方案\n\n| 场景 | 操作 |\n|---|---|\n| **代码有问题、DB 已迁移** | 回滚 slot_console 到上一版本;**保留 DB 新列**(默认 0旧代码忽略即可 |\n| **仅后台有问题** | 单独回滚 slot_admin / slot_admin_vue |\n| **误发新代码但未迁移** | 立即补跑 §3 迁移,或回滚代码 |\n\n**不建议** DROP 新列(除非确认无新定格用户且已回滚代码)。\n\n---\n\n## 8. 监控与告警\n\n上线后关注\n\n- slot_console 日志Free Credits 定格失败、解锁异常\n- 业务指标:新定格用户的 package 行数分布(应与瀑布规则一致,不再全是 $10 均分)\n- 客诉:「再充多少解锁下一档」— 当前 C 端未返回 `unlock_recharge_amount`,需 help 文案说明\n\n---\n\n## 9. 相关文档\n\n- 需求:[`docs/requirements/首充前免费余额定格与分档释放需求文档.md`](../../docs/requirements/首充前免费余额定格与分档释放需求文档.md) §5.7、§5.8\n- 迁移脚本:[`db/migrate_free_credits_release_tiers.sql`](../db/migrate_free_credits_release_tiers.sql)\n"}},{"type":"tool_use","name":"StrReplace","input":{"new_string":" - id: write-deploy-md\n content: 确认后将本文档写入 slot_console/doc/FreeCredits瀑布分档部署说明.md\n status: completed","old_string":" - id: write-deploy-md\n content: 确认后将本文档写入 slot_console/doc/FreeCredits瀑布分档部署说明.md\n status: pending","path":"/Users/ray/.cursor/plans/free_credits_部署文档_149ece64.plan.md"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Shell","input":{"command":"~/.cursor/hooks/verify-slot-backend.sh","description":"Run backend verify script for changed files"}}]}}
{"role":"assistant","message":{"content":[{"type":"text","text":"部署文档已写入:\n\n**[`slot_console/doc/FreeCredits瀑布分档部署说明.md`](slot_console/doc/FreeCredits瀑布分档部署说明.md)**\n\n文档内容包括\n- 变更摘要与发布前检查\n- DB 迁移(`migrate_free_credits_release_tiers.sql`)及校验 SQL\n- 发布顺序DB → slot_console → slot_admin → slot_admin_vue\n- 存量 grandfather 兼容说明\n- 上线验收步骤(新定格、解锁链路、后台、回归)\n- 回滚方案与监控要点\n\n与同目录 [`首充前免费余额定格与分档释放需求部署说明.md`](slot_console/doc/首充前免费余额定格与分档释放需求部署说明.md) 并存,前者是首版 checklist新文档专述本次增量变更。\n\n剩余待办需你或运维手动完成\n1. slot_console / slot_admin / slot_admin_vue 提交并提 PR\n2. 各环境先跑 DB 迁移再发 console\n3. 按文档 §6 做上线验收\n\n```\n=== verify-slot-backend ===\nchanged: 8 file(s), 5 php\nPASS\n```\n\n[REDACTED]"}]}}