From 20cfa015795c671d05bf6be637f2fac6ee835646 Mon Sep 17 00:00:00 2001 From: hskwon Date: Thu, 4 Dec 2025 15:23:59 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20=EC=88=98=EC=8B=9D=20=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=ED=84=B0=20[object=20Object]=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=8F=20=EA=B3=84=EC=82=B0=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - simulator.blade.php: Range 결과 JSON 문자열 파싱 로직 추가 - QuoteFormulaController.php: simulate 응답 success 항상 true로 변경 --- .../Admin/Quote/QuoteFormulaController.php | 5 +- .../views/quote-formulas/simulator.blade.php | 62 +++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/Quote/QuoteFormulaController.php b/app/Http/Controllers/Api/Admin/Quote/QuoteFormulaController.php index d912f781..39204a56 100644 --- a/app/Http/Controllers/Api/Admin/Quote/QuoteFormulaController.php +++ b/app/Http/Controllers/Api/Admin/Quote/QuoteFormulaController.php @@ -289,9 +289,12 @@ public function simulate(Request $request): JsonResponse $validated['input_variables'] ); + // 오류가 있어도 계산된 결과는 반환 (부분 성공) + // 오류는 data.errors에 포함되어 UI에서 별도 표시 return response()->json([ - 'success' => empty($result['errors']), + 'success' => true, 'data' => $result, + 'has_errors' => ! empty($result['errors']), ]); } diff --git a/resources/views/quote-formulas/simulator.blade.php b/resources/views/quote-formulas/simulator.blade.php index b84379ba..a19402b9 100644 --- a/resources/views/quote-formulas/simulator.blade.php +++ b/resources/views/quote-formulas/simulator.blade.php @@ -262,7 +262,7 @@ function renderCategoryOrder() { 'Accept': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' }, - body: JSON.stringify({ inputs }) + body: JSON.stringify({ input_variables: inputs }) }); const result = await response.json(); @@ -270,7 +270,7 @@ function renderCategoryOrder() { document.getElementById('resultLoading').classList.add('hidden'); if (response.ok && result.success) { - renderResults(result.data); + renderResults(result.data, result.has_errors); document.getElementById('resultContainer').classList.remove('hidden'); } else { errorDiv.textContent = result.message || '수식 실행에 실패했습니다.'; @@ -290,7 +290,24 @@ function renderCategoryOrder() { }); // 결과 렌더링 - function renderResults(data) { + function renderResults(data, hasErrors = false) { + // 경고 배너 (일부 오류가 있는 경우) + const resultContainer = document.getElementById('resultContainer'); + let warningBanner = document.getElementById('warningBanner'); + if (!warningBanner) { + warningBanner = document.createElement('div'); + warningBanner.id = 'warningBanner'; + warningBanner.className = 'mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg text-sm text-yellow-700'; + resultContainer.insertBefore(warningBanner, resultContainer.firstChild); + } + + if (hasErrors) { + warningBanner.innerHTML = '⚠️ 일부 수식에서 오류가 발생했습니다. 아래 오류 섹션을 확인하세요.'; + warningBanner.classList.remove('hidden'); + } else { + warningBanner.classList.add('hidden'); + } + // 계산된 변수 const variablesContainer = document.getElementById('calculatedVariables'); const variables = data.variables || {}; @@ -300,11 +317,44 @@ function renderResults(data) { variablesContainer.innerHTML = '

계산된 변수가 없습니다.

'; } else { variablesContainer.innerHTML = variableKeys.map(key => { - const value = variables[key]; - const formattedValue = typeof value === 'number' ? value.toLocaleString() : value; + const varInfo = variables[key]; + // varInfo가 객체면 value 추출, 아니면 직접 사용 + let rawValue = varInfo && typeof varInfo === 'object' ? varInfo.value : varInfo; + const varName = varInfo && typeof varInfo === 'object' ? varInfo.name : ''; + const category = varInfo && typeof varInfo === 'object' ? varInfo.category : ''; + + // JSON 문자열인 경우 파싱 시도 + if (typeof rawValue === 'string' && rawValue.startsWith('{')) { + try { + rawValue = JSON.parse(rawValue); + } catch (e) { + // 파싱 실패 시 원본 유지 + } + } + + // 값 포맷팅 + let formattedValue; + if (rawValue === null || rawValue === undefined) { + formattedValue = 'null'; + } else if (typeof rawValue === 'object') { + // Range 결과 등 객체인 경우 - value 필드 우선, 없으면 전체 표시 + if (rawValue.value) { + formattedValue = `${rawValue.value}`; + } else { + formattedValue = JSON.stringify(rawValue); + } + } else if (typeof rawValue === 'number') { + formattedValue = rawValue.toLocaleString(); + } else { + formattedValue = rawValue; + } + return `
- ${key} +
+ ${key} + ${varName ? `${varName}` : ''} +
${formattedValue}
`;