import { vars } from '../archive/variable.js'; import { checkProjectInactive } from '../main.js'; import { drawList, generateCalendar, startTimer, updateTimeBar, makeTaskHistory } from './overviewPageRenderer.js'; import { fileDragAndDrop } from './overviewModalManager.js'; import { addJointContractDelimiter, restrictDuplicatedTabName, uploadImgData, setIssueEditMode, generateDeleteImgUrl, setOverviewType } from './overviewCommon.js'; import { headerBtnForceClick, closeInitProgress } from '../archive/common.js'; import { overviewVars } from './overviewVariable.js'; // overviewDataManager.js는 db 통신처럼 데이터가 실질적으로 저장되고 삭제되는 함수 및 dom 조작을 모아놓은 js이다. // getData는 tb_overview에 데이터를 가져와서 데이터를 함수들에게 뿌려주는 역할을 한다. export async function getData() { if (checkProjectInactive()) return; try { const res = await axios.get(`/${vars.project_id}/overview/getData`, { params: { projectId: vars.project_id }, }); if (res.data.success) { const data = res.data.data; await setOverviewType(); await drawList(data); //위치도 개요도 드래그앤 드롭 fileDragAndDrop(); // 현재 날짜로 달력 생성 generateCalendar(overviewVars.currentYear, overviewVars.currentMonth); // 교류시간 동작 if(overviewVars.overseas)startTimer(data[0]?.nation_nm); //////// pm-bcmf 연결용 테스트 코드 - 파라미터로 전달받은 시작경로로 화면 전환 (depth1) if (vars.startPathDepth1) { let headerBtn = document.querySelector(`body > .header .center .left.wrap .menu-tab .btn[data-resource-path="/${vars.startPathDepth1}"]`); if (headerBtn) await headerBtnForceClick(headerBtn); } // 과업개요 생성 후 if (!vars.startPathDepth1 && !vars.startPathDepth2 && !vars.startPathDepth3) { // // 시작경로가 없으면 초기 프로그레스 종료 // console.log('******** 과업개요 렌더링 후 초기 프로그레스 종료 (시작경로 없음)'); await closeInitProgress(); } else { if (document.querySelectorAll('body > .header .center .menu-tab .folder-btn').length == 0) { // // 시작경로가 있는데 헤더폴더버튼이 없으면 초기 프로그레스 종료 // console.log('******** 과업개요 렌더링 후 초기 프로그레스 종료 (시작경로 있음, 헤더폴더버튼 없음)'); await closeInitProgress(); } else { if (JSON.parse(vars.userInfoString).user_id.includes('bcmf-') && vars.project_id == 'dsdj2') { // 시작경로, 헤더폴더버튼이 있고 현재 계정이 bcmf계정이고 현재 프로젝트가 대산당진2공구인 경우 과업개요 숨김 document.querySelector('.overview-main').style.display = 'none'; } else { // 시작경로, 헤더폴더버튼이 있고 현재 계정이 bcmf계정이 아니거나 현재 프로젝트가 대산당진2공구가 아닌 경우 과업개요 숨김 // console.log('******** 과업개요 렌더링 후 초기 프로그레스 종료 (현재 계정이 bcmf계정이 아니거나 현재 프로젝트가 대산당진2공구가 아님)'); // console.log(`현재 계정: ${JSON.parse(vars.userInfoString).user_id}`); // console.log(`현재 프로젝트: ${vars.project_id}`); closeInitProgress(); } } } } else { console.error("getData error"); } } catch (error) { console.error("getData error", error); } } //🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 Section-Left 저장 시작 🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 // Section-left 저장 document.querySelector('.overview-modal.section-left .section-left-save')?.addEventListener('click', async () => { const modal = document.querySelector('.overview-modal.section-left'); const modalWrapper = document.querySelector('.overview-modal-wrapper'); // // 시설규모 탭 제목만 입력 후 저장할때 경고문 // for(const key in overviewVars.sectionTabData){ // if (overviewVars.sectionTabData[key].length === 0) return alert('시설규모 탭에 입력되지 않은 항목이 있습니다. 작성 후 저장해 주세요.'); // } // // 중복된 탭 이름 사용하지 못하게 // const duplicatedTabName = restrictDuplicatedTabName(); // if(!duplicatedTabName) return; let locationImgKey; let originFileSize; try{ // 이미지 파일 업로드 for(let i = 0; overviewVars.filesArr.length > i; i++){ await uploadImgData(overviewVars.filesArr[i], overviewVars.filesArr.type); } // 이미지 파일 objectKey 형식으로 변환 for(let j = 0; overviewVars.filesNameArr.length > j; j++){ if(!overviewVars.filesNameArr[j].includes('overview/')) overviewVars.filesNameArr[j] = 'overview/'+ overviewVars.filesNameArr[j]; } // JSON 문자화 시킨다음에 db에 삽입 locationImgKey = JSON.stringify(overviewVars.filesNameArr); originFileSize = JSON.stringify(overviewVars.filesSizeArr); // 파일 사이즈가 빈 배열일때 기본값 설정 if(originFileSize === '[]') originFileSize = '[0]'; } catch (err) { console.error(err); } if(overviewVars.deleteImgArr.length > 0){ for(let i = 0; overviewVars.deleteImgArr.length > i; i++){ await generateDeleteImgUrl(overviewVars.deleteImgArr[i]); } await axios.post(`/${vars.project_id}/overview/updateOverviewImgData`, { projectId: vars.project_id, locationImgKey : locationImgKey, originFileSize : originFileSize }); } const projectId = vars.project_id; const businessPurpose = modal.querySelector('.business-purpose').value; const performanceArea = modal.querySelector('.performance-area').value; const referenceArea = modal.querySelector('.reference-area').value; const facilityOverview = modal.querySelector('.facility-overview').value; let data = {projectId, businessPurpose, performanceArea, referenceArea, facilityOverview, originFileSize, locationImgKey }; //overseas용 분기 if(!overviewVars.overseas){ data.nation = modal.querySelector('.nation').value; data.continent = modal.querySelector('.continent').value; } else { data.nation = modal.querySelector('.nation').innerText; data.continent = modal.querySelector('.continent').innerText; } // minIO에 저장, DB 저장이 완료되면 minIO에 기존에 있던 사진을 삭제 try { const res = await axios.post(`/${projectId}/overview/saveSectionLeftData`, data); if (res.data.message === '200') { try{ // 탭만 입력했을때 기본값 세팅 for (const title in overviewVars.sectionTabData) { if (!overviewVars.sectionTabData[title] || overviewVars.sectionTabData[title].length === 0) { // 기본값 세팅 overviewVars.sectionTabData[title] = [ { key: '', value: '', id: null, projectId } ]; } } await upsertSectionTabData(); const secondRes = await axios.post(`/${projectId}/overview/saveSectionLeftTabData`, overviewVars.sectionTabData); if (secondRes.data.message === '200') overviewVars.sectionTabData = {}; } catch(err){ console.error(err, 'sectionLeftTabData 저장 오류') } alert('저장이 완료되었습니다.'); modal.style.display = 'none'; modalWrapper.style.display = 'none'; getData(); updateTimeBar(); } else { alert('파일 저장에 실패하였습니다.'); } }catch(err){ console.error('S3 이미지 삭제 오류 : ' , err); } }); async function upsertSectionTabData() { const deleteArr = []; // 섹션별 비교 for (let sectionName in overviewVars.originalSectionTabData) { const originalArr = overviewVars.originalSectionTabData[sectionName]; const currentArr = overviewVars.sectionTabData[sectionName] || []; // currentArr에 없는 항목만 삭제 대상으로 const toDelete = originalArr.filter(item => { return !currentArr.some(c => c.id === item.id); }); if (toDelete.length > 0) { deleteArr.push(...toDelete); } } // 삭제 API 호출 try { const deleteRes = await axios.delete(`/${vars.project_id}/overview/deleteCellData`, { data: { deleteArr: deleteArr }}); if(deleteRes.data.message === 200)console.log('overviewSectionLeftCellData 삭제 완료'); } catch (err) { console.error('삭제 실패', cell.id, err); } } // 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼 Section-Left 저장 끝 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼 //🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 Section-Middle 저장, 삭제 시작 🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 // section-middle 저장 document.querySelector('.overview-modal.section-middle .btn-active')?.addEventListener('click', async () => { const modal = document.querySelector('.overview-modal.section-middle'); const modalWrapper = document.querySelector('.overview-modal-wrapper'); const projectId = vars.project_id; const abbreviatedName = modal.querySelector('.abbreviated-name').value; const taskNmEn = modal.querySelector('.task-nm-en').value; const taskPurpose = modal.querySelector('.task-purpose').value; const orderSizeUsd = modal.querySelector('.order-size-usd').value; const orderSizeKrw = modal.querySelector('.order-size-krw').value; const clientOrigin = modal.querySelector('.client-origin').value; const financial = modal.querySelector('.financial').value; const financialCountry = modal.querySelector('.financial-country').value; const selectionMethod = modal.querySelector('.selection-method').value; const supportDepartment = modal.querySelector('.support-department').value; const supportManagerNm = modal.querySelector('.support-manager-nm').value; const completionDate = modal.querySelector('.completion-date').value; let data = {projectId, abbreviatedName, taskNmEn, taskPurpose, orderSizeUsd, orderSizeKrw, clientOrigin, financial, financialCountry, selectionMethod, supportDepartment, supportManagerNm, completionDate}; // overseas용 분기 if(!overviewVars.overseas){ data.projectNo = modal.querySelector('.project-no').value data.taskType = modal.querySelector('.task-type').value data.bid = modal.querySelector('.bid').value data.relativeClient = modal.querySelector('.client').value data.department = modal.querySelector('.department').value data.taskNmKr = modal.querySelector('.task-nm-kr').value; data.scheduledCommencementDate = modal.querySelector('.scheuled-commencement-date').value; data.contractPeriod = modal.querySelector('.contract-period').value; data.projectManagerNm = modal.querySelector('.projectmanager-nm').value; data.managerNm = modal.querySelector('.manager-nm').value; data.contractDate = modal.querySelector('.contract-date').value; data.commencementDate = modal.querySelector('.commencement-date').value; data.originalCompletionDate = modal.querySelector('.scheduled-completion-date').value; // 공동도급 데이터 DB 삽입을 위한 식별자(^&)추가 const jointContract = addJointContractDelimiter(); data.jointContractComapnyName = jointContract.companyName; data.jointContractShares = jointContract.companyShares; data.jointContractKrw = jointContract.contractKrw; data.jointContractUsd = jointContract.contractUsd; data.representativeCompany = jointContract.representativeCompany; } else { data.projectNo = modal.querySelector('.project-no').innerText; data.taskType = modal.querySelector('.task-type').innerText; data.bid = modal.querySelector('.bid').innerText; data.relativeClient = modal.querySelector('.client').innerText; data.department = modal.querySelector('.department').innerText; data.taskNmKr = modal.querySelector('.task-nm-kr').innerText; data.scheduledCommencementDate = modal.querySelector('.scheuled-commencement-date').innerText; data.contractPeriod = modal.querySelector('.contract-period').innerText.replace('개월', ''); data.projectManagerNm = modal.querySelector('.projectmanager-nm').innerText; data.managerNm = modal.querySelector('.manager-nm').innerText; data.contractDate = modal.querySelector('.contract-date').innerText.replaceAll('-', ''); data.commencementDate = modal.querySelector('.commencement-date').innerText.replaceAll('-', ''); data.originalCompletionDate = modal.querySelector('.scheduled-completion-date').innerText.replaceAll('-', ''); // 공동도급 데이터 DB 삽입을 위한 식별자(^&)추가 const jointContract = addJointContractDelimiter(); data.jointContractComapnyName = jointContract.companyName; data.jointContractShares = jointContract.companyShares; data.jointContractKrw = jointContract.contractKrw; data.jointContractUsd = jointContract.contractUsd; data.representativeCompany = jointContract.representativeCompany; } try { const res = await axios.post(`/${projectId}/overview/saveSectionMiddleData`, data); if (res.data.message = '200') { alert('저장이 완료되었습니다.'); modal.style.display = 'none'; modalWrapper.style.display = 'none'; getData(); updateTimeBar(); } else { alert('오류가 발생하였습니다.'); } } catch (err) { console.log(err); } }); // Section-Middle - 과업중지 이력 저장 document.querySelector('.overview-modal.task-period .modal-footer .btn-active')?.addEventListener('click', async () => { const liList = document.querySelectorAll('.overview-modal.task-period .overview-modal-body ul li input'); const modal = document.querySelector('.overview-modal.task-period'); const modalWrapper = document.querySelector('.overview-modal-wrapper'); const saveLiArr = []; if(overviewVars.deleteTaskHistory.length > 0)await deleteTaskHistory(); for (let i = 0; i < liList.length; i += 6) { // 과업중지이력의 Value가 전부 미입력 상태일때는 저장하지 않는다. const values = [liList[i].value, liList[i+1].value, liList[i+2].value, liList[i+3].value, liList[i+4].value, liList[i+5].value]; if(values.every(value => value === ''))continue; saveLiArr.push({ projectId: vars.project_id, order: liList[i].value, suspensionDate: liList[i + 1].value, suspensionReason: liList[i + 2].value, resumptionDate: liList[i + 3].value, consultationContent: liList[i + 4].value, changeDate: liList[i + 5].value }); } try { const res = await axios.post(`/${vars.project_id}/overview/saveTaskHistoryData`, saveLiArr); if (res.data.message === '200') { alert('과업중지 이력이 저장되었습니다.'); makeTaskHistory(); modal.style.display = 'none'; modalWrapper.style.display = 'none'; } } catch (err) { alert('과업중지 이력 저장에 실패하였습니다.'); } }); export async function deleteTaskHistory() { if(overviewVars.deleteTaskHistory.length > 0){ try{ const res = await axios.delete(`/${vars.project_id}/overview/deleteTaskPeriodData`, { data: { deleteArr : overviewVars.deleteTaskHistory } }); if(res.data.message === '200') overviewVars.deleteTaskHistory = []; } catch(err) { console.error(err, '과업중지이력 삭제 실패'); } } } // 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼 Section-Middle 저장, 삭제 끝 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼 //🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 Section-Right 저장, 삭제 시작 🔽🔽🔽🔽🔽🔽🔽🔽🔽🔽 // Section-Right calendar 주요일정 저장 document.querySelector('.overview-modal.schedule .schedule-save')?.addEventListener('click', async () => { const modal = document.querySelector('.overview-modal.schedule'); const modalWrapper = document.querySelector('.overview-modal-wrapper'); const projectId = vars.project_id; const country = document.querySelector('.overview-modal.schedule input[type=radio]:checked').value; const color = document.querySelector('.overview-modal .color .label-color.on').dataset.color; const title = document.querySelector('.overview-modal.schedule .schedule-title').value; const content = document.querySelector('.overview-modal.schedule .schedule-content').value; const startDate = document.querySelector('.overview-modal.schedule .startDate').value; const startTime = document.querySelector('.overview-modal.schedule .startTime').value; const endDate = document.querySelector('.overview-modal.schedule .endDate').value; const endTime = document.querySelector('.overview-modal.schedule .endTime').value; const scheduleId = document.querySelector('.overview-modal.schedule').dataset.scheduleId; if (!title) return alert('일정의 제목을 입력해주세요.') // 주요일정 하루종일 기능 const alldayChecked = document.querySelector('.overview-modal.schedule .custom-checkbox.all-day input').checked; const startDateTimeStr = `${startDate}T${startTime}`; const endDateTimeStr = `${endDate}T${endTime}`; if(alldayChecked === true){ //날짜 유효성 검증 const startDay = new Date(startDate); const endDay = new Date(endDate); if(startDay > endDay) return alert('시작일은 종료일보다 늦을 수 없습니다. 다시 설정해주십시오.'); } else { //날짜 + 시간 유효성 검증 const startDateTime = new Date(startDateTimeStr); const endDateTime = new Date(endDateTimeStr); if (startDateTime > endDateTime)return alert('시작일은 종료일보다 늦을 수 없습니다. 다시 설정해주십시오.'); } let data = { scheduleId, projectId, country, color, title, content, startDateTimeStr, endDateTimeStr } // 기존일정 id 삽입 if (scheduleId !== '') data.scheduleId = scheduleId; try { const res = await axios.post(`/${projectId}/overview/saveScheduleData`, data); if (res.data.message == '200') { modal.style.display = 'none'; modalWrapper.style.display = 'none'; alert('일정 저장이 완료되었습니다.'); generateCalendar(overviewVars.currentYear, overviewVars.currentMonth); } } catch (err) { console.log(err); } }); // Section-Right calendar 주요일정 삭제 document.querySelector('.overview-modal.schedule .schedule-delete')?.addEventListener('click', async () => { if (confirm('일정을 삭제하시겠습니까?')) { const modal = document.querySelector('.overview-modal.schedule'); const modalWrapper = document.querySelector('.overview-modal-wrapper'); const scheduleId = document.querySelector('.overview-modal.schedule').dataset.scheduleId; const res = await axios.delete(`/${vars.project_id}/overview/deleteScheduleData`, { data: { scheduleId } }); if (res.data.message = '200') { alert('일정이 삭제되었습니다.'); modal.style.display = 'none'; modalWrapper.style.display = 'none'; generateCalendar(overviewVars.currentYear, overviewVars.currentMonth); } else { alert('삭제에 실패하였습니다.') } } }); // 주요 현안 및 이슈 document.querySelector('.overview .xs-btn-type.issue-edit')?.addEventListener('click', () => { setIssueEditMode(true) }); // 메모 입력시 내용의 길이에 따라 document.querySelector('.overview .box.issue .wrap .issue-content')?.addEventListener('input', () => { const issueMessage = document.querySelector('.overview .box.issue .wrap .message') const issueContent = document.querySelector('.overview .box.issue .wrap .issue-content'); if(issueContent.value.length > 0){ issueMessage.style.color = '#ddd'; } else { issueMessage.style.color = '#111'; } }); document.querySelector('.overview .xs-btn-type.issue-save')?.addEventListener('click', async () => { const projectId = vars.project_id; const issueContent = document.querySelector('.overview .box.issue .wrap .issue-content'); const issueData = issueContent.value; let data = {projectId, issueData} try{ const result = await axios.post(`/${projectId}/overview/saveIssueData`, data); if(result.data.message === '200'){ alert('주요 현안 및 이슈 저장 성공'); setIssueEditMode(false) overviewVars.issueData = issueData; } } catch (err) { console.error(err) } }); document.querySelector('.overview .xs-btn-type.issue-cancle')?.addEventListener('click', () => { const issueContent = document.querySelector('.overview .box.issue .wrap .issue-content'); issueContent.value = overviewVars.issueData; setIssueEditMode(false); }); // 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼 Section-Right 저장, 삭제 끝 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