2026-01-07 14:33:30 +08:00
|
|
|
|
<!-- eslint-disable vue/no-v-html -->
|
|
|
|
|
|
<template>
|
2025-12-27 21:15:26 +08:00
|
|
|
|
<div class="page-container-flex">
|
2025-12-25 11:20:56 +08:00
|
|
|
|
<!-- 下拉刷新区域 -->
|
2026-01-16 11:15:44 +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 && !(emailList && emailList.length)"
|
|
|
|
|
|
vertical
|
|
|
|
|
|
style="padding: 50px 0"
|
|
|
|
|
|
>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
加载中...
|
|
|
|
|
|
</van-loading>
|
|
|
|
|
|
<!-- 邮件列表 -->
|
|
|
|
|
|
<van-list
|
|
|
|
|
|
v-model:loading="loading"
|
|
|
|
|
|
:finished="finished"
|
|
|
|
|
|
finished-text="没有更多了"
|
|
|
|
|
|
@load="onLoad"
|
|
|
|
|
|
>
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<van-cell-group
|
|
|
|
|
|
v-if="emailList && emailList.length"
|
|
|
|
|
|
inset
|
|
|
|
|
|
style="margin-top: 10px"
|
|
|
|
|
|
>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
<van-swipe-cell
|
|
|
|
|
|
v-for="email in emailList"
|
|
|
|
|
|
:key="email.id"
|
|
|
|
|
|
>
|
|
|
|
|
|
<van-cell
|
|
|
|
|
|
:title="email.subject"
|
2025-12-27 16:54:08 +08:00
|
|
|
|
:label="`来自: ${email.from}\n收件: ${email.toName || email.to || '未知'}`"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
is-link
|
|
|
|
|
|
@click="viewDetail(email)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #value>
|
|
|
|
|
|
<div class="email-info">
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<div class="email-date">
|
|
|
|
|
|
{{ formatDate(email.receivedDate) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-if="email.transactionCount > 0"
|
|
|
|
|
|
class="bill-count"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span style="font-size: 12px">已解析{{ email.transactionCount }}条账单</span>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</van-cell>
|
|
|
|
|
|
<template #right>
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<van-button
|
2025-12-25 11:20:56 +08:00
|
|
|
|
square
|
2026-01-16 11:15:44 +08:00
|
|
|
|
type="danger"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
text="删除"
|
|
|
|
|
|
class="delete-button"
|
|
|
|
|
|
@click="handleDelete(email)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</van-swipe-cell>
|
|
|
|
|
|
</van-cell-group>
|
|
|
|
|
|
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<van-empty
|
|
|
|
|
|
v-if="!loading && !(emailList && emailList.length)"
|
|
|
|
|
|
description="暂无邮件记录"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</van-list>
|
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>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 详情弹出层 -->
|
2026-01-01 15:20:59 +08:00
|
|
|
|
<PopupContainer
|
|
|
|
|
|
v-model="detailVisible"
|
2026-01-16 11:15:44 +08:00
|
|
|
|
:title="currentEmail ? currentEmail.Subject || currentEmail.subject || '(无主题)' : ''"
|
2026-01-11 11:21:13 +08:00
|
|
|
|
height="75%"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
>
|
2026-01-01 15:20:59 +08:00
|
|
|
|
<template #header-actions>
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<van-button
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
type="primary"
|
2026-01-01 15:20:59 +08:00
|
|
|
|
:loading="refreshingAnalysis"
|
|
|
|
|
|
@click="handleRefreshAnalysis"
|
|
|
|
|
|
>
|
|
|
|
|
|
重新分析
|
|
|
|
|
|
</van-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="currentEmail">
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<van-cell-group
|
|
|
|
|
|
inset
|
|
|
|
|
|
style="margin-top: 12px"
|
|
|
|
|
|
>
|
|
|
|
|
|
<van-cell
|
|
|
|
|
|
title="发件人"
|
|
|
|
|
|
:value="currentEmail.From || currentEmail.from || '未知'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<van-cell
|
|
|
|
|
|
title="接收时间"
|
|
|
|
|
|
:value="formatDate(currentEmail.ReceivedDate || currentEmail.receivedDate)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<van-cell
|
|
|
|
|
|
title="记录时间"
|
|
|
|
|
|
:value="formatDate(currentEmail.CreateTime || currentEmail.createTime)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<van-cell
|
|
|
|
|
|
v-if="(currentEmail.TransactionCount || currentEmail.transactionCount || 0) > 0"
|
|
|
|
|
|
title="已解析账单数"
|
2026-01-07 14:33:30 +08:00
|
|
|
|
:value="`${currentEmail.TransactionCount || currentEmail.transactionCount || 0}条`"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
is-link
|
|
|
|
|
|
@click="viewTransactions"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</van-cell-group>
|
|
|
|
|
|
<div class="email-content">
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<h4 style="margin-left: 10px">
|
|
|
|
|
|
邮件内容
|
|
|
|
|
|
</h4>
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-if="currentEmail.htmlBody"
|
|
|
|
|
|
class="content-body html-content"
|
2026-01-07 14:33:30 +08:00
|
|
|
|
v-html="currentEmail.htmlBody"
|
2026-01-16 11:15:44 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-else-if="currentEmail.body"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
class="content-body"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ currentEmail.body }}
|
|
|
|
|
|
</div>
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-else
|
|
|
|
|
|
class="content-body empty-content"
|
|
|
|
|
|
>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
暂无邮件内容
|
2026-01-16 11:15:44 +08:00
|
|
|
|
<div style="font-size: 12px; margin-top: 8px; color: var(--van-gray-6)">
|
2025-12-25 11:20:56 +08:00
|
|
|
|
Debug: {{ Object.keys(currentEmail).join(', ') }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-01 15:20:59 +08:00
|
|
|
|
</PopupContainer>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 账单列表弹出层 -->
|
2025-12-30 17:02:30 +08:00
|
|
|
|
<PopupContainer
|
|
|
|
|
|
v-model="transactionListVisible"
|
|
|
|
|
|
title="关联账单列表"
|
2026-01-11 11:21:13 +08:00
|
|
|
|
height="75%"
|
2025-12-25 11:20:56 +08:00
|
|
|
|
>
|
2025-12-30 17:02:30 +08:00
|
|
|
|
<TransactionList
|
|
|
|
|
|
:transactions="transactionList"
|
|
|
|
|
|
:loading="false"
|
|
|
|
|
|
:finished="true"
|
2025-12-31 11:49:25 +08:00
|
|
|
|
:show-delete="true"
|
2025-12-30 17:02:30 +08:00
|
|
|
|
@click="handleTransactionClick"
|
2026-01-01 11:58:21 +08:00
|
|
|
|
@delete="handleTransactionDelete"
|
2025-12-30 17:02:30 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</PopupContainer>
|
2025-12-25 11:20:56 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 账单详情编辑弹出层 -->
|
|
|
|
|
|
<TransactionDetail
|
|
|
|
|
|
:show="transactionDetailVisible"
|
|
|
|
|
|
:transaction="currentTransaction"
|
|
|
|
|
|
@update:show="transactionDetailVisible = $event"
|
|
|
|
|
|
@save="handleTransactionSave"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-01-01 11:58:21 +08:00
|
|
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
2025-12-25 11:20:56 +08:00
|
|
|
|
import { showToast, showConfirmDialog } from 'vant'
|
2026-01-16 11:15:44 +08:00
|
|
|
|
import {
|
|
|
|
|
|
getEmailList,
|
|
|
|
|
|
getEmailDetail,
|
|
|
|
|
|
deleteEmail,
|
|
|
|
|
|
refreshTransactionRecords,
|
|
|
|
|
|
syncEmails,
|
|
|
|
|
|
getEmailTransactions
|
|
|
|
|
|
} from '@/api/emailRecord'
|
2025-12-25 11:20:56 +08:00
|
|
|
|
import { getTransactionDetail } from '@/api/transactionRecord'
|
|
|
|
|
|
import TransactionList from '@/components/TransactionList.vue'
|
|
|
|
|
|
import TransactionDetail from '@/components/TransactionDetail.vue'
|
2025-12-30 17:02:30 +08:00
|
|
|
|
import PopupContainer from '@/components/PopupContainer.vue'
|
2025-12-25 11:20:56 +08:00
|
|
|
|
|
|
|
|
|
|
const emailList = 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 currentEmail = ref(null)
|
|
|
|
|
|
const refreshingAnalysis = ref(false)
|
|
|
|
|
|
const syncing = ref(false)
|
|
|
|
|
|
const transactionListVisible = ref(false)
|
|
|
|
|
|
const transactionList = ref([])
|
|
|
|
|
|
const transactionDetailVisible = ref(false)
|
|
|
|
|
|
const currentTransaction = ref(null)
|
|
|
|
|
|
|
|
|
|
|
|
// 加载数据
|
|
|
|
|
|
const loadData = async (isRefresh = false) => {
|
2026-01-16 11:15:44 +08:00
|
|
|
|
if (loading.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
} // 防止重复加载
|
|
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
if (isRefresh) {
|
2025-12-27 22:05:50 +08:00
|
|
|
|
pageIndex.value = 1
|
2025-12-25 11:20:56 +08:00
|
|
|
|
emailList.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
|
|
|
|
const response = await getEmailList(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) {
|
|
|
|
|
|
emailList.value = newList
|
|
|
|
|
|
} else {
|
|
|
|
|
|
emailList.value = [...(emailList.value || []), ...newList]
|
|
|
|
|
|
}
|
2026-01-16 11:15:44 +08:00
|
|
|
|
|
2025-12-27 22:05:50 +08:00
|
|
|
|
// 判断是否还有更多数据(返回数据少于pageSize条或为空,说明没有更多了)
|
|
|
|
|
|
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 = () => {
|
|
|
|
|
|
loadData(true)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载更多
|
|
|
|
|
|
const onLoad = () => {
|
|
|
|
|
|
if (!finished.value && !loading.value) {
|
|
|
|
|
|
loadData()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查看详情
|
|
|
|
|
|
const viewDetail = async (email) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await getEmailDetail(email.id)
|
|
|
|
|
|
console.log('详情 API 返回:', response)
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
currentEmail.value = response.data
|
|
|
|
|
|
console.log('currentEmail:', currentEmail.value)
|
|
|
|
|
|
detailVisible.value = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '获取详情失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取详情出错:', error)
|
|
|
|
|
|
showToast('获取详情失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除
|
|
|
|
|
|
const handleDelete = async (email) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await showConfirmDialog({
|
|
|
|
|
|
title: '提示',
|
2026-01-16 11:15:44 +08:00
|
|
|
|
message: '确定要删除这封邮件吗?'
|
2025-12-25 11:20:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const response = await deleteEmail(email.id)
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
showToast('删除成功')
|
|
|
|
|
|
loadData(true)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '删除失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
if (error !== 'cancel') {
|
|
|
|
|
|
console.error('删除出错:', error)
|
|
|
|
|
|
showToast('删除失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重新分析
|
|
|
|
|
|
const handleRefreshAnalysis = async () => {
|
2026-01-16 11:15:44 +08:00
|
|
|
|
if (!currentEmail.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
try {
|
|
|
|
|
|
await showConfirmDialog({
|
|
|
|
|
|
title: '提示',
|
2026-01-16 11:15:44 +08:00
|
|
|
|
message: '确定要重新分析该邮件并刷新交易记录吗?'
|
2025-12-25 11:20:56 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
refreshingAnalysis.value = true
|
2026-01-01 11:58:21 +08:00
|
|
|
|
const response = await refreshTransactionRecords(currentEmail.value.id)
|
2026-01-16 11:15:44 +08:00
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
if (response.success) {
|
|
|
|
|
|
showToast('重新分析成功')
|
|
|
|
|
|
detailVisible.value = false
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '重新分析失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
if (error !== 'cancel') {
|
|
|
|
|
|
console.error('重新分析出错:', error)
|
|
|
|
|
|
showToast('重新分析失败: ' + (error.message || '未知错误'))
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
refreshingAnalysis.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 立即同步
|
|
|
|
|
|
const handleSync = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
syncing.value = true
|
|
|
|
|
|
const response = await syncEmails()
|
2026-01-16 11:15:44 +08:00
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
if (response.success) {
|
|
|
|
|
|
showToast(response.message || '同步成功')
|
|
|
|
|
|
// 同步成功后刷新列表
|
|
|
|
|
|
loadData(true)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '同步失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('同步出错:', error)
|
|
|
|
|
|
showToast('同步失败: ' + (error.message || '未知错误'))
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
syncing.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查看关联的账单列表
|
|
|
|
|
|
const viewTransactions = async () => {
|
2026-01-16 11:15:44 +08:00
|
|
|
|
if (!currentEmail.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
try {
|
2026-01-01 11:58:21 +08:00
|
|
|
|
const emailId = currentEmail.value.id
|
2025-12-25 11:20:56 +08:00
|
|
|
|
const response = await getEmailTransactions(emailId)
|
2026-01-16 11:15:44 +08:00
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
if (response.success) {
|
|
|
|
|
|
transactionList.value = response.data || []
|
|
|
|
|
|
transactionListVisible.value = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '获取账单列表失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取账单列表出错:', error)
|
|
|
|
|
|
showToast('获取账单列表失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-01 11:58:21 +08:00
|
|
|
|
// 监听全局删除事件,保持弹窗内交易列表一致
|
|
|
|
|
|
const onGlobalTransactionDeleted = (e) => {
|
2026-01-01 15:20:59 +08:00
|
|
|
|
console.log('收到全局交易删除事件:', e)
|
2026-01-01 11:58:21 +08:00
|
|
|
|
// 如果交易列表弹窗打开,尝试重新加载邮箱的交易列表
|
|
|
|
|
|
if (transactionListVisible.value && currentEmail.value) {
|
|
|
|
|
|
const emailId = currentEmail.value.id || currentEmail.value.Id
|
2026-01-16 11:15:44 +08:00
|
|
|
|
getEmailTransactions(emailId)
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
transactionList.value = response.data || []
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {})
|
2026-01-01 11:58:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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 = (e) => {
|
2026-01-01 15:20:59 +08:00
|
|
|
|
console.log('收到全局交易变更事件:', e)
|
2026-01-01 11:58:21 +08:00
|
|
|
|
if (transactionListVisible.value && currentEmail.value) {
|
|
|
|
|
|
const emailId = currentEmail.value.id || currentEmail.value.Id
|
2026-01-16 11:15:44 +08:00
|
|
|
|
getEmailTransactions(emailId)
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
transactionList.value = response.data || []
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {})
|
2026-01-01 11:58:21 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// 也刷新邮件列表以保持统计一致
|
|
|
|
|
|
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
|
|
|
|
// 处理点击账单
|
|
|
|
|
|
const handleTransactionClick = async (transaction) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await getTransactionDetail(transaction.id)
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
currentTransaction.value = response.data
|
|
|
|
|
|
transactionDetailVisible.value = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(response.message || '获取账单详情失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取账单详情出错:', error)
|
|
|
|
|
|
showToast('获取账单详情失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-01 11:58:21 +08:00
|
|
|
|
const handleTransactionDelete = (transactionId) => {
|
|
|
|
|
|
// 从当前的交易列表中移除该交易
|
2026-01-16 11:15:44 +08:00
|
|
|
|
transactionList.value = transactionList.value.filter((t) => t.id !== transactionId)
|
2026-01-01 11:58:21 +08:00
|
|
|
|
|
|
|
|
|
|
// 刷新邮件列表
|
|
|
|
|
|
loadData(true)
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新当前邮件详情
|
|
|
|
|
|
if (currentEmail.value) {
|
|
|
|
|
|
const emailId = currentEmail.value.id
|
2026-01-16 11:15:44 +08:00
|
|
|
|
getEmailDetail(emailId).then((response) => {
|
2026-01-01 11:58:21 +08:00
|
|
|
|
if (response.success) {
|
|
|
|
|
|
currentEmail.value = response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2026-01-16 11:15:44 +08:00
|
|
|
|
try {
|
|
|
|
|
|
window.dispatchEvent(new CustomEvent('transaction-deleted', { detail: transactionId }))
|
|
|
|
|
|
} catch (e) {
|
2026-01-01 15:20:59 +08:00
|
|
|
|
console.error(e)
|
|
|
|
|
|
}
|
2026-01-01 11:58:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
// 账单保存后刷新列表
|
|
|
|
|
|
const handleTransactionSave = async () => {
|
|
|
|
|
|
// 刷新账单列表
|
|
|
|
|
|
if (currentEmail.value) {
|
2026-01-01 11:58:21 +08:00
|
|
|
|
const emailId = currentEmail.value.id
|
2025-12-25 11:20:56 +08:00
|
|
|
|
const response = await getEmailTransactions(emailId)
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
transactionList.value = response.data || []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-16 11:15:44 +08:00
|
|
|
|
try {
|
2026-01-01 15:20:59 +08:00
|
|
|
|
window.dispatchEvent(
|
2026-01-16 11:15:44 +08:00
|
|
|
|
new CustomEvent('transactions-changed', {
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
emailId: currentEmail.value?.id
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
)
|
|
|
|
|
|
} catch (e) {
|
2026-01-01 15:20:59 +08:00
|
|
|
|
console.error(e)
|
|
|
|
|
|
}
|
2025-12-25 11:20:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期
|
|
|
|
|
|
const formatDate = (dateString) => {
|
2026-01-16 11:15:44 +08:00
|
|
|
|
if (!dateString) {
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
2025-12-25 11:20:56 +08:00
|
|
|
|
const date = new Date(dateString)
|
2026-01-16 11:15:44 +08:00
|
|
|
|
return date.toLocaleString('zh-CN', {
|
|
|
|
|
|
year: 'numeric',
|
|
|
|
|
|
month: '2-digit',
|
2025-12-25 11:20:56 +08:00
|
|
|
|
day: '2-digit',
|
|
|
|
|
|
hour: '2-digit',
|
|
|
|
|
|
minute: '2-digit',
|
|
|
|
|
|
second: '2-digit'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
loadData(true)
|
|
|
|
|
|
})
|
2025-12-28 10:23:57 +08:00
|
|
|
|
|
|
|
|
|
|
// 暴露给父级方法调用
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
|
handleSync
|
|
|
|
|
|
})
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 11:20:56 +08:00
|
|
|
|
.email-info {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bill-count {
|
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.email-date {
|
|
|
|
|
|
font-size: 12px;
|
2026-01-13 17:00:44 +08:00
|
|
|
|
color: var(--van-text-color-2);
|
2025-12-25 11:20:56 +08:00
|
|
|
|
padding-right: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.email-content {
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.email-content h4 {
|
|
|
|
|
|
margin: 0 0 12px 0;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.content-body {
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
white-space: pre-wrap;
|
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
max-height: 300px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
margin: 0 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-13 17:00:44 +08:00
|
|
|
|
/* @media (prefers-color-scheme: dark) {
|
2025-12-25 11:20:56 +08:00
|
|
|
|
.content-body {
|
2026-01-13 17:00:44 +08:00
|
|
|
|
background-color: var(--van-background-2);
|
|
|
|
|
|
border: 1px solid var(--van-border-color);
|
2025-12-25 11:20:56 +08:00
|
|
|
|
}
|
2026-01-13 17:00:44 +08:00
|
|
|
|
} */
|
2025-12-25 11:20:56 +08:00
|
|
|
|
|
|
|
|
|
|
.delete-button {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
2025-12-26 18:03:52 +08:00
|
|
|
|
|
|
|
|
|
|
/* 设置页面容器背景色 */
|
|
|
|
|
|
:deep(.van-nav-bar) {
|
|
|
|
|
|
background: transparent !important;
|
|
|
|
|
|
}
|
2026-01-16 11:15:44 +08:00
|
|
|
|
</style>
|