From 6dd24864e89d7a5dc68b0d0d8d970cc4c6ca6a4f Mon Sep 17 00:00:00 2001 From: admin <1297598740@qq.com> Date: Mon, 2 Feb 2026 15:30:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A2=84=E7=AE=97?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=EF=BC=8C=E5=8C=85=E5=90=AB=E9=A2=84=E7=AE=97?= =?UTF-8?q?=E7=9A=84=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5=E3=80=81=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E8=8E=B7=E5=8F=96=E5=8F=8A=E7=9B=B8=E5=85=B3=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/budgetService.ts | 60 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/src/services/budgetService.ts b/src/services/budgetService.ts index 69be8d6..2bcb48b 100644 --- a/src/services/budgetService.ts +++ b/src/services/budgetService.ts @@ -5,6 +5,47 @@ import api from './api'; import type { Budget, ApiResponse, BudgetPeriodType } from '../types'; +/** + * Backend Budget API response (snake_case) + */ +interface ApiBudget { + id: number; + name: string; + amount: number; + period_type: BudgetPeriodType; + category_id?: number; + account_id?: number; + is_rolling: boolean; + start_date: string; + end_date?: string; + spent?: number; + progress?: number; + created_at: string; + // Nested objects from Preload + category?: { id: number; name: string; icon?: string }; + account?: { id: number; name: string }; +} + +/** + * Convert backend API response to frontend Budget model + */ +function mapApiBudgetToBudget(apiBudget: ApiBudget): Budget { + return { + id: apiBudget.id, + name: apiBudget.name, + amount: apiBudget.amount, + periodType: apiBudget.period_type, + categoryId: apiBudget.category_id, + accountId: apiBudget.account_id, + isRolling: apiBudget.is_rolling, + startDate: apiBudget.start_date, + endDate: apiBudget.end_date, + spent: apiBudget.spent ?? 0, + progress: apiBudget.progress ?? 0, + createdAt: apiBudget.created_at, + }; +} + /** * Budget form input interface */ @@ -35,19 +76,20 @@ export interface BudgetProgress { * Get all budgets */ export async function getBudgets(): Promise { - const response = await api.get>('/budgets'); - return response.data || []; + const response = await api.get>('/budgets'); + const apiBudgets = response.data || []; + return apiBudgets.map(mapApiBudgetToBudget); } /** * Get a single budget by ID */ export async function getBudget(id: number): Promise { - const response = await api.get>(`/budgets/${id}`); + const response = await api.get>(`/budgets/${id}`); if (!response.data) { throw new Error('Budget not found'); } - return response.data; + return mapApiBudgetToBudget(response.data); } /** @@ -77,11 +119,11 @@ export async function createBudget(data: BudgetFormInput): Promise { start_date: data.startDate ? `${data.startDate}T00:00:00Z` : undefined, end_date: data.endDate ? `${data.endDate}T23:59:59Z` : undefined, }; - const response = await api.post>('/budgets', payload); + const response = await api.post>('/budgets', payload); if (!response.data) { throw new Error(response.error || 'Failed to create budget'); } - return response.data; + return mapApiBudgetToBudget(response.data); } /** @@ -99,12 +141,12 @@ export async function updateBudget(id: number, data: Partial): if (data.isRolling !== undefined) payload.is_rolling = data.isRolling; if (data.startDate !== undefined) payload.start_date = `${data.startDate}T00:00:00Z`; if (data.endDate !== undefined) payload.end_date = data.endDate ? `${data.endDate}T23:59:59Z` : null; - - const response = await api.put>(`/budgets/${id}`, payload); + + const response = await api.put>(`/budgets/${id}`, payload); if (!response.data) { throw new Error(response.error || 'Failed to update budget'); } - return response.data; + return mapApiBudgetToBudget(response.data); } /**