rosewiper 2024-01-16
카카오 친구톡 스팸 필터링 개발
@1b04bc71048de2cf00687a9c2bc73350349e1bb0
src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
--- src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
@@ -12,6 +12,7 @@
 import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiJsonSave;
 import itn.let.mjo.msg.service.MjonMsgVO;
 import itn.let.mjo.msgdata.service.MjonMsgDataService;
+import itn.let.mjo.spammsg.web.ComGetSpamStringParser;
 import itn.let.sym.site.service.JoinSettingVO;
 import itn.let.uss.umt.service.MberManageVO;
 
@@ -341,4 +342,155 @@
 		}
 		return tempSubMagTxt;
 	}
+	
+	/*
+	 * 카카오 친구톡 치환 내용에 대한 변환 처리
+	 * 
+	 * 
+	 * */
+	public String getKakaoFTCntReplace(String varValStr, String contents) throws Exception{		
+		
+		String[] array = varValStr.split("¶");
+		String tmpContents = contents;
+		for(int j=0; j < array.length; j++) {
+			String tmpVarVal = array[j].replaceAll("§", ",");
+			if(tmpVarVal.length() > 0) {
+				
+				if(tmpContents.contains("#{이름}") && j == 0) {
+					tmpContents = tmpContents.replaceAll("\\#\\{이름\\}", tmpVarVal);
+				}
+				
+				//1번째에 핸드폰 번호가 포함 되어 있어서 건너뜀
+				
+				if(tmpContents.contains("#{1}") && j == 2) {
+					tmpContents = tmpContents.replaceAll("\\#\\{1\\}", tmpVarVal);
+				}
+				
+				if(tmpContents.contains("#{2}") && j == 3) {
+					tmpContents = tmpContents.replaceAll("\\#\\{2\\}", tmpVarVal);
+				}
+				
+				if(tmpContents.contains("#{3}") && j == 4) {
+					tmpContents = tmpContents.replaceAll("\\#\\{3\\}", tmpVarVal);
+				}
+				
+				if(tmpContents.contains("#{4}") && j == 5) {
+					tmpContents = tmpContents.replaceAll("\\#\\{4\\}", tmpVarVal);
+				}
+				
+			}
+			
+		}
+		
+		System.out.println(tmpContents); 
+		
+		return tmpContents;
+	}
+	
+	/*
+	 * 카카오 친구톡 치환문자 내용 스팸 필터
+	 * 치환변수 내용 및 템플릿 내용, 스팸필터 단어 리스트를 전달하면 스팸 문구 포함 문구 리턴
+	 * 없으면 공백을 리턴
+	 * 
+	 * */
+	public String getKakaoFTCntRepToSpamFilter(List<String[]> varValList, List<String> resultSpamTxt, String contents) throws Exception {
+		String spmFilterTxt = "";
+		for(int i=0; i < varValList.size(); i++) {
+			//String[] array = varValList.get(i)[0].split("¶");
+			String tmpContents = getKakaoFTCntReplace(varValList.get(i)[0], contents);
+			System.out.println(tmpContents);
+			
+			//입력 문장에 대해서 우회 문장 또는 특수 기호 입력 제거 등 문장 재구성 처리, 한글 자모음 분리 및 재조함도 함께 처리함.
+			String resultParser = ComGetSpamStringParser.getSpamTextParse(tmpContents).trim();
+			//List<String> jasoList = HangulParser.disassemble(resultParser);
+			//String assembleStr = HangulParser.assemble(jasoList);
+			
+			System.out.println("++++++++++++++ spam resultParser ::: "+resultParser);
+			
+			//데이터베이스에 등록된 스팸문구와 일치하는 단어/문구가 있는지 체크함.
+			int spmCnt = 0;
+			for(String spmTxt : resultSpamTxt) {
+				
+				String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
+				
+				if(resultParser.contains(parserStr)) {
+					
+					//스팸 단어/문구가 있으면 콤마로 연결시킨 후 리턴해줌.
+					spmFilterTxt += spmTxt + ",";
+					spmCnt++;
+					
+				}
+				
+			}
+			
+			if(spmCnt > 0) {//스팸문자가 포함되어 있으면 문자열 끝 , 단어 삭제 처리
+				
+				if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
+					// 처음부터 idx 만큼 잘라낸 나머지 글자 
+					spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1); 	
+					
+				}
+				
+				System.out.println("++++++++++++++ spmFilterTxt ::: "+spmFilterTxt);
+				
+				return spmFilterTxt;
+				
+			}
+			
+		}
+		return "";
+	}
+	
+	/*
+	 * 치환문자가 없는 내용에 대한 스팸필터링 처리
+	 * 
+	 * */
+	public String getKakaoFTCntToSpamFilter(List<String> resultSpamTxt, String contents) throws Exception {
+		String spmFilterTxt = "";
+		//for(int i=0; i < varValList.size(); i++) {
+			//String[] array = varValList.get(i)[0].split("¶");
+			String tmpContents = contents;
+			System.out.println(tmpContents);
+			
+			//입력 문장에 대해서 우회 문장 또는 특수 기호 입력 제거 등 문장 재구성 처리, 한글 자모음 분리 및 재조함도 함께 처리함.
+			String resultParser = ComGetSpamStringParser.getSpamTextParse(tmpContents).trim();
+			//List<String> jasoList = HangulParser.disassemble(resultParser);
+			//String assembleStr = HangulParser.assemble(jasoList);
+			
+			System.out.println("++++++++++++++ spam resultParser ::: "+resultParser);
+			
+			//데이터베이스에 등록된 스팸문구와 일치하는 단어/문구가 있는지 체크함.
+			int spmCnt = 0;
+			for(String spmTxt : resultSpamTxt) {
+				
+				String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
+				
+				if(resultParser.contains(parserStr)) {
+					
+					//스팸 단어/문구가 있으면 콤마로 연결시킨 후 리턴해줌.
+					spmFilterTxt += spmTxt + ",";
+					spmCnt++;
+					
+				}
+				
+			}
+			
+			if(spmCnt > 0) {//스팸문자가 포함되어 있으면 문자열 끝 , 단어 삭제 처리
+				
+				if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
+					// 처음부터 idx 만큼 잘라낸 나머지 글자 
+					spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1); 	
+					
+				}
+				
+				System.out.println("++++++++++++++ spmFilterTxt ::: "+spmFilterTxt);
+				
+				return spmFilterTxt;
+				
+			}
+			
+		//}
+		return "";
+	}
+	
 }
