/** * Daily Work Report - State Manager * 작업보고서 페이지의 전역 상태 관리 (BaseState 상속) */ class DailyWorkReportState extends BaseState { constructor() { super(); // 마스터 데이터 this.workTypes = []; this.workStatusTypes = []; this.errorTypes = []; // 레거시 호환용 this.issueCategories = []; // 신고 카테고리 (nonconformity) this.issueItems = []; // 신고 아이템 this.workers = []; this.projects = []; // UI 상태 this.selectedWorkers = new Set(); this.workEntryCounter = 0; this.currentStep = 1; this.editingWorkId = null; this.currentTab = 'tbm'; // TBM 관련 this.incompleteTbms = []; // 부적합 원인 관리 this.currentDefectIndex = null; this.tempDefects = {}; // { index: [{ error_type_id, defect_hours, note }] } // 작업장소 지도 관련 this.mapCanvas = null; this.mapCtx = null; this.mapImage = null; this.mapRegions = []; this.selectedWorkplace = null; this.selectedWorkplaceName = null; this.selectedWorkplaceCategory = null; this.selectedWorkplaceCategoryName = null; // 시간 선택 관련 this.currentEditingField = null; // { index, type: 'total' | 'error' } this.currentTimeValue = 0; // 캐시 this.dailyIssuesCache = {}; // { 'YYYY-MM-DD': [issues] } console.log('[State] DailyWorkReportState 초기화 완료'); } /** * 토큰에서 사용자 정보 추출 */ getCurrentUser() { try { const token = localStorage.getItem('sso_token'); if (!token) return null; const payloadBase64 = token.split('.')[1]; if (payloadBase64) { const payload = JSON.parse(atob(payloadBase64)); return payload; } } catch (error) { console.log('[State] 토큰에서 사용자 정보 추출 실패:', error); } try { const userInfo = localStorage.getItem('sso_user') || localStorage.getItem('userInfo') || localStorage.getItem('currentUser'); if (userInfo) { return JSON.parse(userInfo); } } catch (error) { console.log('[State] localStorage에서 사용자 정보 가져오기 실패:', error); } return null; } /** * 선택된 작업자 토글 */ toggleWorkerSelection(workerId) { if (this.selectedWorkers.has(workerId)) { this.selectedWorkers.delete(workerId); } else { this.selectedWorkers.add(workerId); } this.notifyListeners('selectedWorkers', this.selectedWorkers, null); } /** * 작업자 전체 선택/해제 */ selectAllWorkers(select = true) { if (select) { this.workers.forEach(w => this.selectedWorkers.add(w.worker_id)); } else { this.selectedWorkers.clear(); } this.notifyListeners('selectedWorkers', this.selectedWorkers, null); } /** * 작업 항목 카운터 증가 */ incrementWorkEntryCounter() { this.workEntryCounter++; return this.workEntryCounter; } /** * 탭 변경 */ setCurrentTab(tab) { const prevTab = this.currentTab; this.currentTab = tab; this.notifyListeners('currentTab', tab, prevTab); } /** * 부적합 임시 저장소 초기화 */ initTempDefects(index) { if (!this.tempDefects[index]) { this.tempDefects[index] = []; } } /** * 부적합 추가 */ addTempDefect(index, defect) { this.initTempDefects(index); this.tempDefects[index].push(defect); this.notifyListeners('tempDefects', this.tempDefects, null); } /** * 부적합 업데이트 */ updateTempDefect(index, defectIndex, field, value) { if (this.tempDefects[index] && this.tempDefects[index][defectIndex]) { this.tempDefects[index][defectIndex][field] = value; this.notifyListeners('tempDefects', this.tempDefects, null); } } /** * 부적합 삭제 */ removeTempDefect(index, defectIndex) { if (this.tempDefects[index]) { this.tempDefects[index].splice(defectIndex, 1); this.notifyListeners('tempDefects', this.tempDefects, null); } } /** * 일일 이슈 캐시 설정 */ setDailyIssuesCache(dateStr, issues) { this.dailyIssuesCache[dateStr] = issues; } /** * 일일 이슈 캐시 조회 */ getDailyIssuesCache(dateStr) { return this.dailyIssuesCache[dateStr] || []; } /** * 상태 초기화 */ reset() { this.selectedWorkers.clear(); this.workEntryCounter = 0; this.currentStep = 1; this.editingWorkId = null; this.tempDefects = {}; this.currentDefectIndex = null; this.dailyIssuesCache = {}; } /** * 디버그 출력 */ debug() { console.log('[State] 현재 상태:', { workTypes: this.workTypes.length, workers: this.workers.length, projects: this.projects.length, selectedWorkers: this.selectedWorkers.size, currentTab: this.currentTab, incompleteTbms: this.incompleteTbms.length, tempDefects: Object.keys(this.tempDefects).length }); } } // 전역 인스턴스 생성 window.DailyWorkReportState = new DailyWorkReportState(); // 하위 호환성을 위한 전역 변수 프록시 const stateProxy = window.DailyWorkReportState; // 기존 전역 변수들과 호환 Object.defineProperties(window, { workTypes: { get: () => stateProxy.workTypes, set: (v) => { stateProxy.workTypes = v; } }, workStatusTypes: { get: () => stateProxy.workStatusTypes, set: (v) => { stateProxy.workStatusTypes = v; } }, errorTypes: { get: () => stateProxy.errorTypes, set: (v) => { stateProxy.errorTypes = v; } }, issueCategories: { get: () => stateProxy.issueCategories, set: (v) => { stateProxy.issueCategories = v; } }, issueItems: { get: () => stateProxy.issueItems, set: (v) => { stateProxy.issueItems = v; } }, workers: { get: () => stateProxy.workers, set: (v) => { stateProxy.workers = v; } }, projects: { get: () => stateProxy.projects, set: (v) => { stateProxy.projects = v; } }, selectedWorkers: { get: () => stateProxy.selectedWorkers, set: (v) => { stateProxy.selectedWorkers = v; } }, incompleteTbms: { get: () => stateProxy.incompleteTbms, set: (v) => { stateProxy.incompleteTbms = v; } }, tempDefects: { get: () => stateProxy.tempDefects, set: (v) => { stateProxy.tempDefects = v; } }, dailyIssuesCache: { get: () => stateProxy.dailyIssuesCache, set: (v) => { stateProxy.dailyIssuesCache = v; } }, currentTab: { get: () => stateProxy.currentTab, set: (v) => { stateProxy.currentTab = v; } }, currentStep: { get: () => stateProxy.currentStep, set: (v) => { stateProxy.currentStep = v; } }, editingWorkId: { get: () => stateProxy.editingWorkId, set: (v) => { stateProxy.editingWorkId = v; } }, workEntryCounter: { get: () => stateProxy.workEntryCounter, set: (v) => { stateProxy.workEntryCounter = v; } }, currentDefectIndex: { get: () => stateProxy.currentDefectIndex, set: (v) => { stateProxy.currentDefectIndex = v; } }, currentEditingField: { get: () => stateProxy.currentEditingField, set: (v) => { stateProxy.currentEditingField = v; } }, currentTimeValue: { get: () => stateProxy.currentTimeValue, set: (v) => { stateProxy.currentTimeValue = v; } }, selectedWorkplace: { get: () => stateProxy.selectedWorkplace, set: (v) => { stateProxy.selectedWorkplace = v; } }, selectedWorkplaceName: { get: () => stateProxy.selectedWorkplaceName, set: (v) => { stateProxy.selectedWorkplaceName = v; } }, selectedWorkplaceCategory: { get: () => stateProxy.selectedWorkplaceCategory, set: (v) => { stateProxy.selectedWorkplaceCategory = v; } }, selectedWorkplaceCategoryName: { get: () => stateProxy.selectedWorkplaceCategoryName, set: (v) => { stateProxy.selectedWorkplaceCategoryName = v; } } });