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

455 lines
8.9 KiB
Vue

<template>
<page-container title="福利屋" :showBack="true">
<banner :type-id="8" :height="328"></banner>
<view class="tab-container">
<view class="tab">
<view class="tab-item1 center" @click="$refs.rulePop.getRule(20, '规则说明')">
<text>规则说明</text>
</view>
<view class="tab-item2 center" :class="[tabCur == 1 ? 'act' : 'unact']" @click="tabChange(1)">
<text>进行中</text>
</view>
<view class="tab-item3 center" :class="[tabCur == 2 ? 'act' : 'unact']" @click="tabChange(2)">
<text>已结束</text>
</view>
</view>
</view>
<!-- 内容列表区域 -->
<view class="benefits-container">
<!-- 进行中列表 -->
<template v-if="tabCur == 1">
<scroll-view scroll-y="true" class="benefits-scroll">
<!-- 已结束列表 -->
<view v-for="(item, index) in ongoingData" :key="index" class="benefit-item relative"
@click="$c.to({ url: '/pages/infinite/bonus_house_details?goods_id=' + item.id })">
<text class="benefit-title">{{ item.title }}</text>
<text class="benefit-tips">{{ item.tips }}</text>
<view class="action-btn center">
<text>马上参与</text>
</view>
<scroll-view scroll-x="true" class="goods-scroll">
<view v-for="(item1, index1) in item.GoodsList" :key="index1" class="goods-item relative">
<image class="goods-img" :src="item1.imgUrl">
</image>
<view class="goods-num center">
<text>x{{ item1.num }}</text>
</view>
</view>
</scroll-view>
<view class="divider"></view>
<view class="popularity center">
<image class="fire-icon" :src="$img1('checkin/Fire.png')"></image>
<text class="popularity-text">{{ item.Popularity }}</text>
</view>
<text class="time-text">{{ item.Time }}</text>
</view>
</scroll-view>
</template>
<template v-else>
<scroll-view scroll-y="true" class="benefits-scroll">
<view v-for="(item, index) in endedData" :key="index" class="benefit-item relative"
@click="$c.to({ url: '/pages/infinite/bonus_house_details?goods_id=' + item.id })">
<text class="benefit-title">{{ item.title }}</text>
<text class="benefit-tips">{{ item.tips }}</text>
<view class="action-btn center ended">
<text>已结束</text>
</view>
<scroll-view scroll-x="true" class="goods-scroll">
<view v-for="(item1, index1) in item.GoodsList" :key="index1" class="goods-item relative">
<image class="goods-img" :src="item1.imgUrl">
</image>
<view class="goods-num center">
<text>x{{ item1.num }}</text>
</view>
</view>
</scroll-view>
<view class="divider"></view>
<view class="popularity center">
<image class="fire-icon" :src="$img1('checkin/Fire.png')"></image>
<text class="popularity-text">{{ item.Popularity }}</text>
</view>
<text class="time-text">{{ item.Time }}</text>
</view>
</scroll-view>
</template>
</view>
<view class="btn-group row center">
<view class="my-coupon center" @click="$c.to({ url: '/pages/infinite/my_coupons' })">
<text>我的卡券</text>
</view>
<view class="reward-record center" @click="$c.to({ url: '/pages/infinite/reward_records' })">
<text>赏品记录</text>
</view>
</view>
<rule-pop ref="rulePop"></rule-pop>
</page-container>
</template>
<script>
import PageContainer from '@/components/page-container/page-container.vue'
export default {
components: {
PageContainer
},
data() {
return {
tabCur: 1,
ongoingData: [], // 进行中数据
endedData: [], // 已结束数据
loading: false
}
},
async onLoad() {
this.loadOngoingData();
},
methods: {
// 加载进行中的福利屋数据
async loadOngoingData() {
if (this.loading) return;
this.loading = true;
try {
const res = await this.req({
url: "fuliwu", // 进行中接口
data: {
type: 1
}
});
if (res?.data?.data) {
this.ongoingData = this.formatBenefitsData(res.data.data);
}
} catch (error) {
console.error('加载进行中福利屋数据失败:', error);
} finally {
this.loading = false;
}
},
// 加载已结束的福利屋数据
async loadEndedData() {
if (this.loading) return;
this.loading = true;
try {
const res = await this.req({
url: "fuliwu", // 已结束接口
data: {
type: 3
}
});
if (res?.data?.data) {
this.endedData = this.formatBenefitsData(res.data.data);
}
} catch (error) {
console.error('加载已结束福利屋数据失败:', error);
} finally {
this.loading = false;
}
},
// 格式化福利屋数据
formatBenefitsData(data) {
return data.map(item => {
const goodsList = [];
if (item.goodslist && item.goodslist.length) {
item.goodslist.forEach(goods => {
if (goods.stock > 0) {
goodsList.push({
imgUrl: goods.imgurl,
num: goods.stock//item1.price,
})
}
});
}
return {
id: item.id,
choujiang_xianzhi: item.choujiang_xianzhi,
title: item.title,
tips: item.goods_describe,
Popularity: item.join_count,
Time: `${item.flw_start_time} — ${item.flw_end_time}`,
GoodsList: goodsList
};
});
},
// 切换标签
tabChange(i) {
if (this.tabCur === i) return; // 避免重复加载
this.tabCur = i;
if (i === 1) {
// 切换到进行中,加载进行中数据
if (this.ongoingData.length === 0) {
this.loadOngoingData();
}
} else {
// 切换到已结束,加载已结束数据
if (this.endedData.length === 0) {
this.loadEndedData();
}
}
},
}
}
</script>
<style lang="scss">
.tab-container {
width: 100%;
margin-top: 30rpx;
}
.tab {
display: flex;
align-items: center;
justify-content: center;
.tab-item1 {
width: 160rpx;
height: 92rpx;
font-weight: 400;
margin-right: 30rpx;
background: url($imgurl + "index/uncheckTab1.png") no-repeat 0 0 / 100% 100%;
>text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
.tab-item2 {
width: 160rpx;
height: 92rpx;
font-weight: 400;
margin-right: 30rpx;
&.act {
background: url($imgurl + "index/checkTab2.png") no-repeat 0 0 / 100% 100%;
>text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
&.unact {
background: url($imgurl + "index/uncheckTab2.png") no-repeat 0 0 / 100% 100%;
>text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
}
.tab-item3 {
width: 160rpx;
height: 92rpx;
font-weight: 400;
&.act {
background: url($imgurl + "index/checkTab3.png") no-repeat 0 0 / 100% 100%;
>text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
&.unact {
background: url($imgurl + "index/uncheckTab3.png") no-repeat 0 0 / 100% 100%;
>text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
}
}
.benefits-container {
width: 672rpx;
height: 760rpx;
margin: 40rpx auto 0;
overflow: hidden;
}
.benefits-scroll {
height: 760rpx;
}
.benefit-item {
width: 100%;
height: 274rpx;
background-color: #F8F8F8;
margin-bottom: 36rpx;
border-radius: 16rpx;
}
.benefit-title {
position: absolute;
left: 24rpx;
top: 28rpx;
color: #333333;
font-size: 24rpx;
}
.benefit-tips {
position: absolute;
left: 24rpx;
top: 62rpx;
color: #FF862D;
font-size: 18rpx;
}
.action-btn {
width: 128rpx;
height: 60rpx;
background-color: #D8FD24;
border-radius: 16rpx;
position: absolute;
top: 20rpx;
right: 24rpx;
&.ended {
background-color: #333333;
text {
color: #D8FD24;
}
}
text {
font-size: 20rpx;
color: #333333;
font-weight: 600;
}
}
.goods-scroll {
height: 80rpx;
white-space: nowrap;
position: absolute;
left: 24rpx;
top: 112rpx;
}
.goods-item {
width: 80rpx;
height: 80rpx;
display: inline-block;
margin-right: 36rpx;
}
.goods-img {
width: 100%;
height: 100%;
position: absolute;
}
.goods-num {
width: 44rpx;
height: 20rpx;
background-color: rgba(172, 172, 172, 0.60);
position: absolute;
border-radius: 10rpx;
bottom: 4rpx;
left: 50%;
transform: translateX(-50%);
text {
font-size: 18rpx;
color: #fff;
}
}
.divider {
width: 624rpx;
height: 2rpx;
background-color: #F3F3F3;
position: absolute;
left: 24rpx;
bottom: 54rpx;
}
.popularity {
position: absolute;
left: 24rpx;
bottom: 16rpx;
}
.fire-icon {
width: 18rpx;
height: 20rpx;
}
.popularity-text {
font-size: 16rpx;
color: #999999;
margin-left: 8rpx;
}
.time-text {
font-size: 16rpx;
color: #999999;
position: absolute;
right: 24rpx;
bottom: 18rpx;
}
.btn-group {
margin-top: 20rpx;
}
.my-coupon {
width: 220rpx;
height: 72rpx;
background-color: #333333;
border-radius: 16rpx;
text {
font-size: 24rpx;
color: #D8FD24;
}
}
.reward-record {
width: 220rpx;
height: 72rpx;
background-color: #D8FD24;
border-radius: 16rpx;
margin-left: 38rpx;
text {
font-weight: 600;
font-size: 24rpx;
color: #333333;
}
}
</style>