2026-02-15 10:08:14 +08:00
|
|
|
|
<!--
|
|
|
|
|
|
CalendarV2 专用的交易列表组件
|
|
|
|
|
|
|
|
|
|
|
|
特殊功能:
|
|
|
|
|
|
- 自定义 header(Items 数量、Smart 按钮)
|
|
|
|
|
|
- 与日历视图紧密集成
|
2026-02-19 21:52:23 +08:00
|
|
|
|
- 使用统一的 BillListComponent 展示账单列表
|
2026-02-15 10:08:14 +08:00
|
|
|
|
|
2026-02-19 21:52:23 +08:00
|
|
|
|
迁移说明:已迁移至使用 BillListComponent,保留自定义 header 和 Smart 按钮
|
2026-02-15 10:08:14 +08:00
|
|
|
|
-->
|
2026-02-03 17:56:32 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<!-- 交易列表 -->
|
|
|
|
|
|
<div class="transactions">
|
2026-02-19 21:52:23 +08:00
|
|
|
|
<!-- 自定义 header (保留) -->
|
2026-02-03 17:56:32 +08:00
|
|
|
|
<div class="txn-header">
|
|
|
|
|
|
<h2 class="txn-title">
|
|
|
|
|
|
交易记录
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
<div class="txn-actions">
|
|
|
|
|
|
<div class="txn-badge badge-success">
|
|
|
|
|
|
{{ transactionCount }} Items
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button
|
|
|
|
|
|
class="smart-btn"
|
|
|
|
|
|
@click="onSmartClick"
|
|
|
|
|
|
>
|
|
|
|
|
|
<van-icon name="fire" />
|
|
|
|
|
|
<span>Smart</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-19 21:52:23 +08:00
|
|
|
|
<!-- 统一的账单列表组件 -->
|
|
|
|
|
|
<BillListComponent
|
|
|
|
|
|
data-source="custom"
|
|
|
|
|
|
:transactions="transactions"
|
|
|
|
|
|
:loading="transactionsLoading"
|
|
|
|
|
|
:finished="true"
|
|
|
|
|
|
:show-delete="false"
|
|
|
|
|
|
:enable-filter="false"
|
|
|
|
|
|
@click="onTransactionClick"
|
|
|
|
|
|
/>
|
2026-02-03 17:56:32 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { computed, watch, ref } from 'vue'
|
|
|
|
|
|
import { getTransactionsByDate } from '@/api/transactionRecord'
|
2026-02-19 21:52:23 +08:00
|
|
|
|
import BillListComponent from '@/components/Bill/BillListComponent.vue'
|
2026-02-03 17:56:32 +08:00
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
|
selectedDate: Date
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['transactionClick', 'smartClick'])
|
|
|
|
|
|
|
|
|
|
|
|
// 组件内部数据
|
|
|
|
|
|
const transactions = ref([])
|
|
|
|
|
|
const transactionsLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期为 key (yyyy-MM-dd)
|
|
|
|
|
|
const formatDateKey = (date) => {
|
|
|
|
|
|
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}`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取选中日期的交易列表
|
|
|
|
|
|
const fetchDayTransactions = async (date) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
transactionsLoading.value = true
|
|
|
|
|
|
const dateKey = formatDateKey(date)
|
|
|
|
|
|
const response = await getTransactionsByDate(dateKey)
|
|
|
|
|
|
|
|
|
|
|
|
if (response.success && response.data) {
|
2026-02-19 21:52:23 +08:00
|
|
|
|
// 直接使用原始数据,交给 BillListComponent 处理格式化
|
|
|
|
|
|
transactions.value = response.data
|
2026-02-03 17:56:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取交易记录失败:', error)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
transactionsLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 监听 selectedDate 变化,重新加载数据
|
2026-02-15 10:08:14 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => props.selectedDate,
|
|
|
|
|
|
async (newDate) => {
|
|
|
|
|
|
if (newDate) {
|
|
|
|
|
|
await fetchDayTransactions(newDate)
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true }
|
|
|
|
|
|
)
|
2026-02-03 17:56:32 +08:00
|
|
|
|
|
|
|
|
|
|
// 交易数量
|
|
|
|
|
|
const transactionCount = computed(() => transactions.value.length)
|
|
|
|
|
|
|
|
|
|
|
|
// 点击交易卡片
|
|
|
|
|
|
const onTransactionClick = (txn) => {
|
|
|
|
|
|
emit('transactionClick', txn)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 点击 Smart 按钮
|
|
|
|
|
|
const onSmartClick = () => {
|
|
|
|
|
|
emit('smartClick')
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
@import '@/assets/theme.css';
|
|
|
|
|
|
|
2026-02-19 21:52:23 +08:00
|
|
|
|
/* ========== 交易列表容器 ========== */
|
2026-02-03 17:56:32 +08:00
|
|
|
|
.transactions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: var(--spacing-lg);
|
|
|
|
|
|
padding: var(--spacing-3xl);
|
|
|
|
|
|
padding-top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-19 21:56:23 +08:00
|
|
|
|
/* 移除 BillListComponent 内部的左右 padding/margin */
|
|
|
|
|
|
:deep(.van-cell-group) {
|
|
|
|
|
|
margin-left: 0 !important;
|
|
|
|
|
|
margin-right: 0 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.van-list) {
|
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
|
padding-right: 0 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-19 21:52:23 +08:00
|
|
|
|
/* ========== 自定义 Header (保留) ========== */
|
2026-02-03 17:56:32 +08:00
|
|
|
|
.txn-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.txn-title {
|
|
|
|
|
|
font-family: var(--font-display);
|
|
|
|
|
|
font-size: var(--font-xl);
|
|
|
|
|
|
font-weight: var(--font-bold);
|
|
|
|
|
|
color: var(--text-primary);
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.txn-actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: var(--spacing-md);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.txn-badge {
|
|
|
|
|
|
padding: 6px 12px;
|
|
|
|
|
|
font-size: var(--font-base);
|
|
|
|
|
|
font-weight: var(--font-semibold);
|
|
|
|
|
|
border-radius: var(--radius-sm);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.badge-success {
|
|
|
|
|
|
background-color: var(--accent-success-bg);
|
|
|
|
|
|
color: var(--accent-success);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.smart-btn {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-left: 6px;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
padding: 6px 12px;
|
|
|
|
|
|
background-color: var(--accent-info-bg);
|
|
|
|
|
|
color: var(--accent-info);
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: var(--radius-sm);
|
|
|
|
|
|
font-size: var(--font-base);
|
|
|
|
|
|
font-weight: var(--font-semibold);
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: opacity 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.smart-btn:active {
|
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|