2025-10-14 17:46:23 +08:00

319 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="flower-page">
<!-- 顶部统计栏与截图一致两项 -->
<uni-nav-bar
left-icon="left"
title="我的鲜花"
@clickLeft="goBack"
fixed
color="#8B2316"
height="180rpx"
:border="false"
backgroundColor="#eeeeee"
/>
<view class="stats-bar">
<view class="stat">
<up-image :src="flowerImg" width="36rpx" height="36rpx" ></up-image>
<text class="num">{{ stat.totalCount }}</text>
</view>
<view class="stat">
<up-image :src="moneyImg" width="36rpx" height="36rpx" ></up-image>
<text class="num">{{ stat.totalAmount.toFixed(2) }}</text>
</view>
</view>
<!-- 表头条红底白字 -->
<view class="table-header">
<text class="col name">姓名</text>
<text class="col time">时间</text>
<text class="col qty">数量</text>
</view>
<!-- 表体/列表或空状态 -->
<scroll-view
class="table-body"
scroll-y
:show-scrollbar="false"
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
lower-threshold="100"
:scroll-top="scrollTop"
>
<view v-if="records.length === 0" class="empty-wrap">
<up-image :src="emptyImg" width="176rpx" height="204rpx" ></up-image>
<text class="empty-text">您暂未收到鲜花</text>
</view>
<view v-else class="row" v-for="(item, idx) in records" :key="idx">
<text class="cell name">{{ item.name }}</text>
<text class="cell time">{{ item.time }}</text>
<text class="cell qty" :class="{ plus: item.amount > 0, minus: item.amount < 0 }">{{ item.amount }}</text>
</view>
<view v-if="loading" class="loading">
<text>加载中...</text>
</view>
<view v-if="noMore && records.length > 0" class="no-more">
<text>没有更多数据了</text>
</view>
<view class="debug-actions">
<!-- <button @click="testLoadMore" size="mini" type="primary">测试加载更多</button>
<text class="debug-info">当前页: {{ page }}, 加载中: {{ loading }}, 无更多: {{ noMore }}</text> -->
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import flowerImg from "@/static/flowers.png"
import moneyImg from "@/static/mind_totle_money.png"
import emptyImg from "@/static/icon_empty.png"
import api from '@/api/api.js';
// 与截图一致的顶部两项统计:总鲜花数与累计金额
const stat = ref({ totalCount: 0, totalAmount: 0.0 });
// 与表格结构匹配:姓名/时间/数量
const records = ref([]);
// 列表状态
const refreshing = ref(false);
const loading = ref(false);
const noMore = ref(false);
const page = ref(1);
const pageSize = ref(10);
const scrollTop = ref(0);
const goBack = () => {
uni.navigateBack({
fail() {
uni.redirectTo({ url: '/pages/index/index' });
}
});
};
const getFlowerList = () => {
return new Promise((resolve, reject) => {
// 只在第一页时设置loading状态避免与onLoadMore冲突
if (page.value === 1) {
loading.value = true;
}
console.log('正在获取第', page.value, '页数据...');
api.getFlowerList({page: page.value}).then(res => {
console.log('接口返回数据:', res);
if (res.code === 200 && res.data) {
const { flower_data, total_amount, total_num } = res.data;
// 更新统计数据
stat.value.totalCount = total_num || 0;
stat.value.totalAmount = total_amount || 0;
// 处理列表数据
if (flower_data && flower_data.list) {
const newRecords = flower_data.list.map(item => ({
name: item.patient_name || '未知',
time: item.create_date || '',
amount: item.num || 0,
// 保留原始数据以备后用
original: item
}));
// 如果是第一页,替换数据;否则追加数据
if (page.value === 1) {
records.value = newRecords;
console.log('第一页数据,替换列表,共', newRecords.length, '条');
} else {
records.value.push(...newRecords);
console.log('第', page.value, '页数据,追加到列表,新增', newRecords.length, '条');
}
// 判断是否还有更多数据
noMore.value = flower_data.isLastPage;
console.log('是否最后一页:', flower_data.isLastPage, ',总页数:', flower_data.pages);
}
resolve(res);
} else {
reject(new Error('接口返回错误'));
}
}).catch(err => {
console.error('获取鲜花列表失败:', err);
uni.showToast({ title: '获取数据失败', icon: 'error' });
reject(err);
}).finally(() => {
// 只在第一页时重置loading状态
if (page.value === 1) {
loading.value = false;
}
refreshing.value = false;
});
});
};
onMounted(() => {
getFlowerList();
});
const onRefresh = async () => {
if (refreshing.value) return;
refreshing.value = true;
try {
page.value = 1;
noMore.value = false;
records.value = []; // 清空数据
getFlowerList(); // 重新获取第一页数据
uni.showToast({ title: '刷新成功', icon: 'none' });
} catch (error) {
console.error('刷新失败:', error);
uni.showToast({ title: '刷新失败', icon: 'error' });
}
};
const onLoadMore = async () => {
console.log('触发上拉加载更多事件');
// 检查各种状态
if (loading.value) {
console.log('正在加载中,忽略重复请求');
return;
}
if (noMore.value) {
console.log('已经没有更多数据了');
return;
}
console.log('开始加载下一页,当前页码:', page.value);
loading.value = true;
try {
page.value += 1;
await getFlowerList(); // 等待数据加载完成
console.log('加载完成,当前页码:', page.value);
} catch (error) {
console.error('加载更多失败:', error);
page.value -= 1; // 恢复页码
uni.showToast({ title: '加载失败', icon: 'error' });
} finally {
loading.value = false;
}
};
// 测试加载更多功能
const testLoadMore = () => {
console.log('手动测试加载更多');
onLoadMore();
};
</script>
<style lang="scss" scoped>
$theme: #8B2316;
$bg: #ffffff;
$text: #333;
$muted: #999;
$card: #ffffff;
.flower-page {
background: $bg;
}
.stats-bar {
display: flex;
align-items: center;
padding: 24rpx 30rpx;
background: #fff;
border-bottom: 2rpx solid #eee;
.stat { display: flex; align-items: center; gap: 16rpx; }
.stat:last-child{
margin-left: 120px;
}
.icon { font-size: 34rpx; }
.num { font-size: 30rpx; color: #333; }
}
.table-header {
background: #9e3a2e;
color: #fff;
display: flex;
justify-content: space-between;
padding: 22rpx 30rpx;
font-size: 30rpx;
position: sticky;
top: 180rpx; /* nav 高度 */
z-index: 5;
.col { width: 33%; }
.name { text-align: left; }
.time { text-align: center; }
.qty { text-align: right; }
}
.table-body {
height: calc(100vh - 180rpx - 88rpx - 70rpx);
/* 充满剩余高度,避免滚动穿透 */
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 26rpx 30rpx;
border-bottom: 2rpx solid #f2f2f2;
font-size: 28rpx;
color: #333;
.cell { width: 33%; }
.name { text-align: left; }
.time { text-align: center; color: #666; }
.qty { text-align: right; }
.qty.plus { color: #2dbd85; }
.qty.minus { color: #e34d4d; }
}
.empty-wrap { padding-top: 200rpx; display: flex; flex-direction: column; align-items: center; color: #bdbdbd; }
.empty-icon { width: 220rpx; height: 220rpx; opacity: .4; }
.empty-text { margin-top: 20rpx; font-size: 30rpx; }
.loading, .no-more {
text-align: center;
color: #9aa0a6;
padding: 30rpx 0;
font-size: 26rpx;
text {
display: inline-block;
padding: 10rpx 20rpx;
background: #f5f5f5;
border-radius: 20rpx;
}
}
.debug-actions {
height: 50rpx;
text-align: center;
padding: 20rpx;
border-top: 1rpx solid #eee;
button {
margin-bottom: 10rpx;
}
.debug-info {
display: block;
font-size: 24rpx;
color: #999;
background: #f8f8f8;
padding: 10rpx;
border-radius: 8rpx;
}
}
</style>