157 lines
4.7 KiB
Vue
157 lines
4.7 KiB
Vue
|
|
<script setup>
|
|||
|
|
import { ref } from 'vue'
|
|||
|
|
|
|||
|
|
// 按日期分组的交易列表(当前为纯前端 Mock 数据,后续会接 Pinia/SQLite)
|
|||
|
|
const groupedTransactions = ref([
|
|||
|
|
{
|
|||
|
|
date: '今天, 5月20日',
|
|||
|
|
totalExpense: '42.50',
|
|||
|
|
items: [
|
|||
|
|
{
|
|||
|
|
title: '全家便利店',
|
|||
|
|
type: 'expense',
|
|||
|
|
amount: '24.50',
|
|||
|
|
time: '10:30',
|
|||
|
|
icon: 'ph-coffee',
|
|||
|
|
bg: 'bg-orange-100',
|
|||
|
|
color: 'text-orange-600',
|
|||
|
|
note: '早餐',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '滴滴出行',
|
|||
|
|
type: 'expense',
|
|||
|
|
amount: '18.00',
|
|||
|
|
time: '09:15',
|
|||
|
|
icon: 'ph-taxi',
|
|||
|
|
bg: 'bg-blue-100',
|
|||
|
|
color: 'text-blue-600',
|
|||
|
|
note: '',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
date: '昨天, 5月19日',
|
|||
|
|
totalExpense: '380.00',
|
|||
|
|
items: [
|
|||
|
|
{
|
|||
|
|
title: '工资收入',
|
|||
|
|
type: 'income',
|
|||
|
|
amount: '12,500.00',
|
|||
|
|
time: '18:00',
|
|||
|
|
icon: 'ph-wallet',
|
|||
|
|
bg: 'bg-emerald-100',
|
|||
|
|
color: 'text-emerald-600',
|
|||
|
|
note: '包含奖金',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: '乐刻健身',
|
|||
|
|
type: 'expense',
|
|||
|
|
amount: '380.00',
|
|||
|
|
time: '12:30',
|
|||
|
|
icon: 'ph-barbell',
|
|||
|
|
bg: 'bg-purple-100',
|
|||
|
|
color: 'text-purple-600',
|
|||
|
|
note: '月卡续费',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
date: '5月18日',
|
|||
|
|
totalExpense: '120.00',
|
|||
|
|
items: [
|
|||
|
|
{
|
|||
|
|
title: '山姆会员店',
|
|||
|
|
type: 'expense',
|
|||
|
|
amount: '120.00',
|
|||
|
|
time: '15:40',
|
|||
|
|
icon: 'ph-basket',
|
|||
|
|
bg: 'bg-red-100',
|
|||
|
|
color: 'text-red-600',
|
|||
|
|
note: '零食采购',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
])
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div class="space-y-4 pb-10 animate-fade-in">
|
|||
|
|
<!-- 顶部月份与统计卡片 -->
|
|||
|
|
<div class="sticky top-0 z-20 bg-warmOffwhite/95 backdrop-blur-sm py-2">
|
|||
|
|
<div class="flex justify-between items-center mb-4">
|
|||
|
|
<h2 class="text-2xl font-extrabold text-stone-800">账单明细</h2>
|
|||
|
|
<div
|
|||
|
|
class="flex items-center gap-2 bg-white border border-stone-100 px-3 py-1.5 rounded-full shadow-sm"
|
|||
|
|
>
|
|||
|
|
<span class="text-sm font-bold text-stone-600">2024年 5月</span>
|
|||
|
|
<i class="ph-bold ph-caret-down text-xs text-stone-400" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 汇总统计 -->
|
|||
|
|
<div class="flex gap-4 overflow-x-auto hide-scrollbar pb-2">
|
|||
|
|
<div
|
|||
|
|
class="shrink-0 bg-stone-700 text-white px-5 py-3 rounded-2xl shadow-lg shadow-stone-200 flex flex-col justify-center min-w-[140px]"
|
|||
|
|
>
|
|||
|
|
<span class="text-xs text-white/60 mb-1">总支出</span>
|
|||
|
|
<span class="font-bold text-xl">¥ 8,215.40</span>
|
|||
|
|
</div>
|
|||
|
|
<div
|
|||
|
|
class="shrink-0 bg-white text-stone-800 border border-stone-100 px-5 py-3 rounded-2xl flex flex-col justify-center min-w-[140px]"
|
|||
|
|
>
|
|||
|
|
<span class="text-xs text-stone-400 mb-1">总收入</span>
|
|||
|
|
<span class="font-bold text-xl text-emerald-500">+ ¥ 12,500</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 按日期分组列表 -->
|
|||
|
|
<div class="space-y-6 pb-10">
|
|||
|
|
<div v-for="(group, gIndex) in groupedTransactions" :key="gIndex">
|
|||
|
|
<div class="flex justify-between items-center mb-3 px-1">
|
|||
|
|
<h4 class="text-sm font-bold text-stone-400">{{ group.date }}</h4>
|
|||
|
|
<span class="text-xs text-stone-300 font-bold">支出 {{ group.totalExpense }}</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="bg-white rounded-3xl p-1 shadow-sm border border-stone-50">
|
|||
|
|
<div
|
|||
|
|
v-for="(item, iIndex) in group.items"
|
|||
|
|
:key="iIndex"
|
|||
|
|
class="flex items-center justify-between p-4 hover:bg-stone-50 rounded-2xl transition"
|
|||
|
|
>
|
|||
|
|
<div class="flex items-center gap-4">
|
|||
|
|
<div
|
|||
|
|
:class="[
|
|||
|
|
'w-10 h-10 rounded-full flex items-center justify-center text-lg shrink-0',
|
|||
|
|
item.bg,
|
|||
|
|
item.color,
|
|||
|
|
]"
|
|||
|
|
>
|
|||
|
|
<i :class="['ph-fill', item.icon]" />
|
|||
|
|
</div>
|
|||
|
|
<div>
|
|||
|
|
<p class="font-bold text-stone-800 text-sm">
|
|||
|
|
{{ item.title }}
|
|||
|
|
</p>
|
|||
|
|
<p class="text-xs text-stone-400 mt-0.5">
|
|||
|
|
{{ item.time }}
|
|||
|
|
<span v-if="item.note" class="text-stone-300">| {{ item.note }}</span>
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<span
|
|||
|
|
:class="[
|
|||
|
|
'font-bold text-base',
|
|||
|
|
item.type === 'expense' ? 'text-stone-800' : 'text-emerald-500',
|
|||
|
|
]"
|
|||
|
|
>
|
|||
|
|
{{ item.type === 'expense' ? '-' : '+' }} {{ item.amount }}
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|