src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
@@ -228,18 +228,128 @@
 	}
 	
 	
-	/** 
-	 * @methodName	: kakaoFriendsTalkMsgDataView 
-	 * @author		: 우영두
-	 * @date		: 2024.01.05 
-	 * @description	: kakaoFriendsTalkMsgDataView 카카오 친구톡 발송 화면 템플릿 팝업 리스트 조회
-	 * @param kakaoVO
-	 * @param model
-	 * @param response
-	 * @return
-	 * @throws Exception 
-	 */
+	/**
+	* @Method Name : selectSpamKakaoFriendsTalkMsgChkAjax
+	* @작성일 : 2024. 1. 15.
+	* @작성자 :  우영두
+	* @Method 설명 : 카카오 친구톡 전송시 스팸문구 확인 체크
+	*/
+	@RequestMapping(value= {"/web/mjon/kakao/friendstalk/selectSpamKakaoFriendsTalkMsgChkAjax.do"})
+	public ModelAndView selectSpamKakaoFriendsTalkMsgChkAjax(ModelMap model
+			, @ModelAttribute("kakaoVO")  KakaoVO kakaoVO) throws Exception {
+		ModelAndView modelAndView = new ModelAndView(); 
+		modelAndView.setViewName("jsonView");
+		
+		try {
+			List<String> resultSpamTxt = mjonMsgDataService.selectSpamKeywordList();
+			System.out.println("친구톡  스팸 필터링");
+			
+			if(resultSpamTxt == null) {
+				modelAndView.addObject("result", "listEmpty");
+				return modelAndView;
+			}else {
+				//변환변수 포함(Y) 미포함(N)
+				String spmFilterTxt = "";
+
+				if(kakaoVO.getTxtReplYn().equals("Y")) {
+					List<String[]> varValList = kakaoVO.getVarValList(); // value 값
+					
+					String resultSpam = kakaoSendUtil.getKakaoFTCntRepToSpamFilter(varValList, resultSpamTxt, kakaoVO.getTemplateContent());
+					
+					if(resultSpam.length() > 0) {
+						
+						modelAndView.addObject("result", "spams");
+						return modelAndView;
+						
+					}
+					
+					if(kakaoVO.getSubMsgSendYn().equals("Y")) {
+						
+						String resultSmsTxtSpam = kakaoSendUtil.getKakaoFTCntRepToSpamFilter(varValList, resultSpamTxt, kakaoVO.getSmsTxtArea());
+						
+						if(resultSmsTxtSpam.length() > 0) {
+							
+							modelAndView.addObject("result", "spams");
+							return modelAndView;
+							
+						}
+						
+					}
+					
+				}else {//치환문자가 없는 경우 스팸 필터링
+					
+					String resultSpam = kakaoSendUtil.getKakaoFTCntToSpamFilter(resultSpamTxt, kakaoVO.getTemplateContent());
+					
+					if(resultSpam.length() > 0) {
+						
+						modelAndView.addObject("result", "spams");
+						return modelAndView;
+						
+					}
+					
+					if(kakaoVO.getSubMsgSendYn().equals("Y")) {
+						
+						String resultSmsTxtSpam = kakaoSendUtil.getKakaoFTCntToSpamFilter(resultSpamTxt, kakaoVO.getSmsTxtArea());
+						
+						if(resultSmsTxtSpam.length() > 0) {
+							
+							modelAndView.addObject("result", "spams");
+							return modelAndView;
+							
+						}
+						
+					}
+					
+				}
+				
+			}
+			
+		}catch (Exception e) {
+			e.printStackTrace();
+			modelAndView.addObject("message", egovMessageSource.getMessage("fail.common.select"));
+			modelAndView.addObject("result", "fail");
+			return modelAndView;
+		}
+		
+		return modelAndView;
+	}
 	
 	
 	
+	/**
+	* @Method Name : kakaoFriendsTalkMsgSendAjax
+	* @작성일 : 2024. 1. 16.
+	* @작성자 :  우영두
+	* @Method 설명 : 카카오 친구톡 전송
+	*/
+	@RequestMapping(value= {"/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax.do"})
+	public ModelAndView kakaoFriendsTalkMsgSendAjax(ModelMap model
+			, @ModelAttribute("kakaoVO")  KakaoVO kakaoVO) throws Exception {
+		ModelAndView modelAndView = new ModelAndView(); 
+		modelAndView.setViewName("jsonView");
+		
+		System.out.println("++++++++++++++++++++++ senderKey ::: "+kakaoVO.getSenderKey());
+		System.out.println("++++++++++++++++++++++ imageType ::: "+kakaoVO.getImageType());
+		System.out.println("++++++++++++++++++++++ imageTitle ::: "+kakaoVO.getImageTitle());
+		System.out.println("++++++++++++++++++++++ imageLink ::: "+kakaoVO.getImageLink());
+		System.out.println("++++++++++++++++++++++ imageFileName ::: "+kakaoVO.getImageFileName());
+		System.out.println("++++++++++++++++++++++ adFlag ::: "+kakaoVO.getAdFlag());
+		System.out.println("++++++++++++++++++++++ templateContents ::: "+kakaoVO.getTemplateContent());
+		System.out.println("++++++++++++++++++++++ kakaoFtPrice ::: "+kakaoVO.getKakaoFtPrice());
+		System.out.println("++++++++++++++++++++++ eachPrice ::: "+kakaoVO.getEachPrice());
+		System.out.println("++++++++++++++++++++++ totPrice ::: "+kakaoVO.getTotalPrice());
+		
+		List<String[]> varValList = new ArrayList<String[]>();
+		
+		System.out.println(kakaoVO.getTxtReplYn());
+		
+		/*for(List<String[]> varValList : kakaoVO.getVarValList()) {
+			
+			
+		} */
+		
+		
+		return modelAndView;
+	}
+	
 }
