buddhism/pages/memorial/compositons/enshrinedList.vue
2025-09-23 13:32:04 +08:00

374 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="enshrined-list">
<!-- 表格头部 -->
<view class="table-header">
<view class="header-cell worshiper-col">供奉人</view>
<view class="header-cell time-col">供奉时间</view>
<view class="header-cell time-col">结束时间</view>
<view class="header-cell type-col">供奉类型</view>
</view>
<!-- 表格内容 -->
<view class="table-body">
<view
v-for="(item, index) in enshrinedList"
:key="item.id || index"
class="table-row"
@click="handleItemClick(item)"
>
<view class="table-cell worshiper-col"
>{{ item.worshiperName || "未知" }}
</view>
<view class="table-cell time-col"
>{{ formatDate(item.startDate) }}
</view>
<view class="table-cell time-col">{{ formatDate(item.endDate) }}</view>
<view class="table-cell type-col"
>{{ item.thaliName || "未知类型" }}
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="!loading && enshrinedList.length === 0" class="empty-state">
<view class="empty-icon">📝</view>
<view class="empty-text">暂无供奉记录</view>
</view>
<!-- 加载更多 -->
<view v-if="hasMore && !loading" class="load-more" @click="loadMore">
<text>加载更多</text>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<text>加载中...</text>
</view>
</view>
</template>
<script>
import { getEnshrinedList } from "@/api/memorial/memorial.js";
export default {
name: "EnshrinedList",
props: {
memorialId: {
type: [String, Number],
required: true,
},
searchKeyword: {
type: String,
default: "",
},
},
data() {
return {
enshrinedList: [],
loading: false,
pageNum: 1,
pageSize: 12,
total: 0,
hasMore: true,
};
},
watch: {
// 移除对searchKeyword的自动监听避免输入时自动刷新
// searchKeyword: {
// handler(newVal) {
// this.resetList()
// this.loadData()
// },
// immediate: false
// }
},
mounted() {
this.loadData();
},
methods: {
// 加载数据
async loadData() {
if (this.loading) return;
this.loading = true;
try {
const params = {
memorialId: this.memorialId,
pageNum: this.pageNum,
pageSize: this.pageSize,
};
// 暂时注释搜索功能,等后续实现
// if (this.searchKeyword) {
// params.keyword = this.searchKeyword
// }
const response = await getEnshrinedList(params);
console.log("API 响应数据:", response); // 调试日志
// 新的API响应格式: { code: 200, msg: "操作成功", data: [...] }
let total = 0;
let rows = [];
if (response && response.code === 200) {
// API成功响应
rows = response.rows || [];
total = rows.length; // 如果没有分页信息,使用数组长度
console.log("API 返回数据:", rows);
} else {
console.log("API 响应异常:", response);
// API响应异常时使用模拟数据
rows = this.getMockData();
total = rows.length;
}
this.total = total;
if (this.pageNum === 1) {
this.enshrinedList = rows || [];
} else {
this.enshrinedList = [...this.enshrinedList, ...(rows || [])];
}
this.hasMore = this.enshrinedList.length < total;
} catch (error) {
console.error("加载供奉列表失败:", error);
// 错误时使用模拟数据(仅用于测试)
console.log("API 调用失败,使用模拟数据");
const mockData = this.getMockData();
if (this.pageNum === 1) {
this.enshrinedList = mockData;
} else {
this.enshrinedList = [...this.enshrinedList, ...mockData];
}
this.total = mockData.length;
this.hasMore = false;
uni.showToast({
title: "网络异常,请稍后重试",
icon: "none",
});
} finally {
this.loading = false;
}
},
// 获取模拟数据(仅用于测试)
getMockData() {
return [];
},
// 重置列表
resetList() {
this.enshrinedList = [];
this.pageNum = 1;
this.total = 0;
this.hasMore = true;
},
// 加载更多
loadMore() {
if (this.hasMore && !this.loading) {
this.pageNum++;
this.loadData();
}
},
// 格式化日期
formatDate(dateStr) {
return this.$u.date(dateStr, "yyyy-mm-dd");
// if (!dateStr) return '未知'
//
// try {
// // 如果已经是 YYYY-MM-DD 格式,直接返回
// if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
// return dateStr
// }
//
// const date = new Date(dateStr)
// if (isNaN(date.getTime())) {
// return dateStr
// }
//
// const year = date.getFullYear()
// const month = String(date.getMonth() + 1).padStart(2, '0')
// const day = String(date.getDate()).padStart(2, '0')
//
// return `${year}-${month}-${day}`
// } catch (error) {
// console.warn('日期格式化失败:', dateStr, error)
// return dateStr
// }
},
// 处理项目点击
handleItemClick(item) {
this.$emit("item-click", item);
},
// 刷新列表
refresh() {
this.resetList();
this.loadData();
},
},
};
</script>
<style lang="scss" scoped>
.enshrined-list {
padding: 46rpx 0 30rpx 44rpx;
width: 680rpx;
height: 858rpx;
background-color: #fffbf5;
border-radius: 20rpx 20rpx 20rpx 20rpx;
border: 1rpx solid #c7a26d;
margin-bottom: 12rpx;
}
.table-header {
display: flex;
border-radius: 12rpx 12rpx 0 0;
overflow: hidden;
justify-content: space-between;
}
.header-cell {
position: relative;
font-weight: 400;
font-size: 28rpx;
color: #695347;
line-height: 38rpx;
text-align: left;
&:last-child {
border-right: none;
}
&.worshiper-col {
flex: 2;
}
&.time-col {
flex: 2;
}
&.type-col {
flex: 2;
}
}
.table-body {
border-radius: 0 0 12rpx 12rpx;
overflow: hidden;
}
.table-row {
display: flex;
transition: background-color 0.2s ease;
margin-top: 30rpx;
//&:last-child {
// border-bottom: none;
//}
//
//&:hover {
// background-color: #f9f9f9;
//}
//
//&:active {
// background-color: #f0f0f0;
//}
//
//&:nth-child(even) {
// background-color: #fafafa;
//
// &:hover {
// background-color: #f5f5f5;
// }
//}
}
.table-cell {
//padding: 20rpx 16rpx;
word-break: break-all;
display: flex;
align-items: center;
font-weight: 400;
font-size: 24rpx;
color: #522510;
line-height: 32rpx;
text-align: left;
//border: 1rpx solid #C7A26D;
&:last-child {
border-right: none;
}
&.worshiper-col {
flex: 1;
font-weight: 500;
color: #333333;
}
&.time-col {
flex: 1;
color: #666666;
}
&.type-col {
flex: 1;
color: #666666;
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
background: #ffffff;
border-radius: 12rpx;
margin-top: 20rpx;
}
.empty-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
opacity: 0.5;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
.load-more {
text-align: center;
padding: 30rpx 0;
margin-top: 20rpx;
text {
font-size: 28rpx;
color: #666666;
padding: 16rpx 32rpx;
background: #ffffff;
border-radius: 24rpx;
}
}
.loading-state {
text-align: center;
padding: 30rpx 0;
background: #ffffff;
border-radius: 12rpx;
margin-top: 20rpx;
text {
font-size: 28rpx;
color: #999999;
}
}
</style>