import { query } from './db'; import { MOCK_ACCOUNTS, MOCK_BUDGETS, MOCK_CATEGORIES, MOCK_CURRENCIES, MOCK_EXCHANGE_RATES, } from './mock-data'; interface AccountRow { id: number; name: string; type: string; currency: string; icon: null | string; color: null | string; user_id: null | number; is_active: boolean; } interface CategoryRow { id: number; name: string; type: string; icon: null | string; color: null | string; user_id: null | number; is_active: boolean; } function mapAccount(row: AccountRow) { return { id: row.id, userId: row.user_id ?? 1, name: row.name, type: row.type, currency: row.currency, balance: 0, icon: row.icon ?? '💳', color: row.color ?? '#1677ff', isActive: Boolean(row.is_active), }; } function mapCategory(row: CategoryRow) { return { id: row.id, userId: row.user_id ?? 1, name: row.name, type: row.type as 'expense' | 'income', icon: row.icon ?? '📝', color: row.color ?? '#dfe4ea', sortOrder: row.id, isSystem: row.user_id === null, isActive: Boolean(row.is_active), }; } export async function listAccounts() { try { const { rows } = await query( `SELECT id, name, type, currency, icon, color, user_id, is_active FROM finance_accounts ORDER BY id`, ); if (rows.length === 0) { return MOCK_ACCOUNTS; } return rows.map((row) => mapAccount(row)); } catch (error) { console.error('从数据库读取账户失败,使用 MOCK 数据:', error); return MOCK_ACCOUNTS; } } export async function listCategories() { try { const { rows } = await query( `SELECT id, name, type, icon, color, user_id, is_active FROM finance_categories WHERE is_active = TRUE ORDER BY type, id`, ); if (rows.length === 0) { return MOCK_CATEGORIES; } return rows.map((row) => mapCategory(row)); } catch (error) { console.error('从数据库读取分类失败,使用 MOCK 数据:', error); return MOCK_CATEGORIES; } } export function listBudgets() { return MOCK_BUDGETS; } export function listCurrencies() { return MOCK_CURRENCIES; } export function listExchangeRates() { return MOCK_EXCHANGE_RATES; } export async function createCategoryRecord(category: any) { try { const { rows } = await query( `INSERT INTO finance_categories (name, type, icon, color, user_id, is_active) VALUES ($1, $2, $3, $4, $5, TRUE) RETURNING id, name, type, icon, color, user_id, is_active`, [ category.name, category.type, category.icon || '📝', category.color || '#dfe4ea', category.userId || 1, ], ); const row = rows[0]; return row ? { ...mapCategory(row), createdAt: new Date().toISOString(), } : null; } catch (error) { console.error('创建分类失败:', error); return null; } } export async function updateCategoryRecord(id: number, category: any) { try { const updates: string[] = []; const params: any[] = []; if (category.name) { params.push(category.name); updates.push(`name = $${params.length}`); } if (category.icon) { params.push(category.icon); updates.push(`icon = $${params.length}`); } if (category.color) { params.push(category.color); updates.push(`color = $${params.length}`); } if (updates.length === 0) { return null; } params.push(id); const setClause = updates.join(', '); const { rows } = await query( `UPDATE finance_categories SET ${setClause} WHERE id = $${params.length} RETURNING id, name, type, icon, color, user_id, is_active`, params, ); const row = rows[0]; return row ? mapCategory(row) : null; } catch (error) { console.error('更新分类失败:', error); return null; } } export async function deleteCategoryRecord(id: number) { try { await query( `UPDATE finance_categories SET is_active = FALSE WHERE id = $1`, [id], ); return true; } catch (error) { console.error('删除分类失败:', error); return false; } }