이호영 이호영 2025-03-25
알림톡발송 종료
@1c382cb088292202297788d51e31d70afad00a82
 
src/main/java/itn/com/cmm/util/SlackMessageFormatUtil.java (added)
+++ src/main/java/itn/com/cmm/util/SlackMessageFormatUtil.java
@@ -0,0 +1,144 @@
+package itn.com.cmm.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+import itn.let.kakao.kakaoComm.KakaoVO;
+import itn.let.mjo.msg.service.MjonMsgVO;
+
+public class SlackMessageFormatUtil {
+	
+	private static final String PREFIX_SMISHING = "[스미싱의심]";
+	private static final String PREFIX_RESERVE = "[예약]";
+	private static final String PREFIX_IMAGE = "그림문자 ";
+
+	/**
+	 * 일반 SMS 메시지 텍스트 포맷팅
+	 */
+	public static String formatSmsText(MjonMsgVO mjonMsgVO) {
+		String smsTxt = mjonMsgVO.getSmsTxt();
+		String reserveYn = safeGetString(mjonMsgVO.getReserveYn());
+		String delayYn = safeGetString(mjonMsgVO.getDelayYn());
+		String smishingYn = safeGetString(mjonMsgVO.getSmishingYn());
+		
+		// 공통 텍스트 포맷팅 로직 적용
+		smsTxt = formatMessagePrefix(smsTxt, reserveYn, 
+					"Y".equals(smishingYn) || "Y".equals(delayYn));
+		
+		// 그림 문자 처리 (SMS 전용 로직)
+		int fileCount = parseIntOrDefault(mjonMsgVO.getFileCnt(), 0);
+		if ("6".equals(mjonMsgVO.getMsgType()) && fileCount > 0 && StringUtils.isEmpty(smsTxt)) {
+		    smsTxt = "그림문자 " + smsTxt;
+		}
+		
+		return smsTxt;
+	}
+	
+	/**
+	 * 카카오톡 메시지 텍스트 포맷팅
+	 */
+	public static String formatKakaoText(KakaoVO kakaoVO) {
+		String smsTxt = kakaoVO.getTemplateContent();
+		String reserveYn = safeGetString(kakaoVO.getReserveYn());
+		String atDelayYn = safeGetString(kakaoVO.getAtDelayYn());
+		
+		// 공통 텍스트 포맷팅 로직 적용
+		return formatMessagePrefix(smsTxt, reserveYn, "Y".equals(atDelayYn));
+	}
+	
+	
+	public static String formatSandName(MjonMsgVO mjonMsgVO) {
+		String userId = mjonMsgVO.getUserId();
+		String callFrom = mjonMsgVO.getCallFrom();
+		String msgType = getMessageTypeLabel(mjonMsgVO.getMsgType(), mjonMsgVO.getFileCnt());
+		return String.format("[%s][%s]%s", userId, callFrom, msgType);
+	}
+	
+	/**
+	 * 메시지 접두사 포맷팅 공통 로직 (예약 및 스미싱 의심 접두사 처리)
+	 * 
+	 * @param messageText 원본 메시지 텍스트
+	 * @param reserveYn   예약 여부
+	 * @param isSmishing  스미싱 의심 여부
+	 * @return 포맷팅된 메시지 텍스트
+	 */
+	public static String formatMessagePrefix(String messageText, String reserveYn, boolean isSmishing) {
+		if ("Y".equals(reserveYn)) {
+			return isSmishing ? PREFIX_SMISHING + PREFIX_RESERVE + messageText : PREFIX_RESERVE + messageText;
+		} else if (isSmishing) {
+			return PREFIX_SMISHING + messageText;
+		}
+		return messageText;
+	}
+
+	/**
+	 * @카카오톡용 sandName 포맷팅 메서드
+	 */
+	public static String formatKakaoSandName(KakaoVO kakaoVO) {
+		String userId = kakaoVO.getUserId();
+		String callFrom = kakaoVO.getCallFrom();
+		String msgType = getKakaoMessageTypeLabel(kakaoVO.getMsgType());
+		return String.format("[%s][%s]%s", userId, callFrom, msgType);
+	}
+	
+	/**
+	 * 메시지 타입 레이블 반환 (SMS 전용)
+	 * 
+	 * @param msgType 메시지 타입
+	 * @param fileCnt 파일 개수
+	 * @return 메시지 타입 레이블
+	 */
+	public static String getMessageTypeLabel(String msgType, String fileCnt) {
+		int fileCount = parseIntOrDefault(fileCnt, 0);
+
+		switch (msgType) {
+			case "4":
+				return "[단문]";
+			case "6":
+				return fileCount == 0 ? "[장문]" : "[그림]";
+			default:
+				return "";
+		}
+	}
+
+	/**
+	 * 카카오톡 메시지 타입 레이블 반환
+	 * 
+	 * @param msgType 메시지 타입
+	 * @return 메시지 타입 레이블
+	 */
+	public static String getKakaoMessageTypeLabel(String msgType) {
+		switch (msgType) {
+			case "8":
+				return "[알림톡]";
+			case "9":
+				return "[친구톡]";
+			default:
+				return "";
+		}
+	}
+
+	/**
+	 * 정수로 변환, 변환 실패 시 기본값 반환
+	 * 
+	 * @param value        변환할 문자열
+	 * @param defaultValue 기본값
+	 * @return 변환된 정수 또는 기본값
+	 */
+	public static int parseIntOrDefault(String value, int defaultValue) {
+		try {
+			return Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			return defaultValue;
+		}
+	}
+
+	/**
+	 * 안전하게 문자열 가져오기 (null 체크)
+	 * 
+	 * @param value 원본 문자열
+	 * @return 원본 문자열 또는 빈 문자열
+	 */
+	public static String safeGetString(String value) {
+		return value == null ? "" : value;
+	}
+}
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
@@ -73,7 +73,7 @@
 	 * @throws Exception
 	 * 
 	 */
