package itn.let.mjo.mjocommon; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; 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 org.springframework.transaction.annotation.Transactional; import egovframework.com.idgen.CustomIdGnrService; import egovframework.rte.fdl.cmmn.exception.FdlException; import itn.com.cmm.MjonMsgSendVO; import itn.com.cmm.OptimalMsgResultDTO; import itn.com.cmm.util.MsgSendUtils; import itn.com.cmm.util.SlackMessageFormatUtil; import itn.com.cmm.util.StringUtil; import itn.let.kakao.kakaoComm.KakaoSendAdvcVO; 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.msg.service.impl.MjonMsgDAO; import itn.let.mjo.msgdata.service.MjonMsgDataService; 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.sym.site.service.EgovSiteManagerService; import itn.let.sym.site.service.JoinSettingVO; import itn.let.uat.uia.web.SendLogVO; 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 { /** 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; @Resource(name = "egovMjonMsgIdCGnrService") private CustomIdGnrService idgenMsgCId; @Resource(name = "mjonMsgDAO") private MjonMsgDAO mjonMsgDAO; @Resource(name = "MjonMsgDataService") private MjonMsgDataService mjonMsgDataService; /** * @methodName : getAdminSandSlack * @author : 이호영 * @date : 2024.12.04 * @description : 기존 메소드 리펙토링 * @param mjonMsgVO */ public void getAdminSandSlack(String smsTxt, String sandName) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(SLACK_URL); try { // 메시지 내용 설정 // 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(); } } /** * @methodName : getAdminMsgSandSlack * @author : 이호영 * @date : 2024.12.04 * @description : 기존 메소드 리펙토링 * @param mjonMsgVO */ public void getAdminMsgSandSlack(MjonMsgVO mjonMsgVO) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(SLACK_URL); try { // 메시지 내용 설정 String smsTxt = SlackMessageFormatUtil.formatSmsText(mjonMsgVO); String sandName = SlackMessageFormatUtil.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(); } } public void getAdminKakaoAtSendSlack(KakaoSendAdvcVO kakaoVO) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(SLACK_URL); try { // 메시지 내용 설정 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"); // 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(); } } private String formatKakaoSandName(KakaoVO kakaoVO) { // TODO Auto-generated method stub return null; } /** * @Method Name : sendSimpleSlackMsg * @작성일 : 2022. 12. 9 * @작성자 : AnJooYoung * @Method 설명 : slack 단순 메시지 전송 */ @SuppressWarnings("unchecked") public void sendSimpleSlackMsg(String msg) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(SLACK_URL); JSONObject json = new JSONObject(); try { json.put("channel", SLACK_CHANNEL); //json.put("channel", "C04DNV4FYP6"); //개발 서버용 json.put("text", msg); post.addParameter("payload", json.toString()); // 처음에 utf-8로 content-type안넣어주니까 한글은 깨져서 content-type넣어줌 post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); int responseCode = client.executeMethod(post); String response = post.getResponseBodyAsString(); if (responseCode != HttpStatus.SC_OK) { System.out.println("Response: " + response); } } catch (IllegalArgumentException e) { System.out.println("IllegalArgumentException posting to Slack " + e); } catch (IOException e) { System.out.println("IOException posting to Slack " + e); } catch (Exception e) { System.out.println("Exception posting to Slack " + e); } finally { post.releaseConnection(); } } /** * 관리자로 문자 발송해주기 * 사용자가 보낸 문자를 문자온 법인폰으로 발송해주는 기능 함수. * 일반문자 와 대량 문자 모두 적용하고 있음 * 2022.09.19 우영두 추가 * 2023.01.26 우영두 수정 => 대표전송사로 발송되도록 수정 * */ public MjonMsgVO getAdminPhoneSendMsgDataComm(MjonMsgVO mjonMsgVO) throws Exception{ try { mjonMsgVO.setUserId("system");//시스템 발송 문자로 처리 //전송사 선택 String msgType = mjonMsgVO.getMsgType(); int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt());//그림 이미지 갯수 if(msgType.equals("6")) {//장문 혹은 그림문자인 경우 if(fileCount > 0) {//그림문자인 경우 mjonMsgVO.setNeoType("4"); } } //수신번호가 배열로 되어있어서 배열에 담아준다. String[] phone = new String[1]; String callTo = "15518011"; phone[0] = callTo; mjonMsgVO.setCallToList(phone);//수신번호 리스트 //시스템 로그용 수신 정보 mjonMsgVO.setCallTo("help@iten.co.kr"); //현재 고객의 보유 캐시가 문자 발송이 가능한 금액인지 체크 //String userMoney = "0.0"; String userPoint = "0.0"; mjonMsgVO.setBefPoint(userPoint); //현재 보유 포인트 정보 저장 mjonMsgVO.setBefCash("0.0"); //관리자가 발송하는 것이라서 0원으로 입력 mjonMsgVO.setMsgGroupCnt("1"); //문자종류 관리자가 발송하는 것은 msgKind : S 로 셋팅 mjonMsgVO.setMsgKind("S"); Date now = new Date(); SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); mjonMsgVO.setReqDate(sdFormat.format(now)); //예약 문자 발송 없이 즉시 발송으로 처리 mjonMsgVO.setReserveYn("N"); } catch (Exception e) { System.out.println("+++++++++++++++++++++++++++++ MjonCommon Class getAdminPhoneSendMsgData Function Error !!!" + e); } return mjonMsgVO; } /** * 관리자가 사용자에게 문자 발송해주기 * 발신번호 승인 / 반려시 사용자에게 문자 발송해 주기. * 일반문자 와 대량 문자 모두 적용하고 있음 * 2022.09.26 우영두 추가 * * */ public MjonMsgVO getAdminToMberPhoneSendMsgDataComm(MjonMsgVO mjonMsgVO) throws Exception{ try { mjonMsgVO.setUserId("system");//시스템 발송 문자로 처리 //전송사 선택 String msgType = mjonMsgVO.getMsgType(); int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt());//그림 이미지 갯수 if(msgType.equals("6")) {//장문 혹은 그림문자인 경우 if(fileCount > 0) {//그림문자인 경우 mjonMsgVO.setNeoType("4"); } } //수신번호가 배열로 되어있어서 배열에 담아준다. String[] phone = new String[1]; String callTo = mjonMsgVO.getCallTo(); phone[0] = callTo; mjonMsgVO.setCallToList(phone);//수신번호 리스트 //시스템 로그용 수신 정보 mjonMsgVO.setCallTo(callTo); //현재 고객의 보유 캐시가 문자 발송이 가능한 금액인지 체크 //String userMoney = "0.0"; String userPoint = "0.0"; mjonMsgVO.setBefPoint(userPoint); //현재 보유 포인트 정보 저장 mjonMsgVO.setBefCash("0.0"); //관리자가 발송하는 것이라서 0원으로 입력 mjonMsgVO.setMsgGroupCnt("1"); //문자종류 관리자가 발송하는 것은 msgKind : S 로 셋팅 mjonMsgVO.setMsgKind("S"); //예약 문자 발송 없이 즉시 발송으로 처리 mjonMsgVO.setReserveYn("N"); } catch (Exception e) { System.out.println("+++++++++++++++++++++++++++++ MjonCommon Class getAdminToMberPhoneSendMsgData Function Error !!!" + e); } return mjonMsgVO; } /* @SuppressWarnings("unchecked") public void getAdminKakaoAtSandSlack(KakaoVO kakaoVO) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(SLACK_URL); JSONObject json = new JSONObject(); try { String reserveYn = kakaoVO.getReserveYn(); String atDelayYn = kakaoVO.getAtDelayYn(); String smsTxt = kakaoVO.getTemplateContent(); String reservSmsTxt = ""; String smisingSmsTxt = ""; //예약문자를 발송하는 경우 문자 내용 앞에 "[예약]" 표시되도록 처리 if(reserveYn.equals("Y")) { if(atDelayYn.equals("Y")) {//예약문자 중 스미싱의심 일 경우 reservSmsTxt = "[스미싱의심][예약]" + smsTxt; }else { reservSmsTxt = "[예약]" + smsTxt; } smsTxt = reservSmsTxt; }else if(atDelayYn.equals("Y")) { smisingSmsTxt = "[스미싱의심]" + smsTxt; smsTxt = smisingSmsTxt; } String sandName = kakaoVO.getCallFrom(); String userId = kakaoVO.getUserId(); String msgType = ""; if(kakaoVO.getMsgType().equals("8")) { msgType = "[알림톡]"; }else if(kakaoVO.getMsgType().equals("9")){ msgType = "[친구톡]"; } sandName = "[" + userId + "]" + "[" + sandName + "]" + msgType; json.put("channel", SLACK_CHANNEL); json.put("text", smsTxt); json.put("username", sandName); post.addParameter("payload", json.toString()); // 처음에 utf-8로 content-type안넣어주니까 한글은 깨져서 content-type넣어줌 post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); int responseCode = client.executeMethod(post); String response = post.getResponseBodyAsString(); if (responseCode != HttpStatus.SC_OK) { System.out.println("Response: " + response); } } catch (IllegalArgumentException e) { System.out.println("IllegalArgumentException posting to Slack " + e); } catch (IOException e) { System.out.println("IOException posting to Slack " + e); } catch (Exception e) { System.out.println("Exception posting to Slack " + e); } finally { post.releaseConnection(); } } */ public String getCreateMsgUserIdgen(String subUserId, String lastId) throws Exception{ String returnId = ""; String[] splitId = lastId.split("_"); if(splitId.length > 0) { int lastNum = Integer.parseInt(splitId[1]); lastNum = lastNum + 1; String tmpLastNum = Integer.toString(lastNum); int zeroPlusCnt = 14 - tmpLastNum.length(); StringBuilder sb = new StringBuilder(); sb.append(subUserId + "_"); for(int i=0; i< zeroPlusCnt; i++) { sb.append('0'); } sb.append(tmpLastNum); returnId = sb.toString(); } return returnId; } 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; } } /** * @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); // 기본값 처리된 사용자 정보와 문자 상태 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(); // 알림 처리 결과 반환 } 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(); // 법인폰 알람 여부 - Y : ON String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON // 조건 체크 if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) { kakaoVO.setAtSmishingYn("Y"); // MjonMsgVO에 스미싱 정보 설정 - Y면 디 // 스미싱 알림 처리 return handleSmishingAlert(); // 알림 처리 결과 반환 } return false; // 알림 처리되지 않음 } /** * @methodName : processUserAndCheckFT * @author : 이호영 * @date : 2025. 8. 21. * @description : * @return : boolean * @param kakaoVO * @return * @throws Exception * * @isHolidayNotified * @false : 알림 X * @true : 알림 O * */ public boolean processUserAndCheckFT(KakaoVO kakaoVO) throws Exception { // UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId()); // kakaoVO.setAtSmishingYn("N"); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리 됨 // 기본값 처리된 사용자 정보와 문자 상태 // String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); // 법인폰 알람 여부 - Y : ON // String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON !== mj_msg_group_data와 다른거임 // 조건 체크 // if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) { // if ("Y".equals(atSmishingYn)) { // Boolean B_return = handleSmishingAlert(); // if(B_return) { // true면 알림ON이라서 스미싱Yn을 Y로 설정 아니면 N / 나머지는 로직에서 처리 // kakaoVO.setAtSmishingYn(atSmishingYn); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리 됨 // } // 스미싱 알림 처리 // return B_return; // 알림 처리 결과 반환 // } return handleSmishingAlert(); // 알림 처리되지 않음 } // 사용자 정보 조회 및 기본값 처리 public UserManageVO getUserManageInfo(String userId) throws Exception { // UserManageVO userManageVO = new UserManageVO(); // userManageVO.setAdminSmsNoticeYn("Y"); // 기본값 // userManageVO.setSmishingYn("N"); // 기본값 // return userManageService.selectAdminSmsNoticeYn(new UserManageVO(userId)); } // 스미싱 알림 처리 public boolean handleSmishingAlert() throws Exception { /** * MJ_MBER_SETTING => 기본 시스템 알림 여부 * 슬랙 Y * 야간스미싱알림 Y * 등등 * */ JoinSettingVO joinSettingVO = egovSiteManagerService.selectAdminNotiDetail(); /** @시스템 설정에 야간스미싱 알림 || 슬랙알림이 N이면 false*/ if (joinSettingVO == null || !"Y".equals(joinSettingVO.getHoliSmishingNoti()) || !"Y".equals(joinSettingVO.getSlackNoti())) { return false; // 알림 조건 미충족 } /** @MJ_SPAMPASS_ALARM : 현재 활성화된 알림 SELECT */ List alarmList = getAlarmSettings(); /** @MJ_HOLIDAY 시스템에 등록된 공휴일 설정 */ List holidayList = getHolidayList(); /** @MJ_HOLIDAY 시스템에 등록된 공휴일 설정 */ boolean isNotificationAllowed = new MjonHolidayApi().getHolidaySmishingPassStatus_advc(alarmList, holidayList); return !isNotificationAllowed; // 알림 발송 조건 미충족 } // 안전하게 문자열 가져오기 private String safeGetString(String value) { return value == null ? "" : value; } // 알림 설정 조회 private List getAlarmSettings() throws Exception { MsgAlarmSetVO msgAlarmSetVO = new MsgAlarmSetVO(); msgAlarmSetVO.setUseYn("Y"); msgAlarmSetVO.setFirstIndex(0); msgAlarmSetVO.setRecordCountPerPage(10000); return msgHolidayService.selectAlarmSettingList(msgAlarmSetVO); } // 공휴일 정보 조회 private List getHolidayList() throws Exception { Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); MsgHolidayVO msgHolidayVO = new MsgHolidayVO(); msgHolidayVO.setFirstIndex(0); msgHolidayVO.setRecordCountPerPage(10000); msgHolidayVO.setSearchHoliYear(Integer.toString(year)); return msgHolidayService.selectMsgHolidayList(msgHolidayVO); } // 이벤트 메시지 처리 public StatusResponse processEventMessages(String userId, MjonMsgVO mjonMsgVO, List mjonMsgSendVOList, MjonEventVO eventMberInfo) throws Exception { StatusResponse statusResponse = new StatusResponse(); try { // 이벤트 여부 확인 if (MsgSendUtils.isNotEvent(eventMberInfo)) { return statusResponse; // 이벤트 상태가 종료이거나 endDate가 없는 경우 처리하지 않음 } log.info(" + 이벤트 진행 대상자 :: [{}]", userId); log.info(" + 이벤트 진행 대상자 eventMberInfo.getMberId() :: [{}]", eventMberInfo.getMberId()); // 최적화된 메시지 리스트 및 이벤트 정보 가져오기 OptimalMsgResultDTO result = MsgSendUtils.getOptimalMsgList(eventMberInfo, mjonMsgSendVOList); List optimalMsgList = result.getOptimalMsgList(); MjonEventVO returnEventMberInfo = result.getEventInfo(); // 이벤트 발송 내역이 있으면 if (CollectionUtils.isNotEmpty(optimalMsgList)) { mjonMsgVO.setEventYn("Y"); // 그룹에 이벤트 발송 여부 설정 mjonMsgSendVOList.addAll(optimalMsgList); // 기존 리스트와 병합 } // 이벤트 관련 데이터가 있으면 updqte eventChkAndInsertAmount(returnEventMberInfo); } catch (IllegalArgumentException e) { // 메시지 타입 에러 처리 MsgSendUtils.statusResponseSet(statusResponse, org.springframework.http.HttpStatus.BAD_REQUEST, "이벤트 데이터 처리 중 오류가 발생하였습니다.\n관리자에게 문의해 주세요."); } return statusResponse; } /** * @methodName : checkEventAndDeductAmount * @author : 이호영 * @date : 2025.02.10 * @description : * @param eventMberInfo * @param eachPrice * @throws Exception */ public void checkEventAndDeductAmount(MjonEventVO eventMberInfo, List groupedMsgList) throws Exception { // 이벤트 그룹인지 확인 if("Y".equals(groupedMsgList.get(0).getEventYn())) { // 이벤트 남은 금액 double remainCash = eventMberInfo.getEventRemainCash(); // 현재 그룹에서 발송한 총 금액 float sendTotalPrice = MsgSendUtils.setPriceforVO(groupedMsgList); // 이벤트 남은 금액에서 현재 그룹에 총 발송금액 차감 remainCash -= sendTotalPrice; MjonEventVO returnEventMberInfo = returnEventMberInfo = MsgSendUtils.terminateEvent(eventMberInfo, remainCash); eventChkAndInsertAmount(returnEventMberInfo); } } /** * @methodName : eventChkAndInsertAmount * @author : 이호영 * @date : 2025.02.10 * @description : 이벤트 관련 데이터가 있으면 update * @param returnEventMberInfo * @throws Exception */ private void eventChkAndInsertAmount(MjonEventVO returnEventMberInfo) throws Exception { // 이벤트 상태 종료 시 업데이트 if (returnEventMberInfo != null) { mjonEventService.updateEventEndStatus(returnEventMberInfo); } } public List getNextCustomMsgCId (int cnt) throws FdlException { List idList = idgenMsgCId.getNextStringId(cnt); return idList; } /** * @methodName : getSmsTxtBytes * @author : 이호영 * @date : 2024.09.23 * @description : sms 텍스트 바이트 계산 후 return; * @param smsTxt * @return * @throws UnsupportedEncodingException */ public static int getSmsTxtBytes(String smsTxt) throws UnsupportedEncodingException { //문자열 길이 체크 해주기 int smsBytes = 0; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산 String charset = "euc-kr"; if(org.apache.commons.lang3.StringUtils.isNotEmpty(smsTxt)) { String smsCont = smsTxt.replace("\r\n", "\n"); smsBytes = smsCont.getBytes(charset).length; } // log.info(" + smsBytes :: [{}]", smsBytes); return smsBytes; } /** * @methodName : replaceTemplateVariables * @author : 이호영 * @date : 2025. 3. 12. * @description : 헬퍼 메서드: 템플릿 변수 치환 * @return : String * @param content * @param variables * @return */ public static String ATReplaceTemplateVariables(String content, Map variables) { String result = content; for (Map.Entry entry : variables.entrySet()) { String placeholder = entry.getKey(); String value = entry.getValue(); result = result.replace(placeholder, value); } return result; } public void sendMessagesIfOverFifty(int cnt, String callTo) throws Exception { if( cnt >= 50 //50건 이상일 경우만 발송 && StringUtil.isNotEmpty(callTo) // null, "" 체크 && callTo.startsWith("010") // 010으로 시작하는 휴대폰번호일 경우 && "Y".equals(selectSmsNotiIfOverFiftySetting()) // 안내문자 발송 on 인경우만 && !sysMsgTodaySendYn(callTo) // 금일 1회 이상 보낸 이력없을 경우만 발송 ) { //50건이상 발송 안내문자 구분값 = 01 String sendMsgType = "01"; String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); String contents = "[인터넷 대량문자발송안내] 문자온에서 "+ callTo + " 번호로 " + today + "에 인터넷 대량 문자(50통 이상)가 발송되었습니다." + "\n※ 번호도용이 의심되는 경우, 이용 중인 이동통신사의 휴대전화 번호도용 문자차단 부가서비스(무료)에 가입하여 피해를 예방할 수 있습니다."; this.sendSysMsg( "15518011" , callTo , contents , sendMsgType ); } } /** * Method Name : sendSysMsg * Description : 관리자 안내 문자 공통 * * @param callFrom : 발신번호 * @param callTo : 수신번호 * @param contents : 내용 * @param sendMsgType : 발신내용 타입 - 01: 대량문자발송안내 * @return * @throws Exception * @return MjonMsgReturnVO 설명 */ @Transactional(rollbackFor = Exception.class) public MjonMsgReturnVO sendSysMsg( String callFrom , String callTo , String contents , String sendMsgType ) throws Exception { //결과 vo MjonMsgReturnVO returnVO = new MjonMsgReturnVO(); MjonMsgVO mjonMsgVO = new MjonMsgVO(); mjonMsgVO.setSmsTxt(contents); mjonMsgVO.setReserveYn("N"); // 시스템 문자발송 번호 // mjonMsgVO.setCallFrom("15518011"); mjonMsgVO.setCallFrom(callFrom); mjonMsgVO.setCallTo(callTo); mjonMsgVO.setUserId("system"); /* * 본문길이에 따른 단문/장문 구분 * 단문 4 * 장문 6 * 2000자 이상 invalid */ String msgType = MsgSendUtils.getMsgTypeWithByteValidation(new MjonMsgSendVO(), contents);// mjonMsgVO.setMsgType(msgType); // MsgDiv - S: 단문, L: 장문, P: 그림 if("4".equalsIgnoreCase(msgType)) { mjonMsgVO.setMsgDiv("S"); }else if("6".equalsIgnoreCase(msgType)) { mjonMsgVO.setMsgDiv("L"); } else { // invalid returnVO.setMsgGroupId(""); returnVO.setSendMsgCnt("0"); // 발송 건수 저장 returnVO.setSendMsgBlockCnt("0"); // 수신차단 건수 저장 return returnVO; } // 문자타입별 대표전송사 정보 MjonMsgVO mjonMsgVO2 = new MjonMsgVO(); mjonMsgVO2 = mjonMsgDAO.selectRepMsgAgetnInfo(mjonMsgVO); // 전송사 구분 코드 - 01 : 아이하트, 02 : 현대 퓨쳐넷, 03 : 아이엠오, 04 : 다우기술 mjonMsgVO.setAgentCode(mjonMsgVO2.getAgentCode()); //전송사 선택 // 전송금액 mjonMsgVO.setTotPrice(mjonMsgVO2.getAgentPrice().toString()); //총금액 mjonMsgVO.setEachPrice(mjonMsgVO2.getAgentPrice().toString()); //한건 금액 returnVO = mjonMsgDataService.insertSysMsgDataInfo(mjonMsgVO); // 시스템 발송 로그 SendLogVO sendLogVO = new SendLogVO(); // SendType 1:문자로 발송 2:이메일로 발송 sendLogVO.setSendId(returnVO.getMsgGroupId()); sendLogVO.setSendType("1"); sendLogVO.setFrstSendInfo(mjonMsgVO.getCallFrom()); sendLogVO.setReceive(mjonMsgVO.getCallTo()); sendLogVO.setContents(contents); sendLogVO.setSendMsgType(sendMsgType); mjonMsgDataService.insertSysMsgLog(sendLogVO); return returnVO; } private Boolean sysMsgTodaySendYn(String callTo) throws Exception { SendLogVO sendLogVO = new SendLogVO(); sendLogVO.setReceive(callTo); return mjonMsgDataService.selectSysMsgTodaySendYn(sendLogVO); } private String selectSmsNotiIfOverFiftySetting() throws Exception { JoinSettingVO joinSettingVO = egovSiteManagerService.selectAdminNotiDetail(); return joinSettingVO.getSmsNotiIfOverFifty(); } }