src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp
@@ -4,7 +4,7 @@
 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
 <%@ taglib prefix="ec" uri="/WEB-INF/tld/ecnet_tld.tld"%>
-
+<%@ page import="itn.com.cmm.LoginVO" %>
 <script src="/js/kakao/templateComm.js"></script>
 
 <script type="text/javascript" src="<c:out value='/js/MJUtill.js' />"></script>
@@ -17,6 +17,8 @@
 
 
 <script type="text/javascript">
+
+var loginVO = '${loginVO}';
 /* 파일등록 */
 var _fileIdx = 0;
 var _fileForm2 = new Array();
@@ -80,6 +82,83 @@
 		}
 		
 	});
+	
+	
+	$("#send_fail_check").change(function(){
+		if($("#send_fail_check").is(":checked")){
+
+			
+			if(loginVO == "" || loginVO == null){
+				alert("로그인 후 사용 가능한 기능입니다.");
+				location.href="<c:url value='/web/user/login/login.do'/>";
+				return false;
+				
+				$("#send_fail_check").prop("checked", false);
+			}
+			
+			if($('#callFromList').val() === ''){
+				
+				if(confirm('대체문자 전송을 위한 발신번호가 등록되지 않았습니다. \n대체문자 발신번호를 지금 등록하시겠습니까?')){
+					window.location="<c:out value='/web/user/sendNumberManage.do' />";
+				}
+				$("#send_fail_check").prop("checked", false);
+				
+			}else{
+				// 에러버튼 체크 초기화
+				fn_insertErrorYN('N');
+				
+				$('#smsTxtArea').val('');
+// 				// 미리보기 텍스트를 가져와 줄바꿈 처리 후 대체문자 내용으로 입력
+				$('#smsTxtArea').val(
+					$('.template_text').html().trim().replace(/(<br>|<br\/>|<br \/>)/g, '\r\n')
+				);
+
+// 				//문자 내용 입력시 바이트수 계산하기
+				
+				$(".replace_send_wrap").slideDown(400);
+				thisFnByteString($('#smsTxtArea').val());
+			}
+		}else{
+			$(".replace_send_wrap").slideUp(400);
+			// 초기화 버튼 클릭
+			$('#failCheckInit').click();
+			$('.send_top .send_right .phone').css({'top': '0','transition': 'top .4s linear'});
+		}
+
+		// 금액 계산 fn 호출
+		totalFtPriceSum(tableL.getRows().length);
+		//fn_priceClclt();
+	});
+	
+	// 대체문자 내용 수정
+	$('#smsTxtArea').keyup(function(){
+		// 금액 계산 fn 호출
+		totalFtPriceSum(tableL.getRows().length);
+		//fn_priceClclt();
+		// 문자 바이트수 체크
+		thisFnByteString($('#smsTxtArea').val());
+		// 에러버튼 체크 초기화
+		fn_insertErrorYN('N');
+		
+	});
+	
+	
+	//대체문자 초기화 버튼 선택 처리
+	$("#failCheckInit").click(function(){
+		
+		$('#smsTxtArea').val("");
+		
+		// 금액 계산 fn 호출
+		totalFtPriceSum(tableL.getRows().length);
+		//fn_priceClclt();
+		// 문자 바이트수 체크
+		thisFnByteString($('#smsTxtArea').val());
+		// 에러버튼 체크 초기화
+		fn_insertErrorYN('N');
+		
+	});
+	
+	
 });
 
 function initFormChk(){
@@ -670,11 +749,620 @@
 	
 }
 
