用PHP做了一个领取优惠券活动的示例代码


Posted in PHP onJuly 05, 2019

业务需求

优惠券活动,具体还是要根据自己的需求。以下是最近实现的优惠券活动,主要的业务需求:根据后端设置优惠券模板,用户类型设置,优惠券活动的开始与结束时间,最后生成不同的优惠券活动链接。

代码环境

源码主要laravel5.8,一整个活动要贴的代码很多,下面主要贴核心代码,仅供参考。主要还是要根据自己的业务需求来实现功能吧。

以下是后端截图,做成模块化

用PHP做了一个领取优惠券活动的示例代码

前端需要做的设置与限制:

1 判断优惠券是否存在或者停用
2 判断活动开始时间与优惠券开始时间

接着领取活动优惠券,需要判断以下情况:
1 活动已结束
2 活动为开始时
3 活动为新用户领取,而领取的用户是老用户
4 活动为老用户领取,而领取的用户是新用户
5 优惠券是否领取完
6 已领取过优惠券提示
7 领取成功

下面核心代码实现

/**
 * Function:优惠券领取处理
 * Author:cyw0413
 * @param $params
 * @return array
 * @throws \Exception
 */
public function doCoupon($params)
{
  $activity_id = $params['activity_id'];
  if(!$params){
    throw new \Exception("参数错误!");
  }

  $preg_phone = '/^1[34578]\d{9}$/ims';
  $is_mobile = preg_match ($preg_phone, $params['mobile']);
  if ($is_mobile == 0) {
    throw new \Exception("手机号码不正确!");
  }

  //隐藏手机号码中间4位
  $str_mobile = substr_replace($params['mobile'],'****',3,4);

  $activity = $this->find($activity_id);
  if(empty($activity)){
    throw new \Exception("不存在此活动");
  }

  $activity_link = $activity->activityLink->where('coupon_status',0); //只选择不停用的优惠券
  if(count($activity_link) <= 0){
    throw new \Exception("优惠券不存在或者已经停用");

  }else{

    //查找注册用户ID
    $showUser = $this->showUser($params['mobile']);
    //主要是过滤掉领取优惠券为0的,用laravel的同学注意看看
    $detail = $activity_link->each(function($item,$index) use ($showUser) {

      $diffCouponQuantity = $this->diffCouponQuantity($item['config_id'],$item['quantity'],$item['activity_id'],$showUser);
      $item->title = $this->getCouponName($item['config_id'])['name'];
      $item->number = $item['quantity'];
      $item->msg  = $diffCouponQuantity ['msg'];
      $item->diff   = $diffCouponQuantity ['diff'];
      $item->code   = $diffCouponQuantity ['code'];
    })->toArray();

    if(count($detail) == 1){
      foreach($detail as $val){
        if($val['diff'] == 1 && $val['code'] == '400'){
          throw new \Exception($detail[0]['msg']);
        }
      }

    }

    $collection_coupon = collect($detail);
    $collection_coupon = $collection_coupon->where('diff', '<=' ,'0');  //去除优惠券剩余数量为0,或者领取优惠券数量-剩余数量 > 0

  }
  //判断活动开始时间与优惠券开始时间
  $act_coupon = ActivityCouponBaseModel::where('activity_id',$activity['activity_id'])->first();
  $check_time = $this-> checkCouponTime($act_coupon['start_time'],$activity_link);
  if($check_time == 'error'){
    throw new \Exception("优惠券领取时间未开始,暂不可领取");
  }

  //领取活动有以下几种情况
  //1: 活动已结束
  if($activity['end_time'] < date("Y-m-d H:i:s") || $activity['status'] == 1){
    $result = [
      'code' => 1,
    ];
    return $result;
  }

  //6 活动为开始时
  if($activity['start_time'] > date("Y-m-d H:i:s") || $activity['status'] == 1){
    $result = [
      'code' => 6,
    ];
    return $result;

  }

  $checkUser = $this->haveUser($params['mobile']); //检查是新用户,还是老用户 根据自己的业务需求做,这个方法就不贴了
  //2: 活动为新用户领取,而领取的用户是老用户
  if($activity['user_type'] == 1 && !empty($checkUser)){
    $result = [
      'code' => 2,
    ];
    return $result;
  }

  //3:活动为老用户领取,而领取的用户是新用户
  if($activity['user_type']==2 && empty($checkUser)){
    $result = [
      'code' => 3,
    ];
    return $result;
  }


  //4:优惠券是否领取完
  $coupon = $this->getCouponExpire($collection_coupon,$params['mobile']); //这里提示有一个优惠券列表,根据自己的业务需求做,这个方法就不贴了
  //return $coupon;
  if($coupon == 1){
    $result = [
      'code' => 4,
    ];
    return $result;
  }

  //5:已领取过优惠券提示
  $userCoupon = '';
  $userRate = '';
  if(!empty($checkUser)){
    //user存在则为老用户,再检查是否领取过
    $userCoupon = $this->getUserCoupon($collection_coupon,$checkUser['user_id']);
    $userRate = $this->getUserCouponRate($checkUser['user_id'],$activity['activity_id']);
  }else{
    //新用户,检查是否注册过
    $var_user = UserBaseModel::where('user_name',$params['mobile'])->first();
    if(!empty($var_user)){
      $userCoupon = $this->getUserCoupon($collection_coupon,$var_user['user_id']);
      $userRate = $this->getUserCouponRate($var_user['user_id'],$activity['activity_id']);
    }
  }

  //return $userRate;

  if($userCoupon == 1){
    $result = [
      'code' => 5,
      'phone'=> $str_mobile,
      'coupon' => $userRate,
      'is_get' => false,
    ];
    return $result;
  }

  //5:领取成功
  //如果活动规定是新老用户0,新用户1,老用户2
  $getCouponSuccess = $this->getCouponSuccess($activity['user_type'],$checkUser,$collection_coupon,$params['mobile']);
  //return $getCouponSuccess;
  if($getCouponSuccess['status'] == 200){
    $result = [
      'code' => 5,
      'phone'=> $str_mobile,
      'coupon' => $getCouponSuccess['result'][0],
      'is_get' => true,
    ];
    return $result;
  }


}

