이호영 이호영 2024-12-04
slack 개발 운영 분기
@77c8a48ff2e453475c67f07f7c8df679e73f5019
src/main/java/itn/com/cmm/util/MsgSendUtils.java
--- src/main/java/itn/com/cmm/util/MsgSendUtils.java
+++ src/main/java/itn/com/cmm/util/MsgSendUtils.java
@@ -338,6 +338,19 @@
 			setImagePathsForMsgSendVO(mjonMsgVO, sendVO);
 			
 			
+			
+			
+			
+			
+			
+			
+			
+			
+			// 지연 여부 처리
+			if ("Y".equalsIgnoreCase(mjonMsgVO.getDelayYn())) {
+				calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
+			}
+			
 			// 예약 여부 확인
 			if ("Y".equalsIgnoreCase(mjonMsgVO.getReserveYn())) {
 				// 분할 발송일 경우
@@ -356,6 +369,20 @@
 			}
 			
 			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
 			// 전송사 코드 셋팅
 			String agentCode = "00".equals(mjonMsgVO.getAgentCode())
 					? MsgSendUtils.assignAgentBasedOnCount(agentSendCounts, sendRateList)
@@ -367,10 +394,13 @@
 		}
 		// Group TB에 넣어줄 제목
 		// 치환안된 sms 데이터로 넣어야함
-		mjonMsgVO.setMmsSubject(getMmsgSubject(smsTxtTemp, msgKind)); 
+		log.info(" mjonMsgSendListVO size :: [{}]", mjonMsgSendListVO.size());
+		if (LONG_MSG_TYPE.equals(mjonMsgSendListVO.get(0).getMsgType())){
+			mjonMsgVO.setMmsSubject(getMmsgSubject(smsTxtTemp, msgKind)); 
+		}
 		
 		return true;
-
+ 
 	}
 	
 	/** 
@@ -402,17 +432,29 @@
 	private static void checkSpamAndSetStatus(MjonMsgVO mjonMsgVO, String personalizedSmsTxt, List<String> resultSpamTxt) throws Exception {
 		String resultParser = ComGetSpamStringParser.getSpamTextParse(personalizedSmsTxt).trim();
 		int spmCnt = 0;
+		String spmFilterTxt = "";
 
 		for (String spmTxt : resultSpamTxt) {
 			String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
 			if (resultParser.contains(parserStr)) {
 				spmCnt++;
+				spmFilterTxt += spmTxt + ",";
 			}
 		}
 
 		if (spmCnt > 0) { // 스팸 문자가 포함된 경우
-			System.out.println("++++++++++++++ spam smsTxt ::: " + resultParser);
+
+			if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
+				// 처음부터 idx 만큼 잘라낸 나머지 글자 
+				spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1); 	
+				
+			}
+			log.info(" + spmFilterTxt :: [{}]", spmFilterTxt);
+			log.info(" + resultParser :: [{}]", resultParser);
+			
+//			mjonMsgVO.setSpamKeyword(spmFilterTxt);
 			mjonMsgVO.setSpamStatus("Y");
+			mjonMsgVO.setDelayYn("Y");
 		}else {mjonMsgVO.setSpamStatus("N");}
 	}
 
@@ -487,7 +529,7 @@
 	
 	
 
-	private static void statusResponseSet (StatusResponse statusResponse, HttpStatus httpStatus, String msg ) {
+	public static void statusResponseSet (StatusResponse statusResponse, HttpStatus httpStatus, String msg ) {
 		statusResponse.setStatus(httpStatus);
 		statusResponse.setMessage(msg);
 		
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
@@ -2,24 +2,112 @@
 
 import java.io.IOException;
 import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.json.simple.JSONObject;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import com.mysql.jdbc.StringUtils;
 
+import itn.com.cmm.MjonMsgSendVO;
+import itn.com.cmm.OptimalMsgResultDTO;
+import itn.com.cmm.util.MsgSendUtils;
 import itn.let.kakao.kakaoComm.KakaoVO;
+import itn.let.mail.service.StatusResponse;
+import itn.let.mjo.event.service.MjonEventService;
+import itn.let.mjo.event.service.MjonEventVO;
 import itn.let.mjo.msg.service.MjonMsgVO;
+import itn.let.mjo.msgholiday.service.MsgAlarmSetVO;
+import itn.let.mjo.msgholiday.service.MsgHolidayService;
+import itn.let.mjo.msgholiday.service.MsgHolidayVO;
+import itn.let.sym.site.service.EgovSiteManagerService;
+import itn.let.sym.site.service.JoinSettingVO;
+import itn.let.uss.umt.service.EgovUserManageService;
+import itn.let.uss.umt.service.UserManageVO;
+import lombok.extern.slf4j.Slf4j;
 
+@Slf4j
 @Service("MjonCommon")
 public class MjonCommon {
 	
-	//Slack Web Hook URL
-	private String url = "https://hooks.slack.com/services/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";
+
+	/** userManageService */
+	@Resource(name = "userManageService")
+	private EgovUserManageService userManageService;
+
+	/** 사이트 설정 */ 
+	@Resource(name = "egovSiteManagerService")
+	EgovSiteManagerService egovSiteManagerService;	
+
+	@Resource(name = "MjonEventService")
+	private MjonEventService mjonEventService;
+	
+	@Resource(name = "MsgHolidayService")
+	private MsgHolidayService msgHolidayService;
+
+	@Value("#{globalSettings['Globals.slack.hooks.url']}")
+	private String SLACK_URL;
+	
+	/** xpedite 솔루션 ID*/
+	@Value("#{globalSettings['Globals.slack.channel.name']}")
+	private String SLACK_CHANNEL;
+	
+	
+
+	
+
+	/** 
+	 * @methodName	: getAdminSandSlack 
+	 * @author		: 이호영
+	 * @date		: 2024.12.04 
+	 * @description	: 기존 메소드 리펙토링
+	 * @param mjonMsgVO 
+	 */
+	public void getAdminSandSlack(MjonMsgVO mjonMsgVO) {
+	
+		HttpClient client = new HttpClient();
+		PostMethod post = new PostMethod(SLACK_URL);
+	
+		try {
+			// 메시지 내용 설정
+			String smsTxt = formatSmsText(mjonMsgVO);
+			String sandName = formatSandName(mjonMsgVO);
+		
+			// 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");
+		
+			// Slack 응답 처리
+			int responseCode = client.executeMethod(post);
+			if (responseCode != HttpStatus.SC_OK) {
+				log.warn("Slack 메시지 전송 실패. Response: {}", post.getResponseBodyAsString());
+			}
+	
+		} catch (IllegalArgumentException e) {
+			log.error("Slack 메시지 전송 중 IllegalArgumentException 발생", e);
+		} catch (IOException e) {
+			log.error("Slack 메시지 전송 중 IOException 발생", e);
+		} catch (Exception e) {
+			log.error("Slack 메시지 전송 중 Exception 발생", e);
+		} finally {
+			post.releaseConnection();
+		}
+	}
 	
 	/**
 	* @throws Exception 
@@ -28,8 +116,7 @@
 	* @작성자 :  WYH
 	* @Method 설명 : slack 메시지 전송
 	*/
