From f44acfe2c4e96b645ed3324c7d87d75aa787fe80 Mon Sep 17 00:00:00 2001 From: "hehihoho3@gmail.com" Date: Wed, 27 Nov 2024 16:15:30 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=A0=84=EC=86=A1=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + .../com/idgen/CustomIdGnrService.java | 10 + .../impl/CustomTableIdGnrServiceImpl.java | 196 ++++++++ .../java/itn/com/cmm/OptimalMsgResultDTO.java | 37 ++ src/main/java/itn/com/cmm/util/MJUtil.java | 1 - .../java/itn/com/cmm/util/MsgSendUtils.java | 460 ++++++++++++++---- .../msgdata/service/impl/MjonMsgDataDAO.java | 8 + .../service/impl/MjonMsgDataServiceImpl.java | 276 +++++++---- .../msgdata/web/MjonMsgDataController.java | 5 +- .../itn/let/module/base/PriceAndPoint.java | 12 +- .../spring/com/context-idgen.xml | 25 + .../sqlmap/let/msg/MjonMsgData_SQL_mysql.xml | 33 +- .../jsp/web/msgdata/MsgDataSMLView.jsp | 3 +- .../WEB-INF/jsp/web/msgdata/MsgDataView.jsp | 14 +- src/main/webapp/js/txtSpecialReplace.js | 65 ++- 15 files changed, 924 insertions(+), 222 deletions(-) create mode 100644 src/main/java/egovframework/com/idgen/CustomIdGnrService.java create mode 100644 src/main/java/egovframework/com/idgen/impl/CustomTableIdGnrServiceImpl.java create mode 100644 src/main/java/itn/com/cmm/OptimalMsgResultDTO.java diff --git a/pom.xml b/pom.xml index d5f9bfb7..5878c03c 100644 --- a/pom.xml +++ b/pom.xml @@ -111,6 +111,7 @@ egovframework.rte egovframework.rte.fdl.idgnr ${egovframework.rte.version} + egovframework.rte diff --git a/src/main/java/egovframework/com/idgen/CustomIdGnrService.java b/src/main/java/egovframework/com/idgen/CustomIdGnrService.java new file mode 100644 index 00000000..481ff4d0 --- /dev/null +++ b/src/main/java/egovframework/com/idgen/CustomIdGnrService.java @@ -0,0 +1,10 @@ +package egovframework.com.idgen; + +import java.util.List; + +import egovframework.rte.fdl.cmmn.exception.FdlException; +import egovframework.rte.fdl.idgnr.EgovIdGnrService; + +public interface CustomIdGnrService extends EgovIdGnrService { + List getNextStringId(int count) throws FdlException; +} diff --git a/src/main/java/egovframework/com/idgen/impl/CustomTableIdGnrServiceImpl.java b/src/main/java/egovframework/com/idgen/impl/CustomTableIdGnrServiceImpl.java new file mode 100644 index 00000000..ceafd41f --- /dev/null +++ b/src/main/java/egovframework/com/idgen/impl/CustomTableIdGnrServiceImpl.java @@ -0,0 +1,196 @@ +package egovframework.com.idgen.impl; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; // java.sql.PreparedStatement로 임포트 +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.sql.DataSource; + +import org.springframework.jdbc.datasource.DataSourceUtils; + +import egovframework.com.idgen.CustomIdGnrService; +import egovframework.rte.fdl.cmmn.exception.FdlException; +import egovframework.rte.fdl.idgnr.EgovIdGnrStrategy; + +public class CustomTableIdGnrServiceImpl implements CustomIdGnrService { + + private long allocatedId; + private long allocatedMaxId; + private int blockSize = 10; // 기본값, 필요에 따라 변경 + private DataSource dataSource; + private String table; // 실제 테이블 이름 (예: IDS) + private String tableName; // TABLE_NAME 컬럼에서 사용할 값 (예: MSG_ID) + private String columnName = "NEXT_ID"; // NEXT_ID 컬럼명 + private String prefix; + private String fillChar = "0"; // 채울 문자 (예: 0) + private int cipers = 14; // 자리수 (예: 14) + private boolean applyYear; + private boolean useBigDecimals = false; + + @Override + public synchronized List getNextStringId(int count) throws FdlException { + List idList = new ArrayList<>(count); + try { + for (int i = 0; i < count; i++) { + if (allocatedId >= allocatedMaxId) { + allocateIdBlock(count); + } + long id = allocatedId++; + idList.add(createStringId(id)); + } + } catch (Exception e) { + throw new FdlException("ID Generation Error", e); + } + return idList; + } + + private void allocateIdBlock(int requiredCount) throws SQLException, FdlException { + Connection conn = DataSourceUtils.getConnection(dataSource); + try { + conn.setAutoCommit(false); + + int newBlockSize = Math.max(this.blockSize, requiredCount); + + // SELECT 쿼리 수정 + String query = "SELECT " + columnName + " FROM " + table + " WHERE TABLE_NAME = ? FOR UPDATE"; + try (PreparedStatement stmt = conn.prepareStatement(query)) { + stmt.setString(1, tableName); + try (ResultSet rs = stmt.executeQuery()) { + long oldId = 0; + if (rs.next()) { + oldId = rs.getLong(1); + } else { + throw new FdlException( + "ID Generation Error: No record found in " + table + " for TABLE_NAME = " + tableName); + } + + long newId = oldId + newBlockSize; + + // UPDATE 쿼리 수정 + String update = "UPDATE " + table + " SET " + columnName + " = ? WHERE TABLE_NAME = ? AND " + + columnName + " = ?"; + try (PreparedStatement updateStmt = conn.prepareStatement(update)) { + updateStmt.setLong(1, newId); + updateStmt.setString(2, tableName); + updateStmt.setLong(3, oldId); + int row = updateStmt.executeUpdate(); + + if (row == 0) { + throw new FdlException( + "ID Generation Error: Failed to update ID. Possible concurrent modification."); + } + } + + conn.commit(); + + allocatedId = oldId; + allocatedMaxId = newId; + } + } catch (SQLException e) { + conn.rollback(); + throw e; + } + } catch (SQLException e) { + throw new FdlException("ID Generation Error", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + } + + private String createStringId(long id) { + StringBuilder sb = new StringBuilder(); + if (prefix != null) { + sb.append(prefix); + } + if (applyYear) { + sb.append(new SimpleDateFormat("yyyy").format(new Date())); + } + String idStr = String.format("%0" + cipers + "d", id); + sb.append(idStr); + return sb.toString(); + } + + // 인터페이스의 다른 메서드 구현 (필요에 따라 UnsupportedOperationException 또는 직접 구현) + @Override + public BigDecimal getNextBigDecimalId() throws FdlException { + throw new UnsupportedOperationException("getNextBigDecimalId is not supported"); + } + + @Override + public long getNextLongId() throws FdlException { + throw new UnsupportedOperationException("getNextLongId is not supported"); + } + + @Override + public int getNextIntegerId() throws FdlException { + throw new UnsupportedOperationException("getNextIntegerId is not supported"); + } + + @Override + public short getNextShortId() throws FdlException { + throw new UnsupportedOperationException("getNextShortId is not supported"); + } + + @Override + public byte getNextByteId() throws FdlException { + throw new UnsupportedOperationException("getNextByteId is not supported"); + } + + @Override + public String getNextStringId() throws FdlException { + throw new UnsupportedOperationException("getNextStringId is not supported"); + } + + @Override + public String getNextStringId(String strategyId) throws FdlException { + throw new UnsupportedOperationException("getNextStringId(String strategyId) is not supported"); + } + + @Override + public String getNextStringId(EgovIdGnrStrategy strategy) throws FdlException { + throw new UnsupportedOperationException("getNextStringId(EgovIdGnrStrategy strategy) is not supported"); + } + + // 필요한 setter 메서드들 추가 + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + public void setTable(String table) { + this.table = table; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public void setFillChar(String fillChar) { + this.fillChar = fillChar; + } + + public void setCipers(int cipers) { + this.cipers = cipers; + } + + public void setApplyYear(boolean applyYear) { + this.applyYear = applyYear; + } + + public void setBlockSize(int blockSize) { + this.blockSize = blockSize; + } +} diff --git a/src/main/java/itn/com/cmm/OptimalMsgResultDTO.java b/src/main/java/itn/com/cmm/OptimalMsgResultDTO.java new file mode 100644 index 00000000..f613e995 --- /dev/null +++ b/src/main/java/itn/com/cmm/OptimalMsgResultDTO.java @@ -0,0 +1,37 @@ +package itn.com.cmm; + +import java.util.List; + +import itn.let.mjo.event.service.MjonEventVO; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * + * @author : 이호영 + * @fileName : OptimalMsgResultDTO.java + * @date : 2024.11.26 + * @description : 이벤트 vo 생성 및 종료 vo 생성 + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- * + * 2024.11.26 이호영 최초 생성 + * + * + * + */ +@Getter +@Setter +@ToString +@Builder +public class OptimalMsgResultDTO{ + + private List optimalMsgList; + private MjonEventVO eventInfo; + + + + +} diff --git a/src/main/java/itn/com/cmm/util/MJUtil.java b/src/main/java/itn/com/cmm/util/MJUtil.java index 78e20953..a0dc9411 100644 --- a/src/main/java/itn/com/cmm/util/MJUtil.java +++ b/src/main/java/itn/com/cmm/util/MJUtil.java @@ -144,7 +144,6 @@ public final class MJUtil { date = date.replaceAll("-", "/");//날짜에 하이픈(-)을 슬러쉬(/)로 변환 SimpleDateFormat sdformat = new SimpleDateFormat("yyyy/MM/dd"); - System.out.println(getRealTime()); Date nowDate = sdformat.parse(getRealTime()); Date endDate = sdformat.parse(date); diff --git a/src/main/java/itn/com/cmm/util/MsgSendUtils.java b/src/main/java/itn/com/cmm/util/MsgSendUtils.java index 3f3c33fd..ee5f1891 100644 --- a/src/main/java/itn/com/cmm/util/MsgSendUtils.java +++ b/src/main/java/itn/com/cmm/util/MsgSendUtils.java @@ -1,10 +1,9 @@ package itn.com.cmm.util; import java.io.UnsupportedEncodingException; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -18,14 +17,15 @@ import java.util.regex.Pattern; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import itn.com.cmm.MjonMsgSendVO; +import itn.com.cmm.OptimalMsgResultDTO; import itn.let.mail.service.StatusResponse; +import itn.let.mjo.event.service.MjonEventVO; import itn.let.mjo.msg.service.MjonMsgVO; +import itn.let.mjo.msgagent.service.MjonMsgAgentStsVO; import itn.let.mjo.spammsg.web.ComGetSpamStringParser; -import itn.let.module.base.PriceAndPoint; import itn.let.sym.site.service.JoinSettingVO; import itn.let.uss.umt.service.MberManageVO; import lombok.extern.slf4j.Slf4j; @@ -47,6 +47,12 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public final class MsgSendUtils { + // 단문 메세지 타입 + public static final String SHORT_MSG_TYPE = "4"; + // 장문 메세지 타입 + public static final String LONG_MSG_TYPE = "6"; + // 이벤트 최저 잔액 + public static final double MIN_EVENT_REMAIN_CASH = 7.5; // 이벤트 최소 잔액 /** * @methodName : getSmsTxtBytes @@ -81,28 +87,30 @@ public final class MsgSendUtils { */ public static String getMsgTypeWithByteValidation(MjonMsgSendVO sendVO, String p_smsTxt) throws UnsupportedEncodingException { - + + // // 내문자저장함에 저장 후 문자를 발송하는 경우 문자 타입이 숫자가 아닌 문자로 넘어와서 변경 처리함 + // if ("P".equals(msgType) || "L".equals(msgType)) { + // msgType = "6"; + // } else if ("S".equals(msgType)) { + // msgType = "4"; + // } + int smsTxtByte = getSmsTxtBytes(p_smsTxt); - String msgType = "4"; + String msgType = SHORT_MSG_TYPE; - // // 내문자저장함에 저장 후 문자를 발송하는 경우 문자 타입이 숫자가 아닌 문자로 넘어와서 변경 처리함 - // if ("P".equals(msgType) || "L".equals(msgType)) { - // msgType = "6"; - // } else if ("S".equals(msgType)) { - // msgType = "4"; - // } - - // 그림 이미지가 첨부된 경우 장문으로 설정 - if (StringUtils.isNotEmpty(sendVO.getFilePath1())) { - msgType = "6"; - } else if (smsTxtByte > 2000) { - // 2000 Byte를 초과할 경우 에러 처리 (이 부분은 호출부에서 검사하도록 유지할 수도 있음) - return "INVALID"; // 이 값은 호출부에서 에러 처리를 하도록 활용할 수 있습니다. - } else if (smsTxtByte > 90) { - // 90Byte 초과 시 장문으로 설정 - msgType = "6"; + // 1. 2000 Byte 초과는 에러 처리 + if (smsTxtByte > 2000) { + return "INVALID"; } + // 2. 첨부파일 여부 확인 (첨부파일이 있으면 장문으로 설정) + if (StringUtils.isNotEmpty(sendVO.getFilePath1())) { + msgType = LONG_MSG_TYPE; + } + // 3. 문자 길이에 따라 메시지 타입 설정 (90 Byte 초과는 장문) + else if (smsTxtByte > 90) { + msgType = LONG_MSG_TYPE; + } return msgType; } @@ -129,9 +137,9 @@ public final class MsgSendUtils { float price = 0; String msgType = mjonMsgVO.getMsgType(); - if ("4".equals(msgType)) { + if (SHORT_MSG_TYPE.equals(msgType)) { price = shortPrice; - } else if ("6".equals(msgType)) { + } else if (LONG_MSG_TYPE.equals(msgType)) { // 파일 첨부 여부에 따라 장문 단가 설정 if (mjonMsgVO.getFileName3() != null) { price = picture3Price; @@ -181,19 +189,18 @@ public final class MsgSendUtils { * @param mjonMsgVO * @param lists * @param statusResponse + * @param agentSendCounts + * @param sendRateList * @return * @throws Exception */ - public static Boolean populateSendLists(MjonMsgVO mjonMsgVO, List mjonMsgSendListVO, StatusResponse statusResponse, List resultSpamTxt) throws Exception{ + public static Boolean populateSendLists(MjonMsgVO mjonMsgVO, List mjonMsgSendListVO + , StatusResponse statusResponse, List resultSpamTxt + , Map agentSendCounts, List sendRateList, String nextMsgGroupId) throws Exception{ log.info(" :: populateSendLists :: "); - log.info(" + 예약여부 [{}]", mjonMsgVO.getReserveYn()); // 예약 여부 - log.info(" + 시간 [{}]", mjonMsgVO.getReqDate()); // 시간 - log.info(" + 분할체크 [{}]", mjonMsgVO.getDivideChk()); // 분할체크 - log.info(" + 간격(분) [{}]", mjonMsgVO.getDivideTime()); // 간격 - log.info(" + 몇 건씩 [{}]", mjonMsgVO.getDivideCnt()); // 몇 건식 // 예약 시간 기본값 설정 @@ -230,12 +237,17 @@ public final class MsgSendUtils { boolean hasPerformedSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어 boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어 + String msgKind = mjonMsgVO.getMsgKind(); String smsTxtTemp = mjonMsgVO.getSmsTxt(); Boolean replaceYN = getReplaceYN(smsTxtTemp); String msgTypeResult = null; for (MjonMsgSendVO sendVO : mjonMsgSendListVO) { + + sendVO.setCallFrom(mjonMsgVO.getCallFrom()); + sendVO.setCallTo(sendVO.getPhone()); + sendVO.setUserId(mjonMsgVO.getUserId()); String smsTxt = smsTxtTemp; // 치환 문자면 @@ -255,47 +267,52 @@ public final class MsgSendUtils { } } - String smsSpamChkTxt = mjonMsgVO.getSmsTxt().replaceAll(String.valueOf((char) 13), ""); - // 스팸문자 체크 - // 치환문자가 아닐 경우 - if (!replaceYN && !hasPerformedSpamCheck) { - checkSpamAndSetStatus(mjonMsgVO, smsSpamChkTxt, resultSpamTxt); - hasPerformedSpamCheck = true; // 스팸 체크가 한 번만 수행되도록 설정 - // 치환 문자가 있는 경우에는 spamChkSize 카운트까지만 수행 - } else if (replaceYN && sampleCounter < spamChkSize && !"Y".equals(mjonMsgVO.getSpamStatus())) { - checkSpamAndSetStatus(mjonMsgVO, smsSpamChkTxt, resultSpamTxt); - sampleCounter++; + String smsSpamChkTxt = smsTxt.replaceAll(String.valueOf((char) 13), ""); + + // == 치환 여부에 따라 처리 로직 분기 == + // 치환 문자가 아닌 경우 + if (!replaceYN) { + // 스팸 체크와 메시지 타입 체크 각각 한 번만 수행 + if (!hasPerformedSpamCheck) { + checkSpamAndSetStatus(mjonMsgVO, smsSpamChkTxt, resultSpamTxt); + hasPerformedSpamCheck = true; + } + if (!hasPerformedMsgType) { + msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); + if ("INVALID".equals(msgTypeResult)) { + statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); + return false; + } + hasPerformedMsgType = true; + } + } + else + {// 치환 문자인 경우 + // 스팸 체크는 `spamChkSize`만큼 반복 수행 + if (sampleCounter < spamChkSize && !"Y".equals(mjonMsgVO.getSpamStatus())) { + checkSpamAndSetStatus(mjonMsgVO, smsSpamChkTxt, resultSpamTxt); + sampleCounter++; + } + + // 메시지 타입 체크는 매번 수행 + msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); + if ("INVALID".equals(msgTypeResult)) { + statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); + return false; + } } + + sendVO.setSmsTxt(smsTxt); - - // 이미지 셋팅 - setImagePathsForMsgSendVO(mjonMsgVO, sendVO); - - - // msgType 셋팅 및 문자열 체크 - if (!replaceYN && !hasPerformedMsgType) { - log.info(" 치환 X "); - // byte 체크와 msgType 구하기 - msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); - if ("INVALID".equals(msgTypeResult)) { - statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); - return false; - } - hasPerformedMsgType = true; // 스팸 체크가 한 번만 수행되도록 설정 - }else if(replaceYN){ - log.info(" 치환 O "); - // byte 체크와 msgType 구하기 - msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); - if ("INVALID".equals(msgTypeResult)) { - statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); - return false; - } - } - sendVO.setMsgType(msgTypeResult); + // 제목 셋팅 + + // 이미지 셋팅 + setImagePathsForMsgSendVO(mjonMsgVO, sendVO); + // 예약 여부 확인 if ("Y".equalsIgnoreCase(mjonMsgVO.getReserveYn())) { @@ -315,6 +332,16 @@ public final class MsgSendUtils { } + // 전송사 코드 셋팅 + String agentCode = "00".equals(mjonMsgVO.getAgentCode()) + ? MsgSendUtils.assignAgentBasedOnCount(agentSendCounts, sendRateList) + : mjonMsgVO.getAgentCode(); + sendVO.setAgentCode(agentCode); + + sendVO.setMsgGroupId(nextMsgGroupId); + + + @@ -324,6 +351,14 @@ public final class MsgSendUtils { } + /** + * @methodName : setImagePathsForMsgSendVO + * @author : 이호영 + * @date : 2024.11.26 + * @description : vo에 이미지 셋팅 + * @param mjonMsgVO + * @param sendVO + */ private static void setImagePathsForMsgSendVO(MjonMsgVO mjonMsgVO, MjonMsgSendVO sendVO) { int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt()); @@ -493,6 +528,7 @@ public final class MsgSendUtils { float picture2Price = MsgSendUtils.getValidPrice(mberManageVO.getPicture2Price(), sysJoinSetVO.getPicture2Price()); float picture3Price = MsgSendUtils.getValidPrice(mberManageVO.getPicture3Price(), sysJoinSetVO.getPicture3Price()); + // 각 메시지 타입에 따라 사용자 단가 설정 및 총 단가 계산 float totalPrice = 0.0f; @@ -501,18 +537,17 @@ public final class MsgSendUtils { String eachPrice; switch (msgType) { - case "4": // 단문 메시지 타입 + case SHORT_MSG_TYPE: // 단문 메시지 타입 eachPrice = Float.toString(shortPrice); break; - case "6": // 장문 또는 이미지 메시지 타입 + case LONG_MSG_TYPE: // 장문 또는 이미지 메시지 타입 eachPrice = getPicturePrice(sendVO, longPrice, picturePrice, picture2Price, picture3Price); break; default: // 기본값이 필요하다면 추가 가능 - eachPrice = "0"; - break; + throw new IllegalArgumentException("setPriceforVO :: type Exception "); } sendVO.setEachPrice(eachPrice); @@ -531,46 +566,271 @@ public final class MsgSendUtils { * 이미지 파일 경로를 기준으로 적절한 가격을 반환하는 헬퍼 메소드. */ private static String getPicturePrice(MjonMsgSendVO sendVO, float longPrice, float picturePrice, float picture2Price, float picture3Price) { - if (StringUtils.isNotEmpty(sendVO.getFilePath3())) { + + switch (sendVO.getFilePath3() != null ? "FILE3" : + sendVO.getFilePath2() != null ? "FILE2" : + sendVO.getFilePath1() != null ? "FILE1" : "NONE") { + case "FILE3": return Float.toString(picture3Price); - } else if (StringUtils.isNotEmpty(sendVO.getFilePath2())) { + case "FILE2": return Float.toString(picture2Price); - } else if (StringUtils.isNotEmpty(sendVO.getFilePath1())) { + case "FILE1": return Float.toString(picturePrice); - } else { + default: return Float.toString(longPrice); } + + } + + /** + * @methodName : getOptimalMsgList + * @author : 이호영 + * @date : 2024.11.26 + * @description : 주어진 이벤트 정보와 메시지 리스트를 기반으로, 잔액 내에서 최적의 메시지 리스트를 생성하고 결과를 반환합니다. + * 만약 잔액이 부족하거나 이벤트가 종료된 상태라면, 이벤트 종료 정보를 포함하여 반환합니다. + * + * @param eventMberInfo 이벤트 정보 객체 (MjonEventVO). 이벤트 상태 및 잔액 정보를 포함. + * @param mjonMsgSendVOList 최적화를 수행할 메시지 리스트 (List). + * @return OptimalMsgResultDTO 최적 메시지 리스트와 이벤트 상태 정보를 포함한 DTO 객체. + * @throws Exception 메시지 단가 계산 오류 또는 기타 처리 중 발생한 예외를 상위로 전달. + */ + public static OptimalMsgResultDTO getOptimalMsgList( + MjonEventVO eventMberInfo, + List mjonMsgSendVOList) throws Exception { + + // 최적의 메시지 리스트를 담을 리스트 + List optimalList = new ArrayList<>(); + + // 이벤트 정보가 없는 경우 + if (eventMberInfo == null) { + return OptimalMsgResultDTO.builder() + .optimalMsgList(optimalList) + .eventInfo(null) + .build(); + } + + // 이벤트 잔액과 종료 조건 확인 + double targetCash = eventMberInfo.getEventRemainCash(); + String eventEndDate = eventMberInfo.getEventEndDate(); + + if (isEventExpired(targetCash, eventEndDate)) { + MjonEventVO returnEventMberInfo = terminateEvent(eventMberInfo, targetCash); + return OptimalMsgResultDTO.builder() + .optimalMsgList(optimalList) + .eventInfo(returnEventMberInfo) + .build(); + } + + // 단가 설정 + float shortPrice = Float.parseFloat(eventMberInfo.getEventShortPrice()); + float longPrice = Float.parseFloat(eventMberInfo.getEventLongPrice()); + float picturePrice = Float.parseFloat(eventMberInfo.getEventPicturePrice()); + float picture2Price = Float.parseFloat(eventMberInfo.getEventPicture2Price()); + float picture3Price = Float.parseFloat(eventMberInfo.getEventPicture3Price()); + + // 최적의 메시지 리스트 생성 + double sum = 0.0; + Iterator iterator = mjonMsgSendVOList.iterator(); + + while (iterator.hasNext()) { + MjonMsgSendVO msg = iterator.next(); + + // 단가 계산 및 예외 처리 + String eachPrice = getEachPriceOrThrow(msg, shortPrice, longPrice, picturePrice, picture2Price, picture3Price); + + float floatEachPrice = Float.parseFloat(eachPrice); + + // 최적의 메시지 리스트에 추가 + if (sum + floatEachPrice <= targetCash) { + sum += floatEachPrice; + msg.setEachPrice(eachPrice); + optimalList.add(msg); + iterator.remove(); + } else { + break; // 예산 초과로 추가 불가능 + } + } + + // 잔액 부족 시 이벤트 종료 처리하는 VO 생성 + double remainAmt = targetCash - sum; + log.info("remainAmt :: [{}]", remainAmt); + if (remainAmt < MIN_EVENT_REMAIN_CASH) { + MjonEventVO returnEventMberInfo = terminateEvent(eventMberInfo, remainAmt); + return OptimalMsgResultDTO.builder() + .optimalMsgList(optimalList) + .eventInfo(returnEventMberInfo) + .build(); + } + + // 결과 반환 + return OptimalMsgResultDTO.builder() + .optimalMsgList(optimalList) + .eventInfo(null) + .build(); + } + + /** + * @methodName : getEachPriceOrThrow + * @author : 이호영 + * @date : 2024.11.26 + * @description : + * @param msg + * @param shortPrice + * @param longPrice + * @param picturePrice + * @param picture2Price + * @param picture3Price + * @return + */ + private static String getEachPriceOrThrow( + MjonMsgSendVO msg, + float shortPrice, + float longPrice, + float picturePrice, + float picture2Price, + float picture3Price) { + + switch (msg.getMsgType()) { + case SHORT_MSG_TYPE: + return Float.toString(shortPrice); + case LONG_MSG_TYPE: + return getPicturePrice(msg, longPrice, picturePrice, picture2Price, picture3Price); + default: + throw new IllegalArgumentException("Unsupported message type: " + msg.getMsgType()); + } } - public static List getOptimalMsgList(double totalPrice, double eventRemainCash, - List mjonMsgSendVOList) { - - double targetCash = eventRemainCash; - - // 최적의 리스트를 구성하기 위한 빈 리스트 생성 - List optimalList = new ArrayList<>(); - double sum = 0.0; + private static boolean isEventExpired(double targetCash, String eventEndDate) throws Exception { + return !MJUtil.getCompareDate(eventEndDate) || targetCash < MIN_EVENT_REMAIN_CASH; + } - // 원본 리스트의 요소를 순회하며 조건에 맞는 항목을 최적 리스트에 추가 - Iterator iterator = mjonMsgSendVOList.iterator(); - while (iterator.hasNext()) { - MjonMsgSendVO msg = iterator.next(); - double eachPrice = Double.parseDouble(msg.getEachPrice()); - - // sum + eachPrice가 정확히 targetCash와 같거나 작을 때만 추가하고 원본에서 제거 - if (sum + eachPrice <= targetCash) { - sum += eachPrice; - optimalList.add(msg); - iterator.remove(); // 원본 리스트에서 해당 요소 제거 - } else { - break; // 초과하지 않도록, 더 이상 추가할 수 없는 경우 종료 + /** + * @methodName : terminateEvent + * @author : 이호영 + * @date : 2024.11.26 + * @description : 이벤트 종료 VO 생성 + * @param eventMberInfo + * @param targetCash + * @return + */ + private static MjonEventVO terminateEvent(MjonEventVO eventMberInfo, double targetCash) { + // TODO Auto-generated method stub + + // 이벤트 상태를 종료로 변경 + MjonEventVO returnEventMberInfo = new MjonEventVO(); + returnEventMberInfo.setEventInfoId(eventMberInfo.getEventInfoId()); + returnEventMberInfo.setEventStatus("E"); + returnEventMberInfo.setEventRemainCash(targetCash); + returnEventMberInfo.setEventMemo("발송 최소 금액("+ MIN_EVENT_REMAIN_CASH +") 부족 혹은 이벤트 종료일 초과되어 이벤트 종료 시킴"); + return returnEventMberInfo; + } + + /** + * @methodName : handleHotlineAgentRate + * @author : 이호영 + * @date : 2024.11.26 + * @description : 전용 전송사 비율이 0이면 대표 전송사로 수정 + * @param userInfo + * @param tmp + * @param hotlineAgentCode + * @return + */ + public static String handleHotlineAgentRate(MberManageVO userInfo, MjonMsgAgentStsVO tmp, String hotlineAgentCode) { + String sendRate = tmp.getSendRate(); + String repAgent = tmp.getRepAgent(); + String useYn = tmp.getUseYn(); + + // 블라인드 코드가 'N'인 경우 전송 비율 및 사용 가능 여부 확인 + if ("N".equals(userInfo.getBlineCode())) { + // 전송 비율이 0이거나 사용 불가인 경우 대표 전송사로 변경 + if ("0".equals(sendRate) || "N".equals(useYn)) { + hotlineAgentCode = repAgent; } } - log.info(" + targetCash :: [{}]", targetCash); - log.info(" + sum :: [{}]", sum); - - // 최적 리스트 반환 - return optimalList; - + + return hotlineAgentCode; // 변경된 hotlineAgentCode 반환 } + + + /** + * @methodName : initializeAgentSendCounts + * @author : 이호영 + * @date : 2024.11.26 + * @description : 전송사별 코드로 map 초기화 하기 + * @return + */ + public static Map initializeAgentSendCounts() { + Map agentSendCounts = new HashMap<>(); + agentSendCounts.put("01", 0); // 아이하트 + agentSendCounts.put("02", 0); // 현대 퓨쳐넷 + agentSendCounts.put("03", 0); // 아이엠오 + agentSendCounts.put("04", 0); // 비즈뿌리오 + agentSendCounts.put("05", 0); // 제이제이 + agentSendCounts.put("07", 0); // 인비토 + return agentSendCounts; + } + + + /** + * @methodName : calculateSendCounts + * @author : 이호영 + * @date : 2024.11.26 + * @description : agentSendCounts에 있는 에이젼트 map에 전송사 비율에 따라 카운트 put 하기 + * @param agentSendCounts + * @param sendRate + * @param finalSize + */ + public static void calculateSendCounts(Map agentSendCounts, MjonMsgVO sendRate, int finalSize) { + String agentCode = sendRate.getAgentCode(); + float sendRatePercentage = Float.parseFloat(sendRate.getSendRate()); + + int sendCount = Math.round(finalSize * sendRatePercentage); + + if (agentSendCounts.containsKey(agentCode)) { + agentSendCounts.put(agentCode, sendCount); + } + } + + /** + * @methodName : assignAgentBasedOnCount + * @author : 이호영 + * @date : 2024.11.26 + * @description : initializeAgentSendCounts()에서 만든 map으로 발송 agent 데이터 Set + * @param agentSendCounts + * @param sendRateList + * @return + */ + public static String assignAgentBasedOnCount(Map agentSendCounts, List sendRateList) { + // 전송사 코드 순서대로 확인 :: initializeAgentSendCounts 메소드와 맞춰야함 + List agentCodes = Arrays.asList("01", "02", "03", "04", "05", "07"); + + // 전송 가능한 코드 찾기 + for (String agentCode : agentCodes) { + if (agentSendCounts.get(agentCode) > 0) { + agentSendCounts.put(agentCode, agentSendCounts.get(agentCode) - 1); + return agentCode; + } + } + + // 모든 코드의 전송 가능 횟수가 0이면 대표 전송사로 할당 + return sendRateList.get(0).getRepAgent(); + } + + + + + + + + + + + + + + + + + + } diff --git a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java index 93966423..8449df12 100644 --- a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java +++ b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java @@ -5,6 +5,7 @@ import java.util.List; import org.springframework.stereotype.Repository; import egovframework.rte.psl.dataaccess.EgovAbstractDAO; +import itn.com.cmm.MjonMsgSendVO; import itn.let.lett.service.LetterVO; import itn.let.mjo.addr.service.AddrVO; import itn.let.mjo.msg.service.MjonMsgVO; @@ -371,5 +372,12 @@ public class MjonMsgDataDAO extends EgovAbstractDAO { public List selectPayUserSumFaxList(MjonMsgVO mjonMsgVO) throws Exception{ return (List) list("mjonMsgDAO.selectPayUserSumFaxList",mjonMsgVO); } + + + public int insertMsgDataInfo_advc(List mjonMsgSendVOList) { + //단문 전송 + int result = update("mjonMsgDAO.insertMsgData_advc", mjonMsgSendVOList); + return result; + } } diff --git a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java index 070cfe7b..50867dc6 100644 --- a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java +++ b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java @@ -22,12 +22,15 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.servlet.ModelAndView; +import egovframework.com.idgen.CustomIdGnrService; import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl; +import egovframework.rte.fdl.cmmn.exception.FdlException; import egovframework.rte.fdl.idgnr.EgovIdGnrService; import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper; import egovframework.rte.psl.dataaccess.util.EgovMap; import itn.com.cmm.LoginVO; import itn.com.cmm.MjonMsgSendVO; +import itn.com.cmm.OptimalMsgResultDTO; import itn.com.cmm.util.MJUtil; import itn.com.cmm.util.MsgSendUtils; import itn.com.cmm.util.StringUtil; @@ -95,6 +98,9 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M @Resource(name = "egovMjonMsgIdGnrService") private EgovIdGnrService idgenMsgId; + + @Resource(name = "egovMjonMsgIdCGnrService") + private CustomIdGnrService idgenMsgCId; @Resource(name = "egovMjonMsgGroupIdGnrService") private EgovIdGnrService idgenMjonMsgGroupId; @@ -4033,86 +4039,7 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M return statusResponse; } - log.debug(" + mjonMsgVO.getFileCnt() :: [{}]", mjonMsgVO.getFileCnt()); - - - /* - * 화면에서 넘어오는 단가 금액 및 총 결제 캐시 금액 체크 해주기 - * 검증을 위해서 시스템 단가, 회원 협의 단가, 이벤트 단가 정보 조회 - * 조회 단가를 이용하여 총 결제 캐시 금액 계산 - * 파라미터로 넘어온 개별단가(eachPrice), 총 결제캐시(totPrice)를 비요하여 동일하지 않으면 컨트롤러에서 계산한 금액으로 입력해줌. - */ - - - ///////////////////////////////////////////////////////////////////////////// - // 금액 관련은 끝에서 이벤트 발송 / 기존금액 박송으로 나눠야하기 때문에 나중에 수정 - ///////////////////////////////////////////////////////////////////////////// - /* - - - // 기존 소수점 2째자리에서 반올림하였으나, 정책 변경으로 소수점 버림 처리함 -// boolean compareEndDate = false; - float paramEachPrice = Float.parseFloat(mjonMsgVO.getEachPrice()); - - - - MjonEventVO mjonEventVO = new MjonEventVO(); - mjonEventVO.setMberId(userId); - - MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO); - // 호출부에서 handleEventStatus를 호출하고 예외 처리를 추가 - - // 기존 컨트롤러 2352 라인 - if (eventMberInfo != null) { - String eventEndDate = eventMberInfo.getEventEndDate(); - boolean compareEndDate = MJUtil.getCompareDate(eventEndDate); - boolean isSuccess = handleEventStatus(eventMberInfo, paramEachPrice, mjonEventVO, compareEndDate); - - if (!isSuccess) { - // 예외가 발생했을 때의 리턴 처리 - return new StatusResponse(HttpStatus.INTERNAL_SERVER_ERROR, "이벤트 상태 처리 중 오류가 발생했습니다."); - } - // 이벤트 진행 회원의 발송 단가 처리 - if("Y".equals(eventMberInfo.getEventStatus()) && compareEndDate) { - shortPrice = Float.parseFloat(eventMberInfo.getEventShortPrice()); - longPrice = Float.parseFloat(eventMberInfo.getEventLongPrice()); - picturePrice = Float.parseFloat(eventMberInfo.getEventPicturePrice()); - picture2Price = Float.parseFloat(eventMberInfo.getEventPicture2Price()); - picture3Price = Float.parseFloat(eventMberInfo.getEventPicture3Price()); - } - } - - - - - - // 토탈금액 "," 리플레이스 처리 - mjonMsgVO.setTotPrice(mjonMsgVO.getTotPrice().replaceAll(",", "")); - - // 각 문자 종류별 단가 설정 - float tmpEachPrice = MsgSendUtils.determinePriceByMsgType(mjonMsgVO, shortPrice, longPrice, picturePrice, picture2Price, picture3Price); - mjonMsgVO.setEachPrice(Float.toString(tmpEachPrice)); - - // 수신자 총 수 * 단가를 통해 총 결제 금액 계산 - int tmpTotCallCnt = mjonMsgVO.getCallToList().length; - float tmpTotPrice = tmpTotCallCnt * tmpEachPrice; - mjonMsgVO.setTotPrice(Float.toString(tmpTotPrice)); -*/ - ///////////////////////////////////////////////////////////////////////////// - // 금액 관련은 끝에서 이벤트 발송 / 기존금액 박송으로 나눠야하기 때문에 나중에 수정 - ///////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////// - // 치환 여부 - //////////////////////////////////////////////// List mjonMsgSendVOList = mjonMsgVO.getMjonMsgSendVOList(); -// if (MsgSendUtils.isRepleasYN(mjonMsgVO)) { - -// if (!MsgSendUtils.validateReplacementData(mjonMsgVO, mjonMsgTabulVO)) { -// //특정문구 일괄변환 치환문자 데이터가 없습니다. -// return statusResponse; // 유효성 검사 실패 시 처리 -// } // 삭제 전 리스트 크기 저장 @@ -4126,40 +4053,53 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M int finalSize = mjonMsgSendVOList.size(); // 삭제된 건 수 계산 int deletedCount = initialSize - finalSize; -// log.info(" +삭제된 건수 :: [{}]",deletedCount); + + + + + + + -// long startTime = System.nanoTime(); // 시작 시간 측정 + // 전용 전송사 코드 및 대표 전송사 조회 + MberManageVO userInfo = mjonMsgDataDAO.selectMberManageInfo(userId); + String hotlineAgentCode = userInfo.getHotlineAgentCode(); + + // 핫라인 전송사 처리 + if (!"00".equals(hotlineAgentCode)) { + hotlineAgentCode = handleHotlineAgent(mjonMsgVO, hotlineAgentCode, userInfo); + log.info("Hotline agent code processed: {}", hotlineAgentCode); + } + // 전송사별 전송 수 초기화 + Map agentSendCounts = MsgSendUtils.initializeAgentSendCounts(); + + // 수신자 총 명수 기준으로 전송사 비율 처리 + // 전송사별 배분률 조회 + List sendRateList = mjonMsgDataDAO.selectSendAgentList(mjonMsgVO); + + // finalSize :: 수신거부 번호 제거 후 총 수신자 수 + if (finalSize >= 10) { + // 전송사별 발송 비율 계산 + for (MjonMsgVO sendRate : sendRateList) { + MsgSendUtils.calculateSendCounts(agentSendCounts, sendRate, finalSize); + } + } + + mjonMsgVO.setAgentCode(hotlineAgentCode); + // smstxt 치환 및 스팸체크 후 mjonMsgSendVOList 에 add() List resultSpamTxt = mjonMsgDataService.selectSpamKeywordList(); - if(!MsgSendUtils.populateSendLists(mjonMsgVO, mjonMsgSendVOList, statusResponse, resultSpamTxt)) {; + // msgGroupId 생성 + String nextMsgGroupId = idgenMjonMsgGroupId.getNextStringId(); + if(!MsgSendUtils.populateSendLists(mjonMsgVO, mjonMsgSendVOList, statusResponse, resultSpamTxt + , agentSendCounts, sendRateList, nextMsgGroupId)) {; //문자 치환 후 전송 문자 길이를 초과하였습니다. //문자 치환 중 오류가 발생하였습니다. return statusResponse; } - mjonMsgSendVOList.stream().forEach(t-> System.out.println(" + ReqDate :: "+t.getReqDate())); -// long endTime = System.nanoTime(); // 종료 시간 측정 -// long duration = endTime - startTime; // 실행 시간 계산 (나노초) - -// // 나노초를 초와 분으로 변환 -// long seconds = duration / 1_000_000_000; -// long minutes = seconds / 60; -// seconds = seconds % 60; // 분으로 나누고 남은 초 계산 - -// System.out.println("Execution time: " + minutes + " minutes " + seconds + " seconds"); - - - - - - - - - - - //1.시스템 기본 단가 정보 불러오기 JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo(); @@ -4168,14 +4108,103 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M MsgSendUtils.setPriceforVO(mjonMsgVO, mjonMsgSendVOList, sysJoinSetVO, mberManageVO); + + + /*mjonMsgSendVOList.parallelStream().forEach(t -> { + try { + t.setMsgId(idgenMsgId.getNextStringId()); + } catch (FdlException e) { + log.error("MsgId 생성 중 오류 발생", e); + } + });*/ + List idList = idgenMsgCId.getNextStringId(mjonMsgSendVOList.size()); +// System.out.println(" idList.size() : " + idList.size()); +// System.out.println(" idList : " + idList); + for (int i = 0; i < mjonMsgSendVOList.size(); i++) { + mjonMsgSendVOList.get(i).setMsgId(idList.get(i)); + } + +// mjonMsgSendVOList.stream().forEach(t-> System.out.print(t.toString()+"\n") ); + + + // 이벤트 영역 + // 이벤트 영역 + + // 이벤트 정보 가져오기 + // 이벤트 상태가 "E"가 아닌 경우에만 호출 + // 이벤트 금액이 있을 시 발송 LIST에서 => optimalMsgList로 데이터 이동 + // 이동하면서 이벤트 금액으로 설정 MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo_advc(userId); + OptimalMsgResultDTO result = null; + List optimalMsgList = new ArrayList<>(); - List optimalMsgList = MsgSendUtils.getOptimalMsgList(mjonMsgVO.getTotalPrice(), eventMberInfo.getEventRemainCash(), mjonMsgSendVOList); - + if (eventMberInfo != null && !"E".equals(eventMberInfo.getEventStatus())) { + try { + result = MsgSendUtils.getOptimalMsgList(eventMberInfo, mjonMsgSendVOList); + optimalMsgList = result.getOptimalMsgList(); + MjonEventVO returnEventMberInfo = result.getEventInfo(); + + 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; + } + } log.info(" + optimalMsgList :: [{}]", optimalMsgList.size()); - log.info(" + mjonMsgSendVOList :: [{}]", mjonMsgSendVOList.size()); + + + + + + + + // 시작 시간 측정 + long startTime = System.currentTimeMillis(); + + + + log.info("mj_msg_data insert start [{}]", mjonMsgSendVOList.size()); + + // 분할 최대건수가 되면 디비에 입력하기 + int instCnt = mjonMsgDataDAO.insertMsgDataInfo_advc(mjonMsgSendVOList); + + + // 종료 시간 측정 + long endTime = System.currentTimeMillis(); + // 실행 시간 계산 (밀리초 -> 초로 변환) + double executionTimeInSeconds = (endTime - startTime) / 1000.0; + // 실행 시간 출력 + System.out.println("Execution time: " + executionTimeInSeconds + " seconds"); +// mjonMsgSendVOList.stream().forEach(t-> System.out.print(t.toString()+"\n") ); +// mjonMsgSendVOList.stream().forEach(t-> System.out.print(t.toString()+"\n") ); + + + // 강제로 IllegalArgumentException 발생시키기 + if (true) { + throw new IllegalArgumentException("강제로 발생한 오류입니다."); + } + + + + + + +// log.info(" + optimalMsgList :: [{}]", optimalMsgList.size()); +// log.info(" + optimalMsgList :: [{}]", optimalMsgList.get(0).getEachPrice()); +// log.info(" + mjonMsgSendVOList :: [{}]", mjonMsgSendVOList.size()); +// log.info(" + mjonMsgSendVOList :: [{}]", mjonMsgSendVOList.get(0).getEachPrice()); + + + + // log.info("mjonMsgVO.getTotalPrice() :: [{}]", mjonMsgVO.getTotalPrice()); // log.info(" + userId :: [{}]", userId); @@ -4214,6 +4243,41 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M } + /** + * @methodName : handleHotlineAgent + * @author : 이호영 + * @date : 2024.11.26 + * @description : agent 발송 비율 리스트를 가져오기위해 msgType 수정 + * @param mjonMsgVO + * @param hotlineAgentCode + * @param userInfo + * @return + * @throws Exception + */ + private String handleHotlineAgent(MjonMsgVO mjonMsgVO, String hotlineAgentCode, MberManageVO userInfo) throws Exception { + MjonMsgAgentStsVO mjonMsgAgentStsVO = new MjonMsgAgentStsVO(); + mjonMsgAgentStsVO.setAgentCode(hotlineAgentCode); + + // 메시지 타입에 따른 전송사 설정 + if ("6".equals(mjonMsgVO.getMsgType())) { + int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt()); + mjonMsgAgentStsVO.setMsgType(fileCount > 0 ? "P" : "L"); + } else { + mjonMsgAgentStsVO.setMsgType("S"); + } + + // 핫라인 전송사 리스트 조회 + List hotlineMsgAgentList = mjonMsgAgentStsDAO.selectMsgAgentListByAgentCode(mjonMsgAgentStsVO); + + // 핫라인 전송사 코드 업데이트 + for (MjonMsgAgentStsVO tmp : hotlineMsgAgentList) { + hotlineAgentCode = MsgSendUtils.handleHotlineAgentRate(userInfo, tmp, hotlineAgentCode); + } + + return hotlineAgentCode; // 최종 변경된 hotlineAgentCode 반환 + } + + private MjonMsgVO setImagesSetting(MjonMsgVO mjonMsgVO, StatusResponse statusResponse) throws Exception { int fileCount = 0; diff --git a/src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java b/src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java index c17fa903..e8e587af 100644 --- a/src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java +++ b/src/main/java/itn/let/mjo/msgdata/web/MjonMsgDataController.java @@ -3174,11 +3174,10 @@ public class MjonMsgDataController { ModelMap model) throws Exception { // 디버깅 출력 - System.out.println("mjonMsgVO : " + mjonMsgVO.getMjonMsgSendVOList().toString()); - System.out.println("mjonMsgVO : " + mjonMsgVO.getMjonMsgSendVOList().size()); +// System.out.println("mjonMsgVO : " + mjonMsgVO.getMjonMsgSendVOList().toString()); +// System.out.println("mjonMsgVO : " + mjonMsgVO.getMjonMsgSendVOList().size()); return ResponseEntity.ok().body(mjonMsgDataService.sendMsgData_advc(mjonMsgVO, request)) ; -// return null; } diff --git a/src/main/java/itn/let/module/base/PriceAndPoint.java b/src/main/java/itn/let/module/base/PriceAndPoint.java index ae267bda..dc2785de 100644 --- a/src/main/java/itn/let/module/base/PriceAndPoint.java +++ b/src/main/java/itn/let/module/base/PriceAndPoint.java @@ -34,6 +34,12 @@ public class PriceAndPoint { @Autowired private MjonMsgDataDAO mjonMsgDataDAO; + + @Autowired + private MjonPayDAO mjonPayDAO; + + @Resource(name = "egovMjonCashIdGnrService") + private EgovIdGnrService idgenMjonCashId; /** * @methodName : getBefCash @@ -95,10 +101,8 @@ public class PriceAndPoint { * @param msgGroupId * @throws Exception */ - public static void insertCashAndPoint( - MjonPayDAO mjonPayDAO - , EgovIdGnrService idgenMjonCashId - , String userId + public void insertCashAndPoint( + String userId , float totPrice , String memo , String msgGroupId diff --git a/src/main/resources/egovframework/spring/com/context-idgen.xml b/src/main/resources/egovframework/spring/com/context-idgen.xml index 4b5c4923..69bd5f02 100644 --- a/src/main/resources/egovframework/spring/com/context-idgen.xml +++ b/src/main/resources/egovframework/spring/com/context-idgen.xml @@ -2331,6 +2331,31 @@ + + + + + + + + + + + + + + + + + + + + + + + - + @@ -153,6 +153,37 @@ ) + + + INSERT INTO MJ_MSG_DATA + ( MSG_ID, + MSG_GROUP_ID, + USER_ID, + AGENT_CODE, + CUR_STATE, + REQ_DATE, + CALL_TO, + CALL_FROM, + SUBJECT, + SMS_TXT, + MSG_TYPE + )VALUES + + ( + #[].msgId#, + #[].msgGroupId#, + #[].userId#, + #[].agentCode#, + 0, + #[].reqDate#, + #[].callTo#, + #[].callFrom#, + #[].subject#, + #[].smsTxt#, + #[].msgType# + ) + +