添加:物流管理 - 商品详情页面支持切换国家和物流;并且同步刷新对应的运费
This commit is contained in:
parent
3c96766442
commit
f55c520015
|
|
@ -137,7 +137,7 @@ class CountryRepo
|
|||
// 列表获取
|
||||
$builder = Country::query()
|
||||
->where('name', 'like', "$name%")
|
||||
->select('id', 'name', 'status', 'code')
|
||||
->select('id', 'name', 'icon', 'status', 'code')
|
||||
->orderBy('sort_order','ASC')
|
||||
->orderBy('id','ASC');
|
||||
// if ($onlyActive) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace Beike\Shop\Http\Controllers;
|
|||
|
||||
use Beike\Models\Cart;
|
||||
use Beike\Models\CartProduct;
|
||||
use Beike\Models\Country;
|
||||
use Beike\Models\Logistics;
|
||||
use Beike\Models\Product;
|
||||
use Beike\Models\ProductSku;
|
||||
use Beike\Repositories\AddressRepo;
|
||||
|
|
@ -78,6 +80,7 @@ class ProductController extends Controller
|
|||
*/
|
||||
public function computeOrderMoney(Request $request){
|
||||
// 参数获取
|
||||
$changeLogisticsId = (int)$request->change_logistics_id ?? 0;
|
||||
$list = json_decode($request->list,TRUE) ?? '';
|
||||
if(!is_array($list)) return json_fail(trans('shop/products.buy_sku_error'));
|
||||
// 生成模拟数据
|
||||
|
|
@ -103,12 +106,13 @@ class ProductController extends Controller
|
|||
$defaultAddressId = $defaultAddress->id ?? 0;
|
||||
$shippingMethod = PluginRepo::getShippingMethods()->first();
|
||||
$paymentMethod = PluginRepo::getPaymentMethods()->first();
|
||||
|
||||
$shippingMethodCode = $shippingMethod->code ?? '';
|
||||
$cart = collect([[
|
||||
'customer_id' => $customerId,
|
||||
'session_id' => $sessionId,
|
||||
'shipping_address_id' => $defaultAddressId,
|
||||
'shipping_method_code' => $shippingMethodCode ? $shippingMethodCode . '.0' : '',
|
||||
'shipping_method_code' => (int)$changeLogisticsId > 0 ? (int)$changeLogisticsId : $shippingMethodCode ,
|
||||
'payment_address_id' => $defaultAddressId,
|
||||
'payment_method_code' => $paymentMethod->code ?? '',
|
||||
// "id" => 28,
|
||||
|
|
@ -129,13 +133,71 @@ class ProductController extends Controller
|
|||
$cart = $cart[0];
|
||||
// 计算
|
||||
$checkoutService = new CheckoutService();
|
||||
$totalClass = hook_filter('service.checkout.total_service','Beike\Shop\Services\TotalService');
|
||||
$checkoutService->totalService = (new $totalClass($cart,$cartList));
|
||||
$checkoutData = $checkoutService->checkoutData();
|
||||
$checkoutData = $checkoutService->update([
|
||||
// 'customer_id' => $customerId,
|
||||
// 'session_id' => $sessionId,
|
||||
'shipping_address_id' => $defaultAddressId,
|
||||
'shipping_method_code' => (int)$changeLogisticsId > 0 ? (int)$changeLogisticsId : $shippingMethodCode ,
|
||||
'payment_address_id' => $defaultAddressId,
|
||||
'payment_method_code' => $paymentMethod->code ?? '']);
|
||||
|
||||
|
||||
// $totalClass = hook_filter('service.checkout.total_service','Beike\Shop\Services\TotalService');
|
||||
// $checkoutService->totalService = (new $totalClass($cart,$cartList));
|
||||
// $checkoutData = $checkoutService->checkoutData();
|
||||
$totals = $checkoutData['totals'];
|
||||
|
||||
return json_success(trans('common.success'),$totals);
|
||||
}
|
||||
// 获取物流列表
|
||||
public function productsLogistics(Request $request){
|
||||
$data = [
|
||||
'list' => [],
|
||||
'country' => [],
|
||||
];
|
||||
// 参数获取
|
||||
$countryId = (int)$request->country_id;
|
||||
$goodsList = json_decode($request->goods_list,TRUE) ?? '';
|
||||
if($countryId){
|
||||
// 刷新国家信息
|
||||
$country = Country::query()->where('id',$countryId)->first();
|
||||
$data['country'] = $country ? $country->toArray() : [];
|
||||
}
|
||||
// 信息获取
|
||||
$list = Logistics::query()
|
||||
->select([
|
||||
'id',
|
||||
'name',
|
||||
'day_min',
|
||||
'day_max',
|
||||
])
|
||||
->when($countryId > 0,function($q) use ($countryId){
|
||||
$q->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'));
|
||||
})
|
||||
->orderBy('position','ASC')
|
||||
->orderBy('id','ASC')
|
||||
->get();
|
||||
$data['list'] = $list ? $list->toArray() : [];
|
||||
// 循环处理内容
|
||||
$time = time();
|
||||
foreach($data['list'] as &$logisticsItem){
|
||||
// 预计到达时间处理
|
||||
$startTime = date('Y-m-d',strtotime("+{$logisticsItem['day_min']} day", $time));
|
||||
$endTime = date('Y-m-d',strtotime("+{$logisticsItem['day_max']} day", $time));
|
||||
$logisticsItem['estimated_time'] = trans('order.expected_arrival',['start_time'=>$startTime,'end_time'=>$endTime]);
|
||||
// 判断:如果存在商品 计算物流运费信息
|
||||
if(count($goodsList) > 0){
|
||||
$request->list = $request->goods_list;
|
||||
$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');
|
||||
}
|
||||
}
|
||||
|
||||
return json_success(trans('common.success'),$data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* ZoneController.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
|
|
@ -11,21 +10,41 @@
|
|||
|
||||
namespace Beike\Shop\Http\Controllers;
|
||||
|
||||
use Beike\Repositories\CountryRepo;
|
||||
use Beike\Repositories\ZoneRepo;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ZoneController extends Controller
|
||||
{
|
||||
public function index(Request $request, int $countryId)
|
||||
{
|
||||
class ZoneController extends Controller{
|
||||
public function index(Request $request,int $countryId){
|
||||
ZoneRepo::listByCountry($countryId);
|
||||
|
||||
$data = [
|
||||
'zones' => ZoneRepo::listByCountry($countryId),
|
||||
];
|
||||
|
||||
$data = hook_filter('zone.index.data', $data);
|
||||
|
||||
return json_success(trans('common.success'), $data);
|
||||
$data = hook_filter('zone.index.data',$data);
|
||||
return json_success(trans('common.success'),$data);
|
||||
}
|
||||
/**
|
||||
* Common: 获取全部的国家列表
|
||||
* Author: wu-hui
|
||||
* Time: 2023/08/25 16:57
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function countries(Request $request){
|
||||
|
||||
$brands = CountryRepo::autocomplete($request->get('name') ?? '', 0);
|
||||
|
||||
return json_success(trans('common.get_success'), $brands);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ Route::prefix('/')
|
|||
Route::get('categories/{category}', [CategoryController::class, 'show'])->name('categories.show');
|
||||
|
||||
Route::get('countries/{id}/zones', [ZoneController::class, 'index'])->name('countries.zones.index');
|
||||
Route::get('countries/autocomplete', [ZoneController::class, 'countries'])->name('countries.zones.countries');
|
||||
|
||||
Route::get('currency/{currency}', [CurrencyController::class, 'index'])->name('currency.switch');
|
||||
|
||||
|
|
@ -66,6 +67,7 @@ Route::prefix('/')
|
|||
Route::get('products/search', [ProductController::class, 'search'])->name('products.search');
|
||||
Route::get('products/{product}', [ProductController::class, 'show'])->name('products.show');
|
||||
Route::post('products/computeOrderMoney', [ProductController::class, 'computeOrderMoney'])->name('products.computeOrderMoney');
|
||||
Route::post('products/productsLogistics', [ProductController::class, 'productsLogistics'])->name('products.productsLogistics');
|
||||
|
||||
Route::get('register', [RegisterController::class, 'index'])->name('register.index');
|
||||
Route::post('register', [RegisterController::class, 'store'])->name('register.store');
|
||||
|
|
|
|||
|
|
@ -13,17 +13,25 @@
|
|||
namespace Beike\Shop\Services\TotalServices;
|
||||
|
||||
use Beike\Libraries\Weight;
|
||||
use Beike\Models\Country;
|
||||
use Beike\Models\Logistics;
|
||||
use Beike\Models\Product;
|
||||
use Beike\Repositories\LogisticsRepo;
|
||||
use Beike\Shop\Services\CheckoutService;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ShippingService{
|
||||
protected static $country;
|
||||
|
||||
// 运费计算
|
||||
public static function getTotal(CheckoutService $checkout): ?array{
|
||||
// 计算运费
|
||||
$totalService = $checkout->totalService;
|
||||
$shippingMethod = $totalService->getShippingMethod();
|
||||
$amount = 0;
|
||||
$logisticsInfo = [];// 物流信息
|
||||
self::$country = LogisticsRepo::getDefaultCountries(true);// 国家信息
|
||||
$showTips = 0;// 是否显示【待协商】提示
|
||||
if($shippingMethod && !is_int($checkout->cart->shipping_method_code)){
|
||||
// 通过插件(固定运费) 进行计算
|
||||
if(empty($shippingMethod)) return NULL;
|
||||
|
|
@ -48,7 +56,6 @@ class ShippingService{
|
|||
if($logisticsInfo) {
|
||||
// 商品信息处理 获取同一个商品的数量
|
||||
$products = $totalService->getCartProducts();
|
||||
// $products = $checkout->selectedProducts->toArray() ?? [];
|
||||
$productsList = collect($products)->groupBy('product_id')->map(function($group){
|
||||
$firstInfo = $group->first();
|
||||
$productWeightInfo = Product::query()
|
||||
|
|
@ -73,13 +80,20 @@ class ShippingService{
|
|||
$logisticsHandleFun = 'compute_'.$logisticsInfo['type'];
|
||||
$amount = self::$logisticsHandleFun($logisticsInfo,$productsList);
|
||||
}
|
||||
else{
|
||||
// 如果还是不能获取物流信息 则显示 待协商
|
||||
$showTips = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$totalData = [
|
||||
'code' => 'shipping',
|
||||
'title' => trans('shop/carts.shipping_fee'),
|
||||
'amount' => $amount,
|
||||
'amount_format' => currency_format($amount),
|
||||
'amount_tips' => trans('shop/carts.to_be_negotiated'),
|
||||
'show_tips' => $showTips,
|
||||
'country' => self::$country,// 国家信息
|
||||
'logistics' => $logisticsInfo,// 物流信息
|
||||
];
|
||||
$totalService->amount += $totalData['amount'];
|
||||
$totalService->totals[] = $totalData;
|
||||
|
|
@ -95,24 +109,51 @@ 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'];
|
||||
// 判断:客服端是否切换国家 如果存在切换的国家id 则使用切换的国家id;不存在则继续执行
|
||||
$countryId = (int)request()->input('products_country_id');
|
||||
if($countryId > 0) {
|
||||
// 切换国家或者物流
|
||||
// 仅存在国家ID,直接获取当前国家全部物流信息,取其中一个
|
||||
// 同时存在国家ID和物流ID 则获取对应物流ID;如果未查询到该物流 则执行仅存在国家ID时的操作
|
||||
if($logisticsId) {
|
||||
// 同时存在国家ID 获取物流ID
|
||||
$logisticsInfo = Logistics::query()
|
||||
->whereRaw(\DB::raw('FIND_IN_SET('.$countryId.',country_ids)'))
|
||||
->where('id',$logisticsId)
|
||||
->select($logisticsField)
|
||||
->first();
|
||||
if($logisticsInfo) {
|
||||
// 刷新国家信息
|
||||
self::refreshCurrentCountry($countryId);
|
||||
|
||||
return $logisticsInfo->toArray();
|
||||
}
|
||||
}
|
||||
// 仅存在国家ID时
|
||||
goto CountryGetLogistics;
|
||||
}
|
||||
// 不存在切换国家id 正常流程
|
||||
if($logisticsId <= 0){
|
||||
// 获取当前收货地址国家ID
|
||||
$cartArr = $cart->toArray();
|
||||
$address = $cart->guest_shipping_address ?? $cart->guest_payment_address ?? $cartArr['payment_address'] ?? $cartArr['shipping_address'];
|
||||
if(!$address) return [];
|
||||
$countryId = $address['country_id'];
|
||||
if($address) $countryId = (int)$address['country_id'];// 存在收货地址(用户已经登录 || 用户设置收货地址)
|
||||
else $countryId = (int)self::$country['id'];// 不存在收货地址(用户未登录 || 用户已登录但是未设置收货地址) 获取默认国家收货地址
|
||||
// 获取全部物流 返回第一个物流信息ID
|
||||
$logisticsList = Logistics::getAll($countryId,['id','type','first_weight','first_weight_fee','continuation_weight_max','add_weight','continuation_weight_fee','num_fee']);
|
||||
CountryGetLogistics:
|
||||
$logisticsList = Logistics::getAll($countryId,$logisticsField);
|
||||
// 刷新国家信息
|
||||
self::refreshCurrentCountry($countryId);
|
||||
|
||||
return $logisticsList[0] ?? [];
|
||||
}else{
|
||||
// 获取物流信息
|
||||
$logisticsInfo = Logistics::query()
|
||||
->select(['type','first_weight','first_weight_fee','continuation_weight_max','add_weight','continuation_weight_fee','num_fee'])
|
||||
->find($logisticsId)
|
||||
->toArray();
|
||||
->select($logisticsField)
|
||||
->find($logisticsId);
|
||||
|
||||
return $logisticsInfo;
|
||||
return $logisticsInfo ? $logisticsInfo->toArray() : [];
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -130,9 +171,9 @@ class ShippingService{
|
|||
* 总重量 - 高于首重;则运费 = 首重按照【首重运费】计算;(剩余重量 / 每增加重量 ) * 续重运费
|
||||
*/
|
||||
$amount = (int)0;
|
||||
$firstWeight = (int)$logisticsInfo['first_weight'];// 首重
|
||||
$firstWeight = (float)$logisticsInfo['first_weight'];// 首重
|
||||
$firstWeightFee = (float)$logisticsInfo['first_weight_fee'];// 首重运费
|
||||
$addWeight = (int)$logisticsInfo['add_weight'];// 每增加重量
|
||||
$addWeight = (float)$logisticsInfo['add_weight'];// 每增加重量
|
||||
$continuationWeightFee = (float)$logisticsInfo['continuation_weight_fee'];// 续重运费
|
||||
// 循环处理商品
|
||||
foreach($productsList as $productInfo){
|
||||
|
|
@ -187,6 +228,17 @@ class ShippingService{
|
|||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Common: 刷新当前选择国家信息
|
||||
* Author: wu-hui
|
||||
* Time: 2023/08/28 14:50
|
||||
*/
|
||||
private static function refreshCurrentCountry($countryId){
|
||||
$newCountry = Country::query()->where('id',$countryId)->first();
|
||||
self::$country = $newCountry ? $newCountry->toArray() : [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@
|
|||
let singleInfo = Object.values(info)[0];
|
||||
$http.post('logistics/default_countries',{ country: singleInfo }).then((res) => {
|
||||
_this.default_countries_name = singleInfo.name;
|
||||
_this.$refs['select-countries'].closeSelectCountries();
|
||||
})
|
||||
},
|
||||
// 当前选择国家文字显示
|
||||
|
|
|
|||
|
|
@ -74,4 +74,6 @@ return [
|
|||
'logistics_duration' => 'Delivery within :day working days after shipment',
|
||||
'unit' => 'unit::unit',
|
||||
'default_countries' => 'Default display country for the front desk',
|
||||
'choose_logistics' => 'Select Shipping Service',
|
||||
'estimated_time' => 'Estimated delivery time',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,40 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* cart.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-19 14:54:21
|
||||
* @modified 2022-08-19 14:54:21
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'Cart',
|
||||
'added_to_cart' => 'Added To Cart',
|
||||
'select_all' => 'Select All',
|
||||
'commodity' => 'Product',
|
||||
'quantity' => 'Quantity',
|
||||
'subtotal' => 'Subtotal',
|
||||
'product_total' => 'Quantity total',// Product Total
|
||||
'customer_discount' => 'Customer Discount',
|
||||
'order_total' => 'Order Total',
|
||||
'shipping_fee' => 'Shipping Fee',
|
||||
'all' => 'All',
|
||||
'selected' => 'Selected',
|
||||
'to_checkout' => 'Checkout',
|
||||
'cart_empty' => 'Your shopping cart is empty',
|
||||
'go_buy' => 'You can go and see what you want to buy',
|
||||
'go_shopping' => 'Go Shopping',
|
||||
'must_select' => 'Please select at least one product',
|
||||
'mini' => 'Your cart',
|
||||
'delete' => 'Delete',
|
||||
'check_cart' => 'Shopping Cart',
|
||||
|
||||
'index' => 'Cart',
|
||||
'added_to_cart' => 'Added To Cart',
|
||||
'select_all' => 'Select All',
|
||||
'commodity' => 'Product',
|
||||
'quantity' => 'Quantity',
|
||||
'subtotal' => 'Subtotal',
|
||||
'product_total' => 'Quantity total',// Product Total
|
||||
'customer_discount' => 'Customer Discount',
|
||||
'order_total' => 'Order Total',
|
||||
'shipping_fee' => 'Shipping Fee',
|
||||
'all' => 'All',
|
||||
'selected' => 'Selected',
|
||||
'to_checkout' => 'Checkout',
|
||||
'cart_empty' => 'Your shopping cart is empty',
|
||||
'go_buy' => 'You can go and see what you want to buy',
|
||||
'go_shopping' => 'Go Shopping',
|
||||
'must_select' => 'Please select at least one product',
|
||||
'mini' => 'Your cart',
|
||||
'delete' => 'Delete',
|
||||
'check_cart' => 'Shopping Cart',
|
||||
'invalid_customer' => 'Invalid customer.',
|
||||
'empty_selected_products' => 'Empty selected products.',
|
||||
'invalid_shipping_address' => 'Invalid shipping address',
|
||||
'invalid_payment_address' => 'Invalid payment address.',
|
||||
'invalid_shipping_method' => 'Invalid shipping method.',
|
||||
'invalid_payment_method' => 'Invalid payment method.',
|
||||
'to_be_negotiated' => 'To be negotiated',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -27,4 +27,5 @@ return [
|
|||
'product_total' => 'Quantity total',// Product Total
|
||||
'shipping_fee' => 'Shipping Fee',
|
||||
'order_total' => 'Order Total',
|
||||
'ship_to' => 'Ship to',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -79,4 +79,10 @@ return [
|
|||
'logistics_duration' => '发货后:day个工作日内交货',
|
||||
'unit' => '单位::unit',
|
||||
'default_countries' => '前台默认展示国家',
|
||||
'choose_logistics' => '选择运输服务',
|
||||
'estimated_time' => '预计送达时间',
|
||||
|
||||
|
||||
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,40 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* common.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-17 23:10:20
|
||||
* @modified 2022-08-17 23:10:20
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => '购物车',
|
||||
'added_to_cart' => '已加入购物车',
|
||||
'select_all' => '全选',
|
||||
'commodity' => '商品',
|
||||
'quantity' => '数量',
|
||||
'subtotal' => '小计',
|
||||
'product_total' => '商品总计',
|
||||
'customer_discount' => '会员优惠',
|
||||
'order_total' => '应付总金额',
|
||||
'shipping_fee' => '运费',
|
||||
'all' => '全部',
|
||||
'selected' => '已选',
|
||||
'to_checkout' => '去结账',
|
||||
'cart_empty' => '您的购物车是空的',
|
||||
'go_buy' => '您可以去看看有哪些想买的',
|
||||
'go_shopping' => '去逛逛',
|
||||
'must_select' => '请选择至少一个商品',
|
||||
'mini' => '您的购物车',
|
||||
'delete' => '删除',
|
||||
'check_cart' => '查看购物车',
|
||||
|
||||
'index' => '购物车',
|
||||
'added_to_cart' => '已加入购物车',
|
||||
'select_all' => '全选',
|
||||
'commodity' => '商品',
|
||||
'quantity' => '数量',
|
||||
'subtotal' => '小计',
|
||||
'product_total' => '商品总计',
|
||||
'customer_discount' => '会员优惠',
|
||||
'order_total' => '应付总金额',
|
||||
'shipping_fee' => '运费',
|
||||
'all' => '全部',
|
||||
'selected' => '已选',
|
||||
'to_checkout' => '去结账',
|
||||
'cart_empty' => '您的购物车是空的',
|
||||
'go_buy' => '您可以去看看有哪些想买的',
|
||||
'go_shopping' => '去逛逛',
|
||||
'must_select' => '请选择至少一个商品',
|
||||
'mini' => '您的购物车',
|
||||
'delete' => '删除',
|
||||
'check_cart' => '查看购物车',
|
||||
'invalid_customer' => '购物车客户无效',
|
||||
'empty_selected_products' => '购物车选中商品为空',
|
||||
'invalid_shipping_address' => '配送地址无效',
|
||||
'invalid_payment_address' => '账单地址无效',
|
||||
'invalid_shipping_method' => '配送方式不可用',
|
||||
'invalid_payment_method' => '支付方式不可用',
|
||||
'to_be_negotiated' => '待协商',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -27,4 +27,5 @@ return [
|
|||
'product_total' => '产品总计',
|
||||
'shipping_fee' => '运费',
|
||||
'order_total' => '订单总额',
|
||||
'ship_to' => '运送至',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@
|
|||
<span class="radio"></span>
|
||||
</div>
|
||||
<div class="right ms-3">
|
||||
<div class="title">${methods.name}(${methods.quotes.warehouse_name} }})</div>
|
||||
<div class="title">${methods.name}(${methods.quotes.warehouse_name})</div>
|
||||
<div class="title">
|
||||
${typeText}
|
||||
<span style="margin-left: 10px;">${logistics_duration}</span>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<video
|
||||
id="product-video"
|
||||
class="video-js vjs-big-play-centered vjs-fluid vjs-16-9"
|
||||
controls loop muted
|
||||
controls muted
|
||||
>
|
||||
<source src="{{ image_origin($product['video']) }}" type="video/mp4" />
|
||||
</video>
|
||||
|
|
|
|||
|
|
@ -77,6 +77,46 @@
|
|||
.quantity-btns .operating-content button:first-child{
|
||||
margin-left: 0!important;
|
||||
}
|
||||
|
||||
.shipping-line{
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.shipping-line .country{
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.shipping-line .country .country-name{
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
user-select: none; /* 标准语法 */
|
||||
}
|
||||
.shipping-line .country .country-name i{
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
|
||||
.logistics-content{
|
||||
margin-left: 20px;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
user-select: none; /* 标准语法 */
|
||||
}
|
||||
.logistics-content i{
|
||||
margin-left: 3px;
|
||||
}
|
||||
</style>
|
||||
<div class="container {{ request('iframe') ? 'pt-4' : '' }}" id="product-app" v-cloak>
|
||||
<div class="row mb-5 mt-3 mt-md-0" id="product-top">
|
||||
|
|
@ -327,8 +367,33 @@
|
|||
</li>--}}
|
||||
|
||||
<li v-for="(item,index) in totals">
|
||||
<span>@{{ item.title }}</span>
|
||||
<span>@{{ item.amount_format }}</span>
|
||||
<template v-if="item.code == 'shipping'">
|
||||
{{--当内容为运费时--}}
|
||||
<span class="shipping-line">
|
||||
<div>@{{ item.title }}</div>
|
||||
<div class="country" v-if="Object.keys(item.country).length > 0">
|
||||
{{ __('shop/products.ship_to') }}:
|
||||
<div class="wh-20 border d-flex justify-content-center rounded-2 align-items-center">
|
||||
<img :src="item.country.icon" class="img-fluid rounded-2">
|
||||
</div>
|
||||
<div class="country-name" @click="$refs['select-countries'].showSelectCountries()">
|
||||
@{{ item.country.name }}<i class="bi bi-chevron-down"></i>
|
||||
@{{ logisticsChangeCountry(item.country.id) }}
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="shipping-line" v-if="item.show_tips != 1" @click="$refs['select-logistics'].showSelectLogistics()">
|
||||
<div>@{{ item.amount_format }}</div>
|
||||
<div class="logistics-content" v-if="Object.keys(item.logistics).length > 0">
|
||||
@{{ item.logistics.name }}<i class="bi bi-chevron-down"></i>
|
||||
</div>
|
||||
</span>
|
||||
<span class="shipping-line" v-else>@{{ item.amount_tips }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>@{{ item.title }}</span>
|
||||
<span>@{{ item.amount_format }}</span>
|
||||
</template>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
@ -442,6 +507,10 @@
|
|||
@hook('product.tab.after.pane')
|
||||
</div>
|
||||
</div>
|
||||
{{-- 国家选择器 --}}
|
||||
<select-countries ref="select-countries" :country_list="country_list" @change-info="changeCountry" :is_single="true"></select-countries>
|
||||
{{-- 物流选择器 --}}
|
||||
<select-logistics ref="select-logistics" @change-info="changeLogistics" :country_id="logistics_country_id" :goods_list="goods_list"></select-logistics>
|
||||
</div>
|
||||
|
||||
@if ($relations && !request('iframe'))
|
||||
|
|
@ -470,13 +539,14 @@
|
|||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
@include('shared.select-countries')
|
||||
@include('shared.select-logistics')
|
||||
<script>
|
||||
let swiperMobile = null;
|
||||
const isIframe = bk.getQueryString('iframe', false);
|
||||
|
||||
let app = new Vue({
|
||||
el: '#product-app',
|
||||
|
||||
data: {
|
||||
product_total: 0,
|
||||
shipping_fee: 0,
|
||||
|
|
@ -530,9 +600,15 @@
|
|||
},],
|
||||
},
|
||||
// 多规格批量购买
|
||||
goods_list: {},
|
||||
add_buy_sku:{},
|
||||
totals: {},// 支付金额统计
|
||||
|
||||
// 国家选择
|
||||
country_list: {},
|
||||
country_id: 0,
|
||||
// 物流切换
|
||||
logistics_country_id: 0,
|
||||
change_logistics_id: 0,
|
||||
},
|
||||
watch: {
|
||||
quantity: function (newval, oldval) {
|
||||
|
|
@ -544,7 +620,9 @@
|
|||
product_sku_id: this.product.id,
|
||||
quantity: this.quantity,
|
||||
};
|
||||
_this.computeOrderMoney(list);
|
||||
_this.goods_list = list;
|
||||
|
||||
_this.computeOrderMoney();
|
||||
|
||||
// let price = 0;
|
||||
// if (this.numPrices.light == 0) {
|
||||
|
|
@ -574,8 +652,8 @@
|
|||
quantity: item.quantity,
|
||||
};
|
||||
})
|
||||
|
||||
_this.computeOrderMoney(list);
|
||||
_this.goods_list = list;
|
||||
_this.computeOrderMoney();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -717,7 +795,6 @@
|
|||
})
|
||||
});
|
||||
},
|
||||
|
||||
// 提交购物车
|
||||
addCart(isBuyNow = false) {
|
||||
let _this = this;
|
||||
|
|
@ -757,6 +834,10 @@
|
|||
isBuyNow
|
||||
};
|
||||
}
|
||||
// 公共参数加入
|
||||
params.products_country_id = _this.country_id;
|
||||
params.change_logistics_id = _this.change_logistics_id;
|
||||
|
||||
// 提交内容
|
||||
bk.addCart(params, null, () => {
|
||||
if (isIframe) {
|
||||
|
|
@ -830,10 +911,12 @@
|
|||
_this.$forceUpdate();
|
||||
},
|
||||
// 计算当前订单总额
|
||||
computeOrderMoney(list){
|
||||
computeOrderMoney(){
|
||||
let _this = this;
|
||||
$http.post(`products/computeOrderMoney`, {
|
||||
list: JSON.stringify(list),
|
||||
list: JSON.stringify(_this.goods_list),
|
||||
products_country_id: _this.country_id,
|
||||
change_logistics_id: _this.change_logistics_id
|
||||
}).then((res) => {
|
||||
if(res.status === 'success'){
|
||||
_this.totals = res.data;
|
||||
|
|
@ -842,6 +925,28 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
// 国家改变
|
||||
changeCountry(info){
|
||||
let _this = this;
|
||||
let singleInfo = Object.values(info)[0];
|
||||
_this.country_id = singleInfo['id'];
|
||||
_this.computeOrderMoney();
|
||||
_this.$refs['select-countries'].closeSelectCountries();
|
||||
},
|
||||
// 物流切换 - 物流国家改变
|
||||
logisticsChangeCountry(countryId){
|
||||
this.logistics_country_id = countryId || 0;
|
||||
},
|
||||
// 物流切换 - 使用物流改变
|
||||
changeLogistics(info){
|
||||
let id = info.id;
|
||||
let _this = this;
|
||||
if(parseInt(id) > 0 && !isNaN(parseInt(id))){
|
||||
_this.change_logistics_id = info.id;
|
||||
_this.computeOrderMoney();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
<style>
|
||||
.logistics-list{
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.country{
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.country .country-name{
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
user-select: none; /* 标准语法 */
|
||||
}
|
||||
.country .country-name i{
|
||||
margin-left: 3px;
|
||||
}
|
||||
</style>
|
||||
<template id="select-logistics">
|
||||
<el-dialog custom-class="mobileWidth" title="{{ __('admin/logistics.choose_logistics') }}" :visible.sync="is_show" width="80%" @close="closeSelectLogistics">
|
||||
{{--国家信息--}}
|
||||
<div class="country" v-if="Object.keys(country).length > 0">
|
||||
{{ __('shop/products.ship_to') }}:
|
||||
<div class="wh-20 border d-flex justify-content-center rounded-2 align-items-center">
|
||||
<img :src="country.icon" class="img-fluid rounded-2">
|
||||
</div>
|
||||
<div class="country-name">@{{ country.name }}</div>
|
||||
</div>
|
||||
{{--物流列表--}}
|
||||
<div class="logistics-list" v-if="Object.keys(logistics_list).length > 0">
|
||||
<el-table :data="logistics_list" style="width: 100%">
|
||||
<el-table-column label="{{ __('admin/logistics.logistics_name') }}" prop="name" min-width="130"></el-table-column>
|
||||
<el-table-column label="{{ __('admin/logistics.estimated_time') }}" prop="estimated_time" min-width="200"></el-table-column>
|
||||
<el-table-column label="{{ __('shop/carts.shipping_fee') }}" prop="shipping_fee" min-width="120"></el-table-column>
|
||||
<el-table-column label="{{ __('common.action') }}" width="80">
|
||||
<template #default="scope">
|
||||
<el-button type="success" circle @click="selectedLogistics(scope.row)">
|
||||
<i class="bi bi-check-lg"></i>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-empty v-else description="{{ __('common.no_data') }}" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
Vue.component('select-logistics', {
|
||||
template: '#select-logistics',
|
||||
props: {
|
||||
country_id:{
|
||||
default: 0,
|
||||
type: [Number,String],
|
||||
},
|
||||
goods_list:{
|
||||
default: {},
|
||||
type: [Object,Array],
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
is_show: false,
|
||||
logistics_list: {},
|
||||
country: {},
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
country_id(){
|
||||
this.getLogisticsList();
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
beforeMount() {},
|
||||
mounted(){
|
||||
this.getLogisticsList()
|
||||
},
|
||||
methods: {
|
||||
// 显示选择器
|
||||
showSelectLogistics() {
|
||||
this.is_show = true;
|
||||
},
|
||||
// 关闭选择器
|
||||
closeSelectLogistics() {
|
||||
this.is_show = false;
|
||||
},
|
||||
// 列表获取
|
||||
getLogisticsList(){
|
||||
let _this = this;
|
||||
// 发起请求
|
||||
$http.post(`products/productsLogistics`, {
|
||||
country_id: _this.country_id,
|
||||
goods_list: JSON.stringify(_this.goods_list),
|
||||
}).then((res) => {
|
||||
if(res.status === 'success'){
|
||||
_this.logistics_list = res.data.list || {};
|
||||
_this.country = res.data.country || {};
|
||||
}
|
||||
})
|
||||
},
|
||||
// 切换物流选中
|
||||
selectedLogistics(item){
|
||||
let _this = this;
|
||||
_this.closeSelectLogistics();
|
||||
_this.$message.success("{{ __('common.edit_success') }}");
|
||||
_this.$emit('change-info',item);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in New Issue