refactor: TBM/작업보고 코드 통합 및 API 쿼리 버그 수정
- 공통 유틸리티 추출 (common/utils.js, common/base-state.js) - TBM 모바일 인라인 JS/CSS 외부 파일로 분리 (tbm-mobile.js, tbm-mobile.css) - 미사용 코드 삭제 (index.js, work-report-*.js 등 5개 파일) - TBM/작업보고 state.js, utils.js를 공통 모듈 기반으로 전환 - 작업보고서 SSO 인증 호환 수정 (token/user 함수) - tbmModel.js: incomplete-reports 쿼리에서 users→sso_users 조인 수정, leader_name 조인 추가 - docker-compose.yml: system1-web 볼륨 마운트 추가 - 모바일 인계(handover) 기능 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,67 +1,29 @@
|
||||
/**
|
||||
* Daily Work Report - Utilities
|
||||
* 작업보고서 관련 유틸리티 함수들
|
||||
* 작업보고서 관련 유틸리티 함수들 (공통 함수는 CommonUtils에 위임)
|
||||
*/
|
||||
|
||||
class DailyWorkReportUtils {
|
||||
constructor() {
|
||||
this._common = window.CommonUtils;
|
||||
console.log('[Utils] DailyWorkReportUtils 초기화');
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 시간 기준 오늘 날짜 (YYYY-MM-DD)
|
||||
*/
|
||||
getKoreaToday() {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
// --- CommonUtils 위임 ---
|
||||
getKoreaToday() { return this._common.getTodayKST(); }
|
||||
formatDateForApi(date) { return this._common.formatDate(date); }
|
||||
formatDate(date) { return this._common.formatDate(date) || '-'; }
|
||||
getDayOfWeek(date) { return this._common.getDayOfWeek(date); }
|
||||
isToday(date) { return this._common.isToday(date); }
|
||||
generateUUID() { return this._common.generateUUID(); }
|
||||
escapeHtml(text) { return this._common.escapeHtml(text); }
|
||||
debounce(func, wait) { return this._common.debounce(func, wait); }
|
||||
throttle(func, limit) { return this._common.throttle(func, limit); }
|
||||
deepClone(obj) { return this._common.deepClone(obj); }
|
||||
isEmpty(value) { return this._common.isEmpty(value); }
|
||||
groupBy(array, key) { return this._common.groupBy(array, key); }
|
||||
|
||||
/**
|
||||
* 날짜를 API 형식(YYYY-MM-DD)으로 변환
|
||||
*/
|
||||
formatDateForApi(date) {
|
||||
if (!date) return null;
|
||||
|
||||
let dateObj;
|
||||
if (date instanceof Date) {
|
||||
dateObj = date;
|
||||
} else if (typeof date === 'string') {
|
||||
dateObj = new Date(date);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
const year = dateObj.getFullYear();
|
||||
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(dateObj.getDate()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜 포맷팅 (표시용)
|
||||
*/
|
||||
formatDate(date) {
|
||||
if (!date) return '-';
|
||||
|
||||
let dateObj;
|
||||
if (date instanceof Date) {
|
||||
dateObj = date;
|
||||
} else if (typeof date === 'string') {
|
||||
dateObj = new Date(date);
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
|
||||
const year = dateObj.getFullYear();
|
||||
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(dateObj.getDate()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
// --- 작업보고 전용 ---
|
||||
|
||||
/**
|
||||
* 시간 포맷팅 (HH:mm)
|
||||
@@ -104,24 +66,6 @@ class DailyWorkReportUtils {
|
||||
return Number(num).toFixed(decimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* 요일 반환
|
||||
*/
|
||||
getDayOfWeek(date) {
|
||||
const days = ['일', '월', '화', '수', '목', '금', '토'];
|
||||
const dateObj = date instanceof Date ? date : new Date(date);
|
||||
return days[dateObj.getDay()];
|
||||
}
|
||||
|
||||
/**
|
||||
* 오늘인지 확인
|
||||
*/
|
||||
isToday(date) {
|
||||
const today = this.getKoreaToday();
|
||||
const targetDate = this.formatDateForApi(date);
|
||||
return today === targetDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 날짜 사이 일수 계산
|
||||
*/
|
||||
@@ -132,63 +76,6 @@ class DailyWorkReportUtils {
|
||||
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
}
|
||||
|
||||
/**
|
||||
* 디바운스 함수
|
||||
*/
|
||||
debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 쓰로틀 함수
|
||||
*/
|
||||
throttle(func, limit) {
|
||||
let inThrottle;
|
||||
return function(...args) {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML 이스케이프
|
||||
*/
|
||||
escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* 객체 깊은 복사
|
||||
*/
|
||||
deepClone(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 빈 값 확인
|
||||
*/
|
||||
isEmpty(value) {
|
||||
if (value === null || value === undefined) return true;
|
||||
if (typeof value === 'string') return value.trim() === '';
|
||||
if (Array.isArray(value)) return value.length === 0;
|
||||
if (typeof value === 'object') return Object.keys(value).length === 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자 유효성 검사
|
||||
*/
|
||||
@@ -249,20 +136,6 @@ class DailyWorkReportUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열 그룹화
|
||||
*/
|
||||
groupBy(array, key) {
|
||||
return array.reduce((result, item) => {
|
||||
const groupKey = typeof key === 'function' ? key(item) : item[key];
|
||||
if (!result[groupKey]) {
|
||||
result[groupKey] = [];
|
||||
}
|
||||
result[groupKey].push(item);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열 정렬 (다중 키)
|
||||
*/
|
||||
@@ -280,17 +153,6 @@ class DailyWorkReportUtils {
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* UUID 생성
|
||||
*/
|
||||
generateUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
const r = Math.random() * 16 | 0;
|
||||
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 전역 인스턴스 생성
|
||||
|
||||
Reference in New Issue
Block a user