From 6545410d49bbdba4395bc89f14f2402d3b389d2f Mon Sep 17 00:00:00 2001 From: leeheejin Date: Mon, 1 Dec 2025 15:42:40 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=EC=B0=A8=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LocationSwapSelectorComponent.tsx | 22 ++++- frontend/lib/utils/buttonActions.ts | 87 +++++++++++++++++-- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/frontend/lib/registry/components/location-swap-selector/LocationSwapSelectorComponent.tsx b/frontend/lib/registry/components/location-swap-selector/LocationSwapSelectorComponent.tsx index 53fd0c0c..5dc4a165 100644 --- a/frontend/lib/registry/components/location-swap-selector/LocationSwapSelectorComponent.tsx +++ b/frontend/lib/registry/components/location-swap-selector/LocationSwapSelectorComponent.tsx @@ -208,41 +208,59 @@ export function LocationSwapSelectorComponent(props: LocationSwapSelectorProps) // 출발지 변경 const handleDepartureChange = (selectedValue: string) => { - console.log("[LocationSwapSelector] 출발지 변경:", { selectedValue, options }); + console.log("[LocationSwapSelector] 출발지 변경:", { + selectedValue, + departureField, + hasOnFormDataChange: !!onFormDataChange, + options + }); // 로컬 상태 업데이트 setLocalDeparture(selectedValue); // 부모에게 전달 if (onFormDataChange) { + console.log(`[LocationSwapSelector] onFormDataChange 호출: ${departureField} = ${selectedValue}`); onFormDataChange(departureField, selectedValue); // 라벨 필드도 업데이트 if (departureLabelField) { const selectedOption = options.find((opt) => opt.value === selectedValue); if (selectedOption) { + console.log(`[LocationSwapSelector] onFormDataChange 호출: ${departureLabelField} = ${selectedOption.label}`); onFormDataChange(departureLabelField, selectedOption.label); } } + } else { + console.warn("[LocationSwapSelector] ⚠️ onFormDataChange가 없습니다!"); } }; // 도착지 변경 const handleDestinationChange = (selectedValue: string) => { - console.log("[LocationSwapSelector] 도착지 변경:", { selectedValue, options }); + console.log("[LocationSwapSelector] 도착지 변경:", { + selectedValue, + destinationField, + hasOnFormDataChange: !!onFormDataChange, + options + }); // 로컬 상태 업데이트 setLocalDestination(selectedValue); // 부모에게 전달 if (onFormDataChange) { + console.log(`[LocationSwapSelector] onFormDataChange 호출: ${destinationField} = ${selectedValue}`); onFormDataChange(destinationField, selectedValue); // 라벨 필드도 업데이트 if (destinationLabelField) { const selectedOption = options.find((opt) => opt.value === selectedValue); if (selectedOption) { + console.log(`[LocationSwapSelector] onFormDataChange 호출: ${destinationLabelField} = ${selectedOption.label}`); onFormDataChange(destinationLabelField, selectedOption.label); } } + } else { + console.warn("[LocationSwapSelector] ⚠️ onFormDataChange가 없습니다!"); } }; diff --git a/frontend/lib/utils/buttonActions.ts b/frontend/lib/utils/buttonActions.ts index fe544706..6ff97083 100644 --- a/frontend/lib/utils/buttonActions.ts +++ b/frontend/lib/utils/buttonActions.ts @@ -3554,14 +3554,87 @@ export class ButtonActionExecutor { toast.success(successMsg); // 자동 저장 옵션이 활성화된 경우 - if (config.geolocationAutoSave && context.onSave) { + if (config.geolocationAutoSave) { console.log("📍 위치정보 자동 저장 실행"); - try { - await context.onSave(); - toast.success("위치 정보가 저장되었습니다."); - } catch (saveError) { - console.error("❌ 위치정보 자동 저장 실패:", saveError); - toast.error("위치 정보 저장에 실패했습니다."); + + // onSave 콜백이 있으면 사용 + if (context.onSave) { + try { + await context.onSave(); + toast.success("위치 정보가 저장되었습니다."); + } catch (saveError) { + console.error("❌ 위치정보 자동 저장 실패:", saveError); + toast.error("위치 정보 저장에 실패했습니다."); + } + } else if (context.tableName && context.formData) { + // onSave가 없으면 직접 API 호출 + // 키 필드 설정이 있으면 update-field API 사용 (더 안전) + const keyField = config.geolocationExtraKeyField; + const keySourceField = config.geolocationExtraKeySourceField; + + if (keyField && keySourceField) { + try { + const { apiClient } = await import("@/lib/api/client"); + const keyValue = resolveSpecialKeyword(keySourceField, context); + + if (keyValue) { + // formData에서 저장할 필드들 추출 (위치정보 + 출발지/도착지 등) + const fieldsToSave = { ...updates }; + + // formData에서 추가로 저장할 필드들 (테이블에 존재할 가능성이 높은 필드만) + // departure, arrival은 location-swap-selector에서 설정한 필드명 사용 + const additionalFields = ['departure', 'arrival']; + additionalFields.forEach(field => { + if (context.formData?.[field] !== undefined && context.formData[field] !== '') { + fieldsToSave[field] = context.formData[field]; + } + }); + + console.log("📍 개별 필드 UPDATE:", { + tableName: context.tableName, + keyField, + keyValue, + fieldsToSave, + }); + + // 각 필드를 개별적으로 UPDATE (에러가 나도 다른 필드 계속 저장) + let successCount = 0; + let failCount = 0; + + for (const [field, value] of Object.entries(fieldsToSave)) { + try { + console.log(`🔄 UPDATE: ${context.tableName}.${field} = ${value}`); + + const response = await apiClient.put(`/dynamic-form/update-field`, { + tableName: context.tableName, + keyField: keyField, + keyValue: keyValue, + updateField: field, + updateValue: value, + }); + + if (response.data?.success) { + successCount++; + console.log(`✅ ${field} 업데이트 성공`); + } else { + failCount++; + console.warn(`⚠️ ${field} 업데이트 실패:`, response.data); + } + } catch (fieldError) { + failCount++; + console.warn(`⚠️ ${field} 업데이트 오류 (컬럼이 없을 수 있음):`, fieldError); + } + } + + console.log(`✅ 필드 저장 완료: 성공 ${successCount}개, 실패 ${failCount}개`); + } + } catch (saveError) { + console.error("❌ 위치정보 자동 저장 실패:", saveError); + toast.error("위치 정보 저장에 실패했습니다."); + } + } else { + console.warn("⚠️ 키 필드가 설정되지 않아 자동 저장을 건너뜁니다."); + } } }