rosewiper 2024-08-30
1. 관리자 문자전송 리스트 30분 딜레이 발송승인/취소 버튼 날짜처리 변경 - 기존 날짜 시간 비교가 24시간 단위로 안되어 있어 24시간 단위로 변경 - yyyyMMddhhmm --> yyyyMMddHHmm 으로 변경
	- 기존 날짜 시간 비교가 24시간 단위로 안되어 있어 24시간 단위로 변경
	- yyyyMMddhhmm --> yyyyMMddHHmm 으로 변경

2. 카카오 알림톡 발송 화면 #{변수명} 설정파일 첨부기능 변경
	- 기존 자바스크립트로 처리되고 있어 한셀 엑셀파일로 저장된 경우 오류 발생
	- 컨트롤러에서 POI방식으로 처리되도록 로직 변경
@78a4cdcaf8f8b6944c41ee645024e2558f31f115
src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
@@ -466,6 +466,318 @@
 		
 		return jr;
 	}
+	
+	
+	/*
+	 * 20240829 신규 추가 우영두
+	 * 기존 Script에서 처리하던 방식 변경
+	 * 카카오 알림톡 엑셀 불러오기 엑셀 처리
+	 * 
+	 * */
+	@RequestMapping(value = "/web/mjon/alimtalk/sendAlimtalkExelVarFilePhoneNumAjax.do")
+	@ResponseBody
+	public Object sendAlimtalkExelVarFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
+	
+		JsonResult jr = new JsonResult();
+		jr.setSuccess(false);
+		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
+		
+		
+		try {
+			
+			//final Map<String, MultipartFile> files = multiRequest.getFileMap();
+			List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
+			
+			// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
+			int fileNameSplitCnt = 0;
+			int excelVarCnt = Integer.parseInt(multiRequest.getParameter("excelVarCnt"));// 알림톡 템플릿 변수 갯수 데이터  
+			String [] excelVarArr = multiRequest.getParameter("excelVarList").split(",");
+			
+			
+			if(!files.isEmpty()) {
+				fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
+				
+				if (files.get(0).getSize() > 0 
+						&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
+						|| files.get(0).getContentType().indexOf("ms-excel") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
+					
+					// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
+					long fileSize = multiRequest.getFile("file0").getSize();
+					
+					String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
+					String errMessage = "";
+			        String cellValue  = "";
+			        String errPhoneLine = "";
+			        int errPhoneCnt = 0;
+			        
+			        //수신번호 유효성 체크
+					String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
+					
+					if(Ext.equals("xls")) {
+						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
+					    HSSFSheet sheet = workbook.getSheetAt(0);
+					    
+					    if(sheet.getLastRowNum() > 501) { 
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+						
+					    List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+					    for(int i=1; i< sheet.getLastRowNum() + 1; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	HSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                HSSFCell cell = null;
+			                boolean errSts = true;
+			                String rtnValueStr = "";
+			                for(int j = 0 ; j < excelVarCnt + 1; j++){ //행읽기(변수갯수 +1 개 만큼 컬럼을 읽음 수신번호 + 변수들)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //수신번호 , 변수들
+			                	if(null == cell || "".equals(cell.toString().trim())) { //수신번호 셀에 값이 없으면 
+			                		if(j == 0) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+			                		}
+			                    	
+			                    }
+			                	
+			                	if(j == 0) {
+			                		
+			                		if(null != cell){
+				                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+				                			case  Cell.CELL_TYPE_NUMERIC:
+				                			cell.setCellType(Cell.CELL_TYPE_STRING);
+				                		}
+				                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+				                		
+				                		if(cellValue.matches(phoneRegExp) && errSts) {
+				                			jm.put("phone", cellValue);
+				                		}else {
+					    	            	errPhoneCnt++;
+					    	            	errPhoneLine += (i+1) + "행 ";
+					    	            	errSts = false;
+					    	            	break;
+				                		}
+				                    }
+			                	}else {
+			                		
+			                		if(cell != null) {
+			                			
+			                			if(j <= excelVarCnt) {//등록 변수 갯수 까지만 입력
+				                			
+			                				switch(cell.getCellType()){ //숫자타임을 문자로 변환
+					                			case  Cell.CELL_TYPE_NUMERIC:
+					                			cell.setCellType(Cell.CELL_TYPE_STRING);
+					                		}
+				                			cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+					                		
+					                		if(cellValue != null && !cellValue.equals("")) {
+					                			rtnValueStr += cellValue + "§";
+					                		}else {//변ㅅ
+					                			rtnValueStr += "" + "§";
+					                		}
+				                			
+				                		}
+			                			
+			                		}else {
+			                			rtnValueStr += "" + "§";
+			                			
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+		                	jm.put("varVal", rtnValueStr.replaceFirst(".$", ""));//변수 데이터 추가
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+					    }
+					    
+					    int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+					
+					}else {//xlsx 엑셀 자료 처리
+						
+						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
+						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
+			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
+			            opcPackage.close();
+			            
+			            int totRowDataCnt = 0;
+			            for(int r=1; r<sheet.getPhysicalNumberOfRows(); r++) {
+			            	
+			            	XSSFRow tmpRow = sheet.getRow(r);
+			            	//System.out.println("=================r:"+r);
+			            	XSSFCell cell = null;
+			            	if(tmpRow.getCell(0) != null) {
+			            		
+			            		cell = tmpRow.getCell(0); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+				            	if(cell != null && !cell.toString().trim().equals("")) {
+				            		//System.out.println("value-" + r + ":" +cell.getStringCellValue()); 
+				            		totRowDataCnt++;
+				            		//System.out.println("tmpRowCnt:"+totRowDataCnt);
+				            	}
+			            		
+			            	}
+			            	
+			            }
+			            
+			            if(totRowDataCnt > 501) { //
+			            	errMessage = "한번에 전송 가능한 최대 발송건은 500건 입니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }
+			            
+			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+			            
+			            for(int i=1; i< sheet.getLastRowNum() + 1; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	XSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                XSSFCell cell = null;
+			                boolean errSts = true;
+			                String rtnValueStr = "";
+			                for(int j = 0 ; j < excelVarCnt + 1; j++){ //행읽기(변수갯수 +1 개 만큼 컬럼을 읽음 수신번호 + 변수들)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //수신번호 , 변수들
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                    	//System.out.println("Cell 데이터가 없습니다.");
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+				                		
+			                		}
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                    }
+			                	
+			                	if(j == 0) {//수신번호 추가
+			                		
+			                		if(cellValue.matches(phoneRegExp) && errSts) {
+			                			jm.put("phone", cellValue);
+			                		}else {
+				    	            	errPhoneCnt++;
+				    	            	errPhoneLine += (i+1) + "행 ";
+				    	            	errSts = false;
+				    	            	break;
+			                		}
+			                		
+			                	}else {//변수 데이터 추가
+			                		
+			                		if(cell != null) {
+			                			
+			                			if(j <= excelVarCnt) {//등록 변수 갯수 까지만 입력
+				                			
+			                				switch(cell.getCellType()){ //숫자타임을 문자로 변환
+					                			case  Cell.CELL_TYPE_NUMERIC:
+					                			cell.setCellType(Cell.CELL_TYPE_STRING);
+					                		}
+				                			cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+					                		
+					                		if(cellValue != null && !cellValue.equals("")) {
+					                			rtnValueStr += cellValue + "§";
+					                		}else {
+					                			rtnValueStr += "" + "§";
+					                		}
+				                			
+				                		}
+			                			
+			                		}else {
+			                			rtnValueStr += "" + "§";
+			                			
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+			                jm.put("varVal", rtnValueStr.replaceFirst(".$", ""));//변수 데이터 추가
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+			                
+			            }
+			            
+			            int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+			            
+					}
+					
+				}
+			}
+			
+		} catch (Exception e) {
+			// TODO: handle exception
+			System.out.println("+++++++++++++++++ sendAlimtalkExelVarFilePhoneNumAjax Controller Error !!! "+e);
+			jr.setSuccess(false);
+			jr.setMessage("엑셀 데이터에 오류가 있습니다. 엑셀 데이터를 확인해 주세요.");
+			return jr;
+			
+		}
+	
+ 		return jr;
+	}
 
 
 	// 카카오 템플릿 목록 조회
src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/msg/SendMsgList.jsp
@@ -781,9 +781,9 @@
 												
 												<c:if test="${result.reserveCYn eq 'N' && result.delayYn eq 'Y' && result.delayCompleteYn eq 'N'}">
 													<br />
-													<fmt:formatDate value="${now}" pattern="yyyyMMddhhmm" var="nowDate" />
+													<fmt:formatDate value="${now}" pattern="yyyyMMddHHmm" var="nowDate" />
 													<fmt:parseDate value="${result.reqFullDate}" pattern="yyyy-MM-dd HH:mm" var="checkValue" />
-													<fmt:formatDate value="${checkValue}" pattern="yyyyMMddhhmm" var="checkDate"/>																								
+													<fmt:formatDate value="${checkValue}" pattern="yyyyMMddHHmm" var="checkDate"/>		
 													<c:if test="${nowDate < checkDate}">
 														<button type="button" class="fillBlue" onclick="fnMsgDelaySendArray('<c:out value="${result.msgGroupId}"/>','<c:out value="${result.userId}"/>'); return false;">발송승인</button>
 														<button type="button" class="fillRed" onclick="fnMsgDelayCancelArray('<c:out value="${result.msgGroupId}"/>','<c:out value="${result.userId}"/>'); return false;">발송취소</button>
src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
@@ -1355,7 +1355,8 @@
 												<div class="receipt_num_top">
 													<input type="text" placeholder="선택된 파일이 없습니다." onfocus="this.placeholder=''" onblur="this.placeholder='번호를 입력하세요'" style="width:340px;">
 													<button type="button" class="btnType btnType6" id="fileClick"/>파일선택</button>
-													<input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExport02(event); return false;" style="display:none"/>
+													<input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExportVarAjax(event); return false;" style="display:none"/>
+													<!-- <input type="file" id="excelFile" accept=".xls, .xlsx" onchange="excelExport02(event); return false;" style="display:none"/> -->
 												</div>
 												<div class="receipt_num_midde">
 													<div class="listType list01" id="wrap02">
@@ -1754,7 +1755,11 @@
 		</div>
 	</div><!--// 엑셀 불러오기 -->
 </form>
-
+<form id="excelVarFileForm" name="excelVarFileForm" method="post">
+	<input type="hidden" id="excelVarCnt" name="excelVarCnt" value="0"/>
+	<input type="hidden" id="excelVarList" name="excelVarList" value=""/>
+	
+</form>
 
 <form id="msgResendForm" name="msgResendForm" method="post">
 	<input name="msgResendFlag" type="hidden" value="N"/>
src/main/webapp/js/kakao/at/alimtalkExcel.js
--- src/main/webapp/js/kakao/at/alimtalkExcel.js
+++ src/main/webapp/js/kakao/at/alimtalkExcel.js
@@ -192,6 +192,208 @@
 }
 
 
+/*
+ * 신규 변수명 설정 엑셀 파일 불러오기
+ * 기존 json 처리가 아닌 POI 방식으로 처리하기 위함
+ * 
+ * */
+function excelExportVarAjax(){
+	
+	var data = document.getElementById('excelFile').files;
+	
+	var fileValue = $("#excelFile").val().split("\\");
+	var fileName = fileValue[fileValue.length-1];
+	
+	var fileExt = fileName.split('.').pop().toLowerCase();
+	
+	if(fileExt.length > 0){
+		if($.inArray(fileExt, ['xls','xlsx']) == -1) {
+
+			alert('xls, xlsx 파일만 업로드 할수 있습니다.');
+			return false;
+
+	   	}
+		
+	}
+	fn_viewDataInit01();
+	excelAddVarAjax();
+}
+
+function excelAddVarAjax(){
+	
+	var varList = $("#excelTemplateContent").val().match(/#\{([^}]+)\}/g);
+	
+	var form = document.excelVarFileForm;
+	form.excelVarCnt.value = varList.length;
+	form.excelVarList.value = varList;
+	
+	var data =  new FormData(form);
+	data.append("file0", $('#excelFile').prop('files')[0]);
+	
+	var url = "/web/mjon/alimtalk/sendAlimtalkExelVarFilePhoneNumAjax.do";
+	
+	$.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){
+						
+						//수신목록 Html 태그
+						// 엑셀 헤더
+						var excelTitleHeadText ='<div class="list_table_name">'
+										+'\t<p>$HEADTITLE$</p>'
+										+'</div>';
+
+						// 바디 row 수신자 tag
+						var excelBodyRowTextIndex00 ='<div class="list_table_name phoneArea">'
+												+'\t\t<p>$ROWTEXT$</p>'
+												+'\t</div>';
+												
+						// 바디 row tag
+						var excelBodyRowTextIndex01 ='<div class="list_table_name transData">'
+												+'\t\t<p>$ROWTEXT$</p>'
+												+'\t</div>';
+						
+						//맨 앞에 수신번호 배열 추가
+						varList.unshift('수신번호'); 
+						//변수 문자열 중복 제거
+						var newList = Array.from(new Set(varList));
+						
+						//엑셀헤더 selector
+						var $excelHead = $('#excelHead');
+						//엑셀바디 selector
+						var $excelBody = $('#excelBody02');
+
+						// 엑셀 헤더 부분
+						$.each(newList, function(headerIndex, value) {
+							$excelHead.append(excelTitleHeadText.replace('$HEADTITLE$', value));
+						});
+						
+						var totalDuplCnt = $('#rowDupCnt').text();//중복 건수 정보
+						var $excelBody = $('#excelBody02');
+						var bodyData;
+						var addDiv = "";
+						var phoneNum;
+
+						//입력데이터를 역정렬해준다.
+						data.reverse();
+
+						//변수명 추출해주기
+						var varListArr = [];
+						varListArr = form.excelVarList.value.split(",");
+						
+						$.each(data, function(i, item){
+							
+							if(checkHpNum(item.phone)){
+							
+								phoneNum = removeDash(item.phone);
+								
+								if(!phoneDupl(phoneNum)){
+									var varVal = item.varVal;
+									var lengthCheck =true;
+									/*23.04.06  이름제거 요청으로인한 화면 이름 제거*/
+									var excelBody = '<div class="list_table list_body excelBody">';
+									
+									//수신번호 화면 태그 생성
+									excelBody += excelBodyRowTextIndex00.replace('$ROWTEXT$', removeDash(phoneNum));
+									
+									//변수 데이터 태그 생성
+									var varValArr = []
+									varValArr = varVal.split("§");
+									for(var i=0; i < varValArr.length; i++){
+										
+										var bodyData = varValArr[i];
+										
+										// 기타변수는 50자리 까지 입력
+										if(bodyData.length > 100 || bodyData.length == 0){
+											alert("등록 변수[ "+varListArr[i]+" ] \n기타변수의 입력 값이 없거나 100자리를 초과하는 내용이 포함되어 해당 내용 제외되었습니다.");
+											lengthCheck = false;
+											break;
+										}
+										excelBody += excelBodyRowTextIndex01.replace('$ROWTEXT$', bodyData);
+										
+									}
+									
+									excelBody += '</div>';
+									
+									if(lengthCheck){
+										addDiv += excelBody;
+									}
+									
+								}
+									
+								else
+									totalDuplCnt++;
+								
+							} else{
+								
+								alert("엑셀 파일 데이터의 형식이 맞지 않는 부분이 있습니다.");
+				        		excelAddr = []; //엑셀 데이터 저장 변수 초기화
+				        		$("#excelFile").val(""); //첨부파일 input 초기화
+				        	    $("#excelNm").val("");  // 첨부파일 명 초기화
+				        	    fileName = "";
+				        		return;
+								
+							} 
+						 
+						});
+						
+						//화면에 수신번호 및 변수 데이터 추가해 주기
+						$excelBody.append(addDiv);
+
+					}
+					
+				}else{
+					alert(returnData.message);
+//						alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
+					excelAddr = []; //엑셀 데이터 저장 변수 초기화
+	        		$("#excelFile01").val(""); //첨부파일 input 초기화
+	        	    $("#excelNm01").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');
+		}
+    });
+	
+}
+
+
 /**
  * 엑셀 파일 불러오기
  */
@@ -481,7 +683,6 @@
 	var resultBoo = true;
 
 	data = removeDash(data);
-
 	/*
 	* 중복체크
 	* 기존 데이터 배열화
Add a comment
List