8.0 KiB
8.0 KiB
todos:
- id: "constants" content: "TrialRewardConstants:ACTIVITY_CODE + ext 键;移除 center CONFIG_KEY_*" status: pending
- id: "model" content: "ActivityModel::findActiveByCode(activity_code, source, now)" status: pending
- id: "resolver" content: "新增 TrialRewardActivityResolver,从 activity.ext 解析 threshold/cap" status: pending
- id: "logic" content: "TrialFirstDepositLogic / queryRecord 改用 resolver,去掉 ShareConfig trialReward" status: pending
- id: "center-cleanup" content: "删除 slot-center share_config activity.trialReward 块" status: pending
- id: "seed-sql" content: "新增 activity 表 patch(trial_reward + ext JSON)" status: pending
- id: "test-e2e" content: "补 resolver 单测 + 联调验证(不依赖 center 业务配置)" status: pending isProject: false
试玩活动配置:center 迁出,按 activity_code 解析
结论(对你问题的回应)
我同意你的方向,且比当前联调实现更贴合项目既有模式:
- center 不应承载
deposit_threshold、trial_withdrawal_cap、activity_id等业务参数;它只适合walletApiHost等基础设施。 - 活动服决定业务规则:阈值、上限、开关、时间窗应来自
activity表(运营在 slot-admin 维护),与DepositBonusLogic/SignInLogic读ext的方式一致。 - 按
activity_code定位:代码里固定trial_reward(你已选 PHP 常量),各环境 DB 里activity_id可以不同,发版/切环境不依赖 center 改数字 ID。
当前临时方案的问题:
'activity' => [
'trialReward' => [
'activity_id' => 9001,
'activity_code' => 'trial_reward',
'deposit_threshold' => 50,
'trial_withdrawal_cap' => 500,
],
],
TrialFirstDepositLogic 通过 ShareConfigService 读上述键,与「活动服自治」冲突。
目标架构
sequenceDiagram
participant Pay as slot_pay
participant Act as slot_activity
participant DB as activity_table
participant Wal as slot_wallet
Pay->>Act: first_deposit(uid, source, order_no, ...)
Act->>DB: findActiveByCode(trial_reward, source, now)
DB-->>Act: activity_id + ext(deposit_threshold, cap, ...)
Act->>Wal: clearTrialBonusForPool
Act->>Act: persist trial_reward_record(uid, activity_id)
| 配置项 | 现位置 | 目标位置 |
|---|---|---|
| activity 身份 | center trialReward.activity_id |
activity.activity_code = trial_reward → 得到 activity_id |
| deposit_threshold | center | activity.ext.deposit_threshold(美元,入库 *1000) |
| trial_withdrawal_cap | center | activity.ext.trial_withdrawal_cap |
| activity_code 常量 | center | TrialRewardConstants::ACTIVITY_CODE |
center 保留:walletApiHost(TrialWalletGatewayService 仍需要)。
实现步骤
1. 定义活动编码与 ext 键(slot-activity)
- 新增
ACTIVITY_CODE = 'trial_reward'(PHP 常量,跨环境稳定) - 新增 ext 字段键名常量:
EXT_DEPOSIT_THRESHOLD、EXT_TRIAL_WITHDRAWAL_CAP等 - 删除 指向 center 的
CONFIG_KEY_ACTIVITY_ID / CODE / DEPOSIT_THRESHOLD / WITHDRAWAL_CAP - 保留
DEFAULT_DEPOSIT_THRESHOLD、DEFAULT_WITHDRAWAL_CAP作为 ext 缺省兜底(与 SignIn 读 ext 缺字段时给默认值一致)
2. ActivityModel 增加按 code 查询
在 ActivityModel.php 新增(对齐现有 findMatchedSignInBySource / findActiveByIdForDeposit 风格):
public static function findActiveByCode(string $activityCode, string $source, string $now): ?self
条件:activity_code 精确匹配 + status=1 + 时间窗 + source_list 命中(all 或 $source)。
可选后续:在 slot-foundation 增加 ActivityType::TRIAL_WITHDRAWAL,admin 筛选用;本期不强制,code 已足够唯一标识。
3. 抽取活动配置解析(避免 Logic 堆 ext 解析)
新增小类,例如 TrialRewardActivityResolver.php:
- 输入:
source(来自TrialFirstDepositDto) - 输出:
activity_id、activity_code(快照用)、deposit_threshold(*1000)、trial_withdrawal_cap(*1000) - 活动不存在/未启用/未命中渠道 → 抛业务异常或返回明确 reason(如
activity_not_found),禁止静默用 center 默认值
解析规则:
activity_id/activity_code来自 DB 行- 阈值从
ext读,缺省用TrialRewardConstants::DEFAULT_*,再MoneyTool::bigUnitToSmallUnit
4. 改造 TrialFirstDepositLogic
handleFirstDeposit():先resolveActivity($dto->source),再用返回的activity_id查/建trial_reward_recordpersistPool():activity_code、阈值、cap 均来自 resolver,移除所有ShareConfigService::get(trialReward.*)queryRecord():同样按ACTIVITY_CODEresolve 后再findByUidActivityresolveThresholdAmount()/resolveWithdrawalCap():改为接收已解析的 Activity 或 config DTO,不再读 center
失败语义建议:
| reason | 含义 |
|---|---|
activity_not_found |
无生效的 trial_reward 活动 |
wallet_clear_failed |
wallet 清零失败(保持现有) |
duplicate / success |
不变 |
5. 移除 center 试玩业务配置
改 slot-center/config/share_config.php:
- 删除整个
activity.trialReward块(不是只删 threshold) - 重启 center(本地 dev 已习惯
php webman restart -d)
6. 联调/上线数据:activity 表种子
新增 SQL 补丁,例如 slot-activity/db/patch_trial_reward_activity.sql(插入/更新 activity 行,activity_code=trial_reward):
{
"deposit_threshold": 50,
"trial_withdrawal_cap": 500,
"trial_bonus_amount": 20
}
字段建议:status=1、new_user_only=1、first_deposit_only=0(首充事件另管 Pool)、source_list=["all"]、合理 start_time/end_time。activity_id 自增即可,各环境可以不同。
7. 测试调整
- 单测
TrialFirstDepositStatusTest:纯状态机不变 - 新增 resolver 单测:mock
ActivityModel或测 ext 解析私有方法(ext 有/无字段、美元→*1000) - 联调:在 slotMysql.s_activity 执行 activity 种子后,重跑首充 happy-path(不再依赖 center trialReward)
不变更范围(刻意不做)
- slot-pay:仍只调
/innerapi/trial-reward/first-deposit,不传activity_id(符合「pay 只报事件,activity 解析活动」) - slot-wallet / slot-sdk:无改动
- slot-admin 后台表单:本期可先用 SQL 种子 + ext JSON;完整 07 子需求的可视化配置可后续单独做
风险与注意
- 必须先有 activity 行:删掉 center 配置后,若 DB 无
trial_reward活动,首充会activity_not_found(比误用 9001 更安全)。 - 历史联调数据:若
trial_reward_record里是activity_id=9001,新环境 activity 自增 ID 不同;新用户无影响,老测试 uid 需清数据或对齐 activity_id。 - ShareConfigService 仍保留:仅用于
walletApiHost等,与试玩业务解耦。