feat: 添加账单软删除功能

- 新增删除按钮(带二次确认)到账单详情抽屉
- 后端实现软删除(设置 is_deleted 标记)
- 所有查询方法自动过滤已删除记录
- 账单列表和复核页面都支持删除
- 版本更新至 1.2.0
This commit is contained in:
clz
2026-01-25 18:49:07 +08:00
parent a97a8d6a20
commit bacbabc0a5
12 changed files with 373 additions and 8 deletions

View File

@@ -12,6 +12,8 @@
import { Separator } from '$lib/components/ui/separator';
import { DateRangePicker } from '$lib/components/ui/date-range-picker';
import ManualBillInput from '$lib/components/bills/ManualBillInput.svelte';
import BillDetailDrawer from '$lib/components/analysis/BillDetailDrawer.svelte';
import { cleanedBillToUIBill, type UIBill } from '$lib/models/bill';
import { formatLocalDate, formatDateTime } from '$lib/utils';
import Loader2 from '@lucide/svelte/icons/loader-2';
import AlertCircle from '@lucide/svelte/icons/alert-circle';
@@ -178,6 +180,51 @@
// 重新加载账单列表(保持当前日期筛选)
loadBills();
}
// 账单详情抽屉
let drawerOpen = $state(false);
let selectedBill = $state<UIBill | null>(null);
// 点击行打开详情
function handleRowClick(record: CleanedBill) {
selectedBill = cleanedBillToUIBill(record);
drawerOpen = true;
}
// 更新账单后刷新列表
function handleBillUpdate(updated: UIBill) {
// 在当前列表中更新对应的记录
const index = records.findIndex(r => r.id === updated.id);
if (index !== -1) {
records[index] = {
...records[index],
time: updated.time,
category: updated.category,
merchant: updated.merchant,
description: updated.description || '',
income_expense: updated.incomeExpense,
amount: updated.amount,
pay_method: updated.paymentMethod || '',
status: updated.status || '',
remark: updated.remark || '',
review_level: updated.reviewLevel || '',
};
}
}
// 删除账单后刷新列表
function handleBillDelete(deleted: UIBill) {
// 从列表中移除对应的记录
records = records.filter(r => r.id !== deleted.id);
totalRecords = Math.max(0, totalRecords - 1);
// 更新聚合统计
if (deleted.incomeExpense === '支出') {
totalExpense = Math.max(0, totalExpense - deleted.amount);
} else if (deleted.incomeExpense === '收入') {
totalIncome = Math.max(0, totalIncome - deleted.amount);
}
}
</script>
<svelte:head>
@@ -383,7 +430,10 @@
</Table.Header>
<Table.Body>
{#each displayRecords as record}
<Table.Row>
<Table.Row
class="cursor-pointer hover:bg-muted/50 transition-colors"
onclick={() => handleRowClick(record)}
>
<Table.Cell class="text-muted-foreground text-sm">
{formatDateTime(record.time)}
</Table.Cell>
@@ -486,3 +536,16 @@
<ManualBillInput onSuccess={handleManualBillSuccess} />
{/if}
</div>
<!-- 账单详情抽屉 -->
<BillDetailDrawer
bind:open={drawerOpen}
bind:record={selectedBill}
categories={categories}
title="账单详情"
viewDescription="查看这笔账单的完整信息"
editDescription="修改这笔账单的信息"
allowDelete={true}
onUpdate={handleBillUpdate}
onDelete={handleBillDelete}
/>