<template>
|
<view class="container">
|
<view style="height:50rpx"></view>
|
|
<u-empty v-if="mockData.length === 0 && !loading" mode="data"
|
icon="http://cdn.uviewui.com/uview/empty/data.png">
|
</u-empty>
|
|
<!-- 关键修复:确保scroll-view高度正确且事件绑定有效 -->
|
<scroll-view
|
scroll-y class="scroll-view-container" style="height: 40vh" @scrolltolower="loadMore" :lower-threshold="50"
|
>
|
<view v-for="(item, idx) in mockData" :key="idx" class="prize-record-item card">
|
<view class="prize-record-info">
|
<view class="info-header">
|
<view class="prize-activity-name">{{ item.prizeActivityName }}</view>
|
<view class="prize-status-tag"
|
:class="item.prizeStatus === 'WIN' ? 'tag-winning' : 'tag-not-win'">
|
{{ item.prizeStatus === 'WIN' ? '已中奖' : '未中奖' }}
|
</view>
|
</view>
|
|
<view class="info-content">
|
<view class="content-label">奖品内容:</view>
|
<view class="prize-content">{{ item.prizeContent || '暂无奖品描述' }}</view>
|
</view>
|
|
<view class="prize-record-meta">
|
<view class="meta-item">
|
<u-icon name="clock-o" size="16" color="#999"></u-icon>
|
<text class="meta-text">{{ formatTime(item.createTime) }}</text>
|
</view>
|
<view class="meta-item" v-if="item.activitySource">
|
<u-icon name="map" size="16" color="#999"></u-icon>
|
<text class="meta-text">{{ item.activitySource }}</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="load-more">
|
<u-loadmore v-if="mockData.length > 0" :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'"
|
:load-text="{
|
loadmore: '上拉加载更多',
|
loading: '正在加载',
|
nomore: '没有更多了'
|
}" />
|
</view>
|
<view style="height:150rpx"></view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import { getPage } from '@/api/prize-record.js'
|
export default {
|
data() {
|
return {
|
query: {
|
pageNumber: 1,
|
pageSize: 5,
|
},
|
loading: false,
|
total: 0,
|
mockData: [],
|
noMore: false,
|
}
|
},
|
onLoad() {
|
this.getPage();
|
},
|
methods: {
|
onPullDownRefresh() {
|
this.mockData = [];
|
this.query.pageNumber = 1;
|
this.getPage()
|
setTimeout(() => {
|
uni.stopPullDownRefresh();
|
}, 1000);
|
},
|
|
formatTime(timeStr) {
|
if (!timeStr || typeof timeStr !== 'string') return '未知时间';
|
|
try {
|
// 手动解析格式,解决兼容性问题
|
const [datePart, timePart] = timeStr.split('T');
|
if (!datePart || !timePart) return '无效时间';
|
|
const [year, month, day] = datePart.split('-');
|
const hourMinute = timePart.split('.')[0].slice(0, 5);
|
const [hour, minute] = hourMinute.split(':');
|
|
return `${year}-${month}-${day} ${hour}:${minute}`;
|
} catch (error) {
|
console.warn('日期解析失败:', error);
|
return '未知时间';
|
}
|
},
|
|
async getPage() {
|
try {
|
const res = await getPage(this.query);
|
if (res.statusCode === 200) {
|
const newData = res.data.data || [];
|
this.total = res.data.total || 0;
|
this.mockData = this.query.pageNumber === 1 ? newData : [...this.mockData, ...newData];
|
this.noMore = newData.length < this.query.pageSize || this.mockData.length >= this.total;
|
}
|
} catch (error) {
|
console.error('加载失败:', error);
|
if (this.query.pageNumber > 1) {
|
this.query.pageNumber -= 1;
|
}
|
} finally {
|
this.loading = false;
|
uni.hideLoading();
|
uni.stopPullDownRefresh();
|
}
|
},
|
|
loadMore() {
|
// 增加日志便于调试
|
console.log('触发上拉加载', 'loading:', this.loading, 'noMore:', this.noMore);
|
|
if (this.loading || this.noMore) return;
|
|
this.loading = true;
|
// 移除不必要的延迟,避免影响体验
|
this.query.pageNumber += 1;
|
this.getPage();
|
},
|
}
|
}
|
</script>
|
|
<style>
|
.container {
|
height: 100vh;
|
display: flex;
|
flex-direction: column;
|
background-color: #f7f8fa;
|
}
|
|
/* 关键修复:使用flex确保高度正确计算 */
|
.scroll-view-container {
|
flex: 1;
|
overflow-y: auto; /* 明确设置垂直滚动 */
|
padding: 0 20rpx;
|
box-sizing: border-box;
|
-webkit-overflow-scrolling: touch; /* 优化移动端滚动体验 */
|
}
|
|
.load-more {
|
padding: 20rpx 0;
|
text-align: center;
|
color: #999;
|
font-size: 26rpx;
|
background-color: #f8f9fa;
|
}
|
|
.card {
|
background: #fff;
|
border-radius: 20rpx;
|
margin: 0 0 24rpx;
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03),
|
0 6rpx 16rpx rgba(0, 0, 0, 0.04);
|
transition: all 0.25s ease;
|
}
|
|
.prize-record-item {
|
padding: 30rpx 28rpx;
|
}
|
|
.info-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 22rpx;
|
}
|
|
.prize-activity-name {
|
font-size: 34rpx;
|
font-weight: 600;
|
color: #222;
|
line-height: 1.4;
|
max-width: 70%;
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
|
.prize-status-tag {
|
padding: 6rpx 18rpx;
|
border-radius: 20rpx;
|
font-size: 24rpx;
|
font-weight: 500;
|
text-align: center;
|
}
|
|
.tag-winning {
|
background-color: #fff1f0;
|
color: #ff4d4f;
|
border: 1px solid #ffccc7;
|
}
|
|
.tag-not-win {
|
background-color: #f5f5f5;
|
color: #888;
|
border: 1px solid #e5e5e5;
|
}
|
|
.info-content {
|
margin-bottom: 24rpx;
|
padding-left: 4rpx;
|
}
|
|
.content-label {
|
font-size: 24rpx;
|
color: #999;
|
margin-bottom: 8rpx;
|
}
|
|
.prize-content {
|
font-size: 28rpx;
|
color: #555;
|
line-height: 1.6;
|
display: -webkit-box;
|
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 2;
|
overflow: hidden;
|
}
|
|
.prize-record-meta {
|
display: flex;
|
justify-content: flex-start;
|
gap: 24rpx;
|
padding-top: 20rpx;
|
border-top: 1px solid #f8f8f8;
|
}
|
|
.meta-item {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
}
|
|
.meta-text {
|
font-size: 22rpx;
|
color: #888;
|
white-space: nowrap;
|
letter-spacing: 0.5rpx;
|
}
|
</style>
|