当前位置: 首页 > 后端技术 > PHP

H5抽奖

时间:2023-03-29 20:11:25 PHP

本文详细讲解了四种抽奖逻辑和两种抽奖要求的细节。一般H5抽奖活动的获奖要求分为1.肯定中奖(如果奖品库存不为空)2.不一定中奖奖品分配接口最终实现的要求1.奖品不应该超发2.唯一奖一次发3.并发有一定限制::find()->where(['openid'=>''])->andWhere(['>','open_at',0])->andWhere(['<','open_at',time()])->orderBy('open_atASC')->limit(1)->one();如果(!empty($award)){$res=Award::updateAll(['openid'=>$openid],'code=:codeANDopenid=:openid',[':code'=>$award['代码'],':openid'=>'']);如果($res){返回ArrayHelper::toArray($award);}}返回[];这样,在多个并发用户的情况下,就会有多个用户获得相同的奖品。由于更新声明的限制,只有获得相同奖品代码的用户之一才能获得奖品。2.在开放时间的基础上增加类型概率publicfunctionrandAward($openid){$number=rand(0,100);$类型=5;如果($number<10){$type=1;}elseif($number<30){$type=2;}elseif($number<70){$type=3;}elseif($number<80){$type=4;$award=Award::find()->where(['openid'=>''])->andWhere(['>','open_at',0])->andWhere(['<','open_at',time()])->andWhere(['type'=>$type])->orderBy('open_atASC')->limit(1)->one();如果(!empty($award)){$res=Award::updateAll(['openid'=>$openid],'code=:codeANDopenid=:openid',[':code'=>$award['代码'],':openid'=>'']);如果($res){返回ArrayHelper::toArray($award);}}返回[];}这样,同样的奖品也会有多个用户,但是加入类型限制后,用户会分散在各个类型中,没中奖的概率会比上面的例子低3、利用Redis奖池概念发放奖品publicfunctionredisAward($openid){try{$redis=\Yii::$app->redis->client();$code=$redis->LPop(self::AWARD_LIST_KEY);}catch(Exception$err){返回[];}$res=Award::updateAll(['openid'=>$openid],'code=:codeANDopenid=:openid',[':code'=>$code,':openid'=>'']);如果($res){$award=Award::find()->where(['code'=>$code])->limit(1)->one();返回ArrayHelper::toArray($award);}返回[];}这种使用预生成奖池的方式,当奖池不为空时,每个用户都会取一个不同的奖品代码,需要注意的是,在前期生成奖池和运行奖池时后期防止奖品码被重复使用。4.根据开奖时间(类型)抽奖,替换为开奖sql语句publicfunctionsqlAward($openid){$sql="UPDATEawardSETopenid=:openidWHEREopen_at>0ANDopenid=''和open_at<:timeORDERBYopen_atASCLIMIT1";$res=\Yii::$app->db->createCommand($sql,[':time'=>time(),':openid'=>$openid])->execute();if($res){returnAward::find()->where(['openid'=>$openid])->limit(1)->asArray()->one();}返回[];}在一定的中奖要求下,建议使用Redis奖池或SQL语句更新以上四种方式,在多个并发用户的情况下会带来不同的结果,进入前应限制用户的并发请求抽奖逻辑,可根据实际需要,通过以下方式进行限制//用户单次计数if(!$redis->sAdd(self::USER_LIST_KEY,$openid)){return[];}return$this->sqlAward($openid);}也可以限制抽奖次数publicfunctionactionAward(){$openid=CommonTool::randString(32);try{$redis=\Yii::$app->redis->client();//数字彩票用户的$list=$redis->sMembers(self::USER_LIST_KEY);如果(计数($列表)>1000){返回;}}catch(Exception$err){}$award=$this->sqlAward($openid);}写在最后的H5活动抽奖界面中有几点需要注意:1.检查用户有效性;5.控制奖品的分配(时间、插值、概率等)6.做好指标关系