feat:新增账单导出、支付宝账单导入
This commit is contained in:
@@ -102,30 +102,30 @@ const hasData = computed(() => groupedTransactions.value.length > 0)
|
||||
|
||||
<template>
|
||||
<div class="space-y-5 pb-10 animate-fade-in">
|
||||
<div class="sticky top-0 z-20 bg-warmOffwhite/95 backdrop-blur-sm py-2">
|
||||
<div class="sticky top-0 z-20 bg-warmOffwhite/95 backdrop-blur-sm py-3">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h2 class="text-2xl font-extrabold text-stone-800">账单明细</h2>
|
||||
<button
|
||||
class="flex items-center gap-2 bg-white border border-stone-100 px-3 py-1.5 rounded-full shadow-sm text-xs font-bold text-stone-500"
|
||||
class="flex items-center gap-2 bg-white border border-stone-100 px-3.5 py-2 rounded-full shadow-sm text-xs font-bold text-stone-500"
|
||||
@click="uiStore.openAddEntry()"
|
||||
>
|
||||
<i class="ph-bold ph-plus" /> 新增
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 overflow-x-auto pb-2 hide-scrollbar">
|
||||
<div class="flex gap-3 overflow-x-auto pb-3 hide-scrollbar">
|
||||
<button
|
||||
v-for="chip in categoryChips"
|
||||
:key="chip.value"
|
||||
class="px-3 py-1.5 rounded-full text-xs font-bold flex items-center gap-1 border transition"
|
||||
class="shrink-0 min-h-[44px] px-4 py-2.5 rounded-[22px] text-sm font-bold flex items-center gap-2 border transition whitespace-nowrap"
|
||||
:class="
|
||||
filters.category === chip.value
|
||||
? 'bg-gradient-warm text-white border-transparent shadow-sm'
|
||||
? 'bg-gradient-warm text-white border-transparent shadow-sm shadow-orange-200/40'
|
||||
: 'bg-white text-stone-500 border-stone-100'
|
||||
"
|
||||
@click="setCategory(chip.value)"
|
||||
>
|
||||
<i :class="['text-sm', chip.icon]" />
|
||||
<i :class="['text-base', chip.icon]" />
|
||||
{{ chip.label }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@ const hasData = computed(() => groupedTransactions.value.length > 0)
|
||||
<div class="flex items-center justify-between text-[11px] text-stone-400 font-bold px-1">
|
||||
<span>点按一条记录可快速编辑</span>
|
||||
<button
|
||||
class="flex items-center gap-1 px-2 py-1 rounded-full border border-stone-200"
|
||||
class="flex items-center gap-1.5 px-2.5 py-1.5 rounded-full border border-stone-200"
|
||||
:class="filters.showOnlyToday ? 'bg-gradient-warm text-white border-transparent' : 'bg-white'"
|
||||
@click="toggleTodayOnly"
|
||||
>
|
||||
@@ -163,16 +163,16 @@ const hasData = computed(() => groupedTransactions.value.length > 0)
|
||||
<span class="text-xs text-stone-300 font-bold">{{ group.dayKey }}</span>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-3xl p-1 shadow-sm border border-stone-50 divide-y divide-stone-50">
|
||||
<div class="bg-white rounded-[28px] p-2 shadow-sm border border-stone-50 divide-y divide-stone-50">
|
||||
<div
|
||||
v-for="item in group.items"
|
||||
:key="item.id"
|
||||
class="flex items-center justify-between p-4 hover:bg-stone-50 rounded-2xl transition group"
|
||||
class="flex items-start justify-between gap-4 px-4 py-4 hover:bg-stone-50 rounded-[22px] transition group"
|
||||
@click="handleEdit(item)"
|
||||
>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex min-w-0 flex-1 items-start gap-4">
|
||||
<div
|
||||
class="w-11 h-11 rounded-2xl bg-stone-100 flex items-center justify-center text-stone-500 group-active:scale-95 transition"
|
||||
class="shrink-0 w-11 h-11 rounded-[18px] bg-stone-100 flex items-center justify-center text-stone-500 group-active:scale-95 transition"
|
||||
>
|
||||
<i
|
||||
:class="[
|
||||
@@ -181,9 +181,9 @@ const hasData = computed(() => groupedTransactions.value.length > 0)
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<p class="font-bold text-stone-800 text-sm">
|
||||
<div class="min-w-0 flex-1 space-y-1.5">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<p class="min-w-0 text-[15px] leading-6 font-bold text-stone-800 break-words">
|
||||
{{ item.merchant }}
|
||||
</p>
|
||||
<span
|
||||
@@ -209,34 +209,34 @@ const hasData = computed(() => groupedTransactions.value.length > 0)
|
||||
{{ resolveAiBadge(item).label }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-stone-400 mt-0.5">
|
||||
<p class="text-xs leading-5 text-stone-400">
|
||||
{{ formatTime(item.date) }}
|
||||
<span v-if="item.category" class="text-stone-300">
|
||||
· {{ getCategoryLabel(item.category) }}
|
||||
</span>
|
||||
<span v-if="item.note" class="text-stone-300">
|
||||
<span v-if="item.note" class="text-stone-300 break-words">
|
||||
· {{ item.note }}
|
||||
</span>
|
||||
</p>
|
||||
<p v-if="formatLedgerHint(item)" class="text-[10px] text-stone-400 mt-1">
|
||||
<p v-if="formatLedgerHint(item)" class="text-[11px] leading-5 text-stone-400">
|
||||
{{ formatLedgerHint(item) }}
|
||||
</p>
|
||||
<p v-if="formatAiHint(item)" class="text-[10px] text-stone-400 mt-1">
|
||||
<p v-if="formatAiHint(item)" class="text-[11px] leading-5 text-stone-400">
|
||||
{{ formatAiHint(item) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="shrink-0 pl-2 text-right space-y-1.5">
|
||||
<p
|
||||
:class="[
|
||||
'font-bold text-base',
|
||||
'font-bold text-base leading-none',
|
||||
item.amount < 0 ? 'text-stone-800' : 'text-emerald-600',
|
||||
]"
|
||||
>
|
||||
{{ formatAmount(item.amount) }}
|
||||
</p>
|
||||
<button
|
||||
class="text-[11px] text-stone-400 mt-1"
|
||||
class="text-[11px] text-stone-400"
|
||||
:disabled="deletingId === item.id"
|
||||
@click.stop="handleDelete(item)"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user