PHP实现抽奖功能实例代码
在项目开发中经常会遇到花钱抽奖类型的需求。但是老板总是担心用户用小钱抽到大奖。这样会导致项目亏损。下边这段代码可以有效制止抽奖项目亏钱。
个人奖池:
语言:thinkphpredismysql
表:desire抽奖商品表desire_log用户抽奖奖品表user_desire_log用户抽奖记录表 desire_risk抽奖风控表
需求:用户奖池分为进行中奖池和已完成奖池当用户抽到大奖后用户个人奖池重置否则将继续抽奖最后一次抽奖必中大奖通过风控金额来判断用户是否可以抽大奖
当所有用户已完成的抽奖盈利大于风控金额的时候可以让用户抽大奖否则用户抽不到大奖
userSessionData();///用户的唯一标识
$time=time();
$this->limit_reward_time($userData['id'],$time);///限制抽奖间隔时间防止被恶意刷奖品
//活动开启开关
$num=input('num/d');
if(!$num){
output('1008','参数错误');
}
if($num!=1){
if($num!=10){
if($num!=100){
output('1008','参数错误');
}else{
$send=$this->draw($num);
}
}else{
$send=$this->draw($num);
}
}else{
$send=$this->draw($num);
}
if($send!='金币不足'){
output('200','列表',$send);
}else{
output('1012',$send);
}
}
/////抽奖核心
publicfunctiondraw($num)
{
$userData=$this->userSessionData();
$resultSend=Cache::get('奖池名称加上用户的唯一标识,确保一人一奖池'.$userData['id']);//获取个人奖池
if(!empty($resultSend)){
$userRedis=unserialize(Cache::get('newdesiredraw'.$userData['id']));///将奖池序列化
}else{
$userRedis='';///当前用户不存在奖池
}
///查询当前用户的金币
$desireDiamonds=Db::connect('db_qmconfig')->name('user_money')->where(['uid'=>$userData['id']])->field('diamonds')->find();
$sendNum=$num;
if($desireDiamonds['diamonds']<$num){
return['msg'=>'金币不足'];///判断当前用户的金币是不是够抽奖
}
$gift_height=0;///检测是否更新个人奖池和抽奖数量
$newNum=0;///检测下一轮抽奖数量
$suiji=Db::connect('db_qmconfig')->name('desire')->order('numdesc')->find();///随机小礼物
if($userRedis){///如果用户奖池存在
$joins=[
['gift_infof','d.giftid=f.id']
];
$gift=Db::connect('db_qmconfig')->name('desire')
->alias('d')
->join($joins)
->where(['d.state'=>1])
->order('f.pricedesc')
->field('f.name,f.price,f.egif,d.num,f.id,d.position')->find();
///查询抽奖表的礼物
if(!$gift){
return['msg'=>'礼物查询错误'];
}
///查询用户的总抽奖数量
$user_all=Db::connect('db_qmconfig')->name('user_desire_log')->order('kinddesc')
->where(['uid'=>$userData['id'],'state'=>0])->field('SUM(num)askindNum')->find();
//十次抽奖必中
$count=count($userRedis);
if($num==10){
$where[]=['d.state','=',1];
$where[]=['d.ten','=',1];
$giftId=$this->giftInfo($where);
if($giftId){
$result[]=$giftId[0]['id'];
}
$num=$num-1;
}
///百次抽奖必中
if($num==100){
$where[]=['d.state','=',1];
$where[]=['d.hundred','=',1];
$giftId=$this->giftInfo($where);
$lwhere[]=['d.state','=',1];
$lwhere[]=['d.ten','=',1];
$lgiftId=$this->giftInfo($lwhere);
if($lgiftId){
for($l=0;$l<10;$l++){
$result[]=$lgiftId[0]['id'];
}
}
if($giftId){
$result[]=$giftId[0]['id'];
}
$num=$num-11;
}
if($num==1){
if($user_all){
$number1='';
$num1=str_split($user_all['kindNum']);
$number=$num1[count($num1)-1];
if($user_all['kindNum']>98){
$number1=$num1[count($num1)-2];
}
if(($number==9)&&($number1!=9)){//十抽必中
$where[]=['d.state','=',1];
$where[]=['d.ten','=',1];
$giftId=$this->giftInfo($where);
if($giftId){
$result[]=$giftId[0]['id'];
}
$num=$num-1;
}
if(($number1==9)&&($number==9)){//百抽必中
$where[]=['d.state','=',1];
$where[]=['d.hundred','=',1];
$giftId=$this->giftInfo($where);
if($giftId){
$result[]=$giftId[0]['id'];
}
$num=$num-1;
}
}
}
////判断当前奖池的奖品是否够此次抽奖如果奖池奖品数量不够此次抽奖将此次奖池抽完后获取剩下要抽将的数量重置奖池并且递归此方法传入剩下要抽的数量
if($count<$num){
$newNum=$num-$count;
$num=$count;
}
$user=Db::connect('db_qmconfig')
->name('desire_log')->where(['uid'=>$userData['id']])
->field('SUM(num)asnum')
->find();///已抽数量
if(!$user){
return['msg'=>'已抽数量有误'];
}
$res['zongshu']=Db::connect('db_qmconfig')
->name('desire')->where(['state'=>1])
->field('SUM(num)asnum,checksum')
->find();///总数量
if(!$res['zongshu']){
return['msg'=>'总数量有误'];
}
$resNum=0;
////获取个人多少次抽奖
if(($user['num']+$sendNum)>$res['zongshu']['checksum']){
$res['zongshu']['user_num']=$user['num']%$res['zongshu']['checksum'];///获取余数
if(($res['zongshu']['user_num']+$sendNum)>$res['zongshu']['checksum']){
///获取这次抽奖的数量
$resNum=$sendNum-(($res['zongshu']['user_num']+$sendNum)-$res['zongshu']['checksum']);
}
//return['msg'=>$res['zongshu']['user_num']];
}else{
$res['zongshu']['user_num']=$user['num'];
}
$cruuy=0;
///随机选择奖池
for($i=0;$i<$num;$i++){
$send=array_rand($userRedis);
if($resNum>0){
///如果本轮奖池抽完并且没有抽到大奖那么必中大奖
$result[]=$gift['id'];
$gift_height=1;//抽到大奖后更改三个变量状态
$resNum=0;
$cruuy=1;
}else{
if($userRedis[$send]==$gift['id']){
$haveJoin=[
['desire_logd','d.cid=u.id'],
['gift_infof','d.giftid=f.id']
];
$all=Db::connect('db_qmconfig')
->name('user_desire_log')
->alias('u')
->where(['u.state'=>1])
->field('SUM(u.num)asnum')->find();
//var_dump($all);
///如果抽到大奖
if($all['num']==null){
///如果这是整个奖池第一轮抽奖那么可以中大奖
$result[]=$suiji['giftid'];
}else{
$alls=Db::connect('db_qmconfig')->name('user_desire_log')
->alias('u')
->where(['u.state'=>1])
->join($haveJoin)
->field('SUM(f.price*d.num)asnum')->find();
///查询奖池风控金额
$reskList=Db::connect('db_qmconfig')->name('desire_risk')->find();
$riskPrice=$all['num']*20-$alls['num'];
///如果风控金额小于当前已完成抽奖的金额那么代表软件处于盈利状态可以中大奖
if(($riskPrice>=$reskList['price'])&&($cruuy==0)){
$result[]=$userRedis[$send];
$gift_height=1;
$cruuy=1;
}else{
///如果风控金额大于当前已完成抽奖金额不能中大奖随机选择一次小奖品替换大奖
$result[]=$suiji['giftid'];
}
}
}else{
$result[]=$userRedis[$send];
}
}
///清空个人奖池此次抽奖的礼物
unset($userRedis[$send]);
}
////新增用户抽奖次数
$result=array_count_values($result);
$user_desire_list=Db::connect('db_qmconfig')->name('user_desire_log')->order('iddesc')->where(['uid'=>$userData['id']])->find();
if($user_desire_list){
if($user_desire_list['state']==0){
$user_desire_logData['kind']=$user_desire_list['kind']+1;
}else{
$user_desire_logData['kind']=1;
}
}else{
$user_desire_logData['kind']=1;
}
$user_desire_logData['uid']=$userData['id'];
$user_desire_logData['ctime']=time();
$user_desire_logData['num']=$sendNum;
////更改此轮抽奖后用户奖池的状态
if($gift_height==1){
$user_desire_log_update=Db::connect('db_qmconfig')->name('user_desire_log')
->where(['uid'=>$userData['id'],'state'=>0])->update(['state'=>1]);
$user_desire_logData['state']=1;
}else{
$user_desire_logData['state']=0;
}
$user_desire_log=Db::connect('db_qmconfig')->name('user_desire_log')->insertGetId($user_desire_logData);
foreach($resultas$k=>$v){
if($resNum==($k+1)){
///如果这次抽奖大于奖池总数那么更新奖池并且抽奖剩下的次数
Cache::set('newdesiredraw'.$userData['id'],serialize([]));
return$this->draw($sendNum-($k+1));
}
////礼物新增用户背包
$data=[
'uid'=>$userData['id'],
'giftid'=>$k,
'num'=>$v,
'ctime'=>time(),
'cid'=>$user_desire_log
];
$join=[
['gift_infof','d.giftid=f.id']
];
$gift_info=Db::connect('db_qmconfig')->name('desire')
->alias('d')
->join($join)
->where(['d.giftid'=>$k])
->field('f.name,f.egif,d.position')->find();
$gift_infonum['num']=$v;
$list['gift'][]=array_merge($gift_info,$gift_infonum);
$desireLog=Db::connect('db_qmconfig')->name('desire_log')->insert($data);
$userKnapsack=Db::connect('db_qmconfig')->name('gift_knapsack')->where(['uid'=>$userData['id'],'giftid'=>$k])->field('id,num')->find();
if($userKnapsack){
$userKnapsackData=[
'num'=>$v+$userKnapsack['num'],
'updatetime'=>time()
];
$userKnapsackUpdate=Db::connect('db_qmconfig')->name('gift_knapsack')->where(['id'=>$userKnapsack['id']])->update($userKnapsackData);
}else{
$userKnapsackData=[
'num'=>$v,
'giftid'=>$k,
'uid'=>$userData['id'],
'createtime'=>time()
];
$userKnapsackInsert=Db::connect('db_qmconfig')->name('gift_knapsack')->insert($userKnapsackData);
}
}
///增加用户消费记录
$userXfData=[
'uid'=>$userData['id'],
'xf_price'=>$sendNum,
'xf_method'=>5,
'scene'=>19,
'status'=>1,
'ctime'=>time()
];
$userXf=Db::connect('db_qmconfig')->name('xfprice')->insert($userXfData);
if($desireLog&&$userXf){
///扣除用户金币
$newDiamondsData=[
'diamonds'=>$desireDiamonds['diamonds']-$sendNum
];
$newDiamonds=Db::connect('db_qmconfig')->name('user_money')->where(['uid'=>$userData['id']])->update($newDiamondsData);
}
if($userRedis){
Cache::set('用户奖池名称'.$userData['id'],serialize($userRedis));
////如果此轮抽奖抽到大奖重置用户个人奖池
if($gift_height==1){
Cache::set('用户奖池名称'.$userData['id'],serialize([]));
$userChecksum=$res['zongshu']['checksum']-($res['zongshu']['user_num']+$sendNum);
$desireLogUserWhere=[
'uid'=>$userData['id'],
'giftid'=>0,
'num'=>$userChecksum,
'ctime'=>time(),
'cid'=>$user_desire_log,
];
///添加礼物抽中记录
$desireLogUser=Db::connect('db_qmconfig')->name('desire_log')->insert($desireLogUserWhere);
}
$swhere[]=['d.state','=',1];
$swhere[]=['d.kind','=',1];
$res['data']=$this->giftInfo($swhere);
if(empty($res['data'])){
output('1008','奖池更新中');
}
////获取用户此轮抽奖数量返回给前端控制奖池动画百分比
$res['zongshu']=Db::connect('db_qmconfig')
->name('desire')->where(['state'=>1,'kind'=>1])
->field('checksumasnum')
->find();
$user=Db::connect('db_qmconfig')
->name('desire_log')->where(['uid'=>$userData['id']])
->field('SUM(num)asnum')
->find();
$res['diamonds']=Db::connect('db_qmconfig')
->name('user_money')->where(['uid'=>$userData['id']])
->value('diamonds');
if($user){
if($user['num']>$res['zongshu']['num']){
$res['zongshu']['user_num']=$user['num']%$res['zongshu']['num'];
}else{
$res['zongshu']['user_num']=$user['num'];
}
}else{
$res['zongshu']['user_num']=0;
}
$list['info']=$res;
return$list;
//return['msg'=>$res['zongshu']['user_num']];
}else{
////如果当前用户奖池抽完奖了那么重置此用户奖池
$where[]=['d.state','=',1];
$where[]=['d.kind','=',1];
$res=$this->giftInfo($where);
if(empty($res)){
return['msg'=>'奖池更新中'];
}
$c=[];
foreach($resas$m=>$n){
///十抽必中奖品
if($n['ten']==1){
$n['num']=$n['num']-$n['checksum']/10;
$giftarr=array_fill(0,$n['num']+$n['checksum']/10,$suiji['giftid']);
$c=array_merge($c,$giftarr);
if($n['num']<=0){
continue;
}
}
///百抽必中奖品
if($n['hundred']==1){
$n['num']=$n['num']-$n['checksum']/100;
$giftarr=array_fill(0,$n['num']+$n['checksum']/100,$suiji['giftid']);
$c=array_merge($c,$giftarr);
if($n['num']<=0){
continue;
}
}
$giftarr=array_fill(0,$n['num'],$n['id']);
$c=array_merge($c,$giftarr);
}
///随机打乱奖池
shuffle($c);
Cache::set('用户奖池名称'.$userData['id'],serialize($c));
if($newNum>0){
///递归此方法抽剩下的奖品
return$this->draw($newNum);
}
}
}else{
///如果没有奖池生成奖池
$where[]=['d.state','=',1];
$where[]=['d.kind','=',1];
$res=$this->giftInfo($where);
if(empty($res)){
return['msg'=>'奖池更新中'];
}
$c=[];
foreach($resas$m=>$n){
if($n['ten']==1){
$n['num']=$n['num']-$n['checksum']/10;
$giftarr=array_fill(0,$n['num']+$n['checksum']/10,$suiji['giftid']);
$c=array_merge($c,$giftarr);
if($n['num']<=0){
continue;
}
}
if($n['hundred']==1){
$n['num']=$n['num']-$n['checksum']/100;
$giftarr=array_fill(0,$n['num']+$n['checksum']/100,$suiji['giftid']);
$c=array_merge($c,$giftarr);
if($n['num']<=0){
continue;
}
}
$giftarr=array_fill(0,$n['num'],$n['id']);
$c=array_merge($c,$giftarr);
}
shuffle($c);
Cache::set('用户奖池名称'.$userData['id'],serialize($c));
///递归此方法抽奖
return$this->draw($num);
}
}
?>
以上就是PHP实现抽奖功能实例代码的详细内容,更多关于PHP实现抽奖功能的资料请关注毛票票其它相关文章!