fjrcloud-community-app/pages/sub/activity/my-registration.vue

315 lines
7.4 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="my-registration-page">
<!-- 空状态 -->
<view class="empty-state" v-if="list.length === 0 && !loading">
<text class="empty-text">暂无报名记录</text>
</view>
<!-- 报名列表 -->
<scroll-view
v-else
class="registration-scroll"
scroll-y
@scrolltolower="onLoadMore"
@refresherrefresh="onRefresh"
:refresher-triggered="loading"
refresher-enabled
>
<view class="list-inner">
<view
class="registration-item"
v-for="(item, index) in list"
: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="list.length > 0">
<text class="load-text">{{ finished ? '没有更多了' : loading ? '加载中...' : '上拉加载更多' }}</text>
</view>
</view>
</scroll-view>
<!-- 底部固定返回按钮 -->
<view class="bottom-bar">
<view class="back-btn" @tap="goBack"></view>
</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 list = ref([]);
// 页面加载
onLoad(() => {
loadList();
});
// 加载报名列表
async function loadList() {
if (loading.value || finished.value) return;
loading.value = true;
const { code, data } = await ActivityApi.getMyRegistrationPage({
pageNo: pageNo.value,
pageSize: pageSize.value,
});
if (code === 0 && data) {
const mapped = (data.list || []).map((item) => ({
id: item.id,
activityId: item.activityId,
title: item.activityTitle || '',
cover: item.activityCoverImage || '/static/img/guest.png',
status: item.status,
statusText: getStatusText(item.status),
statusType: getStatusType(item.status),
// 接口暂未返回以下字段,先留空兼容;若后端补充后可自动展示
location: item.location || '',
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')}`
: '',
}));
list.value = pageNo.value === 1 ? mapped : [...list.value, ...mapped];
total.value = data.total || 0;
if (list.value.length >= total.value) {
finished.value = true;
} else {
pageNo.value++;
}
}
loading.value = false;
}
// 报名状态映射0-待审核 1-已通过 2-已拒绝 3-已取消)
function getStatusText(status) {
const map = { 0: '待审核', 1: '已通过', 2: '已拒绝', 3: '已取消' };
return map[status] || '未知';
}
function getStatusType(status) {
const map = { 0: 'pending', 1: 'passed', 2: 'rejected', 3: 'cancelled' };
return map[status] || 'cancelled';
}
// 下拉刷新
function onRefresh() {
pageNo.value = 1;
finished.value = false;
list.value = [];
loadList();
}
// 滚动到底部加载更多
function onLoadMore() {
loadList();
}
// 跳转详情使用活动ID
function goDetail(item) {
uni.navigateTo({
url: `/pages/sub/activity/detail?id=${item.activityId}`,
});
}
// 返回上一页
function goBack() {
uni.navigateBack();
}
</script>
<style lang="scss" scoped>
/* 页面容器 - flex布局底部按钮固定 */
.my-registration-page {
display: flex;
flex-direction: column;
height: calc(100vh - 176rpx);
overflow: hidden;
background-color: #F5F5F5;
}
/* 报名列表滚动区域 */
.registration-scroll {
flex: 1;
height: 0;
}
/* 列表内容包裹层 */
.list-inner {
padding: 24rpx 32rpx;
}
/* 报名卡片 */
.registration-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: 200rpx;
height: 160rpx;
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: #1890FF;
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;
}
// 状态标签颜色0-待审核 1-已通过 2-已拒绝 3-已取消)
.item-status {
font-size: 26rpx;
font-weight: 500;
flex-shrink: 0;
&.status-passed { color: #52C41A; } // 已通过-绿色
&.status-pending { color: #FAAD14; } // 待审核-橙色
&.status-rejected { color: #FF4D4F; } // 已拒绝-红色
&.status-cancelled { color: #999999; } // 已取消-灰色
}
.item-label {
font-size: 24rpx;
color: #666666;
flex-shrink: 0;
}
.item-value {
font-size: 24rpx;
color: #333333;
}
.item-date {
font-size: 24rpx;
color: #333333;
}
}
}
.load-more {
text-align: center;
padding: 30rpx 0;
.load-text {
font-size: 24rpx;
color: #999999;
}
}
/* 空状态 */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
.empty-text {
font-size: 28rpx;
color: #999999;
}
}
/* 底部固定栏 */
.bottom-bar {
flex-shrink: 0;
padding: 24rpx 40rpx calc(24rpx + env(safe-area-inset-bottom));
// background-color: #FFFFFF;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.04);
.back-btn {
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #FA7E49;
color: #FFFFFF;
font-size: 30rpx;
font-weight: 500;
border-radius: 44rpx;
&:active {
opacity: 0.85;
}
}
}
</style>