-	public List<KakaoSendAdvcVO> populateSendLists(KakaoVO kakaoVO, boolean isHolidayNotified, StatusResponse statusResponse) throws Exception {
+	public List<KakaoSendAdvcVO> populateSendLists(KakaoVO kakaoVO, boolean isNotified, StatusResponse statusResponse) throws Exception {
 		
 		//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
 //		String befCash = kakaoVO.getBefCash();
@@ -84,7 +84,7 @@
 		log.info(" +kakaoVO.getVarListMap().size() :: [{}]", kakaoVO.getVarListMap().size()); 
 		
 		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = new ArrayList<>();
-		Calendar calendar = setupBaseDate(kakaoVO, isHolidayNotified);
+		Calendar calendar = setupBaseDate(kakaoVO, isNotified);
 
 		
 		
@@ -120,9 +120,7 @@
 		
 
 		/** @MSGID KEY값 */
-		log.info("idList ===================================================== ");
 		List<String> idList = mjonCommon.getNextCustomMsgCId(kakaoVO.getVarListMap().size());
-		log.info("+ idList:: [{}]", idList.toArray().toString());
 //		for (int i = 0; i < kakaoSendAdvcListVO.size(); i++) {
 //			kakaoSendAdvcListVO.get(i).setMsgId(idList.get(i));
 //			kakaoSendAdvcListVO.get(i).setBizJsonName(idList.get(i));
@@ -270,7 +268,7 @@
 		return kakaoSendAdvcListVO;
 	}
 	
-	private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isHolidayNotified) throws ParseException {
+	private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isNotified) throws ParseException {
 		// 예약 시간 기본값 설정
 		Date now = new Date();
 		// ReqDate가 비어 있으면 현재 시간으로 설정, 그렇지 않으면 ReqDate로 설정
@@ -290,7 +288,7 @@
 		// 지연 여부 처리
 		// 알림톡 스미싱의심 + 공휴일알림 조건이 맞으면 30분 delay
 		if ( "Y".equalsIgnoreCase(kakaoVO.getAtSmishingYn())
-				&& isHolidayNotified) {
+				&& isNotified) {
 			calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
 		}
 		return calendar;
src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
--- src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
@@ -899,7 +899,7 @@
 /** @isHolidayNotified 
  * @false : 알림 X
  * @true  : 알림 O */
-		boolean isHolidayNotified = mjonCommon.handleSmishingAlert();
+		boolean isNotified = mjonCommon.processUserAndCheckAT(kakaoVO);
 		
 		
 /** @LETTNGNRLMBER 사용자 정보 -> 스미싱의심 여부 */
@@ -907,7 +907,7 @@
 		kakaoVO.setAtSmishingYn(userManageVO.getAtSmishingYn());
 		
 /** @카카오톡 전송 list 셋팅 -------------------------------------------*/
-		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendLists(kakaoVO, isHolidayNotified, statusResponse);
+		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendLists(kakaoVO, isNotified, statusResponse);
 		if (statusResponse.getStatus() != null && !statusResponse.getStatus().equals(HttpStatus.OK)) {
 			log.error(" + populateSendLists 처리 중 오류 발생: {}", statusResponse.getMessage());
 			return statusResponse;
@@ -923,13 +923,14 @@
 
 		
 		
-		start = Instant.now();
 		Map<String, List<KakaoSendAdvcVO>> priceGroupedMessages = kakaoSendAdvcListVO.stream()
 				.collect(Collectors.groupingBy(KakaoSendAdvcVO::getEachPrice));
 		
 
 		// instTotalCnt : 화면에서 보여줄 총 발송건수
 		int instTotalCnt = 0;
+		// 임시
+		List<String> nextMsgGroupIdA = new ArrayList<>();
 			// 대안: entrySet() 직접 사용
 		for (Map.Entry<String, List<KakaoSendAdvcVO>> entry : priceGroupedMessages.entrySet()) {
 			    // entry 사용
@@ -965,22 +966,39 @@
 				
 				priceAndPoint.insertCashAndPoint(kakaoVO.getUserId()
 						, -Float.parseFloat(sendVO.getTotPrice())
-//						, "SMS 문자 " + groupedMsgList.size() + "건 발송"
 						, "카카오 알림톡 총 "+groupedMsgList.size()+"건 중 " + instCnt + "건 발송"
 						, nextMsgGroupId
 					);
+
+
+/** @SLACK발송 */ 
+				/** @발송조건이되면 발송 */ 
+				if(isNotified) {
+					mjonCommon.getAdminKakaoAtSendSlack(kakaoVO);
+				}else if("Y".equals(kakaoVO.getAtSmishingYn())){
+				/** @발송조건이 안되면 DB INSERT */ 
+					mjonMsgDAO.insertSpamPassMsgData(MjonMsgVO.builder()
+							.msgGroupId(nextMsgGroupId)
+							.userId(kakaoVO.getUserId())
+							.reqDate(kakaoVO.getReqDate())
+							.smsTxt(groupedMsgList.get(0).getTemplateContent())
+							.totalCallCnt(instCnt)
+							.callFrom(kakaoVO.getCallFrom())
+							.msgType("8")
+							.reserveYn(kakaoVO.getReserveYn())
+							.build()
+						);
+				}
 				
+				nextMsgGroupIdA.add(nextMsgGroupId);
 				
 			}
 			
-			
 		}
-		
-		
-		if(isHolidayNotified
-				&& "Y".equals(kakaoVO.getAtSmishingYn())) {
-			
-		}
+
+		returnMap.put("resultSts", instTotalCnt);
+		returnMap.put("reserYn", kakaoVO.getReserveYn());
+		returnMap.put("groupIds", nextMsgGroupIdA);
 		
 		
 		// 측정할 메소드 호출 후 시간 기록
@@ -988,15 +1006,15 @@
 
 		log.info(" + start :: [{}]", start);
 		// 실행 시간 계산 (나노초, 밀리초, 초)
-		System.out.println("메소드 실행 시간 (초): " + Duration.between(start, end).getSeconds() + " s");
-		System.out.println("메소드 실행 시간 (Nano): " + Duration.between(start, end).getNano() + " Nano");
-//		kakaoSendAdvcListVO.forEach(t-> log.info(" + t.toString() :: [{}]", t.toString()) );		
+		long seconds = Duration.between(start, end).getSeconds();
+		System.out.println("메소드 실행 시간 (초): " + seconds + " s");
+		double minutes = seconds / 60.0; // 소수점 포함을 위해 60.0으로 나눔
+
+		returnMap.put("second", seconds+" s");
+		returnMap.put("minutes", minutes+" min");
 		
-//		idgenMjonMsgGroupId.getNextStringId();
-		
-		
-		
-		
+
+//		System.out.println("메소드 실행 시간 (분): " + minutes + " min");
 		
 		
 		
@@ -1005,7 +1023,9 @@
 		
 		
 		
-		
+
+		statusResponse.setStatus(HttpStatus.OK);
+		statusResponse.setObject(returnMap);
 		
 		return statusResponse;
 	}
@@ -1032,6 +1052,7 @@
 		sendVO.setAtDelayYn(kakaoVO.getAtSmishingYn()); 
 		sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt());
 		sendVO.setBizKakaoResendType(sendVO.getSubMsgType());
+		
 		kakaoAlimTalkDAO.insertKakaoGroupDataTb_advc(sendVO);
 		
 	}
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
@@ -1408,7 +1408,7 @@
 						
 						if(!smishingAlarmPassSts) {//평일,주말, 공휴일 알림설정 시간에 포함되지 않는 경우 슬랙 알림 발송
 							
-							mjonCommon.getAdminKakaoAtSandSlack(kakaoVO);
+							mjonCommon.getAdminKakaoAtSendSlack(kakaoVO);
 							
 						}
 						
src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
--- src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
+++ src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
@@ -26,6 +26,7 @@
 import itn.com.cmm.MjonMsgSendVO;
 import itn.com.cmm.OptimalMsgResultDTO;
 import itn.com.cmm.util.MsgSendUtils;
+import itn.com.cmm.util.SlackMessageFormatUtil;
 import itn.let.kakao.kakaoComm.KakaoVO;
 import itn.let.mail.service.StatusResponse;
 import itn.let.mjo.event.service.MjonEventService;
@@ -72,7 +73,7 @@
 	
 
 	/** 
-	 * @methodName	: getAdminMsgSandSlack 
+	 * @methodName	: getAdminSandSlack 
 	 * @author		: 이호영
 	 * @date		: 2024.12.04 
 	 * @description	: 기존 메소드 리펙토링
@@ -128,8 +129,8 @@
 	
 		try {
 			// 메시지 내용 설정
-			String smsTxt = formatSmsText(mjonMsgVO);
-			String sandName = formatSandName(mjonMsgVO);
+			String smsTxt = SlackMessageFormatUtil.formatSmsText(mjonMsgVO);
+			String sandName = SlackMessageFormatUtil.formatSandName(mjonMsgVO);
 		
 			// Slack 메시지 생성
 			JSONObject json = new JSONObject();
@@ -158,21 +159,21 @@
 		}
 	}
 	
-	public void getAdminKakaoAtSandSlack(KakaoVO kakaoVO) {
+	public void getAdminKakaoAtSendSlack(KakaoVO kakaoVO) {
 		HttpClient client = new HttpClient();
 		PostMethod post = new PostMethod(SLACK_URL);
-	
+
 		try {
 			// 메시지 내용 설정
-			String smsTxt = formatKakaoText(kakaoVO);
-			String sandName = formatKakaoSandName(kakaoVO);
-		
+			String smsTxt = SlackMessageFormatUtil.formatKakaoText(kakaoVO);
+			String sandName = SlackMessageFormatUtil.formatKakaoSandName(kakaoVO);
+			
 			// Slack 메시지 생성
 			JSONObject json = new JSONObject();
 			json.put("channel", SLACK_CHANNEL);
 			json.put("text", smsTxt);
 			json.put("username", sandName);
-		
+			
 			// Slack 요청
 			post.addParameter("payload", json.toString());
 			post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
@@ -180,9 +181,8 @@
 			// Slack 응답 처리
 			int responseCode = client.executeMethod(post);
 			if (responseCode != HttpStatus.SC_OK) {
-			    log.warn("Slack 메시지 전송 실패. Response: {}", post.getResponseBodyAsString());
+				log.warn("Slack 메시지 전송 실패. Response: {}", post.getResponseBodyAsString());
 			}
-	
 		} catch (IllegalArgumentException e) {
 			log.error("Slack 메시지 전송 중 IllegalArgumentException 발생", e);
 		} catch (IOException e) {
@@ -200,32 +200,6 @@
 	}
 
 	
-	
-	/**
-	 * 카카오톡 메시지 텍스트 포맷팅
-	 */
-	public String formatKakaoText(KakaoVO kakaoVO) {
-		String smsTxt = kakaoVO.getTemplateContent();
-		String reserveYn = safeGetString(kakaoVO.getReserveYn());
-		String atDelayYn = safeGetString(kakaoVO.getAtDelayYn());
-		
-		// 공통 텍스트 포맷팅 로직 적용
-		return formatMessagePrefix(smsTxt, reserveYn, "Y".equals(atDelayYn));
-	}
-
-
-	/**
-	 * 메시지 접두사 포맷팅 공통 로직
-	 * (예약 및 스미싱 의심 접두사 처리)
-	 */
-	private static String formatMessagePrefix(String messageText, String reserveYn, boolean isSmishing) {
-		if ("Y".equals(reserveYn)) {
-			return isSmishing ? "[스미싱의심][예약]" + messageText : "[예약]" + messageText;
-		} else if (isSmishing) {
-			return "[스미싱의심]" + messageText;
-		}
-		return messageText;
-	}
 
 
 	/**
@@ -374,7 +348,7 @@
 		
 		return mjonMsgVO;
 	}
-	
+	/*
 	@SuppressWarnings("unchecked")
 	public void getAdminKakaoAtSandSlack(KakaoVO kakaoVO) {
 		
@@ -438,7 +412,7 @@
 		}
 		
 	}
-	
+	*/
 	
 	public String getCreateMsgUserIdgen(String subUserId, String lastId) throws Exception{
 		
@@ -475,27 +449,6 @@
 
 
 
-private String formatSmsText(MjonMsgVO mjonMsgVO) {
-    String smsTxt = mjonMsgVO.getSmsTxt();
-    String reserveYn = safeGetString(mjonMsgVO.getReserveYn());
-    String delayYn = safeGetString(mjonMsgVO.getDelayYn());
-    String smishingYn = safeGetString(mjonMsgVO.getSmishingYn());
-
-    // 예약 문자와 스미싱 의심 처리
-    if ("Y".equals(reserveYn)) {
-        smsTxt = ("Y".equals(smishingYn) || "Y".equals(delayYn)) ? "[스미싱의심][예약]" + smsTxt : "[예약]" + smsTxt;
-    } else if ("Y".equals(smishingYn) || "Y".equals(delayYn)) {
-        smsTxt = "[스미싱의심]" + smsTxt;
-    }
-
-    // 그림 문자 처리
-    int fileCount = parseIntOrDefault(mjonMsgVO.getFileCnt(), 0);
-    if ("6".equals(mjonMsgVO.getMsgType()) && fileCount > 0 && StringUtils.isNullOrEmpty(smsTxt)) {
-        smsTxt = "그림문자 " + smsTxt;
-    }
-
-    return smsTxt;
-}
 
 private String formatSandName(MjonMsgVO mjonMsgVO) {
     String userId = mjonMsgVO.getUserId();
@@ -532,7 +485,18 @@
 	
 	
 
-	// 전체 로직 처리 (한 번에 모든 필요한 정보 반환)
+	/**
+	 * @methodName	: processUserAndCheckSms 
+	 * @author		: 이호영
+	 * @date		: 2025. 3. 25.
+	 * @description	: SMS 알림 전체 로직 처리 (한 번에 모든 필요한 정보 반환)
+	 * @return : boolean
+	 * @param mjonMsgVO
+	 * @param userId
+	 * @return
+	 * @throws Exception
+	 * 
+	 */
 	public boolean processUserAndCheckSms(MjonMsgVO mjonMsgVO, String userId) throws Exception {
 		UserManageVO userManageVO = getUserManageInfo(userId);
 
@@ -551,6 +515,36 @@
 
 		return false; // 알림 처리되지 않음
 	}
+	
+	/**
+	 * @methodName	: processUserAndCheckAT 
+	 * @author		: 이호영
+	 * @date		: 2025. 3. 25.
+	 * @description	: SMS 알림 전체 로직 처리 (한 번에 모든 필요한 정보 반환)
+	 * @return : boolean
+	 * @param mjonMsgVO
+	 * @param userId
+	 * @return
+	 * @throws Exception
+	 * 
+	 */
+	public boolean processUserAndCheckAT(KakaoVO kakaoVO) throws Exception {
+		UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId());
+		
+		// 기본값 처리된 사용자 정보와 문자 상태
+		String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn();
+		String atSmishingYn = userManageVO.getAtSmishingYn();
+		
+		// 조건 체크
+		if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) {
+			kakaoVO.setAtSmishingYn(atSmishingYn); // MjonMsgVO에 스미싱 정보 설정
+			
+			// 스미싱 알림 처리
+			return handleSmishingAlert(); // 알림 처리 결과 반환
+		}
+		
+		return false; // 알림 처리되지 않음
+	}
 
 	// 사용자 정보 조회 및 기본값 처리
 	public UserManageVO getUserManageInfo(String userId) throws Exception {
src/main/java/itn/let/mjo/msg/service/MjonMsgVO.java
--- src/main/java/itn/let/mjo/msg/service/MjonMsgVO.java
+++ src/main/java/itn/let/mjo/msg/service/MjonMsgVO.java
@@ -7,12 +7,18 @@
 
 import itn.com.cmm.ComDefaultVO;
 import itn.com.cmm.MjonMsgSendVO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
 @Getter
 @Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class MjonMsgVO extends ComDefaultVO{
 	
 	private static final long serialVersionUID = 1L;
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
@@ -686,16 +686,38 @@
 	
 	if(confirm("알림톡을 발송하시겠습니까?")){
 
-        
-        
-    $.ajax({
-        type: "POST",
-        url: "/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do",
-        data: JSON.stringify(formData),
-        contentType: 'application/json',
-        dataType: 'json',
-        success: function (data) {
+	// 프로그래스파 시간을 위한 계산
+	var estimtedTime = calculateEstimatedTime(dataList.length);
+
+	$.ajax({
+		type: "POST",
+		url: "/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do",
+		data: JSON.stringify(formData),
+		contentType: 'application/json',
+		dataType: 'json',
+		success: function (data) {
 				console.log('data : ', data);
+				
+				
+
+				var status = data.status;
+				if("OK" == status){
+					var resultSts = data.object.resultSts;
+					var reserYn = data.object.reserYn;
+					var resText = (reserYn === 'Y') ? '예약' : '발송';
+						
+					$('.pop_msg_success').css({'display':'block','opacity':'1','left':'50%','top':'50%','transform':'translate(-50%,-50%)'});
+					$('.pop_msg_success .msg_text').html(resText+" 성공 : <strong>"+ resultSts + "</strong>건의<br>알림톡이 " + resText + " 되었습니다.");
+					
+				}else if("UNAUTHORIZED" == status){
+					alert(data.message);
+				    location.reload();
+				}else{
+					alert(data.message);
+					return false;
+				}
+				
+				
 // 				if(data == 'success'){
 					/* if("loginFail" == returnData.result){
 						
@@ -731,11 +753,16 @@
 			}
 			,beforeSend : function(xmlHttpRequest) {
 				//로딩창 show
-				$('.loading_layer').addClass('active');
+// 				$('.loading_layer').addClass('active');
+				// 프로그래스 바 실행
+				progressStart(estimtedTime);
 			}
 			,complete : function(xhr, textStatus) {
 				//로딩창 hide
-				$('.loading_layer').removeClass('active');
+// 				$('.loading_layer').removeClass('active');
+
+				// 프로그래스 바 종료
+				progressComplete();;
 			}
 			,error: function (e) {
 				console.log("ERROR : ", e);
@@ -743,6 +770,82 @@
 			}
 		}); 
 	}
+}
+//선택된 데이터의 길이에 따라 예상 시간 계산 함수
+function calculateEstimatedTime(selectedCount) {
+    //기준값
+    // const processTimePerBatch = 130; // 130초
+    
+    
+    // 30만건 기준 10분으로 기준을 잡아서 
+    // 시간계산함
+    const processTimePerBatch = 600;
+    const batchSize = 300000;
+    
+    // 1건당 처리 시간
+    const timePerRecord = processTimePerBatch / batchSize;
+
+    // 예상 시간 계산
+    const estimatedTimeInSeconds = selectedCount * timePerRecord;
+
+    return estimatedTimeInSeconds.toFixed(2);
+}
+
+
+//프로그레스바 
+var start, change;
+var progressInterval = null; // 전역 변수로 타이머 ID 관리
+function progressStart(time) {
+    // 기존 타이머 정지 및 초기화
+    if (progressInterval !== null) {
+        clearInterval(progressInterval); // 이전 타이머 정지
+        progressInterval = null; // 타이머 ID 초기화
+    }
+    resetProgressBar(); // 프로그레스바 초기화
+
+    // 프로그레스바 보이기
+    $(".progress_bar_wrap").css("display", "flex");
+
+    // 프로그레스바 요소 가져오기
+    var timeText = document.querySelector(".time_text");
+    var bar = document.querySelector(".change_bar");
+
+    // 초기 상태 설정
+    var width = 1;
+    var totalTime = time * 1000; // 총 실행 시간 (밀리초)
+    var cmpWid = totalTime / 100; // width 증가 간격 (밀리초)
+
+    // 새 타이머 시작
+    progressInterval = setInterval(changeWidth, cmpWid);
+
+    function changeWidth() {
+        if (width >= 100) {
+            // 프로그레스바 100% 도달
+            clearInterval(progressInterval); // 타이머 종료
+            progressInterval = null; // 타이머 ID 초기화
+
+            timeText.innerHTML = "100%";
+
+            setTimeout(function () {
+                // 100% 표시 후 "잠시만 기다려주세요" 변경
+                timeText.innerHTML = "잠시만 기다려주세요...";
+                $(".time_text").addClass("animation");
+            }, 1000);
+        } else {
+            // 프로그레스바 진행
+            width++;
+            bar.style.width = width + "%";
+            timeText.innerHTML = width + "%";
+        }
+    }
+}
+
+
+//프로그레스바 완료
+function progressComplete() {
+ // var width = parseInt($(".time_text").text().replace('%', '')) || 0; // 현재 width 가져오기
+
+ $(".progress_bar_wrap").hide();
 }
 
 /*
@@ -1132,6 +1235,17 @@
 		</div>
 	</div>
 	
+    <div class="progress_bar_wrap">
+        <div class="progress_box">
+            <p class="time_text">0%</p>
+            <div class="bar">
+                <span class="change_bar"></span>
+            </div>
+        </div>
+        <div class="btn_wrap">
+        </div>
+
+    </div>
 	<!-- 기업회원 이동 팝업 -->
 	<div class="tooltip-wrap cvt_member_popup_wrap">
 	    <div class="popup-com cvt_member_layer" tabindex="0" data-tooltip-con="cvt_member_layer" data-focus="cvt_member_layer" data-focus-prev="cvt_member_layer-close">
@@ -1766,6 +1880,7 @@
 
 
 
+
 <!-- 엑셀 불러오기 -->
 <form id="excelToolTipForm" name="excelToolTipForm" method="post">
 	<div class="tooltip-wrap">
src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgdata/MsgDataView.jsp
@@ -71,8 +71,6 @@
             </div>
         </div>
         <div class="btn_wrap">
-            <!-- <button type="button" class="btnType btnType2" style="margin:50px 0;" onclick="progressStart(10,'완료되었습니다.');">시작</button>
-            <button type="button" class="btnType btnType2" style="margin:50px 0;" onclick="progressComplete('완료되었습니다.');return false;">멈춤</button> -->
         </div>
 
     </div>
src/main/webapp/js/web/msgdata/msgDataView.js
--- src/main/webapp/js/web/msgdata/msgDataView.js
+++ src/main/webapp/js/web/msgdata/msgDataView.js
@@ -1265,8 +1265,6 @@
 	
 	var url = "/web/mjon/msgdata/sendMsgDataAjax_advc.do";
 	 // 시작 시간
-	const startTime = new Date();
-	 
 	
 	 // 프로그래스파 시간을 위한 계산
 	var estimtedTime = calculateEstimatedTime($selectedData.length);
Add a comment
List