| 번호 | -AI Model 역할 | -파일명 | -현재 버전 | -삭제 | -
|---|---|---|---|---|
| 1 | -객체 탐지/ 분류 | -- | -v1.0 | -- - | -
| 2 | -화재(불꽃, 연기) 감지 | -- | -v1.0 | -- - | -
| 3 | -이상행동(쓰러짐, 폭행) 감지 | -- | -v1.0 | -- - | -
| 4 | -얼굴/ 인상착의 인식 | -- | -- | -- - | -
| 5 | -차량 번호판/ 차종 인식 | -- | -- | -- - | -
| 번호 | -관심인물명 | -미리 보기 | -파일 등록 | -
|---|
diff --git a/public/_app.js b/public/_app.js deleted file mode 100644 index e275df3..0000000 --- a/public/_app.js +++ /dev/null @@ -1,610 +0,0 @@ -// app.js - -document.addEventListener('DOMContentLoaded', () => { - - // ================================================= - // 0. 로그아웃 로직 - // ================================================= - const logoutBtn = document.getElementById('logout-button'); - if (logoutBtn) { - logoutBtn.addEventListener('click', () => { - if (confirm('정말로 로그아웃 하시겠습니까?')) { - // 로그인 페이지(루트)로 이동 - window.location.href = '/'; - } - }); - } - - // ================================================= - // 1. 탭 전환 로직 - // ================================================= - const tabVideo = document.getElementById('tab-video'); - const tabModels = document.getElementById('tab-models'); - const contentVideo = document.getElementById('content-video'); - const contentModels = document.getElementById('content-models'); - - if (tabVideo && tabModels) { - tabVideo.addEventListener('click', () => { - tabVideo.classList.add('active'); - tabModels.classList.remove('active'); - contentVideo.classList.add('active'); - contentModels.classList.remove('active'); - }); - - tabModels.addEventListener('click', () => { - tabModels.classList.add('active'); - tabVideo.classList.remove('active'); - contentModels.classList.add('active'); - contentVideo.classList.remove('active'); - loadModelList(); - loadPoiList(); - }); - } - - // ================================================= - // 2. AI 모델 관리 로직 - // ================================================= - function loadModelList() { - const tableBody = document.querySelector('.model-table tbody'); - if (!tableBody) return; - fetch('/list-models').then(r=>r.json()).then(models=>{ - tableBody.querySelectorAll('tr[data-role]').forEach(row => { - const role = row.dataset.role; - const d = models[role]; - const f = row.querySelector('.model-filename'); - const v = row.querySelector('.model-version'); - const btn = row.querySelector('.btn-delete'); - if(d){ f.textContent=d.file; v.textContent=d.version; btn.classList.remove('hidden'); } - else { f.textContent='-'; v.textContent='-'; btn.classList.add('hidden'); } - }); - }); - } - - const modelTableBody = document.querySelector('.model-table tbody'); - if(modelTableBody) { - modelTableBody.addEventListener('click', (e) => { - if(e.target.classList.contains('btn-delete')) { - const row = e.target.closest('tr'); - const filename = row.querySelector('.model-filename').textContent; - if(filename && filename !== '-') deleteModelFile(filename); - } - }); - } - - function deleteModelFile(filename) { - if (!confirm(`정말로 이 모델 파일(${filename})을 삭제하시겠습니까?`)) return; - fetch('/delete-model', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({filename: filename}) - }).then(res => res.json()).then(data => { - if (data.status === 'success') { alert('삭제되었습니다.'); loadModelList(); } - else { alert(`삭제 실패: ${data.message}`); } - }); - } - - const globalUploadBtn = document.getElementById('global-upload-button'); - const globalFileInput = document.getElementById('global-file-input'); - const fileNameDisplay = document.getElementById('file-name-display'); - const refreshButton = document.querySelector('.refresh-button'); - - if (globalFileInput) { - globalFileInput.addEventListener('change', () => { - fileNameDisplay.textContent = globalFileInput.files.length > 0 ? globalFileInput.files[0].name : '선택된 파일 없음'; - }); - } - if (globalUploadBtn) { - globalUploadBtn.addEventListener('click', () => { - if (!globalFileInput.files.length) return alert('파일을 선택해주세요.'); - const formData = new FormData(); - formData.append('modelFile', globalFileInput.files[0]); - fetch('/upload-model', { method: 'POST', body: formData }) - .then(res => res.json()) - .then(data => { - if (data.status === 'success') { alert('업로드 성공'); globalFileInput.value=''; fileNameDisplay.textContent='선택된 파일 없음'; loadModelList(); } - else { alert(`실패: ${data.message}`); } - }); - }); - } - if (refreshButton) refreshButton.addEventListener('click', loadModelList); - - - // ================================================= - // 3. 관심 인물(POI) 관리 로직 - // ================================================= - const poiTableBody = document.querySelector('#poi-table tbody'); - const poiEmptyMsg = document.getElementById('poi-empty-msg'); - const btnPoiRegister = document.getElementById('btn-poi-register'); - const btnPoiRefresh = document.getElementById('btn-poi-refresh'); - - // 모달 및 뷰어 요소 - const poiModal = document.getElementById('poi-modal'); - const poiNameInput = document.getElementById('poi-name-input'); - const btnModalConfirm = document.getElementById('btn-modal-confirm'); - const btnModalCancel = document.getElementById('btn-modal-cancel'); - - const imageViewerModal = document.getElementById('image-viewer-modal'); - const fullImage = document.getElementById('full-image'); - const closeViewerBtn = document.querySelector('.close-viewer'); - - // POI 목록 로드 - function loadPoiList() { - if (!poiTableBody) return; - - fetch('/poi/list') - .then(res => res.json()) - .then(list => { - poiTableBody.innerHTML = ''; - - if (!list || list.length === 0) { - poiEmptyMsg.classList.remove('hidden'); - poiTableBody.parentElement.classList.add('hidden'); - } else { - poiEmptyMsg.classList.add('hidden'); - poiTableBody.parentElement.classList.remove('hidden'); - - list.forEach((item, index) => { - const tr = document.createElement('tr'); - - let previewHtml = '-'; - if (item.images && item.images.length > 0) { - const imagesHtml = item.images.map(imgName => { - const imgSrc = `/poi-images/${item.name}/${imgName}`; - return ` -
| 번호 | -AI Model 역할 | -파일명 | -현재 버전 | -삭제 | -
|---|---|---|---|---|
| 1 | -객체 탐지/ 분류 | -- | -v1.0 | -- - | -
| 2 | -화재(불꽃, 연기) 감지 | -- | -v1.0 | -- - | -
| 3 | -이상행동(쓰러짐, 폭행) 감지 | -- | -v1.0 | -- - | -
| 4 | -얼굴/ 인상착의 인식 | -- | -- | -- - | -
| 5 | -차량 번호판/ 차종 인식 | -- | -- | -- - | -
| 번호 | -관심인물명 | -미리 보기 | -파일 등록 | -
|---|
Sign In to your account
- - -