ProductDeductService.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <?php
  2. namespace app\api\service\coupon;
  3. use app\common\library\helper;
  4. /**
  5. * 优惠券抵扣金额
  6. */
  7. class ProductDeductService
  8. {
  9. private $actualReducedMoney;
  10. private $coupon_column;
  11. private $price_column;
  12. /**
  13. * 构造方法
  14. */
  15. public function __construct($coupon_column, $price_column)
  16. {
  17. $this->coupon_column = $coupon_column;
  18. $this->price_column = $price_column;
  19. }
  20. public function setProductCouponMoney($productList, $reducedMoney)
  21. {
  22. // 统计订单商品总金额,(单位分)
  23. $orderTotalPrice = 0;
  24. foreach ($productList as &$product) {
  25. $product[$this->price_column] *= 100;
  26. $orderTotalPrice += $product[$this->price_column];
  27. }
  28. // 计算实际抵扣金额
  29. $this->setActualReducedMoney($reducedMoney, $orderTotalPrice);
  30. // 实际抵扣金额为0,
  31. if ($this->actualReducedMoney > 0) {
  32. // 计算商品的价格权重
  33. $productList = $this->getProductListWeight($productList, $orderTotalPrice);
  34. // 计算商品优惠券抵扣金额
  35. $this->setProductListCouponMoney($productList);
  36. // 总抵扣金额
  37. $totalCouponMoney = helper::getArrayColumnSum($productList, $this->coupon_column);
  38. $this->setProductListCouponMoneyFill($productList, $totalCouponMoney);
  39. $this->setProductListCouponMoneyDiff($productList, $totalCouponMoney);
  40. }
  41. return $productList;
  42. }
  43. public function getActualReducedMoney()
  44. {
  45. return $this->actualReducedMoney;
  46. }
  47. private function setActualReducedMoney($reducedMoney, $orderTotalPrice)
  48. {
  49. $reducedMoney *= 100;
  50. $this->actualReducedMoney = ($reducedMoney >= $orderTotalPrice) ? $orderTotalPrice - 1 : $reducedMoney;
  51. }
  52. private function arraySortByWeight($productList)
  53. {
  54. return array_sort($productList, 'weight', true);
  55. }
  56. private function getProductListWeight($productList, $orderTotalPrice)
  57. {
  58. foreach ($productList as &$product) {
  59. $product['weight'] = $product[$this->price_column] / $orderTotalPrice;
  60. }
  61. return $this->arraySortByWeight($productList);
  62. }
  63. private function setProductListCouponMoney(&$productList)
  64. {
  65. foreach ($productList as &$product) {
  66. $product[$this->coupon_column] = bcmul($this->actualReducedMoney, $product['weight']);
  67. }
  68. return true;
  69. }
  70. private function setProductListCouponMoneyFill(&$productList, $totalCouponMoney)
  71. {
  72. if ($totalCouponMoney === 0) {
  73. $temReducedMoney = $this->actualReducedMoney;
  74. foreach ($productList as &$product) {
  75. if ($temReducedMoney === 0) break;
  76. $product[$this->coupon_column] = 1;
  77. $temReducedMoney--;
  78. }
  79. }
  80. return true;
  81. }
  82. private function setProductListCouponMoneyDiff(&$productList, $totalCouponMoney)
  83. {
  84. $tempDiff = $this->actualReducedMoney - $totalCouponMoney;
  85. foreach ($productList as &$product) {
  86. if ($tempDiff < 1) break;
  87. $product[$this->coupon_column]++ && $tempDiff--;
  88. }
  89. return true;
  90. }
  91. }