This commit is contained in:
hehihoho3@gmail.com 2025-10-27 11:04:29 +09:00
commit 6ccf642f6c
8 changed files with 248 additions and 721 deletions

View File

@ -284,7 +284,6 @@ public class MjonMsgVO extends ComDefaultVO{
private String totFWPriceSum;
private String resultLogUpdtPnttm;
private int successCount; // 문자발송 성공건수
private int callRejectionCount; // 번호도용 문자차단 서비스로 착신거절 오류
private String callbackYn; // 번호도용 문자차단 서비스로 인한 발송실패 문자알림 여부(N:미알림, Y:알림)
private String userCallbackYn;
@ -315,5 +314,18 @@ public class MjonMsgVO extends ComDefaultVO{
private List<MjonMsgSendVO> mjonMsgSendVOList = new ArrayList<>();
private String rsltCodeMsgTxt; //전송사 결과 코드 내용
private int waitCount; //대기 건수
private int successCount; //문자발송 성공건수
private int failCount; //실패 건수
private int resendWaitCount; //대체문자 대기 건수
private int resendSuccCount; //대체문자 성공 건수
private int resendFailCount; //대체문자 실패 건수
private String[] msgTypeList; //발송 타입 리스트
private String selectType; //조회 타입 ex) reqDateLast3M : 발송일이 지난 3개월간
private String yellowId; //채널아이디
private String yellowIdYn; //채널아이디 여부
}

View File

@ -190,7 +190,8 @@ public interface MjonMsgDataService {
public MjonMsgReturnVO sendSysMsgData(MjonMsgVO mjonMsgVO, HttpServletRequest request) throws Exception;
//mj_msg_data 테이블의 msg_result 컬럼을 이용한 발송건수 조회 쿼리
public List<MjonMsgVO> selectSendListByResultCode(MjonMsgVO mjonMsgVO) throws Exception;
}

View File

@ -462,7 +462,10 @@ public class MjonMsgDataDAO extends EgovAbstractDAO {
return totalInsertedCount; // 처리된 전체 데이터 반환
}
@SuppressWarnings("unchecked")
public List<MjonMsgVO> selectSendListByResultCode(MjonMsgVO mjonMsgVO) throws Exception{
return (List<MjonMsgVO>) list("mjonMsgDAO.selectSendListByResultCode",mjonMsgVO);
}
public Timestamp convertToTimestamp(String reqDate) {
try {

View File

@ -5147,5 +5147,10 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M
return returnVO;
}
@Override
public List<MjonMsgVO> selectSendListByResultCode(MjonMsgVO mjonMsgVO) throws Exception {
return mjonMsgDataDAO.selectSendListByResultCode(mjonMsgVO);
}
}

View File

@ -45,479 +45,4 @@ import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S") // Scheduler Lock 사용 가능 설정 (기본 30초동안 Lock)
public class SchedulerUtil {
@Resource(name = "SchdlrManageService")
private SchdlrManageService schdlrManageService;
@Resource (name = "MailTemplateService")
private MailTemplateService mailTemplateService;
@Resource (name = "userManageService")
private EgovUserManageService egovUserManageService;
@Resource(name = "hackIpService")
private HackIpService hackIpService;
@Resource(name = "mjonMsgService")
private MjonMsgService mjonMsgService;
@Resource(name = "KakaoStatisticsService")
private KakaoStatisticsService kakaoStatisticsService;
@Resource(name = "propertiesService")
protected EgovPropertyService propertyService;
@Resource(name = "conectStatsService")
private EgovConectStatsService conectStatsService;
/** 알림전송 Util */
@Resource(name = "mjonNoticeSendUtil")
private MjonNoticeSendUtil mjonNoticeSendUtil;
@Resource(name = "faxAdmService")
private FaxAdmService faxAdmService;
@Resource(name = "LetterService")
private LetterService letterService;
@Resource(name="MjonMsgDataDAO")
private MjonMsgDataDAO mjonMsgDataDAO;
/** 설정값 가져오기 */
@Value("#{globalSettings['Globals.Env']}")
private String GlobalsEnv;
private static final String ONE_MIN = "PT1M"; // 1분동안 LOCK
/*
* 10분 마다 1주일 데이터에서 환불 대상을 찾아서 환불 한다.
* */
// Schdule Lock (10분동안)
@Scheduled(cron = "0 0/10 * * * ?")
@SchedulerLock(name = "runScenarioOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runScenarioOneTime() throws Exception {
// do something...
try {
System.out.println("=============SchedulerUtil=====runScenarioOneTime =============>");
System.out.println("=============SchedulerUtil=====runScenarioOneTime =============>");
System.out.println("=============SchedulerUtil=====runScenarioOneTime =============>");
System.out.println("=============SchedulerUtil=====runScenarioOneTime =============>");
System.out.println("=============SchedulerUtil=====runScenarioOneTime =============>");
//문자 환불, 팩스 환불
PayBack("");
/*
// 문자 환불
schdlrManageService.msgFailPayBack();
* */
// do something...
}catch(Exception ex) {
ex.printStackTrace();
}
}
/*
* 매일 5시20분 20초에 31일전 데이터에서 환불 대상을 찾아서 환불 한다.
* */
@Scheduled(cron = "20 25 5 * * ?")
@SchedulerLock(name = "runScenarioOneTimeOneByDay", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runScenarioOneTimeOneByDay() throws Exception {
// do something...
try {
System.out.println("=============EgovSysLogScheduling=====runScenarioOneTimeOneByDay =============>");
//문자 환불, 팩스 환불
PayBack("ONE");
/*
// 문자 환불
schdlrManageService.msgFailPayBack();
* */
}catch(Exception ex) {
ex.printStackTrace();
}
}
// Schdule Lock (2분동안)
//세틀뱅크 자동 충전 배치
@Scheduled(cron = "0 0/2 * * * ?")
@SchedulerLock(name = "runVacsChargeOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runVacsChargeOneTime() throws Exception {
System.out.println("=============EgovSysLogScheduling=====runVacsChargeOneTime =============>");
// do something...
try {
schdlrManageService.vacsAutoCharge();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 매일 오전 4시마다 실행 ex) 04:00
// 휴면회원으로 지정
@Scheduled(cron = "0 0 4 * * *")
@SchedulerLock(name = "runMemberDormantUpdate", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runMemberDormantUpdate() throws Exception {
System.out.println("=============EgovSysLogScheduling=====runMemberDormantUpdate =============>");
try {
mailTemplateService.setMemberDormantUpdate();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 매일 오전 8시마다 실행 ex) 08:00
// 휴면회원 메일발송
@Scheduled(cron = "0 0 8 * * *")
@SchedulerLock(name = "runMailSendMemberDormant", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runMailSendMemberDormant() throws Exception {
System.out.println("=============EgovSysLogScheduling=====runMailSendMemberDormant =============>");
try {
mailTemplateService.mailSendMemberDormant();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 매일 오전 10시마다 실행 ex) 10:00
// 휴면회원 SMS발송
@Scheduled(cron = "0 0 10 * * *")
@SchedulerLock(name = "runSmsSendMemberDormant", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runSmsSendMemberDormant() throws Exception {
System.out.println("=============EgovSysLogScheduling=====runSmsSendMemberDormant =============>");
try {
mailTemplateService.smsSendMemberDormant();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 매일 오전 5시마다 실행 ex) 05:00
// 문자 우선순위 랜덤 업데이트 All
@Scheduled(cron = "0 0 5 * * *")
@SchedulerLock(name = "runLetterPriorityUpdateAll", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runLetterPriorityUpdateAll() throws Exception {
System.out.println("=============EgovSysLogScheduling=====runLetterPriorityUpdateAll =============>");
try {
letterService.updateLetterPriorityAll();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 매달 1일 0시 10분 실행
// "0 10 0 1 * *"
// 매달 3일 6시 40분 실행
// "0 40 18 3 * *"
// 매일 오전 1시 1분 0초
// "0 1 1 * * *"
// @Scheduled(cron = "0 * * * * *") // 1분마다 실행(TEST)
@Scheduled(cron = "0 1 0 1 * *") // 매달 1일 0시 1분 실행
@SchedulerLock(name = "runUserCashByAutoCashUpdate", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runUserCashByAutoCashUpdate() throws Exception {
//System.out.println("AutoCash Start");
// 후불제회원 Cash충전
//egovUserManageService.updateUserCashByAutoCash();
//System.out.println("AutoCash End");
try {
System.out.println("AutoCash Start");
// 후불제회원 Cash충전
egovUserManageService.updateUserCashByAutoCash();
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 트래픽 감시 스케줄러
// 3분마다 실행
@Scheduled(cron = "0 0/3 * * * ?")
@SchedulerLock(name = "highTrafficIgnoreIpInsert", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void highTrafficIgnoreIpInsert() throws Exception {
//5분 300회 이상 접속로그가 있는 경우 차단아이피 등록
//hackIpService.selectHighTrafficNotIgnoreIp();
try {
System.out.println("=============EgovSysLogScheduling=====highTrafficIgnoreIpInsert =============>");
//5분 300회 이상 접속로그가 있는 경우 차단아이피 등록
hackIpService.selectHighTrafficNotIgnoreIp();
// do something...
}catch(Exception ex) {
ex.printStackTrace();
}
}
// AGENT별 SMS LMS MMS 발송건수 , 카카오 알림톡 발송건수 통계 스케쥴러
@Scheduled(cron = "0 10 1 * * *") // 매일 새벽1시 10분 실행
@SchedulerLock(name = "insertAgentSmsCountStat", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void agentSmsCountStatInsert() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====insertAgentSmsCountStat scheduler RUN (YESTERDAY) =============>");
int minusDate =EgovDateUtil.dayMinusToInt("yyyyMMdd", 1);
int minusSevenDays =EgovDateUtil.dayMinusToInt("yyyyMMdd", 7);
// 전일 문자발송 통계 insert
MjonMsgStatVO mjonMsgStatVO = new MjonMsgStatVO();
mjonMsgStatVO.setStatStartDate(minusSevenDays);
mjonMsgStatVO.setStatEndDate(minusDate);
mjonMsgService.insertAgentSmsCountStat(mjonMsgStatVO);
// 전일 알림톡발송 통계 insert
MjonKakaoAtStatVO kakaoAtStatVO = new MjonKakaoAtStatVO();
kakaoAtStatVO.setStatStartDate(minusSevenDays);
kakaoAtStatVO.setStatEndDate(minusDate);
kakaoStatisticsService.insertKakaoAtCountStat(kakaoAtStatVO);
// 전일 알림톡발송 통계 insert
FaxStatVO faxStatVO = new FaxStatVO();
faxStatVO.setStatStartDate(minusSevenDays);
faxStatVO.setStatEndDate(minusDate);
faxAdmService.insertFaxCountStat(faxStatVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// AGENT별 SMS 발송건수 통계 스케쥴러
@Scheduled(cron = "0 5,35 * * * *") // 5,35분마다 실행
@SchedulerLock(name = "insertAgentSmsCountStatByMinute", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void agentSmsCountStatByMinuteInsert() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====insertAgentSmsCountStatByMinute =============>");
int nowDate =EgovDateUtil.nowDateToInt("yyyyMMdd");
// 당일 문자발송 통계 insert
MjonMsgStatVO mjonMsgStatVO = new MjonMsgStatVO();
mjonMsgStatVO.setStatStartDate(nowDate);
mjonMsgStatVO.setStatEndDate(nowDate);
mjonMsgService.insertAgentSmsCountStat(mjonMsgStatVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// AGENT별 Kakao 발송건수 통계 스케쥴러
//@Scheduled(cron = "0 10,40 * * * *") // 10,40분마다 실행
//@Scheduled(cron = "0 47 * * * *") // 47분마다 실행
@Scheduled(cron = "0 57 23 * * *")
@SchedulerLock(name = "insertAgentKakaoCountStatByMinute", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void agentKakaoCountStatByMinuteInsert() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====insertAgentKakaoCountStatByMinute =============>");
int nowDate =EgovDateUtil.nowDateToInt("yyyyMMdd");
// 당일 알림톡발송 통계 insert
MjonKakaoAtStatVO kakaoAtStatVO = new MjonKakaoAtStatVO();
kakaoAtStatVO.setStatStartDate(nowDate);
kakaoAtStatVO.setStatEndDate(nowDate);
kakaoStatisticsService.insertKakaoAtCountStat(kakaoAtStatVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// AGENT별 Fax 발송건수 통계 스케쥴러
@Scheduled(cron = "0 15,45 * * * *") // 15,45분마다 실행
@SchedulerLock(name = "insertAgentFaxCountStatByMinute", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void agentFaxCountStatByMinuteInsert() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====insertAgentFaxCountStatByMinute =============>");
int nowDate =EgovDateUtil.nowDateToInt("yyyyMMdd");
// 전일 카톡발송 통계 insert
FaxStatVO faxStatVO = new FaxStatVO();
faxStatVO.setStatStartDate(nowDate);
faxStatVO.setStatEndDate(nowDate);
faxAdmService.insertFaxCountStat(faxStatVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 대시보드 어제/오늘 접속현황 & 접속통계
@Scheduled(cron = "0 1 0 * * *") // 매일 새벽0시 1분 실행
@SchedulerLock(name = "insertDashBoardStat", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void dashBoardStatInsert() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====dashBoardStatInsert =============>");
// 어제날짜
Calendar calendar = new GregorianCalendar();
SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
String yesterdayDate = SDF.format(calendar.getTime());
calendar.add(Calendar.DATE, -1);
yesterdayDate = SDF.format(calendar.getTime());
StatsVO yesterdayStatsVO = new StatsVO();
yesterdayStatsVO.setStatDate(yesterdayDate);
// 대시보드 인서트 Logic
conectStatsService.insertDashBoardStatLogic(yesterdayStatsVO);
// 대시보드 업데이트 Logic
conectStatsService.updateDashBoardStatLogic(yesterdayStatsVO);
// 오늘날짜
Date nowDate = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String strNowDate = simpleDateFormat.format(nowDate);
StatsVO statsVO = new StatsVO();
statsVO.setStatDate(strNowDate);
// 대시보드 인서트 Logic
conectStatsService.insertDashBoardStatLogic(statsVO);
// 대시보드 업데이트 Logic
conectStatsService.updateDashBoardStatLogic(statsVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 대시보드 어제/오늘 접속현황 & 접속통계
@Scheduled(cron = "0 20,50 * * * *") // 20,50분마다 실행
@SchedulerLock(name = "updateDashBoardStat", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void dashBoardStatUpdate() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====DashBoardStatUpdate =============>");
// 오늘날짜
Date nowDate = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String strNowDate = simpleDateFormat.format(nowDate);
StatsVO statsVO = new StatsVO();
statsVO.setStatDate(strNowDate);
// 대시보드 인서트 Logic
conectStatsService.insertDashBoardStatLogic(statsVO);
// 대시보드 업데이트 Logic
conectStatsService.updateDashBoardStatLogic(statsVO);
}catch(Exception ex) {
ex.printStackTrace();
}
}
// 이용약관 메일발송
@Scheduled(cron = "0 */15 * * * *") // 15분마다 실행
@SchedulerLock(name = "sendTermsEmail", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void TermsEmailSend() throws Exception {
try {
System.out.println("=============EgovSysLogScheduling=====TermsEmailSend =============>");
// 이용약관 회원 전체발송
mjonNoticeSendUtil.userAllTermsEmailSend();
}catch(Exception ex) {
ex.printStackTrace();
}
}
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
@Scheduled(cron = "0 0/3 * * * ?") // 3분마다 실행
@SchedulerLock(name = "runKakaoOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
public void runKakaoOneTime() throws Exception {
// do something...
try {
System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>");
schdlrManageService.kakaoFailPayBack();
}catch(Exception ex) {
ex.printStackTrace();
}
}
//환불 실행
private void PayBack(String p_type) throws Exception {
// 문자 환불
schdlrManageService.payBack_advc(p_type);
/*
if ("ONE".equals(p_type)) { //하루에 한번만 31일 대상으로 실행
schdlrManageService.msgFailPayBackOneByDay();
}else {
// 10분 마다 1주일 데이터에서 환불 대상을 찾아서 환불 한다.
//어플리케이션 트랜잭션 문제가 있어 Util 단으로 DB 호출을 가져옴 - 2024-03-14
//schdlrManageService.msgFailPayBack();
List<MjonMsgVO> msgFailList = mjonMsgDataDAO.selectMsgSentFailList();
long forBeforeTime = System.currentTimeMillis(); // 코드 실행 시간
System.out.println("== msgFailList =============> : "+ msgFailList.size());
for(MjonMsgVO vo : msgFailList) {
try {
mjonMsgDataDAO.updateMsgSentFailPayBack(vo);
}catch(Exception ex) {
System.out.println("=============SchedulerUtil=====PayBack Catch =============>");
System.out.println(vo.getUserId()+" : "+ vo.getMsgGroupId() +" : "+ vo.getUserData());
ex.printStackTrace();
}
}
long forAfterTime = System.currentTimeMillis(); // 코드 실행 시간
long forSecDiffTime = (forAfterTime - forBeforeTime)/1000; // 코드 실행 전후 시간 차이 계산( 단위)
System.out.println("==PayBack for 2 =============> 수량 : "+msgFailList.size()+" ===== " + forSecDiffTime +"");
}
*/
System.out.println("==== faxFailPayBack ====");
// 팩스 환불
schdlrManageService.faxFailPayBack();
}
}

View File

@ -19,6 +19,7 @@ import java.security.spec.RSAPublicKeySpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
@ -1471,61 +1472,33 @@ public class EgovUserManageController {
model.addAttribute("channelIdCnt", channelIdCnt);
model.addAttribute("resultKakaoChannelIDList", resultKakaoChannelIDList);
/*
* 알림톡/친구톡 최근 발송내역 리스트 불러오기
*/
KakaoVO sendKakaoVO = new KakaoVO();
//sendKakaoVO.setSearchCondition2("N");//예약건은 제외하기
sendKakaoVO.setReserveCYn("N");//예약취소건은 제외하기
sendKakaoVO.setUserId(reqMberManageVO.getMberId());
// 문자발송 완료건은 모두 보이도록 처리
//kakaoVO.setMsgType("8");
sendKakaoVO.setSearchSortCnd("reqDate");
sendKakaoVO.setSearchSortOrd("desc");
sendKakaoVO.setFirstIndex(0);
sendKakaoVO.setPageType("sand");
List<KakaoVO> kakaoResultList = new ArrayList<KakaoVO>();
//kakaoResultList = mjonKakaoATService.selectMjonKakaoATGroupCompleteByUserList(sendKakaoVO);
/*250620 - 회원 정보 팝업 최근 알림톡/친구톡 전송 내역을 조회하는 임시 쿼리
* 기존 쿼리 성능으로 인하여 회원 정보 팝업 오픈 간헐적으로 에러 발생
* 임시 쿼리는 화면에 필요한 최소한의 정보만 조회하며, USER_ID를 제외한 조건은 하드코딩 처리
* DB 개선 작업 이후 알림톡/친구톡 관련 조회 공통 쿼리 생성 예정
* */
sendKakaoVO.setReserveYn("N");
kakaoResultList = mjonKakaoATService.selectMjonKakaoATGroupCompleteByUserListTemp(sendKakaoVO);
/* 카카오 전송 완료, 예약 조회 */
/* 전송완료, 예약 공통 set */
MjonMsgVO kakaoListVO = new MjonMsgVO();
kakaoListVO.setUserId(reqMberManageVO.getMberId());
kakaoListVO.setReserveCYn("N");
kakaoListVO.setRecordCountPerPage(3);
kakaoListVO.setFirstIndex(0);
kakaoListVO.setYellowIdYn("Y");
String[] msgTypeList = {"8","9"};
kakaoListVO.setMsgTypeList(msgTypeList);
/* 전송완료 set*/
kakaoListVO.setSelectType("reqDateLast3M"); //발송일시가 지금부터 지난 3개월
kakaoListVO.setSearchSortCnd("REQ_DATE");
kakaoListVO.setSearchSortOrd("DESC");
List<MjonMsgVO> kakaoResultList = mjonMsgDataService.selectSendListByResultCode(kakaoListVO);
model.addAttribute("kakaoResultList", kakaoResultList);
/*
* 알림톡/친구톡 예약발송 리스트 불러오기
*/
KakaoVO reserveKakaoVO = new KakaoVO();
reserveKakaoVO.setReserveYn("Y"); //예약건만 조회
reserveKakaoVO.setSearchCondition2("Y");//예약건만 불러오기
reserveKakaoVO.setReserveCYn("N");//예약취소건은 제외하기
reserveKakaoVO.setUserId(reqMberManageVO.getMberId());
// 문자발송 완료건은 모두 보이도록 처리
//kakaoVO.setMsgType("8");
reserveKakaoVO.setSearchSortCnd("reqDate");
reserveKakaoVO.setSearchSortOrd("desc");
reserveKakaoVO.setFirstIndex(0);
reserveKakaoVO.setPageType("sand");
List<KakaoVO> kakaoReserveList = new ArrayList<KakaoVO>();
//kakaoReserveList = mjonKakaoATService.selectReserveMjonKakaoATGroupList(reserveKakaoVO);
/*250620 - 회원 정보 팝업 최근 알림톡/친구톡 전송 내역을 조회하는 임시 쿼리
* 기존 쿼리 성능으로 인하여 회원 정보 팝업 오픈 간헐적으로 에러 발생
* 임시 쿼리는 화면에 필요한 최소한의 정보만 조회하며, USER_ID를 제외한 조건은 하드코딩 처리
* DB 개선 작업 이후 알림톡/친구톡 관련 조회 공통 쿼리 생성 예정
* */
sendKakaoVO.setReserveYn("Y");
kakaoReserveList = mjonKakaoATService.selectMjonKakaoATGroupCompleteByUserListTemp(sendKakaoVO);
/* 예약 set */
kakaoListVO.setReserveYn("Y");
kakaoListVO.setSelectType("reqDateNext3M"); //발송일시가 지금부터 다음 3개월
kakaoListVO.setSearchSortCnd("REQ_DATE");
kakaoListVO.setSearchSortOrd("ASC");
List<MjonMsgVO> kakaoReserveList = mjonMsgDataService.selectSendListByResultCode(kakaoListVO);
Collections.reverse(kakaoReserveList); //조회된 3건들은 발송일 내림차순으로 변경
model.addAttribute("kakaoReserveList", kakaoReserveList);
/*
* 알림톡 지연처리 알림톡 내용 불러오기(30분 지연처리된 알림톡 내역 불러오기)
*/

View File

@ -8688,7 +8688,113 @@
GROUP BY M.msgGroupId
order by M.reqDate desc
</select>
<select id="mjonMsgDAO.selectSendListByResultCode" parameterClass="mjonMsgVO" resultClass="mjonMsgVO">
SELECT
MMGD.USER_ID AS userId
, MMGD.MSG_GROUP_ID AS msgGroupId
, MMGD.MSG_TYPE AS msgType
, MMGD.REGDATE AS regDate
, MMGD.REQ_DATE AS reqDate
, MMGD.SMS_TXT AS smsTxt
, MMGD.MSG_GROUP_CNT AS msgGroupCnt
, MMGD.RESERVE_YN AS reserveYn
, MMGD.RESERVE_C_YN AS reserveCYn
, MMGD.CANCELDATE AS cancelDate
, MMGD.DELAY_YN AS delayYn
, MMGD.DELAY_COMPLETE_YN AS delayCompleteYn
, MMGD.AT_DELAY_YN AS atDelayYn
, MMGD.AT_DELAY_COMPLETE_YN AS atDelayCompleteYn
, MMD.waitCount AS waitCount
, MMD.successCount AS successCount
, MMD.failCount AS failCount
, MMD.resendWaitCount AS resendWaitCount
, MMD.resendSuccCount AS resendSuccCount
, MMD.resendFailCount AS resendFailCount
<isEqual property="yellowIdYn" compareValue="Y">
, MKPI.YELLOW_ID AS yellowId
</isEqual>
FROM
(
SELECT
USER_ID
, MSG_GROUP_ID
, MSG_TYPE
, REGDATE
, REQ_DATE
, SMS_TXT
, MSG_GROUP_CNT
, RESERVE_YN
, RESERVE_C_YN
, CANCELDATE
, DELAY_YN
, DELAY_COMPLETE_YN
, AT_DELAY_YN
, AT_DELAY_COMPLETE_YN
FROM
MJ_MSG_GROUP_DATA
WHERE 1=1
<isNotEmpty property="userId">
AND USER_ID = #userId#
</isNotEmpty>
<isNotEmpty property="msgType">
AND MSG_TYPE = #msgType#
</isNotEmpty>
<isNotEmpty property="msgTypeList">
AND MSG_TYPE IN
<iterate property="msgTypeList" open="(" close=")" conjunction=",">
#msgTypeList[]#
</iterate>
</isNotEmpty>
<isNotEmpty property="reserveYn">
AND RESERVE_YN = #reserveYn#
</isNotEmpty>
<isNotEmpty property="reserveCYn">
AND RESERVE_C_YN = #reserveCYn#
</isNotEmpty>
<isNotEmpty property="selectType">
<!-- 조회 타입 ex) last3M : 지난 3개월간 -->
<isEqual property="selectType" compareValue="reqDateLast3M">
and (REQ_DATE BETWEEN DATE_SUB(NOW(), INTERVAL 3 MONTH) AND NOW())
</isEqual>
<!-- 조회 타입 ex) next3M : 다음 3개월간 -->
<isEqual property="selectType" compareValue="reqDateNext3M">
AND (REQ_DATE BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 3 MONTH))
</isEqual>
</isNotEmpty>
ORDER BY 1=1
<isNotEmpty property="searchSortCnd">
,$searchSortCnd$
</isNotEmpty>
<isNotEmpty property="searchSortOrd">
$searchSortOrd$
</isNotEmpty>
LIMIT #recordCountPerPage# OFFSET #firstIndex#
) MMGD
JOIN (
SELECT
MSG_GROUP_ID
, MSG_NOTICETALK_SENDER_KEY
, SUM(CASE WHEN MSG_RESULT = '00' THEN 1 ELSE 0 END) AS waitCount
, SUM(CASE WHEN MSG_RESULT = '10' THEN 1 ELSE 0 END) AS successCount
, SUM(CASE WHEN MSG_RESULT = '20' THEN 1 ELSE 0 END) AS failCount
, SUM(CASE WHEN MSG_RESULT = '30' THEN 1 ELSE 0 END) AS resendWaitCount
, SUM(CASE WHEN MSG_RESULT = '40' THEN 1 ELSE 0 END) AS resendSuccCount
, SUM(CASE WHEN MSG_RESULT = '50' THEN 1 ELSE 0 END) AS resendFailCount
FROM
MJ_MSG_DATA
GROUP BY
MSG_GROUP_ID
) MMD
ON MMGD.MSG_GROUP_ID = MMD.MSG_GROUP_ID
<isEqual property="yellowIdYn" compareValue="Y">
LEFT JOIN
MJ_KAKAO_PROFILE_INFO MKPI
ON MKPI.SENDER_KEY = MMD.MSG_NOTICETALK_SENDER_KEY
AND MKPI.USER_ID = MMGD.USER_ID
</isEqual>
</select>
</sqlMap>

View File

@ -4728,102 +4728,59 @@ function fnInputSmsTxt(){
<c:choose>
<c:when test="${not empty kakaoResultList}">
<c:forEach var="kakaoResultList" items="${kakaoResultList}" varStatus="status">
<c:if test="${status.count < 4}">
<tr>
<td><c:out value="${status.count}"/></td>
<td>
<c:choose>
<c:when test="${kakaoResultList.msgType == '8'}">
알림톡
</c:when>
<c:when test="${kakaoResultList.msgType == '9'}">
친구톡
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${not empty kakaoResultList.regDate}">
<%-- ${fnc:setStrToDataFormatter(kakaoResultList.regDate, 'MM-dd HH:mm') } --%>
<fmt:parseDate value="${kakaoResultList.regDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${not empty kakaoResultList.rsltDate}">
<c:if test="${kakaoResultList.reserveYn eq 'Y'}">
[예약]<br />
</c:if>
<fmt:parseDate value="${kakaoResultList.rsltDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${kakaoResultList.atDelayYn eq 'Y' && kakaoResultList.atDelayCompleteYn eq 'Y' && not empty kakaoResultList.cancelDate}">
<span style="color: red;">
[발송취소]<br />
<c:if test="${kakaoResultList.reserveYn eq 'Y'}">
[예약]<br />
</c:if>
<fmt:parseDate value="${kakaoResultList.cancelDate}" var="cancelDateValue" pattern="yyyy-MM-dd HH:mm"/>
<fmt:formatDate value="${cancelDateValue}" pattern="MM-dd HH:mm"/>
</span>
</c:when>
<c:when test="${kakaoResultList.reserveCYn eq 'Y'}">
[예약취소]<br />
<fmt:parseDate value="${kakaoResultList.cancelDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:when test="${kakaoResultList.reserveYn eq 'Y' && kakaoResultList.reserveCYn eq 'N'}">
[예약]<br />
<fmt:parseDate value="${kakaoResultList.reqDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
</td>
<td><c:out value="${kakaoResultList.yellowId}"/></td>
<td class="sms_detail" style="text-align: left;">
<c:choose>
<c:when test="${empty kakaoResultList.smsTxt}">
-
</c:when>
<c:otherwise>
<div class="ellipsis_line">
<c:out value="${kakaoResultList.smsTxt}"/>
<div class="kakao_detail_hover">
<c:out value="${kakaoResultList.smsTxt}"/>
</div>
</div>
</c:otherwise>
</c:choose>
</td>
<td><fmt:formatNumber value="${kakaoResultList.msgGroupCnt}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.successCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.kakaoResendSuccCount + kakaoResultList.kakaoResendFailCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.kakaoResendSuccCount}" type="number" /></td>
<td><fmt:formatNumber value="${(kakaoResultList.successCount / kakaoResultList.msgGroupCnt) * 100}" pattern="#,###" />%</td>
</tr>
</c:if>
<tr>
<td><c:out value="${status.count}"/></td>
<td>
<c:choose>
<c:when test="${kakaoResultList.msgType == '8'}">
알림톡
</c:when>
<c:when test="${kakaoResultList.msgType == '9'}">
친구톡
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<fmt:parseDate value="${kakaoResultList.regDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</td>
<td>
<c:if test="${kakaoResultList.reserveYn eq 'Y'}">
[예약]<br/>
</c:if>
<c:if test="${kakaoResultList.atDelayYn eq 'Y'
and kakaoResultList.atDelayCompleteYn eq 'Y'
and not empty kakaoResultList.cancelDate}">
<span style="color: red;">
[발송취소]
</span>
</c:if>
<fmt:parseDate value="${kakaoResultList.reqDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</td>
<td><c:out value="${kakaoResultList.yellowId}"/></td>
<td class="sms_detail" style="text-align: left;">
<div class="ellipsis_line">
<c:out value="${kakaoResultList.smsTxt}"/>
<div class="kakao_detail_hover">
<c:out value="${kakaoResultList.smsTxt}"/>
</div>
</div>
</td>
<td><fmt:formatNumber value="${kakaoResultList.msgGroupCnt}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.successCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.resendSuccCount + kakaoResultList.resendFailCount + kakaoResultList.resendWaitCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoResultList.resendSuccCount}" type="number" /></td>
<td><fmt:formatNumber value="${(kakaoResultList.successCount / kakaoResultList.msgGroupCnt) * 100}" pattern="#,###" />%</td>
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<td colspan="11">카카오톡 송 내역이 없습니다.</td>
<td colspan="11">카카오톡 전송 내역이 없습니다.</td>
</tr>
</c:otherwise>
</c:choose>
@ -4846,10 +4803,6 @@ function fnInputSmsTxt(){
<col style="width:15%;">
<col style="width:auto;">
<col style="width:8%;">
<col style="width:8%;">
<col style="width:8%;">
<col style="width:8%;">
<col style="width:8%;">
</colgroup>
<thead>
<tr>
@ -4860,112 +4813,61 @@ function fnInputSmsTxt(){
<th>채널ID</th>
<th>내용</th>
<th>발송</th>
<th>성공</th>
<th>발송(대)</th>
<th>성공(대)</th>
<th>성공율</th>
</tr>
</thead>
<tbody>
<c:choose>
<c:when test="${not empty kakaoReserveList}">
<c:forEach var="kakaoReserveList" items="${kakaoReserveList}" varStatus="status">
<c:if test="${status.count < 4}">
<tr>
<td><c:out value="${status.count}"/></td>
<td>
<c:choose>
<c:when test="${kakaoReserveList.msgType == '8'}">
알림톡
</c:when>
<c:when test="${kakaoReserveList.msgType == '9'}">
친구톡
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${not empty kakaoReserveList.regDate}">
<%-- ${fnc:setStrToDataFormatter(kakaoReserveList.regDate, 'MM-dd HH:mm') } --%>
<fmt:parseDate value="${kakaoReserveList.regDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${not empty kakaoReserveList.rsltDate}">
<c:if test="${kakaoReserveList.reserveYn eq 'Y'}">
[예약]<br />
</c:if>
<fmt:parseDate value="${kakaoReserveList.rsltDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${kakaoReserveList.atDelayYn eq 'Y' && kakaoReserveList.atDelayCompleteYn eq 'Y' && not empty kakaoReserveList.cancelDate}">
<span style="color: red;">
[발송취소]<br />
<c:if test="${kakaoReserveList.reserveYn eq 'Y'}">
[예약]<br />
</c:if>
<fmt:parseDate value="${kakaoReserveList.cancelDate}" var="cancelDateValue" pattern="yyyy-MM-dd HH:mm"/>
<fmt:formatDate value="${cancelDateValue}" pattern="MM-dd HH:mm"/>
</span>
</c:when>
<c:when test="${kakaoReserveList.reserveCYn eq 'Y'}">
[예약취소]<br />
<fmt:parseDate value="${kakaoReserveList.cancelDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:when test="${kakaoReserveList.reserveYn eq 'Y' && kakaoReserveList.reserveCYn eq 'N'}">
[예약]<br />
<fmt:parseDate value="${kakaoReserveList.reqDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
</td>
</td>
<td><c:out value="${kakaoReserveList.yellowId}"/></td>
<td class="sms_detail" style="text-align: left;">
<c:choose>
<c:when test="${empty kakaoReserveList.smsTxt}">
-
</c:when>
<c:otherwise>
<div class="ellipsis_line">
<c:out value="${kakaoReserveList.smsTxt}"/>
<div class="kakao_detail_hover">
<c:out value="${kakaoReserveList.smsTxt}"/>
</div>
</div>
</c:otherwise>
</c:choose>
</td>
<td><fmt:formatNumber value="${kakaoReserveList.msgGroupCnt}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoReserveList.successCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoReserveList.kakaoResendSuccCount + kakaoReserveList.kakaoResendFailCount}" type="number" /></td>
<td><fmt:formatNumber value="${kakaoReserveList.kakaoResendSuccCount}" type="number" /></td>
<td><fmt:formatNumber value="${(kakaoReserveList.successCount / kakaoReserveList.msgGroupCnt) * 100}" pattern="#,###" />%</td>
</tr>
</c:if>
<tr>
<td><c:out value="${status.count}"/></td>
<td>
<c:choose>
<c:when test="${kakaoReserveList.msgType == '8'}">
알림톡
</c:when>
<c:when test="${kakaoReserveList.msgType == '9'}">
친구톡
</c:when>
<c:otherwise>
-
</c:otherwise>
</c:choose>
</td>
<td>
<fmt:parseDate value="${kakaoReserveList.regDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</td>
<td>
<c:if test="${kakaoReserveList.reserveYn eq 'Y'}">
[예약]<br/>
</c:if>
<c:if test="${kakaoReserveList.atDelayYn eq 'Y'
and kakaoReserveList.atDelayCompleteYn eq 'Y'
and not empty kakaoReserveList.cancelDate}">
<span style="color: red;">
[발송취소]
</span>
</c:if>
<fmt:parseDate value="${kakaoReserveList.reqDate}" var="dateValue" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateValue}" pattern="MM-dd HH:mm"/>
</td>
<td><c:out value="${kakaoReserveList.yellowId}"/></td>
<td class="sms_detail" style="text-align: left;">
<div class="ellipsis_line">
<c:out value="${kakaoReserveList.smsTxt}"/>
<div class="kakao_detail_hover">
<c:out value="${kakaoReserveList.smsTxt}"/>
</div>
</div>
</td>
<td><fmt:formatNumber value="${kakaoReserveList.msgGroupCnt}" type="number" /></td>
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<td colspan="11">카카오톡 발송 내역이 없습니다.</td>
<td colspan="7">카카오톡 예약 내역이 없습니다.</td>
</tr>
</c:otherwise>
</c:choose>