rosewiper 2024-02-02
선거문자 대용량 발송 개발 3차 커밋
@5ddb2353c3fa3714f029d902e8cab358733049f1
src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
--- src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
+++ src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
@@ -309,4 +309,38 @@
 		
 	}
 	
+	
+	public String getCreateMsgUserIdgen(String subUserId, String lastId) throws Exception{
+		
+		String returnId = "";
+		String[] splitId = lastId.split("_");
+		
+		if(splitId.length > 0) {
+			
+			int lastNum = Integer.parseInt(splitId[1]);
+			
+			lastNum = lastNum + 1;
+			
+			String tmpLastNum = Integer.toString(lastNum);
+			
+			int zeroPlusCnt = 14 - tmpLastNum.length();
+			
+			StringBuilder sb = new StringBuilder();
+			sb.append(subUserId + "_");
+			
+			for(int i=0; i< zeroPlusCnt; i++) {
+				
+				sb.append('0');
+				
+			}
+			
+			sb.append(tmpLastNum);
+
+			returnId = sb.toString();
+			
+		}
+		
+		return returnId;
+	}
+	
 }
src/main/java/itn/let/mjo/msgcampain/service/impl/MjonCandidateServiceImpl.java
--- src/main/java/itn/let/mjo/msgcampain/service/impl/MjonCandidateServiceImpl.java
+++ src/main/java/itn/let/mjo/msgcampain/service/impl/MjonCandidateServiceImpl.java
@@ -302,7 +302,28 @@
 		
 		try {
 			
-			resultList = mjonCandidateDAO.selectAddrGrpHGList(mjonMsgVO);
+			for(String addrId : mjonMsgVO.getCallToList()) {
+				
+				MjonMsgVO tmpMsgVO = new MjonMsgVO();
+				tmpMsgVO.setUserId(mjonMsgVO.getUserId());
+				tmpMsgVO.setAddrGrpId(addrId);
+				
+				List<String> tmpAddrList = new ArrayList<String>();
+				System.out.println("++++++++++++++ addrId ::: "+addrId);
+				
+				if(addrId.equals("group1") || addrId.equals("bookmark")) {
+					
+					tmpMsgVO.setAddrGrpNm(addrId);
+					
+				}
+				
+				tmpAddrList = mjonCandidateDAO.selectAddrGrpHGList(tmpMsgVO);
+				
+				resultList.addAll(tmpAddrList);
+				
+			}
+			
+			//resultList = mjonCandidateDAO.selectAddrGrpHGList(mjonMsgVO);
 			
 		} catch (Exception e) {
 			System.out.println("selectAddrGrpHGList Service Imple Error!!! " + e);
src/main/java/itn/let/mjo/msgcampain/web/MjonMsgCampainHGDataController.java
--- src/main/java/itn/let/mjo/msgcampain/web/MjonMsgCampainHGDataController.java
+++ src/main/java/itn/let/mjo/msgcampain/web/MjonMsgCampainHGDataController.java
@@ -604,6 +604,31 @@
     		mjonMsgVO.setDivideTime("1");
     		mjonMsgVO.setDivideCnt("20");
     		
+    		//대용량 발송자의 msg_id 마지막 값 불러오기
+        	/*String subUserId = mjonMsgVO.getUserId().substring(0, 5).toUpperCase();
+        	mjonMsgVO.setSearchKeyword(subUserId);
+        	System.out.println("+++++++++++ subUserId ::: "+subUserId);
+
+        	String userLastIdgen = mjonMsgDataService.selectMsgUserLastIdgen(mjonMsgVO);
+        	System.out.println(userLastIdgen);
+        	
+        	if(userLastIdgen == null) {
+        		
+        		userLastIdgen = subUserId + "_00000000000000";
+        		
+        	}
+    		
+        	MjonCommon mjComm = new MjonCommon();
+        	String startUserId = userLastIdgen; 
+    		
+        	System.out.println("+_+++++ startUserId ::: "+startUserId);
+        	
+        	//문자발송 리스트 생성 시작
+    		for(int i = 0; i < 100; i++) {
+    			startUserId = mjComm.getCreateMsgUserIdgen(subUserId, startUserId);
+    			System.out.println("++++++++++++ startUserId ::: "+startUserId);
+    		}*/
+    		
 /*++++++스미싱 의심 및 문자 길이 초과 여부 체크++++++++++++++++ */    		
         	//회원정보에서 스미싱 회원 여부 정보 조회
         	UserManageVO userManageVO = new UserManageVO();
@@ -871,13 +896,19 @@
     		//제거 중복 건수 계산
     		addrDupListLen = resultAddrList.size();
     		
+    		System.out.println("++++++++++++++ 중복제거 후 리스트 갯수 ::: "+addrDupListLen);
+    		
     		//수신자 총 수 * 단가 를 통해 총 결제 금액 계산
     		int tmpTotCallCnt = addrDupListLen; //mjonMsgVO.getCallToList().length;
     		float tmpTotPrice = tmpTotCallCnt * tmpEachPrice;
     		
+    		//중복 제거한 주소록 총 건수 와 개별 단가를 이용하여 총 발송 금액 계산하기
+    		mjonMsgVO.setEachPrice(Float.toString(tmpEachPrice));
+    		mjonMsgVO.setTotPrice(Float.toString(tmpTotPrice));
+    		
     		
     		//화면에서 넘어온 파라미터 개별 단가와 컨트롤러에서 계산한 단가를 비교하여 맞지 않으면 컨트롤러 계산 단가 입력
-    		if(tmpOrgEachPrice != tmpEachPrice) {
+    		/*if(tmpOrgEachPrice != tmpEachPrice) {
     			mjonMsgVO.setEachPrice(Float.toString(tmpEachPrice));
     			
     			System.out.println("화면 : tmpOrgEachPrice ::: "+tmpOrgEachPrice);
@@ -893,7 +924,7 @@
     			System.out.println("컨트롤러 : tmpTotPrice ::: "+tmpTotPrice);    			
     		}else {
     			System.out.println("tmpOrgTotPrice ::: "+tmpOrgTotPrice);
-    		}
+    		}*/
     		
 /*
  * 개별단가 및  총결제 캐시 금액 체크 로직 종료
@@ -977,7 +1008,7 @@
         				System.out.println("arrPhoneList len ::: "+arrPhoneList.length);
         				mjonMsgVO.setCallToList(arrPhoneList);
         				
-        				MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
+        				MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfoBatch(mjonMsgVO);
     					mjonMsgVO.setAgentCode(returnVO.getAgentCode());
     					resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
     		    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
@@ -1007,7 +1038,7 @@
         		
         		mjonMsgVO.setCallToList(arrLastPhoneList);
 				
-				MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
+				MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfoBatch(mjonMsgVO);
 				mjonMsgVO.setAgentCode(returnVO.getAgentCode());
 				resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
 	    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
src/main/java/itn/let/mjo/msgdata/service/MjonMsgDataService.java
--- src/main/java/itn/let/mjo/msgdata/service/MjonMsgDataService.java
+++ src/main/java/itn/let/mjo/msgdata/service/MjonMsgDataService.java
@@ -17,6 +17,9 @@
 	// 중계사 문자 내용 입력
 	public MjonMsgReturnVO insertMsgDataInfo(MjonMsgVO mjonMsgVO) throws Exception;
 	
+	//대량 문자 데이터 배치 입력 처리
+	public MjonMsgReturnVO insertMsgDataInfoBatch(MjonMsgVO mjonMsgVO) throws Exception;
+	
 	// 중계사 문자 내용 입력(성능테스트용)
 	public MjonMsgReturnVO insertMsgTestDataInfo(MjonMsgVO mjonMsgVO
 			, int i_nRate
@@ -167,4 +170,7 @@
 	// 문자 상세정보 => 재전송용
 	public List<MjonMsgDataVO> selectMjMsgListByResend(MjonMsgDataVO mjonMsgDataVO) throws Exception;
 	
+	//대용량 문자 전송시 사용자 마지막 PK 값 조회하기
+	public String selectMsgUserLastIdgen(MjonMsgVO mjonMsgVO) throws Exception;
+	
 }
src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java
--- src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java
+++ src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java
@@ -346,4 +346,9 @@
 		return (List<MjonMsgDataVO>) list("MjonMsgDataDAO.selectMjMsgListByResend", mjonMsgDataVO);
 	}
 	
+	
+	public String selectMsgUserLastIdgen(MjonMsgVO mjonMsgVO) throws Exception{
+		return (String) select("mjonMsgDAO.selectMsgUserLastIdgen", mjonMsgVO);
+	}
+	
 }
src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
--- src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
+++ src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
@@ -19,6 +19,7 @@
 import itn.let.mjo.addr.service.AddrVO;
 import itn.let.mjo.event.service.MjonEventService;
 import itn.let.mjo.event.service.MjonEventVO;
+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.msgagent.service.MjonMsgAgentStsService;
@@ -2300,4 +2301,750 @@
 		return mjonMsgDataDAO.selectMjMsgListByResend(mjonMsgDataVO);
 	}
 	
+	
+	
+/*
+ * 대량 문자 데이터 배치 입력 처리 신규 추가
+ * 2024/02/02 우영두 
+ * 
+ * 
+ * */
+	public MjonMsgReturnVO insertMsgDataInfoBatch(MjonMsgVO mjonMsgVO) throws Exception{
+		
+		MjonMsgReturnVO returnVO = new MjonMsgReturnVO();
+		
+		try {
+		
+		String msgType = mjonMsgVO.getMsgType();
+		String agentCode = mjonMsgVO.getAgentCode(); 
+		// 장문 전송
+		String contSeq = "";
+		
+		//float myPrice = 10000;
+		//float totPrice = Float.parseFloat(mjonMsgVO.getTotPrice());
+		// 최종 입력 수 저장 변수
+		int resultCnt = 0;
+		int limitCnt = 10000;
+		int blockCnt = 0;
+		
+		// 총 보유 금액과 전송 합계 비교
+		
+		/*if(myPrice < totPrice) { // 보유 금액보다 전송 합계가 적은 경우 리턴 
+			
+			return 0 ; 
+		}*/
+		
+		int callToCnt = mjonMsgVO.getCallToList().length;	//전체 받는사람 건수
+
+		mjonMsgVO.setMsgGroupCnt(Integer.toString(callToCnt));
+		
+		
+		//그룹 테이블에 입력할 발송 시간 및 예약 발송 시간 처리
+		/*if(mjonMsgVO.getReserveYn().equals("N")) {//즉시 전송의 경우 현재 시간을 입력
+			
+			Date now = new Date();
+			
+			SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+			
+			mjonMsgVO.setReqDate(sdFormat.format(now));
+			
+		}*/
+		
+		//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
+		String befCash = mjonMsgVO.getBefCash();
+		
+		//VO에서 현재 보유금액이 없으면 디비에서 조회해서 불러옴
+		if("".equals(befCash) || befCash == null) {
+			befCash = mjonMsgDataDAO.selectBeforeCashData(mjonMsgVO);
+		}
+		
+		mjonMsgVO.setBefCash(befCash);
+		// 문자 전송 그룹 테이블에 정보 입력
+		//mjonMsgDAO.insertGroupMsgData(mjonMsgVO);
+		
+    	//수신거부 목록 불러오기
+		List<String> userBlockList = mjonMsgDAO.selectUserBlockList(mjonMsgVO);
+		
+		List<String> dupliBlockList = MJUtil.getDuplicateList(userBlockList);
+		int usrBlockCnt = dupliBlockList.size();
+		
+		//회원 전용 전송사 정보 불러오기
+		MberManageVO userInfo = mjonMsgDataDAO.selectMberManageInfo(mjonMsgVO.getUserId());
+		String hotlineAgentCode = userInfo.getHotlineAgentCode();
+		
+		//전용 전송사가 지정되어 있으면 실행
+		if(!hotlineAgentCode.equals("00")) {
+			
+			MjonMsgAgentStsVO mjonMsgAgentStsVO = new MjonMsgAgentStsVO();
+			mjonMsgAgentStsVO.setAgentCode(hotlineAgentCode);
+			
+			//문자 타입 셋팅
+			if(msgType.equals("6")) {
+				int fCnt = Integer.parseInt(mjonMsgVO.getFileCnt()); 
+				if(fCnt > 0) {
+					
+					mjonMsgAgentStsVO.setMsgType("P");
+					
+				}else {
+					mjonMsgAgentStsVO.setMsgType("L");
+				}
+				
+			}else {
+				mjonMsgAgentStsVO.setMsgType("S");
+			}
+			
+			List<MjonMsgAgentStsVO> hotlineMsgAgentList = mjonMsgAgentStsDAO.selectMsgAgentListByAgentCode(mjonMsgAgentStsVO);
+			
+			String mberAgentConde = "";
+			String mberSendRate = "";
+			String mberRepAgent = "";
+			
+			for(MjonMsgAgentStsVO tmp : hotlineMsgAgentList) {
+				
+				mberAgentConde = tmp.getAgentCode();
+				mberSendRate = tmp.getSendRate();
+				mberRepAgent = tmp.getRepAgent();
+				String useYn = tmp.getUseYn();
+				
+				if(userInfo.getBlineCode().equals("N")) {
+					//회원 전용 전송사의 전송 비율이 0 이면 대표전송사로 전송되도록 셋팅함.
+					if(mberSendRate.equals("0") || useYn.equals("N")) {
+						
+						hotlineAgentCode = mberRepAgent;
+						
+					}
+				}
+				
+			}
+			
+		}
+		
+		
+		/**
+		 * Agent 추가시 셋팅하기
+		 * Agent 발송 비율 불러오기
+		 * 최초 : 아이하트(01), 현대 퓨쳐넷(02), 아이앰오(03)
+		 * 22.10.12 : 비즈뿌리오(04) 추가
+		 * 23.04.10 : 제이제이(05) 추가
+		 * 23.05.02 : 인비토 (07) 추가
+		 * */
+		
+		int iheartCnt = 0;	//아이하트 전송갯수
+		int hncCnt = 0;		//현대퓨처넷 전송갯수
+		int imoCnt = 0;		//아이엠오 전송갯수
+		int bizCnt = 0;		//비즈뿌리오 전송갯수
+		int jjCnt = 0;		//제이제이 전송갯수
+		int ivtCnt = 0; 	//인비토 전송갯수
+		
+		// 전송사별 발송 리스트 조회
+		List<MjonMsgVO> sendRateList = mjonMsgDataDAO.selectSendAgentList(mjonMsgVO);
+		
+		if(callToCnt >= 10) {
+			// 전송사별 배분률 조회
+			int sendRateSize = sendRateList.size();
+			
+			/**
+			 * Agent 추가시 셋팅하기
+			 * 
+			 * 최초 : 아이하트(01), 현대 퓨쳐넷(02), 아이앰오(03)
+			 * 22.10.12 : 비즈뿌리오(04) 추가
+			 * 23.04.10 : 제이제이(05) 추가
+			 * 23.05.02 : 인비토 (07) 추가
+			 * */
+			
+			for(int i=0; i< sendRateSize; i++) {
+				
+				String sndAgentCode = sendRateList.get(i).getAgentCode();
+				
+				if(sndAgentCode.equals("01")) {//아이하트 전송비율
+					
+					iheartCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}else if(sndAgentCode.equals("02")) {//현대퓨처넷 전송비율
+					
+					hncCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}else if(sndAgentCode.equals("03")) {//아이엠오 전송비율
+					
+					imoCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}else if(sndAgentCode.equals("04")) {//비즈뿌리오 전송비율
+					
+					bizCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}else if(sndAgentCode.equals("05")) {//제이제이 전송비율
+					
+					jjCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}else if(sndAgentCode.equals("07")) {//인비토 전송비율
+					
+					ivtCnt = Math.round(callToCnt * Float.parseFloat(sendRateList.get(i).getSendRate()));
+					
+				}
+				
+			}
+		}
+		
+		/**
+		 * 한번에 서버가 보낼수 있는 문자건수를 체크 해서 넘으면 분할해서 디비 입렵해 준다.
+		 * 발송 건수가 천 건이 넘어가면, 백건씩 끊어서 발송 하도록 한다.
+		 * */
+		
+		/*if(callToCnt >= 10000) {
+			
+			limitCnt = 1000;
+			
+		}*/
+		
+		//수신자 리스트 처리
+		List<MjonMsgVO> msgDataInfo = new ArrayList<MjonMsgVO>();
+		
+		int cnt = 1;
+		int totCnt = 1;
+		
+		//분할문자 시간에 간격시간 더해주기
+    	String dividDay = null;
+    	Calendar cal = Calendar.getInstance();
+    	
+    	//예약시간 변환
+    	SimpleDateFormat transFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+    	
+		int turmMin = 0;
+		int totalCallCnt = 0;
+		int divideCnt = 0;
+		int count = 1;		//분할 카운트
+		String delayTime ="";//30분 지연시간
+		String spamStatus = mjonMsgVO.getSpamStatus();//스팸 문구 유무
+		String smishingYn = mjonMsgVO.getSmishingYn();//스미싱 의심 유무
+		String delayYn = "N";	//문자발송 30분 지연 처리 유무
+		
+		if(spamStatus == null || spamStatus.equals("")) {
+			
+			spamStatus = "N";
+			
+		}
+		
+		if(smishingYn == null || smishingYn.equals("")) {
+			
+			smishingYn = "N";
+			
+		}
+		
+		
+		if(!mjonMsgVO.getReserveYn().equals("N")) {//예약문자인 경우 시간 셋팅
+			
+	    	Date toDate = transFormat.parse(mjonMsgVO.getReqDate());
+	    	cal.setTime(toDate); 										//예약 시간 캘린터 변수에 입력
+	    	
+	    	//String 타입 시간 Int로 변환
+	    	turmMin = Integer.parseInt(mjonMsgVO.getDivideTime()); //분할발송 시간 간격
+	    	dividDay = transFormat.format(cal.getTime());
+	    	
+	    	totalCallCnt = mjonMsgVO.getCallToList().length; // 수신자 전체 갯수
+	    	divideCnt = Integer.parseInt(mjonMsgVO.getDivideCnt()); //분할 발송 갯수
+	    	
+	    	if(spamStatus.equals("Y") || smishingYn.equals("Y")) {
+	    		
+	    		mjonMsgVO.setDelayYn("Y");//일단 값만 등록해준다. 이거 안해주면 NULL 값으로 들어간다. 차후에 변경하도록 할 예정임, 원래는 스팸이면 Y로 넣어줘야한다.
+	    		
+	    	}else {
+	    		
+	    		mjonMsgVO.setDelayYn("N");//일단 값만 등록해준다. 이거 안해주면 NULL 값으로 들어간다. 차후에 변경하도록 할 예정임
+	    	}
+			
+		}else {//즉시발송의 경우 현재 시간으로 입력해 준다.
+			
+			Date now = new Date();
+			if(spamStatus.equals("Y") || smishingYn.equals("Y")) {//스팸 문자가 포함되었거나, 스미싱 의심 회원의 경우 문자발송 시간을 30분 딜레이 시킨다.
+				
+				String nowDate = transFormat.format(now);
+        		Date toDate = transFormat.parse(nowDate);
+    	    	System.out.println("++++++++++++++++++++ origin reqDate ::: "+toDate);
+        		cal.setTime(toDate); 
+        		
+    	    	cal.add(Calendar.MINUTE, 30);
+    			delayTime = transFormat.format(cal.getTime());
+    			mjonMsgVO.setReqDate(delayTime);
+    			System.out.println("++++++++++++++++++++ delay reqDate ::: "+mjonMsgVO.getReqDate());
+    			delayYn = "Y";
+    			mjonMsgVO.setDelayYn(delayYn);//문자 발송 30분 지연 코드 셋팅
+				
+			}else {//정상적인 문자인 경우 즉시발송 처리해준다.
+				
+				mjonMsgVO.setReqDate(transFormat.format(now));
+				mjonMsgVO.setDelayYn(delayYn);//문자 발송 30분 지연 디폴트 값 셋팅(N)
+				
+			}
+			
+		}
+		
+		
+    	//String[] nameList = mjonMsgVO.getNameList();	//치환 이름 리스트
+    	String[] phoneList = mjonMsgVO.getCallToList();	//받는사람 연락처 리스트
+    	//String[] rep1 = mjonMsgVO.getRep1List();		//치환 문자1 리스트
+    	//String[] rep2 = mjonMsgVO.getRep2List();		//치환 문자2 리스트
+    	//String[] rep3 = mjonMsgVO.getRep3List();		//치환 문자3 리스트
+    	//String[] rep4 = mjonMsgVO.getRep4List();		//치환 문자4 리스트
+    	
+    	//Controller에서 전달 받은 분할 시간 정보 리스트 
+    	List<String> dividDayList = mjonMsgVO.getDividDay();
+    	
+    	String frstDelayTime = mjonMsgVO.getReqDate();
+    	
+/*
+ * 대용량 발송자의 msg_id 마지막 값 불러오기
+ * 신규 IDgen 값 생성해주기
+ * 
+ * */
+    	String subUserId = mjonMsgVO.getUserId().substring(0, 5).toUpperCase();
+    	mjonMsgVO.setSearchKeyword(subUserId);
+    	System.out.println("+++++++++++ subUserId ::: "+subUserId);
+
+    	String userLastIdgen = mjonMsgDataDAO.selectMsgUserLastIdgen(mjonMsgVO);
+    	System.out.println(userLastIdgen);
+    	
+    	//기존에 등록된 pk값이 없으면 초기 번호로 셋팅
+    	if(userLastIdgen == null) {
+    		
+    		userLastIdgen = subUserId + "_00000000000000";
+    		
+    	}
+		
+    	MjonCommon mjComm = new MjonCommon();
+    	String startUserId = userLastIdgen; 
+    	System.out.println("+_+++++ startUserId ::: "+startUserId);
+    	
+    	//문자발송 리스트 생성 시작
+		for(int i = 0; i < callToCnt; i++) {
+			
+			//신규 pk IDgen 데이터 생성
+			startUserId = mjComm.getCreateMsgUserIdgen(subUserId, startUserId);
+			
+			Boolean blockSts = false;
+			for(int j = 0; j < usrBlockCnt; j++) {
+
+				if(phoneList[i].equals(dupliBlockList.get(j).toString())) {
+					
+					blockCnt++; //수신 차단 카운드를 해준다.
+					blockSts = true;
+					
+				}
+				
+			}
+			
+			if(!blockSts) { //수신거부가 아니면 추가
+				
+				MjonMsgVO tempVO = new MjonMsgVO();
+				
+				/**
+				 * Agent 추가시 셋팅하기
+				 * 
+				 * 최초 : 아이하트(01), 현대 퓨쳐넷(02), 아이앰오(03)
+				 * 22.10.12 : 비즈뿌리오(04) 추가
+				 * 23.04.10 : 제이제이(05) 추가
+				 * 23.05.02 : 인비토 (07) 추가
+				 * 23.05.09 : 회원 전용 전송사 정보가 있으면 모든 문자를 전용 전송사로 발송처리함. 
+				 * */
+
+				if(hotlineAgentCode.equals("00")) {//전용 전송사가 사용 안함인 경우 분배 및 대표 전송사로 설정
+					
+					if(iheartCnt > 0) {
+						agentCode = "01";
+						tempVO.setAgentCode(agentCode);
+						iheartCnt--;
+					}else if(hncCnt > 0) {
+						agentCode = "02";
+						tempVO.setAgentCode(agentCode);
+						hncCnt--;
+					}else if(imoCnt > 0) {
+						agentCode = "03";
+						tempVO.setAgentCode(agentCode);
+						imoCnt--;
+					}else if(bizCnt > 0) {
+						agentCode = "04";
+						tempVO.setAgentCode(agentCode);
+						bizCnt--;
+					}else if(jjCnt > 0) {
+						agentCode = "05";
+						tempVO.setAgentCode(agentCode);
+						jjCnt--;
+					}else if(ivtCnt > 0) {
+						agentCode = "07";
+						tempVO.setAgentCode(agentCode);
+						ivtCnt--;
+					}else {//전송사 Agent 대표 전송사로 지정한다.
+						
+						agentCode = sendRateList.get(0).getRepAgent();
+						tempVO.setAgentCode(agentCode);
+					}
+					
+				}else {//전용 전송사가 지정되어 있는 경우 전용 전송사로 지정
+					
+					agentCode = hotlineAgentCode;
+					tempVO.setAgentCode(hotlineAgentCode);
+				}
+				//Agent 셋팅 끝
+				
+				//tempVO.setMsgId(idgenMsgId.getNextStringId());
+				
+				tempVO.setMsgId(startUserId);
+				
+				tempVO.setUserId(mjonMsgVO.getUserId());
+				tempVO.setCallTo(phoneList[i]);
+				tempVO.setCallFrom(mjonMsgVO.getCallFrom());
+				tempVO.setMsgType(mjonMsgVO.getMsgType());
+				tempVO.setMsgGroupId(mjonMsgVO.getMsgGroupId());
+				tempVO.setMsgCnt(mjonMsgVO.getMsgCnt());
+				
+				//아이엠오 전송사 문자 타입 설정해 주기
+				if(agentCode.equals("03")) {
+	        		
+	        		// 단순 장문 문자는 neoType : 2, 그림 포함 : 4
+	        		if(mjonMsgVO.getFileCnt().equals("0")) { // 단순 장문 문자
+	        			
+	        			mjonMsgVO.setNeoType("2");
+	        			
+	        		}else{ // 그림포함 문자인경우
+	        			
+	        			mjonMsgVO.setNeoType("4");
+	        			
+	        		}
+	        		
+	        	}
+				
+				//문자내용 내용 - 치환 처리
+				String smsTxt = mjonMsgVO.getSmsTxt();		//발송 문자 내용
+	    		
+				//일괄변환문자 리스트에서 콤마(,)를 특수문자(§)로 변환해서 넘겨받기 때문에 치환 처리를 해준도록 한다.
+	    		smsTxt = smsTxt.replaceAll(String.valueOf((char)13), "");
+	 			/*if (smsTxt.indexOf("[*이름*]") > -1) {
+	 				if(nameList.length > i && StringUtil.isNotEmpty(nameList[i])) {
+	 					smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", StringUtil.getString(nameList[i].replaceAll("§", ",")));
+	 				}else {
+	 					smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", "");
+	 				}
+	 			}
+	 			
+				if (smsTxt.indexOf("[*1*]") > -1) {
+					if(rep1.length > i && StringUtil.isNotEmpty(rep1[i])) {
+						smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", StringUtil.getString(rep1[i].replaceAll("§", ",")));
+					}else {
+						smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", "");
+					}
+				}
+				
+				if (smsTxt.indexOf("[*2*]") > -1) {
+					if(rep2.length > i && StringUtil.isNotEmpty(rep2[i])) {
+						smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", StringUtil.getString(rep2[i].replaceAll("§", ",")));
+					}else {
+						smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", "");
+					}
+				}
+				
+				if (smsTxt.indexOf("[*3*]") > -1) {
+					if(rep3.length > i && StringUtil.isNotEmpty(rep3[i])) {
+						smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", StringUtil.getString(rep3[i].replaceAll("§", ",")));
+					}else {
+						smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", "");
+					}
+				}
+				
+				if (smsTxt.indexOf("[*4*]") > -1) {
+					if(rep4.length > i && StringUtil.isNotEmpty(rep4[i])) {
+						smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", StringUtil.getString(rep4[i].replaceAll("§", ",")));
+					}else {
+						smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", "");
+					}
+				}*/
+				
+				tempVO.setSmsTxt(smsTxt);
+				
+				//즉시 / 예약 전송 처리
+				if(mjonMsgVO.getReserveYn().equals("N")) {//즉시 전송의 경우 현재 시간을 입력
+					
+					if(spamStatus.equals("Y") || smishingYn.equals("Y")) {//스팸문자가 있거나, 스미싱 의심 회원의 경우 30분 지연시간을 입력해 준다.
+						
+						tempVO.setReqDate(mjonMsgVO.getReqDate());//상단에서 스팸문구가 있는겨우 30분 딜레이시간을 입력해 두었기 때문에 같은 데이터를 입력함.
+						
+						
+					}else {//일반 문자인 경우 현재시간을 입력해 준다.
+					
+						Date now = new Date();
+						SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+						tempVO.setReqDate(sdFormat.format(now));
+						
+					}
+					
+				}else { // 예약 발송의 경우 예약 시간을 입력
+					
+					//분할 발송을 체크 한 경우
+					if(mjonMsgVO.getDivideChk() != null) {
+						
+						//스팸문구 혹은 스미싱 의심 회원의 경우 30분 딜레이 처리해준다.
+						//20230630 우영두 추가
+						if(spamStatus.equals("Y") || smishingYn.equals("Y")) {
+							
+							Date delayDate = transFormat.parse(dividDayList.get(i));
+							
+							cal.setTime(delayDate);
+							cal.add(Calendar.MINUTE, 30);
+							delayTime = transFormat.format(cal.getTime());		
+							
+							tempVO.setReqDate(delayTime); //분할 문자 예약 시간 입력해주기
+							
+						}else {
+							
+							tempVO.setReqDate(dividDayList.get(i)); //분할 문자 예약 시간 입력해주기
+							
+						}
+						
+						
+					}else {//일반 예약 발송의 경우
+						
+						if(spamStatus.equals("Y") || smishingYn.equals("Y")) {//스팸문구 혹은 스미싱 의심 회원의 경우 30분 딜레이 처리해준다.
+							
+							Date delayDate = transFormat.parse(mjonMsgVO.getReqDate());
+							
+							cal.setTime(delayDate);
+							cal.add(Calendar.MINUTE, 30);
+							delayTime = transFormat.format(cal.getTime());
+							
+							tempVO.setReqDate(delayTime);
+							
+						}else {
+							
+							tempVO.setReqDate(mjonMsgVO.getReqDate());
+							
+						}
+						
+					}
+					
+					//딜레이 처리되었을 수 있어서 임시 데이터의 발송 시간을 업데이트 해준다.
+					//분할 발송일 경우 Loop을 돌기 때문에 마지막 시간이 reqDate에 들어가기 때문에 첫번째 데이터에서만 시간을 입력해 준다.
+					//mj_group_data 테이블의 reqdate 컬럼 값으로 셋팅 된다.
+					if(i==0) {
+						frstDelayTime = tempVO.getReqDate();
+					}
+				}
+				
+				if(!msgType.equals("4")) { // 장문 혹은 그림문자일 경우 추가
+					
+					/**
+					 * 장문 / 그림문자 일 경우 제목 처리
+					 * 만약 제목을 입력하지 않았을 경우 문자 내용의 텍스트 일부를 제목으로 사용
+					 * 내용 텍스트가 없는 경우는 어쩔수 없는 것으로 간주하여 Null로 처리한다.
+					 * 
+					 * */
+					String contents = tempVO.getSmsTxt();	//문자 내용 
+					if(StringUtil.isEmpty(mjonMsgVO.getMmsSubject()) || mjonMsgVO.getMmsSubject() == null) {// 제목 입력이 없는 경우
+						
+						if(StringUtil.isNotEmpty(contents) && contents != null) {//문자내용이 있는 경우 처리
+							
+							String[] split = contents.split("\n");
+							
+							if(split.length > 0) {
+								
+								String subject = "";
+								String msgKind = mjonMsgVO.getMsgKind();//문자 타입(일반, 광고, 선거문자)
+								
+								//선거문자인 경우 첫 글내용이 "(선거운동정보)"로 되어있어서 그 다음줄의 내용을 제목으로 사용
+								if(msgKind.equals("C")) {
+									if(split.length > 1) {
+										subject = split[1].trim();
+									}else {
+										subject = split[0].substring(0,20);
+									}
+								}else {
+									subject = split[0].trim();
+								}
+
+							}
+							
+						}
+						
+					}else {// 제목 입력이 있는 경우 입력한 제목으로 셋팅
+						tempVO.setMmsSubject(mjonMsgVO.getMmsSubject());
+					}
+					
+					tempVO.setFileCnt(mjonMsgVO.getFileCnt());
+					tempVO.setFileName1(mjonMsgVO.getFileName1());
+					tempVO.setFileName2(mjonMsgVO.getFileName2());
+					tempVO.setFileName3(mjonMsgVO.getFileName3());
+					tempVO.setNeoType(mjonMsgVO.getNeoType());
+					tempVO.setContSeq(mjonMsgVO.getContSeq());
+						
+				}
+				
+				//아이하트 전송사의 LMS(장문) / MMS(그림문자) 전송시 컨텐츠 번호 받아오기 먼저 처리
+				if(agentCode.equals("01") && msgType.equals("6")) {
+					
+					// 아이하트 MMS Contents 테이블에 입력 후 컨텐츠 아이디 받아오기
+					
+					//이미지가 있는경우 file_type, file_Cnt 값 셋팅
+					int fileCnt = Integer.parseInt(mjonMsgVO.getFileCnt());
+					String contents = mjonMsgVO.getSmsTxt();
+					
+					if(fileCnt > 0) {
+						tempVO.setFileType1("IMG");	//아이하트 그림문자 전송시 파일종류 이미지로 셋팅
+						
+						//그림문자일 경우 이미지 갯수 + 1을 해줘야한다. (+1은 컨텐츠 내용을 의미한다.)
+						if(StringUtil.isNotEmpty(contents)) {
+							fileCnt = fileCnt + 1;
+						}
+						tempVO.setFileCnt(Integer.toString(fileCnt));
+						
+					}else {
+						tempVO.setFileCnt("1");
+					}
+					
+ 					contSeq = mjonMsgDataDAO.insertIHeartMmsMsgContentsInfo(tempVO);
+ 					mjonMsgVO.setContSeq(contSeq);
+					tempVO.setSmsTxt(smsTxt);
+					tempVO.setContSeq(contSeq);
+					
+				}
+				
+				//문자 내용 추가해 주기
+				msgDataInfo.add(tempVO);
+				
+			}//수신거부 처리로직 끝
+			
+			int instCnt = 0;
+			//지금까지 루프 돌아간 것이 전체 수신자 갯수와 같으면 추가가 완료된 것으로 판단 되어 전송 해줌
+			if(totCnt == callToCnt) {
+				
+				if(msgDataInfo.size() > 0) {
+					
+					//데이터 디비 입력해주기
+					instCnt = mjonMsgDataDAO.insertMsgDataInfo(msgDataInfo, msgType, agentCode);
+					
+				}
+				
+				//총 디비 입력 건수 저장하기
+				resultCnt = resultCnt + instCnt;
+				
+			}else {
+				
+				//특정 건수 이상일 경우 분할해서 디비에 넣어준다.
+				if(cnt == limitCnt) {
+					
+					if(msgDataInfo.size() > 0) {
+						
+						//분할 최대건수가 되면 디비에 입력하기
+						instCnt = mjonMsgDataDAO.insertMsgDataInfo(msgDataInfo, msgType, agentCode);
+						
+					}
+					
+					//총 디비 입력 건수 저장하기
+					resultCnt = resultCnt + instCnt;
+					cnt = 0;
+					
+					//List 초기화 하기
+					msgDataInfo.clear();
+					
+				}
+				
+			}
+			
+			cnt++;
+			totCnt++;
+			
+		}
+		
+		/*
+		 * 각 처리 건별로 캐시 차감 및 그룹 데이터 정보 업데이트
+		 * 1. 디비에 입력한 건수만큼 캐시 차감 및 회원 캐시 정보 업데이트 
+		 * 2. 그룹데이터에 처리 건수 업데이트(총 발송건수 합산 정보 업데이트)
+		 * 
+		 * */
+		
+		//문자 발송 캐시 차감 해주기
+		MjonPayVO mjonPayVO = new MjonPayVO(); 
+		
+		//1건 이상 발송이 있는 경우만 캐쉬를 차감 시킨다.
+		if(resultCnt > 0) {
+			
+			int totSendCnt = mjonMsgVO.getTotalCallCnt();
+			Float eachPrice = Float.parseFloat(mjonMsgVO.getEachPrice());
+			Float totPrice = eachPrice * resultCnt;
+			String strTotPrice = String.format("%.1f", totPrice);
+			
+			mjonMsgVO.setTotPrice(strTotPrice);//현재 합산 금액 셋팅
+			mjonPayVO.setCashId(idgenMjonCashId.getNextStringId());
+			mjonPayVO.setUserId(mjonMsgVO.getUserId());
+			mjonPayVO.setCash(-Float.parseFloat(strTotPrice));
+			mjonPayVO.setFrstRegisterId(mjonMsgVO.getUserId());
+			mjonPayVO.setMemo("SMS 문자 총 "+totSendCnt+"건 중 " + resultCnt + "건 발송");
+			mjonPayVO.setMsgGroupId(mjonMsgVO.getMsgGroupId());
+			
+			mjonPayService.insertCash(mjonPayVO); //캐시차감 
+			mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
+		}
+		
+		//문자 발송 테이블에 입력 데이터가 있는 경우 그룹 테이블에도 입력 해 준다.
+		if(resultCnt > 0) {
+			
+			// 문자 전송 그룹 테이블에 정보 입력
+			int groupCnt = resultCnt;
+			mjonMsgVO.setMsgGroupCnt(Integer.toString(groupCnt));
+			//mjonMsgService.insertGroupMsgData(mjonMsgVO);
+			int msgGroupDataCnt = mjonMsgDAO.selectMsgGroupDataCntByGroupId(mjonMsgVO);
+
+			//메세지 그룹 데이터가 없으면 추가 해주고 있으면 총메세지 건수를 합산해준다.
+			if(msgGroupDataCnt < 1) {
+				mjonMsgVO.setAgentCode(agentCode);//전송사 코드 번호를 셋팅해 준다.
+				
+				//지연 유무 코드가 Null 인경우 체크
+				String tmpDelayYn = mjonMsgVO.getDelayYn();
+				if(tmpDelayYn == null) {
+					mjonMsgVO.setDelayYn("N");
+				}
+				
+				//예약 문자이고 30분 지연이 된 문자의 Mj_msg_group_data 테이블의 req_date 시간을 첫번째 문자의 지연된 시간으로 셋팅해준다.
+				if(mjonMsgVO.getReserveYn().equals("Y") && (spamStatus.equals("Y") || smishingYn.equals("Y"))) {
+					
+					mjonMsgVO.setReqDate(frstDelayTime);
+					
+				}
+				mjonMsgDAO.insertGroupMsgData(mjonMsgVO);
+				
+			}else {
+				mjonMsgDAO.updateMsgGroupDataForTotCntSum(mjonMsgVO);
+			}
+			
+			//이벤트 회원 남은 캐시 업데이트
+			fnUpdateEventRemainCash(mjonPayVO);
+			
+		}
+		
+		// 성공
+		returnVO.setSendMsgCnt(Integer.toString(resultCnt)); //발송 건수 저장
+		returnVO.setSendMsgBlockCnt(Integer.toString(blockCnt)); //수신차단 건수 저장
+		returnVO.setAgentCode(agentCode);
+			
+		} catch (Exception e) {
+			// 실패
+			returnVO.setSendMsgCnt(Integer.toString(0)); //발송 건수 저장
+			returnVO.setSendMsgBlockCnt(Integer.toString(0)); //수신차단 건수 저장
+			returnVO.setAgentCode("01");
+			
+			System.out.println("=========================================================================");
+			System.out.println("+++++++++++++++++++++++++++++ 문자발송 ==> insertMsgDataInfoBatch ERROR !!! : " + e);
+			System.out.println("=========================================================================");
+			return returnVO;
+			
+		}
+		
+		return returnVO;
+		
+	}
+
+	
+	//대용량 문자 전송시 사용자 마지막 PK 값 조회하기
+	@Override
+	public String selectMsgUserLastIdgen(MjonMsgVO mjonMsgVO) throws Exception{
+		return mjonMsgDataDAO.selectMsgUserLastIdgen(mjonMsgVO);
+	}
+	
+	
 }
src/main/resources/egovframework/sqlmap/let/msg/MjonMsgCampainData_SQL_mysql.xml
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgCampainData_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgCampainData_SQL_mysql.xml
@@ -281,19 +281,20 @@
 		FROM   MJ_ADDR a
 		WHERE  a.MBER_ID = #userId#
 		
-		<iterate prepend="AND ADDR_GRP_ID IN " open="(" close=")" conjunction="," property="callToList">
+		<!-- <iterate prepend="AND ADDR_GRP_ID IN " open="(" close=")" conjunction="," property="callToList">
 			#callToList[]#
-		</iterate>
+		</iterate> -->
 		
-		<isEqual property="bookmarkYn" compareValue="N">
-			AND    a.BOOKMARK = 'N' 
-		</isEqual>
-		<isEqual property="bookmarkYn" compareValue="B">
-			AND    a.BOOKMARK IN ('N','Y') 
-		</isEqual>
-		<isEqual property="bookmarkYn" compareValue="Y">
-			AND    a.BOOKMARK = 'Y' 
-		</isEqual>
+		AND ADDR_GRP_ID = #addrGrpId#
+		
+		<isNotEmpty property="addrGrpNm">
+			<isEqual property="addrGrpNm" compareValue="group1">
+				AND    a.BOOKMARK = 'N' 
+			</isEqual>
+			<isEqual property="addrGrpNm" compareValue="bookmark">
+				AND    a.BOOKMARK = 'Y'  
+			</isEqual>
+		</isNotEmpty>
 		
 		AND a.DELETE_YN = 'N'
 		
src/main/resources/egovframework/sqlmap/let/msg/MjonMsgData_SQL_mysql.xml
--- src/main/resources/egovframework/sqlmap/let/msg/MjonMsgData_SQL_mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/msg/MjonMsgData_SQL_mysql.xml
@@ -7501,6 +7501,17 @@
 			USER_ID = #userId#
 			AND MSG_GROUP_ID = #msgGroupId#
 	</select>
-			
+	
+	<select id="mjonMsgDAO.selectMsgUserLastIdgen" parameterClass="mjonMsgVO" resultClass="String">
+		
+		SELECT   MSG_ID
+		FROM     MJ_MSG_DATA
+		WHERE    USER_ID   = #userId#
+		AND      MSG_ID LIKE CONCAT('%', #searchKeyword#, '%') 
+		ORDER BY USERDATA DESC
+		LIMIT    1
+	
+	</select>
+	
 </sqlMap>
 
src/main/webapp/WEB-INF/jsp/web/msgcampain/huge/MsgHGDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/msgcampain/huge/MsgHGDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/msgcampain/huge/MsgHGDataView.jsp
@@ -998,6 +998,7 @@
 		
 		var groupSts = false;
 		var bookSts = false;
+		var myAddrSts = false;
 		
 		for(var i=0; i < selectedData.length; i++){
 			//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
@@ -1007,7 +1008,7 @@
 				return false;
 			}
 			
-			if(addrGrpId == 'group1'){
+			/* if(addrGrpId == 'group1'){
 				
 				addrGrpId = '0';
 				groupSts = true;
@@ -1017,11 +1018,17 @@
 				addrGrpId = '0';
 				bookSts = true;
 				
-			}
+			}else{//사용자가 추가한 주소록 그룹
+				
+				myAddrSts = true;
+				
+			} */
 			addrGrpList[i] = addrGrpId;
 		}
 		
-		if(groupSts && bookSts){
+		
+		//모든 그룹을 선택하거나 미지정그룹과 자주보내는 그룹 선택 또는 자주보내는 그룹과 사용자 생성 그룹 선택시
+		/* if((groupSts && bookSts) || (bookSts && myAddrSts)){
 			
 			$("#bookmarkYn").val("B");
 			
@@ -1029,7 +1036,7 @@
 			
 			$("#bookmarkYn").val("Y");
 			
-		}
+		} */
 		
 	}
 	
Add a comment
List