/** * Workplace Management - API Client * 작업장 관리 관련 모든 API 호출을 관리 */ class WorkplaceAPI { constructor() { this.state = window.WorkplaceState; this.utils = window.WorkplaceUtils; console.log('[WorkplaceAPI] 초기화 완료'); } /** * 모든 데이터 로드 */ async loadAllData() { try { await Promise.all([ this.loadCategories(), this.loadWorkplaces() ]); console.log('✅ 모든 데이터 로드 완료'); } catch (error) { console.error('데이터 로딩 오류:', error); window.showToast?.('데이터를 불러오는데 실패했습니다.', 'error'); } } /** * 카테고리 목록 로드 */ async loadCategories() { try { const response = await window.apiCall('/workplaces/categories', 'GET'); let categoryData = []; if (response && response.success && Array.isArray(response.data)) { categoryData = response.data; } else if (Array.isArray(response)) { categoryData = response; } this.state.categories = categoryData; console.log(`✅ 카테고리 ${this.state.categories.length}개 로드 완료`); return categoryData; } catch (error) { console.error('카테고리 로딩 오류:', error); this.state.categories = []; return []; } } /** * 카테고리 저장 (생성/수정) */ async saveCategory(categoryId, categoryData) { try { let response; if (categoryId) { response = await window.apiCall(`/workplaces/categories/${categoryId}`, 'PUT', categoryData); } else { response = await window.apiCall('/workplaces/categories', 'POST', categoryData); } if (response && (response.success || response.category_id)) { return response; } throw new Error(response?.message || '저장에 실패했습니다.'); } catch (error) { console.error('카테고리 저장 오류:', error); throw error; } } /** * 카테고리 삭제 */ async deleteCategory(categoryId) { try { const response = await window.apiCall(`/workplaces/categories/${categoryId}`, 'DELETE'); if (response && response.success) { return response; } throw new Error(response?.message || '삭제에 실패했습니다.'); } catch (error) { console.error('카테고리 삭제 오류:', error); throw error; } } /** * 작업장 목록 로드 */ async loadWorkplaces() { try { const response = await window.apiCall('/workplaces', 'GET'); let workplaceData = []; if (response && response.success && Array.isArray(response.data)) { workplaceData = response.data; } else if (Array.isArray(response)) { workplaceData = response; } this.state.workplaces = workplaceData; console.log(`✅ 작업장 ${this.state.workplaces.length}개 로드 완료`); return workplaceData; } catch (error) { console.error('작업장 로딩 오류:', error); this.state.workplaces = []; return []; } } /** * 작업장 저장 (생성/수정) */ async saveWorkplace(workplaceId, workplaceData) { try { let response; if (workplaceId) { response = await window.apiCall(`/workplaces/${workplaceId}`, 'PUT', workplaceData); } else { response = await window.apiCall('/workplaces', 'POST', workplaceData); } if (response && (response.success || response.workplace_id)) { return response; } throw new Error(response?.message || '저장에 실패했습니다.'); } catch (error) { console.error('작업장 저장 오류:', error); throw error; } } /** * 작업장 삭제 */ async deleteWorkplace(workplaceId) { try { const response = await window.apiCall(`/workplaces/${workplaceId}`, 'DELETE'); if (response && response.success) { return response; } throw new Error(response?.message || '삭제에 실패했습니다.'); } catch (error) { console.error('작업장 삭제 오류:', error); throw error; } } /** * 카테고리의 지도 영역 로드 */ async loadMapRegions(categoryId) { try { const response = await window.apiCall(`/workplaces/categories/${categoryId}/map-regions`, 'GET'); let regions = []; if (response && response.success && Array.isArray(response.data)) { regions = response.data; } else if (Array.isArray(response)) { regions = response; } return regions; } catch (error) { console.error('지도 영역 로드 오류:', error); return []; } } /** * 작업장의 지도 영역 로드 */ async loadWorkplaceMapRegion(workplaceId) { try { const response = await window.apiCall(`/workplaces/map-regions/workplace/${workplaceId}`, 'GET'); return response; } catch (error) { console.error('작업장 지도 영역 로드 오류:', error); return null; } } /** * 작업장의 설비 목록 로드 */ async loadWorkplaceEquipments(workplaceId) { try { const response = await window.apiCall(`/equipments/workplace/${workplaceId}`, 'GET'); let equipments = []; if (response && response.success && Array.isArray(response.data)) { equipments = response.data; } else if (Array.isArray(response)) { equipments = response; } // 지도 영역이 있는 설비만 workplaceEquipmentRegions에 추가 this.state.workplaceEquipmentRegions = equipments .filter(eq => eq.map_x_percent != null && eq.map_y_percent != null) .map(eq => ({ equipment_id: eq.equipment_id, equipment_name: eq.equipment_name, equipment_code: eq.equipment_code, x_percent: parseFloat(eq.map_x_percent), y_percent: parseFloat(eq.map_y_percent), width_percent: parseFloat(eq.map_width_percent) || 10, height_percent: parseFloat(eq.map_height_percent) || 10 })); this.state.existingEquipments = equipments; console.log(`✅ 작업장 ${workplaceId}의 설비 ${equipments.length}개 로드 완료`); return equipments; } catch (error) { console.error('설비 로드 오류:', error); this.state.workplaceEquipmentRegions = []; this.state.existingEquipments = []; return []; } } /** * 전체 설비 목록 로드 */ async loadAllEquipments() { try { const response = await window.apiCall('/equipments', 'GET'); let equipments = []; if (response && response.success && Array.isArray(response.data)) { equipments = response.data; } else if (Array.isArray(response)) { equipments = response; } this.state.allEquipments = equipments; console.log(`✅ 전체 설비 ${this.state.allEquipments.length}개 로드 완료`); return equipments; } catch (error) { console.error('전체 설비 로드 오류:', error); this.state.allEquipments = []; return []; } } /** * 설비 지도 위치 업데이트 */ async updateEquipmentMapPosition(equipmentId, positionData) { try { const response = await window.apiCall(`/equipments/${equipmentId}/map-position`, 'PATCH', positionData); if (!response || !response.success) { throw new Error(response?.message || '위치 저장 실패'); } return response; } catch (error) { console.error('설비 위치 업데이트 오류:', error); throw error; } } /** * 새 설비 생성 */ async createEquipment(equipmentData) { try { const response = await window.apiCall('/equipments', 'POST', equipmentData); if (!response || !response.success) { throw new Error(response?.message || '설비 생성 실패'); } return response; } catch (error) { console.error('설비 생성 오류:', error); throw error; } } /** * 다음 관리번호 조회 */ async getNextEquipmentCode() { try { const response = await window.apiCall('/equipments/next-code', 'GET'); if (response && response.success) { return response.data.next_code; } return null; } catch (error) { console.error('다음 관리번호 조회 실패:', error); return null; } } /** * 작업장 레이아웃 이미지 업로드 */ async uploadWorkplaceLayout(workplaceId, formData) { try { const response = await fetch( `${this.utils.getApiBaseUrl()}/workplaces/${workplaceId}/layout-image`, { method: 'POST', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: formData } ); return await response.json(); } catch (error) { console.error('레이아웃 이미지 업로드 오류:', error); throw error; } } } // 전역 인스턴스 생성 window.WorkplaceAPI = new WorkplaceAPI(); // 하위 호환성: 기존 함수들 window.loadCategories = () => window.WorkplaceAPI.loadCategories(); window.loadWorkplaces = () => window.WorkplaceAPI.loadWorkplaces(); window.loadWorkplaceEquipments = (id) => window.WorkplaceAPI.loadWorkplaceEquipments(id); window.loadAllEquipments = () => window.WorkplaceAPI.loadAllEquipments(); console.log('[Module] workplace-management/api.js 로드 완료');