FreightItems.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. namespace app\common\model;
  3. use think\Model;
  4. /**
  5. * 运费条件模型
  6. */
  7. class FreightItems extends Model
  8. {
  9. // 表名
  10. protected $name = 'shop_freight_items';
  11. // 开启自动写入时间戳字段
  12. protected $autoWriteTimestamp = 'int';
  13. // 定义时间戳字段名
  14. protected $createTime = 'createtime';
  15. protected $updateTime = 'updatetime';
  16. // 追加属性
  17. protected $append = [];
  18. /**
  19. * @ DateTime 2021-05-31
  20. * @ 计件费用
  21. * @param Freight $freight
  22. * @param int $area_id
  23. * @param int $nums
  24. * @param float $amount
  25. * @return float
  26. */
  27. public function numPostage($freight, $area_id, $nums, $amount)
  28. {
  29. //计件
  30. $shippingfee = 0; //邮费
  31. $is_free = false; //包邮的
  32. $result = []; //计费的
  33. $freightItems = $this->where('freight_id', $freight->id)->select();
  34. if (empty($freightItems)) {
  35. // 默认计件费用
  36. //首件
  37. $money = $freight['price'];
  38. //续费
  39. if ($freight['num'] < $nums && $freight['continue_num'] > 0 && $freight['continue_price'] > 0) {
  40. $money = bcadd($money, bcmul(bcdiv($freight['continue_price'], $freight['continue_num'], 2), bcsub($nums, $freight['num'], 2), 2), 2);
  41. }
  42. return $money;
  43. }
  44. // 是否指定地区包邮 -> 是否有在包邮地区里 ->
  45. foreach ($freightItems as $item) {
  46. $postage_area_ids = explode(',', $item['postage_area_ids']); //包邮限制地区
  47. $area_ids = explode(',', $item['area_ids']); //邮费限制地区
  48. //首先判断是否满足包邮
  49. if (in_array($item['type'], [1, 2])) {
  50. $is_free = $this->getWeightNumsFree($item, $area_id, $postage_area_ids, $nums, $amount);
  51. if ($is_free) {
  52. break;
  53. }
  54. }
  55. //走到这里,则包邮未满足,追加邮费结果
  56. if (in_array($area_id, $area_ids)) {
  57. $result[] = $item;
  58. }
  59. }
  60. //包邮
  61. if ($is_free) {
  62. return $shippingfee;
  63. }
  64. if (!$result) {
  65. //如果未找到指定地区的运费模板,则使用主运费模板
  66. $result = $freight;
  67. }
  68. //计算邮费
  69. $monies = [];
  70. foreach ($result as $res) {
  71. //首件
  72. $money = $res['first_price'];
  73. //续费
  74. if ($res['first_num'] < $nums && $res['continue_num'] > 0 && $res['continue_price'] > 0) {
  75. $money = bcadd($money, bcmul(bcdiv($res['continue_price'], $res['continue_num'], 2), bcsub($nums, $res['first_num'], 2), 2), 2);
  76. }
  77. $monies[] = $money;
  78. }
  79. $config = get_addon_config('shop');
  80. $shippingfee = isset($config['freightitemfee']) || $config['freightitemfee'] == 'max' ? max($monies) : min($monies);
  81. return $shippingfee;
  82. }
  83. /**
  84. * @ DateTime 2021-05-31
  85. * @ 计重费用
  86. * @param Freight $freight
  87. * @param int $area_id
  88. * @param int $nums
  89. * @param float $weight
  90. * @param float $amount
  91. * @return float
  92. */
  93. public function weightPostage($freight, $area_id, $nums, $weight, $amount)
  94. {
  95. //计重
  96. $shippingfee = 0; //邮费
  97. $is_free = false; //包邮的
  98. $result = []; //计费的
  99. $totalWeight = bcmul($nums, $weight, 2); //总重量
  100. $freightItems = $this->where('freight_id', $freight->id)->select();
  101. if (empty($freightItems)) {
  102. // 默认计件费用
  103. //首重
  104. $money = $freight['price'];
  105. //续费
  106. if ($freight['num'] < $totalWeight && $freight['continue_num'] > 0 && $freight['continue_price'] > 0) {
  107. $money = bcadd($money, bcmul(bcdiv($freight['continue_price'], $freight['continue_num'], 2), bcsub($totalWeight, $freight['num'], 2), 2), 2);
  108. }
  109. return $money;
  110. }
  111. // 是否指定地区包邮 -> 是否有在包邮地区里 ->
  112. foreach ($freightItems as $item) {
  113. $postage_area_ids = explode(',', $item['postage_area_ids']); //包邮限制地区
  114. $area_ids = explode(',', $item['area_ids']); //邮费限制地区
  115. if (in_array($item['type'], [1, 2])) {
  116. $is_free = $this->getWeightNumsFree($item, $area_id, $postage_area_ids, $nums, $amount);
  117. if ($is_free) {
  118. break;
  119. }
  120. }
  121. //走到这里,则包邮未满足,追加邮费结果
  122. if (in_array($area_id, $area_ids)) {
  123. $result[] = $item;
  124. }
  125. }
  126. //包邮
  127. if ($is_free) {
  128. return $shippingfee;
  129. }
  130. if (!$result) {
  131. //如果未找到指定地区的运费模板,则使用主运费模板
  132. $result = [$freight];
  133. }
  134. //计算邮费
  135. $monies = [];
  136. foreach ($result as $res) {
  137. //首重
  138. $money = $res['first_price'];
  139. //续费
  140. if ($res['first_num'] < $totalWeight && $res['continue_num'] > 0 && $res['continue_price'] > 0) {
  141. $money = bcadd($money, bcmul(bcdiv($res['continue_price'], $res['continue_num'], 2), bcsub($totalWeight, $res['first_num'], 2), 2), 2);
  142. }
  143. $monies[] = $money;
  144. }
  145. $config = get_addon_config('shop');
  146. $shippingfee = isset($config['freightitemfee']) || $config['freightitemfee'] == 'max' ? max($monies) : min($monies);
  147. return $shippingfee;
  148. }
  149. /**
  150. * @ DateTime 2021-05-31
  151. * @ 包邮判断
  152. * @param $item
  153. * @param $area_id
  154. * @param $postage_area_ids
  155. * @param $nums
  156. * @param $amount
  157. * @return boolean
  158. */
  159. protected function getWeightNumsFree($item, $area_id, $postage_area_ids, $nums, $amount)
  160. {
  161. //判断条件
  162. if (empty($postage_area_ids)) {
  163. //开启包邮,没有限制地区,则全部包邮
  164. return true;
  165. }
  166. if ($item['type'] == 1 && in_array($area_id, $postage_area_ids) && $item['postage_num'] <= $nums) { //计件的开启包邮
  167. //在包邮地区里
  168. //满足包邮条件
  169. return true;
  170. } elseif ($item['type'] == 2 && in_array($area_id, $postage_area_ids) && $item['postage_price'] <= $amount) { //金额开启包邮
  171. //在包邮地区里
  172. //满足包邮条件
  173. return true;
  174. }
  175. return false;
  176. }
  177. }