抽奖大转盘设计演化

发布于:2023-03-27 ⋅ 阅读:(162) ⋅ 点赞:(0)

刚开始只有一个抽奖大转盘活动 有如下抽奖规则

  • 每个用户每天可以抽3次

  • 新客第一次抽奖100%中奖

  • 新客接下来抽奖只能中红包奖品

  • 中了优惠券一个月内只能中红包 中了实物半年内只能中红包

对应的数据库表设计为

create table lottery_activity(
    id int primary key auto_increment, 
    name varchar(20) not null comment '活动名称',
    start_time datetime not null default current_timestamp comment '活动起始时间', 
    end_time datetime comment '活动截止时间 为空表示无截止时间', 
    daily_draw_count tinyint default 3 not null comment '每日抽奖次数',
    new_user_probability tinyint not null comment '新客中奖概率',
    old_user_probability tinyint not null comment '老客中奖概率',
    new_user_first_probability tinyint not null comment '新客首次中奖概率',
    coupon_interval decimal(10,5) not null comment '优惠券间隔时间 单位天', 
    real_object_interval decimal(10,5) not null comment '实物间隔时间 单位天'
)charset utf8 comment '抽奖活动配置'; 

但是后面又有开宝箱活动需要复用抽奖大转盘的玩法 而开宝箱与已有的抽奖大转盘又有所不同 如下所示

名称 开宝箱 抽奖频道
开始时间 2016-09-20 2016-07-01
结束时间 2016-09-30 无截止时间
每天抽奖次数* 3
整个活动期间抽奖次数* 1
用户区分模式* 按用户等级区分 按新老客区分
用户中奖概率* v0中奖概率
v1中奖概率
v2中奖概率
v3中奖概率
v4中奖概率
...
新客中奖概率
老客中奖概率
新客首次抽奖概率
实物奖品间隔 11天 半年
优惠券奖品间隔 11天 一个月

此时抽奖活动配置表 就不够用了 于是重新设计了表结构 如下所示

Create Table: CREATE TABLE `lottery_activity` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL COMMENT '活动名称',
  `start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '活动起始时间',
  `end_time` datetime DEFAULT NULL COMMENT '活动截止时间 为空表示无截止时间',
  `daily_draw_count` tinyint(4) DEFAULT NULL COMMENT '每日抽奖次数',
  `total_draw_count` int(11) DEFAULT NULL COMMENT '活动期间总抽奖次数',
  `lottery_rules` varchar(1000) NOT NULL COMMENT '抽奖规则 json格式',
  `coupon_interval` decimal(10,5) NOT NULL COMMENT '优惠券间隔时间 单位天',
  `real_object_interval` decimal(10,5) NOT NULL COMMENT '实物间隔时间 单位天'
) CHARSET=utf8 COMMENT='抽奖活动配置'

将一些不同抽奖活动特异的抽奖规则放到lottery_rules字段中

如抽奖大转盘

{
   "old_user_probability" : 45, # 老客抽奖概率
   "first_draw_awards" : "28", # 首次抽奖才能中的奖品 如新客只有首次才能中优惠券
   "old_user_first_probability" : 45, # 老客首次抽奖概率
   "new_user_probability" : 30, # 新客抽奖概率
   "new_user_first_probability" : 100, # 新客首次抽奖概率
   "probability_configuration_mode" : 1 #中奖概率配置模式 -- 新老客
}

开宝箱

{
   "default_probability" : 100, # 默认100%中奖
   "probability_configuration_mode" : 2 #中奖概率配置模式 -- 用户等级
}

于是在代码中需要解析该json根据对应的中奖概率配置模式来计算用户的中奖概率 如

        if(PROBABILITY_CONFIGURATION_MODE_OF_NEW_OLD_USER == probabilityConfigurationMode){ // 按照新老客配置得中奖概率

            int newUserFirstProbability = (int) lotteryRulesMap.get("new_user_first_probability"); // 新客首次抽奖概率
            int newUserProbability = (int) lotteryRulesMap.get("new_user_probability"); // 新客中奖概率
            int oldUserFirstProbability = (int) lotteryRulesMap.get("old_user_first_probability"); // 老客首次抽奖概率
            int oldUserProbability = (int) lotteryRulesMap.get("old_user_probability"); // 老客抽奖概率
            probability = isPlatformNewUser?(isUserFirstDraw? newUserFirstProbability : newUserProbability): (isUserFirstDraw?oldUserFirstProbability:oldUserProbability);
        }

参考文档

基于Event Sourcing和DSL的积分规则引擎设计实现案例

本文含有隐藏内容,请 开通VIP 后查看