PHP实现抽奖功能实例代码
发布:smiling 来源: PHP粉丝网 添加日期:2022-03-15 10:07:44 浏览: 评论:0
在项目开发中经常会遇到花钱抽奖类型的需求。但是老板总是担心用户用小钱抽到大奖,这样会导致项目亏损。下边这段代码可以有效制止抽奖项目亏钱。
个人奖池:
语言:thinkphp redis mysql
表:desire抽奖商品表 desire_log用户抽奖奖品表 user_desire_log用户抽奖记录表 desire_risk抽奖风控表
需求:用户奖池分为进行中奖池 和已完成奖池 当用户抽到大奖后 用户个人奖池重置 否则将继续抽奖 最后一次抽奖必中大奖 通过风控金额来判断用户是否可以抽大奖
当所有用户已完成的抽奖 盈利大于风控金额的时候可以让用户抽大奖 否则用户抽不到大奖
- <?php
- //抽奖接口
- public function desire()
- {
- $userData = $this->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);
- }
- }
- /////抽奖核心
- public function draw($num)
- {
- $userData = $this->userSessionData();
- $resultSend = Cache::get('奖池名称加上用户的唯一标识,确保一人一奖池' . $userData['id']);//获取个人奖池
- if (!emptyempty($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('num desc')->find();///随机小礼物
- if ($userRedis) {///如果用户奖池存在
- $joins = [
- ['gift_info f', 'd.giftid = f.id']
- ];
- $gift = Db::connect('db_qmconfig')->name('desire')
- ->alias('d')
- ->join($joins)
- ->where(['d.state' => 1])
- ->order('f.price desc')
- ->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('kind desc')
- ->where(['uid'=>$userData['id'],'state'=>0])->field('SUM(num) as kindNum')->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) as num')
- ->find();///已抽数量
- if (!$user){
- return ['msg'=>'已抽数量有误'];
- }
- $res['zongshu'] = Db::connect('db_qmconfig')
- ->name('desire')->where(['state' => 1])
- ->field('SUM(num) as num,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_log d', 'd.cid = u.id'],
- ['gift_info f', 'd.giftid = f.id']
- ];
- $all = Db::connect('db_qmconfig')
- ->name('user_desire_log')
- ->alias('u')
- ->where(['u.state'=>1])
- ->field('SUM(u.num) as num')->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) as num')->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('id desc')->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 ($result as $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_info f', '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 (emptyempty($res['data'])) {
- output('1008', '奖池更新中');
- }
- ////获取用户此轮抽奖数量 返回给前端 控制奖池动画百分比
- $res['zongshu'] = Db::connect('db_qmconfig')
- ->name('desire')->where(['state' => 1, 'kind' => 1])
- ->field('checksum as num')
- ->find();
- $user = Db::connect('db_qmconfig')
- ->name('desire_log')->where(['uid' => $userData['id']])
- ->field('SUM(num) as num')
- ->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 (emptyempty($res)) {
- return ['msg' => '奖池更新中'];
- }
- $c = [];
- foreach ($res as $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 (emptyempty($res)) {
- return ['msg' => '奖池更新中'];
- }
- $c = [];
- foreach ($res as $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);
- }
- }
- ?>
Tags: PHP抽奖功能
- 上一篇:如何在PHP中使用AES加密算法加密数据
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)