Files
cursor/plans/Trial config by activity_code-d451269e.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

8.0 KiB
Raw Blame History


todos:

  • id: "constants" content: "TrialRewardConstantsACTIVITY_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 表 patchtrial_reward + ext JSON" status: pending
  • id: "test-e2e" content: "补 resolver 单测 + 联调验证(不依赖 center 业务配置)" status: pending isProject: false

试玩活动配置center 迁出,按 activity_code 解析

结论(对你问题的回应)

我同意你的方向,且比当前联调实现更贴合项目既有模式:

  • center 不应承载 deposit_thresholdtrial_withdrawal_capactivity_id 等业务参数;它只适合 walletApiHost 等基础设施。
  • 活动服决定业务规则:阈值、上限、开关、时间窗应来自 activity 表(运营在 slot-admin 维护),与 DepositBonusLogic / SignInLogicext 的方式一致。
  • 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 保留:walletApiHostTrialWalletGatewayService 仍需要)。


实现步骤

1. 定义活动编码与 ext 键slot-activity

TrialRewardConstants.php

  • 新增 ACTIVITY_CODE = 'trial_reward'PHP 常量,跨环境稳定)
  • 新增 ext 字段键名常量:EXT_DEPOSIT_THRESHOLDEXT_TRIAL_WITHDRAWAL_CAP
  • 删除 指向 center 的 CONFIG_KEY_ACTIVITY_ID / CODE / DEPOSIT_THRESHOLD / WITHDRAWAL_CAP
  • 保留 DEFAULT_DEPOSIT_THRESHOLDDEFAULT_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_WITHDRAWALadmin 筛选用;本期不强制code 已足够唯一标识。

3. 抽取活动配置解析(避免 Logic 堆 ext 解析)

新增小类,例如 TrialRewardActivityResolver.php

  • 输入:source(来自 TrialFirstDepositDto
  • 输出:activity_idactivity_code(快照用)、deposit_threshold*1000trial_withdrawal_cap*1000
  • 活动不存在/未启用/未命中渠道 → 抛业务异常或返回明确 reasonactivity_not_found禁止静默用 center 默认值

解析规则:

  • activity_id / activity_code 来自 DB 行
  • 阈值从 ext 读,缺省用 TrialRewardConstants::DEFAULT_*,再 MoneyTool::bigUnitToSmallUnit

4. 改造 TrialFirstDepositLogic

TrialFirstDepositLogic.php

  • handleFirstDeposit():先 resolveActivity($dto->source),再用返回的 activity_id 查/建 trial_reward_record
  • persistPool()activity_code、阈值、cap 均来自 resolver移除所有 ShareConfigService::get(trialReward.*)
  • queryRecord():同样按 ACTIVITY_CODE resolve 后再 findByUidActivity
  • resolveThresholdAmount() / 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=1new_user_only=1first_deposit_only=0(首充事件另管 Poolsource_list=["all"]、合理 start_time/end_timeactivity_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 子需求的可视化配置可后续单独做

风险与注意

  1. 必须先有 activity 行:删掉 center 配置后,若 DB 无 trial_reward 活动,首充会 activity_not_found(比误用 9001 更安全)。
  2. 历史联调数据:若 trial_reward_record 里是 activity_id=9001,新环境 activity 自增 ID 不同;新用户无影响,老测试 uid 需清数据或对齐 activity_id。
  3. ShareConfigService 仍保留:仅用于 walletApiHost 等,与试玩业务解耦。