405 lines
9.7 KiB
Vue
405 lines
9.7 KiB
Vue
<script setup>
|
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
|
import {
|
|
getProductDetail,
|
|
getProductCommentList,
|
|
getParticipateList
|
|
} from '@/api/mall'
|
|
import { ref, computed } from 'vue'
|
|
import { navigateTo, navigateBack } from '@/utils/router'
|
|
import { getRemainingTime, parseDateTime } from '../../utils/dateUtils'
|
|
|
|
const viewData = ref({})
|
|
const productId = ref('')
|
|
// 分享二维码进入
|
|
const groupId = ref('')
|
|
/** 评论数量 */
|
|
const commentNum = ref(0)
|
|
/** 分享弹窗 */
|
|
const shareDialog = ref(false)
|
|
/** 是否显示拼团数据 */
|
|
const isPingTuan = ref(false)
|
|
/** 拼团列表 */
|
|
const pingtuanList = ref([])
|
|
const getData = async productId => {
|
|
try {
|
|
const res = await getProductDetail(productId)
|
|
viewData.value = res.data
|
|
if (res.data.groupActivities.length > 0) {
|
|
const c = await getParticipateList(res.data.groupActivities[0].id)
|
|
console.log(c.data, '====')
|
|
console.log(getRemainingTime('2026-01-28 23:46:40'))
|
|
pingtuanList.value = c.data.map(v => {
|
|
return {
|
|
...v,
|
|
showDate: true
|
|
}
|
|
})
|
|
isPingTuan.value = c.data.length > 0
|
|
} else {
|
|
isPingTuan.value = false
|
|
}
|
|
} catch (error) {
|
|
navigateBack()
|
|
}
|
|
}
|
|
|
|
/** 评论数量获取 */
|
|
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
|
|
})
|
|
|
|
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>
|
|
<!-- shareDialog = true navigateTo -->
|
|
<image
|
|
src="/static/images/public/share-icon.png"
|
|
mode="heightFix"
|
|
class="right-icon"
|
|
@click="navigateTo('/pages/shop-together/user')"
|
|
></image>
|
|
</template>
|
|
</nav-bar>
|
|
<!-- 顶部图片 -->
|
|
<view class="top-img">
|
|
<swiper
|
|
class="swiper"
|
|
circular
|
|
indicator-dots
|
|
autoplay
|
|
:interval="4000"
|
|
:duration="500"
|
|
>
|
|
<swiper-item
|
|
v-for="(item, index) in viewData.imageGallery"
|
|
:key="index"
|
|
>
|
|
<image :src="item" mode="scaleToFill" class="img"></image>
|
|
</swiper-item>
|
|
</swiper>
|
|
</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 v-if="!groupId && isPingTuan" class="ping-box">
|
|
<view v-for="(item, index) in pingtuanList" :key="index">
|
|
<!-- 拼单量 -->
|
|
<view class="line-box">
|
|
<view class="left-img">
|
|
<text>拼单</text>
|
|
<image
|
|
:src="`/static/images/public/random${
|
|
Math.floor(Math.random() * 7) + 1
|
|
}.png`"
|
|
mode="scaleToFill"
|
|
class="avatar"
|
|
></image>
|
|
<image
|
|
:src="`/static/images/public/random${
|
|
Math.floor(Math.random() * 7) + 1
|
|
}.png`"
|
|
mode="scaleToFill"
|
|
class="avatar"
|
|
></image>
|
|
<image
|
|
:src="`/static/images/public/random${
|
|
Math.floor(Math.random() * 7) + 1
|
|
}.png`"
|
|
mode="scaleToFill"
|
|
class="avatar"
|
|
></image>
|
|
</view>
|
|
<text class="right-name">
|
|
还需{{ item.needPeople }}人拼单
|
|
</text>
|
|
</view>
|
|
<!-- 去拼团 -->
|
|
<view class="bottom-name">
|
|
<view class="count-down">
|
|
<text>距离结束:</text>
|
|
<uni-countdown
|
|
:day="parseDateTime(item.endTime).day"
|
|
:hour="parseDateTime(item.endTime).hour"
|
|
:minute="parseDateTime(item.endTime).minute"
|
|
:second="parseDateTime(item.endTime).second"
|
|
:show-colon="false"
|
|
@timeup="
|
|
() => {
|
|
item.showDate = false
|
|
}
|
|
"
|
|
/>
|
|
</view>
|
|
<button
|
|
v-if="item.showDate"
|
|
@click="
|
|
navigateTo('/pages/mall/confirm-order', {
|
|
productId: productId,
|
|
groupId: item.id
|
|
})
|
|
"
|
|
>
|
|
去拼单
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</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"
|
|
:price="viewData.minPrice"
|
|
></share-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.ping-box {
|
|
max-height: 500rpx;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.left-icon,
|
|
.right-icon {
|
|
height: 64rpx;
|
|
}
|
|
|
|
.top-img {
|
|
position: relative;
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -2rpx;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 56rpx;
|
|
background: #fff;
|
|
border-radius: 32rpx 32rpx 0 0;
|
|
}
|
|
.swiper {
|
|
width: 100%;
|
|
height: 628rpx;
|
|
}
|
|
.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: space-between;
|
|
align-items: center;
|
|
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>
|