CustomCoupon.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php namespace App\Models;
  2. use App\Facades\Servers\Redis\RedisLock;
  3. use Illuminate\Database\Eloquent\Factories\HasFactory;
  4. use Illuminate\Database\Eloquent\Model;
  5. /**
  6. * 客户优惠券模型
  7. *
  8. */
  9. class CustomCoupon extends Model
  10. {
  11. use HasFactory;
  12. // 与模型关联的表名
  13. protected $table = 'custom_coupon';
  14. // 是否主动维护时间戳
  15. public $timestamps = false;
  16. // 定义时间戳字段名
  17. // const CREATED_AT = 'insert_time';
  18. // const UPDATED_AT = 'update_time';
  19. /**
  20. * 添加数据
  21. *
  22. */
  23. public function add($data)
  24. {
  25. // 时间
  26. $data['insert_time'] = time();
  27. $data['update_time'] = time();
  28. // 写入数据表
  29. $id = $this->query()->insertGetId($data);
  30. // 返回结果
  31. return $id;
  32. }
  33. /**
  34. * 添加数据
  35. *
  36. */
  37. public function edit($id,$data)
  38. {
  39. // 更新时间
  40. $data['update_time'] = time();
  41. // 写入数据表
  42. $result = $this->query()->where(['id'=>$id])->update($data);
  43. // 返回结果
  44. return $result;
  45. }
  46. /**
  47. * 获取优惠券
  48. *
  49. * @param int $id 客户优惠券ID(注意:不是优惠券的id)
  50. * @param int $uid 客户ID
  51. *
  52. */
  53. public function getCouponById($id,$uid)
  54. {
  55. // 返回结果
  56. if( !$id ) return [];
  57. // 查询条件
  58. $map = [['custom_coupon.id','=',$id],['custom_coupon.custom_uid','=',$uid],['custom_coupon.status','=',0]];
  59. // 查询优惠券
  60. $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']);
  61. // 如果不存在优惠券
  62. if( !$coupon ) return [];
  63. // 转数组方便操作
  64. $coupon = $coupon->toArray();
  65. // 查询优惠券的商品范围
  66. $coupon['product_scope'] = $coupon['type_id'] == 1 ? (new CouponProduct())->getProducts($coupon['coupon_id']) : [];
  67. // 获取赠品信息
  68. $coupon['rebate_scope'] = $coupon['rebate_type'] == 3 ? (new CouponRebate())->getProductByCouponId($coupon['coupon_id']) : [];
  69. // 返回结果
  70. return $coupon;
  71. }
  72. /**
  73. * 过期状态设置
  74. *
  75. */
  76. public function setStatusByExpire()
  77. {
  78. // 上锁
  79. if(RedisLock::lock('customcoupon::set::status::by::expire',1,30)){
  80. // 修改
  81. $result = $this->query()->where([['status','=',0],['exp_time','<=',time()]])->update(['status'=>3,'update_time'=>time()]);
  82. // 不管成功失败,都解锁
  83. RedisLock::unlock('customcoupon::set::status::by::expire',1);
  84. // 返回结果
  85. return $result;
  86. }
  87. }
  88. /**
  89. * 过期状态设置
  90. *
  91. */
  92. public function setStatusByCouponId($couponId,$status)
  93. {
  94. // 修改未使用以及暂停的为对应的状态,其他状态的保持不变
  95. return $this->query()->where([['coupon_id','=',$couponId]])->whereIn('status',[0,2])->update(['status'=>$status,'update_time'=>time()]);
  96. }
  97. /**
  98. * 获取优惠券扣减金额
  99. *
  100. */
  101. public function getRebatePrice($customCouponId,$uid,$productPrice){
  102. // 查询用户的指定优惠券
  103. $coupon = $this->getCouponById($customCouponId,$uid);
  104. // 如果有优惠券
  105. if( !$coupon ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  106. // 总价格
  107. $totalPrice = 0;
  108. // 判断是否指定商品范围
  109. if( $coupon['product_scope'] ) {
  110. // 循环商品范围
  111. foreach ( $coupon['product_scope'] as $productId ) {
  112. // 如果在商品范围
  113. if( isset($productPrice[$productId]['price_total']) ) $totalPrice = $totalPrice + $productPrice[$productId]['price_total'];
  114. }
  115. }else{
  116. $totalPrice = array_sum(array_column($productPrice,'price_total'));
  117. }
  118. // 如果没有达标
  119. if( $coupon['std_pay'] > $totalPrice ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  120. // 达标结果
  121. $rebatePrice = 0;
  122. // 满减 扣减金额
  123. if( $coupon['rebate_type'] == 1 ) $rebatePrice = (float) $coupon['rebate'];
  124. // 折扣 扣减金额
  125. if( $coupon['rebate_type'] == 2 ) $rebatePrice = (float) $totalPrice - ( $totalPrice * $coupon['rebate'] * 0.1);
  126. // 赠品 赠送产品
  127. if( $coupon['rebate_type'] == 3 ) {
  128. // 如果没有赠品范围
  129. if( !$coupon['rebate_scope'] ) return ['is_used'=>1,'product_price'=>$productPrice,'rebate_product'=>[]];
  130. // 返回结果
  131. $productList = (new Product())->getListByIds(array_column($coupon['rebate_scope'],'product_id'));
  132. // 返回赠品数据
  133. $rebateProduct = [];
  134. // 循环处理
  135. foreach ($coupon['rebate_scope'] as $scope) {
  136. foreach ($productList as $product) {
  137. // 如果商品ID相等
  138. if( $scope['product_id'] == $product['id'] ){
  139. // 产品ID
  140. $product['product_id'] = $product['id'];
  141. $product['buy_num'] = $scope['rebate_num'];
  142. $product['price_total'] = $scope['rebate_num'] * $product['price'];
  143. $product['pay_total'] = 0;
  144. $product['coupon_total']= $product['price_total'];
  145. // 写入到赠品中
  146. $rebateProduct[$product['business_id']][$product['product_id']] = $product;
  147. }
  148. }
  149. }
  150. // 返回扣减结果
  151. return ['is_used'=>$customCouponId,'product_price'=>$productPrice,'rebate_product'=>$rebateProduct];
  152. }
  153. // 判断每个产品扣减多少钱
  154. // 循环产品
  155. foreach ($productPrice as $productId => $value) {
  156. // 如果有商品范围,且产品id不在商品范围的
  157. if( !empty($coupon['product_scope']) && !in_array($productId,$coupon['product_scope']) ) {
  158. // 跳过,不做计算
  159. continue;
  160. }
  161. // 优惠价格 = 价格占总价的比例 * 优惠的总价
  162. $value['rebate_price'] = number_format( $rebatePrice * ($value['price_total'] / $totalPrice) , 2 , '.' ,'');
  163. // 重组
  164. $productPrice[$productId] = $value;
  165. }
  166. // 返回扣减结果
  167. return ['is_used'=>$customCouponId,'product_price'=>$productPrice,'rebate_product'=>[]];
  168. }
  169. }