Files
yunxinwei-uniapp/pages/bargain/task.vue
messi 4810dc79e3 fix
2024-08-19 17:17:46 +08:00

839 lines
20 KiB
Vue
Raw 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" class="container">
<!-- 顶部操作栏 -->
<view class="header dis-flex flex-x-between">
<view class="item-touch" @click="$navTo('pages/index/index')">
<text>返回首页</text>
</view>
<view class="item-touch" @click="handleShowRules()">
<text>玩法详情</text>
</view>
</view>
<view class="content">
<!-- 砍价信息 -->
<view class="infos-wrap">
<view class="infos-top">
<view class="infos-img">
<avatar-image :url="task.user.avatar_url" :width="104" />
</view>
<view class="infos-name">
<text>{{ task.user.nick_name }}</text>
</view>
</view>
<view class="infos-mask">
<view class="infos-prompt" v-if="active.prompt_words">
<text>{{ active.prompt_words }}</text>
</view>
<!-- 商品信息 -->
<view class="infos-item" @click="$navTo('pages/bargain/goods/index', { activeId, goodsId: goods.goods_id })">
<view class="infos-item-img">
<image class="image" :src="goodsSkuInfo.goods_image ? goodsSkuInfo.goods_image : goods.goods_image"></image>
</view>
<view class="infos-item-info">
<view class="infos-item-name">
<text class="twoline-hide">{{ goods.goods_name }}</text>
</view>
<view class="infos-item-stock">
<view class="stock-widget">
<text>仅剩</text>
<text class="stock-num">{{ goodsSkuInfo.stock_num }}</text>
<text></text>
</view>
</view>
<view class="infos-item-price dis-flex flex-y-end">
<text class="price1 col-m">底价¥</text>
<text class="price2 col-m">{{ task.floor_price }}</text>
<text class="price3">¥{{ task.goods_price }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 分割线 -->
<view class="connect">
<view class="connect-ring bgf-ring--left">
<text class="line"></text>
</view>
<view class="connect-ring bgf-ring--right">
<text class="line"></text>
</view>
</view>
<!-- 砍价进度 -->
<view class="bargain-wrap">
<!-- 已砍数目 -->
<view class="bargain-info">
<view v-if="task.status" class="bargain-ing">
<block v-if="!task.is_floor">
<text>已砍</text>
<text class="focal col-m">{{ task.cut_money }}</text>
<text>还差</text>
<text class="focal col-m">{{ task.surplus_money }}</text>
<text></text>
</block>
<block v-else>
<text>已砍至最低</text>
<text class="focal col-m">{{ task.floor_price }}</text>
<text>砍价成功</text>
</block>
</view>
<view v-else class="bargain-ing">
<text class="col-9">该砍价任务已结束</text>
</view>
</view>
<!-- 砍价进度条 -->
<view class="bgn__process m-top30">
<view class="bgn__process-bottom">
<view class="bgn__process-process process--ani" :style="{ width: `${task.bargain_rate}%` }"></view>
</view>
</view>
<!-- 操作按钮 -->
<view class="btn-container m-top30 dis-flex flex-x-center">
<!-- 立即购买 -->
<view v-if="showBuyBtn" class="btn-item btn-item__buy" :class="{ complete: task.is_floor }" @click="handleBuyNow()">
<text>立即购买</text>
</view>
<!-- 分享给朋友 -->
<button v-if="showShareBtn" open-type="share" class="btn-normal" @click="handleShareBtn()">
<view class="btn-item btn-item__main">
<text>邀请好友砍价</text>
</view>
</button>
<!-- 砍一刀操作 -->
<view v-if="showCatBtn" class="btn-item btn-item__main btn-item-long" @click="handleHelpCut()">
<text>帮TA砍一刀</text>
</view>
<!-- 查看其他砍价活动 -->
<view v-if="showOtherBtn" class="btn-item btn-item__main btn-item-long" @click="$navTo('pages/bargain/index')">
<text>查看其他砍价活动</text>
</view>
</view>
<!-- 到期时间 -->
<view class="bargain-p" v-if="task.status">
<view class="bargain-people dis-flex flex-x-center flex-y-center">
<text>活动还剩</text>
<count-down :date="active.end_time" separator="zh" theme="text" />
<text>结束快来砍价吧~</text>
</view>
</view>
</view>
<!-- 好友助力榜 -->
<view class="records-container" v-if="helpList.length">
<view class="records">
<view class="records-back"></view>
<view class="records-content">
<view class="records-h2">
<text>好友助力榜</text>
</view>
<view class="friend-help">
<view class="records-item" v-for="(help, idx) in helpList" :key="idx">
<view class="records-left">
<avatar-image :url="help.user.avatar_url" :width="70" />
<text class="nick-name">{{ help.user.nick_name }}</text>
</view>
<view class="records-right">
<text class="bold m-r-6">帮砍了</text>
<text class="red">¥{{ help.cut_money }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 砍价规则弹窗 -->
<u-modal v-if="!isLoading" v-model="showRules" title="砍价规则">
<scroll-view style="height: 610rpx;" :scroll-y="true">
<view class="pops-content">
<text>{{ setting.rulesDesc }}</text>
</view>
</scroll-view>
</u-modal>
</view>
</template>
<script>
import { getCurrentPage, buildUrL } from '@/core/app'
import AvatarImage from '@/components/avatar-image'
import CountDown from '@/components/countdown'
import SettingModel from '@/common/model/Setting'
import * as GoodsApi from '@/api/goods'
import * as TaskApi from '@/api/bargain/task'
import * as ActiveApi from '@/api/bargain/active'
export default {
components: {
AvatarImage,
CountDown
},
data() {
return {
// 是否正在加载中
isLoading: true,
taskId: undefined, // 砍价任务ID
activeId: undefined, // 砍价活动ID
task: {}, // 砍价任务详情
active: {}, // 活动详情
goods: {}, // 商品详情
goodsSkuInfo: {}, // 商品SKU信息
helpList: [], // 好友助力榜
isCreater: false, // 是否为当前砍价任务的发起人
isCut: false, // 当前是否已砍
setting: {}, // 砍价规则
showRules: false, // 显示砍价规则
disabled: false, // 按钮禁用状态
showBuyBtn: false, // 立即购买
showShareBtn: false, // 邀请好友砍价
showCatBtn: false, // 帮TA砍一刀
showOtherBtn: false, // 查看其他砍价活动
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.taskId = options.taskId
// 刷新页面数据
this.onRefreshPage()
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
methods: {
// 刷新页面数据
onRefreshPage() {
const app = this
app.isLoading = true
// 获取砍价任务详情
app.getTaskDetail()
.then(result => {
Promise.all([
app.getActiveDetail(),
app.getGoodsBasic(),
app.getGoodsSku(),
app.getHelpList()
])
.then(() => app.initShowBtn())
.finally(() => app.isLoading = false)
})
},
// 获取砍价任务详情
getTaskDetail() {
const app = this
return new Promise((resolve, reject) => {
TaskApi.detail(app.taskId)
.then(result => {
app.task = result.data.taskInfo
app.activeId = app.task.active_id
app.isCreater = result.data.isCreater
app.isCut = result.data.isCut
app.setting = result.data.setting
resolve(result)
})
.catch(reject)
})
},
// 获取砍价活动详情
getActiveDetail() {
const app = this
return new Promise((resolve, reject) => {
ActiveApi.detail(app.activeId)
.then(result => {
app.active = result.data.active
resolve(result)
})
.catch(reject)
})
},
// 获取商品信息
getGoodsBasic() {
const app = this
const goodsId = app.task.goods_id
return new Promise((resolve, reject) => {
GoodsApi.basic(goodsId, false)
.then(result => {
app.goods = result.data.detail
resolve(result)
})
.catch(reject)
})
},
// 获取商品SKU信息
getGoodsSku() {
const app = this
const goodsId = app.task.goods_id
const goodsSkuId = app.task.goods_sku_id
return new Promise((resolve, reject) => {
GoodsApi.skuInfo(goodsId, goodsSkuId)
.then(result => {
app.goodsSkuInfo = result.data.skuInfo
resolve(result)
})
.catch(reject)
})
},
// 获取砍价活动详情
getHelpList() {
const app = this
return new Promise((resolve, reject) => {
TaskApi.helpList(app.taskId)
.then(result => {
app.helpList = result.data.list
resolve(result)
})
.catch(reject)
})
},
// 初始化:显示操作按钮
initShowBtn() {
const app = this
// 立即购买
const showBuyBtn = app.isCreater && !app.task.is_buy && app.task.status && (!app.active.is_floor_buy ||
app.task.is_floor)
// 帮砍一刀
const showCatBtn = !app.isCreater && !app.isCut && !app.task.is_floor && app.task.status
// 邀请好友砍价
const showShareBtn = !showCatBtn && !app.task.is_floor && app.task.status
// 查看其他砍价活动
const showOtherBtn = !showBuyBtn && !showShareBtn && !showCatBtn
app.showBuyBtn = showBuyBtn
app.showCatBtn = showCatBtn
app.showShareBtn = showShareBtn
app.showOtherBtn = showOtherBtn
},
// 显示砍价规则
handleShowRules() {
this.showRules = true
},
// 立即购买
handleBuyNow() {
// 跳转到结算页
const app = this
app.$navTo('pages/checkout/index', {
mode: 'bargain',
taskId: app.taskId
})
},
// 帮砍一刀
handleHelpCut() {
const app = this
app.disabled = true
TaskApi.helpCut(app.taskId)
.then(result => {
app.$toast(result.message)
setTimeout(() => app.onRefreshPage(), 1800)
})
.finally(() => app.disabled = false)
},
// 点击分享按钮
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)
})
})
},
},
/**
* 分享当前页面
*/
onShareAppMessage() {
// 构建页面参数
const app = this
const params = app.$getShareUrlParams({ taskId: app.taskId })
return {
title: app.active.share_title,
path: `/pages/bargain/task?${params}`
}
},
/**
* 分享到朋友圈
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
*/
onShareTimeline() {
// 构建页面参数
const app = this
const params = app.$getShareUrlParams({ taskId: app.taskId })
return {
title: app.active.share_title,
path: `/pages/bargain/task?${params}`
}
},
}
</script>
<style>
page {
height: 100%;
}
</style>
<style lang="scss" scoped>
.container {
background: url('https://si.geilicdn.com/img-310900000167962321710a026860-unadjust_750_686.png') top no-repeat,
linear-gradient(90deg, #fea044, #f9565d 63%, #e63378);
background-size: 100% auto;
min-height: 100%;
}
/* 头部区域 */
.header {
padding: 30rpx 30rpx;
.item-touch {
color: #fff;
font-size: 24rpx;
padding: 7rpx 20rpx;
background: rgba(0, 0, 0, 0.17);
border-radius: 22rpx;
}
}
/* 内容区域 */
.content {
position: relative;
box-sizing: border-box;
padding: 10rpx 30rpx 60rpx 30rpx;
}
/* 砍价信息 */
.infos-wrap {
background: #fff;
box-shadow: 0 4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
padding: 0 30rpx 40rpx;
border-radius: 16rpx;
}
.infos-top {
position: relative;
top: -42rpx;
margin-bottom: -22rpx;
}
.infos-img {
width: 120rpx;
height: 120rpx;
padding: 8rpx;
background: #fff;
overflow: hidden;
margin: 0 auto;
border-radius: 50%;
}
.infos-name {
margin: 8rpx auto 0;
width: 80%;
font-size: 26rpx;
color: #9a9a9a;
text-align: center;
line-height: 32rpx;
}
.infos-prompt {
text-align: center;
font-size: 30rpx;
color: #222;
line-height: 48rpx;
margin-bottom: 30rpx;
}
.infos-item {
margin-top: 40rpx;
display: flex;
}
.infos-item-img {
flex: none;
width: 180rpx;
height: 180rpx;
.image {
width: 100%;
height: 100%;
}
}
.infos-item-info {
margin-left: 25rpx;
flex: auto;
}
.infos-item-name {
font-size: 28rpx;
color: #404040;
line-height: 40rpx;
height: 80rpx;
}
.infos-item-stock {
.stock-widget {
display: inline-block;
min-width: 100rpx;
padding: 0 20rpx;
background-image: linear-gradient(-90deg, #fe9c3f, #fb6253 99%);
border-radius: 40rpx;
height: 40rpx;
font-size: 24rpx;
color: #fff;
line-height: 40rpx;
margin-top: 6rpx;
.stock-num {
margin: 0 6rpx;
}
}
}
.infos-item-price {
font-size: 0;
margin-top: 8rpx;
.price1 {
font-size: 24rpx;
line-height: 32rpx;
}
.price2 {
margin-left: 4rpx;
font-size: 36rpx;
line-height: 40rpx;
}
.price3 {
margin-left: 10rpx;
font-size: 24rpx;
color: #9a9a9a;
line-height: 32rpx;
text-decoration: line-through;
}
}
/* 分割线 */
.connect {
position: relative;
height: 20rpx;
}
.connect-ring {
position: absolute;
top: -28rpx;
height: 76rpx;
width: 20rpx;
padding: 8rpx 6rpx;
box-sizing: border-box;
&:after,
&:before {
content: "";
position: absolute;
z-index: 6;
left: 0;
height: 20rpx;
width: 20rpx;
border-radius: 20rpx;
}
.line {
z-index: 8;
display: block;
height: 100%;
width: 100%;
background: #fff;
border-radius: 20rpx;
}
&.bgf-ring--left {
left: 20rpx;
&:before {
top: 0;
background: #f4914e;
}
&:after {
bottom: 0;
background: #f4914e;
}
}
&.bgf-ring--right {
right: 20rpx;
&:before {
top: 0;
background: #e03e71;
}
&:after {
bottom: 0;
background: #e03e71;
}
}
}
/* 砍价进度 */
.bargain-wrap {
position: relative;
background: #fff;
padding: 40rpx 30rpx 30rpx;
box-shadow: 0 4rpx 40rpx 0 rgba(144, 52, 52, 0.1);
border-radius: 16rpx;
}
.bargain-info {
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #404040;
line-height: 40rpx;
.focal {
margin: 0 5rpx;
}
}
.bargain-p {
margin-top: 40rpx;
min-height: 32rpx;
}
.bargain-people {
font-size: 24rpx;
color: #9a9a9a;
text-align: center;
line-height: 32rpx;
}
/* 进度条 */
.bgn__process {
position: relative;
padding: 30rpx 0;
}
.bgn__process-bottom {
z-index: 1;
overflow: hidden;
background-image: linear-gradient(0deg, #f0f2f7, #e8ebf3);
}
.bgn__process-bottom,
.bgn__process-process {
position: relative;
height: 30rpx;
border-radius: 30rpx;
}
.bgn__process-process {
background-image: linear-gradient(90deg, #ffc108, #fde586);
background: #ffc108;
&.process--ani {
&:after {
content: "";
position: absolute;
width: 100%;
height: 32rpx;
top: 50%;
left: 0;
margin-top: -16rpx;
}
}
}
/* 操作按钮 */
.btn-container {
.btn-item {
color: #fff;
height: 80rpx;
font-size: 30rpx;
border-radius: 15rpx;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
}
.btn-item__buy {
width: 280rpx;
margin-right: 30rpx;
background-image: linear-gradient(90deg, #fa9e1b, #fe5b1b);
box-shadow: #fe5b1b 0 22rpx 48rpx -22rpx;
&.complete {
width: 360rpx;
animation: btn_anim 0.9s linear infinite;
transform-origin: center;
}
}
.btn-item__main {
width: 320rpx;
background-image: linear-gradient(90deg, #fe316c, #fd584e);
box-shadow: #fd584e 0 22rpx 48rpx -22rpx;
animation: btn_anim 0.9s linear infinite;
transform-origin: center;
}
.btn-item-long {
max-width: 400rpx;
}
/* 按钮动画 */
@keyframes btn_anim {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
40% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
/* 好友助力榜 */
.records-container {
margin-top: 44rpx;
}
.records {
position: relative;
color: #404040;
box-shadow: 0 4rpx 40rpx 0 rgba(0, 0, 0, 0.08);
}
.records-back {
position: absolute;
left: -14rpx;
right: -14rpx;
top: -14rpx;
height: 28rpx;
border-radius: 28rpx;
z-index: 1;
background: #cb272d;
}
.records-content {
position: relative;
z-index: 2;
background: #fff;
padding: 40rpx 30rpx;
}
.records-h2 {
display: flex;
justify-content: space-between;
height: 60rpx;
align-items: center;
font-weight: 700;
font-size: 34rpx;
line-height: 48rpx;
}
.friend-help {
overflow: hidden;
padding: 40rpx 0 20rpx;
transition: max-height 0.6s ease-out;
}
.records-left,
.records-item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.records-left {
.nick-name {
display: inline-block;
margin-left: 14rpx;
}
}
.records-left .nick-name,
.records-right {
font-size: 28rpx;
line-height: 40rpx;
}
.records-right {
display: flex;
justify-content: center;
align-items: center;
.red {
color: #e53a40;
}
}
// 砍价规则(弹窗)
.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>