FullDiscount.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. namespace addons\shopro\library\activity\provider;
  3. /**
  4. * 满额折扣
  5. */
  6. class FullDiscount extends Base
  7. {
  8. protected $rules = [
  9. "type" => "require",
  10. "discounts" => "require|array"
  11. ];
  12. protected $message = [
  13. "discounts.require" => '请填写优惠规则',
  14. "discounts.array" => '请填写优惠规则',
  15. ];
  16. protected $default = [
  17. "type" => "money", // money=满足金额|num=满足件数
  18. "discounts" => []
  19. ];
  20. public function check($params, $activity_id = 0)
  21. {
  22. // 数据验证
  23. $params = parent::check($params);
  24. // 检测活动之间是否存在冲突
  25. $this->checkActivityConflict($params, $params['goods_list'], $activity_id);
  26. return $params;
  27. }
  28. public function formatTags($rules, $type)
  29. {
  30. $tags = [];
  31. $discounts = $rules['discounts'] ?? [];
  32. foreach ($discounts as $discount) {
  33. $tags[] = $this->formatTag([
  34. 'type' => $rules['type'],
  35. 'full' => $discount['full'],
  36. 'discount' => $discount['discount']
  37. ]);
  38. }
  39. return array_values(array_filter($tags));
  40. }
  41. /**
  42. * 格式化 discount 折扣为具体优惠标签
  43. *
  44. * @param string $type
  45. * @param array $discountData
  46. * @return string
  47. */
  48. public function formatTag($discountData)
  49. {
  50. $tag = '满' . $discountData['full'] . ($discountData['type'] == 'money' ? '元' : '件');
  51. $tag .= $discountData['discount'] . '折';
  52. return $tag;
  53. }
  54. public function formatTexts($rules, $type)
  55. {
  56. $texts = [];
  57. $discounts = $rules['discounts'] ?? [];
  58. foreach ($discounts as $discount) {
  59. $text = '满' . $discount['full'] . ($rules['type'] == 'money' ? '元' : '件');
  60. $text .= ',商品总价打' . $discount['discount'] . '折';
  61. $texts[] = $text;
  62. }
  63. return array_values(array_filter($texts));
  64. }
  65. public function getPromoInfo($promo, $data = [])
  66. {
  67. extract($this->promoGoodsData($promo));
  68. $rules = $promo['rules'];
  69. // 是按金额,还是按件数比较
  70. $compareif = $rules['type'] == 'num' ? 'promo_goods_num' : 'promo_goods_amount';
  71. // 将规则按照从大到校排列,优先比较是否满足最大规则
  72. $rulesDiscounts = isset($rules['discounts']) && $rules['discounts'] ? array_reverse($rules['discounts']) : []; // 数组反转
  73. // 满减, 满折多个规则从大到小匹配最优惠
  74. foreach ($rulesDiscounts as $d) {
  75. if (${$compareif} < $d['full']) {
  76. // 不满足条件,接着循环下个规则
  77. continue;
  78. }
  79. $dis = bcdiv($d['discount'], '10', 3); // 保留三位小数,转化折扣
  80. $dis = $dis > 1 ? 1 : ($dis < 0 ? 0 : $dis); // 定义边界 0 - 1
  81. $promo_dis = 1 - $dis;
  82. $current_promo_discount_money = bcmul($promo_goods_amount, (string)$promo_dis, 3);
  83. $current_promo_discount_money = number_format((float)$current_promo_discount_money, 2, '.', ''); // 计算折扣金额,四舍五入
  84. // 记录该活动的一些统计信息
  85. $promo_discount_info = [
  86. 'activity_id' => $promo['id'], // 活动id
  87. 'activity_title' => $promo['title'], // 活动标题
  88. 'activity_type' => $promo['type'], // 活动类型
  89. 'activity_type_text' => $promo['type_text'], // 活动类型中文
  90. 'promo_discount_money' => $current_promo_discount_money, // 优惠金额
  91. 'promo_goods_amount' => $promo_goods_amount, // 当前活动商品总金额
  92. 'rule_type' => $rules['type'], // 满多少元|还是满多少件
  93. 'discount_rule' => $d, // 满足的那条规则
  94. 'goods_ids' => $goodsIds // 这个活动包含的这次购买的商品
  95. ];
  96. break;
  97. }
  98. return $promo_discount_info ?? null;
  99. }
  100. }