+
+//친구톡 발송 금지 시간 처리
 function fn_noTimeSend(){
 	
 	alert("친구톡은 20:50 ~ 익일 08:00까지 발송할 수 없습니다.");
 	return false;
 	
+}
+
+//친구톡 데이터 전송 처리
+function fn_sendMsgData(){
+	
+	//이미지 첨부 체크	
+	var imgChk = $("input[name=img_file_add]:checked").val();
+	if(imgChk == 'I' || imgChk == 'W'){
+		
+		var imgTitle = $("#imgTitle").val();
+		var imgLink = $("#imgLink").val();
+		var imgFileName = $("#imageFileName").val();
+		
+		if(imgTitle == ''){
+			
+			alert("친구톡 이미지 제목정보를 입력해 주세요.");
+			return false;
+			
+		}
+		
+		if(imgLink == ''){
+			
+			alert("친구톡 이미지 선택시 이동할 링크 주소를 입력해 주세요.");
+			return false;
+			
+		}
+		
+		if(imgFileName == ''){
+			
+			alert("친구톡 이미지를 등록해 주세요.");
+			return false;
+			
+		}
+		
+		$("#imageType").val(imgChk);
+		
+	}
+	
+	//친구톡 내용 체크
+	var tmpContents = $('#inputTemplateContent').val();
+
+	if(tmpContents == ""){
+		
+		alert("친구톡 내용을 입력해 주세요.");
+		return false;
+		
+	}
+	
+	var rtnStr = strChinJpnCheck(tmpContents);
+	
+	console.log(tmpContents);
+	console.log("+++++++++++ emojiCheck ::: "+emojiCheck(tmpContents));
+	
+	//문자내용에 이모지가 있는지 체크
+	if(!emojiCheck(tmpContents)) return false;
+	
+	if(rtnStr.length > 0){
+		
+		alert("입력하신 문구 중 \" " + rtnStr + " \" 는 일부 휴대폰에서 표기되지 않을 수 있습니다.");
+		
+	}
+	
+	
+
+	//수신번호 리스트 체크하기
+	var numCnt = 0;
+	var nameList = [];		//치환문자 이름
+	var phoneNum = [];	//받는사람
+	var rep1List = [];		//치환문자1
+	var rep2List = [];		//치환문자2
+	var rep3List = [];		//치환문자3
+	var rep4List = [];		//치환문자4
+	
+	var varValList = [];		//치환문자 연결시킬 변수 셋팅
+	
+	var selectedData = tableL.getRows();
+	
+	var varValStatus = true; //치환분자 데이터 체크용
+	
+	if(selectedData == "" || selectedData == null){
+		
+		alert("받는사람 주소를 한 건 이상 입력해주세요.");
+		return false;
+	
+	}else{ // 선택한 Row '-' 문자 삭제하기
+		
+		var txtReplYn = $("#txtReplYn").val();
+		
+		if(txtReplYn == 'Y'){//치환문자가 있는 경우 변수 치환 처리
+		
+			for(var i=0; i < selectedData.length; i++){
+				
+				var nmStatus = false;
+				var rep1Status = false;
+				var rep2Status = false;
+				var rep3Status = false;
+				var rep4Status = false;
+				
+				
+				if(tmpContents.indexOf("\#{이름}")  > -1){
+					
+					nmStatus = true;
+				}
+				
+				if(tmpContents.indexOf("\#{1}")  > -1){
+					
+					rep1Status = true;
+				}
+				
+				if(tmpContents.indexOf("\#{2}")  > -1){
+					
+					rep2Status = true;
+				}
+				
+				if(tmpContents.indexOf("\#{3}")  > -1){
+					
+					rep3Status = true;
+				}
+				
+				if(tmpContents.indexOf("\#{4}")  > -1){
+					
+					rep4Status = true;
+				}
+				
+				//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
+				var name = tableL.getRows()[i].getData().name;
+				var phone = removeDash(tableL.getRows()[i].getData().phone);
+				var rep1 = tableL.getRows()[i].getData().rep1;
+				var rep2 = tableL.getRows()[i].getData().rep2;
+				var rep3 = tableL.getRows()[i].getData().rep3;
+				var rep4 = tableL.getRows()[i].getData().rep4;
+				var varValStr = "";	//¶ 구분자
+				
+				if(phone == ""){
+					
+					alert("수신 목록에 핸드폰 번호가 없는 항목이 있습니다.");
+					return false;
+					
+				}else if(!checkHpNum(phone)){
+					
+					alert("수신 목록에 잘 못된 핸드폰 번호가 있습니다. 핸드폰 번호 : " + phone + " 입니다.");
+					return false;
+					
+				}else{
+					
+					if(typeof(name) != 'undefined' && name != null && name !=""){
+						if(!emojiCheck(name)){//이모지 체크 해주기
+							return false;
+						}
+						
+						//이름 치환변수가 있으면 저장
+						if(nmStatus){
+							//nameList[i] = name.replaceAll(",","§");
+							if(varValStr == ''){
+								
+								varValStr = name.replaceAll(",","§");
+							}else{
+								
+								varValStr = varValStr + "¶" +  name.replaceAll(",","§");
+								
+							}
+						}
+					}else{
+						if(nmStatus){
+							varValStatus = false;
+						}
+					}
+
+					
+					if(phone != '' && phone != null){
+						//연락처 변수 저장하기
+						phoneNum[i] = phone;
+						if(varValStr == ''){
+							varValStr = phone;	
+						}else{
+							varValStr = varValStr + "¶" +  phone;
+						}
+					}else{
+						varValStatus = false;
+					}
+					
+					if(typeof(rep1) != 'undefined' && rep1 != null && rep1 !=""){
+						if(!emojiCheck(rep1)){//이모지 체크 해주기
+							return false;
+						}
+						
+						if(rep1Status){
+							
+							if(varValStr == ''){
+								//rep1List[i] = rep1.replaceAll(",","§");
+								varValStr = rep1.replaceAll(",","§");
+							}else{
+								//rep1List[i] = rep1.replaceAll(",","§");
+								varValStr = varValStr + "¶" +  rep1.replaceAll(",","§");
+							}
+						}
+					}else{
+						if(rep1Status){
+							varValStatus = false;
+						}
+					}
+					
+					if(typeof(rep2) != 'undefined' && rep2 != null && rep2 !=""){
+						if(!emojiCheck(rep2)){//이모지 체크 해주기
+							return false;
+						}
+						
+						if(rep2Status){
+							
+							if(varValStr == ''){
+								varValStr = rep2.replaceAll(",","§");
+							}else{
+								//rep2List[i] = rep2.replaceAll(",","§");
+								varValStr = varValStr + "¶" +  rep2.replaceAll(",","§");
+							}
+						}
+					}else{
+						if(rep2Status){
+							varValStatus = false;
+						}
+					}
+					
+					
+					if(typeof(rep3) != 'undefined' && rep3 != null && rep3 !=""){
+						if(!emojiCheck(rep3)){//이모지 체크 해주기
+							return false;
+						}
+						
+						if(rep3Status){
+							
+							if(varValStr == ''){
+								varValStr = rep3.replaceAll(",","§");
+							}else{
+								//rep3List[i] = rep3.replaceAll(",","§");
+								varValStr = varValStr + "¶" +  rep3.replaceAll(",","§");
+							}
+						}
+					}else{
+						if(rep3Status){
+							varValStatus = false;
+						}
+					}
+					
+					
+					if(typeof(rep4) != 'undefined' && rep4 != null && rep4 !=""){
+						if(!emojiCheck(rep4)){//이모지 체크 해주기
+							return false;
+						}
+						
+						if(rep4Status){
+							
+							if(varValStr == ''){
+								varValStr = rep4.replaceAll(",","§");
+							}else{
+								//rep4List[i] = rep4.replaceAll(",","§");
+								varValStr = varValStr + "¶" +  rep4.replaceAll(",","§");
+							}
+						}
+					}else{
+						if(rep4Status){
+							varValStatus = false;
+						}
+					}
+					
+				}
+				
+				varValList[i] = varValStr;
+				
+			}
+		
+		}else{//치환문자가 없는 경우 휴대폰 번호만 입력
+			
+			for(var i=0; i < selectedData.length; i++){
+				
+				//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
+				var phone = removeDash(tableL.getRows()[i].getData().phone);
+				
+				if(phone == ""){
+					
+					alert("수신 목록에 핸드폰 번호가 없는 항목이 있습니다.");
+					return false;
+					
+				}else if(!checkHpNum(phone)){
+					
+					alert("수신 목록에 잘 못된 핸드폰 번호가 있습니다. 핸드폰 번호 : " + phone + " 입니다.");
+					return false;
+					
+				}else{
+					
+					phoneNum[i] = phone;
+					
+				}
+				
+			}
+		
+		}
+	
+	}
+	
+	//예약문자 시간 체크
+	var reserYn = $("input[name=reserYn]:checked").val(); // 예약 발송 여부 확인
+	
+	if(reserYn == 'Y'){
+		
+		var date = $(".resDate").val();//form.msgResDate.value;
+		var hour = $("#msgResHour option:selected").val();
+		var min = $("#msgResMin option:selected").val();
+		
+		if(date == ""){
+			
+			alert("예약전송 날짜를 선택해 주세요.");
+			return false;
+			
+		}else{
+			
+			var now = new Date();
+			var reqDate = date + " " + hour + ":" + min + ":00";
+			var gapDate = getGapDayTime(date, hour, min);
+			
+			if(gapDate < 0){ // 음수이면 이전날짜, 크면 이후 날짜.
+				alert("예약 날짜는 현재 시간 이후의 날짜 및 시간을 선택해 주세요.");
+				return false;
+			}else{
+				$("#reqDate").val(reqDate);	//예약일자 파라미터 저장
+			}
+		}
+
+	}else{
+		
+		$("#reqDate").val("");	//예약일자 파라미터 저장
+		
+	}
+	
+	
+	//대체문자 선택 및 내용 체크
+	var subMsgSendYn = "N";
+	
+	if($("#send_fail_check").is(":checked")){
+		
+		subMsgSendYn = "Y";
+		$("#subMsgSendYn").val("Y");
+		
+		//대체문자 체크사항 함수 호출
+		if(!fn_subMsgCheck()){ 
+			
+			/* $("#send_fail_check").prop("checked", false);
+			$(".replace_send_wrap").slideUp(400);
+			// 초기화 버튼 클릭
+			$('#failCheckInit').click();
+			$('.send_top .send_right .phone').css({'top': '0','transition': 'top .4s linear'}); */
+			return false;
+		
+		}
+		
+	}else{
+		
+		subMsgSendYn = "N";
+		$("#subMsgSendYn").val("N");
+		
+	}
+	
+	//수신전화번호 목록
+	$("#callToList").val(phoneNum);
+	
+	//치환변수 데이터 정보 목록(수신번호 포함, tabulator 정보 모두 )
+	$("#varValList").val(varValList);
+
+	//템플릿 내용 입력
+	$("#templateContent").val(tmpContents);
+	
+	//광고포함 여부
+	var adFlag = $("input[name=ad_flag]:checked").val();
+	$("#adFlag").val(adFlag);
+	
+	if(!varValStatus){
+		
+		alert("특정문구 일괄변환에 대한 일부 데이터가 누락된 부분이 있습니다. 데이터를 확인해 주세요.");
+		return false;
+		
+	}
+	
+	if(!confirm("친구톡을 발송하시겠습니까?")){
+		
+		return false;
+		
+	}
+	
+	var spamChk = true;
+	
+	var spmData = new FormData(document.bizForm);
+	$.ajax({
+		type: "POST"
+		, url: "/web/mjon/kakao/friendstalk/selectSpamKakaoFriendsTalkMsgChkAjax.do"
+		, data: spmData
+		, dataType:'json'
+		, async: false
+		, processData: false
+		, contentType: false
+		, cache: false
+		, success: function (returnData, status) {
+			if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
+				
+				if("fail" == returnData.result){
+					alert(returnData.message);
+					return false;
+				}else if("loginFail" == returnData.result){
+					alert(returnData.message);
+					return false;
+				}else if("spams" == returnData.result){
+					alert("전송 내용에  스팸문구가 포함되어 있습니다.")
+					$("#spamStatus").val("Y");
+					return false;
+				}else{
+					spamChk = true;
+					return false;
+				}
+				
+			} else if(status== 'fail'){
+				alert(returnData.message);
+				return false;
+			}
+		}
+		, error: function (e) {
+			alert("문자 발송에 실패하였습니다.");
+			console.log("ERROR : ", e);
+			return false;
+		}
+	});
+	
+	if(spamChk){
+		var data = new FormData(document.bizForm);
+		$.ajax({
+			type: "POST"
+			, url: "/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax.do"
+			, data: data
+			, dataType: 'json'
+			, async: true
+			, processData: false
+			, contentType: false
+			, cache: false
+			, success: function (returnData, status) {
+				if(status == 'success'){
+					if("loginFail" == returnData.result){
+						
+						alert(returnData.message);
+						return false;
+						
+					}else  if('fail' == returnData.result){
+						
+						alert(returnData.message);
+						return false;
+						
+					}else if('authFail' == returnData.result){
+						
+						alert(returnData.message);
+						location.reload();
+						
+					} else if(status == 'success'){
+						
+						var kakaoSendCnt = returnData.resultSts;
+						
+						$('.pop_msg_success').css({'display':'block','opacity':'1','left':'50%','top':'50%','transform':'translate(-50%,-50%)'});
+						
+						//예약발송 건의 경우 결과 팝업 문구 변경
+						if(reserYn == 'Y'){
+							$('.pop_msg_success .msg_text').html("예약 성공 : <strong>"+ kakaoSendCnt + "</strong>건의<br>친구톡이 예약 되었습니다.");
+						}else{
+							$('.pop_msg_success .msg_text').html("발송 성공 : <strong>"+ kakaoSendCnt + "</strong>건의<br>친구톡이 발송 되었습니다.");
+						}
+						
+						$('.mask').addClass('on');
+					}
+				}
+			}
+			,beforeSend : function(xmlHttpRequest) {
+				//로딩창 show
+				$('.loading_layer').addClass('active');
+			}
+			,complete : function(xhr, textStatus) {
+				//로딩창 hide
+				$('.loading_layer').removeClass('active');
+			}
+			,error: function (e) {
+				console.log("ERROR : ", e);
+				alert("카카오 친구톡 전송에 실패하였습니다.");
+			}
+		}); 
+	}
+	
+}
+
+
+/**
+ * @description 대체문자 오류체크 funciton
+ */
+function fn_errorChk(){
+
+	// 대체문자가 없을 시 return false;
+	if($('#txtReplYn').val() === 'N')
+	{
+		alert('오류가 없습니다.');
+		return false;
+	}
+
+	// 치환 부분 변수명만 추출 = 배열
+	var varList = $("#inputTemplateContent").val().match(/#\{([^}]+)\}/g);
+	
+	var smsTxt = $('#smsTxtArea').val();
+	for(var i=0; i < varList.length; i++){
+		if(smsTxt.indexOf(varList[i]) < 0){
+			if(confirm(varList[i] + '값이 없습니다. 치환문자 없이 진행하시겠습니까?')){
+				fn_insertErrorYN('Y');
+			};
+			return false;
+		}
+		smsTxt = smsTxt.replace(varList[i], '');
+	};
+	alert('오류가 없습니다.');
+	fn_insertErrorYN('Y');
+}
+
+
+function fn_insertErrorYN(val){
+	$('#errorChk').val(val);
+}
+
+/*
+ *대체문자 필수 항목 체크 
+ *
+ **/
+ 
+function fn_subMsgCheck(){
+
+	if($('#callFromList').val() === ''){
+		
+		if(confirm('대체문자 전송을 위한 발신번호가 등록되지 않았습니다. \n대체문자 발신번호를 지금 등록하시겠습니까?')){
+			window.location="<c:out value='/web/user/sendNumberManage.do' />";
+		}
+		$("#send_fail_check").prop("checked", false);
+		
+		return false;
+		
+	}else{
+	
+		//발신번호 입력 처리
+		$("#callFrom").val(removeDash($('#callFromList').val()));
+		
+	}
+	
+	if($("#smsTxtArea").val() === ''){
+		
+		alert("대체문자 내용을 입력해 주세요.");
+		return false;
+		
+	}
+	
+	return true;
+	
+}
+
+//문자 바이트수 계산하기 함수
+function thisFnByteString(contents){
+	var totalByte = 0; 
+	//var content = contents;
+	var adverYn = $("input[name='send_adYn']:checked").val();
+	var adTxtLeng = 0;
+	var denyTxtLeng = 0;
+
+	$('#msgLeng').html("");
+	$('#limitLeng').html("");
+	var conLeng = conByteLeng(contents); // 내용 문자 입력 바이트 수 계산하기
+	
+		
+	$('#msgLeng').text(conLeng);
+	
+	//문자 길이 변수에 저장해주기
+	$('#smsLen').val(conLeng);
+	
+	
+	if(conLeng > 90){
+		
+		$('#msgLeng').html(conLeng + " / ");
+		$('#limitLeng').html("2000");
+		$('.msg_com').html("장문");
+		$('#msgType').val("6"); // 메세지 타입 설정
+		
+		$('.msg_com').removeClass("msg_short"); //단문 클래스 삭제하고
+		$('.put_left').removeClass("short"); //내용 입력 박스 클래스 삭제
+		$('.msg_com').addClass("msg_long"); // 장문 클래스 삽입
+// 		$('.put_left').addClass("long");  // 내용 입력 박스에 클래스 삽입
+// 		$('.msg_title').addClass('active');
+		//document.getElementById("mmsSubject").disabled = false;
+		
+	}else{
+		
+		$('#msgLeng').html(conLeng + " / ");
+		$('#limitLeng').html("90");
+		$('.msg_com').html("단문");
+		$('#msgType').val("4"); // 메세지 타입 설정
+		$('.msg_com').removeClass("msg_long"); //단문 클래스 삭제하고
+		$('.put_left').removeClass("long"); //내용 입력 박스 클래스 삭제
+		$('.msg_com').addClass("msg_short"); // 장문 클래스 삽입
+// 		$('.put_left').addClass("short");  // 내용 입력 박스에 클래스 삽입
+// 		$('.msg_title, .title_wrap .textbox').removeClass('active');
+		
+	}
+		
 }
 
 </script>
@@ -719,8 +1407,30 @@
 				
 				<!-- 예약발송 여부 -->
 				<input type="hidden" id="reserveYn" name="reserveYn" value="N"/>
+				<input type="hidden" id="reqDate" name="reqDate" value=""/>
+				
 				<!-- 변환문자 유무 -->
 				<input type="hidden" id="txtReplYn" name="txtReplYn" value="N"/>
+				<input type="hidden" id="varValList" name="varValList" value=""/>
+				
+				<!-- 수신목록 -->
+				<input type="hidden" id="callToList" name="callToList" value=""/>
+				
+				<!-- 스팸 문구 유무 -->
+				<input type="hidden" id="spamStatus" name="spamStatus" value="N"/>
+				
+				<!-- 오류 체크 -->
+				<input type="hidden" id="errorChk" name="errorChk" value="N"/>
+				
+				<!-- 대체문자 여부 -->
+				<input type="hidden" id="subMsgSendYn" name="subMsgSendYn" value="N"/>
+				
+				<!-- 발신번호정보 -->
+				<input type="hidden" id="callFrom" name="callFrom" value=""/>
+				
+				<!-- 친구톡 발송 단가 정보 -->
+				<input type="hidden" id="eachPrice" name="eachPrice" value=""/>
+				<input type="hidden" id="totPrice" name="totalPrice" value=""/>
 				
 				<div class="send_general friend_talk_wrap kakao_wrap">
 					<div class="send_left">
@@ -1204,7 +1914,7 @@
 								<tr>
 									<th colspan="2" class="replace_send_th">
 										<div class="title_th"><p>대체문자</p> 
-											<input type="checkbox" id="send_fail_check" class="send_fail_check">
+											<input type="checkbox" id="send_fail_check" name="send_fail_check" class="send_fail_check">
 											<label for="send_fail_check">친구톡 전송 실패 시 문자 전송</label>
 										</div>
 										<div class="replace_send_wrap">
@@ -1249,7 +1959,7 @@
 																				<span class="fwMd" id="msgLeng">0 /</span>
 																				<span class="c_002c9a fwMd" id="limitLeng">90</span>byte
 																			</p>
-																			<spanclass="msg_com msg_short">단문</span>
+																			<span class="msg_com msg_short">단문</span>
 																		</div>
 																	</div>
 																</div>
@@ -1258,7 +1968,6 @@
 																	<button type="button" class="btnType btnType7" onclick="javascript:fn_errorChk(); return false;">오류검사<i class="qmMark"></i></button>
 																</div>
 															</div>
-															<p>* 현재 [<span id="nowMsgType">단문</span>] <span class="c_e40000 fwBold nowMsgCnt">0</span>건 발송 가능합니다.</p>
 														</td>
 													</tr>
 												</tbody>
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
@@ -541,9 +541,6 @@
 			
 		}
 		
