Files
messi 4810dc79e3 fix
2024-08-19 17:17:46 +08:00

534 lines
13 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view v-if="!isLoading && detail && goods" class="container">
<!-- 背景区块 -->
<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 { 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 * as GoodsApi from '@/api/groupon/goods'
import SettingModel from '@/common/model/Setting'
import GrouponSettingModel from '@/common/model/groupon/Setting'
export default {
components: {
AvatarImage,
SkuPopup,
CountDown,
Recommended
},
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(true).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
})
.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: err => app.$toast('复制失败')
})
})
},
// 获取分享链接 (H5外链)
getShareUrl() {
const { path, query } = getCurrentPage()
return new Promise((resolve, reject) => {
// 获取h5站点地址
SettingModel.h5Url(true).then(baseUrl => {
// 生成完整的分享链接
const shareUrl = buildUrL(baseUrl, path, query)
resolve(shareUrl)
})
})
},
// 显示拼团规则
handleShowRules() {
this.showRules = true
},
// 显示/隐藏SKU弹窗
onShowSkuPopup() {
this.showSkuPopup = !this.showSkuPopup
}
},
/**
* 分享当前页面
*/
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>