242 lines
7.4 KiB
Vue
242 lines
7.4 KiB
Vue
|
<template>
|
|||
|
<view v-else class="goods-detail">
|
|||
|
<!-- 轮播图 -->
|
|||
|
<goods-swiper :images="goodsInfo.goods_image" :video="goodsInfo.video" :video-cover="goodsInfo.video_cover" />
|
|||
|
|
|||
|
<!-- 商品基础信息 -->
|
|||
|
<view class="goods-info">
|
|||
|
<view class="flex row-between">
|
|||
|
<view class="flex primary">
|
|||
|
<view style="font-size: 36rpx;">¥{{goodsInfo.min_price}}</view>
|
|||
|
<text v-if="goodsInfo.spec_type == 2">~</text>
|
|||
|
<view style="font-size: 36rpx;" v-if="goodsInfo.spec_type == 2">{{goodsInfo.max_price}}</view>
|
|||
|
|
|||
|
<view class="btn" v-if="goodsInfo.type">虚拟商品</view>
|
|||
|
</view>
|
|||
|
<view class="muted xs">商品编号:{{goodsInfo.code}}</view>
|
|||
|
</view>
|
|||
|
<view class="goods-name lg">{{ goodsInfo.name }}</view>
|
|||
|
<view class="flex row-between muted xs">
|
|||
|
<view>市场价: {{ goodsInfo.market_price }}</view>
|
|||
|
<view>库存: {{ goodsInfo.stock }}</view>
|
|||
|
<view>销量: {{ goodsInfo.sales_actual }}</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
|
|||
|
<!-- S 规格 -->
|
|||
|
<view class="nr specification" @click="onGoodsOptions">
|
|||
|
<text class="muted">查看商品规格</text>
|
|||
|
<text class="m-l-20">{{ specValueStr }}</text>
|
|||
|
<u-icon name="arrow-right" class="muted" style="margin-left: auto;" />
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 规格选择Popup -->
|
|||
|
<goods-spec :show="showGoodsSpec" :goods="goodsInfo" @close="showGoodsSpec = false"></goods-spec>
|
|||
|
|
|||
|
<!-- E 规格 -->
|
|||
|
|
|||
|
|
|||
|
<!-- 商品介绍 -->
|
|||
|
<view class="detail">
|
|||
|
<view class="detail-title nr">商品详情</view>
|
|||
|
<u-parse :html="goodsInfo.content" :show-with-animation="true"></u-parse>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
import {
|
|||
|
apiGoodsDetail
|
|||
|
} from '@/api/goods'
|
|||
|
import {
|
|||
|
baseURL,
|
|||
|
basePath
|
|||
|
} from '@/config/app'
|
|||
|
import {
|
|||
|
PageStatusEnum,
|
|||
|
OrderTypeEnum
|
|||
|
} from '@/utils/enum'
|
|||
|
import {
|
|||
|
mapGetters
|
|||
|
} from 'vuex'
|
|||
|
import {
|
|||
|
strToParams
|
|||
|
} from '@/utils/tools'
|
|||
|
|
|||
|
export default {
|
|||
|
name: 'GoodsDetail',
|
|||
|
|
|||
|
data() {
|
|||
|
return {
|
|||
|
// 页面状态
|
|||
|
pageStatus: PageStatusEnum['LOADING'],
|
|||
|
pagesData: [],
|
|||
|
pageErrorMsg: '', // 页面异常信息
|
|||
|
|
|||
|
showShare: false,
|
|||
|
goodsInfo: {}, // 商品信息
|
|||
|
|
|||
|
showGoodsSpec: false, // 商品规格: 显示 | 隐藏
|
|||
|
|
|||
|
goodsSpecOptions: {}, // 已选商品规格
|
|||
|
specButtonsList: [], // 规格按钮
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
computed: {
|
|||
|
...mapGetters(['isLogin']),
|
|||
|
|
|||
|
// 已选商品规格
|
|||
|
specValueStr() {
|
|||
|
return this.goodsSpecOptions?.spec?.spec_value_str ?? ''
|
|||
|
},
|
|||
|
|
|||
|
},
|
|||
|
|
|||
|
methods: {
|
|||
|
// 更改规格
|
|||
|
changeGoodsSpec(options) {
|
|||
|
this.goodsSpecOptions = options
|
|||
|
console.log(options)
|
|||
|
},
|
|||
|
|
|||
|
|
|||
|
// 点击已选规格
|
|||
|
onGoodsOptions() {
|
|||
|
this.showGoodsSpec = true
|
|||
|
this.specButtonsList = [{
|
|||
|
...this.specButtonsGroups.cart,
|
|||
|
style: {
|
|||
|
border: `solid 1px ${this.themeColor}`,
|
|||
|
color: this.themeColor,
|
|||
|
backgroundColor: '#FFFFFF',
|
|||
|
}
|
|||
|
},
|
|||
|
this.specButtonsGroups.buy
|
|||
|
]
|
|||
|
},
|
|||
|
|
|||
|
// 初始化商品详情数据
|
|||
|
initGoodsDetail() {
|
|||
|
return new Promise((resolve, reject) => {
|
|||
|
apiGoodsDetail({
|
|||
|
id: this.goods_id,
|
|||
|
visit: 1,
|
|||
|
}).then(data => {
|
|||
|
this.goodsInfo = data
|
|||
|
const hasComment = JSON.stringify(data.goods_comment) !== '[]'
|
|||
|
this.goodsComment = hasComment ? data.goods_comment : {}
|
|||
|
this.isGoodsCollect = !!data.is_collect
|
|||
|
}).then(data => {
|
|||
|
// #ifdef H5
|
|||
|
// 设置分享
|
|||
|
this.$store.dispatch('setWxShare', {
|
|||
|
shareImage: data?.image,
|
|||
|
shareDesc: data?.name
|
|||
|
})
|
|||
|
// #endif
|
|||
|
resolve(data)
|
|||
|
}).catch(err => {
|
|||
|
reject(err)
|
|||
|
})
|
|||
|
})
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
async onLoad() {
|
|||
|
const options = this.$Route.query
|
|||
|
|
|||
|
// 商品ID赋值:点击 | 扫码
|
|||
|
options['scene'] ?
|
|||
|
this.goods_id = strToParams(options['scene'])['id'] :
|
|||
|
this.goods_id = options.id
|
|||
|
|
|||
|
try {
|
|||
|
if (!this.goods_id) throw new Error('该商品不存在')
|
|||
|
|
|||
|
// 商品详情数据
|
|||
|
await this.initGoodsDetail()
|
|||
|
// 促销
|
|||
|
this.pageStatus = PageStatusEnum['NORMAL']
|
|||
|
} catch (err) {
|
|||
|
console.log(err)
|
|||
|
this.pageErrorMsg = err.message
|
|||
|
this.pageStatus = PageStatusEnum['ERROR']
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
onShareAppMessage() {
|
|||
|
const {
|
|||
|
name,
|
|||
|
image
|
|||
|
} = this.goodsInfo
|
|||
|
return {
|
|||
|
title: name,
|
|||
|
path: `/pages/goods_detail/goods_detail?id=${this.goods_id}&invite_code=${this.userInfo.code}`,
|
|||
|
imageUrl: image
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
.goods-detail {
|
|||
|
padding-bottom: calc(100rpx + 20rpx + constant(safe-area-inset-bottom));
|
|||
|
padding-bottom: calc(100rpx + 20rpx + env(safe-area-inset-bottom));
|
|||
|
}
|
|||
|
|
|||
|
.goods-info {
|
|||
|
padding: 20rpx 24rpx;
|
|||
|
background-color: #FFFFFF;
|
|||
|
|
|||
|
.primary {
|
|||
|
color: #FF4141;
|
|||
|
}
|
|||
|
|
|||
|
.share {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
width: 134rpx;
|
|||
|
height: 60rpx;
|
|||
|
margin-right: -24rpx;
|
|||
|
border-radius: 30px 0 0 30px;
|
|||
|
background-color: #F6f6f6;
|
|||
|
}
|
|||
|
|
|||
|
.goods-name {
|
|||
|
padding: 20rpx 0 10rpx 0;
|
|||
|
font-weight: 500;
|
|||
|
}
|
|||
|
|
|||
|
.btn {
|
|||
|
margin-left: 10px;
|
|||
|
font-size: 24rpx;
|
|||
|
padding: 6rpx 20rpx;
|
|||
|
border-radius: 8rpx;
|
|||
|
color: $-color-primary;
|
|||
|
background: rgba($color: $-color-primary, $alpha: .1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.specification {
|
|||
|
display: flex;
|
|||
|
padding: 24rpx;
|
|||
|
margin-top: 20rpx;
|
|||
|
background-color: #FFFFFF;
|
|||
|
}
|
|||
|
|
|||
|
.detail {
|
|||
|
padding: 24rpx;
|
|||
|
margin-top: 20rpx;
|
|||
|
background-color: #FFFFFF;
|
|||
|
|
|||
|
&-title {
|
|||
|
text-align: center;
|
|||
|
font-weight: 500;
|
|||
|
padding-bottom: 24rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|