前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >根据自己的业务需求,用PHP做一个优惠券活动

根据自己的业务需求,用PHP做一个优惠券活动

原创
作者头像
码农程序
修改2019-07-08 11:39:44
7770
修改2019-07-08 11:39:44
举报
文章被收录于专栏:PHP自学中心PHP自学中心

文章来自公众号:PHP自学中心 链接:https://mp.weixin.qq.com/s/vt-_Awa0wmhVNMM9CwSGqg

作者:磊丰

业务需求

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

代码环境:

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

以下是后端截图

clipboard.png
clipboard.png

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

1 判断优惠券是否存在或者停用

2 判断活动开始时间与优惠券开始时间

接着领取活动优惠券,需要判断以下情况:

1 活动已结束

2 活动为开始时

3 活动为新用户领取,而领取的用户是老用户

4 活动为老用户领取,而领取的用户是新用户

5 优惠券是否领取完

6 已领取过优惠券提示

7 领取成功

看看前端的测试的截图

360截图167510211019895.png
360截图167510211019895.png

下面是核心代码实现

代码语言:txt
复制
/**
 * Function:优惠券领取处理
 * Author:磊丰
 * @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;
	}


}

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

代码语言:txt
复制
/**
 * Function:用户领取活动
 * Author:磊丰
 * @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("优惠券不存在或者已经停用");
	}


}

领取成功,则发放优惠券

代码语言:txt
复制
/**
 * 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;
}
代码语言:txt
复制

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 业务需求
  • 代码环境:
  • 以下是后端截图
  • 前端需要做的设置与限制:
  • 看看前端的测试的截图
  • 用户领取优惠券并发放优惠券
  • 领取成功,则发放优惠券
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档