Fix: Worker/Project status update and filtering issues
- Added cache invalidation for Workers and Projects - Implemented server-side status filtering for Workers - Fixed worker update query bug (removed non-existent join_date column) - Updated daily-work-report UI to fetch only active workers
This commit is contained in:
@@ -30,7 +30,7 @@ function getCurrentUser() {
|
||||
try {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) return null;
|
||||
|
||||
|
||||
const payloadBase64 = token.split('.')[1];
|
||||
if (payloadBase64) {
|
||||
const payload = JSON.parse(atob(payloadBase64));
|
||||
@@ -40,7 +40,7 @@ function getCurrentUser() {
|
||||
} catch (error) {
|
||||
console.log('토큰에서 사용자 정보 추출 실패:', error);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const userInfo = localStorage.getItem('user') || localStorage.getItem('userInfo') || localStorage.getItem('currentUser');
|
||||
if (userInfo) {
|
||||
@@ -51,7 +51,7 @@ function getCurrentUser() {
|
||||
} catch (error) {
|
||||
console.log('localStorage에서 사용자 정보 가져오기 실패:', error);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ function getCurrentUser() {
|
||||
function showMessage(message, type = 'info') {
|
||||
const container = document.getElementById('message-container');
|
||||
container.innerHTML = `<div class="message ${type}">${message}</div>`;
|
||||
|
||||
|
||||
if (type === 'success') {
|
||||
setTimeout(() => {
|
||||
hideMessage();
|
||||
@@ -76,7 +76,7 @@ function showSaveResultModal(type, title, message, details = null) {
|
||||
const modal = document.getElementById('saveResultModal');
|
||||
const titleElement = document.getElementById('resultModalTitle');
|
||||
const contentElement = document.getElementById('resultModalContent');
|
||||
|
||||
|
||||
// 아이콘 설정
|
||||
let icon = '';
|
||||
switch (type) {
|
||||
@@ -92,14 +92,14 @@ function showSaveResultModal(type, title, message, details = null) {
|
||||
default:
|
||||
icon = 'ℹ️';
|
||||
}
|
||||
|
||||
|
||||
// 모달 내용 구성
|
||||
let content = `
|
||||
<div class="result-icon ${type}">${icon}</div>
|
||||
<h3 class="result-title ${type}">${title}</h3>
|
||||
<p class="result-message">${message}</p>
|
||||
`;
|
||||
|
||||
|
||||
// 상세 정보가 있으면 추가
|
||||
if (details && details.length > 0) {
|
||||
content += `
|
||||
@@ -111,20 +111,20 @@ function showSaveResultModal(type, title, message, details = null) {
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
titleElement.textContent = '저장 결과';
|
||||
contentElement.innerHTML = content;
|
||||
modal.style.display = 'flex';
|
||||
|
||||
|
||||
// ESC 키로 닫기
|
||||
document.addEventListener('keydown', function(e) {
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') {
|
||||
closeSaveResultModal();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 배경 클릭으로 닫기
|
||||
modal.addEventListener('click', function(e) {
|
||||
modal.addEventListener('click', function (e) {
|
||||
if (e.target === modal) {
|
||||
closeSaveResultModal();
|
||||
}
|
||||
@@ -135,7 +135,7 @@ function showSaveResultModal(type, title, message, details = null) {
|
||||
function closeSaveResultModal() {
|
||||
const modal = document.getElementById('saveResultModal');
|
||||
modal.style.display = 'none';
|
||||
|
||||
|
||||
// 이벤트 리스너 제거
|
||||
document.removeEventListener('keydown', closeSaveResultModal);
|
||||
}
|
||||
@@ -155,10 +155,10 @@ function goToStep(stepNumber) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 진행 단계 표시 업데이트
|
||||
updateProgressSteps(stepNumber);
|
||||
|
||||
|
||||
currentStep = stepNumber;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ function updateProgressSteps(currentStepNumber) {
|
||||
const progressStep = document.getElementById(`progressStep${i}`);
|
||||
if (progressStep) {
|
||||
progressStep.classList.remove('active', 'completed');
|
||||
|
||||
|
||||
if (i < currentStepNumber) {
|
||||
progressStep.classList.add('completed');
|
||||
} else if (i === currentStepNumber) {
|
||||
@@ -189,14 +189,14 @@ async function loadData() {
|
||||
await loadWorkTypes();
|
||||
await loadWorkStatusTypes();
|
||||
await loadErrorTypes();
|
||||
|
||||
|
||||
console.log('로드된 작업자 수:', workers.length);
|
||||
console.log('로드된 프로젝트 수:', projects.length);
|
||||
console.log('작업 유형 수:', workTypes.length);
|
||||
|
||||
populateWorkerGrid();
|
||||
hideMessage();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('데이터 로드 실패:', error);
|
||||
showMessage('데이터 로드 중 오류가 발생했습니다: ' + error.message, 'error');
|
||||
@@ -206,7 +206,8 @@ async function loadData() {
|
||||
async function loadWorkers() {
|
||||
try {
|
||||
console.log('Workers API 호출 중... (통합 API 사용)');
|
||||
const data = await window.apiCall(`${window.API}/workers`);
|
||||
// 활성 작업자 1000명까지 조회 (서버 사이드 필터링 적용)
|
||||
const data = await window.apiCall(`${window.API}/workers?status=active&limit=1000`);
|
||||
const allWorkers = Array.isArray(data) ? data : (data.data || data.workers || []);
|
||||
|
||||
// 활성화된 작업자만 필터링
|
||||
@@ -245,9 +246,9 @@ async function loadWorkTypes() {
|
||||
} catch (error) {
|
||||
console.log('⚠️ 작업 유형 API 사용 불가, 기본값 사용');
|
||||
workTypes = [
|
||||
{id: 1, name: 'Base'},
|
||||
{id: 2, name: 'Vessel'},
|
||||
{id: 3, name: 'Piping'}
|
||||
{ id: 1, name: 'Base' },
|
||||
{ id: 2, name: 'Vessel' },
|
||||
{ id: 3, name: 'Piping' }
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -264,8 +265,8 @@ async function loadWorkStatusTypes() {
|
||||
} catch (error) {
|
||||
console.log('⚠️ 업무 상태 유형 API 사용 불가, 기본값 사용');
|
||||
workStatusTypes = [
|
||||
{id: 1, name: '정규'},
|
||||
{id: 2, name: '에러'}
|
||||
{ id: 1, name: '정규' },
|
||||
{ id: 2, name: '에러' }
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -282,10 +283,10 @@ async function loadErrorTypes() {
|
||||
} catch (error) {
|
||||
console.log('⚠️ 에러 유형 API 사용 불가, 기본값 사용');
|
||||
errorTypes = [
|
||||
{id: 1, name: '설계미스'},
|
||||
{id: 2, name: '외주작업 불량'},
|
||||
{id: 3, name: '입고지연'},
|
||||
{id: 4, name: '작업 불량'}
|
||||
{ id: 1, name: '설계미스' },
|
||||
{ id: 2, name: '외주작업 불량' },
|
||||
{ id: 3, name: '입고지연' },
|
||||
{ id: 4, name: '작업 불량' }
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -294,18 +295,18 @@ async function loadErrorTypes() {
|
||||
function populateWorkerGrid() {
|
||||
const grid = document.getElementById('workerGrid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
|
||||
workers.forEach(worker => {
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.className = 'worker-card';
|
||||
btn.textContent = worker.worker_name;
|
||||
btn.dataset.id = worker.worker_id;
|
||||
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
toggleWorkerSelection(worker.worker_id, btn);
|
||||
});
|
||||
|
||||
|
||||
grid.appendChild(btn);
|
||||
});
|
||||
}
|
||||
@@ -319,7 +320,7 @@ function toggleWorkerSelection(workerId, btnElement) {
|
||||
selectedWorkers.add(workerId);
|
||||
btnElement.classList.add('selected');
|
||||
}
|
||||
|
||||
|
||||
const nextBtn = document.getElementById('nextStep2');
|
||||
nextBtn.disabled = selectedWorkers.size === 0;
|
||||
}
|
||||
@@ -331,12 +332,12 @@ function addWorkEntry() {
|
||||
console.log('🔧 컨테이너:', container);
|
||||
workEntryCounter++;
|
||||
console.log('🔧 작업 항목 카운터:', workEntryCounter);
|
||||
|
||||
|
||||
const entryDiv = document.createElement('div');
|
||||
entryDiv.className = 'work-entry';
|
||||
entryDiv.dataset.id = workEntryCounter;
|
||||
console.log('🔧 생성된 작업 항목 div:', entryDiv);
|
||||
|
||||
|
||||
entryDiv.innerHTML = `
|
||||
<div class="work-entry-header">
|
||||
<div class="work-entry-title">작업 항목 #${workEntryCounter}</div>
|
||||
@@ -414,12 +415,12 @@ function addWorkEntry() {
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
container.appendChild(entryDiv);
|
||||
console.log('🔧 작업 항목이 컨테이너에 추가됨');
|
||||
console.log('🔧 현재 컨테이너 내용:', container.innerHTML.length, '문자');
|
||||
console.log('🔧 현재 .work-entry 개수:', container.querySelectorAll('.work-entry').length);
|
||||
|
||||
|
||||
setupWorkEntryEvents(entryDiv);
|
||||
console.log('🔧 이벤트 설정 완료');
|
||||
}
|
||||
@@ -430,7 +431,7 @@ function setupWorkEntryEvents(entryDiv) {
|
||||
const workStatusSelect = entryDiv.querySelector('.work-status-select');
|
||||
const errorTypeSection = entryDiv.querySelector('.error-type-section');
|
||||
const errorTypeSelect = entryDiv.querySelector('.error-type-select');
|
||||
|
||||
|
||||
// 시간 입력 이벤트
|
||||
timeInput.addEventListener('input', updateTotalHours);
|
||||
|
||||
@@ -440,7 +441,7 @@ function setupWorkEntryEvents(entryDiv) {
|
||||
e.preventDefault();
|
||||
timeInput.value = btn.dataset.hours;
|
||||
updateTotalHours();
|
||||
|
||||
|
||||
// 버튼 클릭 효과
|
||||
btn.style.transform = 'scale(0.95)';
|
||||
setTimeout(() => {
|
||||
@@ -452,11 +453,11 @@ function setupWorkEntryEvents(entryDiv) {
|
||||
// 업무 상태 변경 시 에러 유형 섹션 토글
|
||||
workStatusSelect.addEventListener('change', (e) => {
|
||||
const isError = e.target.value === '2'; // 에러 상태 ID가 2라고 가정
|
||||
|
||||
|
||||
if (isError) {
|
||||
errorTypeSection.classList.add('visible');
|
||||
errorTypeSelect.required = true;
|
||||
|
||||
|
||||
// 에러 상태일 때 시각적 피드백
|
||||
errorTypeSection.style.animation = 'slideDown 0.4s ease-out';
|
||||
} else {
|
||||
@@ -465,7 +466,7 @@ function setupWorkEntryEvents(entryDiv) {
|
||||
errorTypeSelect.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 폼 필드 포커스 효과
|
||||
entryDiv.querySelectorAll('.form-field-group').forEach(group => {
|
||||
const input = group.querySelector('select, input');
|
||||
@@ -473,7 +474,7 @@ function setupWorkEntryEvents(entryDiv) {
|
||||
input.addEventListener('focus', () => {
|
||||
group.classList.add('focused');
|
||||
});
|
||||
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
group.classList.remove('focused');
|
||||
});
|
||||
@@ -499,15 +500,15 @@ function removeWorkEntry(id) {
|
||||
function updateTotalHours() {
|
||||
const timeInputs = document.querySelectorAll('.time-input');
|
||||
let total = 0;
|
||||
|
||||
|
||||
timeInputs.forEach(input => {
|
||||
const value = parseFloat(input.value) || 0;
|
||||
total += value;
|
||||
});
|
||||
|
||||
|
||||
const display = document.getElementById('totalHoursDisplay');
|
||||
display.textContent = `총 작업시간: ${total}시간`;
|
||||
|
||||
|
||||
if (total > 24) {
|
||||
display.style.background = 'linear-gradient(135deg, #e74c3c 0%, #c0392b 100%)';
|
||||
display.textContent += ' ⚠️ 24시간 초과';
|
||||
@@ -532,7 +533,7 @@ async function saveWorkReport() {
|
||||
const entries = document.querySelectorAll('.work-entry');
|
||||
console.log('🔍 찾은 작업 항목들:', entries);
|
||||
console.log('🔍 작업 항목 개수:', entries.length);
|
||||
|
||||
|
||||
if (entries.length === 0) {
|
||||
showSaveResultModal(
|
||||
'error',
|
||||
@@ -544,16 +545,16 @@ async function saveWorkReport() {
|
||||
|
||||
const newWorkEntries = [];
|
||||
console.log('🔍 작업 항목 수집 시작...');
|
||||
|
||||
|
||||
for (const entry of entries) {
|
||||
console.log('🔍 작업 항목 처리 중:', entry);
|
||||
|
||||
|
||||
const projectSelect = entry.querySelector('.project-select');
|
||||
const workTypeSelect = entry.querySelector('.work-type-select');
|
||||
const workStatusSelect = entry.querySelector('.work-status-select');
|
||||
const errorTypeSelect = entry.querySelector('.error-type-select');
|
||||
const timeInput = entry.querySelector('.time-input');
|
||||
|
||||
|
||||
console.log('🔍 선택된 요소들:', {
|
||||
projectSelect,
|
||||
workTypeSelect,
|
||||
@@ -561,13 +562,13 @@ async function saveWorkReport() {
|
||||
errorTypeSelect,
|
||||
timeInput
|
||||
});
|
||||
|
||||
|
||||
const projectId = projectSelect?.value;
|
||||
const workTypeId = workTypeSelect?.value;
|
||||
const workStatusId = workStatusSelect?.value;
|
||||
const errorTypeId = errorTypeSelect?.value;
|
||||
const workHours = timeInput?.value;
|
||||
|
||||
|
||||
console.log('🔍 수집된 값들:', {
|
||||
projectId,
|
||||
workTypeId,
|
||||
@@ -575,7 +576,7 @@ async function saveWorkReport() {
|
||||
errorTypeId,
|
||||
workHours
|
||||
});
|
||||
|
||||
|
||||
if (!projectId || !workTypeId || !workStatusId || !workHours) {
|
||||
showSaveResultModal(
|
||||
'error',
|
||||
@@ -593,7 +594,7 @@ async function saveWorkReport() {
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const workEntry = {
|
||||
project_id: parseInt(projectId),
|
||||
work_type_id: parseInt(workTypeId),
|
||||
@@ -601,18 +602,18 @@ async function saveWorkReport() {
|
||||
error_type_id: errorTypeId ? parseInt(errorTypeId) : null,
|
||||
work_hours: parseFloat(workHours)
|
||||
};
|
||||
|
||||
console.log('🔍 생성된 작업 항목:', workEntry);
|
||||
console.log('🔍 작업 항목 상세:', {
|
||||
project_id: workEntry.project_id,
|
||||
work_type_id: workEntry.work_type_id,
|
||||
work_status_id: workEntry.work_status_id,
|
||||
error_type_id: workEntry.error_type_id,
|
||||
work_hours: workEntry.work_hours
|
||||
});
|
||||
newWorkEntries.push(workEntry);
|
||||
|
||||
console.log('🔍 생성된 작업 항목:', workEntry);
|
||||
console.log('🔍 작업 항목 상세:', {
|
||||
project_id: workEntry.project_id,
|
||||
work_type_id: workEntry.work_type_id,
|
||||
work_status_id: workEntry.work_status_id,
|
||||
error_type_id: workEntry.error_type_id,
|
||||
work_hours: workEntry.work_hours
|
||||
});
|
||||
newWorkEntries.push(workEntry);
|
||||
}
|
||||
|
||||
|
||||
console.log('🔍 최종 수집된 작업 항목들:', newWorkEntries);
|
||||
console.log('🔍 총 작업 항목 개수:', newWorkEntries.length);
|
||||
|
||||
@@ -628,7 +629,7 @@ async function saveWorkReport() {
|
||||
|
||||
for (const workerId of selectedWorkers) {
|
||||
const workerName = workers.find(w => w.worker_id == workerId)?.worker_name || '알 수 없음';
|
||||
|
||||
|
||||
// 서버가 기대하는 work_entries 배열 형태로 전송
|
||||
const requestData = {
|
||||
report_date: reportDate,
|
||||
@@ -656,11 +657,11 @@ async function saveWorkReport() {
|
||||
} catch (error) {
|
||||
console.error('❌ 저장 실패:', error);
|
||||
totalFailed++;
|
||||
|
||||
|
||||
failureDetails.push(`${workerName}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 결과 모달 표시
|
||||
if (totalSaved > 0 && totalFailed === 0) {
|
||||
showSaveResultModal(
|
||||
@@ -683,14 +684,14 @@ async function saveWorkReport() {
|
||||
failureDetails
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (totalSaved > 0) {
|
||||
setTimeout(() => {
|
||||
refreshTodayWorkers();
|
||||
resetForm();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('저장 오류:', error);
|
||||
showSaveResultModal(
|
||||
@@ -709,18 +710,18 @@ async function saveWorkReport() {
|
||||
// 폼 초기화
|
||||
function resetForm() {
|
||||
goToStep(1);
|
||||
|
||||
|
||||
selectedWorkers.clear();
|
||||
document.querySelectorAll('.worker-card.selected').forEach(btn => {
|
||||
btn.classList.remove('selected');
|
||||
});
|
||||
|
||||
|
||||
const container = document.getElementById('workEntriesList');
|
||||
container.innerHTML = '';
|
||||
|
||||
|
||||
workEntryCounter = 0;
|
||||
updateTotalHours();
|
||||
|
||||
|
||||
document.getElementById('nextStep2').disabled = true;
|
||||
}
|
||||
|
||||
@@ -728,19 +729,19 @@ function resetForm() {
|
||||
async function loadTodayWorkers() {
|
||||
const section = document.getElementById('dailyWorkersSection');
|
||||
const content = document.getElementById('dailyWorkersContent');
|
||||
|
||||
|
||||
if (!section || !content) {
|
||||
console.log('당일 현황 섹션이 HTML에 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const today = getKoreaToday();
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
|
||||
content.innerHTML = '<div class="loading-spinner">📊 내가 입력한 오늘의 작업 현황을 불러오는 중... (통합 API)</div>';
|
||||
section.style.display = 'block';
|
||||
|
||||
|
||||
// 본인이 입력한 데이터만 조회 (통합 API 사용)
|
||||
let queryParams = `date=${today}`;
|
||||
if (currentUser?.user_id) {
|
||||
@@ -748,21 +749,21 @@ async function loadTodayWorkers() {
|
||||
} else if (currentUser?.id) {
|
||||
queryParams += `&created_by=${currentUser.id}`;
|
||||
}
|
||||
|
||||
|
||||
console.log(`🔒 본인 입력분만 조회 (통합 API): ${API}/daily-work-reports?${queryParams}`);
|
||||
|
||||
|
||||
const rawData = await window.apiCall(`${window.API}/daily-work-reports?${queryParams}`);
|
||||
console.log('📊 당일 작업 데이터 (통합 API):', rawData);
|
||||
|
||||
|
||||
let data = [];
|
||||
if (Array.isArray(rawData)) {
|
||||
data = rawData;
|
||||
} else if (rawData?.data) {
|
||||
data = rawData.data;
|
||||
}
|
||||
|
||||
|
||||
displayMyDailyWorkers(data, today);
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('당일 작업자 로드 오류:', error);
|
||||
content.innerHTML = `
|
||||
@@ -777,7 +778,7 @@ async function loadTodayWorkers() {
|
||||
// 본인 입력 작업자 현황 표시 (수정/삭제 기능 포함)
|
||||
function displayMyDailyWorkers(data, date) {
|
||||
const content = document.getElementById('dailyWorkersContent');
|
||||
|
||||
|
||||
if (!Array.isArray(data) || data.length === 0) {
|
||||
content.innerHTML = `
|
||||
<div class="no-data-message">
|
||||
@@ -787,7 +788,7 @@ function displayMyDailyWorkers(data, date) {
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 작업자별로 데이터 그룹화
|
||||
const workerGroups = {};
|
||||
data.forEach(work => {
|
||||
@@ -797,10 +798,10 @@ function displayMyDailyWorkers(data, date) {
|
||||
}
|
||||
workerGroups[workerName].push(work);
|
||||
});
|
||||
|
||||
|
||||
const totalWorkers = Object.keys(workerGroups).length;
|
||||
const totalWorks = data.length;
|
||||
|
||||
|
||||
const headerHtml = `
|
||||
<div class="daily-workers-header">
|
||||
<h4>📊 내가 입력한 오늘(${date}) 작업 현황 - 총 ${totalWorkers}명, ${totalWorks}개 작업</h4>
|
||||
@@ -809,12 +810,12 @@ function displayMyDailyWorkers(data, date) {
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
const workersHtml = Object.entries(workerGroups).map(([workerName, works]) => {
|
||||
const totalHours = works.reduce((sum, work) => {
|
||||
return sum + parseFloat(work.work_hours || 0);
|
||||
}, 0);
|
||||
|
||||
|
||||
// 개별 작업 항목들 (수정/삭제 버튼 포함)
|
||||
const individualWorksHtml = works.map((work) => {
|
||||
const projectName = work.project_name || '미지정';
|
||||
@@ -823,7 +824,7 @@ function displayMyDailyWorkers(data, date) {
|
||||
const workHours = work.work_hours || 0;
|
||||
const errorTypeName = work.error_type_name || null;
|
||||
const workId = work.id;
|
||||
|
||||
|
||||
return `
|
||||
<div class="individual-work-item">
|
||||
<div class="work-details-grid">
|
||||
@@ -861,7 +862,7 @@ function displayMyDailyWorkers(data, date) {
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
|
||||
return `
|
||||
<div class="worker-status-item">
|
||||
<div class="worker-header">
|
||||
@@ -874,7 +875,7 @@ function displayMyDailyWorkers(data, date) {
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
|
||||
content.innerHTML = headerHtml + '<div class="worker-status-grid">' + workersHtml + '</div>';
|
||||
}
|
||||
|
||||
@@ -882,17 +883,17 @@ function displayMyDailyWorkers(data, date) {
|
||||
async function editWorkItem(workId) {
|
||||
try {
|
||||
console.log('수정할 작업 ID:', workId);
|
||||
|
||||
|
||||
// 1. 기존 데이터 조회 (통합 API 사용)
|
||||
showMessage('작업 정보를 불러오는 중... (통합 API)', 'loading');
|
||||
|
||||
|
||||
const workData = await window.apiCall(`${window.API}/daily-work-reports/${workId}`);
|
||||
console.log('수정할 작업 데이터 (통합 API):', workData);
|
||||
|
||||
|
||||
// 2. 수정 모달 표시
|
||||
showEditModal(workData);
|
||||
hideMessage();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('작업 정보 조회 오류:', error);
|
||||
showMessage('작업 정보를 불러올 수 없습니다: ' + error.message, 'error');
|
||||
@@ -902,7 +903,7 @@ async function editWorkItem(workId) {
|
||||
// 수정 모달 표시
|
||||
function showEditModal(workData) {
|
||||
editingWorkId = workData.id;
|
||||
|
||||
|
||||
const modalHtml = `
|
||||
<div class="edit-modal" id="editModal">
|
||||
<div class="edit-modal-content">
|
||||
@@ -973,9 +974,9 @@ function showEditModal(workData) {
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', modalHtml);
|
||||
|
||||
|
||||
// 업무 상태 변경 이벤트
|
||||
document.getElementById('editWorkStatus').addEventListener('change', (e) => {
|
||||
const errorTypeGroup = document.getElementById('editErrorTypeGroup');
|
||||
@@ -1004,17 +1005,17 @@ async function saveEditedWork() {
|
||||
const workStatusId = document.getElementById('editWorkStatus').value;
|
||||
const errorTypeId = document.getElementById('editErrorType').value;
|
||||
const workHours = document.getElementById('editWorkHours').value;
|
||||
|
||||
|
||||
if (!projectId || !workTypeId || !workStatusId || !workHours) {
|
||||
showMessage('모든 필수 항목을 입력해주세요.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (workStatusId === '2' && !errorTypeId) {
|
||||
showMessage('에러 상태인 경우 에러 유형을 선택해주세요.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const updateData = {
|
||||
project_id: parseInt(projectId),
|
||||
work_type_id: parseInt(workTypeId),
|
||||
@@ -1022,20 +1023,20 @@ async function saveEditedWork() {
|
||||
error_type_id: errorTypeId ? parseInt(errorTypeId) : null,
|
||||
work_hours: parseFloat(workHours)
|
||||
};
|
||||
|
||||
|
||||
showMessage('작업을 수정하는 중... (통합 API)', 'loading');
|
||||
|
||||
|
||||
const result = await window.apiCall(`${window.API}/daily-work-reports/${editingWorkId}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(updateData)
|
||||
});
|
||||
|
||||
|
||||
console.log('✅ 수정 성공 (통합 API):', result);
|
||||
showMessage('✅ 작업이 성공적으로 수정되었습니다!', 'success');
|
||||
|
||||
|
||||
closeEditModal();
|
||||
refreshTodayWorkers();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 수정 실패:', error);
|
||||
showMessage('수정 중 오류가 발생했습니다: ' + error.message, 'error');
|
||||
@@ -1047,23 +1048,23 @@ async function deleteWorkItem(workId) {
|
||||
if (!confirm('정말로 이 작업을 삭제하시겠습니까?\n삭제된 작업은 복구할 수 없습니다.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
console.log('삭제할 작업 ID:', workId);
|
||||
|
||||
|
||||
showMessage('작업을 삭제하는 중... (통합 API)', 'loading');
|
||||
|
||||
|
||||
// 개별 항목 삭제 API 호출 (본인 작성분만 삭제 가능) - 통합 API 사용
|
||||
const result = await window.apiCall(`${window.API}/daily-work-reports/my-entry/${workId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
|
||||
console.log('✅ 삭제 성공 (통합 API):', result);
|
||||
showMessage('✅ 작업이 성공적으로 삭제되었습니다!', 'success');
|
||||
|
||||
|
||||
// 화면 새로고침
|
||||
refreshTodayWorkers();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 삭제 실패:', error);
|
||||
showMessage('삭제 중 오류가 발생했습니다: ' + error.message, 'error');
|
||||
@@ -1117,9 +1118,9 @@ async function init() {
|
||||
await loadData();
|
||||
setupEventListeners();
|
||||
loadTodayWorkers();
|
||||
|
||||
|
||||
console.log('✅ 시스템 초기화 완료 (통합 API 설정 적용)');
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('초기화 오류:', error);
|
||||
showMessage('초기화 중 오류가 발생했습니다.', 'error');
|
||||
|
||||
Reference in New Issue
Block a user