65 lines
2.6 KiB
PHP
65 lines
2.6 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Exceptions\ShippingNotSupportedException;
|
||
use App\Models\ShippingRule;
|
||
|
||
class ShippingService
|
||
{
|
||
/**
|
||
* 运费模板根据地址,重量, 商品金额 计算运费; 重量传g,金额传分
|
||
*
|
||
* @param integer $weight
|
||
* @param integer $totalAmount
|
||
* @param integer $templateId
|
||
* @param integer $zoneId
|
||
* @return integer
|
||
*
|
||
* @throws \App\Exceptions\ShippingNotSupportedException
|
||
*/
|
||
public function countShippingAmount(int $weight, int $totalAmount, int $templateId, int $zoneId): int
|
||
{
|
||
$shipping_amount = 0;
|
||
$canShipping = true;//是否支持寄送
|
||
|
||
//如果该模板下无运费规则,则直接包邮
|
||
if (ShippingRule::where('template_id', $templateId)->count() > 0) {
|
||
$canShipping = false;
|
||
//只拿有这个地区配置的模板规则,减少sql查询市区数量
|
||
$rules = ShippingRule::with('zones')->where('template_id', $templateId)->whereHas('zones', function ($q) use ($zoneId) {
|
||
return $q->where('zones.id', $zoneId);
|
||
})->get();
|
||
//按包邮/计重
|
||
$rules = $rules->sortBy('type');//优先计算包邮
|
||
foreach ($rules as $rule) {
|
||
$_ruleInfo = json_decode($rule->info, true);
|
||
$canShipping = true;
|
||
if ($rule->type == ShippingRule::TYPE_FREE) {
|
||
if ($totalAmount >= bcmul($_ruleInfo['threshold'], 100)) {//在包邮价格范围内
|
||
break;//跳出foreach循环, 直接包邮
|
||
}
|
||
} elseif ($rule->type == ShippingRule::TYPE_WEIGHT) {
|
||
$_firstWeight = (int) bcmul($_ruleInfo['first_weight'], 1000);
|
||
$_firstWamount = (int) bcmul($_ruleInfo['first_w_amount'], 100);
|
||
$_contiueWeight = (int) bcmul($_ruleInfo['continue_weight'], 1000);
|
||
$_contiueWamount = (int) bcmul($_ruleInfo['continue_w_amount'], 100);
|
||
if ($weight <= $_firstWeight) {
|
||
$shipping_amount = $_firstWamount;
|
||
break;
|
||
} else {//计算续重价格
|
||
$num = (int) bcdiv(($weight - $_firstWeight), $_contiueWeight);
|
||
$shipping_amount = (int) bcadd($_firstWamount, bcmul($num+1, $_contiueWamount));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (!$canShipping) {
|
||
throw new ShippingNotSupportedException();
|
||
}
|
||
|
||
return $shipping_amount;
|
||
}
|
||
}
|