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']){
|
public static function getAll(int $countryId,$field = ['id','name','warehouse_name','type','day_min','day_max']){
|
||||||
$list = self::select($field)
|
$list = self::select($field)
|
||||||
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
||||||
|
->with(['weights'])
|
||||||
->orderBy('position','ASC')
|
->orderBy('position','ASC')
|
||||||
->orderBy('id','ASC')
|
->orderBy('id','ASC')
|
||||||
->get();
|
->get();
|
||||||
|
|
@ -45,7 +46,57 @@ class Logistics extends Base{
|
||||||
return $list ? $list->toArray() : [];
|
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(){
|
public function country(){
|
||||||
return $this->belongsTo(Country::class,'country_id','id');
|
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);
|
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){
|
public function productsLogistics(Request $request){
|
||||||
$data = [
|
$data = [
|
||||||
'list' => [],
|
'list' => [],
|
||||||
|
|
@ -191,10 +198,14 @@ class ProductController extends Controller
|
||||||
$request->change_logistics_id = $logisticsItem['id'];
|
$request->change_logistics_id = $logisticsItem['id'];
|
||||||
$totals = $this->computeOrderMoney($request);
|
$totals = $this->computeOrderMoney($request);
|
||||||
$shipping = array_column($totals['data'],null,'code')['shipping'] ?? [];
|
$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);
|
return json_success(trans('common.success'),$data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ use Beike\Shop\Services\CheckoutService;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class ShippingService{
|
class ShippingService{
|
||||||
protected static $country;
|
protected static $country;// 国家信息
|
||||||
|
protected static $productsList;// 商品分组统计列表
|
||||||
|
|
||||||
// 运费计算
|
// 运费计算
|
||||||
public static function getTotal(CheckoutService $checkout): ?array{
|
public static function getTotal(CheckoutService $checkout): ?array{
|
||||||
|
|
@ -50,40 +51,33 @@ class ShippingService{
|
||||||
$amount = (float)(new $className)->getShippingFee($checkout);
|
$amount = (float)(new $className)->getShippingFee($checkout);
|
||||||
}
|
}
|
||||||
else{
|
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;
|
$logisticsId = (int)$checkout->cart->shipping_method_code;
|
||||||
$logisticsInfo = self::getLogistics($logisticsId,$checkout->cart);
|
$logisticsInfo = self::getLogistics($logisticsId,$checkout->cart);
|
||||||
if($logisticsInfo) {
|
if($logisticsInfo) $amount = $logisticsInfo['amount'];// 存在物流 获取运费
|
||||||
// 商品信息处理 获取同一个商品的数量
|
else $showTips = 1;// 如果还是不能获取物流信息 则显示 待协商
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$totalData = [
|
$totalData = [
|
||||||
'code' => 'shipping',
|
'code' => 'shipping',
|
||||||
|
|
@ -109,7 +103,7 @@ class ShippingService{
|
||||||
* @return array|mixed|mixed[]
|
* @return array|mixed|mixed[]
|
||||||
*/
|
*/
|
||||||
private static function getLogistics($logisticsId,$cart){
|
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;不存在则继续执行
|
// 判断:客服端是否切换国家 如果存在切换的国家id 则使用切换的国家id;不存在则继续执行
|
||||||
$countryId = (int)request()->input('products_country_id');
|
$countryId = (int)request()->input('products_country_id');
|
||||||
if($countryId > 0) {
|
if($countryId > 0) {
|
||||||
|
|
@ -120,6 +114,7 @@ class ShippingService{
|
||||||
// 同时存在国家ID 获取物流ID
|
// 同时存在国家ID 获取物流ID
|
||||||
$logisticsInfo = Logistics::query()
|
$logisticsInfo = Logistics::query()
|
||||||
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
||||||
|
->with(['weights'])
|
||||||
->where('id',$logisticsId)
|
->where('id',$logisticsId)
|
||||||
->select($logisticsField)
|
->select($logisticsField)
|
||||||
->first();
|
->first();
|
||||||
|
|
@ -127,7 +122,9 @@ class ShippingService{
|
||||||
// 刷新国家信息
|
// 刷新国家信息
|
||||||
self::refreshCurrentCountry($countryId);
|
self::refreshCurrentCountry($countryId);
|
||||||
|
|
||||||
return $logisticsInfo->toArray();
|
$logisticsList = [$logisticsInfo->toArray()];
|
||||||
|
|
||||||
|
goto logisticsListHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 仅存在国家ID时
|
// 仅存在国家ID时
|
||||||
|
|
@ -146,25 +143,41 @@ class ShippingService{
|
||||||
// 刷新国家信息
|
// 刷新国家信息
|
||||||
self::refreshCurrentCountry($countryId);
|
self::refreshCurrentCountry($countryId);
|
||||||
|
|
||||||
return $logisticsList[0] ?? [];
|
|
||||||
}else{
|
}else{
|
||||||
// 获取物流信息
|
// 获取物流信息
|
||||||
$logisticsInfo = Logistics::query()
|
$logisticsInfo = Logistics::query()
|
||||||
|
->with(['weights'])
|
||||||
->select($logisticsField)
|
->select($logisticsField)
|
||||||
->find($logisticsId);
|
->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: 运费计算 - 物流运费 - 运费计算(按重量计费)
|
* Common: 运费计算 - 物流运费 - 运费计算(按重量计费)
|
||||||
* Author: wu-hui
|
* Author: wu-hui
|
||||||
* Time: 2023/08/22 15:34
|
* Time: 2023/08/22 15:34
|
||||||
* @param $logisticsInfo
|
* @param $logisticsInfo
|
||||||
* @param $productsList
|
|
||||||
* @return float|int
|
* @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'];// 每增加重量
|
$addWeight = (float)$logisticsInfo['add_weight'];// 每增加重量
|
||||||
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续重运费
|
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续重运费
|
||||||
// 循环处理商品
|
// 循环处理商品
|
||||||
foreach($productsList as $productInfo){
|
foreach(self::$productsList as $productInfo){
|
||||||
// 首重运费
|
// 首重运费
|
||||||
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
||||||
// 判断:如果总重量超过首重 则计算续重运费
|
// 判断:如果总重量超过首重 则计算续重运费
|
||||||
|
|
@ -191,10 +204,9 @@ class ShippingService{
|
||||||
* Author: wu-hui
|
* Author: wu-hui
|
||||||
* Time: 2023/08/22 14:47
|
* Time: 2023/08/22 14:47
|
||||||
* @param $logisticsInfo
|
* @param $logisticsInfo
|
||||||
* @param $productsList
|
|
||||||
* @return float|int
|
* @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'];// 每增加件
|
$addWeight = (int)$logisticsInfo['add_weight'];// 每增加件
|
||||||
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续件运费
|
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续件运费
|
||||||
// 循环处理商品
|
// 循环处理商品
|
||||||
foreach($productsList as $productInfo){
|
foreach(self::$productsList as $productInfo){
|
||||||
// 首件运费
|
// 首件运费
|
||||||
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
$amount += (float)sprintf("%.2f",$firstWeightFee);
|
||||||
// 判断:如果数量超过首件数量 则计算续件运费
|
// 判断:如果数量超过首件数量 则计算续件运费
|
||||||
|
|
@ -221,10 +233,9 @@ class ShippingService{
|
||||||
* Author: wu-hui
|
* Author: wu-hui
|
||||||
* Time: 2023/08/22 11:59
|
* Time: 2023/08/22 11:59
|
||||||
* @param $logisticsInfo
|
* @param $logisticsInfo
|
||||||
* @param $productsList
|
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
private static function compute_free($logisticsInfo,$productsList){
|
private static function compute_free($logisticsInfo){
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -240,8 +251,6 @@ class ShippingService{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过配送方式获取插件编码
|
* 通过配送方式获取插件编码
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,7 @@
|
||||||
_this.goods_list = list;
|
_this.goods_list = list;
|
||||||
|
|
||||||
_this.computeOrderMoney();
|
_this.computeOrderMoney();
|
||||||
|
_this.$refs['select-logistics'].getLogisticsList()
|
||||||
|
|
||||||
// let price = 0;
|
// let price = 0;
|
||||||
// if (this.numPrices.light == 0) {
|
// if (this.numPrices.light == 0) {
|
||||||
|
|
@ -653,7 +654,9 @@
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
_this.goods_list = list;
|
_this.goods_list = list;
|
||||||
|
|
||||||
_this.computeOrderMoney();
|
_this.computeOrderMoney();
|
||||||
|
_this.$refs['select-logistics'].getLogisticsList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
goods_list: JSON.stringify(_this.goods_list),
|
goods_list: JSON.stringify(_this.goods_list),
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if(res.status === 'success'){
|
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 || {};
|
_this.country = res.data.country || {};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue