이호영 이호영 2024-09-05
주소록 탭마다 문구 수정 및 문자전송 엑셀 불러오기도 동일하게 맞춤
@9328e68d6f10adb37ca40736020287e859968bc9
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
@@ -13,6 +13,7 @@
 <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>
+<script type="text/javascript" src="<c:url value='/js/web/addr/cmn.js?date=202409021440'/>"></script>
 
 
 <script type="text/javascript">
@@ -212,8 +213,16 @@
 function setAddrMassClose() {
 	var $objTabul = fn_utils_getTabulator();
 	$objTabul.clearData();
+	
+	fn_rowDataClear();
+	
+	
 	$("#rowTotCnt").text(0); //총건수 수정
 	$("#rowDupCnt").text(0); //중복건수 수정
+	$("#rowErrorCnt").text(0); //중복건수 수정
+	
+	
+	
 	dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
 	addrMassDupliSaveList = null;
 
@@ -226,6 +235,31 @@
 	addrLoadAjax();		
 	errorPopClean(); // 에러 팝업 초기화
 }
+
+// 주소록 탭마다 돌면서 총, 중복, 오류 건수 초기화
+function fn_rowDataClear(){
+
+	// 모든 .tab 요소를 선택하여 반복
+	$('#tbTabl .tab').each(function() {
+	    // 현재 반복 중인 요소
+	    var tab = $(this);
+
+	    // data-tabul 값 가져오기
+	    var tabulNm = tab.data('tabul');
+		var tabluC = '.'+tabulNm
+
+	    // 중복 카운트
+	    $(tabluC+" #rowTotCnt").text(0);
+	    // 에러 카운트
+	    $(tabluC+" #rowDupCnt").text(0);
+	    // 
+	    $(tabluC+" #rowErrorCnt").text(0);
+		
+		
+	});
+}
+
+
 
 // 주소록 그룹 중복체크
 function getAddrGroupDuplCheckAjax() {
@@ -733,7 +767,7 @@
                     <li>ex) 발송불가 특수문자, 자릿수 오류 등</li>
                 </ul>
                 <div class="popup_btn_wrap2">
-                    <button type="button">저장</button>
+<!--                     <button type="button">저장</button> -->
                     <button type="button" class="tooltip-close" data-focus="adr_popup14-close" data-focus-next="adr_popup14">닫기</button>                      
                 </div>
 			</div>
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
@@ -396,15 +396,12 @@
 	                <!-- 붙여넣기 -->
 	                <div class="popCont pop_more_cont" id="popCont_2">
 	                    <div class="titBox">
-	                        <p>- 텍스트(txt) 파일로 작성된 주소록을 등록하실 수 있습니다.</p>
-	                        <p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 붙여 넣으셔야 합니다.</p>
-	                        <p>- 입력 내용은 (Tab) 또는 (,) 구분하여 입력하여야 합니다.</p>
-	                        <p>- 한 줄(열)에 주소 한 건만 입력 가능합니다.</p>
-	                        <p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
-	                        <p>&nbsp;&nbsp;(예) 홍길동,010-1234-5678 또는 홍길동,01012345678</p>
-	                        <p>- 한번에 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+c) + 붙여넣기(Ctrl+v)’ 또는 ‘엑셀입력’을 이용하세요.</p>
-	                        <p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                        
+	                        <p>- 엑셀(EXCEL), 텍스트(TXT) 파일로 작성된 주소록 내용을 복사하여 등록 가능합니다.</p>
+	                        <p>- 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+C) + 붙여넣기(Ctrl+V)’를 이용해주세요.</p>
+	                        <p>- 입력 내용은 (Tab) 또는 (,) 기호로 구분하여 입력하여야 합니다.</p>
+	                        <p>- 이름 200byte, [*1*]~[*4*] 200byte, 메모 250byte까지 입력 가능합니다.</p>
+	                        <p>- 주소록 등록이 어려우신 경우에는 <a href="<c:url value='/web/mjon/addragency/selectAddrAgencyList.do'/>" style="font-weight: bold; color: blue;">주소록 입력대행</a> 메뉴를 이용하실 수 있습니다. </p>
+<!-- 	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                         -->
 	                    </div>
 	                    <div class="pop_more_wrap">
 	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
@@ -552,8 +549,8 @@
 							<div>
 								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
 								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
-								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
-								<button type="button" class="check_validity">오류 검사 <i></i></button>
+<!-- 								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button> -->
+<!-- 								<button type="button" class="check_validity">오류 검사 <i></i></button> -->
 								<div class="error_hover_cont send_hover_cont addr_hover_cont">
 									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
 									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
@@ -564,12 +561,12 @@
 					</div><!--// 공통 -->     
 	
 					<!-- 붙여놓기 설명 -->
-	                <div class="req_area">
-	                  	<div class="text_box">
-	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
-							- 휴대폰 번호는 필수입력 항목입니다.<br>
-							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
-							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
-							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
-						</div>
-	                </div>
+<!-- 	                <div class="req_area"> -->
+<!-- 	                  	<div class="text_box"> -->
+<!-- 	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br> -->
+<!-- 							- 휴대폰 번호는 필수입력 항목입니다.<br> -->
+<!-- 							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br> -->
+<!-- 							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br> -->
+<!-- 							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다. -->
+<!-- 						</div> -->
+<!-- 	                </div> -->
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
@@ -501,19 +501,12 @@
 	               <!-- 엑셀입력 -->
 	               <div class="popCont current pop_more_cont" id="popCont_1">
 	                   <div class="titBox">
