문자전송개선 테스트

This commit is contained in:
hehihoho3@gmail.com 2024-11-27 16:15:30 +09:00
parent 060c8afe41
commit f44acfe2c4
15 changed files with 924 additions and 222 deletions

View File

@ -111,6 +111,7 @@
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.fdl.idgnr</artifactId>
<version>${egovframework.rte.version}</version>
<!--<version>4.2.0</version>-->
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>

View File

@ -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<String> getNextStringId(int count) throws FdlException;
}

View File

@ -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<String> getNextStringId(int count) throws FdlException {
List<String> 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;
}
}

View File

@ -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<MjonMsgSendVO> optimalMsgList;
private MjonEventVO eventInfo;
}

View File

@ -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);

View File

@ -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<MjonMsgSendVO> mjonMsgSendListVO, StatusResponse statusResponse, List<String> resultSpamTxt) throws Exception{
public static Boolean populateSendLists(MjonMsgVO mjonMsgVO, List<MjonMsgSendVO> mjonMsgSendListVO
, StatusResponse statusResponse, List<String> resultSpamTxt
, Map<String, Integer> agentSendCounts, List<MjonMsgVO> 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<MjonMsgSendVO>).
* @return OptimalMsgResultDTO 최적 메시지 리스트와 이벤트 상태 정보를 포함한 DTO 객체.
* @throws Exception 메시지 단가 계산 오류 또는 기타 처리 발생한 예외를 상위로 전달.
*/
public static OptimalMsgResultDTO getOptimalMsgList(
MjonEventVO eventMberInfo,
List<MjonMsgSendVO> mjonMsgSendVOList) throws Exception {
// 최적의 메시지 리스트를 담을 리스트
List<MjonMsgSendVO> 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<MjonMsgSendVO> 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<MjonMsgSendVO> getOptimalMsgList(double totalPrice, double eventRemainCash,
List<MjonMsgSendVO> mjonMsgSendVOList) {
double targetCash = eventRemainCash;
// 최적의 리스트를 구성하기 위한 리스트 생성
List<MjonMsgSendVO> 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<MjonMsgSendVO> 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<String, Integer> initializeAgentSendCounts() {
Map<String, Integer> 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<String, Integer> 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<String, Integer> agentSendCounts, List<MjonMsgVO> sendRateList) {
// 전송사 코드 순서대로 확인 :: initializeAgentSendCounts 메소드와 맞춰야함
List<String> 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();
}
}

View File

@ -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<MjonMsgVO> selectPayUserSumFaxList(MjonMsgVO mjonMsgVO) throws Exception{
return (List<MjonMsgVO>) list("mjonMsgDAO.selectPayUserSumFaxList",mjonMsgVO);
}
public int insertMsgDataInfo_advc(List<MjonMsgSendVO> mjonMsgSendVOList) {
//단문 전송
int result = update("mjonMsgDAO.insertMsgData_advc", mjonMsgSendVOList);
return result;
}
}

View File

@ -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<MjonMsgSendVO> 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<String, Integer> agentSendCounts = MsgSendUtils.initializeAgentSendCounts();
// 수신자 명수 기준으로 전송사 비율 처리
// 전송사별 배분률 조회
List<MjonMsgVO> sendRateList = mjonMsgDataDAO.selectSendAgentList(mjonMsgVO);
// finalSize :: 수신거부 번호 제거 수신자
if (finalSize >= 10) {
// 전송사별 발송 비율 계산
for (MjonMsgVO sendRate : sendRateList) {
MsgSendUtils.calculateSendCounts(agentSendCounts, sendRate, finalSize);
}
}
mjonMsgVO.setAgentCode(hotlineAgentCode);
// smstxt 치환 스팸체크 mjonMsgSendVOList add()
List<String> 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<String> 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<MjonMsgSendVO> optimalMsgList = new ArrayList<>();
List<MjonMsgSendVO> 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<MjonMsgAgentStsVO> 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;

View File

@ -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;
}

View File

@ -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

View File

@ -2331,6 +2331,31 @@
<property name="fillChar" value="0" />
</bean>
<!-- 문자온 개선 작업(advc) 중 대량 발송을 위한 ids
문자ID Generation Strategy Config -->
<bean id="egovMjonMsgIdCGnrService"
class="egovframework.com.idgen.impl.CustomTableIdGnrServiceImpl">
<property name="dataSource" ref="dataSource" />
<property name="blockSize" value="1000"/>
<property name="table" value="IDS"/> <!-- 실제 테이블 이름 -->
<property name="tableName" value="MSGC_ID"/> <!-- TABLE_NAME 컬럼의 값 -->
<!-- <property name="columnName" value="NEXT_ID"/> NEXT_ID 컬럼명 -->
<property name="prefix" value="MSGCID_"/>
<property name="cipers" value="14"/>
<property name="fillChar" value="0"/>
<property name="applyYear" value="false"/>
<!-- 필요에 따라 추가 프로퍼티 설정 -->
</bean>
<!-- 문자의 장문,단문, 그림문자 등록 ID Generation Strategy Config -->
<bean name="egovLetterInfoIdGnrService"
class="egovframework.rte.fdl.idgnr.impl.EgovTableIdGnrServiceImpl"

View File

