parent
caf65fa1d8
commit
df8cff8869
|
|
@ -37,6 +37,7 @@ class Logistics extends Base{
|
|||
public static function getAll(int $countryId,$field = ['id','name','warehouse_name','type','day_min','day_max']){
|
||||
$list = self::select($field)
|
||||
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
||||
->with(['weights'])
|
||||
->orderBy('position','ASC')
|
||||
->orderBy('id','ASC')
|
||||
->get();
|
||||
|
|
@ -45,7 +46,57 @@ class Logistics extends Base{
|
|||
return $list ? $list->toArray() : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Common: 物流过滤 - 根据商品和物流列表过滤 仅返回有效的物流
|
||||
* Author: wu-hui
|
||||
* Time: 2023/08/29 10:02
|
||||
* @param $logisticsList
|
||||
* @param $productsList
|
||||
* @return array|array[]
|
||||
*/
|
||||
public static function LogisticsFiltering($logisticsList,$productsList){
|
||||
$eligibleList = array_map(function($logisticsItem) use ($productsList){
|
||||
// 判断:物流是否按照重量计算 weight:按重量计费,num:按数量计费,free:卖家包邮
|
||||
if($logisticsItem['type'] == 'weight'){
|
||||
$weights = (array)$logisticsItem['weights'];// 续重区间列表
|
||||
$firstWeight = (float)$logisticsItem['first_weight'];// 首重
|
||||
if(!$weights) {
|
||||
$logisticsItem = [];
|
||||
}else{
|
||||
// 循环判断:只要有一个商品不符合条件 则当前物流不可用;
|
||||
foreach($productsList as $productItem){
|
||||
$surplusWeight = $productItem['sum_weight'] - $firstWeight;// 总重量 - 减首重 = 剩余重量
|
||||
// 判断:如果剩余重量小于等于0 则符合条件;否则计算续重区间
|
||||
if($surplusWeight <= 0){
|
||||
continue;
|
||||
}else{
|
||||
$eligibleCount = collect($weights)
|
||||
->where('min','<=',$surplusWeight)
|
||||
->where('max','>',$surplusWeight)
|
||||
->count();
|
||||
if($eligibleCount <= 0) {
|
||||
$logisticsItem = [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $logisticsItem;
|
||||
},$logisticsList);
|
||||
|
||||
return array_filter($eligibleList);
|
||||
}
|
||||
|
||||
|
||||
public function country(){
|
||||
return $this->belongsTo(Country::class,'country_id','id');
|
||||
}
|
||||
|
||||
public function weights(){
|
||||
return $this->hasMany(LogisticsWeight::class,'logistics_id','id');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,14 @@ class ProductController extends Controller
|
|||
|
||||
return json_success(trans('common.success'),$totals);
|
||||
}
|
||||
// 获取物流列表
|
||||
/**
|
||||
* Common: 获取物流列表
|
||||
* Author: wu-hui
|
||||
* Time: 2023/08/29 10:06
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function productsLogistics(Request $request){
|
||||
$data = [
|
||||
'list' => [],
|
||||
|
|
@ -191,10 +198,14 @@ class ProductController extends Controller
|
|||
$request->change_logistics_id = $logisticsItem['id'];
|
||||
$totals = $this->computeOrderMoney($request);
|
||||
$shipping = array_column($totals['data'],null,'code')['shipping'] ?? [];
|
||||
$logisticsItem['shipping_fee'] = $shipping['show_tips'] == 0 ? $shipping['amount_format'] : trans('shop/carts.to_be_negotiated');
|
||||
// $logisticsItem['shipping_fee'] = $shipping['show_tips'] == 0 ? $shipping['amount_format'] : trans('shop/carts.to_be_negotiated');
|
||||
if($shipping['show_tips'] == 0) $logisticsItem['shipping_fee'] = $shipping['amount_format'];
|
||||
else $logisticsItem = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$data['list'] = array_filter($data['list']);
|
||||
return json_success(trans('common.success'),$data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ use Beike\Shop\Services\CheckoutService;
|
|||
use Illuminate\Support\Str;
|
||||
|
||||
class ShippingService{
|
||||
protected static $country;
|
||||
protected static $country;// 国家信息
|
||||
protected static $productsList;// 商品分组统计列表
|
||||
|
||||
// 运费计算
|
||||
public static function getTotal(CheckoutService $checkout): ?array{
|
||||
|
|
@ -50,40 +51,33 @@ class ShippingService{
|
|||
$amount = (float)(new $className)->getShippingFee($checkout);
|
||||
}
|
||||
else{
|
||||
// 商品信息处理 获取同一个商品的数量、重量
|
||||
$products = $totalService->getCartProducts();
|
||||
self::$productsList = collect($products)->groupBy('product_id')->map(function($group){
|
||||
$firstInfo = $group->first();
|
||||
$productWeightInfo = Product::query()
|
||||
->select(['id','weight','weight_class'])
|
||||
->find($firstInfo['product_id']);
|
||||
if($productWeightInfo) $productWeightInfo = $productWeightInfo->toArray();
|
||||
// 重量转换 - 物流重量单位为 千克;商品重量需要进行转换
|
||||
$weight = $productWeightInfo['weight'] ?? 0;
|
||||
$sumQuantity = $group->sum('quantity');
|
||||
$sumWeight = (float)sprintf("%.2f",($weight * $sumQuantity));
|
||||
$weightClass = $productWeightInfo['weight_class'];
|
||||
$sumWeight = Weight::convert($sumWeight,$weightClass);// 总重量 单位:克
|
||||
return [
|
||||
'product_id' => $firstInfo['product_id'],
|
||||
'sum_quantity' => $sumQuantity,
|
||||
'sum_weight' => $sumWeight,
|
||||
'weight' => $weight,
|
||||
'weight_class' => $weightClass,
|
||||
];
|
||||
});
|
||||
// 通过物流进行计算
|
||||
$logisticsId = (int)$checkout->cart->shipping_method_code;
|
||||
$logisticsInfo = self::getLogistics($logisticsId,$checkout->cart);
|
||||
if($logisticsInfo) {
|
||||
// 商品信息处理 获取同一个商品的数量
|
||||
$products = $totalService->getCartProducts();
|
||||
$productsList = collect($products)->groupBy('product_id')->map(function($group){
|
||||
$firstInfo = $group->first();
|
||||
$productWeightInfo = Product::query()
|
||||
->select(['id','weight','weight_class'])
|
||||
->find($firstInfo['product_id']);
|
||||
if($productWeightInfo) $productWeightInfo = $productWeightInfo->toArray();
|
||||
// 重量转换 - 物流重量单位为 千克;商品重量需要进行转换
|
||||
$weight = $productWeightInfo['weight'] ?? 0;
|
||||
$sumQuantity = $group->sum('quantity');
|
||||
$sumWeight = (float)sprintf("%.2f",($weight * $sumQuantity));
|
||||
$weightClass = $productWeightInfo['weight_class'];
|
||||
$sumWeight = Weight::convert($sumWeight,$weightClass);// 总重量 单位:克
|
||||
return [
|
||||
'product_id' => $firstInfo['product_id'],
|
||||
'sum_quantity' => $sumQuantity,
|
||||
'sum_weight' => $sumWeight,
|
||||
'weight' => $weight,
|
||||
'weight_class' => $weightClass,
|
||||
];
|
||||
});
|
||||
// weight:按重量计费,num:按数量计费,free:卖家包邮
|
||||
$logisticsHandleFun = 'compute_'.$logisticsInfo['type'];
|
||||
$amount = self::$logisticsHandleFun($logisticsInfo,$productsList);
|
||||
}
|
||||
else{
|
||||
// 如果还是不能获取物流信息 则显示 待协商
|
||||
$showTips = 1;
|
||||
}
|
||||
if($logisticsInfo) $amount = $logisticsInfo['amount'];// 存在物流 获取运费
|
||||
else $showTips = 1;// 如果还是不能获取物流信息 则显示 待协商
|
||||
}
|
||||
$totalData = [
|
||||
'code' => 'shipping',
|
||||
|
|
@ -109,7 +103,7 @@ class ShippingService{
|
|||
* @return array|mixed|mixed[]
|
||||
*/
|
||||
private static function getLogistics($logisticsId,$cart){
|
||||
$logisticsField = ['type', 'name','first_weight','first_weight_fee','continuation_weight_max','add_weight','continuation_weight_fee','num_fee'];
|
||||
$logisticsField = ['id','type', 'name','first_weight','first_weight_fee','continuation_weight_max','add_weight','continuation_weight_fee','num_fee'];
|
||||
// 判断:客服端是否切换国家 如果存在切换的国家id 则使用切换的国家id;不存在则继续执行
|
||||
$countryId = (int)request()->input('products_country_id');
|
||||
if($countryId > 0) {
|
||||
|
|
@ -120,6 +114,7 @@ class ShippingService{
|
|||
// 同时存在国家ID 获取物流ID
|
||||
$logisticsInfo = Logistics::query()
|
||||
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
||||
->with(['weights'])
|
||||
->where('id',$logisticsId)
|
||||
->select($logisticsField)
|
||||
->first();
|
||||
|
|
@ -127,7 +122,9 @@ class ShippingService{
|
|||
// 刷新国家信息
|
||||
self::refreshCurrentCountry($countryId);
|
||||
|
||||
return $logisticsInfo->toArray();
|
||||
$logisticsList = [$logisticsInfo->toArray()];
|
||||
|
||||
goto logisticsListHandle;
|
||||
}
|
||||
}
|
||||
// 仅存在国家ID时
|
||||
|
|
@ -146,25 +143,41 @@ class ShippingService{
|
|||
// 刷新国家信息
|
||||
self::refreshCurrentCountry($countryId);
|
||||
|
||||
return $logisticsList[0] ?? [];
|
||||
}else{
|
||||
// 获取物流信息
|
||||
$logisticsInfo = Logistics::query()
|
||||
->with(['weights'])
|
||||
->select($logisticsField)
|
||||
->find($logisticsId);
|
||||
|
||||
return $logisticsInfo ? $logisticsInfo->toArray() : [];
|
||||
$logisticsList = [$logisticsInfo ? $logisticsInfo->toArray() : []];
|
||||
}
|
||||
// 根据已查询的物流列表 筛选出符合条件的物流并且返回第一个
|
||||
logisticsListHandle:
|
||||
$eligibleLogisticsList = Logistics::LogisticsFiltering($logisticsList,self::$productsList);
|
||||
// 循环计算物流运费
|
||||
foreach($eligibleLogisticsList as &$eligibleLogisticsListItem){
|
||||
// weight:按重量计费,num:按数量计费,free:卖家包邮
|
||||
$logisticsHandleFun = 'compute_'.$eligibleLogisticsListItem['type'];
|
||||
$eligibleLogisticsListItem['amount'] = (float)self::$logisticsHandleFun($eligibleLogisticsListItem);
|
||||
}
|
||||
// 存在多个物流 需要获取运费最小的物流
|
||||
if(count($eligibleLogisticsList) > 1){
|
||||
$amounts = array_column($eligibleLogisticsList,'amount');
|
||||
array_multisort($amounts,SORT_ASC,$eligibleLogisticsList);
|
||||
}
|
||||
|
||||
|
||||
return $eligibleLogisticsList[0] ?? [];
|
||||
}
|
||||
/**
|
||||
* Common: 运费计算 - 物流运费 - 运费计算(按重量计费)
|
||||
* Author: wu-hui
|
||||
* Time: 2023/08/22 15:34
|
||||
* @param $logisticsInfo
|
||||
* @param $productsList
|
||||
* @return float|int
|
||||
*/
|
||||
private static function compute_weight($logisticsInfo,$productsList){
|
||||
private static function compute_weight($logisticsInfo){
|
||||
/**
|
||||
* 计算规则:
|
||||
* 总重量 - 低于首重;则运费 = 【首重运费】
|
||||
|
|
@ -176,7 +189,7 @@ class ShippingService{
|
|||
$addWeight = (float)$logisticsInfo['add_weight'];// 每增加重量
|
||||
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续重运费
|
||||
// 循环处理商品
|
||||
foreach($productsList as $productInfo){
|
||||
foreach(self::$productsList as $productInfo){
|
||||
// 首重运费
|
||||
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
||||
// 判断:如果总重量超过首重 则计算续重运费
|
||||
|
|
@ -191,10 +204,9 @@ class ShippingService{
|
|||
* Author: wu-hui
|
||||
* Time: 2023/08/22 14:47
|
||||
* @param $logisticsInfo
|
||||
* @param $productsList
|
||||
* @return float|int
|
||||
*/
|
||||
private static function compute_num($logisticsInfo,$productsList){
|
||||
private static function compute_num($logisticsInfo){
|
||||
/**
|
||||
* 计算规则:
|
||||
* 购买数量 - 低于首件数量;则运费 = 【首件运费】
|
||||
|
|
@ -206,7 +218,7 @@ class ShippingService{
|
|||
$addWeight = (int)$logisticsInfo['add_weight'];// 每增加件
|
||||
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续件运费
|
||||
// 循环处理商品
|
||||
foreach($productsList as $productInfo){
|
||||
foreach(self::$productsList as $productInfo){
|
||||
// 首件运费
|
||||
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
||||
// 判断:如果数量超过首件数量 则计算续件运费
|
||||
|
|
@ -221,10 +233,9 @@ class ShippingService{
|
|||
* Author: wu-hui
|
||||
* Time: 2023/08/22 11:59
|
||||
* @param $logisticsInfo
|
||||
* @param $productsList
|
||||
* @return int
|
||||
*/
|
||||
private static function compute_free($logisticsInfo,$productsList){
|
||||
private static function compute_free($logisticsInfo){
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -240,8 +251,6 @@ class ShippingService{
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通过配送方式获取插件编码
|
||||
*
|
||||
|
|
|
|||
|
|
@ -623,6 +623,7 @@
|
|||
_this.goods_list = list;
|
||||
|
||||
_this.computeOrderMoney();
|
||||
_this.$refs['select-logistics'].getLogisticsList()
|
||||
|
||||
// let price = 0;
|
||||
// if (this.numPrices.light == 0) {
|
||||
|
|
@ -653,7 +654,9 @@
|
|||
};
|
||||
})
|
||||
_this.goods_list = list;
|
||||
|
||||
_this.computeOrderMoney();
|
||||
_this.$refs['select-logistics'].getLogisticsList()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@
|
|||
goods_list: JSON.stringify(_this.goods_list),
|
||||
}).then((res) => {
|
||||
if(res.status === 'success'){
|
||||
_this.logistics_list = res.data.list || {};
|
||||
_this.logistics_list = Object.values(Object.assign({},res.data.list || {})) ;
|
||||
_this.country = res.data.country || {};
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue