You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
548 lines
14 KiB
548 lines
14 KiB
<template>
|
|
<view v-if="!isLoading && detail && goods" class="container" :style="appThemeStyle">
|
|
<!-- 背景区块 -->
|
|
<view class="bg-layer"></view>
|
|
|
|
<!-- 商品信息 -->
|
|
<view class="goods-info" @click="onTargetGoods()">
|
|
<view class="goods-image">
|
|
<view v-if="detail.active_type != ActiveTypeEnum.NORMAL.value" class="label">
|
|
<text>{{ ActiveTypeEnum[detail.active_type].name2 }}</text>
|
|
</view>
|
|
<image class="image" :src="goods.goods_image"></image>
|
|
</view>
|
|
<view class="goods-detail">
|
|
<view class="goods-name">
|
|
<text class="twoline-hide">{{ goods.goods_name }}</text>
|
|
</view>
|
|
<view class="goods-price">
|
|
<text class="f-26 col-m">¥</text>
|
|
<text class="m-price">{{ goods.groupon_price }}</text>
|
|
<text class="line-price">¥{{ goods.original_price }}</text>
|
|
</view>
|
|
<view class="goods-tag">
|
|
<text class="tag-item">{{ detail.people }}人团</text>
|
|
<text v-if="goods.diff_price != '0.00'" class="tag-item">拼团省{{ goods.diff_price }}元</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 拼团成员 -->
|
|
<view class="main">
|
|
<!-- 拼团状态 (成功、失败) -->
|
|
<view v-if="detail.status == TaskStatusEnum.FAIL.value" class="main_status main_status__fail">
|
|
<text class="status-icon iconfont icon-shibai"></text>
|
|
<text>超过有效时间,拼团失败</text>
|
|
</view>
|
|
<view v-if="detail.status == TaskStatusEnum.SUCCESS.value" class="main_status main_status__success">
|
|
<text class="status-icon iconfont icon-success"></text>
|
|
<text>拼团已成功</text>
|
|
</view>
|
|
<!-- 参团用户 -->
|
|
<view class="main-user">
|
|
<view v-for="(item, index) in detail.users" :key="item.id" class="user-item">
|
|
<avatar-image :url="item.userInfo.avatar_url" :width="100" />
|
|
<view v-if="item.is_leader" class="user-role"><text class="role-name">团长</text></view>
|
|
</view>
|
|
<!-- 虚位以待 -->
|
|
<view v-for="(val, idx) in detail.people - detail.joined_people" :key="idx" class="user-item user-item__wait">
|
|
<text class="iconfont icon-wenhao"></text>
|
|
</view>
|
|
</view>
|
|
<!-- 拼单状态:拼团中 -->
|
|
<view v-if="detail.status == TaskStatusEnum.NORMAL.value" class="main_tiem">
|
|
<text>还差</text>
|
|
<text class="main_timer_color">{{ detail.people - detail.joined_people }}</text>
|
|
<text>个名额,</text>
|
|
<!-- 倒计时 -->
|
|
<count-down :date="detail.end_time" separator="colon" theme="custom" customBgColor="#FE5246" />
|
|
<text>后结束</text>
|
|
</view>
|
|
<!-- 操作按钮 -->
|
|
<block v-if="detail.status == TaskStatusEnum.NORMAL.value">
|
|
<view v-if="!detail.is_join" class="button" @click="onShowSkuPopup()">立即参团</view>
|
|
<!-- 分享给朋友 -->
|
|
<button v-else open-type="share" class="button btn-normal" @click="handleShareBtn()">
|
|
<view class="btn-item btn-item__main"><text>立即分享</text></view>
|
|
</button>
|
|
</block>
|
|
<view v-else class="button" @click="onTargetGoods()">去开团</view>
|
|
</view>
|
|
<!-- 拼团须知 -->
|
|
<view class="notice" @click="handleShowRules()">
|
|
<text class="f-30">拼团须知</text>
|
|
<text class="t-brief">{{ setting.ruleBrief }}</text>
|
|
<text class="icon-arrow"></text>
|
|
</view>
|
|
|
|
<!-- 商品SKU弹窗 -->
|
|
<SkuPopup v-model="showSkuPopup" :skuMode="skuMode" :goods="goods" :buyMode="1" :taskId="detail.task_id" :stepPeople="detail.people" />
|
|
|
|
<!-- 拼团规则弹窗 -->
|
|
<u-modal v-model="showRules" title="拼团规则">
|
|
<scroll-view style="height: 610rpx; touch-action: none;" :scroll-y="true">
|
|
<view class="pops-content">
|
|
<text>{{ setting.ruleDetail }}</text>
|
|
</view>
|
|
</scroll-view>
|
|
</u-modal>
|
|
<!-- 商品推荐 -->
|
|
<recommended />
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import WxofficialMixin from '@/core/mixins/wxofficial'
|
|
import { getCurrentPage, buildUrL } from '@/core/app'
|
|
import AvatarImage from '@/components/avatar-image'
|
|
import CountDown from '@/components/countdown'
|
|
import Recommended from '@/components/recommended'
|
|
import SkuPopup from '../goods/components/SkuPopup'
|
|
import { ActiveTypeEnum, ActiveStatusEnum, TaskStatusEnum } from '@/common/enum/groupon'
|
|
import * as TaskApi from '@/api/groupon/task'
|
|
import StoreModel from '@/common/model/Store'
|
|
import GrouponSettingModel from '@/common/model/groupon/Setting'
|
|
|
|
export default {
|
|
components: {
|
|
AvatarImage,
|
|
SkuPopup,
|
|
CountDown,
|
|
Recommended
|
|
},
|
|
mixins: [WxofficialMixin],
|
|
data() {
|
|
return {
|
|
// 正在加载
|
|
isLoading: true,
|
|
// 枚举类
|
|
ActiveTypeEnum,
|
|
ActiveStatusEnum,
|
|
TaskStatusEnum,
|
|
// 显示拼团规则
|
|
showRules: false,
|
|
// 显示/隐藏SKU弹窗
|
|
showSkuPopup: false,
|
|
// 按钮模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
|
skuMode: 3,
|
|
// 当前拼单ID
|
|
taskId: null,
|
|
// 拼单详情
|
|
detail: null,
|
|
// 拼团商品
|
|
goods: null,
|
|
// 拼团设置
|
|
setting: {}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
onLoad({ taskId }) {
|
|
// 记录拼单ID
|
|
this.taskId = taskId
|
|
// 获取拼团设置
|
|
this.getSetting()
|
|
// 获取拼单详情
|
|
this.getTaskDetail()
|
|
},
|
|
|
|
methods: {
|
|
|
|
// 获取拼团设置
|
|
getSetting() {
|
|
GrouponSettingModel.data().then(setting => (this.setting = setting))
|
|
},
|
|
|
|
// 获取拼单详情
|
|
getTaskDetail() {
|
|
const { taskId } = this
|
|
this.isLoading = true
|
|
TaskApi.detail(taskId)
|
|
.then(result => {
|
|
this.detail = result.data.detail
|
|
this.goods = result.data.goods
|
|
// 设置微信公众号链接分享卡片内容
|
|
this.setWxofficialShareData()
|
|
})
|
|
.finally(() => (this.isLoading = false))
|
|
},
|
|
|
|
// 跳转到拼团商品详情
|
|
onTargetGoods() {
|
|
const { goods } = this
|
|
this.$navTo('pages/groupon/goods/index', { grouponGoodsId: goods.groupon_goods_id })
|
|
},
|
|
|
|
// 点击分享按钮
|
|
handleShareBtn() {
|
|
// #ifndef MP
|
|
this.handleCopyLink()
|
|
// #endif
|
|
},
|
|
|
|
// 复制当前页面链接
|
|
handleCopyLink() {
|
|
const app = this
|
|
app.getShareUrl().then(shareUrl => {
|
|
// 复制到剪贴板
|
|
uni.setClipboardData({
|
|
data: shareUrl,
|
|
success: () => app.$toast('复制链接成功,快去发送给朋友吧'),
|
|
fail: ({ errMsg }) => app.$toast('复制失败 ' + errMsg)
|
|
})
|
|
})
|
|
},
|
|
|
|
// 获取分享链接 (H5外链)
|
|
getShareUrl() {
|
|
const { path, query } = getCurrentPage()
|
|
return new Promise((resolve, reject) => {
|
|
// 获取h5站点地址
|
|
StoreModel.h5Url().then(baseUrl => {
|
|
// 生成完整的分享链接
|
|
const shareUrl = buildUrL(baseUrl, path, query)
|
|
resolve(shareUrl)
|
|
})
|
|
})
|
|
},
|
|
|
|
// 显示拼团规则
|
|
handleShowRules() {
|
|
this.showRules = true
|
|
},
|
|
|
|
// 显示/隐藏SKU弹窗
|
|
onShowSkuPopup() {
|
|
this.showSkuPopup = !this.showSkuPopup
|
|
},
|
|
|
|
// 设置微信公众号链接分享卡片内容
|
|
setWxofficialShareData() {
|
|
const { detail, goods } = this
|
|
this.updateShareCardData({
|
|
title: goods.goods_name,
|
|
desc: goods.selling_point,
|
|
imgUrl: goods.goods_image
|
|
})
|
|
},
|
|
|
|
},
|
|
|
|
/**
|
|
* 分享当前页面
|
|
*/
|
|
onShareAppMessage() {
|
|
// 构建页面参数
|
|
const app = this
|
|
const params = app.$getShareUrlParams({ taskId: app.taskId })
|
|
return {
|
|
title: app.goods.goods_name,
|
|
path: `/pages/groupon/task/index?${params}`
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 分享到朋友圈
|
|
*/
|
|
onShareTimeline() {
|
|
// 构建页面参数
|
|
const app = this
|
|
const params = app.$getShareUrlParams({ taskId: app.taskId })
|
|
return {
|
|
title: app.goods.goods_name,
|
|
path: `/pages/groupon/task/index?${params}`
|
|
}
|
|
},
|
|
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
// 箭头图标
|
|
.icon-arrow {
|
|
display: inline-block;
|
|
width: 0;
|
|
height: 0;
|
|
border-width: 10rpx;
|
|
border-style: solid;
|
|
border-color: transparent transparent transparent #ccc;
|
|
}
|
|
|
|
// 背景区块
|
|
.bg-layer {
|
|
position: absolute;
|
|
top: 0;
|
|
width: 100%;
|
|
z-index: 0;
|
|
height: 250rpx;
|
|
text-align: center;
|
|
line-height: 100rpx;
|
|
|
|
&::after {
|
|
width: 140%;
|
|
height: 250rpx;
|
|
position: absolute;
|
|
left: -20%;
|
|
top: 0;
|
|
z-index: -1;
|
|
content: '';
|
|
border-radius: 0 0 50% 50%;
|
|
background-image: linear-gradient(180deg, #ff5644, #fd7524);
|
|
}
|
|
}
|
|
|
|
// 商品信息
|
|
.goods-info {
|
|
position: relative;
|
|
margin: auto;
|
|
margin-top: 30rpx;
|
|
padding: 28rpx;
|
|
padding-bottom: 22rpx;
|
|
width: 92%;
|
|
background: #fff;
|
|
border-radius: 10rpx;
|
|
box-sizing: border-box;
|
|
box-shadow: 0px 5px 12px rgba(226, 226, 226, 0.62);
|
|
display: flex;
|
|
|
|
.goods-image {
|
|
position: relative;
|
|
margin-right: 30rpx;
|
|
|
|
.label {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 1;
|
|
background: linear-gradient(to right, #ffa600, #f5b914);
|
|
color: #fff;
|
|
font-size: 24rpx;
|
|
padding: 6rpx 8rpx;
|
|
border-radius: 8rpx;
|
|
}
|
|
|
|
.image {
|
|
display: block;
|
|
width: 240rpx;
|
|
height: 240rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
}
|
|
|
|
.goods-detail {
|
|
background: #fff;
|
|
|
|
.goods-name {
|
|
display: block;
|
|
font-size: 28rpx;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.goods-price {
|
|
margin: 20rpx 0;
|
|
color: #eb5841;
|
|
|
|
.m-price {
|
|
display: inline-block;
|
|
font-size: 40rpx;
|
|
}
|
|
|
|
.line-price {
|
|
display: inline-block;
|
|
margin: 10rpx;
|
|
font-size: 24rpx;
|
|
color: #8e8e8e;
|
|
text-decoration: line-through;
|
|
}
|
|
}
|
|
|
|
.goods-tag {
|
|
margin-bottom: -10rpx;
|
|
|
|
.tag-item {
|
|
display: inline-block;
|
|
padding: 4rpx 12rpx;
|
|
font-size: 24rpx;
|
|
line-height: 36rpx;
|
|
border-radius: 5rpx;
|
|
color: #fa3534;
|
|
background: #fef0f0;
|
|
margin-right: 10rpx;
|
|
margin-bottom: 10rpx;
|
|
box-sizing: border-box;
|
|
}
|
|
}
|
|
}
|
|
|
|
&:after {
|
|
display: block;
|
|
clear: both;
|
|
content: '';
|
|
visibility: hidden;
|
|
height: 0;
|
|
}
|
|
}
|
|
|
|
// 拼团成员
|
|
.main {
|
|
position: relative;
|
|
margin: auto;
|
|
margin-top: 30rpx;
|
|
padding: 50rpx 20rpx;
|
|
background: #fff;
|
|
box-sizing: border-box;
|
|
|
|
.main-user {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
margin: 0 auto;
|
|
width: 600rpx;
|
|
margin-bottom: 30rpx;
|
|
|
|
.user-item {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
margin: 0 25rpx 25rpx 0;
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
|
|
&:nth-child(5n + 0) {
|
|
margin-right: 0;
|
|
}
|
|
|
|
.user-role {
|
|
width: 100%;
|
|
text-align: center;
|
|
height: 40rpx;
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: -1rpx;
|
|
|
|
.role-name {
|
|
background: #eb5841;
|
|
border-radius: 15rpx;
|
|
display: inline-block;
|
|
line-height: 1.4;
|
|
font-size: 24rpx;
|
|
color: #fff;
|
|
width: 78rpx;
|
|
}
|
|
}
|
|
|
|
&.user-item__wait {
|
|
border-radius: 50%;
|
|
background: #f8f8f8;
|
|
border: 1rpx dashed #dbdbdb;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
text {
|
|
color: #dbdbdb;
|
|
font-size: 38rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.button {
|
|
display: block;
|
|
margin-top: 40rpx;
|
|
width: 550rpx;
|
|
line-height: 84rpx;
|
|
font-size: 28rpx;
|
|
background-image: linear-gradient(90deg, #fe5246, #fb265a);
|
|
border: none;
|
|
box-shadow: 0px 3px 8px rgba(255, 8, 15, 0.25);
|
|
text-align: center;
|
|
margin: 0 auto;
|
|
color: #fff;
|
|
border-radius: 40rpx;
|
|
animation: btn_anim 0.9s linear infinite;
|
|
transform-origin: center;
|
|
}
|
|
}
|
|
|
|
// 按钮动画
|
|
@keyframes btn_anim {
|
|
0% {
|
|
-webkit-transform: scale(1);
|
|
transform: scale(1);
|
|
}
|
|
|
|
40% {
|
|
-webkit-transform: scale(1.05);
|
|
transform: scale(1.05);
|
|
}
|
|
}
|
|
|
|
/* 拼团状态 */
|
|
.main_status {
|
|
margin-bottom: 40rpx;
|
|
font-size: 35rpx;
|
|
text-align: center;
|
|
|
|
.status-icon {
|
|
margin-right: 15rpx;
|
|
}
|
|
}
|
|
|
|
.main_status__fail {
|
|
color: $main-bg;
|
|
}
|
|
|
|
.main_status__success {
|
|
color: #08b625;
|
|
}
|
|
|
|
/* 倒计时 */
|
|
.main_tiem {
|
|
margin-bottom: 50rpx;
|
|
font-size: 30rpx;
|
|
text-align: center;
|
|
display: flex;
|
|
justify-content: center;
|
|
|
|
.main_timer_color {
|
|
color: #fc8434;
|
|
margin: 0 6rpx;
|
|
}
|
|
}
|
|
|
|
// 拼团须知
|
|
.notice {
|
|
display: flex;
|
|
margin: auto;
|
|
margin-top: 30rpx;
|
|
padding: 35rpx 20rpx;
|
|
background: #fff;
|
|
border-radius: 10rpx;
|
|
box-sizing: border-box;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
.t-brief {
|
|
font-size: 26rpx;
|
|
color: #a6a6a6;
|
|
}
|
|
}
|
|
|
|
// 拼团规则 (弹窗)
|
|
.pops-content {
|
|
padding: 30rpx 48rpx;
|
|
font-size: 28rpx;
|
|
line-height: 44rpx;
|
|
text-align: left;
|
|
color: #606266;
|
|
min-height: 320rpx;
|
|
max-height: 640rpx;
|
|
box-sizing: border-box;
|
|
}
|
|
</style>
|
|
|