-							<p>- 엑셀(EXCEL) 파일로 주소록을 한 번에 최대 2만건까지 등록하여 간편하게 발송 및 관리하실 수 있습니다.</p>
-							<p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 작성하셔야 합니다.</p>
-							<p>  &nbsp;&nbsp;※ 주소록 관리 메뉴에서 다운로드 받으신 엑셀 파일 또한 업로드 양식에 맞추어 작성하셔야 하며, </p>
-							<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;주소록에 이미 등록된 휴대폰 번호는 업데이트 되지 않으므로 기존 주소록에서 해당 휴대폰 번호를 삭제한 후 재등록해 주시기 바랍니다.</p>
-							<p>- 쉼표(,), 구분선(|), 역슬래시(\, ₩), 작은따옴표('), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
-							<p>- 휴대폰 번호는 필수입력 항목입니다.</p>
-							<p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
+							<p>- 주소록은 한 번에 최대 30만건까지 등록(EXCEL파일, 최대용량 3MB) 가능합니다. </p>
 							<p>- 엑셀 파일에 비밀번호 설정, 제한된 보기, 수식 등이 설정되어 있는 경우 업로드가 불가합니다.</p>
-							<p>- 이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte까지 입력 가능합니다.</p>
-							<p>- 첨부가능 파일 : xlsx, xls(최대용량 3MB)</p>
-							<p>- ‘오류 검사’를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.</p>
-							<p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-	                       <button type="button" class="excel_btn" onclick="location.href='/download/addr/주소록_대량등록.xlsx'"><i class="downroad"></i>샘플파일 다운로드</button>
+							<p>- 구분선(|), 역슬래시(\, ₩), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
+							<p>- 이름 200byte, [*1*]~[*4*] 200byte, 메모 250byte까지 입력 가능합니다.</p>
+							<p>- 주소록 등록이 어려우신 경우에는 <a href="<c:url value='/web/mjon/addragency/selectAddrAgencyList.do'/>" style="font-weight: bold; color: blue;">주소록 입력대행</a> 메뉴를 이용하실 수 있습니다. </p>
+<!-- 	                       <button type="button" class="excel_btn" onclick="location.href='/download/addr/주소록_대량등록.xlsx'"><i class="downroad"></i>샘플파일 다운로드</button> -->
 	                   </div>
 	                   <div class="pop_more_wrap">
 	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
@@ -674,8 +667,8 @@
 							<div>
 								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
 								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
-								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
-								<button type="button" class="check_validity">오류 검사 <i></i></button>
+<!-- 								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button> -->
+<!-- 								<button type="button" class="check_validity">오류 검사 <i></i></button> -->
 								<div class="error_hover_cont send_hover_cont addr_hover_cont">
 									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
 									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
@@ -686,12 +679,12 @@
 					</div><!--// 공통 -->     
 	
 					<!-- 붙여놓기 설명 -->
-	                <div class="req_area">
-	                  	<div class="text_box">
-	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
-							- 휴대폰 번호는 필수입력 항목입니다.<br>
-							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
-							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
-							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
-						</div>
-	                </div>
+<!-- 	                <div class="req_area"> -->
+<!-- 	                  	<div class="text_box"> -->
+<!-- 	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br> -->
+<!-- 							- 휴대폰 번호는 필수입력 항목입니다.<br> -->
+<!-- 							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br> -->
+<!-- 							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br> -->
+<!-- 							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다. -->
+<!-- 						</div> -->
+<!-- 	                </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
@@ -7,341 +7,11 @@
 <script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
 
 <script type="text/javascript">
-$(document).ready(function(){
-	
-	// 중복 휴대폰번호 버튼 노출여부
-// 	$("#btnAddrMassDupli").hide();
-// 	$("#btnAddrMassSaveDupli").hide();
-
-
-}); 
-
-
-
-
-function addrGroupLoadAjax(){
-	$("#addrRegistSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
-	$("#funcAddrGroupSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
-}
-
-
-function insertAddrGroupAjax() {
-	var form = document.addrGrpInsertForm;
-	if(form.addrGrpNm.value == "") {
-		alert("주소록 그룹명을 입력해주세요.");
-		return;
-	}
-	if(!confirm("주소록 그룹을 추가하시겠습니까?")) {
-		return;
-	}
-	var data = new FormData(form);
-	
-	$.ajax({
-		cache : false,
-		url : "<c:url value='/web/addr/insertAddrGroupAjax.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();
-				
-			}else{ alert("ERROR!");return;} 
-		},
-		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
-	});
-	
-}
-
-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) {
-	$("#addrRegistSelect").val(selectVal).prop("selected", true);	
-}
-	
-function linkPage(pageNo){
-	if ($('#searchKeywordAddr').val() != "" && $('#searchKeywordAddr').val() != null && $('#searchKeywordAddr').val() != undefined) {
-		// 문자전송 검색용
-		$("#msgStartKeyword").val("");
-	}
-
-	var searchForm = document.searchAddrForm;
-	searchForm.pageIndex.value = pageNo;
-	searchForm.pageUnit.value = $('#pageUnit').val();
-	searchForm.searchCondition.value = $('#searchConditionAddr').val();
-	searchForm.searchKeyword.value = $('#searchKeywordAddr').val();
-	searchForm.startKeyword.value = $("#msgStartKeyword").val();
-	
-	var sendData = $(document.searchAddrForm).serializeArray();
-	$("#adr1_right").load("/web/mjon/addr/selectAddrAjax.do", sendData, function(response, status, xhr){tableAllChk();});
-	addrGroupLoadAjax();
-}
-
-
-
-//#############################################################################################
-//Tabulator
-//#############################################################################################
 
 $(document).ready(function(){
 	//Tabulator AJAX Data Loading
-
-    // 파일 선택 버튼 클릭 이벤트
-    $("#file-load-trigger").on("click", function() {
-        $("#excelFile").click();
-    });
-
-
-	//받는사람 오류번호 삭제 처리해주기
-	$('.chkVali_del').click(function(){
-		//기존 연락처 모두 불러오기
-	    var data = $tableClip.getRows();
-	    var tableData = [];
-	    var totLen = $tableClip.getRows().length;
-	    var errCnt = 0;
-	    
-	    if(totLen > 0){
-	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
-	    		for(var i=0; i < totLen; i++){
-
-	    			
-	            	var phone = data[i].getData().phone;
-	            	var valiCheck = checkHpNum(phone);
-	            	if(valiCheck){
-	            		tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim(), info1:data[i].getData().info1, info2:data[i].getData().info2, info3:data[i].getData().info3, info4:data[i].getData().info4, memo:data[i].getData().memo});
-	            	}else{
-	            		errCnt++;
-	            	}
-	            }
-	            
-	            var removeDuplData = dupliPhoneData(tableData);
-	        	
-// 	            $tableClip.setData(removeDuplData);
-	            
-	            //총 받는사람 수 계산
-	            totRows = $tableClip.getRows().length;
-	            updateTotCnt(totRows);
-	            
-	          	if(errCnt > 0){
-	          		alert(errCnt + " 건의 연락처를 삭제하였습니다.");
-	          		return false;
-	          	}else{
-	          		alert("오류가 있는 연락처가 없습니다.");
-	          	}
-	    	}
-	    }else{
-	    	alert("연락처 정보를 입력해 주세요.");
-	    	return false;
-	    }
-	});
 	
 
-
-    
-    
-	// 오류검사 항목 중복제거
-	function SetTableErrorDupliCheck(sVal) {
-		var isDuplicate = false;
-		if (tableErrorCheckData.length == 0) {
-			tableErrorCheckData.push(sVal);
-		}
-		else {
-			for (var i = 0; i < tableErrorCheckData.length; i++)
-			{
-				if (tableErrorCheckData[i] == sVal) {
-					isDuplicate = true;
-				}
-			}
-			
-			if (isDuplicate) {
-				return;
-			}
-			else {
-				tableErrorCheckData.push(sVal);
-			}
-		}
-	}	
-	
-	
-	// 오류검사 항목 중복제거
-	function SetTableErrorDupliCheck(sVal) {
-		var isDuplicate = false;
-		if (tableErrorCheckData.length == 0) {
-			tableErrorCheckData.push(sVal);
-		}
-		else {
-			for (var i = 0; i < tableErrorCheckData.length; i++)
-			{
-				if (tableErrorCheckData[i] == sVal) {
-					isDuplicate = true;
-				}
-			}
-			
-			if (isDuplicate) {
-				return;
-			}
-			else {
-				tableErrorCheckData.push(sVal);
-			}
-		}
-	}	
-	
-	$('.check_validity').click(function(){
-		tableErrorCheckData.length = 0;	// 오류 번호 배열 초기화
-		
-		var data = $tableClip.getRows();
-		var invalid = $tableClip.getInvalidCells();		//오류 데이터 체크
-		var dataLen = $tableClip.getRows().length;		//연락처 데이터 갯수
-		var totLen = invalid.length;				//오류 데이터 갯수
-		var errMsg = "";							//최종 alert에 표시할 메시지 저장 변수
-		
-		if(dataLen > 0) { //연락처 정보가 있으면 수행
-			if(totLen > 0) { //내용에 오류가 있으면 수행
-				//오류 데이터 값 저장
-				for(var i=0; i < totLen; i++) {
-					var cellValue = invalid[i].getValue();
-					SetTableErrorDupliCheck(cellValue);
-				}
-				
-				for(var i=0; i < dataLen; i++){
-					// 휴대폰번호 체크
-		        	var phone = data[i].getData().phone;
-		        	var valiCheck = checkHpNum(phone);
-		        	if(!valiCheck){
-		        		SetTableErrorDupliCheck(phone);
-		        	}
-				}
-			}
-			else {
-				for(var i=0; i < dataLen; i++){
-					// 휴대폰번호 체크
-		        	var phone = data[i].getData().phone;
-		        	var valiCheck = checkHpNum(phone);
-		        	if(!valiCheck){
-		        		SetTableErrorDupliCheck(phone);
-		        	}
-				}				
-			}
-		}
-		else {
-			alert("연락처를 입력해 주세요.");
-			return false;
-		}
-		
-		if (tableErrorCheckData.length > 0) {
-			for (var i = 0; i < tableErrorCheckData.length; i++)
-			{
-				errMsg += tableErrorCheckData[i];
-				if ((tableErrorCheckData.length - 1) > i) {
-					errMsg += ", ";
-				}
-			}			
-    		alert(errMsg + "의 내용에 오류가 있습니다.");			
-		}
-		else {
-			alert("오류 데이터가 없습니다.");			
-		}
-		
-		return false;		
-	});
-	
-
-
-	//받는사람 중복 삭제
-	$('.duple_del').click(function(){
-		//기존 연락처 모두 불러오기
-	    var data = $tableClip.getRows();
-	    var tableData = [];
-	    var dpCnt = 0;
-	    var totLen = $tableClip.getRows().length;
-	    
-	    for(var i=0; i < totLen; i++){
-	    	tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim()});
-	    }
-	    
-	    var removeDuplData = dupliPhoneData(tableData);
-// 	    $tableClip.setData(removeDuplData);
-	    
-	    //총 받는사람 수 계산
-	    totRows = $tableClip.getRows().length;
-	    updateTotCnt(totRows);
-	});	
-	
 	
 });
 
