// department-management.js // 부서 관리 페이지 JavaScript let departments = []; let selectedDepartmentId = null; let selectedWorkers = new Set(); // 페이지 초기화 document.addEventListener('DOMContentLoaded', async () => { await waitForApiConfig(); await loadDepartments(); }); // API 설정 로드 대기 async function waitForApiConfig() { let retryCount = 0; while (!window.apiCall && retryCount < 50) { await new Promise(resolve => setTimeout(resolve, 100)); retryCount++; } if (!window.apiCall) { console.error('API 설정 로드 실패'); } } // 부서 목록 로드 async function loadDepartments() { try { const result = await window.apiCall('/departments'); if (result.success) { departments = result.data; renderDepartmentList(); updateMoveToDepartmentSelect(); } } catch (error) { console.error('부서 목록 로드 실패:', error); } } // 부서 목록 렌더링 function renderDepartmentList() { const container = document.getElementById('departmentList'); if (departments.length === 0) { container.innerHTML = `
등록된 부서가 없습니다.
`; return; } container.innerHTML = departments.map(dept => `
${dept.department_name} ${dept.worker_count || 0}명
`).join(''); } // 부서 선택 async function selectDepartment(departmentId) { selectedDepartmentId = departmentId; selectedWorkers.clear(); updateBulkActions(); renderDepartmentList(); const dept = departments.find(d => d.department_id === departmentId); document.getElementById('workerListTitle').textContent = `${dept.department_name} 작업자`; document.getElementById('addWorkerBtn').style.display = 'inline-flex'; await loadWorkers(departmentId); } // 부서별 작업자 로드 async function loadWorkers(departmentId) { try { const result = await window.apiCall(`/departments/${departmentId}/workers`); if (result.success) { renderWorkerList(result.data); } } catch (error) { console.error('작업자 목록 로드 실패:', error); } } // 작업자 목록 렌더링 function renderWorkerList(workers) { const container = document.getElementById('workerList'); if (workers.length === 0) { container.innerHTML = `
이 부서에 소속된 작업자가 없습니다.
`; return; } container.innerHTML = workers.map(worker => `
${worker.worker_name.charAt(0)}
${worker.worker_name} ${getJobTypeName(worker.job_type)}
`).join(''); } // 직책 한글 변환 function getJobTypeName(jobType) { const names = { leader: '그룹장', worker: '작업자', admin: '관리자' }; return names[jobType] || jobType || '-'; } // 작업자 선택 토글 function toggleWorkerSelection(workerId) { if (selectedWorkers.has(workerId)) { selectedWorkers.delete(workerId); } else { selectedWorkers.add(workerId); } updateBulkActions(); // 선택 상태 업데이트 const card = document.querySelector(`.worker-card[onclick*="${workerId}"]`); if (card) { card.classList.toggle('selected', selectedWorkers.has(workerId)); const checkbox = card.querySelector('input[type="checkbox"]'); if (checkbox) checkbox.checked = selectedWorkers.has(workerId); } } // 일괄 작업 영역 업데이트 function updateBulkActions() { const bulkActions = document.getElementById('bulkActions'); const selectedCount = document.getElementById('selectedCount'); if (selectedWorkers.size > 0) { bulkActions.classList.add('visible'); selectedCount.textContent = selectedWorkers.size; } else { bulkActions.classList.remove('visible'); } } // 이동 대상 부서 선택 업데이트 function updateMoveToDepartmentSelect() { const select = document.getElementById('moveToDepartment'); select.innerHTML = '' + departments.map(d => ``).join(''); } // 선택한 작업자 이동 async function moveSelectedWorkers() { const targetDepartmentId = document.getElementById('moveToDepartment').value; if (!targetDepartmentId) { alert('이동할 부서를 선택하세요.'); return; } if (selectedWorkers.size === 0) { alert('이동할 작업자를 선택하세요.'); return; } if (parseInt(targetDepartmentId) === selectedDepartmentId) { alert('같은 부서로는 이동할 수 없습니다.'); return; } try { const result = await window.apiCall('/departments/move-workers', 'POST', { workerIds: Array.from(selectedWorkers), departmentId: parseInt(targetDepartmentId) }); if (result.success) { alert(result.message); selectedWorkers.clear(); updateBulkActions(); document.getElementById('moveToDepartment').value = ''; await loadDepartments(); await loadWorkers(selectedDepartmentId); } else { alert(result.error || '이동 실패'); } } catch (error) { console.error('작업자 이동 실패:', error); alert('작업자 이동에 실패했습니다.'); } } // 부서 모달 열기 function openDepartmentModal(departmentId = null) { const modal = document.getElementById('departmentModal'); const title = document.getElementById('departmentModalTitle'); const form = document.getElementById('departmentForm'); // 상위 부서 선택 옵션 업데이트 const parentSelect = document.getElementById('parentDepartment'); parentSelect.innerHTML = '' + departments .filter(d => d.department_id !== departmentId) .map(d => ``) .join(''); if (departmentId) { const dept = departments.find(d => d.department_id === departmentId); title.textContent = '부서 수정'; document.getElementById('departmentId').value = dept.department_id; document.getElementById('departmentName').value = dept.department_name; document.getElementById('parentDepartment').value = dept.parent_id || ''; document.getElementById('departmentDescription').value = dept.description || ''; document.getElementById('displayOrder').value = dept.display_order || 0; document.getElementById('isActive').checked = dept.is_active; } else { title.textContent = '새 부서 등록'; form.reset(); document.getElementById('departmentId').value = ''; document.getElementById('isActive').checked = true; } modal.classList.add('show'); } // 부서 모달 닫기 function closeDepartmentModal() { document.getElementById('departmentModal').classList.remove('show'); } // 부서 저장 async function saveDepartment(event) { event.preventDefault(); const departmentId = document.getElementById('departmentId').value; const data = { department_name: document.getElementById('departmentName').value, parent_id: document.getElementById('parentDepartment').value || null, description: document.getElementById('departmentDescription').value, display_order: parseInt(document.getElementById('displayOrder').value) || 0, is_active: document.getElementById('isActive').checked }; try { const url = departmentId ? `/departments/${departmentId}` : '/departments'; const method = departmentId ? 'PUT' : 'POST'; const result = await window.apiCall(url, method, data); if (result.success) { alert(result.message); closeDepartmentModal(); await loadDepartments(); } else { alert(result.error || '저장 실패'); } } catch (error) { console.error('부서 저장 실패:', error); alert('부서 저장에 실패했습니다.'); } } // 부서 수정 function editDepartment(departmentId) { openDepartmentModal(departmentId); } // 부서 삭제 async function deleteDepartment(departmentId) { const dept = departments.find(d => d.department_id === departmentId); if (!confirm(`"${dept.department_name}" 부서를 삭제하시겠습니까?\n\n소속 작업자가 있거나 하위 부서가 있으면 삭제할 수 없습니다.`)) { return; } try { const result = await window.apiCall(`/departments/${departmentId}`, 'DELETE'); if (result.success) { alert('부서가 삭제되었습니다.'); if (selectedDepartmentId === departmentId) { selectedDepartmentId = null; document.getElementById('workerListTitle').textContent = '부서를 선택하세요'; document.getElementById('addWorkerBtn').style.display = 'none'; document.getElementById('workerList').innerHTML = `
왼쪽에서 부서를 선택하면 해당 부서의 작업자가 표시됩니다.
`; } await loadDepartments(); } else { alert(result.error || '삭제 실패'); } } catch (error) { console.error('부서 삭제 실패:', error); alert('부서 삭제에 실패했습니다.'); } } // 작업자 추가 모달 (작업자 관리 페이지로 이동) function openAddWorkerModal() { alert('작업자 관리 페이지에서 작업자를 등록한 후 이 페이지에서 부서를 배정하세요.'); // window.location.href = '/pages/admin/workers.html'; }