Files
uniapp-im-shop/pages/mall/detail.vue

335 lines
7.5 KiB
Vue

<script setup>
import { onLoad, onShow } from '@dcloudio/uni-app'
import { getProductDetail, getProductCommentList } from '@/api/mall'
import { ref, computed } from 'vue'
import { navigateTo } from '@/utils/router'
const viewData = ref({})
const productId = ref('')
// 分享二维码进入
const groupId = ref('')
/** 评论数量 */
const commentNum = ref(0)
/** 分享弹窗 */
const shareDialog = ref(false)
const getData = async productId => {
const res = await getProductDetail(productId)
viewData.value = res.data
}
/** 评论数量获取 */
const getComment = async productId => {
const res = await getProductCommentList(
{
productId,
pageNum: 1,
pageSize: 1
},
false
)
commentNum.value = res.total
}
/** 拼单人数 */
const getPeople = computed(() => {
if (!viewData.value.groupActivities?.length) return 0
return viewData.value.groupActivities[0].totalPeople
})
/**
* 顶部导航按钮点击事件
* @param index 0 返回 1 分享
*/
const onTopNav = index => {
console.log(index)
}
const onConfirm = () => {
navigateTo('/pages/mall/confirm-order', {
productId: productId.value,
groupId: groupId.value
})
}
onLoad(async e => {
productId.value = e.productId
groupId.value = e?.groupId || ''
await getData(e.productId)
})
onShow(() => {
getComment(productId.value)
})
</script>
<template>
<view class="mall-detail">
<nav-bar>
<template #back>
<image
src="/static/images/public/return-icon.png"
mode="heightFix"
class="left-icon"
></image>
</template>
<template #right>
<image
src="/static/images/public/share-icon.png"
mode="heightFix"
class="right-icon"
@click="shareDialog = true"
></image>
</template>
</nav-bar>
<!-- 顶部图片 -->
<view class="top-img">
<image
:src="viewData.mainImage"
mode="scaleToFill"
class="img"
></image>
</view>
<!-- 商品详情 -->
<view class="detail-box">
<text class="title">{{ viewData.productName }}</text>
<view class="price">
<text>¥</text>
<text>{{ viewData.minPrice }}</text>
</view>
<view class="name-box">
<text>拼单数量:{{ viewData.salesCount }}</text>
<text>好评率:99%</text>
</view>
<!-- 拼单量 -->
<view class="line-box">
<view class="left-img">
<text>拼单</text>
<image
src="/static/images/public/random1.png"
mode="scaleToFill"
class="avatar"
></image>
<image
src="/static/images/public/random2.png"
mode="scaleToFill"
class="avatar"
></image>
<image
src="/static/images/public/random3.png"
mode="scaleToFill"
class="avatar"
></image>
</view>
<text class="right-name">还需{{ getPeople }}人拼单</text>
</view>
<!-- 去拼团 -->
<!-- <view class="bottom-name">
<view class="count-down">
<text>拼单倒计时:</text>
<text>23:53:00</text>
</view>
<button>去拼单</button>
</view>-->
<!-- 评论入口 -->
<view
class="comment-box"
@click="navigateTo('/pages/mall/comment', { productId })"
>
<text class="comment-name">评论({{ commentNum }})</text>
<view class="right-box">
<text>查看全部</text>
<image
src="/static/images/public/right-arrow.png"
mode="heightFix"
class="right-img"
></image>
</view>
</view>
<!-- 商品详情 -->
<view class="detail-content">
<text class="title">商品详情</text>
<mp-html
:content="viewData.description"
class="rich-box"
></mp-html>
</view>
</view>
<!-- 底部按钮 -->
<bottom-view>
<cb-button @click="onConfirm">拼单购买</cb-button>
</bottom-view>
<!-- 分享弹窗 -->
<share-popup
v-model:show="shareDialog"
:id="productId"
:text="viewData.productName"
:cover="viewData.mainImage"
></share-popup>
</view>
</template>
<style lang="scss" scoped>
.left-icon,
.right-icon {
height: 64rpx;
}
.top-img {
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 56rpx;
background: #fff;
border-radius: 32rpx 32rpx 0 0;
}
.img {
width: 100%;
height: 628rpx;
}
}
.detail-box {
padding: 0 58rpx 150rpx;
font-family:
PingFang SC,
PingFang SC;
font-style: normal;
text-transform: none;
.title {
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
.price {
display: flex;
align-items: baseline;
text {
font-weight: 500;
font-size: 24rpx;
color: #eb1c26;
&:last-child {
font-weight: bold;
font-size: 48rpx;
margin: 16rpx 0 16rpx 8rpx;
}
}
}
.name-box {
text {
font-weight: 500;
font-size: 24rpx;
color: #999999;
&:last-child {
margin-left: 66rpx;
}
}
}
.line-box {
margin: 48rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 500;
font-size: 28rpx;
.left-img {
display: flex;
align-items: center;
.avatar {
width: 64rpx;
height: 64rpx;
border-radius: 64rpx;
margin-left: 16rpx;
}
text {
color: #333333;
}
}
.right-name {
color: #999999;
}
}
.bottom-name {
display: flex;
justify-content: flex-end;
font-weight: 500;
.count-down {
display: flex;
flex-direction: column;
text {
font-size: 28rpx;
color: #eb1c26;
&:last-child {
color: #999999;
}
}
}
button {
margin: 0;
width: 252rpx;
height: 64rpx;
border-radius: 64rpx;
line-height: 64rpx;
font-size: 28rpx;
color: #00d993;
border: 2rpx solid #00d993;
background: #ffffff;
&::after {
border: none;
}
}
}
.detail-content {
border-top: 2rpx solid #f9f9f9;
padding-top: 20rpx;
margin-top: 20rpx;
.title {
margin-bottom: 16rpx;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.rich-box {
margin-top: 16rpx;
width: 100%;
}
}
.comment-box {
border-top: 2rpx solid #f9f9f9;
padding-top: 20rpx;
margin-top: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-family:
PingFang SC,
PingFang SC;
font-weight: 500;
font-style: normal;
text-transform: none;
.comment-name {
font-size: 28rpx;
color: #333333;
}
.right-box {
display: flex;
align-items: center;
text {
font-size: 28rpx;
color: #999999;
margin-right: 8rpx;
}
.right-img {
height: 32rpx;
}
}
}
}
</style>