-	@SuppressWarnings("unchecked")
-	public void getAdminSandSlack(MjonMsgVO mjonMsgVO) {
+	/*public void getAdminSandSlack(MjonMsgVO mjonMsgVO) {
 		
 		HttpClient client = new HttpClient();
 		PostMethod post = new PostMethod(url);
@@ -43,6 +130,7 @@
 			String reservSmsTxt = "";
 			String smisingSmsTxt = "";
 			//예약문자를 발송하는 경우 문자 내용 앞에 "[예약]" 표시되도록 처리
+			
 			if(reserveYn.equals("Y")) {
 				
 				if(smishingYn.equals("Y") || delayYn.equals("Y")) {
@@ -52,6 +140,8 @@
 				}
 				
 				smsTxt = reservSmsTxt;
+				System.out.println("smishingYn : "+ smishingYn);
+				System.out.println("delayYn : "+ delayYn);
 			}else if(smishingYn.equals("Y") || delayYn.equals("Y")) {
 				
 				smisingSmsTxt = "[스미싱의심]" + smsTxt;
@@ -75,7 +165,8 @@
 					}
 				}
 			}
-			sandName = "[" + userId + "]" + "[" + sandName + "]" + msgType;
+//			sandName = "[" + userId + "]" + "[" + sandName + "]" + msgType;
+			sandName = "[개발테스트]"+"[" + userId + "]" + "[" + sandName + "]" + msgType;
 			
 			json.put("channel", "mjon메시지");
 			json.put("text", smsTxt);
@@ -92,15 +183,18 @@
 			}
 		} catch (IllegalArgumentException e) {
 			System.out.println("IllegalArgumentException posting to Slack " + e);
-		} catch (IOException e) {
+		} 
+		catch (IOException e) {
 			System.out.println("IOException posting to Slack " + e);
-		} catch (Exception e) {
+		} 
+		catch (Exception e) {
 			System.out.println("Exception posting to Slack " + e);
+			e.printStackTrace();
 		} finally {
 			post.releaseConnection();
 		}
 		
-	}
+	}*/
 	
 	
 	/**
@@ -113,11 +207,11 @@
 	public void sendSimpleSlackMsg(String msg) {
 		
 		HttpClient client = new HttpClient();
-		PostMethod post = new PostMethod(url);
+		PostMethod post = new PostMethod(SLACK_URL);
 		JSONObject json = new JSONObject();
 		try {
 			
-			json.put("channel", "mjon메시지");
+			json.put("channel", SLACK_CHANNEL);
 			//json.put("channel", "C04DNV4FYP6");	//개발 서버용
 			
 			json.put("text", msg);
@@ -254,7 +348,7 @@
 	public void getAdminKakaoAtSandSlack(KakaoVO kakaoVO) {
 		
 		HttpClient client = new HttpClient();
-		PostMethod post = new PostMethod(url);
+		PostMethod post = new PostMethod(SLACK_URL);
 		JSONObject json = new JSONObject();
 		try {
 			
@@ -289,7 +383,7 @@
 			}
 			sandName = "[" + userId + "]" + "[" + sandName + "]" + msgType;
 			
-			json.put("channel", "mjon메시지");
+			json.put("channel", SLACK_CHANNEL);
 			json.put("text", smsTxt);
 			json.put("username", sandName);
 			
@@ -347,5 +441,179 @@
 		
 		return returnId;
 	}
+
+
+
+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();
+    String callFrom = mjonMsgVO.getCallFrom();
+    String msgType = getMessageTypeLabel(mjonMsgVO);
+
+    return String.format("[%s][%s]%s", userId, callFrom, msgType);
+}
+
+private String getMessageTypeLabel(MjonMsgVO mjonMsgVO) {
+    String msgType = mjonMsgVO.getMsgType();
+    int fileCount = parseIntOrDefault(mjonMsgVO.getFileCnt(), 0);
+
+    switch (msgType) {
+        case "4":
+            return "[단문]";
+        case "6":
+            return fileCount == 0 ? "[장문]" : "[그림]";
+        default:
+            return "";
+    }
+}
+
+
+private int parseIntOrDefault(String value, int defaultValue) {
+    try {
+        return Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+        return defaultValue;
+    }
+}
+	
+	
+	
+	
+
+	// 전체 로직 처리 (한 번에 모든 필요한 정보 반환)
+	public boolean processUserAndCheckSms(MjonMsgVO mjonMsgVO, String userId) throws Exception {
+		UserManageVO userManageVO = getUserManageInfo(userId);
+
+		// 기본값 처리된 사용자 정보와 문자 상태
+		String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn();
+		String smishingYn = userManageVO.getSmishingYn();
+		String spamStatus = safeGetString(mjonMsgVO.getSpamStatus());
+
+		// 조건 체크
+		if ("Y".equals(adminSmsNoticeYn) || "Y".equals(spamStatus) || "Y".equals(smishingYn)) {
+			mjonMsgVO.setSmishingYn(smishingYn); // MjonMsgVO에 스미싱 정보 설정
+
+			// 스미싱 알림 처리
+			return handleSmishingAlert(mjonMsgVO); // 알림 처리 결과 반환
+		}
+
+		return false; // 알림 처리되지 않음
+	}
+
+	// 사용자 정보 조회 및 기본값 처리
+	private UserManageVO getUserManageInfo(String userId) throws Exception {
+//		UserManageVO userManageVO = new UserManageVO();
+//		userManageVO.setAdminSmsNoticeYn("Y"); // 기본값
+//		userManageVO.setSmishingYn("N"); // 기본값
+//		
+		return userManageService.selectAdminSmsNoticeYn(new UserManageVO(userId));
+	}
+
+	// 스미싱 알림 처리
+	private boolean handleSmishingAlert(MjonMsgVO mjonMsgVO) throws Exception {
+		JoinSettingVO joinSettingVO = egovSiteManagerService.selectAdminNotiDetail();
+		if (joinSettingVO == null || !"Y".equals(joinSettingVO.getHoliSmishingNoti()) || 
+			!"Y".equals(joinSettingVO.getSlackNoti())) {
+			return false; // 알림 조건 미충족
+		}
+
+		// 알림 조건 충족 시 추가 작업
+		List<MsgAlarmSetVO> alarmList = getAlarmSettings();
+		List<MsgHolidayVO> holidayList = getHolidayList();
+		boolean isNotificationAllowed = new MjonHolidayApi().getHolidaySmishingPassStatus(alarmList, holidayList);
+
+		// 알림 발송
+		if (!isNotificationAllowed) {
+			getAdminSandSlack(mjonMsgVO);
+			return true; // 알림 발송 성공
+		}
+
+		return false; // 알림 발송 조건 미충족
+	}
+
+	// 안전하게 문자열 가져오기
+	private String safeGetString(String value) {
+		return value == null ? "" : value;
+	}
+
+	// 알림 설정 조회
+	private List<MsgAlarmSetVO> getAlarmSettings() throws Exception {
+		MsgAlarmSetVO msgAlarmSetVO = new MsgAlarmSetVO();
+		msgAlarmSetVO.setUseYn("Y");
+		msgAlarmSetVO.setFirstIndex(0);
+		return msgHolidayService.selectAlarmSettingList(msgAlarmSetVO);
+	}
+
+	// 공휴일 정보 조회
+	private List<MsgHolidayVO> getHolidayList() throws Exception {
+		Calendar calendar = Calendar.getInstance();
+		int year = calendar.get(Calendar.YEAR);
+
+		MsgHolidayVO msgHolidayVO = new MsgHolidayVO();
+		msgHolidayVO.setFirstIndex(0);
+		msgHolidayVO.setRecordCountPerPage(100);
+		msgHolidayVO.setSearchHoliYear(Integer.toString(year));
+		return msgHolidayService.selectMsgHolidayList(msgHolidayVO);
+	}
+
+	// 이벤트 메시지 처리
+	public StatusResponse processEventMessages(String userId, MjonMsgVO mjonMsgVO, 
+											List<MjonMsgSendVO> mjonMsgSendVOList) throws Exception {
+		StatusResponse statusResponse = new StatusResponse();
+
+		try {
+			// 이벤트 정보 가져오기
+			MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo_advc(userId);
+			if (eventMberInfo == null || "E".equals(eventMberInfo.getEventStatus())) {
+				return statusResponse; // 이벤트 상태가 종료인 경우 처리하지 않음
+			}
+
+			// 최적화된 메시지 리스트 및 이벤트 정보 가져오기
+			OptimalMsgResultDTO result = MsgSendUtils.getOptimalMsgList(eventMberInfo, mjonMsgSendVOList);
+			List<MjonMsgSendVO> optimalMsgList = result.getOptimalMsgList();
+			MjonEventVO returnEventMberInfo = result.getEventInfo();
+
+			// 이벤트 발송 내역이 있으면
+			if (CollectionUtils.isNotEmpty(optimalMsgList)) {
+				mjonMsgVO.setEventYn("Y"); // 그룹에 이벤트 발송 여부 설정
+				mjonMsgSendVOList.addAll(optimalMsgList); // 기존 리스트와 병합
+			}
+
+			// 이벤트 상태 종료 시 업데이트
+			if (returnEventMberInfo != null && "E".equals(returnEventMberInfo.getEventStatus())) {
+				returnEventMberInfo.setMberId(userId);
+				mjonEventService.updateEventEndStatus(returnEventMberInfo);
+			}
+
+		} catch (IllegalArgumentException e) {
+			
+			// 메시지 타입 에러 처리
+			MsgSendUtils.statusResponseSet(statusResponse, org.springframework.http.HttpStatus.BAD_REQUEST, "이벤트 데이터 처리 중 오류가 발생하였습니다.\n관리자에게 문의해 주세요.");
+			
+		}
+
+		return statusResponse;
+	}
 	
 }
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
@@ -145,7 +145,7 @@
 	
 	private String spamKeyword; 	//스팸 키워드
 	private String spamMsgGroupId; 	//스팸문자 문자전송 아이디
-	private String spamStatus;		//스팸문자 유무 (Y/N)
+	private String spamStatus="N";		//스팸문자 유무 (Y/N)
 	private String vipYn;			//VIP 유무 (Y/N)
 	private String approvalPnttm;	// 승인일자
 	private String atchFiles; 		// 그림문자 파일정보
src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
--- src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
+++ src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
@@ -53,6 +53,7 @@
 import itn.let.mjo.msgdata.service.MjonMsgDataVO;
 import itn.let.mjo.msgdata.service.MjonMsgReturnVO;
 import itn.let.mjo.msgholiday.service.MsgAlarmSetVO;
+import itn.let.mjo.msgholiday.service.MsgHolidayService;
 import itn.let.mjo.msgholiday.service.MsgHolidayVO;
 import itn.let.mjo.msgholiday.service.impl.MsgHolidayDAO;
 import itn.let.mjo.pay.service.MjonPayService;
@@ -60,11 +61,13 @@
 import itn.let.mjo.pay.service.impl.MjonPayDAO;
 import itn.let.mjo.spammsg.service.MjonSpamMsgService;
 import itn.let.module.base.PriceAndPoint;
+import itn.let.sym.site.service.EgovSiteManagerService;
 import itn.let.sym.site.service.JoinSettingVO;
 import itn.let.sym.site.service.impl.SiteManagerDAO;
 import itn.let.uat.uia.web.SendLogVO;
 import itn.let.uss.umt.service.EgovUserManageService;
 import itn.let.uss.umt.service.MberManageVO;
+import itn.let.uss.umt.service.UserManageVO;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
@@ -130,9 +133,20 @@
 	@Resource(name = "mjonSpamMsgService")
     private MjonSpamMsgService mjonSpamMsgService;
 
+	/** 사이트 설정 */ 
+	@Resource(name = "egovSiteManagerService")
+	EgovSiteManagerService egovSiteManagerService;	
+
+	
+	@Resource(name = "MsgHolidayService")
+    private MsgHolidayService msgHolidayService;
+	
 
     @Autowired
     private PriceAndPoint priceAndPoint;
+    
+    @Autowired
+    private MjonCommon mjonCommon;
 	
 
 	public List<MjonMsgDataVO> selectCcmCmmCodeList() throws Exception {
@@ -3988,6 +4002,7 @@
     @Override
     public StatusResponse sendMsgData_advc(MjonMsgVO mjonMsgVO, HttpServletRequest request) throws Exception {
 
+    	log.info("mjonMsgVO [{}]" , mjonMsgVO.getMjonMsgSendVOList().get(0).getPhone());
 		log.info(" :: sendMsgData_advc :: ");
 		
 		Map<String, Object> returnMap = new HashMap<>();
@@ -4004,7 +4019,6 @@
 		
 		//발신번호가 등록된 유효한 번호인지 확인
 		int sendCallFromCnt = mjonMsgDAO.selectCallFromNumberChk(mjonMsgVO);
-		System.out.println("sendCallFromCnt : "+ sendCallFromCnt);
 		if(sendCallFromCnt < 1) {
 			return new StatusResponse(HttpStatus.BAD_REQUEST, "등록된 발신번호를 찾을 수 없습니다.");
 		}
@@ -4056,6 +4070,10 @@
 		// 수신거부 목록
 		returnMap.put("resultBlockSts", deletedCount);
 		
+		if(mjonMsgSendVOList.size() < 1) {
+			return new StatusResponse(HttpStatus.BAD_REQUEST, "수신거부와 매칭되는 번호 제거 후 \n발송 가능한 수신목록이 존재하지 않습니다.");
+		}
+		
 		
 		
 		
@@ -4087,7 +4105,7 @@
 		
 		mjonMsgVO.setAgentCode(hotlineAgentCode);
 		
-		// smstxt 치환 및 스팸체크 후  mjonMsgSendVOList 에 add()
+		// 스팸관련 키워드 select
 		List<String> resultSpamTxt = mjonMsgDataService.selectSpamKeywordList();
 		// msgGroupId 생성
 		String nextMsgGroupId = idgenMjonMsgGroupId.getNextStringId();
@@ -4141,38 +4159,12 @@
 		 * 		=> optimalMsgList로 데이터 이동 
 		 * 	  		이동하면서 이벤트 금액으로 설정
 		 */		
-		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo_advc(userId);
-		OptimalMsgResultDTO result = null;
-		List<MjonMsgSendVO> optimalMsgList = new ArrayList<>();
-		
-		if (eventMberInfo != null && !"E".equals(eventMberInfo.getEventStatus())) {
-			try {
-				result = MsgSendUtils.getOptimalMsgList(eventMberInfo, mjonMsgSendVOList);
-				optimalMsgList = result.getOptimalMsgList();
-				MjonEventVO returnEventMberInfo = result.getEventInfo();
+		// mjonCommon 호출
+		statusResponse = mjonCommon.processEventMessages(userId, mjonMsgVO, mjonMsgSendVOList);
 
-				// 이벤트 list에 내역에 있으면
-				if(CollectionUtils.isNotEmpty(optimalMsgList))
-				{
-					//  group tb에 이벤트 발송인지 Y 입력해야함
-					mjonMsgVO.setEventYn("Y");
-					//  기존 리스트로 병합
-					// 따로 분기 후 병합 하는 이유는 유지보수 및 기능 분리르 위함
-					mjonMsgSendVOList.addAll(optimalMsgList);
-				}
-	
-				// 이벤트 금액이 끝났거나 종료상태로 전환되면 update해야함
-				if (returnEventMberInfo != null && "E".equals(returnEventMberInfo.getEventStatus())) {
-					returnEventMberInfo.setMberId(userId);
-					mjonEventService.updateEventEndStatus(returnEventMberInfo);
-				}
-	
-			} catch (IllegalArgumentException e) {
-				// 메시지 타입 에러에 대한 응답 처리
-				statusResponse.setStatus(HttpStatus.BAD_REQUEST);
-				statusResponse.setMessage("이벤트 데이터 처리 중 오류가 발생하였습니다.\n관리자에게 문의해 주세요.");
-				return statusResponse;
-			}
+		if (statusResponse.getStatus() != null && !statusResponse.getStatus().equals(HttpStatus.OK)) {
+			log.error("이벤트 처리 중 오류 발생: {}", statusResponse.getMessage());
+			return statusResponse;
 		}
 
 
@@ -4192,6 +4184,7 @@
 		// Batch 시작 시간 측정
 		long insetStartTime = System.currentTimeMillis();
 		// 총 발송 건수 = DB insert
+//		int instCnt = 0;
 		int instCnt = this.insertMsgData_advc(mjonMsgSendVOList);
 
 		// Batch 종료 시간 측정 및 실행 시간 계산
@@ -4217,12 +4210,25 @@
 							, "SMS 문자 총 " + mjonMsgVO.getMjonMsgSendVOList().size() + "건 중 " + instCnt + "건 발송"
 							, mjonMsgVO.getMsgGroupId()
 							);
+			
+			// 스팸 데이터가 있으면 MJ_SPAM_MSG_GROUP_DATA 테이블에 insert
+			handleSpamMsg_advc(mjonMsgVO, mjonMsgSendVOList.get(0));
+			
 		}
 		
+
 		
 
-		//TODO : group tb insert 후 처리
-//		handleSpamMsg_advc(mjonMsgVO, mjonMsgSendVOList.get(0));
+		
+		
+		// 한 줄 호출
+		boolean isNotified = mjonCommon.processUserAndCheckSms(mjonMsgVO, userId);
+
+		if (isNotified) {
+			System.out.println("스미싱 알림이 처리되었습니다.");
+		} else {
+			System.out.println("알림 조건을 충족하지 않았습니다.");
+		}
 
 		
 		
@@ -4551,28 +4557,21 @@
 		}
 	}
 	