@@ -369,74 +39,40 @@
 });	
 
 
+function fn_selfUpdataCount(){
 
-// 중복 연락처
-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>";
+	// '휴대폰' 필드의 셀들 가져오기
+	var cells = $tableSelf.getColumn("addrPhoneNo").getCells();
 	
-	$("#addrMassDupli_layer").html(sHtml);
+	// 값이 있는 셀만 필터링하여 개수 카운트
+	var count = cells.filter(function(cell) {
+		var value = cell.getValue();
+		console.log('cell value: ', value);
+		return value !== "" && value !== undefined; // 빈 문자열과 undefined가 아닌 경우
+	}).length;
+	
+	console.log("휴대폰 번호가 있는 행 수: " + count);
+	
+	var tabulNm = fn_utils_getTabulatorNm();
+	var tabluC = '.'+tabulNm
+	
+	$(tabluC+" #rowTotCnt").text(count);
+	return ;
 }
 
-//중복 연락처 => 저장시
-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>
 	             
 	                <!-- 붙여넣기 -->
-	                <div class="popCont pop_more_cont" id="popCont_2">
+	                <div class="popCont pop_more_cont" id="popCont_3">
 	                    <div class="titBox">
-	                        <p>- 텍스트(txt) 파일로 작성된 주소록을 등록하실 수 있습니다.</p>
-	                        <p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 붙여 넣으셔야 합니다.</p>
-	                        <p>- 입력 내용은 (Tab) 또는 (,) 구분하여 입력하여야 합니다.</p>
-	                        <p>- 한 줄(열)에 주소 한 건만 입력 가능합니다.</p>
-	                        <p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
-	                        <p>&nbsp;&nbsp;(예) 홍길동,010-1234-5678 또는 홍길동,01012345678</p>
-	                        <p>- 한번에 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+c) + 붙여넣기(Ctrl+v)’ 또는 ‘엑셀입력’을 이용하세요.</p>
-	                        <p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                        
+	                        <p>- 엑셀(EXCEL), 텍스트(TXT) 파일로 작성된 주소록 내용을 복사하여 등록 가능합니다.</p>
+	                        <p>- 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+C) + 붙여넣기(Ctrl+V)’를 이용해주세요.</p>
+	                        <p>- 입력 내용은 (Tab) 또는 (,) 기호로 구분하여 입력하여야 합니다.</p>
+	                        <p>- 이름 200byte, [*1*]~[*4*] 200byte, 메모 250byte까지 입력 가능합니다.</p>
+	                        <p>- 주소록 등록이 어려우신 경우에는 <a href="<c:url value='/web/mjon/addragency/selectAddrAgencyList.do'/>" style="font-weight: bold; color: blue;">주소록 입력대행</a> 메뉴를 이용하실 수 있습니다. </p>
+<!-- 	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                         -->
 	                    </div>
 	                    <div class="pop_more_wrap">
 	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
