import { ApiCode } from '@/config' import type { ApiResponse } from '@/types/api' import type { VaultListItem, VaultTransactionItem } from '@/types/vault' import { http, postJson } from './http' export function fetchVaultsList() { return postJson('/vaultody/vaults/list', {}) } export interface FetchVaultTransactionsBody { vaultId?: string | number | null /** 页码,从 1 开始 */ page?: number pageSize?: number } export interface VaultTransactionsResult { list: VaultTransactionItem[] /** 总条数,用于分页;若后端暂未返回可先不传,前端会按当前页条数展示 */ total?: number } function buildVaultTransactionsPayload(body: FetchVaultTransactionsBody): Record { const payload: Record = {} if (body.vaultId != null) payload.vaultId = body.vaultId if (body.page != null) payload.page = body.page if (body.pageSize != null) payload.pageSize = body.pageSize return payload } export function fetchVaultTransactions(body: FetchVaultTransactionsBody = {}) { return postJson('/vaultody/vaults/transactions', buildVaultTransactionsPayload(body)) } function parseFilenameFromContentDisposition(cd: string | undefined): string | null { if (!cd) return null const m = /filename\*=UTF-8''([^;\n]+)|filename="?([^";\n]+)"?/i.exec(cd) const raw = m?.[1] ?? m?.[2] if (!raw) return null try { return decodeURIComponent(raw.trim()) } catch { return raw.trim() } } async function tryParseJsonErrorBlob(blob: Blob): Promise { const text = await blob.text() try { const json = JSON.parse(text) as ApiResponse if (typeof json.code === 'number' && json.code !== ApiCode.StatusOK) { return json.msg || 'Export failed' } } catch { /* not JSON */ } return null } /** POST /vaultody/export,请求体与列表接口一致;成功返回文件 blob */ export async function exportVaultTransactions( body: FetchVaultTransactionsBody = {} ): Promise<{ blob: Blob; filename: string | null } | { error: string }> { const res = await http.post('/vaultody/export', buildVaultTransactionsPayload(body), { responseType: 'blob', }) const raw = res.data if (!(raw instanceof Blob)) { const api = raw as ApiResponse return { error: api?.msg ?? 'Export failed' } } const blob = raw const ct = String(res.headers['content-type'] ?? res.headers['Content-Type'] ?? '').toLowerCase() if (ct.includes('application/json') || ct.includes('text/json')) { const err = await tryParseJsonErrorBlob(blob) return { error: err ?? 'Export failed' } } const filename = parseFilenameFromContentDisposition( res.headers['content-disposition'] ?? res.headers['Content-Disposition'] ) return { blob, filename } }