10 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Lucky Reward 奖池迁移 | 采用全平台统一的 reward_pool / reward_pool_item,以 pool_code = lucky_reward 承载大转盘手动 Spin 奖项;外层仅 prize_type 表达类型,lucky_reward 业务参数(含 unlockInviteCount)一律进 config;逐步替换 lucky_reward_prize_config。 |
|
false |
Lucky Reward 奖池方案评估与迁移计划
结论:pool_code = lucky_reward 可行,推荐做
方向正确:把「可复用奖池」与「活动专用抽奖/入账」拆开,比继续扩 lucky_reward_prize_config 更适合后续其它活动复用同一套表结构。
与你已确认的前提对齐:
- 全平台 一个 奖池:
pool_code = 'lucky_reward' - 替换 现有
lucky_reward_prize_config(非并存长期双写) - 外层仅
prize_type表达奖项类型;lucky_reward 业务参数(含开放条件)一律进config,避免个别字段外置导致表结构膨胀
flowchart LR
subgraph admin [slot_admin]
PoolCRUD[RewardPoolItem CRUD]
end
subgraph db [s_common]
RP[reward_pool pool_code=lucky_reward]
RPI["reward_pool_item prize_type + config"]
end
subgraph console [slot_console]
Draw[LuckyRewardDrawService]
Spin[LuckyRewardLogic.executeManualSpin]
end
PoolCRUD --> RPI
RP --> RPI
RPI --> Draw
Draw --> Spin
核心设计:prize_type 外层 + 业务参数全进 config
字段分层原则:
| 层级 | 字段 | 说明 |
|---|---|---|
| 表通用列 | pool_id、pool_code、item_code、item_name、prize_type、weight、display_text、icon_url、status、sort |
奖池项元数据,各 pool 共用 |
config JSON |
lucky_reward 及后续各 pool 的业务参数 | 含开放条件、金额区间等;禁止再拆个别业务字段到表列 |
| 禁止 | 表列 unlock_invite_count 等 lucky_reward 专用字段 |
与「通用奖池表 + pool 级 config 约定」冲突 |
1. 表字段调整(相对你初版 DDL)
原 DDL 中的 reward_type 改为 prize_type(TINYINT,奖项命中语义)。不同 pool_code 可约定不同枚举;lucky_reward 池定义如下:
| prize_type | 含义 | 抽奖 | 入账行为(与现网一致) |
|---|---|---|---|
| 1 | 随机金额 | 参与权重 | My Amount 增加(封顶至 target) |
| 2 | 1x Spin | 参与权重 | spin_available +1 |
| 3 | Cash Out | 参与权重 | playerStatus → 可提取 |
| 4 | Jackpot 展示 | 不参与(weight=0 或 Draw 过滤) | 无入账,仅转盘 UI 展示 |
常量命名沿用现有 LuckyRewardPrizeConfigModel::PRIZE_TYPE_*,迁移到 RewardPoolItemModel(或共用常量类),保证 lucky_reward_spin_record.prize_type 与 DrawResultEntity::prizeType 数值不变。
2. lucky_reward 池 config 结构(SSOT)
禁止 config 内写 prizeType(类型只看外层列)。按 prize_type 校验必填/可选字段(admin Validate + 文档):
各类型共有可选字段(参与抽奖的类型 1/2/3 常用):
| config 字段 | 说明 |
|---|---|
unlockInviteCount |
开放命中所需有效邀请人数,默认 0(无需) |
各类型专有字段:
| prize_type | 专有 config 字段 | 说明 |
|---|---|---|
| 1 随机金额 | amountMinQf, amountMaxQf |
千分位区间,min ≤ max |
| 2 1x Spin | — | 可无专有字段 |
| 3 Cash Out | — | 可无专有字段;开放条件用 unlockInviteCount |
| 4 Jackpot | displayAmountQf |
展示用金额(千分位) |
示例:
// prize_type = 1,需 3 个有效邀请后才开放
{ "unlockInviteCount": 3, "amountMinQf": 100, "amountMaxQf": 500 }
// prize_type = 3,Cash Out 需 5 个邀请
{ "unlockInviteCount": 5 }
// prize_type = 4
{ "displayAmountQf": 6666000 }
3. 外层列(不进 config)
仅保留奖池项通用列,不含 lucky_reward 业务参数:
| 字段 | 说明 |
|---|---|
weight |
抽取权重 |
display_text / icon_url / sort |
前端展示与排序 |
reward_pool_item 建议 DDL 片段(相对初版变更点):
`prize_type` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '奖项类型,lucky_reward池见 PRIZE_TYPE_* 常量',
`config` JSON NOT NULL COMMENT 'pool 业务参数,lucky_reward见文档 SSOT',
-- 删除 reward_type;不新增 unlock_invite_count 等 pool 专用列
4. 全平台单池
所有 source 共用 pool_code = lucky_reward 一套转盘格子和权重;LuckyRewardConfigService::listEnabledPrizeConfigs($configId) 改为按 pool_code 加载,不再依赖 lucky_reward_config.id。
活动 per-source 配置(开关、周期、分层开宝箱、目标金额)不变。
5. DDL 其它细节
| 项 | 建议 |
|---|---|
| 主键 | 确认 ID 策略:若无雪花发号,补 AUTO_INCREMENT |
| 时间字段 | Model 层映射 created_at/updated_at |
| 库 | s_common |
| 索引 | item 表增加 KEY idx_pool_code_status (pool_code, status)、KEY idx_prize_type (prize_type) |
6. 常量约定
/** Lucky Rewards 大转盘手动 Spin 奖池编码 */
public const POOL_CODE_LUCKY_REWARD = 'lucky_reward';
prize_type 常量(中文注释必填)与现网 1/2/3/4 对齐。
迁移与实现步骤
Phase 1 — 表结构与数据迁移
- 在
s_common执行reward_pool、reward_pool_itemDDL(prize_type+config,无reward_type、无unlock_invite_count列) - Seed:
pool_code = lucky_reward,pool_name = Lucky Rewards Wheel,status = 1 - 迁移
lucky_reward_prize_config→reward_pool_item:prize_type← 旧prize_type(直迁)weight、sort、status直迁config:写入unlockInviteCount(← 旧unlock_invite_count)+ 类型专有字段(amountMinQf/MaxQf 或 displayAmountQf)item_code:建议lr_prize_{old_id}
- 验证通过后 drop 旧表(或先 rename
_bak)
Phase 2 — slot_console 读新池抽奖
| 文件 | 变更 |
|---|---|
新建 RewardPoolModel / RewardPoolItemModel |
listEnabledByPoolCode() |
LuckyRewardConfigService |
listLuckyRewardPoolItems(),固定 POOL_CODE_LUCKY_REWARD |
LuckyRewardDrawService |
读列 prize_type;过滤读 config.unlockInviteCount(缺省 0);随机金额读 config.amountMinQf/MaxQf;Jackpot(4) 仍排除 |
DrawResultEntity |
增加 poolItemId;prizeType 来自 item 的 prize_type 列 |
LuckyRewardLogic::executeManualSpin |
切换数据源;spin_record.prize_type 仍写 Draw 结果 |
行为不变:随机封顶、+1 Spin、Cash Out 改状态、spin_record 写入。
Phase 3 — slot_admin 后台替换 CRUD
| 现状 | 目标 |
|---|---|
LuckyRewardPrizeConfigController 等 |
Lucky Reward 奖池项管理(scoped pool_code=lucky_reward) |
| Validate | 校验外层 prize_type、按类型校验 config(含 unlockInviteCount、金额区间)、权重 |
menu-lucky-rewards.sql |
路由指向新 Controller |
表单:美元展示 → 写入 config 内 _qf;unlockInviteCount 表单项写入 config;prize_type 下拉与现网四类一致。
Phase 4 — 文档、测试、清理
- 更新
02_管理后台方案.md:reward_pool_item.prize_type枚举 + config 结构 SSOT - 更新
LuckyRewardDrawServiceTestfixture:pool item 含prize_type列 + 精简 config - 删除
LuckyRewardPrizeConfigModel及旧表引用
风险与规避
| 风险 | 规避 |
|---|---|
| 运营迁移窗口改旧表 | 迁移前冻结编辑;脚本完成后立即切读新表 |
| Jackpot 无 C 端拉取 | 后台仍配 prize_type=4;后续如需动态转盘再补接口 |
| 其它 pool_code 的 prize_type 语义冲突 | 按 pool 文档约定枚举;通用表结构复用,语义由 pool_code + 文档定义 |
| config 误写 prizeType | Validate 拒绝;迁移脚本不写入 prizeType |
| 业务字段外置导致表膨胀 | 约定:除 prize_type 外 lucky_reward 参数一律 config;其它 pool 同理 |
总体评价
- 赞成
pool_code = lucky_reward作为大转盘唯一奖池编码。 - 采纳:类型语义 外层
prize_type;unlockInviteCount等业务参数进 config,与通用奖池表设计一致。 - 其它活动复用
reward_pool_item时,同一prize_type数值在不同 pool 可代表不同含义,需在各自 pool 文档中定义(lucky_reward 池先用 1/2/3/4 四态)。
确认本计划后,按 Phase 1→4 落地。