资讯专栏INFORMATION COLUMN

设计翻牌抽奖

cfanr / 2539人阅读

摘要:实现功能抽奖需求后台控制每种中奖的概率控制奖品数量备注奖品是以优惠券的形式发放给用户进行兑换,需要考虑到优惠券数量问题以此为例九宫格一个开始,一个谢谢参与,后台设置七个奖品获取每个奖品中奖概率,及该奖品的我是以的总数概率来计算的获取奖品及该

实现功能:抽奖

需求:后台控制每种中奖的概率、控制奖品数量

备注:奖品是以优惠券的形式发放给用户进行兑换,需要考虑到优惠券数量问题

以此为例:
九宫格一个开始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 yiidbException
 */
 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29753.html

相关文章

  • 来百度“上云节” 领取你的双十一“超级锦鲤”

    摘要:未来已来,百度云特推出上云节,通过爆款产品秒杀新购专享特惠等方式来支持全民普惠上云,更有机会抽取等好礼,保证参与的你中奖。在这场云计算的双十一狂欢盛宴中,属于你的私人锦鲤,最终只能被你翻牌。这个双十一,百度云超强福利已打包完毕。 导语:狂欢是一群人的孤单,但至少,云计算的剁手更加高级一点。又是一年双十一,相信各位对于这个已满十岁的剁手大party期盼已久,或因为去年没有实现的愿望,或因...

    Dean 评论0 收藏0
  • 如何设计一个百万级用户的抽奖系统?

    摘要:如下图所示负载均衡层的限流防止用户重复抽奖首先第一次在负载均衡层可以做的事情,就是防止重复抽奖。然后负载均衡感知到了之后,后续请求全部拦截掉返回一个抽奖结束的标识就可以了。一旦抽奖结束,抽奖服务更新状态,负载均衡层会感知到。公众号:狸猫技术窝作者:爱钓鱼的桌子哥,资深架构师1、抽奖系统的背景引入本文给大家分享一个之前经历过的抽奖系统的流量削峰架构的设计方案。抽奖、抢红包、秒杀,这类系统其实都...

    Leck1e 评论0 收藏0
  • PHPer的月工作总结之构建抽奖工具

    摘要:这个月的计划本来是对基础的数据结构做一个沉淀,但是,但是,但是这个月的的状态就是工作工作既然这样就总结下这个月的工作吧。 前言 目标是每个月写一篇文章,对从事编程开发的基础知识做一个学习总结。这个月的计划本来是对基础的数据结构做一个沉淀,但是,但是,但是......这个月的的状态就是工作工作...既然这样就总结下这个月的工作吧。 工作内容 促销活动的抽奖工具,具备如下功能: 根据不同...

    W_BinaryTree 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<