|
|
<template> <view class="activity-list"> <view class="tab-box"> <view class="tab-item" :class="{ active: currentTab === 0 }" @click="switchTab(0)" > 进行中 </view> <view class="tab-item" :class="{ active: currentTab === 1 }" @click="switchTab(1)" > 往期活动 </view> </view>
<scroll-view scroll-y @scrolltolower="onLoadMore" lower-threshold="150" class="scroll-view" > <view class="activity-item" v-for="(item, index) in displayList" @click="toActivityDetail(item)" :key="index"> <image class="activity-img" :src="item.coverImage" mode="aspectFill"></image> <!-- 状态小标 --> <view class="status-tag" v-if="item.status === '未开始' || item.status === '进行中' || item.status === '已结束'" :class="[ item.status === '未开始' ? 'tag-wait' : '', item.status === '进行中' ? 'tag-doing' : '', item.status === '已结束' ? 'tag-end' : '' ]" > {{item.status}} </view> <view class="activity-info"> <view class="activity-info-left"> <view class="title-wrap"> <text class="activity-title">{{ item.title }}</text> </view> <view class="time"> <uni-icons class="time-icon" custom-prefix="iconfont" type="icon-shijian" size="15"></uni-icons> <text>{{ item.startTime }} - {{ item.endTime }}</text> </view> </view> </view> </view>
<view class="empty" v-if="displayList.length === 0 && !loading"> <uni-icons custom-prefix="iconfont" type="icon-kongshuju" size="80"></uni-icons> <text style="margin-top: 20px;">暂无{{ currentTab === 0 ? '进行中的活动' : '往期活动' }}~</text> </view>
<!-- 底部加载提示 --> <view class="footer-tip" v-if="displayList.length>0"> <text v-if="loading">加载中...</text> <text v-else-if="noMore">没有更多数据了</text> </view> </scroll-view> </view></template>
<script>import { FetchActivityInfo } from '@/api/activity';import config from '@/utils/config';
export default { data() { return { currentTab: 0, activityList: [], baseUrl: config.baseUrl, page: 0, size: 10, loading: false, noMore: false }; }, computed: { displayList() { return this.activityList } }, onLoad() { this.getNewActivityList(false); }, /** 页面原生下拉刷新,pages.json对应页面开启enablePullDownRefresh */ async onPullDownRefresh() { if(this.loading){ uni.stopPullDownRefresh() return } this.page = 0; this.noMore = false; try{ await this.getNewActivityList(false); }finally{ uni.stopPullDownRefresh() } }, methods: { switchTab(index) { this.currentTab = index; //切换tab重置分页
this.page = 0; this.activityList = []; this.noMore = false; this.getNewActivityList(false); },
/** * @param {Boolean} isLoadMore true=上拉加载更多追加 false=刷新重置列表 */ async getNewActivityList(isLoadMore = false){ if(this.loading) return; this.loading = true;
let statusArr = [] if(this.currentTab === 0){ // 进行中:未开始0、进行中1
statusArr = [0, 1] }else{ // 往期:已结束2
statusArr = [2] } const params = { page: this.page, size: this.size, status: statusArr } console.log('params',params) try { const res = await FetchActivityInfo(params) console.log(res) if (res.code === 200 ) { const records = res.data.content || [] records.forEach(item => { if(item.coverImage){ const imgId = encodeURIComponent(item.coverImage); item.coverImage = `https://wechatapi.aiyxlib.com/files/${imgId}`; }else{ item.coverImage = '' } }) if(isLoadMore){ this.activityList.push(...records) }else{ this.activityList = records } // 判断是否没有更多
this.noMore = records.length < this.size }else{ if(!isLoadMore){ this.activityList = []; } } } catch (e) { console.error(e) } finally { this.loading = false } },
//上拉加载更多
onLoadMore(){ if(this.loading || this.noMore) return this.page = this.page + 1 this.getNewActivityList(true) },
getBtnText(status) { switch(status){ case '已结束': return '活动结束' case '已取消': return '活动取消' case '未开始': case '进行中': return '立即参加' default: return '立即参加' } }, isItemDisabled(item) { return ['已结束', '已取消'].includes(item.status) },
toActivityDetail(item) { uni.navigateTo({ url: "/subpkg/pages/activity-detail/activity-detail?item=" + encodeURIComponent(JSON.stringify(item)) }); } },};</script>
<style lang="scss" scoped>.activity-list { padding: 0; height: 100vh; box-sizing: border-box; background-color: #f5f5f5; display:flex; flex-direction:column;}
.tab-box { display: flex; background-color: #fff; margin-bottom: 10px; position: sticky; top: 0; z-index: 99;}.tab-item { flex: 1; text-align: center; padding: 10px 0; font-size: 15px; color: #333; position: relative;}.tab-item.active { color: #01a4fe; font-weight: bold;}.tab-item.active::after { content: ''; position: absolute; width: 25px; height: 2px; background-color: #01a4fe; bottom: 0; left: 50%; transform: translateX(-50%); border-radius: 2px;}
.scroll-view { flex: 1; height: 0; padding: 0 12px; box-sizing: border-box;}
.empty { padding: 80rpx 0; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #999;}
.footer-tip{ text-align: center; padding: 10px 0 20px; color:#999; font-size:13px;}
.activity-item { position: relative; background: #fff; border-radius: 12px; margin-bottom: 15px; overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
.activity-img { width: 100%; height: 100px; object-fit: cover; }
.status-tag{ position: absolute; top: 0; left: 0; padding: 4px 8px; border-radius: 12px 0 12px 0; font-size: 12px; &.tag-wait{ color: #01a4fe; background: #e6f7ff; } &.tag-doing{ color: #00b42a; background: #e6ffed; } &.tag-end{ color:#868686; background:#f2f2f2; } }
.activity-info { padding: 15px; display: flex; justify-content: space-between; align-items: center;
.activity-info-left { flex: 1; .title-wrap{ display:flex; justify-content: flex-start; align-items: flex-start; gap:5px; margin-bottom:8px; } .activity-title { flex: 1; font-size: 16px; font-weight: bold; color: #333; }
.time { display: flex; align-items: center; font-size: 12px; color: #999;
.time-icon { margin-right: 4px; } } }
.activity-btn { background-color: #01a4fe; font-size: 14px; border-radius: 30px; padding: 0 15px; height: 36px; line-height: 36px; &::after{ border:none; } }
.disabled-btn { background-color: #ccc !important; } }}</style>
|