이호영 이호영 2024-08-02
주소록 속도 개선중
@72f3d54b61b59c106659698e4efba2cb7caaa2aa
src/main/java/itn/let/mail/service/StatusResponse.java
--- src/main/java/itn/let/mail/service/StatusResponse.java
+++ src/main/java/itn/let/mail/service/StatusResponse.java
@@ -26,6 +26,24 @@
  * 
  * 
  */
+
+
+
+/*
+ * • 1XX : 조건부 응답
+ * • 2XX : 성공
+ * • 3XX : 리다이렉션 완료
+ * • 4XX : 요청 오류
+ * • 500 : 서버 오류
+ *
+ * 참고 : https://km0830.tistory.com/33
+ *
+ * ====== 자주 사용하는 코드 =====
+ * 200 : Ok : 서버가 클라이언트의 요청을 성공적으로 처리, 웹 페이지에서는 페이지 요청이 정상적으로 완료 (Ok)
+ * 400 : Bad Request : 잘못 요청 (Bad Request)
+ * 401 : Unauthorized : 권한 없음, 예를 들면, 로그인 페이지가 필요한 페이지를 로그인 없이 접속하려는 경우 반환되는 코드 (인증 실패) (Unauthorized)
+ *
+ * */
 @Getter
 @Setter
 @NoArgsConstructor
src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
--- src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
@@ -64,9 +64,10 @@
     private static final Charset EUC_KR = Charset.forName("EUC-KR");
 //    private static final int MAX_ADDR_CNT = 500000;
     //임시 500만개
-    private static final int MAX_ADDR_CNT = 5000000;
-//    private static final int BATCH_SIZE = 10000;
-//    private static final int THREAD_COUNT = 3;
+    private static final int MAX_SINGLE_ENTRY_CNT = 100000;
+    private static final int MAX_ADDR_CNT = 500000;
+    private static final int BATCH_SIZE = 10000;
+    private static final int THREAD_COUNT = 3;
 	
 	
 	public List<AddrVO> selectAddrList(AddrVO addrVO) throws Exception {
@@ -398,6 +399,14 @@
 
 		
 		
+		if(addrListVO.size() > MAX_SINGLE_ENTRY_CNT) {
+			return new StatusResponse(
+					HttpStatus.BAD_REQUEST
+					, "주소록은 한번에 10만개까지만 등록이 가능합니다."
+					, LocalDateTime.now()
+					);
+			
+		}
 		// step1 현재 주소록 갯수 조회
 
 		//회원별 주소록 전체 갯수 조회
@@ -478,11 +487,7 @@
 	        if(addrListVO.size() > 0) {
 	    		// 등록 
 	            // Batch insert
-//	                batchInsertAddrList(addrListVO);
-//	                batchInsertAddrListAsync(addrListVO);
-
-                addrDAO.insertAddrList(addrListVO);
-					
+                batchInsertAddrListAsync(addrListVO);
 	//    		addrDAO.insertAddrList(addrListVO);
 	        	
 	        }
@@ -519,7 +524,7 @@
 	}
 
 
