web-africa-h5/pages/product/detail.vue

847 lines
21 KiB
Vue
Raw Normal View History

2025-03-21 14:49:01 +08:00
<template>
<view class="product-detail pr">
<view class="product-pic">
<swiper class="swiper" indicator-active-color="#ffffff" indicator-color="rgba(255,255,255,.3)"
indicator-dots autoplay :interval="2000" :duration="500">
<swiper-item v-if="detail.videoUrl && detail.cover">
<view v-if="!isVideoPlay" class="icon iconfont icon-bofang" @click="isVideoPlay = true"></view>
<image v-if="!isVideoPlay" :src="detail.cover" mode="" @click="isVideoPlay = true"></image>
<video v-if="isVideoPlay" :src="detail.videoUrl" :autoplay="isVideoPlay"
@click="isVideoPlay = false" class="video" :controls="false" :show-center-play-btn="false"
:show-play-btn="false" :enable-progress-gesture="false"></video>
</swiper-item>
<swiper-item v-if="detail.cover1">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
<swiper-item v-if="detail.cover2">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
<swiper-item v-if="detail.cover3">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
<swiper-item v-if="detail.cover4">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
<swiper-item v-if="detail.cover5">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
<swiper-item v-if="detail.cover6">
<image :src="detail.cover1" mode="aspectFit"></image>
</swiper-item>
</swiper>
</view>
<view class="product-content">
<view class="white d-b-c preview-box pr" v-if="detail.preSaleStatus == 1">
<image class="preview-bg" src="/static/bg/preview-bg.png" mode=""></image>
<view class="pr z1">
<view class="f28">
{{ currencyIcon() }}
<text class="f42 fb">{{ formatNum(priceTotal) }}</text>
</view>
<view class="f24">
<text>{{ formatNum(achieveTotal) || "" }}</text>
</view>
</view>
<view class="pr z1">
<view class="d-e-c f24 mb16">
<u-icon name="clock" size="30rpx" color="#fff"></u-icon>
<text class="ml10">{{ $t("w_0116") }}</text>
</view>
<view class="f20 d-e-c">
{{ $t("CK_KS_11") }}
<Countdown ref="countdown" :color="'#999999'" :timeSize="'22rpx'" :config="countdownConfig"
@returnVal="returnValFunc"></Countdown>
</view>
</view>
</view>
<view class="product-info">
<view class="d-s-c mb10" v-if="detail.preSaleStatus == 0 || cid == 21">
<view class="f28 price-color">
<view v-if="
(cid == 101 || cid == 102 || cid == 201 || cid == 202) &&
userinfo.pkSettleCountry != pkCountry
">
{{ borderunits1
}}<text class="f42 fb">{{ formatNum(priceTotal1) }}</text>({{ currencyIcon() }}
<text class="f42 fb">{{
formatNum(priceTotal || detail.waresPrice)
}}</text>)
</view>
<view v-else>
{{ currencyIcon() }}
<text class="f42 fb">{{
formatNum(priceTotal || detail.waresPrice)
}}</text>
</view>
</view>
<view class="f24 gray9 ml20" v-if="cid != 10 && cid != 13&& cid!=30">{{
formatNum(achieveTotal) || ""
}}</view>
<view class="f24 gray9 ml20" v-if="cid == 10">{{ $t("w_0118") }}{{ formatNum(detail.deductMoney) }}
</view>
<view class="f24 gray9 ml20" v-if="cid == 13">BV:{{ formatNum(achieveTotal) || "" }}</view>
</view>
<view class="f24 gray9 mb20">{{ $t("w_0252") }}
{{ detail.sales * 1 > 999 ? "999+" : detail.sales }}
</view>
<view class="text-ellipsis-2 mb23">
<!-- <text class="type-tips">爆款</text> -->
<text class="f32 gray3">{{ detail.waresName }}</text>
</view>
<view class="f28 mb23" v-if="detail.giftNames">
<text class="domation">{{ $t("ENU_SALE_T_0") }}</text>
<text class="gray9">{{ detail.giftNames }}</text>
</view>
<view class="sellingPoints" v-if="detail.sellingPoints">{{
detail.sellingPoints
}}</view>
</view>
<view class="secend-info">
<view class="d-b-c sec-info-item" @click="openSpec">
<view class="sec-info-label">{{ $t("w_0107") }}</view>
<view class="flex-1">{{ alreadyChioce }}</view>
<view class="icon iconfont icon-jiantou"></view>
</view>
<!-- <view class="d-b-c sec-info-item">
<view class="sec-info-label">地址</view>
<view class="flex-1">形成自行车</view>
<view class="icon iconfont icon-jiantou"></view>
</view> -->
<!-- <view class="d-b-c sec-info-item">
<view class="sec-info-label">活动</view>
<view class="flex-1">新人福利</view>
<view class="icon iconfont icon-jiantou"></view>
</view> -->
<!-- <view class="d-b-c sec-info-item">
<view class="sec-info-label">邮费</view>
<view class="flex-1">免邮</view>
</view> -->
<view class="d-b-c sec-info-item">
<view class="sec-info-label">{{ $t("w_0122") }}</view>
<view class="flex-1"></view>
</view>
</view>
<view class="thi-info">
<view class="thi-nav">
<view class="thi-nav-item" :class="{ active: thiType == 0 }" @click="thiType = 0">{{ $t("w_0124") }}
</view>
<!-- <view class="thi-nav-item" :class="{active:thiType == 1}">规格与包装</view> -->
<view class="thi-nav-item" :class="{ active: thiType == 2 }" @click="thiType = 2">{{ $t("w_0125") }}
</view>
</view>
<view v-if="thiType == 0"><u-parse :content="detail.details"></u-parse></view>
<!-- <view v-if="thiType == 1"><u-parse :content="detail.details"></u-parse></view> -->
<view v-if="thiType == 2"><u-parse :content="detail.afterGuarantee"></u-parse></view>
</view>
</view>
<view class="btns-wrap">
<view class="d-a-c flex-1">
<view class="icon-box d-c-c" @click="gotoPage('/pages/index/index')">
<button class="d-c-c d-c bg-white">
<image style="width: 33rpx; height: 33rpx; margin-bottom: 10rpx"
src="/static/icon/product/home.png" mode=""></image>
<text class="f20"
style="height: 20rpx; line-height: 20rpx; color: #fb3024">{{ $t("ENU_MENU_10") }}</text>
</button>
</view>
<!-- <view class="icon-box d-c-c">
<button
class="d-c-c d-c bg-white"
@click="
gotoWeb(
'https://im1c5366d.7x24cc.com/phone_webChat.html?accountId=N000000033467&chatId=302384fb-eda1-436e-a5e9-c03a2dbd6e97&visitorId=' +
getUserId() +
'&nickName=' +
getUserId()
)
"
>
<image style="width: 33rpx;height: 33rpx;margin-bottom: 10rpx;" src="/static/icon/product/service.png" mode=""></image>
<text class="f20 gray3" style="height: 20rpx;line-height: 20rpx;">{{ $t('w_0259') }}</text>
</button>
</view> -->
<view class="icon-box d-c-c" @click="gotoPage('/pages/cart/cart')">
<button class="pr d-c-c d-c bg-white">
<image style="width: 33rpx; height: 33rpx; margin-bottom: 10rpx"
src="/static/icon/product/cart.png" mode=""></image>
<text class="f20 gray3" style="height: 20rpx; line-height: 20rpx">{{
$t("N_I_194")
}}</text>
<text v-if="sCount > 0" class="cart_num">{{ sCount }}</text>
</button>
</view>
</view>
<!-- <template>
<button type="primary" class="add-cart">加入购物车</button>
<button type="primary" class="buy">立即购买</button>
</template> -->
<template>
<button type="primary" class="buy one" @click="openSpec">
{{ $t("N_I_192") }}
</button>
<!-- <button type="primary" class="buy one" @click="isTablePopup = true">加入购物车</button> -->
</template>
</view>
<!--购物确定-->
<specTable v-if="cid != 21" :isPopup="isTablePopup" :productModel="productModel" @close="closePopup"
@addCart="addCart" :pkCountry="pkCountry" :cid="cid"></specTable>
<!--海粉购物确定-->
<spec v-if="cid == 21" :active_id="active_id" :isPopup="isTablePopup" :productModel="productModel"
@close="closePopup" @addCart="addHfen" @changeFunc="changeFunc"></spec>
</view>
</template>
<script>
import specTable from "./popup/spec-table.vue";
import spec from "./popup/spec.vue";
import Countdown from "@/components/countdown/countdown-presale.vue";
export default {
components: {
specTable,
Countdown,
spec,
},
data() {
return {
cid: 0,
waresCode: "",
title: "",
productModel: null,
isPopup: false,
isTablePopup: false,
isPreview: false,
isVideoPlay: false,
detail: {},
thiType: 0,
alreadyChioce: "",
isFirst: true,
userinfo: {},
productParams: [],
/*倒计时配置*/
countdownConfig: {
/*开始时间*/
startstamp: 1683194245,
/*结束时间*/
endstamp: 1683367044,
},
sCount: 0,
active_id: "",
pkCountry: 1,
borderunits1: "",
};
},
onLoad(e) {
this.cid = e.cid;
this.pkCountry = e.pkCountry || 0;
this.waresCode = e.waresCode;
this.pkId = e.pkId;
let title = this.$t("ENU_TRADE_T_121");
switch (this.cid) {
case 0:
title = this.$t("ENU_TRADE_T_121");
break;
case 1:
title = this.$t("ENU_MENU_311");
break;
case 2:
title = this.$t("ENU_MENU_321");
break;
case 3:
title = this.$t("ENU_TRADE_T_121");
break;
case 7:
title = this.$t("N_I_2");
break;
case 10:
title = this.$t("ENU_MENU_360");
break;
case 11:
title = this.$t("ENU_MENU_350");
break;
case 12:
title = this.$t("ENU_MENU_333");
break;
case 13:
title = this.$t("ENU_MENU_340");
break;
case 14:
title = this.$t("ENU_MENU_334");
break;
case 18:
title = this.$t("ENU_SPECIAL_A_18");
break;
case 19:
title = this.$t("ENU_SPECIAL_A_19");
break;
case 21:
title = this.$t("N_I_4");
break;
case 22:
title = this.$t("ENU_SPECIAL_A_22");
break;
case 23:
title = this.$t("ENU_SPECIAL_A_8");
break;
case 24:
// title = '乐学易考';
title = this.$t("ENU_MENU_312");
break;
case 25:
// title = '乐学易考';
title = this.$t("ENU_MENU_322");
break;
case 26:
// title = '乐学易考';
title = this.$t("ENU_MENU_335");
break;
case 27:
// title = '海粉升级';
title = this.$t("ENU_ORDER_T_27");
break;
case 101:
title = this.$t("fn_004");
break;
case 102:
title = this.$t("ENU_MENU_316");
break;
case 201:
title = this.$t("fn_007");
break;
case 202:
title = this.$t("fn_008");
break;
case 30:
title = this.$t("fn_009");
break;
case 33:
title = this.$t("APP_ADD_27");
break;
}
this.title = title;
this.getData();
},
onShow() {
this.getShoppingCount();
this.getInfo();
this.borderunits1 = uni.getStorageSync("borderUnit");
},
computed: {
achieveTotal: function() {
let self = this;
let price = 0;
if (this.cid == 21 && self.detail && self.detail.waresSkuList) {
self.detail.waresSkuList.forEach((item) => {
if (item.pkId == self.active_id) {
price = item.achieve;
}
});
return price;
}
if (self.productParams) {
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
if (self.cid == 13) {
price += pitem.number * pitem.assAchieve;
} else {
price += pitem.number * pitem.achieveTotal;
}
});
});
}
return price;
},
priceTotal: function() {
let self = this;
let price = 0;
if (this.cid == 21 && self.detail.waresSkuList) {
self.detail.waresSkuList.forEach((item) => {
if (item.pkId == self.active_id) {
price = item.price;
}
});
return price;
}
if (self.productParams) {
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
price += pitem.number * pitem.price;
});
});
}
return price;
},
priceTotal1: function() {
let self = this;
let price1 = 0;
if (self.productParams) {
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
price1 += pitem.number * pitem.borderPrice;
});
});
}
return price1;
},
},
methods: {
getInfo() {
let self = this;
self._get("member/api/member/get-info", {}, (res) => {
self.userinfo = res.data;
});
},
getShoppingCount() {
let self = this;
self._get(
"sale/api/shopping/getShoppingCount", {
specialArea: self.cid,
},
(res) => {
self.sCount = res.data.smallCount;
}
);
},
gotoWeb(url) {
this.gotoPage("/pages/webview/webview?url=" + encodeURIComponent(url));
},
addHfen(e) {
let self = this;
this.isTablePopup = false;
self._post(
"sale/api/shopping/addShopping", {
number: 1,
pkId: self.pkId,
productGroup: [{
pkProduct: self.pkId,
pkSkuId: self.active_id,
}, ],
specialArea: self.cid,
source: 2,
},
(res) => {
uni.showToast({
title: res.msg,
icon: "none",
});
self.getShoppingCount();
}
);
},
addCart(e) {
let self = this;
this.isTablePopup = false;
if (e) {
this.productParams = e;
this.getalreadyChioce();
}
let productGroup = [];
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
if (pitem.number > 0) {
productGroup.push({
pkProduct: pitem.pkProduct,
pkSkuId: pitem.pkSkuId,
quantity: pitem.number,
});
}
});
});
self._post(
"sale/api/shopping/addShopping", {
number: 1,
productGroup: productGroup,
specialArea: self.cid,
pkCountry: self.pkCountry,
waresCode: self.waresCode,
},
(res) => {
uni.showToast({
title: res.msg,
icon: "none",
});
self.getShoppingCount();
}
);
},
getData() {
let self = this;
let url = "sale/api/wares/query-spe-wares-detail";
let params = {
specialArea: self.cid || 0,
waresCode: self.waresCode || "",
pkCountry: self.pkCountry || 1,
};
if (!self.waresCode) {
url = "sale/api/wares/query-spe-sharing-wares-detail";
params = {
pkId: self.pkId || 0,
// source: 2
};
self._get(url, params, (res) => {
self.detail = res.data;
if (self.isFirst) {
if (self.cid == 21) {
self.productParams = self.detail.waresSkuList;
self.active_id = self.productParams[0] ?
self.productParams[0].pkId :
0;
} else {
self.productParams = [...self.detail.productParams];
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
if (pindex == 0) {
pitem.number = item.quantity;
} else {
pitem.number = 0;
}
});
});
self.getalreadyChioce();
}
self.isFirst = false;
}
});
} else {
self._post(url, params, (res) => {
self.detail = res.data;
if (self.isFirst) {
self.productParams = [...self.detail.productParams];
self.productParams.forEach((item, index) => {
item.waresItemsParamsList.forEach((pitem, pindex) => {
if (pindex == 0) {
pitem.number = item.quantity;
} else {
pitem.number = 0;
}
});
});
self.getalreadyChioce();
self.isFirst = false;
}
});
}
},
changeFunc(e) {
this.active_id = e;
},
openSpec() {
let obj = {
specData: this.productParams,
detail: this.detail,
};
this.productModel = obj;
this.isTablePopup = true;
},
getalreadyChioce() {
let self = this;
self.alreadyChioce = "";
let has = self.$t("w_0112");
let noone = "";
console.log("--", self.productParams);
self.productParams.forEach((item) => {
if (item.waresItemsParamsList) {
let h = "";
for (let i = 0; i < item.waresItemsParamsList.length; i++) {
let child = item.waresItemsParamsList[i];
if (child.number > 0) {
h += child.specsName + "*" + child.number + " / ";
} else {
h += "";
}
}
if (h != "") {
has += h;
} else {
noone += item.productName;
}
}
if (self.cid == 21) {
self.detail.waresSkuList.forEach(
(item,
(index) => {
if (item.pkId == self.active_id) {
has = item.specValueNames;
}
})
);
}
});
if (noone != "") {
self.alreadyChioce = noone;
} else {
has = has.replace(/(\s\/\s)$/gi, "");
self.alreadyChioce = has;
}
},
/*关闭弹窗*/
closePopup(e) {
this.isTablePopup = false;
if (e) {
this.productParams = e;
this.getalreadyChioce();
}
},
/*倒计时返回值*/
returnValFunc(e) {},
},
};
</script>
<style lang="scss">
.product-detail {
padding-bottom: 150rpx;
}
.product-detail .product-pic,
.product-detail .product-pic .swiper,
.product-detail .product-pic image {
width: 750rpx;
height: 750rpx;
}
.product-detail .product-pic .swiper .icon-bofang {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
font-size: 48rpx;
color: #ffffff;
border-radius: 50%;
border: 4rpx solid #ffffff;
width: 120rpx;
height: 120rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #00000080;
padding-left: 16rpx;
box-sizing: border-box;
z-index: 10;
}
.video {
width: 100%;
height: 100%;
}
.product-content {
padding: 22rpx 23rpx;
}
.preview-box {
width: 100%;
height: 134rpx;
padding: 0 20rpx;
box-sizing: border-box;
margin-bottom: -10rpx;
.preview-bg {
width: 704rpx;
height: 134rpx;
position: absolute;
left: 0;
top: 0;
z-index: 0;
}
}
.product-info {
width: 704rpx;
background: #ffffff;
border-radius: 15rpx;
position: relative;
z-index: 2;
padding: 42rpx 20rpx 30rpx 20rpx;
box-sizing: border-box;
margin-bottom: 22rpx;
}
.type-tips {
font-size: 22rpx;
padding: 0 17rpx;
line-height: 37rpx;
background-color: #fb3024;
border-radius: 19rpx;
color: #ffffff;
margin-right: 8rpx;
}
.sellingPoints {
background-color: #f5f5f5;
border-radius: 10rpx;
padding: 13rpx 38rpx;
font-size: 22rpx;
color: #666;
word-break: break-all;
}
.secend-info {
width: 704rpx;
padding: 0 15rpx 0 19rpx;
background: #ffffff;
border-radius: 15rpx;
box-sizing: border-box;
margin-bottom: 25rpx;
.sec-info-item {
padding: 20rpx 0;
box-sizing: border-box;
min-height: 90rpx;
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
.sec-info-label {
max-width: 125rpx;
min-width: 105rpx;
flex-shrink: 0;
word-break: break-all;
color: #999999;
margin-right: 20rpx;
}
}
.sec-info-item:last-child {
border: none;
}
}
.thi-info {
width: 702rpx;
background: #ffffff;
border-radius: 20rpx;
padding: 0 15rpx 15rpx 15rpx;
box-sizing: border-box;
}
.thi-nav {
display: flex;
justify-content: flex-start;
align-items: center;
overflow-x: auto;
width: 100%;
padding-left: 20rpx;
box-sizing: border-box;
border-bottom: 1rpx solid #eee;
margin-bottom: 22rpx;
.thi-nav-item {
font-size: 30rpx;
color: #333;
padding: 0 30rpx;
height: 92rpx;
line-height: 92rpx;
white-space: nowrap;
flex-shrink: 0;
position: relative;
}
.thi-nav-item.active::after {
position: absolute;
content: "";
left: 0;
right: 0;
margin: auto;
bottom: 0;
width: 30%;
height: 6rpx;
border-radius: 4rpx;
z-index: 1;
background-color: #fb3024;
}
}
.btns-wrap {
position: fixed;
height: 100rpx;
right: 0;
bottom: 0;
left: 0;
display: flex;
background: #ffffff;
align-items: center;
z-index: 97;
border-top: 1rpx solid #eee;
}
.btns-wrap .icon-box {
width: 92rpx;
height: 100rpx;
}
.btns-wrap .icon-box .iconfont {
font-size: 40rpx;
color: #888888;
}
.btns-wrap .icon-box .iconfont .num {
position: absolute;
top: 10rpx;
left: 50%;
height: 30rpx;
min-width: 30rpx;
overflow: hidden;
line-height: 32rpx;
border-radius: 15rpx;
font-size: 20rpx;
color: #ffffff;
background: red;
}
.btns-wrap button,
.btns-wrap button:after {
height: 100rpx;
line-height: 100rpx;
margin: 0;
padding: 0;
border-radius: 0;
border: 0;
}
.btns-wrap button.add-cart {
background: $dominant-color;
font-size: 28rpx;
width: 214rpx;
height: 75rpx;
line-height: 75rpx;
margin-left: 17rpx;
border-radius: 40rpx 0 0 40rpx;
}
.btns-wrap button.buy {
background: #fb3024;
font-size: 28rpx;
width: 214rpx;
height: 75rpx;
line-height: 75rpx;
border-radius: 0 40rpx 40rpx 0;
margin-right: 25rpx;
}
.btns-wrap button.buy.one {
border-radius: 40rpx;
width: 428rpx;
margin-left: 30rpx;
}
.share-icon {}
.cart_num {
position: absolute;
background: #f6220c;
width: 30rpx;
height: 30rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 22rpx;
border-radius: 50%;
color: #ffff;
right: 4rpx;
top: 4rpx;
}
</style>