diff --git a/src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java b/src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java index b4513d7a..ef3278b4 100644 --- a/src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java +++ b/src/main/java/itn/let/kakao/admin/kakaoAt/web/MjonKakaoATController.java @@ -796,9 +796,16 @@ public class MjonKakaoATController { String lastUpdtPnttm = resultChannelList.get(i).getLastUpdtPnttm(); kakaoProfileVO.setSenderKey(senderKey); kakaoProfileVO.setProfileId(profileId); - - KakaoReturnVO tmpProfileVO = kakaoApiProfile.kakaoApiProfileList(kakaoProfileVO); - + KakaoReturnVO tmpProfileVO = null; +// try { +// +// tmpProfileVO = kakaoApiProfile.kakaoApiProfileList(kakaoProfileVO); +// } catch (Exception e) { +// e.printStackTrace(); +// // TODO: handle exception +// } + + tmpProfileVO = kakaoApiProfile.kakaoApiProfileList(kakaoProfileVO); ChannelIDVO returnChannelVO = new ChannelIDVO(); returnChannelVO.setSenderKey(tmpProfileVO.getSenderKey()); diff --git a/src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java b/src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java index 480cf85a..54a7331e 100644 --- a/src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java +++ b/src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java @@ -83,7 +83,7 @@ public class KakaoSendAdvcVO implements Serializable { "\n , msgType=[" + msgType + "]" + "\n , templateContent=[" + templateContent + "]" + "\n , templateTitle=[" + templateTitle + "]" + - "\n , buttonList=[" + buttonList.toString() + "]" + + "\n , buttonList=[" + (buttonList != null ? buttonList.toString() : "") + "]" + "\n , subMsgSendYn=[" + subMsgSendYn + "]" + "\n , subMsgTxt=[" + subMsgTxt + "]" + "\n , subMsgType=[" + subMsgType + "]" + diff --git a/src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java b/src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java index b3e10af4..e2387ece 100644 --- a/src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java +++ b/src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java @@ -1,6 +1,8 @@ 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; @@ -28,6 +30,7 @@ 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; @@ -44,6 +47,9 @@ public class KakaoSendUtil { @Autowired KakaoApiJsonSave kakaoApiJsonSave; + + @Resource(name="kakaoAlimTalkDAO") + private KakaoAlimTalkDAO kakaoAlimTalkDAO; @Resource(name = "MjonMsgDataService") private MjonMsgDataService mjonMsgDataService; @@ -57,6 +63,7 @@ public class KakaoSendUtil { @Autowired private MjonCommon mjonCommon; + // 클래스 수준에서 정적 Pattern 정의 (성능 최적화) private static final Pattern REPLACEMENT_PATTERN = Pattern.compile("#\\{[^}]+\\}"); @@ -142,7 +149,7 @@ public class KakaoSendUtil { log.info(""); /** @공통 기본값 */ - KakaoSendAdvcVO sendVO = createSendVO(kakaoVO); + KakaoSendAdvcVO sendVO = createATSendVO(kakaoVO); String msgId = idList.get(i); sendVO.setMsgId(msgId); @@ -293,33 +300,16 @@ public class KakaoSendUtil { //사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액) // String befCash = kakaoVO.getBefCash(); - + log.info(" [{}]", kakaoVO.ftToString()); List kakaoSendAdvcListVO = new ArrayList<>(); Calendar calendar = setupBaseDate(kakaoVO, isNotified); - - String templateContent = kakaoVO.getTemplateContent(); // 친구톡 내용 -// kakaoVO.setTemplateContent(templateContent); -// String templateTitle = templateDetail.getTemplateTitle(); - - -// log.info(" + templateDetail :: [{}]", templateDetail); -// templateDetail.getButtonList().forEach(t->log.info(" + ButtonList :: [{}]", t.toString())); - - Boolean hasContentReplacement = this.replBooleanStrChecker(templateContent); -// Boolean hasTitleReplacement = this.replBooleanStrChecker(templateTitle); -// Boolean hasButtonReplacement = this.needsButtonReplacement(templateDetail.getButtonList()); - - /** @jsonStr 필요유무 */ - boolean hasTitleOrButtons = CollectionUtils.isNotEmpty(kakaoVO.getButtonVOList()); - - /** @jsonStr 반복유무 */ -// boolean needsJsonReplacement = hasTitleReplacement || hasButtonReplacement; - String sharedJsonStr = null; - - String subMsgTxt = kakaoVO.getSubMsgTxt(); // 실패 대체 문자 + // 친구톡 내용 + String templateContent = kakaoVO.getTemplateContent(); + // 실패 대체 문자 + String subMsgTxt = kakaoVO.getSubMsgTxt(); // 시스템 기본 단가 정보 불러오기 JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo(); @@ -327,14 +317,15 @@ public class KakaoSendUtil { MberManageVO mberManageVO = mjonMsgDataService.selectMberManageInfo(kakaoVO.getUserId()); - String smsTxtTemp = templateContent; + // 치환 문구가 있는지 확인 Boolean replaceYN = MsgSendUtils.getReplaceYN(templateContent); + Boolean replaceSubYN = MsgSendUtils.getReplaceYN(subMsgTxt); boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어 /** @MSGID KEY값 */ - List idList = mjonCommon.getNextCustomMsgCId(kakaoVO.getVarListMap().size()); + List idList = mjonCommon.getNextCustomMsgCId(kakaoVO.getMjonFTSendVOList().size()); Map> placeholders = new HashMap<>(); @@ -345,97 +336,114 @@ public class KakaoSendUtil { placeholders.put("[*4*]", MjonFTSendVO::getRep4); + // 친구통 금액 + Float kakaoFtPrice = mberManageVO.getKakaoFtPrice(); + + // 대체문자가 있을경우 사용 + float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice()); + float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice()); + + String shortPStr = Float.toString(shortPrice); + String mmsPStr = Float.toString(longPrice); + + + /** @jsonStr 필요유무 */ + boolean hasTitleOrButtons = CollectionUtils.isNotEmpty(kakaoVO.getButtonVOList()); + String sharedJsonStr = null; + + - String msgTypeResult = null; List mjonFTSendVOList = kakaoVO.getMjonFTSendVOList(); // 분할 건수 카운터 int counter = 0; - for (MjonFTSendVO sendVO : mjonFTSendVOList) { - KakaoSendAdvcVO kakaoSendAdvcVO = new KakaoSendAdvcVO(); - - kakaoSendAdvcVO.setCallFrom(kakaoVO.getCallFrom()); - kakaoSendAdvcVO.setCallTo(sendVO.getPhone()); - kakaoSendAdvcVO.setUserId(kakaoVO.getUserId()); + for (int i = 0; i < mjonFTSendVOList.size(); i++) { + MjonFTSendVO mjonFTSendVO = mjonFTSendVOList.get(i); - String smsTxt = smsTxtTemp; + KakaoSendAdvcVO sendVO = createFTSendVO(kakaoVO, calendar); + // 공통 가격 설정 + sendVO.setSmsPrice(shortPStr); + sendVO.setMmsPrice(mmsPStr); + + sendVO.setCallTo(mjonFTSendVO.getPhone()); + sendVO.setMsgId(idList.get(i)); + + String smsTxt = templateContent; // 치환 문자면 if(replaceYN) { // 각 치환 구문을 확인하고 치환할 값이 없으면 오류 반환 for (Map.Entry> entry : placeholders.entrySet()) { String placeholder = entry.getKey(); - String value = entry.getValue().apply(sendVO); -// log.info(" + smsTxtTemp [{}]", smsTxtTemp); -// log.info(" + placeholder [{}]", placeholder); -// log.info(" + value [{}]", value); -// log.info(" + smsTxtTemp.contains(placeholder) [{}]", smsTxtTemp.contains(placeholder)); + String value = entry.getValue().apply(mjonFTSendVO); if (smsTxt.contains(placeholder)) { if (StringUtils.isEmpty(value)) { statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다."); - return false; + return null; } smsTxt = smsTxt.replace(placeholder, value); -// log.info(" + smsTxt [{}]", smsTxt); - } } } - - String smsSpamChkTxt = smsTxt; - if(StringUtils.isNotEmpty(smsTxt)) { - smsSpamChkTxt = smsTxt.replaceAll(String.valueOf((char) 13), ""); - } - + sendVO.setTemplateContent(smsTxt); - // == 치환 여부에 따라 처리 로직 분기 == - // 치환 문자가 아닌 경우 - if (!replaceYN) { - if (!hasPerformedMsgType) { - msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); - if ("INVALID".equals(msgTypeResult)) { - statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); - return null; + + String subMsgTxtTemp = null; + + if(StringUtils.isNotEmpty(subMsgTxt)) { + subMsgTxtTemp = subMsgTxt; + + // 각 치환 구문을 확인하고 치환할 값이 없으면 오류 반환 + for (Map.Entry> 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); } - hasPerformedMsgType = true; - } - } - else - {// 치환 문자인 경우 - - // 메시지 타입 체크는 매번 수행 - msgTypeResult = getMsgTypeWithByteValidation(sendVO, smsTxt); - if ("INVALID".equals(msgTypeResult)) { - statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다."); - return null; } } + sendVO.setSubMsgTxt(subMsgTxtTemp); - - - kakaoSendAdvcVO.setTemplateContent(smsTxt); - kakaoSendAdvcVO.setMsgType(msgTypeResult); - - + //대체문자가 있으면 + // Step 1-4: 실패 대체 문자 치환데이터 설정 + if(StringUtils.isNotEmpty(subMsgTxtTemp)) { // 대체문자가 있나? + int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxtTemp); + String sendType = getMsgType(smsTxtByte); + sendVO.setSubMsgType(sendType); - - // 예약 여부 확인 - if ("Y".equalsIgnoreCase(kakaoVO.getReserveYn()) - && "Y".equalsIgnoreCase(kakaoVO.getDivideChk()) - && counter == Integer.parseInt(kakaoVO.getDivideCnt())) - { - counter = 0; - calendar.add(Calendar.MINUTE, Integer.parseInt(kakaoVO.getDivideTime())); + if ("INVALID".equals(sendType)) { + statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");return kakaoSendAdvcListVO; + } + + boolean isMms = "MMS".equals(sendType); + sendVO.setEachPrice(isMms ? mmsPStr : shortPStr); + sendVO.setSubMsgTxt(subMsgTxt);// 실패 + }else { + kakaoFtPrice = getValidPrice(mberManageVO.getKakaoAtPrice(), sysJoinSetVO.getKakaoAtPrice()); + sendVO.setEachPrice( Float.toString(kakaoFtPrice) ); } - counter++; - // 즉시 발송인경우 현재 시간 - // 예약인 경우 위에 설정한 시간 입력 - kakaoSendAdvcVO.setReqDate(DATE_FORMATTER.format(calendar.getTime())); - kakaoSendAdvcListVO.add(kakaoSendAdvcVO); + + // 타이틀과 버튼이 있고 + if(hasTitleOrButtons) { + // + 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()); } @@ -508,14 +516,40 @@ public class KakaoSendUtil { * @return * */ - private KakaoSendAdvcVO createSendVO(KakaoVO kakaoVO) { + 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()); return sendVO; } @@ -1401,4 +1435,165 @@ public class KakaoSendUtil { statusResponse.setMessage(msg); } + + + // 보유 금액이 충분한지 확인하는 메서드 + public boolean isCashSufficient(String userId, List kakaoSendAdvcListVO) throws Exception { + + + String userMoney = priceAndPoint.getBefCash(userId); + // 쉼표 제거 + userMoney = userMoney.replace(",", ""); + + // 사용자 보유 금액 BigDecimal 변환 (HALF_EVEN 적용) + BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN); + + // 총 메시지 금액 계산 (HALF_EVEN 적용) + BigDecimal totalEachPrice = kakaoSendAdvcListVO.stream() + .map(msg -> new BigDecimal(String.valueOf(msg.getEachPrice()))) // 변환 오류 방지 + .reduce(BigDecimal.ZERO, BigDecimal::add) + .setScale(2, RoundingMode.HALF_EVEN); // 일관성 유지 + + // 비교 수행 + 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 kakaoSendAdvcListVO) { + + List 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 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 batchExecutionTimes = new ArrayList<>(); + + + // 첫 번째 배치에서만 삽입했는지 추적하는 플래그 + for (int i = 0; i < totalSize; i += batchSize) { + // Batch 시작 시간 측정 + long batchStartTime = System.currentTimeMillis(); + + // Batch 리스트 생성 + List 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.setMsgGroupCnt(Integer.toString(instCnt)); + sendVO.setReserveYn(kakaoVO.getReserveYn()); + sendVO.setBefCash(priceAndPoint.getBefCash(sendVO.getUserId())); + sendVO.setBefPoint(priceAndPoint.getBefPoint(sendVO.getUserId())); + + Float eachPrice = Float.parseFloat(sendVO.getEachPrice()); + + Float totPrice = eachPrice * instCnt; + sendVO.setTotPrice(String.format("%.1f", totPrice)); + + sendVO.setAtDelayYn(kakaoVO.getAtSmishingYn()); + sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt()); + sendVO.setBizKakaoResendType(sendVO.getSubMsgType()); + + kakaoAlimTalkDAO.insertKakaoGroupDataTb_advc(sendVO); + + } + + + } diff --git a/src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java b/src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java index 5b742f52..db393fb5 100644 --- a/src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java +++ b/src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java @@ -344,6 +344,7 @@ public class KakaoVO extends MjonMsgVO{ sb.append("\n , subMsgSendYn=[").append(subMsgSendYn).append("]"); sb.append("\n , subMsgTxtReplYn=[").append(subMsgTxtReplYn).append("]"); sb.append("\n , subMsgType=[").append(subMsgType).append("]"); + sb.append("\n , subMsgTxt=[").append(subMsgTxt).append("]"); sb.append("\n , reserveYn=[").append(getReserveYn()).append("]"); sb.append("\n , menuTopTab=[").append(menuTopTab).append("]"); sb.append("\n , bizJsonYn=[").append(bizJsonYn).append("]"); diff --git a/src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiJsonSave.java b/src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiJsonSave.java index a1127285..bc505002 100644 --- a/src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiJsonSave.java +++ b/src/main/java/itn/let/kakao/kakaoComm/kakaoApi/KakaoApiJsonSave.java @@ -10,6 +10,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.springframework.beans.factory.annotation.Autowired; @@ -246,12 +247,12 @@ public class KakaoApiJsonSave { JSONObject templateImageExtInfo = new JSONObject(); String imageType = kakaoVO.getImageType(); - if(!imageType.equals("")) { + if(StringUtils.isNotEmpty(imageType)) { templateImageInfo.put("img_url", kakaoVO.getTemplateImageUrl()); templateImageInfo.put("img_link", kakaoVO.getImgLink()); } - if(imageType.equals("W")) { + if("W".equals(imageType)) { templateImageExtInfo.put("wide", "Y"); } diff --git a/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java b/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java index cef9cf34..4d62cb43 100644 --- a/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java +++ b/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java @@ -913,7 +913,7 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements /** @전송금액 확인 --------------------------------------------------*/ - if (!isCashSufficient(userId, kakaoSendAdvcListVO)) { + if (!kakaoSendUtil.isCashSufficient(userId, kakaoSendAdvcListVO)) { log.error("Insufficient balance for message sending."); return new StatusResponse(HttpStatus.BAD_REQUEST, "문자 발송에 필요한 보유 잔액이 부족 합니다."); } @@ -921,7 +921,8 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements /** @json파일이 있을 떄 biz_attachments insert */ - this.insertKakaoAtDataJsonInfo_advc(kakaoSendAdvcListVO); + kakaoSendUtil.insertKakaoAtDataJsonInfo_advc(kakaoSendAdvcListVO); +// this.insertKakaoAtDataJsonInfo_advc(kakaoSendAdvcListVO); Map> priceGroupedMessages = kakaoSendAdvcListVO.stream() @@ -941,7 +942,7 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements // 발송 데이터 삽입 - int instCnt = this.insertKakaoData_advc(groupedMsgList); + int instCnt = kakaoSendUtil.insertKakaoData_advc(groupedMsgList); // int instCnt = 6; if(instCnt > 0) { @@ -951,7 +952,7 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements KakaoSendAdvcVO sendVO = groupedMsgList.get(0); /** @groupData 테이블 insert */ - this.insertKakaoGroupDataTb_advc(instCnt, kakaoVO, sendVO); + kakaoSendUtil.insertKakaoGroupDataTb_advc(instCnt, kakaoVO, sendVO); /** @biz_kakao_price에 insert (대체문자 환불관련 테이블)*/ @@ -1032,146 +1033,26 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements - private void insertKakaoAtDataJsonInfo_advc(List kakaoSendAdvcListVO) { - // TODO Auto-generated method stub - - // 측정할 메소드 호출 전 시간 기록 - List 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); - } - - } - - private 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.setMsgGroupCnt(Integer.toString(instCnt)); - sendVO.setReserveYn(kakaoVO.getReserveYn()); - sendVO.setBefCash(priceAndPoint.getBefCash(sendVO.getUserId())); - sendVO.setBefPoint(priceAndPoint.getBefPoint(sendVO.getUserId())); - - Float eachPrice = Float.parseFloat(sendVO.getEachPrice()); - - Float totPrice = eachPrice * instCnt; - sendVO.setTotPrice(String.format("%.1f", totPrice)); - - sendVO.setAtDelayYn(kakaoVO.getAtSmishingYn()); - sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt()); - sendVO.setBizKakaoResendType(sendVO.getSubMsgType()); - - kakaoAlimTalkDAO.insertKakaoGroupDataTb_advc(sendVO); - - } - - /** - * @methodName : insertKakaoData_advc - * @author : 이호영 - * @date : 2025. 3. 20. - * @description : 카카오 batch 발송 => mj_msg_data - * @return : int - * @param kakaoSendAdvcVOList - * @param parentLoopCount - * @param isJsonNotEmpty - * @param isJsonNameAllSame - * @return - * - */ - private int insertKakaoData_advc(List 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 batchExecutionTimes = new ArrayList<>(); - - - // 첫 번째 배치에서만 삽입했는지 추적하는 플래그 - for (int i = 0; i < totalSize; i += batchSize) { - // Batch 시작 시간 측정 - long batchStartTime = System.currentTimeMillis(); - - // Batch 리스트 생성 - List 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; - - } - - // 보유 금액이 충분한지 확인하는 메서드 - private boolean isCashSufficient(String userId, List kakaoSendAdvcListVO) throws Exception { - - - String userMoney = priceAndPoint.getBefCash(userId); - // 쉼표 제거 - userMoney = userMoney.replace(",", ""); - - // 사용자 보유 금액 BigDecimal 변환 (HALF_EVEN 적용) - BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN); - - // 총 메시지 금액 계산 (HALF_EVEN 적용) - BigDecimal totalEachPrice = kakaoSendAdvcListVO.stream() - .map(msg -> new BigDecimal(String.valueOf(msg.getEachPrice()))) // 변환 오류 방지 - .reduce(BigDecimal.ZERO, BigDecimal::add) - .setScale(2, RoundingMode.HALF_EVEN); // 일관성 유지 - - // 비교 수행 - return befCash.compareTo(totalEachPrice) >= 0; - } +// // 보유 금액이 충분한지 확인하는 메서드 +// private boolean isCashSufficient(String userId, List kakaoSendAdvcListVO) throws Exception { +// +// +// String userMoney = priceAndPoint.getBefCash(userId); +// // 쉼표 제거 +// userMoney = userMoney.replace(",", ""); +// +// // 사용자 보유 금액 BigDecimal 변환 (HALF_EVEN 적용) +// BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN); +// +// // 총 메시지 금액 계산 (HALF_EVEN 적용) +// BigDecimal totalEachPrice = kakaoSendAdvcListVO.stream() +// .map(msg -> new BigDecimal(String.valueOf(msg.getEachPrice()))) // 변환 오류 방지 +// .reduce(BigDecimal.ZERO, BigDecimal::add) +// .setScale(2, RoundingMode.HALF_EVEN); // 일관성 유지 +// +// // 비교 수행 +// return befCash.compareTo(totalEachPrice) >= 0; +// } diff --git a/src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java b/src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java index 89e0f1e7..8d118f6b 100644 --- a/src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java +++ b/src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java @@ -1,9 +1,12 @@ package itn.let.kakao.user.kakaoFt.service.impl; +import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -20,9 +23,13 @@ import itn.com.utl.fcc.service.EgovStringUtil; import itn.let.kakao.kakaoComm.KakaoSendAdvcVO; import itn.let.kakao.kakaoComm.KakaoSendUtil; import itn.let.kakao.kakaoComm.KakaoVO; +import itn.let.kakao.user.kakaoAt.service.impl.KakaoAlimTalkDAO; import itn.let.kakao.user.kakaoFt.service.KakaoFriendsTalkService; 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.module.base.PriceAndPoint; import itn.let.uss.umt.service.EgovUserManageService; import lombok.extern.slf4j.Slf4j; @@ -36,17 +43,29 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem @Resource(name="kakaoFriendsTalkTemplateDAO") private KakaoFriendsTalkTemplateDAO kakaoFriendsTalkTemplateDAO; + @Resource(name="mjonMsgDAO") + private MjonMsgDAO mjonMsgDAO; + /** userManageService */ @Resource(name = "userManageService") private EgovUserManageService userManageService; - @Autowired - private MjonCommon mjonCommon; + @Resource(name = "egovMjonMsgGroupIdGnrService") + private EgovIdGnrService idgenMjonMsgGroupId; + @Resource(name="kakaoAlimTalkDAO") + private KakaoAlimTalkDAO kakaoAlimTalkDAO; + @Autowired KakaoSendUtil kakaoSendUtil; + @Autowired + private MjonCommon mjonCommon; + + @Autowired + private PriceAndPoint priceAndPoint; + @Override public StatusResponse insertKakaoFtSandAjax_advc(KakaoVO kakaoVO, HttpServletRequest request) throws Exception { StatusResponse statusResponse = new StatusResponse(); @@ -103,29 +122,122 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem +/** @전송금액 확인 --------------------------------------------------*/ + if (!kakaoSendUtil.isCashSufficient(userId, kakaoSendAdvcListVO)) { + log.error("Insufficient balance for message sending."); + return new StatusResponse(HttpStatus.BAD_REQUEST, "문자 발송에 필요한 보유 잔액이 부족 합니다."); + } - - - - - - - - - - - - - - - - - // KakaoSendAdvcVO 발송 VO +/** @json파일이 있을 떄 biz_attachments insert */ + kakaoSendUtil.insertKakaoAtDataJsonInfo_advc(kakaoSendAdvcListVO); + + Map> priceGroupedMessages = kakaoSendAdvcListVO.stream() + .collect(Collectors.groupingBy(KakaoSendAdvcVO::getEachPrice)); + // instTotalCnt : 화면에서 보여줄 총 발송건수 + int instTotalCnt = 0; + + + // 임시 + List nextMsgGroupIdA = new ArrayList<>(); + // 대안: entrySet() 직접 사용 + for (Map.Entry> entry : priceGroupedMessages.entrySet()) { + // entry 사용 + + List groupedMsgList = entry.getValue(); // 해당 가격의 메시지 리스트 + + String nextMsgGroupId = idgenMjonMsgGroupId.getNextStringId(); + groupedMsgList.forEach(t -> t.setMsgGroupId(nextMsgGroupId)); + + + // 발송 데이터 삽입 + int instCnt = kakaoSendUtil.insertKakaoData_advc(groupedMsgList); +// int instCnt = 6; + + if(instCnt > 0) { + + instTotalCnt += instCnt; + + KakaoSendAdvcVO sendVO = groupedMsgList.get(0); + +/** @groupData 테이블 insert */ + kakaoSendUtil.insertKakaoGroupDataTb_advc(instCnt, kakaoVO, sendVO); + + +/** @biz_kakao_price에 insert (대체문자 환불관련 테이블)*/ + kakaoVO.setMsgGroupId(sendVO.getMsgGroupId()); + kakaoVO.setKakaoAtPrice(Float.parseFloat(sendVO.getEachPrice())); + kakaoVO.setSmsPrice(Float.parseFloat(sendVO.getSmsPrice())); + kakaoVO.setMmsPrice(Float.parseFloat(sendVO.getMmsPrice())); + + kakaoAlimTalkDAO.insertKakaoSendPrice(kakaoVO); + + + priceAndPoint.insertCashAndPoint(kakaoVO.getUserId() + , -Float.parseFloat(sendVO.getTotPrice()) + , "카카오 알림톡 총 "+groupedMsgList.size()+"건 중 " + instCnt + "건 발송" + , nextMsgGroupId + ); + + +/** @SLACK발송 */ + /** @발송조건이되면 발송 */ + if(isNotified) { + mjonCommon.getAdminKakaoAtSendSlack(sendVO); + }else if("Y".equals(kakaoVO.getAtSmishingYn())){ + /** @발송조건이 안되면 DB INSERT */ + mjonMsgDAO.insertSpamPassMsgData(MjonMsgVO.builder() + .msgGroupId(nextMsgGroupId) + .userId(kakaoVO.getUserId()) + .reqDate(kakaoVO.getReqDate()) + .smsTxt(groupedMsgList.get(0).getTemplateContent()) + .totalCallCnt(instCnt) + .callFrom(kakaoVO.getCallFrom()) + .msgType("8") + .reserveYn(kakaoVO.getReserveYn()) + .build() + ); + } + + nextMsgGroupIdA.add(nextMsgGroupId); + + } + + } + + returnMap.put("resultSts", instTotalCnt); + returnMap.put("reserYn", kakaoVO.getReserveYn()); + returnMap.put("groupIds", nextMsgGroupIdA); + + + // 측정할 메소드 호출 후 시간 기록 + Instant end = Instant.now(); + + log.info(" + start :: [{}]", start); + // 실행 시간 계산 (나노초, 밀리초, 초) + long seconds = Duration.between(start, end).getSeconds(); + log.info("메소드 실행 시간 (초): {} s", seconds); + double minutes = seconds / 60.0; // 소수점 포함을 위해 60.0으로 나눔 + + returnMap.put("second", seconds+" s"); + returnMap.put("minutes", minutes+" min"); + + +// System.out.println("메소드 실행 시간 (분): " + minutes + " min"); + + + + +// priceAndPoint.getBefCash(userId); + + + + statusResponse.setStatus(HttpStatus.OK); -// statusResponse.setObject(returnMap); + statusResponse.setObject(returnMap); + return statusResponse; } diff --git a/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp b/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp index d5b2e0da..c21ea04b 100644 --- a/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp +++ b/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp @@ -700,7 +700,7 @@ function sendTemplateInfo(){ success: function (data) { console.log('data : ', data); - var status = data.status; + /* var status = data.status; if("OK" == status){ var resultSts = data.object.resultSts; var reserYn = data.object.reserYn; @@ -715,7 +715,7 @@ function sendTemplateInfo(){ }else{ alert(data.message); return false; - } + } */ // if(data == 'success'){ diff --git a/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp b/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp index d377e429..52ea868b 100644 --- a/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp +++ b/src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/ft/KakaoFriendsTalkMsgDataView.jsp @@ -313,17 +313,12 @@ function upImgClick(){ alert("이미지 클릭시 이동할 URL 주소를 http:// 또는 https:// 포함하여 입력해 주세요."); return false; - }else{ - - if(link.search("http://") == -1 && link.search("https://") == -1){ - - $("#imgNm").text(""); - $("#imgFile").val(""); - alert("이미지 URL 주소에는 http:// 또는 https://를 포함하여 입력해야 합니다."); - return false; - - } - + }else if(link.search("http://") == -1 && link.search("https://") == -1){ + + $("#imgNm").text(""); + $("#imgFile").val(""); + alert("이미지 URL 주소에는 http:// 또는 https://를 포함하여 입력해야 합니다."); + return false; } //첨부파일 선택 팝업 호출해주기 @@ -891,8 +886,10 @@ function fn_sendMsgData(){ var subMsgSendYn = "N"; if($("#send_fail_check").is(":checked")){ subMsgSendYn = 'Y' + $('#callFrom').val($('#callFromList').val()) } $("#subMsgSendYn").val(subMsgSendYn); + $("#subMsgTxt").val( $('#smsTxtArea').val()); @@ -912,166 +909,120 @@ function fn_sendMsgData(){ } - var spamChk = true; + + + // 타블레이터 호출 + var $selectedData = tableL.getData(); // 데이터 가져오기 - var spmData = new FormData(document.bizForm); - $.ajax({ - type: "POST" - , url: "/web/mjon/kakao/friendstalk/selectSpamKakaoFriendsTalkMsgChkAjax.do" - , data: spmData - , dataType:'json' - , async: false - , processData: false - , contentType: false - , cache: false - , success: function (returnData, status) { - if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나 - - if("fail" == returnData.result){ - alert(returnData.message); - spamChk = false; - return false; - }else if("loginFail" == returnData.result){ - alert(returnData.message); - spamChk = false; - return false; - }else if("spams" == returnData.result){ - //alert("전송 내용에 스팸문구가 포함되어 있습니다.") - $("#spamStatus").val("Y"); - return false; - }else{ - spamChk = true; - return false; - } - - } else if(status== 'fail'){ - alert(returnData.message); - return false; - } - } - , error: function (e) { - alert("문자 발송에 실패하였습니다."); - console.log("ERROR : ", e); - return false; + var data = $('#bizForm'); + var formDataArray = data.serializeArray(); + + // 배열을 객체로 변환 + var formData = {}; + $.each(formDataArray, function(index, field) { + formData[field.name] = field.value; + }); + + // 2. buttonVOList 수동으로 수집 + var buttonList = []; + $('input[name^="buttonVOList"]').each(function() { + let nameAttr = $(this).attr('name'); + let match = nameAttr.match(/buttonVOList\[(\d+)\]\.(\w+)/); + + if (match) { + let index = parseInt(match[1]); + let key = match[2]; + let value = $(this).val(); + + if (!buttonList[index]) buttonList[index] = {}; + buttonList[index][key] = value; + } + }); + + // 3. formData에 배열로 추가 + formData["buttonVOList"] = buttonList; + + // 4. 기존의 buttonVOList[0].xxx 형태 제거 + Object.keys(formData).forEach(function(key) { + if (/^buttonVOList\[\d+\]\./.test(key)) { + delete formData[key]; } }); - if(spamChk){ - + // VO에 정의되어있지 않는 필요없는 값은 제거 + ["adFlag", "img_file_add", "userMoney", "callToList"].forEach(function(key) { + delete formData[key]; + }); - // 타블레이터 호출 - var $selectedData = tableL.getData(); // 데이터 가져오기 - - var data = $('#bizForm'); - var formDataArray = data.serializeArray(); - - // 배열을 객체로 변환 - var formData = {}; - $.each(formDataArray, function(index, field) { - formData[field.name] = field.value; - }); - - // 2. buttonVOList 수동으로 수집 - var buttonList = []; - $('input[name^="buttonVOList"]').each(function() { - let nameAttr = $(this).attr('name'); - let match = nameAttr.match(/buttonVOList\[(\d+)\]\.(\w+)/); - - if (match) { - let index = parseInt(match[1]); - let key = match[2]; - let value = $(this).val(); - - if (!buttonList[index]) buttonList[index] = {}; - buttonList[index][key] = value; - } - }); - - // 3. formData에 배열로 추가 - formData["buttonVOList"] = buttonList; - - // 4. 기존의 buttonVOList[0].xxx 형태 제거 - Object.keys(formData).forEach(function(key) { - if (/^buttonVOList\[\d+\]\./.test(key)) { - delete formData[key]; - } - }); - - // VO에 정의되어있지 않는 필요없는 값은 제거 - ["adFlag", "img_file_add", "userMoney", "callToList"].forEach(function(key) { - delete formData[key]; - }); - - - // 빈 값 제거 - removeEmptyValues(formData); - // 선택된 데이터 추가 - formData["mjonFTSendVOList"] = $selectedData; - // JSON 데이터 확인 - console.log("최종 formData:", JSON.stringify(formData)); - - - - - $.ajax({ - type: "POST" - , url: "/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax_advc.do" - , data: JSON.stringify(formData) - , contentType: 'application/json' - , dataType: 'json' - , success: function (returnData) { - - console.log('returnData : ', returnData); - - - /* - if(status == 'success'){ - if("loginFail" == returnData.result){ - - alert(returnData.message); - return false; - - }else if('fail' == returnData.result){ - - alert(returnData.message); - return false; - - }else if('authFail' == returnData.result){ - - alert(returnData.message); - location.reload(); - - } else if(status == 'success'){ - - var kakaoSendCnt = returnData.resultSts; - - $('.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("예약 성공 : "+ kakaoSendCnt + "건의
친구톡이 예약 되었습니다."); - }else{ - $('.pop_msg_success .msg_text').html("발송 성공 : "+ kakaoSendCnt + "건의
친구톡이 발송 되었습니다."); - } - - $('.mask').addClass('on'); + + // 빈 값 제거 + removeEmptyValues(formData); + // 선택된 데이터 추가 + formData["mjonFTSendVOList"] = $selectedData; + // JSON 데이터 확인 + console.log("최종 formData:", JSON.stringify(formData)); + + + + + $.ajax({ + type: "POST" + , url: "/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax_advc.do" + , data: JSON.stringify(formData) + , contentType: 'application/json' + , dataType: 'json' + , success: function (returnData) { + + console.log('returnData : ', returnData); + + + /* + if(status == 'success'){ + if("loginFail" == returnData.result){ + + alert(returnData.message); + return false; + + }else if('fail' == returnData.result){ + + alert(returnData.message); + return false; + + }else if('authFail' == returnData.result){ + + alert(returnData.message); + location.reload(); + + } else if(status == 'success'){ + + var kakaoSendCnt = returnData.resultSts; + + $('.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("예약 성공 : "+ kakaoSendCnt + "건의
친구톡이 예약 되었습니다."); + }else{ + $('.pop_msg_success .msg_text').html("발송 성공 : "+ kakaoSendCnt + "건의
친구톡이 발송 되었습니다."); } - } */ - } - ,beforeSend : function(xmlHttpRequest) { - //로딩창 show - $('.loading_layer').addClass('active'); - } - ,complete : function(xhr, textStatus) { - //로딩창 hide - $('.loading_layer').removeClass('active'); - } - ,error: function (e) { - console.log("ERROR : ", e); - alert("카카오 친구톡 전송에 실패하였습니다."); - } - }); - } + + $('.mask').addClass('on'); + } + } */ + } + ,beforeSend : function(xmlHttpRequest) { + //로딩창 show + $('.loading_layer').addClass('active'); + } + ,complete : function(xhr, textStatus) { + //로딩창 hide + $('.loading_layer').removeClass('active'); + } + ,error: function (e) { + console.log("ERROR : ", e); + alert("카카오 친구톡 전송에 실패하였습니다."); + } + }); } @@ -1119,6 +1070,8 @@ function fn_insertErrorYN(val){ } + + //문자 바이트수 계산하기 함수 function thisFnByteString(contents){ var totalByte = 0; @@ -1282,154 +1235,6 @@ function goToKakaoTestPopUp(){ alert("받는사람 주소를 한 건 이상 입력해주세요."); return false; - - }else{ - - //치환문구 변환 - var txtReplYn = $("#txtReplYn").val(); - - if(txtReplYn == 'Y'){ - - var name = tableL.getRows()[0].getData().name; - var phone = removeDash(tableL.getRows()[0].getData().phone); - var rep1 = tableL.getRows()[0].getData().rep1; - var rep2 = tableL.getRows()[0].getData().rep2; - var rep3 = tableL.getRows()[0].getData().rep3; - var rep4 = tableL.getRows()[0].getData().rep4; - - var varValList = []; //치환문자 연결시킬 변수 셋팅 - - - var nmStatus = false; - var rep1Status = false; - var rep2Status = false; - var rep3Status = false; - var rep4Status = false; - - var varValStr = ""; - var varValStatus = true; - - - if(tmpContents.indexOf("\#{이름}") > -1){ - nmStatus = true; - } - - if(tmpContents.indexOf("\#{1}") > -1){ - rep1Status = true; - } - - if(tmpContents.indexOf("\#{2}") > -1){ - rep2Status = true; - } - - if(tmpContents.indexOf("\#{3}") > -1){ - rep3Status = true; - } - - if(tmpContents.indexOf("\#{4}") > -1){ - rep4Status = true; - } - - - if(nmStatus && (typeof(name) != 'undefined' && name != null && name !="")){ - - if(varValStr == ''){ - varValStr = name.replaceAll(",","§"); - }else{ - varValStr = varValStr + "¶" + name.replaceAll(",","§"); - } - - }else{ - - if(nmStatus){ - varValStatus = false; - } - - } - - if(varValStr == ''){ - varValStr = phone; - }else{ - varValStr = varValStr + "¶" + phone; - } - - if(rep1Status && (typeof(rep1) != 'undefined' && rep1 != null && rep1 !="")){ - - if(varValStr == ''){ - varValStr = rep1.replaceAll(",","§"); - }else{ - varValStr = varValStr + "¶" + rep1.replaceAll(",","§"); - } - - }else{ - - if(rep1Status){ - varValStatus = false; - } - - } - - - if(rep2Status && (typeof(rep2) != 'undefined' && rep2 != null && rep2 !="")){ - - if(varValStr == ''){ - varValStr = rep2.replaceAll(",","§"); - }else{ - varValStr = varValStr + "¶" + rep2.replaceAll(",","§"); - } - - }else{ - - if(rep2Status){ - varValStatus = false; - } - - } - - if(rep3Status && (typeof(rep3) != 'undefined' && rep3 != null && rep3 !="")){ - - if(varValStr == ''){ - varValStr = rep3.replaceAll(",","§"); - }else{ - varValStr = varValStr + "¶" + rep3.replaceAll(",","§"); - } - - }else{ - - if(rep3Status){ - varValStatus = false; - } - - } - - if(rep4Status && (typeof(rep4) != 'undefined' && rep4 != null && rep4 !="")){ - - if(varValStr == ''){ - varValStr = rep4.replaceAll(",","§"); - }else{ - varValStr = varValStr + "¶" + rep4.replaceAll(",","§"); - } - - }else{ - - if(rep4Status){ - varValStatus = false; - } - - } - - if(!varValStatus){ - - alert("특정문구 일괄변환에 대한 일부 데이터가 누락된 부분이 있습니다. 데이터를 확인해 주세요."); - return false; - - } - - varValList[0] = varValStr; - - $("#varValList").val(varValList); - } - } form.method = "post"; @@ -1730,13 +1535,13 @@ function updateButtons(){

주소록, 엑셀에 입력된 내용을 이용해 수신자마다 다른 내용의 메시지를 발송하는 기능

- +
- - - - + + + +
@@ -2053,7 +1858,7 @@ function updateButtons(){
    - +

    @@ -2066,7 +1871,7 @@ function updateButtons(){

    - +
    diff --git a/src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentView.jsp b/src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentView.jsp index 4a85e26b..5e869392 100644 --- a/src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentView.jsp +++ b/src/main/webapp/WEB-INF/jsp/web/kakao/sent/KakaoSentView.jsp @@ -557,10 +557,10 @@ function fn_sentDetailView(msgGroupId) {
    • - <%--
    • -
      --%> +