From 8373fe9e754d44de37d4864f6e1bee17d124c808 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Fri, 13 Mar 2026 10:31:27 +0900 Subject: [PATCH] =?UTF-8?q?fix(tkpurchase):=20=ED=98=91=EB=A0=A5=EC=97=85?= =?UTF-8?q?=EC=B2=B4=20=ED=8F=AC=ED=83=88=20=EB=B3=B4=EA=B3=A0=20=ED=8F=BC?= =?UTF-8?q?=20=EC=9E=90=EB=8F=99=20=ED=91=9C=EC=8B=9C=20+=20=EC=B2=B4?= =?UTF-8?q?=ED=81=AC=EC=9D=B8=20=EC=9E=91=EC=97=85=EC=9E=90=20pre-populate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 보고 0건일 때 입력 폼 자동 표시 (버튼 클릭 불필요) - 체크인 시 입력한 작업자 명단으로 보고 폼 작업자 행 자동 생성 Co-Authored-By: Claude Opus 4.6 --- .../static/js/tkpurchase-partner-portal.js | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tkpurchase/web/static/js/tkpurchase-partner-portal.js b/tkpurchase/web/static/js/tkpurchase-partner-portal.js index 136dfbd..76f43e0 100644 --- a/tkpurchase/web/static/js/tkpurchase-partner-portal.js +++ b/tkpurchase/web/static/js/tkpurchase-partner-portal.js @@ -165,11 +165,15 @@ async function renderScheduleCards() { `; }).join(''); - // 체크인된 카드의 보고 목록 로드 + // 체크인된 카드의 보고 목록 로드 + 보고 0건이면 폼 자동 표시 for (const s of portalSchedules) { const checkin = portalCheckins[s.id]; if (checkin && !checkin.check_out_time) { + const reportCount = parseInt(checkin.work_report_count) || 0; loadReportsList(checkin.id, s.id); + if (reportCount === 0) { + showReportForm(checkin.id, s.id); + } } } } @@ -200,17 +204,25 @@ function renderReportsList(checkinId, scheduleId, reports) { const workerCount = r.workers ? r.workers.length : 0; const totalHours = r.workers ? r.workers.reduce((sum, w) => sum + Number(w.hours_worked || 0), 0) : 0; const isConfirmed = !!r.confirmed_by; + const isRejected = !!r.rejected_by; + const statusBadge = isConfirmed + ? ' 확인완료' + : isRejected + ? ' 반려' + : '미확인'; + const canEdit = !isConfirmed; return `
보고 #${r.report_seq || 1} - ${isConfirmed ? ' 확인완료' : '미확인'} + ${statusBadge}
${escapeHtml((r.work_content || '').substring(0, 50))}${(r.work_content || '').length > 50 ? '...' : ''}
${workerCount}명 · ${totalHours}h · 진행률 ${r.progress_rate || 0}%
+ ${isRejected && r.rejection_reason ? `
${escapeHtml(r.rejection_reason)}
` : ''}
- ${!isConfirmed ? `` : ''}
`; }).join(''); @@ -230,12 +242,26 @@ async function showReportForm(checkinId, scheduleId, editReport) { const checkin = Object.values(portalCheckins).find(c => c.id === checkinId); const isFirstReport = !editReport && checkin && parseInt(checkin.work_report_count) === 0; - // 기본 작업자 행 + // 기본 작업자 행: 체크인 시 입력한 작업자 명단으로 pre-populate let existingWorkers = []; if (editReport && editReport.workers) { existingWorkers = editReport.workers; - } else if (isFirstReport && currentUser) { - existingWorkers = [{ worker_name: currentUser.name || '', hours_worked: 8.0 }]; + } else if (isFirstReport && checkin) { + let workerNames = []; + if (checkin.worker_names) { + let parsed = checkin.worker_names; + try { parsed = JSON.parse(parsed); } catch(e) { /* 그대로 사용 */ } + if (Array.isArray(parsed)) { + workerNames = parsed.map(n => String(n).trim()).filter(Boolean); + } else { + workerNames = String(parsed).split(/[,,]\s*/).map(n => n.trim()).filter(Boolean); + } + } + if (workerNames.length > 0) { + existingWorkers = workerNames.map(name => ({ worker_name: name, hours_worked: 8.0 })); + } else if (currentUser) { + existingWorkers = [{ worker_name: currentUser.name || '', hours_worked: 8.0 }]; + } } formContainer.innerHTML = `