-    /*private void batchInsertAddrListAsync(List<AddrVO> addrListVO) throws InterruptedException {
+    private void batchInsertAddrListAsync(List<AddrVO> addrListVO) throws InterruptedException {
         int totalSize = addrListVO.size();
         int batchCount = (totalSize + BATCH_SIZE - 1) / BATCH_SIZE;
         ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
@@ -544,7 +549,7 @@
 
         executor.shutdown();
         executor.awaitTermination(1, TimeUnit.HOURS);
-    }*/
+    }
 
 	public static boolean isValidPhoneNumber(String phoneNo) {
         if (phoneNo == null || phoneNo.isEmpty()) {
src/main/java/itn/let/uss/umt/web/EgovUserManageController.java
--- src/main/java/itn/let/uss/umt/web/EgovUserManageController.java
+++ src/main/java/itn/let/uss/umt/web/EgovUserManageController.java
@@ -1388,6 +1388,7 @@
 				
 				//전용 전송사 발송 단가 조회
 				List<MjonMsgAgentStsVO> resultAgentPriceList = mjonMsgAgentStsService.selectHotLineAgentPriceList(hotLineAgentCode);
+				System.out.println("??????????????????????!!!!!!!!!!!!!!");
 				agentCodeNm = resultAgentPriceList.get(0).getAgentCodeNm();
 				
 				for(MjonMsgAgentStsVO hotLineVO : resultAgentPriceList) {
src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
@@ -10,8 +10,8 @@
 
 <script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
 <script type="text/javascript" src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
-<script type="text/javascript" src="<c:url value='/js/web/addr/init.js'/>"></script>
-<script type="text/javascript" src="<c:url value='/js/web/addr/event.js'/>"></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/init.js'/>?v=${currentTime}""></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/event.js'/>?v=${currentTime}""></script>
 <script type="text/javascript" src="<c:url value='/js/web/addr/utils.js'/>?v=${currentTime}"></script>
 
 
@@ -20,7 +20,10 @@
 $(document).ready(function(){
 	listAddrGrp();
 	addrLoadAjax();
-	
+
+	// 엑셀 중복번호 버튼
+	$("#tableExcelDupliBtn").hide();
+// 	$("#btnAddrMassSaveDupli").hide();
 	// 주소록 대량등록
 // 	addrMassTab(1);	
 	
@@ -83,70 +86,6 @@
 	
 }
 
-function insertAddrAjax() {
-	var selectVal = $("#addrRegistSelect option:selected").val();
-	//alert(selectVal);
-	
-	var form = document.addrInsertForm;
-	/*
-	//필수값 아니어서 뺐음
-	if(form.addrNm.value == "") {
-		alert("주소록 이름을 입력하세요");
-		return;
-	}
-	*/
-	if(form.addrPhoneNo.value == "") {
-		alert("주소록 번호를 입력하세요");
-		return;
-	}
-	//if(!confirm("주소록을 추가하시겠습니까?")) {
-	//	return;
-	//}
-	
-	if(!checkHpNum(form.addrPhoneNo.value)){//휴대폰 유효성 검사
-		if(!checkNorPhoneNum(form.addrPhoneNo.value)){//일반전화 유효성 검사
-			
-			alert("잘못된 휴대폰번호 또는 일반전화 번호 입니다.");
-			return false;
-			
-		}
-		
-	}
-	
-	var data = new FormData(form);
-
-	$.ajax({
-		cache : false,
-		url : "<c:url value='/web/mjon/addr/insertAddrAjax.do' />", 
-		type : 'POST', 
-		data : data,
-		dataType:'json',
-		processData: false,
-		contentType: false,
-		success : function(returnData, status){
-			if(status == "success") {
-				if("fail"==returnData.result){
-					alert(returnData.message);
-					return;
-				} else if("dupl"==returnData.result){
-					alert("해당 그룹에 중복된 번호가 있습니다.");
-					return;
-				}
-				//alert("저장 되었습니다.");
-				
-				listAddrGrp();
-				addrGroupLoadAjax();
-				addrLoadAjax();
-				
-				// 주소록그룹 콤보박스 유지
-				setTimeout(setSelectSetting, 500, selectVal);			
-				
-			}else{ alert("ERROR!");return;} 
-		},
-		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
-	});
-	
-}
 
 // 주소록그룹 콤보박스 유지
 function setSelectSetting(selectVal) {
@@ -187,23 +126,6 @@
 
 $(document).ready(function(){
 	
-
-
-	//받는 사람 리스트 영역에 클립보드 데이터 가져와보기 
-	// 붙여넣기 기능
-	
-	
-
-// 	// 필드 선택 이벤트 핸들러
-// 	$("#column-selector").on("change", function() {
-// 		let selectedField = $(this).val();
-// 		let newValue = prompt("새 값을 입력하세요:");
-// 		if (newValue !== null) {
-// 			updateTableField(selectedField, newValue);
-// 		}
-// 	});
-
-
 
 
 	
@@ -358,26 +280,30 @@
 	}
 	
 	// tableExcel 그룹의 select 요소들을 확인
-	var isPhoneSelected = false;
-	var isNameSelected = false;
+// 	var isPhoneSelected = false;
+// 	var isNameSelected = false;
 	$('.adr_hd.select_adr_hd[data-group="'+tabulNm+'"] .field-selector').each(function() {
 		var value = $(this).val();
 		if (value === 'addrPhoneNo') {
-		    isPhoneSelected = true;
-		} else if (value === 'addrNm') {
-		    isNameSelected = true;
-		}
+// 		    isPhoneSelected = true;
+			alert('휴대폰이 선택되지 않았습니다.');
+			return false;
+
+		} 
+// 		else if (value === 'addrNm') {
+// 		    isNameSelected = true;
+// 		}
 		
 		// 두 조건이 모두 충족되면 반복문 종료
-		if (isPhoneSelected && isNameSelected) {
-		    return false;
-		}
+// 		if (isPhoneSelected && isNameSelected) {
+// 		    return false;
+// 		}
 	});
 	
-	if (!isPhoneSelected || !isNameSelected) {
-		alert('휴대폰 또는 이름이 선택되지 않았습니다.');
-		return false;
-	}
+// 	if (!isPhoneSelected || !isNameSelected) {
+// 		alert('휴대폰 또는 이름이 선택되지 않았습니다.');
+// 		return false;
+// 	}
 	
 	
 	// 주소록이 새로생성이면 새로운 주소록명이 있는지 확인
@@ -471,7 +397,7 @@
 				var selectMassVal = $("#addrGrpIdInfo option:selected").val();
 				
 				// 주소록그룹 콤보박스 유지
-				setTimeout(setSelectMassSetting, 500, selectMassVal);					
+// 				setTimeout(setSelectMassSetting, 500, selectMassVal);					
 			} 
 			else {
 				alert("오류 알림 :  :: "+data.message);
src/main/webapp/WEB-INF/jsp/web/addr/AddrListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/AddrListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/AddrListAjax.jsp
@@ -1013,7 +1013,7 @@
 	</div>		
 </div>
 <!--// 중복전화번호 팝업 -->
-
+<!-- 
 <!-- 중복전화번호 저장시 data-tooltip:addrMassSaveDupli_layer -->
 <div class="tooltip-wrap">
 	<div class="popup-com addrMassSaveDupli_layer" tabindex="0" data-tooltip-con="addrMassSaveDupli_layer" data-focus="addrMassSaveDupli_layer" data-focus-prev="addrMassSaveDupli_layer-close" style="width: 320px; height: 500px;">
@@ -1029,8 +1029,8 @@
 		</div>				
 	</div>		
 </div>
-<!--// 중복전화번호 팝업 -->
-
+// 중복전화번호 팝업
+ -->
 <form name="addrMemoForm" name="addrMemoForm" method="post">
 	<input type="hidden" name="addrCheck" />
 	<input type="hidden" name="addrComment" />
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp
@@ -164,13 +164,6 @@
         $("#excelFile").click();
     });
 
-    // 파일 입력 이벤트
-    $("#excelFile").on("change", function(event) {
-    	excelFileChange(event.target.files[0]);
-    });
-    
-
-
 	//받는사람 전체삭제 버튼 처리
 	$('.all_del').click(function(){
 		var data = $tableClip.getRows();	
@@ -431,32 +424,6 @@
 	$("#addrMassDupli_layer").html(sHtml);
 }
 
-//중복 연락처 => 저장시
-function GetAddrMassSaveDupli() {
-	var sHtml = "";
-	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
-	sHtml += "<table class='tType4'>";
-	sHtml += "		<colgroup>";
-	sHtml += "			<col style='width:auto' />";
-	sHtml += "		</colgroup>";
-	sHtml += "		<thead>";
-	sHtml += "			<tr>";
-// 	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(addrMassDupliSaveList.length) + "개)</th>";
-	sHtml += "				<th>중복 휴대폰번호 (10개)</th>";
-	sHtml += "			</tr>";
-	sHtml += "		</thead>";
-	sHtml += "		<tbody>";
-	for (var i = 0; i < addrMassDupliSaveList.length; i++) {
-		sHtml += "		<tr>";
-		sHtml += "			<td>" + addrMassDupliSaveList[i].addrPhoneNo + "</td>";
-		sHtml += "		</tr>";
-	}
-	sHtml += "		</tbody>";
-	sHtml += "	</table>";
-	sHtml += "	</div>";
-	
-	$("#addrMassSaveDupli_layer").html(sHtml);
-}
 
 </script>
 	             
@@ -505,6 +472,7 @@
 						<p>
 							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
 <!-- 							&nbsp;  -->
+							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" id="tableClipDupliBtn">중복번호</button>
 <!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button> -->
 <!-- 							&nbsp; -->
 <!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button> -->
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp
@@ -61,70 +61,6 @@
 	
 }
 
-function insertAddrAjax() {
-	var selectVal = $("#addrRegistSelect option:selected").val();
-	//alert(selectVal);
-	
-	var form = document.addrInsertForm;
-	/*
-	//필수값 아니어서 뺐음
-	if(form.addrNm.value == "") {
-		alert("주소록 이름을 입력하세요");
-		return;
-	}
-	*/
-	if(form.addrPhoneNo.value == "") {
-		alert("주소록 번호를 입력하세요");
-		return;
-	}
-	//if(!confirm("주소록을 추가하시겠습니까?")) {
-	//	return;
-	//}
-	
-	if(!checkHpNum(form.addrPhoneNo.value)){//휴대폰 유효성 검사
-		if(!checkNorPhoneNum(form.addrPhoneNo.value)){//일반전화 유효성 검사
-			
-			alert("잘못된 휴대폰번호 또는 일반전화 번호 입니다.");
-			return false;
-			
-		}
-		
-	}
-	
-	var data = new FormData(form);
-
-	$.ajax({
-		cache : false,
-		url : "<c:url value='/web/mjon/addr/insertAddrAjax.do' />", 
-		type : 'POST', 
-		data : data,
-		dataType:'json',
-		processData: false,
-		contentType: false,
-		success : function(returnData, status){
-			if(status == "success") {
-				if("fail"==returnData.result){
-					alert(returnData.message);
-					return;
-				} else if("dupl"==returnData.result){
-					alert("해당 그룹에 중복된 번호가 있습니다.");
-					return;
-				}
-				//alert("저장 되었습니다.");
-				
-				listAddrGrp();
-				addrGroupLoadAjax();
-				addrLoadAjax();
-				
-				// 주소록그룹 콤보박스 유지
-				setTimeout(setSelectSetting, 500, selectVal);			
-				
-			}else{ alert("ERROR!");return;} 
-		},
-		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
-	});
-	
-}
 
 // 주소록그룹 콤보박스 유지
 function setSelectSetting(selectVal) {
@@ -140,114 +76,15 @@
 
 $(document).ready(function(){
     // 파일 선택 버튼 클릭 이벤트
-    $("#file-load-trigger").on("click", function() {
-        $("#excelFile").click();
-    });
-
     // 파일 입력 이벤트
     $("#excelFile").on("change", function(event) {
-    	excelFileChange(event.target.files[0]);
+    	var fileInfo =  event.target.files;
+    	if(fileInfo.length > 0){
+    		fn_loadAddActive();
+        	excelFileChange(fileInfo[0]);
+    	}
     });
     
-
-	
-	//받는 사람 리스트 영역에 클립보드 데이터 가져와보기 
-	// 붙여넣기 기능
-	/* $('.callList_box').on('paste', function (e) {
-		var element = e.originalEvent.clipboardData.getData('text'); // 클립보드에 복사한 데이터 가져오기
-		var elmSplit= [];
-		elmSplit = element.split("\n");
-		var elmLen = elmSplit.length;
-		console.log('elmSplit : ', elmSplit);
-		if(elmLen < 0){
-			alert("붙여넣을 연락처를 복사해주세요.");
-			return false;
-		}
-		if (elmLen > 20001) {
-			alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-			return false;
-		}			
-		
-		tableErrorData.length = 0;	// 오류 번호 배열 초기화
-
-		var splitData = [];
-		var realPhone = [];
-		
-		for(var i=0; i < elmLen; i++){
-			var splitStr = elmSplit[i];
-			var tabData = splitStr.split("\t"); //탭 구분으로 데이터 분할
-			var comData = splitStr.split(","); //콤마 구분으로 데이터 분할
-			if(tabData.length >= 2){
-				splitData = tabData;
-			}else{
-				splitData = comData;
-			}
-				
-			if(splitData.length == 0){// 데이터가 없는경우
-				alert("탭으로 구분하여 데이터를 복사해 주세요.");
-			  	return false;
-			}
-			
-			
-			if(splitData.length == 1){
-				realPhone.push({A: splitData[0].trim()});
-			}else{
-				
-				let keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
-				let data = {};
-
-				splitData.forEach((item, index) => {
-				    data[keys[index]] = item.trim();
-				});
-
-				realPhone.push(data);
-			}//else end
-		}
-		console.log('realPhone : ', realPhone);
-		var recTableData = $tableExcel.getRows();		 // 받는사람 리스트의 전체 목록을 저장
-		var tableData = [];
-		
-		//기존 받는사람 리스트를 배열에 미리 담아둔다.
-		if (recTableData.length > 0) {
-		    recTableData.forEach(item => {
-		        tableData.push(createDataObject(item.getData()));
-		    });
-		}
-			
-		if (realPhone.length > 0) {
-		    realPhone.forEach(item => {
-		        tableData.push(createDataObject(item));
-		    });
-		}
-			
-		//tableData.push(realPhone);
-			
-		//중복 연락처 1개만 남기고 삭제하기
-		// 20240719 개선작업은 폰위치가 따로없어 중복제거를 못함
-// 			var removeDuplPhone = dupliPhoneData(tableData);
-		var removeDuplPhone = tableData;
-		  
-		//수신자 리스트에 전화번호 추가해주기
-		//$tableExcel.addData(removeDuplPhone);
-		$tableExcel.setData(removeDuplPhone);
-		
-		totRows = $tableExcel.getRows().length; 
-		updateTotCnt(totRows); //전체 데이터 갯수 구하기
-		
-		if (tableErrorData.length > 0) {
-			alert("데이터를 확인해 주세요.");
-			// 	alert("올바르지 않은 휴대폰 번호가 "+ tableErrorData.length +" 건 있습니다.");
-			//for(var x=0; x < tableErrorData.length; x++){
-			//	alert(tableErrorData[x]);
-			//}
-		}
-	});
- */
-	
-	//$tableExcel.setData(tabledata);
-	
-	
-
 
 	//받는사람 전체삭제 버튼 처리
 	$('.all_del').click(function(){
@@ -261,7 +98,6 @@
 			$("#rowDupCnt").text(0); //중복건수 수정
 			dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
 		}
-		
 	});
 
 
@@ -345,10 +181,6 @@
     });
 
 
-
-
-    
-    
     
 	// 오류검사 항목 중복제거
 	function SetTableErrorDupliCheck(sVal) {
@@ -510,11 +342,10 @@
   e.preventDefault();
 });
 $(document).on("drop",".upload_area",function(e){
-  //$(this).css('border', '2px dotted #0B85A1');
-  e.preventDefault();
-  var files = e.originalEvent.dataTransfer.files;
-//   handleFileUpload(files,objDragAndDrop);  //파일업로드
-  excelFileChange(files[0]);
+	fn_loadAddActive();
+	e.preventDefault();
+	var files = e.originalEvent.dataTransfer.files;
+	excelFileChange(files[0]);
 });
 
 $(document).on('dragenter', function (e){
@@ -532,64 +363,95 @@
 });
 //파일 드래그앤드롭 종료
 
+function excelFileChange(file) {
+    if (file) {
+        var reader = new FileReader();
+        var extension = file.name.split('.').pop().toLowerCase();
 
-    function excelFileChange(file){
-
-		$('.loading_layer').addClass('active');	
-//         var file = event.target.files[0];
-        if (file) {
-            var reader = new FileReader();
-            reader.onload = function(e) {
+        reader.onload = function(e) {
+            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});
                 processExcelData(jsonData);
-            };
+            } else if (extension === 'txt') {
+                var textData = e.target.result;
+                processTextData(textData);
+            } else {
+                alert('지원되지 않는 파일 형식입니다.');
+            }
+        };
+
+        if (extension === 'xlsx') {
             reader.readAsArrayBuffer(file);
+        } else if (extension === 'txt') {
+            reader.readAsText(file);
         }
-
-		//로딩창 hide
-		$('.loading_layer').removeClass('active');
-        
     }
 
-    // 엑셀 데이터 처리 함수
-    function processExcelData(data) {
-        var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
-        var tableData = [];
+    // 로딩창 hide
+    fn_loadRemoveActive();
+}
 
-        // 3번째 행부터 입력 
-        // 1,2행은 예시와 타이틀이라 입력안함
-        data.slice(2).forEach(row => {
-            var rowData = {};
-            keys.forEach((key, index) => {
-                rowData[key] = row[index] ? row[index].trim() : ""; // 각 컬럼에 대해 기본값을 설정
-            });
-            tableData.push(rowData);
+// 엑셀 데이터 처리 함수
+function processExcelData(data) {
+    var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+    var tableData = [];
+
+    // 3번째 행부터 입력 
+    // 1, 2행은 예시와 타이틀이라 입력안함
+    data.slice(2).forEach(row => {
+        var rowData = {};
+        keys.forEach((key, index) => {
+            rowData[key] = row[index] ? row[index].trim() : ""; // 각 컬럼에 대해 기본값을 설정
         });
+        tableData.push(rowData);
+    });
 
+    updateTable(tableData);
+}
 
-        $tableExcel.setColumns([ // 열 정의를 다시 설정
-            {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
-                cell.getRow().toggleSelect();
-            }},
-            {title: "A", hozAlign: "center", headerHozAlign: "center", field: "A", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "B", hozAlign: "center", headerHozAlign: "center", field: "B", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "C", hozAlign: "center", headerHozAlign: "center", field: "C", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "D", hozAlign: "center", headerHozAlign: "center", field: "D", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "E", hozAlign: "center", headerHozAlign: "center", field: "E", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "F", hozAlign: "center", headerHozAlign: "center", field: "F", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
-            {title: "G", hozAlign: "center", headerHozAlign: "center", field: "G", editor: "input", width: 125, validator: ["maxLength:100", "string"]}
-        ]);
-        
-        $tableExcel.setData(tableData).then(() => {
-            // rowTotCnt 업데이트
-            document.getElementById("rowTotCnt").innerText = tableData.length;
+// 텍스트 데이터 처리 함수
+function processTextData(text) {
+    var lines = text.split('\n'); // 각 줄을 배열로 분리
+    var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+    var tableData = [];
+
+    lines.forEach(line => {
+        var rowData = {};
+        var row = line.split(','); // 쉼표로 분리
+        keys.forEach((key, index) => {
+            rowData[key] = row[index] ? row[index].trim() : ""; // 각 컬럼에 대해 기본값을 설정
         });
-        
-    }
+        tableData.push(rowData);
+    });
 
+    updateTable(tableData);
+}
+
+//공통 테이블 업데이트 함수
+function updateTable(tableData) {
+ $tableExcel.setColumns([ // 열 정의를 다시 설정
+     {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+         cell.getRow().toggleSelect();
+     }},
+     {title: "A", hozAlign: "center", headerHozAlign: "center", field: "A", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "B", hozAlign: "center", headerHozAlign: "center", field: "B", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "C", hozAlign: "center", headerHozAlign: "center", field: "C", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "D", hozAlign: "center", headerHozAlign: "center", field: "D", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "E", hozAlign: "center", headerHozAlign: "center", field: "E", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "F", hozAlign: "center", headerHozAlign: "center", field: "F", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+     {title: "G", hozAlign: "center", headerHozAlign: "center", field: "G", editor: "input", width: 125, validator: ["maxLength:100", "string"]}
+ ]);
+
+ $tableExcel.setData(tableData).then(() => {
+     // rowTotCnt 업데이트
+     document.getElementById("rowTotCnt").innerText = tableData.length;
+ });
+
+ fn_loadRemoveActive();
+}
     
 
 //#############################################################################################
@@ -650,34 +512,10 @@
 
 
 
-// 중복 연락처
-function GetAddrMassDupli() {
-	var sHtml = "";
-	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
-	sHtml += "<table class='tType4'>";
-	sHtml += "		<colgroup>";
-	sHtml += "			<col style='width:auto' />";
-	sHtml += "		</colgroup>";
-	sHtml += "		<thead>";
-	sHtml += "			<tr>";
-	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(dupliPhoneDataRealList.length) + "개)</th>";
-	sHtml += "			</tr>";
-	sHtml += "		</thead>";
-	sHtml += "		<tbody>";
-	for (var i = 0; i < dupliPhoneDataRealList.length; i++) {
-		sHtml += "		<tr>";
-		sHtml += "			<td>" + dupliPhoneDataRealList[i] + "</td>";
-		sHtml += "		</tr>";
-	}
-	sHtml += "		</tbody>";
-	sHtml += "	</table>";
-	sHtml += "	</div>";
-	
-	$("#addrMassDupli_layer").html(sHtml);
-}
 
 //중복 연락처 => 저장시
-function GetAddrMassSaveDupli() {
+// 해당 그룹
+/* function GetAddrMassSaveDupli() {
 	var sHtml = "";
 	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
 	sHtml += "<table class='tType4'>";
@@ -701,7 +539,7 @@
 	sHtml += "	</div>";
 	
 	$("#addrMassSaveDupli_layer").html(sHtml);
-}
+} */
 
 </script>
 	               <!-- 엑셀입력 -->
@@ -760,9 +598,10 @@
 						<p>
 							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
 							&nbsp; 
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button>
-							&nbsp;
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button>
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button> -->
+							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" id="tableExcelDupliBtn">중복번호</button>
+<!-- 							&nbsp; -->
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button> -->
 						</p>
 <!-- 						<button type="button" class="btnType btnType6 addCallToF">번호추가</button> -->
 					</div>
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp
@@ -186,12 +186,6 @@
         $("#excelFile").click();
     });
 
-    // 파일 입력 이벤트
-    $("#excelFile").on("change", function(event) {
-    	excelFileChange(event.target.files[0]);
-    });
-    
-
 
 	//받는사람 전체삭제 버튼 처리
 	$('.all_del').click(function(){
@@ -545,6 +539,7 @@
 						<p>
 							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
 <!-- 							&nbsp;  -->
+							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" id="tableSelfDupliBtn">중복번호</button>
 <!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button> -->
 <!-- 							&nbsp; -->
 <!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button> -->
src/main/webapp/js/web/addr/event.js
--- src/main/webapp/js/web/addr/event.js
+++ src/main/webapp/js/web/addr/event.js
@@ -5,7 +5,10 @@
 	
 	//타이틀 select 선택 이벤트
 	 $('[data-group]').on('change', '.field-selector', function() {
-		 
+
+		 fn_loadAddActive();
+		
+		
 		var group = $(this).closest('[data-group]').data('group');
 		var selectedFields = [];
 		var isDuplicate = false;
@@ -19,6 +22,7 @@
 		if($objTabul.getData().length < 1){
 			alert('데이터 입력 후 선택해 주세요.');
 			$(this).val(""); 
+			fn_loadRemoveActive();
 			return false;
 		}
 		
@@ -41,36 +45,60 @@
 		updateTableFields($objTabul, group);
 		
 		// 필드가 휴대폰이면 열 중복체크
-		if($(this).val() == 'phone'){
+		if($(this).val() == 'addrPhoneNo'){
 			fn_phoneDupl($objTabul);
 		}
+		fn_loadRemoveActive();
+		
 	});
 
 
-	function fn_phoneDupl($objTabul){
-		
-		var phoneFields = $objTabul.getData().map(row => row.phone);
-	
-		if(phoneFields.length < 1){ return false; }
-	
-		var uniquePhones = new Set();
-		var duplicatePhones = [];
-	
-		phoneFields.forEach(phone => {
-			if (uniquePhones.has(phone)) {
-				duplicatePhones.push(phone);
-			} else {
-				uniquePhones.add(phone);
-			}
-		});
-	
-		$('#rowDupCnt').text(duplicatePhones.length);
-		if (duplicatePhones.length > 0) {
-			alert("중복된 휴대폰 번호가 있습니다: \n" + duplicatePhones.join(", "));
-		} else {
-//			alert("중복된 phone 필드 값이 없습니다.");
+	 /**
+	  * @ 핸드폰 중복 데이터
+	  * */
+	 function fn_phoneDupl($objTabul) {
+		    var data = $objTabul.getData();
+		    var uniquePhones = new Set();
+		    var dupliPhoneDataRealList = [];
+		    var rowsToKeep = [];
+		    var rowsToDelete = [];
+		    var phoneNumberChk = false;
+
+		    data.forEach((row, index) => {
+
+		        if (!isValidKoreanPhoneNumber(phone)) {
+		        	phoneNumberChk = true
+		        	return false;
+		        }
+		    	
+		        if (uniquePhones.has(row.addrPhoneNo)) {
+		        	dupliPhoneDataRealList.push(row.addrPhoneNo);
+		            rowsToDelete.push(index); // 중복된 행의 인덱스를 기록
+		        } else {
+		            uniquePhones.add(row.addrPhoneNo);
+		            rowsToKeep.push(row); // 고유한 데이터만 추가
+		        }
+		    });
+		    
+		    if(phoneNumberChk){
+		    	alert('휴대폰 형식에 맞지 않는 데이터가 있습니다.\n 확인해 주세요');
+		    }
+
+		    $('#rowDupCnt').text(dupliPhoneDataRealList.length);
+
+		    if (dupliPhoneDataRealList.length > 0) {
+//		        alert("중복된 휴대폰 번호가 있습니다: \n" + duplicatePhones.join(", "));
+		    	makeAddrMassDupliPop(dupliPhoneDataRealList);
+		    }
+
+		    // 중복된 행 삭제
+		    rowsToDelete.reverse().forEach(index => {
+		        $objTabul.deleteRow(index);
+		    });
+
+		    // 고유한 데이터만 남기고 테이블 업데이트
+		    $objTabul.setData(rowsToKeep);
 		}
-	}
 
 	/* 
 	* 타이틀 select 선택할때마다 실행해서         
@@ -108,10 +136,59 @@
 
 		$objTabul.setColumns(columns);
 		$objTabul.setData(updatedData);
-		
-		
 	}
+}); 
+
+
+function fn_loadAddActive(){
+	$('.loading_layer').addClass('active');
+}
+
+function fn_loadRemoveActive(){
+	$('.loading_layer').removeClass('active');
+}
+
+//중복 연락처
+function makeAddrMassDupliPop(dupliPhoneDataRealList) {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(dupliPhoneDataRealList.length) + "개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < dupliPhoneDataRealList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + dupliPhoneDataRealList[i] + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+
+	$("#addrMassDupli_layer").html(sHtml);
+	fn_dupliPopupShow();
 	
-	
-	
-}); 
(No newline at end of file)
+}
+
+function fn_dupliPopupShow(){
+
+	var showId = '#'+fn_utils_getTabulatorNm()
+	console.log('showId : ', showId);
+	$(showId+'DupliBtn').show()
+}
+
+//한국의 핸드폰 번호 형식 검사 함수
+function isValidKoreanPhoneNumber(phone) {
+    // 하이픈(-)을 제거하고 숫자만 남긴 후 검사
+    var cleaned = phone.replace(/-/g, '');
+    // 010, 011, 016, 017, 018, 019로 시작하고 10~11자리인 경우 유효
+    var valid = /^(010|011|016|017|018|019)\d{7,8}$/.test(cleaned);
+    return valid;
+}
+
Add a comment
List