fjrcloud-community-app/pages/sub/activity/list.vue

352 lines
8.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 小区活动列表页 -->
<template>
<s-layout title="小区活动">
<view class="activity-list-page">
<!-- 渐变背景装饰 -->
<view class="gradient-bg"></view>
<!-- 固定头部区域 -->
<view class="list-header">
<!-- 顶部提示条 -->
<view class="top-banner">
<text class="banner-text">{{ communityName }}开展活动啦</text>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="activityList.length === 0 && !loading">
<text class="empty-text">暂无活动</text>
</view>
<!-- 活动列表 - 滚动 -->
<scroll-view
v-else
class="activity-scroll"
scroll-y
@scrolltolower="onLoadMore"
@refresherrefresh="onRefresh"
:refresher-triggered="loading"
refresher-enabled
>
<view class="list-inner">
<view
class="activity-item"
v-for="(item, index) in activityList"
:key="index"
@tap="goDetail(item)"
>
<!-- 左侧封面图 -->
<image class="item-cover" :src="item.cover" mode="aspectFill" />
<!-- 右侧内容区 -->
<view class="item-content">
<text class="item-title">{{ item.title }}</text>
<view class="item-row">
<text class="item-location">{{ item.location }}</text>
<text class="item-status" :class="'status-' + item.statusType">{{ item.statusText }}</text>
</view>
<view class="item-row nowrap">
<text class="item-label">报名日期:</text>
<text class="item-value">{{ item.registerDate }}</text>
</view>
<view class="item-row wrap">
<text class="item-date">{{ item.dateRange }}</text>
</view>
</view>
</view>
<!-- 加载更多提示 -->
<view class="load-more" v-if="activityList.length > 0">
<text class="load-text">{{ finished ? '没有更多了' : loading ? '加载中...' : '上拉加载更多' }}</text>
</view>
</view>
</scroll-view>
<!-- 右下角浮动按钮 -->
<view class="float-btn" @tap="handleFloatBtn">
<text class="sicon-edit"></text>
</view>
</view>
</s-layout>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import ActivityApi from '@/sheep/api/community/activity';
import sheep from '@/sheep';
// 分页参数
const pageNo = ref(1);
const pageSize = ref(10);
const total = ref(0);
const loading = ref(false);
const finished = ref(false);
// 小区名称
const communityName = ref('');
// 活动列表数据
const activityList = ref([]);
// 页面加载
onLoad(() => {
const userInfo = sheep.$store('user').userInfo;
communityName.value = userInfo?.currentCommunityName || '';
loadActivityList();
});
// 加载活动列表
async function loadActivityList() {
if (loading.value || finished.value) return;
loading.value = true;
const { code, data } = await ActivityApi.getPage({
pageNo: pageNo.value,
pageSize: pageSize.value,
});
if (code === 0 && data) {
const list = (data.list || []).map((item) => ({
id: item.id,
title: item.title || '',
cover: item.coverImage || '/static/img/guest.png',
status: item.status,
statusText: getStatusText(item.status),
statusType: getStatusType(item.status),
registerDate: item.registrationStartTime && item.registrationEndTime
? `${sheep.$helper.timeFormat(item.registrationStartTime, 'yyyy/mm/dd')} - ${sheep.$helper.timeFormat(item.registrationEndTime, 'yyyy/mm/dd')}`
: '',
dateRange: item.activityStartTime && item.activityEndTime
? `${sheep.$helper.timeFormat(item.activityStartTime, 'yyyy/mm/dd hh:MM')} - ${sheep.$helper.timeFormat(item.activityEndTime, 'yyyy/mm/dd hh:MM')}`
: '',
location: item.location || '',
}));
activityList.value = pageNo.value === 1 ? list : [...activityList.value, ...list];
total.value = data.total || 0;
if (activityList.value.length >= total.value) {
finished.value = true;
} else {
pageNo.value++;
}
}
loading.value = false;
}
// 状态映射
function getStatusText(status) {
const map = { 0: '报名中', 1: '进行中', 2: '已结束' };
return map[status] || '未知';
}
function getStatusType(status) {
const map = { 0: 'registering', 1: 'ongoing', 2: 'ended' };
return map[status] || 'ended';
}
// 下拉刷新
function onRefresh() {
pageNo.value = 1;
finished.value = false;
activityList.value = [];
loadActivityList();
}
// 滚动到底部加载更多
function onLoadMore() {
loadActivityList();
}
// 跳转详情
function goDetail(item) {
uni.navigateTo({
url: `/pages/sub/activity/detail?id=${item.id}`,
});
}
// 浮动按钮点击 - 跳转我的报名
function handleFloatBtn() {
uni.navigateTo({ url: '/pages/sub/activity/my-registration' });
}
</script>
<style lang="scss" scoped>
/* 页面容器 - flex布局头部固定 + 列表滚动 */
.activity-list-page {
display: flex;
flex-direction: column;
height: calc(100vh - 176rpx);
overflow: hidden;
position: relative;
}
/* 渐变背景装饰 */
.gradient-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100%;
background: linear-gradient(180deg, #F8EDE8 0%, #FFFFFF 30%);
z-index: -1;
}
/* 固定头部区域 */
.list-header {
flex-shrink: 0; /* 不被压缩,固定不动 */
}
/* 顶部提示条 */
.top-banner {
padding: 24rpx 32rpx;
.banner-text {
font-size: 28rpx;
color: #FA7E49;
font-weight: 500;
}
}
/* 活动列表滚动区域flex:1 占满剩余空间height:0 是小程序 scroll-view 配合 flex 的关键 */
.activity-scroll {
flex: 1;
height: 0;
}
/* 列表内容包裹层 */
.list-inner {
padding: 0 32rpx 160rpx; /* 底部留出空间给浮动按钮 */
}
/* 活动卡片 */
.activity-item {
display: flex;
background-color: #FFFFFF;
border-radius: 20rpx;
padding: 24rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
.item-cover {
width: 220rpx;
height: 180rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
.item-content {
flex: 1;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.item-title {
font-size: 30rpx;
font-weight: 500;
color: #FA7E49;
line-height: 1.4;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.item-row {
display: flex;
align-items: center;
margin-top: 8rpx;
&.nowrap {
flex-wrap: nowrap;
white-space: nowrap;
}
&.wrap {
flex-wrap: wrap;
}
}
.item-location {
font-size: 26rpx;
color: #333333;
flex: 1;
}
// 状态标签颜色
.item-status {
font-size: 26rpx;
font-weight: 500;
flex-shrink: 0;
&.status-ongoing { color: #52C41A; } // 进行中-绿色
&.status-registering { color: #FAAD14; } // 报名中-橙色
&.status-ended { color: #999999; } // 已结束-灰色
}
.item-label {
font-size: 24rpx;
color: #666666;
}
.item-value {
font-size: 22rpx;
color: #333333;
}
.item-date {
font-size: 20rpx;
color: #666666;
}
}
}
.load-more{
text-align: center;
padding-top: 30rpx;
}
/* 空状态 */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
.empty-text {
font-size: 28rpx;
color: #999999;
}
}
/* 右下角浮动按钮 */
.float-btn {
position: fixed;
right: 40rpx;
bottom: 80rpx;
width: 100rpx;
height: 100rpx;
background: linear-gradient(135deg, #FA7E49 0%, #E86935 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 24rpx rgba(250, 126, 73, 0.4);
z-index: 99;
&:active {
opacity: 0.85;
transform: scale(0.95);
}
.sicon-edit {
font-size: 44rpx;
color: #FFFFFF;
}
}
</style>