1158 lines
28 KiB
Vue
1158 lines
28 KiB
Vue
<template>
|
||
<page-container title="福利屋详情" :showBack="true">
|
||
<view class="relative header-info" :class="{ 'show': headerShow }"
|
||
style="width: 686rpx; height: 152rpx; background-color: #FFFFFF; border-radius: 16rpx; margin: 0 auto;">
|
||
|
||
<image style="width: 108rpx; height: 108rpx;position: absolute; left: 24rpx; top: 22rpx;"
|
||
:src="$img1('common/logo.jpg')"></image>
|
||
|
||
<text style="font-size: 24rpx; color: #333333; position: absolute; left: 146rpx; top: 34rpx;">{{
|
||
bonusData.title }}</text>
|
||
|
||
<text style="font-size: 18rpx; color: #FF862D; position: absolute; left: 146rpx; top: 68rpx;">{{
|
||
bonusData.tips }}</text>
|
||
|
||
<text style="font-size: 16rpx; color: #999999; position: absolute; left: 146rpx; top: 102rpx;">{{
|
||
bonusData.time }}</text>
|
||
|
||
<view class="row center" style="position: absolute; left: 470rpx; top: 68rpx;">
|
||
<image style="width: 18rpx; height: 20rpx;" :src="$img1('checkin/Fire.png')" mode=""></image>
|
||
<text style="font-size: 16rpx; color: #999999; margin-left: 8rpx;">{{ bonusData.popularity }}</text>
|
||
</view>
|
||
<button open-type="share" class="button"
|
||
style="position: absolute; top: 50rpx; right: 24rpx; width: 50rpx; height: 50rpx; border: none; padding: 0; margin: 0; line-height: 1; ">
|
||
</button>
|
||
|
||
</view>
|
||
|
||
|
||
<view class="content-area" :class="{ 'show': contentShow }"
|
||
style="width: 686rpx; height: 1010rpx; background-color: #FFFFFF; border-radius: 16rpx; margin: 24rpx auto 0;">
|
||
|
||
<view class="tab">
|
||
<view class="tab-item center relative" v-for="(item, i) in tabList" :key="i"
|
||
:class="[currentTab == i ? 'act' : 'unact', { 'show': tabsShow[i] }]" @click="handleTabChange(i)">
|
||
<text>{{ item }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 赏品预览 -->
|
||
<view v-if="currentTab == 0" scroll-y="true" class="" style="width: 100%; height: 900rpx;">
|
||
<view style="height:30rpx">
|
||
<view
|
||
style="display: flex; justify-content: center; align-items: center; height:75%;margin-top: 10rpx;">
|
||
<view style="width: 280rpx; text-align: center;">
|
||
<text style="color: #333333; font-size: 24rpx;">参考价:{{ getGoodsListName }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="swiper-container">
|
||
<swiper class="swiper-box" :current="currentItemId" :autoplay="false" @change="handleSwiperChange"
|
||
:indicator-dots="false" :circular="true" :interval="3000">
|
||
<swiper-item v-for="(item, index) in goodsList" :key="index" :item-id="item.index">
|
||
<view class="swiper-item-content">
|
||
<view class="item-background">
|
||
<image :src="item.imgurl_detail" class="item-image"></image>
|
||
</view>
|
||
</view>
|
||
<view class="item-bottom"></view>
|
||
</swiper-item>
|
||
</swiper>
|
||
</view>
|
||
<scroll-view scroll-y="true" style="width: 100%; height:400rpx;">
|
||
<view class="grid-container">
|
||
<view @click=" currentItemId = item.index" class="grid-item column align-center"
|
||
v-for="(item, index) in goodsList" :key="index" style="">
|
||
<image style="width: 112rpx; height: 112rpx;border-radius:25rpx;" :src="item.imgUrl">
|
||
</image>
|
||
<text style="color: #999999; font-size: 16rpx; margin-top: 16rpx;">{{ item.title }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
</view>
|
||
|
||
|
||
<scroll-view v-if="currentTab == 1" scroll-y="true" style="width: 100%; height: 890rpx; padding: 24rpx;">
|
||
<view class="row align-center participant-row" :class="{ 'show': participantRowsShow[index] }"
|
||
v-for="(item, index) in participantList" :key="index" style="height: 76rpx; margin-bottom: 24rpx;">
|
||
|
||
<view class="center" style="width: 30rpx;">
|
||
<text style="color: #999999; font-size: 20rpx;">{{ index + 1 }}</text>
|
||
</view>
|
||
|
||
|
||
<image :src="item.avatar"
|
||
style="width: 76rpx; height: 76rpx; background-color: #D8D8D8; border-radius: 50%; margin-left: 24rpx;"
|
||
mode=""></image>
|
||
|
||
<view class="column" style="margin-left: 16rpx;">
|
||
<text style="color: #333333; font-size: 20rpx;">{{ item.name }}</text>
|
||
<text style="color: #999999; font-size: 16rpx; margin-top: 12rpx;">{{ item.time }}</text>
|
||
</view>
|
||
|
||
</view>
|
||
</scroll-view>
|
||
<scroll-view v-if="currentTab == 2" scroll-y="true" style="width: 100%; height: 890rpx; padding: 24rpx;">
|
||
<view class="row align-center award-row" :class="{ 'show': awardRowsShow[index] }"
|
||
v-for="(item, index) in awardRecordList" :key="index" style="height: 76rpx; margin-bottom: 24rpx;">
|
||
|
||
<view class="center" style="width: 30rpx;">
|
||
<text style="color: #999999; font-size: 20rpx;">{{ index + 1 }}</text>
|
||
</view>
|
||
<image :src="item.avatar"
|
||
style="width: 76rpx; height: 76rpx; background-color: #D8D8D8; border-radius: 50%; margin-left: 24rpx;"
|
||
mode=""></image>
|
||
<view class="column" style="margin-left: 16rpx;">
|
||
<text style="color: #333333; font-size: 20rpx;">{{ item.name }}</text>
|
||
<text style="color: #999999; font-size: 16rpx; margin-top: 12rpx;">{{ item.time }}</text>
|
||
</view>
|
||
<view class="row center" style="position: absolute; right: 56rpx;">
|
||
<image v-if="item.shang_id == 115" :src="$img1('checkin/Jackpot.png')"
|
||
style="width: 46rpx; height: 26rpx;" mode=""></image>
|
||
<text style="color: #999999; font-size: 20rpx; margin-left: 16rpx;">{{ item.award }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
<view class="column align-center"
|
||
style="width: 100%; height: 198rpx; background-color: #fff; margin-top: 8rpx;">
|
||
|
||
<view class="participation-button" :class="{ 'show': buttonShow, 'pulse': buttonPulse }"
|
||
@click="handleButtonPulse">
|
||
<text class="button-text">{{ buttonText }}</text>
|
||
</view>
|
||
<text style="color: #8A8A8A; font-size: 20rpx; font-weight: 400; margin-top: 12rpx;">{{ remainingTime
|
||
}}</text>
|
||
|
||
</view>
|
||
<OrderConfirmPopupFlw v-if="orderData.goods != null" ref="buyPop" :order-data="orderData" :use-money="useMoney"
|
||
@change-pay="changePay" :use-money2="useMoney2" :use-integral="useIntegral" :is-agree="isAgree"
|
||
:send-rule-data="sendRuleData" :buy-num="1" @close="close('buyPop')" @toggle-agree="isAgree = !isAgree"
|
||
@confirm="$c.noDouble1(confirmSubmit, [1, 1], loading)">
|
||
</OrderConfirmPopupFlw>
|
||
|
||
|
||
<!-- 条件不足弹窗 -->
|
||
<uni-popup ref="condition" type="center" :animation="true" :mask-click="true">
|
||
|
||
<view class="popup-container">
|
||
<view class="popup-title">
|
||
参与提示
|
||
</view>
|
||
<view class="popup-content">
|
||
提示:需在指定时间{{ bonusData.start_time }}-{{ bonusData.end_time }}消耗达到{{ bonusData.choujiang_xianzhi
|
||
}}钻石,即可加入房间,还需{{ $c.removeTrailingZeros(remainingDiamond) }}钻石.
|
||
</view>
|
||
</view>
|
||
|
||
<view class="popup-buttons">
|
||
<view class="popup-button cancel-button" @click="$refs.condition.close()">
|
||
<text>取消</text>
|
||
</view>
|
||
|
||
<view class="popup-button confirm-button" @click="toHome()">
|
||
<text>去抽赏</text>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</page-container>
|
||
</template>
|
||
|
||
<script>
|
||
import { getWelfareHouseDetail, getWelfareParticipants, getWelfareRecords, buyWelfareHouse } from '@/common/server/welfare.js';
|
||
import { calcOrderMoney } from '@/common/server/order.js';
|
||
import OrderConfirmPopupFlw from '@/components/order-confirm-popup/order-confirm-popup-flw.vue';
|
||
import PageContainer from '@/components/page-container/page-container.vue';
|
||
|
||
export default {
|
||
components: {
|
||
OrderConfirmPopupFlw,
|
||
PageContainer
|
||
},
|
||
onShareAppMessage() {
|
||
let imageUrl = this.$config.getShareImageUrl();
|
||
return {
|
||
imageUrl: imageUrl,
|
||
title: this.bonusData.title,
|
||
path: '/pages/infinite/bonus_house_details?goods_id=' + this.goods_id
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
currentItemId: 0,
|
||
currentTab: 0,
|
||
bonusData: {
|
||
title: "",
|
||
tips: "",
|
||
time: "",
|
||
popularity: 0, // 热度
|
||
open_time: '', //开奖时间
|
||
start_time: '', //开始时间
|
||
end_time: '', //结束时间
|
||
choujiang_xianzhi: 0 // 抽奖限制金额
|
||
},
|
||
goodsList: [],
|
||
participantList: [],
|
||
awardRecordList: [],
|
||
tabList: [
|
||
"赏品预览", "参与人数", "赏品记录"
|
||
],
|
||
goods_id: 0,
|
||
remainingTime: "0天00:00:00",
|
||
countdownTimer: null,
|
||
endTime: null,
|
||
currentServerTime: null,
|
||
buttonText: "马上参与",
|
||
user_total_consumption: 0, // 用户抽奖范围内消耗的金额
|
||
orderData: {
|
||
goods: null,
|
||
"use_integral": 0,
|
||
"use_integral_money": 0,
|
||
"money": 0,
|
||
"use_money": 0,
|
||
"score": "0.00",
|
||
"use_score": 0,
|
||
},
|
||
pageData: "",
|
||
logList: [],
|
||
sendRuleData: "",
|
||
useMoney: true,
|
||
useIntegral: false,
|
||
useMoney2: false,
|
||
isAgree: true,
|
||
loading: false,
|
||
user_count: 0, //用户已经购买的次数
|
||
|
||
// 动画状态控制变量
|
||
headerShow: false,
|
||
contentShow: false,
|
||
buttonShow: false,
|
||
tabsShow: [false, false, false],
|
||
participantRowsShow: [],
|
||
awardRowsShow: [],
|
||
|
||
// 按钮脉冲动画
|
||
buttonPulse: false
|
||
}
|
||
},
|
||
computed: {
|
||
getGoodsListName() {
|
||
if (this.goodsList.length > 0) {
|
||
return this.goodsList[this.currentItemId].title
|
||
}
|
||
return '';
|
||
},
|
||
remainingDiamond() {
|
||
let t = (this.bonusData.choujiang_xianzhi - this.user_total_consumption).toFixed(2);
|
||
return t > 0 ? t : 0;
|
||
}
|
||
},
|
||
async onLoad(options) {
|
||
console.log(options)
|
||
this.goods_id = options.goods_id
|
||
await this.load(options.goods_id)
|
||
|
||
// 添加页面加载动画
|
||
setTimeout(() => {
|
||
this.applyPageTransitions();
|
||
}, 100);
|
||
},
|
||
methods: {
|
||
handleSwiperChange(e) {
|
||
this.currentItemId = e.detail.current
|
||
},
|
||
async load(goods_id) {
|
||
// API: fuliwu_detail
|
||
const res = await getWelfareHouseDetail(goods_id);
|
||
console.log(res)
|
||
|
||
if (res.status === 1 && res.data) {
|
||
const {
|
||
goods,
|
||
goodslist,
|
||
joinCount,
|
||
currentTime,
|
||
status,
|
||
statusText,
|
||
userConsumption,
|
||
userCount
|
||
} = res.data;
|
||
this.orderData.goods = goods;
|
||
// 更新福利屋基本信息
|
||
this.bonusData = {
|
||
title: goods.title,
|
||
tips: goods.goodsDescribe,
|
||
time: goods.flwStartTime + '-' + goods.flwEndTime,
|
||
open_time: goods.openTime,
|
||
start_time: goods.flwStartTime,
|
||
end_time: goods.flwEndTime,
|
||
choujiang_xianzhi: goods.choujiangXianzhi,
|
||
popularity: joinCount || 0,
|
||
quanju_xiangou: goods.quanjuXiangou,
|
||
price: goods.price
|
||
};
|
||
if (userConsumption != null) {
|
||
this.user_total_consumption = userConsumption.totalAmount || 0;
|
||
}
|
||
if (userCount != null) {
|
||
this.user_count = userCount;
|
||
}
|
||
let index = 0;
|
||
this.goodsList.splice(0, this.goodsList.length)
|
||
// 更新赏品列表
|
||
goodslist.forEach(item => {
|
||
for (let i = 0; i < item.stock; i++) {
|
||
this.goodsList.push({
|
||
index,
|
||
imgUrl: item.imgurl,
|
||
title: item.title,
|
||
id: item.id,
|
||
stock: item.stock,
|
||
realPrice: item.price,
|
||
sortIndex: item.sort,
|
||
type: item.shangTitle,
|
||
typeColor: item.shangColor,
|
||
imgurl_detail: item.imgurlDetail
|
||
});
|
||
index++;
|
||
}
|
||
})
|
||
|
||
// 计算倒计时
|
||
this.calculateRemainingTime(goods.openTime, goods.flwStartTime, currentTime);
|
||
this.startCountdownTimer(goods.openTime, goods.flwStartTime, currentTime);
|
||
|
||
// 其他状态信息
|
||
this.activityStatus = status;
|
||
this.activityStatusText = statusText;
|
||
|
||
// 获取参与人数和赏品记录列表
|
||
if (joinCount > 0) {
|
||
await this.loadParticipants(goods_id);
|
||
await this.loadAwardRecords(goods_id);
|
||
}
|
||
}
|
||
},
|
||
changePay(e) {
|
||
this[e] = !this[e];
|
||
console.log('aaasdas');
|
||
|
||
this.confirmSubmit([0, 1]);
|
||
},
|
||
async confirmSubmit([type, num, fromNotice = false]) {
|
||
let data = {
|
||
goods_id: this.goods_id,
|
||
prize_num: 1,
|
||
num: 1,
|
||
use_money_is: this.useMoney ? 1 : 2,
|
||
use_integral_is: this.useIntegral ? 1 : 2,
|
||
coupon_id: "",
|
||
use_money2_is: this.useMoney2 ? 1 : 2
|
||
};
|
||
|
||
this.buyNum = num;
|
||
|
||
let res;
|
||
if (type == 1) {
|
||
// API: fuliwu_buy
|
||
res = await buyWelfareHouse(data);
|
||
} else {
|
||
// API: ordermoney
|
||
res = await calcOrderMoney(data);
|
||
}
|
||
|
||
if (res.status == 1) {
|
||
if (type == 0) {
|
||
this.orderData = res.data;
|
||
|
||
// 使用this.$nextTick确保视图已更新,组件已挂载
|
||
this.$nextTick(() => {
|
||
if (this.$refs.buyPop) {
|
||
this.$refs.buyPop.open();
|
||
} else {
|
||
console.error('buyPop组件引用不存在');
|
||
}
|
||
});
|
||
}
|
||
if (type == 1) {
|
||
this.close("buyPop");
|
||
|
||
if (res.data.status == 1) {
|
||
const status = await this.$platform.pay({
|
||
data: res.data.res
|
||
},this);
|
||
|
||
if (status == "success") {
|
||
this.load(this.goods_id);
|
||
}
|
||
} else {
|
||
this.$c.toast({
|
||
title: res.msg,
|
||
duration: 500,
|
||
success: () => {
|
||
this.load(this.goods_id);
|
||
},
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
if (type == 1) {
|
||
this.close("buyPop");
|
||
}
|
||
},
|
||
calculateRemainingTime(openTime, startTime, currentTime) {
|
||
// 将时间字符串转为时间对象
|
||
const endDate = new Date(openTime.replace(/-/g, '/'));
|
||
const startDate = new Date(startTime.replace(/-/g, '/'));
|
||
const currentDate = new Date(currentTime.replace(/-/g, '/'));
|
||
|
||
// 保存结束时间和当前服务器时间,用于实时倒计时
|
||
this.endTime = endDate;
|
||
this.currentServerTime = currentDate;
|
||
|
||
// 判断当前时间与开始时间和结束时间的关系
|
||
if (currentDate > endDate) {
|
||
this.remainingTime = "活动已结束";
|
||
return;
|
||
} else if (currentDate < startDate) {
|
||
this.remainingTime = this.formatRemainingTime(startDate - currentDate, "距离开始时间:");
|
||
return;
|
||
} else if (currentDate >= startDate && currentDate <= endDate) {
|
||
this.remainingTime = this.formatRemainingTime(endDate - currentDate, "距离开奖时间:");
|
||
return;
|
||
}
|
||
},
|
||
|
||
formatRemainingTime(diffTime, prefix) {
|
||
// 转换为天、时、分、秒
|
||
const days = Math.floor(diffTime / (24 * 60 * 60 * 1000));
|
||
diffTime = diffTime % (24 * 60 * 60 * 1000);
|
||
const hours = Math.floor(diffTime / (60 * 60 * 1000));
|
||
diffTime = diffTime % (60 * 60 * 1000);
|
||
const minutes = Math.floor(diffTime / (60 * 1000));
|
||
diffTime = diffTime % (60 * 1000);
|
||
const seconds = Math.floor(diffTime / 1000);
|
||
|
||
// 格式化时间
|
||
return `${prefix}${days}天${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||
},
|
||
|
||
startCountdownTimer(openTime, startTime, currentTime) {
|
||
// 清除之前可能存在的计时器
|
||
if (this.countdownTimer) {
|
||
clearInterval(this.countdownTimer);
|
||
}
|
||
|
||
// 保存结束时间和当前时间的时间差(毫秒)
|
||
const endDate = new Date(openTime.replace(/-/g, '/'));
|
||
const startDate = new Date(startTime.replace(/-/g, '/'));
|
||
const currentDate = new Date(currentTime.replace(/-/g, '/'));
|
||
const serverClientTimeDiff = currentDate.getTime() - new Date().getTime();
|
||
|
||
// 设置每秒更新一次倒计时
|
||
this.countdownTimer = setInterval(() => {
|
||
// 获取当前客户端时间并加上与服务器的时间差,以获得准确的服务器当前时间
|
||
const now = new Date();
|
||
const serverNow = new Date(now.getTime() + serverClientTimeDiff);
|
||
this.updateButtonState();
|
||
// 判断当前时间与开始时间和结束时间的关系
|
||
if (serverNow > endDate) {
|
||
clearInterval(this.countdownTimer);
|
||
this.remainingTime = "活动已结束";
|
||
return;
|
||
} else if (serverNow < startDate) {
|
||
this.remainingTime = this.formatRemainingTime(startDate - serverNow, "距离开始时间:");
|
||
return;
|
||
} else if (serverNow >= startDate && serverNow <= endDate) {
|
||
this.remainingTime = this.formatRemainingTime(endDate - serverNow, "距离开奖时间:");
|
||
return;
|
||
}
|
||
|
||
|
||
}, 1000);
|
||
|
||
|
||
},
|
||
|
||
onUnload() {
|
||
// 组件卸载时清除计时器
|
||
if (this.countdownTimer) {
|
||
clearInterval(this.countdownTimer);
|
||
this.countdownTimer = null;
|
||
}
|
||
},
|
||
|
||
async loadParticipants(goods_id) {
|
||
// 这里应该调用获取参与人数列表的接口
|
||
try {
|
||
// API: fuliwu_participants
|
||
const res = await getWelfareParticipants({ goods_id });
|
||
|
||
if (res.status === 1 && res.data && res.data.list) {
|
||
this.participantList.splice(0, this.participantList.length)
|
||
this.participantList = res.data.list.map(item => ({
|
||
avatar: item.avatar || "",
|
||
name: item.nickname || "用户",
|
||
time: item.createTime || ""
|
||
}));
|
||
}
|
||
} catch (error) {
|
||
console.error("加载参与人数列表失败", error);
|
||
}
|
||
|
||
if (this.currentTab === 1) {
|
||
setTimeout(() => {
|
||
this.animateListItems('participant-row');
|
||
}, 100);
|
||
}
|
||
},
|
||
|
||
async loadAwardRecords(goods_id) {
|
||
// 这里应该调用获取赏品记录的接口
|
||
try {
|
||
// API: fuliwu_records
|
||
const res = await getWelfareRecords({ goods_id });
|
||
|
||
if (res.status === 1 && res.data && res.data.list) {
|
||
this.awardRecordList = res.data.list.map(item => ({
|
||
avatar: item.avatar || "",
|
||
name: item.nickname || "用户",
|
||
time: item.createTime || "",
|
||
award: item.goodslistTitle || "钻石*0",
|
||
shang_id: item.shangId
|
||
}));
|
||
}
|
||
} catch (error) {
|
||
console.error("加载赏品记录失败", error);
|
||
}
|
||
|
||
if (this.currentTab === 2) {
|
||
setTimeout(() => {
|
||
this.animateListItems('award-row');
|
||
}, 100);
|
||
}
|
||
},
|
||
|
||
async handleTabChange(index) {
|
||
this.currentTab = index;
|
||
// 切换到参与人数或赏品记录时,重新加载数据
|
||
if (index === 1) {
|
||
await this.loadParticipants(this.goods_id);
|
||
} else if (index === 2) {
|
||
await this.loadAwardRecords(this.goods_id);
|
||
}
|
||
},
|
||
|
||
// 添加列表项动画方法
|
||
animateListItems(className) {
|
||
// 根据列表类型初始化动画状态数组
|
||
if (className === 'participant-row') {
|
||
this.participantRowsShow = Array(this.participantList.length).fill(false);
|
||
|
||
// 逐个显示列表项
|
||
for (let i = 0; i < this.participantList.length; i++) {
|
||
((index) => {
|
||
setTimeout(() => {
|
||
this.$set(this.participantRowsShow, index, true);
|
||
}, index * 50);
|
||
})(i);
|
||
}
|
||
} else if (className === 'award-row') {
|
||
this.awardRowsShow = Array(this.awardRecordList.length).fill(false);
|
||
|
||
// 逐个显示列表项
|
||
for (let i = 0; i < this.awardRecordList.length; i++) {
|
||
((index) => {
|
||
setTimeout(() => {
|
||
this.$set(this.awardRowsShow, index, true);
|
||
}, index * 50);
|
||
})(i);
|
||
}
|
||
}
|
||
},
|
||
|
||
updateButtonState() {
|
||
const currentDate = new Date();
|
||
const startDate = new Date(this.bonusData.start_time.replace(/-/g, '/'));
|
||
const endDate = new Date(this.bonusData.end_time.replace(/-/g, '/'));
|
||
const openDate = new Date(this.bonusData.open_time.replace(/-/g, '/'));
|
||
// console.log(currentDate,startDate);
|
||
|
||
if (currentDate < startDate) {
|
||
this.buttonText = "未开始";
|
||
} else if (currentDate >= startDate && currentDate <= endDate) {
|
||
if (this.user_count > 0 && this.user_count >= this.bonusData.quanju_xiangou) {
|
||
this.buttonText = "等待开奖中";
|
||
return;
|
||
}
|
||
this.buttonText = "马上参与";
|
||
} else if (currentDate > endDate && currentDate < openDate) {
|
||
this.buttonText = "等待开奖中";
|
||
} else if (currentDate >= openDate) {
|
||
this.buttonText = "活动已结束";
|
||
}
|
||
},
|
||
|
||
handleButtonPulse() {
|
||
// 添加动画类
|
||
this.buttonPulse = true;
|
||
setTimeout(() => {
|
||
this.buttonPulse = false;
|
||
}, 400); // 动画时长结束后移除类
|
||
|
||
// 调用原始点击处理程序
|
||
this.handleButtonClick();
|
||
},
|
||
|
||
handleButtonClick() {
|
||
if (this.buttonText === "未开始") {
|
||
uni.showToast({
|
||
title: "活动未开始",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
} else if (this.buttonText === "等待开奖中") {
|
||
uni.showToast({
|
||
title: "等待开奖中",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
} else if (this.buttonText === "活动已结束") {
|
||
uni.showToast({
|
||
title: "活动已结束",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
if (this.user_count > 0 && this.user_count >= this.bonusData.quanju_xiangou) {
|
||
uni.showToast({
|
||
title: "当前活动限购" + this.bonusData.quanju_xiangou + "次",
|
||
icon: "none"
|
||
});
|
||
return;
|
||
}
|
||
//判断用户今天消费的金额是否满足参与条件
|
||
if (this.user_total_consumption < this.bonusData.choujiang_xianzhi) {
|
||
this.$refs.condition.open();
|
||
// uni.showToast({
|
||
// title: "消费金额不足",
|
||
// icon: "none"
|
||
// });
|
||
return;
|
||
}
|
||
console.log(this.user_total_consumption, this.bonusData.choujiang_xianzhi);
|
||
if (this.bonusData.price == 0) {
|
||
this.useMoney = true;
|
||
this.confirmSubmit([1, 1]);
|
||
return;
|
||
}
|
||
this.confirmSubmit([0, 1])
|
||
// if (this.$refs['buyPop']) {
|
||
// this.$refs['buyPop'].open();
|
||
// } else {
|
||
// console.error("buyPop is undefined");
|
||
// }
|
||
|
||
},
|
||
close(e) {
|
||
console.log('关闭弹窗:', e, this.$refs[e]);
|
||
if (e === 'buyPop') {
|
||
if (this.$refs[e]) {
|
||
this.$refs[e].close();
|
||
} else {
|
||
console.error('找不到buyPop组件引用');
|
||
}
|
||
} else {
|
||
if (this.$refs[e]) {
|
||
this.$refs[e].close();
|
||
} else {
|
||
console.error('找不到组件引用:', e);
|
||
}
|
||
}
|
||
|
||
if (e == "resPop") {
|
||
if (this.prizeData && this.prizeData["user_coupon"] != null) {
|
||
this.$refs["couponPop"].open(this.prizeData["user_coupon"]);
|
||
}
|
||
}
|
||
},
|
||
|
||
toHome() {
|
||
this.$customRouter.navigateTo('/pages/shouye/index', {}, 'reLaunch');
|
||
},
|
||
|
||
applyPageTransitions() {
|
||
// 头部信息
|
||
this.headerShow = true;
|
||
|
||
// 标签
|
||
setTimeout(() => { this.tabsShow[0] = true; }, 100);
|
||
setTimeout(() => { this.tabsShow[1] = true; }, 200);
|
||
setTimeout(() => { this.tabsShow[2] = true; }, 300);
|
||
|
||
// 内容区
|
||
setTimeout(() => { this.contentShow = true; }, 200);
|
||
|
||
// 按钮
|
||
setTimeout(() => { this.buttonShow = true; }, 300);
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.tab {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 10rpx 60rpx;
|
||
position: relative;
|
||
z-index: 1;
|
||
|
||
|
||
.tab-item {
|
||
width: 155rpx;
|
||
height: 68rpx;
|
||
position: relative;
|
||
margin-right: 25rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
&.act {
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 48rpx;
|
||
height: 4rpx;
|
||
background: #333333;
|
||
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
|
||
animation: fadeInWidth 0.3s forwards;
|
||
}
|
||
}
|
||
|
||
&.unact {
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #CCCCCC;
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 0;
|
||
height: 4rpx;
|
||
background: #333333;
|
||
transition: all 0.3s ease;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes fadeInWidth {
|
||
from {
|
||
width: 0;
|
||
}
|
||
|
||
to {
|
||
width: 48rpx;
|
||
}
|
||
}
|
||
|
||
.grid-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 124rpx);
|
||
gap: 24rpx;
|
||
width: 580rpx;
|
||
margin: 10rpx auto 0;
|
||
padding-bottom: 20rpx;
|
||
|
||
|
||
}
|
||
|
||
.grid-item {
|
||
width: 142rpx;
|
||
height: 150rpx;
|
||
transition: all 0.3s ease;
|
||
padding: 8rpx;
|
||
border-radius: 12rpx;
|
||
position: relative;
|
||
|
||
&:active {
|
||
transform: translateY(-6rpx) scale(1.05);
|
||
background-color: rgba(0, 0, 0, 0.02);
|
||
}
|
||
|
||
image {
|
||
transition: all 0.25s ease;
|
||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
&:active image {
|
||
box-shadow: 0 8rpx 12rpx rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
text {
|
||
transition: color 0.25s ease;
|
||
}
|
||
|
||
&:active text {
|
||
color: #666 !important;
|
||
}
|
||
}
|
||
|
||
.button {
|
||
background-image: url($imgurl + 'checkin/ic_share.png');
|
||
background-size: 100% 100%;
|
||
transition: all 0.3s ease;
|
||
position: relative;
|
||
overflow: visible;
|
||
border: none !important;
|
||
outline: none !important;
|
||
|
||
&::after {
|
||
border: none !important;
|
||
}
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -5rpx;
|
||
right: -5rpx;
|
||
bottom: -5rpx;
|
||
left: -5rpx;
|
||
border-radius: 50%;
|
||
background-color: rgba(0, 0, 0, 0.05);
|
||
transform: scale(0);
|
||
opacity: 0;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
&:active {
|
||
transform: scale(0.9) rotate(15deg);
|
||
}
|
||
|
||
&:active::before {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
.swiper-container {
|
||
width: 544rpx;
|
||
height: 500rpx;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.swiper-box {
|
||
height: 500rpx;
|
||
}
|
||
|
||
.swiper-item-content {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 75%;
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
.item-background {
|
||
background-image: url($baseurl +'flw_bj.png');
|
||
background-size: 100% 100%;
|
||
width: 280rpx;
|
||
height: 352rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 2;
|
||
}
|
||
|
||
.item-image {
|
||
width: 154rpx;
|
||
height: 166rpx;
|
||
}
|
||
|
||
.item-bottom {
|
||
background-image: url($baseurl +'flw_dibu.png');
|
||
background-size: 100% 100%;
|
||
width: 100%;
|
||
height: 122rpx;
|
||
position: relative;
|
||
top: -15%;
|
||
z-index: 1;
|
||
}
|
||
|
||
.participation-button {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 340rpx;
|
||
height: 84rpx;
|
||
background-color: #D8FD24;
|
||
border-radius: 16rpx;
|
||
margin-top: 32rpx;
|
||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
// 页面加载动画
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: transform 0.5s ease, opacity 0.5s ease, background-color 0.2s ease, box-shadow 0.2s ease;
|
||
transition-delay: 0.3s;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
&.pulse {
|
||
animation: buttonPulse 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
}
|
||
}
|
||
|
||
.button-text {
|
||
color: #333333;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
z-index: 2;
|
||
position: relative;
|
||
}
|
||
|
||
.popup-container {
|
||
width: 636rpx;
|
||
background-color: #FFFFFF;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
transform: scale(0.9);
|
||
opacity: 0;
|
||
animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
|
||
}
|
||
|
||
.popup-title {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 35rpx;
|
||
background-color: #f9f9f9;
|
||
position: relative;
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 10%;
|
||
width: 80%;
|
||
height: 1px;
|
||
background-color: #eee;
|
||
}
|
||
}
|
||
|
||
.popup-content {
|
||
padding: 24rpx;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.popup-buttons {
|
||
display: flex;
|
||
width: 636rpx;
|
||
justify-content: space-around;
|
||
margin-top: 32rpx;
|
||
animation: slideUp 0.4s ease-out forwards;
|
||
animation-delay: 0.1s;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
|
||
.popup-button {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 200rpx;
|
||
height: 68rpx;
|
||
border-radius: 16rpx;
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
transition: all 0.25s ease;
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
background-color: rgba(255, 255, 255, 0.3);
|
||
border-radius: 50%;
|
||
transform: translate(-50%, -50%) scale(0);
|
||
opacity: 0;
|
||
transition: all 0.3s ease-out;
|
||
}
|
||
|
||
&:active::after {
|
||
transform: translate(-50%, -50%) scale(3);
|
||
opacity: 0;
|
||
}
|
||
|
||
text {
|
||
position: relative;
|
||
z-index: 1;
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.cancel-button {
|
||
background-color: #FFFFFF;
|
||
border: 1px solid #eee;
|
||
|
||
text {
|
||
color: #333333;
|
||
}
|
||
|
||
&:active {
|
||
background-color: #f5f5f5;
|
||
}
|
||
}
|
||
|
||
.confirm-button {
|
||
background-color: #CDEF27;
|
||
box-shadow: 0 4rpx 8rpx rgba(205, 239, 39, 0.3);
|
||
|
||
text {
|
||
color: #333333;
|
||
}
|
||
|
||
&:active {
|
||
background-color: #b9d721;
|
||
box-shadow: 0 2rpx 4rpx rgba(205, 239, 39, 0.2);
|
||
}
|
||
}
|
||
|
||
@keyframes popIn {
|
||
from {
|
||
transform: scale(0.9);
|
||
opacity: 0;
|
||
}
|
||
|
||
to {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes slideUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.participant-row {
|
||
opacity: 0;
|
||
transform: translateX(-20rpx);
|
||
transition: all 0.4s ease;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateX(0);
|
||
}
|
||
}
|
||
|
||
.award-row {
|
||
opacity: 0;
|
||
transform: translateX(-20rpx);
|
||
transition: all 0.4s ease;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateX(0);
|
||
}
|
||
}
|
||
|
||
.header-info {
|
||
opacity: 0;
|
||
transform: translateY(-20rpx);
|
||
transition: all 0.5s ease;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.tab-item {
|
||
opacity: 0;
|
||
transform: translateY(10rpx);
|
||
transition: all 0.4s ease;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.content-area {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
transition-delay: 0.2s;
|
||
|
||
&.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
@keyframes buttonPulse {
|
||
0% {
|
||
transform: scale(1);
|
||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
40% {
|
||
transform: scale(0.92);
|
||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
80% {
|
||
transform: scale(1.05);
|
||
box-shadow: 0 6rpx 10rpx rgba(0, 0, 0, 0.15);
|
||
background-color: #e0ff3a;
|
||
}
|
||
|
||
100% {
|
||
transform: scale(1);
|
||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
}
|
||
</style> |