From bc5d68e46515a5d41712d2b354980529306edae0 Mon Sep 17 00:00:00 2001 From: Hyein Date: Tue, 9 Jun 2026 10:23:49 +0900 Subject: [PATCH] Improve 8092 default contract detail loading --- mysql_preview_server.py | 16 ++++++++++--- project-codes.html | 50 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/mysql_preview_server.py b/mysql_preview_server.py index 20b0e9b..d62dbbb 100644 --- a/mysql_preview_server.py +++ b/mysql_preview_server.py @@ -787,13 +787,22 @@ def get_erp_project_code_cache(conn, source_page='const'): { 'projectCode': row[0], 'projectName': row[1], - 'contractType': row[2] or '', - 'applicationType': row[3] or '', + 'businessCode': row[2] or '', + 'siteLocation': row[3] or '', + 'clientName': row[4] or '', + 'finalContractAmountText': row[5] or '', + 'contractType': row[6] or '', + 'applicationType': row[7] or '', + 'syncedAt': row[8] or '', } for row in conn.execute( ''' SELECT p.projectCode, p.projectName, + COALESCE(d.businessCode, '') AS businessCode, + COALESCE(d.siteLocation, '') AS siteLocation, + COALESCE(d.clientName, '') AS clientName, + COALESCE(d.finalContractAmountText, '') AS finalContractAmountText, COALESCE(d.contractType, '') AS contractType, COALESCE(( SELECT GROUP_CONCAT(applicationType, '||') @@ -805,7 +814,8 @@ def get_erp_project_code_cache(conn, source_page='const'): AND IFNULL(b.applicationType, '') <> '' ORDER BY b.applicationType ) - ), '') AS applicationType + ), '') AS applicationType, + COALESCE(d.syncedAt, '') AS detailSyncedAt FROM erp_project_code_cache p LEFT JOIN erp_contract_detail_cache d ON d.sourcePage = p.sourcePage diff --git a/project-codes.html b/project-codes.html index 1199145..57c3d0e 100644 --- a/project-codes.html +++ b/project-codes.html @@ -833,7 +833,11 @@ detailTitle.textContent = `${detail.projectName || '-'} [${detail.projectCode}]`; detailMeta.textContent = `사업코드 ${detail.businessCode || '-'} · 마지막 동기화 ${detail.syncedAt || '-'}`; + renderDetailRows(detail); + renderMergedBridgeRows(detail.scaleRows || [], state.bridgeOverviews || [], state.budgetPlan); + } + function renderDetailRows(detail) { const rows = [ ['사업코드', detail.businessCode], ['약칭', detail.projectName], @@ -856,8 +860,6 @@ ${typeof value === 'string' && value.includes(' `).join(''); - - renderMergedBridgeRows(detail.scaleRows || [], state.bridgeOverviews || [], state.budgetPlan); } function normalizeBridgeName(value) { @@ -1168,12 +1170,45 @@ if (!detailResponse.ok) { if (!refresh && detailResponse.status === 404) { - state.detail = null; state.bridgeOverviews = overviewResponse.ok ? (Array.isArray(overviewData.overviews) ? overviewData.overviews : []) : []; state.budgetPlan = budgetPlanResponse.ok ? (budgetPlanData.plan || null) : null; detailTitle.textContent = `${projectName || '-'} [${projectCode}]`; - detailMeta.textContent = 'DB 캐시에 계약정보가 없습니다. 새 정보 다시 가져오기를 누르면 ERP에서 수집합니다.'; - detailBody.innerHTML = '저장된 계약정보가 없습니다. 최신 정보가 필요하면 오른쪽 상단 버튼을 눌러주세요.'; + detailMeta.textContent = 'DB 캐시에 계약정보가 없어 ERP에서 기본 계약정보를 가져오는 중입니다.'; + try { + const freshDetailResponse = await fetch( + `/api/erp-contract-detail?page=const&projectCode=${encodeURIComponent(projectCode)}&projectName=${encodeURIComponent(projectName || '')}&refresh=1`, + { cache: 'no-store' } + ); + const freshDetailData = await freshDetailResponse.json(); + if (freshDetailResponse.ok) { + state.detail = freshDetailData.detail || null; + if (state.selectedRow && state.detail) { + state.selectedRow.businessCode = state.detail.businessCode || state.selectedRow.businessCode || ''; + state.selectedRow.siteLocation = state.detail.siteLocation || state.selectedRow.siteLocation || ''; + state.selectedRow.clientName = state.detail.clientName || state.selectedRow.clientName || ''; + state.selectedRow.finalContractAmountText = state.detail.finalContractAmountText || state.selectedRow.finalContractAmountText || ''; + state.selectedRow.contractType = state.detail.contractType || state.selectedRow.contractType || ''; + state.selectedRow.syncedAt = state.detail.syncedAt || state.selectedRow.syncedAt || ''; + } + renderDetail(state.detail); + return; + } + } catch (error) { + } + + state.detail = null; + const selectedSummary = state.selectedRow || {}; + detailMeta.textContent = '기본 계약정보를 아직 가져오지 않았습니다. 새 정보 다시 가져오기를 누르면 ERP에서 수집합니다.'; + renderDetailRows({ + businessCode: selectedSummary.businessCode || '', + projectName: projectName || selectedSummary.projectName || '', + projectCode, + siteLocation: selectedSummary.siteLocation || '', + clientName: selectedSummary.clientName || '', + finalContractAmountText: selectedSummary.finalContractAmountText || '', + contractType: selectedSummary.contractType || '', + syncedAt: selectedSummary.syncedAt || '', + }); renderMergedBridgeRows([], state.bridgeOverviews || [], state.budgetPlan); return; } @@ -1184,7 +1219,12 @@ state.bridgeOverviews = Array.isArray(overviewData.overviews) ? overviewData.overviews : []; state.budgetPlan = budgetPlanResponse.ok ? (budgetPlanData.plan || null) : null; if (state.selectedRow && state.detail) { + state.selectedRow.businessCode = state.detail.businessCode || state.selectedRow.businessCode || ''; + state.selectedRow.siteLocation = state.detail.siteLocation || state.selectedRow.siteLocation || ''; + state.selectedRow.clientName = state.detail.clientName || state.selectedRow.clientName || ''; + state.selectedRow.finalContractAmountText = state.detail.finalContractAmountText || state.selectedRow.finalContractAmountText || ''; state.selectedRow.contractType = state.detail.contractType || state.selectedRow.contractType || ''; + state.selectedRow.syncedAt = state.detail.syncedAt || state.selectedRow.syncedAt || ''; state.selectedRow.applicationType = Array.from(new Set( state.bridgeOverviews.map((item) => String(item.applicationType || '').trim()).filter(Boolean) )).sort((a, b) => a.localeCompare(b, 'ko')).join('||') || state.selectedRow.applicationType || '';