yfs/pages/infinite/bonus_house_details.vue
2025-04-07 06:03:14 +08:00

678 lines
21 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>
<page-container title="福利屋详情" :showBack="true" >
<view class="relative"
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('checkin/logo2.png')"></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>
<image style="width: 50rpx; height: 50rpx; position: absolute; top: 50rpx; right: 24rpx;"
:src="$img1('checkin/ic_share.png')" mode=""></image>
</view>
<view class=""
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'" @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="" style="width: 544rpx; height: 500rpx; margin: 0 auto 0;">
<swiper class="swiper-box" :current="currentItemId" :style="{ height: '500rpx' }" :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
style="display: flex; justify-content: center; align-items: center; height:75%;margin-top: 10rpx;">
<view
style="background-image: url('https://mh.shhuanmeng.com/flw_bj.png');background-size: 100% 100%; width: 280rpx; height:352rpx; display: flex; justify-content: center; align-items: center;z-index: 2;">
<image :src="item.imgurl_detail" style="width:154rpx; height:166rpx;"></image>
</view>
</view>
<view
style="background-image: url('https://mh.shhuanmeng.com/flw_dibu.png');background-size: 100% 100%;width: 100%; height: 122rpx;position: relative;top:-15%;z-index: 1;">
</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" 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 relative" 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="center"
style="width: 340rpx; height: 84rpx; background-color: #D8FD24; border-radius: 16rpx; margin-top: 32rpx;"
@click="handleButtonClick">
<text style="color: #333333; font-size: 32rpx; font-weight: 600;">{{ 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">
<view class="justify-center"
style="width: 636rpx; height: 422rpx; background-color: #FFFFFF; border-radius: 16rpx;">
<text style="font-size: 28rpx; color: #333333; font-weight: 600;padding-top: 26rpx;">规则说明</text>
</view>
<view class="flex row" style="width: 636rpx; justify-content: space-around; margin-top: 32rpx;">
<view class="center" @click="$refs.condition.close()"
style="width: 200rpx; height: 68rpx; background-color: #FFFFFF; border-radius: 16rpx;">
<text style="font-size: 24rpx; color: #333333; font-weight: 600;">取消</text>
</view>
<view class="center" @click="toHome()"
style="width: 200rpx; height: 68rpx; background-color: #CDEF27;border-radius: 16rpx;">
<text style="font-size: 24rpx; color: #333333; font-weight: 600;">去抽赏</text>
</view>
</view>
</uni-popup>
</page-container>
</template>
<script>
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
},
data() {
return {
currentItemId: 0,
currentTab: 0,
bonusData: {
title: "新人消费满5元福利屋",
tips: "消费返利(所有参与者有机会获得奖励",
time: "2025-03-10 14:00",
popularity: 0, // 热度
open_time: '2025-03-10 14:00', //开奖时间
start_time: '2025-03-10 14:00', //开始时间
end_time: '2025-03-10 10:00', //结束时间
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 //用户已经购买的次数
}
},
computed: {
getGoodsListName() {
if (this.goodsList.length > 0) {
return this.goodsList[this.currentItemId].title
}
return 'aaa';
}
},
async onLoad(options) {
console.log(options)
this.goods_id = options.goods_id
await this.load(options.goods_id)
},
methods: {
handleSwiperChange(e) {
this.currentItemId = e.detail.current
},
async load(goods_id) {
const res = await this.req({
url: "fuliwu_detail",
data: {
goods_id: goods_id
}
})
console.log(res)
if (res.status === 1 && res.data) {
const {
goods,
goodslist,
join_count,
current_time,
status,
status_text,
user_consumption,
user_count
} = res.data;
this.orderData.goods = goods;
// 更新福利屋基本信息
this.bonusData = {
title: goods.title,
tips: goods.goods_describe,
time: goods.flw_start_time + '-' + goods.flw_end_time,
open_time: goods.open_time,
start_time: goods.flw_start_time,
end_time: goods.flw_end_time,
choujiang_xianzhi: goods.choujiang_xianzhi,
popularity: join_count || 0,
quanju_xiangou: goods.quanju_xiangou,
price: goods.price
};
if (user_consumption != null) {
this.user_total_consumption = user_consumption.total_consumed;
}
if (user_count != null) {
this.user_count = user_count;
}
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.shang_title,
typeColor: item.shang_color,
imgurl_detail: item.imgurl_detail
});
index++;
}
})
// 计算倒计时
this.calculateRemainingTime(goods.open_time, goods.flw_start_time, current_time);
this.startCountdownTimer(goods.open_time, goods.flw_start_time, current_time);
// 其他状态信息
this.activityStatus = status;
this.activityStatusText = status_text;
// 获取参与人数和赏品记录列表
if (join_count > 0) {
await this.loadParticipants(goods_id);
await this.loadAwardRecords(goods_id);
}
}
},
changePay(e) {
this[e] = !this[e];
console.log('aaasdas');
this.confirmSubmit([0, 1]);
},
confirmSubmit([type, num, fromNotice = false]) {
let url = "ordermoney";
if (type == 1) {
url = "orderbuy";
}
this.buyNum = num;
let data = {
goods_id: this.goods_id,
prize_num: 1,
goods_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.req({
url,
data,
success: async (res) => {
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.$c.wxMpPay({
data: res.data.res,
});
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);
// 判断当前时间与开始时间和结束时间的关系
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);
this.updateButtonState();
},
onUnload() {
// 组件卸载时清除计时器
if (this.countdownTimer) {
clearInterval(this.countdownTimer);
this.countdownTimer = null;
}
},
async loadParticipants(goods_id) {
// 这里应该调用获取参与人数列表的接口
// 示例代码,实际应替换为真实接口
try {
const res = await this.req({
url: "fuliwu_participants",
data: {
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.create_time || ""
}));
}
} catch (error) {
console.error("加载参与人数列表失败", error);
}
},
async loadAwardRecords(goods_id) {
// 这里应该调用获取赏品记录的接口
// 示例代码,实际应替换为真实接口
try {
const res = await this.req({
url: "fuliwu_records",
data: {
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.create_time || "",
award: item.goodslist_title || "钻石*0",
shang_id: item.shang_id
}));
}
} catch (error) {
console.error("加载赏品记录失败", error);
}
},
handleTabChange(index) {
this.currentTab = index
},
updateButtonState() {
const currentDate = new Date(this.currentServerTime);
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, '/'));
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 = "活动已结束";
}
},
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() {
uni.reLaunch({
url: '/pages/shouye/index'
});
}
}
}
</script>
<style lang="scss">
.tab {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 60rpx;
.tab-item {
width: 155rpx;
height: 68rpx;
position: relative;
margin-right: 25rpx;
&.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;
}
}
&.unact {
font-weight: 400;
font-size: 28rpx;
color: #CCCCCC;
}
}
}
.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;
}
</style>