문서 파일 정리
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { isSyncEnabled } from '../syncSettings';
|
||||
import { getModifiedBudget, getModifiedCategoryBudgets } from './modifiedBudgetsTracker';
|
||||
|
||||
/**
|
||||
* 서버에서 예산 데이터 다운로드
|
||||
@@ -107,9 +107,12 @@ async function fetchCategoryBudgetData(userId: string) {
|
||||
/**
|
||||
* 예산 데이터 처리 및 로컬 저장
|
||||
*/
|
||||
async function processBudgetData(budgetData: any, localBudgetDataStr: string | null) {
|
||||
async function processBudgetData(budgetData: Record<string, any>, localBudgetDataStr: string | null) {
|
||||
console.log('서버에서 예산 데이터 수신:', budgetData);
|
||||
|
||||
// 로컬에서 수정된 예산 정보 가져오기
|
||||
const modifiedBudget = getModifiedBudget();
|
||||
|
||||
// 서버 예산이 0이고 로컬 예산이 있으면 로컬 데이터 유지
|
||||
if (budgetData.total_budget === 0 && localBudgetDataStr) {
|
||||
console.log('서버 예산이 0이고 로컬 예산이 있어 로컬 데이터 유지');
|
||||
@@ -117,12 +120,51 @@ async function processBudgetData(budgetData: any, localBudgetDataStr: string | n
|
||||
}
|
||||
|
||||
// 기존 로컬 데이터 가져오기
|
||||
let localBudgetData = localBudgetDataStr ? JSON.parse(localBudgetDataStr) : {
|
||||
const localBudgetData = localBudgetDataStr ? JSON.parse(localBudgetDataStr) : {
|
||||
daily: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
|
||||
weekly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
|
||||
monthly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }
|
||||
};
|
||||
|
||||
// 로컬에서 수정된 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
|
||||
if (modifiedBudget && (!budgetData.updated_at || new Date(budgetData.updated_at).getTime() < modifiedBudget.timestamp)) {
|
||||
console.log('로컬에서 수정된 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
|
||||
|
||||
// 서버 데이터 대신 로컬에서 수정된 예산 사용
|
||||
const monthlyBudget = modifiedBudget.monthlyAmount;
|
||||
const dailyBudget = Math.round(monthlyBudget / 30); // 월간 예산 / 30일
|
||||
const weeklyBudget = Math.round(monthlyBudget / 4.3); // 월간 예산 / 4.3주
|
||||
|
||||
const updatedBudgetData = {
|
||||
daily: {
|
||||
targetAmount: dailyBudget,
|
||||
spentAmount: localBudgetData.daily.spentAmount,
|
||||
remainingAmount: dailyBudget - localBudgetData.daily.spentAmount
|
||||
},
|
||||
weekly: {
|
||||
targetAmount: weeklyBudget,
|
||||
spentAmount: localBudgetData.weekly.spentAmount,
|
||||
remainingAmount: weeklyBudget - localBudgetData.weekly.spentAmount
|
||||
},
|
||||
monthly: {
|
||||
targetAmount: monthlyBudget,
|
||||
spentAmount: localBudgetData.monthly.spentAmount,
|
||||
remainingAmount: monthlyBudget - localBudgetData.monthly.spentAmount
|
||||
}
|
||||
};
|
||||
|
||||
console.log('로컬 수정 데이터 기반 예산 계산:', updatedBudgetData);
|
||||
|
||||
// 로컬 스토리지에 저장
|
||||
localStorage.setItem('budgetData', JSON.stringify(updatedBudgetData));
|
||||
localStorage.setItem('budgetData_backup', JSON.stringify(updatedBudgetData));
|
||||
console.log('로컬 수정 예산 데이터 유지 완료', updatedBudgetData);
|
||||
|
||||
// 이벤트 발생시켜 UI 업데이트
|
||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 서버 데이터로 업데이트 (지출 금액은 유지)
|
||||
// 수정: 올바른 예산 계산 방식으로 변경
|
||||
const monthlyBudget = budgetData.total_budget;
|
||||
@@ -161,9 +203,12 @@ async function processBudgetData(budgetData: any, localBudgetDataStr: string | n
|
||||
/**
|
||||
* 카테고리 예산 데이터 처리 및 로컬 저장
|
||||
*/
|
||||
async function processCategoryBudgetData(categoryData: any[], localCategoryBudgetsStr: string | null) {
|
||||
async function processCategoryBudgetData(categoryData: Record<string, any>[], localCategoryBudgetsStr: string | null) {
|
||||
console.log(`${categoryData.length}개의 카테고리 예산 수신`);
|
||||
|
||||
// 로컬에서 수정된 카테고리 예산 정보 가져오기
|
||||
const modifiedCategoryBudgets = getModifiedCategoryBudgets();
|
||||
|
||||
// 서버 카테고리 예산 합계 계산
|
||||
const serverTotal = categoryData.reduce((sum, item) => sum + item.amount, 0);
|
||||
|
||||
@@ -173,6 +218,21 @@ async function processCategoryBudgetData(categoryData: any[], localCategoryBudge
|
||||
return;
|
||||
}
|
||||
|
||||
// 로컬에서 수정된 카테고리 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
|
||||
if (modifiedCategoryBudgets && categoryData.length > 0) {
|
||||
// 서버 데이터 중 가장 최근 업데이트 시간 확인
|
||||
const latestServerUpdate = categoryData.reduce((latest, curr) => {
|
||||
if (!curr.updated_at) return latest;
|
||||
const currTime = new Date(curr.updated_at).getTime();
|
||||
return currTime > latest ? currTime : latest;
|
||||
}, 0);
|
||||
|
||||
if (latestServerUpdate < modifiedCategoryBudgets.timestamp) {
|
||||
console.log('로컬에서 수정된 카테고리 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 카테고리 예산 로컬 형식으로 변환
|
||||
const localCategoryBudgets = categoryData.reduce((acc, curr) => {
|
||||
acc[curr.category] = curr.amount;
|
||||
|
||||
138
src/utils/sync/budget/modifiedBudgetsTracker.ts
Normal file
138
src/utils/sync/budget/modifiedBudgetsTracker.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* 수정된 예산 데이터를 추적하는 유틸리티
|
||||
* 로컬 스토리지에 수정된 예산 정보를 저장하고 관리합니다.
|
||||
*/
|
||||
|
||||
const MODIFIED_BUDGETS_KEY = 'modified_budgets';
|
||||
const MODIFIED_CATEGORY_BUDGETS_KEY = 'modified_category_budgets';
|
||||
|
||||
interface ModifiedBudget {
|
||||
timestamp: number; // 수정 시간 (밀리초)
|
||||
monthlyAmount: number; // 월간 예산액
|
||||
}
|
||||
|
||||
interface ModifiedCategoryBudgets {
|
||||
timestamp: number; // 수정 시간 (밀리초)
|
||||
categories: Record<string, number>; // 카테고리별 예산액
|
||||
}
|
||||
|
||||
/**
|
||||
* 수정된 예산 정보를 로컬 스토리지에 저장
|
||||
*/
|
||||
export const markBudgetAsModified = (monthlyAmount: number): void => {
|
||||
try {
|
||||
const modifiedBudget: ModifiedBudget = {
|
||||
timestamp: Date.now(),
|
||||
monthlyAmount
|
||||
};
|
||||
|
||||
localStorage.setItem(MODIFIED_BUDGETS_KEY, JSON.stringify(modifiedBudget));
|
||||
console.log(`[예산 추적] 수정된 예산 정보 저장 완료: ${monthlyAmount}원`);
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 예산 정보 저장 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 수정된 카테고리 예산 정보를 로컬 스토리지에 저장
|
||||
*/
|
||||
export const markCategoryBudgetsAsModified = (categories: Record<string, number>): void => {
|
||||
try {
|
||||
const modifiedCategoryBudgets: ModifiedCategoryBudgets = {
|
||||
timestamp: Date.now(),
|
||||
categories
|
||||
};
|
||||
|
||||
localStorage.setItem(MODIFIED_CATEGORY_BUDGETS_KEY, JSON.stringify(modifiedCategoryBudgets));
|
||||
console.log(`[예산 추적] 수정된 카테고리 예산 정보 저장 완료: ${Object.keys(categories).length}개 카테고리`);
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 카테고리 예산 정보 저장 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 단일 카테고리 예산 정보를 수정된 것으로 표시
|
||||
*/
|
||||
export const markSingleCategoryBudgetAsModified = (category: string, amount: number): void => {
|
||||
try {
|
||||
// 기존 수정 정보 가져오기
|
||||
const existing = getModifiedCategoryBudgets();
|
||||
const categories = existing?.categories || {};
|
||||
|
||||
// 새 카테고리 예산 정보 추가
|
||||
categories[category] = amount;
|
||||
|
||||
// 수정된 정보 저장
|
||||
const modifiedCategoryBudgets: ModifiedCategoryBudgets = {
|
||||
timestamp: Date.now(),
|
||||
categories
|
||||
};
|
||||
|
||||
localStorage.setItem(MODIFIED_CATEGORY_BUDGETS_KEY, JSON.stringify(modifiedCategoryBudgets));
|
||||
console.log(`[예산 추적] 카테고리 '${category}' 예산 정보 저장 완료: ${amount}원`);
|
||||
} catch (error) {
|
||||
console.error(`[예산 추적] 카테고리 '${category}' 예산 정보 저장 실패:`, error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 수정된 예산 정보 가져오기
|
||||
*/
|
||||
export const getModifiedBudget = (): ModifiedBudget | null => {
|
||||
try {
|
||||
const data = localStorage.getItem(MODIFIED_BUDGETS_KEY);
|
||||
if (!data) return null;
|
||||
|
||||
return JSON.parse(data) as ModifiedBudget;
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 예산 정보 조회 실패:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 수정된 카테고리 예산 정보 가져오기
|
||||
*/
|
||||
export const getModifiedCategoryBudgets = (): ModifiedCategoryBudgets | null => {
|
||||
try {
|
||||
const data = localStorage.getItem(MODIFIED_CATEGORY_BUDGETS_KEY);
|
||||
if (!data) return null;
|
||||
|
||||
return JSON.parse(data) as ModifiedCategoryBudgets;
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 카테고리 예산 정보 조회 실패:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 예산 수정 정보 초기화
|
||||
*/
|
||||
export const clearModifiedBudget = (): void => {
|
||||
try {
|
||||
localStorage.removeItem(MODIFIED_BUDGETS_KEY);
|
||||
console.log('[예산 추적] 수정된 예산 정보 초기화 완료');
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 예산 정보 초기화 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 카테고리 예산 수정 정보 초기화
|
||||
*/
|
||||
export const clearModifiedCategoryBudgets = (): void => {
|
||||
try {
|
||||
localStorage.removeItem(MODIFIED_CATEGORY_BUDGETS_KEY);
|
||||
console.log('[예산 추적] 수정된 카테고리 예산 정보 초기화 완료');
|
||||
} catch (error) {
|
||||
console.error('[예산 추적] 수정된 카테고리 예산 정보 초기화 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 모든 수정 정보 초기화
|
||||
*/
|
||||
export const clearAllModifiedBudgets = (): void => {
|
||||
clearModifiedBudget();
|
||||
clearModifiedCategoryBudgets();
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { isSyncEnabled } from '../syncSettings';
|
||||
import {
|
||||
clearModifiedBudget,
|
||||
clearModifiedCategoryBudgets
|
||||
} from './modifiedBudgetsTracker';
|
||||
|
||||
/**
|
||||
* 예산 데이터를 서버에 업로드
|
||||
@@ -18,6 +21,9 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
|
||||
if (budgetDataStr) {
|
||||
const budgetData = JSON.parse(budgetDataStr);
|
||||
await uploadBudgetData(userId, budgetData);
|
||||
|
||||
// 업로드 성공 후 수정 추적 정보 초기화
|
||||
clearModifiedBudget();
|
||||
} else {
|
||||
console.log('업로드할 예산 데이터가 없음');
|
||||
}
|
||||
@@ -26,6 +32,9 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
|
||||
if (categoryBudgetsStr) {
|
||||
const categoryBudgets = JSON.parse(categoryBudgetsStr);
|
||||
await uploadCategoryBudgets(userId, categoryBudgets);
|
||||
|
||||
// 업로드 성공 후 수정 추적 정보 초기화
|
||||
clearModifiedCategoryBudgets();
|
||||
} else {
|
||||
console.log('업로드할 카테고리 예산이 없음');
|
||||
}
|
||||
@@ -40,7 +49,7 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
|
||||
/**
|
||||
* 일반 예산 데이터 업로드
|
||||
*/
|
||||
async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<void> {
|
||||
async function uploadBudgetData(userId: string, parsedBudgetData: Record<string, any>): Promise<void> {
|
||||
console.log('예산 데이터 업로드:', parsedBudgetData);
|
||||
|
||||
// 현재 월/년도 가져오기
|
||||
@@ -66,6 +75,9 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
|
||||
|
||||
console.log('업로드할 월간 예산:', monthlyTarget);
|
||||
|
||||
// 현재 타임스탬프
|
||||
const currentTimestamp = new Date().toISOString();
|
||||
|
||||
// 업데이트 또는 삽입 결정
|
||||
if (existingBudgets && existingBudgets.length > 0) {
|
||||
// 기존 데이터 업데이트
|
||||
@@ -73,7 +85,7 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
|
||||
.from('budgets')
|
||||
.update({
|
||||
total_budget: monthlyTarget,
|
||||
updated_at: new Date().toISOString()
|
||||
updated_at: currentTimestamp
|
||||
})
|
||||
.eq('id', existingBudgets[0].id);
|
||||
|
||||
@@ -91,7 +103,9 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
|
||||
user_id: userId,
|
||||
month: currentMonth,
|
||||
year: currentYear,
|
||||
total_budget: monthlyTarget
|
||||
total_budget: monthlyTarget,
|
||||
created_at: currentTimestamp,
|
||||
updated_at: currentTimestamp
|
||||
});
|
||||
|
||||
if (error) {
|
||||
@@ -120,13 +134,18 @@ async function uploadCategoryBudgets(userId: string, parsedCategoryBudgets: Reco
|
||||
// 오류가 나도 계속 진행 (중요 데이터가 아니기 때문)
|
||||
}
|
||||
|
||||
// 현재 타임스탬프
|
||||
const currentTimestamp = new Date().toISOString();
|
||||
|
||||
// 카테고리별 예산 데이터 변환 및 삽입
|
||||
const categoryEntries = Object.entries(parsedCategoryBudgets)
|
||||
.filter(([_, amount]) => amount > 0) // 금액이 0보다 큰 것만 저장
|
||||
.map(([category, amount]) => ({
|
||||
user_id: userId,
|
||||
category,
|
||||
amount
|
||||
amount,
|
||||
created_at: currentTimestamp,
|
||||
updated_at: currentTimestamp
|
||||
}));
|
||||
|
||||
if (categoryEntries.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user