$(document).ready(function(){ //############################################################################################# //파일업로드 드래그앤 드롭 시작 //############################################################################################# var objDragAndDrop = $(".exel_upload_area"); $(document).on("dragenter",".exel_upload_area",function(e){ e.stopPropagation(); e.preventDefault(); }); $(document).on("dragover",".exel_upload_area",function(e){ e.stopPropagation(); e.preventDefault(); }); $(document).on("drop",".exel_upload_area",function(e){ fn_excelLoadAddActive(); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; excelFileChange(files[0]); }); $(document).on('dragenter', function (e){ e.stopPropagation(); e.preventDefault(); }); $(document).on('dragover', function (e){ e.stopPropagation(); e.preventDefault(); }); $(document).on('drop', function (e){ e.stopPropagation(); e.preventDefault(); }); //############################################################################################# //파일업로드 드래그앤 드롭 종료 //############################################################################################# //받는사람 전체삭제 버튼 처리 $('#allDel').click(function(){ var data = tableExcel.getRows(); tableExcel.clearData(); $("#excelRowTotCnt").text(0); //총건수 수정 $("#excelRowDupCnt").text(0); //중복건수 수정 dupliPhoneDataRealList.length = 0; // 중복 휴대폰번호 초기화 // select box 초기화 $('.field-selector').each(function() { $(this).val(''); }); }); //받는사람 선택삭제 버튼 처리해주기 $('#in_select_del').click(function(){ if(tableExcel == null || tableExcel == ""){ alert("받는사람을 추가해 주세요."); return false; } var selectedData = tableExcel.getSelectedRows(); if(selectedData == "" || selectedData == null){ alert("삭제할 연락처를 선택해주세요."); return false; }else{ // 선택한 Row 데이터 삭제하기 if(confirm("선택하신 받는 사람을 삭제하시겠습니까?")){ // 선택 데이터 삭제 selectedData.forEach(row => row.delete()); totRows = tableExcel.getRows().length; $("#excelRowTotCnt").text(totRows); } } }); $("#excelFile").on("change", function(event) { var fileInfo = event.target.files; if(fileInfo.length > 0){ excelFileChange(fileInfo[0]); } else { fn_excelLoadRemoveActive(); // 파일이 선택되지 않은 경우 로딩 상태 제거 setTimeout(() => { $(this).val(''); }, 0); // 파일 선택 초기화 } }); //타이틀 select 선택 이벤트 $('.field-selector').on('change', function() { fn_excelLoadAddActive(); setTimeout(() => { var selectedFields = []; var isDuplicate = false; if(tableExcel.getData().length < 1){ alert('데이터 입력 후 선택해 주세요.'); $(this).val(""); fn_excelLoadRemoveActive(); return false; } // 중복체크 $('.field-selector').each(function() { var selectedField = $(this).val(); if (selectedField) { if (selectedFields.includes(selectedField)) { alert("중복된 필드를 선택할 수 없습니다."); $(this).val(""); // 중복 필드를 선택한 경우 빈 값으로 초기화 isDuplicate = true; return false; // 반복문 종료 } selectedFields.push(selectedField); } }); updateTableFields(tableExcel); // 필드가 휴대폰이면 열 중복체크 if($(this).val() == 'addrFaxNo'){ fn_faxDupl(tableExcel); } fn_excelLoadRemoveActive(); }, 0); // 지연 없이 즉시 실행되도록 0ms 지연을 설정 }); // 추가버튼 $('#btnAddrMassReg').click(function(){ if(tableExcel.getData().length < 1){ alert("한 개 이상의 연락처를 입력하세요"); return false; } // tableExcel 그룹의 select 요소들을 확인 var columns = tableExcel.getColumns(); var isAddrFaxNoSelected = columns.some(column => column.getField() === 'addrFaxNo'); if (!isAddrFaxNoSelected) { alert('팩스번호가 선택되지 않았습니다.'); return false; } var addrData = tableExcel.getData().map((row, index) => ({ name: row.addrNm , phone: removeDash(row.addrFaxNo) })); // 기존 tableL의 데이터를 가져옵니다. var existingData = tableL.getData(); // 기존 데이터와 새로운 데이터를 합칩니다. var combinedData = existingData.concat(addrData); // 합쳐진 데이터를 tableL에 설정합니다. tableL.setData(combinedData); var totRows = 0; // 좌측 받는사람 총 갯수 totRows = tableL.getRows().length; updateTotCnt(totRows); //전체 데이터 갯수 구하기 setAddrMassClose(); $('.field-selector').each(function() { $(this).val(''); }); $('#closeBtn').click(); }); // 닫기버튼 $('#closeBtn').click(function(){ setAddrMassClose(); }); // 닫기버튼 $('#btnAddrMassClose').click(function(){ setAddrMassClose(); }); // excel 오류정보 테스트 $(document).on('click', '#errorExcelBtn', function() { if(tableError.getDataCount()<1){ alert('오류 정보가 없습니다.'); return false; } tableError.download("xlsx", "error_data.xlsx"); }); }); //팝업 텍스트 더보기 클릭 시 펼쳐지고 숨겨짐 function popMore(e){ $(e).closest(".pop_more_cont").toggleClass("pop_more_click"); if($(e).closest(".pop_more_cont").is(".pop_more_click")){ $(e).html('숨기기'); $(e).append(''); }else { $(e).html('더보기'); $(e).append(''); } } //엑셀등록 초기화 값 설정 function setAddrMassClose() { tableExcel.clearData(); $("#excelRowTotCnt").text(0); //총건수 수정 $("#excelRowDupCnt").text(0); //중복건수 수정 $("#excelRowErrorCnt").text(0); //중복건수 수정 dupliPhoneDataRealList.length = 0; // 중복 휴대폰번호 초기화 addrMassDupliSaveList = null; $('#excelFile').val(''); //첨부파일 값 초기화 // popup 영역 tableError.clearData(); $("#errorPopDupCnt").text(0); // 중복 카운트 $("#errorPopErrorCnt").text(0); // 에러 카운트 $("#errorPopTotCnt").text(0); $('.field-selector').each(function() { $(this).val(''); }); //select 선택란 초기화 } //엑셀파일 업로드 function excelFileChange(file) { if (file) { // 파일 크기 체크 (20MB) const maxSize = 20 * 1024 * 1024; // 20MB in bytes if (file.size > maxSize) { alert('파일 크기는 20MB를 초과할 수 없습니다.'); return; } fn_excelLoadAddActive(); var reader = new FileReader(); var extension = file.name.split('.').pop().toLowerCase(); reader.onload = function(e) { setTimeout(() => { // 파일 읽기 완료 후 실행되도록 함 if (extension === 'xlsx') { var data = new Uint8Array(e.target.result); var workbook = XLSX.read(data, {type: 'array'}); var firstSheet = workbook.Sheets[workbook.SheetNames[0]]; var jsonData = XLSX.utils.sheet_to_json(firstSheet, {header: 1}); findInvalidDBCharacters(jsonData); processExcelData(jsonData); } else if (extension === 'xls') { var data = e.target.result; var workbook = XLSX.read(data, { type: 'binary' }); var firstSheet = workbook.Sheets[workbook.SheetNames[0]]; var jsonData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 }); // 문제 데이터를 확인하는 함수 호출 findInvalidDBCharacters(jsonData); processExcelData(jsonData); } else if (extension === 'txt') { var textData = e.target.result; processTextData(textData); } else { alert('지원되지 않는 파일 형식입니다.'); } fn_excelLoadRemoveActive(); }, 0); // 지연 없이 즉시 실행되도록 0ms 지연을 설정 }; if (extension === 'xlsx') { reader.readAsArrayBuffer(file); } else if (extension === 'xls') { reader.readAsBinaryString(file); // xls 파일에 적절한 read 메서드 호출 } else if (extension === 'txt') { reader.readAsText(file); } } } //문제 데이터를 확인하는 함수 function findInvalidDBCharacters(jsonData) { console.log('DB 입력 값 검사 중...'); const invalidCharPattern = /[\uD800-\uDBFF][\uDC00-\uDFFF]/; // 4바이트 유니코드 문자 (이모지 등) for (let rowIndex = 0; rowIndex < jsonData.length; rowIndex++) { const row = jsonData[rowIndex]; if (Array.isArray(row)) { for (let colIndex = 0; colIndex < row.length; colIndex++) { const cell = row[colIndex]; if (typeof cell === 'string' && invalidCharPattern.test(cell)) { console.warn('허용되지 않는 문자: row', rowIndex + 1,', col ', colIndex + 1, ', value:', cell); // 허용되지 않는 문자를 제거 (선택 사항) row[colIndex] = cell.replace(invalidCharPattern, ''); console.log('수정된 값:', row[colIndex]); } } } } } //엑셀 데이터 처리 함수 function processExcelData(data) { var keys = ['A', 'B']; var tableData = []; data.slice(0).forEach((row, index) => { var rowData = {}; keys.forEach((key, idx) => { // index 변수명 변경 (내부와 외부에서 사용되므로 충돌 방지) rowData[key] = (typeof row[idx] === 'string') ? row[idx].trim() : row[idx]; }); tableData.push(rowData); }); updateTable(tableData); } //공통 테이블 업데이트 함수 function updateTable(tableData) { tableExcel.setColumns([ //Define Table Columns {formatter:"rowSelection", titleFormatter:"rowSelection",clipboard:false, headerHozAlign:"center", hozAlign:"center", width:10, headerSort:false, cellClick:function(e, cell){ cell.getRow().toggleSelect(); } } ,{formatter:"rownum", align:"center" ,title:"No", hozAlign:"center", headerHozAlign:"center", width:100} ,{title:"A", field:"A", hozAlign:"center", headerHozAlign: "center", width:400, validator:["maxLength:100", "string"]} ,{title:"B", field:"B", hozAlign:"center", headerHozAlign: "center", width:400, validator:["maxLength:100", "string"]} ]); // excelRowTotCnt 업데이트 tableExcel.setData(tableData).then(() => { document.getElementById("excelRowTotCnt").innerText = tableData.length; }); fn_excelLoadRemoveActive(); } /* * 타이틀 select 선택할때마다 실행해서 * 데이터테이블 필드값 수정 */ function updateTableFields(objTabul) { var currentData = objTabul.getData(); var columns = [ {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", width:10, headerSort: false, cellClick: function(e, cell) { cell.getRow().toggleSelect(); }} ,{formatter:"rownum", align:"center", title:"No", hozAlign:"center", headerHozAlign:"center", width:100} ]; var fieldMapping = []; $('.field-selector').each(function(index) { var selectedField = $(this).val(); var field = String.fromCharCode(65 + index); if (selectedField) { columns.push({ title: field , field: selectedField , hozAlign: "center" , headerHozAlign: "center" , editor: false , width: 400 , validator: ["maxLength:100", "string"] }); fieldMapping.push(selectedField); } else { columns.push({ title: field , field: field , hozAlign: "center" , headerHozAlign: "center" , editor: false , width: 400 , validator: ["maxLength:100", "string"] }); fieldMapping.push(field); } }); var updatedData = currentData.map(row => { var newRow = {}; fieldMapping.forEach((field, index) => { newRow[field] = row[Object.keys(row)[index]] !== null && row[Object.keys(row)[index]] !== undefined ? row[Object.keys(row)[index]] : ""; }); return newRow; }); objTabul.setColumns(columns); objTabul.setData(updatedData); } /** * @ 팩스번호 중복 데이터 * */ function fn_faxDupl(objTabul) { tableError.clearData(); var data = objTabul.getData(); var phoneNumberChk = false; var existingNumbers = new Set(); // 배열에서 Set으로 변경 let errorCount = 0; // 중복 번호 개수를 저장할 변수 let duplicateCount = 0; // 중복 번호 개수를 저장할 변수 const errors = []; // 오류 데이터를 저장할 배열 const newData = []; // 유효한 데이터만 저장할 새로운 배열 data.forEach((row, index) => { const number = row.addrFaxNo; // number가 null, undefined, 빈 문자열이거나 숫자인 경우 처리 if (!number || (typeof number === 'string' && !number.trim())){ console.log("number : ", number); return; } const formattedNumber = formatPhoneNumber(number); // 번호 표준화 const cleanedNumber = formattedNumber.replace(/[^0-9]/g, ''); // 숫자만 남김 if (!existingNumbers.has(cleanedNumber)) { // 중복 번호 체크 if (checkFaxNum(formattedNumber)) { // 유효성 검사 row.addrFaxNo = formattedNumber; existingNumbers.add(cleanedNumber); // 추가된 번호를 기존 목록에 추가 newData.push(row); // 유효한 데이터만 새로운 배열에 추가 } else { // 오류: 유효성 통과 못함 errorCount++; errors.push({ name: row.addrNm // 이름 , phone: row.addrFaxNo // 팩스번호 , result: "오류" // 결과 메시지 추가 }); } } else { // 중복 duplicateCount++; errors.push({ name: row.addrNm // 이름 , phone: row.addrFaxNo // 팩스번호 , result: "중복" // 결과 메시지 추가 }); } }); // data 배열을 newData 배열로 대체 data = newData; // 수정된 데이터로 테이블 업데이트 objTabul.setData(data); // 오류 총 카운트 $("#excelRowTotCnt").text(objTabul.getDataCount()); // 중복 카운트 $("#excelRowDupCnt").text(duplicateCount); // 에러 카운트 $("#excelRowErrorCnt").text(errorCount); // popup 영역 $("#errorPopTotCnt").text(objTabul.getDataCount()); // 중복 카운트 $("#errorPopDupCnt").text(duplicateCount); // 에러 카운트 $("#errorPopErrorCnt").text(errorCount); tableError.setData(errors); if(errorCount > 0){ alert('휴대폰 형식에 맞지 않는 데이터는 삭제 후 업로드 됩니다.\nex) 발송불가 특수문자, 자릿수 오류 등'); } }