기능 개선 — 사진 업로드, HEIC 지원, 재조치 흐름, 신고 순번, 모바일 UI
- 이미지 압축: 삼성/네이버 브라우저 호환, URL.createObjectURL 방식으로 메모리 절감, 대용량 PNG/HEIC 처리, blob 유효성 검증, 순차 압축으로 모바일 OOM 방지 - HEIC/HEIF 지원: pillow-heif 서버사이드 변환, Pillow 12.2.0 업그레이드 - 조치 페이지: '조치 완료 저장' 단일 버튼으로 단순화 - 재조치 흐름: 관리자 재조치 요청 시 이전 조치 이력을 번호 카드로 순차 표시 - 신고 순번: 전체 기준 ROW_NUMBER(oldest=1) 순번 표시, 삭제 gap 제거 - 모바일 탭바: position:fixed 적용으로 nav 하단 흰 여백 제거 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -147,7 +147,7 @@
|
||||
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/auth.js"></script>
|
||||
<script src="/js/imageCompress.js"></script>
|
||||
<script src="/js/imageCompress.js?v=20260603"></script>
|
||||
<script>
|
||||
Auth.require(['admin']);
|
||||
Auth.renderNav(document.getElementById('navUser'));
|
||||
@@ -208,7 +208,7 @@ async function load() {
|
||||
const cost = repair?.cost;
|
||||
const prevRepairs = r.prev_repairs || [];
|
||||
|
||||
document.getElementById('pageTitle').textContent = `신고 #${r.id} 상세`;
|
||||
document.getElementById('pageTitle').textContent = `신고 #${r.seq} 상세`;
|
||||
|
||||
// ── 출장비 요약 HTML 생성 ──
|
||||
let costHtml = '';
|
||||
@@ -522,10 +522,35 @@ async function load() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 조치 정보 -->
|
||||
<div class="card">
|
||||
<!-- 조치 정보 — 이전 조치(순번카드) + 최신 조치 순서로 표시 -->
|
||||
${prevRepairs.length ? (() => {
|
||||
// prev_repairs는 최신순(내림차순)이므로 뒤집어서 오래된 것부터 번호 부여
|
||||
const orderedPrev = prevRepairs.slice().reverse();
|
||||
return orderedPrev.map((pr, idx) => `
|
||||
<div class="card" style="border-left:4px solid #F59E0B;">
|
||||
<div class="card-title" style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
|
||||
<span>🔧 조치 #${idx + 1}${orderedPrev.length + 1 > 2 ? '' : ' (최초)'}</span>
|
||||
<span style="font-size:12px;background:#FEF3C7;color:#92400E;padding:3px 12px;border-radius:10px;font-weight:700;">🔁 재조치 요청됨 · ${Auth.fmtDt(pr.re_dispatch_requested_at)}</span>
|
||||
</div>
|
||||
<table class="no-hover" style="font-size:13px;">
|
||||
<tr><td style="color:var(--gray4);width:100px">정비사</td><td>${pr.mechanic_name||'-'}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">조치유형</td><td>${(pr.repair_types||[]).join(', ')||'-'}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">조치내용</td><td>${pr.description||'-'}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">완료시각</td><td>${Auth.fmtDt(pr.completed_at)}</td></tr>
|
||||
</table>
|
||||
${(pr.photos_before||[]).length || (pr.photos_after||[]).length ? `
|
||||
<div style="margin-top:10px;">
|
||||
${(pr.photos_before||[]).length ? `<label style="font-size:12px;font-weight:700;color:var(--navy2)">조치 전 사진</label>
|
||||
<div class="photo-preview">${(pr.photos_before||[]).map(p=>`<img src="${p}" onclick="window.open('${p}')" style="cursor:zoom-in">`).join('')}</div>` : ''}
|
||||
${(pr.photos_after||[]).length ? `<label style="font-size:12px;font-weight:700;color:var(--navy2);margin-top:8px;display:block">조치 후 사진</label>
|
||||
<div class="photo-preview">${(pr.photos_after||[]).map(p=>`<img src="${p}" onclick="window.open('${p}')" style="cursor:zoom-in">`).join('')}</div>` : ''}
|
||||
</div>` : ''}
|
||||
</div>`).join('');
|
||||
})() : ''}
|
||||
|
||||
<div class="card" style="${prevRepairs.length ? 'border-left:4px solid var(--accent);' : ''}">
|
||||
<div class="card-title" style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
|
||||
<span>🔧 조치 정보</span>
|
||||
<span>🔧 조치 ${prevRepairs.length ? '#' + (prevRepairs.length + 1) + ' (최신)' : '정보'}</span>
|
||||
${repair ? `
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
|
||||
${repair.approved_at
|
||||
@@ -669,34 +694,6 @@ async function load() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${prevRepairs.length ? `
|
||||
<div class="card">
|
||||
<div class="card-title">📋 이전 조치 이력 (재조치 전 기록 ${prevRepairs.length}건)</div>
|
||||
${prevRepairs.map((pr, idx) => `
|
||||
<details style="margin-bottom:10px;border:1px solid var(--gray2);border-radius:8px;overflow:hidden;">
|
||||
<summary style="padding:10px 14px;cursor:pointer;font-size:13px;font-weight:700;color:var(--navy2);background:var(--gray1);list-style:none;display:flex;justify-content:space-between;align-items:center;">
|
||||
<span>#${pr.id} · ${pr.mechanic_name||'?'} · ${Auth.fmtDt(pr.completed_at)}</span>
|
||||
<span style="font-size:11px;background:#FEF3C7;color:#92400E;padding:2px 8px;border-radius:8px;">🔁 재조치 요청됨</span>
|
||||
</summary>
|
||||
<div style="padding:12px 14px;font-size:13px;">
|
||||
<table class="no-hover" style="font-size:13px;">
|
||||
<tr><td style="color:var(--gray4);width:100px">정비사</td><td>${pr.mechanic_name||'-'} (${pr.mechanic_company||'-'})</td></tr>
|
||||
<tr><td style="color:var(--gray4)">조치유형</td><td>${(pr.repair_types||[]).join(', ')||'-'}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">조치내용</td><td>${pr.description||'-'}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">완료시각</td><td>${Auth.fmtDt(pr.completed_at)}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">처리결과</td><td>${Auth.statusBadge(pr.result_status)}</td></tr>
|
||||
<tr><td style="color:var(--gray4)">재조치요청</td><td style="color:#92400E;font-weight:700;">${Auth.fmtDt(pr.re_dispatch_requested_at)}</td></tr>
|
||||
</table>
|
||||
${(pr.photos_before||[]).length || (pr.photos_after||[]).length ? `
|
||||
<div style="margin-top:10px;">
|
||||
${(pr.photos_before||[]).length ? `<div style="font-size:11px;font-weight:700;color:var(--gray4);margin-bottom:4px;">조치 전</div>
|
||||
<div class="photo-preview">${(pr.photos_before||[]).map(p=>`<img src="${p}" onclick="window.open('${p}')" style="cursor:zoom-in">`).join('')}</div>` : ''}
|
||||
${(pr.photos_after||[]).length ? `<div style="font-size:11px;font-weight:700;color:var(--gray4);margin:6px 0 4px;">조치 후</div>
|
||||
<div class="photo-preview">${(pr.photos_after||[]).map(p=>`<img src="${p}" onclick="window.open('${p}')" style="cursor:zoom-in">`).join('')}</div>` : ''}
|
||||
</div>` : ''}
|
||||
</div>
|
||||
</details>`).join('')}
|
||||
</div>` : ''}
|
||||
|
||||
${costHtml}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user