28 lines
39 KiB
JSON
28 lines
39 KiB
JSON
{"role":"user","message":{"content":[{"type":"text","text":"<user_query>\n我要在 www/slot 项目里新增「Lucky Rewards 转盘活动」,活动奖励最终要转入用户游戏现金钱包,并按新的打码类型 Y6 (Share Bonus) 计入打码/流水。请【很彻底地】调研 slot_wallet 服务。仓库路径:/Users/ray/Documents/project/www/slot/slot_wallet\n\n请重点回答并给出具体文件路径与代码引用:\n\n1. 钱包「打码/流水」体系:现有打码类型(如充值 X、首充剩余 Y1、充值赠送 Y2、活动赠送 Y3、VIP 赠送 Y4、装备退回 Y5)在代码里如何定义?是枚举、常量、还是 DB 配置?给出定义文件路径和枚举/常量清单。\n2. 「分享赠送」目前归到哪个打码类型(Y3 Promo Bonus)?在哪里发放/记录?需求要把分享赠送 + 转盘奖金改成新类型 Y6 Share Bonus,请找出所有涉及「分享赠送」打码归类的代码点。\n3. 钱包「入账/加款」的标准接口是什么?(活动赠送入账、bonus 入账)。是 Logic 方法还是对外 innerapi?其它服务(如 slot_console)如何调用钱包入账?走 slot_sdk 还是 MQ?给调用示例。\n4. 打码倍数(playthrough/wager requirement)如何配置与计算?后台可配吗?在哪个表/配置?\n5. 钱包入账的幂等如何保证?(order_no / 唯一键 / 幂等键)给示例。\n6. 是否有「活动金额转入余额(To Balance)」这种从活动进度金额转入现金钱包的现成模式?\n7. bonus / 流水相关核心表的 Model 与建表示例(2个)。\n\n输出结构化,包含文件路径、类名/方法名、常量清单、简短代码引用。不要修改任何文件。\n</user_query>"}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"正在系统调研 `slot_wallet` 的打码类型、入账接口与分享赠送相关实现。\n\n[REDACTED]"},{"type":"tool_use","name":"UpdateCurrentStep","input":{"current_step":"调研 slot_wallet 打码体系"}},{"type":"tool_use","name":"Grep","input":{"pattern":"Y[1-6]|Promo Bonus|Share Bonus|打码|playthrough|wager","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"**/*.{php,sql,md}","head_limit":80}},{"type":"tool_use","name":"Grep","input":{"pattern":"TYPE_.*Y[0-9]|WAGER_TYPE|BET_TYPE|流水类型|打码类型","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"**/*","head_limit":80}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"activity_gift|recharge_gift|first_recharge|vip_gift|withdraw_back|share|分享|Y3|Y6|Promo|TASK_TYPE|task_type|WagerTask","glob":"**/*.php","head_limit":120}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*Wager*","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*.sql","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"order_no|幂等|idempotent|unique","glob":"**/*.php","head_limit":80}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php","limit":120}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/entity/mq/WagerConfigEntity.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/WagerChannelGroupConfigModel.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":100,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"SOURCE_TYPE_SHARE|share|bonus_to|BONUS|activity_gift|SOURCE_TYPE_BONUS|SOURCE_TYPE_ACTIVITY"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"SOURCE_TYPE_SHARE|Share Bonus|share_bonus|Y6|activity_gift"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"offset":250,"limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"function update|bonusToDeposit|createTask|SOURCE_TYPE_SHARE|innerapi"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/Wallet*Controller*.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"SOURCE_TYPE_SHARE|share_bonus|Share Bonus|Y6|activity_gift"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/WalletController.php"}},{"type":"tool_use","name":"Read","input":{"limit":200,"offset":280,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"limit":200,"offset":480,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"limit":200,"offset":760,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"limit":120,"offset":1140,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":280,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletLogModel.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":60,"path":"/Users/ray/Documents/project/www/slot/slot_sdk","pattern":"update|reward|bonusToDeposit|WalletClient"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":60,"path":"/Users/ray/Documents/project/www/slot","pattern":"SOURCE_TYPE_SHARE|reward_type.*59|reward_type.*60|reward_type.*61"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_console","pattern":"SOURCE_TYPE_SHARE|reward_type.*59|reward_type.*60|reward_type.*61|share.*reward|分享"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/Wallet*.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_sdk"}},{"type":"tool_use","name":"Read","input":{"limit":150,"offset":960,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"limit":120,"offset":60,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php"}},{"type":"tool_use","name":"Read","input":{"limit":100,"offset":180,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CreateWagerTask.php"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_sdk/src/service/wallet/WalletService.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"reward_type.*59|reward_type.*60|reward_type.*61|SOURCE_TYPE_SHARE|'type'\\s*=>\\s*'reward'"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/WalletLogService.php"}},{"type":"tool_use","name":"Read","input":{"limit":120,"offset":167,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/validator/Wallet2Validator.php"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"api/wallet/update|wallet/update|bonusToDeposit|type.*reward"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/dto/request/wallet/WalletUpdateRequestDTO.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/01-数据模型与配置基础.md","limit":120}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":60,"path":"/Users/ray/Documents/project/www/slot/slot_user","pattern":"SOURCE_TYPE_SHARE|reward_type|59|60|61"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_console","pattern":"wallet.*update|WalletClient|reward_type|SOURCE_TYPE_SHARE"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_agent","pattern":"wallet.*update|reward_type|SOURCE_TYPE_SHARE|59|60|61"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"wallet/update|->update\\("}},{"type":"tool_use","name":"Read","input":{"limit":150,"offset":120,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/03-打码匹配与对接需求.md"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_agent/app/service/ReferralRewardService.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/app/service/WalletService.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":50,"path":"/Users/ray/Documents/project/www/slot/slot_lib","pattern":"TRANSACTION_TYPE|SOURCE_TYPE|59|60|61|share"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":80,"path":"/Users/ray/Documents/project/www/slot","pattern":"TRANSACTION_TYPE_SHARE|SOURCE_TYPE_SHARE|gift\\(|WALLET_TYPE_REWARD.*59|reward_type.*59"}},{"type":"tool_use","name":"Read","input":{"limit":150,"offset":230,"path":"/Users/ray/Documents/project/www/slot/slot_agent/app/innerapi/logic/AgentLogic.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"insertData|uniq_uid_bizid|Duplicate|1062"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/BaseMultiModel.php","limit":80}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":120,"offset":330,"path":"/Users/ray/Documents/project/www/slot/slot_console/app/api/controller/UserController.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/SelfBaseModel.php","limit":80}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_sdk/src/service/wallet/WalletClient.php"}},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":1100,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/db/wager_channel_group_config.sql"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":120,"path":"/Users/ray/Documents/project/www/slot/slot_console/app/service/EmailService.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_console","pattern":"agent_reward|parseAgentRewardId|TRANSACTION_TYPE_SHARE"}},{"type":"tool_use","name":"Read","input":{"limit":100,"offset":150,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/03-打码匹配与对接需求.md"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config","pattern":"wallet/update|WalletController"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":100,"offset":50,"path":"/Users/ray/Documents/project/www/slot/slot_console/app/api/controller/UserController.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/WagerChannelGroupResolveService.php"}},{"type":"tool_use","name":"Read","input":{"limit":120,"offset":1,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/03-打码匹配与对接需求.md"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"route|wallet/update"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc","pattern":"SOURCE_TYPE_SHARE|activity_gift|Y3|source_type.*59"}},{"type":"tool_use","name":"Read","input":{"limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CreateWagerTask.php"}},{"type":"tool_use","name":"Read","input":{"limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/tests/Integration/WalletControllerUpdateTest.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletAccountModel.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"config/route|Route::|api/wallet"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":120,"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/common/const/Consts.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"*.php","head_limit":20,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config","pattern":"wallet"}},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":200,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/01-数据模型与配置基础.md"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"Duplicate entry|1062|uniq_uid_bizid"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"biz_id.*findOne|findOne.*biz_id|already.*biz"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/route.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Read","input":{"limit":50,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/tests/Support/WalletUpdateTestHelper.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_agent","pattern":"agent_reward|eid.*bind|eid.*first"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":240,"path":"/Users/ray/Documents/project/www/slot/slot_agent/app/command/EventBus.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/route.php"}},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.md","head_limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc","pattern":"source_type|activity_gift|Y3|分享"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*","head_limit":30,"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"Route::|api/wallet"}},{"type":"tool_use","name":"Read","input":{"limit":80,"offset":200,"path":"/Users/ray/Documents/project/www/slot/slot_agent/app/command/EventBus.php"}},{"type":"tool_use","name":"Read","input":{"limit":80,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/02-后台管理需求.md"}},{"type":"tool_use","name":"Read","input":{"limit":60,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletStatModel.php"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet","pattern":"WalletController|api/wallet","glob":"**/*","head_limit":30}},{"type":"tool_use","name":"Read","input":{"limit":50,"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php","offset":250}},{"type":"tool_use","name":"Read","input":{"limit":50,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/ShareConfigService.php","offset":120}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"glob":"**/*.php","head_limit":20,"path":"/Users/ray/Documents/project/www/slot/slot_lib","pattern":"function generateOrderId"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*Controller.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet/app"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"limit":30,"offset":90,"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/common/CommonFn.php"}},{"type":"tool_use","name":"Read","input":{"limit":40,"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/TaskController.php"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"UpdateCurrentStep","input":{"current_step":"整理 slot_wallet 调研结论","final_summary":"已完成 slot_wallet 打码/入账体系调研:Y1–Y5 为 JSON 配置 key + source_type 常量;分享奖励经 `reward` 入账并走 Y3 `activity_gift`;标准入口为 `POST /api/wallet/update`(slot_lib HTTP,打码任务走 MQ)。**Y6 Share Bonus 当前不存在**,需新增配置 key 与 source_type 映射。","completed_subtitle":"完成 slot_wallet 全面调研"}}]}}
|
||
{"role":"assistant","message":{"content":[{"type":"text","text":"# slot_wallet 调研报告(Lucky Rewards / 打码 / 入账)\n\n> 范围:`/Users/ray/Documents/project/www/slot/slot_wallet` 为主,分享赠送链路涉及 `slot_lib`、`slot_console`、`slot_agent`。 \n> **结论前置:代码中尚无 Y6 (Share Bonus);分享三类奖励目前全部归入 Y3 `activity_gift` 倍数。**\n\n---\n\n## 1. 钱包「打码/流水」体系\n\n### 1.1 两套标识(不要混用)\n\n| 层级 | 含义 | 存储方式 | 定义位置 |\n|------|------|----------|----------|\n| **打码倍数类型 (X/Y1–Y5)** | 配置 key,决定 `required_wager = 金额 × 倍数` | Center DB + 渠道打码组 JSON | 见下表 |\n| **打码任务 source_type** | 整数,标识奖励来源 | `wager_task.source_type` 常量 | `WagerTaskModel` |\n| **用户流水 transaction_type** | 整数,PWA/前台展示用 | 请求参数 `reward_type` | `slot_lib/Consts.php` |\n\n**Y6 当前不存在**——`WagerChannelGroupConfigModel::WAGER_TYPE_KEYS` 只有 7 个 key(含 `reset_task_fee`),文档也只列到 Y5 + reset。\n\n### 1.2 打码倍数类型(X / Y1–Y5)— 常量 + DB JSON\n\n**PHP 常量**(字符串 key,非 PHP enum):\n\n`/Users/ray/Documents/project/www/slot/slot_wallet/app/model/WagerChannelGroupConfigModel.php`\n\n| 业务标签 | 常量 | JSON key |\n|----------|------|----------|\n| 充值打码 X | `WAGER_TYPE_RECHARGE` | `recharge` |\n| 充值奖励(v2 reward_amount) | (文档有 `reward`,Model 常量列表未单独列) | `reward` |\n| 首充剩余 Y1 | `WAGER_TYPE_FIRST_RECHARGE_LEFT` | `first_recharge_left` |\n| 充值赠送 Y2 | `WAGER_TYPE_RECHARGE_GIFT` | `recharge_gift` |\n| **活动赠送 Y3** | `WAGER_TYPE_ACTIVITY_GIFT` | `activity_gift` |\n| VIP 赠送 Y4 | `WAGER_TYPE_VIP_GIFT` | `vip_gift` |\n| 装备退回 Y5 | `WAGER_TYPE_WITHDRAW_BACK` | `withdraw_back` |\n| 充值重置任务金额 | `WAGER_TYPE_RESET_TASK_FEE` | `reset_task_fee` |\n\n**Entity 字段**:`/Users/ray/Documents/project/www/slot/slot_wallet/app/entity/mq/WagerConfigEntity.php`\n\n**DB 表(后台可配)**:\n\n- 表:`s_wallet.wager_channel_group_config`\n- DDL:`/Users/ray/Documents/project/www/slot/slot_wallet/db/wager_channel_group_config.sql`\n- 文档:`/Users/ray/Documents/project/www/slot/slot_wallet/doc/requirements/渠道打码组配置/01-数据模型与配置基础.md`\n\n**Center 全局配置**(version1 / win 相关倍数):\n\n- Key:`wagering_configuration`\n- 读取:`ShareConfigService::configSourceCenterData('wagering_configuration', $uid)` \n 文件:`/Users/ray/Documents/project/www/slot/slot_wallet/app/service/ShareConfigService.php`\n\n**version2 合并逻辑**:渠道组 7 项覆盖 center → `WagerChannelGroupResolveService::buildVersion2WagerConfigEntity()` \n文件:`/Users/ray/Documents/project/www/slot/slot_wallet/app/service/WagerChannelGroupResolveService.php`\n\n### 1.3 打码任务 source_type(整数常量)\n\n`/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php`\n\n与 Y 类型相关的核心常量:\n\n```34:80:/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php\n const SOURCE_TYPE_REGISTER = 1;\n const SOURCE_TYPE_FIRST_RECHARGE = 2;\n const SOURCE_TYPE_ACTIVITY_REWARD = 3;\n // ...\n const SOURCE_TYPE_FIRST_LEFT = 12; // Y1\n const SOURCE_TYPE_RECHARGE_GIFT = 16; // Y2\n const SOURCE_TYPE_WITHDRAW_BACK = 15; // Y5\n const SOURCE_TYPE_VIP = 55; // Y4\n const SOURCE_TYPE_VIP_REBATE = 58;\n const SOURCE_TYPE_SHARE_BIND = 59; // 分享-绑码\n const SOURCE_TYPE_SHARE_FIRST = 60; // 分享-首充\n const SOURCE_TYPE_SHARE_EXTRA = 61; // 分享-里程碑/阶段\n```\n\n**UI 筛选分组**(filter `source_type` 1–6 映射到 Y 类):\n\n```271:282:/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php\n $sources = [\n 1 => [self::SOURCE_TYPE_FIRST_RECHARGE, ...], // X 充值类\n 2 => [self::SOURCE_TYPE_FIRST_LEFT], // Y1\n 3 => [self::SOURCE_TYPE_RECHARGE_GIFT, ...], // Y2\n 4 => [self::SOURCE_TYPE_ACTIVITY_REWARD, self::SOURCE_TYPE_SHARE_BIND,\n self::SOURCE_TYPE_SHARE_FIRST, self::SOURCE_TYPE_SHARE_EXTRA, ...], // Y3\n 5 => [self::SOURCE_TYPE_VIP_REBATE, self::SOURCE_TYPE_VIP], // Y4\n 6 => [self::SOURCE_TYPE_WITHDRAW_BACK], // Y5\n ];\n```\n\n### 1.4 source_type → 打码倍数(version2 计算)\n\n`/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CreateWagerTask.php` 的 `version2()`:\n\n```198:209:/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CreateWagerTask.php\n if ($dto->source_type == WagerTaskModel::SOURCE_TYPE_WITHDRAW_BACK) {\n $dto->required_wager = $dto->reward_amount * $wagerConfigEntity->withdraw_back;\n } elseif (in_array($dto->source_type, [..., SOURCE_TYPE_VIP, SOURCE_TYPE_VIP_REBATE])) {\n $dto->required_wager = $dto->reward_amount * $wagerConfigEntity->vip_gift;\n } elseif ($dto->source_type == WagerTaskModel::SOURCE_TYPE_RECHARGE_SIGN) {\n $dto->required_wager = $dto->reward_amount * $wagerConfigEntity->recharge_gift;\n } elseif ($dto->source_type == WagerTaskModel::SOURCE_TYPE_FIRST_LEFT) {\n $dto->required_wager = $dto->reward_amount * $wagerConfigEntity->first_recharge_left;\n } else {\n $dto->required_wager = $dto->reward_amount * $wagerConfigEntity->activity_gift; // 默认 Y3\n }\n```\n\n**分享 59/60/61 走 `else` → Y3 `activity_gift`。**\n\n---\n\n## 2. 「分享赠送」与 Y3 归类 — 全链路代码点\n\n### 2.1 常量定义(transaction_type = source_type 数值对齐)\n\n`/Users/ray/Documents/project/www/slot/slot_lib/src/common/const/Consts.php`\n\n```64:66:/Users/ray/Documents/project/www/slot/slot_lib/src/common/const/Consts.php\n const TRANSACTION_TYPE_SHARE_BIND = 59; // 绑定分享\n const TRANSACTION_TYPE_SHARE_FIRST = 60; // 分享首充\n const TRANSACTION_TYPE_SHARE_EXTRA = 61; // 分享阶段奖励\n```\n\n### 2.2 发奖记录(slot_agent,尚未入账)\n\n| 步骤 | 文件 | 说明 |\n|------|------|------|\n| 绑码/首充/里程碑发奖 | `/Users/ray/Documents/project/www/slot/slot_agent/app/service/ReferralRewardService.php` | 写 `ref_reward_detail`,状态 `UNCLAIMED` |\n| 发站内信 | `/Users/ray/Documents/project/www/slot/slot_agent/app/command/EventBus.php` | `eid = agent_reward:{bind\\|first\\|cap}:{rewardId}` |\n\n### 2.3 用户领取 → 钱包入账(slot_console + slot_lib)\n\n| 步骤 | 文件 | 方法 | 行为 |\n|------|------|------|------|\n| 解析 eid → reward_type | `/Users/ray/Documents/project/www/slot/slot_console/app/api/controller/UserController.php` | `parseAgentRewardId()` | `bind→59`, `first→60`, `cap→61` |\n| 领取邮件 | 同上 | `receiveEmail()` | 调 `EmailService::receiveReward()` |\n| HTTP 入账 | `/Users/ray/Documents/project/www/slot/slot_console/app/service/EmailService.php` | `receiveReward()` | `slotLib\\WalletService::gift(coin, 0, $type)` |\n| 更新 agent 状态 | `UserController` | `notifyAgentAfterEmailClaim()` | slot_sdk → agent `claimByRequest` |\n\n```383:391:/Users/ray/Documents/project/www/slot/slot_console/app/api/controller/UserController.php\n switch ($category) {\n case 'bind':\n $type = Consts::TRANSACTION_TYPE_SHARE_BIND; // 59\n break;\n case 'first':\n $type = Consts::TRANSACTION_TYPE_SHARE_FIRST; // 60\n break;\n case 'cap':\n $type = Consts::TRANSACTION_TYPE_SHARE_EXTRA; // 61\n break;\n }\n```\n\n### 2.4 slot_wallet 内归类为 Y3 的代码点\n\n| # | 文件 | 位置 | 作用 |\n|---|------|------|------|\n| 1 | `WagerTaskModel.php` | `getQuery()` filter 4 | 分享三类与 Y3 活动赠送同组展示 |\n| 2 | `WalletLogic.php` | `reward()` | `reward_type>=13` 时 `source_type=reward_type`(59/60/61 原样传入) |\n| 3 | `WalletLogic.php` | `createTask()` | MQ 异步创建打码任务 |\n| 4 | `CreateWagerTask.php` | `version2()` else 分支 | **用 `activity_gift` 算倍数(Y3)** |\n| 5 | `WagerChannelGroupConfigModel.php` | 仅 `activity_gift` key | 后台只能配 Y3,无 share_bonus |\n\n`WalletLogic::reward()` 关键逻辑:\n\n```528:546:/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php\n public function reward()\n {\n $result = $this->inc();\n // ...\n $sourceType = 3;\n if ($this->requestDTO->reward_type >= 13 || $this->requestDTO->reward_type == 11) {\n $sourceType = $this->requestDTO->reward_type;\n }\n $this->createTask(0, $this->requestDTO->fee, $sourceType);\n```\n\n### 2.5 改 Y6 时需动到的点(现状无 Y6)\n\n1. `WagerChannelGroupConfigModel` — 新增 `WAGER_TYPE_SHARE_BONUS = 'share_bonus'`(或类似 key)及 `WAGER_TYPE_KEYS`\n2. `WagerConfigEntity` — 新字段\n3. `db/wager_channel_group_config.sql` + 后台 CRUD / 文档 01–02\n4. `CreateWagerTask::version2()` — 对 59/60/61(及 Lucky Rewards 新 source_type)单独分支读 Y6 倍数\n5. `WagerTaskModel::getQuery()` — filter 分组(现 filter 4 = Y3)\n6. 可选:新增 `SOURCE_TYPE_LUCKY_WHEEL` 等 source_type + `Consts::TRANSACTION_TYPE_*`\n7. `slot_lib WalletService::gift()` — 传入新 `reward_type`;**biz_id 建议用业务幂等键**(见 §5)\n\n---\n\n## 3. 钱包「入账/加款」标准接口\n\n### 3.1 对外 HTTP 入口(非 innerapi)\n\n| 项 | 值 |\n|----|-----|\n| 路由 | `POST {walletApiHost}/api/wallet/update`(Webman 约定路由) |\n| Controller | `/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/WalletController.php` → `update()` |\n| Logic | `/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php` → `run()` 按 `type` 分发 |\n| DTO | `/Users/ray/Documents/project/www/slot/slot_wallet/app/api/dto/request/wallet/WalletUpdateRequestDTO.php` |\n\n**活动赠送 / bonus 相关 `type`:**\n\n| type | Logic 方法 | 余额影响 | 打码 |\n|------|------------|----------|------|\n| `reward` | `reward()` | `deposit_balance += fee`(`inc()`) | 异步 MQ 创建任务 |\n| `bonusToDeposit` | `bonusToDeposit()` | `available_bonus → deposit_balance` | `SOURCE_TYPE_BONUS`(7) |\n| `switchBonus` | `switchBonus()` | `frozen_bonus → available_bonus` | 无 |\n| `recharge` | `recharge()` | `withdraw_balance += fee` | 充值+X/Y2 等 |\n| `freeCreditsClaim` | `freeCreditsClaim()` | 入账 deposit | Y1 |\n\n### 3.2 其它服务如何调用\n\n**主路径:HTTP(slot_lib),不是 slot_sdk 的 update。**\n\n- 封装类:`/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php`\n- `slot_sdk` 的 `WalletClient` 只有查询/统计/打码组 admin,**没有** `update()` \n 文件:`/Users/ray/Documents/project/www/slot/slot_sdk/src/service/wallet/WalletService.php`\n\n**活动赠送示例(分享领取同款):**\n\n```php\nuse slotLib\\services\\WalletService;\nuse slotLib\\common\\const\\Consts;\n\n$walletService = WalletService::getNoWalletDataService($uid, $currency, $source, $organization);\n\n// 分享首充奖励入账 + 打码(当前 Y3)\n$walletService->gift(\n $amountQf, // fee,千分位\n 0, // bonus\n Consts::TRANSACTION_TYPE_SHARE_FIRST, // reward_type = 60 → source_type 60\n 'from share'\n);\n// 内部 → POST api/wallet/update { type: 'reward', fee, reward_type: 60, biz_id, ... }\n```\n\n**bonus 转现金示例:**\n\n```php\n$walletService->bonusToDeposit($bonusQf, 'order_or_unique_biz_id');\n// → type: bonusToDeposit\n```\n\n**slot_console 包装:** `/Users/ray/Documents/project/www/slot/slot_console/app/service/WalletService.php` → `getWalletClient()` 仅用于查询;**写账仍用 slot_lib**。\n\n### 3.3 MQ 角色\n\n| MQ | 用途 |\n|----|------|\n| `EXCHANGE_WAGER_TASK_CREATE` | 入账后 `WalletLogic::createTask()` 发消息;消费者 `CreateWagerTask` 算倍数写 `wager_task` |\n| `EXCHANGE_CONSOLE_BUS` | 入账后 `sendConsoleBus()` 通知 console 统计/活动 |\n\n**入账本身走同步 HTTP;打码任务创建走 MQ。**\n\n---\n\n## 4. 打码倍数配置与计算\n\n### 4.1 配置来源\n\n| 版本 | 配置来源 | 读取方式 |\n|------|----------|----------|\n| version1 | Center `wagering_configuration` | `ShareConfigService::configSourceCenterData()` |\n| version2 | Center(win_* 等)+ **渠道打码组** 7 key | `WagerChannelGroupResolveService` + `wager_channel_group_config.wager_config` JSON |\n\n### 4.2 后台可配\n\n- **是** — `s_wallet.wager_channel_group_config`\n- Admin API:`/Users/ray/Documents/project/www/slot/slot_wallet/app/innerapi/controller/admin/WagerChannelGroupConfigController.php`\n- 也可经 slot_sdk:`WalletService::wagerChannelGroupConfigList/Save/Update(...)`\n\n### 4.3 计算公式(version2)\n\n```\nrequired_wager = intval(reward_amount × wager_multiplier)\n```\n\n- 充值本金:`recharge × recharge_amount + recharge_gift × reward_amount`(充送拆任务时另算)\n- 分享/活动默认:`reward_amount × activity_gift`(Y3)\n- 倍数为 0 → 不创建任务(`createVersion2Task` 内 `required_wager <= 0` 直接 return)\n\n---\n\n## 5. 钱包入账幂等\n\n### 5.1 DB 唯一键\n\n`wallet_log_{shard}` 表(InitDB):\n\n```103:103:/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php\n UNIQUE KEY `uniq_uid_bizid_type` (`uid`, `biz_id`, `biz_type`),\n```\n\n- **幂等键**:`(uid, biz_id, biz_type)`,`biz_type` = 请求的 `type`(如 `reward`、`recharge`)\n- 字段:`WalletUpdateRequestDTO::$biz_id`(注释:提现/充值需传订单号)\n\n### 5.2 写入路径\n\n`WalletLogic::addLog()` → `WalletLogService::create()` → `wallet_log` insert\n\n### 5.3 显式幂等短路示例\n\n`freeCreditsFirstCashoutStat()` 在写库前先查:\n\n```804:812:/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php\n $existingLog = $logModel->findOne([\n 'uid' => $this->requestDTO->uid,\n 'biz_id' => $this->requestDTO->biz_id,\n 'biz_type' => WalletLogModel::BIZ_TYPE_FREE_CREDITS_FIRST_CASHOUT_STAT,\n ]);\n if (!is_null($existingLog)) {\n return $this->snapshotWalletEntity();\n }\n```\n\n### 5.4 一般 `reward` / `recharge` 行为\n\n- 重复相同 `(uid, biz_id, biz_type)` → insert 冲突 → `addLog` 失败 → 事务回滚 → `maxRetry` 重试 → 最终抛 `WalletException`\n- **多数接口没有**像 `freeCreditsFirstCashoutStat` 那样的「命中幂等直接返回成功快照」\n- `gift()` 的 `biz_id` 由 `CommonFn::generateOrderId()` **每次随机**,依赖**邮件/业务层只领一次**做幂等,而非 wallet_log 唯一键\n\n**Lucky Rewards 建议**:`biz_id = lucky_wheel:{uid}:{spin_id}` 或活动订单号,保证 wallet 层可重入。\n\n### 5.5 并发控制\n\n- `wallet_account.version` 乐观锁;冲突 `ErrorCode::WALLET_CONFLICT_ERROR`,`maxRetry()` 最多 3 次\n\n---\n\n## 6. 「活动金额转入余额 (To Balance)」现成模式\n\n| 模式 | type | 方法 | 场景 |\n|------|------|------|------|\n| **Bonus → 现金 deposit** | `bonusToDeposit` | `WalletLogic::bonusToDeposit()` | 用户点「领取 bonus」:`available_bonus` → `deposit_balance`,打码 `SOURCE_TYPE_BONUS`(7) |\n| **活动奖励直接入账** | `reward` | `WalletLogic::reward()` | 邮件/活动领取,直接加 `deposit_balance` |\n| **Free Credits 分档释放** | `freeCreditsClaim` | `WalletLogic::freeCreditsClaim()` | 活动进度金额释放到 deposit + Y1 打码 |\n| **第一档保留可提** | `freeCreditsFirstCashKeep` | 入账 `withdraw_balance`,**不打码** |\n| **冻结 bonus 可领** | `switchBonus` | 仅 `frozen → available`,未到现金 |\n\n最接近「活动进度 → 游戏现金钱包」的是 **`freeCreditsClaim`** 和通用的 **`reward`**。 \n`bonusToDeposit` 是「返利池 → 现金」,不是活动进度表,但是成熟的 To Balance 模式。\n\n`bonusToDeposit` 核心:\n\n```326:359:/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php\n public function bonusToDeposit()\n {\n // ...\n $ok = $walletService->bonusToDeposit($this->requestDTO->bonus, $wallet->version, ...);\n $ok = $this->addLog(..., $this->requestDTO->type, 0);\n $this->createTask(0, $this->requestDTO->bonus, WagerTaskModel::SOURCE_TYPE_BONUS);\n```\n\n---\n\n## 7. 核心 Model 与建表示例\n\n### 7.1 `WagerTaskModel` — 打码任务\n\n- 文件:`/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WagerTaskModel.php`\n- 表:`wallet_{NN}.wager_task_{MM}`(分库分表)\n- 建表:`/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php` → `initTask()`\n\n```192:211:/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php\n $taskSql = \"CREATE TABLE `wager_task_{$t}` (\n `id` bigint unsigned NOT NULL,\n `uid` bigint NOT NULL,\n `recharge_amount` bigint unsigned NOT NULL DEFAULT '0' COMMENT '充值金额',\n `reward_amount` bigint unsigned NOT NULL DEFAULT '0' COMMENT '奖励金额',\n `required_wager` bigint NOT NULL DEFAULT '0' COMMENT '打码量要求金额',\n `current_wager` bigint NOT NULL DEFAULT '0' COMMENT '当前已完成打码金额',\n `source_type` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '...',\n `recharge_order_id` varchar(128) NOT NULL DEFAULT '' COMMENT '可关联充值订单 ID',\n ...\n) ENGINE=InnoDB ... COMMENT='打码任务表';\";\n```\n\n(version2 需求文档还建议增加 `wager_group_name`、`wager_multiplier`、`wager_config_snapshot` 快照字段。)\n\n### 7.2 `WalletLogModel` — 账变/幂等流水\n\n- 文件:`/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletLogModel.php`\n- 表:`wallet_{NN}.wallet_log_{MM}`\n\n```90:106:/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php\n $logSql = \"CREATE TABLE `{$db}`.`wallet_log_{$t}` (\n `uid` BIGINT NOT NULL,\n `biz_type` VARCHAR(32) NOT NULL COMMENT 'register|recharge|bet|...|bonus_to_deposit|...',\n `biz_id` VARCHAR(64) NOT NULL COMMENT '业务唯一ID(幂等用)',\n `amount` BIGINT NOT NULL,\n `balance` BIGINT NOT NULL,\n ...\n UNIQUE KEY `uniq_uid_bizid_type` (`uid`, `biz_id`, `biz_type`)\n) ... COMMENT='钱包账变日志';\";\n```\n\n---\n\n## Lucky Rewards 转盘活动实施要点(基于现状)\n\n1. **入账**:`slot_lib WalletService::gift()` 或 `update('reward', ...)` + 新 `reward_type` / 新 `source_type`;`biz_id` 必须稳定唯一。 \n2. **打码**:MQ → `CreateWagerTask::version2()`;**必须先新增 Y6 配置 key**,并在 version2 分支把分享(59–61) + 转盘从 `activity_gift` 拆出。 \n3. **后台**:扩展 `wager_channel_group_config.wager_config` 与 admin 表单(参考 doc 02 的 Y3 字段模式)。 \n4. **Y6 全仓库尚不存在**——需跨 `slot_wallet` + `slot_lib` + 文档 + 后台同步新增。\n\n如需我在 Agent 模式下直接起草 Y6 改动清单或 patch 方案,可以切换模式继续。\n\n[REDACTED]"}]}}
|
||
{"type":"turn_ended","status":"success"}
|