Files
EmailBill/Web/src/views/TransactionsRecord.vue

247 lines
5.9 KiB
Vue
Raw Normal View History

2025-12-25 11:20:56 +08:00
<template>
2025-12-27 21:15:26 +08:00
<div class="page-container-flex">
<!-- 顶部固定搜索框 -->
<div class="top-search-bar">
<van-search
v-model="searchKeyword"
placeholder="搜索交易摘要、来源、卡号、分类"
shape="round"
@update:model-value="onSearchChange"
@clear="onSearchClear"
/>
</div>
2025-12-25 11:20:56 +08:00
<!-- 下拉刷新区域 -->
2025-12-27 21:15:26 +08:00
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
2025-12-25 11:20:56 +08:00
<!-- 加载提示 -->
2026-01-16 11:15:44 +08:00
<van-loading
v-if="loading && !(transactionList && transactionList.length)"
vertical
style="padding: 50px 0"
>
2025-12-25 11:20:56 +08:00
加载中...
</van-loading>
<!-- 交易记录列表 -->
<TransactionList
:transactions="transactionList"
:loading="loading"
:finished="finished"
2026-01-01 11:58:21 +08:00
:show-delete="true"
2025-12-25 11:20:56 +08:00
@load="onLoad"
@click="viewDetail"
2026-01-16 11:15:44 +08:00
@delete="
(id) => {
// 从当前的交易列表中移除该交易
transactionList.value = transactionList.value.filter((t) => t.id !== id)
}
"
2025-12-25 11:20:56 +08:00
/>
2025-12-28 10:23:57 +08:00
<!-- 底部安全距离 -->
2026-01-16 11:15:44 +08:00
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))" />
2025-12-25 11:20:56 +08:00
</van-pull-refresh>
<!-- 详情/编辑弹出层 -->
<TransactionDetail
v-model:show="detailVisible"
:transaction="currentTransaction"
@save="onDetailSave"
/>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
2026-01-01 11:58:21 +08:00
import { showToast } from 'vant'
2026-01-16 11:15:44 +08:00
import { getTransactionList, getTransactionDetail } from '@/api/transactionRecord'
2025-12-25 11:20:56 +08:00
import TransactionList from '@/components/TransactionList.vue'
import TransactionDetail from '@/components/TransactionDetail.vue'
const transactionList = ref([])
const loading = ref(false)
const refreshing = ref(false)
const finished = ref(false)
2025-12-27 22:05:50 +08:00
const pageIndex = ref(1)
const pageSize = 20
2025-12-25 11:20:56 +08:00
const total = ref(0)
const detailVisible = ref(false)
const currentTransaction = ref(null)
// 搜索相关
const searchKeyword = ref('')
let searchTimer = null
// 加载数据
const loadData = async (isRefresh = false) => {
if (isRefresh) {
2025-12-27 22:05:50 +08:00
pageIndex.value = 1
2025-12-25 11:20:56 +08:00
transactionList.value = []
finished.value = false
}
loading.value = true
try {
2025-12-27 22:05:50 +08:00
const params = {
pageIndex: pageIndex.value,
pageSize: pageSize
2025-12-25 11:20:56 +08:00
}
2026-01-16 11:15:44 +08:00
2025-12-25 11:20:56 +08:00
// 添加搜索关键词
if (searchKeyword.value) {
params.searchKeyword = searchKeyword.value
}
2026-01-16 11:15:44 +08:00
2025-12-25 11:20:56 +08:00
const response = await getTransactionList(params)
2026-01-16 11:15:44 +08:00
2025-12-25 11:20:56 +08:00
if (response.success) {
const newList = response.data || []
total.value = response.total || 0
2026-01-16 11:15:44 +08:00
2025-12-25 11:20:56 +08:00
if (isRefresh) {
transactionList.value = newList
} else {
transactionList.value = [...(transactionList.value || []), ...newList]
}
2026-01-16 11:15:44 +08:00
2025-12-27 22:05:50 +08:00
if (newList.length === 0 || newList.length < pageSize) {
2025-12-25 11:20:56 +08:00
finished.value = true
} else {
finished.value = false
2025-12-27 22:05:50 +08:00
pageIndex.value++
2025-12-25 11:20:56 +08:00
}
} else {
showToast(response.message || '加载数据失败')
finished.value = true
}
} catch (error) {
console.error('加载数据出错:', error)
showToast('加载数据出错: ' + (error.message || '未知错误'))
finished.value = true
} finally {
loading.value = false
refreshing.value = false
}
}
// 下拉刷新
const onRefresh = () => {
finished.value = false
transactionList.value = []
2026-01-01 11:58:21 +08:00
loadData(true)
2025-12-25 11:20:56 +08:00
}
// 搜索相关方法
const onSearchChange = () => {
// 防抖处理用户停止输入500ms后自动搜索
if (searchTimer) {
clearTimeout(searchTimer)
}
searchTimer = setTimeout(() => {
onSearch()
}, 500)
}
const onSearch = () => {
// 重置分页状态并刷新数据
transactionList.value = []
finished.value = false
loadData(true)
}
const onSearchClear = () => {
searchKeyword.value = ''
onSearch()
}
// 加载更多
const onLoad = () => {
loadData(false)
}
// 查看详情
const viewDetail = async (transaction) => {
try {
const response = await getTransactionDetail(transaction.id)
if (response.success) {
currentTransaction.value = response.data
detailVisible.value = true
} else {
showToast(response.message || '获取详情失败')
}
} catch (error) {
console.error('获取详情出错:', error)
showToast('获取详情失败')
}
}
// 详情保存后的回调
const onDetailSave = async () => {
loadData(true)
}
2026-01-01 11:58:21 +08:00
// 删除功能由 TransactionList 组件内部处理,组件通过 :show-delete 启用
2025-12-25 11:20:56 +08:00
onMounted(async () => {
// 不需要手动调用 loadDatavan-list 会自动触发 onLoad
})
2025-12-28 10:23:57 +08:00
2026-01-01 11:58:21 +08:00
// 监听全局删除事件,保持页面一致性
const onGlobalTransactionDeleted = () => {
2026-01-01 11:58:21 +08:00
// 如果在此页面,重新刷新当前列表以保持数据一致
transactionList.value = []
pageIndex.value = 1
finished.value = false
loadData(true)
}
2026-01-16 11:15:44 +08:00
window.addEventListener &&
window.addEventListener('transaction-deleted', onGlobalTransactionDeleted)
2026-01-01 11:58:21 +08:00
onBeforeUnmount(() => {
2026-01-16 11:15:44 +08:00
window.removeEventListener &&
window.removeEventListener('transaction-deleted', onGlobalTransactionDeleted)
2026-01-01 11:58:21 +08:00
})
// 外部新增/修改/批量更新时的刷新监听
const onGlobalTransactionsChanged = () => {
2026-01-01 11:58:21 +08:00
transactionList.value = []
pageIndex.value = 1
finished.value = false
loadData(true)
}
2026-01-16 11:15:44 +08:00
window.addEventListener &&
window.addEventListener('transactions-changed', onGlobalTransactionsChanged)
2026-01-01 11:58:21 +08:00
onBeforeUnmount(() => {
2026-01-16 11:15:44 +08:00
window.removeEventListener &&
window.removeEventListener('transactions-changed', onGlobalTransactionsChanged)
2026-01-01 11:58:21 +08:00
})
2025-12-25 11:20:56 +08:00
</script>
<style scoped>
2025-12-27 21:15:26 +08:00
:deep(.van-pull-refresh) {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.top-search-bar {
background: var(--van-background-2);
padding: 4px 12px;
z-index: 100;
margin-top: 10px;
2025-12-25 11:20:56 +08:00
}
.top-search-bar :deep(.van-search) {
padding: 4px 0;
background: transparent;
2025-12-25 11:20:56 +08:00
}
2025-12-26 18:03:52 +08:00
/* 设置页面容器背景色 */
:deep(.van-nav-bar) {
background: transparent !important;
}
2026-01-16 11:15:44 +08:00
</style>