const API_BASE = ''; // 使用相对路径,同源代理 function getAuthHeaders() { const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null; return token ? { Authorization: `Bearer ${token}` } : {}; } async function apiCall(url, options = {}) { const res = await fetch(`${API_BASE}${url}`, { ...options, headers: { 'Content-Type': 'application/json', ...getAuthHeaders(), ...options.headers, }, }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || '请求失败'); } return data; } // 认证 export async function login(username, password) { const data = await apiCall('/api/auth/login', { method: 'POST', body: JSON.stringify({ username, password }), }); if (typeof window !== 'undefined') { localStorage.setItem('token', data.token); } return data; } export async function register(username, password) { const data = await apiCall('/api/auth/register', { method: 'POST', body: JSON.stringify({ username, password }), }); if (typeof window !== 'undefined') { localStorage.setItem('token', data.token); } return data; } export function logout() { if (typeof window !== 'undefined') { localStorage.removeItem('token'); } } export function isLoggedIn() { if (typeof window === 'undefined') return false; return !!localStorage.getItem('token'); } // 账目 export async function getRecords(month, type = 'all') { let url = `/api/records?month=${month}`; if (type !== 'all') { url += `&type=${type}`; } return apiCall(url); } export async function getStats(month) { return apiCall(`/api/stats?month=${month}`); } export async function createRecord(data) { return apiCall('/api/records', { method: 'POST', body: JSON.stringify(data), }); } export async function updateRecord(id, data) { return apiCall(`/api/records/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } export async function deleteRecord(id) { return apiCall(`/api/records/${id}`, { method: 'DELETE', }); } // 批量删除指定分类的记录 export async function deleteRecordsByCategory(category) { return apiCall(`/api/records/by-category/${encodeURIComponent(category)}`, { method: 'DELETE', }); } // 搜索 export async function searchRecords(keyword) { return apiCall(`/api/records/search?q=${encodeURIComponent(keyword)}`); } // 统计 export async function getTrendStats(period = 'month', month) { let url = `/api/stats/trend?period=${period}`; if (month) url += `&month=${month}`; return apiCall(url); } export async function getCategoryStats(month, type = 'all') { let url = `/api/stats/category?type=${type}`; if (month) url += `&month=${month}`; return apiCall(url); } // 周期性账单 export async function getRecurringBills() { return apiCall('/api/recurring'); } export async function createRecurringBill(data) { return apiCall('/api/recurring', { method: 'POST', body: JSON.stringify(data), }); } export async function updateRecurringBill(id, data) { return apiCall(`/api/recurring/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } export async function deleteRecurringBill(id) { return apiCall(`/api/recurring/${id}`, { method: 'DELETE', }); } export async function applyRecurringBill(id) { return apiCall(`/api/recurring/${id}/apply`, { method: 'POST', }); } // 分类 export async function getCategories() { return apiCall('/api/categories'); } export async function createCategory(data) { return apiCall('/api/categories', { method: 'POST', body: JSON.stringify(data), }); } export async function deleteCategory(id) { return apiCall(`/api/categories/${id}`, { method: 'DELETE', }); } // 数据导入导出 export async function exportData() { return apiCall('/api/export'); } export async function importData(data) { return apiCall('/api/import', { method: 'POST', body: JSON.stringify(data), }); }