wyh 2024-12-26
XSS 변경관련 기능 추가
@4478e4880b4c0d934aeda6e320690afd6d60986b
src/main/webapp/js/MJUtill.js
--- src/main/webapp/js/MJUtill.js
+++ src/main/webapp/js/MJUtill.js
@@ -1,1095 +1,1109 @@
-/**
- * 휴대폰번호 유효성 체크
- * true, false 반환
- * 대시 유무 상관없음
- */
-function checkHpNum(str) {
-	
-	var regExp = /^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
-	//var regExp = /^(01[016789]{1}|070|02|0[3-9]{1}[0-9]{1})-?[0-9]{3,4}-?[0-9]{4}$/; //지역번호(일반전화) 형식까지 체크해주는 정규식
-	return regExp.test(str);
-}
-
-/**
- * 휴대폰번호만 유효성 체크
- * true, false 반환
- * 대시 유무 상관없음
- */
-function checkOnlyHpNum(str) {
-	
-	//var regExp = /^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
-	var regExp = /^(01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/; //지역번호(일반전화) 형식까지 체크해주는 정규식
-	return regExp.test(str);
-}
-
-/**
- * 팩스 번호 유효성 체크
- * true, false 반환
- * 앞 3자리를 체크 함
- * -- 전국 지역번호
- * 	02	서울특별시
-	031	경기도
-	032	인천광역시
-	033	강원도
-	041	충청남도
-	042	대전광역시
-	043	충청북도
-	044	세종특별자치시
-	051	부산광역시
-	052	울산광역시
-	053	대구광역시
-	054	경상북도
-	055	경상남도
-	061	전라남도
-	062	광주광역시
-	063	전라북도
-	064	제주특별자치도
-	
-	-- 타사부가번호
-	030*
-	050*
-	060
-	070
-	080
-	1**
-	
-	위 번호로 시작하는 팩스 번호만 허용함.
- */
-	function checkFaxNum(str) {
-		str = removeDash(str);
-		var subNum = str.substring(0,3);
-		var regExp = /^(02\d|03[1-3]|04[1-4]|05[1-5]|06[1-4]|030|050|060|070|080|1\d{2})$/; // 수정된 정규식
-		return regExp.test(subNum);
-	}
-
-/*
- * 일반전화 유효성 체크
- * true, false 반환
- * 
- * */
-function checkNorPhoneNum(str){
-	
-	var regExp = /^(02|0[3-9]{1}[0-9]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
-	
-	/**
-	 * 기간통신사업자 공통 부가서비스 번호 체크
-	 * 번호 사업자
-		1588,1577,1899 KT
-		1544,1644,1661,1800 ,1833 LG유플러스
-		1566,1600,1670 SK브로드밴드
-		1688,1666 온세텔레콤
-		1599 SK텔링크
-		1877 한국케이블텔레콤
-		1855 CJ헬로비전
-		1661 alleh KT
-	 * 
-	 * */
-	
-	if(str.substring(0,2) == "15"){
-		
-		regExp = /^(15[0-9]{2})-?[0-9]{4}$/;
-		
-	}else if(str.substring(0,2) == "16"){
-		
-		regExp = /^(16[0-9]{2})-?[0-9]{4}$/;
-		
-	}else if(str.substring(0,2) == "18"){
-		
-		regExp = /^(18[0-9]{2})-?[0-9]{4}$/;
-		
-	}
-	
-	return regExp.test(str);
-}
-
-/*
- * 일반전화 / 핸드폰 번호 종류 확인
- * true, false 반환
- * 
- * */
-function checkTelHpType(str){
-	
-	var subCall = str.substring(0,3);	// 전화번호 앞 3자리 받아오기
-	var strType = "";				 	// 결과 반환
-	
-	if(subCall != '010' 
-		&& subCall != '011' 
-		&& subCall != '016' 
-		&& subCall != '017'){//일반전화 번호이면
-		
-		strType = "Tel";
-		
-	}else{
-		
-		strType = "Hp";
-	}
-	
-	return strType;
-}
-
-
-/**
- * 휴대폰번호 대시('-') 제거
- */
-/**
- * 휴대폰번호에서 숫자가 아닌 문자를 모두 제거
- */
-function removeDash(str) {
-	return str.replace(/\D/g, ''); // 숫자 이외의 문자 제거
-}
-
-
-/**
- * 휴대폰번호 대시('-') 추가
- * 대시 유무 상관없음
- * 유효성 맞지 않을시 변환안됨.
- */
-function addDash(str) {
-	return str.replace(/(^01[016789]{1}|070)([0-9]{3}|[0-9]{4})([0-9]{4})$/,"$1-$2-$3").replace("--", "-");
-}
-
-/**
- * ReplaceAll (by javascript prototype)
- * 정규식 패턴에서 \는 두 개 사용 
- */
-String.prototype.replaceAll = function(pattern, changeString) {
-	var regExp = new RegExp(pattern, 'g');
-	return this.replace(regExp, changeString);
-};
-
-/**
- * 이메일 유효성 체크
- * true, false 반환
- * 
- */
-function checkEmail(str) {
-	var regExp = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+/;
-	return regExp.test(str);
-}
-
-/**
- * XSS 체크하기
- * 
- * 
- */
-
-function XSSCheck(str, level) {
-    if (level == undefined || level == 0) {
-        str = str.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,"");
-    } else if (level != undefined && level == 1) {
-        str = str.replace(/\</g, "&lt;");
-        str = str.replace(/\>/g, "&gt;");
-    }
-    return str;
-}
-
-
-//숫자 천단위 콤마 찍어주기
-function numberWithCommas(x) { 
-	return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 
-}
-
-function comma(num){ 
-	var len, point, str; 
-	num = num + ""; 
-	point = num.length % 3; 
-	len = num.length; 
-	str = num.substring(0, point); 
-	while (point < len) { 
-		if (str != "") str += ","; 
-		str += num.substring(point, point + 3); 
-		point += 3; 
-		} 
-	return str; 
-}
-
-
-function totalPriceSum(totRows){
-	
-	var contents = $('#smsTxtArea').val();	//입력 문자 내용
-	var msgType = conTypeCheck(contents);	//입력 문자 길이 체크
-	var collNumCnt = parseInt(totRows); 	//받는사람 건수
-	var price = 0;							//개별 건수 금액
-	var totalPrice = 0;						//전체 금액
-	//var strDot = [];
-	//var subPrice = "";
-	//var spPrice = "";
-	var totalStr = "0";							//전체 합계 금액
-	var userMoney = $('#hdUserMoney').text(); 	//헤더 영역 보유 금액 불러오기
-	var msgCnt = 0;								//발송 가능 문자 건수
-	var imgCnt = $("#imgCnt").val(); // 현재 페이지에 첨부된 이미지 갯수
-	
-	if(!userMoney > 0){
-		
-		userMoney = 0;
-		
-	}
-	//헤더 영역 보유 금액 콤마 문자 제거
-	if(userMoney != ''){
-		
-		userMoney = userMoney.replaceAll("," , "");
-		
-	}
-	
-	/*if(msgType == "P"){//그림문자
-		
-		//그림 이미지 갯수에 따른 금액 계산
-		if(imgCnt > 2){//그림 3장일경우
-			price = parseFloat($('#p3Price').val());
-		}else if(imgCnt > 1){//그림 2장일경우
-			price = parseFloat($('#p2Price').val());
-		}else{//그림 1장일 경우
-			price = parseFloat($('#pPrice').val());
-		}
-		
-		msgCnt = parseFloat(userMoney) / price;
-	
-	}else if(msgType == "M"){//장문 문자
-		
-		price = parseFloat($('#mPrice').val());
-		msgCnt = parseFloat(userMoney) / price;
-		
-	}else{//단문문자
-		
-		price = parseFloat($('#sPrice').val());
-		msgCnt = parseFloat(userMoney) / price;
-	
-	}*/
-	
-	//금액 소수점 제거 하여 적용 20220623 소수점 버림 처리
-	if(msgType == "P"){//그림문자
-		
-		//그림 이미지 갯수에 따른 금액 계산
-		if(imgCnt > 2){//그림 3장일경우
-			price = $('#p3Price').val();
-		}else if(imgCnt > 1){//그림 2장일경우
-			price = $('#p2Price').val();
-		}else{//그림 1장일 경우
-			price = $('#pPrice').val();
-		}
-		
-		msgCnt = userMoney / price;
-	
-	}else if(msgType == "M"){//장문 문자
-		
-		price = $('#mPrice').val();
-		msgCnt = userMoney / price;
-		
-	}else{//단문문자
-		
-		price = $('#sPrice').val();
-		msgCnt = userMoney / price;
-	
-	}
-	
-	totalPrice = price * collNumCnt;
-	
-	// 소수점 첫째자리 까지 표시
-	totalPrice = totalPrice.toFixed(1);
-	
-	if(totalPrice > 0){
-		
-		//totalStr = totalPrice.toFixed(2);
-		totalStr = totalPrice;
-		
-	}
-	
-	//개별 문자 단가 파라미터에 입력
-	$('#eachPrice').val(numberWithCommas(price));
-	
-	
-	//결제금액 합계 파라이터에 입력
-	$('#totPrice').val(numberWithCommas(totalStr));
-	
-	//결제금액 합계 화면에 표시
-	$('#totalPriceTxt').text(numberWithCommas(totalStr));
-	
-	//현재 문자 전송 가능 갯수 표시
-	$('.nowMsgCnt').text(numberWithCommas(msgCnt.toFixed()));
-	
-	if(msgType == 'P'){
-		
-		$('#nowMsgType').text("그림");
-		
-	}else if(msgType == 'M'){
-		
-		$('#nowMsgType').text("장문");
-	
-	}else{
-		
-		$('#nowMsgType').text("단문");
-		
-	}
-	
-	$('#repPriceTxt').hide();
-	
-	return totalStr;
-	
-}
-
-function replTotalPriceSum(msg_short, msg_long, totRows){
-	
-	var shortPrice = 0;		//단문 개별 건수 금액
-	var longPrice = 0;		//장문 개별 건수 금액
-	var imgPrice = 0;		//그림문자 개별 건수 금액
-	var totalPrice = 0;		//전체 금액
-	var totalStr = "0";		//전체 합계 금액
-	var contents = $('#smsTxtArea').val();	//입력 문자 내용
-	var msgType = conTypeCheck(contents);	//입력 문자 길이 체크
-	var userMoney = $('#hdUserMoney').text(); 	//헤더 영역 보유 금액 불러오기
-	var msgCnt = 0;								//발송 가능 문자 건수
-	var imgCnt = $("#imgCnt").val(); // 현재 페이지에 첨부된 이미지 갯수
-	var collNumCnt = parseInt(totRows); 	//받는사람 건수
-	var totalCntTxt = "";
-	
-	//금액 소수점 제거하여 금액 처리
-	if(msgType == "P"){//그림문자
-		
-		//그림 이미지 갯수에 따른 금액 계산
-		if(imgCnt > 2){//그림 3장일경우
-			imgPrice = $('#p3Price').val();
-		}else if(imgCnt > 1){//그림 2장일경우
-			imgPrice = $('#p2Price').val();
-			
-		}else{//그림 1장일 경우
-			imgPrice = $('#pPrice').val();
-		}
-		
-		msgCnt = userMoney.replaceAll(",","") / imgPrice;
-		
-		var imgTotPrice = imgPrice * collNumCnt; 
-		imgTotPrice = Math.round(imgTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
-		
-		totalPrice =  totalPrice + imgTotPrice;
-		
-		//input hidden 개별 문자 단가 파라미터에 입력
-		$('#eachPrice').val(numberWithCommas(imgPrice));
-		
-		//input hidden 결제금액 합계 파라이터에 입력
-		$('#totPrice').val(numberWithCommas(totalStr));
-		
-		//결제금액 합계 화면에 표시
-		$('#totalPriceTxt').text(numberWithCommas(totalStr));
-		
-		//현재 문자 전송 가능 갯수 표시
-		$('.nowMsgCnt').text(numberWithCommas(msgCnt.toFixed()));
-		
-		//변환문자 건수 내용 표기
-		totalCntTxt = "그림 : <strong>" + numberWithCommas(totRows) + "</strong> 건";;
-		
-	}else{
-		
-		if(msg_long > 0){//장문 문자
-			
-			longPrice = $('#mPrice').val();
-			var longTotPrice = longPrice * msg_long; 
-			longTotPrice = Math.round(longTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
-			
-			totalPrice = totalPrice + longTotPrice;
-			
-			//input hidden 개별 문자 단가 파라미터에 입력
-			$('#eachPrice').val(numberWithCommas(longPrice));
-			
-			//변환문자 건수 내용 표기
-			totalCntTxt = "장문 : <strong>" + numberWithCommas(msg_long) + "</strong> 건";
-			
-			//변환장문 건수 Hidden 폼에 넣어주기
-			$('#longMsgCnt').val(msg_long);
-			
-		}else{
-			
-			//변환장문 건수 Hidden 폼에 넣어주기
-			$('#longMsgCnt').val(msg_long);
-			
-		}
-
-		if(msg_short > 0){//단문문자
-			
-			shortPrice = $('#sPrice').val();
-			var shortTotPrice = shortPrice * msg_short; 
-			shortTotPrice = Math.round(shortTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
-
-			totalPrice = totalPrice + shortTotPrice;
-			
-			//input hidden 개별 문자 단가 파라미터에 입력
-			$('#eachPrice').val(numberWithCommas(shortPrice));
-			
-			if(msg_long > 0){
-				
-				//변환문자 건수 내용 표기
-				totalCntTxt = totalCntTxt + "/ 단문 : <strong>" + numberWithCommas(msg_short) + "</strong> 건";
-				
-			}else{
-				
-				//변환문자 건수 내용 표기
-				totalCntTxt = "단문 : <strong>" + numberWithCommas(msg_short) + "</strong> 건";
-				
-			}
-			
-			//변환단문 건수 Hidden 폼에 넣어주기
-			$('#shortMsgCnt').val(msg_short);
-		
-		}else{
-			
-			//변환단문 건수 Hidden 폼에 넣어주기
-			$('#shortMsgCnt').val(msg_short);
-			
-		}
-		
-	}
-	
-	
-	if(totalPrice > 0){
-		
-		//totalStr = totalPrice.toFixed(2);
-		totalStr = totalPrice;
-		
-	}
-	
-	//input hidden 결제금액 합계 파라이터에 입력
-	$('#totPrice').val(numberWithCommas(totalStr));
-	
-	//결제금액 합계 화면에 표시
-	$('#totalPriceTxt').text(numberWithCommas(totalStr));
-	
-	//결제금액 합계 파라이터에 입력
-	$('#totPrice').val(numberWithCommas(totalStr));
-	
-	//특정문구 일괄 변환으로 인한 단/장문 건수 표시
-	$('#repPriceTxt').show();
-	$('#repPriceTxt').html("(" + totalCntTxt + ")");
-	
-	if(msgType == 'P'){
-		
-		$('#nowMsgType').text("그림");
-		
-	}else if(msgType == 'M'){
-		
-		$('#nowMsgType').text("장문");
-	
-	}else{
-		
-		$('#nowMsgType').text("단문");
-		
-	}
-	
-	return totalStr;
-	
-}
-
-//예약 날짜 체크 함수
-function getGday(date) {												/*	현재와 이전 날자의 차이를 년-개월-일 형태로 가져오기 	*/
-	var now = new Date().getTime();								// 현재 날짜를 시간으로 변환
-	var d = new Date(date.substring(0, 10)).getTime();			// 이전 날짜를 시간으로 변환 
-	var gap = now - d;											// 현재 날짜와 이전 날짜의 차이를 밀리초 시간으로 구한다.
-	var result = Math.floor(gap/(1000 * 60 * 60 * 24));			// 날짜 차이를 일수로 계산
-	
-	var year = Math.floor(result / 365);						// 현재 날짜 년 - 개월 - 일 수로 표현하기
-	var month = Math.floor(result % 365 / 30);					
-	var day = result % 365 % 30;
-	
-	return result;
-	
-	//각 년도, 월, 일을 따로 리턴하려면 아래를 사용하면 됨
-	/* return {
-		year: year,
-		month: month,
-		day: day
-	}; */
-}
-
-/*
- * 예약 날짜 오류 체크 함수
- * 날짜, 시간, 분 파라미터 전달
- * 현재 날짜와 파라미터 시간의 분 간격 계산해주기
- * */
-function getGapDayTime(paramDate,paramHours,paramMin) {												/*	현재와 이전 날자의 차이를 년-개월-일 형태로 가져오기 	*/
-	
-	var now = new Date();
-	
-	//현재시간 구분하기
-	var year = now.getFullYear();
-	var month = now.getMonth() + 1 ;
-	var day = now.getDate();
-	var hours = now.getHours();
-	var min = now.getMinutes();
-	
-	//비교시간
-	var stDt = paramDate.split("/");
-	var stYear = stDt[0];
-	var stMonth = stDt[1];
-	var stDay = stDt[2];
-	
-	var nowDate = new Date(year, month-1, day, hours, min);
-	var stDate = new Date(stYear, stMonth-1, stDay, paramHours, paramMin);
-	var elapsedMSec = stDate.getTime() - nowDate.getTime();
-	var elapseMin = elapsedMSec / 1000 / 60;
-	
-	elapseMin = parseInt(elapseMin);
-	
-	return elapseMin;
-	
-	//각 년도, 월, 일을 따로 리턴하려면 아래를 사용하면 됨
-	/* return {
-		year: year,
-		month: month,
-		day: day
-	}; */
-}
-
-// 중복 주소 체크하기
-/*function dupliAddrData(data){
-	
-	var chk = true; //중복값 유무
-	var uniqData = []; // 중복값 삭제 후 데이터 저장
-	var dupCnt = 0;
-	
-	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
-	$.each(data, function(i, item){
-		
-		chk = true; //중복값 유무
-		
-		$.each(uniqData, function(j, item2){
-			
-			if(item.phone == item2.phone){
-				
-				chk = false;
-				dupCnt = dupCnt + 1;
-				console.log("++++++++++++++ dupCnt ::: "+ dupCnt);
-				
-			}
-			
-		});			
-		
-		if(chk){
-			
-			uniqData.push(item);
-			
-		}
-		
-	});	
-	
-	$("#rowDupCnt").text(dupCnt);
-	return uniqData;
-	
-}*/
-
-var dupliPhoneDataRealList = [];
-
-//중복 전화번호 체크하기
-function dupliPhoneData(data){
-	// console.log('dupliPhoneData : ', data);
-	
-	var chk = true; //중복값 유무
-	var uniqData = []; // 중복값 삭제 후 데이터 저장
-	var dupCnt = 0;
-	
-	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
-	$.each(data, function(i, item){
-		
-		chk = true; //중복값 유무
-		
-		$.each(uniqData, function(j, item2){
-			if(item.phone.length > 0){
-				if(item.phone == item2.phone){
-					
-					chk = false;
-					dupCnt = dupCnt + 1;
-					
-				}
-			}
-			
-		});			
-		
-		if(chk){
-			uniqData.push(item);
-		}
-		else {
-			// Get 중복 연락처 
-			GetDupliPhoneDataReal(item.phone);
-		}
-		
-	});	
-	
-	//중복건수 텍스트 입력해 주기
-	$("#rowDupCnt").text(dupCnt);
-
-	// 중복번호 버튼 노출
-	if($("#btnAddrMassDupli").length > 0) {
-		$("#btnAddrMassDupli").show();
-	}
-
-	// 중복번호(기존 주소록) 버튼 노출
-	if($("#btnAddrMassSaveDupli").length > 0) {
-		$("#btnAddrMassSaveDupli").hide();
-	}
-	
-	return uniqData;
-}
-
-
-//연락처 중복검사 속도 개선 버전
-function getSpupDupliPhoneDataChk(data){
-	
-	var dataLen = data.length;
-	const arrUnique = data.filter((character, idx, arr)=>{
-	    return arr.findIndex((item) => item.phone === character.phone) === idx
-	});
-
-	var uniqLen = arrUnique.length;
-	var dupCnt = dataLen - uniqLen;
-	//중복건수 텍스트 입력해 주기
-	$("#rowDupCnt").text(dupCnt);
-	
-	return arrUnique;
-}
-
-// Get 중복 연락처 
-function GetDupliPhoneDataReal(item) {
-	var isDuplicate = false;
-	if (dupliPhoneDataRealList.length == 0) {
-		dupliPhoneDataRealList.push(item);
-	}
-	else {
-		for (var i = 0; i < dupliPhoneDataRealList.length; i++)	{
-			if (dupliPhoneDataRealList[i] == item) {
-				isDuplicate = true;
-			}
-		}
-		
-		if (isDuplicate) {
-			return;
-		}
-		else {
-			dupliPhoneDataRealList.push(item);
-		}
-	}
-}	
-
-//중복 전화번호 체크하여 중복 갯수 리턴하기
-function dupliPhoneDataChk(data){
-	
-	var chk = true; //중복값 유무
-	var uniqData = []; // 중복값 삭제 후 데이터 저장
-	var dupCnt = 0;
-	
-	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
-	$.each(data, function(i, item){
-		
-		chk = true; //중복값 유무
-		
-		$.each(uniqData, function(j, item2){
-			
-			if(item.phone.length > 0){
-				
-				if(item.phone == item2.phone){
-					
-					chk = false;
-					dupCnt = dupCnt + 1;
-					
-				}
-				
-			}
-			
-		});		
-		
-		if(chk){
-			
-			uniqData.push(item);
-			
-		}
-		
-	});	
-
-	return dupCnt;
-	
-}
-
-//특정 바이트수 만큼 문자열 잘라서 반환해주기
-function strUnderLineSubstring(str, maxLength){
-	
-	for(b=i=0;c=str.charCodeAt(i);) {
-
-		b+=c>>7?2:1;
-
-		if (b > maxLength)
-
-		break;
-
-		i++;
-
-	}
-	
-	return str.substring(0,i);
-	
-}
-
-
-//특정 글자수 만큼 문자열 잘라서 반환해주기
-function strMaxLengthSubstring(str, maxLength){
-	
-	for(b=i=0;c=str.charCodeAt(i);) {
-
-		if (i > maxLength)
-
-		break;
-
-		i++;
-
-	}
-	
-	return str.substring(0,i);
-	
-}
-
-//문자열 글자수 반환해주기(한글, 영문, 특수문자, 엔터와 상관없이 글자수로 체크함)
-function strMaxCharacterCnt(str){
-	
-	var totLen = 0;
-	for(b=i=0;c=str.charCodeAt(i);) {
-		i++;
-		totLen = i;
-	}
-	return totLen;
-}
-
-//문자입력 첫번째 글자가 한글, 숫자, 영문자가 아니면 경고 표시
-function strFirstCharCheck(str){
-	
-	var pattern1 = /[0-9]/;
-	var pattern2 = /[a-zA-Z]/;
-	var pattern3 = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
-	
-	var spChar = 0;
-	for(var i=0; i<str.length; i++){
-		
-		if (!pattern1.test(str.charAt(i)) && !pattern2.test(str.charAt(i)) && !pattern3.test(str.charAt(i))) {
-			spChar++;
-		}else{
-			break;
-		}
-
-	}
-
-	var repStr = str.substring(0,spChar);
-	return repStr;
-	
-}
-
-function strChinJpnCheck(str){
-	
-	var rtnStr = "";
-	for(var i=0; i < str.length; i++){
-		
-		var cont = str.charAt(i);
-		
-		if(str.charAt(i) >= '\u4E00' && str.charAt(i) <= '\u9FFF'){//한중일 공통한자일 경우 
-			
-			if(rtnStr.length == 0){
-				rtnStr = cont;
-			}else{
-				rtnStr = rtnStr + ", " + cont;
-			}
-			
-		}else if(str.charAt(i) >= '\u2E80' && str.charAt(i) <= '\u2EFF'){//한자부수
-			
-			if(rtnStr.length == 0){
-				rtnStr = cont;
-			}else{
-				rtnStr = rtnStr + ", " + cont;
-			}
-			
-		}else if(str.charAt(i) >= '\u3400' && str.charAt(i) <= '\u4DB5'){//한자확장A
-			
-			if(rtnStr.length == 0){
-				rtnStr = cont;
-			}else{
-				rtnStr = rtnStr + ", " + cont;
-			}
-			
-		}
-		
-	}
-	
-	return rtnStr;
-}
-
-//받아온 str 에 이모지가 포함되어있는지 체크하여 갯수로 반환
-function kakaoTemplateEmojiCheck (str) {
-	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
-	var usedEmoji = "";
-	var returnFlag = true;
-	
-	var splitMsg = str.split(/.*?/u);
-
-	for(var i=0; i < splitMsg.length; i++){
- 		if(splitMsg[i].match(regex)) {
-			usedEmoji =  usedEmoji + splitMsg[i];
-			returnFlag = false;
-		}
-	}
-	if(!returnFlag) alert("알림톡 내용에 이모지는 사용할 수 없습니다.\n이모지 삭제후 등록해주세요.\n(" + usedEmoji + ")");
-	
-	return returnFlag;
-}
-
-//받아온 str 에 이모지가 포함되어있는지 체크하여 갯수로 반환
-function emojiCheck (str) {
-	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
-	var usedEmoji = "";
-	var returnFlag = true;
-	
-	var splitMsg = str.split(/.*?/u);
-
-	for(var i=0; i < splitMsg.length; i++){
- 		if(splitMsg[i].match(regex)) {
-			usedEmoji =  usedEmoji + splitMsg[i];
-			returnFlag = false;
-		}
-	}
-	if(!returnFlag) alert("문자 제목, 내용에 이모지는 사용할 수 없습니다.\n이모지 삭제후 발송해주세요.\n(" + usedEmoji + ")");
-	
-	return returnFlag;
-}
-
-function addrEmojiCheck (str) {
-	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
-	var usedEmoji = "";
-	var returnFlag = true;
-	
-	var splitMsg = str.split(/.*?/u);
-
-	for(var i=0; i < splitMsg.length; i++){
- 		if(splitMsg[i].match(regex)) {
-			usedEmoji =  usedEmoji + splitMsg[i];
-			returnFlag = false;
-		}
-	}
-
-	if(!returnFlag) {
-    	//로딩창 hide
-    	$('.loading_layer').removeClass('active');
-    	
-		alert("주소록 저장 목록 중 이모지를 사용할 수 없습니다.\n이모지 삭제후 발송해주세요.\n(" + usedEmoji + ")");
-	}
-	
-	return returnFlag;
-}
-
-// 제목이 치환 문구 체크
-function getSpacialStringChk(mmsSubject){
-	
-	var returnStr = false;
-	
-	if(mmsSubject.indexOf("[*이름*]") > -1 || mmsSubject.indexOf("[*1*]") > -1 || mmsSubject.indexOf("[*2*]") > -1 || mmsSubject.indexOf("[*3*]") > -1 || mmsSubject.indexOf("[*4*]") > -1){
-		returnStr = true;
-	}
-	
-	return returnStr;
-	
-}
-
-//커서 위치에 삽입
-function setCursorInsertText(pTxtArea, pAddTxt) {
-	var txtArea = document.getElementById(pTxtArea);
-	var txtValue = txtArea.value;
-	var selectPos = txtArea.selectionStart; // 커서 위치 지정
-	var beforeTxt = txtValue.substring(0, selectPos);  // 기존텍스트 ~ 커서시작점 까지의 문자
-	var afterTxt = txtValue.substring(txtArea.selectionEnd, txtValue.length);   // 커서끝지점 ~ 기존텍스트 까지의 문자
-	var addTxt = pAddTxt; // 추가 입력 할 텍스트
-	txtArea.value = beforeTxt + addTxt + afterTxt;
-
-	selectPos = selectPos + addTxt.length;
-	txtArea.selectionStart = selectPos; // 커서 시작점을 추가 삽입된 텍스트 이후로 지정
-	txtArea.selectionEnd = selectPos; // 커서 끝지점을 추가 삽입된 텍스트 이후로 지정
-	txtArea.focus();
-}
-
-//받는사람 목록의 체크박스가 20개가 모두 체크 되었는지 확인
-function fnCallToChkAllCnt(){
-	
-	var chkCnt = 0;
-	var totChkCnt = $("input:checkbox[name='chkCallTo']").length;
-	var btnAllVal = $("#checkAll").val();
-	
-	//체크박스 체크된 갯수 구하기
-	$("input:checkbox[name='chkCallTo']").each(function () {
-		if($(this).is(':checked')){
-			chkCnt++;
-		};
-	});
-	
-	//전체선택 체크 여부 값 변경해 주기
-	//현재 체크된 체크박스 갯수와 전체 체크박스 갯수 비교하기
-	if(totChkCnt > 0 && totChkCnt == chkCnt){
-
-		if(btnAllVal == 'N'){
-	    	$("#checkAll").val("Y");
-	    	$("#checkAll").text("선택해제");
-	    }else{
-	    	$("#checkAll").val("N");
-	    	$("#checkAll").text("전체선택");
-	    }
-	    
-	}else{
-		
-		$("#checkAll").val("N");
-    	$("#checkAll").text("전체선택");
-		
-	}
-	
-}
-
-//선거문자 20건 수신자 목록 추가된 건수 및 발송 금액 변경해주기
-function fnChkCallToChange(){
-	
-	var callToCnt = 0;
-	$("input[name=chkCallTo]").each(function(){
-		
-		var chkSts = $(this).is(':checked');
-		if(chkSts){
-			callToCnt++;
-		}
-	});
-	
-	//체크박스가 모두 체크 되어있는지 확인 하기
-	fnCallToChkAllCnt();
-	
-	updateTotCnt(callToCnt); //전체 데이터 갯수 구하기
-	totalPriceSum(callToCnt);
-	
-}
-
-//Tabulator 주소록 그룹 목록일 경우 각 그룹 주소 갯수 합산해주기
-function getTabulatorLAddrGrpCnt(){
-	
-	var selectedData = tableL.getRows();
-	var totAddrCnt = 0;
-	for(var i=0; i < selectedData.length; i++){
-		
-		//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
-		var addrGrpCnt = tableL.getRows()[i].getData().addrGrpCnt;
-		
-		totAddrCnt = Number(totAddrCnt) + Number(addrGrpCnt);
-		
-	}
-	
-	return totAddrCnt;
+/**
+ * 휴대폰번호 유효성 체크
+ * true, false 반환
+ * 대시 유무 상관없음
+ */
+function checkHpNum(str) {
+	
+	var regExp = /^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
+	//var regExp = /^(01[016789]{1}|070|02|0[3-9]{1}[0-9]{1})-?[0-9]{3,4}-?[0-9]{4}$/; //지역번호(일반전화) 형식까지 체크해주는 정규식
+	return regExp.test(str);
+}
 
-}
-
-/** 
-* @ phone을 기준으로 중복 제거 및 갯수 계산
-* @ 결과 반환
-* 	return {
-* 		uniqueArray,       // 중복 제거된 배열                    
-* 		uniqueCount, // 중복 제거된 데이터 개수  
-* 		duplicateArray // 중복된 데이터 배열                   
-* 		duplicateCount: duplicateArray.length // 중복된 데이터 개수
-* 	};
-*/
-function removeDuplicatesAndCount(array, key) {
-	// 중복 체크를 위한 Map 사용
-	const seen = new Map();
-	const uniqueArray = [];
-	const duplicateArray = [];
-	
-	array.forEach(item => {
-		const value = item[key];
-		if (seen.has(value)) {
-			// 중복된 데이터는 중복 배열에 추가
-			duplicateArray.push(item);
-		} else {
-			// 처음 본 데이터는 고유 배열에 추가하고 Map에 기록
-			uniqueArray.push(item);
-			seen.set(value, true);
-		}
-	});
-	
-	// 결과 반환
-	return {
-		uniqueArray,       // 중복 제거된 배열
-		uniqueCount: uniqueArray.length, // 중복 제거된 데이터 개수
-		duplicateArray,    // 중복된 데이터 배열
-		duplicateCount: duplicateArray.length // 중복된 데이터 개수
-	};
-}
-
-
-function validateRowLimit(totalRows, limit = 300000) {
-	// 값과 타입 확인
-
-	// 숫자 변환
-	const totalRowsNum = Number(totalRows);
-	const limitNum = Number(limit);
-	console.log('totalRowsNum : ', totalRowsNum);
-	console.log('limitNum : ', limitNum);
-
-	// 변환 후 값 확인
-
-	// 비교 연산 결과 확인
-	const isOverLimit = totalRowsNum > limitNum;
-	
-	// 조건 처리
-	 if (isOverLimit) {
-	     alert('안정적인 서비스 운영을 위해서 최대 ' + limit + '건 이내로 분할 발송해 주시기 바랍니다.');
-	     return false;
-	 }
-	return true;
-}
-
-
-// 전화번호 리스트 처리
-function processPhoneNumbers(phoneList) {
-	return phoneList
-		.map(number => {
-			const cleanPhone = removeDash(number.trim());
-			if (!isValidPhoneNumber(cleanPhone)) return null;
-			return {
-				name: "",
-				phone: cleanPhone,
-				rep1: "",
-				rep2: "",
-				rep3: "",
-				rep4: "",
-			};
-		})
-		.filter(data => data !== null);
-}
-
-
-// 데이터 병합 및 중복 제거
-function mergeAndValidateData(existingData, newData, uniqueKey = 'phone') {
-	const combinedData = existingData.concat(newData);
-	const result = removeDuplicatesAndCount(combinedData, uniqueKey);
-
-	if (!validateRowLimit(result.uniqueCount)) {
-		return null;
-	}
-
-	return result;
-}
-
-// 테이블 데이터 업데이트
-function updateTableData(table, result) {
-	if (!result) return false;
-
-	table.setData(result.uniqueArray);
-	setRowDupCnt(result.duplicateArray.length);
-	updateButtons(0);
-	const totRows = table.getRows().length;
-	updateTotCnt(totRows);
-	totalPriceSum(totRows);
-	return true;
-}
-
-/**
- * @Discript : 문자발송 화면에 중복 카운트 입력
- * 
- */
-function setRowDupCnt(cnt){
-	$('#rowDupCnt').text(cnt)
-}
-
-
-
+/**
+ * 휴대폰번호만 유효성 체크
+ * true, false 반환
+ * 대시 유무 상관없음
+ */
+function checkOnlyHpNum(str) {
+	
+	//var regExp = /^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
+	var regExp = /^(01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$/; //지역번호(일반전화) 형식까지 체크해주는 정규식
+	return regExp.test(str);
+}
+
+/**
+ * 팩스 번호 유효성 체크
+ * true, false 반환
+ * 앞 3자리를 체크 함
+ * -- 전국 지역번호
+ * 	02	서울특별시
+	031	경기도
+	032	인천광역시
+	033	강원도
+	041	충청남도
+	042	대전광역시
+	043	충청북도
+	044	세종특별자치시
+	051	부산광역시
+	052	울산광역시
+	053	대구광역시
+	054	경상북도
+	055	경상남도
+	061	전라남도
+	062	광주광역시
+	063	전라북도
+	064	제주특별자치도
+	
+	-- 타사부가번호
+	030*
+	050*
+	060
+	070
+	080
+	1**
+	
+	위 번호로 시작하는 팩스 번호만 허용함.
+ */
+	function checkFaxNum(str) {
+		str = removeDash(str);
+		var subNum = str.substring(0,3);
+		var regExp = /^(02\d|03[1-3]|04[1-4]|05[1-5]|06[1-4]|030|050|060|070|080|1\d{2})$/; // 수정된 정규식
+		return regExp.test(subNum);
+	}
+
+/*
+ * 일반전화 유효성 체크
+ * true, false 반환
+ * 
+ * */
+function checkNorPhoneNum(str){
+	
+	var regExp = /^(02|0[3-9]{1}[0-9]{1})-?[0-9]{3,4}-?[0-9]{4}$/;
+	
+	/**
+	 * 기간통신사업자 공통 부가서비스 번호 체크
+	 * 번호 사업자
+		1588,1577,1899 KT
+		1544,1644,1661,1800 ,1833 LG유플러스
+		1566,1600,1670 SK브로드밴드
+		1688,1666 온세텔레콤
+		1599 SK텔링크
+		1877 한국케이블텔레콤
+		1855 CJ헬로비전
+		1661 alleh KT
+	 * 
+	 * */
+	
+	if(str.substring(0,2) == "15"){
+		
+		regExp = /^(15[0-9]{2})-?[0-9]{4}$/;
+		
+	}else if(str.substring(0,2) == "16"){
+		
+		regExp = /^(16[0-9]{2})-?[0-9]{4}$/;
+		
+	}else if(str.substring(0,2) == "18"){
+		
+		regExp = /^(18[0-9]{2})-?[0-9]{4}$/;
+		
+	}
+	
+	return regExp.test(str);
+}
+
+/*
+ * 일반전화 / 핸드폰 번호 종류 확인
+ * true, false 반환
+ * 
+ * */
+function checkTelHpType(str){
+	
+	var subCall = str.substring(0,3);	// 전화번호 앞 3자리 받아오기
+	var strType = "";				 	// 결과 반환
+	
+	if(subCall != '010' 
+		&& subCall != '011' 
+		&& subCall != '016' 
+		&& subCall != '017'){//일반전화 번호이면
+		
+		strType = "Tel";
+		
+	}else{
+		
+		strType = "Hp";
+	}
+	
+	return strType;
+}
+
+
+/**
+ * 휴대폰번호 대시('-') 제거
+ */
+/**
+ * 휴대폰번호에서 숫자가 아닌 문자를 모두 제거
+ */
+function removeDash(str) {
+	return str.replace(/\D/g, ''); // 숫자 이외의 문자 제거
+}
+
+
+/**
+ * 휴대폰번호 대시('-') 추가
+ * 대시 유무 상관없음
+ * 유효성 맞지 않을시 변환안됨.
+ */
+function addDash(str) {
+	return str.replace(/(^01[016789]{1}|070)([0-9]{3}|[0-9]{4})([0-9]{4})$/,"$1-$2-$3").replace("--", "-");
+}
+
+/**
+ * ReplaceAll (by javascript prototype)
+ * 정규식 패턴에서 \는 두 개 사용 
+ */
+String.prototype.replaceAll = function(pattern, changeString) {
+	var regExp = new RegExp(pattern, 'g');
+	return this.replace(regExp, changeString);
+};
+
+/**
+ * 이메일 유효성 체크
+ * true, false 반환
+ * 
+ */
+function checkEmail(str) {
+	var regExp = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+/;
+	return regExp.test(str);
+}
+
+/**
+ * XSS 체크하기
+ * 
+ * 
+ */
+
+function XSSCheck(str, level) {
+    if (level == undefined || level == 0) {
+        str = str.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,"");
+    } else if (level != undefined && level == 1) {
+        str = str.replace(/\</g, "&lt;");
+        str = str.replace(/\>/g, "&gt;");
+    }
+    return str;
+}
+
+/**
+ * XSS 변경하기
+ * 
+ * 
+ */
+function XSSChange(str) {
+	
+	str = str.replaceAll(/(<br>|<br\/>|<br \/>)/g, '\r\n');
+	str = str.replaceAll("&lt;", '<');
+    str = str.replaceAll("&gt;", '>');
+    str = str.replaceAll("&amp;", '&');
+    
+    return str;
+}
+
+//숫자 천단위 콤마 찍어주기
+function numberWithCommas(x) { 
+	return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 
+}
+
+function comma(num){ 
+	var len, point, str; 
+	num = num + ""; 
+	point = num.length % 3; 
+	len = num.length; 
+	str = num.substring(0, point); 
+	while (point < len) { 
+		if (str != "") str += ","; 
+		str += num.substring(point, point + 3); 
+		point += 3; 
+		} 
+	return str; 
+}
+
+
+function totalPriceSum(totRows){
+	
+	var contents = $('#smsTxtArea').val();	//입력 문자 내용
+	var msgType = conTypeCheck(contents);	//입력 문자 길이 체크
+	var collNumCnt = parseInt(totRows); 	//받는사람 건수
+	var price = 0;							//개별 건수 금액
+	var totalPrice = 0;						//전체 금액
+	//var strDot = [];
+	//var subPrice = "";
+	//var spPrice = "";
+	var totalStr = "0";							//전체 합계 금액
+	var userMoney = $('#hdUserMoney').text(); 	//헤더 영역 보유 금액 불러오기
+	var msgCnt = 0;								//발송 가능 문자 건수
+	var imgCnt = $("#imgCnt").val(); // 현재 페이지에 첨부된 이미지 갯수
+	
+	if(!userMoney > 0){
+		
+		userMoney = 0;
+		
+	}
+	//헤더 영역 보유 금액 콤마 문자 제거
+	if(userMoney != ''){
+		
+		userMoney = userMoney.replaceAll("," , "");
+		
+	}
+	
+	/*if(msgType == "P"){//그림문자
+		
+		//그림 이미지 갯수에 따른 금액 계산
+		if(imgCnt > 2){//그림 3장일경우
+			price = parseFloat($('#p3Price').val());
+		}else if(imgCnt > 1){//그림 2장일경우
+			price = parseFloat($('#p2Price').val());
+		}else{//그림 1장일 경우
+			price = parseFloat($('#pPrice').val());
+		}
+		
+		msgCnt = parseFloat(userMoney) / price;
+	
+	}else if(msgType == "M"){//장문 문자
+		
+		price = parseFloat($('#mPrice').val());
+		msgCnt = parseFloat(userMoney) / price;
+		
+	}else{//단문문자
+		
+		price = parseFloat($('#sPrice').val());
+		msgCnt = parseFloat(userMoney) / price;
+	
+	}*/
+	
+	//금액 소수점 제거 하여 적용 20220623 소수점 버림 처리
+	if(msgType == "P"){//그림문자
+		
+		//그림 이미지 갯수에 따른 금액 계산
+		if(imgCnt > 2){//그림 3장일경우
+			price = $('#p3Price').val();
+		}else if(imgCnt > 1){//그림 2장일경우
+			price = $('#p2Price').val();
+		}else{//그림 1장일 경우
+			price = $('#pPrice').val();
+		}
+		
+		msgCnt = userMoney / price;
+	
+	}else if(msgType == "M"){//장문 문자
+		
+		price = $('#mPrice').val();
+		msgCnt = userMoney / price;
+		
+	}else{//단문문자
+		
+		price = $('#sPrice').val();
+		msgCnt = userMoney / price;
+	
+	}
+	
+	totalPrice = price * collNumCnt;
+	
+	// 소수점 첫째자리 까지 표시
+	totalPrice = totalPrice.toFixed(1);
+	
+	if(totalPrice > 0){
+		
+		//totalStr = totalPrice.toFixed(2);
+		totalStr = totalPrice;
+		
+	}
+	
+	//개별 문자 단가 파라미터에 입력
+	$('#eachPrice').val(numberWithCommas(price));
+	
+	
+	//결제금액 합계 파라이터에 입력
+	$('#totPrice').val(numberWithCommas(totalStr));
+	
+	//결제금액 합계 화면에 표시
+	$('#totalPriceTxt').text(numberWithCommas(totalStr));
+	
+	//현재 문자 전송 가능 갯수 표시
+	$('.nowMsgCnt').text(numberWithCommas(msgCnt.toFixed()));
+	
+	if(msgType == 'P'){
+		
+		$('#nowMsgType').text("그림");
+		
+	}else if(msgType == 'M'){
+		
+		$('#nowMsgType').text("장문");
+	
+	}else{
+		
+		$('#nowMsgType').text("단문");
+		
+	}
+	
+	$('#repPriceTxt').hide();
+	
+	return totalStr;
+	
+}
+
+function replTotalPriceSum(msg_short, msg_long, totRows){
+	
+	var shortPrice = 0;		//단문 개별 건수 금액
+	var longPrice = 0;		//장문 개별 건수 금액
+	var imgPrice = 0;		//그림문자 개별 건수 금액
+	var totalPrice = 0;		//전체 금액
+	var totalStr = "0";		//전체 합계 금액
+	var contents = $('#smsTxtArea').val();	//입력 문자 내용
+	var msgType = conTypeCheck(contents);	//입력 문자 길이 체크
+	var userMoney = $('#hdUserMoney').text(); 	//헤더 영역 보유 금액 불러오기
+	var msgCnt = 0;								//발송 가능 문자 건수
+	var imgCnt = $("#imgCnt").val(); // 현재 페이지에 첨부된 이미지 갯수
+	var collNumCnt = parseInt(totRows); 	//받는사람 건수
+	var totalCntTxt = "";
+	
+	//금액 소수점 제거하여 금액 처리
+	if(msgType == "P"){//그림문자
+		
+		//그림 이미지 갯수에 따른 금액 계산
+		if(imgCnt > 2){//그림 3장일경우
+			imgPrice = $('#p3Price').val();
+		}else if(imgCnt > 1){//그림 2장일경우
+			imgPrice = $('#p2Price').val();
+			
+		}else{//그림 1장일 경우
+			imgPrice = $('#pPrice').val();
+		}
+		
+		msgCnt = userMoney.replaceAll(",","") / imgPrice;
+		
+		var imgTotPrice = imgPrice * collNumCnt; 
+		imgTotPrice = Math.round(imgTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
+		
+		totalPrice =  totalPrice + imgTotPrice;
+		
+		//input hidden 개별 문자 단가 파라미터에 입력
+		$('#eachPrice').val(numberWithCommas(imgPrice));
+		
+		//input hidden 결제금액 합계 파라이터에 입력
+		$('#totPrice').val(numberWithCommas(totalStr));
+		
+		//결제금액 합계 화면에 표시
+		$('#totalPriceTxt').text(numberWithCommas(totalStr));
+		
+		//현재 문자 전송 가능 갯수 표시
+		$('.nowMsgCnt').text(numberWithCommas(msgCnt.toFixed()));
+		
+		//변환문자 건수 내용 표기
+		totalCntTxt = "그림 : <strong>" + numberWithCommas(totRows) + "</strong> 건";;
+		
+	}else{
+		
+		if(msg_long > 0){//장문 문자
+			
+			longPrice = $('#mPrice').val();
+			var longTotPrice = longPrice * msg_long; 
+			longTotPrice = Math.round(longTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
+			
+			totalPrice = totalPrice + longTotPrice;
+			
+			//input hidden 개별 문자 단가 파라미터에 입력
+			$('#eachPrice').val(numberWithCommas(longPrice));
+			
+			//변환문자 건수 내용 표기
+			totalCntTxt = "장문 : <strong>" + numberWithCommas(msg_long) + "</strong> 건";
+			
+			//변환장문 건수 Hidden 폼에 넣어주기
+			$('#longMsgCnt').val(msg_long);
+			
+		}else{
+			
+			//변환장문 건수 Hidden 폼에 넣어주기
+			$('#longMsgCnt').val(msg_long);
+			
+		}
+
+		if(msg_short > 0){//단문문자
+			
+			shortPrice = $('#sPrice').val();
+			var shortTotPrice = shortPrice * msg_short; 
+			shortTotPrice = Math.round(shortTotPrice * 100) / 100;	//소수점 2자리 반올리 처리해주기
+
+			totalPrice = totalPrice + shortTotPrice;
+			
+			//input hidden 개별 문자 단가 파라미터에 입력
+			$('#eachPrice').val(numberWithCommas(shortPrice));
+			
+			if(msg_long > 0){
+				
+				//변환문자 건수 내용 표기
+				totalCntTxt = totalCntTxt + "/ 단문 : <strong>" + numberWithCommas(msg_short) + "</strong> 건";
+				
+			}else{
+				
+				//변환문자 건수 내용 표기
+				totalCntTxt = "단문 : <strong>" + numberWithCommas(msg_short) + "</strong> 건";
+				
+			}
+			
+			//변환단문 건수 Hidden 폼에 넣어주기
+			$('#shortMsgCnt').val(msg_short);
+		
+		}else{
+			
+			//변환단문 건수 Hidden 폼에 넣어주기
+			$('#shortMsgCnt').val(msg_short);
+			
+		}
+		
+	}
+	
+	
+	if(totalPrice > 0){
+		
+		//totalStr = totalPrice.toFixed(2);
+		totalStr = totalPrice;
+		
+	}
+	
+	//input hidden 결제금액 합계 파라이터에 입력
+	$('#totPrice').val(numberWithCommas(totalStr));
+	
+	//결제금액 합계 화면에 표시
+	$('#totalPriceTxt').text(numberWithCommas(totalStr));
+	
+	//결제금액 합계 파라이터에 입력
+	$('#totPrice').val(numberWithCommas(totalStr));
+	
+	//특정문구 일괄 변환으로 인한 단/장문 건수 표시
+	$('#repPriceTxt').show();
+	$('#repPriceTxt').html("(" + totalCntTxt + ")");
+	
+	if(msgType == 'P'){
+		
+		$('#nowMsgType').text("그림");
+		
+	}else if(msgType == 'M'){
+		
+		$('#nowMsgType').text("장문");
+	
+	}else{
+		
+		$('#nowMsgType').text("단문");
+		
+	}
+	
+	return totalStr;
+	
+}
+
+//예약 날짜 체크 함수
+function getGday(date) {												/*	현재와 이전 날자의 차이를 년-개월-일 형태로 가져오기 	*/
+	var now = new Date().getTime();								// 현재 날짜를 시간으로 변환
+	var d = new Date(date.substring(0, 10)).getTime();			// 이전 날짜를 시간으로 변환 
+	var gap = now - d;											// 현재 날짜와 이전 날짜의 차이를 밀리초 시간으로 구한다.
+	var result = Math.floor(gap/(1000 * 60 * 60 * 24));			// 날짜 차이를 일수로 계산
+	
+	var year = Math.floor(result / 365);						// 현재 날짜 년 - 개월 - 일 수로 표현하기
+	var month = Math.floor(result % 365 / 30);					
+	var day = result % 365 % 30;
+	
+	return result;
+	
+	//각 년도, 월, 일을 따로 리턴하려면 아래를 사용하면 됨
+	/* return {
+		year: year,
+		month: month,
+		day: day
+	}; */
+}
+
+/*
+ * 예약 날짜 오류 체크 함수
+ * 날짜, 시간, 분 파라미터 전달
+ * 현재 날짜와 파라미터 시간의 분 간격 계산해주기
+ * */
+function getGapDayTime(paramDate,paramHours,paramMin) {												/*	현재와 이전 날자의 차이를 년-개월-일 형태로 가져오기 	*/
+	
+	var now = new Date();
+	
+	//현재시간 구분하기
+	var year = now.getFullYear();
+	var month = now.getMonth() + 1 ;
+	var day = now.getDate();
+	var hours = now.getHours();
+	var min = now.getMinutes();
+	
+	//비교시간
+	var stDt = paramDate.split("/");
+	var stYear = stDt[0];
+	var stMonth = stDt[1];
+	var stDay = stDt[2];
+	
+	var nowDate = new Date(year, month-1, day, hours, min);
+	var stDate = new Date(stYear, stMonth-1, stDay, paramHours, paramMin);
+	var elapsedMSec = stDate.getTime() - nowDate.getTime();
+	var elapseMin = elapsedMSec / 1000 / 60;
+	
+	elapseMin = parseInt(elapseMin);
+	
+	return elapseMin;
+	
+	//각 년도, 월, 일을 따로 리턴하려면 아래를 사용하면 됨
+	/* return {
+		year: year,
+		month: month,
+		day: day
+	}; */
+}
+
+// 중복 주소 체크하기
+/*function dupliAddrData(data){
+	
+	var chk = true; //중복값 유무
+	var uniqData = []; // 중복값 삭제 후 데이터 저장
+	var dupCnt = 0;
+	
+	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
+	$.each(data, function(i, item){
+		
+		chk = true; //중복값 유무
+		
+		$.each(uniqData, function(j, item2){
+			
+			if(item.phone == item2.phone){
+				
+				chk = false;
+				dupCnt = dupCnt + 1;
+				console.log("++++++++++++++ dupCnt ::: "+ dupCnt);
+				
+			}
+			
+		});			
+		
+		if(chk){
+			
+			uniqData.push(item);
+			
+		}
+		
+	});	
+	
+	$("#rowDupCnt").text(dupCnt);
+	return uniqData;
+	
+}*/
+
+var dupliPhoneDataRealList = [];
+
+//중복 전화번호 체크하기
+function dupliPhoneData(data){
+	// console.log('dupliPhoneData : ', data);
+	
+	var chk = true; //중복값 유무
+	var uniqData = []; // 중복값 삭제 후 데이터 저장
+	var dupCnt = 0;
+	
+	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
+	$.each(data, function(i, item){
+		
+		chk = true; //중복값 유무
+		
+		$.each(uniqData, function(j, item2){
+			if(item.phone.length > 0){
+				if(item.phone == item2.phone){
+					
+					chk = false;
+					dupCnt = dupCnt + 1;
+					
+				}
+			}
+			
+		});			
+		
+		if(chk){
+			uniqData.push(item);
+		}
+		else {
+			// Get 중복 연락처 
+			GetDupliPhoneDataReal(item.phone);
+		}
+		
+	});	
+	
+	//중복건수 텍스트 입력해 주기
+	$("#rowDupCnt").text(dupCnt);
+
+	// 중복번호 버튼 노출
+	if($("#btnAddrMassDupli").length > 0) {
+		$("#btnAddrMassDupli").show();
+	}
+
+	// 중복번호(기존 주소록) 버튼 노출
+	if($("#btnAddrMassSaveDupli").length > 0) {
+		$("#btnAddrMassSaveDupli").hide();
+	}
+	
+	return uniqData;
+}
+
+
+//연락처 중복검사 속도 개선 버전
+function getSpupDupliPhoneDataChk(data){
+	
+	var dataLen = data.length;
+	const arrUnique = data.filter((character, idx, arr)=>{
+	    return arr.findIndex((item) => item.phone === character.phone) === idx
+	});
+
+	var uniqLen = arrUnique.length;
+	var dupCnt = dataLen - uniqLen;
+	//중복건수 텍스트 입력해 주기
+	$("#rowDupCnt").text(dupCnt);
+	
+	return arrUnique;
+}
+
+// Get 중복 연락처 
+function GetDupliPhoneDataReal(item) {
+	var isDuplicate = false;
+	if (dupliPhoneDataRealList.length == 0) {
+		dupliPhoneDataRealList.push(item);
+	}
+	else {
+		for (var i = 0; i < dupliPhoneDataRealList.length; i++)	{
+			if (dupliPhoneDataRealList[i] == item) {
+				isDuplicate = true;
+			}
+		}
+		
+		if (isDuplicate) {
+			return;
+		}
+		else {
+			dupliPhoneDataRealList.push(item);
+		}
+	}
+}	
+
+//중복 전화번호 체크하여 중복 갯수 리턴하기
+function dupliPhoneDataChk(data){
+	
+	var chk = true; //중복값 유무
+	var uniqData = []; // 중복값 삭제 후 데이터 저장
+	var dupCnt = 0;
+	
+	//첨부 주소 정보에서 연락처가 중복되는 경우 하나만 남기고 나머지는 삭제 하고 보여줌
+	$.each(data, function(i, item){
+		
+		chk = true; //중복값 유무
+		
+		$.each(uniqData, function(j, item2){
+			
+			if(item.phone.length > 0){
+				
+				if(item.phone == item2.phone){
+					
+					chk = false;
+					dupCnt = dupCnt + 1;
+					
+				}
+				
+			}
+			
+		});		
+		
+		if(chk){
+			
+			uniqData.push(item);
+			
+		}
+		
+	});	
+
+	return dupCnt;
+	
+}
+
+//특정 바이트수 만큼 문자열 잘라서 반환해주기
+function strUnderLineSubstring(str, maxLength){
+	
+	for(b=i=0;c=str.charCodeAt(i);) {
+
+		b+=c>>7?2:1;
+
+		if (b > maxLength)
+
+		break;
+
+		i++;
+
+	}
+	
+	return str.substring(0,i);
+	
+}
+
+
+//특정 글자수 만큼 문자열 잘라서 반환해주기
+function strMaxLengthSubstring(str, maxLength){
+	
+	for(b=i=0;c=str.charCodeAt(i);) {
+
+		if (i > maxLength)
+
+		break;
+
+		i++;
+
+	}
+	
+	return str.substring(0,i);
+	
+}
+
+//문자열 글자수 반환해주기(한글, 영문, 특수문자, 엔터와 상관없이 글자수로 체크함)
+function strMaxCharacterCnt(str){
+	
+	var totLen = 0;
+	for(b=i=0;c=str.charCodeAt(i);) {
+		i++;
+		totLen = i;
+	}
+	return totLen;
+}
+
+//문자입력 첫번째 글자가 한글, 숫자, 영문자가 아니면 경고 표시
+function strFirstCharCheck(str){
+	
+	var pattern1 = /[0-9]/;
+	var pattern2 = /[a-zA-Z]/;
+	var pattern3 = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
+	
+	var spChar = 0;
+	for(var i=0; i<str.length; i++){
+		
+		if (!pattern1.test(str.charAt(i)) && !pattern2.test(str.charAt(i)) && !pattern3.test(str.charAt(i))) {
+			spChar++;
+		}else{
+			break;
+		}
+
+	}
+
+	var repStr = str.substring(0,spChar);
+	return repStr;
+	
+}
+
+function strChinJpnCheck(str){
+	
+	var rtnStr = "";
+	for(var i=0; i < str.length; i++){
+		
+		var cont = str.charAt(i);
+		
+		if(str.charAt(i) >= '\u4E00' && str.charAt(i) <= '\u9FFF'){//한중일 공통한자일 경우 
+			
+			if(rtnStr.length == 0){
+				rtnStr = cont;
+			}else{
+				rtnStr = rtnStr + ", " + cont;
+			}
+			
+		}else if(str.charAt(i) >= '\u2E80' && str.charAt(i) <= '\u2EFF'){//한자부수
+			
+			if(rtnStr.length == 0){
+				rtnStr = cont;
+			}else{
+				rtnStr = rtnStr + ", " + cont;
+			}
+			
+		}else if(str.charAt(i) >= '\u3400' && str.charAt(i) <= '\u4DB5'){//한자확장A
+			
+			if(rtnStr.length == 0){
+				rtnStr = cont;
+			}else{
+				rtnStr = rtnStr + ", " + cont;
+			}
+			
+		}
+		
+	}
+	
+	return rtnStr;
+}
+
+//받아온 str 에 이모지가 포함되어있는지 체크하여 갯수로 반환
+function kakaoTemplateEmojiCheck (str) {
+	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
+	var usedEmoji = "";
+	var returnFlag = true;
+	
+	var splitMsg = str.split(/.*?/u);
+
+	for(var i=0; i < splitMsg.length; i++){
+ 		if(splitMsg[i].match(regex)) {
+			usedEmoji =  usedEmoji + splitMsg[i];
+			returnFlag = false;
+		}
+	}
+	if(!returnFlag) alert("알림톡 내용에 이모지는 사용할 수 없습니다.\n이모지 삭제후 등록해주세요.\n(" + usedEmoji + ")");
+	
+	return returnFlag;
+}
+
+//받아온 str 에 이모지가 포함되어있는지 체크하여 갯수로 반환
+function emojiCheck (str) {
+	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
+	var usedEmoji = "";
+	var returnFlag = true;
+	
+	var splitMsg = str.split(/.*?/u);
+
+	for(var i=0; i < splitMsg.length; i++){
+ 		if(splitMsg[i].match(regex)) {
+			usedEmoji =  usedEmoji + splitMsg[i];
+			returnFlag = false;
+		}
+	}
+	if(!returnFlag) alert("문자 제목, 내용에 이모지는 사용할 수 없습니다.\n이모지 삭제후 발송해주세요.\n(" + usedEmoji + ")");
+	
+	return returnFlag;
+}
+
+function addrEmojiCheck (str) {
+	var regex = /[\u{1F004}-\u{1F9E6}]|[\u{1F600}-\u{1F9D0}]/gu;
+	var usedEmoji = "";
+	var returnFlag = true;
+	
+	var splitMsg = str.split(/.*?/u);
+
+	for(var i=0; i < splitMsg.length; i++){
+ 		if(splitMsg[i].match(regex)) {
+			usedEmoji =  usedEmoji + splitMsg[i];
+			returnFlag = false;
+		}
+	}
+
+	if(!returnFlag) {
+    	//로딩창 hide
+    	$('.loading_layer').removeClass('active');
+    	
+		alert("주소록 저장 목록 중 이모지를 사용할 수 없습니다.\n이모지 삭제후 발송해주세요.\n(" + usedEmoji + ")");
+	}
+	
+	return returnFlag;
+}
+
+// 제목이 치환 문구 체크
+function getSpacialStringChk(mmsSubject){
+	
+	var returnStr = false;
+	
+	if(mmsSubject.indexOf("[*이름*]") > -1 || mmsSubject.indexOf("[*1*]") > -1 || mmsSubject.indexOf("[*2*]") > -1 || mmsSubject.indexOf("[*3*]") > -1 || mmsSubject.indexOf("[*4*]") > -1){
+		returnStr = true;
+	}
+	
+	return returnStr;
+	
+}
+
+//커서 위치에 삽입
+function setCursorInsertText(pTxtArea, pAddTxt) {
+	var txtArea = document.getElementById(pTxtArea);
+	var txtValue = txtArea.value;
+	var selectPos = txtArea.selectionStart; // 커서 위치 지정
+	var beforeTxt = txtValue.substring(0, selectPos);  // 기존텍스트 ~ 커서시작점 까지의 문자
+	var afterTxt = txtValue.substring(txtArea.selectionEnd, txtValue.length);   // 커서끝지점 ~ 기존텍스트 까지의 문자
+	var addTxt = pAddTxt; // 추가 입력 할 텍스트
+	txtArea.value = beforeTxt + addTxt + afterTxt;
+
+	selectPos = selectPos + addTxt.length;
+	txtArea.selectionStart = selectPos; // 커서 시작점을 추가 삽입된 텍스트 이후로 지정
+	txtArea.selectionEnd = selectPos; // 커서 끝지점을 추가 삽입된 텍스트 이후로 지정
+	txtArea.focus();
+}
+
+//받는사람 목록의 체크박스가 20개가 모두 체크 되었는지 확인
+function fnCallToChkAllCnt(){
+	
+	var chkCnt = 0;
+	var totChkCnt = $("input:checkbox[name='chkCallTo']").length;
+	var btnAllVal = $("#checkAll").val();
+	
+	//체크박스 체크된 갯수 구하기
+	$("input:checkbox[name='chkCallTo']").each(function () {
+		if($(this).is(':checked')){
+			chkCnt++;
+		};
+	});
+	
+	//전체선택 체크 여부 값 변경해 주기
+	//현재 체크된 체크박스 갯수와 전체 체크박스 갯수 비교하기
+	if(totChkCnt > 0 && totChkCnt == chkCnt){
+
+		if(btnAllVal == 'N'){
+	    	$("#checkAll").val("Y");
+	    	$("#checkAll").text("선택해제");
+	    }else{
+	    	$("#checkAll").val("N");
+	    	$("#checkAll").text("전체선택");
+	    }
+	    
+	}else{
+		
+		$("#checkAll").val("N");
+    	$("#checkAll").text("전체선택");
+		
+	}
+	
+}
+
+//선거문자 20건 수신자 목록 추가된 건수 및 발송 금액 변경해주기
+function fnChkCallToChange(){
+	
+	var callToCnt = 0;
+	$("input[name=chkCallTo]").each(function(){
+		
+		var chkSts = $(this).is(':checked');
+		if(chkSts){
+			callToCnt++;
+		}
+	});
+	
+	//체크박스가 모두 체크 되어있는지 확인 하기
+	fnCallToChkAllCnt();
+	
+	updateTotCnt(callToCnt); //전체 데이터 갯수 구하기
+	totalPriceSum(callToCnt);
+	
+}
+
+//Tabulator 주소록 그룹 목록일 경우 각 그룹 주소 갯수 합산해주기
+function getTabulatorLAddrGrpCnt(){
+	
+	var selectedData = tableL.getRows();
+	var totAddrCnt = 0;
+	for(var i=0; i < selectedData.length; i++){
+		
+		//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
+		var addrGrpCnt = tableL.getRows()[i].getData().addrGrpCnt;
+		
+		totAddrCnt = Number(totAddrCnt) + Number(addrGrpCnt);
+		
+	}
+	
+	return totAddrCnt;
+
+}
+
+/** 
+* @ phone을 기준으로 중복 제거 및 갯수 계산
+* @ 결과 반환
+* 	return {
+* 		uniqueArray,       // 중복 제거된 배열                    
+* 		uniqueCount, // 중복 제거된 데이터 개수  
+* 		duplicateArray // 중복된 데이터 배열                   
+* 		duplicateCount: duplicateArray.length // 중복된 데이터 개수
+* 	};
+*/
+function removeDuplicatesAndCount(array, key) {
+	// 중복 체크를 위한 Map 사용
+	const seen = new Map();
+	const uniqueArray = [];
+	const duplicateArray = [];
+	
+	array.forEach(item => {
+		const value = item[key];
+		if (seen.has(value)) {
+			// 중복된 데이터는 중복 배열에 추가
+			duplicateArray.push(item);
+		} else {
+			// 처음 본 데이터는 고유 배열에 추가하고 Map에 기록
+			uniqueArray.push(item);
+			seen.set(value, true);
+		}
+	});
+	
+	// 결과 반환
+	return {
+		uniqueArray,       // 중복 제거된 배열
+		uniqueCount: uniqueArray.length, // 중복 제거된 데이터 개수
+		duplicateArray,    // 중복된 데이터 배열
+		duplicateCount: duplicateArray.length // 중복된 데이터 개수
+	};
+}
+
+
+function validateRowLimit(totalRows, limit = 300000) {
+	// 값과 타입 확인
+
+	// 숫자 변환
+	const totalRowsNum = Number(totalRows);
+	const limitNum = Number(limit);
+	console.log('totalRowsNum : ', totalRowsNum);
+	console.log('limitNum : ', limitNum);
+
+	// 변환 후 값 확인
+
+	// 비교 연산 결과 확인
+	const isOverLimit = totalRowsNum > limitNum;
+	
+	// 조건 처리
+	 if (isOverLimit) {
+	     alert('안정적인 서비스 운영을 위해서 최대 ' + limit + '건 이내로 분할 발송해 주시기 바랍니다.');
+	     return false;
+	 }
+	return true;
+}
+
+
+// 전화번호 리스트 처리
+function processPhoneNumbers(phoneList) {
+	return phoneList
+		.map(number => {
+			const cleanPhone = removeDash(number.trim());
+			if (!isValidPhoneNumber(cleanPhone)) return null;
+			return {
+				name: "",
+				phone: cleanPhone,
+				rep1: "",
+				rep2: "",
+				rep3: "",
+				rep4: "",
+			};
+		})
+		.filter(data => data !== null);
+}
+
+
+// 데이터 병합 및 중복 제거
+function mergeAndValidateData(existingData, newData, uniqueKey = 'phone') {
+	const combinedData = existingData.concat(newData);
+	const result = removeDuplicatesAndCount(combinedData, uniqueKey);
+
+	if (!validateRowLimit(result.uniqueCount)) {
+		return null;
+	}
+
+	return result;
+}
+
+// 테이블 데이터 업데이트
+function updateTableData(table, result) {
+	if (!result) return false;
+
+	table.setData(result.uniqueArray);
+	setRowDupCnt(result.duplicateArray.length);
+	updateButtons(0);
+	const totRows = table.getRows().length;
+	updateTotCnt(totRows);
+	totalPriceSum(totRows);
+	return true;
+}
+
+/**
+ * @Discript : 문자발송 화면에 중복 카운트 입력
+ * 
+ */
+function setRowDupCnt(cnt){
+	$('#rowDupCnt').text(cnt)
+}
+
+
+
Add a comment
List