-		
-		
-		
 	});//문자 바이트수 계산하기 끝
 	
 	
src/main/webapp/js/kakao/ft/friendstalkExcel.js
--- src/main/webapp/js/kakao/ft/friendstalkExcel.js
+++ src/main/webapp/js/kakao/ft/friendstalkExcel.js
@@ -151,154 +151,3 @@
 	}
 	
 }
-/*function excelExport(event){
-	
-	var fileValue = $("#excelFile").val().split("\\");
-	var fileName = fileValue[fileValue.length-1];
-	
-	var fileExt = fileName.split('.').pop().toLowerCase();
-
-	if(fileExt.length > 0){
-		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
-
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return false;
-
-	   	}
-		
-		//$("#excelFile").val("");
-		//선택 파일명 화면에 표시해주기
-	    $("#excelNm").val(fileName);
-		
-	}
-	
-}*/
-
-
-//엑셀파일 자료 데이터베이스에 입력해주기
-function fnInsertAttchFileData(){
-	
-	var data = new FormData(document.excelForm);
-	data.append("file0", $('#excelFile').prop('files')[0]);
-	
-	var fileValue = $("#excelFile").val().split("\\");
-	var fileName = fileValue[fileValue.length-1];
-	
-	var fileExt = fileName.split('.').pop().toLowerCase();
-	
-	var url = "";
-	
-	if(fileExt == "xls" || fileExt == "xlsx"){
-		
-		//url = "/web/mjon/msgcampain/insertExelFileTWCallToAjax.do";
-		
-	}else if(fileExt = "txt"){
-		
-		//url = "/web/mjon/msgcampain/insertTxtFileTWCallToAjax.do";
-		
-	}else{
-		
-		alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-		return;
-		
-	}
-	
-	//엑셀 데이터 변수에 자료가 있으면 지워준다.
-   	if(excelAddr.length > 0){
-    	
-    	excelAddr = [];
-    	
-    }
-	
-	$.ajax({
-        type: "POST",
-        enctype: 'multipart/form-data',
-        url: url,
-        data: data,
-        dataType:'json',
-        async: true,
-        processData: false,
-        contentType: false,
-        cache: false,
-        //timeout: 600000,
-        success: function (returnData, status) {
-			if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
-				
-				if(returnData.success){
-					
-					var data = returnData.data;
-					var message = returnData.message;
-					
-					if(message != '' ){
-						alert(returnData.message);
-					}
-					
-					
-					if(data != null){
-						
-						$.each(data, function(i, item){
-							
-							//form 데이터 callSeq에 순번 입력해주기
-							$("#callSeq").val(item.callSeq);
-							
-						});
-
-					}
-					
-					//입력된 데이터베이스에서 받는사람 20건 불러와서 화면에 표시해주기
-					var callSeq = $("#callSeq").val();
-					if(callSeq > 0){
-						
-						//첨부파일로 불러온 데이터를 받는사람 목록에 추가해 준다.
-						addTWCallToInfo();
-						
-						//첨부파일 초기화 시켜주기
-					    $("#excelFile").val("");
-					    $("#excelNm").val("");
-						
-					}else{
-						
-						alert("추가 엑셀 데이터가 없습니다.");
-						return false;
-						
-					}
-					
-				}else{
-					alert(returnData.message);
-					excelAddr = []; //엑셀 데이터 저장 변수 초기화
-	        		$("#excelFile").val(""); //첨부파일 input 초기화
-	        	    $("#excelNm").val("");  // 첨부파일 명 초기화
-	        	    fileName = "";
-					return;
-					
-				}
-			} else if(status== 'fail'){
-				alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
-				console.log("status : fail ~");
-			}
-		},
-		error: function (e) { 
-        	alert("첨부파일 불러오는 중 오류가 발생하였습니다."); 
-        	console.log("ERROR : ", e); 
-        },
-		beforeSend : function(xmlHttpRequest) {
-        	//로딩창 show
-        	$('.loading_layer').addClass('active');				
-		},	        	        
-        complete : function(xhr, textStatus) {
-        	//로딩창 hide
-        	$('.loading_layer').removeClass('active');
-		}
-    });
-	
-}
-
-//엑셀 불러오기 팝업의 추가 버튼 처리
-$("#excelAdd").click(function(){
-	
-	var callSeq = $("#callSeq").val();
-	
-	//엑셀파일 자료 데이터베이스에 입력해주기
-	fnInsertAttchFileData();
-	
-});
(No newline at end of file)
src/main/webapp/js/kakao/ft/ftPriceClclt.js
--- src/main/webapp/js/kakao/ft/ftPriceClclt.js
+++ src/main/webapp/js/kakao/ft/ftPriceClclt.js
@@ -41,6 +41,20 @@
 		
 	}
 	