@@ -464,129 +100,33 @@
 <!-- 		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/> -->
 		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" style="display:none"/>
 <!-- 		                                  <button type="button" id="file-load-trigger">Choose File</button> -->
-		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button>
+<!-- 		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button> -->
 		                            </td>
 		                        </tr>
 		                    </tbody>
 		                </table>
 	                </div>
-					<div class="file_add upload_area">
-						<p><img src="/publish/images/content/file_add.png" alt="파일 붙여넣기">마우스로 엑셀, TXT파일을 여기에 끌어다 놓으세요</p>
-					</div>
+
 					<div class="excel_middle2">
 						<p>
-							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
+							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 
+							/ 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건 
+							/ 오류 <span class="c_002c9a fwBold" id="rowErrorCnt">0</span>건 
+							<button type="button" class="btn_list_detail" data-tooltip="adr_popup14"><img src="/publish/images/search.png"></button>
 <!-- 							&nbsp;  -->
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" id="tableSelfDupliBtn">중복번호</button>
+<!-- 							<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> -->
 						</p>
-						<button type="button" class="btnType btnType6 addCallToF">번호추가</button>
+<!-- 						<button type="button" class="btnType btnType6 addCallToF">번호추가</button> -->
 					</div>
 					
 					
 					
 
-                    <div class="adr_excel" style="margin-top: 13px;">
-                        <!-- thead -->
-                        <div class="adr_hd select_adr_hd" data-group="tabulClip">
-                            <div></div>
-                            <div style="width: 125px;">
-                            	<label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                            <div style="width: 125px;">
-                                <label for="" class="label"></label>
-								<select class="field-selector">
-									<option value="">선택하기</option>
-									<option value="addrNm">이름</option>
-									<option value="addrPhoneNo">휴대폰</option>
-									<option value="addrInfo1">[*1*]</option>
-									<option value="addrInfo2">[*2*]</option>
-									<option value="addrInfo3">[*3*]</option>
-									<option value="addrInfo4">[*4*]</option>
-									<option value="addrComment">메모</option>
-								</select>
-                            </div>
-                        </div>
-                     </div>					
 					
-					<div class="drag_drop_wrap callList_box" id="tabulator_clip">
+					<div class="drag_drop_wrap callList_box" id="tabulator_self">
 						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
 					</div>
 					<div class="excel_middle">
@@ -594,8 +134,8 @@
 							<div>
 								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
 								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
-								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
-								<button type="button" class="check_validity">오류 검사 <i></i></button>
+<!-- 								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button> -->
+<!-- 								<button type="button" class="check_validity">오류 검사 <i></i></button> -->
 								<div class="error_hover_cont send_hover_cont addr_hover_cont">
 									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
 									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
@@ -606,12 +146,12 @@
 					</div><!--// 공통 -->     
 	
 					<!-- 붙여놓기 설명 -->
-	                <div class="req_area">
-	                  	<div class="text_box">
-	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
-							- 휴대폰 번호는 필수입력 항목입니다.<br>
-							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
-							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
-							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
-						</div>
-	                </div>
+<!-- 	                <div class="req_area"> -->
+<!-- 	                  	<div class="text_box"> -->
+<!-- 	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br> -->
+<!-- 							- 휴대폰 번호는 필수입력 항목입니다.<br> -->
+<!-- 							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br> -->
+<!-- 							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br> -->
+<!-- 							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다. -->
+<!-- 						</div> -->
+<!-- 	                </div> -->
src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataSMLView.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataSMLView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataSMLView.jsp
@@ -8,7 +8,7 @@
 <script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
 <script type="text/javascript" src="<c:url value='/js/txtSpecialReplace.js?date=202304250003'/>"></script>
 <!-- 주소록 유효성 체크 공통유틸로 인해 추가 -->
-<script type="text/javascript" src="<c:url value='/js/web/addr/event.js?date=202409021440'/>"></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/cmn.js?date=202409021440'/>"></script>
 
 <% pageContext.setAttribute("newLineChar", "\r\n"); %>
 <script type="text/javascript">
src/main/webapp/WEB-INF/jsp/web/msgdata/include/msgDataIncludeExcel.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgdata/include/msgDataIncludeExcel.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgdata/include/msgDataIncludeExcel.jsp
@@ -9,10 +9,28 @@
 <script type="text/javascript">
 
 var $tableExcel = null; //엑셀입력 탭
