454 lines
22 KiB
JavaScript
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 저장, 삭제 끝 🔼🔼🔼🔼🔼🔼🔼🔼🔼🔼
|