+	//대체문자가 있는 경우 대체문자의 단/장문에 따른 금액 계산
+	var subMsgSts = $("#send_fail_check").is(":checked");
+	
+	if(subMsgSts){
+		
+		var conLeng = conByteLeng($('#smsTxtArea').val()); // 내용 문자 입력 바이트 수 계산하기
+		if(conLeng > 90){
+			price = $("#longPrice").val();
+		}else{
+			price = $("#shortPrice").val();
+		}
+		
+	}
+	
 	totalPrice = price * collNumCnt;
 	
 	// 소수점 첫째자리 까지 표시
src/main/webapp/js/kakao/ft/ftTabulator.js
--- src/main/webapp/js/kakao/ft/ftTabulator.js
+++ src/main/webapp/js/kakao/ft/ftTabulator.js
@@ -653,6 +653,7 @@
 		var rep2Status = false;
 		var rep3Status = false;
 		var rep4Status = false;
+		var varValStatus = true;
 		
 		if(smsTxtArea.indexOf("#{이름}")  > -1){
 			
@@ -692,12 +693,28 @@
 					var name = recTableData[j].getData().name;
 					smsTxt = stringReplaceAll(smsTxt, "#{이름}", name);
 					
+				}else{
+					
+					if(nmStatus){
+						//alert("#{이름} 변수에 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+						varValStatus = false;
+						//break;
+					}
+					
 				}
 				
 				if(typeof recTableData[j].getData().rep1 != 'undefined' && recTableData[j].getData().rep1 != null && recTableData[j].getData().rep1 != ""){
 					
 					var rep1 = recTableData[j].getData().rep1;
 					smsTxt = stringReplaceAll(smsTxt, "#{1}", rep1);
+					
+				}else{
+					
+					if(rep1Status){
+						//alert("#{1} 변수에 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+						varValStatus = false;
+						//break;
+					}
 					
 				}
 				
