抽奖大转盘设计演化

刚开始只有一个抽奖大转盘活动 有以下抽奖规则数据库

  • 每一个用户天天能够抽3次json

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

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

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

对应的数据库表设计为ci

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 '抽奖活动配置';

可是后面又有开宝箱活动须要复用抽奖大转盘的玩法 而开宝箱与已有的抽奖大转盘又有所不一样 以下所示rem

名称 开宝箱 抽奖频道
开始时间 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字段中get

如抽奖大转盘it

{
   "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的积分规则引擎设计实现案例

相关文章
相关标签/搜索