1905 lines
63 KiB
Java
1905 lines
63 KiB
Java
package itn.let.kakao.kakaoComm;
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.math.BigDecimal;
|
|
import java.math.RoundingMode;
|
|
import java.text.ParseException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.function.Function;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
|
|
import itn.com.cmm.MjonFTSendVO;
|
|
import itn.com.cmm.MjonMsgSendVO;
|
|
import itn.com.cmm.util.MsgSendUtils;
|
|
import itn.com.cmm.util.StringUtil;
|
|
import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiJsonSave;
|
|
import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiTemplate;
|
|
import itn.let.kakao.user.kakaoAt.service.impl.KakaoAlimTalkDAO;
|
|
import itn.let.mail.service.StatusResponse;
|
|
import itn.let.mjo.mjocommon.MjonCommon;
|
|
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.spammsg.web.ComGetSpamStringParser;
|
|
import itn.let.module.base.PriceAndPoint;
|
|
import itn.let.sym.site.service.JoinSettingVO;
|
|
import itn.let.uss.umt.service.MberManageVO;
|
|
import itn.let.uss.umt.service.UserManageVO;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
@Slf4j
|
|
@Component
|
|
public class KakaoSendUtil {
|
|
|
|
@Autowired
|
|
KakaoApiJsonSave kakaoApiJsonSave;
|
|
|
|
@Resource(name="kakaoAlimTalkDAO")
|
|
private KakaoAlimTalkDAO kakaoAlimTalkDAO;
|
|
|
|
@Resource(name = "MjonMsgDataService")
|
|
private MjonMsgDataService mjonMsgDataService;
|
|
|
|
@Resource(name = "mjonMsgDAO")
|
|
private MjonMsgDAO mjonMsgDAO;
|
|
|
|
@Autowired
|
|
KakaoApiTemplate kakaoApiTemplate;
|
|
|
|
@Autowired
|
|
private PriceAndPoint priceAndPoint;
|
|
|
|
@Autowired
|
|
private MjonCommon mjonCommon;
|
|
|
|
|
|
// 클래스 수준에서 정적 Pattern 정의 (성능 최적화)
|
|
private static final Pattern REPLACEMENT_PATTERN = Pattern.compile("#\\{[^}]+\\}");
|
|
|
|
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
|
|
|
// 단문 메세지 타입
|
|
public static final String SHORT_MSG_TYPE = "SMS";
|
|
// 장문 메세지 타입
|
|
public static final String LONG_MSG_TYPE = "MMS";
|
|
|
|
/**
|
|
* @methodName : populateSendLists _advc
|
|
* @author : 이호영
|
|
* @date : 2025. 3. 7.
|
|
* @description : 기존 kakaoSendPrice 개선
|
|
* @return : KakaoVO
|
|
* @param kakaoVO
|
|
* @param statusResponse
|
|
* @return
|
|
* @throws Exception
|
|
*
|
|
*/
|
|
public List<KakaoSendAdvcVO> populateSendLists(KakaoVO kakaoVO, boolean isNotified, StatusResponse statusResponse) throws Exception {
|
|
|
|
//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
|
|
// String befCash = kakaoVO.getBefCash();
|
|
|
|
|
|
|
|
List<KakaoSendAdvcVO> kakaoSendAdvcListVO = new ArrayList<>();
|
|
Calendar calendar = setupBaseDate(kakaoVO, isNotified);
|
|
|
|
|
|
|
|
KakaoReturnVO templateDetail = kakaoApiTemplate.selectKakaoApiTemplateDetail(kakaoVO);
|
|
String templateContent = templateDetail.getTemplateContent(); // 알림톡 템플릿
|
|
kakaoVO.setTemplateContent(templateContent);
|
|
String templateTitle = templateDetail.getTemplateTitle();
|
|
|
|
|
|
// log.info(" + templateDetail :: [{}]", templateDetail);
|
|
// templateDetail.getButtonList().forEach(t->log.info(" + ButtonList :: [{}]", t.toString()));
|
|
|
|
// API인지 확인하는 Boolean
|
|
Boolean isApiData = "A".equals(kakaoVO.getSendKind());
|
|
|
|
Boolean hasContentReplacement = this.replBooleanStrChecker(templateContent);
|
|
Boolean hasTitleReplacement = this.replBooleanStrChecker(templateTitle);
|
|
Boolean hasButtonReplacement = this.needsButtonReplacement(templateDetail.getButtonList());
|
|
|
|
/** @jsonStr 필요유무 */
|
|
boolean hasTitleOrButtons = StringUtils.isNotEmpty(templateTitle)
|
|
|| CollectionUtils.isNotEmpty(templateDetail.getButtonList())
|
|
|| "IMAGE".equalsIgnoreCase(templateDetail.getTemplateEmphasizeType()); // 템플릿 강조 유형 이미지 유형을 알기 위해 추가
|
|
|
|
/** @jsonStr 반복유무 */
|
|
boolean needsJsonReplacement = hasTitleReplacement || hasButtonReplacement;
|
|
String sharedJsonStr = null;
|
|
|
|
String subMsgTxt = kakaoVO.getSubMsgTxt(); // 실패 대체 문자
|
|
|
|
// 시스템 기본 단가 정보 불러오기
|
|
JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
|
|
// 사용자 개인 단가 정보 불러오기
|
|
MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(kakaoVO.getUserId());
|
|
|
|
|
|
float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice());
|
|
float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice());
|
|
float kakaoAtPrice = getValidPrice(mberManageVO.getKakaoAtPrice(), sysJoinSetVO.getKakaoAtPrice());
|
|
|
|
|
|
String shortPStr = Float.toString(shortPrice);
|
|
String mmsPStr = Float.toString(longPrice);
|
|
String kakaoAtPStr = Float.toString(kakaoAtPrice);
|
|
|
|
|
|
/** @MSGID KEY값 */
|
|
List<String> idList = mjonCommon.getNextCustomMsgCId(kakaoVO.getVarListMap().size());
|
|
// for (int i = 0; i < kakaoSendAdvcListVO.size(); i++) {
|
|
// kakaoSendAdvcListVO.get(i).setMsgId(idList.get(i));
|
|
// kakaoSendAdvcListVO.get(i).setBizJsonName(idList.get(i));
|
|
// }
|
|
|
|
String templateEmphasizeType = kakaoVO.getTemplateEmphasizeType();
|
|
|
|
|
|
// 분할 건수 카운터
|
|
int counter = 0;
|
|
/** @Map에 총 갯수가 수신자 갯수와 동일함 */
|
|
List<Map<String, String>> varList = kakaoVO.getVarListMap();
|
|
|
|
for (int i = 0; i < varList.size(); i++) {
|
|
// for(Map<String, String> variables : kakaoVO.getVarListMap()) {
|
|
// 치환 데이터
|
|
Map<String, String> variables = varList.get(i);
|
|
log.info("");
|
|
|
|
/** @공통 기본값 */
|
|
KakaoSendAdvcVO sendVO = createATSendVO(kakaoVO);
|
|
// 공통 가격 설정
|
|
sendVO.setSmsPrice(shortPStr);
|
|
sendVO.setMmsPrice(mmsPStr);
|
|
sendVO.setKakaoAtPrice(kakaoAtPStr);
|
|
|
|
|
|
String msgId = idList.get(i);
|
|
sendVO.setMsgId(msgId);
|
|
|
|
// step1
|
|
// Step 1-1: 값 치환 및 수신번호 셋팅
|
|
// Step 1-2: 수신자 정보 설정 (callToList는 항상 설정).
|
|
if (variables.containsKey("callToList")) {
|
|
sendVO.setCallTo(variables.get("callToList"));
|
|
variables.remove("callToList"); // 사용 후 제거.
|
|
}
|
|
|
|
/** @Step1-3: 템플릿 치환데이터 설정 */
|
|
String templateContentTemp = templateContent;
|
|
String templateTitleTemp = templateTitle;
|
|
|
|
// api가 아니면
|
|
if(!isApiData) {
|
|
if (hasContentReplacement) {
|
|
templateContentTemp = mjonCommon.ATReplaceTemplateVariables(templateContent, variables);
|
|
if(hasTitleReplacement) {
|
|
templateTitleTemp = mjonCommon.ATReplaceTemplateVariables(templateTitle, variables);
|
|
}
|
|
}
|
|
}else {
|
|
templateContentTemp = variables.get("templateContent");
|
|
templateTitleTemp = variables.get("templateTitle");
|
|
}
|
|
|
|
|
|
/** @버튼 치환 */ // 버튼 리스트가 있으면 치환 수행, 항상 sendVO에 설정
|
|
List<KakaoButtonVO> buttonList = templateDetail.getButtonList();
|
|
if(hasButtonReplacement) {
|
|
buttonList = replaceButtonLinks(buttonList, variables);
|
|
}
|
|
sendVO.setButtonList(buttonList);
|
|
|
|
sendVO.setTemplateTitle(templateTitleTemp);
|
|
sendVO.setTemplateContent(templateContentTemp);
|
|
|
|
|
|
String subMsgTxtTemp = subMsgTxt;
|
|
// Step 1-4: 실패 대체 문자 치환데이터 설정
|
|
if("Y".equals(kakaoVO.getSubMsgSendYn())) { // 대체문자가 있나?
|
|
// api가 아니면
|
|
if(!isApiData) {
|
|
if ("Y".equals(kakaoVO.getSubMsgTxtReplYn())) { // 치환데이터가 있나?
|
|
subMsgTxtTemp = mjonCommon.ATReplaceTemplateVariables(subMsgTxt, variables);
|
|
}
|
|
}else {
|
|
subMsgTxtTemp = variables.get("subMsgTxt");
|
|
}
|
|
sendVO.setSubMsgTxt(subMsgTxtTemp);// 실패
|
|
}
|
|
sendVO.setSubMsgSendYn(kakaoVO.getSubMsgSendYn());
|
|
|
|
|
|
|
|
if("Y".equals(kakaoVO.getSubMsgSendYn())) {
|
|
int smsTxtByte = mjonCommon.getSmsTxtBytes(sendVO.getSubMsgTxt());
|
|
String sendType = getMsgType(smsTxtByte);
|
|
sendVO.setSubMsgType(sendType);
|
|
|
|
if ("INVALID".equals(sendType)) {
|
|
// statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");return kakaoSendAdvcListVO;
|
|
StatusResponse.statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.", "STAT_1080");return kakaoSendAdvcListVO;
|
|
}
|
|
|
|
boolean isMms = "MMS".equals(sendType);
|
|
sendVO.setEachPrice(isMms ? mmsPStr : shortPStr);
|
|
|
|
|
|
} else {
|
|
sendVO.setEachPrice(kakaoAtPStr);
|
|
}
|
|
|
|
|
|
|
|
// step4
|
|
// 예약 시간 설정 및 분할 데이터 설정
|
|
if ("Y".equalsIgnoreCase(kakaoVO.getReserveYn())
|
|
&& "Y".equalsIgnoreCase(kakaoVO.getDivideChk())
|
|
&& counter == Integer.parseInt(kakaoVO.getDivideCnt()))
|
|
{
|
|
counter = 0;
|
|
calendar.add(Calendar.MINUTE, Integer.parseInt(kakaoVO.getDivideTime()));
|
|
}
|
|
counter++;
|
|
// 즉시 발송인경우 현재 시간
|
|
// 예약인 경우 위에 설정한 시간 입력
|
|
sendVO.setReqDate(DATE_FORMATTER.format(calendar.getTime()));
|
|
|
|
|
|
|
|
/** @step5 전송 메세지 설정 json파일 만들기*/
|
|
// 타이틀과 버튼이 있고
|
|
if(hasTitleOrButtons) {
|
|
// 버튼과 타이틀에 치환데이터가 있으면 json String을 계속 생성
|
|
if(needsJsonReplacement) {
|
|
sharedJsonStr = kakaoApiJsonSave.kakaoApiJsonSave_advc(sendVO, templateDetail);
|
|
sendVO.setBizJsonName(msgId);
|
|
sendVO.setJsonStr(sharedJsonStr);
|
|
} else if (StringUtils.isEmpty(sharedJsonStr)) {
|
|
// 치환 데이터가 없고 아직 생성되지 않았으면 한 번만 생성
|
|
sharedJsonStr = kakaoApiJsonSave.kakaoApiJsonSave_advc(sendVO, templateDetail);
|
|
sendVO.setBizJsonName(idList.get(0));
|
|
sendVO.setJsonStr(sharedJsonStr);
|
|
}else {
|
|
sendVO.setBizJsonName(idList.get(0));
|
|
}
|
|
|
|
}
|
|
log.info(" sendVO :: [{}]", sendVO);
|
|
kakaoSendAdvcListVO.add(sendVO);
|
|
}
|
|
|
|
|
|
return kakaoSendAdvcListVO;
|
|
}
|
|
|
|
/**
|
|
* @methodName : populateSendListsFT
|
|
* @author : 이호영
|
|
* @date : 2025. 4. 18.
|
|
* @description :
|
|
* @return : List<KakaoSendAdvcVO>
|
|
* @param kakaoVO
|
|
* @param isHolidayNotified
|
|
* @param statusResponse
|
|
* @return
|
|
* @throws Exception
|
|
*
|
|
*/
|
|
public List<KakaoSendAdvcVO> populateSendListsFT(KakaoVO kakaoVO
|
|
, boolean isHolidayNotified
|
|
, StatusResponse statusResponse
|
|
, UserManageVO userManageVO
|
|
, List<String> resultSpamTxt
|
|
) throws Exception {
|
|
|
|
//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
|
|
// String befCash = kakaoVO.getBefCash();
|
|
|
|
log.info("kakaoVO.ftToString() :: [{}]", kakaoVO.ftToString());
|
|
|
|
|
|
// 예약 시간 기본값 설정
|
|
Date now = new Date();
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
|
|
|
String atSmishingYn = userManageVO.getAtSmishingYn();
|
|
String exceptSpamYn = userManageVO.getExceptSpamYn();
|
|
|
|
|
|
List<KakaoSendAdvcVO> kakaoSendAdvcListVO = new ArrayList<>();
|
|
Calendar calendar = setupBaseDateFT(kakaoVO);
|
|
|
|
|
|
|
|
// 친구톡 내용
|
|
String templateContent = kakaoVO.getTemplateContent();
|
|
// 실패 대체 문자
|
|
String subMsgTxt = kakaoVO.getSubMsgTxt();
|
|
log.info(" + StringUtils.isNotEmpty(subMsgTxt) :: [{}]", StringUtils.isNotEmpty(subMsgTxt));
|
|
if(StringUtils.isNotEmpty(subMsgTxt)) {
|
|
kakaoVO.setSubMsgSendYn("Y");
|
|
|
|
// 광고문자면 처리 - 광고 Y
|
|
if ("Y".equals(kakaoVO.getAdFlag())) {
|
|
subMsgTxt = "(광고)" + subMsgTxt + "\n" + "무료거부 0808800858";
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 사용자 개인 단가 정보 불러오기
|
|
MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(kakaoVO.getUserId());
|
|
// 시스템 기본 단가 정보 불러오기
|
|
JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
|
|
|
|
|
|
// 치환 문구가 있는지 확인
|
|
Boolean replaceYN = MsgSendUtils.getReplaceYN(templateContent);
|
|
Boolean replaceSubYN = MsgSendUtils.getReplaceYN(subMsgTxt);
|
|
|
|
|
|
/** @MSGID KEY값 */
|
|
List<String> idList = mjonCommon.getNextCustomMsgCId(kakaoVO.getMjonFTSendVOList().size());
|
|
|
|
|
|
Map<String, Function<MjonFTSendVO, String>> placeholders = new HashMap<>();
|
|
placeholders.put("[*이름*]", MjonFTSendVO::getName);
|
|
placeholders.put("[*1*]", MjonFTSendVO::getRep1);
|
|
placeholders.put("[*2*]", MjonFTSendVO::getRep2);
|
|
placeholders.put("[*3*]", MjonFTSendVO::getRep3);
|
|
placeholders.put("[*4*]", MjonFTSendVO::getRep4);
|
|
|
|
String imageType = kakaoVO.getImageType();
|
|
// 개인단가
|
|
Float kakaoMemberFtPrice =
|
|
imageType == null ? mberManageVO.getKakaoFtPrice() :
|
|
"I".equals(imageType) ? mberManageVO.getKakaoFtImgPrice() :
|
|
"W".equals(imageType) ? mberManageVO.getKakaoFtWideImgPrice() :
|
|
mberManageVO.getKakaoFtPrice();
|
|
|
|
// 시스템단가
|
|
Float kakaoSysJoinFtPrice =
|
|
imageType == null ? sysJoinSetVO.getKakaoFtPrice() :
|
|
"I".equals(imageType) ? sysJoinSetVO.getKakaoFtImgPrice() :
|
|
"W".equals(imageType) ? sysJoinSetVO.getKakaoFtWideImgPrice() :
|
|
sysJoinSetVO.getKakaoFtPrice();
|
|
|
|
Float kakaoFtPrice =
|
|
getValidPrice(kakaoMemberFtPrice, kakaoSysJoinFtPrice);
|
|
|
|
// 대체문자가 있을경우 사용
|
|
float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice());
|
|
float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice());
|
|
float picturePrice = getValidPrice(mberManageVO.getPicturePrice(), sysJoinSetVO.getPicturePrice());
|
|
|
|
boolean hasPerformedSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
|
|
boolean hasPerformedSubSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
|
|
boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 메세지 타입 체크 한번
|
|
boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우,
|
|
|
|
|
|
|
|
String imgFilePath = "";
|
|
if(StringUtils.isNotEmpty(kakaoVO.getAtchFileId()) &&
|
|
("I".equals(imageType) || "W".equals(imageType))) {
|
|
imgFilePath = mjonMsgDAO.selectPhotoImgFileRealPath(kakaoVO.getAtchFileId());
|
|
}
|
|
|
|
|
|
|
|
/** @jsonStr 필요유무 */
|
|
boolean hasButtons = CollectionUtils.isNotEmpty(kakaoVO.getButtonVOList());
|
|
String sharedJsonStr = null;
|
|
|
|
|
|
// 치환데이터가 없는 경우 한 번만 계산하기 위한 캐시 변수 추가
|
|
Map<String, Object> sharedPricingResult = null;
|
|
// 치환데이터가 없는 경우 for문 전에 한 번만 계산
|
|
if (!replaceSubYN && StringUtils.isNotEmpty(subMsgTxt)) {
|
|
sharedPricingResult = calculateSubMsgPricing(subMsgTxt, imgFilePath, shortPrice, longPrice, picturePrice, kakaoFtPrice);
|
|
|
|
// 사전계산에서 INVALID인 경우 즉시 리턴
|
|
String preSendType = (String) sharedPricingResult.get("sendType");
|
|
if ("INVALID".equals(preSendType)) {
|
|
statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");
|
|
return kakaoSendAdvcListVO;
|
|
}
|
|
}
|
|
|
|
List<MjonFTSendVO> mjonFTSendVOList = kakaoVO.getMjonFTSendVOList();
|
|
|
|
for (int i = 0; i < mjonFTSendVOList.size(); i++) {
|
|
MjonFTSendVO mjonFTSendVO = mjonFTSendVOList.get(i);
|
|
|
|
KakaoSendAdvcVO sendVO = createFTSendVO(kakaoVO, calendar);
|
|
// 공통 가격 설정
|
|
sendVO.setSmsPrice(Float.toString(shortPrice));
|
|
sendVO.setMmsPrice(Float.toString(longPrice));
|
|
sendVO.setPicturePrice(Float.toString(picturePrice));
|
|
|
|
sendVO.setCallTo(mjonFTSendVO.getPhone());
|
|
sendVO.setMsgId(idList.get(i));
|
|
|
|
|
|
// 친구톡 문자
|
|
String templateContentTemp = templateContent;
|
|
// 치환 문자면
|
|
if(replaceYN) {
|
|
|
|
// 각 치환 구문을 확인하고 치환할 값이 없으면 오류 반환
|
|
for (Map.Entry<String, Function<MjonFTSendVO, String>> entry : placeholders.entrySet()) {
|
|
String placeholder = entry.getKey();
|
|
String value = entry.getValue().apply(mjonFTSendVO);
|
|
if (templateContentTemp.contains(placeholder)) {
|
|
if (StringUtils.isEmpty(value)) {
|
|
statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");
|
|
return null;
|
|
}
|
|
templateContentTemp = templateContentTemp.replace(placeholder, value);
|
|
}
|
|
}
|
|
}
|
|
sendVO.setTemplateContent(templateContentTemp);
|
|
|
|
// 실패 대체 문자
|
|
String subMsgTxtTemp = null;
|
|
if(StringUtils.isNotEmpty(subMsgTxt)) {
|
|
subMsgTxtTemp = subMsgTxt;
|
|
|
|
if(replaceSubYN) {
|
|
// 각 치환 구문을 확인하고 치환할 값이 없으면 오류 반환
|
|
for (Map.Entry<String, Function<MjonFTSendVO, String>> entry : placeholders.entrySet()) {
|
|
String placeholder = entry.getKey();
|
|
String value = entry.getValue().apply(mjonFTSendVO);
|
|
if (subMsgTxtTemp.contains(placeholder)) {
|
|
if (StringUtils.isEmpty(value)) {
|
|
statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");
|
|
return null;
|
|
}
|
|
subMsgTxtTemp = subMsgTxtTemp.replace(placeholder, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sendVO.setSubMsgTxt(subMsgTxtTemp);
|
|
|
|
|
|
//대체문자가 있으면
|
|
// Step 1-4: 실패 대체 문자 치환데이터 설정
|
|
if(StringUtils.isNotEmpty(subMsgTxtTemp)) { // 대체문자가 있나?
|
|
|
|
// 최적화된 계산 로직
|
|
Map<String, Object> pricingResult;
|
|
|
|
if (replaceSubYN) {
|
|
// 치환데이터 있음 → 매번 새로 계산
|
|
pricingResult = calculateSubMsgPricing(subMsgTxtTemp, imgFilePath,
|
|
shortPrice, longPrice, picturePrice, kakaoFtPrice);
|
|
|
|
// INVALID 체크
|
|
String resultSendType = (String) pricingResult.get("sendType");
|
|
if ("INVALID".equals(resultSendType)) {
|
|
statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");
|
|
return kakaoSendAdvcListVO;
|
|
}
|
|
} else {
|
|
// 치환데이터 없음 → 미리 계산된 결과 재사용
|
|
pricingResult = sharedPricingResult;
|
|
}
|
|
|
|
|
|
// 결과 적용
|
|
applyPricingResult(sendVO, pricingResult);
|
|
|
|
|
|
}else {
|
|
// 대체문자가 없으면 카카오톡 단가 그대로 사용
|
|
sendVO.setEachPrice( Float.toString(kakaoFtPrice) );
|
|
}
|
|
|
|
|
|
// 스팸 단어 체크
|
|
// exceptSpam는 사용자 스팸 단어 체크할건지에 대한 여부 N : 체크
|
|
if("N".equals(exceptSpamYn)) {
|
|
// 친구톡 내용
|
|
if(replaceYN) {
|
|
checkSpamAndSetStatus(kakaoVO
|
|
, templateContentTemp
|
|
, resultSpamTxt, isHolidayNotified);
|
|
}else if(!hasPerformedSpamCheck) {
|
|
checkSpamAndSetStatus(kakaoVO
|
|
, templateContentTemp
|
|
, resultSpamTxt, isHolidayNotified);
|
|
hasPerformedSpamCheck = true;
|
|
}
|
|
// 대체문자 내용
|
|
if(StringUtils.isNotEmpty(subMsgTxtTemp)) {
|
|
if(replaceSubYN) {
|
|
checkSpamAndSetStatus(kakaoVO
|
|
, subMsgTxtTemp
|
|
, resultSpamTxt, isHolidayNotified);
|
|
}else if(!hasPerformedSubSpamCheck) {
|
|
checkSpamAndSetStatus(kakaoVO
|
|
, subMsgTxtTemp
|
|
, resultSpamTxt, isHolidayNotified);
|
|
hasPerformedSubSpamCheck = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
log.info(" kakaoVO.toString() :: [{}]",kakaoVO.ftToString());
|
|
|
|
|
|
/* @isHolidayNotified
|
|
* - 관리자 알림 설정으로 인해
|
|
* - 해당 시간이면 지연 미처리
|
|
* @smishingYn
|
|
* - 회원 별 '스미싱 온' 상태값
|
|
* - Y면 알림, 지연 처리해야 함
|
|
* */
|
|
if("Y".equalsIgnoreCase(atSmishingYn) && isHolidayNotified) {
|
|
kakaoVO.setSpamStatus("Y");
|
|
kakaoVO.setSmishingYn("Y");
|
|
kakaoVO.setAtDelayYn("Y");
|
|
}
|
|
|
|
// 지연 여부 처리
|
|
if (( "Y".equalsIgnoreCase(atSmishingYn) || "Y".equalsIgnoreCase(kakaoVO.getAtDelayYn()))
|
|
&& !hasPerformedDelayYn && isHolidayNotified) {
|
|
calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
|
|
// TEST
|
|
// calendar.add(Calendar.MINUTE, 5); // 모든 시간을 30분 뒤로 미룸
|
|
hasPerformedDelayYn = true;
|
|
}
|
|
|
|
sendVO.setReqDate(sdf.format(calendar.getTime())); // 분할된 시간 설정 또는 기본 예약 시간 사용
|
|
|
|
|
|
|
|
|
|
// 타이틀이나 버튼이 있고
|
|
if(hasButtons || StringUtils.isNotEmpty(kakaoVO.getTemplateImageUrl())) {
|
|
//
|
|
if (StringUtils.isEmpty(sharedJsonStr)) {
|
|
// 치환 데이터가 없고 아직 생성되지 않았으면 한 번만 생성
|
|
sharedJsonStr = kakaoApiJsonSave.kakaoApiFTJsonSave_advc(kakaoVO);
|
|
sendVO.setJsonStr(sharedJsonStr);
|
|
}
|
|
sendVO.setBizJsonName(idList.get(0));
|
|
|
|
}
|
|
|
|
kakaoSendAdvcListVO.add(sendVO);
|
|
log.info(" sendVO.toString() :: [{}]",sendVO.toString());
|
|
}
|
|
|
|
|
|
return kakaoSendAdvcListVO;
|
|
}
|
|
|
|
private void checkSpamAndSetStatus(KakaoVO kakaoVO
|
|
, String chkText
|
|
, List<String> resultSpamTxt, boolean isHolidayNotified) throws Exception {
|
|
// TODO Auto-generated method stub
|
|
|
|
|
|
kakaoVO.setSpamStatus("N");
|
|
kakaoVO.setAtDelayYn("N");
|
|
|
|
if(StringUtils.isNotEmpty(chkText)) {
|
|
|
|
String resultParser = ComGetSpamStringParser.getSpamTextParse(chkText).trim();
|
|
int spmCnt = 0;
|
|
String spmFilterTxt = "";
|
|
|
|
for (String spmTxt : resultSpamTxt) {
|
|
String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
|
|
if (resultParser.contains(parserStr) || chkText.contains(parserStr)) {
|
|
spmCnt++;
|
|
spmFilterTxt += spmTxt + ",";
|
|
}
|
|
}
|
|
|
|
if (spmCnt > 0) { // 스팸 문자가 포함된 경우
|
|
|
|
if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
|
|
// 처음부터 idx 만큼 잘라낸 나머지 글자
|
|
spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1);
|
|
|
|
}
|
|
|
|
/* @isHolidayNotified
|
|
* - 관리자 알림 설정으로 인해
|
|
* - 해당 시간이면 지연 미처리
|
|
* */
|
|
kakaoVO.setSpamStatus("Y");
|
|
if(isHolidayNotified) {
|
|
kakaoVO.setAtDelayYn("Y");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// TODO(human): 아래에 새로운 메소드 구현
|
|
/**
|
|
* 대체문자 가격 계산 최적화 메소드
|
|
* @param subMsgTxt 대체문자 내용
|
|
* @param imgFilePath 이미지 파일 경로
|
|
* @param shortPrice 단문 가격
|
|
* @param longPrice 장문 가격
|
|
* @param picturePrice 사진 가격
|
|
* @param kakaoFtPrice 카카오 친구톡 가격
|
|
* @return 계산 결과 Map (sendType, chosenPrice, filePath 포함)
|
|
* @throws UnsupportedEncodingException
|
|
*/
|
|
private Map<String, Object> calculateSubMsgPricing(String subMsgTxt, String imgFilePath,
|
|
float shortPrice, float longPrice,
|
|
float picturePrice, float kakaoFtPrice) throws UnsupportedEncodingException {
|
|
Map<String, Object> result = new HashMap<>();
|
|
|
|
String sendType = "MMS";
|
|
if(StringUtils.isEmpty(imgFilePath)) {
|
|
int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxt);
|
|
sendType = getMsgType(smsTxtByte);
|
|
}
|
|
|
|
result.put("sendType", sendType);
|
|
|
|
// INVALID인 경우 추가 처리 없이 반환
|
|
if ("INVALID".equals(sendType)) {
|
|
return result;
|
|
}
|
|
|
|
float chosenPrice = 0f;
|
|
if(StringUtils.isNotEmpty(imgFilePath)) {
|
|
chosenPrice = Math.max(picturePrice, kakaoFtPrice);
|
|
result.put("filePath", imgFilePath);
|
|
} else if ("MMS".equals(sendType)) {
|
|
chosenPrice = Math.max(longPrice, kakaoFtPrice);
|
|
} else {
|
|
chosenPrice = Math.max(shortPrice, kakaoFtPrice);
|
|
}
|
|
|
|
result.put("sendType", sendType);
|
|
result.put("chosenPrice", Float.toString(chosenPrice));
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 가격 계산 결과를 sendVO에 적용하는 헬퍼 메소드
|
|
* @param sendVO 적용할 KakaoSendAdvcVO 객체
|
|
* @param pricingResult 가격 계산 결과 Map
|
|
*/
|
|
private void applyPricingResult(KakaoSendAdvcVO sendVO, Map<String, Object> pricingResult) {
|
|
sendVO.setSubMsgType((String) pricingResult.get("sendType"));
|
|
sendVO.setEachPrice((String) pricingResult.get("chosenPrice"));
|
|
if (pricingResult.get("filePath") != null) {
|
|
sendVO.setFilePath1((String) pricingResult.get("filePath"));
|
|
sendVO.setFileCnt("1");
|
|
}
|
|
}
|
|
|
|
public static String getMsgTypeWithByteValidation(MjonFTSendVO sendVO, String p_smsTxt) throws UnsupportedEncodingException {
|
|
|
|
|
|
// // 내문자저장함에 저장 후 문자를 발송하는 경우 문자 타입이 숫자가 아닌 문자로 넘어와서 변경 처리함
|
|
// if ("P".equals(msgType) || "L".equals(msgType)) {
|
|
// msgType = "6";
|
|
// } else if ("S".equals(msgType)) {
|
|
// msgType = "4";
|
|
// }
|
|
|
|
int smsTxtByte = MjonCommon.getSmsTxtBytes(p_smsTxt);
|
|
String msgType = SHORT_MSG_TYPE;
|
|
|
|
// 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;
|
|
}
|
|
|
|
|
|
private Calendar setupBaseDateFT(KakaoVO kakaoVO) throws ParseException {
|
|
|
|
// baseDate 추출
|
|
Date baseDate = resolveBaseDate(kakaoVO);
|
|
|
|
// 시간 성정
|
|
Calendar calendar = Calendar.getInstance();
|
|
calendar.setTime(baseDate); // calendar에 baseDate 설정
|
|
|
|
return calendar;
|
|
}
|
|
|
|
private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isHolidayNotified) throws ParseException {
|
|
|
|
// baseDate 추출
|
|
Date baseDate = resolveBaseDate(kakaoVO);
|
|
|
|
// 시간 성정
|
|
Calendar calendar = Calendar.getInstance();
|
|
calendar.setTime(baseDate); // calendar에 baseDate 설정
|
|
|
|
// 지연 여부 처리
|
|
// 알림톡 스미싱의심 + 공휴일알림 조건이 맞으면 30분 delay
|
|
if ( "Y".equalsIgnoreCase(kakaoVO.getAtSmishingYn())
|
|
&& isHolidayNotified) {
|
|
calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
|
|
}
|
|
return calendar;
|
|
}
|
|
|
|
public Date resolveBaseDate(KakaoVO kakaoVO) throws ParseException {
|
|
Date now = new Date();
|
|
|
|
if (StringUtils.isEmpty(kakaoVO.getReqDate())) {
|
|
kakaoVO.setReqDate(DATE_FORMATTER.format(now));
|
|
return now;
|
|
}
|
|
return DATE_FORMATTER.parse(kakaoVO.getReqDate());
|
|
}
|
|
|
|
// 2. 친구톡 발송 제한 시간인지 확인
|
|
public boolean isRestrictedFriendTalkTime(Date baseDate) {
|
|
Calendar cal = Calendar.getInstance();
|
|
cal.setTime(baseDate);
|
|
|
|
int hour = cal.get(Calendar.HOUR_OF_DAY);
|
|
int minute = cal.get(Calendar.MINUTE);
|
|
|
|
// 20:50 이후 ~ 익일 08:00 이전은 제한
|
|
if ((hour == 20 && minute >= 50) || hour > 20 || hour < 8) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @methodName : createSendVO
|
|
* @author : 이호영
|
|
* @date : 2025. 3. 19.
|
|
* @description : populateSendLists 반복에 필요한 공통생성 부분
|
|
* @return : KakaoSendAdvcVO
|
|
* @param kakaoVO
|
|
* @return
|
|
*
|
|
*/
|
|
private KakaoSendAdvcVO createATSendVO(KakaoVO kakaoVO) {
|
|
KakaoSendAdvcVO sendVO = new KakaoSendAdvcVO();
|
|
sendVO.setMsgType("8");
|
|
sendVO.setAgentCode("04");
|
|
sendVO.setSenderKey(kakaoVO.getSenderKey());
|
|
sendVO.setTemplateCode(kakaoVO.getTemplateCode());
|
|
sendVO.setUserId(kakaoVO.getUserId());
|
|
sendVO.setCallFrom(kakaoVO.getCallFrom());
|
|
return sendVO;
|
|
}
|
|
|
|
|
|
/**
|
|
* @methodName : createFTSendVO
|
|
* @author : 이호영
|
|
* @date : 2025. 4. 23.
|
|
* @description :
|
|
* @return : KakaoSendAdvcVO
|
|
* @param kakaoVO
|
|
* @return
|
|
*
|
|
*/
|
|
private KakaoSendAdvcVO createFTSendVO(KakaoVO kakaoVO, Calendar calendar) {
|
|
KakaoSendAdvcVO sendVO = new KakaoSendAdvcVO();
|
|
|
|
sendVO.setMsgType("9"); // 알림톡 8 친구톡 9
|
|
sendVO.setAgentCode("04");
|
|
// 발송시간 : 친구톡은 분할 발송이 없어 처음 vo 생성 시 입력
|
|
sendVO.setReqDate(DATE_FORMATTER.format(calendar.getTime()));
|
|
|
|
sendVO.setSenderKey(kakaoVO.getSenderKey());
|
|
sendVO.setTemplateCode(kakaoVO.getTemplateCode());
|
|
sendVO.setUserId(kakaoVO.getUserId());
|
|
sendVO.setCallFrom(kakaoVO.getCallFrom());
|
|
sendVO.setSubMsgSendYn(kakaoVO.getSubMsgSendYn());
|
|
|
|
sendVO.setAdFlag(kakaoVO.getAdFlag());
|
|
|
|
|
|
return sendVO;
|
|
}
|
|
|
|
private List<KakaoButtonVO> replaceButtonLinks(List<KakaoButtonVO> buttonList,
|
|
Map<String, String> variables) {
|
|
|
|
if (buttonList != null) {
|
|
for (KakaoButtonVO button : buttonList) {
|
|
// 각 링크 필드에 대해 치환 수행
|
|
if (button.getLinkAnd() != null) {
|
|
button.setLinkAnd(mjonCommon.ATReplaceTemplateVariables(button.getLinkAnd(), variables));
|
|
}
|
|
if (button.getLinkIos() != null) {
|
|
button.setLinkIos(mjonCommon.ATReplaceTemplateVariables(button.getLinkIos(), variables));
|
|
}
|
|
if (button.getLinkMo() != null) {
|
|
button.setLinkMo(mjonCommon.ATReplaceTemplateVariables(button.getLinkMo(), variables));
|
|
}
|
|
if (button.getLinkPc() != null) {
|
|
button.setLinkPc(mjonCommon.ATReplaceTemplateVariables(button.getLinkPc(), variables));
|
|
}
|
|
}
|
|
// 치환된 버튼 리스트를 sendVO에 반영
|
|
// sendVO.setButtonList(buttonList); // KakaoSendAdvcVO에 setButtonList가 있다고 가정
|
|
}
|
|
|
|
return buttonList;
|
|
}
|
|
|
|
/**
|
|
* 버튼 리스트에 치환 패턴(#{...})이 있는지 확인합니다.
|
|
* @param buttonList 버튼 리스트 (null 가능)
|
|
* @return 치환 패턴이 있으면 true, 없으면 false
|
|
*/
|
|
private boolean needsButtonReplacement(List<KakaoButtonVO> buttonList) {
|
|
if (buttonList == null) {
|
|
return false;
|
|
}
|
|
return buttonList.stream().anyMatch(button ->
|
|
replBooleanStrChecker(button.getLinkAnd()) ||
|
|
replBooleanStrChecker(button.getLinkIos()) ||
|
|
replBooleanStrChecker(button.getLinkMo()) ||
|
|
replBooleanStrChecker(button.getLinkPc())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 입력 문자열에 치환 패턴(#{...})이 있는지 확인합니다.
|
|
* @param input 확인할 문자열 (null 가능)
|
|
* @return 치환 패턴이 있으면 true, 없으면 false
|
|
*/
|
|
private boolean replBooleanStrChecker(String input) {
|
|
// #{...} 패턴을 확인하는 정규 표현식
|
|
if (input == null) {
|
|
return false;
|
|
}
|
|
Matcher matcher = REPLACEMENT_PATTERN.matcher(input);
|
|
return matcher.find();
|
|
}
|
|
|
|
|
|
public static Float getValidPrice(Float personalPrice, Float defaultPrice) {
|
|
return (personalPrice != null && personalPrice > 0) ? personalPrice : defaultPrice;
|
|
}
|
|
|
|
|
|
/**
|
|
* @methodName : getMsgType
|
|
* @author : 이호영
|
|
* @date : 2025. 3. 12.
|
|
* @description : 메세지 타입 구하기
|
|
* @return : String
|
|
* @param smsTxtByte
|
|
* @return
|
|
*
|
|
*/
|
|
private String getMsgType(int smsTxtByte) {
|
|
// TODO Auto-generated method stub
|
|
|
|
String msgType = SHORT_MSG_TYPE;
|
|
|
|
// 1. 2000 Byte 초과는 에러 처리
|
|
if (smsTxtByte > 2000) {
|
|
return "INVALID";
|
|
}
|
|
|
|
// 2. 문자 길이에 따라 메시지 타입 설정 (90 Byte 초과는 장문)
|
|
if (smsTxtByte > 90) {
|
|
msgType = LONG_MSG_TYPE;
|
|
}
|
|
|
|
return msgType;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @Method Name : kakaoSendPrice
|
|
* @작성일 : 2023. 2. 14.
|
|
* @작성자 : WYH
|
|
* @Method 설명 : 카카오 전송 가격 설정
|
|
*/
|
|
public KakaoVO kakaoSendPrice(KakaoVO kakaoVO) throws Exception {
|
|
|
|
System.out.println(" :: kakaoSendPrice :: ");
|
|
|
|
//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
|
|
// String befCash = kakaoVO.getBefCash();
|
|
|
|
MjonMsgVO mjonMsgVO = new MjonMsgVO();
|
|
mjonMsgVO.setUserId(kakaoVO.getUserId());
|
|
String userMoney = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
|
|
String userPoint = mjonMsgDataService.selectBeforePointData(mjonMsgVO);
|
|
|
|
//1.시스템 기본 단가 정보 불러오기
|
|
JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
|
|
|
|
//2.사용자 개인 단가 정보 불러오기
|
|
MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(kakaoVO.getUserId());
|
|
Float kakaoAtPrice = mberManageVO.getKakaoAtPrice();
|
|
|
|
/** 대체문자 여부 체크(있으면 대체문자 가격으로 없으면 카카오톡 가격으로) */
|
|
//대체문자 발송 여부 확인
|
|
System.out.println(" :: kakaoVO.getSubMsgSendYn() :: "+ kakaoVO.getSubMsgSendYn());
|
|
if(kakaoVO.getSubMsgSendYn().equals("Y")) {
|
|
|
|
|
|
String charset = "euc-kr"; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
int callToCnt = kakaoVO.getCallToList().length;
|
|
String sendType = "";
|
|
|
|
for(int count =0; count < callToCnt; count++) {
|
|
String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
if(kakaoVO.getSubMsgTxtReplYn().equals("Y")) {
|
|
tempSubMagTxt = kakaoSubMagTxtRepl(tempSubMagTxt, kakaoVO, count);
|
|
}
|
|
int bytes = tempSubMagTxt.getBytes(charset).length;
|
|
|
|
if(bytes < 2000) {
|
|
if(bytes > 90) {
|
|
sendType = "MMS";
|
|
break;
|
|
}else {
|
|
sendType = "SMS";
|
|
}
|
|
}else {
|
|
kakaoVO.setResultCode("2000");
|
|
return kakaoVO;
|
|
}
|
|
}
|
|
|
|
if(sendType.equals("MMS")) {
|
|
//협의 단가가 없으면 시스템 단가로 지정
|
|
if(mberManageVO.getLongPrice() < 1) {
|
|
kakaoAtPrice = sysJoinSetVO.getLongPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
}else {
|
|
kakaoAtPrice = mberManageVO.getLongPrice();
|
|
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
|
|
if(mberManageVO.getKakaoAtPrice() < 1) {
|
|
kakaoVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
}else {
|
|
kakaoVO.setKakaoAtPrice(mberManageVO.getKakaoAtPrice());
|
|
}
|
|
}
|
|
}else {
|
|
//협의 단가가 없으면 시스템 단가로 지정
|
|
if(mberManageVO.getShortPrice() < 1) {
|
|
kakaoAtPrice = sysJoinSetVO.getShortPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
}else {
|
|
kakaoAtPrice = mberManageVO.getShortPrice();
|
|
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
if(mberManageVO.getKakaoAtPrice() < 1) {
|
|
kakaoVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
}else {
|
|
kakaoVO.setKakaoAtPrice(mberManageVO.getKakaoAtPrice());
|
|
}
|
|
}
|
|
}
|
|
}else {
|
|
if(kakaoAtPrice < 1) { //협의 단가가 없으면 시스템 단가로 지정
|
|
kakaoAtPrice = sysJoinSetVO.getKakaoAtPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
}else {
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
kakaoVO.setKakaoAtPrice(mberManageVO.getKakaoAtPrice());
|
|
}
|
|
}
|
|
|
|
/** 전송인원 확인*/
|
|
int totCallCnt = kakaoVO.getCallToList().length;
|
|
Float kakaoTotPrice = totCallCnt * kakaoAtPrice; // 총결제 금액 = 총 전송수량 * 카카오 알림톡 단가
|
|
String totPrice = kakaoTotPrice.toString();
|
|
System.out.println("@@@@@@@ : "+kakaoTotPrice +" = "+totCallCnt+" * "+kakaoAtPrice);
|
|
|
|
kakaoVO.setEachPrice(kakaoAtPrice.toString());
|
|
kakaoVO.setBefCash(userMoney); // 고객 충전금액
|
|
kakaoVO.setBefPoint(userPoint); // 고객 충전 포인트
|
|
kakaoVO.setTotPrice(totPrice); // 총 카카오 전송 금액
|
|
|
|
return kakaoVO;
|
|
}
|
|
|
|
|
|
/**
|
|
* @Method Name : kakaoFTSendPrice
|
|
* @작성일 : 2024. 1. 17.
|
|
* @작성자 : WYH
|
|
* @Method 설명 : 카카오 친구톡 전송 가격 설정
|
|
*/
|
|
public KakaoVO kakaoFTSendPrice(KakaoVO kakaoVO) throws Exception {
|
|
|
|
//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
|
|
String befCash = kakaoVO.getBefCash();
|
|
|
|
//VO에서 현재 보유금액이 없으면 디비에서 조회해서 불러옴
|
|
if("".equals(befCash) || befCash == null) {
|
|
|
|
}
|
|
MjonMsgVO mjonMsgVO = new MjonMsgVO();
|
|
mjonMsgVO.setUserId(kakaoVO.getUserId());
|
|
String userMoney = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
|
|
String userPoint = mjonMsgDataService.selectBeforePointData(mjonMsgVO);
|
|
|
|
//1.시스템 기본 단가 정보 불러오기
|
|
JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
|
|
|
|
//2.사용자 개인 단가 정보 불러오기
|
|
MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(kakaoVO.getUserId());
|
|
Float kakaoFtPrice = mberManageVO.getKakaoFtPrice();
|
|
|
|
/** 대체문자 여부 체크(있으면 대체문자 가격으로 없으면 카카오톡 가격으로) */
|
|
//대체문자 발송 여부 확인
|
|
if(kakaoVO.getSubMsgSendYn().equals("Y")) {
|
|
|
|
|
|
String charset = "euc-kr"; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
int callToCnt = kakaoVO.getCallToList().length;
|
|
String sendType = "";
|
|
|
|
for(int count =0; count < callToCnt; count++) {
|
|
String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
if(kakaoVO.getSubMsgTxtReplYn().equals("Y")) {
|
|
tempSubMagTxt = kakaoFTSubMagTxtRepl(tempSubMagTxt, kakaoVO, count);
|
|
}
|
|
int bytes = tempSubMagTxt.getBytes(charset).length;
|
|
|
|
if(bytes < 2000) {
|
|
if(bytes > 90) {
|
|
sendType = "MMS";
|
|
break;
|
|
}else {
|
|
sendType = "SMS";
|
|
}
|
|
}else {
|
|
kakaoVO.setResultCode("2000");
|
|
return kakaoVO;
|
|
}
|
|
}
|
|
|
|
if(sendType.equals("MMS")) {
|
|
//협의 단가가 없으면 시스템 단가로 지정
|
|
if(mberManageVO.getLongPrice() < 1) {
|
|
kakaoFtPrice = sysJoinSetVO.getLongPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
}else {
|
|
kakaoFtPrice = mberManageVO.getLongPrice();
|
|
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
|
|
if(mberManageVO.getKakaoFtPrice() < 1) {
|
|
kakaoVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
}else {
|
|
kakaoVO.setKakaoFtPrice(mberManageVO.getKakaoFtPrice());
|
|
}
|
|
}
|
|
}else {
|
|
//협의 단가가 없으면 시스템 단가로 지정
|
|
if(mberManageVO.getShortPrice() < 1) {
|
|
kakaoFtPrice = sysJoinSetVO.getShortPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
}else {
|
|
kakaoFtPrice = mberManageVO.getShortPrice();
|
|
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
|
|
if(mberManageVO.getKakaoFtPrice() < 1) {
|
|
kakaoVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
}else {
|
|
kakaoVO.setKakaoFtPrice(mberManageVO.getKakaoFtPrice());
|
|
}
|
|
}
|
|
}
|
|
}else {
|
|
|
|
if(kakaoFtPrice < 1) { //협의 단가가 없으면 시스템 단가로 지정
|
|
kakaoFtPrice = sysJoinSetVO.getKakaoFtPrice();
|
|
|
|
kakaoVO.setSmsPrice(sysJoinSetVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(sysJoinSetVO.getLongPrice());
|
|
kakaoVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
}else {
|
|
kakaoVO.setSmsPrice(mberManageVO.getShortPrice());
|
|
kakaoVO.setMmsPrice(mberManageVO.getLongPrice());
|
|
kakaoVO.setKakaoFtPrice(mberManageVO.getKakaoFtPrice());
|
|
}
|
|
}
|
|
|
|
/** 전송인원 확인*/
|
|
int totCallCnt = kakaoVO.getCallToList().length;
|
|
Float kakaoTotPrice = totCallCnt * kakaoFtPrice; // 총결제 금액 = 총 전송수량 * 카카오 친구톡 단가
|
|
String totPrice = kakaoTotPrice.toString();
|
|
System.out.println("@@@@@@@ : "+kakaoTotPrice +" = "+totCallCnt+" * "+kakaoFtPrice);
|
|
|
|
kakaoVO.setEachPrice(kakaoFtPrice.toString());
|
|
kakaoVO.setBefCash(userMoney); // 고객 충전금액
|
|
kakaoVO.setBefPoint(userPoint); // 고객 충전 포인트
|
|
kakaoVO.setTotPrice(totPrice); // 총 카카오 전송 금액
|
|
|
|
return kakaoVO;
|
|
}
|
|
|
|
|
|
/**
|
|
* @methodName : selectSendPriceOfKakaoAtAndSmsAndMms
|
|
* @author : 이호영
|
|
* @date : 2023.03.02
|
|
* @description : 알림톡 / sms / mms 가격 불러오기
|
|
* @param String userID
|
|
* @return MberManageVO
|
|
* @throws Exception
|
|
*/
|
|
public MberManageVO selectSendPriceOfKakaoAtAndSmsAndMms(String userId) throws Exception {
|
|
|
|
//1.시스템 기본 단가 정보 불러오기
|
|
JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
|
|
|
|
//2.사용자 개인 단가 정보 불러오기
|
|
MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(userId);
|
|
|
|
// kakao 단가
|
|
// 사용자 개인 단가가 없으면 시스템 단가로
|
|
if(mberManageVO.getKakaoAtPrice() == 0.0f)
|
|
mberManageVO.setKakaoAtPrice(sysJoinSetVO.getKakaoAtPrice());
|
|
|
|
//카카오 친구톡 개인 단가가 없는 경우 시스템 단가로
|
|
if(mberManageVO.getKakaoFtPrice() == 0.0f)
|
|
mberManageVO.setKakaoFtPrice(sysJoinSetVO.getKakaoFtPrice());
|
|
if(mberManageVO.getKakaoFtImgPrice() == 0.0f)
|
|
mberManageVO.setKakaoFtImgPrice(sysJoinSetVO.getKakaoFtImgPrice());
|
|
if(mberManageVO.getKakaoFtWideImgPrice() == 0.0f)
|
|
mberManageVO.setKakaoFtWideImgPrice(sysJoinSetVO.getKakaoFtWideImgPrice());
|
|
|
|
|
|
// SMS 인경우
|
|
// 사용자 개인 단가가 없으면 시스템 단가로
|
|
if(mberManageVO.getShortPrice() == 0.0f)
|
|
mberManageVO.setShortPrice(sysJoinSetVO.getShortPrice());
|
|
|
|
// // MMS 인경우
|
|
// 사용자 개인 단가가 없으면 시스템 단가로
|
|
if(mberManageVO.getLongPrice() == 0.0f)
|
|
mberManageVO.setLongPrice(sysJoinSetVO.getLongPrice());
|
|
|
|
if(mberManageVO.getPicturePrice() == 0.0f)
|
|
mberManageVO.setPicturePrice(sysJoinSetVO.getPicturePrice());
|
|
|
|
return mberManageVO;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @Method Name : kakaoSendMsg
|
|
* @작성일 : 2023. 2. 14.
|
|
* @작성자 : WYH
|
|
* @Method 설명 : 카카오톡 전송 메세지 설정
|
|
*/
|
|
public KakaoVO kakaoSendMsg(KakaoVO kakaoVO) throws Exception {
|
|
List<KakaoVO> kakaoSendList = new ArrayList<KakaoVO>();
|
|
//전체 받는사람 수량만큼 반복 확인
|
|
int callToCnt = kakaoVO.getCallToList().length;
|
|
try {
|
|
for(int count =0; count < callToCnt; count++) {
|
|
|
|
KakaoVO setSendMsgVO = new KakaoVO();
|
|
|
|
setSendMsgVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
// 카카오 전송내용 설정
|
|
// 변환문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getTxtReplYn().equals("Y")) {
|
|
|
|
String templateContent = kakaoSubMagTxtRepl(kakaoVO.getTemplateContent(), kakaoVO, count);
|
|
setSendMsgVO.setTemplateContent(templateContent);
|
|
|
|
if(kakaoVO.getTemplateEmphasizeType().equals("TEXT")) {
|
|
|
|
String title = kakaoSubMagTxtRepl(kakaoVO.getTemplateTitle(), kakaoVO, count);
|
|
String subTitle = kakaoVO.getTemplateSubtitle();
|
|
// title = title +"§§"+ subTitle;
|
|
setSendMsgVO.setTemplateEmphasizeType(kakaoVO.getTemplateEmphasizeType());
|
|
setSendMsgVO.setTemplateTitle(title);
|
|
}
|
|
|
|
}else {
|
|
|
|
if(kakaoVO.getTemplateEmphasizeType().equals("TEXT")) {
|
|
|
|
String title = kakaoSubMagTxtRepl(kakaoVO.getTemplateTitle(), kakaoVO, count);
|
|
String subTitle = kakaoVO.getTemplateSubtitle();
|
|
// title = title +"§§"+ subTitle;
|
|
setSendMsgVO.setTemplateEmphasizeType(kakaoVO.getTemplateEmphasizeType());
|
|
setSendMsgVO.setTemplateTitle(title);
|
|
}
|
|
|
|
// 템플릿 내용 설정
|
|
setSendMsgVO.setTemplateContent(kakaoVO.getTemplateContent());
|
|
}
|
|
|
|
//대체문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getSubMsgSendYn().equals("Y")) {
|
|
|
|
String charset = "euc-kr"; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
|
|
String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
kakaoVO.setKakaoSubMagOrgnlTxt(tempSubMagTxt);
|
|
if(kakaoVO.getSubMsgTxtReplYn().equals("Y")) {
|
|
tempSubMagTxt = kakaoSubMagTxtRepl(tempSubMagTxt, kakaoVO, count);
|
|
}
|
|
System.out.println("@@ 대체문자내용 : " + tempSubMagTxt);
|
|
setSendMsgVO.setSubMsgTxt(tempSubMagTxt);
|
|
|
|
int FrBytes = tempSubMagTxt.getBytes(charset).length;
|
|
System.out.println("@@ 대체문자길이 : " + FrBytes);
|
|
//메세지 길이가 90Byte가 초과시 MMS
|
|
if(FrBytes > 90) {
|
|
setSendMsgVO.setSubMsgType("MMS");
|
|
}else {// 아니면 SMS
|
|
setSendMsgVO.setSubMsgType("SMS");
|
|
}
|
|
|
|
System.out.println("@@ 대체문자타입 : " + setSendMsgVO.getSubMsgType());
|
|
}
|
|
|
|
if(kakaoVO.getBizJsonYn().equals("Y")) {
|
|
kakaoVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
|
|
String[] varValInfo = null;
|
|
if( kakaoVO.getVarValList().size() != 0) {
|
|
varValInfo = kakaoVO.getVarValList().get(count);
|
|
}
|
|
String jsonFileName = kakaoApiJsonSave.kakaoApiJsonSave(kakaoVO, varValInfo);
|
|
setSendMsgVO.setBizJsonName(jsonFileName); //json 파일명
|
|
}
|
|
|
|
kakaoSendList.add(setSendMsgVO);
|
|
}
|
|
kakaoVO.setKakaoSendList(kakaoSendList);
|
|
|
|
} catch (Exception e) {
|
|
System.out.println(e.toString());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return kakaoVO;
|
|
}
|
|
|
|
/**
|
|
* @methodName : kakaoSendMsg_advc
|
|
* @author : 이호영
|
|
* @date : 2025. 3. 13.
|
|
* @description : kakaoSendMsg 개선
|
|
* @return : KakaoVO
|
|
* @param kakaoVO
|
|
* @return
|
|
* @throws Exception
|
|
*
|
|
*/
|
|
public KakaoVO kakaoSendMsg_advc(KakaoVO kakaoVO) throws Exception {
|
|
List<KakaoVO> kakaoSendList = new ArrayList<KakaoVO>();
|
|
//전체 받는사람 수량만큼 반복 확인
|
|
int callToCnt = kakaoVO.getCallToList().length;
|
|
try {
|
|
for(int count =0; count < callToCnt; count++) {
|
|
|
|
KakaoVO setSendMsgVO = new KakaoVO();
|
|
|
|
setSendMsgVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
// 카카오 전송내용 설정
|
|
// 변환문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getTxtReplYn().equals("Y")) {
|
|
|
|
String templateContent = kakaoSubMagTxtRepl(kakaoVO.getTemplateContent(), kakaoVO, count);
|
|
setSendMsgVO.setTemplateContent(templateContent);
|
|
|
|
if(kakaoVO.getTemplateEmphasizeType().equals("TEXT")) {
|
|
|
|
String title = kakaoSubMagTxtRepl(kakaoVO.getTemplateTitle(), kakaoVO, count);
|
|
String subTitle = kakaoVO.getTemplateSubtitle();
|
|
// title = title +"§§"+ subTitle;
|
|
setSendMsgVO.setTemplateEmphasizeType(kakaoVO.getTemplateEmphasizeType());
|
|
setSendMsgVO.setTemplateTitle(title);
|
|
}
|
|
|
|
}else {
|
|
|
|
if(kakaoVO.getTemplateEmphasizeType().equals("TEXT")) {
|
|
|
|
String title = kakaoSubMagTxtRepl(kakaoVO.getTemplateTitle(), kakaoVO, count);
|
|
String subTitle = kakaoVO.getTemplateSubtitle();
|
|
// title = title +"§§"+ subTitle;
|
|
setSendMsgVO.setTemplateEmphasizeType(kakaoVO.getTemplateEmphasizeType());
|
|
setSendMsgVO.setTemplateTitle(title);
|
|
}
|
|
|
|
// 템플릿 내용 설정
|
|
setSendMsgVO.setTemplateContent(kakaoVO.getTemplateContent());
|
|
}
|
|
|
|
//대체문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getSubMsgSendYn().equals("Y")) {
|
|
|
|
String charset = "euc-kr"; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
|
|
String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
kakaoVO.setKakaoSubMagOrgnlTxt(tempSubMagTxt);
|
|
if(kakaoVO.getSubMsgTxtReplYn().equals("Y")) {
|
|
tempSubMagTxt = kakaoSubMagTxtRepl(tempSubMagTxt, kakaoVO, count);
|
|
}
|
|
System.out.println("@@ 대체문자내용 : " + tempSubMagTxt);
|
|
setSendMsgVO.setSubMsgTxt(tempSubMagTxt);
|
|
|
|
int FrBytes = tempSubMagTxt.getBytes(charset).length;
|
|
System.out.println("@@ 대체문자길이 : " + FrBytes);
|
|
//메세지 길이가 90Byte가 초과시 MMS
|
|
if(FrBytes > 90) {
|
|
setSendMsgVO.setSubMsgType("MMS");
|
|
}else {// 아니면 SMS
|
|
setSendMsgVO.setSubMsgType("SMS");
|
|
}
|
|
|
|
System.out.println("@@ 대체문자타입 : " + setSendMsgVO.getSubMsgType());
|
|
}
|
|
|
|
if(kakaoVO.getBizJsonYn().equals("Y")) {
|
|
kakaoVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
|
|
String[] varValInfo = null;
|
|
if( kakaoVO.getVarValList().size() != 0) {
|
|
varValInfo = kakaoVO.getVarValList().get(count);
|
|
}
|
|
String jsonFileName = kakaoApiJsonSave.kakaoApiJsonSave(kakaoVO, varValInfo);
|
|
// String jsonFileName = kakaoApiJsonSave.kakaoApiJsonSave_advc(kakaoVO, varValInfo);
|
|
// String jsonFileName = kakaoApiJsonSave.kakaoApiJsonSave(kakaoVO, kakaoVO.getVarValList().get(count));
|
|
setSendMsgVO.setBizJsonName(jsonFileName); //json 파일명
|
|
}
|
|
|
|
kakaoSendList.add(setSendMsgVO);
|
|
}
|
|
kakaoVO.setKakaoSendList(kakaoSendList);
|
|
|
|
} catch (Exception e) {
|
|
System.out.println(e.toString());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return kakaoVO;
|
|
}
|
|
|
|
|
|
/**
|
|
* @Method Name : kakaoFTSendMsg
|
|
* @작성일 : 2024. 1. 17.
|
|
* @작성자 : 우영두
|
|
* @Method 설명 : 카카오 친톡 전송 메세지 설정
|
|
*/
|
|
public KakaoVO kakaoFTSendMsg(KakaoVO kakaoVO) throws Exception {
|
|
List<KakaoVO> kakaoSendList = new ArrayList<KakaoVO>();
|
|
//전체 받는사람 수량만큼 반복 확인
|
|
int callToCnt = kakaoVO.getCallToList().length;
|
|
try {
|
|
for(int count =0; count < callToCnt; count++) {
|
|
|
|
KakaoVO setSendMsgVO = new KakaoVO();
|
|
|
|
setSendMsgVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
// 카카오 전송내용 설정
|
|
// 변환문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getTxtReplYn().equals("Y")) {
|
|
|
|
String templateContent = kakaoFTSubMagTxtRepl(kakaoVO.getTemplateContent(), kakaoVO, count);
|
|
setSendMsgVO.setTemplateContent(templateContent);
|
|
|
|
}else {
|
|
|
|
// 템플릿 내용 설정
|
|
setSendMsgVO.setTemplateContent(kakaoVO.getTemplateContent());
|
|
}
|
|
|
|
//대체문자 포함(Y), 미포함(N)
|
|
if(kakaoVO.getSubMsgSendYn().equals("Y")) {
|
|
|
|
String charset = "euc-kr"; //문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
|
|
String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
kakaoVO.setKakaoSubMagOrgnlTxt(tempSubMagTxt);
|
|
if(kakaoVO.getSubMsgTxtReplYn().equals("Y")) {
|
|
tempSubMagTxt = kakaoFTSubMagTxtRepl(tempSubMagTxt, kakaoVO, count);
|
|
}
|
|
|
|
setSendMsgVO.setSubMsgTxt(tempSubMagTxt);
|
|
|
|
int FrBytes = tempSubMagTxt.getBytes(charset).length;
|
|
|
|
//메세지 길이가 90Byte가 초과시 MMS
|
|
if(FrBytes > 90) {
|
|
setSendMsgVO.setSubMsgType("MMS");
|
|
}else {// 아니면 SMS
|
|
setSendMsgVO.setSubMsgType("SMS");
|
|
}
|
|
}
|
|
|
|
if(kakaoVO.getBizJsonYn().equals("Y")) {
|
|
kakaoVO.setDestPhone(kakaoVO.getCallToList()[count]); // 수신 번호
|
|
|
|
String[] varValInfo = null;
|
|
if( kakaoVO.getVarValList().size() != 0) {
|
|
varValInfo = kakaoVO.getVarValList().get(count);
|
|
}
|
|
String jsonFileName = kakaoApiJsonSave.kakaoApiFTJsonSave(kakaoVO);
|
|
// String jsonFileName = kakaoApiJsonSave.kakaoApiJsonSave(kakaoVO, kakaoVO.getVarValList().get(count));
|
|
setSendMsgVO.setBizJsonName(jsonFileName); //json 파일명
|
|
}
|
|
|
|
kakaoSendList.add(setSendMsgVO);
|
|
}
|
|
kakaoVO.setKakaoSendList(kakaoSendList);
|
|
|
|
} catch (Exception e) {
|
|
System.out.println(e.toString());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return kakaoVO;
|
|
}
|
|
|
|
|
|
public String kakaoSendMsgTest(KakaoVO kakaoVO) throws Exception {
|
|
String templateContent = "";
|
|
try {
|
|
templateContent = kakaoSubMagTxtRepl(kakaoVO.getTemplateContent(), kakaoVO, 0);
|
|
} catch (Exception e) {
|
|
System.out.println(e.toString());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return templateContent;
|
|
}
|
|
|
|
|
|
public String kakaoSubMagTxtRepl(String tempSubMagTxt, KakaoVO kakaoVO, int count) {
|
|
System.out.println("tempSubMagTxt : "+ tempSubMagTxt);
|
|
|
|
// String tempSubMagTxt = kakaoVO.getSubMsgTxt().replace("\r\n", "\n");
|
|
// String tempSubMagTxt = msgTxt;
|
|
|
|
//대체문자에 변환문자가 있는경우
|
|
String[] varNm = new String[kakaoVO.getVarNmList().size()];
|
|
int q=0;
|
|
if(varNm.length != 0) {
|
|
for(String temp : kakaoVO.getVarNmList()) {
|
|
temp = temp.replaceAll("\\#\\{" , "§§");
|
|
temp = temp.replaceAll("\\}" , "§");
|
|
varNm[q] = temp;
|
|
q++;
|
|
}
|
|
List<String[]> varValList = kakaoVO.getVarValList(); // value 값
|
|
|
|
tempSubMagTxt = tempSubMagTxt.replaceAll(String.valueOf((char)13), "");
|
|
|
|
tempSubMagTxt = tempSubMagTxt.replaceAll("\\#\\{" , "§§");
|
|
tempSubMagTxt = tempSubMagTxt.replaceAll("\\}" , "§");
|
|
|
|
String[] array = varValList.get(count)[0].split("§");
|
|
for(int i=0; i < varNm.length; i++) {
|
|
|
|
if (tempSubMagTxt.indexOf(varNm[i]) > -1) {
|
|
if(array[i] != null) {
|
|
|
|
System.out.println("as : "+varNm[i] +" : "+ StringUtil.getString(array[i]).replace('Ï', ','));
|
|
|
|
tempSubMagTxt = tempSubMagTxt.replaceAll(varNm[i] , StringUtil.getString(array[i]).replace('Ï', ','));
|
|
|
|
System.out.println(varNm[i] +" : "+ array[i].replace('Ï', ','));
|
|
|
|
}else {
|
|
tempSubMagTxt = tempSubMagTxt.replaceAll(varNm[i] , "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return tempSubMagTxt;
|
|
}
|
|
|
|
|
|
public String kakaoFTSubMagTxtRepl(String tempSubMagTxt, KakaoVO kakaoVO, int count) throws Exception{
|
|
|
|
List<String[]> varValList = kakaoVO.getVarValList();
|
|
|
|
tempSubMagTxt = getKakaoFTCntReplace(varValList.get(count)[0], tempSubMagTxt);
|
|
|
|
return tempSubMagTxt;
|
|
}
|
|
|
|
/*
|
|
* 카카오 친구톡 치환 내용에 대한 변환 처리
|
|
*
|
|
*
|
|
* */
|
|
public String getKakaoFTCntReplace(String varValStr, String contents) throws Exception{
|
|
|
|
String[] array = varValStr.split("¶");
|
|
String tmpContents = contents;
|
|
for(int j=0; j < array.length; j++) {
|
|
String tmpVarVal = array[j].replaceAll("§", ",");
|
|
if(tmpVarVal.length() > 0) {
|
|
|
|
if(tmpContents.contains("#{이름}") && j == 0) {
|
|
tmpContents = tmpContents.replaceAll("\\#\\{이름\\}", tmpVarVal);
|
|
}
|
|
|
|
//1번째에 핸드폰 번호가 포함 되어 있어서 건너뜀
|
|
|
|
if(tmpContents.contains("#{1}") && j == 2) {
|
|
tmpContents = tmpContents.replaceAll("\\#\\{1\\}", tmpVarVal);
|
|
}
|
|
|
|
if(tmpContents.contains("#{2}") && j == 3) {
|
|
tmpContents = tmpContents.replaceAll("\\#\\{2\\}", tmpVarVal);
|
|
}
|
|
|
|
if(tmpContents.contains("#{3}") && j == 4) {
|
|
tmpContents = tmpContents.replaceAll("\\#\\{3\\}", tmpVarVal);
|
|
}
|
|
|
|
if(tmpContents.contains("#{4}") && j == 5) {
|
|
tmpContents = tmpContents.replaceAll("\\#\\{4\\}", tmpVarVal);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return tmpContents;
|
|
}
|
|
|
|
/*
|
|
* 카카오 친구톡 치환문자 내용 스팸 필터
|
|
* 치환변수 내용 및 템플릿 내용, 스팸필터 단어 리스트를 전달하면 스팸 문구 포함 문구 리턴
|
|
* 없으면 공백을 리턴
|
|
*
|
|
* */
|
|
public String getKakaoFTCntRepToSpamFilter(List<String[]> varValList, List<String> resultSpamTxt, String contents) throws Exception {
|
|
String spmFilterTxt = "";
|
|
for(int i=0; i < varValList.size(); i++) {
|
|
|
|
String tmpContents = getKakaoFTCntReplace(varValList.get(i)[0], contents);
|
|
|
|
//입력 문장에 대해서 우회 문장 또는 특수 기호 입력 제거 등 문장 재구성 처리, 한글 자모음 분리 및 재조함도 함께 처리함.
|
|
String resultParser = ComGetSpamStringParser.getSpamTextParse(tmpContents).trim();
|
|
//List<String> jasoList = HangulParser.disassemble(resultParser);
|
|
//String assembleStr = HangulParser.assemble(jasoList);
|
|
|
|
//데이터베이스에 등록된 스팸문구와 일치하는 단어/문구가 있는지 체크함.
|
|
int spmCnt = 0;
|
|
for(String spmTxt : resultSpamTxt) {
|
|
|
|
String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
|
|
|
|
if(resultParser.contains(parserStr)) {
|
|
|
|
//스팸 단어/문구가 있으면 콤마로 연결시킨 후 리턴해줌.
|
|
spmFilterTxt += spmTxt + ",";
|
|
spmCnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(spmCnt > 0) {//스팸문자가 포함되어 있으면 문자열 끝 , 단어 삭제 처리
|
|
|
|
if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
|
|
// 처음부터 idx 만큼 잘라낸 나머지 글자
|
|
spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1);
|
|
|
|
}
|
|
|
|
System.out.println("++++++++++++++ spmFilterTxt ::: "+spmFilterTxt);
|
|
|
|
return spmFilterTxt;
|
|
|
|
}
|
|
|
|
}
|
|
return "";
|
|
}
|
|
|
|
/*
|
|
* 치환문자가 없는 내용에 대한 스팸필터링 처리
|
|
*
|
|
* */
|
|
public String getKakaoFTCntToSpamFilter(List<String> resultSpamTxt, String contents) throws Exception {
|
|
String spmFilterTxt = "";
|
|
//for(int i=0; i < varValList.size(); i++) {
|
|
//String[] array = varValList.get(i)[0].split("¶");
|
|
String tmpContents = contents;
|
|
System.out.println(tmpContents);
|
|
|
|
//입력 문장에 대해서 우회 문장 또는 특수 기호 입력 제거 등 문장 재구성 처리, 한글 자모음 분리 및 재조함도 함께 처리함.
|
|
String resultParser = ComGetSpamStringParser.getSpamTextParse(tmpContents).trim();
|
|
//List<String> jasoList = HangulParser.disassemble(resultParser);
|
|
//String assembleStr = HangulParser.assemble(jasoList);
|
|
|
|
System.out.println("++++++++++++++ spam resultParser ::: "+resultParser);
|
|
|
|
//데이터베이스에 등록된 스팸문구와 일치하는 단어/문구가 있는지 체크함.
|
|
int spmCnt = 0;
|
|
for(String spmTxt : resultSpamTxt) {
|
|
|
|
String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
|
|
|
|
if(resultParser.contains(parserStr)) {
|
|
|
|
//스팸 단어/문구가 있으면 콤마로 연결시킨 후 리턴해줌.
|
|
spmFilterTxt += spmTxt + ",";
|
|
spmCnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(spmCnt > 0) {//스팸문자가 포함되어 있으면 문자열 끝 , 단어 삭제 처리
|
|
|
|
if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
|
|
// 처음부터 idx 만큼 잘라낸 나머지 글자
|
|
spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1);
|
|
|
|
}
|
|
|
|
System.out.println("++++++++++++++ spmFilterTxt ::: "+spmFilterTxt);
|
|
|
|
return spmFilterTxt;
|
|
|
|
}
|
|
|
|
//}
|
|
return "";
|
|
}
|
|
|
|
public static void statusResponseSet (StatusResponse statusResponse, HttpStatus httpStatus, String msg ) {
|
|
statusResponse.setStatus(httpStatus);
|
|
statusResponse.setMessage(msg);
|
|
|
|
}
|
|
|
|
|
|
// 보유 금액이 충분한지 확인하는 메서드
|
|
public boolean isCashSufficient(String userId, List<KakaoSendAdvcVO> kakaoSendAdvcListVO) throws Exception {
|
|
|
|
|
|
String userMoney = priceAndPoint.getBefCash(userId);
|
|
// 쉼표 제거
|
|
userMoney = userMoney.replace(",", "");
|
|
|
|
|
|
// 사용자 보유 금액 BigDecimal 변환 (HALF_EVEN 적용)
|
|
BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN);
|
|
log.info(" + userMoney :: [{}]", userMoney);
|
|
log.info(" + befCash :: [{}]", befCash);
|
|
|
|
|
|
// 총 메시지 금액 계산 (HALF_EVEN 적용)
|
|
BigDecimal totalEachPrice = kakaoSendAdvcListVO.stream()
|
|
.map(msg -> new BigDecimal(String.valueOf(msg.getEachPrice()))) // 변환 오류 방지
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
.setScale(2, RoundingMode.HALF_EVEN); // 일관성 유지
|
|
|
|
log.info(" + totalEachPrice :: [{}]", totalEachPrice);
|
|
// 비교 수행
|
|
return befCash.compareTo(totalEachPrice) >= 0;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @methodName : insertKakaoAtDataJsonInfo_advc
|
|
* @author : 이호영
|
|
* @date : 2025. 4. 24.
|
|
* @description : INSERT INTO BIZ_ATTACHMENTS
|
|
* @return : void
|
|
* @param kakaoSendAdvcListVO
|
|
*
|
|
*/
|
|
public void insertKakaoAtDataJsonInfo_advc(List<KakaoSendAdvcVO> kakaoSendAdvcListVO) {
|
|
|
|
List<KakaoSendAdvcVO> jsonInfoData = new ArrayList<>(kakaoSendAdvcListVO);
|
|
jsonInfoData.removeIf(t -> StringUtils.isBlank(t.getJsonStr()));
|
|
log.info(" + jsonInfoData Insert :: [{}]", jsonInfoData.size());
|
|
if(jsonInfoData.size() > 0) {
|
|
kakaoAlimTalkDAO.insertKakaoAtDataJsonInfo_advc(jsonInfoData);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @methodName : insertKakaoData_advc
|
|
* @author : 이호영
|
|
* @date : 2025. 3. 20.
|
|
* @description : 카카오 batch 발송 => mj_msg_data
|
|
* @return : int
|
|
* @param kakaoSendAdvcVOList
|
|
* @param parentLoopCount
|
|
* @param isJsonNotEmpty
|
|
* @param isJsonNameAllSame
|
|
* @return
|
|
*
|
|
*/
|
|
public int insertKakaoData_advc(List<KakaoSendAdvcVO> kakaoSendAdvcVOList) {
|
|
|
|
|
|
// 시작 시간 측정
|
|
long totalStartTime = System.currentTimeMillis();
|
|
|
|
int totalSize = kakaoSendAdvcVOList.size(); // 총 데이터 개수
|
|
// Batch 크기 설정 (고정값)
|
|
// int batchSize = 10000; 465
|
|
int batchSize = 50000; // 9분 18초
|
|
|
|
log.info("총 데이터 개수 :: [{}] ", totalSize);
|
|
log.info("설정된 Batch 크기 :: [{}] ", batchSize);
|
|
|
|
// 총 insert 카운트
|
|
int instCnt = 0;
|
|
int batchCount = 0;
|
|
|
|
// 각 배치별 실행 시간 기록
|
|
List<Double> batchExecutionTimes = new ArrayList<>();
|
|
|
|
|
|
// 첫 번째 배치에서만 삽입했는지 추적하는 플래그
|
|
for (int i = 0; i < totalSize; i += batchSize) {
|
|
// Batch 시작 시간 측정
|
|
long batchStartTime = System.currentTimeMillis();
|
|
|
|
// Batch 리스트 생성
|
|
List<KakaoSendAdvcVO> batchList = kakaoSendAdvcVOList.subList(i, Math.min(i + batchSize, totalSize));
|
|
System.out.println("Batch 시작 인덱스: " + i);
|
|
|
|
// mj_msg_data 테이블 insert
|
|
int insertedCount = kakaoAlimTalkDAO.insertKakaoAtDataInfo_advc(batchList);
|
|
|
|
/** @kakaoSendUtil.populateSendLists
|
|
* 하단에서
|
|
* getJsonStr 데이터 처리 후 활용
|
|
* */
|
|
instCnt += insertedCount;
|
|
|
|
// Batch 종료 시간 측정 및 실행 시간 계산
|
|
long batchEndTime = System.currentTimeMillis();
|
|
double batchExecutionTimeInSeconds = (batchEndTime - batchStartTime) / 1000.0;
|
|
|
|
// 실행 시간 기록
|
|
batchExecutionTimes.add(batchExecutionTimeInSeconds);
|
|
batchCount++;
|
|
}
|
|
|
|
// 종료 시간 측정
|
|
long totalEndTime = System.currentTimeMillis();
|
|
|
|
// 총 실행 시간 계산 (밀리초 -> 초로 변환)
|
|
double totalExecutionTimeInSeconds = (totalEndTime - totalStartTime) / 1000.0;
|
|
|
|
// 실행 시간 출력
|
|
log.info("총 배치 실행 횟수 :: [{}] ", batchCount);
|
|
log.info("batchSize :: [{}] ", batchSize);
|
|
log.info("총 실행 시간 :: [{}] ", totalExecutionTimeInSeconds + "초");
|
|
log.info("총 삽입 건수 :: [{}] ", instCnt);
|
|
|
|
// 각 배치별 실행 시간 출력
|
|
for (int k = 0; k < batchExecutionTimes.size(); k++) {
|
|
System.out.println("배치 " + (k + 1) + " 실행 시간 :: " + batchExecutionTimes.get(k) + "초");
|
|
}
|
|
|
|
return instCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void insertKakaoGroupDataTb_advc(int instCnt, KakaoVO kakaoVO, KakaoSendAdvcVO sendVO) throws Exception {
|
|
// TODO Auto-generated method stub
|
|
|
|
// log.info(" + insertKakaoGroupDataTb_advc kakaoVO :: \n[{}]", kakaoVO.toString());;
|
|
// log.info(" + insertKakaoGroupDataTb_advc kakaoSendAdvcVOList :: \n[{}]", sendVO.toString());
|
|
|
|
|
|
|
|
sendVO.setTemplateContent(kakaoVO.getTemplateContent());
|
|
sendVO.setMsgGroupCnt(Integer.toString(instCnt));
|
|
sendVO.setReserveYn(kakaoVO.getReserveYn());
|
|
sendVO.setBefCash(priceAndPoint.getBefCash(sendVO.getUserId()));
|
|
sendVO.setBefPoint(priceAndPoint.getBefPoint(sendVO.getUserId()));
|
|
sendVO.setAdFlag(kakaoVO.getAdFlag());
|
|
|
|
Float eachPrice = Float.parseFloat(sendVO.getEachPrice());
|
|
|
|
Float totPrice = eachPrice * instCnt;
|
|
sendVO.setTotPrice(String.format("%.1f", totPrice));
|
|
|
|
sendVO.setAtDelayYn(kakaoVO.getAtDelayYn());
|
|
sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt());
|
|
sendVO.setBizKakaoResendType(sendVO.getSubMsgType());
|
|
sendVO.setBizKakaoImageType(kakaoVO.getImageType());
|
|
|
|
kakaoAlimTalkDAO.insertKakaoGroupDataTb_advc(sendVO);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|