实现抽奖的过程:
-
涉及抽奖数据表:
抽奖分类表 :抽奖类型可以方便以后做其他的抽奖方式
抽奖概率表:中奖率根据需求要求配置
中奖人员记录表表:记录用户抽奖的奖品信息
编码:
主要贴出计算中奖概率代码段:
/**
* 抽奖逻辑
* @param array $data 抽奖表中有效的抽奖数据集合
* @param int $customerId 抽奖的用户
* @return mixed 返回概率数据
*/
function drawLotteryLogic($data = [],$customerId = 0) {
// 循环奖项设置数组,通过概率计算函数get_rand获取抽中的奖项id,将中奖奖品保存在数组$res['yes']中
$arr = [];
foreach ($data as $key => $val) {
$arr[$val['id']] = $val['win_rate'];// 概率数组
}
$rid = get_rand($arr); //根据概率获取奖项id
// 中奖项
$res['yes'] = [
'yes' => $data[$rid-1]['prize_name'],
'yes_id' => $data[$rid-1]['id'],
'customer_id' => $customerId,
];
unset($data[$rid-1]); // 将中奖项从数组中剔除,剩下未中奖项
shuffle($data); // 打乱数组顺序
$pr = [];
for($i = 0;$i < count($data);$i++){
// 未中奖项数组
$pr[] = [
'prize_name' => $data[$i]['prize_name'],
'id' => $data[$i]['id']
];
}
// 未中奖的信息保存在$res['no']中
$res['no'] = $pr;
return $res;
}
返回的数据:
{
"code": 200,
"msg": "Success",
"data": {
"yes": { // 中奖的数据
"yes": "谢谢参与", // 奖品名称
"yes_id": 6, // 奖品id
"customer_id": "22" // 中奖的客户
},
"no": [
{
"prize_name": "优惠券", // 未中奖的奖品名称
"id": 3 // 未中奖的奖品id
},
{
"prize_name": "15000积分",
"id": 2
},
{
"prize_name": "3000积分",
"id": 1
}
]
}
}
限制抽奖次数:
目前使用的是redis实现,存储在reids中,用户点击抽奖消耗一下机会,每人每天可抽5次,过期时间设置为today当天,第二天可继续抽奖5次。
redis配置信息:
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'prefix' => '',
'database' => 0,
'expired' => 'today' // 过期时间
];
计算抽奖次数:
/**
* redis 存储抽奖次数
* @param int $customerId 抽奖人id
* @return array|bool 返回当前抽奖的次数
*/
public function lotteryNumber($customerId = 0) {
$params = Redis::instance()->get($customerId);// 查询redis中客户抽奖次数
// 客户未抽奖
if(!isset($params) || empty($params)) {
$params = 0;
$num = 0;
$inc = $num + 1;
Redis::instance()->set($customerId,$inc);// 第一次抽奖存进redis中
}
} else {
// 每日五次抽奖次数
if($params == 5) {
return '当天抽奖次数达到上限,明日再来';
} elseif($params < 5) {
// <5次 增加抽奖次数
$inc = $params + 1;
$res = Redis::instance()->set($customerId,$inc);
} else {
return '数据有误,当前次数为:'.$params;
}
}
return $inc;
}