PromoProduct.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php namespace App\Models;
  2. use Illuminate\Database\Eloquent\Factories\HasFactory;
  3. use Illuminate\Database\Eloquent\Model;
  4. /**
  5. * 产品促销活动商品范围模型
  6. *
  7. */
  8. class PromoProduct extends Model
  9. {
  10. use HasFactory;
  11. // 与模型关联的表名
  12. protected $table = 'promo_product';
  13. // 是否主动维护时间戳
  14. public $timestamps = false;
  15. // 定义时间戳字段名
  16. // const CREATED_AT = 'insert_time';
  17. // const UPDATED_AT = 'update_time';
  18. /**
  19. * 添加数据
  20. *
  21. */
  22. public function add($data)
  23. {
  24. // 时间
  25. $data['insert_time'] = time();
  26. $data['update_time'] = time();
  27. // 写入数据表
  28. $id = $this->query()->insertGetId($data);
  29. // 返回结果
  30. return $id;
  31. }
  32. /**
  33. * 添加数据
  34. *
  35. */
  36. public function edit($id,$data)
  37. {
  38. // 更新时间
  39. $data['update_time'] = time();
  40. // 写入数据表
  41. $result = $this->query()->where(['id'=>$id])->update($data);
  42. // 返回结果
  43. return $result;
  44. }
  45. /**
  46. * 查询多个优惠券的商品范围列表
  47. *
  48. * @param array $couponIds 适用产品的列表
  49. *
  50. */
  51. public function getProductList($couponIds)
  52. {
  53. // 写入数据表
  54. $result = $this->query()->whereIn('coupon_id',$couponIds)->get(['coupon_id','product_id'])->toArray();
  55. // 返回结果
  56. return $result;
  57. }
  58. /**
  59. * 通过产品ids查询活动列表
  60. *
  61. */
  62. public function getListByIds($productIds)
  63. {
  64. $time = time();
  65. $where = [
  66. ['promo.status','=','0'],
  67. ['promo.start_time','<=',$time],
  68. ['promo.end_time','>=',$time],
  69. ['promo_product.status','=',0],
  70. ];
  71. $data = $this->query()
  72. ->join('promo','promo.id','=','promo_product.promo_id')
  73. ->where($where)
  74. ->whereIn('promo_product.product_id',$productIds)
  75. ->select('promo.*','promo_product.product_id','promo_product.id as promo_product_id')
  76. ->get()
  77. ->toArray();
  78. // 列表
  79. $list = [];
  80. // 循环处理
  81. foreach ($data as $value) {
  82. // 重组数据
  83. $list[$value['product_id']]= $value;
  84. }
  85. // 返回结果
  86. return $list;
  87. }
  88. /**
  89. * 通过产品id查询活动
  90. *
  91. */
  92. public function getListById($productId)
  93. {
  94. $time = time();
  95. $where = [
  96. ['promo.status','=','0'],
  97. ['promo.start_time','<=',$time],
  98. ['promo.end_time','>=',$time],
  99. ['promo_product.status','=',0],
  100. ['promo_product.product_id','=',$productId],
  101. ];
  102. $data = $this->query()
  103. ->join('promo','promo.id','=','promo_product.promo_id')
  104. ->where($where)
  105. ->select('promo.*','promo_product.product_id','promo_product.id as promo_product_id')
  106. ->first();
  107. // 返回结果
  108. return $data;
  109. }
  110. /**
  111. * 获取优惠券扣减金额
  112. *
  113. */
  114. public function getRebatePrice($productIds,$uid,$productPrice,$cityId,$tags){
  115. // 如果有产品
  116. if( !$productIds ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  117. // 获取产品活动
  118. $promoList = $this->getListByIds($productIds);
  119. $promoProductList = [];
  120. foreach ($promoList as $promoInfo) {
  121. $promoInfoCity = [];
  122. if ($promoInfo['city_ids']){
  123. $promoInfoCity = explode(',',$promoInfo['city_ids']);
  124. }
  125. $promoInfo['price_total'] = $productPrice[$promoInfo['product_id']]['price_total'];
  126. // 判断是不是可以参与
  127. if (!$promoInfoCity || in_array($cityId, $promoInfoCity)) {
  128. if ($promoInfo['tag_scope']) {
  129. // 解析数组
  130. $promoInfo['tag_scope'] = explode(',', $promoInfo['tag_scope']);
  131. // 标签范围限定时,默认不能参与
  132. $allowJoin = 0;
  133. // 判断标签是不是存在
  134. if ($tags) {
  135. foreach ($tags as $v) {
  136. // 标签范围内,允许参加
  137. if (in_array($v['name'], $promoInfo['tag_scope'])) $allowJoin = 1;
  138. }
  139. // 在范围
  140. if ($allowJoin) {
  141. $promoProductList[$promoInfo['id']][] = $promoInfo;
  142. }
  143. }
  144. } else {
  145. $promoProductList[$promoInfo['id']][] = $promoInfo;
  146. }
  147. }
  148. }
  149. if( !$promoProductList ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  150. $reductionTotal = 0;
  151. $promoRebateIds = [];
  152. foreach ($promoProductList as $key => $value){
  153. $reduction = 0;
  154. $priceSum = array_sum(array_column($value,'price_total'));
  155. if ($priceSum >= $value[0]['std_pay']) {
  156. switch ($value[0]['rebate_type']){
  157. case 1:
  158. $reduction = $value[0]['rebate'];
  159. $reductionTotal += $value[0]['rebate'];
  160. break;
  161. case 2:
  162. $reduction = $priceSum - number_format($priceSum * $value[0]['rebate']/10,2);
  163. $reductionTotal += $priceSum - number_format($priceSum * $value[0]['rebate']/10,2);
  164. break;
  165. case 3:
  166. $promoRebateIds[] = $key;
  167. }
  168. }
  169. if ($reduction){
  170. foreach ($value as $k=>$v){
  171. // 优惠价格 = 价格占总价的比例 * 优惠的总价
  172. $productPrice[$v['product_id']]['promo_rebate_price'] = number_format( $reduction * ($productPrice[$v['product_id']]['price_total'] / $priceSum) , 2 , '.' ,'');
  173. }
  174. }
  175. }
  176. //如果有赠品
  177. $list = [];
  178. if ($promoRebateIds){
  179. $promoRebateList = PromoRebate::query()
  180. ->join('product','promo_rebate.product_id','=','product.id')
  181. ->where('status','=',0)
  182. ->whereIn('promo_id',$promoRebateIds)
  183. ->select(['promo_rebate.id as promo_rebate_id','promo_rebate.rebate_num as buy_num','product.id as product_id','product.stock','product.business_id','product.spec','product.thumb','product.name','product.price','product.market_price','product.status as product_status','product.spec as sku_attr_names'])
  184. ->get()
  185. ->toArray();
  186. if ($promoRebateList){
  187. foreach ($promoRebateList as $value){
  188. // 库存超出的时候
  189. if($value['buy_num'] > $value['stock'] && $value['stock'] > 0) $value['buy_num'] = $value['stock'];
  190. $value['price_total'] = $value['price'] * $value['buy_num'];
  191. $value['pay_total'] = 0;
  192. $value['coupon_total']= 0;
  193. $list[$value['business_id']][] = $value;
  194. }
  195. }
  196. }
  197. // 返回扣减结果
  198. return ['product_price'=>$productPrice,'rebate_product'=>$list,'reduction_total'=>$reductionTotal];
  199. }
  200. }