用户领取优惠券并发放优惠券

/**
 * Function:用户领取活动
 * Author:cyw0413
 * @param $user_type
 */
public function getCouponSuccess($user_type,$user,$coupon,$mobile)
{
  if(count($coupon) > 0){

    switch ($user_type){
      case 1:
        //新用户领取,如果从来没注册过就要新增用户
        $res = $this->addUser($mobile,$coupon); 
        return [
          'result' => $res,
          'status' => 200
        ];
        break;
      case 2:
        //老用户领取
        $res = $this->insertUserCoupon($user,$coupon);
        return [
          'result' => $res,
          'status' => 200
        ];
        break;
      default:
        //新老用户领取,判断是新用户还是老用户,这里的$user是有无配送单,有则为老用户;
        if(empty($user)){
          $res = $this->addUser($mobile,$coupon);
        }else{

          $res = $this->insertUserCoupon($user,$coupon); //老用户,直接发放优惠券
        }
        return [
          'result' => $res,
          'status' => 200
        ];
        break;
    }
  }else{
    throw new \Exception("优惠券不存在或者已经停用");
  }


}

领取成功,则发放优惠券

/**
 * Function:发放优惠券
 * Author:cyw0413
 * @param $user
 * @param $coupon
 */
public function insertUserCoupon($user,$coupon)
{
  $relate = [];
  foreach($coupon as $item){

    $res = CouponConfigSendBaseModel::where([
      'config_id'=>$item['config_id'],
      'status'  => 0,
    ])->first();

    if(empty($res) || (!empty($res) && $res['is_send'] == 0) ){
      throw new \Exception("优惠券未发放,暂不可领取");
    }

    //发放优惠券,有多少张就添加多少张,这里扣除优惠券时,主要用不同的coupon_sn来区别
    $onlyCoupon = $this->getCouponName($item['config_id']);
    if ($onlyCoupon['expire_type'] == 0) {
      $start_time = $onlyCoupon['expire_start_time'];
      $end_time = $onlyCoupon['expire_end_time'];
    } else {
      $start_time = date('Y-m-d H:i:s');
      $end_time = date('Y-m-d H:i:s', time()+86400*$onlyCoupon['expire_type']);
    }

    $result = [
      'user_id'  => $user['user_id'],
      'config_id' => $item['config_id'],
      'name'   => $onlyCoupon['name'],
      'get_type' => $onlyCoupon['get_type'],
      'amount'  => $onlyCoupon['amount'],
      'require_price' => $onlyCoupon['require_price'],
      'status'    => 1,
      'start_time'  => $start_time,
      'end_time'   => $end_time,
    ];
    for($i=0; $i < $item['quantity'];$i++){
      $result['coupon_sn'] = 'B'.mt_rand(1, 10000) . strtoupper(uniqid(mt_rand(1, 10000)));
      $userCoupon = UserCouponBaseModel::create($result);
    }

    //扣除相应的优惠券数量,这里用到了锁表,防止并发时,优惠券为-1
    $couponConfig = CouponConfigBaseModel::where('config_id',$item['config_id'])->lockForUpdate()->first();
    if($couponConfig->left_quantity > 0 ){
      if($couponConfig->left_quantity >= $item['quantity']){
        $couponConfig->left_quantity = $couponConfig->left_quantity-$item['quantity'];
        $couponConfig->save();
      }else{
        throw new \Exception("优惠券剩余数量不够扣减");
      }

    }


    $relate = [
      'coupon_id' => $userCoupon->coupon_id,
      'user_id'  => $user['user_id'],
      'config_id' => $item['config_id'],
      'activity_id' => $item['activity_id']
    ];

    ActivityCouponUserRelateBaseModel::create($relate);

    $relate[] = $this->getUserCouponRate($user['user_id'],$item['activity_id']);


  }

  return $relate;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php下一个阿拉伯数字转中文数字的函数
Jul 16 PHP
php合并数组array_merge函数运算符加号与的区别
Oct 31 PHP
PHP 字符串分割和比较
Oct 06 PHP
php 无极分类(递归)实现代码
Jan 05 PHP
ajax完美实现两个网页 分页功能的实例代码
Apr 16 PHP
php模拟服务器实现autoindex效果的方法
Mar 10 PHP
php检查是否是ajax请求的方法
Apr 16 PHP
php验证码生成代码
Nov 11 PHP
ZF框架实现发送邮件的方法
Dec 03 PHP
PHP+AjaxForm异步带进度条上传文件实例代码
Aug 14 PHP
Thinkphp自定义生成缩略图尺寸的方法
Aug 05 PHP
PHP中关于php.ini参数优化详解
Feb 28 PHP
php无限极分类实现方法分析
Jul 04 #PHP
php常用日期时间函数实例小结
Jul 04 #PHP
JS操作XML中DTD介绍及使用方法分析
Jul 04 #PHP
PHP操作XML中XPath的应用示例
Jul 04 #PHP
PHP实现财务审核通过后返现金额到客户的功能
Jul 04 #PHP
PHP使用DOM对XML解析处理操作示例
Jul 04 #PHP
PHP创建XML接口示例
Jul 04 #PHP
You might like
PHP has encountered a Stack overflow问题解决方法
2014/11/03 PHP
PHP实现的json类实例
2015/07/28 PHP
JavaScript版代码高亮
2006/06/26 Javascript
使用js实现一个可编辑的select下拉列表
2014/02/20 Javascript
js实现数字每三位加逗号的方法
2015/02/05 Javascript
JavaScript获取网页中第一个链接ID的方法
2015/04/03 Javascript
jQuery动画效果图片轮播特效
2016/01/12 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
函数四种调用模式以及其中的this指向
2017/01/16 Javascript
vue2.0 axios前后端数据处理实例代码
2017/06/30 Javascript
详解基于angular-cli配置代理解决跨域请求问题
2017/07/05 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
深入浅析AngularJs模版与v-bind
2018/07/06 Javascript
详解Angularjs 自定义指令中的数据绑定
2018/07/19 Javascript
Vue动态面包屑功能的实现方法
2019/07/01 Javascript
Vue2.0实现简单分页及跳转效果
2019/07/29 Javascript
详解小程序如何动态绑定点击的执行方法
2019/11/26 Javascript
[56:18]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#2 MVP.Phx VS Fnatic第二局
2016/03/05 DOTA
python实现数通设备端口监控示例
2014/04/02 Python
Python导出DBF文件到Excel的方法
2015/07/25 Python
TensorFlow实现Batch Normalization
2018/03/08 Python
python 定义n个变量方法 (变量声明自动化)
2018/11/10 Python
Win10下配置tensorflow-gpu的详细教程(无VS2015/2017)
2020/07/14 Python
Pycharm github配置实现过程图解
2020/10/13 Python
联想墨西哥官方网站:Lenovo墨西哥
2016/08/17 全球购物
中国海淘族值得信赖的海淘返利网站:55海淘
2017/01/16 全球购物
美国奢侈品购物平台:Orchard Mile
2018/05/02 全球购物
牦牛毛户外探险服装:Kora
2019/02/08 全球购物
秘书专业自荐信范文
2013/12/26 职场文书
高一物理教学反思
2014/01/24 职场文书
人力资源管理专业应届生求职信
2014/04/24 职场文书
预备党员学习十八届三中全会精神思想汇报
2014/09/13 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
2019如何书写演讲稿?
2019/07/01 职场文书
FFmpeg视频处理入门教程(新手必看)
2022/01/22 杂记