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>
|