문서 파일 정리
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) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { isSyncEnabled } from '../syncSettings';
|
||||
import { addToDeletedTransactions } from './deletedTransactionsTracker';
|
||||
|
||||
/**
|
||||
* Supabase 서버에서 트랜잭션을 삭제하는 함수 - 안정성 및 성능 최적화 버전
|
||||
@@ -21,6 +22,9 @@ export const deleteTransactionFromServer = async (userId: string, transactionId:
|
||||
}, 2000);
|
||||
|
||||
try {
|
||||
// 삭제된 트랜잭션 ID 추적 목록에 추가
|
||||
addToDeletedTransactions(transactionId);
|
||||
|
||||
// 서버 요청 실행
|
||||
const { error } = await supabase
|
||||
.from('transactions')
|
||||
|
||||
69
src/utils/sync/transaction/deletedTransactionsTracker.ts
Normal file
69
src/utils/sync/transaction/deletedTransactionsTracker.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 삭제된 트랜잭션 ID를 추적하는 유틸리티
|
||||
* 로컬에서 삭제된 트랜잭션이 서버 동기화 후 다시 나타나는 문제를 해결합니다.
|
||||
*/
|
||||
|
||||
// 삭제된 트랜잭션 ID를 저장하는 로컬 스토리지 키
|
||||
const DELETED_TRANSACTIONS_KEY = 'deletedTransactions';
|
||||
|
||||
/**
|
||||
* 삭제된 트랜잭션 ID를 저장
|
||||
* @param id 삭제된 트랜잭션 ID
|
||||
*/
|
||||
export const addToDeletedTransactions = (id: string): void => {
|
||||
try {
|
||||
const deletedIds = getDeletedTransactions();
|
||||
if (!deletedIds.includes(id)) {
|
||||
deletedIds.push(id);
|
||||
localStorage.setItem(DELETED_TRANSACTIONS_KEY, JSON.stringify(deletedIds));
|
||||
console.log(`[삭제 추적] ID 추가됨: ${id}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[삭제 추적] ID 추가 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 삭제된 트랜잭션 ID 목록 가져오기
|
||||
* @returns 삭제된 트랜잭션 ID 배열
|
||||
*/
|
||||
export const getDeletedTransactions = (): string[] => {
|
||||
try {
|
||||
const deletedStr = localStorage.getItem(DELETED_TRANSACTIONS_KEY);
|
||||
const deletedIds = deletedStr ? JSON.parse(deletedStr) : [];
|
||||
return Array.isArray(deletedIds) ? deletedIds : [];
|
||||
} catch (error) {
|
||||
console.error('[삭제 추적] 목록 조회 실패:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 삭제된 트랜잭션 ID 제거 (서버에서 성공적으로 삭제된 경우)
|
||||
* @param id 제거할 트랜잭션 ID
|
||||
*/
|
||||
export const removeFromDeletedTransactions = (id: string): void => {
|
||||
try {
|
||||
const deletedIds = getDeletedTransactions();
|
||||
const updatedIds = deletedIds.filter(deletedId => deletedId !== id);
|
||||
|
||||
if (deletedIds.length !== updatedIds.length) {
|
||||
localStorage.setItem(DELETED_TRANSACTIONS_KEY, JSON.stringify(updatedIds));
|
||||
console.log(`[삭제 추적] ID 제거됨: ${id}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[삭제 추적] ID 제거 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 삭제된 트랜잭션 ID 목록 초기화
|
||||
*/
|
||||
export const clearDeletedTransactions = (): void => {
|
||||
try {
|
||||
localStorage.removeItem(DELETED_TRANSACTIONS_KEY);
|
||||
console.log('[삭제 추적] 목록 초기화됨');
|
||||
} catch (error) {
|
||||
console.error('[삭제 추적] 목록 초기화 실패:', error);
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import { supabase } from '@/lib/supabase';
|
||||
import { Transaction } from '@/components/TransactionCard';
|
||||
import { isSyncEnabled } from '../syncSettings';
|
||||
import { formatDateForDisplay } from './dateUtils';
|
||||
import { getDeletedTransactions } from './deletedTransactionsTracker';
|
||||
|
||||
/**
|
||||
* Download transaction data from Supabase to local storage
|
||||
@@ -30,40 +31,53 @@ export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
|
||||
console.log(`서버에서 ${data.length}개의 트랜잭션 다운로드`);
|
||||
|
||||
// 서버 데이터를 로컬 형식으로 변환
|
||||
const serverTransactions = data.map(t => {
|
||||
// 날짜 형식 변환 시 오류 방지 처리
|
||||
let formattedDate = '날짜 없음';
|
||||
try {
|
||||
if (t.date) {
|
||||
// ISO 형식이 아닌 경우 기본 변환 수행
|
||||
if (!t.date.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
||||
console.log(`비표준 날짜 형식 감지: ${t.date}, ID: ${t.transaction_id || t.id}`);
|
||||
// 유효한 Date 객체로 변환 가능한지 확인
|
||||
const testDate = new Date(t.date);
|
||||
if (isNaN(testDate.getTime())) {
|
||||
console.warn(`잘못된 날짜 형식 감지, 현재 날짜 사용: ${t.date}`);
|
||||
t.date = new Date().toISOString(); // 잘못된 날짜는 현재 날짜로 대체
|
||||
}
|
||||
}
|
||||
formattedDate = formatDateForDisplay(t.date);
|
||||
// 삭제된 트랜잭션 ID 목록 가져오기
|
||||
const deletedIds = getDeletedTransactions();
|
||||
console.log(`[동기화] 삭제된 트랜잭션 ${deletedIds.length}개 필터링 적용`);
|
||||
|
||||
// 서버 데이터를 로컬 형식으로 변환 (삭제된 항목 제외)
|
||||
const serverTransactions = data
|
||||
.filter(t => {
|
||||
const transactionId = t.transaction_id || t.id;
|
||||
const isDeleted = deletedIds.includes(transactionId);
|
||||
if (isDeleted) {
|
||||
console.log(`[동기화] 삭제된 트랜잭션 필터링: ${transactionId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`날짜 변환 오류 (ID: ${t.transaction_id || t.id}):`, err);
|
||||
// 오류 발생 시 기본값 사용
|
||||
formattedDate = new Date().toLocaleString('ko-KR');
|
||||
}
|
||||
|
||||
return {
|
||||
id: t.transaction_id || t.id,
|
||||
title: t.title,
|
||||
amount: t.amount,
|
||||
date: formattedDate,
|
||||
category: t.category,
|
||||
type: t.type,
|
||||
notes: t.notes
|
||||
};
|
||||
});
|
||||
return !isDeleted; // 삭제된 항목 제외
|
||||
})
|
||||
.map(t => {
|
||||
// 날짜 형식 변환 시 오류 방지 처리
|
||||
let formattedDate = '날짜 없음';
|
||||
try {
|
||||
if (t.date) {
|
||||
// ISO 형식이 아닌 경우 기본 변환 수행
|
||||
if (!t.date.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
||||
console.log(`비표준 날짜 형식 감지: ${t.date}, ID: ${t.transaction_id || t.id}`);
|
||||
// 유효한 Date 객체로 변환 가능한지 확인
|
||||
const testDate = new Date(t.date);
|
||||
if (isNaN(testDate.getTime())) {
|
||||
console.warn(`잘못된 날짜 형식 감지, 현재 날짜 사용: ${t.date}`);
|
||||
t.date = new Date().toISOString(); // 잘못된 날짜는 현재 날짜로 대체
|
||||
}
|
||||
}
|
||||
formattedDate = formatDateForDisplay(t.date);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`날짜 변환 오류 (ID: ${t.transaction_id || t.id}):`, err);
|
||||
// 오류 발생 시 기본값 사용
|
||||
formattedDate = new Date().toLocaleString('ko-KR');
|
||||
}
|
||||
|
||||
return {
|
||||
id: t.transaction_id || t.id,
|
||||
title: t.title,
|
||||
amount: t.amount,
|
||||
date: formattedDate,
|
||||
category: t.category,
|
||||
type: t.type,
|
||||
notes: t.notes
|
||||
};
|
||||
});
|
||||
|
||||
// 기존 로컬 데이터 불러오기
|
||||
const localDataStr = localStorage.getItem('transactions');
|
||||
|
||||
Reference in New Issue
Block a user