|
|
<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 class="tab-item" :class="{ active: currentTab === 2 }" @click="switchTab(2)" > 已结束 </view> </view>
<scroll-view scroll-y refresher-enabled :refresher-triggered="refreshing" @refresherrefresh="onRefresh" lower-threshold="100" class="scroll-view" > <view class="activity-item" v-for="item in displayList" :key="item.id" @click="toActivityDetail(item)" > <view class="activity-info"> <text class="title">{{ item.area }}</text> <view class="item-info"> <text class="label">开始时间:</text> <text class="value">{{ item.startTime }}</text> </view> <view class="item-info"> <text class="label">结束时间:</text> <text class="value">{{ item.endTime }}</text> </view> <view class="item-info"> <text class="label">座位号:</text> <text class="value">{{ item.seatNumber }}</text> </view> <view class="item-info"> <text class="label">状态:</text> <text class="value status-tag" :class="item.statusClass">{{ item.statusText }}</text> </view> <view class="btn-box" v-if="item.status === 0"> <button class="activity-btn" type="primary" @click.stop="cancelAppoint(item)"> 取消预约 </button> </view> </view> </view> <view class="empty-box" v-if="displayList.length === 0"> <uni-icons type="empty" size="80" color="#ccc"></uni-icons> <text class="empty-text">{{ getEmptyText() }}</text> </view> </scroll-view> </view></template>
<script>export default { data() { return { currentTab: 0, activityList: [], refreshing: false }; }, computed: { displayList() { const statusMap = { 0: [0, '0', '未开始', 'pending'], 1: [1, '1', '进行中', 'ongoing'], 2: [2, '2', '已结束', 'ended'] }; const targetStatuses = statusMap[this.currentTab] || []; return this.activityList.filter(item => { const itemStatus = String(item.status); return targetStatuses.some(status => String(status) === itemStatus); }); } }, onLoad() { this.getActivityList(); }, methods: { switchTab(index) { this.currentTab = index; },
getActivityList() { this.refreshing = true; setTimeout(() => { const rawData = [ {id:1,area:'一楼自习区',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'}, {id:2,area:'综合阅览一',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:1,statusText:'进行中'}, {id:4,area:'专题阅览室',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'}, ]; this.activityList = rawData.map(item => ({ ...item, statusClass: `status-${item.status}` })); this.refreshing = false; }, 500); },
onRefresh() { this.getActivityList(); }, cancelAppoint(item) { uni.showModal({ title: '提示', content: `确定要取消${item.area}的预约吗?`, success: (res) => { if (res.confirm) { uni.showToast({ title: '取消成功', icon: 'success' }); this.getActivityList(); } } }) },
toActivityDetail(item) { uni.navigateTo({ url: "/subpkg/pages/activity-detail/activity-detail?item=" + encodeURIComponent(JSON.stringify(item)) }); }, getEmptyText() { const textMap = { 0: '未开始', 1: '进行中', 2: '已结束' } return `暂无${textMap[this.currentTab]}的预约~` } },};</script>
<style lang="scss" scoped>.activity-list { padding: 0; height: 100vh; box-sizing: border-box; background-color: #f5f5f5;}
.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: 12px 0; font-size: 15px; color: #666; position: relative;}.tab-item.active { color: #01a4fe; font-weight: bold;}.tab-item.active::after { content: ''; position: absolute; width: 30px; height: 3px; background-color: #01a4fe; bottom: 0; left: 50%; transform: translateX(-50%); border-radius: 2px;}
.scroll-view { height: calc(100vh - 60px); padding: 0 12px; box-sizing: border-box;}
.empty-box { height: calc(100vh - 200px); display: flex; flex-direction: column; align-items: center; justify-content: center;}.empty-text { margin-top: 16px; font-size: 14px; color: #999;}
.activity-item { background: #fff; border-radius: 12px; margin-bottom: 12px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); cursor: pointer; transition: transform 0.2s; &:active { transform: scale(0.98); }}
.activity-info { display: flex; flex-direction: column; align-items: flex-start; padding: 16px; .title { font-size: 16px; font-weight: bold; color: #222; margin-bottom: 12px; display: block; } .item-info { display: flex; padding: 4px 0; font-size: 14px; .label { color: #666; width: 72px; } .value { color: #333; flex: 1; } }}
/* 正确的状态样式 */.status-tag { padding: 2px 8px; border-radius: 4px; font-size: 12px;}.status-tag.status-0 { color: #01a4fe; background: #e6f7ff;}.status-tag.status-1 { color: #00b42a; background: #e6ffed;}.status-tag.status-2 { color: #999; background: #f5f5f5;}
.btn-box { width: 100%; display: flex; justify-content: flex-end; margin-top: 10px;}.activity-btn { background-color: #01a4fe; font-size: 13px; border-radius: 6px; padding: 0 14px; height: 28px; line-height: 28px;}</style>
|