+var $tableError = null; //엑셀입력 탭
 $(document).ready(function(){
-	// 엑셀 중복번호 버튼
-	$("#tableExcelDupliBtn").hide();
 
+	//Tabulator AJAX Data Loading
+	$tableError = new Tabulator("#tabulator_error", {
+		height:"255px",
+		width:"100%",
+	    layout:"fitColumns",
+	    autoColumns:false,
+	    headerHozAlign:"center", 
+	    validationMode:"highlight",
+	    clipboard:false,
+	    clipboardCopySelector:"table",
+	    clipboardPasteAction:"insert", // insert, update, replace
+	    placeholder:"등록 팝업에서 휴대폰을 선택 후 확인해주세요.", //fit columns to width of table (optional)
+	 	columns:[ //Define Table Columns
+		 	{title:"이름", field:"name", hozAlign:"center", headerHozAlign: "center", width:125},
+		 	{title:"휴대폰", field:"phone", hozAlign:"center", headerHozAlign: "center", width:158},
+		 	{title:"미등록 결과", field:"result", hozAlign:"center", headerHozAlign: "center", width:125}
+	 	]
+	});
+	
 
 	//Tabulator AJAX Data Loading
 	$tableExcel = new Tabulator("#tabulator_excel", {
@@ -80,13 +98,20 @@
 		$tableExcel.clearData();
 		$("#excelRowTotCnt").text(0); //총건수 수정
 		$("#excelRowDupCnt").text(0); //중복건수 수정
+		$("#excelRowErrorCnt").text(0); //중복건수 수정
 		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
 		addrMassDupliSaveList = null;
 		
-		$("#btnAddrMassDupli").hide();
-		$('#tableExcelDupliBtn').hide();
-// 		$("#btnAddrMassSaveDupli").hide();
-// 		$('#closeBtn').click();
+		
+		// popup 영역
+		$tableError.clearData();
+		// 중복 카운트
+		$("#errorPopDupCnt").text(0);
+		// 에러 카운트
+		$("#errorPopErrorCnt").text(0);
+		// 
+		$("#errorPopTotCnt").text(0);
+
 		
 	}
     
@@ -133,7 +158,7 @@
 	 $('.field-selector').on('change', function() {
 		fn_loadAddActive();
 
-		setTimeout(() => { // 파일 읽기 완료 후 실행되도록 함
+		setTimeout(() => { 
 			var selectedFields = [];
 			var isDuplicate = false;
 	
@@ -169,6 +194,8 @@
 			fn_loadRemoveActive();
 
 		}, 0); // 지연 없이 즉시 실행되도록 0ms 지연을 설정
+		
+		
 	});
 	
   
@@ -457,56 +484,102 @@
 	$objTabul.setData(updatedData);
 }
 
+
 /**
  * @ 핸드폰 중복 데이터
  * */
 function fn_phoneDupl($objTabul) {
-	    var data = $objTabul.getData();
-	    var uniquePhones = new Set();
-	    var dupliPhoneDataRealList = [];
-	    var rowsToKeep = [];
-	    var rowsToDelete = [];
-	    var phoneNumberChk = false;
+	 
+	$tableError.clearData();
+	
+	var data = $objTabul.getData();
+	var phoneNumberChk = false;
+	var existingNumbers = new Set(); // 배열에서 Set으로 변경
+	
+	let errorCount = 0; // 중복 번호 개수를 저장할 변수
+	let duplicateCount = 0; // 중복 번호 개수를 저장할 변수
+	
+	const errors = [];  // 오류 데이터를 저장할 배열
+	const duplicates = [];  // 오류 데이터를 저장할 배열
+	const newData = []; // 유효한 데이터만 저장할 새로운 배열
+	
+	data.forEach((row, index) => {
+		if (index % 10000 === 0) {
+		    console.log('i : ', index);
+		}
+		
+		const number = row.addrPhoneNo;
+		const formattedNumber = formatPhoneNumber(number); // 번호 표준화
+		const cleanedNumber = formattedNumber.replace(/[^0-9]/g, ''); // 숫자만 남김
+		
+		if (!existingNumbers.has(cleanedNumber)) { // 중복 번호 체크
+		    if (isValidPhoneNumber(formattedNumber)) { // 유효성 검사
+		        row.addrPhoneNo = formattedNumber;
+		        existingNumbers.add(cleanedNumber); // 추가된 번호를 기존 목록에 추가
+		        newData.push(row); // 유효한 데이터만 새로운 배열에 추가
+		    } else {
+		        // 오류: 유효성 통과 못함
+		        errorCount++;
+		        $tableError.addRow({ 
+		            name: row.addrNm, // 이름
+		            phone: row.addrPhoneNo, // 폰번호
+		            result: "오류" // 결과 메시지 추가
+		        });
+		        errors.push({ 
+		            name: row.addrNm, // 이름
+		            phone: row.addrPhoneNo, // 폰번호
+		            result: "오류" // 결과 메시지 추가
+		        });
+		    }
+		} else {
+		    // 중복
+		    duplicateCount++; // 중복 번호가 발견될 때마다 카운트를 증가
+		    $tableError.addRow({ 
+		        name: row.addrNm, // 이름
+		        phone: row.addrPhoneNo, // 폰번호
+		        result: "중복" // 결과 메시지 추가
+		    });
+		    duplicates.push({ 
+		       name: row.addrNm, // 이름
+		       phone: row.addrPhoneNo, // 폰번호
+		       result: "중복" // 결과 메시지 추가
+		   });
+		}
+	});
+	
+	// data 배열을 newData 배열로 대체
+	data = newData;
+	
 
-
-	    
-	    data.forEach((row, index) => {
-
-	        if (!isValidKoreanPhoneNumber(row.addrPhoneNo)) {
-	        	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 확인해 주세요');
-	    }
-
-	    $("#excelRowDupCnt").text(dupliPhoneDataRealList.length);
-
-	    if (dupliPhoneDataRealList.length > 0) {
-//	        alert("중복된 휴대폰 번호가 있습니다: \n" + duplicatePhones.join(", "));
-	    	makeAddrMassDupliPop(dupliPhoneDataRealList);
-	    }
-
-	    // 중복된 행 삭제
-	    rowsToDelete.reverse().forEach(index => {
-	        $objTabul.deleteRow(index);
-	    });
-
-	    // 고유한 데이터만 남기고 테이블 업데이트
-	    $objTabul.setData(rowsToKeep);
-	    $("#excelRowTotCnt").text(rowsToKeep.length);
+	// 수정된 데이터로 테이블 업데이트
+	$objTabul.setData(data);
+	// 오류 총 카운트
+    $("#excelRowTotCnt").text($objTabul.getDataCount());
+	// 중복 카운트
+	$("#excelRowDupCnt").text(duplicateCount);
+	// 에러 카운트
+	$("#excelRowErrorCnt").text(errorCount);
+	
+	// popup 영역
+	// 중복 카운트
+	$("#errorPopDupCnt").text(duplicateCount);
+	// 에러 카운트
+	$("#errorPopErrorCnt").text(errorCount);
+	// 
+	$("#errorPopTotCnt").text(duplicateCount+errorCount);
+	
+	
+	var errorData = errors.concat(duplicates);
+	 // 오류 및 중복 데이터를 한 번에 추가
+	$tableError.setData(errorData);
+	
+	if(errorCount > 0){
+		alert('휴대폰 형식에 맞지 않는 데이터는 삭제 후 업로드 됩니다.\nex) 발송불가 특수문자, 자릿수 오류 등');
 	}
-
+	
+	
+	
+}
 
 function fn_dupliPopupShow(){
 
@@ -588,6 +661,39 @@
 		
 	</div>		
 </div>
+
+
+<!-- 주소록 상세 결과 팝업 data-tooltip:adr_popup14 -->
+	<div class="tooltip-wrap">
+		<div class="popup-com adr_layer adr_popup14" tabindex="0" data-tooltip-con="adr_popup14" data-focus="adr_popup14" data-focus-prev="adr_popu14-close" style="width: 450px;">
+			<div class="popup_heading">
+				<p>주소록 상세 결과</p>
+				<button type="button" class="tooltip-close" data-focus="adr_popup14-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+			</div>
+			<div class="layer_in" style="padding:30px 20px;">
+				<div class="table_top">
+					<p>
+						총 <span class="c_e40000" id="errorPopTotCnt">0</span>건 
+						/ 중복 <span class="c_002c9a" id="errorPopDupCnt">0</span>건
+						/ 오류 <span class="c_002c9a" id="errorPopErrorCnt">0</span>건</p>
+						<button type="button" class="excel_btn btnType" id="errorExcelBtn"><i class="downroad"></i>엑셀 다운로드</button>
+				</div>
+				<div class="tb_wrap adr_list" id="tabulator_error">
+				<!-- $tableError 참고  -->
+                </div>
+                <ul class="cf_text_ul">
+                    <li>*중복번호는 하나의 번호만 등록됩니다.</li>
+                    <li>*휴대폰 형식에 맞지 않는 데이터는 삭제 후 업로드 됩니다.</li>
+                    <li>ex) 발송불가 특수문자, 자릿수 오류 등</li>
+                </ul>
+                <div class="popup_btn_wrap2">
+<!--                     <button type="button">저장</button> -->
+                    <button type="button" class="tooltip-close" data-focus="adr_popup14-close" data-focus-next="adr_popup14">닫기</button>                      
+                </div>
+			</div>
+		</div>
+	</div>
+
 <!--// 중복전화번호 팝업 -->
 				<div class="popup_heading">
 					<p>엑셀 불러오기</p>
@@ -605,19 +711,11 @@
 					<!-- 엑셀입력 -->
 					<div class="popCont current pop_more_cont" id="popCont_1">
 						<div class="titBox">
-							<p>- 엑셀(EXCEL) 파일로 주소록을 한 번에 최대 2만건까지 등록하여 간편하게 발송 및 관리하실 수 있습니다.</p>
-							<p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 작성하셔야 합니다.</p>
-							<p>  &nbsp;&nbsp;※ 주소록 관리 메뉴에서 다운로드 받으신 엑셀 파일 또한 업로드 양식에 맞추어 작성하셔야 하며, </p>
-							<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;주소록에 이미 등록된 휴대폰 번호는 업데이트 되지 않으므로 기존 주소록에서 해당 휴대폰 번호를 삭제한 후 재등록해 주시기 바랍니다.</p>
-							<p>- 쉼표(,), 구분선(|), 역슬래시(\, ₩), 작은따옴표('), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
-							<p>- 휴대폰 번호는 필수입력 항목입니다.</p>
-							<p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
+							<p>- 주소록은 한 번에 최대 30만건까지 등록(EXCEL파일, 최대용량 3MB) 가능합니다. </p>
 							<p>- 엑셀 파일에 비밀번호 설정, 제한된 보기, 수식 등이 설정되어 있는 경우 업로드가 불가합니다.</p>
-							<p>- 이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte까지 입력 가능합니다.</p>
-							<p>- 첨부가능 파일 : xlsx, xls(최대용량 3MB)</p>
-							<p>- ‘오류 검사’를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.</p>
-							<p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-							<button type="button" class="excel_btn" onclick="location.href='/download/addr/주소록_대량등록.xlsx'"><i class="downroad"></i>샘플파일 다운로드</button>
+							<p>- 구분선(|), 역슬래시(\, ₩), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
+							<p>- 이름 200byte, [*1*]~[*4*] 200byte, 메모 250byte까지 입력 가능합니다.</p>
+							<p>- 주소록 등록이 어려우신 경우에는 <a href="<c:url value='/web/mjon/addragency/selectAddrAgencyList.do'/>" style="font-weight: bold; color: blue;">주소록 입력대행</a> 메뉴를 이용하실 수 있습니다. </p>
 						</div>
 						<div class="pop_more_wrap">
 								<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
@@ -661,9 +759,13 @@
 					
 					<div class="excel_middle2">
 						<p>
-							총 <span class="c_e40000 fwBold" id="excelRowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="excelRowDupCnt">0</span>건
-							&nbsp; 
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" id="tableExcelDupliBtn">중복번호</button>
+							총 <span class="c_e40000 fwBold" id="excelRowTotCnt">0</span>건 
+							/ 중복 <span class="c_002c9a fwBold" id="excelRowDupCnt">0</span>건
+							/ 오류 <span class="c_002c9a fwBold" id="excelRowErrorCnt">0</span>건
+							<button type="button" class="btn_list_detail" data-tooltip="adr_popup14"><img src="/publish/images/search.png"></button>
+						</p>
+<!-- 							&nbsp;  -->
+<!-- 							<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>
@@ -779,27 +881,21 @@
 							<div>
 								<button type="button" id="allDel"><i class="remove_img"></i>전체삭제</button>
 								<button type="button" id="in_select_del"><i class="remove_img"></i>선택삭제</button>
-								<button type="button" id="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
-								<button type="button" id="check_validity">오류 검사 <i></i></button>
-								<div class="error_hover_cont send_hover_cont addr_hover_cont">
-									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
-									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
-								</div>
 							</div>
 	
 						</div>
 					</div><!--// 공통 -->     
 	
 					<!-- 붙여놓기 설명 -->
-	                <div class="req_area">
-	                  	<div class="text_box">
-	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
-							- 휴대폰 번호는 필수입력 항목입니다.<br>
-							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
-							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
-							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
-						</div>
-	                </div>
+<!-- 	                <div class="req_area"> -->
+<!-- 	                  	<div class="text_box"> -->
+<!-- 	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br> -->
+<!-- 							- 휴대폰 번호는 필수입력 항목입니다.<br> -->
+<!-- 							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br> -->
+<!-- 							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br> -->
+<!-- 							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다. -->
+<!-- 						</div> -->
+<!-- 	                </div> -->
 					<div class="popup_btn_wrap2" style="margin: 0 auto 30px auto;">
 						<button type="button" id="btnAddrMassReg">추가</button>
 						<button type="button" id="btnAddrMassClose" class="tooltip-close" data-focus="adr_popup01-close"  data-focus-next="popup02">닫기</button>                      
 
src/main/webapp/js/web/addr/cmn.js (added)
+++ src/main/webapp/js/web/addr/cmn.js
@@ -0,0 +1,48 @@
+
+
+// 유효한 번호인지 확인하는 함수
+function isValidPhoneNumber(phone) {
+    // 숫자만 추출
+    const numberOnly = phone.replace(/\D/g, '');
+
+    // 유효한 형식 체크
+    return (
+        (numberOnly.startsWith("010") && numberOnly.length === 11) ||    // 010으로 시작하고 11자리
+        (/^01[1-9]/.test(numberOnly) && numberOnly.length === 10) ||    // 011~019로 시작하고 10자리
+        (numberOnly.startsWith("050") && numberOnly.length === 12)      // 050X로 시작하고 12자리
+    );
+}
+
+// 유효성 후 포맷 맞추는 함수
+function formatPhoneNumber(phone) {
+    if (typeof phone !== 'string') {
+        phone = String(phone); // phone을 문자열로 변환
+    }
+    // 숫자만 남기기
+    let cleanedPhone = phone.replace(/\D/g, ''); // 모든 숫자가 아닌 문자 제거
+//    console.log('cleanedPhone : ', cleanedPhone);
+
+    // 앞에 0이 추가된 경우 처리
+    if (cleanedPhone.length === 10 && cleanedPhone.startsWith("10")) {
+        // 10으로 시작하는 10자리 번호는 앞에 0을 추가하여 11자리로 만듦
+        cleanedPhone = "0" + cleanedPhone;
+    }else if (cleanedPhone.length === 9 && (cleanedPhone.startsWith("11") || cleanedPhone.startsWith("16") || cleanedPhone.startsWith("19"))) {
+        // 11, 16, 19로 시작하는 9자리 번호는 앞에 0을 추가하여 10자리로 만듦
+        cleanedPhone = "0" + cleanedPhone;
+    }
+
+    // 번호 형식 변환
+    if (cleanedPhone.startsWith("010") && cleanedPhone.length === 11) {
+        // 010-1234-5678 형식
+        return cleanedPhone.substring(0, 3) + '-' + cleanedPhone.substring(3, 7) + '-' + cleanedPhone.substring(7);
+    } else if ((/^01[1-9]/.test(cleanedPhone)) && cleanedPhone.length === 10) {
+        // 01X-123-5678 형식
+        return cleanedPhone.substring(0, 3) + '-' + cleanedPhone.substring(3, 6) + '-' + cleanedPhone.substring(6);
+    } else if (cleanedPhone.startsWith("050") && cleanedPhone.length === 12) {
+        // 050X-1234-5678 형식
+        return cleanedPhone.substring(0, 4) + '-' + cleanedPhone.substring(4, 8) + '-' + cleanedPhone.substring(8);
+    }
+
+	// 원본 반환 (표준 형식으로 변환되지 않으면)
+	return phone;
+}
src/main/webapp/js/web/addr/event.js
--- src/main/webapp/js/web/addr/event.js
+++ src/main/webapp/js/web/addr/event.js
@@ -146,9 +146,14 @@
 		 // 오류 및 중복 데이터를 한 번에 추가
 	    $tableError.setData(errorData);
 	    
+	    if(errorCount > 0){
+	    	alert('휴대폰 형식에 맞지 않는 데이터는 삭제 후 업로드 됩니다.\nex) 발송불가 특수문자, 자릿수 오류 등');
+	    }
+
+	    
 
 	}
-	 
+	 /*
 	function fn_phoneDupl_old($objTabul) {
 	    var data = $objTabul.getData();
 	    var uniquePhones = new Set();
@@ -196,7 +201,7 @@
 	    // 고유한 데이터만 남기고 테이블 업데이트
 	    $objTabul.setData(rowsToKeep);
 	    $(tabluC+" #rowTotCnt").text(rowsToKeep.length);
-	}
+	}*/
 
 		//받는사람 전체삭제 버튼 처리
 		$('.all_del').click(function(){
@@ -312,111 +317,24 @@
 	}
 }); 
 
-//
-//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();
-	
-}
-
-function fn_dupliPopupShow(){
-
-	var showId = '#'+fn_utils_getTabulatorNm()
-	console.log('showId : ', showId);
-	$(showId+'DupliBtn').show()
-}
 
 
-
-
-// 유효한 번호인지 확인하는 함수
-function isValidPhoneNumber(phone) {
-    // 숫자만 추출
-    const numberOnly = phone.replace(/\D/g, '');
-
-    // 유효한 형식 체크
-    return (
-        (numberOnly.startsWith("010") && numberOnly.length === 11) ||    // 010으로 시작하고 11자리
-        (/^01[1-9]/.test(numberOnly) && numberOnly.length === 10) ||    // 011~019로 시작하고 10자리
-        (numberOnly.startsWith("050") && numberOnly.length === 12)      // 050X로 시작하고 12자리
-    );
-}
-
-// 유효성 후 포맷 맞추는 함수
-function formatPhoneNumber(phone) {
-    if (typeof phone !== 'string') {
-        phone = String(phone); // phone을 문자열로 변환
-    }
-    // 숫자만 남기기
-    let cleanedPhone = phone.replace(/\D/g, ''); // 모든 숫자가 아닌 문자 제거
-//    console.log('cleanedPhone : ', cleanedPhone);
-
-    // 앞에 0이 추가된 경우 처리
-    if (cleanedPhone.length === 10 && cleanedPhone.startsWith("10")) {
-        // 10으로 시작하는 10자리 번호는 앞에 0을 추가하여 11자리로 만듦
-        cleanedPhone = "0" + cleanedPhone;
-    }else if (cleanedPhone.length === 9 && (cleanedPhone.startsWith("11") || cleanedPhone.startsWith("16") || cleanedPhone.startsWith("19"))) {
-        // 11, 16, 19로 시작하는 9자리 번호는 앞에 0을 추가하여 10자리로 만듦
-        cleanedPhone = "0" + cleanedPhone;
-    }
-
-    // 번호 형식 변환
-    if (cleanedPhone.startsWith("010") && cleanedPhone.length === 11) {
-        // 010-1234-5678 형식
-        return cleanedPhone.substring(0, 3) + '-' + cleanedPhone.substring(3, 7) + '-' + cleanedPhone.substring(7);
-    } else if ((/^01[1-9]/.test(cleanedPhone)) && cleanedPhone.length === 10) {
-        // 01X-123-5678 형식
-        return cleanedPhone.substring(0, 3) + '-' + cleanedPhone.substring(3, 6) + '-' + cleanedPhone.substring(6);
-    } else if (cleanedPhone.startsWith("050") && cleanedPhone.length === 12) {
-        // 050X-1234-5678 형식
-        return cleanedPhone.substring(0, 4) + '-' + cleanedPhone.substring(4, 8) + '-' + cleanedPhone.substring(8);
-    }
-
-	// 원본 반환 (표준 형식으로 변환되지 않으면)
-	return phone;
-}
 
 // 주소록 에러결과 초기화
 function errorPopClean(){
 
     // popup 영역
 	$tableError.clearData();
+	
+
     // 중복 카운트
     $("#errorPopDupCnt").text(0);
     // 에러 카운트
     $("#errorPopErrorCnt").text(0);
     // 
     $("#errorPopTotCnt").text(0);
+	
+	
 }
 
 
src/main/webapp/js/web/addr/init.js
--- src/main/webapp/js/web/addr/init.js
+++ src/main/webapp/js/web/addr/init.js
@@ -97,7 +97,82 @@
 		},
 	});
 	
+	
+	
+	
+	var tableData = [];
+	for (var i = 0; i < 1000; i++) {
+		tableData.push({A: "", B: "", C: "", D: "", E: "", F: "", G: ""});
+	}
 
+	// 테이블 초기화
+	$tableSelf = new Tabulator("#tabulator_self", {
+		height: "255px",
+		width: "100%",
+		layout: "fitColumns",
+		clipboardPasteAction: "update",
+		keybindings: {
+			"navRight": "tab", // Tab 키를 누르면 오른쪽 셀로 이동
+			"navLeft": "shift+tab",
+			"editNext": false // Tab 키를 누를 때 편집 모드를 종료하지 않도록 설정
+		},
+		data: tableData,
+		columns: [
+			{formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+				cell.getRow().toggleSelect();
+			}},
+			{formatter:"rownum", hozAlign:"center" ,title:"No", headerHozAlign:"center", width:40},
+			{title:"이름", field:"addrNm", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"},
+			{title:"휴대폰", field:"addrPhoneNo", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"
+				, formatter:function(cell, formatterParams){
+					var value = cell.getValue();
+
+					fn_selfUpdataCount();
+//					if(value.indexOf("o") > 0){
+//						return "<span style='color:#3FB449; font-weight:bold;'>" + value + "</span>";
+//					}else{
+//						return value;
+//					}
+					return value;
+			}},
+			{title:"[*1*]", field:"addrInfo1", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"},
+			{title:"[*2*]", field:"addrInfo2", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"},
+			{title:"[*3*]", field:"addrInfo3", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"},
+			{title:"[*4*]", field:"addrInfo4", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"},
+			{title:"메모", field:"addrComment", hozAlign:"center", headerHozAlign: "center", width:119, validator:["maxLength:100"], editor:"input"}
+		],
+		navigation: true // 키보드 탐색 활성화
+	});
+	// 사용자 정의 필터 설정: addrPhoneNo가 빈 값이나 undefined가 아닌 경우
+//	$tableSelf.setFilter(function(data, filterParams) {
+//		var value = data.addrPhoneNo;
+//		return value !== "" && value !== undefined; // 빈 문자열과 undefined가 아닌 경우
+//	});
+
+//	// 테이블의 셀 편집 후 이벤트를 등록
+//	document.addEventListener('keydown', function(e) {
+//		if(e.key === "Tab") {
+//			e.preventDefault();
+//			let selectedCells = $tableSelf.getSelectedCells();
+//			let cell = selectedCells[selectedCells.length - 1]; // 현재 선택된 셀 가져오기
+//
+//			if (cell) {
+//				let row = cell.getRow();
+//				let table = cell.getTable();
+//				let nextCell = cell.getNextCell("tab");
+//
+//				if (!nextCell && row === table.getRows().slice(-1)[0]) {
+//					// 현재 셀이 마지막 행의 마지막 셀인 경우
+//					table.addRow({A: "", B: "", C: "", D: "", E: "", F: "", G: ""}, false).then(function() {
+//						table.scrollToRow(table.getRows().slice(-1)[0]); // 새로 추가된 행으로 스크롤
+//						table.setActiveCell(table.getRows().slice(-1)[0].getCell("A")); // 새로운 행의 첫 번째 셀에 포커스
+//					});
+//				}
+//			}
+//		}
+//	});
+//	
+	
 	//Tabulator AJAX Data Loading
 	$tableError = new Tabulator("#tabulator_error", {
 		height:"255px",
Add a comment
List