437 lines
19 KiB
Vue
437 lines
19 KiB
Vue
<template>
|
|
<view class="waper">
|
|
<u-navbar :autoBack="true" :bgColor="scrollTop > 20 ? '#fff' : 'transparent'" :leftIconColor="scrollTop > 20 ? '#303133' : '#fff'">
|
|
<view slot='center' style="font-size: 36rpx; font-weight: bold;">{{scrollTop > 20 ? '文创详情' : ''}}</view>
|
|
</u-navbar>
|
|
<template v-if="detail">
|
|
<view class="swiper">
|
|
<swiper autoplay :interval="3000" :duration="1000" circular>
|
|
<swiper-item v-for="(img, index) in detail.images" :key="index">
|
|
<view class="swiper-item">
|
|
<image :src="$utils.setImgUrl(img)" mode=""></image>
|
|
</view>
|
|
</swiper-item>
|
|
</swiper>
|
|
</view>
|
|
<view class="waper_content" :style="'padding-bottom: ' + paddingBottom + 'px;'">
|
|
<view class="money">
|
|
<view>{{detail.price.toFixed(2)}}</view>
|
|
<view>库存{{detail.stock || 0}}</view>
|
|
</view>
|
|
<view class="titl">
|
|
<view>{{detail.title}}</view>
|
|
<view>已售{{(detail.showSales ? detail.showSales : 0) + detail.sales}}</view>
|
|
</view>
|
|
<view class="list_waper">
|
|
<view class="list" v-if="areaInfo">
|
|
<view class="left">配送</view>
|
|
<view class="right" style="padding: 0;">
|
|
<view class="text">{{areaInfo.provinceName + areaInfo.cityName + areaInfo.areaName}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="list" @click="showService = true;">
|
|
<view class="left">售后</view>
|
|
<view class="right">
|
|
<view class="text">
|
|
<text v-for="(item, index) in detail.serviceList.slice(0, 3)" :key="index">{{item.name}}</text>
|
|
</view>
|
|
<view class="icon">
|
|
<u-icon name="arrow-right" color="#333" size="30rpx"></u-icon>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="list">
|
|
<view class="left">运费</view>
|
|
<view class="right">
|
|
<view class="text">{{detail.dispatchName}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="store-box" v-if="detail.storeId">
|
|
<view class="store">
|
|
<image class="img" :src="$utils.setImgUrl(detail.storeImage)" mode="aspectFill"></image>
|
|
<view class="store-title" v-if="detail.storeName">{{detail.storeName}}</view>
|
|
</view>
|
|
<view class="btn" @click="goStore">进入店铺</view>
|
|
</view>
|
|
<view class="detail" v-if="detail.params.length">
|
|
<view class="detail_title">
|
|
<text>参数</text>
|
|
</view>
|
|
<view class="detail_cont">
|
|
<view class="goods-list-box" v-for="(item, index) in detail.params" :key="index">
|
|
<view class="goods-list-item">{{item.title}}</view>
|
|
<view class="goods-list-item">{{item.content}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="detail">
|
|
<view class="detail_title">
|
|
<text>商品介绍</text>
|
|
</view>
|
|
<view class="detail_cont">
|
|
<u-parse :content="detail.content"></u-parse>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="bottom" :style="'padding-bottom: ' + safeAreaBottom + 'px'">
|
|
<view class="bottom_waper">
|
|
<view @click="buyGoods('card')">加入购物车</view>
|
|
<view @click="buyGoods('order')">立即购买</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
<u-popup :show="showService" bgColor="transparent">
|
|
<view class="service_waper" v-if="detail">
|
|
<view class="list_waper">
|
|
<view class="list" v-for="(item, index) in detail.serviceList" :key="index">
|
|
<view>{{item.name}}</view>
|
|
<view>{{item.description}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="btn" @click="showService = false;">我知道了</view>
|
|
<view class="close" @click="showService = false;">
|
|
<u-icon name="close" color="#333" size="32rpx"></u-icon>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
<u-popup :show="showOrder" bgColor="transparent">
|
|
<view class="order_waper" v-if="orderInfo">
|
|
<view class="info">
|
|
<view class="img">
|
|
<image :src="$utils.setImgUrl(orderInfo.image)" mode=""></image>
|
|
</view>
|
|
<view class="text">{{orderInfo.buyMoney.toFixed(2)}}</view>
|
|
</view>
|
|
<view class="list_waper" v-if="orderInfo.isSku === 1">
|
|
<view class="list" v-for="(i, index) in orderInfo.skuList" :key="index">
|
|
<view class="title">{{i.name}}</view>
|
|
<view class="select">
|
|
<view v-for="(item, itemIndex) in i.children" :key="itemIndex" :class="{ active: item.active }" @click="selectSku(index, itemIndex)">{{item.name}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="number">
|
|
<view class="left">数量</view>
|
|
<view class="right">
|
|
<view class="right_info" v-if="orderInfo.buyMax > 0">
|
|
<u-number-box v-model="orderInfo.buyNum" :min="1" :max="orderInfo.buyMax"></u-number-box>
|
|
</view>
|
|
<view class="null" v-else>无货</view>
|
|
</view>
|
|
</view>
|
|
<view class="btn" @click="submitForm">确认</view>
|
|
<view class="close" @click="clearOrder">
|
|
<u-icon name="close" color="#333" size="32rpx"></u-icon>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data () {
|
|
return {
|
|
scrollTop: 0,
|
|
safeAreaBottom: 0,
|
|
paddingBottom: 0,
|
|
detail: null,
|
|
showService: false,
|
|
areaInfo: null,
|
|
showOrder: false,
|
|
orderInfo: null
|
|
}
|
|
},
|
|
onPageScroll (e) {
|
|
this.scrollTop = e.scrollTop;
|
|
},
|
|
async onLoad (options) {
|
|
this.safeAreaBottom = this.$safeAreaBottom;
|
|
this.paddingBottom = this.safeAreaBottom + uni.upx2px(152);
|
|
let info = await this.$shop.getGoodsDetail({ id: options.id });
|
|
info.data.images = info.data.images.split(',');
|
|
if (info.data.content) {
|
|
info.data.content = this.$utils.replaceImg(info.data.content);
|
|
}
|
|
info.data.params = JSON.parse(info.data.params);
|
|
this.detail = info.data;
|
|
|
|
let area = await this.$shop.getUserInfoAddressDefault();
|
|
if (area.data) this.areaInfo = area.data;
|
|
},
|
|
methods: {
|
|
async submitForm () {
|
|
if (this.orderInfo.isSku === 1) {
|
|
let num = 0;
|
|
this.orderInfo.skuList.forEach((item) => {
|
|
item.children.forEach((info) => {
|
|
if (info.active) num ++
|
|
})
|
|
})
|
|
if (num < this.orderInfo.skuList.length) {
|
|
uni.showToast({ mask: true, title: '请选择规格', icon: 'none' })
|
|
return false;
|
|
}
|
|
}
|
|
if (this.orderInfo.buyMax > 0) {
|
|
const type = this.orderInfo.type;
|
|
let info = null;
|
|
let skuPriceId = this.orderInfo.skuPriceId || this.orderInfo.zdyWcscGoodsSkuPrice.id;
|
|
if (type == 'card') {
|
|
info = await this.$shop.addshoppingcart({ goodsId: this.orderInfo.id, goodsNum: this.orderInfo.buyNum, skuPriceId: skuPriceId })
|
|
uni.showToast({ mask: true, title: '操作成功', icon: 'success' });
|
|
}
|
|
if (type == 'order') {
|
|
uni.navigateTo({ url: `/pages/shop/submit?id=${this.orderInfo.id}&skuId=${skuPriceId}&buyNum=${this.orderInfo.buyNum}&addressId=${this.areaInfo ? this.areaInfo.id : ''}` })
|
|
}
|
|
}
|
|
this.clearOrder();
|
|
},
|
|
buyGoods (type) {
|
|
let obj = Object.assign({}, this.detail);
|
|
obj.type = type;
|
|
obj.buyNum = 1;
|
|
obj.buyMoney = obj.price;
|
|
obj.buyMax = obj.stock;
|
|
if (obj.skuList) {
|
|
obj.skuList.forEach((i, index) => {
|
|
i.children.forEach((item, itemIndex) => {
|
|
obj.skuList[index].children[itemIndex].active = false;
|
|
})
|
|
})
|
|
}
|
|
this.orderInfo = obj;
|
|
this.showOrder = true;
|
|
},
|
|
clearOrder () {
|
|
this.showOrder = false;
|
|
this.orderInfo = null;
|
|
},
|
|
selectSku (parentIndex, childIndex) {
|
|
this.orderInfo.skuList[parentIndex].children.forEach((i, index) => {
|
|
this.orderInfo.skuList[parentIndex].children[index].active = false;
|
|
})
|
|
this.orderInfo.skuList[parentIndex].children[childIndex].active = true;
|
|
this.getActiveData();
|
|
this.$forceUpdate()
|
|
},
|
|
getActiveData () {
|
|
let arr = [];
|
|
this.orderInfo.skuList.forEach((i, index) => {
|
|
i.children.forEach((item, itemIndex) => {
|
|
if (item.active) arr.push(String(item.id))
|
|
})
|
|
})
|
|
if (arr.length != this.orderInfo.skuList.length) {
|
|
this.orderInfo.buyMax = this.orderInfo.stock;
|
|
this.orderInfo.buyMoney = this.orderInfo.price;
|
|
} else {
|
|
this.orderInfo.skuPriceList.forEach((item) => {
|
|
if (item.goodsSkuIds == arr.toString()) {
|
|
this.orderInfo.buyMax = item.stock;
|
|
this.orderInfo.buyMoney = item.price;
|
|
this.orderInfo.skuPriceId = item.id;
|
|
}
|
|
})
|
|
}
|
|
},
|
|
goStore() {
|
|
uni.navigateTo({
|
|
url: '/pages/shop/shopDetail?id=' + this.detail.storeId
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
|
|
.swiper{
|
|
width: 100%; height: 750rpx;
|
|
swiper, .swiper-item{ width: 100%; height: 100%; }
|
|
}
|
|
.waper_content{
|
|
width: 100%; box-sizing: border-box; padding: 48rpx 32rpx 0; background: #FBFBFB; border-radius: 50rpx 50rpx 0 0; position: relative; z-index: 3; margin-top: -80rpx;
|
|
.money{
|
|
width: 100%; height: 78rpx; display: flex; justify-content: space-between; align-items: flex-end;
|
|
view{
|
|
&:nth-child(1){
|
|
color: #FF3333; padding-left: 42rpx; position: relative; font-size: 64rpx; font-weight: bold;
|
|
&::after{ content: "¥"; font-size: 24rpx; position: absolute; left: 0; bottom: 14rpx; }
|
|
}
|
|
&:nth-child(2){ color: rgba(0,0,0,0.45); font-size: 28rpx; padding-bottom: 5rpx; }
|
|
}
|
|
}
|
|
.titl{
|
|
width: 100%; margin-top: 16rpx; box-sizing: border-box; padding-right: 100rpx; position: relative;
|
|
view{
|
|
&:nth-child(1){ color: rgba(0,0,0,0.85); font-size: 36rpx; font-weight: 500; line-height: 50rpx; }
|
|
&:nth-child(2){ color: rgba(0,0,0,0.45); font-size: 28rpx; position: absolute; line-height: 34rpx; right: 0; top: 8rpx; }
|
|
}
|
|
}
|
|
.list_waper{
|
|
width: 100%; margin-top: 32rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 4rpx 24rpx;
|
|
.list{
|
|
width: 100%; box-sizing: border-box; border-bottom: 2rpx solid #E8E8E8; padding: 18rpx 0; padding-left: 88rpx; position: relative;
|
|
&:last-child{ border-bottom: 0; }
|
|
.left{ color: rgba(0,0,0,0.85); font-size: 28rpx; line-height: 48rpx; position: absolute; left: 0; top: 50%; transform: translateY(-50%); }
|
|
.right{
|
|
width: 100%; height: 100%; display: flex; align-items: center; box-sizing: border-box; padding-right: 44rpx; position: relative;
|
|
.text{
|
|
width: 100%; color: rgba(0,0,0,0.45); font-size: 28rpx; display: flex; flex-wrap: wrap; line-height: 48rpx;
|
|
text{
|
|
margin-right: 24rpx; position: relative; line-height: 48rpx;
|
|
&:last-child{
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
}
|
|
.icon{ position: absolute; right: 0; top: 50%; transform: translateY(-50%); }
|
|
}
|
|
}
|
|
}
|
|
.store-box {
|
|
background: #FFFFFF;
|
|
border-radius: 10rpx;
|
|
margin-top: 20rpx;
|
|
padding: 24rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
.store {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-direction: row;
|
|
.img {
|
|
width: 116rpx;
|
|
height: 116rpx;
|
|
border-radius: 10rpx;
|
|
margin-right: 28rpx;
|
|
}
|
|
.store-title {
|
|
font-weight: 500;
|
|
font-size: 32rpx;
|
|
color: rgba(0,0,0,0.85);
|
|
width: 300rpx;
|
|
overflow:hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
-o-text-overflow:ellipsis;
|
|
}
|
|
}
|
|
.btn {
|
|
width: 168rpx;
|
|
height: 64rpx;
|
|
background: #03AE80;
|
|
border-radius: 100rpx;
|
|
text-align: center;
|
|
line-height: 64rpx;
|
|
font-size: 24rpx;
|
|
color: #FFFFFF;
|
|
}
|
|
}
|
|
.detail{
|
|
width: 100%; margin-top: 20rpx; box-sizing: border-box; padding: 24rpx; border-radius: 10rpx; background: #fff;
|
|
.detail_title{
|
|
position: relative; font-weight: 500; font-size: 32rpx; color: rgba(0,0,0,0.85);
|
|
text{ position: relative; z-index: 3; }
|
|
}
|
|
.detail_cont{
|
|
width: 100%; margin-top: 20rpx;
|
|
.goods-list-box {
|
|
display: flex; align-items: center;
|
|
border-left: 1rpx solid rgba(0, 0, 0, 0.1);
|
|
&:first-child {
|
|
border-top: 1rpx solid rgba(0, 0, 0, 0.1);
|
|
}
|
|
.goods-list-item {
|
|
font-size: 28rpx;
|
|
border: 1rpx solid rgba(0, 0, 0, 0.1);
|
|
border-top: none;
|
|
border-left: none;
|
|
line-height: 56rpx;
|
|
height: 56rpx;
|
|
padding: 0 12rpx;
|
|
box-sizing: border-box;
|
|
&:first-child { width: 40%; }
|
|
&:last-child { width: 60%; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.bottom{
|
|
box-shadow: 0 -2rpx 12rpx 0 rgba(0,0,0,0.05); width: 100%; background: #fff; position: fixed; left: 0; bottom: 0; z-index: 6;
|
|
.bottom_waper{
|
|
width: 100%; height: 120rpx; box-sizing: border-box; padding: 0 32rpx; display: flex; justify-content: flex-end; align-items: center;
|
|
view{
|
|
width: 230rpx; height: 80rpx; text-align: center; line-height: 80rpx; font-size: 30rpx; color: #03AE80; font-weight: 500; border-radius: 66rpx 0 0 66rpx; background: rgba(1, 190, 105, 0.2);
|
|
&:last-child{ background: #03AE80; border-radius: 0 66rpx 66rpx 0; color: #fff; }
|
|
}
|
|
}
|
|
}
|
|
.service_waper{
|
|
width: 100%; height: 882rpx; background: #fff; border-radius: 50rpx 50rpx 0 0; box-sizing: border-box; padding: 32rpx 24rpx 17rpx; position: relative;
|
|
.list_waper{
|
|
width: 100%; height: 700rpx; overflow-y: auto;
|
|
.list{
|
|
width: 100%; margin-bottom: 26rpx;
|
|
&:last-child{ margin-bottom: 0; }
|
|
view{
|
|
&:nth-child(1){ color: rgba(0,0,0,0.85); font-size: 36rpx; font-weight: 500; line-height: 42rpx; }
|
|
&:nth-child(2){ margin-top: 14rpx; line-height: 33rpx; color: rgba(0,0,0,0.45); font-size: 28rpx; }
|
|
}
|
|
}
|
|
}
|
|
.btn{ width: 686rpx; height: 80rpx; background: #03AE80; border-radius: 66rpx; text-align: center; line-height: 80rpx; color: #fff; font-size: 32rpx; font-weight: 500; position: absolute; bottom: 17rpx; left: 50%; transform: translateX(-50%); }
|
|
.close{ position: absolute; right: 32rpx; top: 38rpx; }
|
|
}
|
|
.order_waper{
|
|
width: 100%; min-height: 462rpx; background: #fff; border-radius: 50rpx 50rpx 0 0; box-sizing: border-box; padding: 32rpx 24rpx 17rpx; position: relative;
|
|
.close{ position: absolute; right: 32rpx; top: 38rpx; }
|
|
.info{
|
|
width: 100%; height: 188rpx; box-sizing: border-box; padding-left: 208rpx; position: relative;
|
|
.img{
|
|
width: 188rpx; height: 100%; position: absolute; left: 0; top: 0;
|
|
image{ border-radius: 10rpx; }
|
|
}
|
|
.text{
|
|
color: #FF3333; padding-left: 42rpx; position: relative; font-size: 64rpx; font-weight: bold; display: flex; align-items: flex-end; height: 100%;
|
|
&::after{ content: "¥"; font-size: 36rpx; font-weight: 500; color: #FF3333; position: absolute; left: 0; bottom: 4rpx; }
|
|
}
|
|
}
|
|
.list_waper{
|
|
width: 100%; margin-top: 40rpx;
|
|
.list{
|
|
width: 100%; margin-bottom: 40rpx;
|
|
&:last-child{ margin-bottom: 0; }
|
|
.title{ line-height: 46rpx; color: #000; font-size: 32rpx; font-weight: bold; }
|
|
.select{
|
|
width: 100%; font-size: 0;
|
|
view{
|
|
display: inline-block; vertical-align: top; height: 60rpx; margin-top: 24rpx; border-radius: 45rpx; line-height: 60rpx; margin-right: 32rpx; padding: 0 30rpx; background: #F4F4F4; color: #333; font-size: 24rpx;
|
|
&.active{ background: #03AE80; color: #fff; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.number{
|
|
width: 100%; margin-top: 32rpx; display: flex; justify-content: space-between; align-items: center;
|
|
.left{ line-height: 38rpx; color: #000; font-size: 32rpx; font-weight: 500; }
|
|
.right{
|
|
.null{ color: #666; font-size: 32rpx; }
|
|
.right_info{
|
|
border: 2rpx solid #E1E1E1; border-radius: 50rpx;
|
|
.u-number-box__input{ margin: 0; background: transparent !important; border: 2rpx solid #E1E1E1; border-top: none; border-bottom: none; }
|
|
.u-number-box__plus{ background: transparent !important; }
|
|
.u-icon__icon{ color: #03AE80 !important; font-weight: 400 !important; }
|
|
.u-number-box__minus{ background: transparent !important; }
|
|
.u-number-box__minus--disabled .u-icon__icon{ color: #c8c9cc !important; }
|
|
}
|
|
}
|
|
}
|
|
.btn{ width: 686rpx; height: 80rpx; background: #03AE80; border-radius: 66rpx; text-align: center; line-height: 80rpx; color: #fff; font-size: 32rpx; font-weight: 500; position: absolute; bottom: 17rpx; left: 50%; transform: translateX(-50%); }
|
|
}
|
|
</style> |