PromoProduct.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. ->toArray();
  108. // 返回结果
  109. return $data;
  110. }
  111. /**
  112. * 获取优惠券扣减金额
  113. *
  114. */
  115. public function getRebatePrice($productIds,$uid,$productPrice,$cityId,$tags){
  116. // 如果有产品
  117. if( !$productIds ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  118. // 获取产品活动
  119. $promoList = $this->getListByIds($productIds);
  120. $promoProductList = [];
  121. foreach ($promoList as $promoInfo) {
  122. $promoInfoCity = explode(',', $promoInfo['city_ids']);
  123. $promoInfo['price_total'] = $productPrice[$promoInfo['product_id']]['price_total'];
  124. // 判断是不是可以参与
  125. if (in_array($cityId, $promoInfoCity)) {
  126. if ($promoInfo['tag_scope']) {
  127. // 解析数组
  128. $promoInfo['tag_scope'] = explode(',', $promoInfo['tag_scope']);
  129. // 标签范围限定时,默认不能参与
  130. $allowJoin = 0;
  131. // 判断标签是不是存在
  132. if ($tags) {
  133. foreach ($tags as $v) {
  134. // 标签范围内,允许参加
  135. if (in_array($v['name'], $promoInfo['tag_scope'])) $allowJoin = 1;
  136. }
  137. // 在范围
  138. if ($allowJoin) {
  139. $promoProductList[$promoInfo['id']][] = $promoInfo;
  140. }
  141. }
  142. } else {
  143. $promoProductList[$promoInfo['id']][] = $promoInfo;
  144. }
  145. }
  146. }
  147. if( !$promoProductList ) return ['is_used'=>0,'product_price'=>$productPrice,'rebate_product'=>[]];
  148. $reductionTotal = 0;
  149. $promoRebateIds = [];
  150. foreach ($promoProductList as $key => $value){
  151. $reduction = 0;
  152. $priceSum = array_sum(array_column($value,'price_total'));
  153. if ($priceSum >= $value[0]['std_pay']) {
  154. switch ($value[0]['rebate_type']){
  155. case 1:
  156. $reduction = $value[0]['rebate'];
  157. $reductionTotal += $value[0]['rebate'];
  158. break;
  159. case 2:
  160. $reduction = $priceSum - number_format($priceSum * $value[0]['rebate']/10,2);
  161. $reductionTotal += $priceSum - number_format($priceSum * $value[0]['rebate']/10,2);
  162. break;
  163. case 3:
  164. $promoRebateIds[] = $key;
  165. }
  166. }
  167. if ($reduction){
  168. foreach ($value as $k=>$v){
  169. // 优惠价格 = 价格占总价的比例 * 优惠的总价
  170. $productPrice[$v['product_id']]['promo_rebate_price'] = number_format( $reduction * ($productPrice[$v['product_id']]['price_total'] / $reduction) , 2 , '.' ,'');
  171. }
  172. }
  173. }
  174. //如果有赠品
  175. $list = [];
  176. if ($promoRebateIds){
  177. $promoRebateList = PromoRebate::query()
  178. ->join('product','promo_rebate.product_id','=','product.id')
  179. ->where('status','=',0)
  180. ->whereIn('promo_id',$promoRebateIds)
  181. ->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'])
  182. ->get()
  183. ->toArray();
  184. if ($promoRebateList){
  185. foreach ($promoRebateList as $value){
  186. // 库存超出的时候
  187. if($value['buy_num'] > $value['stock'] && $value['stock'] > 0) $value['buy_num'] = $value['stock'];
  188. $value['price_total'] = $value['price'] * $value['buy_num'];
  189. $value['pay_total'] = 0;
  190. $value['coupon_total']= 0;
  191. $list[$value['business_id']][] = $value;
  192. }
  193. }
  194. }
  195. // 返回扣减结果
  196. return ['product_price'=>$productPrice,'rebate_product'=>$list,'reduction_total'=>$reductionTotal];
  197. }
  198. }