feat: 新增账单导出 Excel 功能

- 后端新增 /api/bills/export 接口,支持当前筛选条件导出全部记录
- 使用 excelize 库生成 xlsx 格式文件
- 前端账单管理页面添加导出按钮
- 更新 Go 版本到 1.24 以支持 excelize 依赖
This commit is contained in:
clz
2026-03-23 19:16:54 +08:00
parent d813fe4307
commit 02de11caac
9 changed files with 312 additions and 173 deletions

View File

@@ -316,6 +316,46 @@ export async function fetchBills(params: FetchBillsParams = {}): Promise<BillsRe
return response.json();
}
// 导出账单为 Excel
export async function exportBills(params: FetchBillsParams = {}): Promise<void> {
const searchParams = new URLSearchParams();
if (params.start_date) searchParams.set('start_date', params.start_date);
if (params.end_date) searchParams.set('end_date', params.end_date);
if (params.category) searchParams.set('category', params.category);
if (params.type) searchParams.set('type', params.type);
if (params.income_expense) searchParams.set('income_expense', params.income_expense);
const queryString = searchParams.toString();
const url = `${API_BASE}/api/bills/export${queryString ? '?' + queryString : ''}`;
const response = await apiFetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const blob = await response.blob();
const contentDisposition = response.headers.get('Content-Disposition');
let filename = `bills_${new Date().toISOString().slice(0, 10)}.xlsx`;
if (contentDisposition) {
const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (match && match[1]) {
filename = match[1].replace(/['"]/g, '');
}
}
const objectUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = objectUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(objectUrl);
}
// 手动输入账单数据
export interface ManualBillInput {
time: string;