421 lines
11 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 class="page">
<view class="page-content flex-col">
<!-- 筛选导航 -->
<view class="filter-tabs">
<view class="tabs-content">
<view
class="tab-item"
:class="{'active-tag': queryForm.orderType == 'latest'}"
@click="changeOrder('latest')"
>最新发布</view>
<view
class="tab-item"
:class="{'active-tag': queryForm.orderType == 'popularity'}"
@click="changeOrder('popularity')"
>人气排名</view>
<view class="brand-filter" :class="{ active: selectedBrand !== null }" @click="showBrandFilter">
<text>筛选品牌</text>
<image :src="'/static/icons/filter.svg'" mode="aspectFit" class="filter-icon"></image>
</view>
</view>
</view>
<!-- 列表内容区域 -->
<view class="list-container">
<scroll-view
style="height: 100%;"
scroll-y="true"
@scrolltolower="changePage"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onRefresh"
>
<view class="activity-item flex" v-for="(it, index) in activeList" :key="index" @click="toDetail(it)">
<view class="left flex flex-col justify-between align-center">
<image :src="it.brandLogo" style="width: 140rpx;height: 140rpx;"></image>
<text>活动状态</text>
<view v-if="it.audit_status == 0" style="color: #9E9E9E;font-size: 24rpx;">待审核</view>
<view v-if="it.audit_status == 2" style="color: #DE3C4B;font-size: 24rpx;">未通过</view>
<view v-if="it.audit_status == 1">
<block v-if="it.activity_status == 1">
<view class="margin-bottom-xs" style="color: #9E9E9E;font-size: 24rpx;">招募进行中</view>
<view>
<text style="font-size: 72rpx; color: #DE3C4B;">{{it.remainingDays}}</text>
</view>
</block>
<block v-else>
<view style="color: #9E9E9E;font-size: 24rpx;">活动已结束</view>
</block>
</view>
</view>
<view class="right">
<view class="title">{{ it.breweryName }}</view>
<view class="sub">时间首次扫码开始累计 <text style="color:#DE3C4B">{{it.duration}}天内</text></view>
<view class="sub">目标全系列酒款累积扫码 {{ it.activityTarget}}</view>
<scroll-view v-if="it.beers" scroll-x="true" class="scroll-img">
<view class="beer-box" v-for="(beer, beerIndex) in it.beers" :key="beerIndex" @click="toReview(beer)">
<image v-if="beer.cover" :src="beer.cover" class="cover"></image>
</view>
</scroll-view>
<view class="flex align-center">
<text v-if="it.activityRewardType == 2 || (it.activityRewardType == 1 && it.activityRewardGoods)" class="zeng"></text>
<text v-if="it.activityRewardType == 1 && it.activityRewardGoods" style="color: #0B0E26;font-size: 24rpx;">{{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}}</text>
<text v-if="it.activityRewardType == 2" style="color: #0B0E26;font-size: 24rpx;">啤酒币 * {{it.activityRewardCount}}</text>
</view>
</view>
</view>
<view class="cu-load" :class="loading?'loading': activeList.length == total ? 'over' :'more'"></view>
</scroll-view>
</view>
<loginPopup ref="loginRef"></loginPopup>
<!-- 品牌筛选组件 -->
<brand-filter ref="brandFilterRef" @confirm="onBrandFilterConfirm"></brand-filter>
</view>
</view>
</template>
<script>
import {
getActivities
} from '@/api/bar.js'
import loginPopup from '@/components/loginPopup.vue'
import brandFilter from '@/components/brandFilter.vue'
export default {
components: {
loginPopup,
brandFilter
},
data() {
return {
activeList: [], // 活动列表
loading: false,
isRefreshing: false,
queryForm: {
pageNum: 1,
pageSize: 5,
orderType: 'latest',
},
total: 0,
isFilterActive: false,
selectedBrand: null, // 选中的品牌ID
};
},
onLoad() {
// 获取活动列表
this.getActivitiesFun();
},
methods: {
// 获取活动列表
getActivitiesFun() {
this.loading = true;
const params = {
pageNum: this.queryForm.pageNum,
pageSize: this.queryForm.pageSize
};
// 添加品牌筛选
if (this.selectedBrand) {
params.breweryId = this.selectedBrand;
} else {
// 只有在没有品牌筛选时,才应用排序
params.orderBy = this.queryForm.orderType === 'latest' ? 'start_date' : 'popularity';
params.order = 'desc';
}
getActivities(params).then(res => {
console.log('获取到的原始数据:', res);
this.total = res.total;
if(res.rows && res.rows.length > 0) {
let arr = res.rows.map(it => {
it.remainingDays = this.getRemainingDays(it.endDate);
return it;
});
console.log('处理后的数据:', arr);
// 如果有品牌筛选,确保只显示选中品牌的活动
if (this.selectedBrand) {
arr = arr.filter(item => item.breweryId === this.selectedBrand);
}
console.log('最终显示的数据:', arr);
// 更新显示列表
if (this.queryForm.pageNum === 1) {
this.activeList = arr;
} else {
this.activeList = [...this.activeList, ...arr];
}
} else {
if (this.queryForm.pageNum === 1) {
this.activeList = [];
}
}
this.loading = false;
}).catch(err => {
console.error('获取活动列表失败:', err);
this.loading = false;
});
},
// 计算剩余天数
getRemainingDays(date) {
const targetDate = new Date(date);
const currentDate = new Date();
const timeDiff = targetDate.getTime() - currentDate.getTime();
const remainingDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
return remainingDays;
},
// 切换排序
changeOrder(type) {
// 如果点击当前激活的排序方式,不做处理
if (this.queryForm.orderType === type) return;
// 切换排序方式
this.queryForm.orderType = type;
// 重置分页
this.queryForm.pageNum = 1;
this.activeList = [];
// 重新获取数据
this.getActivitiesFun();
},
// 分页加载
changePage() {
if (this.activeList.length < this.total) {
this.queryForm.pageNum++;
this.getActivitiesFun();
}
},
// 跳转详情
toDetail(item) {
uni.navigateTo({
url: "/pagesActivity/activityDetail?id=" + item.id
});
},
// 跳转酒评
toReview(it) {
const token = uni.getStorageSync('token')
if (!token) {
this.$refs.loginRef.show()
return
}
uni.navigateTo({
url: "/pages/index/review?beerId=" + it.id
});
},
// 显示品牌筛选
showBrandFilter() {
// 如果还没有数据,先获取数据
if (!this.activeList || this.activeList.length === 0) {
this.queryForm.pageNum = 1;
this.getActivitiesFun().then(() => {
this.$refs.brandFilterRef.extractBrandsFromList(this.activeList);
this.$refs.brandFilterRef.open();
});
} else {
this.$refs.brandFilterRef.extractBrandsFromList(this.activeList);
this.$refs.brandFilterRef.open();
}
},
// 品牌筛选确认
onBrandFilterConfirm(result) {
this.selectedBrand = result.id;
this.queryForm.pageNum = 1;
this.activeList = [];
this.getActivitiesFun();
},
// 添加下拉刷新方法
onRefresh() {
this.isRefreshing = true;
// 重置分页参数
this.queryForm.pageNum = 1;
this.activeList = [];
// 重新获取数据
this.getActivitiesFun();
}
}
}
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #F9F9F9;
}
.filter-tabs {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 99;
background: #FFFFFF;
// border-bottom: 1rpx solid #F5F5F5
.tabs-content {
display: flex;
align-items: center;
padding: 20rpx 32rpx;
height: 112rpx;
width: 100%;
.tab-item {
width: 144rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 12rpx;
background: #F9F9F9;
margin-right: 16rpx;
font-size: 24rpx;
font-weight: 500;
text-align: center;
&.active-tag {
// 选中状态的样式
color: #FFF;
background: #D42E78;
}
}
.brand-filter {
margin-left: auto;
display: flex;
align-items: center;
justify-content: center;
height: 64rpx;
min-width: 144rpx; // 最小宽度
padding: 0 24rpx; // 左右内边距
border-radius: 12rpx;
background: #FFFFFF;
border: 1rpx solid #D42E78;
transition: all 0.3s; // 添加过渡效果
text {
color: #D42E78;
font-size: 24rpx;
font-weight: 500;
margin-right: 8rpx; // 文字和图标的间距
}
.filter-icon {
width: 32rpx;
height: 32rpx;
}
// 激活状态
&.active {
background: #D42E78;
border-color: #D42E78;
text {
color: #FFFFFF;
}
.filter-icon {
filter: brightness(0) invert(1); // 将图标改为白色
}
}
}
}
}
.list-container {
margin-top: 104rpx; // 筛选栏高度
padding: 24rpx 32rpx;
}
.activity-item {
border-radius: 20rpx;
background: #FDFDFD;
box-sizing: border-box;
border: 1px solid #F2F2F2;
width: 702rpx;
margin-bottom: 32rpx;
.left {
padding: 24rpx 20rpx;
border-radius: 20rpx;
background: #FFFFFF;
box-sizing: border-box;
border: 1px solid #EFEDE9;
width: 180rpx;
margin-top: -10rpx;
margin-bottom: -10rpx;
}
.right {
padding: 20rpx;
flex:1;
.title {
font-family: Source Han Sans;
font-size: 28rpx;
font-weight: bold;
line-height: 30rpx;
color: #0B0E26;
margin-bottom: 20rpx;
}
.sub {
font-family: Source Han Sans;
font-size: 24rpx;
font-weight: 500;
line-height: 30rpx;
color: #0B0E26;
margin-bottom: 16rpx;
}
.scroll-img {
width: 500rpx;
display: flex;
flex-direction: row;
white-space: nowrap;
height: 144rpx;
margin-bottom: 20rpx;
.beer-box {
width: 100rpx;
background: #FFFFFF;
margin-right: 20rpx;
box-sizing: border-box;
display: inline-block;
// &:nth-child(1) {
// margin-left: 32rpx;
// }
.cover {
width: 100rpx;
height: 144rpx;
border-radius: 10rpx;
}
}
}
.zeng {
font-family: Source Han Sans;
font-size: 20rpx;
font-weight: bold;
line-height: normal;
text-align: center;
color: #0B0E26;
padding: 8rpx 12rpx;
border-radius: 10rpx;
background: #FEE034;
margin-right: 20rpx;
}
}
}
</style>