1239 lines
49 KiB
PHP
1239 lines
49 KiB
PHP
@extends('layout.master')
|
||
@section('body-class', 'page-product')
|
||
@section('title', $product['meta_title'] ?: $product['name'])
|
||
@section('keywords', $product['meta_keywords'] ?: system_setting('base.meta_keyword'))
|
||
@section('description', $product['meta_description'] ?: system_setting('base.meta_description'))
|
||
|
||
@push('header')
|
||
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
|
||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||
|
||
<script src="{{ asset('vendor/element-ui/index.js') }}"></script>
|
||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/index.css') }}">
|
||
@if ($product['video'])
|
||
<script src="{{ asset('vendor/video/video.min.js') }}"></script>
|
||
<link rel="stylesheet" href="{{ asset('vendor/video/video-js.min.css') }}">
|
||
@endif
|
||
@endpush
|
||
|
||
@php
|
||
$iframeClass = request('iframe') ? 'd-none' : '';
|
||
@endphp
|
||
|
||
@section('content')
|
||
@if (!request('iframe'))
|
||
<x-shop-breadcrumb type="product" :value="$product['id']"/>
|
||
@endif
|
||
<style>
|
||
.quantity-btns{
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
flex-wrap: nowrap;
|
||
justify-content: center;
|
||
}
|
||
.quantity-btns .add-wishlist{
|
||
margin-left: 10px;
|
||
}
|
||
.quantity-btns .add-wishlist .text-secondary{
|
||
height: 100% !important;
|
||
}
|
||
.quantity-btns .buy-num-list{
|
||
width: 100%;
|
||
padding: 5px 10px;
|
||
}
|
||
.quantity-btns .list-box{
|
||
width: 100%;
|
||
display: inline-flex;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
.quantity-btns .list-box .sku-info{
|
||
display: inline-flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-start;
|
||
height: 42px;
|
||
width: 50%;
|
||
align-content: center;
|
||
align-items: center;
|
||
margin-right: 30px;
|
||
}
|
||
.quantity-btns .list-box .sku-info span{
|
||
margin-right: 20px!important;
|
||
}
|
||
.quantity-btns .operating-content {
|
||
width: 100%;
|
||
display: inline-flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
flex-direction: row;
|
||
}
|
||
.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{
|
||
/* width: 80px;
|
||
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;
|
||
}
|
||
.logistics-bottom-content {
|
||
height: 20px!important;
|
||
margin-top: 10px;
|
||
width: 100%;
|
||
display: inline-flex;
|
||
justify-content: flex-end;
|
||
}
|
||
.other-amount-format{
|
||
/*margin-right: 100px;*/
|
||
}
|
||
|
||
.trade-term-img{
|
||
width: 1200px!important;
|
||
max-width: 90vw!important;
|
||
max-height: 95vh!important;
|
||
}
|
||
.popover{
|
||
--bs-popover-max-width: 100vw!important;
|
||
}
|
||
.sku-min-order {
|
||
position: absolute;
|
||
bottom: -20px;
|
||
left: 0;
|
||
}
|
||
.num-price-content{
|
||
border-top: 1px solid #aaaaaa;
|
||
border-bottom: 1px solid #aaaaaa;
|
||
padding: 10px;
|
||
position: relative;
|
||
@if($product['sales_method'] == 'batches')
|
||
padding-bottom: 30px!important;
|
||
@endif
|
||
}
|
||
.num-min-order{
|
||
position: absolute;
|
||
bottom: 5px;
|
||
left: 85px;
|
||
}
|
||
.sku-price-wrap{
|
||
position: relative;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
}
|
||
.sku-price-wrap-content{
|
||
width: 100%;
|
||
line-height: 20px !important;
|
||
}
|
||
.num-item-content{
|
||
white-space: nowrap;
|
||
color: #777777;
|
||
font-size: 18px;
|
||
margin-bottom: 5px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
width: 100%;
|
||
}
|
||
.num-trade-term-content {
|
||
height: 54px;
|
||
line-height: 85px;
|
||
display: inline-flex;
|
||
margin-right:10px;
|
||
font-size: calc(1.265rem + 0.18vw) !important;
|
||
}
|
||
.num-trade-term-content-i{
|
||
font-size: 15px;
|
||
}
|
||
</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">
|
||
<div class="col-12 col-lg-6 mb-3">
|
||
<div class="product-image d-flex align-items-start">
|
||
@if(!is_mobile())
|
||
<div class="left {{ $iframeClass }}" v-if="images.length">
|
||
<div class="swiper" id="swiper">
|
||
<div class="swiper-wrapper">
|
||
<div class="swiper-slide" :class="!index ? 'active' : ''" v-for="image, index in images">
|
||
<a href="javascript:;" :data-image="image.preview" :data-zoom-image="image.popup">
|
||
<img :src="image.thumb" class="img-fluid">
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<div class="swiper-pager">
|
||
<div class="swiper-button-next new-feature-slideshow-next"></div>
|
||
<div class="swiper-button-prev new-feature-slideshow-prev"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="right" id="zoom">
|
||
@include('product.product-video')
|
||
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
||
</div>
|
||
@else
|
||
@include('product.product-video')
|
||
<div class="swiper" id="swiper-mobile">
|
||
<div class="swiper-wrapper">
|
||
<div class="swiper-slide" v-for="image, index in images">
|
||
<img :src="image.preview" class="img-fluid">
|
||
</div>
|
||
</div>
|
||
<div class="swiper-pagination mobile-pagination"></div>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12 col-lg-6">
|
||
<div class="peoduct-info">
|
||
@hookwrapper('product.detail.name')
|
||
<h1 class="mb-4 product-name">{{ $product['name'] }}</h1>
|
||
@endhookwrapper
|
||
@hookwrapper('product.detail.price')
|
||
{{-- 非阶梯价 --}}
|
||
<div class="price-wrap d-flex align-items-end sku-price-wrap" v-if="price_setting === 'sku'">
|
||
<div class="sku-price-wrap-content fs-3">
|
||
<span>{{ $product['trade_term'] ?? 'DAP'}}<i class="bi bi-question-circle" id="tradeTerm" style="font-size: 15px;"></i></span>
|
||
<span class="fw-bold">@{{ product.price_format }}</span>
|
||
<span v-if="product.price != product.origin_price && product.origin_price !== 0" class="fw-bold"> - @{{ product.origin_price_format }}</span>
|
||
@if($product['unit'])
|
||
<span style="font-weight: 700 !important;">/ {{explode('/',$product['unit'])[0]}}</span>
|
||
@endif
|
||
<span v-if="minimum_order > 0" style="font-size: 18px;">
|
||
@if($product['sales_method'] == 'piece')
|
||
| {{ $product['minimum_order'] }} {{explode('/',$product['unit'])[1]}}
|
||
@else
|
||
| {{ ($product['piece_to_batch'] * $product['minimum_order']) }} {{explode('/',$product['unit'])[1]}}
|
||
@endif
|
||
<span style="color: #777777;">({{__('product.minimum_order')}})</span>
|
||
</span>
|
||
</div>
|
||
{{--<span class="new-price fs-1 lh-1 fw-bold me-2">{{$product['trade_term'] ?? 'DAP'}}</span>--}}
|
||
{{--<span class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}</span>--}}
|
||
{{--<span class="new-price fs-1 lh-1 fw-bold me-2">-</span>--}}
|
||
{{--<span class="old-price fs-1 lh-1 fw-bold me-2" v-if="product.price != product.origin_price && product.origin_price !== 0">@{{ product.origin_price_format }}</span>--}}
|
||
{{--@if($product['unit'])--}}
|
||
{{-- <span class="new-price fs-1 lh-1 fw-bold me-2">/ {{explode('/',$product['unit'])[0]}} |</span>--}}
|
||
{{--@endif--}}
|
||
{{--<span v-if="minimum_order > 0" style="font-size: 15px;color: #101010;">--}}
|
||
{{-- @if($product['sales_method'] == 'piece')--}}
|
||
{{-- {{ $product['minimum_order'] }} {{explode('/',$product['unit'])[1]}}<span style="color: #999999;">({{__('product.minimum_order')}})</span>--}}
|
||
{{-- @else--}}
|
||
{{-- {{ ($product['piece_to_batch'] * $product['minimum_order']) }} {{explode('/',$product['unit'])[1]}}<span style="color: #999999;">({{__('product.minimum_order')}})</span>--}}
|
||
{{-- @endif--}}
|
||
{{--</span>--}}
|
||
@if($product['sales_method'] == 'batches')
|
||
<span class="sku-min-order">
|
||
{{__('product.minimum_order')}}:@{{ minimum_order }}
|
||
{{ __('product.batches') }}
|
||
(1 {{ __('product.batches') }} = {{ $product['piece_to_batch'] }} {{ strpos($product['unit'], '/') !== false ? explode('/',$product['unit'])[0] : $product['unit']}} in total)
|
||
</span>
|
||
@endif
|
||
</div>
|
||
{{--阶梯价--}}
|
||
<div class="num-price-content price-wrap d-flex align-items-end" v-if="price_setting === 'num'">
|
||
<div class="item num-trade-term-content">
|
||
{{$product['trade_term'] ?? 'DAP'}}<i class="bi bi-question-circle num-trade-term-content-i" id="tradeTerm"></i>
|
||
</div>
|
||
<div class="item" v-for="(item,index) in numPrices" style="flex: 1" :style="{width: 100 / numPrices.length + '%'}">
|
||
<div class="num num-item-content" v-if="index < numPrices.length - 1">
|
||
@{{ item.num }} - @{{ numPrices[index + 1].num - 1 }} {{ strpos($product['unit'], '/') !== false ? explode('/',$product['unit'])[1] : $product['unit']}}
|
||
</div>
|
||
<div class="num num-item-content" v-else-if="item.num">
|
||
>= @{{ item.num }} {{ strpos($product['unit'], '/') !== false ? explode('/',$product['unit'])[1] : $product['unit']}}
|
||
</div>
|
||
<div class="price">
|
||
<div class="new-price fs-3 lh-1 fw-bold me-2">@{{ item.price_format }}</div>
|
||
</div>
|
||
</div>
|
||
@if($product['sales_method'] == 'batches')
|
||
<div class="num-min-order">
|
||
{{__('product.minimum_order')}}:@{{ minimum_order }}
|
||
{{ __('product.batches') }}
|
||
(1 {{ __('product.batches') }} = {{ $product['piece_to_batch'] }} {{ strpos($product['unit'], '/') !== false ? explode('/',$product['unit'])[0] : $product['unit']}} in total)
|
||
</div>
|
||
@endif
|
||
</div>
|
||
@endhookwrapper
|
||
<div class="stock-and-sku mb-4">
|
||
|
||
<div class="d-flex" >
|
||
<span class="title text-muted" style="width: auto!important;">{{__('product.product_type')}}:</span>
|
||
{{ $product['active'] == 1 ? __('common.enable_status') : __('common.disable_status') }}
|
||
</div>
|
||
|
||
@hookwrapper('product.detail.quantity')
|
||
<div class="d-flex">
|
||
<span class="title text-muted">{{ __('product.quantity') }}:</span>
|
||
<div :class="product.quantity > 0 ? 'text-success' : 'text-secondary'">
|
||
<template v-if="product.quantity > 0">@{{ product.quantity }}</template>
|
||
<template v-else>@{{ product.quantity }}</template>
|
||
</div>
|
||
</div>
|
||
@endhookwrapper
|
||
|
||
@if ($product['brand_id'])
|
||
@hookwrapper('product.detail.brand')
|
||
<div class="d-flex">
|
||
<span class="title text-muted">{{ __('product.brand') }}:</span>
|
||
<a href="{{ shop_route('brands.show', $product['brand_id']) }}">{{ $product['brand_name'] }}</a>
|
||
</div>
|
||
@endhookwrapper
|
||
@endif
|
||
|
||
@hookwrapper('product.detail.sku')
|
||
<div class="d-flex" v-if="product.sku">
|
||
<span class="title text-muted">SKU:</span>@{{ product.sku }}
|
||
</div>
|
||
@endhookwrapper
|
||
|
||
@hookwrapper('product.detail.model')
|
||
<div class="d-flex" v-if="product.model"><span class="title text-muted">{{ __('shop/products.model') }}:</span> @{{ product.model }}</div>
|
||
@endhookwrapper
|
||
|
||
{{--<div v-if="minimum_order > 0" class="d-flex" >
|
||
<span class="title text-muted" style="width: auto!important;">{{ __('product.sales_method') }}:</span>
|
||
@if($product['sales_method'] == 'piece')
|
||
{{ __('product.sales_method_piece_unit',['unit'=>$product['unit']]) }}
|
||
@else
|
||
{{ __('product.sales_method_batches') }}({{ __('product.pieces_per_batch',['num'=>$product['piece_to_batch'],'unit'=>$product['unit']]) }})
|
||
@endif
|
||
</div>--}}
|
||
|
||
{{--<div class="d-flex" >
|
||
<span class="title text-muted" style="width: auto!important;">{{__('product.minimum_order')}}:</span>@{{ minimum_order }}
|
||
@if($product['sales_method'] == 'piece')
|
||
{{ $product['unit'] }}
|
||
@else
|
||
{{ __('product.batches') }}({{__('product.total_num',['num'=>($product['piece_to_batch'] * $product['minimum_order']),'unit'=>$product['unit']])}})
|
||
@endif
|
||
</div>--}}
|
||
|
||
{{--@if(!empty($product['unit']))
|
||
<div class="d-flex">
|
||
<span class="title text-muted" style="width: auto!important;">{{__('product.unit_of_measurement')}}:</span> {{ $product['unit'] }}
|
||
</div>
|
||
@endif--}}
|
||
|
||
|
||
</div>
|
||
@if (0)
|
||
<div class="rating-wrap d-flex">
|
||
<div class="rating">
|
||
@for ($i = 0; $i < 5; $i++)
|
||
<i class="iconfont"></i>
|
||
@endfor
|
||
</div>
|
||
<span class="text-muted">132 reviews</span>
|
||
</div>
|
||
@endif
|
||
|
||
{{--商品规格--}}
|
||
<div class="variables-wrap mb-4" v-if="source.variables.length">
|
||
<div class="variable-group mb-2" v-for="variable, variable_index in source.variables" :key="variable_index">
|
||
<p class="mb-2">@{{ variable.name }}</p>
|
||
<div class="variable-info" v-if="!variable.isNumSelect">
|
||
<div
|
||
v-for="value, value_index in variable.values"
|
||
@click="checkedVariableValue(variable_index, value_index, value)"
|
||
:key="value_index"
|
||
:class="[value.selected ? 'selected' : '', value.disabled ? 'disabled' : '']">
|
||
<span class="image" v-if="value.image"><img :src="value.image" class="img-fluid"></span>
|
||
@{{ value.name }}
|
||
</div>
|
||
</div>
|
||
<div class="variable-info-select" v-if="variable.isNumSelect">
|
||
<div class="variable-info-select-num" v-for="value, value_index in variable.values" style="display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
width: 500px;">
|
||
<div class="variable-info-select-num-show">
|
||
<div
|
||
@click="checkedVariableValue(variable_index, value_index, value)"
|
||
:key="value_index">
|
||
<span class="image" v-if="value.image"><img :src="value.image" class="img-fluid"></span>
|
||
@{{ value.name }}
|
||
</div>
|
||
</div>
|
||
<div class="quantity-wrap">
|
||
<input type="text" @change="quantityChange"
|
||
class="form-control"
|
||
:disabled="!product.quantity"
|
||
onkeyup="this.value=this.value.replace(/\D/g,'')"
|
||
v-model="value.quantity"
|
||
value="0"
|
||
:minimum="minimum_order"
|
||
:sales_method="sales_method"
|
||
:piece_to_batch="piece_to_batch"
|
||
:name="'variables['+ variable_index +'].value['+value_index+'].quantity'">
|
||
<div class="right">
|
||
<i class="bi bi-chevron-up" @click="quantityChange"></i>
|
||
<i class="bi bi-chevron-down" @click="quantityChange"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{{-- 购买数量 - 单规格 --}}
|
||
<div class="quantity-wrap mb-4" v-if="Object.keys(source.skus).length <= 1">
|
||
<input type="text"
|
||
class="form-control"
|
||
:disabled="!product.quantity"
|
||
:value="quantity"
|
||
@input="singleQuantityChange($event)"
|
||
:minimum="minimum_order"
|
||
:sales_method="sales_method"
|
||
:piece_to_batch="piece_to_batch"
|
||
name="quantity">
|
||
<div class="right" v-if="!isNumSelect">
|
||
<i class="bi bi-chevron-up"></i>
|
||
<i class="bi bi-chevron-down"></i>
|
||
</div>
|
||
</div>
|
||
{{--购买&进入购物车按钮--}}
|
||
<div class="quantity-btns">
|
||
@hook('product.detail.buy.before')
|
||
{{--添加购买规格--}}
|
||
<button v-if="product.quantity > 0 && !add_buy_sku[product.id] && Object.keys(source.skus).length > 1" class="btn btn-outline-info btn-sm mb-4" @click="clickAddBuySku">
|
||
<i class="bi bi-plus me-1"></i>{{ __('shop/products.add_buy_sku') }}
|
||
</button>
|
||
{{-- 购买数量 - 多规格 --}}
|
||
<div class="buy-num-list mb-4" v-if="Object.keys(add_buy_sku).length > 0">
|
||
@hookwrapper('product.detail.quantity.input')
|
||
<div class="list-box" v-for="skuValue, skuIndex in add_buy_sku">
|
||
<div class="sku-info">
|
||
<span v-for="skuInfoValue, skuInfoIndex in skuValue.sku_info">@{{ skuInfoValue.name }}:@{{ skuInfoValue.value }}</span>
|
||
</div>
|
||
<div class="quantity-wrap">
|
||
<input type="text"
|
||
class="form-control"
|
||
:disabled="skuValue.stock <= skuValue.quantity"
|
||
onkeyup="this.value=this.value.replace(/\D/g,'')"
|
||
:value="add_buy_sku[skuIndex].quantity"
|
||
@input="skuQuantityChange($event,skuIndex)"
|
||
:minimum="minimum_order"
|
||
:sales_method="sales_method"
|
||
:piece_to_batch="piece_to_batch"
|
||
name="quantity">
|
||
<div class="right" v-if="!isNumSelect">
|
||
<i class="bi bi-chevron-up"></i>
|
||
<i class="bi bi-chevron-down"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endhookwrapper
|
||
</div>
|
||
{{--操作内容--}}
|
||
<div class="operating-content mb-4">
|
||
{{--点击加入购物车--}}
|
||
@hookwrapper('product.detail.add_to_cart')
|
||
<button class="btn btn-outline-dark ms-md-3 add-cart fw-bold" :product-id="product.id" :product-price="product.price" :disabled="!product.quantity" @click="addCart(false, this)">
|
||
<i class="bi bi-cart-fill me-1"></i>{{ __('shop/products.add_to_cart') }}
|
||
</button>
|
||
@endhookwrapper
|
||
{{-- 直接下单产品 - 显示立即购买按钮 --}}
|
||
@if ($product['active'])
|
||
@hookwrapper('product.detail.buy_now')
|
||
<button class="btn btn-dark ms-3 fw-bold" :disabled="!product.quantity" :product-id="product.id" :product-price="product.price" @click="addCart(true, this)">
|
||
<i class="bi bi-bag-fill me-1"></i>{{ __('shop/products.buy_now') }}
|
||
</button>
|
||
@endhookwrapper
|
||
@endif
|
||
@hook('product.detail.buy.after')
|
||
{{-- 加入收藏 --}}
|
||
@if ((current_customer() || !request('iframe')))
|
||
@hookwrapper('product.detail.wishlist')
|
||
<button class="btn btn-link ms-3 text-secondary" data-in-wishlist="{{ $product['in_wishlist'] }}" onclick="bk.addWishlist('{{ $product['id'] }}', this)">
|
||
@if ($product['in_wishlist'])
|
||
<i class="bi bi-heart-fill me-1"></i> {{ __('shop/products.cancel_to_favorites') }}
|
||
@else
|
||
<i class="bi bi-heart me-1"></i> {{ __('shop/products.add_to_favorites') }}
|
||
@endif
|
||
</button>
|
||
@endhookwrapper
|
||
@endif
|
||
</div>
|
||
</div>
|
||
{{--价格实时计算--}}
|
||
<ul class="totals">
|
||
{{--<li>
|
||
<span>{{ __('shop/products.product_total') }}</span>
|
||
<span>@{{ product_total }}</span>
|
||
</li>
|
||
<li>
|
||
<span>{{ __('shop/products.shipping_fee') }}</span>
|
||
<span>@{{ shipping_fee }}</span>
|
||
</li>
|
||
<li>
|
||
<span>{{ __('shop/products.order_total') }}</span>
|
||
<span>@{{ order_tota }}</span>
|
||
</li>--}}
|
||
|
||
<li v-for="(item,index) in totals">
|
||
<template v-if="item.code == 'shipping'">
|
||
{{--当内容为运费时--}}
|
||
<div style="width: 100%;display: inline-flex;flex-direction: column;flex-wrap: nowrap;justify-content: center;align-items: flex-start;">
|
||
<div style="height: 20px !important;width: 100%;display: inline-flex;justify-content: space-between;">
|
||
<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>
|
||
</div>
|
||
<div class="logistics-bottom-content" v-if="item.show_tips != 1" @click="$refs['select-logistics'].showSelectLogistics()">
|
||
<div class="logistics-content">
|
||
@{{ item.logistics.name }}<i class="bi bi-chevron-down"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<span>@{{ item.title }}</span>
|
||
<span class="other-amount-format">@{{ item.amount_format }}</span>
|
||
</template>
|
||
</li>
|
||
|
||
</ul>
|
||
<button
|
||
style="width: 16em;"
|
||
class="btn btn-outline-dark my-lg-2 add-cart fw-bold"
|
||
:disabled="!product.quantity"
|
||
@click="centerDialogVisable = true"
|
||
><i class="bi bi-globe me-1"></i>{{ __('shop/products.inquiry') }}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 弹出层 -->
|
||
<el-dialog title="Inquiry" :visible.sync="centerDialogVisable" width="700px" center>
|
||
<div class="root" style="
|
||
display: flex;">
|
||
<div class="left" style="
|
||
flex: 4;">
|
||
<el-form :model="registerForm" ref="registerForm" label-width="90px" :rules="rules">
|
||
<!-- 弹出层歌手名列 -->
|
||
<el-form-item prop="contacts" label="Contacts" size="mini">
|
||
<el-input v-model="registerForm.contacts" placeholder="Contacts"></el-input>
|
||
</el-form-item>
|
||
<!-- 弹出层歌手性别列 -->
|
||
{{-- <el-form-item prop="sex" label="歌手性别" size="mini">--}}
|
||
{{-- <el-radio-group v-model="registerForm.sex">--}}
|
||
{{-- <el-radio :label="0">女</el-radio>--}}
|
||
{{-- <el-radio :label="1">男</el-radio>--}}
|
||
{{-- <el-radio :label="2">组合</el-radio>--}}
|
||
{{-- <el-radio :label="3">不明</el-radio>--}}
|
||
{{-- </el-radio-group>--}}
|
||
{{-- </el-form-item>--}}
|
||
<!-- <el-form-item prop="pic" label="歌手头像" size="mini">
|
||
<el-input v-model="registerForm.pic" placeholder="歌手头像"></el-input>
|
||
</el-form-item> -->
|
||
<!-- 弹出层歌手生日列 -->
|
||
{{-- <el-form-item prop="birth" label="生日" size="mini">--}}
|
||
{{-- <el-date-picker type="date" placeholder="选择日期" v-model="registerForm.birth" style="width: 100%;"></el-date-picker>--}}
|
||
{{-- </el-form-item>--}}
|
||
<el-form-item prop="email" label="E-mail" size="mini">
|
||
<el-input v-model="registerForm.email" placeholder="E-mail"></el-input>
|
||
</el-form-item>
|
||
<el-form-item prop="content" label="Content" size="mini">
|
||
<el-input v-model="registerForm.content" placeholder="Content" type="textarea" :rows="10"></el-input>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
|
||
@hook('product.detail.after')
|
||
</div>
|
||
<div class="right" style="
|
||
flex: 2;
|
||
display: flex;
|
||
align-items: center;
|
||
}">
|
||
<div class="product" style="
|
||
margin: -35px 10px 0 10px;">
|
||
<div class="product-image">
|
||
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
||
</div>
|
||
<div class="product-info" style="
|
||
margin: 5px 5px 0 5px;">
|
||
<div class="product-name">{{ $product['name'] }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 取消,确定按钮点击事件 -->
|
||
<span slot="footer">
|
||
{{-- <el-button size="mini" @click="centerDialogVisable = false">Cancel</el-button>--}}
|
||
<el-button size="mini" @click="addSinger('registerForm')">Submit</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<div class="product-description {{ $iframeClass }}">
|
||
<div class="nav nav-tabs nav-overflow justify-content-start justify-content-md-center border-bottom mb-3">
|
||
<a class="nav-link fw-bold active fs-5" data-bs-toggle="tab" href="#product-description">
|
||
{{ __('shop/products.product_details') }}
|
||
</a>
|
||
@if ($product['attributes'])
|
||
<a class="nav-link fw-bold fs-5" data-bs-toggle="tab" href="#product-attributes">
|
||
{{ __('admin/attribute.index') }}
|
||
</a>
|
||
@endif
|
||
@hook('product.tab.after.link')
|
||
</div>
|
||
<div class="tab-content">
|
||
<div class="tab-pane fade show active" id="product-description" role="tabpanel">
|
||
{!! $product['description'] !!}
|
||
</div>
|
||
<div class="tab-pane fade" id="product-attributes" role="tabpanel">
|
||
<table class="table table-bordered attribute-table">
|
||
@foreach ($product['attributes'] as $group)
|
||
<thead class="table-light">
|
||
<tr>
|
||
<td colspan="2"><strong>{{ $group['attribute_group_name'] }}</strong></td>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach ($group['attributes'] as $item)
|
||
<tr>
|
||
<td>{{ $item['attribute'] }}</td>
|
||
<td>{{ $item['attribute_value'] }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
@endforeach
|
||
</table>
|
||
</div>
|
||
@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'))
|
||
<div class="relations-wrap mt-5">
|
||
<div class="container position-relative">
|
||
<div class="title text-center fs-1 mb-4">{{ __('admin/product.product_relations') }}</div>
|
||
<div class="product swiper-style-plus">
|
||
<div class="swiper relations-swiper">
|
||
<div class="swiper-wrapper">
|
||
@foreach ($relations as $item)
|
||
<div class="swiper-slide">
|
||
@include('shared.product', ['product' => $item])
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
<div class="swiper-pagination relations-pagination"></div>
|
||
<div class="swiper-button-prev relations-swiper-prev"></div>
|
||
<div class="swiper-button-next relations-swiper-next"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@hook('product.detail.footer')
|
||
@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,
|
||
order_tota: 0,
|
||
isNumSelect: false,
|
||
selectedVariantsIndex: [], // 选中的变量索引
|
||
images: [],
|
||
product: {
|
||
id: 0,
|
||
images: "",
|
||
model: "",
|
||
origin_price: 0,
|
||
origin_price_format: "",
|
||
position: 0,
|
||
price: 0,
|
||
price_format: "",
|
||
quantity: 0,
|
||
sku: "",
|
||
},
|
||
quantity: 0,
|
||
source: {
|
||
skus: @json($product['skus']),
|
||
variables: @json($product['variables'] ?? []),
|
||
},
|
||
product_id: "{{$product_id}}",
|
||
price_setting: @json($product['price_setting'] ?? 'sku'),
|
||
numPrices: @json($product['numPrices'] ?? []),
|
||
minimum_order: @json($product['minimum_order'] ?? 0),
|
||
sales_method: @json($product['sales_method'] ?? 'piece'),
|
||
piece_to_batch: @json($product['piece_to_batch'] ?? 0),
|
||
centerDialogVisable: false, // 设置显示框的状态
|
||
registerForm: { // 添加的信息
|
||
contacts: '',
|
||
email: '',
|
||
content: '',
|
||
product_sku_id: '',
|
||
},
|
||
rules: {
|
||
contacts: [{
|
||
required: true,
|
||
message: '{{ __('shop/products.enter_contacts') }}',
|
||
trigger: 'blur'
|
||
},],
|
||
email: [{
|
||
required: true,
|
||
type: 'email',
|
||
message: '{{ __('shop/products.enter_email') }}',
|
||
trigger: 'blur'
|
||
},],
|
||
content: [{
|
||
required: true,
|
||
message: '{{ __('shop/products.enter_content') }}',
|
||
trigger: 'blur'
|
||
},],
|
||
},
|
||
// 多规格批量购买
|
||
goods_list: {},
|
||
add_buy_sku:{},
|
||
totals: {},// 支付金额统计
|
||
// 国家选择
|
||
country_list: {},
|
||
country_id: 0,
|
||
// 物流切换
|
||
logistics_country_id: 0,
|
||
change_logistics_id: 0,
|
||
},
|
||
watch: {
|
||
quantity: function (newval, oldval) {
|
||
let _this = this;
|
||
let list = {};
|
||
// 请求计算运费
|
||
list[0] = {
|
||
product_id: _this.product_id,
|
||
product_sku_id: this.product.id,
|
||
quantity: this.quantity,
|
||
};
|
||
_this.goods_list = list;
|
||
|
||
_this.computeOrderMoney();
|
||
_this.$refs['select-logistics'].getLogisticsList()
|
||
|
||
// let price = 0;
|
||
// if (this.numPrices.light == 0) {
|
||
// price = this.product.price
|
||
// } else {
|
||
// price = this.numPrices[0].price
|
||
// this.numPrices.forEach(v => {
|
||
// if (this.quantity > v.num) {
|
||
// }
|
||
// price = v.price
|
||
// })
|
||
// }
|
||
//
|
||
// this.product_total = (price * this.quantity).toFixed(2)
|
||
// this.shipping_fee = (this.product_total * 0.1).toFixed(2)
|
||
// this.order_tota = (this.product_total * 1 + this.shipping_fee * 1).toFixed(2)
|
||
},
|
||
add_buy_sku: {
|
||
deep: true,//true为进行深度监听,false为不进行深度监听
|
||
handler(){
|
||
let _this = this;
|
||
let list = {};
|
||
Object.values(this.add_buy_sku).forEach((item,index) =>{
|
||
list[index] = {
|
||
product_id: _this.product_id,
|
||
product_sku_id: item.id,
|
||
quantity: item.quantity,
|
||
};
|
||
})
|
||
_this.goods_list = list;
|
||
|
||
_this.computeOrderMoney();
|
||
_this.$refs['select-logistics'].getLogisticsList()
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
if (this.price_setting === 'num') {
|
||
// this.quantity = this.numPrices[0].num;
|
||
}
|
||
this.source.variables.forEach(variable => {
|
||
if (variable.isNumSelect == true) {
|
||
this.isNumSelect = true;
|
||
}
|
||
variable.values.forEach(value => {
|
||
value.quantity = 0
|
||
})
|
||
})
|
||
},
|
||
beforeMount() {
|
||
const skus = JSON.parse(JSON.stringify(this.source.skus));
|
||
const skuDefault = skus.find(e => e.is_default)
|
||
this.selectedVariantsIndex = skuDefault.variants
|
||
|
||
// 为 variables 里面每一个 values 的值添加 selected、disabled 字段
|
||
if (this.source.variables.length) {
|
||
this.source.variables.forEach(variable => {
|
||
variable.values.forEach(value => {
|
||
this.$set(value, 'selected', false)
|
||
this.$set(value, 'disabled', false)
|
||
})
|
||
})
|
||
|
||
this.checkedVariants()
|
||
this.getSelectedSku(false);
|
||
this.updateSelectedVariantsStatus()
|
||
} else {
|
||
// 如果没有默认的sku,则取第一个sku的第一个变量的第一个值
|
||
this.product = skus[0];
|
||
this.images = @json($product['images'] ?? []);
|
||
}
|
||
},
|
||
methods: {
|
||
quantityChange() {
|
||
setTimeout(() => {
|
||
|
||
let num = 0;
|
||
this.source.variables.forEach(variable => {
|
||
variable.values.forEach(value => {
|
||
num += parseInt(value.quantity);
|
||
})
|
||
})
|
||
this.quantity = num;
|
||
console.log(this.quantity, num)
|
||
}, 200);
|
||
},
|
||
addSinger(form) { // 点击确定按钮添加方法
|
||
|
||
this.$refs[form].validate((valid) => {
|
||
if (!valid) {
|
||
this.$message.error('{{ __('shop/checkout.check_form') }}');
|
||
return;
|
||
}
|
||
this.registerForm.product_sku_id = this.product.id
|
||
$http.post(`/inquiry`, this.registerForm).then((res) => {
|
||
layer.msg('Success')
|
||
this.registerForm = {
|
||
contacts: '',
|
||
email: '',
|
||
content: '',
|
||
product_sku_id: '',
|
||
}
|
||
})
|
||
|
||
this.centerDialogVisable = false
|
||
});
|
||
},
|
||
checkedVariableValue(variable_index, value_index, value) {
|
||
$('.product-image .swiper .swiper-slide').eq(0).addClass('active').siblings().removeClass('active');
|
||
this.source.variables[variable_index].values.forEach((v, i) => {
|
||
v.selected = i == value_index
|
||
})
|
||
|
||
this.updateSelectedVariantsIndex();
|
||
this.getSelectedSku();
|
||
this.updateSelectedVariantsStatus()
|
||
},
|
||
// 把对应 selectedVariantsIndex 下标选中 variables -> values 的 selected 字段为 true
|
||
checkedVariants() {
|
||
this.source.variables.forEach((variable, index) => {
|
||
variable.values[this.selectedVariantsIndex[index]].selected = true
|
||
})
|
||
},
|
||
getSelectedSku(reload = true) {
|
||
// 通过 selectedVariantsIndex 的值比对 skus 的 variables
|
||
const sku = this.source.skus.find(sku => sku.variants.toString() == this.selectedVariantsIndex.toString())
|
||
this.images =
|
||
@json($product['images'] ?? [])
|
||
|
||
if (reload) {
|
||
this.images.unshift(...sku.images)
|
||
}
|
||
|
||
this.product = sku;
|
||
|
||
if (swiperMobile) {
|
||
swiperMobile.slideTo(0, 0, false)
|
||
}
|
||
|
||
this.$nextTick(() => {
|
||
$('#zoom img').attr('src', $('#swiper a').attr('data-image'));
|
||
$('#zoom').trigger('zoom.destroy');
|
||
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
||
})
|
||
|
||
closeVideo()
|
||
},
|
||
updateSelectedVariantsIndex() {
|
||
// 获取选中的 variables 内 value的 下标 index 填充到 selectedVariantsIndex 中
|
||
this.source.variables.forEach((variable, index) => {
|
||
variable.values.forEach((value, value_index) => {
|
||
if (value.selected) {
|
||
this.selectedVariantsIndex[index] = value_index
|
||
}
|
||
})
|
||
})
|
||
},
|
||
updateSelectedVariantsStatus() {
|
||
// skus 里面 quantity 不为 0 的 sku.variants
|
||
const skus = this.source.skus.filter(sku => sku.quantity > 0).map(sku => sku.variants);
|
||
this.source.variables.forEach((variable, index) => {
|
||
variable.values.forEach((value, value_index) => {
|
||
const selectedVariantsIndex = this.selectedVariantsIndex.slice(0);
|
||
|
||
selectedVariantsIndex[index] = value_index;
|
||
const selectedSku = skus.find(sku => sku.toString() == selectedVariantsIndex.toString());
|
||
if (selectedSku) {
|
||
value.disabled = false;
|
||
} else {
|
||
value.disabled = true;
|
||
}
|
||
})
|
||
});
|
||
},
|
||
// 提交购物车
|
||
addCart(isBuyNow = false) {
|
||
let _this = this;
|
||
let params = {};
|
||
// 判断:当前商品如果是单规格则使用旧版本下单流程 为多规格则使用新版本下单流程
|
||
let minimum_order_error = '{{ __('product.minimum_order_error') }}';
|
||
let multiple_error = '{{ __('product.multiple_error') }}';
|
||
if(Object.keys(_this.source.skus).length > 1){
|
||
// 多规格
|
||
if (Object.keys(_this.add_buy_sku).length <= 0) {
|
||
layer.msg('{{ __('shop/products.buy_sku_error') }}');
|
||
return;
|
||
}
|
||
// 购买数量判断
|
||
let total = 0;
|
||
Object.values(_this.add_buy_sku).forEach((item,index) =>{
|
||
total += parseInt(item.quantity);
|
||
})
|
||
if(total <= 0){
|
||
layer.msg('{{ __('shop/products.quantity_error') }}');
|
||
return;
|
||
}
|
||
// 判断:当前商品购买数量是否大于等于最小起订量
|
||
let minimum_order = _this.sales_method === 'batches' ? _this.minimum_order * _this.piece_to_batch : _this.minimum_order;
|
||
if(minimum_order > total){
|
||
layer.msg(minimum_order_error.replace(':num',minimum_order));
|
||
return;
|
||
}
|
||
// 判断:当前销售方式是批量销售,购买数量必须是N的倍数
|
||
let multiple_num = _this.sales_method === 'batches' ? parseInt(_this.piece_to_batch) : 1;
|
||
if(parseInt(total % multiple_num) != 0){
|
||
layer.msg(multiple_error.replace(':num',multiple_num));
|
||
return;
|
||
}
|
||
// 请求参数
|
||
params = {
|
||
isBuyNow,
|
||
sku_id: JSON.stringify(_this.add_buy_sku) || {},
|
||
quantity: 1,
|
||
};
|
||
}else{
|
||
// 单规格
|
||
if (_this.quantity <= 0 || _this.quantity > _this.product.quantity) {
|
||
layer.msg('{{ __('shop/products.quantity_error') }}');
|
||
return;
|
||
}
|
||
// 判断:当前商品购买数量是否大于等于最小起订量
|
||
let minimum_order = _this.sales_method === 'batches' ? _this.minimum_order * _this.piece_to_batch : _this.minimum_order;
|
||
if(minimum_order > _this.quantity){
|
||
layer.msg(minimum_order_error.replace(':num',minimum_order));
|
||
return;
|
||
}
|
||
// 判断:当前销售方式是批量销售,购买数量必须是N的倍数
|
||
let multiple_num = _this.sales_method === 'batches' ? parseInt(_this.piece_to_batch) : 1;
|
||
if(parseInt(_this.quantity % multiple_num) != 0){
|
||
layer.msg(multiple_error.replace(':num',multiple_num));
|
||
return;
|
||
}
|
||
// 请求参数
|
||
params = {
|
||
sku_id: _this.product.id,
|
||
quantity: _this.quantity,
|
||
isBuyNow
|
||
};
|
||
}
|
||
// 公共参数加入
|
||
params.products_country_id = _this.country_id;
|
||
params.change_logistics_id = _this.change_logistics_id;
|
||
// 提交内容
|
||
bk.addCart(params, null, () => {
|
||
if (isIframe) {
|
||
let index = parent.layer.getFrameIndex(window.name); //当前iframe层的索引
|
||
parent.bk.getCarts();
|
||
|
||
setTimeout(() => {
|
||
parent.layer.close(index);
|
||
|
||
if (isBuyNow) {
|
||
parent.location.href = 'checkout'
|
||
} else {
|
||
parent.$('.btn-right-cart')[0].click()
|
||
}
|
||
}, 400);
|
||
} else {
|
||
if (isBuyNow) {
|
||
location.href = 'checkout'
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// 点击添加公共
|
||
clickAddBuySku(){
|
||
let _this = this;
|
||
let product = {
|
||
id: _this.product.id,
|
||
model: _this.product.model,
|
||
sku: _this.product.sku,
|
||
origin_price: _this.product.origin_price,
|
||
price: _this.product.price,
|
||
total_price: 0,
|
||
quantity: 0,// 当前购买数量
|
||
stock: _this.product.quantity,// 当前商品库存
|
||
sku_info: {},
|
||
};
|
||
// 获取规格信息
|
||
let variables = _this.source.variables;
|
||
let variants = _this.product.variants;
|
||
variants.forEach((index,key) => {
|
||
let variablesInfo = variables[key];
|
||
product.sku_info[key] = {
|
||
name: variablesInfo.name,
|
||
value: variablesInfo.values[index].name,
|
||
};
|
||
});
|
||
_this.add_buy_sku[product.id] = product;
|
||
|
||
_this.$forceUpdate();
|
||
},
|
||
// 多规格 - 某个规格的购买数量改变
|
||
skuQuantityChange(event,skuIndex){
|
||
let _this = this;
|
||
let stock = _this.add_buy_sku[skuIndex].stock || 0;
|
||
let quantity = event.target.value || 0;
|
||
// 判断是否超过库存
|
||
quantity = quantity > stock ? stock : quantity;// 不能超过库存
|
||
_this.add_buy_sku[skuIndex].quantity = typeof quantity != 'number' ? quantity.replace(/\D/g, '') : quantity;
|
||
// 处理深度监听失败的问题
|
||
_this.add_buy_sku = Object.assign({}, _this.add_buy_sku);
|
||
|
||
_this.$forceUpdate();
|
||
},
|
||
// 单规格 - 购买数量改变
|
||
singleQuantityChange(event){
|
||
let multiple_error = '{{ __('product.multiple_error') }}';
|
||
let _this = this;
|
||
let stock = _this.product.quantity || 0;// 库存
|
||
let quantity = event.target.value || 0;// 购买数量
|
||
// 判断是否超过库存
|
||
quantity = quantity > stock ? stock : quantity;// 不能超过库存
|
||
_this.quantity = typeof quantity != 'number' ? quantity.replace(/\D/g,'') : quantity;
|
||
// 判断:如果是批量购买 只能为N的倍数
|
||
let multiple_num = _this.sales_method === 'batches' ? parseInt(_this.piece_to_batch) : 1;
|
||
if(parseInt(quantity % multiple_num) != 0){
|
||
layer.msg(multiple_error.replace(':num',multiple_num));
|
||
return;
|
||
}
|
||
|
||
_this.$forceUpdate();
|
||
},
|
||
// 计算当前订单总额
|
||
computeOrderMoney(){
|
||
let _this = this;
|
||
$http.post(`products/computeOrderMoney`, {
|
||
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;
|
||
|
||
_this.$forceUpdate();
|
||
}
|
||
})
|
||
},
|
||
// 国家改变
|
||
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();
|
||
}
|
||
},
|
||
|
||
|
||
|
||
}
|
||
});
|
||
|
||
$(document).on("mouseover", ".product-image #swiper .swiper-slide a", function () {
|
||
$(this).parent().addClass('active').siblings().removeClass('active');
|
||
$('#zoom').trigger('zoom.destroy');
|
||
$('#zoom img').attr('src', $(this).attr('data-image'));
|
||
$('#zoom').zoom({url: $(this).attr('data-zoom-image')});
|
||
closeVideo()
|
||
});
|
||
|
||
var swiper = new Swiper("#swiper", {
|
||
direction: "vertical",
|
||
slidesPerView: 1,
|
||
spaceBetween: 3,
|
||
breakpoints: {
|
||
375: {
|
||
slidesPerView: 3,
|
||
spaceBetween: 3,
|
||
},
|
||
480: {
|
||
slidesPerView: 4,
|
||
spaceBetween: 27,
|
||
},
|
||
768: {
|
||
slidesPerView: 6,
|
||
spaceBetween: 3,
|
||
},
|
||
},
|
||
navigation: {
|
||
nextEl: '.new-feature-slideshow-next',
|
||
prevEl: '.new-feature-slideshow-prev',
|
||
},
|
||
observer: true,
|
||
observeParents: true
|
||
});
|
||
|
||
var relationsSwiper = new Swiper('.relations-swiper', {
|
||
watchSlidesProgress: true,
|
||
breakpoints: {
|
||
320: {
|
||
slidesPerView: 2,
|
||
spaceBetween: 10,
|
||
},
|
||
768: {
|
||
slidesPerView: 4,
|
||
spaceBetween: 30,
|
||
},
|
||
},
|
||
spaceBetween: 30,
|
||
// 如果需要前进后退按钮
|
||
navigation: {
|
||
nextEl: '.relations-swiper-next',
|
||
prevEl: '.relations-swiper-prev',
|
||
},
|
||
|
||
// 如果需要分页器
|
||
pagination: {
|
||
el: '.relations-pagination',
|
||
clickable: true,
|
||
},
|
||
})
|
||
|
||
@if (is_mobile())
|
||
swiperMobile = new Swiper("#swiper-mobile", {
|
||
slidesPerView: 1,
|
||
pagination: {
|
||
el: ".mobile-pagination",
|
||
},
|
||
observer: true,
|
||
observeParents: true
|
||
});
|
||
@endif
|
||
|
||
$(document).ready(function () {
|
||
$('#zoom').trigger('zoom.destroy');
|
||
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
||
|
||
$('#tradeTerm').popover({
|
||
trigger : 'hover',//鼠标以上时触发弹出提示框
|
||
html: true,//开启html 为true的话,data-content里就能放html代码了
|
||
placement: 'bottom',
|
||
delay: { "show": 0, "hide": 100 },
|
||
content:"<img class='trade-term-img' src='image/trade_term_web.png'>"
|
||
});
|
||
});
|
||
|
||
const selectedVariantsIndex = app.selectedVariantsIndex;
|
||
const variables = app.source.variables;
|
||
|
||
const selectedVariants = variables.map((variable, index) => {
|
||
return variable.values[selectedVariantsIndex[index]]
|
||
});
|
||
</script>
|
||
@endpush
|