Merge branch '5102_친구톡_발송속도_개선'

This commit is contained in:
hehihoho3@gmail.com 2025-08-25 12:11:36 +09:00
commit 64818ff86d
34 changed files with 1839 additions and 539 deletions

1
.claude/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/settings.local.json

View File

@ -229,8 +229,8 @@ public final class MsgSendUtils {
placeholders.put("[*4*]", MjonMsgSendVO::getRep4);
boolean hasPerformedSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 번만 수행되도록 제어
boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 스팸 체크가 번만 수행되도록 제어
boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우, 스팸 체크가 번만 수행되도록 제어
boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 메세지 타입 체크 한번
boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우,
String msgKind = mjonMsgVO.getMsgKind();
String smsTxtTemp = mjonMsgVO.getSmsTxt();
@ -257,10 +257,6 @@ public final class MsgSendUtils {
for (Map.Entry<String, Function<MjonMsgSendVO, String>> 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));
if (smsTxt.contains(placeholder)) {
if (StringUtils.isEmpty(value)) {
// statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");

View File

@ -67,13 +67,16 @@ public class KakaoSendAdvcVO implements Serializable {
private String kakaoAtPrice; // 카카오 알림톡 단가
private String bizJsonName; // 카카오 알림톡 단가
private String reserveYn; // 카카오 알림톡 단가
private String atDelayYn; // 카카오 알림톡 단가
private String atDelayYn; // 지연 문자 발송
private String bizKakaoResendOrgnlTxt; // 카카오 알림톡 단가
private String bizKakaoResendType; // 카카오 알림톡 단가
private String filePath1; // 대체문자 이미지
private String fileCnt; // 파일 카운트
private String bizKakaoImageType; // 파일 카운트
private String spamStatus;

View File

@ -40,6 +40,7 @@ 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
@ -300,21 +301,36 @@ public class KakaoSendUtil {
* @description :
* @return : List<KakaoSendAdvcVO>
* @param kakaoVO
* @param isNotified
* @param isHolidayNotified
* @param statusResponse
* @return
* @throws Exception
*
*/
public List<KakaoSendAdvcVO> populateSendListsFT(KakaoVO kakaoVO, boolean isNotified, StatusResponse statusResponse) 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 = setupBaseDate(kakaoVO, isNotified);
Calendar calendar = setupBaseDateFT(kakaoVO);
// 친구톡 내용
@ -378,18 +394,18 @@ public class KakaoSendUtil {
float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice());
float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice());
float picturePrice = getValidPrice(mberManageVO.getPicturePrice(), sysJoinSetVO.getPicturePrice());
// String shortPStr = Float.toString(shortPrice);
// String mmsPStr = Float.toString(longPrice);
// String imgPrice = Float.toString(picturePrice);
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());
}
@ -399,6 +415,19 @@ public class KakaoSendUtil {
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();
@ -414,7 +443,9 @@ public class KakaoSendUtil {
sendVO.setCallTo(mjonFTSendVO.getPhone());
sendVO.setMsgId(idList.get(i));
String smsTxt = templateContent;
// 친구톡 문자
String templateContentTemp = templateContent;
// 치환 문자면
if(replaceYN) {
@ -422,21 +453,19 @@ public class KakaoSendUtil {
for (Map.Entry<String, Function<MjonFTSendVO, String>> entry : placeholders.entrySet()) {
String placeholder = entry.getKey();
String value = entry.getValue().apply(mjonFTSendVO);
if (smsTxt.contains(placeholder)) {
if (templateContentTemp.contains(placeholder)) {
if (StringUtils.isEmpty(value)) {
statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");
return null;
}
smsTxt = smsTxt.replace(placeholder, value);
templateContentTemp = templateContentTemp.replace(placeholder, value);
}
}
}
sendVO.setTemplateContent(smsTxt);
sendVO.setTemplateContent(templateContentTemp);
// 실패 대체 문자
String subMsgTxtTemp = null;
if(StringUtils.isNotEmpty(subMsgTxt)) {
subMsgTxtTemp = subMsgTxt;
@ -462,34 +491,28 @@ public class KakaoSendUtil {
// Step 1-4: 실패 대체 문자 치환데이터 설정
if(StringUtils.isNotEmpty(subMsgTxtTemp)) { // 대체문자가 있나?
String sendType = "MMS";
if(StringUtils.isEmpty(imgFilePath)) {
int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxtTemp); // 문자 byte 계산
sendType = getMsgType(smsTxtByte); // 문자 타입(SHORT / MMS) 판별
}
sendVO.setSubMsgType(sendType); // 실패 대체 문자 타입 설정
// 최적화된 계산 로직
Map<String, Object> pricingResult;
if ("INVALID".equals(sendType)) {
// INVALID 타입이면 길이 초과 에러 응답 리턴
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;
}
float chosenPrice = 0f;
if(StringUtils.isNotEmpty(imgFilePath)) {
chosenPrice = Math.max(picturePrice, kakaoFtPrice);
sendVO.setFilePath1(imgFilePath);
sendVO.setFileCnt("1");
}else if ("MMS".equals(sendType)) {
// MMS 타입일 경우: longPrice(장문 가격) 카카오톡 단가 값을 선택
chosenPrice = Math.max(longPrice, kakaoFtPrice);
} else {
// SHORT 타입일 경우: shortPrice(단문 가격) 카카오톡 단가 값을 선택
chosenPrice = Math.max(shortPrice, kakaoFtPrice);
// 치환데이터 없음 미리 계산된 결과 재사용
pricingResult = sharedPricingResult;
}
sendVO.setEachPrice(Float.toString(chosenPrice)); // 선택된 단가 설정
// 결과 적용
applyPricingResult(sendVO, pricingResult);
}else {
@ -498,7 +521,67 @@ public class KakaoSendUtil {
}
// 타이틀과 버튼이 있고
// 스팸 단어 체크
// 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)) {
@ -518,6 +601,110 @@ public class KakaoSendUtil {
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 {
@ -548,7 +735,19 @@ public class KakaoSendUtil {
}
private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isNotified) throws ParseException {
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);
@ -560,7 +759,7 @@ public class KakaoSendUtil {
// 지연 여부 처리
// 알림톡 스미싱의심 + 공휴일알림 조건이 맞으면 30분 delay
if ( "Y".equalsIgnoreCase(kakaoVO.getAtSmishingYn())
&& isNotified) {
&& isHolidayNotified) {
calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
}
return calendar;
@ -1691,7 +1890,7 @@ public class KakaoSendUtil {
Float totPrice = eachPrice * instCnt;
sendVO.setTotPrice(String.format("%.1f", totPrice));
sendVO.setAtDelayYn(kakaoVO.getAtSmishingYn());
sendVO.setAtDelayYn(kakaoVO.getAtDelayYn());
sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt());
sendVO.setBizKakaoResendType(sendVO.getSubMsgType());
sendVO.setBizKakaoImageType(kakaoVO.getImageType());

View File

@ -358,6 +358,7 @@ public class KakaoVO extends MjonMsgVO{
sb.append("\n , spamStatus=[").append(getSpamStatus()).append("]");
sb.append("\n , txtReplYn=[").append(getTxtReplYn()).append("]");
sb.append("\n , atSmishingYn=[").append(getAtSmishingYn()).append("]");
sb.append("\n , atDelayYn=[").append(getAtDelayYn()).append("]");
// sb.append("\n , tmpBtnSelect=[").append(getTmpBtnSelect()).append("]");
StringBuilder btnListSb = new StringBuilder("[");
if (buttonVOList != null && !buttonVOList.isEmpty()) {

View File

@ -23,12 +23,10 @@ public interface KakaoAlimTalkService {
//카카오 친구톡 발신
public MjonMsgReturnVO insertKakaoFtSendAjax(KakaoVO kakaoVO) throws Exception;
//카카오 알림톡 전송 실패 환불리스트 조회
public void selectKakaoAtSentRefundList() throws Exception;
//카카오 친구톡 전송 실패 환불리스트 조회
public void selectKakaoFtSentRefundList() throws Exception;
StatusResponse insertKakaoAtSandAjax_advc(KakaoVO kakaoVO, HttpServletRequest request) throws Exception;
//카카오(알림톡, 친구톡 통합) 전송 실패 환불리스트 조회
public List<KakaoVO> selectKakaoSentRefundListForSingle() throws Exception;
public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception;
}

View File

@ -49,13 +49,8 @@ public class KakaoAlimTalkDAO extends EgovAbstractDAO {
}
@SuppressWarnings("unchecked")
public List<KakaoVO> selectKakaoAtSentRefundList() throws Exception{
return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoAtSentRefundList");
}
@SuppressWarnings("unchecked")
public List<KakaoVO> selectKakaoFtSentRefundList() throws Exception{
return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoFtSentRefundList");
public List<KakaoVO> selectKakaoSentRefundList() throws Exception{
return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoSentRefundList");
}
public KakaoVO selectKakaoAtUmid(KakaoVO kakaoVO) throws Exception{

View File

@ -11,8 +11,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@ -22,12 +20,13 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import itn.com.cmm.LoginVO;
import itn.com.cmm.MjonMsgSendVO;
import itn.com.utl.fcc.service.EgovStringUtil;
import itn.let.kakao.kakaoComm.BizKakaoPriceVO;
import itn.let.kakao.kakaoComm.KakaoSendAdvcVO;
@ -51,7 +50,6 @@ import itn.let.module.base.PriceAndPoint;
import itn.let.sym.site.service.JoinSettingVO;
import itn.let.sym.site.service.impl.SiteManagerDAO;
import itn.let.uss.umt.service.EgovUserManageService;
import itn.let.uss.umt.service.UserManageVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -105,6 +103,8 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements
final String RESEND_YN_YES = "Y";
final String SMS_SUCCESS_CODE = "4100"; // SMS 성공 코드
final String MMS_SUCCESS_CODE = "6600"; // MMS 성공 코드
final String AT_MSG_TYPE = "8"; // MSG 타입 알림톡
final String FT_MSG_TYPE = "9"; // MSG 타입 친구톡
//발신프로필 상태값 변경(삭제/복구 기능)
@Override
@ -793,76 +793,18 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements
return returnVO;
}
private void processKakaoSendCharge(KakaoVO kakaoVO) throws Exception {
/*
* 카카오 알림톡 발송 실패에 따른 금액 환불 처리
*
* */
@Override
public void selectKakaoAtSentRefundList() throws Exception {
/**
* 1. 카카오 AT 전송성공 확인
* 2. 카카오 AT 전송실패, 대채문자 전송확인
* 3. 카카오 AT 전송 실패 확인
*/
List<KakaoVO> kakaoAtSentRefundList = kakaoAlimTalkDAO.selectKakaoAtSentRefundList();
for(KakaoVO vo : kakaoAtSentRefundList) {
System.out.println(vo.getMsgGroupId() +"________결과 : " +vo.getRsltCode() +" 대체문자 전송 : "+vo.getSubMsgSendYn());
if(vo.getRsltCode().equals("7000")) {
kakaoAlimTalkDAO.updateKakaoAtSend(vo);
}else if(vo.getSubMsgSendYn().equals("Y")) {
KakaoVO info = kakaoAlimTalkDAO.selectKakaoAtUmid(vo);
System.out.println("대체문자 전송 : " + info.getBizUmid());
if (info.getBizUmid() != null) {
kakaoAlimTalkDAO.updateKakaoAtSubMsgSend(vo);
}else {
kakaoAlimTalkDAO.updateKakaoAtNotSend(vo);
}
}else {
kakaoAlimTalkDAO.updateKakaoAtNotSend(vo);
}
}
}
/**
* @ 카카오 친구톡 환불
*/
@Override
public void selectKakaoFtSentRefundList() throws Exception {
List<KakaoVO> kakaoFtSentRefundList = kakaoAlimTalkDAO.selectKakaoFtSentRefundList();
for(KakaoVO kakaoVO : kakaoFtSentRefundList) {
System.out.println(kakaoVO.getMsgGroupId() +"________결과 : " +kakaoVO.getRsltCode() +" 대체문자 전송 : "+kakaoVO.getSubMsgSendYn());
if(KAKAO_SUCCESS_CODE.equals(kakaoVO.getRsltCode())) {//친구톡 발송 성공시
processFtSendCharge(kakaoVO);
}else if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {
//친구톡 발송 실패 했고, 대체문자 발송 했을 경우
handleAlternativeMessageScenario(kakaoVO);
}else {
handleRefund(kakaoVO, "카카오 친구톡 전송 실패로 인한 결재 금액 환불");
}
}
}
private void processFtSendCharge(KakaoVO kakaoVO) throws Exception {
//1-1.카카오톡 발송 성공 + 대체문자 신청 O : 대체문자 금액 환불
if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {
BizKakaoPriceVO bizKakaoPriceVO = mjonPayDAO.selectBizKakaoPrice(kakaoVO.getMsgGroupId());
BigDecimal sendPrice = null;
if(AT_MSG_TYPE.equals(kakaoVO.getMsgType())){
sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoAtPrice());
}else {
if(StringUtils.isEmpty(kakaoVO.getBizKakaoImageType())){
sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtPrice());
}else if("I".equals(kakaoVO.getBizKakaoImageType())){
@ -870,67 +812,57 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements
}else if("W".equals(kakaoVO.getBizKakaoImageType())){
sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtWideImgPrice());
}
}
// 예시: 건당 가격이 이미 String 형태라면 변환
BigDecimal eachPrice = new BigDecimal(kakaoVO.getEachPrice());
// 차이 계산
BigDecimal diffPrice = eachPrice.subtract(sendPrice);
//대체문자 비용(eachPrace - sendPrice)
if (diffPrice.compareTo(BigDecimal.ZERO) > 0) {
String result = diffPrice.toString();
kakaoVO.setEachPrice(result);
handleRefund(kakaoVO, "카카오 친구톡 전송으로 인한 결재 차액 환불");
handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 발송 성공 후 대체문자 금액 환불");
}
}else {
mjonMsgDAO.updateRefundY(kakaoVO);
}
// TODO Auto-generated method stub
//1-2.카카오톡 발송 성공 + 대체문자 신청 X : 금액 환불 X
}
private void handleAlternativeMessageScenario(KakaoVO kakaoVO) throws Exception {
KakaoVO bizLogVO = kakaoAlimTalkDAO.selectBizLog(kakaoVO.getBizUmid());
log.info("대체문자 전송 UMID: {}", kakaoVO.getBizUmid());
// 대체문자가 성공적으로 발송되었는지 확인 (SMS 또는 MMS 성공)
//2-1.카카오톡 발송 실패 + 대체문자 발송 성공 : 금액 환불 X
boolean isAlternativeMessageSuccessful = false;
if (bizLogVO != null && StringUtils.isNotEmpty(bizLogVO.getBizLogCallStatus())) {
if (SMS_SUCCESS_CODE.equals(bizLogVO.getBizLogCallStatus())
|| MMS_SUCCESS_CODE.equals(bizLogVO.getBizLogCallStatus())) {
isAlternativeMessageSuccessful = true;
}
}
log.info("bizLogVO.getBizLogCallStatus() :: [{}]", bizLogVO.getBizLogCallStatus());
log.info("isAlternativeMessageSuccessful :: [{}]", isAlternativeMessageSuccessful);
}
// 대체문자 성공이면 환불 완료처리면 한다.
if (isAlternativeMessageSuccessful) {
mjonMsgDAO.updateRefundY(kakaoVO);
} else {
// 대체문자 발송 실패 경우 (친구톡 비용 환불 필요)
handleRefund(kakaoVO, "카카오 친구톡 전송 실패로 인한 결재 금액 환불");
//2-2.카카오톡 발송 실패 + 대체문자 발송 실패 : 전액 환불
if (!isAlternativeMessageSuccessful) {
handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 전송 실패로 인한 결제 금액 환불");
}
}
private void handleRefund(KakaoVO vo, String msg) throws Exception {
// mj_cash 테이블에 환불 내역 추가 회원 금액 업데이트
// eachPrice는 환불될 금액이므로 양수여야 합니다.
priceAndPoint.insertCashAndPoint(
priceAndPoint.insertCashAndPointNoUpdate(
vo.getUserId(),
Float.parseFloat(vo.getEachPrice()), // 환불 금액은 양수
msg,
vo.getMsgGroupId(),
vo.getUserData()
);
// 해당 row 환불 처리 (mj_msg_data.REFUND_YN = 'Y')
mjonMsgDAO.updateRefundY(vo);
}
@Override
@ -1146,7 +1078,33 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements
return statusResponse;
}
@Override
public List<KakaoVO> selectKakaoSentRefundListForSingle() throws Exception{
return kakaoAlimTalkDAO.selectKakaoSentRefundList();
}
@Override
public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception {
System.out.println(kakaoVO.getMsgGroupId() +"________결과 : " +kakaoVO.getRsltCode() +" 대체문자 전송 : "+kakaoVO.getSubMsgSendYn());
kakaoVO.setMsgTypeTxt(AT_MSG_TYPE.equals(kakaoVO.getMsgType()) ? "알림톡" : "친구톡");
if(KAKAO_SUCCESS_CODE.equals(kakaoVO.getRsltCode())) {
//1.카카오톡 발송 성공
processKakaoSendCharge(kakaoVO);
}else if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {//카카오톡 발송 실패, 대체문자 발송 신청 O
//2.카카오톡 발송 실패 + 대체문자 신청 O
handleAlternativeMessageScenario(kakaoVO);
}else {
//3.카카오톡 발송 실패 + 대체문자 신청 X : 전액 환불
handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 전송 실패로 인한 결제 금액 환불");
}
//모든 유형 환불 완료 처리
mjonMsgDAO.updateRefundY(kakaoVO);
}
private void insertKakaoAtDataJsonInfo_advc(List<KakaoSendAdvcVO> kakaoSendAdvcListVO) {
// TODO Auto-generated method stub
@ -1294,5 +1252,4 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements
}

View File

@ -9,9 +9,11 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@ -61,7 +63,6 @@ import itn.com.cmm.util.MJUtil;
import itn.com.cmm.util.StringUtil;
import itn.com.utl.fcc.service.EgovStringUtil;
import itn.let.kakao.kakaoComm.KakaoReturnVO;
import itn.let.kakao.kakaoComm.KakaoSendAdvcVO;
import itn.let.kakao.kakaoComm.KakaoSendUtil;
import itn.let.kakao.kakaoComm.KakaoVO;
import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiJsonSave;
@ -79,6 +80,9 @@ import itn.let.mjo.msgdata.service.MjonMsgReturnVO;
import itn.let.mjo.msgholiday.service.MsgAlarmSetVO;
import itn.let.mjo.msgholiday.service.MsgHolidayService;
import itn.let.mjo.msgholiday.service.MsgHolidayVO;
import itn.let.mjo.pay.service.MjonPayService;
import itn.let.mjo.pay.service.MjonPayVO;
import itn.let.org.web.OrgChartManageController;
import itn.let.sym.site.service.EgovSiteManagerService;
import itn.let.sym.site.service.JoinSettingVO;
import itn.let.uss.umt.service.EgovUserManageService;
@ -102,6 +106,8 @@ import itn.let.uss.umt.service.UserManageVO;
@Controller
public class KakaoAlimTalkSendController {
private final OrgChartManageController orgChartManageController;
@Resource(name = "egovMjonMsgGroupIdGnrService")
private EgovIdGnrService idgenMjonMsgGroupId;
@ -150,6 +156,13 @@ public class KakaoAlimTalkSendController {
@Autowired
private MjonCommon mjonCommon;
@Resource(name = "mjonPayService")
private MjonPayService mjonPayService;
KakaoAlimTalkSendController(OrgChartManageController orgChartManageController) {
this.orgChartManageController = orgChartManageController;
}
@RequestMapping(value= {"/web/mjon/alimtalk/kakaoAlimtalkMsgDataView.do"})
public String KakaoAlimtalkMsgDataView(ModelMap model
, @ModelAttribute("kakaoVO") KakaoVO kakaoVO) throws Exception {
@ -1540,4 +1553,55 @@ public class KakaoAlimTalkSendController {
return "web/kakao/msgdata/at/KakaoAlimtalkMsgDataView_tmp";
}
public void kakaoRefundSingleTransaction() throws Exception{
System.out.println("=============카카오 환불 싱글 트랜잭션 수행 =============");
/* 회원 money 업데이트 처리 트랜잭션 분리를 위하여 impl이 아닌 현재 위치에서 반복문 실행 */
System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>");
List<KakaoVO> kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle();
Set<String> targetIdSet = new HashSet<>();
for(KakaoVO kakaoVO : kakaoRefundList) {
try {
kakaoAlimTalkService.kakaoSingleRefund(kakaoVO);
targetIdSet.add(kakaoVO.getUserId());
} catch (Exception e) {
String msg = "[문자온] 환불 실패 - " + kakaoVO.getMsgId() +"("+ kakaoVO.getUserId() + ")";
mjonCommon.sendSimpleSlackMsg(msg);;
}
}
MjonPayVO mjonPayVO = new MjonPayVO();
for(String userId : targetIdSet) {
try {
mjonPayVO.setUserId(userId);
mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
} catch(Exception e) {
String msg = "[문자온] 환불 후 잔액 갱신 실패 - " + userId;
mjonCommon.sendSimpleSlackMsg(msg);;
}
}
}
/**
* @Method Name : kakaoMsgSendRefundTestAjax
* @작성일 : 2025. 8. 6.
* @작성자 : 이지우
* @Method 설명 : 카카오 친구톡 전송 환불 스케줄러 서비스 테스트
*/
@RequestMapping(value= {"/web/mjon/kakao/alimtalk/kakaoMsgSendRefundTestAjax.do"})
public ModelAndView kakaoMsgSendRefundTestAjax(ModelMap model
, HttpServletRequest request
, @ModelAttribute("kakaoVO") KakaoVO kakaoVO) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("jsonView");
this.kakaoRefundSingleTransaction();
modelAndView.addObject("result", "success");
return modelAndView;
}
}

View File

@ -29,8 +29,10 @@ 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.module.base.PriceAndPoint;
import itn.let.uss.umt.service.EgovUserManageService;
import itn.let.uss.umt.service.UserManageVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -57,6 +59,9 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem
@Resource(name="kakaoAlimTalkDAO")
private KakaoAlimTalkDAO kakaoAlimTalkDAO;
@Resource(name = "MjonMsgDataService")
private MjonMsgDataService mjonMsgDataService;
@Autowired
KakaoSendUtil kakaoSendUtil;
@ -70,9 +75,9 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem
public StatusResponse insertKakaoFtSandAjax_advc(KakaoVO kakaoVO, HttpServletRequest request) throws Exception {
StatusResponse statusResponse = new StatusResponse();
log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.toString());
// log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.toString());
log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.ftToString());
// log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.ftToString());
@ -118,12 +123,17 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem
/** @isHolidayNotified
* @false : 알림 X
* @true : 알림 O */
boolean isNotified = mjonCommon.processUserAndCheckAT(kakaoVO);
boolean isHolidayNotified = mjonCommon.processUserAndCheckFT(kakaoVO);
UserManageVO userManageVO = mjonCommon.getUserManageInfo(userId);
// 스팸관련 키워드 select
List<String> resultSpamTxt = mjonMsgDataService.selectSpamKeywordList();
/** @카카오톡 전송 list 셋팅 -------------------------------------------*/
List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendListsFT(kakaoVO, isNotified, statusResponse);
List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendListsFT(kakaoVO, isHolidayNotified, statusResponse, userManageVO, resultSpamTxt);
if (statusResponse.getStatus() != null && !statusResponse.getStatus().equals(HttpStatus.OK)) {
log.error(" + populateSendLists 처리 중 오류 발생: {}", statusResponse.getMessage());
return statusResponse;
@ -189,7 +199,9 @@ public class KakaoFriendsTalkServiceImpl extends EgovAbstractServiceImpl implem
/** @SLACK발송 */
/** @발송조건이되면 발송 */
if(isNotified) {
if(isHolidayNotified
&& ("Y".equals(userManageVO.getAtSmishingYn()) || "Y".equals(kakaoVO.getAtDelayYn()))
) {
mjonCommon.getAdminKakaoAtSendSlack(sendVO);
}else if("Y".equals(kakaoVO.getAtSmishingYn())){
/** @발송조건이 안되면 DB INSERT */

View File

@ -711,27 +711,6 @@ public class KakaoFriendsTalkSendController {
return modelAndView;
}
/**
* @Method Name : kakaoFriendsTalkMsgSendRefundTestAjax
* @작성일 : 2024. 1. 18.
* @작성자 : 우영두
* @Method 설명 : 카카오 친구톡 전송 환불 스케줄러 서비스 테스트
*/
@RequestMapping(value= {"/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendRefundTestAjax.do"})
public ModelAndView kakaoFriendsTalkMsgSendRefundTestAjax(ModelMap model
, HttpServletRequest request
, @ModelAttribute("kakaoVO") KakaoVO kakaoVO) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("jsonView");
kakaoAlimTalkService.selectKakaoFtSentRefundList();
modelAndView.addObject("result", "success");
return modelAndView;
}
/**
* @Method Name : kakaoFriendsTalkMsgSendRefundTestAjax
* @작성일 : 2024. 1. 18.

View File

@ -272,6 +272,25 @@ public class KakaoSentController {
model.addAttribute("kakaoTemplateInfo", kakaoTemplateInfo);
if(StringUtils.isNotEmpty( mjonKakaoATResultVO.getFilePath1() )) {
List<FileInfoVO> fileInfos = new ArrayList<>();
// 확장자 제외한 파일명
String fileId = FilenameUtils.getBaseName(mjonKakaoATResultVO.getFilePath1());
// 파일 정보 조회
MjonMsgSentVO info = mjonMsgSentDAO.selectFileInfo(fileId);
// FileInfo 객체 생성 추가
FileInfoVO fileInfo = new FileInfoVO();
fileInfo.setAtchFileId(info.getAtchFileId());
fileInfo.setFileSn(info.getFileSn());
fileInfos.add(fileInfo);
model.addAttribute("fileInfos", fileInfos);
}
}else {
model.addAttribute("kakaoTemplateInfo", "");
@ -1109,6 +1128,6 @@ public class KakaoSentController {
e.printStackTrace();
// TODO: handle exception
}
return "web/kakao/sent/KakaoSentDetailPopAjax";
return "web/kakao/sent/KakaoSentDetailPhoneAjax";
}
}

View File

@ -188,6 +188,29 @@ public class KakaoStepInfoController {
return "/web/kakao/intrd/KakaoAllimtalkIntro";
}
/**
* @Method Name : kakaotalkIntrdView
* @Project : mjon
* @Date : 2025. 8. 21
* @작성자 : 원영현
* @프로그램 설명 :카카오 알림톡, 친구토 통합 소개페이지
*/
@RequestMapping(value= {"/web/mjon/kakao/alimtalk/kakaotalkIntrdView.do"})
public String kakaotalkIntrdView(HttpServletRequest request,
@ModelAttribute("searchVO") BoardMasterVO boardMasterVO, ModelMap model , BoardVO boardVO ,
RedirectAttributes redirectAttributes) throws Exception {
LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
if(userId == "") {
return "redirect:/web/user/login/login.do";
}
model.addAttribute("loginVO", loginVO);
return "/web/kakao/intrd/KakaotalkIntro";
}
/**
* XSS 방지 처리.

View File

@ -533,12 +533,12 @@ private int parseIntOrDefault(String value, int defaultValue) {
UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId());
// 기본값 처리된 사용자 정보와 문자 상태
String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn();
String atSmishingYn = userManageVO.getAtSmishingYn();
String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); // 법인폰 알람 여부 - Y : ON
String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON
// 조건 체크
if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) {
kakaoVO.setAtSmishingYn("Y"); // MjonMsgVO에 스미싱 정보 설정
kakaoVO.setAtSmishingYn("Y"); // MjonMsgVO에 스미싱 정보 설정 - Y면
// 스미싱 알림 처리
return handleSmishingAlert(); // 알림 처리 결과 반환
@ -547,6 +547,46 @@ private int parseIntOrDefault(String value, int defaultValue) {
return false; // 알림 처리되지 않음
}
/**
* @methodName : processUserAndCheckFT
* @author : 이호영
* @date : 2025. 8. 21.
* @description :
* @return : boolean
* @param kakaoVO
* @return
* @throws Exception
*
* @isHolidayNotified
* @false : 알림 X
* @true : 알림 O
*
*/
public boolean processUserAndCheckFT(KakaoVO kakaoVO) throws Exception {
// UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId());
// kakaoVO.setAtSmishingYn("N"); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리
// 기본값 처리된 사용자 정보와 문자 상태
// String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); // 법인폰 알람 여부 - Y : ON
// String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON !== mj_msg_group_data와 다른거임
// 조건 체크
// if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) {
// if ("Y".equals(atSmishingYn)) {
// Boolean B_return = handleSmishingAlert();
// if(B_return) { // true면 알림ON이라서 스미싱Yn을 Y로 설정 아니면 N / 나머지는 로직에서 처리
// kakaoVO.setAtSmishingYn(atSmishingYn); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리
// }
// 스미싱 알림 처리
// return B_return; // 알림 처리 결과 반환
// }
return handleSmishingAlert(); // 알림 처리되지 않음
}
// 사용자 정보 조회 기본값 처리
public UserManageVO getUserManageInfo(String userId) throws Exception {
// UserManageVO userManageVO = new UserManageVO();

View File

@ -95,6 +95,7 @@ public class MjonMsgVO extends ComDefaultVO{
private String reserveYn ; //예약문자 여부
private String reserveCYn ; //예약문자 취소 여부
private String cancelDate; //예약 취소 일자
private String msgResult; //문자 발송결과 10:성공 20:실패 30:대체문자 대기 40:대체문자 성공 50:대체문자 실패
private String sendRate; // 전송 배분률
@ -319,4 +320,7 @@ public class MjonMsgVO extends ComDefaultVO{
private List<MjonMsgSendVO> mjonMsgSendVOList = new ArrayList<>();
private String cmId; //다우기술 cmId
}

View File

@ -463,6 +463,23 @@ public class MjonMsgDataDAO extends EgovAbstractDAO {
}
//대체문자 대기 목록 조회
@SuppressWarnings("unchecked")
public List<MjonMsgVO> selectBizResendLogList()throws Exception{
return (List<MjonMsgVO>) list("mjonMsgDataDAO.selectBizResendLogList");
}
//대체문자 결과 반영
public int updateResendResult(MjonMsgVO mjonMsgVO)throws Exception{
return update("mjonMsgDataDAO.updateResendResult", mjonMsgVO);
}
//대체문자 로그 삭제
public int deleteBizResendLog(MjonMsgVO mjonMsgVO)throws Exception{
return delete("mjonMsgDataDAO.deleteBizResendLog", mjonMsgVO);
}
public Timestamp convertToTimestamp(String reqDate) {
try {

View File

@ -6543,5 +6543,4 @@ public class MjonMsgDataController {
return "web/msgdata/MsgSentListAjax";
}
}

View File

@ -4901,10 +4901,11 @@ public class MjonPayController {
model.addAttribute("endDate", endDate);
DecimalFormat decFormat = new DecimalFormat("###,###");
DecimalFormat decFormatFloat = new DecimalFormat("###,###.#");
model.addAttribute("sendSumCount", decFormat.format(sendSumCount));
model.addAttribute("supplySumPrice", decFormat.format(supplySumPrice));
model.addAttribute("vatSumPrice", decFormat.format(vatSumPrice));
model.addAttribute("totalSumPrice", decFormat.format(totalSumPrice));
model.addAttribute("totalSumPrice", decFormatFloat.format(totalSumPrice));
model.addAttribute("resultList", payUserSumList);
// 수신자 정보

View File

@ -214,5 +214,35 @@ public class PriceAndPoint {
}
/**
* @methodName : insertCashAndPoint
* @author : 이지우
* @date : 2025. 8. 14.
* @description : insertCashAndPoint 에서 updateMemberCash 제외
* @return : void
* @param userId
* @param totPrice
* @param memo
* @param msgGroupId
* @param userData
* @throws Exception
*
*/
public void insertCashAndPointNoUpdate(
String userId
, float totPrice
, String memo
, String msgGroupId
, String userData
) throws Exception {
MjonPayVO mjonPayVO = buildPayVO(userId, totPrice, memo, msgGroupId);
// 환불로 인해 userData가 추후 사용될 경우 여기에 처리
if (StringUtils.isNotEmpty(userData)) { mjonPayVO.setOrderId(userData); }
mjonPayDAO.insertCash(mjonPayVO); //캐시
}
}

View File

@ -47,11 +47,11 @@ public interface SchdlrManageService {
//전용계좌 자동 충전 배치
public void vacsAutoCharge() throws Exception;
//문자온 카카오톡 실패 건수 환불 배치
public void kakaoFailPayBack() throws Exception;
//문자온 문자전송 실패 건수 환불 배치
public void payBack(String type, int limitCout) throws Exception;
public void payBack_advc(String p_type) throws Exception;
//대체문자 결과 반영 배치
public void updateKakaoResendResult() throws Exception;
}

View File

@ -2,7 +2,9 @@ package itn.let.schdlr.service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import javax.sql.DataSource;
@ -24,12 +26,16 @@ import itn.let.fax.admin.service.FaxAdmService;
import itn.let.fax.admin.service.FaxStatVO;
import itn.let.kakao.admin.kakaoAt.service.MjonKakaoAtStatVO;
import itn.let.kakao.admin.statistics.service.KakaoStatisticsService;
import itn.let.kakao.kakaoComm.KakaoVO;
import itn.let.kakao.user.kakaoAt.service.KakaoAlimTalkService;
import itn.let.lett.service.LetterService;
import itn.let.mail.service.MailTemplateService;
import itn.let.mjo.mjocommon.MjonCommon;
import itn.let.mjo.msg.service.MjonMsgService;
import itn.let.mjo.msg.service.MjonMsgStatVO;
import itn.let.mjo.msg.service.MjonMsgVO;
import itn.let.mjo.msgdata.service.impl.MjonMsgDataDAO;
import itn.let.mjo.pay.service.MjonPayService;
import itn.let.mjo.pay.service.MjonPayVO;
import itn.let.sts.com.StatsVO;
import itn.let.sts.cst.service.EgovConectStatsService;
import itn.let.uss.umt.service.EgovUserManageService;
@ -82,6 +88,15 @@ public class SchedulerUtil {
@Resource(name="MjonMsgDataDAO")
private MjonMsgDataDAO mjonMsgDataDAO;
@Resource(name="kakaoAlimTalkService")
private KakaoAlimTalkService kakaoAlimTalkService;
@Resource(name="MjonCommon")
private MjonCommon mjonCommon;
@Resource(name = "mjonPayService")
private MjonPayService mjonPayService;
/** 설정값 가져오기 */
@Value("#{globalSettings['Globals.Env']}")
private String GlobalsEnv;
@ -470,13 +485,46 @@ public class SchedulerUtil {
@SchedulerLock(name = "runKakaoOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runKakaoOneTime() throws Exception {
// do something...
try {
/* 회원 money 업데이트 처리 트랜잭션 분리를 위하여 impl이 아닌 현재 위치에서 반복문 실행 */
System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>");
schdlrManageService.kakaoFailPayBack();
List<KakaoVO> kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle();
Set<String> targetIdSet = new HashSet<>();
for(KakaoVO kakaoVO : kakaoRefundList) {
try {
kakaoAlimTalkService.kakaoSingleRefund(kakaoVO);
targetIdSet.add(kakaoVO.getUserId());
} catch (Exception e) {
String msg = "[문자온] 환불 실패 - " + kakaoVO.getMsgId() +"("+ kakaoVO.getUserId() + ")";
mjonCommon.sendSimpleSlackMsg(msg);;
}
}
MjonPayVO mjonPayVO = new MjonPayVO();
for(String userId : targetIdSet) {
try {
mjonPayVO.setUserId(userId);
mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
} catch(Exception e) {
String msg = "[문자온] 환불 후 잔액 갱신 실패 - " + userId;
mjonCommon.sendSimpleSlackMsg(msg);;
}
}
}
//대체문자 결과 반영
@Scheduled(cron = "0 0/2 * * * ?") // 2분마다 실행
@SchedulerLock(name = "updateKakaoResendResult", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runUpdateKakaoResendResult() throws Exception {
try {
System.out.println("=============SchedulerUtil=====runUpdateKakaoResendResult =============>");
schdlrManageService.updateKakaoResendResult();
}catch(Exception ex) {
ex.printStackTrace();
}
}
//환불 실행

View File

@ -393,12 +393,12 @@ public class SchdlrManageServiceImpl extends EgovAbstractServiceImpl implements
// 대상 : 휴대폰결제, 즉시이체, 전용계좌
// Step 1. 스미싱의심 지정 여부
JoinSettingVO joinSettingVO = new JoinSettingVO();
joinSettingVO = egovSiteManagerService.selectAdminNotiDetail();
// JoinSettingVO joinSettingVO = new JoinSettingVO();
JoinSettingVO joinSettingVO = egovSiteManagerService.selectAdminNotiDetail();
if (joinSettingVO != null && joinSettingVO.getSmishingNoti().equals("Y")) {
// Step 1. 개인회원 여부 체크
int isPersnalMemberCnt = egovSiteManagerService.selectPersnalMemberCnt(Userid);
if (isPersnalMemberCnt == 1) {
// int isPersnalMemberCnt = egovSiteManagerService.selectPersnalMemberCnt(Userid);
// if (isPersnalMemberCnt == 1) {
// Step 2. 첫결제 여부 체크
int isFirstPayCnt = egovSiteManagerService.selectFirstPayCnt(Userid);
if (isFirstPayCnt == 1) {
@ -418,10 +418,11 @@ public class SchdlrManageServiceImpl extends EgovAbstractServiceImpl implements
// 스미싱 의심회원으로 변경
UserManageVO userManageVO = new UserManageVO();
userManageVO.setSmishingYn("Y");
userManageVO.setAtSmishingYn("Y");
userManageVO.setMberId(Userid);
userManageService.updateOneUserSmishingYnNotAlert(userManageVO);
}
}
// }
}
} catch (Exception e) {
@ -437,17 +438,6 @@ public class SchdlrManageServiceImpl extends EgovAbstractServiceImpl implements
}
// 카카오 환불 처리 리스트
public void kakaoFailPayBack() throws Exception {
// 카카오 알림톡 환불 처리
kakaoAlimTalkService.selectKakaoAtSentRefundList();
// 카카오 친구톡 환불 처리
kakaoAlimTalkService.selectKakaoFtSentRefundList();
}
@Override
public void payBack(String type, int limitCout) throws Exception {
// 문자 환불
@ -566,4 +556,37 @@ public class SchdlrManageServiceImpl extends EgovAbstractServiceImpl implements
return msgFailList;
}
/**
* @methodName : updateKakaoResendResult
* @author : 이지우
* @date : 2025.07.15
* @description : 대체문자 결과 반영
* @param p_type
* @param request
* @param model
* @return
* @throws Exception
*/
@Override
public void updateKakaoResendResult() throws Exception {
long startTime = System.currentTimeMillis();
// 대체문자 대상 조회
List<MjonMsgVO> resendLogList = mjonMsgDataDAO.selectBizResendLogList();
for(MjonMsgVO vo : resendLogList) {
if("4100".equals(vo.getResultCode())
|| "6600".equals(vo.getResultCode())
|| "7000".equals(vo.getResultCode())) {
vo.setMsgResult("40");
}else {
vo.setMsgResult("50");
}
mjonMsgDataDAO.updateResendResult(vo);
mjonMsgDataDAO.deleteBizResendLog(vo);
}
long endTime = System.currentTimeMillis();
long elapsedTime = (endTime - startTime) / 1000; // 단위 변환
System.out.println("updateKakaoResendResult 실행 시간: " + elapsedTime + "초 (" + resendLogList.size() + "건 처리)");
}
}

View File

@ -207,36 +207,11 @@
)
</insert>
<select id="kakaoAlimTalkDAO.selectKakaoAtSentRefundList" resultClass="kakaoVO">
SELECT
MMD.USER_ID AS userId
, MMD.MSG_GROUP_ID AS msgGroupId
, MMD.MSG_SEQ AS msgSeq
, MMD.USERDATA AS userData
, MMD.REFUND_YN AS refundYn
, MMD.RSLT_CODE AS rsltCode
, MMD.RSLT_CODE2 AS rsltCode2
, MMD.AGENT_CODE AS agentCode
, DATE_FORMAT(MMD.SENT_DATE,'%Y-%m-%d %T') AS sentDate
, DATE_FORMAT(MMD.RSLT_DATE,'%Y-%m-%d %T') AS rsltDate
, MMD.BIZ_KAKAO_RESEND_YN AS subMsgSendYn
, MMD.BIZ_KAKAO_RESEND_TYPE AS subMsgType
FROM
MJ_MSG_DATA MMD
INNER JOIN LETTNGNRLMBER MB
ON MMD.USER_ID = MB.MBER_ID
WHERE 1=1
AND MMD.CUR_STATE = '3'
AND MMD.REFUND_YN = 'N'
AND MMD.RESERVE_C_YN = 'N'
AND MMD.MSG_TYPE = 8
</select>
<select id="kakaoAlimTalkDAO.selectKakaoFtSentRefundList" resultClass="kakaoVO">
<select id="kakaoAlimTalkDAO.selectKakaoSentRefundList" resultClass="kakaoVO">
SELECT
MMD.USER_ID AS userId
, MMD.MSG_GROUP_ID AS msgGroupId
, MMD.MSG_ID AS msgId
, MMD.MSG_SEQ AS msgSeq
, MMGD.BIZ_KAKAO_IMAGE_TYPE AS bizKakaoImageType
, MMGD.EACH_PRICE AS eachPrice
@ -251,6 +226,7 @@
, MMD.BIZ_KAKAO_RESEND_TYPE AS subMsgType
, MMD.FILE_CNT AS fileCnt
, MMD.BIZ_UMID AS bizUmid
, MMD.MSG_TYPE AS msgType
FROM
MJ_MSG_DATA MMD
INNER JOIN LETTNGNRLMBER MB
@ -261,7 +237,8 @@
AND MMD.CUR_STATE = '3'
AND MMD.REFUND_YN = 'N'
AND MMD.RESERVE_C_YN = 'N'
AND MMD.MSG_TYPE = 9
AND MMD.MSG_TYPE IN(8, 9)
ORDER BY MMD.USER_ID ASC
</select>
<select id="kakaoAlimTalkDAO.selectKakaoAtUmid" resultClass="kakaoVO" parameterClass="kakaoVO">

View File

@ -3607,9 +3607,9 @@
, SUM(IF(M.msgTypeName = '알림톡', 1, 0)) AS atSendCount
, SUM(IF(M.msgTypeName = '친구톡', 1, 0)) AS ftSendCount
<!-- , SUM(M.MSG_GROUP_CNT) AS sendCount -->
, ifnull(TRUNCATE(SUM(M.EACH_PRICE) , 0), 0) AS supplyPrice
, ifnull(TRUNCATE(SUM(M.EACH_PRICE) , 1), 0) AS supplyPrice
, 0 AS vatPrice
, ifnull(TRUNCATE(SUM(M.EACH_PRICE) , 0), 0) AS totalPrice
, ifnull(TRUNCATE(SUM(M.EACH_PRICE) , 1), 0) AS totalPrice
, M.MSG_TYPE
FROM (
SELECT
@ -3647,8 +3647,6 @@
AND A.MSG_GROUP_ID = B.MSG_GROUP_ID
AND A.USER_ID = #userId#
AND B.USER_ID = #userId#
AND B.DEL_FLAG = 'N'
AND IFNULL(B.DEL_FLAG,'N') = 'N'
AND B.RESERVE_C_YN = 'N'
<isNotEmpty property="startDate">
@ -3676,6 +3674,9 @@
<isEqual property="pageType" compareValue="at">
AND B.MSG_TYPE = '8'
</isEqual>
<isEqual property="pageType" compareValue="ft">
AND B.MSG_TYPE = '9'
</isEqual>
</isNotEmpty>
) M
WHERE 1=1
@ -3691,9 +3692,9 @@
, IFNULL(MIN(DATE_FORMAT(M.REQ_DATE, '%Y-%m-%d' )), 0) AS minRegDate
, M.msgTypeName
, IFNULL(SUM(SentEA), 0) AS ftSendCount
, ifnull(TRUNCATE(SUM(supplyPrice) , 0), 0) AS supplyPrice
, ifnull(TRUNCATE(SUM(supplyPrice) , 1), 0) AS supplyPrice
, 0 AS vatPrice
, ifnull(TRUNCATE(SUM(M.TOT_PRICE) , 0), 0) AS totalPrice
, ifnull(TRUNCATE(SUM(M.TOT_PRICE) , 1), 0) AS totalPrice
FROM (
SELECT pf.ReqDate AS REGDATE
, pf.ReqDate AS REQ_DATE
@ -8265,5 +8266,35 @@
</update>
<select id="mjonMsgDataDAO.selectBizResendLogList" resultClass="mjonMsgVO">
SELECT
BRLA.CMID AS cmId,
BRLA.CALL_STATUS AS resultCode,
BRLB.USER_KEY AS userData
FROM
BIZ_RESEND_LOG BRLA
JOIN
BIZ_RESEND_LOG BRLB
ON BRLB.UMID = BRLA.CMID
WHERE (BRLA.UMID = '' OR BRLA.UMID IS NULL);
</select>
<update id="mjonMsgDataDAO.updateResendResult" parameterClass="mjonMsgVO" >
UPDATE MJ_MSG_DATA
SET MSG_RESULT = #msgResult#
WHERE USERDATA = #userData#
</update>
<delete id="mjonMsgDataDAO.deleteBizResendLog" parameterClass="mjonMsgVO" >
DELETE FROM BIZ_RESEND_LOG
WHERE CMID = #cmId# OR UMID = #cmId#
</delete>
</sqlMap>

View File

@ -1367,6 +1367,7 @@
LETTNGNRLMBER
SET
SMISHING_YN = #smishingYn#
, AT_SMISHING_YN = #atSmishingYn#
WHERE 1=1
AND MBER_ID = #mberId#
</update>

View File

@ -1557,8 +1557,10 @@ function actionLogin_end(){
<dd>
<ul>
<li><a href="<c:out value='/web/mjon/alimtalk/kakaoAlimtalkMsgDataView.do'/>">알림톡</a></li>
<li><a href="<c:out value='/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgDataView.do'/>">친구톡</a></li>
<li><a href="<c:out value='/web/mjon/kakao/stepinfo/selectKaKaoStepInfo.do'/>" >카카오톡 설정</a></li>
<li><a href="<c:out value='/web/mjon/kakao/alimtalk/kakaoAlimtalkIntrdView.do'/>" >알림톡 소개</a></li>
<%-- <li><a href="<c:out value='/web/mjon/kakao/alimtalk/kakaoAlimtalkIntrdView.do'/>" >알림톡 소개</a></li> --%>
<li><a href="<c:out value='/web/mjon/kakao/alimtalk/kakaotalkIntrdView.do'/>" >카카오톡 소개</a></li>
</ul>
</dd>
</dl>

View File

@ -60,9 +60,9 @@ function fnLinkPageTopTab(tabInfo){
url = "<c:url value='/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgDataView.do'/>";
}else if(tabInfo == 'tabAlimtalkIntrd'){
}else if(tabInfo == 'tabKakaotalkIntrd'){
url = "<c:url value='/web/mjon/kakao/alimtalk/kakaoAlimtalkIntrdView.do'/>";
url = "<c:url value='/web/mjon/kakao/alimtalk/kakaotalkIntrdView.do'/>";
}
@ -142,12 +142,7 @@ function cntntBtnInfo(stepInfo){
<ul class="tabType4">
<li id="tabAt" class="tab topTab"><button type="button" onclick="javascript:fnLinkPageTopTab('tabAlim');">알림톡</button></li>
<c:if test="${pageContext.request.serverName == 'localhost'
|| pageContext.request.serverName == '119.193.215.98'
|| pageContext.request.serverName == '192.168.0.176'
}">
<li id="tabFt" class="tab topTab"><button type="button" onclick="javascript:fnLinkPageTopTab('tabFriend');">친구톡</button></li>
</c:if>
<li id="tabConf" class="tab topTab"><button type="button" onclick="javascript:fnLinkPageTopTab('tabConf');">카카오톡 설정</button></li>
<li id="tabIntro" class="tab topTab"><button type="button" onclick="javascript:fnLinkPageTopTab('tabAlimtalkIntrd');">알림톡 소개</button></li>
<li id="tabIntro" class="tab topTab"><button type="button" onclick="javascript:fnLinkPageTopTab('tabKakaotalkIntrd');">카카오톡 소개</button></li>
</ul>

View File

@ -17,11 +17,20 @@
<%@include file="/WEB-INF/jsp/web/kakao/include/KaKaoAlimtalkTopMenuTap.jsp" %>
<!--// tab button -->
<div class="top_content kakao_intro_cont current">
<div class="top_content kakao_intro_cont pay_tab_wrap current">
<div class="heading">
<h2>알림톡 소개</h2>
<h2>카카오톡 소개</h2>
</div>
<ul class="tabType1">
<li class="tab active"><button type="button" onclick="contentTab(this,'1');">알림톡</button></li>
<li class="tab"><button type="button" onclick="contentTab(this,'2');">친구톡</button></li>
</ul>
<!-- 알림톡 소개 -->
<div class="tab_content current" id="tab_content_1">
<div class="kakao_intro">
<div class="title">
<h3>알림톡이란?</h3>
@ -203,7 +212,7 @@
</div>
<div class="text">
<div class="btn">
<%-- <a href="<c:url value='/web/mjon/kakao/profile/selectKaKaoProfileList.do'/>">채널 ID 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<%-- <a href="<c:url value='/web/mjon/kakao/profile/selectKaKaoProfileList.do'/>">채널 ID 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<a href="javascript:cntntBtnInfo('step02');">채널 ID 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
@ -226,7 +235,7 @@
</div>
<div class="text">
<div class="btn">
<%-- <a href="<c:url value='/web/mjon/kakao/template/selectKaKaoTemplateList.do'/>">알림톡 템플릿 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<%-- <a href="<c:url value='/web/mjon/kakao/template/selectKaKaoTemplateList.do'/>">알림톡 템플릿 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<a href="javascript:cntntBtnInfo('step03');">알림톡 템플릿 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
@ -293,6 +302,208 @@
</ul>
</div>
</div>
<!-- // 알림톡 소개 -->
<!-- 친구톡 소개 -->
<div class="tab_content friendtalk" id="tab_content_2">
<div class="kakao_intro">
<div class="title">
<h3>친구톡이란?</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<div class="con">
<!--설명-->
<div class="intro">
<img class="phone" src="/publish/images/kakao_intro_cont/phone_friendtalk.png" alt="핸드폰">
<ul class="list">
<li>
<img src="/publish/images/kakao_intro_cont/text_friendtalk.png" alt="카카오톡 전용 기업 메시지 서비스 “알림톡”">
</li>
<li>
<p>1</p>
<p><span>광고성 메시지</span> 발송 가능(광고 표기 및 수신거부 안내 포함)</p>
</li>
<li>
<p>2</p>
<p>채널 친구 추가된 사용자라면 <span>누구에게나</span> 발송 가능</p>
</li>
<li>
<p>3</p>
<p><span>1,000자 이내</span> 텍스트 및 <span>이미지</span> 전송 가능</p>
</li>
<li>
<p>4</p>
<p><span>맞춤형 메시지 및 쿠폰, 링크</span> 버튼 제공 가능</p>
</li>
<li>
<p>5</p>
<p>문자 메시지 대비 <span>O % 이상</span> 저렴</p>
</li>
<li>
<p>6</p>
<p>발송실패 시 <span>대체문자 발송</span> 기능 지원</p>
</li>
<li>
<p>7</p>
<p>클릭률/도달률 분석을 통한 <span>마케팅 효율 강화</span></p>
</li>
<li>
<p>8</p>
<p>브랜드 친화적인 <span>이미지 커스터마이징</span> 가능</p>
</li>
</ul>
</div>
<!--문자vs알림톡-->
<div class="fight">
<div class="line"></div>
<div class="fight-title">
<h4>알림톡 <span>VS</span> 친구톡</h4>
<div class="circle"></div>
</div>
<div class="wrap">
<div class="vs allimtalk_vs">
<div class="title">알림톡</div>
<div class="box">
<ul>
<li>전화번호 보유자</li>
<li>정보성 <span>(예 : 주문, 예약, 안내 등)</span></li>
<li>텍스트, 이미지 등</li>
<li>최대 5개</li>
<li>사전 승인 필요</li>
<li>6.9원</li>
<li>1,000자</li>
<li>로고, 아이콘 형식만 가능</li>
</ul>
</div>
</div>
<div class="vs vs_title">
<div class="title">VS</div>
<ul>
<li>전송대상</li>
<li>발송목적</li>
<li>메세지 형태</li>
<li>버튼 사용</li>
<li>템플릿 승인</li>
<li>비용</li>
<li>길이제한</li>
<li>이미지</li>
</ul>
</div>
<div class="vs friendtalk_vs">
<div class="title">친구톡</div>
<div class="box">
<ul>
<li>채널 친구</li>
<li>광고 및 마케팅성<span>(예 : 이벤트, 쿠폰 등)</span></li>
<li>텍스트, 기본이미지, 와이드 이미지형 등</li>
<li>최대 5개</li>
<li>별도 승인 없음 <span>야간 발송 제한(20:50 ~ 익일 08:00)</span></li>
<li>0.0원 ~ 0.0원</li>
<li>1,000자</li>
<li>가능</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 친구톡 유형 -->
<div class="use">
<div class="title">
<h3>친구톡 유형</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<ul class="friendtalk_use">
<li>
<div class="title">텍스트형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use1.png" alt="">
<p class="explan_text">한/영 구분없이&nbsp;<span>1,000자</span>&nbsp;+ 버튼&nbsp;<span>최대 5개</span></p>
</li>
<li>
<div class="title">기본 이미지형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use2.png" alt="">
<p class="explan_text">한/영 구분없이 <span>400자</span> + 이미지 <span>1</span>장 + 버튼 <span>최대 5개</span></p>
</li>
<li>
<div class="title">와이드 이미지형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use3.png" alt="">
<p class="explan_text">한/영 구분없이 <span>76자</span> + 이미지 <span>1</span>장 + 버튼 <span>최대 1개</span></p>
</li>
</ul>
</div>
<!--서비스이용방법-->
<div class="service">
<div class="title">
<h3>서비스 이용 방법</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<ul class="kakao_use_guide">
<li class="guide_01">
<div class="title">STEP <span>01</span></div>
<i></i>
<p class="guide_title">카카오톡 채널 가입</p>
<span class="guide_info">카카오톡 채널 생성을 위한 <br> 계정이 없으시다면, 카카오에서 <br> 카카오톡 비즈니스 회원가입을<br> 먼저 진행해주세요.</span>
</li>
<li class="guide_02">
<div class="title">STEP <span>02</span></div>
<i></i>
<p class="guide_title">채널 ID 등록하러 가기</p>
<span class="guide_info">가입하신 카카오톡 채널의 채널 ID(채널이름)를 채널 ID 등록 메뉴에 등록해주세요.</span>
</li>
<li class="guide_03">
<div class="title">STEP <span>03</span></div>
<i></i>
<p class="guide_title">친구톡 전송</p>
<span class="guide_info">친구톡은 별도의 템플릿 심사 절차 없이, 즉시 발송 가능합니다.</span>
</li>
</ul>
<!--이용가이드 버튼-->
<div class="guide">
<a href="https://kakaobusiness.gitbook.io/main/ad/brandmessage" target="_blank">친구톡 이용가이드 보기 <img src="/publish/images/kakao_intro_cont/guide_arrow.png" alt="알림톡 이용가이드 화살표"></a>
</div>
</div>
<!--유의사항-->
<div class="note">
<div class="note-title">
<p><span><img src="/publish/images/kakao_intro_cont/note_icon.png" alt="유의사항 아이콘"></span>유의사항</p>
</div>
<ul>
<li>- (광고) 표기 여부는 선택 가능하나 , (광고)표기 해제에 따른 법령상 의무사항을 미 준수시에는 메시지 발송이 중단될 수 있습니다.</li>
<li>- 광고성 친구톡 메시지에는 “(광고) 표시 및 수신거부 방식”이 표시되며, 대체 문자의 경우에는 “(광고) 문구 및 080 무료수신거부 번호”가 자동으로 포함됩니다.</li>
<li><b>- 광고성 메시지의 발송 가능 시간은 08:00 ~ 20:50(한국시간) 입니다.</b></li>
<li>- 친구톡 발송 실패에 따른 대체문자 발송 시 문자요금(단문, 장문, 그림)이 보유 캐시에서 차감됩니다.</li>
<li>- 카카오정책 및 심의기준을 반드시 준수하여야 합니다.</li>
</ul>
</div>
</div>
<!-- // 친구톡 소개 -->
</div>
</div>
</div>
<!--// send top -->

View File

@ -0,0 +1,509 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="ec" uri="/WEB-INF/tld/ecnet_tld.tld"%>
<%@ page import="itn.com.cmm.LoginVO" %>
<form id="bizForm" name="bizForm" method="post">
<input type="hidden" id="menuTopTab" name="menuTopTab" value="tabIntro">
</form>
<div class="inner">
<!-- send top -->
<div class="send_top">
<!-- tab button -->
<%@include file="/WEB-INF/jsp/web/kakao/include/KaKaoAlimtalkTopMenuTap.jsp" %>
<!--// tab button -->
<div class="top_content kakao_intro_cont pay_tab_wrap current">
<div class="heading">
<h2>카카오톡 소개</h2>
</div>
<ul class="tabType1">
<li class="tab active"><button type="button" onclick="contentTab(this,'1');">알림톡</button></li>
<li class="tab"><button type="button" onclick="contentTab(this,'2');">친구톡</button></li>
</ul>
<!-- 알림톡 소개 -->
<div class="tab_content current" id="tab_content_1">
<div class="kakao_intro">
<div class="title">
<h3>알림톡이란?</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<div class="con">
<!--설명-->
<div class="intro">
<img class="phone" src="/publish/images/kakao_intro_cont/phone.png" alt="핸드폰">
<ul class="list">
<li>
<img src="/publish/images/kakao_intro_cont/text.png" alt="카카오톡 전용 기업 메시지 서비스 “알림톡”">
</li>
<li>
<p>1</p>
<p>1,000자 이내 <span>텍스트 및 이미지 전송 가능</span></p>
</li>
<li>
<p>2</p>
<p><span>문자 메시지 대비</span> 65% 이상 저렴</p>
</li>
<li>
<p>3</p>
<p>
<span>카톡 채널아이디를 추가하지 않은 이용자에게도</span>
<br>전화번호만 있으면 메시지 전송 가능
</p>
</li>
<li>
<p>4</p>
<p><span>발송실패 시</span> 자동으로 문자 대체 발송</p>
</li>
<li>
<p>5</p>
<p><span>카카오 인증마크를 통해</span> 신뢰도 높은 메시지 발송</p>
</li>
<li>
<p>6</p>
<p><span>발신자 브랜드의 이미지 및 </span>신뢰도 상승 효과 달성</p>
</li>
</ul>
</div>
<!--문자vs알림톡-->
<div class="fight">
<div class="line"></div>
<div class="fight-title">
<h4>문자 <span>VS</span> 알림톡</h4>
<div class="circle"></div>
</div>
<div class="wrap">
<div class="box box-01">
<div class="fight-img">
<p class="name">문자</p>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/message.jpg.jpg" alt="문자">
<p class="price">18원</p>
</div>
</div>
<p class="vs">VS</p>
<div class="fight-img kakao">
<p class="name">알림톡</p>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/kakao.jpg.jpg" alt="카카오">
<p class="price">6.9원</p>
</div>
</div>
<div class="text">
<p>문자 대비&nbsp;<span>65% 저렴</span></p>
</div>
</div>
<div class="fight-line"></div>
<div class="box box-02">
<div class="fight-img">
<p class="name">문자</p>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/message.jpg.jpg" alt="문자">
<p class="price">90Byte</p>
</div>
</div>
<p class="vs">VS</p>
<div class="fight-img kakao">
<p class="name">알림톡</p>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/kakao.jpg.jpg" alt="카카오">
<p class="price">1,000글자</p>
</div>
</div>
<div class="text">
<p>바이트(byte)에 관계없이&nbsp;<span>무조건 1,000자(한/영) 발송</span></p>
</div>
</div>
</div>
</div>
</div>
</div>
<!--알림톡 활용 방법-->
<div class="use">
<div class="title">
<h3>알림톡 활용 방법</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<div class="tab-wrap">
<ul class="tabs">
<li class="tab-link current" data-tab="tab-1">금융/보험</li>
<li class="tab-link" data-tab="tab-2">기관/단체</li>
<li class="tab-link" data-tab="tab-3">여행</li>
<li class="tab-link" data-tab="tab-4">예약/예매</li>
<li class="tab-link" data-tab="tab-5">배송/배달</li>
<li class="tab-link" data-tab="tab-6">안내/이벤트</li>
</ul>
<div id="tab-1" class="tab-content current">
<img src="/publish/images/kakao_intro_cont/bank.png" alt="금융,보험">
</div>
<div id="tab-2" class="tab-content">
<img src="/publish/images/kakao_intro_cont/organization.png" alt="기관,단체">
</div>
<div id="tab-3" class="tab-content">
<img src="/publish/images/kakao_intro_cont/travel.png" alt="여행">
</div>
<div id="tab-4" class="tab-content">
<img src="/publish/images/kakao_intro_cont/reservation.png" alt="예약,예약">
</div>
<div id="tab-5" class="tab-content">
<img src="/publish/images/kakao_intro_cont/delivery.png" alt="배송,배달">
</div>
<div id="tab-6" class="tab-content">
<img src="/publish/images/kakao_intro_cont/event.png" alt="안내,이벤트">
</div>
</div>
</div>
<!--서비스이용방법-->
<div class="service">
<div class="title">
<h3>서비스 이용 방법</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<div class="con first-line">
<div class="service-01 common">
<div class="step">
<p>STEP <span>01</span></p>
</div>
<div class="text">
<div class="btn">
<a href="https://center-pf.kakao.com/" target="_blank">카카오톡 채널 가입하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
<div class="type">
<p>
카카오톡 채널을 먼저 가입해주신 다음 <br>
비즈니스 채널 전환 신청을 해주세요.
</p>
<p>
※ 가입 후 카카오톡 채널 설정에서 <br>
공개, 검색허용 설정을 하셔야 합니다.
</p>
</div>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/service_01.jpg" alt="카카오톡 채널 가입하러 가기 아이콘">
</div>
</div>
</div>
<div class="service-02 common">
<div class="step">
<p>STEP <span>02</span></p>
</div>
<div class="text">
<div class="btn">
<%-- <a href="<c:url value='/web/mjon/kakao/profile/selectKaKaoProfileList.do'/>">채널 ID 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<a href="javascript:cntntBtnInfo('step02');">채널 ID 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
<div class="type">
<p>
가입하신 카카오톡 채널의 채널ID(채널이름)를 <br>
채널ID 등록 메뉴에 등록해주세요.
</p>
</div>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/service_02.jpg" alt="채널 ID 등록하러 가기 아이콘">
</div>
</div>
</div>
</div>
<div class="con second-line">
<div class="service-03 common">
<div class="step">
<p>STEP <span>03</span></p>
</div>
<div class="text">
<div class="btn">
<%-- <a href="<c:url value='/web/mjon/kakao/template/selectKaKaoTemplateList.do'/>">알림톡 템플릿 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a> --%>
<a href="javascript:cntntBtnInfo('step03');">알림톡 템플릿 등록하러 가기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
<div class="type">
<p>
알림톡 발송을 위해서는 사용하실 템플릿(메시지 내용)에
대한 카카오의 승인이 반드시 필요합니다.
템플릿을 작성하신 후 심사요청을 진행해주세요.
</p>
<p>
※ 템플릿 승인까지 최대 3일 소요
</p>
</div>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/service_03.jpg" alt="알림톡 템플릿 등록하러 가기 아이콘">
</div>
</div>
</div>
<div class="service-04 common">
<div class="step">
<p>STEP <span>04</span></p>
</div>
<div class="text">
<div class="btn">
<a href="<c:url value='/web/mjon/alimtalk/kakaoAlimtalkMsgDataView.do'/>">알림톡 전송하기<img src="/publish/images/kakao_intro_cont/arrow.jpg" alt="화살표"></a>
</div>
<div class="text-line"></div>
<div class="type">
<p>
템플릿이 승인되셨다면 문자온 알림톡을 <br>
통해 메시지를 발송하실 수 있습니다.
</p>
</div>
<div class="icon">
<img src="/publish/images/kakao_intro_cont/service_04.jpg" alt="알림톡 전송하기 아이콘">
</div>
</div>
</div>
</div>
<!--이용가이드 버튼-->
<div class="guide">
<a href="https://kakaobusiness.gitbook.io/main/ad/bizmessage/notice-friend" target="_blank">알림톡 이용가이드 보기 <img src="/publish/images/kakao_intro_cont/guide_arrow.png" alt="알림톡 이용가이드 화살표"></a>
</div>
</div>
<!--유의사항-->
<div class="note">
<div class="note-title">
<p>
<span>
<img src="/publish/images/kakao_intro_cont/note_icon.png" alt="유의사항 아이콘">
</span>유의사항
</p>
</div>
<ul>
<li>- 한글, 영문 구분 없이 최대 1,000자까지 전송 가능합니다.</li>
<li>- 알림톡 발송 실패에 따른 대체문자 발송 시 문자요금(단문, 장문, 그림)이 보유 캐시에서 차감됩니다.</li>
<li>- 알림톡에서 허용하는 영리목적이 없는 정보성 메시지에 해당하는지 여부는 스팸 관련 정보통신망법 안내서를 꼭 참고하시길 바랍니다.</li>
<li>(주문/예약 확인, 결제 내역, 배송 현황 메시지 등이 이에 해당하며 구독자 대상의 뉴스레터나 일반적인 공지문은 포함되지 않습니다.)</li>
<li>
<a href="/download/msg/K003_불법스팸_방지_안내서_제6차_개정판(수정_2024년).pdf" target="_blank">스팸 관련 정보통신망법 안내서 바로가기</a>
</li>
<li>- 부고, 답례, 초대장 등은 정보성 메시지가 아니므로 알림톡으로 보내실 수 없습니다. </li>
</ul>
</div>
</div>
<!-- // 알림톡 소개 -->
<!-- 친구톡 소개 -->
<div class="tab_content friendtalk" id="tab_content_2">
<div class="kakao_intro">
<div class="title">
<h3>친구톡이란?</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<div class="con">
<!--설명-->
<div class="intro">
<img class="phone" src="/publish/images/kakao_intro_cont/phone_friendtalk.png" alt="핸드폰">
<ul class="list">
<li>
<img src="/publish/images/kakao_intro_cont/text_friendtalk.png" alt="카카오톡 전용 기업 메시지 서비스 “알림톡”">
</li>
<li>
<p>1</p>
<p><span>광고성 메시지</span> 발송 가능(광고 표기 및 수신거부 안내 포함)</p>
</li>
<li>
<p>2</p>
<p>채널 친구 추가된 사용자라면 <span>누구에게나</span> 발송 가능</p>
</li>
<li>
<p>3</p>
<p><span>1,000자 이내</span> 텍스트 및 <span>이미지</span> 전송 가능</p>
</li>
<li>
<p>4</p>
<p><span>맞춤형 메시지 및 쿠폰, 링크</span> 버튼 제공 가능</p>
</li>
<li>
<p>5</p>
<p>문자 메시지 대비 <span>저렴한</span> 단가</p>
</li>
<li>
<p>6</p>
<p>발송실패 시 <span>대체문자 발송</span> 기능 지원</p>
</li>
<li>
<p>7</p>
<p>클릭률/도달률 분석을 통한 <span>마케팅 효율 강화</span></p>
</li>
<li>
<p>8</p>
<p>브랜드 친화적인 <span>이미지 커스터마이징</span> 가능</p>
</li>
</ul>
</div>
<!--문자vs알림톡-->
<div class="fight">
<div class="line"></div>
<div class="fight-title">
<h4>알림톡 <span>VS</span> 친구톡</h4>
<div class="circle"></div>
</div>
<div class="wrap">
<div class="vs allimtalk_vs">
<div class="title">알림톡</div>
<div class="box">
<ul>
<li>전화번호 보유자</li>
<li>정보성 <span>(예 : 주문, 예약, 안내 등)</span></li>
<li>텍스트, 이미지 등</li>
<li>최대 5개</li>
<li>사전 승인 필요</li>
<li>6.9원</li>
<li>1,000자</li>
<li>로고, 아이콘 형식만 가능</li>
</ul>
</div>
</div>
<div class="vs vs_title">
<div class="title">VS</div>
<ul>
<li>전송대상</li>
<li>발송목적</li>
<li>메세지 형태</li>
<li>버튼 사용</li>
<li>템플릿 승인</li>
<li>비용</li>
<li>길이제한</li>
<li>이미지</li>
</ul>
</div>
<div class="vs friendtalk_vs">
<div class="title">친구톡</div>
<div class="box">
<ul>
<li>채널 친구</li>
<li>광고 및 마케팅성<span>(예 : 이벤트, 쿠폰 등)</span></li>
<li>텍스트, 기본이미지, 와이드 이미지형 등</li>
<li>최대 5개</li>
<li>별도 승인 없음 <span>야간 발송 제한(20:50 ~ 익일 08:00)</span></li>
<li>13.8원 ~ 22.9원</li>
<li>1,000자</li>
<li>가능</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 친구톡 유형 -->
<div class="use">
<div class="title">
<h3>친구톡 유형</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<ul class="friendtalk_use">
<li>
<div class="title">텍스트형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use1.png" alt="">
<p class="explan_text">한/영 구분없이&nbsp;<span>1,000자</span>&nbsp;+ 버튼&nbsp;<span>최대 5개</span></p>
</li>
<li>
<div class="title">기본 이미지형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use2.png" alt="">
<p class="explan_text">한/영 구분없이 <span>400자</span> + 이미지 <span>1</span>장 + 버튼 <span>최대 5개</span></p>
</li>
<li>
<div class="title">와이드 이미지형</div>
<img src="/publish/images/kakao_intro_cont/friendtalk_use3.png" alt="">
<p class="explan_text">한/영 구분없이 <span>76자</span> + 이미지 <span>1</span>장 + 버튼 <span>최대 1개</span></p>
</li>
</ul>
</div>
<!--서비스이용방법-->
<div class="service">
<div class="title">
<h3>서비스 이용 방법</h3>
</div>
<div class="title-line">
<div class="left-line"></div>
<div class="right-line"></div>
</div>
<ul class="kakao_use_guide">
<li class="guide_01">
<div class="title">STEP <span>01</span></div>
<i></i>
<p class="guide_title">카카오톡 채널 가입</p>
<span class="guide_info">카카오톡 채널 생성을 위한 <br> 계정이 없으시다면, 카카오에서 <br> 카카오톡 비즈니스 회원가입을<br> 먼저 진행해주세요.</span>
</li>
<li class="guide_02">
<div class="title">STEP <span>02</span></div>
<i></i>
<p class="guide_title">채널 ID 등록하러 가기</p>
<span class="guide_info">가입하신 카카오톡 채널의 채널 ID(채널이름)를 채널 ID 등록 메뉴에 등록해주세요.</span>
</li>
<li class="guide_03">
<div class="title">STEP <span>03</span></div>
<i></i>
<p class="guide_title">친구톡 전송</p>
<span class="guide_info">친구톡은 별도의 템플릿 심사 절차 없이, 즉시 발송 가능합니다.</span>
</li>
</ul>
<!--이용가이드 버튼-->
<div class="guide">
<a href="https://kakaobusiness.gitbook.io/main/ad/brandmessage" target="_blank">친구톡 이용가이드 보기 <img src="/publish/images/kakao_intro_cont/guide_arrow.png" alt="알림톡 이용가이드 화살표"></a>
</div>
</div>
<!--유의사항-->
<div class="note">
<div class="note-title">
<p><span><img src="/publish/images/kakao_intro_cont/note_icon.png" alt="유의사항 아이콘"></span>유의사항</p>
</div>
<ul>
<li>- (광고) 표기 여부는 선택 가능하나 , (광고)표기 해제에 따른 법령상 의무사항을 미 준수시에는 메시지 발송이 중단될 수 있습니다.</li>
<li>- 광고성 친구톡 메시지에는 “(광고) 표시 및 수신거부 방식”이 표시되며, 대체 문자의 경우에는 “(광고) 문구 및 080 무료수신거부 번호”가 자동으로 포함됩니다.</li>
<li><b>- 광고성 메시지의 발송 가능 시간은 08:00 ~ 20:50(한국시간) 입니다.</b></li>
<li>- 친구톡 발송 실패에 따른 대체문자 발송 시 문자요금(단문, 장문, 그림)이 보유 캐시에서 차감됩니다.</li>
<li>- 카카오정책 및 심의기준을 반드시 준수하여야 합니다.</li>
</ul>
</div>
</div>
<!-- // 친구톡 소개 -->
</div>
</div>
</div>
<!--// send top -->

View File

@ -0,0 +1,155 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<% pageContext.setAttribute("newLineChar", "\n"); %>
<div class="phone">
<!-- 탭스타일 -->
<div class="list_tab_wrap2 type5 kakao_rev_tab">
<ul class="tabType3" id="tabType" name="tabType">
<li class="tab active"><button type="button" onclick="phoneTab(this,'1');" title="선택됨">카카오톡</button></li>
<c:if test="${resultMsgDetail.bizKakaoResendYn eq 'Y'}">
<li class="tab"><button type="button" onclick="phoneTab(this,'2');">대체문자</button></li>
</c:if>
</ul>
</div>
<!--// 탭스타일 -->
<!-- 카카오 알림톡 미리보기 -->
<!-- <div class="tab_phone current" id="tab_phone_1"> -->
<!-- <div class="phone_kakako friendtalk"> -->
<div class="tab_phone current kakao_wrap" id="tab_phone_1">
<div class="phone_kakako friendtalk">
<div class="phoneIn">
<p class="prev_p"><img src="/publish/images/content/kakao_prev_icon.png" alt=""><c:out value="${searchVO.yellowId}"/></p>
<!-- 텍스트 미리보기 -->
<div class="text_preview">
<%--< div class="allimtalk_title">
<img src="/publish/images/content/icon_allimtalk.png" alt="">
<c:choose>
<c:when test="${msgType eq '8'}">알림톡 도착</c:when>
<c:when test="${msgType eq '9'}">친구톡 도착</c:when>
</c:choose>
</div> --%>
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="friend_talk_title"><span>(광고)</span></p>
</c:if>
<div class="allimtalk_content">
<c:choose>
<c:when test="${kakaoTemplateInfo.templateEmphasizeType eq 'TEXT'}">
<p class="emphasis_side_text"><c:out value="${kakaoTemplateInfo.templateSubtitle}"/></p>
<p class="emphasis_title_text"><c:out value="${kakaoTemplateInfo.templateTitle}"/></p>
</c:when>
<c:when test="${kakaoTemplateInfo.templateEmphasizeType eq 'IMAGE'}">
<div class="kakao_image">
<img src="<c:url value='${kakaoTemplateInfo.templateImageUrl}'/>" alt="">
</div>
</c:when>
</c:choose>
<p class="template_text">
<c:out value="${fn:replace(fn:replace(kakaoTemplateInfo.templateContent, newLineChar, '<br/>'), newLineChar2, '<br/>')}" escapeXml="false"/>
</p>
<c:choose>
<c:when test="${kakaoTemplateInfo.templateMessageType eq 'EX'}">
<p class="side_info_text"><c:out value="${kakaoTemplateInfo.templateExtra}"/></p>
</c:when>
<c:when test="${kakaoTemplateInfo.templateMessageType eq 'AD'}">
<p class="channel_info_text"><c:out value="${kakaoTemplateInfo.templateAd}"/></p>
</c:when>
</c:choose>
<c:forEach var="templatInfoButtonList" items="${kakaoTemplateInfo.buttonList}" varStatus="status">
<c:choose>
<c:when test="${templatInfoButtonList.name eq '채널 추가'}">
<button type="button" class="btn_kakao_channel"><img src="/publish/images/content/icon_kakao_channel_plus.png" alt=""> 채널추가</button>
</c:when>
<c:otherwise>
<button type="button" class="btn_kakao_type"><c:out value="${templatInfoButtonList.name}"/></button>
</c:otherwise>
</c:choose>
</c:forEach>
</div>
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="kakao_block_text">수신거부 : 홈 > 채널차단</p>
</c:if>
</div>
</div>
<p class="addText">※ 단말기 설정에 따라 다르게 보일 수 있습니다</p>
</div>
</div>
<!--// 카카오 알림톡 미리보기 -->
<c:if test="${resultMsgDetail.bizKakaoResendYn eq 'Y'}">
<!-- 문자 미리보기 -->
<div class="tab_phone" id="tab_phone_2" style="display: none;position:relative;">
<!-- <div class="tab_phone" id="tab_phone_2" > -->
<!-- <div class="tab_phone" id="tab_phone_2" style="display:none" > -->
<div class="phoneIn">
<div>
<p class="prev_p"><img src="/publish/images/search.png"> 문자내용</p>
<div class="text_length2 clearfix">
<c:if test="${resultMsgDetail.bizKakaoResendYn eq 'Y'}">
<c:choose>
<c:when test="${resultMsgDetail.bizKakaoResendType eq 'SMS'}">
<span class="msg_com msg_short">단문</span>
</c:when>
<c:otherwise>
<span class="msg_com msg_long">장문</span>
</c:otherwise>
</c:choose>
<%-- <c:choose>
<c:when test="${resultMsgDetail.bizKakaoResendTypeCnt > 1}">
<span class="msg_com msg_short">단문</span>
<span class="msg_com msg_long">장문</span>
</c:when>
<c:when test="${resultMsgDetail.bizKakaoResendTypeCnt < 2
&& resultMsgDetail.bizKakaoResendType eq 'SMS'}">
<span class="msg_com msg_short">단문</span>
</c:when>
<c:otherwise>
<span class="msg_com msg_long">장문</span>
</c:otherwise>
</c:choose> --%>
</c:if>
<!-- <div>
<span>글자크기</span>
<button type="button" onclick="changeFontSize('plus');"><img src="/publish/images/content/font_plus.png"></button>
<button type="button" onclick="changeFontSize('minus');"><img src="/publish/images/content/font_minus.png"></button>
</div> -->
</div>
<div class="text_preview">
<c:if test="${not empty fileInfos}">
<div class="preiew_img">
<c:forEach var="fileInfo" items="${fileInfos}">
<div class="img_box">
<img src="<c:url value='/cmm/fms/getImage2.do'/>?atchFileId=<c:out value="${fileInfo.atchFileId}"/>&fileSn=<c:out value="${fileInfo.fileSn}"/>" alt="발송된 그림문자 미리보기" style="width: 100%">
</div>
</c:forEach>
</div>
</c:if>
<div class="preview_auto">
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="ad_tit">(광고)</p>
</c:if>
<p class="realtime">${fn:replace(resultMsgDetail.bizKakaoResendOrgnlTxt, newLineChar, "<br/>")}</p>
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="deny_receipt">무료거부 0808800858</p>
</c:if>
</div>
</div>
</div>
</div>
<p class="addText">※ 단말기 설정에 따라 다르게 보일 수 있습니다</p>
</div>
</c:if>
<!--// 문자 미리보기 -->
</div>

View File

@ -18,17 +18,29 @@
<!--// 탭스타일 -->
<!-- 카카오 알림톡 미리보기 -->
<!-- <div class="tab_phone current" id="tab_phone_1"> -->
<!-- <div class="phone_kakako friendtalk"> -->
<div class="tab_phone current kakao_wrap" id="tab_phone_1">
<div class="phone_kakako friendtalk">
<div class="phoneIn">
<p class="prev_p"><img src="/publish/images/content/kakao_prev_icon.png" alt=""><c:out value="${searchVO.yellowId}"/></p>
<div class="rev_pop_middle clearfix">
<fmt:parseDate value="${resultMsgDetail.reqDate}" var="parsedDate" pattern="yyyy-MM-dd HH:mm:ss.S"/>
<span>발송일시 : <fmt:formatDate value="${parsedDate}" pattern="yyyy-MM-dd HH:mm:ss"/></span>
<span class="msg_com msg_allimtalk">
<c:choose>
<c:when test="${msgType eq '8'}">알림톡</c:when>
<c:when test="${msgType eq '9'}">친구톡</c:when>
</c:choose>
</span>
</div>
<!-- 텍스트 미리보기 -->
<div class="rev_pop_txt">
<div class="text_preview">
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="friend_talk_title"><span>(광고)</span></p>
</c:if>
<div class="allimtalk_title">
<img src="/publish/images/content/icon_allimtalk.png" alt="">
<c:choose>
<c:when test="${msgType eq '8'}">알림톡 도착</c:when>
<c:when test="${msgType eq '9'}">친구톡 도착</c:when>
</c:choose>
</div>
<div class="allimtalk_content">
<c:choose>
<c:when test="${kakaoTemplateInfo.templateEmphasizeType eq 'TEXT'}">
@ -41,7 +53,9 @@
</div>
</c:when>
</c:choose>
<c:if test="${resultMsgDetail.adFlag eq 'Y'}">
<p class="friend_talk_title"><span>(광고)</span></p>
</c:if>
<p class="template_text">
<c:out value="${fn:replace(fn:replace(kakaoTemplateInfo.templateContent, newLineChar, '<br/>'), newLineChar2, '<br/>')}" escapeXml="false"/>
</p>
@ -73,6 +87,7 @@
</div>
</div>
</div>
<p class="addText">※ 단말기 설정에 따라 다르게 보일 수 있습니다</p>
</div>
</div>
@ -90,10 +105,10 @@
<c:if test="${resultMsgDetail.bizKakaoResendYn eq 'Y'}">
<c:choose>
<c:when test="${resultMsgDetail.bizKakaoResendType eq 'SMS'}">
<span class="msg_com msg_short">단문</span>
<span class="msg_com msg_short" style="float:right;">단문</span>
</c:when>
<c:otherwise>
<span class="msg_com msg_long">장문</span>
<span class="msg_com msg_long" style="float:right;">장문</span>
</c:otherwise>
</c:choose>
<%-- <c:choose>

View File

@ -644,12 +644,7 @@ function fn_sentDetailView(msgGroupId) {
<ul class="list_tab">
<li class="tab active"><button type="button" onclick="fnTabLoad('',0); return false;">전체</button></li>
<li class="tab"><button type="button" onclick="fnTabLoad('at', 1); return false;">알림톡</button></li>
<c:if test="${pageContext.request.serverName == 'localhost'
|| pageContext.request.serverName == '119.193.215.98'
|| pageContext.request.serverName == '192.168.0.176'
}">
<li class="tab"><button type="button" onclick="fnTabLoad('ft', 2); return false;">친구톡</button></li>
</c:if>
</ul><!--// tab button -->
</div>
<!-- 예약관리 > 전체 -->

View File

@ -11,7 +11,7 @@
<%-- <label for="subject" class="label">발송된 문자 제목</label>
<input type="text" id="subject" name="subject" placeholder="${resultMsgDetail.subject}" value="${resultMsgDetail.subject}" readonly> --%>
<div class="rev_pop_middle clearfix">
<span>발송일시 : <c:out value="${resultMsgDetail.sentDate}"/></span>
<span>발송일시 : <c:out value="${resultMsgDetail.reqDate}"/></span>
<c:choose>
<c:when test="${resultMsgDetail.msgType == '4'}">
<span class="msg_com msg_short">SMS</span>

View File

@ -563,7 +563,7 @@ function fnRevDetailPop03(msgGroupId){
<li class="tab"><button type="button" onclick="payUserTab(this,'mms');">그림</button></li>
<li class="tab"><button type="button" onclick="payUserTab(this,'cam');">선거</button></li>
<li class="tab"><button type="button" onclick="payUserTab(this,'at');">알림톡</button></li>
<!-- <li class="tab"><button type="button" onclick="payUserTab(this,'ft');">친구톡</button></li> -->
<li class="tab"><button type="button" onclick="payUserTab(this,'ft');">친구톡</button></li>
<li class="tab"><button type="button" onclick="payUserTab(this,'fax');">팩스</button></li>
</ul>
<!--// tab button -->