@ -3,7 +3,7 @@
========= ======= =================================================
2021.03.01 신명섭
-->
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Msg">
<typeAlias alias="mjonMsgVO" type="itn.let.mjo.msg.service.MjonMsgVO"/>
<typeAlias alias="mjonResvMsgVO" type="itn.let.mjo.reservmsg.service.MjonResvMsgVO"/>
@ -153,6 +153,37 @@
)
</iterate>
</insert>
<insert id="mjonMsgDAO.insertMsgData_advc" parameterClass="java.util.List">
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
<iterate conjunction=",">
(
#[].msgId#,
#[].msgGroupId#,
#[].userId#,
#[].agentCode#,
0,
#[].reqDate#,
#[].callTo#,
#[].callFrom#,
#[].subject#,
#[].smsTxt#,
#[].msgType#
)
</iterate>
</insert>
<select id="mjonMsgDAO.selectMjonMsgList" parameterClass="mjonMsgVO" resultClass="mjonMsgVO">
SELECT

View File

@ -2207,7 +2207,8 @@ function fnByteString(contents){
|| contents.indexOf("[*3*]") > -1
|| contents.indexOf("[*4*]") > -1){
fnReplCell();
// fnReplCell();
fnReplCell_advc();
}else{

View File

@ -1105,6 +1105,7 @@ function fn_sendMsgData(){
if(eventStatus == 'Y'
&& parseFloat(eventRemainCash) < parseFloat(totPriceOnly))
{
console.log('eventRemainCash : ', eventRemainCash);
if(!confirm("고객님의 이벤트 캐시 잔액(" + eventRemainCash + "원) 부족으로 요청하신 문자("+numberWithCommas($selectedData.length)+"건)를 모두 발송할 수 없습니다. 이벤트 캐시 초과 건에 대해서는 일반 단가를 적용하여 발송하시겠습니까?")){
return false;
}
@ -1288,11 +1289,16 @@ function sendMsgAjax_advc(){
$('.pop_msg_success').css({'display':'block','opacity':'1','left':'50%','top':'50%','transform':'translate(-50%,-50%)'});
//예약발송 건의 경우 결과 팝업 문구 변경
if(reserYn == 'Y'){
$('.pop_msg_success .msg_text').html("예약 성공 : <strong>"+ smsCnt + "</strong>건,수신거부 : <span>" + blockCnt + "</span>건의<br>문자가 예약 되었습니다.");
}else{
$('.pop_msg_success .msg_text').html("발송 성공 : <strong>"+ smsCnt + "</strong>건,수신거부 : <span>" + blockCnt + "</span>건의<br>문자가 발송 되었습니다.");
var resText = (reserYn === 'Y') ? '예약' : '발송';
if(reserYn == 'Y')
/* {
resText = "예약";
}
else
{
resText = "발송";
} */
$('.pop_msg_success .msg_text').html(resText+" 성공 : <strong>"+ smsCnt + "</strong>건,수신거부 : <span>" + blockCnt + "</span>건의<br>문자가 "+resText+" 되었습니다.");
$('.mask').addClass('on');

View File

@ -1,3 +1,59 @@
function fnReplCell_advc(){
var smsTxtArea = $('#smsTxtArea').val();
console.log('smsTxtArea : ', smsTxtArea);
var orgSmsTxt = smsTxtArea; // 광고문자 뺀 문자내용
var recTableData = tableL.getRows(); // 받는사람 리스트의 전체 목록을 저장
var smsTxt = smsTxtArea;
var data = recTableData[0].getData();
if(typeof data.name != 'undefined'
&& data.name != null
&& data.name != ""){
var name = data.name;
smsTxt = stringReplaceAll(smsTxt, "[*이름*]", name);
}
if(typeof data.rep1 != 'undefined' && data.rep1 != null && data.rep1 != ""){
var rep1 = data.rep1;
smsTxt = stringReplaceAll(smsTxt, "[*1*]", rep1);
}
if(typeof data.rep2 != 'undefined' && data.rep2 != null && data.rep2 != ""){
var rep2 = data.rep2;
smsTxt = stringReplaceAll(smsTxt, "[*2*]", rep2);
}
if(typeof data.rep3 != 'undefined' && data.rep3 != null && data.rep3 != ""){
var rep3 = data.rep3;
smsTxt = stringReplaceAll(smsTxt, "[*3*]", rep3);
}
if(typeof data.rep4 != 'undefined' && data.rep4 != null && data.rep4 != ""){
var rep4 = data.rep4;
smsTxt = stringReplaceAll(smsTxt, "[*4*]", rep4);
}
console.log('smsTxt : ', smsTxt);
$('.realtime').text(smsTxt);
}
//특정문구 일괄변환 문자길이 체크 하기
function fnReplCell(){
@ -86,7 +142,9 @@ function fnReplCell(){
var smsTxt = smsTxtArea;
if(typeof recTableData[j].getData().name != 'undefined' && recTableData[j].getData().name != null && recTableData[j].getData().name != ""){
if(typeof recTableData[j].getData().name != 'undefined'
&& recTableData[j].getData().name != null
&& recTableData[j].getData().name != ""){
// console.log('name : ', name);
// console.log('smsTxt : ', smsTxt);
@ -343,7 +401,10 @@ function fnReplCellExcel(){
for(var j=0; j < recTableData.length; j++){
var smsTxt = smsTxtArea;
if(typeof recTableData[j].getData().name != 'undefined' && recTableData[j].getData().name != null && recTableData[j].getData().name != ""){
if(typeof recTableData[j].getData().name != 'undefined'
&& recTableData[j].getData().name != null
&& recTableData[j].getData().name != "")
{
var name = recTableData[j].getData().name;
smsTxt = stringReplaceAll(smsTxt, "[*이름*]", name);