@@ -706,12 +723,28 @@
 					var rep2 = recTableData[j].getData().rep2;
 					smsTxt = stringReplaceAll(smsTxt, "#{2}", rep2);
 					
+				}else{
+					
+					if(rep2Status){
+						//alert("#{2} 변수에 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+						varValStatus = false;
+						//break;
+					}
+					
 				}
 				
 				if(typeof recTableData[j].getData().rep3 != 'undefined' && recTableData[j].getData().rep3 != null  && recTableData[j].getData().rep3 != ""){
 					
 					var rep3 = recTableData[j].getData().rep3;
 					smsTxt = stringReplaceAll(smsTxt, "#{3}", rep3);
+					
+				}else{
+					
+					if(rep3Status){
+						//alert("#{3} 변수에 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+						varValStatus = false;
+						//break;
+					}
 					
 				}
 				
@@ -720,8 +753,15 @@
 					var rep4 = recTableData[j].getData().rep4;
 					smsTxt = stringReplaceAll(smsTxt, "#{4}", rep4);
 					
+				}else{
+					
+					if(rep4Status){
+						//alert("#{4} 변수에 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+						varValStatus = false;
+						//break;
+					}
+					
 				}
-				
 				
 				var msgLen = strMaxCharacterCnt(smsTxt);
 				var maxLenChar = 1000;
@@ -750,16 +790,17 @@
 					
 				}
 				
-				//첫번째 수신자의 변환 텍스트 내용을 적용하여 미리보기 문자내용에 보여주자.
-				if(j == 0){
-					
-					//미리보기에 내용 입력해 주기
-					$('.template_text').text(smsTxt);
-					
-				}
-				
 			}
-
+			
+			//치환문자에 데이터가 누락된 경우 알림 메세지를 보여주고 받는사람 목록을 지워준다.
+			/*if(!varValStatus){
+				
+				alert("치환변수 데이터가 없는 항목이 있습니다. 받는사람 변수 데이터를 확인해 주세요.");
+				tableL.clearData(); //기존 받는사람 목록을 삭제.
+				return false;
+			
+			}*/
+			
 		}
 		
 		//결제 금액 구하기
Add a comment
List