Files
PM_test/views/main/jsm/overview/overviewDataManager.js
2026-06-12 17:14:03 +09:00

454 lines
22 KiB
JavaScript

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 저장, 삭제 끝 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