实现功能:抽奖
需求:后台控制每种中奖的概率、控制奖品数量
备注:奖品是以优惠券的形式发放给用户进行兑换,需要考虑到优惠券数量问题
以此为例:
九宫格一个开始btn,一个谢谢参与,后台设置七个奖品
1.获取每个奖品中奖概率,及该奖品的id,我是以1000的总数概率来计算的
/**获取奖品及该奖品的中奖概率
* Created by PhpStorm.
* User: Alisa
* Date: 2018/12/6
* Time: 18:02
* @param $extract_prize_id
* @return mixed
*/
public function user_prize ($extract_prize_id)
{
$prize = (new Query())
->from(['p'=>Prize::tableName()])
->leftJoin(['c'=>Coupon::tableName()],'c.id = p.coupon_id')
->select('p.prize_pro,p.id')
->where(['p.extract_prize_id'=>$extract_prize_id])
->andWhere(['>','c.surplus_num',0])
->all();
$sum = (new Query())
->from(['p'=>Prize::tableName()])
->leftJoin(['c'=>Coupon::tableName()],'c.id = p.coupon_id')
->where(['p.extract_prize_id'=>$extract_prize_id])
->andWhere(['>','c.surplus_num',0])
->sum('p.prize_pro');
$count = count($prize);
foreach ($prize as $k=>$v){
$list[$k] = $v;
}
$list[$count] = [
"prize_pro"=>Math::sub(1000,$sum,0),
"id"=>0
];
$res = $this->get_rand($list);
return $list[$res]['id'];
}
2.进行抽奖计算,返回中奖的奖品id,id是0的话,表示谢谢参与
/**抽奖计算
* Created by PhpStorm.
* User: Alisa
* Date: 2018/12/6
* Time: 18:10
* @param $proArr
* @return int|string
*/
public function get_rand($proArr){
$result = '';
foreach ($proArr as $key => $val) {
$arr[$key] = $val['prize_pro'];
}
// 概率数组的总概率
$proSum = 1000;
// 概率数组循环
foreach ($arr as $k => $v) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $v) {
$result = $k;
break;
} else {
$proSum -= $v;
}
}
return $result;
}
3.进行后续逻辑处理,判断优惠券剩余数量并减去、减去用户抽奖册数、增加用户抽奖记录、中奖的话优惠券到账
/**用户抽奖
* @param $userId
* @param $extract_prize_id
* @return array|bool
* @throws \yii\db\Exception
*/
public function extractPrize($userId,$extract_prize_id)
{
$prize_id = $this->user_prize($extract_prize_id);
$coupon_id = 0;
$prize_name = '谢谢参与';
$prize_url = '';
if($prize_id){
$coupon = (new Query())
->select('c.id,c.name,c.rule,c.validity,c.surplus_num')
->from(['pr'=>Prize::tableName()])
->leftJoin(['c'=>Coupon::tableName()],'c.id = pr.coupon_id')
->where(['pr.id'=>$prize_id])
->one();
if($coupon['surplus_num'] > 0){
$coupon_id = $coupon['id'];
$prize_name = $coupon['name'];
$url = (new Query())
->select('pi.url')
->from(['pr'=>Prize::tableName()])
->leftJoin(['pi'=>Picture::tableName()],'pi.id = pr.img_id')
->where(['pr.id'=>$prize_id])
->one();
$prize_url = $url['url'];
}
}
$trans = Yii::$app->db->beginTransaction();
try{
$model = new ExtractPrizeRecord();
$model->prize_id = $prize_id;
$model->coupon_id = $coupon_id;
$model->prize_name = $prize_name;
$model->user_id = $userId;
$model->type = $extract_prize_id;
$model->create_at = time();
$res_ex = $model->save();
if ( $res_ex ) {
//减去用户抽奖次数
\Yii::$app->db->createCommand("update users set $str = $str - 1 where $str > 0 and user_id = :user_id",
[
':user_id' => $userId,
]
)->execute();
if(($coupon_id > 0) && ($coupon['surplus_num'] > 0)){
//减去优惠券剩余数量
\Yii::$app->db->createCommand("update coupon set surplus_num = surplus_num -1 where id = :coupon_id and surplus_num > 0",
[
':coupon_id' => $coupon_id,
]
)->execute();
$myModel = new MyCoupon();
$myModel->user_id = $userId;
$myModel->name = $coupon['name'];
$myModel->rule = $coupon['rule'];
$myModel->coupon_id = $coupon_id;
$myModel->create_at = time();
$myModel->update_at = time();
$myModel->start_at = time();
$myModel->end_at = time() + $coupon['validity']* 86400;
$myModel->re_code = StringTools::randString(10);
$myModel->coupon_number = date('YmdHis') . rand(10000000,99999999);
$myModel->save();
}
} else {
return false;
}
$trans ->commit();
return ['prize_name'=>$prize_name,'prize_url'=>$prize_url];
}catch (\Throwable $t) {
$trans->rollBack();
return false;
}
}
如果你觉得这篇文章还不错,下角点个赞,是对我开源最大的鼓励O(∩_∩)O