123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <?php namespace App\Models;
- use App\Facades\Servers\Redis\RedisLock;
- use Illuminate\Database\Eloquent\Factories\HasFactory;
- use Illuminate\Database\Eloquent\Model;
- /**
- * 客户优惠券模型
- *
- */
- class CustomCoupon extends Model
- {
- use HasFactory;
- // 与模型关联的表名
- protected $table = 'custom_coupon';
- // 是否主动维护时间戳
- public $timestamps = false;
- // 定义时间戳字段名
- // const CREATED_AT = 'insert_time';
- // const UPDATED_AT = 'update_time';
- /**
- * 添加数据
- *
- */
- public function add($data)
- {
- // 时间
- $data['insert_time'] = time();
- $data['update_time'] = time();
- // 写入数据表
- $id = $this->query()->insertGetId($data);
- // 返回结果
- return $id;
- }
- /**
- * 添加数据
- *
- */
- public function edit($id,$data)
- {
- // 更新时间
- $data['update_time'] = time();
- // 写入数据表
- $result = $this->query()->where(['id'=>$id])->update($data);
- // 返回结果
- return $result;
- }
- /**
- * 获取优惠券
- *
- * @param int $id 客户优惠券ID(注意:不是优惠券的id)
- * @param int $uid 客户ID
- *
- */
- public function getCouponById($id,$uid)
- {
- // 返回结果
- if( !$id ) return [];
- // 查询条件
- $map = [['custom_coupon.id','=',$id],['custom_coupon.custom_uid','=',$uid],['custom_coupon.status','=',0]];
- // 查询优惠券
- $coupon = $this->query()->join('coupon','custom_coupon.coupon_id','=','coupon.id')->where($map)->first(['custom_coupon.id','coupon.id as coupon_id','coupon.name','coupon.type_id','coupon.rebate_type','coupon.std_pay','coupon.rebate','custom_coupon.status','custom_coupon.exp_time']);
- // 如果不存在优惠券
- if( !$coupon ) return [];
- // 转数组方便操作
- $coupon = $coupon->toArray();
- // 查询优惠券的商品范围
- $coupon['product_scope'] = $coupon['type_id'] == 1 ? (new CouponProduct())->getProducts($coupon['coupon_id']) : [];
- // 查询优惠券的商品范围
- $coupon['product_exclude'] = $coupon['type_id'] == 3 ? (new CouponProductExclude())->getProducts($coupon['coupon_id']) : [];
- // 获取赠品信息
- $coupon['rebate_scope'] = $coupon['rebate_type'] == 3 ? (new CouponRebate())->getProductByCouponId($coupon['coupon_id']) : [];
- // 返回结果
- return $coupon;
- }
- /**
- * 是否已有优惠券
- *
- * @param array $couponIds 多个优惠券ID
- *
- */
- public function isHaveCoupon($couponIds,$uid)
- {
- // 查询优惠券
- $haveList = $this->query()->where([['custom_uid','=',$uid]])->whereIn('coupon_id',$couponIds)->pluck('id','coupon_id')->toArray();
- // 如果不存在优惠券
- if( !$haveList ) return [];
- // 返回结果
- return $haveList;
- }
- /**
- * 过期状态设置
- *
- */
- public function setStatusByExpire()
- {
- // 上锁
- if(RedisLock::lock('customcoupon::set::status::by::expire',1,30)){
- // 修改
- $result = $this->query()->where([['status','=',0],['exp_time','<=',time()]])->update(['status'=>3,'update_time'=>time()]);
- // 不管成功失败,都解锁
- RedisLock::unlock('customcoupon::set::status::by::expire',1);
- // 返回结果
- return $result;
- }
- }
- /**
- * 过期状态设置
- *
- */
- public function setStatusByCouponId($couponId,$status)
- {
- // 修改未使用以及暂停的为对应的状态,其他状态的保持不变
- return $this->query()->where([['coupon_id','=',$couponId]])->whereIn('status',[0,2])->update(['status'=>$status,'update_time'=>time()]);
- }
- /**
- * 获取优惠券扣减金额
- *
- */
- public function getRebatePrice($customCouponId,$uid,$productPrice){
- // 如果有优惠券
- if( !$customCouponId ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
- // 查询用户的指定优惠券
- $coupon = $this->getCouponById($customCouponId,$uid);
- // 如果有优惠券
- if( !$coupon ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
- // 总价格
- $totalPrice = 0;
- // 判断是否指定商品范围
- if( $coupon['product_scope'] ) {
- // 去重,避免重复计算
- $coupon['product_scope'] = array_values(array_unique($coupon['product_scope']));
- // 循环商品范围
- foreach ( $coupon['product_scope'] as $productId ) {
- // 如果在商品范围
- if( isset($productPrice[$productId]['price_total']) ) $totalPrice = $totalPrice + $productPrice[$productId]['price_total'];
- }
- // 排除的商品,不参与
- } elseif ( $coupon['product_exclude'] ) {
- // 去重,避免重复计算
- $coupon['product_exclude'] = array_values(array_unique($coupon['product_exclude']));
- // 循环产品价格
- foreach ( $productPrice as $productId=>$value ) {
- // 如果产品在排除范围内
- if( in_array($productId,$coupon['product_exclude']) ) continue;
- // 计算总价
- $totalPrice = $totalPrice + $value['price_total'];
- }
- } else{
- $totalPrice = array_sum(array_column($productPrice,'price_total'));
- }
- // 如果没有达标
- if( $coupon['std_pay'] > $totalPrice ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
- // 达标结果
- $rebatePrice = 0;
- // 满减 扣减金额
- if( $coupon['rebate_type'] == 1 ) $rebatePrice = (float) $coupon['rebate'];
- // 折扣 扣减金额
- if( $coupon['rebate_type'] == 2 ) $rebatePrice = (float) $totalPrice - ( $totalPrice * $coupon['rebate'] * 0.1);
- // 赠品 赠送产品
- if( $coupon['rebate_type'] == 3 ) {
- // 如果没有赠品范围
- if( !$coupon['rebate_scope'] ) return ['is_used'=>1,'product_price'=>$productPrice,'rebate_product'=>[]];
- // 返回结果
- $productList = (new Product())->getListByIds(array_column($coupon['rebate_scope'],'product_id'));
- // 返回赠品数据
- $rebateProduct = [];
- // 循环处理
- foreach ($coupon['rebate_scope'] as $scope) {
- foreach ($productList as $product) {
- // 如果商品ID相等
- if( $scope['product_id'] == $product['id'] ){
- // 产品ID
- $product['product_id'] = $product['id'];
- $product['buy_num'] = $scope['rebate_num'];
- $product['price_total'] = $scope['rebate_num'] * $product['price'];
- $product['pay_total'] = 0;
- $product['coupon_total']= $product['price_total'];
- // 写入到赠品中
- $rebateProduct[$product['business_id']][$product['product_id']] = $product;
- }
- }
- }
- // 返回扣减结果
- return ['is_used'=>$customCouponId,'product_price'=>$productPrice,'rebate_product'=>$rebateProduct];
- }
- // 判断每个产品扣减多少钱
- // 循环产品
- foreach ($productPrice as $productId => $value) {
- // 如果有商品范围,且产品id不在商品范围的
- if( !empty($coupon['product_scope']) && !in_array($productId,$coupon['product_scope']) ) {
- // 跳过,不做计算
- continue;
- }
- // 如果有商品排除范围,且产品id在商品排除范围的
- if( !empty($coupon['product_exclude']) && in_array($productId,$coupon['product_exclude']) ) {
- // 跳过,不做计算
- continue;
- }
- // 优惠价格 = 价格占总价的比例 * 优惠的总价
- $value['rebate_price'] = number_format( $rebatePrice * ($value['price_total'] / $totalPrice) , 2 , '.' ,'');
- // 重组
- $productPrice[$productId] = $value;
- }
- // 返回扣减结果
- return ['is_used'=>$customCouponId,'product_price'=>$productPrice,'rebate_product'=>[]];
- }
- /**
- * 发放优惠券
- *
- * @param int $couponId 优惠券ID
- * @param int $customUid 客户ID
- *
- */
- public function giveCoupon($couponId,$customUid){
- // 达标的是否已经发送过优惠券
- $havaCoupon = $this->query()->where([['custom_uid','=',$customUid],['coupon_id','=',$couponId]])->first(['status']);
- // 已经发过优惠券的,不发
- if( $havaCoupon ) return 0;
- // 优惠券
- $Coupon = new \App\Models\Coupon();
- // 获取优惠券的可用时间
- $couponData = $Coupon->query()->where([['id','=',$couponId],['status','=','0']])->first(['issue_total','status','exp_time']);
- // 如果不存在数据,发送失败
- if( !$couponData || $couponData['status'] ) return 0;
- // 查询总共发放数量
- $total = $this->query()->where([['coupon_id','=',$couponId]])->count();
- // 数量超过的话。不发
- if( $total >= $couponData['issue_total'] ) return 0;
- // 时间转时间
- $expTime = $Coupon->getExpTime($couponData['exp_time']);
- // 发送优惠券
- return $this->add(['coupon_id'=>$couponId,'custom_uid'=>$customUid,'exp_time'=>$expTime]);
- }
- }
|