기능 개선 — 사진 업로드, 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:
byun
2026-06-02 05:38:33 +09:00
parent 5ebd0a6ae7
commit 9f0f4326fe
18 changed files with 436 additions and 255 deletions

View File

@@ -316,7 +316,7 @@ body { background: var(--gray1); }
</div>
<script src="/js/api.js"></script>
<script src="/js/imageCompress.js"></script>
<script src="/js/imageCompress.js?v=20260603"></script>
<script>
let ISSUES = [
{key:'충전불가', label:'⚡ 충전 불가'},
@@ -450,19 +450,21 @@ function initCollapseHeight() {
}
// ── GPS ──
navigator.geolocation?.getCurrentPosition(
pos => {
document.getElementById('gpsLat').value = pos.coords.latitude;
document.getElementById('gpsLng').value = pos.coords.longitude;
document.getElementById('gpsStatus').textContent =
`📍 위치 수집 완료 (${pos.coords.latitude.toFixed(5)}, ${pos.coords.longitude.toFixed(5)})`;
document.getElementById('gpsStatus').className = 'alert alert-success';
},
() => {
document.getElementById('gpsStatus').textContent = '위치 정보를 가져올 수 없습니다. (수동 신고로 진행)';
document.getElementById('gpsStatus').className = 'alert alert-warn';
}
);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(pos) {
document.getElementById('gpsLat').value = pos.coords.latitude;
document.getElementById('gpsLng').value = pos.coords.longitude;
document.getElementById('gpsStatus').textContent =
'📍 위치 수집 완료 (' + pos.coords.latitude.toFixed(5) + ', ' + pos.coords.longitude.toFixed(5) + ')';
document.getElementById('gpsStatus').className = 'alert alert-success';
},
function() {
document.getElementById('gpsStatus').textContent = '위치 정보를 가져올 수 없습니다. (수동 신고로 진행)';
document.getElementById('gpsStatus').className = 'alert alert-warn';
}
);
}
// ── 에러코드 UI 갱신 ──
function updateErrorCodeUI() {
@@ -494,7 +496,7 @@ function getErrorCodeValue() {
const sel = document.getElementById('errorCode');
if (!sel) return '';
if (sel.tagName === 'SELECT') {
if (sel.value === '__other__') return document.getElementById('errorCodeCustom')?.value || '';
if (sel.value === '__other__') { var ecEl = document.getElementById('errorCodeCustom'); return ecEl ? ecEl.value : ''; }
return sel.value;
}
return sel.value;
@@ -547,7 +549,8 @@ document.getElementById('submitBtn').addEventListener('click', async () => {
document.getElementById('submitBtn').disabled = true;
document.getElementById('submitBtn').textContent = '접수 중...';
const scope = document.querySelector('input[name="scope"]:checked')?.value || 'single';
var scopeEl = document.querySelector('input[name="scope"]:checked');
var scope = scopeEl ? scopeEl.value : 'single';
const fd = new FormData();
fd.append('charger_id', chargerId);