-	private void handleSpamMsg_advc(MjonMsgVO mjonMsgVO, MjonMsgSendVO mjonMsgSendVO) {
-		try {
+	private void handleSpamMsg_advc(MjonMsgVO mjonMsgVO, MjonMsgSendVO mjonMsgSendVO) throws Exception{
 			if ("Y".equals(mjonMsgVO.getSpamStatus())) 
 			{
 				MjonMsgVO mjonSpamMsgVO = mjonMsgVO;
-				mjonSpamMsgVO.setCallFrom(mjonMsgSendVO.getCallFrom());
-				mjonSpamMsgVO.setMsgGroupCnt(mjonMsgSendVO.getMsgGroupId());
 
-				mjonSpamMsgVO.setSubject(null);
-				mjonSpamMsgVO.setReqDate(null);
-				mjonSpamMsgVO.setMsgType(null);
-				mjonSpamMsgVO.setMsgType(null);
-				mjonSpamMsgVO.setEachPrice(null);
+				mjonSpamMsgVO.setSubject(mjonSpamMsgVO.getMmsSubject());
 				
-				
+				mjonSpamMsgVO.setEachPrice(mjonMsgSendVO.getEachPrice());
+				mjonSpamMsgVO.setFilePath1(mjonMsgSendVO.getFilePath1());
+				mjonSpamMsgVO.setFilePath2(mjonMsgSendVO.getFilePath2());
+				mjonSpamMsgVO.setFilePath3(mjonMsgSendVO.getFilePath3());
 				
 				int resultCnt = mjonSpamMsgService.insertSpamKeyWordMsgData(mjonMsgVO);
 				System.out.println("스팸 문구 발송 내용 등록: " + resultCnt);
 			}
-		} catch (Exception e) {
-			System.err.println("스팸 문구 처리 중 오류 발생: " + e.getMessage());
-		}
 	}
 
 	// 예약 문자인 경우 처리하는 메서드
src/main/java/itn/let/uss/umt/service/UserManageVO.java
--- src/main/java/itn/let/uss/umt/service/UserManageVO.java
+++ src/main/java/itn/let/uss/umt/service/UserManageVO.java
@@ -1,5 +1,10 @@
 package itn.let.uss.umt.service;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
 /**
  * 업무사용자VO클래스로서 업무사용자관리 비지니스로직 처리용 항목을 구성한다.
  * @author 공통서비스 개발팀 조재영
@@ -17,6 +22,10 @@
  *
  * </pre>
  */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
 public class UserManageVO extends UserDefaultVO{
 
 	/** 
@@ -209,536 +218,12 @@
 	private String nextPayMethod;
 	private float paymentCash;		//이전달에 실제 사용한 캐시 정보
 	
-	public String getNextPayMethod() {
-		return nextPayMethod;
-	}
-	public void setNextPayMethod(String nextPayMethod) {
-		this.nextPayMethod = nextPayMethod;
-	}
-	public String getSpamYn() {
-		return spamYn;
-	}
-	public void setSpamYn(String spamYn) {
-		this.spamYn = spamYn;
-	}
-	public String getAtSmishingYn() {
-		return atSmishingYn;
-	}
-	public void setAtSmishingYn(String atSmishingYn) {
-		this.atSmishingYn = atSmishingYn;
-	}
-	public String getBlineCode() {
-		return blineCode;
-	}
-	public void setBlineCode(String blineCode) {
-		this.blineCode = blineCode;
-	}
-	public String getRecommendId() {
-		return recommendId;
-	}
-	public void setRecommendId(String recommendId) {
-		this.recommendId = recommendId;
-	}
 	
-	public float getCash() {
-		return cash;
-	}
-	public void setCash(float cash) {
-		this.cash = cash;
-	}
-	public String getMberNm() {
-		return mberNm;
-	}
-	public void setMberNm(String mberNm) {
-		this.mberNm = mberNm;
-	}
-	
-	public String getSmishingYn() {
-		return smishingYn;
-	}
-	public void setSmishingYn(String smishingYn) {
-		this.smishingYn = smishingYn;
-	}
-	
-	public float getNowChargeCash() {
-		return nowChargeCash;
-	}
-	public void setNowChargeCash(float nowChargeCash) {
-		this.nowChargeCash = nowChargeCash;
-	}
-	public String getPrePaymentYn() {
-		return prePaymentYn;
-	}
-	public void setPrePaymentYn(String prePaymentYn) {
-		this.prePaymentYn = prePaymentYn;
-	}
-	public int getAutoCash() {
-		return autoCash;
-	}
-	public void setAutoCash(int autoCash) {
-		this.autoCash = autoCash;
-	}
-	
-	public String getMberId() {
-		return mberId;
-	}
 
-	public void setMberId(String mberId) {
-		this.mberId = mberId;
-	}
-	
-	public String getAdminSmsNoticeYn() {
-		return adminSmsNoticeYn;
-	}
-
-	public void setAdminSmsNoticeYn(String adminSmsNoticeYn) {
-		this.adminSmsNoticeYn = adminSmsNoticeYn;
-	}
-
-	public String getMobilePwsaveYn() {
-		return mobilePwsaveYn;
-	}
-
-	public void setMobilePwsaveYn(String mobilePwsaveYn) {
-		this.mobilePwsaveYn = mobilePwsaveYn;
-	}
-
-	public String getOldPassword() {
-		return oldPassword;
-	}
-
-	public void setOldPassword(String oldPassword) {
-		this.oldPassword = oldPassword;
-	}
-
-	public String getSbscrbDe() {
-		return sbscrbDe;
-	}
-
-	public void setSbscrbDe(String sbscrbDe) {
-		this.sbscrbDe = sbscrbDe;
-	}
-
-	public String getUniqId() {
-		return uniqId;
-	}
-
-	public void setUniqId(String uniqId) {
-		this.uniqId = uniqId;
-	}
-
-	public String getUserTy() {
-		return userTy;
-	}
-
-	public void setUserTy(String userTy) {
-		this.userTy = userTy;
-	}
-
-	public String getAreaNo() {
-		return areaNo;
-	}
-
-	public void setAreaNo(String areaNo) {
-		this.areaNo = areaNo;
-	}
-
-	public String getBrth() {
-		return brth;
-	}
-
-	public void setBrth(String brth) {
-		this.brth = brth;
-	}
-
-	public String getDetailAdres() {
-		return detailAdres;
-	}
-
-	public void setDetailAdres(String detailAdres) {
-		this.detailAdres = detailAdres;
-	}
-
-	public String getEmailAdres() {
-		return emailAdres;
-	}
-
-	public void setEmailAdres(String emailAdres) {
-		this.emailAdres = emailAdres;
-	}
-
-	public String getEmplNo() {
-		return emplNo;
-	}
-
-	public void setEmplNo(String emplNo) {
-		this.emplNo = emplNo;
-	}
-
-	public String getEmplyrId() {
-		return emplyrId;
-	}
-
-	public void setEmplyrId(String emplyrId) {
-		this.emplyrId = emplyrId;
-	}
-
-	public String getEmplyrIdDec() {
-		return emplyrIdDec;
-	}
-
-	public void setEmplyrIdDec(String emplyrIdDec) {
-		this.emplyrIdDec = emplyrIdDec;
-	}
-
-	public String getEmplyrNm() {
-		return emplyrNm;
-	}
-
-	public void setEmplyrNm(String emplyrNm) {
-		this.emplyrNm = emplyrNm;
-	}
-
-	public String getEmplyrSttusCode() {
-		return emplyrSttusCode;
-	}
-
-	public void setEmplyrSttusCode(String emplyrSttusCode) {
-		this.emplyrSttusCode = emplyrSttusCode;
-	}
-
-	public String getEmplyrSttusCodeTxt() {
-		return emplyrSttusCodeTxt;
-	}
-
-	public void setEmplyrSttusCodeTxt(String emplyrSttusCodeTxt) {
-		this.emplyrSttusCodeTxt = emplyrSttusCodeTxt;
-	}
-
-	public String getFxnum() {
-		return fxnum;
-	}
-
-	public void setFxnum(String fxnum) {
-		this.fxnum = fxnum;
-	}
-
-	public String getGroupId() {
-		return groupId;
-	}
-
-	public void setGroupId(String groupId) {
-		this.groupId = groupId;
-	}
-
-	public String getHomeadres() {
-		return homeadres;
-	}
-
-	public void setHomeadres(String homeadres) {
-		this.homeadres = homeadres;
-	}
-
-	public String getHomeendTelno() {
-		return homeendTelno;
-	}
-
-	public void setHomeendTelno(String homeendTelno) {
-		this.homeendTelno = homeendTelno;
-	}
-
-	public String getHomemiddleTelno() {
-		return homemiddleTelno;
-	}
-
-	public void setHomemiddleTelno(String homemiddleTelno) {
-		this.homemiddleTelno = homemiddleTelno;
-	}
-
-	public String getIhidnum() {
-		return ihidnum;
-	}
-
-	public void setIhidnum(String ihidnum) {
-		this.ihidnum = ihidnum;
-	}
-
-	public String getInsttCode() {
-		return insttCode;
-	}
-
-	public void setInsttCode(String insttCode) {
-		this.insttCode = insttCode;
-	}
-
-	public String getMberTy() {
-		return mberTy;
-	}
-
-	public void setMberTy(String mberTy) {
-		this.mberTy = mberTy;
-	}
-
-	public String getMoblphonNo() {
-		return moblphonNo;
-	}
-
-	public void setMoblphonNo(String moblphonNo) {
-		this.moblphonNo = moblphonNo;
-	}
-
-	public String getOfcpsNm() {
-		return ofcpsNm;
-	}
-
-	public void setOfcpsNm(String ofcpsNm) {
-		this.ofcpsNm = ofcpsNm;
-	}
-
-	public String getOffmTelno() {
-		return offmTelno;
-	}
-
-	public void setOffmTelno(String offmTelno) {
-		this.offmTelno = offmTelno;
-	}
-
-	public String getOrgnztId() {
-		return orgnztId;
-	}
-
-	public void setOrgnztId(String orgnztId) {
-		this.orgnztId = orgnztId;
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public String getPasswordCnsr() {
-		return passwordCnsr;
-	}
-
-	public void setPasswordCnsr(String passwordCnsr) {
-		this.passwordCnsr = passwordCnsr;
-	}
-
-	public String getPasswordHint() {
-		return passwordHint;
-	}
-
-	public void setPasswordHint(String passwordHint) {
-		this.passwordHint = passwordHint;
-	}
-
-	public String getSbscrbDeBegin() {
-		return sbscrbDeBegin;
-	}
-
-	public void setSbscrbDeBegin(String sbscrbDeBegin) {
-		this.sbscrbDeBegin = sbscrbDeBegin;
-	}
-
-	public String getSbscrbDeEnd() {
-		return sbscrbDeEnd;
-	}
-
-	public void setSbscrbDeEnd(String sbscrbDeEnd) {
-		this.sbscrbDeEnd = sbscrbDeEnd;
-	}
-
-	public String getSexdstnCode() {
-		return sexdstnCode;
-	}
-
-	public void setSexdstnCode(String sexdstnCode) {
-		this.sexdstnCode = sexdstnCode;
-	}
-
-	public String getZip() {
-		return zip;
-	}
-
-	public void setZip(String zip) {
-		this.zip = zip;
-	}
-
-	public String getSubDn() {
-		return subDn;
-	}
-
-	public void setSubDn(String subDn) {
-		this.subDn = subDn;
-	}
-
-	public String getPartIdx() {
-		return partIdx;
-	}
-
-	public void setPartIdx(String partIdx) {
-		this.partIdx = partIdx;
-	}
-
-	public String getPartIdxTxt() {
-		return partIdxTxt;
-	}
-
-	public void setPartIdxTxt(String partIdxTxt) {
-		this.partIdxTxt = partIdxTxt;
-	}
-
-	public String getAuthorCode() {
-		return authorCode;
-	}
-
-	public void setAuthorCode(String authorCode) {
-		this.authorCode = authorCode;
-	}
-
-	public String getAuthorNm() {
-		return authorNm;
-	}
-
-	public void setAuthorNm(String authorNm) {
-		this.authorNm = authorNm;
-	}
-
-	public String getRsaPasswd() {
-		return rsaPasswd;
-	}
-
-	public void setRsaPasswd(String rsaPasswd) {
-		this.rsaPasswd = rsaPasswd;
-	}
-
-	public String getEsntlId() {
-		return esntlId;
-	}
-
-	public void setEsntlId(String esntlId) {
-		this.esntlId = esntlId;
-	}
-
-	public String getSearchWord() {
-		return searchWord;
-	}
-
-	public void setSearchWord(String searchWord) {
-		this.searchWord = searchWord;
-	}
-
-	public String getUserNm() {
-		return userNm;
-	}
-
-	public void setUserNm(String userNm) {
-		this.userNm = userNm;
-	}
-
-	public String getUserWork() {
-		return userWork;
-	}
-
-	public void setUserWork(String userWork) {
-		this.userWork = userWork;
-	}
-
-	public String getLocInfoId() {
-		return locInfoId;
-	}
-
-	public void setLocInfoId(String locInfoId) {
-		this.locInfoId = locInfoId;
-	}
-
-	public String getSort() {
-		return sort;
-	}
-
-	public void setSort(String sort) {
-		this.sort = sort;
-	}
-
-	public String getCheckNo() {
-		return checkNo;
-	}
-
-	public void setCheckNo(String checkNo) {
-		this.checkNo = checkNo;
-	}
-
-	public String getFindType() {
-		return findType;
-	}
-
-	public void setFindType(String findType) {
-		this.findType = findType;
-	}
-
-	public String getEmailSendYN() {
-		return emailSendYN;
-	}
-
-	public void setEmailSendYN(String emailSendYN) {
-		this.emailSendYN = emailSendYN;
-	}
-
-	public String getMbtlSendYN() {
-		return mbtlSendYN;
-	}
-
-	public void setMbtlSendYN(String mbtlSendYN) {
-		this.mbtlSendYN = mbtlSendYN;
-	}
-
-	public String getPasswordOverlapCheck() {
-		return passwordOverlapCheck;
-	}
-
-	public void setPasswordOverlapCheck(String passwordOverlapCheck) {
-		this.passwordOverlapCheck = passwordOverlapCheck;
-	}
-
-	public String getUserSe() {
-		return userSe;
-	}
-
-	public void setUserSe(String userSe) {
-		this.userSe = userSe;
-	}
-
-	public String getCrtfcDnValue() {
-		return crtfcDnValue;
-	}
-
-	public void setCrtfcDnValue(String crtfcDnValue) {
-		this.crtfcDnValue = crtfcDnValue;
-	}
-
-	public String getOuterCertYn() {
-		return outerCertYn;
-	}
-
-	public void setOuterCertYn(String outerCertYn) {
-		this.outerCertYn = outerCertYn;
-	}
-	public String getVipYn() {
-		return vipYn;
-	}
-	public void setVipYn(String vipYn) {
-		this.vipYn = vipYn;
-	}
-	public float getPaymentCash() {
-		return paymentCash;
-	}
-	public void setPaymentCash(float paymentCash) {
-		this.paymentCash = paymentCash;
+	public UserManageVO(String userId) {
+		this.mberId = userId;
+		// TODO Auto-generated constructor stub
 	}
-	
 	
 	
 	
src/main/resources/egovframework/egovProps/globals_dev.properties
--- src/main/resources/egovframework/egovProps/globals_dev.properties
+++ src/main/resources/egovframework/egovProps/globals_dev.properties
@@ -115,3 +115,7 @@
 #MOBILE
 Globals.pay.kgm.mobile.mcSvcid=170622040674
 Globals.pay.kgm.mobile.payMode=00
+
+#Slack
+Globals.slack.hooks.url=https://hooks.slack.com/services/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
+Globals.slack.channel.name=\ud14c\uc2a4\ud2b8_mjon\uba54\uc2dc\uc9c0
src/main/resources/egovframework/egovProps/globals_local.properties
--- src/main/resources/egovframework/egovProps/globals_local.properties
+++ src/main/resources/egovframework/egovProps/globals_local.properties
@@ -116,3 +116,12 @@
 #MOBILE
 Globals.pay.kgm.mobile.mcSvcid=170622040674
 Globals.pay.kgm.mobile.payMode=00
+
+#Slack
+Globals.slack.hooks.url=https://hooks.slack.com/services/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
+Globals.slack.channel.name=\ud14c\uc2a4\ud2b8_mjon\uba54\uc2dc\uc9c0
+
+
+
+
+
src/main/resources/egovframework/egovProps/globals_prod.properties
--- src/main/resources/egovframework/egovProps/globals_prod.properties
+++ src/main/resources/egovframework/egovProps/globals_prod.properties
@@ -102,4 +102,8 @@
 Globals.pay.kgm.bank.payMode=10
 #MOBILE
 Globals.pay.kgm.mobile.mcSvcid=220613125202
-Globals.pay.kgm.mobile.payMode=10
(No newline at end of file)
+Globals.pay.kgm.mobile.payMode=10
+
+#Slack
+Globals.slack.hooks.url=https://hooks.slack.com/services/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
+Globals.slack.channel.name=mjon\uba54\uc2dc\uc9c0
(No newline at end of file)
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
@@ -1016,7 +1016,7 @@
 		const numbers = textarea.val().split('\n')
 		    .map(num => num.trim())
 		    .filter(num => num !== "");
-
+		
 		console.log('입력된 번호들 : ', numbers);
 
 		// 현재 테이블에 있는 데이터 가져오기
@@ -1028,13 +1028,19 @@
 
 		// 각 번호를 테이블에 추가 (중복 검사 및 포맷팅 포함)
 		numbers.forEach(number => {
+// 			const formattedNumber = formatPhoneNumber(number); // 번호 표준화
+
 			const formattedNumber = formatPhoneNumber(number); // 번호 표준화
+			console.log('formattedNumber : ', formattedNumber);
 // 			console.log('number : ', number)
 // 			console.log('formattedNumber : ', formattedNumber)
 			const cleanedNumber = formattedNumber.replace(/[^0-9]/g, ''); // 숫자만 남김
+			console.log('cleanedNumber : ', cleanedNumber);
+			console.log('cleanedNumber : ', cleanedNumber);
 			if (!existingNumbers.has(cleanedNumber)) { // 중복 번호 체크
 				if (isValidPhoneNumber(formattedNumber)) { // 유효성 검사
-					tableL.addRow({ phone: formattedNumber }); // 표준화된 번호로 추가
+// 					tableL.addRow({ phone: formattedNumber }); // 표준화된 번호로 추가
+					tableL.addRow({ phone: cleanedNumber }); // 하이픈 제거된 번호로 추가
 					existingNumbers.add(cleanedNumber); // 추가된 번호를 기존 목록에 추가
 				} else {
 // 					alert(`유효하지 않은 번호 형식: ${number}`);
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
@@ -1081,6 +1081,7 @@
 		}
 	}
 	
+
 	
 	if(!confirm("문자를 전송하시겠습니까?")){
 		return false;
@@ -1236,6 +1237,23 @@
 }
 
 
+// 선택된 데이터의 길이에 따라 예상 시간 계산 함수
+function calculateEstimatedTime(selectedCount) {
+	//기준값
+	// const processTimePerBatch = 130; // 130초
+	
+	
+	const processTimePerBatch = 260; // 260초
+	const batchSize = 300000; // 30만 건
+	
+	// 1건당 처리 시간
+	const timePerRecord = processTimePerBatch / batchSize;
+
+	// 예상 시간 계산
+	const estimatedTimeInSeconds = selectedCount * timePerRecord;
+
+	return estimatedTimeInSeconds.toFixed(2);
+}
 
 
 
@@ -1268,6 +1286,12 @@
 	 // 시작 시간
 	const startTime = new Date();
 	 
+	
+	 // 프로그래스파 시간을 위한 계산
+	var estimtedTime = calculateEstimatedTime($selectedData.length);
+	console.log('estimtedTime  : ', estimtedTime);
+	
+	 
 	$.ajax({
 		type: "POST",
 		url: url,
@@ -1275,6 +1299,7 @@
 		contentType: 'application/json',
 		dataType: 'json',
 		success: function (data) {
+			
 			// 요청 종료 시간 및 경과 시간 계산
 			const endTime = new Date();
 			const elapsed = (endTime - startTime) / 1000; // 밀리초 -> 초로 변환
@@ -1345,12 +1370,19 @@
 				
 		},
 		beforeSend : function(xmlHttpRequest) {
+			// 프로그래스 바 실행
+			// 프로그래스 바 실행
+			progressStart(estimtedTime);
 			//로딩창 show
-			$('.loading_layer').addClass('active');
+// 			$('.loading_layer').addClass('active');
 		},
 		complete : function(xhr, textStatus) {
-			//로딩창 hide
-			$('.loading_layer').removeClass('active');
+
+			// 프로그래스 바 종료
+			// 프로그래스 바 종료
+			progressComplete();;
+// 			로딩창 hide
+// 			$('.loading_layer').removeClass('active');
 		},
 		error: function (e) { alert("문자 발송에 실패하였습니다."); console.log("ERROR : ", e); }
 	});
@@ -1359,6 +1391,14 @@
 
 //폼 유효성 검사 함수
 function validateForm(form) {
+
+    // 타블레이터 호출
+    var $selectedData = tableL.getData(); // 데이터 가져오기
+    if($selectedData.length < 1){
+		alert("받는사람 내역을 입력해주세요.");
+		return false;
+    }
+	
 	
 	if(form.callFromList.value == ""){
 		
@@ -1390,7 +1430,7 @@
 	}
 	
 	if (imgFilePath.length === 0 && !form.smsTxtArea.value) {
-		alert("문자 내용을 입력해 주세요.");
+		alert("문자내용을 입력해 주세요.");
 		return false;
 	}
 	return true;
src/main/webapp/publish/js/content.js
--- src/main/webapp/publish/js/content.js
+++ src/main/webapp/publish/js/content.js
@@ -1587,7 +1587,7 @@
 
 // 프로그레스바 
 var start, change;
-let progressInterval = null; // 전역 변수로 타이머 ID 관리
+var progressInterval = null; // 전역 변수로 타이머 ID 관리
 
 function progressStart(time) {
     // 기존 타이머 정지 및 초기화
@@ -1644,52 +1644,12 @@
 
 
 
-
-/*
-function progressStart(time) {
-
-	// 초기셋팅   
-	$(".time_text").text("0%");
-	$(".change_bar").css("width", "0");
-	$(".time_text").removeClass("animation");
-
-    $(".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 증가하는 시간
-
-    start = setInterval(changeWidth, cmpWid); // 프로그레스바 시작
-
-    function changeWidth() {
-        if (width >= 100) {
-        	// width 100% 됐을 때
-            clearInterval(start); // 프로그래스바 멈춤
-            
-            timeText.innerHTML = "100%";
-            setTimeout(function () {
-            	// 100%되고 1초 후 잠시만 기다려주세요 변경 및 애니메이션 추가
-                timeText.innerHTML = "잠시만 기다려주세요...";
-                $(".time_text").addClass("animation");
-            }, 1000)
-
-
-        } else {
-        	// width 증가 및 text 변경
-            width++;
-            bar.style.width = width + "%";
-            timeText.innerHTML = width + "%";
-        }
-    }
-}*/
-
 // 프로그레스바 완료
 function progressComplete() {
     // var width = parseInt($(".time_text").text().replace('%', '')) || 0; // 현재 width 가져오기
 
+	$(".progress_bar_wrap").hide();
+	/*
 	var widthText = $(".change_bar").attr("style");
 	var width = widthText.replace(/[width:%;overfloen]/ig, ""); // width 값 퍼센트로 가져오기
     var currentText = $(".time_text").text().trim(); // 현재 텍스트 가져오기
@@ -1725,7 +1685,7 @@
             $(".time_text").text(width + "%");
             $(".change_bar").css("width", width + "%");
         }
-    }, 10); // DOM 업데이트 간격 (10ms)
+    }, 10); // DOM 업데이트 간격 (10ms)*/
 }
 
 /*// 프로그레스바 완료
Add a comment
List