dingdong-mall/pages/product/product-detail.vue

305 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<page-meta :page-style="'overflow:'+(ifShowPageMeta?'hidden':'visible')"></page-meta>
<view>
<!-- 顶部操作条 -->
<cu-custom :bgColor="'bg-white'" :isBack="true" :isBackHome="true" :homePageUrl="'/pages/index/index'">
<!-- <block slot="backText">返回</block> -->
<!-- <block slot="backHomeText">首页</block> -->
<!-- <block slot="content">商品详情</block> -->
</cu-custom>
<!-- 导航栏 -->
<uni-transition class="fixed-top-bar" mode-class="fade" :show="showTopNav">
<view class="grid text-center col-3 solid-top solid-bottom bg-white">
<view class="padding" :class="curTopNav == 0 ? 'bg-blue' : ''" @click.stop="clickNav(0)">服务</view>
<view class="padding" :class="curTopNav == 1 ? 'bg-blue' : ''" @click.stop="clickNav(1)">评价</view>
<view class="padding" :class="curTopNav == 2 ? 'bg-blue' : ''" @click.stop="clickNav(2)">详情</view>
</view>
</uni-transition>
<!-- 轮播图视频 -->
<swiper class="screen-swiper" @change="changeSwiper">
<swiper-item v-for="(item,index) in swiperList" :key="item.id" @click="clickSwiper($event, item)">
<image :src="item.url" mode="aspectFill" v-if="item.type=='image'"></image>
<video v-if="item.type=='video'" id="productVideo" :src="item.url" :controls="true" :autoplay="false"
:show-center-play-btn="true" :show-fullscreen-btn="false"></video>
</swiper-item>
</swiper>
<!-- 价格及活动栏 -->
<view class="bg-gradual-color padding-sm margin-bottom-xs shadow-blur">
<view class="flex justify-between align-center">
<view>
<text class="text-sl text-price">{{curProductSpecs.salePrice}}</text>
<text class="text-del">
<text class="text-xxl">¥{{curProductSpecs.price}}</text>
</text>
</view>
<view>
<text class="text-df">已售:{{curProductSpecs.saledCount}}</text>
</view>
</view>
<view id="pageAnchor0" class="flex justify-between align-end">
<view class="text-df">
佣金:<text class="text-price margin-right-sm">{{curProductSpecs.commission}}</text>
<!-- <text class="cuIcon-share"></text> -->
</view>
<!-- <view class="text-df">
距结束:<uni-countdown style="float: right;" :day="1" :hour="1" :minute="12" :second="40" background-color="#fff" splitorColor="#fff"></uni-countdown>
</view> -->
<view class="flex justify-end text-df align-center">
<view>距结束:</view>
<uni-countdown style="float: right;" :day="1" :hour="1" :minute="12" :second="40"
background-color="#fff" splitorColor="#fff"></uni-countdown>
</view>
</view>
</view>
<!-- 产品概要 -->
<view class="bg-white padding-sm">
<view class="flex justify-between text-df align-center">
<view class="padding-right-sm text-left solid-right">
<view class="text-xl">
<view class='cu-tag round bg-orange light' v-if="productInfo.isGoldServ">
<text class="cuIcon-medal">金牌服务</text>
</view>
{{productInfo.name}}
</view>
<view class="text-sm text-gray margin-top-xs">{{productInfo.desc}}</view>
</view>
<view class="text-xl text-right padding-lr">
<!-- <view class="margin-tb-xs"><text class="cuIcon-share"></text></view> -->
<view v-if="productInfo.isGoldServ" class="margin-tb-xs text-orange"><text
class="cuIcon-friendfamous"></text></view>
</view>
</view>
</view>
<!-- 服务保障和规格 -->
<view class="margin-lr-sm padding margin-top-sm bg-white">
<view v-for="(item, index) in guaranteeList" :key="item.id">
<view class="cu-capsule margin-tb-xs">
<view class='cu-tag bg-main-color'>
<text :class="'cuIcon-' + item.icon"></text>
</view>
<view class="cu-tag line-main-color">
{{item.name}}
</view>
</view>
<text class="margin-lr-xs text-sm">{{item.desc}}</text>
</view>
<view class="solid-top text-lg padding-tb-sm">
<text class="text-black">选择品类</text>
</view>
<view class="flex flex-wrap" :class="isShowAllSpecs ? '' : 'certern-height'">
<view class="margin-tb-xs margin-right-xs" v-for="(item,index) in specsList" :key="item.id">
<view class='cu-tag round padding'
:class="curProductSpecs.id === item.id ? 'line-main-color' : 'line-default'"
@click="chooseSpecs(item)">{{item.name}}</view>
</view>
</view>
<view class="text-bold text-gray text-lg text-center bg-white padding-top-sm" @click="showAllSpecs()"><text
:class="'cuIcon-' + (isShowAllSpecs ? 'fold' : 'unfold')"></text></view>
</view>
<!-- 服务评价 -->
<view id="pageAnchor1" class="margin-lr-sm margin-top-sm bg-white">
<view class="flex justify-between align-end padding">
<view class="text-black text-lg">商品评价</view>
<view class="text-red text-sm">好评率95%<text class="text-bold text-gray cuIcon-right"></text></view>
</view>
<comments-card :reviewers="reviewers"></comments-card>
</view>
<!-- 店家链接 -->
<view class="margin-lr-sm margin-top-sm padding bg-white">
<view class="flex justify-between align-center">
<view class="flex justify-start align-center">
<view class="cu-avatar round" :style="'background-image:url(' + shopInfo.avatarUrl + ');'"></view>
<view class="content flex-sub margin-lr-sm">
<view class="text-black">{{shopInfo.name}}</view>
<uni-rate :size="15" :readonly="true" allow-half :value="shopInfo.totalScore" />
</view>
</view>
<view class="text-sm" @click="showShopDetail(shopInfo)">店铺查看<text class="text-bold text-gray cuIcon-right"></text></view>
</view>
</view>
<!-- 服务详情 -->
<view id="pageAnchor2" class="margin-lr-sm margin-top-sm bg-white margin-bottom-with-bar image">
<!-- <image :src="productDetailImgUrl" mode="widthFix"></image> -->
详情图片......
</view>
<!-- 底部操作条 -->
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar">
<button class="action" open-type="contact">
<view class="cuIcon-service text-green">
<view class="cu-tag badge" v-if="ifHasCsMsg"></view>
</view>
客服
</button>
<!-- <view class="action">
<view class=" cuIcon-shop"></view> 店铺
</view> -->
<view class="action" @click="showCart">
<view class="cuIcon-cart">
<view class="cu-tag badge" v-if="totalPickCount > 0">{{totalPickCount}}</view>
</view>
购物车
</view>
<view class="bg-main-color light submit" @click="toggleProductPickModal">加入购物车</view>
<view class="bg-main-color submit" @click="toggleProductPickModal($event, true)">立即订购</view>
</view>
<!-- 底部弹窗 -->
<uni-popup ref="productPickPopup" type="bottom" @change="changePopupState">
<view class="text-bold text-gray text-lg text-center left-top-sm-bar" @click="toggleProductPickModal"><text
class="cuIcon-close"></text></view>
<product-pick :specsList="specsList" :orderNow="orderNow"></product-pick>
</uni-popup>
</view>
</template>
<script>
import commentsCard from '@/components/goods-card/comments-card.vue';
import productPick from '@/pages/product/product-pick.vue';
export default {
components: {
commentsCard,
productPick
},
data() {
return {
swiperList: [],
curProductSpecs: {},
productInfo: {},
guaranteeList: [],
specsList: [],
isShowAllSpecs: false,
reviewers: [],
productDetailImgUrl: '',
productVideoPlaying: false,
showTopNav: false,
curTopNav: 0,
shopInfo: {},
ifShowPageMeta: false,
orderNow: false,
totalPickCount: 0,
ifHasCsMsg: true,
swiperPicUrls: []
}
},
onLoad() {
this.loadData();
this.bindEvent();
},
onUnload() {
this.offBindEvent();
},
onReady() {
this.productVideoContext = uni.createVideoContext('productVideo');
},
onPageScroll(e) {
this.showTopNav = e.scrollTop > 250 ? true : false
},
methods: {
async loadData() {
let productDetail = await this.$api.data('productDetail');
this.swiperList = productDetail.swiperList;
this.productInfo = productDetail.productInfo;
this.guaranteeList = productDetail.guaranteeList;
this.specsList = productDetail.specsList;
this.curProductSpecs = this.specsList[0];
this.reviewers = productDetail.reviewers;
this.productDetailImgUrl = productDetail.productDetailImgUrl;
this.shopInfo = productDetail.shopInfo;
for (let i = 0; i < this.swiperList.length; i++) {
if (this.swiperList[i].type === 'image') {
this.swiperPicUrls.push(this.swiperList[i].url);
}
}
},
bindEvent() {
uni.$on('product-detail_add2Cart', this.add2Cart);
},
offBindEvent() {
uni.$off('product-detail_add2Cart');
},
chooseSpecs(item) {
this.curProductSpecs = item;
},
showAllSpecs() {
this.isShowAllSpecs = !this.isShowAllSpecs;
},
clickSwiper(e, item) {
if (item.type === 'image') {
this.viewImage(item.url);
} else if (item.type === 'video') {
this.pauseVideo(e);
}
},
viewImage(url) {
uni.previewImage({
urls: this.swiperPicUrls,
current: url
});
},
pauseVideo(e) {
if (this.productVideoPlaying) {
this.productVideoContext.pause();
} else {
this.productVideoContext.play();
}
this.productVideoPlaying = !this.productVideoPlaying;
},
changeSwiper(e) {
// 只有第一个是视频,如果是切换到图片就停止播放
if (e.detail.current !== 0) {
this.productVideoContext.pause();
this.productVideoPlaying = false;
}
},
clickNav(index) {
// 修改聚焦时的样式
this.curTopNav = index;
// 跳转到指定目录
uni.pageScrollTo({
selector: '#pageAnchor' + index
})
},
toggleProductPickModal(e, orderNow) {
this.orderNow = orderNow ? true : false;
if (this.ifShowPageMeta) {
this.$refs.productPickPopup.close();
} else {
this.$refs.productPickPopup.open();
}
},
changePopupState(e) {
this.ifShowPageMeta = e.show;
},
add2Cart(totalPickCount) {
this.totalPickCount = totalPickCount;
this.toggleProductPickModal();
},
showShopDetail(shopInfo) {
uni.navigateTo({
url: '../product/shop-detail?shopInfo=' + encodeURIComponent(JSON.stringify(shopInfo))
});
},
showCart() {
let myCartInfo = {};
uni.navigateTo({
url: '/pages/my/my-cart?myCartInfo=' + encodeURIComponent(JSON.stringify(myCartInfo))
});
}
}
}
</script>
<style scoped>
.certern-height {
height: 300rpx;
overflow: hidden;
}
.left-top-sm-bar {
position: absolute;
right: 25rpx;
top: 25rpx;
z-index: 99;
}
</style>