package itn.let.mjo.msgdata.web;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import egovframework.rte.psl.dataaccess.util.EgovMap;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import itn.com.cmm.EgovMessageSource;
import itn.com.cmm.JsonResult;
import itn.com.cmm.LoginVO;
import itn.com.cmm.service.EgovFileMngService;
import itn.com.cmm.service.EgovFileMngUtil;
import itn.com.cmm.service.FileVO;
import itn.com.cmm.util.MJUtil;
import itn.com.cmm.util.RedirectUrlMaker;
import itn.com.cmm.util.StringUtil;
import itn.com.utl.fcc.service.EgovStringUtil;
import itn.let.lett.service.HashConfVO;
import itn.let.lett.service.LetterService;
import itn.let.lett.service.LetterVO;
import itn.let.mjo.addr.service.AddrGroupService;
import itn.let.mjo.addr.service.AddrGroupVO;
import itn.let.mjo.addr.service.AddrService;
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.MjonMsgService;
import itn.let.mjo.msg.service.MjonMsgVO;
import itn.let.mjo.msgdata.service.MjonMsgDataService;
import itn.let.mjo.msgdata.service.MjonMsgDataVO;
import itn.let.mjo.msgdata.service.MjonMsgReturnVO;
import itn.let.mjo.msgdata.service.PhoneVO;
import itn.let.mjo.pay.service.MjonPayService;
import itn.let.mjo.pay.service.MjonPayVO;
import itn.let.mjo.spammsg.service.MjonSpamMsgService;
import itn.let.mjo.spammsg.web.ComGetSpamStringParser;
import itn.let.mjo.symbol.service.MjonSymbolService;
import itn.let.mjo.symbol.service.MjonSymbolVO;
import itn.let.schdlr.service.SchdlrManageService;
import itn.let.sym.ccm.cde.service.CateCode;
import itn.let.sym.ccm.cde.service.EgovCcmCmmnDetailCodeManageService;
import itn.let.sym.site.service.EgovSiteManagerService;
import itn.let.sym.site.service.JoinSettingVO;
import itn.let.uss.umt.service.EgovMberManageService;
import itn.let.uss.umt.service.EgovUserManageService;
import itn.let.uss.umt.service.MberManageVO;
import itn.let.uss.umt.service.UserManageVO;
import itn.let.utl.sim.service.EgovClntInfo;


@Controller
public class MjonMsgDataController {

	@Resource(name = "mjonMsgService")
    private MjonMsgService mjonMsgService;
	
	@Resource(name = "mjonPayService")
    private MjonPayService mjonPayService;
	
	@Resource(name = "MjonMsgDataService")
    private MjonMsgDataService mjonMsgDataService;
	
	@Resource(name = "LetterService")
    private LetterService letterService;
	
	@Resource(name = "mjonSymbolService")
	private MjonSymbolService mjonSymbolService;
	
	/** mberManageService */
	@Resource(name = "mberManageService")
	private EgovMberManageService mberManageService;
	
	@Resource (name = "AddrService")
	private AddrService addrService;
	
	@Resource (name = "AddrGroupService")
	private AddrGroupService addrGroupService;
	
	/** EgovMessageSource */
    @Resource(name="egovMessageSource")
    EgovMessageSource egovMessageSource;
    
    @Resource(name="EgovFileMngUtil")
	private EgovFileMngUtil fileUtil;
    
    @Resource(name="EgovFileMngService")
    private EgovFileMngService fileMngService;
    
	@Resource(name = "SchdlrManageService")
    private SchdlrManageService schdlrManageService;
	
    @Resource(name = "egovMjonMsgGroupIdGnrService")
    private EgovIdGnrService idgenMjonMsgGroupId;
    
	@Resource(name = "egovMjonCashIdGnrService")
    private EgovIdGnrService idgenMjonCashId;
    
	@Resource(name = "CmmnDetailCodeManageService")
    private EgovCcmCmmnDetailCodeManageService cmmnDetailCodeManageService;
	
    /** 첨부파일 저장경로 */
	@Value("#{globalSettings['Globals.file.saveDir']}")
	private String fileSaveDir;
	
	/** userManageService */
	@Resource(name = "userManageService")
	private EgovUserManageService userManageService;
	
	@Resource(name = "MjonEventService")
    private MjonEventService mjonEventService;
	
	@Resource(name = "mjonSpamMsgService")
    private MjonSpamMsgService mjonSpamMsgService;
    
	/** 사이트 설정 */ 
	@Resource(name = "egovSiteManagerService")
	EgovSiteManagerService egovSiteManagerService;	
    
    private static final Logger logger = LoggerFactory.getLogger(MjonMsgDataController.class);
	
    /**
     * 문자 발송 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/selectMsgDataView.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/selectMsgDataView.do"})
	public String selectMsgDataView(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, 
			@ModelAttribute("cateCodeVO") CateCode cateCode,
			HttpServletRequest request,
			ModelMap model,
			RedirectAttributes redirectAttributes) throws Exception{
		
		try {
		
			/*
			 * 문자 샘플 검색어에 한글,영문,숫자, 공백을 제외한 문자가 포함된 경우 
			 * 검색이 안되도록 조치함.
			 * 2023.05.02 우영두
			 * 
			 * */
			String keyword = searchVO.getSearchKeyword();
			if(keyword != null) {
				
				keyword = URLDecoder.decode(keyword, "UTF-8");	
				keyword = keyword.replaceAll("[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9 ]", "");
				
				if(!keyword.equals("")) {
					
					System.out.println("==========================잘못된 접근 경로 정보 시작==========================================");
					System.out.println("1. 접근 IP 정보 ::: " + request.getRemoteAddr());
					
					System.out.println("전달 파라미터 값 ");
					Set<String> keySet = request.getParameterMap().keySet();
					int paramCnt = 2;
					for(String key: keySet) {
						System.out.println(paramCnt + ". " +key + " : " + request.getParameter(key));
						paramCnt++;
					}
					
					System.out.println("==========================잘못된 접근 경로 정보 종료==========================================");
					
					redirectAttributes.addFlashAttribute("message", "잘못된 검색어입니다.");
					RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/web/main/mainPage.do");
					return redirectUrlMaker.getRedirectUrl();
					
				}
				
			}
			
			//로그인 권한정보 불러오기
			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
			model.addAttribute("loginVO", loginVO);
					
			String categoryType = cateCode.getCateType();
			
			if(categoryType == null) {
				
				categoryType = "N";
				
			}
			
			// 문자 카테고리 리스트 불러오기
			//List<CateCode> cateConfList = letterService.selectCateConfWithList(categoryType);
			//2뎁스 카테고리만 조회하게 수정
			List<CateCode> cateConfList = letterService.selectCateConfTwoDepthWithList(categoryType);
			model.addAttribute("cateCodeList", cateConfList);	
			
			// 문자 해쉬태그 리스트 불러오기
			String msgType = "M"; //문자발송, 선거문자에서만 보여질 해시 태그리스트를 불러온다.
			List<HashConfVO> hashTagList = letterService.selectHashTagWithList(msgType);
			model.addAttribute("hashTagList", hashTagList);
			
			// 문자 리스트 불러오기
			LetterVO letterVO = new LetterVO();
			if(letterVO.getPageUnit() != 10) {
				letterVO.setPageUnit(letterVO.getPageUnit());
			}
			
			letterVO.setLetterType(searchVO.getMsgType());

			/** pageing */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
			paginationInfo.setPageSize(letterVO.getPageSize());

			letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
			letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			
			List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
			
			model.addAttribute("resultPhoList", resultPhoList);
			paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
			model.addAttribute("paginationInfo", paginationInfo);
			model.addAttribute("letterVO", letterVO);
			
			//System.out.println(letterVO.getLetterType());
			
			//발송결과 문자 재전송에서 넘어오는 경우 파마리터 전달
			List<String> temp = searchVO.getMsgSeqList();
			
			if(temp != null) {
				
				model.addAttribute("reSendMsgVO", searchVO);
				
			}
			
			//주소록에서 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getMoveAddrFlag())) {
				model.addAttribute("addrVO", searchVO);
			}
			
			//주소록에서 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getMoveAddrAllFlag())) {
				AddrVO addrVO = new AddrVO();
				
				String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
				if(userId != "") {
					addrVO.setMberId(userId);
				} 
				addrVO.setRecordCountPerPage(100000);
				addrVO.setFirstIndex(0);
				addrVO.setSearchAddrGrpId(request.getParameter("searchAddrGrpId"));
				addrVO.setSearchCondition(request.getParameter("searchCondition"));
				addrVO.setSearchKeyword(request.getParameter("searchKeyword"));
				addrVO.setStartKeyword(request.getParameter("startKeyword"));
				List<AddrVO> addrList = addrService.selectAddrList(addrVO);
				
				List<String> addrIdList = new ArrayList<String>();
				for(AddrVO item : addrList) {
					addrIdList.add(item.getAddrId());
				}
				
				searchVO.setAddrIdList(addrIdList);
				searchVO.setMoveAddrFlag("Y");
				
				model.addAttribute("addrVO", searchVO);
			}		

			
			
			//맞춤문자에서 이미지 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getCustomImgFlag())) {
				
				model.addAttribute("customImgVO", searchVO);
				
			}
			
			//메인화면에서 이미지 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getMainImgFlag())) {
				
				model.addAttribute("mainImgVO", searchVO);
				
			}
			
			//메인화면 인기문자(단/장문) 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getMainLetterFlag())) {
				
				MjonMsgDataVO mainLetterVO = mjonMsgDataService.selectLetterCnById(searchVO);
				mainLetterVO.setMainLetterFlag(searchVO.getMainLetterFlag());
				//기존 문자내용에서 줄바꿈 문자를 태그로 변환해줌 - 사용자 화면단의 스크립트에서 오류 발생 방지
				mainLetterVO.setSmsTxt(mainLetterVO.getSmsTxt().replace("\r\n", "<br/>")
						.replace("\r", "<br/>")
						.replace("\n", "<br/>")
						.replace("\n\r", "<br/>")
						.replace("\"", "\\\"")
						.replace("\'", "\\'"));
				model.addAttribute("mainLetterVO", mainLetterVO);
				
			}
			
			//메인화면 더많은 샘플 보기 선택시 넘어오는 파라미터
			if("Y".equals(searchVO.getMainMoreSamFlag())) {
				
				model.addAttribute("moreSampleYn", searchVO.getMainMoreSamFlag());
				
			}
			
			//헤더 문자검색에서 넘어오는 파라미터
			if("Y".equals(searchVO.getHeaderMsgSearchFlag())){
				
				//공인 IP 구하기
		  		String userIp = EgovClntInfo.getClntIP(request);
				//java.util.Scanner s = new java.util.Scanner(new java.net.URL("https://api.ipify.org").openStream(), "UTF-8").useDelimiter("\\A");
				//userIp = s.next();
		  	    
				System.out.println(userIp);
				System.out.println(searchVO.getSearchKeyword());
				
				
				
				//기존 검색된 단어가 있는지 체크
				int searchWordCnt = mjonMsgDataService.selectMsgSearchWordCnt(searchVO);
				
				if(searchWordCnt > 0) {
					
					searchVO.setUserIp(userIp);
					//기존 검색어가 있는 경우 검색 카운트만 증가시켜 준다.
					mjonMsgDataService.updateMsgSearchWordCnt(searchVO);
					
				}else {
					
					searchVO.setUserIp(userIp);
					//문자검색어 디비 저장처리
					int resultCnt = mjonMsgDataService.insertMsgSearchWordInfo(searchVO);
					
				}
				
				//문자검색 인기검색어 4개 불러오기
				List<?> resultSearchWordList = mjonMsgDataService.selectMsgSearchWordList(searchVO); 
				
				model.addAttribute("resultSearchWordList", resultSearchWordList);
				model.addAttribute("headerMsgSearchVO", searchVO);
				
			}
			
		}catch(Exception ex) {
			ex.printStackTrace();
			
		}
		
		return "web/msgdata/MsgDataView";
	}
	
	
	 /**
     * 문자 발송 단문/장문/그림문자 전송 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/selectMsgDataSMLViewAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/selectMsgDataSMLViewAjax.do"})
	public String selectMsgDataSMLView(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, CateCode cateCode, ModelMap model) throws Exception{
		
		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	String author = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getAuthority());
    	
		String categoryType = cateCode.getCateType();
		
		if(categoryType == null) {
			
			categoryType = "N";
			
		}
		
		//문자 전송 개인 단가 불러오기
		
		//0.이벤트 진행중이 회원 정보 불러오기.
		//이벤트 회원 정보 테이블에서 대상자의 정보를 불러온다.
		MjonEventVO mjonEventVO = new MjonEventVO();
		mjonEventVO.setMberId(userId);
		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO);
		
		
		long eventDiffDate = 0;
		float eventRemainCash = 0;
		boolean compareEndDate = false;
		
		if(eventMberInfo != null) {
			
			String eventEndDate = eventMberInfo.getEventEndDate();
			
			/**
			 * MJUtil.getCompareDate()
			 * 현재 날짜와 파라미터 전달 날짜를 비교
			 * 전달날짜를 지난경우 False를 리턴함.
			 * 현재날짜 이전 혹은 같은 날짜면 True를 리턴함.
			 * 
			 * */
			
			if(eventEndDate != null) {
				compareEndDate = MJUtil.getCompareDate(eventEndDate);
				eventRemainCash = (float) eventMberInfo.getEventRemainCash(); 
				
				//이벤트 종료 일자가 지난 경우, 이벤트 상태가 종료아 아니면 종료 처리 시킴
				//이벤트 남은 캐시가 단문 발송금액 7.5원 보다 낮으면 이벤트 종료 시킴
				if(!compareEndDate || eventRemainCash < 7.5) {
					
					if(!eventMberInfo.getEventStatus().equals("E")) {
						
						//이벤트 상태값을 종료로 변경한다.
						mjonEventVO.setEventInfoId(eventMberInfo.getEventInfoId());
						mjonEventVO.setEventStatus("E");
						mjonEventVO.setEventMemo("이벤트 발송 최소 금액(7.5) 부족 혹은 이벤트 종료일 초과되어 이벤트 종료 시킴");
						mjonEventVO.setEventRemainCash(eventRemainCash);
						mjonEventService.updateEventEndStatus(mjonEventVO);
						eventMberInfo.setEventStatus("E");
						
					}
					
				}else {//이벤트 진행중이면 남은 날짜 계산해서 전달.
					
					/**
					 * MJUtil.getDiffDateDay()
					 * 현재 날짜와 파라미터 날짜 사이의 날짜 수를 계산해줌.
					 * 
					 * */
					eventDiffDate = MJUtil.getDiffDateDay(eventEndDate);
					
				}
			}
			
		}
		
		//남은 날짜값을 절대값으로 변경(음수로 나오기 때문)
		model.addAttribute("eventDiffDate", Math.abs(eventDiffDate));
		model.addAttribute("compareEndDate", compareEndDate);
		model.addAttribute("eventRemainCash", eventRemainCash);
		model.addAttribute("eventMberInfo", eventMberInfo);
		
		
		//1.시스템 기본 단가 정보 불러오기
		JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
		
		//2.사용자 개인 단가 정보 불러오기
		MberManageVO mberManageVO = new MberManageVO(); 
		
		if(!userId.equals("") && !author.equals("ROLE_ADMIN")) {
			
			mberManageVO = mjonMsgDataService.selectMberManageInfo(userId);
			searchVO.setUserId(userId);
			
		}
		
		model.addAttribute("exceptSpamYn", mberManageVO.getExceptSpamYn());
		
		//3.사용자 개인단가 정보가 0이 아니면 개인단가 사용, 없으면 시스템 기본 단가 사용
		Float shortPrice = mberManageVO.getShortPrice();
		Float longPrice = mberManageVO.getLongPrice();
		Float picturePrice = mberManageVO.getPicturePrice();
		Float picture2Price = mberManageVO.getPicture2Price();
		Float picture3Price = mberManageVO.getPicture3Price();
		BigDecimal userMoney = new BigDecimal(mberManageVO.getUserMoney()).setScale(2, RoundingMode.HALF_EVEN);
		
		//일반 단가정보 저장 변수 셋팅 - 이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
		Float norShortPrice = mberManageVO.getShortPrice();
		Float norLongPrice = mberManageVO.getLongPrice();
		Float norPicturePrice = mberManageVO.getPicturePrice();
		Float norPicture2Price = mberManageVO.getPicture2Price();
		Float norPicture3Price = mberManageVO.getPicture3Price();
		
		//기존 소수점 2째자리에서 반올림하였으나, 정책 변경으로 소수점 버림 처리함 20220623 
		/*int shortPrice = (int) mberManageVO.getShortPrice();
		int longPrice = (int) mberManageVO.getLongPrice();
		int picturePrice = (int) mberManageVO.getPicturePrice();
		int picture2Price = (int) mberManageVO.getPicture2Price();
		int picture3Price = (int) mberManageVO.getPicture3Price();
		int userMoney = (int) mberManageVO.getUserMoney();*/
		
		String userPoint = mberManageVO.getUserPoint();
		
		//이벤트 진행 회원의 발송 단가 처리해주기
		if(eventMberInfo != null && eventMberInfo.getEventStatus().equals("Y") && compareEndDate) {
			
			shortPrice = Float.parseFloat(eventMberInfo.getEventShortPrice());
			longPrice = Float.parseFloat(eventMberInfo.getEventLongPrice());
			picturePrice = Float.parseFloat(eventMberInfo.getEventPicturePrice());
			picture2Price = Float.parseFloat(eventMberInfo.getEventPicture2Price());
			picture3Price = Float.parseFloat(eventMberInfo.getEventPicture3Price());
			
			//이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
			if(shortPrice < 1 || longPrice < 1 || picturePrice < 1) {//이벤트 단가 적용시 일반단가도 필요하여 셋팅 해줌.
				
				norShortPrice = (float) sysJoinSetVO.getShortPrice();
				norLongPrice = (float) sysJoinSetVO.getLongPrice();
				norPicturePrice = (float) sysJoinSetVO.getPicturePrice();
				norPicture2Price = (float) sysJoinSetVO.getPicture2Price();
				norPicture3Price = (float) sysJoinSetVO.getPicture3Price();
				
			}
			
		}else if(shortPrice < 1 || longPrice < 1 || picturePrice < 1) {//협의 단가가 없는 경우 시스템 단가 적용해 주기
			
			shortPrice = (float) sysJoinSetVO.getShortPrice();
			longPrice = (float) sysJoinSetVO.getLongPrice();
			picturePrice = (float) sysJoinSetVO.getPicturePrice();
			picture2Price = (float) sysJoinSetVO.getPicture2Price();
			picture3Price = (float) sysJoinSetVO.getPicture3Price();
			
		}
		
		model.addAttribute("shortPrice", shortPrice);
		model.addAttribute("longPrice", longPrice);
		model.addAttribute("picturePrice", picturePrice);
		model.addAttribute("picture2Price", picture2Price);
		model.addAttribute("picture3Price", picture3Price);
		model.addAttribute("userMoney", userMoney);
		model.addAttribute("userPoint", userPoint);
		
		
		//이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
		if(norShortPrice < 1 || norLongPrice < 1 || norPicturePrice < 1) {//협의 단가가 없는 경우 일반단가에 시스템 단가로 셋팅해줌
			
			norShortPrice = (float) sysJoinSetVO.getShortPrice();
			norLongPrice = (float) sysJoinSetVO.getLongPrice();
			norPicturePrice = (float) sysJoinSetVO.getPicturePrice();
			norPicture2Price = (float) sysJoinSetVO.getPicture2Price();
			norPicture3Price = (float) sysJoinSetVO.getPicture3Price();
			
		}
		
		model.addAttribute("norShortPrice", norShortPrice);
		model.addAttribute("norLongPrice", norLongPrice);
		model.addAttribute("norPicturePrice", norPicturePrice);
		model.addAttribute("norPicture2Price", norPicture2Price);
		model.addAttribute("norPicture3Price", norPicture3Price);
		
		if(!userId.equals("")) {//로그인 된 사용자만 발신번호를 불러오도록 수정
			
			//아이디 발신번호 리스트 불러오기.
			List<String> resultSendPhonList = mjonMsgDataService.selectSendPhonNumList(userId);
			List<String> resultPhonList = new ArrayList<String>();
			MJUtil mjUtil = new MJUtil();
			
			for(String phone : resultSendPhonList) {
				
				resultPhonList.add(mjUtil.addDash(phone));
				
			}
			model.addAttribute("resultPhonList", resultPhonList);
			
		}
		
		//발신번호 차단 리스트 불러오기
		//List<String> resultBlockPhonList = mjonMsgDataService.selectBlockPhonNumList();
		//model.addAttribute("resultBlockPhonList", resultBlockPhonList);
		
		// 문자 카테고리 리스트 불러오기
		List<CateCode> cateConfList = letterService.selectCateConfWithList(categoryType);
		model.addAttribute("cateCodeList", cateConfList);
		
		//그림 문자 리스트 불러오기
		LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}
		
		MjonSymbolVO symbolVO = new MjonSymbolVO();
		// 특수문자 리스트 불러오기
		List<MjonSymbolVO> symbolList = mjonSymbolService.selectMjonSymbolList(symbolVO);
		model.addAttribute("symbolList", symbolList);
		
		//최근 전송 내역
		Calendar cal = Calendar.getInstance();
    	Date now = new Date();
    	
    	SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    	
    	cal.setTime(now);
    	cal.add(Calendar.DATE, -3);
    	
    	String chkDate = format.format(cal.getTime());
    	
    	searchVO.setMyMsgStDt(chkDate);	//검색 시작일 저장 - 현재날짜로 부터 3일 이전 날짜로 시작
		List<?> resultLatestMsgList = mjonMsgDataService.selectLatestMsgList(searchVO);
		model.addAttribute("resultLatestMsgList", resultLatestMsgList);
		
		//자주보내는 번호
		List<?> resultBookMarkMsgList = mjonMsgDataService.selectBookMarkMsgList(searchVO);
		model.addAttribute("resultBookMarkMsgList", resultBookMarkMsgList);
		

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		
		return "web/msgdata/MsgDataSMLView";
	}
	
	
		
	/**
	 * 문자재전송 내용 처리
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectReSendMsgDataListAjax.do"})
	public ModelAndView selectReSendMsgDataListAjax(
			MjonMsgDataVO mjonMsgDataVO, 
			HttpServletRequest req,
			ModelMap model) throws Exception {

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
    	if(userId.equals("")) {
    		
    		modelAndView.addObject("status", "loginFail");
    		modelAndView.addObject("message", "로그인이 필요합니다.");
    		return modelAndView;
    		
    	}else {
    		
    		mjonMsgDataVO.setUserId(userId);
    		
    	}
		
		List<String> msgSeqList = mjonMsgDataVO.getMsgSeqList();
		List<String> tempList = new ArrayList<String>();
		
		for(String seqStr : msgSeqList) {
			
			String seqId = seqStr.replace("[", "");
			seqId = seqId.replace("]", "");
			
			tempList.add(seqId);
		}
		
		mjonMsgDataVO.setMsgSeqList(tempList);
		
		List<MjonMsgVO> resultList = mjonMsgDataService.selectReSendMsgDataList(mjonMsgDataVO);
		
		//문자발송 이미지 처리 - 사용하지 않아서 주석처리함.
		/*int fileCnt = Integer.parseInt(resultList.get(0).getFileCnt());
		MjonMsgDataVO resultMsgPhotoInfo = new MjonMsgDataVO();
		
		if(fileCnt > 0) {
			
			MjonMsgVO resultMsgInfo = new MjonMsgVO();
			//재발송 리스트의 첫번째 이미지 정보만 받아온다.(여러 발송문자를 선택 할 경우 첫번째 리스트의 정보를 사용함)
			resultMsgInfo.setFileType1(resultList.get(0).getFileType1());
			resultMsgInfo.setFileType2(resultList.get(0).getFileType2());
			resultMsgInfo.setFileType3(resultList.get(0).getFileType3());
			
			//문자함 리스트의 첨부이미지 정보 불러오기
			resultMsgPhotoInfo = mjonMsgDataService.selectMsgReSendPhotoInfo(resultMsgInfo);
			
		}*/
		
		if(resultList == null) {
			
			modelAndView.addObject("status", "emptyList");
			modelAndView.addObject("message", "재전송 문자 내용이 없습니다.");
			
		}else {
			
			modelAndView.addObject("status", "success");
			modelAndView.addObject("resultList", resultList);
			modelAndView.addObject("resultListCnt", resultList.size());
			//modelAndView.addObject("resultMsgPhotoInfo", resultMsgPhotoInfo);
			
		}
		
		return modelAndView;
	}
	
	
    /**
     * 엑셀 문자 발송 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/excel/selectMsgExcelDataView.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/excel/selectMsgExcelDataView.do"})
	public String selectMsgExcelDataView(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, CateCode cateCode, ModelMap model) throws Exception{
		
		//로그인 권한정보 불러오기
		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
		model.addAttribute("loginVO", loginVO);
		
		String categoryType = cateCode.getCateType();
		
		if(categoryType == null) {
			
			categoryType = "N";
			
		}
		
		// 문자 카테고리 리스트 불러오기
		List<CateCode> cateConfList = letterService.selectCateConfWithList(categoryType);
		model.addAttribute("cateCodeList", cateConfList);	
		
		// 문자 해쉬태그 리스트 불러오기
		String msgType = "M";
		List<HashConfVO> hashTagList = letterService.selectHashTagWithList(msgType);
		model.addAttribute("hashTagList", hashTagList);
		
		// 문자 리스트 불러오기
		LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		
		return "web/msgdata/excel/MsgExcelDataView";
	}
	
	 /**
     * 문자 발송 엑셀문자(대량전송) 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/excel/selectMsgExcelDataViewAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/excel/selectMsgExcelDataViewAjax.do"})
	public String selectMsgDataExcelViewAjax(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, CateCode cateCode, ModelMap model) throws Exception{
		
		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	String author = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getAuthority());
    	
		String categoryType = cateCode.getCateType();
		
		if(categoryType == null) {
			
			categoryType = "N";
			
		}
		
		//문자 전송 개인 단가 불러오기
		
		//0.이벤트 진행중이 회원 정보 불러오기.
		//이벤트 회원 정보 테이블에서 대상자의 정보를 불러온다.
		MjonEventVO mjonEventVO = new MjonEventVO();
		mjonEventVO.setMberId(userId);
		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO);
		
		long eventDiffDate = 0;
		float eventRemainCash = 0;
		boolean compareEndDate = false;
		
		if(eventMberInfo != null) {
			
			String eventEndDate = eventMberInfo.getEventEndDate();
			
			/**
			 * MJUtil.getCompareDate()
			 * 현재 날짜와 파라미터 전달 날짜를 비교
			 * 전달날짜를 지난경우 False를 리턴함.
			 * 현재날짜 이전 혹은 같은 날짜면 True를 리턴함.
			 * 
			 * */
			
			if(eventEndDate != null) {
				compareEndDate = MJUtil.getCompareDate(eventEndDate);
				eventRemainCash = (float) eventMberInfo.getEventRemainCash(); 
				
				//이벤트 종료 일자가 지난 경우, 이벤트 상태가 종료아 아니면 종료 처리 시킴
				//이벤트 남은 캐시가 단문 발송금액 7.5원 보다 낮으면 이벤트 종료 시킴
				if(!compareEndDate || eventRemainCash < 7.5) {
					
					if(!eventMberInfo.getEventStatus().equals("E")) {
						
						//이벤트 상태값을 종료로 변경한다.
						mjonEventVO.setEventInfoId(eventMberInfo.getEventInfoId());
						mjonEventVO.setEventStatus("E");
						mjonEventVO.setEventMemo("이벤트 발송 최소 금액(7.5) 부족 혹은 이벤트 종료일 초과되어 이벤트 종료 시킴");
						mjonEventVO.setEventRemainCash(eventRemainCash);
						mjonEventService.updateEventEndStatus(mjonEventVO);
						eventMberInfo.setEventStatus("E");
						
					}
					
				}else {//이벤트 진행중이면 남은 날짜 계산해서 전달.
					
					/**
					 * MJUtil.getDiffDateDay()
					 * 현재 날짜와 파라미터 날짜 사이의 날짜 수를 계산해줌.
					 * 
					 * */
					eventDiffDate = MJUtil.getDiffDateDay(eventEndDate);
					
				}
			}
			
		}
		
		//남은 날짜값을 절대값으로 변경(음수로 나오기 때문)
		model.addAttribute("eventDiffDate", Math.abs(eventDiffDate));
		model.addAttribute("compareEndDate", compareEndDate);
		model.addAttribute("eventRemainCash", eventRemainCash);
		model.addAttribute("eventMberInfo", eventMberInfo);
		
		
		//1.시스템 기본 단가 정보 불러오기
		JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
		
		//2.사용자 개인 단가 정보 불러오기
		MberManageVO mberManageVO = new MberManageVO(); 
		
		if(!userId.equals("") && !author.equals("ROLE_ADMIN")) {
			
			mberManageVO = mjonMsgDataService.selectMberManageInfo(userId);
			
		}
		
		model.addAttribute("exceptSpamYn", mberManageVO.getExceptSpamYn());
		
		//3.사용자 개인단가 정보가 0이 아니면 개인단가 사용, 없으면 시스템 기본 단가 사용
		Float shortPrice = mberManageVO.getShortPrice();
		Float longPrice = mberManageVO.getLongPrice();
		Float picturePrice = mberManageVO.getPicturePrice();
		Float picture2Price = mberManageVO.getPicture2Price();
		Float picture3Price = mberManageVO.getPicture3Price();
		BigDecimal userMoney = new BigDecimal(mberManageVO.getUserMoney()).setScale(2, RoundingMode.HALF_EVEN);
		
		//일반 단가정보 저장 변수 셋팅 - 이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
		Float norShortPrice = mberManageVO.getShortPrice();
		Float norLongPrice = mberManageVO.getLongPrice();
		Float norPicturePrice = mberManageVO.getPicturePrice();
		Float norPicture2Price = mberManageVO.getPicture2Price();
		Float norPicture3Price = mberManageVO.getPicture3Price();
		
		//기존 소수점 2째자리에서 반올림하였으나, 정책 변경으로 소수점 버림 처리함 20220623 
		/*int shortPrice = (int) mberManageVO.getShortPrice();
		int longPrice = (int) mberManageVO.getLongPrice();
		int picturePrice = (int) mberManageVO.getPicturePrice();
		int picture2Price = (int) mberManageVO.getPicture2Price();
		int picture3Price = (int) mberManageVO.getPicture3Price();
		int userMoney = (int) mberManageVO.getUserMoney();*/
		
		String userPoint = mberManageVO.getUserPoint();
		
		//이벤트 진행 회원의 발송 단가 처리해주기
		if(eventMberInfo != null && eventMberInfo.getEventStatus().equals("Y") && compareEndDate) {
			
			shortPrice = Float.parseFloat(eventMberInfo.getEventShortPrice());
			longPrice = Float.parseFloat(eventMberInfo.getEventLongPrice());
			picturePrice = Float.parseFloat(eventMberInfo.getEventPicturePrice());
			picture2Price = Float.parseFloat(eventMberInfo.getEventPicture2Price());
			picture3Price = Float.parseFloat(eventMberInfo.getEventPicture3Price());
			
			//이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
			if(shortPrice < 1 || longPrice < 1 || picturePrice < 1) {//이벤트 단가 적용시 일반단가도 필요하여 셋팅 해줌.
				
				norShortPrice = (float) sysJoinSetVO.getShortPrice();
				norLongPrice = (float) sysJoinSetVO.getLongPrice();
				norPicturePrice = (float) sysJoinSetVO.getPicturePrice();
				norPicture2Price = (float) sysJoinSetVO.getPicture2Price();
				norPicture3Price = (float) sysJoinSetVO.getPicture3Price();
				
			}
			
		}else if(shortPrice < 1 || longPrice < 1 || picturePrice < 1) {
			
			shortPrice = (float) sysJoinSetVO.getShortPrice();
			longPrice = (float) sysJoinSetVO.getLongPrice();
			picturePrice = (float) sysJoinSetVO.getPicturePrice();
			picture2Price = (float) sysJoinSetVO.getPicture2Price();
			picture3Price = (float) sysJoinSetVO.getPicture3Price();
			
		}
		
		model.addAttribute("shortPrice", shortPrice);
		model.addAttribute("longPrice", longPrice);
		model.addAttribute("picturePrice", picturePrice);
		model.addAttribute("picture2Price", picture2Price);
		model.addAttribute("picture3Price", picture3Price);
		model.addAttribute("userMoney", userMoney);
		model.addAttribute("userPoint", userPoint);
		
		//이벤트 캐시 부족시 일반단가로 계산하기 위해서임.20230328, 우영두추가
		if(norShortPrice < 1 || norLongPrice < 1 || norPicturePrice < 1) {//협의 단가가 없는 경우 일반단가에 시스템 단가로 셋팅해줌
			
			norShortPrice = (float) sysJoinSetVO.getShortPrice();
			norLongPrice = (float) sysJoinSetVO.getLongPrice();
			norPicturePrice = (float) sysJoinSetVO.getPicturePrice();
			norPicture2Price = (float) sysJoinSetVO.getPicture2Price();
			norPicture3Price = (float) sysJoinSetVO.getPicture3Price();
			
		}
		
		model.addAttribute("norShortPrice", norShortPrice);
		model.addAttribute("norLongPrice", norLongPrice);
		model.addAttribute("norPicturePrice", norPicturePrice);
		model.addAttribute("norPicture2Price", norPicture2Price);
		model.addAttribute("norPicture3Price", norPicture3Price);
		
		
		if(!userId.equals("")) {//로그인 된 사용자만 발신번호를 불러오도록 수정
		
			//아이디 발신번호 리스트 불러오기.
			List<String> resultSendPhonList = mjonMsgDataService.selectSendPhonNumList(userId);
			List<String> resultPhonList = new ArrayList<String>();
			MJUtil mjUtil = new MJUtil();
			
			for(String phone : resultSendPhonList) {
				
				resultPhonList.add(mjUtil.addDash(phone));
				
			}
			model.addAttribute("resultPhonList", resultPhonList);
		
		}
		
		// 문자 카테고리 리스트 불러오기
		List<CateCode> cateConfList = letterService.selectCateConfWithList(categoryType);
		model.addAttribute("cateCodeList", cateConfList);	
		
		//그림 문자 리스트 불러오기
		LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}
		
		MjonSymbolVO symbolVO = new MjonSymbolVO();
		// 특수문자 리스트 불러오기
		List<MjonSymbolVO> symbolList = mjonSymbolService.selectMjonSymbolList(symbolVO);
		model.addAttribute("symbolList", symbolList);
		
		/*String categoryType = cateCode.getCateType();
		
		if(categoryType == null) {
			
			categoryType = "N";
			
		}
		
		// 문자 카테고리 리스트 불러오기
		List<CateCode> cateConfList = letterService.selectCateConfWithList(categoryType);
		model.addAttribute("cateCodeList", cateConfList);	
		
		//그림 문자 리스트 불러오기
		LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}*/
  
		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		
		return "web/msgdata/excel/MsgExcelDataSMLView";
	}
	
	/**
	 * 하위 카테고리 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectCateConfThrDptListAjax.do"})
	public String selectCateConfThreeDepthListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO,
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		
		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		
		//하위카테고리에서 전체 클릭 시 상위카테고리로 하위카테고리 조회
		if(letterVO.getCategoryCode().equals("") && !letterVO.getUpperCateNo().equals("")) {
			cateCode.setCateNo(letterVO.getUpperCateNo());
		}
		
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회
		if(cateCodeInfoVO != null) { //전체 카테고리가 아닌 경우
			if(cateCodeInfoVO.getCateDepth().equals("2")) { //선택한 카테고리가 2뎁스(중분류)일 시 중분류의 코드로 하위분류 조회
				cateCode.setUpperCateNo(cateCodeInfoVO.getId()); 
			}else if(cateCodeInfoVO.getCateDepth().equals("3")) { //선택한 카테고리가 3뎁스(하위분류)일 시 해당 부모코드로 형제카테고리 조회 
				cateCode.setUpperCateNo(cateCodeInfoVO.getParent());
			}
		}
		
		cateCode.setCateType("N"); //일반 o 맞춤제작 x
		
		String thrDptCateNo = ""; //클릭한 카테고리가 2뎁스(하위분류)일 시 하위 카테고리는 '전체' selected효과
		if(cateCodeInfoVO != null && cateCodeInfoVO.getCateDepth().equals("3")) { //클릭한 카테고리가 3뎁스(하위분류)일 시 해당 카테고리 selected 효과 
			thrDptCateNo= letterVO.getCategoryCode();
		}
		
		//3뎁스(하위분류) 카테고리 조회
		List<CateCode> cateThreeConfList = letterService.selectCateConfThreeDepthWithList(cateCode);
		model.addAttribute("resultCateThreeConfList", cateThreeConfList);
		model.addAttribute("thrDptCateNo", thrDptCateNo);
		
		return "web/msgdata/CateThrDptListAjax";
	}	
	
	/**
	 * 문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectLetterDataListAjax.do"})
	public String selectLetterDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회
		
		//1번. 문자 샘플 탭 or 단문문자 탭 or 상위카테고리에서 ALL 클릭 시 - 카테고리 관련 조건 없이 select
		//2번. 상위 카테고리 BEST 클릭 시 - bestCategory = Y 조건 추가
		//3번. 상위 카테고리(All or BEST가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 2으로 넘겨주고 해당 카테고리 번호와 해당 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회 
		//4번. 하위 카테고리 전체 클릭 시 - cateDepth를 2으로 넘겨주고 상위 카테고리와 상위 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회
		//5번. 하위 카테고리(전체가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 3으로 넘겨주고 해당 카테고리를 조건절에 추가 
		
		if(cateCodeInfoVO != null) { //3번. 상위 카테고리 클릭 시
			letterVO.setCateDepth(cateCodeInfoVO.getCateDepth());
		}

		if ("best".equals(letterVO.getCategoryCode())) { //2번. BEST 클릭 시 경우
			letterVO.setBestCategory("Y");
			letterVO.setCategoryCode("");
		}else if(letterVO.getCategoryCode().equals("") && !letterVO.getUpperCateNo().equals("")) { //하위분류에서 전체 클릭 시 중분류의 코드로 문자샘플 조회
			letterVO.setCateDepth("2");
			letterVO.setCategoryCode(letterVO.getUpperCateNo());
		}
		
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit((int)letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 단문문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			
			letterVO.setLetterType("S");
			
		}
		
		// 장/단문 문자 리스트
		List<?> resultLetterList = mjonMsgDataService.selectLetterList(letterVO);
		model.addAttribute("resultLetterList", resultLetterList);
		paginationInfo.setTotalRecordCount( resultLetterList.size()> 0 ? ((Long)((EgovMap)resultLetterList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/LetterListAjax";
	}
	
	/**
	 * (메인화면)문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectMainLetterDataListAjax.do"})
	public String selectMainLetterDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		
		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회
		
		//1번. 문자 샘플 탭 or 단문문자 탭 or 상위카테고리에서 ALL 클릭 시 - 카테고리 관련 조건 없이 select
		//2번. 상위 카테고리 BEST 클릭 시 - bestCategory = Y 조건 추가
		//3번. 상위 카테고리(All or BEST가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 2으로 넘겨주고 해당 카테고리 번호와 해당 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회 
		//4번. 하위 카테고리 전체 클릭 시 - cateDepth를 2으로 넘겨주고 상위 카테고리와 상위 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회
		//5번. 하위 카테고리(전체가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 3으로 넘겨주고 해당 카테고리를 조건절에 추가 
		
		if(cateCodeInfoVO != null) { //3번. 상위 카테고리 클릭 시
			letterVO.setCateDepth(cateCodeInfoVO.getCateDepth());
		}

		if ("best".equals(letterVO.getCategoryCode())) { //2번. BEST 클릭 시 경우
			letterVO.setBestCategory("Y");
			letterVO.setCategoryCode("");
		}else if(letterVO.getCategoryCode().equals("") && !letterVO.getUpperCateNo().equals("")) { //하위분류에서 전체 클릭 시 중분류의 코드로 문자샘플 조회
			letterVO.setCateDepth("2");
			letterVO.setCategoryCode(letterVO.getUpperCateNo());
		}
		

		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 단문문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			
			letterVO.setLetterType("S");
			
		}
		
		// 장/단문 문자 리스트
		List<?> resultLetterList = mjonMsgDataService.selectLetterList(letterVO);
		model.addAttribute("resultLetterList", resultLetterList);
		paginationInfo.setTotalRecordCount( resultLetterList.size()> 0 ? ((Long)((EgovMap)resultLetterList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/MainLetterListAjax";
	}
	
	/**
	 * 그림 문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectPhotoDataListAjax.do"})
	public String selectPhotoDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		
/*		String subStr = letterVO.getCategoryCode();
		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회		
		
		if ("best".equals(subStr)) {
			letterVO.setBestCategory("Y");
			letterVO.setCategoryCode("");
			
		} else if(!subStr.equals("") && cateCodeInfoVO.getCateDepth().equals("3")) { //하위분류일 시 substring 없이 해당 카테고리만 조회
			letterVO.setCategoryCode(subStr);
		}else if(!subStr.equals("")) { //중분류일 시 substiring을 통해 하위카테고리들 조회
			subStr = subStr.substring(0, 3);
			letterVO.setCategoryCode(subStr);
		} else if(subStr.equals("") && !letterVO.getUpperCateNo().equals("")) { //하위분류에서 전체 클릭 시 중분류의 코드로 문자샘플 조회
			letterVO.setCategoryCode(letterVO.getUpperCateNo().substring(0, 3));
		}*/
		
		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회
		
		//1번. 문자 샘플 탭 or 단문문자 탭 or 상위카테고리에서 ALL 클릭 시 - 카테고리 관련 조건 없이 select
		//2번. 상위 카테고리 BEST 클릭 시 - bestCategory = Y 조건 추가
		//3번. 상위 카테고리(All or BEST가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 2으로 넘겨주고 해당 카테고리 번호와 해당 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회 
		//4번. 하위 카테고리 전체 클릭 시 - cateDepth를 2으로 넘겨주고 상위 카테고리와 상위 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회
		//5번. 하위 카테고리(전체가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 3으로 넘겨주고 해당 카테고리를 조건절에 추가 
		
		if(cateCodeInfoVO != null) { //3번. 상위 카테고리 클릭 시
			letterVO.setCateDepth(cateCodeInfoVO.getCateDepth());
		}

		if ("best".equals(letterVO.getCategoryCode())) { //2번. BEST 클릭 시 경우
			letterVO.setBestCategory("Y");
			letterVO.setCategoryCode("");
		}else if(letterVO.getCategoryCode().equals("") && !letterVO.getUpperCateNo().equals("")) { //하위분류에서 전체 클릭 시 중분류의 코드로 문자샘플 조회
			letterVO.setCateDepth("2");
			letterVO.setCategoryCode(letterVO.getUpperCateNo());
		}		
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 그림문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			
			letterVO.setLetterType("P");	//그림문자 셋팅
			letterVO.setMemberType("P");	//개인 카테고리 셋팅
			
		}
		
		// 그림 문자 리스트
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/PhotoListAjax";
	}
	
	
	
	/**
	 * 그림 문자샘플 리스트 화면 불러오기 2
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectPhotoDataList2Ajax.do"})
	public ModelAndView selectPhotoDataList2Ajax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			ModelMap model) throws Exception {

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		String subStr = letterVO.getCategoryCode();
		if(!subStr.equals("")) {
			
			subStr = subStr.substring(0, 3);
			letterVO.setCategoryCode(subStr);
			
		}
		
		//그림 문자 리스트 불러오기
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 단문문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			letterVO.setLetterType("P");
		}
		
		try {
			// 그림 문자 리스트
			List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
			model.addAttribute("resultPhoList", resultPhoList);
			paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
			model.addAttribute("paginationInfo", paginationInfo);
			model.addAttribute("letterVO", letterVO);

			modelAndView.addObject("status", "success");
		} catch (Exception e) {
			modelAndView.addObject("status", "fail");
		}
		
		return modelAndView;
	}
	
	/**
	 * (메인화면)그림 문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectMainPhotoDataListAjax.do"})
	public String selectMainPhotoDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		
		CateCode cateCode = new CateCode();
		cateCode.setCateNo(letterVO.getCategoryCode());
		CateCode cateCodeInfoVO = cmmnDetailCodeManageService.selectCateCodeInfo(cateCode); //카테고리 상세 조회
		
		//1번. 문자 샘플 탭 or 단문문자 탭 or 상위카테고리에서 ALL 클릭 시 - 카테고리 관련 조건 없이 select
		//2번. 상위 카테고리 BEST 클릭 시 - bestCategory = Y 조건 추가
		//3번. 상위 카테고리(All or BEST가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 2으로 넘겨주고 해당 카테고리 번호와 해당 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회 
		//4번. 하위 카테고리 전체 클릭 시 - cateDepth를 2으로 넘겨주고 상위 카테고리와 상위 카테고리리 번호를 upper 카테고리로 가지고 있는 하위 카테고리들 조회
		//5번. 하위 카테고리(전체가 아닌 관리자가 등록한 카테고리) 클릭 시 - cateDepth를 3으로 넘겨주고 해당 카테고리를 조건절에 추가 
		
		if(cateCodeInfoVO != null) { //3번. 상위 카테고리 클릭 시
			letterVO.setCateDepth(cateCodeInfoVO.getCateDepth());
		}

		if ("best".equals(letterVO.getCategoryCode())) { //2번. BEST 클릭 시 경우
			letterVO.setBestCategory("Y");
			letterVO.setCategoryCode("");
		}else if(letterVO.getCategoryCode().equals("") && !letterVO.getUpperCateNo().equals("")) { //하위분류에서 전체 클릭 시 중분류의 코드로 문자샘플 조회
			letterVO.setCateDepth("2");
			letterVO.setCategoryCode(letterVO.getUpperCateNo());
		}
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 단문문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			
			letterVO.setLetterType("P");
			
		}
		
		// 그림 문자 리스트
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/MainPhotoListAjax";
	}
	
	/**
	 * 내문자함 리스트 화면 불러오기
	 *
	 * @param MjonMsgDataVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectMyMsgDataListAjax.do"})
	public String selectMyMsgDataListAjax(
			@ModelAttribute("searchVO") MjonMsgDataVO mjonMsgDataVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
		if(loginVO == null) {
            return "redirect:/web/main/mainPage.do";
         }
    	
    	mjonMsgDataVO.setUserId(userId);
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(mjonMsgDataVO.getPageUnit() != 10) {
			mjonMsgDataVO.setPageUnit(mjonMsgDataVO.getPageUnit());
		}
		
		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(mjonMsgDataVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(mjonMsgDataVO.getPageUnit());
		paginationInfo.setPageSize(mjonMsgDataVO.getPageSize());

		mjonMsgDataVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		mjonMsgDataVO.setLastIndex(paginationInfo.getLastRecordIndex());
		mjonMsgDataVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		// 내 문자함 문자 리스트
		List<?> resultMyMsgList = mjonMsgDataService.selectMyMsgDataListAjax(mjonMsgDataVO);
		model.addAttribute("resultMyMsgList", resultMyMsgList);
		paginationInfo.setTotalRecordCount( resultMyMsgList.size()> 0 ? ((Long)((EgovMap)resultMyMsgList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("mjonMsgDataVO", mjonMsgDataVO);

		//문자함 리스트의 첨부이미지 정보 불러오기
		List<?> resultMyMsgPhotoList = mjonMsgDataService.selectMyMsgPhotoListInfo(resultMyMsgList);
		
		model.addAttribute("resultMyMsgPhotoList", resultMyMsgPhotoList);
		return "web/msgdata/MyMsgListAjax";
		
	}
	
	
	/**
	 * 추천인 아이디 확인 
	 *
	 * @param String
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectRecommIdCheckAjax.do"})
	public ModelAndView selectRecommIdCheckAjax(
			MjonMsgVO mjonMsgVO, 
			ModelMap model) throws Exception {

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		List<String> checkId = new ArrayList<String>();
		checkId = mberManageService.selectIdCheck(mjonMsgVO.getRecommId());
		
		int checkIdCnt = checkId.size();
		String resultSts = "fail";
		
		if(checkIdCnt > 0) {
			
			resultSts = "success";
			
		}
		
		modelAndView.addObject("status", resultSts);
		
		return modelAndView;
	}
	
	/**
	 * 주소록 그룹 리스트 화면 불러오기
	 *
	 * @param MjonMsgDataVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectAddrGroupListAjax.do"})
	public String selectAddrGroupListAjax(
			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, 
			AddrVO addrVO,
			ModelMap model, 
			RedirectAttributes redirectAttributes) throws Exception {

		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
    	if(loginVO == null) {
            
            return "redirect:/web/main/mainPage.do";
            
         }
    	
    	if(userId != "") {
    		addrGroupVO.setMberId(userId);
    		addrVO.setMberId(userId);
    	}
    	
    	if(addrGroupVO.getPageUnit() != 10) {
    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
		}
    	
		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
			addrGroupVO.setSearchSortCnd("addrGrpId");
			addrGroupVO.setSearchSortOrd("desc");
		}
    	
		addrGroupVO.setSiteId("web");
    	List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
    	
    	//회원별 주소록 전체 갯수 조회
    	int addrTotalCount = addrService.selectAddrTotalCount(addrVO);
    	
    	addrVO.setType("bookmark");
		List<AddrVO> addrBookmarkList = addrService.selectAddrBasicGrpList(addrVO);

		addrVO.setType("noGrp");
		List<AddrVO> addrNoGrpList = addrService.selectAddrBasicGrpList(addrVO);
		
		model.addAttribute("addrTotalCount", addrTotalCount);
    	model.addAttribute("addrGroupList", addrGroupList);
     	model.addAttribute("addrBookmarkList", addrBookmarkList);
		model.addAttribute("addrNoGrpList", addrNoGrpList);
		
		return "web/msgdata/addr/MsgAddrGroupListAjax";
	}
	
	
		/**
		 * 주소록 그룹 선택시 우측 주소록 리스트 화면 불러오기
		 *
		 * @param AddrGroupVO
		 * @param AddrVO
		 * @param sessionVO
		 * @param model
		 * @return
		 * @throws Exception
		 */
		@RequestMapping(value= {"/web/mjon/msgdata/selectMsgAddrListAjax.do"})
		public ModelAndView selectMsgAddrListAjax(
				@ModelAttribute("searchVO") AddrVO addrVO,
				ModelMap model, 
				RedirectAttributes redirectAttributes) throws Exception {

			ModelAndView modelAndView = new ModelAndView();
			modelAndView.setViewName("jsonView");
			
			//로그인 권한정보 불러오기
	    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
	    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
	    	
	    	if(userId != "") {
	    		addrVO.setMberId(userId);
	    	}else {
	    		
	    		modelAndView.addObject("message", "로그인 후 이용이 가능합니다.");
		    	modelAndView.addObject("result", "loginFail");
		    	return modelAndView;
	    		
	    	}
	    	
	    	List<AddrVO> resultAddrList = mjonMsgDataService.selectMsgAddrListAjax(addrVO);
	    	
	    	modelAndView.addObject("resultAddrList", resultAddrList);
	    	modelAndView.addObject("result", "success");
			
			return modelAndView;
		}
		
	/**
	 * 최근 전송내역 리스트 화면 불러오기
	 * 
	 * @param MjonMsgDataVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectLatestMsgListAjax.do"})
	public String selectLatestMsgListAjax(
			@ModelAttribute("searchVO") MjonMsgDataVO mjonMsgDataVO, 
			ModelMap model, 
			RedirectAttributes redirectAttributes) throws Exception {

		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
    	Calendar cal = Calendar.getInstance();
    	Date now = new Date();
    	
    	SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    	
    	cal.setTime(now);
    	cal.add(Calendar.DATE, -3);
    	
    	String chkDate = format.format(cal.getTime());
    	
    	mjonMsgDataVO.setMyMsgStDt(chkDate);	//검색 시작일 저장 - 현재날짜로 부터 3일 이전 날짜로 시작
    	mjonMsgDataVO.setUserId(userId);
    	
    	List<?> resultLatestMsgList = mjonMsgDataService.selectLatestMsgList(mjonMsgDataVO);
    	
		model.addAttribute("resultLatestMsgList", resultLatestMsgList);
		
		return "web/msgdata/MsgLatestListAjax";
	}	
	
	
	/**
	 * 자주 보내는 번호 리스트 화면 불러오기
	 *
	 * @param MjonMsgDataVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectBookMarkMsgListAjax.do"})
	public String selectBookMarkMsgListAjax(
			@ModelAttribute("searchVO") MjonMsgDataVO mjonMsgDataVO, 
			ModelMap model, 
			RedirectAttributes redirectAttributes) throws Exception {
		
    	List<?> resultBookMarkMsgList = mjonMsgDataService.selectBookMarkMsgList(mjonMsgDataVO);
    	
		model.addAttribute("resultBookMarkMsgList", resultBookMarkMsgList);
		
		return "web/msgdata/MsgBookMarkListAjax";
	}


	/**
	 * 내문자함 리스트 삭제 처리
	 *
	 * @param MjonMsgDataVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/deleteMyMsgDataListAjax.do"})
	public String deleteMyMsgDataListAjax(
			@ModelAttribute("searchVO") MjonMsgDataVO mjonMsgDataVO, 
			BindingResult bindingResult, 
			ModelMap model, 
			SessionStatus status, 
			RedirectAttributes redirectAttributes) throws Exception {

		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
    	mjonMsgDataVO.setUserId(userId);
    	
    	//내문자함 문자 삭제 처리하기
    	mjonMsgDataService.deleteMyMsgDataListAjax(mjonMsgDataVO);
    	
    	//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(mjonMsgDataVO.getPageUnit() != 10) {
			mjonMsgDataVO.setPageUnit(mjonMsgDataVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(mjonMsgDataVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(mjonMsgDataVO.getPageUnit());
		paginationInfo.setPageSize(mjonMsgDataVO.getPageSize());

		mjonMsgDataVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		mjonMsgDataVO.setLastIndex(paginationInfo.getLastRecordIndex());
		mjonMsgDataVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		// 내 문자함 문자 리스트
		List<?> resultMyMsgList = mjonMsgDataService.selectMyMsgDataListAjax(mjonMsgDataVO);
		model.addAttribute("resultMyMsgList", resultMyMsgList);
		paginationInfo.setTotalRecordCount( resultMyMsgList.size()> 0 ? ((Long)((EgovMap)resultMyMsgList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("mjonMsgDataVO", mjonMsgDataVO);
		
		//문자함 리스트의 첨부이미지 정보 불러오기
		List<?> resultMyMsgPhotoList = mjonMsgDataService.selectMyMsgPhotoListInfo(resultMyMsgList);
		
		model.addAttribute("resultMyMsgPhotoList", resultMyMsgPhotoList);
		
		return "web/msgdata/MyMsgListAjax";
	}
	
	
	/*
	 * 문자발송처리 서비스만 공통으로 분리하였음
	 * param : MjonMsgVO
	 * return : ModelAndView
	 * 
	 * */
	@RequestMapping(value= {"/web/mjon/msgdata/selectSpamTxtChkAjax.do"})
	public ModelAndView selectSpamTxtChkAjax(MjonMsgVO mjonMsgVO) {
		ModelAndView modelAndView = new ModelAndView(); 
		modelAndView.setViewName("jsonView");
		
		try {
		
			List<String> resultSpamTxt = mjonMsgDataService.selectSpamKeywordList();
	    	String spmFilterTxt = "";
			if(resultSpamTxt == null) {//스팸 체크리스트가 없는 경우
				
				modelAndView.addObject("result", "listEmpty");
				return modelAndView;
				
			}else {
				
				
				
				String smsTxt = mjonMsgVO.getSmsTxt();		//발송 문자 내용
				
				/*
				 * 치환문자에 스팸문구가 있을수 있어서 첫번째 치환데이터만 변환 적용 해서 스팸문구가 있는지 체크하도록 함.
				 * 차후에 전체 치환 데이터에 대한 체크를 할지를 검토하겠음.
				 * 
				 * */
				
				String txtReplYn = mjonMsgVO.getTxtReplYn();
				if(txtReplYn.equals("Y")) {
					
					String[] nameList = mjonMsgVO.getNameList();	//치환 이름 리스트
	        		String[] rep1 = mjonMsgVO.getRep1List();		//치환 문자1 리스트
	        		String[] rep2 = mjonMsgVO.getRep2List();		//치환 문자2 리스트
	        		String[] rep3 = mjonMsgVO.getRep3List();		//치환 문자3 리스트
	        		String[] rep4 = mjonMsgVO.getRep4List();		//치환 문자4 리스트
					
					//이름, 휴대폰, 치환문자 데이터가 없으면 취소 처리
	        		if((nameList.length == 0 || nameList == null) 
	        				&& (rep1.length == 0 || rep1 == null)
	        				&& (rep2.length == 0 || rep2 == null)
	        				&& (rep3.length == 0 || rep3 == null)
	        				&& (rep4.length == 0 || rep4 == null)) {
	        			
	        			//modelAndView.addObject("message", "특정문구 일괄변환 치환문자 데이터가 없습니다.");
	    				//modelAndView.addObject("result", "fail");
	    				return modelAndView;
	        			
	        		}
					
					
	        		if (smsTxt.indexOf("[*이름*]") > -1) {
						smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", StringUtil.getString(nameList[0].replaceAll("§", ",")));
					}else {
						smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", "");
					}
	        		
	        		if (smsTxt.indexOf("[*1*]") > -1) {
						smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", StringUtil.getString(rep1[0].replaceAll("§", ",")));
					}else {
						smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", "");
					}
	        		
	        		if (smsTxt.indexOf("[*2*]") > -1) {
						smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", StringUtil.getString(rep2[0].replaceAll("§", ",")));
					}else {
						smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", "");
					}
	        		
					if (smsTxt.indexOf("[*3*]") > -1) {
						smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", StringUtil.getString(rep3[0].replaceAll("§", ",")));
					}else {
						smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", "");
					}
					
					if (smsTxt.indexOf("[*4*]") > -1) {
						smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", StringUtil.getString(rep4[0].replaceAll("§", ",")));
					}else {
						smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", "");
					}
					
				}
				
				//입력 문장에 대해서 우회 문장 또는 특수 기호 입력 제거 등 문장 재구성 처리, 한글 자모음 분리 및 재조함도 함께 처리함.
				String resultParser = ComGetSpamStringParser.getSpamTextParse(smsTxt).trim();
				//List<String> jasoList = HangulParser.disassemble(resultParser);
				//String assembleStr = HangulParser.assemble(jasoList);
				
				System.out.println("++++++++++++++ spam resultParser ::: "+resultParser);
				
				/*
				//형태소 분석기 처리
				KomoranUtils komoran = new KomoranUtils();
				String resultKomoran = komoran.parseKomoranTextByString(assembleStr);*/
				
				//System.out.println(resultKomoran);
				
				//한글, 영문, 숫자, 띄어쓰기를 제외한 다른 단어들을 삭제함.
				//String repSmsTxt = smsTxt.replaceAll("[^ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9 ]", "");
				
				//데이터베이스에 등록된 스팸문구와 일치하는 단어/문구가 있는지 체크함.
				int spmCnt = 0;
				for(String spmTxt : resultSpamTxt) {
					
					String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
					
					if(resultParser.contains(parserStr)) {
						
						//스팸 단어/문구가 있으면 콤마로 연결시킨 후 리턴해줌.
						spmFilterTxt += spmTxt + ",";
						spmCnt++;
						
					}
					
				}
				
				if(spmCnt > 0) {//스팸문자가 포함되어 있으면 문자열 끝 , 단어 삭제 처리
					
					if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
						// 처음부터 idx 만큼 잘라낸 나머지 글자 
						spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1); 	
						
					}
					
					System.out.println("++++++++++++++ spmFilterTxt ::: "+spmFilterTxt);
					
					modelAndView.addObject("result", "spams");
//					modelAndView.addObject("spmFilterTxt", spmFilterTxt);
					return modelAndView;
					
				}
				
			}
	    	
	    	
		}catch(Exception e) {
			
			logger.error(e.getMessage(), e);
			modelAndView.addObject("result", "fail");
			modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
			return modelAndView;
	
		}
	
		return modelAndView;
	}
	
	// MsgGroupData Not Exist Check
	@RequestMapping(value="/web/mjon/msgdata/selectMsgGroupNotExistInfoAjax.do")
	public ModelAndView selectMsgGroupNotExistInfoAjax(@ModelAttribute MjonMsgVO mjonMsgVO
			, HttpServletRequest request) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");

		boolean isSuccess = true;
		boolean isError = false;
		String msg = "";
		
		//로그인 권한정보 불러오기
    	LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	mjonMsgVO.setUserId(userId);
    	
		try {
			mjonMsgVO = mjonMsgDataService.selectMsgGroupNotExistInfo(mjonMsgVO);
			if (null == mjonMsgVO) {
				isError = true;		// 문자발송중 에러발생 데이터 존재	
			}
			
		}
		catch(Exception e) {
			isSuccess = false;
			msg = e.getMessage();
		}		

		modelAndView.addObject("isSuccess", isSuccess);
		modelAndView.addObject("isError", isError);
		modelAndView.addObject("msg", msg);
			
		return modelAndView;
	}			
	
    /**
     * 문자 발송  기능
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/sendMsgDataAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/sendMsgDataAjax.do"})
	public ModelAndView sendMsgData(@ModelAttribute("searchVO") MjonMsgVO mjonMsgVO, 
			RedirectAttributes redirectAttributes, 
			HttpServletRequest request,
			ModelMap model) throws Exception{
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		String resultSts = "0";
		String resultBlockSts = "0";
		String userId = ""; 
				
		try {
			
			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
	    	userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
	    	
        	if(userId.equals("")) {
        		
        		modelAndView.addObject("message", "로그인 후 이용이 가능합니다.");
    			modelAndView.addObject("result", "loginFail");
    			modelAndView.addObject("resultSts", resultSts);
    			return modelAndView;
        		
        	}else {
        		
        		mjonMsgVO.setUserId(userId);
        		
        		/**
        		 * 회원 정지된 상태이면 문자 발송이 안되도록 처리함
        		 * 현재 로그인 세션도 만료 처리함
        		 * */
        		boolean mberSttus = userManageService.selectUserStatusInfo(userId);
        		
        		if(!mberSttus) {
        			
        			modelAndView.addObject("message", "현재 고객님께서는 문자온 서비스 이용이 정지된 상태로 문자를 발송하실 수 없습니다. 이용정지 해제를 원하시면 고객센터로 연락주시기 바랍니다.");
        			modelAndView.addObject("result", "statusFail");
        			modelAndView.addObject("resultSts", resultSts);
        			
        			request.getSession().invalidate();
        			
        			return modelAndView;
        			
        		}
        		
        	}
        	
        	//회원정보에서 스미싱 회원 여부 정보 조회
        	UserManageVO userManageVO = new UserManageVO();
        	
        	userManageVO.setMberId(userId);
        	UserManageVO resultUserVO = userManageService.selectSmishingYnUserInfo(userManageVO);
        	String smishingYn = resultUserVO.getSmishingYn();
        	mjonMsgVO.setSmishingYn(smishingYn);

        	//문자열 길이 체크 해주기
        	String charset = "euc-kr"; 						//문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
        	String smsCont = mjonMsgVO.getSmsTxt().replace("\r\n", "\n");
        	int FrBytes = smsCont.getBytes(charset).length;
        	
        	if(FrBytes > 2000) {
        		
        		modelAndView.addObject("message", "문자 내용은 2000Byte를 넘을 수 없습니다.");
    			modelAndView.addObject("result", "smsLengFail");
    			return modelAndView;
        		
        	}
    		
        	System.out.println("mjonMsgVO.getMsgType1() ::: "+mjonMsgVO.getMsgType());
        	
        	String msgType = mjonMsgVO.getMsgType();
        	
        	//내문자저장함에 저장후 문자를 발송하는경우 문자 타입이 숫자가 아닌 문자로 넘어와서 변경 처리함- 20220520 우영두
        	if(msgType.equals("P") || msgType.equals("L")) {
        		msgType = "6";
        	}else if(msgType.equals("S")) {
        		
        		msgType = "4";
        	}
        	
        	//메세지 타입이 단문이면 진짜 단문인지 한번더 확인해 준다.
        	if(msgType.equals("4")) {
        		
        		//메세지 길이가 90Byte를초과 하거나, 그림 이미지가 있는경우 메세지 타입을 6으로 변경해준다.
        		if(FrBytes > 90 || mjonMsgVO.getImgFilePath().length > 0) {
        			
        			msgType = "6";
        			
        		}
        		
        	}
        	
        	mjonMsgVO.setMsgType(msgType);
        	
        	//장문 메세지일 경우
        	int fileCount = 0;
        	if(msgType.equals("6")) {
        		
        		//그림 이미지가 첨부된 경우
        		if(mjonMsgVO.getImgFilePath() != null || mjonMsgVO.getImgFilePath().length > 0) {
        			
        			String[] path = mjonMsgVO.getImgFilePath();
        			String[] fileId = mjonMsgVO.getImgFileId();
        			String[] templateYn = mjonMsgVO.getTemplateYn();
        			
            		for(int i=0; i<path.length; i++) {
            			
                		if("Y".equals(templateYn[i])) {
            				//템플릿 사용누계 증가
                			letterService.updateTemplateUseCount(fileId[i]);
            			}
                		
                		String atchFileId = fileId[i];
                		String imgFilePath = mjonMsgService.selectPhotoImgFileRealPath(atchFileId);
                		
                		// 아이하트, 현대퓨쳐넷 두 중계사는 이미지 경로는 풀패스 경로로 넘겨주면 됨
                		if(i == 0) {
                			
                			mjonMsgVO.setFileName1(imgFilePath);
                			
                		}else if(i == 1) {
                			
                			mjonMsgVO.setFileName2(imgFilePath);
                			
                		}else {
                			
                			mjonMsgVO.setFileName3(imgFilePath);
                			
                		}
                		fileCount ++;
                	}
                	
                	//첨부파일 갯수 셋팅해주기
                	mjonMsgVO.setFileCnt(Integer.toString(fileCount));
        			
        		}
            	
        	}
        	
        	//파일 갯수는 있는데 파일 경로가 없는 경우 문자발송이 안되도록 튕겨내도록 함 - 20220520 우영두
        	if(fileCount > 0) {
        		
        		if(mjonMsgVO.getFileName1() == null && mjonMsgVO.getFileName2() == null && mjonMsgVO.getFileName3() == null) {
        			
        			modelAndView.addObject("message", "문자 메세지 이미지 추가에 오류가 발생하여 문자 발송이 취소 되었습니다.");
    				modelAndView.addObject("result", "imgSourceFail");
    				modelAndView.addObject("resultSts", "0");
    				modelAndView.addObject("resultBlockSts", "0");
    				
    				return modelAndView; 
        			
        		}
        		
        	}
        	
        	
        	/*
        	 * 화면에서 넘어오는 단가 금액 및 총 결제 캐시 금액 체크 해주기
        	 * 검증을 위해서 시스템 단가, 회원 협의 단가, 이벤트 단가 정보 조회
        	 * 조회 단가를 이용하여 총 결제 캐시 금액 계산
        	 * 파라미터로 넘어온 개별단가(eachPrice), 총 결제캐시(totPrice)를 비요하여 동일하지 않으면 컨트롤러에서 계산한 금액으로 입력해줌.
        	 */
        	MjonEventVO mjonEventVO = new MjonEventVO();
    		mjonEventVO.setMberId(userId);
    		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO);
    		
    		//1.시스템 기본 단가 정보 불러오기
    		JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo();
    		
    		//2.사용자 개인 단가 정보 불러오기
    		MberManageVO mberManageVO = new MberManageVO(); 
    		mberManageVO = mjonMsgDataService.selectMberManageInfo(userId);
    			
    		//3.사용자 개인단가 정보가 0이 아니면 개인단가 사용, 없으면 시스템 기본 단가 사용
    		Float shortPrice = mberManageVO.getShortPrice();
    		Float longPrice = mberManageVO.getLongPrice();
    		Float picturePrice = mberManageVO.getPicturePrice();
    		Float picture2Price = mberManageVO.getPicture2Price();
    		Float picture3Price = mberManageVO.getPicture3Price();
    		
    		//기존 소수점 2째자리에서 반올림하였으나, 정책 변경으로 소수점 버림 처리함 20220623 
    		boolean compareEndDate = false;
    		float eventRemainCash = 0;
    		float paramEachPrice = Float.parseFloat(mjonMsgVO.getEachPrice());
    		
    		if(eventMberInfo != null) {
    			
    			String eventEndDate = eventMberInfo.getEventEndDate();
    			
    			if(eventEndDate != null) {
    				compareEndDate = MJUtil.getCompareDate(eventEndDate);
    				eventRemainCash = (float) eventMberInfo.getEventRemainCash();
    				
    				//이벤트 금액 및 기간 체크
    				if(!compareEndDate || eventRemainCash < paramEachPrice) {
    					
    					if(!eventMberInfo.getEventStatus().equals("E")) {
    						
    						//이벤트 상태값을 종료로 변경한다.
    						mjonEventVO.setEventInfoId(eventMberInfo.getEventInfoId());
    						mjonEventVO.setEventStatus("E");
    						mjonEventVO.setEventMemo("발송 최소 금액("+ paramEachPrice +") 부족 혹은 이벤트 종료일 초과되어 이벤트 종료 시킴");
    						mjonEventVO.setEventRemainCash(eventRemainCash);
    						mjonEventService.updateEventEndStatus(mjonEventVO);
    						eventMberInfo.setEventStatus("E");
    						
    					}
    					
    				}
    				
    			}
    		}
    		
    		//이벤트 진행 회원의 발송 단가 처리해주기
    		if(eventMberInfo != null && eventMberInfo.getEventStatus().equals("Y") && compareEndDate) {
    			
    			shortPrice = Float.parseFloat(eventMberInfo.getEventShortPrice());
    			longPrice = Float.parseFloat(eventMberInfo.getEventLongPrice());
    			picturePrice = Float.parseFloat(eventMberInfo.getEventPicturePrice());
    			picture2Price = Float.parseFloat(eventMberInfo.getEventPicture2Price());
    			picture3Price = Float.parseFloat(eventMberInfo.getEventPicture3Price());
    			
    		}else if(shortPrice < 1 || longPrice < 1 || picturePrice < 1) {//협의 단가가 없는 경우 시스템 단가 적용해 주기
    			
    			shortPrice = (float) sysJoinSetVO.getShortPrice();
    			longPrice = (float) sysJoinSetVO.getLongPrice();
    			picturePrice = (float) sysJoinSetVO.getPicturePrice();
    			picture2Price = (float) sysJoinSetVO.getPicture2Price();
    			picture3Price = (float) sysJoinSetVO.getPicture3Price();
    			
    		}
    		
    		// 토탈금액 "," 리플레이스 처리
    		mjonMsgVO.setTotPrice(mjonMsgVO.getTotPrice().replaceAll(",", ""));
    		
        	float tmpOrgEachPrice = Float.parseFloat(mjonMsgVO.getEachPrice());
        	float tmpOrgTotPrice = Float.parseFloat(mjonMsgVO.getTotPrice());
        	
        	System.out.println("mjonMsgVO.getMsgType2() ::: "+mjonMsgVO.getMsgType());
        	
        	//각 문자 종류별 단가 셋팅해주기
    		float tmpEachPrice = 0;
    		if(mjonMsgVO.getMsgType().equals("4")) {
    			mjonMsgVO.setEachPrice(shortPrice.toString());
    			tmpEachPrice = shortPrice;
    		}else if(mjonMsgVO.getMsgType().equals("6")) {
    			
    			if(mjonMsgVO.getFileName3() != null) {
    				mjonMsgVO.setEachPrice(picture3Price.toString());
    				tmpEachPrice = picture3Price;
    			}else if(mjonMsgVO.getFileName2() != null) {
    				mjonMsgVO.setEachPrice(picture2Price.toString());
    				tmpEachPrice = picture2Price;
    			}else if(mjonMsgVO.getFileName1() != null) {
    				mjonMsgVO.setEachPrice(picturePrice.toString());
    				tmpEachPrice = picturePrice;
    			}else {
    				mjonMsgVO.setEachPrice(longPrice.toString());
    				tmpEachPrice = longPrice;
    			}
    			
    		}
    		
    		//수신자 총 수 * 단가 를 통해 총 결제 금액 계산
    		int tmpTotCallCnt = mjonMsgVO.getCallToList().length;
    		float tmpTotPrice = tmpTotCallCnt * tmpEachPrice;
    		
    		
    		//화면에서 넘어온 파라미터 개별 단가와 컨트롤러에서 계산한 단가를 비교하여 맞지 않으면 컨트롤러 계산 단가 입력
    		if(tmpOrgEachPrice != tmpEachPrice) {
    			mjonMsgVO.setEachPrice(Float.toString(tmpEachPrice));
    			
    			System.out.println("화면 : tmpOrgEachPrice ::: "+tmpOrgEachPrice);
    			System.out.println("컨트롤러 : tmpEachPrice ::: "+tmpEachPrice);    			
    		}else {
    			System.out.println("tmpOrgEachPrice ::: "+tmpOrgEachPrice);
    		}
    		
    		if(tmpOrgTotPrice != tmpTotPrice ) {
    			mjonMsgVO.setTotPrice(Float.toString(tmpTotPrice));
    			
    			System.out.println("화면 : tmpOrgTotPrice ::: "+tmpOrgTotPrice);
    			System.out.println("컨트롤러 : tmpTotPrice ::: "+tmpTotPrice);    			    			
    		}else {
    			System.out.println("tmpOrgTotPrice ::: "+tmpOrgTotPrice);
    		}
    		
    		/*
    		 * 개별단가 및  총결제 캐시 금액 체크 로직 종료
    		 * 
    		 * */
    		
    		
        	// 치환문자가 있는경우
        	String txtReplYn = mjonMsgVO.getTxtReplYn();
        	if(txtReplYn.equals("Y")) {
        		
        		//치환문자 체크 처리
        		int totListCnt = mjonMsgVO.getCallToList().length;
        		String[] nameList = mjonMsgVO.getNameList();	//치환 이름 리스트
        		String[] phone = mjonMsgVO.getCallToList();		//수신자 휴대폰 번호
        		String[] rep1 = mjonMsgVO.getRep1List();		//치환 문자1 리스트
        		String[] rep2 = mjonMsgVO.getRep2List();		//치환 문자2 리스트
        		String[] rep3 = mjonMsgVO.getRep3List();		//치환 문자3 리스트
        		String[] rep4 = mjonMsgVO.getRep4List();		//치환 문자4 리스트
        		
        		//이름, 휴대폰, 치환문자 데이터가 없으면 취소 처리
        		if((nameList.length == 0 || nameList == null) 
        				&& (rep1.length == 0 || rep1 == null)
        				&& (rep2.length == 0 || rep2 == null)
        				&& (rep3.length == 0 || rep3 == null)
        				&& (rep4.length == 0 || rep4 == null)) {
        			
        			modelAndView.addObject("message", "특정문구 일괄변환 치환문자 데이터가 없습니다.");
    				modelAndView.addObject("result", "fail");
    				return modelAndView;
        			
        		}
        		
				// 치환문자 전체 필수체크 Start
				boolean isRepCountOk = true;
				if (mjonMsgVO.getSmsTxt().indexOf("[*이름*]") > -1) {
					if(nameList.length != phone.length) {
						isRepCountOk = false;
					}
    			}
    			if (mjonMsgVO.getSmsTxt().indexOf("[*1*]") > -1) {
					if(rep1.length != phone.length) {
						isRepCountOk = false;
					}
    			}
    			if (mjonMsgVO.getSmsTxt().indexOf("[*2*]") > -1) {
					if(rep2.length != phone.length) {
						isRepCountOk = false;
					}
    			}
    			if (mjonMsgVO.getSmsTxt().indexOf("[*3*]") > -1) {
					if(rep3.length != phone.length) {
						isRepCountOk = false;
					}
    			}
    			if (mjonMsgVO.getSmsTxt().indexOf("[*4*]") > -1) {
					if(rep4.length != phone.length) {
						isRepCountOk = false;
					}
    			}
				
				if (isRepCountOk == false) {
					modelAndView.addObject("message", "특정문구 일괄변환 치환문자 데이터가 없습니다");
					modelAndView.addObject("result", "fail");
					return modelAndView;
				}
				// End
				
        		//---------------------------------------------------------------------------------------------------------------
        		
        		//단문, 장문 분리해서 전달하기 위해서 동일한 VO를 생성해 준다.
        		MjonMsgVO shortMsgVO = new MjonMsgVO();
        		MjonMsgVO longMsgVO = new MjonMsgVO();
        		MjonMsgVO imgMsgVO = new MjonMsgVO();
        		
        		shortMsgVO = mjonMsgVO;
        		longMsgVO = mjonMsgVO;
        		imgMsgVO = mjonMsgVO;
        		
        		int shortMsgCnt = Integer.parseInt(mjonMsgVO.getShortMsgCnt());
        		int longMsgCnt = Integer.parseInt(mjonMsgVO.getLongMsgCnt());
        		int imgMsgCnt = mjonMsgVO.getCallToList().length;
        		
        		int tmpFileCnt = Integer.parseInt(mjonMsgVO.getFileCnt());
        		int tmpPhoMsgCnt = mjonMsgVO.getCallToList().length;
        		
        		/*if(tmpFileCnt > 0) {
        			
        			shortMsgCnt = tmpPhoMsgCnt;
        			longMsgCnt = tmpPhoMsgCnt;
        			
        		}*/
        		
        		String[] shortNameList = new String[shortMsgCnt];	//단문 치환 이름 리스트
        		String[] shortPhone = new String[shortMsgCnt];		//단문 수신자 휴대폰 번호
        		String[] shortRep1 = new String[shortMsgCnt];		//단문 치환 문자1 리스트
        		String[] shortRep2 = new String[shortMsgCnt];		//단문 치환 문자2 리스트
        		String[] shortRep3 = new String[shortMsgCnt];		//단문 치환 문자3 리스트
        		String[] shortRep4 = new String[shortMsgCnt];		//단문 치환 문자4 리스트
        		
        		String[] longNameList = new String[longMsgCnt];		//장문 치환 이름 리스트
        		String[] longPhone = new String[longMsgCnt];		//장문 수신자 휴대폰 번호
        		String[] longRep1 = new String[longMsgCnt];			//장문 치환 문자1 리스트
        		String[] longRep2 = new String[longMsgCnt];			//장문 치환 문자2 리스트
        		String[] longRep3 = new String[longMsgCnt];			//장문 치환 문자3 리스트
        		String[] longRep4 = new String[longMsgCnt];			//장문 치환 문자4 리스트
        		
        		String[] imgNameList = new String[imgMsgCnt];		//이미지 치환 이름 리스트
        		String[] imgPhone = new String[imgMsgCnt];			//이미지 수신자 휴대폰 번호
        		String[] imgRep1 = new String[imgMsgCnt];			//이미지 치환 문자1 리스트
        		String[] imgRep2 = new String[imgMsgCnt];			//이미지 치환 문자2 리스트
        		String[] imgRep3 = new String[imgMsgCnt];			//이미지 치환 문자3 리스트
        		String[] imgRep4 = new String[imgMsgCnt];			//이미지 치환 문자4 리스트
        		
        		int shortCnt = 0;
        		int longCnt = 0;
        		int imgCnt = 0;
        		
        		Map<String, String> returnImgMap = new HashMap<String, String>();
        		Map<String, String> returnShortMap = new HashMap<String, String>();
        		Map<String, String> returnLongMap = new HashMap<String, String>();
        		
        		for(int i=0; i < totListCnt; i ++) {
        			
        			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\\*\\]", "");
        				}
        			}
        			
        			//문자열 바이트 수 구하기(한글 2Byte로 계산)
        			// 한글 3Byte로 하기 위해서는 StandardCharsets.UTF_8 로 변경하면 된다. 
        			int bytes = smsTxt.getBytes(charset).length;
        			
        			//단문문자 리스트 만들기
        			if(bytes < 2000) {
        				
        				if(fileCount > 0) {
        					
        					if(nameList.length > i && !"".equals(nameList[i]) && nameList[i] != null) {
        						imgNameList[imgCnt] = StringUtil.getString(nameList[i].replaceAll("§", ","));	//장문 치환 이름 리스트
        					}else {
        						imgNameList[imgCnt] = " ";
        					}
        					
        					if(phone.length > i && !"".equals(phone[i]) && phone[i] != null) {
        						imgPhone[imgCnt] = StringUtil.getString(phone[i].replaceAll("§", ","));		//장문 수신자 휴대폰 번호
        					}
        					
        					if(rep1.length > i && !"".equals(rep1[i]) && rep1[i] != null) {
        						imgRep1[imgCnt] = StringUtil.getString(rep1[i].replaceAll("§", ","));		//장문 치환 문자1 리스트
        					}else {
        						imgRep1[imgCnt] = " ";
        					}
        					
        					if(rep2.length > i && !"".equals(rep2[i]) && rep2[i] != null) {
        						imgRep2[imgCnt] = StringUtil.getString(rep2[i].replaceAll("§", ","));		//장문 치환 문자2 리스트
        					}else {
        						imgRep2[imgCnt] = " ";
        					}
        					
        					if(rep3.length > i && !"".equals(rep3[i]) && rep3[i] != null) {
        						imgRep3[imgCnt] = StringUtil.getString(rep3[i].replaceAll("§", ","));		//장문 치환 문자3 리스트
        					}else {
        						imgRep3[imgCnt] = " ";
        					}
        					
        					if(rep4.length > i && !"".equals(rep4[i]) && rep4[i] != null) {
        						imgRep4[imgCnt] = StringUtil.getString(rep4[i].replaceAll("§", ","));		//장문 치환 문자4 리스트
        					}else {
        						imgRep4[imgCnt] = " ";
        					}
                    		
                    		imgCnt++;
                    		
        				}else if(bytes > 90) {//장문문자 리스트 만들기
            				//shortMsgListVO.add(mjonMsgVO.get)
        					
        					/**
                			 * 
                			 * 치환 리스트 중 데이터가 없는 경우 데이터 밀림방지를 위하여 공백 하나를 추가해줌
                			 * 공백처리를 안하는 경우 데이터가 밀려서 치환되는 오류가 있어서 처리해줌
                			 * 
                			 * */
        					
        					if(nameList.length > i && !"".equals(nameList[i]) && nameList[i] != null) {
        						longNameList[longCnt] = StringUtil.getString(nameList[i].replaceAll("§", ","));	//장문 치환 이름 리스트
        					}else {
        						longNameList[longCnt] = " ";
        					}
        					
        					if(phone.length > i && !"".equals(phone[i]) && phone[i] != null) {
        						longPhone[longCnt] = StringUtil.getString(phone[i].replaceAll("§", ","));		//장문 수신자 휴대폰 번호
        					}
        					
        					if(rep1.length > i && !"".equals(rep1[i]) && rep1[i] != null) {
        						longRep1[longCnt] = StringUtil.getString(rep1[i].replaceAll("§", ","));		//장문 치환 문자1 리스트
        					}else {
        						longRep1[longCnt] = " ";
        					}
        					
        					if(rep2.length > i && !"".equals(rep2[i]) && rep2[i] != null) {
        						longRep2[longCnt] = StringUtil.getString(rep2[i].replaceAll("§", ","));		//장문 치환 문자2 리스트
        					}else {
        						longRep2[longCnt] = " ";
        					}
        					
        					if(rep3.length > i && !"".equals(rep3[i]) && rep3[i] != null) {
        						longRep3[longCnt] = StringUtil.getString(rep3[i].replaceAll("§", ","));		//장문 치환 문자3 리스트
        					}else {
        						longRep3[longCnt] = " ";
        					}
        					
        					if(rep4.length > i && !"".equals(rep4[i]) && rep4[i] != null) {
        						longRep4[longCnt] = StringUtil.getString(rep4[i].replaceAll("§", ","));		//장문 치환 문자4 리스트
        					}else {
        						longRep4[longCnt] = " ";
        					}
                    		
                    		longCnt++;
                    		
            			} else {//단문문자 리스트 만들기
            				
            				/**
                			 * 
                			 * 치환 리스트 중 데이터가 없는 경우 데이터 밀림방지를 위하여 공백 하나를 추가해줌
                			 * 공백처리를 안하는 경우 데이터가 밀려서 치환되는 오류가 있어서 처리해줌
                			 * 
                			 * */
            				
            				if(nameList.length > i && !"".equals(nameList[i]) && nameList[i] != null) {
            					shortNameList[shortCnt] = StringUtil.getString(nameList[i].replaceAll("§", ","));	//단문 치환 이름 리스트
            				}else {
            					shortNameList[shortCnt] = " ";
            				}
            				
            				if(phone.length > i && !"".equals(phone[i]) && phone[i] != null) {
            					shortPhone[shortCnt] = StringUtil.getString(phone[i].replaceAll("§", ","));		//단문 수신자 휴대폰 번호
            				}
            				
            				if(rep1.length > i && !"".equals(rep1[i]) && rep1[i] != null) {
            					shortRep1[shortCnt] = StringUtil.getString(rep1[i].replaceAll("§", ","));		//단문 치환 문자1 리스트
            				}else {
            					shortRep1[shortCnt] = " ";
            				}
            				
            				if(rep2.length > i && !"".equals(rep2[i]) && rep2[i] != null) {
            					shortRep2[shortCnt] = StringUtil.getString(rep2[i].replaceAll("§", ","));		//단문 치환 문자2 리스트
            				}else {
            					shortRep2[shortCnt] = " ";
            				}
                    		
            				if(rep3.length > i && !"".equals(rep3[i]) && rep3[i] != null) {
                    			shortRep3[shortCnt] = StringUtil.getString(rep3[i].replaceAll("§", ","));		//단문 치환 문자3 리스트
                    		}else {
                    			shortRep3[shortCnt] = " ";
                    		}
                    		
            				if(rep4.length > i && !"".equals(rep4[i]) && rep4[i] != null) {
                    			shortRep4[shortCnt] = StringUtil.getString(rep4[i].replaceAll("§", ","));		//단문 치환 문자4 리스트
                    		}else {
                    			shortRep4[shortCnt] = " ";
                    		}
                    		
                    		shortCnt++;
            				
            			}
        				
        			}else {
        				
        				modelAndView.addObject("message", "문자 치환 후 전송 문자 길이를 초과하였습니다.");
        				modelAndView.addObject("result", "fail");
        				modelAndView.addObject("resultSts", "0");
        				modelAndView.addObject("resultBlockSts", "0");
        				
        				return modelAndView; 
        				
        			}
        			
        		}
        		
        		
        		if(imgCnt > 0) {//그림문자 전송 이름, 전화번호, 변환문자 입력해주기
        			
        			imgMsgVO.setNameList(imgNameList);
        			imgMsgVO.setCallToList(imgPhone);
        			imgMsgVO.setRep1List(imgRep1);
        			imgMsgVO.setRep2List(imgRep2);
        			imgMsgVO.setRep3List(imgRep3);
        			imgMsgVO.setRep4List(imgRep4);
        			
        			//개별단가 계산하기
        			String eachPrice = imgMsgVO.getpPrice();
        			
        			//api 서버에서 pPrice 값이 없는 경우가 있어서 오류 방지를위해서 추가
        			if(eachPrice == null) {
        				
        				eachPrice = imgMsgVO.getEachPrice();
        				
        			}
        			
        			/**
        			 * 그림문자에 치환 내용이 포함되어 있는 경우 단가 계산하기.
        			 * 그림문자의 경우 이로직을 타지 않지만 혹시 몰라서 추가해놓음
        			 * */
        			
        			if(fileCount > 2) {//그림 이미지가 3개
            			
            			eachPrice = mjonMsgVO.getP3Price();
            			
            		}else if(fileCount > 1) {//그림 이미지가 2개
            			
            			eachPrice = mjonMsgVO.getP2Price();
            			
            		}else if(fileCount == 1) {//그림 이미지가 1개
            			eachPrice = mjonMsgVO.getpPrice();
            			
            		}
        			
        			imgMsgVO.setEachPrice(eachPrice);
        			
        			//문자 종류 선택 
        			imgMsgVO.setMsgType("6");
        			
        			//총금액 계산하기
        			Float sTotPrice = Float.parseFloat(imgMsgVO.getEachPrice()) * imgCnt;
        			imgMsgVO.setTotPrice(sTotPrice.toString());
        			
        			//그림문자 발송 처리
        			returnImgMap = fncSendMsgRtnMap(imgMsgVO);
        			
        		}
        		
        		if(shortCnt > 0) {//단문문자 전송 이름, 전화번호, 변환문자 입력해주기
        			
        			shortMsgVO.setNameList(shortNameList);
        			shortMsgVO.setCallToList(shortPhone);
        			shortMsgVO.setRep1List(shortRep1);
        			shortMsgVO.setRep2List(shortRep2);
        			shortMsgVO.setRep3List(shortRep3);
        			shortMsgVO.setRep4List(shortRep4);
        			
        			//개별단가 계산하기
        			String eachPrice = shortMsgVO.getsPrice();
        			
        			//api 서버에서 sPrice 값이 없는 경우가 있어서 오류 방지를위해서 추가
        			if(eachPrice == null) {
        				
        				eachPrice = shortMsgVO.getEachPrice();
        				
        			}
        			
        			/**
        			 * 그림문자에 치환 내용이 포함되어 있는 경우 단가 계산하기.
        			 * 그림문자의 경우 이로직을 타지 않지만 혹시 몰라서 추가해놓음
        			 * */
        			
        			if(fileCount > 2) {//그림 이미지가 3개
            			
            			eachPrice = mjonMsgVO.getP3Price();
            			
            		}else if(fileCount > 1) {//그림 이미지가 2개
            			
            			eachPrice = mjonMsgVO.getP2Price();
            			
            		}else if(fileCount == 1) {//그림 이미지가 1개
            			eachPrice = mjonMsgVO.getpPrice();
            			
            		}
        			
        			shortMsgVO.setEachPrice(eachPrice);
        			
        			//문자 종류 선택 
        			if(fileCount > 0) {//그림문자인 경우 문자타임 지정
        				shortMsgVO.setMsgType("6");
        			}else {
        				shortMsgVO.setMsgType("4");
        			}
        			
        			//총금액 계산하기
        			Float sTotPrice = Float.parseFloat(shortMsgVO.getEachPrice()) * shortCnt;
        			shortMsgVO.setTotPrice(sTotPrice.toString());
        			
        			//단문문자 발송 처리
        			returnShortMap = fncSendMsgRtnMap(shortMsgVO);
        			
        		}
        		
        		if(longCnt > 0) {//장문문자 전송 이름, 전화번호, 변환문자 입력해주기
        			
        			longMsgVO.setNameList(longNameList);
        			longMsgVO.setCallToList(longPhone);
        			longMsgVO.setRep1List(longRep1);
        			longMsgVO.setRep2List(longRep2);
        			longMsgVO.setRep3List(longRep3);
        			longMsgVO.setRep4List(longRep4);
        			
        			/**
        			 * 그림문자에 치환 내용이 포함되어 있는 경우 단가 계산하기.
        			 * 그림문자의 경우 이로직을 타지 않지만 혹시 몰라서 추가해놓음
        			 * */
        			
        			String eachPrice = longMsgVO.getmPrice();
        			
        			//api 서버에서 mPrice 값이 없는 경우가 있어서 오류 방지를위해서 추가
        			if(eachPrice == null) {
        				
        				eachPrice = longMsgVO.getEachPrice();
        				
        			}
        			
        			if(fileCount > 2) {//그림 이미지가 3개
            			
            			eachPrice = mjonMsgVO.getP3Price();
            			
            		}else if(fileCount > 1) {//그림 이미지가 2개
            			
            			eachPrice = mjonMsgVO.getP2Price();
            			
            		}else if(fileCount == 1) {//그림 이미지가 1개
            			eachPrice = mjonMsgVO.getpPrice();
            			
            		}
        			
        			longMsgVO.setEachPrice(eachPrice);
        			
        			//문자 종류 선택
        			longMsgVO.setMsgType("6");
        			
        			//총금액 계산하기
        			Float mTotPrice = Float.parseFloat(longMsgVO.getEachPrice()) * longCnt;
        			longMsgVO.setTotPrice(mTotPrice.toString());
        			
        			//장문문자 발송
        			returnLongMap = fncSendMsgRtnMap(longMsgVO);
        		}
        		
        		//일괄변환에 의한 단문, 장문 별개로 전송을 했기 때문에 각각 전송 결과 건수를 합쳐준 후 결과를  modelAndView로 리턴해준다.
        		String returnMessage = "";
        		String returnStatus = "";
        		
        		//그림 결과 내용
        		if(!returnImgMap.isEmpty()) {
        			
        			if(!returnImgMap.get("result").contains("fail")) {
            			
        				//발송건수 계산
        				int sendCnt = Integer.parseInt(resultSts) + Integer.parseInt(returnImgMap.get("resultSts"));
            			resultSts = Integer.toString(sendCnt);
            			
            			//수신거부 건수 계산
            			int sendBlockCnt = Integer.parseInt(resultBlockSts) + Integer.parseInt(returnImgMap.get("resultBlockSts"));
            			resultBlockSts = Integer.toString(sendBlockCnt);
            			
            			returnMessage = returnImgMap.get("message");
            			returnStatus = returnImgMap.get("result");
            			
        			}else {
            			returnMessage = returnImgMap.get("message");
            			returnStatus = returnImgMap.get("result");
            			
            			modelAndView.addObject("message", returnMessage);
        				modelAndView.addObject("result", returnStatus);
        				modelAndView.addObject("resultSts", "0");
        				modelAndView.addObject("resultBlockSts", "0");
        				
        				return modelAndView;
            		}
        			
        		}
        		
        		//장문발송 결과 내용
        		if(!returnLongMap.isEmpty()) {
        			
        			if(!returnLongMap.get("result").contains("fail")) {
            			
        				//발송건수 계산
        				int sendCnt = Integer.parseInt(resultSts) + Integer.parseInt(returnLongMap.get("resultSts"));
            			resultSts = Integer.toString(sendCnt);
            			
            			//수신거부 건수 계산
            			int sendBlockCnt = Integer.parseInt(resultBlockSts) + Integer.parseInt(returnLongMap.get("resultBlockSts"));
            			resultBlockSts = Integer.toString(sendBlockCnt);
            			
            			returnMessage = returnLongMap.get("message");
            			returnStatus = returnLongMap.get("result");
            			
        			}else {
            			returnMessage = returnLongMap.get("message");
            			returnStatus = returnLongMap.get("result");
            			
            			modelAndView.addObject("message", returnMessage);
        				modelAndView.addObject("result", returnStatus);
        				modelAndView.addObject("resultSts", "0");
        				modelAndView.addObject("resultBlockSts", "0");
        				
        				return modelAndView;
            		}
        			
        		}
        		
        		//단문발송 결과 내용
        		if(!returnShortMap.isEmpty()) {
        			
        			if(!returnShortMap.get("result").contains("fail")) {
            			
            			//발송건수 계산
        				int sendCnt = Integer.parseInt(resultSts) + Integer.parseInt(returnShortMap.get("resultSts"));
            			resultSts = Integer.toString(sendCnt);
            			
            			//수신거부 건수 계산
            			int sendBlockCnt = Integer.parseInt(resultBlockSts) + Integer.parseInt(returnShortMap.get("resultBlockSts"));
            			resultBlockSts = Integer.toString(sendBlockCnt);
            			
            			returnMessage = returnShortMap.get("message");
            			returnStatus = returnShortMap.get("result");
            			
            		}else {
            			returnMessage = returnShortMap.get("message");
            			returnStatus = returnShortMap.get("result");
            			
            			modelAndView.addObject("message", returnMessage);
        				modelAndView.addObject("result", returnStatus);
        				modelAndView.addObject("resultSts", "0");
        				modelAndView.addObject("resultBlockSts", "0");
        				
        				return modelAndView;
            		}
        			
        		}

        		modelAndView.addObject("msgType", mjonMsgVO.getMsgType());
        		modelAndView.addObject("msgGroupId", mjonMsgVO.getMsgGroupId());
        		modelAndView.addObject("message", returnMessage);
				modelAndView.addObject("result", returnStatus);
				modelAndView.addObject("resultSts", resultSts);
				modelAndView.addObject("resultBlockSts", resultBlockSts);
        		
        	}else {
        		
        		//문자발송 함수 호출 - 일괄변환이 없거나, 그림문자 일괄변환의 경우 한번에 전송 처리
        		modelAndView = fncSendMsg(mjonMsgVO);
        		
        	}
        	
    	}catch(Exception e) {
    		
			System.out.println("=========================================================================");
			System.out.println("+++++++++++++++++++++++++++++ 일반문자 ==> 기타 시스템 오류 !!! : " + e.getMessage());
			System.out.println("=========================================================================");
			
    		//logger.error(e.getMessage(), e);
    		e.printStackTrace();
    		modelAndView.addObject("result", "fail");
    		modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
    		return modelAndView;

    	}
		
		
		/**
		 * 사용자가 보낸 문자를 문자온 법인폰으로도 하나 전송하는 기능 시작
		 * 
		 * */
		
		try {
			
				
			String adminSmsNoticeYn = "Y";
			String smishingYn = "N";
			String spamStatus = mjonMsgVO.getSpamStatus(); //스미싱 의심으로 체크된 문자 정보
			
			UserManageVO userManageVO = new UserManageVO();
			userManageVO.setMberId(userId);
			
			
			if(!userId.equals("")) {
				userManageVO = userManageService.selectAdminSmsNoticeYn(userManageVO);
				adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); 
				smishingYn = userManageVO.getSmishingYn();
			}

			//법인폰 알림 온 이거나 스미싱의심 문자인 경우 법인폰으로 발송
			if(adminSmsNoticeYn.equals("Y") || spamStatus.equals("Y") || smishingYn.equals("Y")) {
				
				if(spamStatus.equals("Y")) {
					
					mjonMsgVO.setDelayYn("Y");
					
				}else if(smishingYn.equals("Y")) {
					
					mjonMsgVO.setSmishingYn("Y");
				}
				
				
				// 법인폰 알람여부 체크
				JoinSettingVO joinSettingVO = new JoinSettingVO();
				joinSettingVO = egovSiteManagerService.selectAdminNotiDetail();
				// SMS 체크
				if (joinSettingVO != null && joinSettingVO.getSmsNoti().equals("Y")) {
					getAdminPhoneSendMsgData(mjonMsgVO);	
				}				
				
				// SLACK 체크
				if (joinSettingVO != null && joinSettingVO.getSlackNoti().equals("Y")) {
					//Slack으로 메세지 전송 처리
					MjonCommon comm = new MjonCommon();
					comm.getAdminSandSlack(mjonMsgVO);
				}
			}
			

    	} catch (Exception e) {
			throw new Exception("++++++++++++++++++++++ getAdminPhoneSendMsgData Error !!! " + e);
		}
		
 		return modelAndView;
	}
	
	/**
	 * 관리자로 문자 발송해주기
	 * 사용자가 보낸 문자를 문자온 법인폰으로 발송해주는 기능 함수.
	 * 일반문자 와 대량 문자 모두 적용하고 있음
	 * 2022.09.19 우영두 추가
	 * 
	 * */
	public boolean getAdminPhoneSendMsgData(MjonMsgVO mjonMsgVO) throws Exception{
		
		try {
			
			mjonMsgVO.setUserId("system");//시스템 발송 문자로 처리
			
			//전송사 선택
			String msgType = mjonMsgVO.getMsgType();
			int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt());//그림 이미지 갯수
			
			
			//예약문자를 발송하는 경우 문자 내용 앞에 "[예약]" 표시되도록 처리 - 법인폰으로 발송되는 문자내용 수정함.20221123 추가
			//스팸/스미싱 대상자 문자를 발송하는 경우 문자 내용 앞에 "[발송지연문자]" 표시되도록 처리 - 법인폰으로 발송되는 문자내용 수정함.20221202 추가
			String reserveYn = mjonMsgVO.getReserveYn();
			String delayYn = mjonMsgVO.getDelayYn();
			String smishingYn = mjonMsgVO.getSmishingYn();
			
			String smsTxt = mjonMsgVO.getSmsTxt();
			String transSmsTxt = smsTxt;
			
			if(reserveYn.equals("Y")) {
				
				if(smishingYn.equals("Y") || delayYn.equals("Y")) {
					
					transSmsTxt = "[스미싱의심][예약]" + smsTxt;
					
				}else {
					transSmsTxt = "[예약]" + smsTxt;
				}

			}else if(delayYn.equals("Y")) {
				
				transSmsTxt = "[스미싱의심]" + smsTxt;
				
			}
			
			//[예약], [발송지연문자] 문구 추가시 문자열 길이 및 문자 종류 재계산 하기
			String charset = "euc-kr";
			int bytes = transSmsTxt.getBytes(charset).length;	//발송 문자 길이
			
			if(bytes > 2000) {//문자열 길이가 2000을 넘어가면 [예약], [발송지연문자] 문구를 제외한 원래 문구를 넣어준다. 안그러면 문자전송이 실패하게 됨.
				
				mjonMsgVO.setSmsTxt(smsTxt);
				
			}else {
				
				//[예약], [발송지연문자] 문구를 추가한 내용으로 메세지 내용을 셋팅해 준다.
				mjonMsgVO.setSmsTxt(transSmsTxt);
				if(bytes > 90) {//장문일 경우 문자타입을 변경해준다.
					
					msgType = "6";
					mjonMsgVO.setMsgType(msgType);
					
				}
				
			}
			
			// 문자타입 구분
			if (msgType.equals("4")) {
				mjonMsgVO.setMsgDiv("S");	// 단문	
			}
			else if (msgType.equals("6")) {
				if (fileCount > 0) {
					mjonMsgVO.setMsgDiv("P");	// 그림
					mjonMsgVO.setNeoType("4");
				}
				else {
					mjonMsgVO.setMsgDiv("L");	// 장문
				}
			}
			
    		// 문자타입별 대표전송사 정보
			MjonMsgVO mjonMsgVO2 = new MjonMsgVO();
			mjonMsgVO2 = mjonMsgService.selectRepMsgAgetnInfo(mjonMsgVO);
			// 전송사 구분 코드 - 01 : 아이하트, 02 : 현대 퓨쳐넷, 03 : 아이엠오, 04 : 다우기술
        	mjonMsgVO.setAgentCode(mjonMsgVO2.getAgentCode()); //전송사 선택			
        	// 전송금액
			mjonMsgVO.setTotPrice(mjonMsgVO2.getAgentPrice().toString());	//총금액
			mjonMsgVO.setEachPrice(mjonMsgVO2.getAgentPrice().toString());	//한건 금액
			
			
			//수신번호가 배열로 되어있어서 배열에 담아준다.
			String[] phone = new String[1];
			String callTo = "01084329333";
			phone[0] = callTo;
			mjonMsgVO.setCallToList(phone);//수신번호 리스트
			
			//시스템 로그용 수신 정보
			mjonMsgVO.setCallTo("help@iten.co.kr");
			
			//현재 고객의 보유 캐시가 문자 발송이 가능한 금액인지 체크
	    	//String userMoney = "0.0";
	    	String userPoint = "0.0";
	    	mjonMsgVO.setBefPoint(userPoint); //현재 보유 포인트 정보 저장
	    	mjonMsgVO.setBefCash("0.0");		//관리자가 발송하는 것이라서 0원으로 입력
	    	mjonMsgVO.setMsgGroupCnt("1");
	    	
	    	//문자종류 관리자가 발송하는 것은 msgKind : S 로 셋팅
			mjonMsgVO.setMsgKind("S");
			
			Date now = new Date();
			SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			mjonMsgVO.setReqDate(sdFormat.format(now));
			
			//문자 발송 처리
			mjonMsgDataService.insertAdmToMberMsgDataInfo(mjonMsgVO); 
			
		} catch (Exception e) {
			throw new Exception("+++++++++++++++++++++++++++++ getAdminPhoneSendMsgData Function Error !!!" + e);
		}
		
		return true;
	}
	
	/**
	 * 문자발송시 치환문자가 있거나 단문, 장문 일경우 타는 로직
	 * param : MjonMsgVO
	 * return : ModelAndView
	 * 
	 * */
	public Map<String, String> fncSendMsgRtnMap(MjonMsgVO mjonMsgVO) {
		Map<String, String> returnMap = new HashMap<String, String>();
		
		//String resultSts = "0";			//발송결과 건수
		//String resultBlockSts = "0";	//수신거부 등록번호로 발송을 안한 건수
		
		int resultSts = 0;			//발송결과 건수
		int resultBlockSts = 0;	//수신거부 등록번호로 발송을 안한 건수
		
		try {
		
			//현재 고객의 보유 캐시가 문자 발송이 가능한 금액인지 체크
	    	String userMoney = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
	    	String userPoint = mjonMsgDataService.selectBeforePointData(mjonMsgVO);
	    	mjonMsgVO.setBefPoint(userPoint); //현재 보유 포인트 정보 저장
	    	String totPrice = mjonMsgVO.getTotPrice();
	    	
	    	BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN);
	    	BigDecimal totMsgPrice = new BigDecimal(totPrice).setScale(2, RoundingMode.HALF_EVEN);
	    	
	    	
	    	//현재 보유 금액이 발송 문자 총 금액보다 클 경우만 문자 발송
	    	//BigDecimal 비교 연산
	    	// befCash(현재 보유금액) 값이 totMsgPrice(문자전송 금액) 보다 많으면 문자 전송
	    	if(befCash.compareTo(totMsgPrice) != -1) { // -1 : befCash < totMsgPrice, 0 : befCash = totMsgPrice, 1 : befCash > totMsgPrice,
	    		
	    		//문자 발송 처리
	    		//MjonMsgReturnVO returnVO = new MjonMsgReturnVO();
	    		//현재 보유 캐쉬금액 셋팅
	    		mjonMsgVO.setBefCash(befCash.toString());
	    		
	    		//문자 전송 그룹아이디 생성
	    		mjonMsgVO.setMsgGroupId(idgenMjonMsgGroupId.getNextStringId());
	    		
	    		String[] tempPhoneList = new String[200];				//임시 수신번호 리스트 저장용 배열
	    		String[] tempNameList = new String[200];				//임시 이름 리스트 저장용 배열
	    		String[] tempRep1List = new String[200];				//임시 치환문자1 리스트 저장용 배열
	    		String[] tempRep2List = new String[200];				//임시 치환문자1 리스트 저장용 배열
	    		String[] tempRep3List = new String[200];				//임시 치환문자1 리스트 저장용 배열
	    		String[] tempRep4List = new String[200];				//임시 치환문자1 리스트 저장용 배열
	    		
	    		String[] phoneList = mjonMsgVO.getCallToList();
	    		String[] nameList = mjonMsgVO.getNameList();
	    		String[] rep1List = mjonMsgVO.getRep1List();
	    		String[] rep2List = mjonMsgVO.getRep2List();
	    		String[] rep3List = mjonMsgVO.getRep3List();
	    		String[] rep4List = mjonMsgVO.getRep4List();
	    		
	    		
	    		int callToListCnt = mjonMsgVO.getCallToList().length;
	    		mjonMsgVO.setTotalCallCnt(callToListCnt);
	    		
	    		/** 예약 문자인 경우 시간 및 분할 시간 셋팅 해주기 */
	    		//분할문자 시간에 간격시간 더해주기
	        	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;		//분할 카운트
	    		
	    		
	    		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()); //분할 발송 갯수
	    			
	    		}
	    		
	    		//분할 예약 시간 저장 리스트 생성
	    		List<String> dividDayList = new ArrayList<String>();
	    		
	    		//서비스 단으로 특정 문자 건수 이상으로 한번에 보내지 않기 위해서 처리함
	    		if(callToListCnt > 200) {
	    			
	    			int sendCnt = 0;
	    			for(int i=0; i< callToListCnt; i++) {
	    				
	    				//분할 발송을 체크 한 경우
						if(mjonMsgVO.getDivideChk() != null) {
							
							if(count > divideCnt) {
		            			
		            			count = 1;
		            			
		            			//분할 시간 간격을 증가시켜 준다.
		            			cal.add(Calendar.MINUTE, turmMin);
		            			dividDay = transFormat.format(cal.getTime());
		                    	
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		                		count++;
		                		
		            		}else {
		            			
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		            			count++;
		            			
		            		}
							
						}
	    				
	    				if((i < callToListCnt -1) && sendCnt == 199) {
	    					
	    					//sendCnt 4번째 값을 추가해준다.
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					tempNameList[sendCnt] = nameList[i];
	    					tempRep1List[sendCnt] = rep1List[i];
	    					tempRep2List[sendCnt] = rep2List[i];
	    					tempRep3List[sendCnt] = rep3List[i];
	    					tempRep4List[sendCnt] = rep4List[i];
	    					
	    					List<String> arrPhoneList = new ArrayList<String>();
	    					List<String> arrNameList = new ArrayList<String>();
	    					List<String> arrRep1List = new ArrayList<String>();
	    					List<String> arrRep2List = new ArrayList<String>();
	    					List<String> arrRep3List = new ArrayList<String>();
	    					List<String> arrRep4List = new ArrayList<String>();
	    					
	    					for(String temp : tempPhoneList) {
	    						
	    						if(temp != null) {
	    							
	    							arrPhoneList.add(temp);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpName : tempNameList) {
	    						
	    						if(tmpName != null) {
	    							
	    							arrNameList.add(tmpName);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep1 : tempRep1List) {
	    						
	    						if(tmpRep1 != null) {
	    							
	    							arrRep1List.add(tmpRep1);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep2 : tempRep2List) {
	    						
	    						if(tmpRep2 != null) {
	    							
	    							arrRep2List.add(tmpRep2);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep3 : tempRep3List) {
	    						
	    						if(tmpRep3 != null) {
	    							
	    							arrRep3List.add(tmpRep3);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep4 : tempRep4List) {
	    						
	    						if(tmpRep4 != null) {
	    							
	    							arrRep4List.add(tmpRep4);
	    							
	    						}
	    						
	    					}
	    					
	    					String[] sendPhoneList = new String[arrPhoneList.size()];
	    					String[] sendNameList = new String[arrNameList.size()];
	    					String[] sendRep1List = new String[arrRep1List.size()];
	    					String[] sendRep2List = new String[arrRep2List.size()];
	    					String[] sendRep3List = new String[arrRep3List.size()];
	    					String[] sendRep4List = new String[arrRep4List.size()];
	    					
	    					for(int j=0; j< arrPhoneList.size(); j++) {
	    						
	    						sendPhoneList[j] = arrPhoneList.get(j);
	    						
	    					}
	    					
	    					for(int k=0; k< arrNameList.size(); k++) {
	    						
	    						sendNameList[k] = arrNameList.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep1List.size(); k++) {
	    						
	    						sendRep1List[k] = arrRep1List.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep2List.size(); k++) {
	    						
	    						sendRep2List[k] = arrRep2List.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep3List.size(); k++) {
	    						
	    						sendRep3List[k] = arrRep3List.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep4List.size(); k++) {
	    						
	    						sendRep4List[k] = arrRep4List.get(k);
	    						
	    					}
	    					
	    					mjonMsgVO.setCallToList(sendPhoneList);
	    					mjonMsgVO.setNameList(sendNameList);
	    					mjonMsgVO.setRep1List(sendRep1List);
	    					mjonMsgVO.setRep2List(sendRep2List);
	    					mjonMsgVO.setRep3List(sendRep3List);
	    					mjonMsgVO.setRep4List(sendRep4List);
	    					sendCnt = 0;
	    					
	    					mjonMsgVO.setDividDay(dividDayList);
	    					MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    					mjonMsgVO.setAgentCode(returnVO.getAgentCode());
	    		    		resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
	    		    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
	    		    		
	    		    		//발송 처리후 배열 초기화
	    		    		Arrays.fill(tempPhoneList, null);
	    		    		dividDayList.clear();
	    		    		
	    					
	    				}else if((i == callToListCnt -1) && sendCnt < 200){//200개의 마지막일 경우 처리
	    					
	    					//마지막 리스트의 수신번호를 추가해 준다.
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					tempNameList[sendCnt] = nameList[i];
	    					tempRep1List[sendCnt] = rep1List[i];
	    					tempRep2List[sendCnt] = rep2List[i];
	    					tempRep3List[sendCnt] = rep3List[i];
	    					tempRep4List[sendCnt] = rep4List[i];
	    					
	    					List<String> arrPhoneList2 = new ArrayList<String>();
	    					List<String> arrNameList2 = new ArrayList<String>();
	    					List<String> arrRep1List2 = new ArrayList<String>();
	    					List<String> arrRep2List2 = new ArrayList<String>();
	    					List<String> arrRep3List2 = new ArrayList<String>();
	    					List<String> arrRep4List2 = new ArrayList<String>();
	    					
	    					for(String temp : tempPhoneList) {
	    						
	    						if(temp != null) {
	    							
	    							arrPhoneList2.add(temp);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpName : tempNameList) {
	    						
	    						if(tmpName != null) {
	    							
	    							arrNameList2.add(tmpName);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep1 : tempRep1List) {
	    						
	    						if(tmpRep1 != null) {
	    							
	    							arrRep1List2.add(tmpRep1);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep2 : tempRep2List) {
	    						
	    						if(tmpRep2 != null) {
	    							
	    							arrRep2List2.add(tmpRep2);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep3 : tempRep3List) {
	    						
	    						if(tmpRep3 != null) {
	    							
	    							arrRep3List2.add(tmpRep3);
	    							
	    						}
	    						
	    					}
	    					
	    					for(String tmpRep4 : tempRep4List) {
	    						
	    						if(tmpRep4 != null) {
	    							
	    							arrRep4List2.add(tmpRep4);
	    							
	    						}
	    						
	    					}
	    					
	    					String[] sendPhoneList2 = new String[arrPhoneList2.size()];
	    					String[] sendNameList2 = new String[arrNameList2.size()];
	    					String[] sendRep1List2 = new String[arrRep1List2.size()];
	    					String[] sendRep2List2 = new String[arrRep2List2.size()];
	    					String[] sendRep3List2 = new String[arrRep3List2.size()];
	    					String[] sendRep4List2 = new String[arrRep4List2.size()];
	    					
	    					for(int j=0; j< arrPhoneList2.size(); j++) {
	    						
	    						sendPhoneList2[j] = arrPhoneList2.get(j);
	    						
	    					}
	    					
	    					for(int j=0; j< arrNameList2.size(); j++) {
	    						
	    						sendNameList2[j] = arrNameList2.get(j);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep1List2.size(); k++) {
	    						
	    						sendRep1List2[k] = arrRep1List2.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep2List2.size(); k++) {
	    						
	    						sendRep2List2[k] = arrRep2List2.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep3List2.size(); k++) {
	    						
	    						sendRep3List2[k] = arrRep3List2.get(k);
	    						
	    					}
	    					
	    					for(int k=0; k< arrRep4List2.size(); k++) {
	    						
	    						sendRep4List2[k] = arrRep4List2.get(k);
	    						
	    					}
	    					
	    					mjonMsgVO.setCallToList(sendPhoneList2);
	    					mjonMsgVO.setNameList(sendNameList2);
	    					mjonMsgVO.setRep1List(sendRep1List2);
	    					mjonMsgVO.setRep2List(sendRep2List2);
	    					mjonMsgVO.setRep3List(sendRep3List2);
	    					mjonMsgVO.setRep4List(sendRep4List2);
	    					sendCnt = 0;
	    					
	    					mjonMsgVO.setDividDay(dividDayList);
	    					MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    					mjonMsgVO.setAgentCode(returnVO.getAgentCode());
	    		    		resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
	    		    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
	    		    		
	    				}else {//198개가 될때까지 배열에 데이터를 쌓는다
	    					
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					
	    					if(nameList.length > 0) {//이름 치환문자가 있는 경우
	    						tempNameList[sendCnt] = nameList[i];
	    					}
	    					
	    					if(rep1List.length > 0) {//치환1 문자가 있는 경우
	    						tempRep1List[sendCnt] = rep1List[i];
	    					}
	    					
	    					if(rep2List.length > 0) {//치환2 문자가 있는 경우
	    						tempRep2List[sendCnt] = rep2List[i];
	    					}
	    					
	    					if(rep3List.length > 0) {//치환3 문자가 있는 경우
	    						tempRep3List[sendCnt] = rep3List[i];
	    					}
	    					
	    					if(rep4List.length > 0) {//치환4 문자가 있는 경우
	    						tempRep4List[sendCnt] = rep4List[i];
	    					}
	    					
	    					sendCnt++;
	    					
	    				}
	    				
	    			}
	    			
	    		}else {
	    				
    				//분할 발송을 체크 한 경우
					if(mjonMsgVO.getDivideChk() != null) {
						for(int i=0; i< callToListCnt; i++) {
							if(count > divideCnt) {
		            			
		            			count = 1;
		            			
		            			//분할 시간 간격을 증가시켜 준다.
		            			cal.add(Calendar.MINUTE, turmMin);
		            			dividDay = transFormat.format(cal.getTime());
		                    	
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		                		count++;
		                		
		            		}else {
		            			
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		            			count++;
		            			
		            		}
						
						}
	    				
	    			}
	    			
					mjonMsgVO.setDividDay(dividDayList);
	    			MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    			mjonMsgVO.setAgentCode(returnVO.getAgentCode());
		    		resultSts = Integer.parseInt(returnVO.getSendMsgCnt());
		    		resultBlockSts = Integer.parseInt(returnVO.getSendMsgBlockCnt());
	    			
	    		}
	    		
	    		System.out.println("=========================================================================");
	    		System.out.println("+++++++++++++++++++++++++++++++++++++++++++ resultSts ::: " + resultSts); 
	    		System.out.println("=========================================================================");
	    		
	    		try {
	    			
	    			//문자 발송 캐시 차감 해주기 - serviceImple에서 처리하도록 변경 함
		    		/*MjonPayVO mjonPayVO = new MjonPayVO(); 
		    		
		    		if(resultSts > 0 && resultBlockSts > 0) {
		    			
		    			Float blockPrice = Float.parseFloat(mjonMsgVO.getEachPrice()) * resultBlockSts;
		    			Float resultTotPrice = Float.parseFloat(mjonMsgVO.getTotPrice());
		    			Float endPrice = resultTotPrice - blockPrice;
		    			
		    			mjonMsgVO.setTotPrice(Float.toString(endPrice));
		    			
		    			//수신거부가 있는 경우 총 건수에서 수신거부 건수를 차감 후 그룹 테이블에 업데이트 해준다.
		    			int groupCnt = resultSts;
		    			mjonMsgVO.setMsgGroupCnt(Integer.toString(groupCnt));
		    			
		    		}
					
	    			//1건 이상 발송이 있는 경우만 캐쉬를 차감 시킨다.
		    		if(resultSts > 0) {
		    			mjonPayVO.setCashId(idgenMjonCashId.getNextStringId());
		    			mjonPayVO.setUserId(mjonMsgVO.getUserId());
		    			mjonPayVO.setCash(-Float.parseFloat(mjonMsgVO.getTotPrice()));
		    			mjonPayVO.setFrstRegisterId(mjonMsgVO.getUserId());
		    			mjonPayVO.setMemo("SMS 문자 " + resultSts + "건 발송");
		    			mjonPayVO.setMsgGroupId(mjonMsgVO.getMsgGroupId());
		    			
		    			mjonPayService.insertCash(mjonPayVO); //캐시차감 
		    			mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
		    		}
		    		
		    		//문자 발송 테이블에 입력 데이터가 있는 경우 그룹 테이블에도 입력 해 준다.
		    		if(resultSts > 0) {
		    			
		    			// 문자 전송 그룹 테이블에 정보 입력
		    			int groupCnt = resultSts;
		    			mjonMsgVO.setMsgGroupCnt(Integer.toString(groupCnt));
		    			mjonMsgService.insertGroupMsgData(mjonMsgVO);
		    			
		    			//이벤트 회원 남은 캐시 업데이트
		    			fnUpdateEventRemainCash(mjonPayVO);
		    			
		    		}*/
	    			
	    			//스팸문구 포함된 문자 발송의 경우 스팸 문구 내용도 별도 저장함.
		    		String spamStatus = mjonMsgVO.getSpamStatus();
		    		
		    		if(spamStatus == null) {
		    			
		    			spamStatus = "N";
		    			mjonMsgVO.setSpamStatus("N");
		    			
		    		}
		    		
		    		if(spamStatus.equals("Y")) {
		    			
		    			int resultCnt = mjonSpamMsgService.insertSpamKeyWordMsgData(mjonMsgVO);
		    			
		    			System.out.println("+++++++++++++스팸문구 발송 내용 등록 +++++++++++++++++++++ "+resultCnt);
		    			
		    		}
	    			
				} catch (Exception e) {
					System.out.println("=========================================================================");
					System.out.println("+++++++++++++++++++++++++++++ fncSendMsgRtnMap()  MJ_MSG_GROUP && CASH INSER ERROR !!! : " + e.getMessage());
					System.out.println("=========================================================================");
				}
	    		
	    	}else {
	    		
	    		returnMap.put("message", "문자 발송에 필요한 보유 잔액이 부족 합니다.");
	    		returnMap.put("result", "fail");
	    		returnMap.put("resultSts", "0");
	    		returnMap.put("resultBlockSts", "0");
				
				return returnMap;
	    		
	    	}
	    	
	    	//문자 발송 후 남은 보유 캐시 정보 불러오기
	    	String afterCash = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
	    	returnMap.put("afterCash", afterCash);
	    	
		}catch(Exception e) {
			
			logger.error(e.getMessage(), e);
			System.out.println("=========================================================================");
			System.out.println("+++++++++++++++++++++++++++++ 기타 시스템 오류 : " + e.getMessage());
			System.out.println("=========================================================================");
			returnMap.put("result", "fail");
			returnMap.put("message", "기타 시스템 오류 : " + e.getMessage());
	
		}
		
		returnMap.put("message", "문자 전송이 완료되었습니다.");
		returnMap.put("result", "success");
		returnMap.put("resultSts", Integer.toString(resultSts));
		returnMap.put("resultBlockSts", Integer.toString(resultBlockSts));
		
		return returnMap;
	}
	
	/**
	 * 문자발송시 치환문자가 없거나 그림문자일 경우 타는 로직
	 * param : MjonMsgVO
	 * return : ModelAndView
	 * 
	 * */
	public ModelAndView fncSendMsg(MjonMsgVO mjonMsgVO) {
		ModelAndView modelAndView = new ModelAndView(); 
		modelAndView.setViewName("jsonView");
		
		int resultSts = 0;			//발송결과 건수
		int resultBlockSts = 0;		//수신거부 등록번호로 발송을 안한 건수
		
		try {
			
			//문자열 길이 체크 해주기
			String charset = "euc-kr";
			String smsCont = mjonMsgVO.getSmsTxt().replace("\r\n", "\n");
			int bytes = smsCont.getBytes(charset).length;	//발송 문자 길이
			
			if(mjonMsgVO.getFileName1() != null) {
				mjonMsgVO.setMsgType("6");
			}else {
				if(bytes < 2000) {
					if(bytes > 90) {// 90Byte 초과시 장문
						mjonMsgVO.setMsgType("6");
					}else {// 그외 단문
						mjonMsgVO.setMsgType("4"); 
					}
				}else { //최대 문자길이 초과시
					
					modelAndView.addObject("message", "문자 치환 후 전송 문자 길이를 초과하였습니다.");
					modelAndView.addObject("result", "fail");
					modelAndView.addObject("resultSts", "0");
					modelAndView.addObject("resultBlockSts", "0");
					
					return modelAndView; 
				}
			}
			
			
			//현재 고객의 보유 캐시가 문자 발송이 가능한 금액인지 체크
	    	String userMoney = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
	    	String userPoint = mjonMsgDataService.selectBeforePointData(mjonMsgVO);
	    	mjonMsgVO.setBefPoint(userPoint); //현재 보유 포인트 정보 저장
	    	String totPrice = mjonMsgVO.getTotPrice();
	    	
	    	BigDecimal befCash = new BigDecimal(userMoney).setScale(2, RoundingMode.HALF_EVEN);
	    	BigDecimal totMsgPrice = new BigDecimal(totPrice).setScale(2, RoundingMode.HALF_EVEN);
	    	
	    	
	    	// 현재 보유 금액이 발송 문자 총 금액보다 클 경우만 문자 발송
	    	// BigDecimal 비교 연산
	    	// befCash(현재 보유금액) 값이 totMsgPrice(문자전송 금액) 보다 많으면 문자 전송
	    	if(befCash.compareTo(totMsgPrice) != -1) { // -1 : befCash < totMsgPrice, 0 : befCash = totMsgPrice, 1 : befCash > totMsgPrice,
	    		
	    		mjonMsgVO.setBefCash(userMoney);
	    		// 문자 전송 그룹아이디 생성
	        	mjonMsgVO.setMsgGroupId(idgenMjonMsgGroupId.getNextStringId());
	        	
	    		//문자 발송 처리
	    		//MjonMsgReturnVO returnVO = new MjonMsgReturnVO();
	    		String[] tempPhoneList = new String[200];				//임시 수신번호 리스트 저장용 배열
	    		String[] phoneList = mjonMsgVO.getCallToList();
	    		
	    		int callToListCnt = mjonMsgVO.getCallToList().length;
	    		mjonMsgVO.setTotalCallCnt(callToListCnt);
	    		
	    		/**
	    		 * 예약 문자인 경우 시간 및 분할 시간 셋팅 해주기
	    		 * 
	    		 * 
	    		 * */
	
	    		//분할문자 시간에 간격시간 더해주기
	        	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;		//분할 카운트
	    		
	    		
	    		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()); //분할 발송 갯수
	    			
	    		}
	    		
	    		//분할 예약 시간 저장 리스트 생성
	    		List<String> dividDayList = new ArrayList<String>();
	    		
	    		//서비스 단으로 특정 문자 건수 이상으로 한번에 보내지 않기 위해서 처리함
	    		if(callToListCnt > 200) {
	    			
	    			int sendCnt = 0;
	    			for(int i=0; i< callToListCnt; i++) {
	    				
	    				//분할 발송을 체크 한 경우
						if(mjonMsgVO.getDivideChk() != null) {
							
							if(count > divideCnt) {
		            			
		            			count = 1;
		            			
		            			//분할 시간 간격을 증가시켜 준다.
		            			cal.add(Calendar.MINUTE, turmMin);
		            			dividDay = transFormat.format(cal.getTime());
		                    	
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		                		count++;
		                		
		            		}else {
		            			
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		            			count++;
		            			
		            		}
							
						}
	    				
	    				if((i < callToListCnt -1) && sendCnt == 199) {
	    					
	    					//sendCnt 4번째 값을 추가해준다.
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					
	    					List<String> arrPhoneList = new ArrayList<String>();
	    					
	    					for(String temp : tempPhoneList) {
	    						
	    						if(temp != null) {
	    							
	    							arrPhoneList.add(temp);
	    							
	    						}
	    						
	    					}
	    					
	    					
	    					String[] sendPhoneList = new String[arrPhoneList.size()];
	    					
	    					for(int j=0; j< arrPhoneList.size(); j++) {
	    						
	    						sendPhoneList[j] = arrPhoneList.get(j);
	    						
	    					}
	    					
	    					
	    					mjonMsgVO.setCallToList(sendPhoneList);
	    					sendCnt = 0;
	    					
	    					mjonMsgVO.setDividDay(dividDayList);
	    					MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    					mjonMsgVO.setAgentCode(returnVO.getAgentCode());
	    		    		resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
	    		    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
	    		    		
	    		    		//발송 처리후 배열 초기화
	    		    		Arrays.fill(tempPhoneList, null);
	    		    		dividDayList.clear();
	    					
	    				}else if((i == callToListCnt -1) && sendCnt < 200){
	    					
	    					//마지막 리스트의 수신번호를 추가해 준다.
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					
	    					List<String> arrPhoneList2 = new ArrayList<String>();
	    					
	    					for(String temp : tempPhoneList) {
	    						
	    						if(temp != null) {
	    							
	    							arrPhoneList2.add(temp);
	    							
	    						}
	    						
	    					}
	    					
	    					
	    					String[] sendPhoneList2 = new String[arrPhoneList2.size()];
	    					
	    					for(int j=0; j< arrPhoneList2.size(); j++) {
	    						
	    						sendPhoneList2[j] = arrPhoneList2.get(j);
	    						
	    					}
	    					
	    					
	    					mjonMsgVO.setCallToList(sendPhoneList2);
	    					sendCnt = 0;
	    					
	    					mjonMsgVO.setDividDay(dividDayList);
	    					MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    					mjonMsgVO.setAgentCode(returnVO.getAgentCode());
	    		    		resultSts = resultSts + Integer.parseInt(returnVO.getSendMsgCnt());
	    		    		resultBlockSts = resultBlockSts + Integer.parseInt(returnVO.getSendMsgBlockCnt());
	    					
	    				}else {
	    					
	    					tempPhoneList[sendCnt] = phoneList[i];
	    					sendCnt++;
	    					
	    				}
	    				
	    			}
	    			
	    		}else {
	    			
	    			//분할 발송을 체크 한 경우
					if(mjonMsgVO.getDivideChk() != null) {
						for(int i=0; i< callToListCnt; i++) {
							if(count > divideCnt) {
		            			
		            			count = 1;
		            			
		            			//분할 시간 간격을 증가시켜 준다.
		            			cal.add(Calendar.MINUTE, turmMin);
		            			dividDay = transFormat.format(cal.getTime());
		                    	
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		                		count++;
		                		
		            		}else {
		            			
		            			dividDayList.add(dividDay);
		            			//tempVO.setReqDate(dividDay); //분할 문자 예약 시간 입력해주기
		            			count++;
		            			
		            		}
						
						}
	    				
	    			}
	    			
					mjonMsgVO.setDividDay(dividDayList);
	    			MjonMsgReturnVO returnVO = mjonMsgDataService.insertMsgDataInfo(mjonMsgVO);
	    			mjonMsgVO.setAgentCode(returnVO.getAgentCode());
		    		resultSts = Integer.parseInt(returnVO.getSendMsgCnt());
		    		resultBlockSts = Integer.parseInt(returnVO.getSendMsgBlockCnt());
		    		System.out.println("======================================== totPrice ::: "+mjonMsgVO.getTotPrice());
	    			
	    		}
	    		
	    		System.out.println("=========================================================================");
	    		System.out.println("+++++++++++++++++++++++++++++++++++++++++++ resultSts ::: " + resultSts);
	    		System.out.println("+++++++++++++++++++++++++++++++++++++++++++ resultBlockSts ::: " + resultBlockSts);
	    		System.out.println("=========================================================================");
	    		
	    		try {
	    			
	    			//문자 발송 캐시 차감 해주기 - serviceImple에서 처리하도록 변경 함
	    			/*MjonPayVO mjonPayVO = new MjonPayVO(); 
		    		
		    		if(resultSts > 0 && resultBlockSts > 0) {
		    			
		    			Float blockPrice = Float.parseFloat(mjonMsgVO.getEachPrice()) * resultBlockSts;
		    			Float resultTotPrice = Float.parseFloat(mjonMsgVO.getTotPrice());
		    			Float endPrice = resultTotPrice - blockPrice;
		    			
		    			mjonMsgVO.setTotPrice(Float.toString(endPrice));
		    			
		    			//수신거부가 있는 경우 총 건수에서 수신거부 건수를 차감 후 그룹 테이블에 업데이트 해준다.
		    			int groupCnt = resultSts;
		    			mjonMsgVO.setMsgGroupCnt(Integer.toString(groupCnt));
		    			
		    		}
	    			
	    			//1건 이상 발송이 있는 경우만 캐쉬를 차감 시킨다.
		    		if(resultSts > 0) {
		    			
		    			mjonPayVO.setCashId(idgenMjonCashId.getNextStringId());
		    			mjonPayVO.setUserId(mjonMsgVO.getUserId());
		    			mjonPayVO.setCash(-Float.parseFloat(mjonMsgVO.getTotPrice()));
		    			mjonPayVO.setFrstRegisterId(mjonMsgVO.getUserId());
		    			mjonPayVO.setMemo("SMS 문자 " + resultSts + "건 발송");
		    			mjonPayVO.setMsgGroupId(mjonMsgVO.getMsgGroupId());
		    			
		    			//mjonPayService.insertCash(mjonPayVO); //캐시차감 
		    			//mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
		    			
		    		}
		    		
		    		//문자 발송 테이블에 입력 데이터가 있는 경우 그룹 테이블에도 입력 해 준다.
		    		if(resultSts > 0) {
		    			
		    			// 문자 전송 그룹 테이블에 정보 입력
		    			int groupCnt = resultSts;
		    			mjonMsgVO.setMsgGroupCnt(Integer.toString(groupCnt));
		    			mjonMsgService.insertGroupMsgData(mjonMsgVO);
		    			
		    			//이벤트 회원 남은 캐시 업데이트
		    			fnUpdateEventRemainCash(mjonPayVO);
		    			
		    		}*/
		    		
		    		//스팸문구 포함된 문자 발송의 경우 스팸 문구 내용도 별도 저장함.
		    		String spamStatus = mjonMsgVO.getSpamStatus();
		    		
		    		if(spamStatus == null) {
		    			
		    			spamStatus = "N";
		    			mjonMsgVO.setSpamStatus("N");
		    			
		    		}
		    		
		    		if(spamStatus.equals("Y")) {
		    			
		    			int resultCnt = mjonSpamMsgService.insertSpamKeyWordMsgData(mjonMsgVO);
		    			
		    			System.out.println("+++++++++++++스팸문구 발송 내용 등록 +++++++++++++++++++++ "+resultCnt);
		    			
		    		}
					
				} catch (Exception e) {
					System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
					System.out.println("====================================== fncSendMsg MJ_MSG_GROUP && CASH ERROR !!! ::: " + e.getMessage());
					System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
				}
	    		
	    	}else {
	    		
	    		modelAndView.addObject("message", "문자 발송에 필요한 보유 잔액이 부족 합니다.");
				modelAndView.addObject("result", "fail");
				modelAndView.addObject("resultSts", "0");
				modelAndView.addObject("resultBlockSts", "0");
				
				return modelAndView;
	    		
	    	}
	    	
	    	//문자 발송 후 남은 보유 캐시 정보 불러오기
	    	String afterCash = mjonMsgDataService.selectBeforeCashData(mjonMsgVO);
	    	modelAndView.addObject("afterCash", afterCash);
	    	
		}catch(Exception e) {
			
			logger.error(e.getMessage(), e);
			
			System.out.println("=========================================================================");
			System.out.println("++++++++++++++++++++++++++++++++++++++++++++기타 시스템 오류 : " + e.getMessage());
			System.out.println("=========================================================================");
			
			modelAndView.addObject("result", "fail");
			modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
	
		}
	
		
		modelAndView.addObject("message", "문자 전송이 완료되었습니다.");
		modelAndView.addObject("msgType", mjonMsgVO.getMsgType());
		modelAndView.addObject("msgGroupId", mjonMsgVO.getMsgGroupId());
		modelAndView.addObject("result", "success");
		modelAndView.addObject("resultSts", resultSts);
		modelAndView.addObject("resultBlockSts", resultBlockSts);
		
		return modelAndView;
	}
	
	//이벤트 회원 캐시 변경 함수
	public void fnUpdateEventRemainCash(MjonPayVO mjonPayVO) throws Exception{
		
		//이벤트 회원인 경우 이벤트 캐시도 함께 차감.
		MjonEventVO mjonEventVO = new MjonEventVO();
		mjonEventVO.setMberId(mjonPayVO.getUserId());
		mjonEventVO.setEventStatus("Y");
		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO);
		
		if(eventMberInfo != null) {
			
			float evntRemainCash = (float) eventMberInfo.getEventRemainCash();
			float totPrice = (float) Math.abs(mjonPayVO.getCash());
			
			float totRemainCash = evntRemainCash - totPrice;
			mjonEventVO.setEventInfoId(eventMberInfo.getEventInfoId());
			
			if(totRemainCash <= 0.0) {//차감액이 남아있지 않으면 이벤트를 종료
				
				//이벤트 상태값을 종료로 변경한다.
				mjonEventVO.setEventStatus("E");
				mjonEventVO.setEventRemainCash(0.0);
				mjonEventService.updateEventEndStatus(mjonEventVO);
				
			}else {//이벤트 회원 캐시 차감시킴
				
				mjonEventVO.setEventRemainCash(totRemainCash);
				mjonEventService.updateEventRemainCash(mjonEventVO);
				
			}
			
		}
		
	}
	
	
	/**
     * 내 문자함 저장 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/insertMyMsgDataAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/insertMyMsgDataAjax.do"})
	public ModelAndView insertMyMsgDataAjax(MjonMsgDataVO mjonMsgDataVO,
			RedirectAttributes redirectAttributes, 
			ModelMap model) throws Exception{
	
		ModelAndView modelAndView = new ModelAndView(); 
		modelAndView.setViewName("jsonView");
		
		//로그인 권한정보 불러오기
    	LoginVO user = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;

    	if(user != null) {
    		
    		mjonMsgDataVO.setUserId(user.getId());
    		
    	}else {
    		
    		modelAndView.addObject("message", "로그인 후 이용이 가능합니다.");
    		modelAndView.addObject("result", "fail");
    		
    		return modelAndView;
    		
    	}
    	
    	//문자에 첨부된 이미지 파일 아이디를 셋팅해준다.
    	int i = 0;
    	for(String fileId : mjonMsgDataVO.getImgFileId()) {
    		
    		if(i == 0) {
    			
    			mjonMsgDataVO.setAtchFileId1(fileId);
    			
    		}else if(i == 1) {
    			
    			mjonMsgDataVO.setAtchFileId2(fileId);
    			
    		}else if(i == 2) {
    			
    			mjonMsgDataVO.setAtchFileId3(fileId);
    			
    		}
    		
    		i++;
    		
    	}
    	
    	 // 디비에 문자 내용을 저장해 준다.
		int resultSts = mjonMsgDataService.insertMyMsgDataAjax(mjonMsgDataVO);
		
		if(resultSts > 0) {
			
			modelAndView.addObject("message", "문자가 저장되었습니다.");
			modelAndView.addObject("result", "success");
			
		}else {
			
			modelAndView.addObject("message", "문자가 저장이 실패 되었습니다.");
			modelAndView.addObject("result", "fail");
			
		}
		
		return modelAndView;
		
	}
	

	
	/**
     * 이미지에디터 팝업 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgtxt/openImageEditorPopup.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/openImageEditorPopup.do"})
	public String openImageEditorPopup(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, CateCode cateCode, ModelMap model) throws Exception{
		
		// 그림문자 카테고리 리스트 불러오기
		List<CateCode> cateConfList = letterService.selectCateConfWithList("N");
		model.addAttribute("cateCodeList", cateConfList);
		
		//그림 문자 리스트 불러오기
		LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit(letterVO.getPageUnit());
		}

		/** paging */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		
		List<?> resultPhoList = mjonMsgDataService.selectPhotoLetterList(letterVO);
		
		model.addAttribute("resultPhoList", resultPhoList);
		paginationInfo.setTotalRecordCount( resultPhoList.size()> 0 ? ((Long)((EgovMap)resultPhoList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		
		return "web/msgdata/imageEditorPopup";
	}	
	
	
	/**
     * 에디터에서 수정한 이미지 등록 Ajax
     * @param mjonMsgDataVO
     * @param model
     * @return modelAndView
     * @throws Exception
     */
	@RequestMapping(value = {"/web/mjon/msgdata/insertEditImageAjax.do"})
	public ModelAndView insertEditImageAjax(final MultipartHttpServletRequest multiRequest
			, MjonMsgDataVO mjonMsgDataVO
			, RedirectAttributes redirectAttributes
			, HttpServletRequest request) throws Exception {
		
		//LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");

		try {
			String atchFileId = "";
			String isThumbFile = "";
			String imagePath = "";
			final Map<String, MultipartFile> files = multiRequest.getFileMap();
			String KeyStr = "CANVASIMG_";
			
			
			Date now = new Date();
			SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd");
			String fdlDate = formatDate.format(now);

			
			//로컬 과 개발서버의 이미지 저장 경로 분기처리
			if(request.getServerName().equals("localhost")) {
				
				imagePath = fileSaveDir+"/file/MMS/" + fdlDate;
				/*fileSaveDir+"src/main/webapp"*/
				
			}else {
				
				/*imagePath = "C:/eGovFrameDev-3.9.0-64bit_ncms/workspace/mjon/src/main/webapp/MMS/" + fdlDate;*/
				/*imagePath = "/usr/local/tomcat_mjon/webapps/mjon/MMS/" + fdlDate;*/
				imagePath = fileSaveDir+"/file/MMS/" + fdlDate;
				
			}
			
			
			if (!files.isEmpty()) {
				List<FileVO> result = fileUtil.parseImageFileInf(files, KeyStr, 0, atchFileId, imagePath, isThumbFile);
				atchFileId = fileMngService.insertFileInfs(result);
				
				FileVO tmpVO = new FileVO();
				tmpVO.setAtchFileId(atchFileId); //insert 한 파일의 정보를 가지고 옴
				
				
				FileVO fileVO = new FileVO();
				fileVO = fileMngService.selectFileInf(tmpVO);
				
				//저장한 파일의 경로 + 파일명
				String filefullPath = fileVO.getFileStreCours() +"/"+ fileVO.getStreFileNm() + "." + fileVO.getFileExtsn();
				
				modelAndView.addObject("atchFileId", atchFileId);
				modelAndView.addObject("filefullPath", filefullPath);
				modelAndView.addObject("result", "success");
				//modelAndView.addObject("message", "이미지 업로드가 완료되었습니다.");
			}
			
		}catch(Exception e) {
			logger.error(e.getMessage(), e);
    		modelAndView.addObject("result", "fail");
    		modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
		}
		
		return modelAndView;
	}
	
	
	/**
     * 내문자함 문자내용 선택시 정보 불러오기
     * @param String msgId, String pageType
     * @param model
     * @return modelAndView
     * @throws Exception
     */
	@RequestMapping(value = {"/web/mjon/msgdata/selectMsgAddInfoAjax.do"})
	public ModelAndView selectMsgAddInfoAjax(@RequestParam Map<?, ?> commandMap
			, MjonMsgDataVO mjonMsgDataVO
			, HttpServletRequest request) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");

		/*LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());*/
    	
		try {
			
				//MjonMsgDataVO mjonMsgDataVO = new MjonMsgDataVO();
			
				//mjonMsgDataVO.setMsgId(commandMap.get("msgId").toString());
				//mjonMsgDataVO.setPageType(commandMap.get("pageType").toString());
					
				//내 문자함 내용 및 첨부파일 정보 불러오기
				MjonMsgDataVO resultMsgInfo = mjonMsgDataService.selectMsgAddInfoAjax(mjonMsgDataVO);
				
				//문자함 리스트의 첨부이미지 정보 불러오기
				List<?> resultMsgAddPhotoInfo = mjonMsgDataService.selectMsgAddPhotoInfo(resultMsgInfo);
					
				modelAndView.addObject("resultMsgInfo", resultMsgInfo);
				modelAndView.addObject("resultMsgAddPhotoInfo", resultMsgAddPhotoInfo);
				modelAndView.addObject("result", "success");
				//modelAndView.addObject("message", "이미지 업로드가 완료되었습니다.");
			
		}catch(Exception e) {
			logger.error(e.getMessage(), e);
    		modelAndView.addObject("result", "fail");
    		modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
		}
		
		return modelAndView;
	}	
		
	
	/**
	 * 단문/장문 템플릿 조회수 증가
	 * @param letterId
	 * @param redirectAttributes
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/updateSmsTemplateCntAjax.do"})
	public ModelAndView updateSmsTemplateCntAjax(@ModelAttribute("letterId") String letterId, 
			RedirectAttributes redirectAttributes, 
			ModelMap model) throws Exception{
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		try {
			
			//템플릿 조회수
			int succCnt = letterService.updateSmsTemplateViewCount(letterId);
			
			if(succCnt > 0) {
				modelAndView.addObject("result","success");
			}else {
				modelAndView.addObject("result","fail");
			}
			
		} catch (Exception e) {
			
			logger.error(e.getMessage(), e);
			modelAndView.addObject("result", "fail");
			modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
			
		}
	
		return modelAndView;
	}
	
	
	/**
	 * 문자 발송 - 엑셀파일 불러오기
	 * @param body
	 * @param uploadFile
	 * @param search
	 * @param result
	 * @param model
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/web/mjon/msgdata/sendExelFilePhoneNumAjax.do")
	@ResponseBody
	public Object sendExelFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
		
		JsonResult jr = new JsonResult();
		jr.setSuccess(false);
		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
		
		try {
			
			//final Map<String, MultipartFile> files = multiRequest.getFileMap();
			List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
			
			// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
			int fileNameSplitCnt = 0;
			
			if(!files.isEmpty()) {
				fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
				
				if (files.get(0).getSize() > 0 
						&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
						|| files.get(0).getContentType().indexOf("ms-excel") > -1 
						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
					
					// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
					long fileSize = multiRequest.getFile("file0").getSize();
					
					if(fileSize > 3374653) {
						jr.setMessage("엑셀 파일은 3MB를 넘을수 없습니다.");
						return jr;
					}
					
					String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
					String errMessage = "";
			        String cellValue  = "";
			        
					//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
					String phoneRegExp = "^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
					
		            int errPhoneCnt = 0;
		            int errNameCnt = 0;
		            int errRep1Cnt = 0;
		            int errRep2Cnt = 0;
		            int errRep3Cnt = 0;
		            int errRep4Cnt = 0;
			        
		            //엑셀 확장자에 따른 처리 로직 분리
					if(Ext.equals("xls")) {
						
						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
					    HSSFSheet sheet = workbook.getSheetAt(0);
					    
					    if(sheet.getLastRowNum() > 20000) { //
			            	errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
			            	jr.setSuccess(false);
			            	jr.setMessage(errMessage);
			            	return jr;
			            }
			            
			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
			            PhoneVO pVO = new PhoneVO();
			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
			            	HSSFRow row = sheet.getRow(i); //열읽기
			            	if(null == row) { 
			                    continue;
			                }
			            	
			            	HashMap<String, String> jm = new HashMap<>();
			            	// 행의 두번째 열(이름부터 받아오기) 
			                HSSFCell cell = null;
			                boolean errSts = true;
			                for(int j = 0 ; j < 6; j++){ //행읽기(6행까지나 2행까지만 필요)
			                	cellValue = "";
			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
			                    	//System.out.println("Cell 데이터가 없습니다.");
			                		if(j == 1) {
				                		if (sheet.getLastRowNum() == i) {
				                			continue;
				                		}
				                		
				                		//errPhoneCnt++;
				                		//errSts = false;
				    	            	break;
			                		}
			                    	
			                    }
			                	if(null != cell){
			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
			                			case  Cell.CELL_TYPE_NUMERIC:
			                			cell.setCellType(Cell.CELL_TYPE_STRING);
			                		}
			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
			                    }
			                	
			                	if(j == 0) {
			                		//이름
			                		boolean nmChk = getNameRepLenChk("name", cellValue);
			                		
			                		if(nmChk && errSts) {
			                			jm.put("name", cellValue);
			                		}else {
			                			errNameCnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	} 
			                	if(j == 1) {
			                		//전화번호
			                		if(cellValue.matches(phoneRegExp) && errSts) {
			                			jm.put("phone", cellValue);
			                		}else {
				    	            	errPhoneCnt++;
				    	            	errSts = false;
				    	            	break;
			                		}
			                	}
			                	if(j == 2) {
			                		//치환1
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace1", cellValue);
			                		}else {
			                			errRep1Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                	}
			                	if(j == 3) {
			                		//치환2
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace2", cellValue);
			                		}else {
			                			errRep2Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	if(j == 4) {
			                		//치환3
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace3", cellValue);
			                		}else {
			                			errRep3Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	if(j == 5) {
			                		//치환4
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace4", cellValue);
			                		}else {
			                			errRep4Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	
			                }
			                if(null != jm.get("phone") && errSts) {
			                	json.add(jm);
			                }
			                
			            }
			            
			            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
			            int resultErrCntExceptPhone = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
			            
			            jr.setData(json);
						jr.setSuccess(true);
						
						if(resultErrCnt > 0) {
							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건,\n이름 : 20byte, [*1*] [*2*] : 40byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
						}else {
							jr.setMessage("");
						}
						
					}else {	//확장자가 xlsx
						
						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
			            opcPackage.close();
			            
			            int totRowDataCnt = 0;
			            for(int r=1; r<sheet.getPhysicalNumberOfRows(); r++) {
			            	
			            	XSSFRow tmpRow = sheet.getRow(r);
			            	//System.out.println("=================r:"+r);
			            	XSSFCell cell = null;
			            	if(tmpRow.getCell(1) != null) {
			            		
			            		cell = tmpRow.getCell(1); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
				            	if(cell != null && !cell.toString().trim().equals("")) {
				            		//System.out.println("value-" + r + ":" +cell.getStringCellValue()); 
				            		totRowDataCnt++;
				            		//System.out.println("tmpRowCnt:"+totRowDataCnt);
				            	}
			            		
			            	}
			            	
			            }
			            
			            System.out.println("+++++++++++++++++ totRowDataCnt ::: "+totRowDataCnt);
			            
			            //if(sheet.getLastRowNum() > 20000) { //
			            if(totRowDataCnt > 20000) { //
			            	errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
			            	jr.setSuccess(false);
			            	jr.setMessage(errMessage);
			            	return jr;
			            }
			            
			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
			            PhoneVO pVO = new PhoneVO();
			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
			            	XSSFRow row = sheet.getRow(i); //열읽기
			            	if(null == row) { 
			                    continue;
			                }
			            	
			            	HashMap<String, String> jm = new HashMap<>();
			            	// 행의 두번째 열(이름부터 받아오기) 
			                XSSFCell cell = null;
			                boolean errSts = true;
			                
			                for(int j = 0 ; j < 6; j++){ //행읽기(6행까지나 2행까지만 필요)
			                	cellValue = "";
			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
			                    	//System.out.println("Cell 데이터가 없습니다.");
			                		if(j == 1) {
				                		if (sheet.getLastRowNum() == i) {
				                			continue;
				                		}
				                		
				                		//errPhoneCnt++;
				                		//errSts = false;
				    	            	break;
				                		
			                		}
			                    }
			                	if(null != cell){
			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
			                			case  Cell.CELL_TYPE_NUMERIC:
			                			cell.setCellType(Cell.CELL_TYPE_STRING);
			                		}
			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
			                    }
			                	
			                	if(j == 0) {
			                		//이름
			                		boolean nmChk = getNameRepLenChk("name", cellValue);
			                		
			                		if(nmChk && errSts) {
			                			jm.put("name", cellValue);
			                		}else {
			                			errNameCnt++;
			                			errSts = false;
			                			break;
			                		}
			                				
			                		
			                	} 
			                	if(j == 1) {
			                		//전화번호
			                		if(cellValue.matches(phoneRegExp) && errSts) {
			                			jm.put("phone", cellValue);
			                		}else {
				    	            	errPhoneCnt++;
				    	            	errSts = false;
				    	            	break;
			                		}
			                	}
			                	if(j == 2) {
			                		//치환1
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace1", cellValue);
			                		}else {
			                			errRep1Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	if(j == 3) {
			                		//치환2
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace2", cellValue);
			                		}else {
			                			errRep2Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	if(j == 4) {
			                		//치환3
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace3", cellValue);
			                		}else {
			                			errRep3Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	if(j == 5) {
			                		//치환4
			                		boolean repChk = getNameRepLenChk("rep", cellValue);
			                		
			                		if(repChk && errSts) {
			                			jm.put("replace4", cellValue);
			                		}else {
			                			errRep4Cnt++;
			                			errSts = false;
			                			break;
			                		}
			                		
			                	}
			                	
			                }
			                
			                if(null != jm.get("phone") && errSts) {
			                	json.add(jm);
			                }
			                
			            }
			            
			            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
			            int resultErrCntExceptPhone = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
			            
						jr.setData(json);
						jr.setSuccess(true);
						
						if(resultErrCnt > 0) {
							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건,\n이름 : 20byte, [*1*] [*2*] : 40byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
						}else {
							jr.setMessage("");
						}
					}	//xlsx 처리 끝
					
				}
				
			}
			
			return jr;
			
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("+++++++++++++++++ sendExelFilePhoneNumAjax Controller Error !!! "+e);
			jr.setSuccess(false);
			jr.setMessage("엑셀 데이터에 오류가 있습니다. 엑셀 데이터를 확인해 주세요.");
			return jr;
		}
		
	}
	
	
	/**
	 * 문자 발송 - TXT파일 불러오기
	 * @param body
	 * @param uploadFile
	 * @param search
	 * @param result
	 * @param model
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/web/mjon/msgdata/sendTxtFilePhoneNumAjax.do")
	@ResponseBody
	public Object sendTxtFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
		
		JsonResult jr = new JsonResult();
		jr.setSuccess(false);
		jr.setMessage("TXT 파일만 업로드할 수 있습니다.");
		
		List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
		
		if(!files.isEmpty()) {
			
			if (files.get(0).getSize() > 0 
					|| files.get(0).getOriginalFilename().split("[.]")[1].indexOf("txt") > -1) {
				
				// txt 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
				long fileSize = multiRequest.getFile("file0").getSize();
				
				if(fileSize > 3374653) {
					jr.setMessage("txt 파일은 3MB를 넘을수 없습니다.");
					return jr;
				}
				
				//Multi file to file 변환해주기
				File file = new File(files.get(0).getOriginalFilename());
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(files.get(0).getBytes());
				fos.close();
				
				BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
				
				String line = null;
				String[] splitedStr = null;
				String[] tempStr = null;
				int errPhoneCnt = 0;
				
				//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
				String phoneRegExp = "^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";				
				
				List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
				
				
				//파일 읽어서 탭으로 구분해주기
				while ((line = reader.readLine()) != null) {

					HashMap<String, String> jm = new HashMap<>();
					splitedStr = null;
					tempStr = null;
					
					//txt 파일의 데이터가 탭 혹은 콤마로 구분되어 있는지 구분처리
					tempStr = line.split("\t");
					if(tempStr.length > 0) {
						
						splitedStr = tempStr;
						
					}else {
						
						splitedStr = line.split(",");
						
					}

					for (int i = 0; i < splitedStr.length; i++) {

						splitedStr[i] = splitedStr[i].trim();
						
						if(i == 0) {
							
							//이름
							jm.put("name", splitedStr[i]);
						}
						
						if(i == 1) {
							
							if(splitedStr[i].matches(phoneRegExp)) {
								//휴대폰 번호
								jm.put("phone", splitedStr[i]);
							}else {
		    	            	errPhoneCnt++;
	                		}
							
						}
						
	                	if(i == 2) {
	                		//치환1
	                		jm.put("replace1", splitedStr[i]);
	                	}
	                	if(i == 3) {
	                		//치환2
	                		jm.put("replace2", splitedStr[i]);
	                	}
	                	if(i == 4) {
	                		//치환3
	                		jm.put("replace3", splitedStr[i]);
	                	}
	                	if(i == 5) {
	                		//치환4
	                		jm.put("replace4", splitedStr[i]);
	                	}

					}
					
					if(jm.get("phone") != null) {
						
						json.add(jm);
						
					}

				} // end while
				jr.setData(json);
				jr.setSuccess(true);
				if(errPhoneCnt > 0) {
					
					jr.setMessage("올바르지 않은 휴대폰 번호가 "+ errPhoneCnt +" 건 있습니다.");
					
				}else {
					
					jr.setMessage("");
					
				}
			}
			
		}
		
		return jr;
	}
	
	
	/**
     * 문자발송 주소록에 등록 기능 처리
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/excelCallAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/insertMsgAddrListAjax.do"})
	public ModelAndView insertMsgAddrListAjax(@ModelAttribute("searchVO") MjonMsgVO mjonMsgVO, ModelMap model) throws Exception{
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	
    	AddrVO addrVO = new AddrVO();
    	
    	if(userId.equals("")) {
    		
    		modelAndView.addObject("message", "로그인 후 이용이 가능합니다.");
			modelAndView.addObject("result", "LoginFail");
			return modelAndView;
			
    	}else {
    		
    		addrVO.setMberId(userId);
    		
    	}
		
		//주소록 데이터 갯수 불러오기 - 주소록은 총 10만개 까지만 등록이 가능함
    	int addrBefAfterCnt = 0;
    	int addrBefCnt = addrService.selectAddrTotalCount(addrVO);
		int addrNewCnt = mjonMsgVO.getCallToList().length;	//신규 추가할 주소록 갯수
		int sumAddrCnt = addrBefCnt + addrNewCnt;			//기존 + 신규 주소록 합산
		int dupliCnt = 0; 	// 중복 데이터 수

		System.out.println("mjonMsgVO.getAddrGrpId() : " + mjonMsgVO.getAddrGrpId());
		System.out.println("mjonMsgVO.getAddrGrpNm() : " + mjonMsgVO.getAddrGrpNm());
		
		// 신규 주소록 여부 체크
		if (mjonMsgVO.getAddrGrpId().equals("NEW")) {
			AddrGroupVO addrGroupVO = new AddrGroupVO();
			addrGroupVO.setMberId(userId);
			addrGroupVO.setAddrGrpNm(mjonMsgVO.getAddrGrpNm());
			// 정렬순서
			int nextOrderNumber = addrGroupService.selectMaxOrderNumber(addrGroupVO);
			addrGroupVO.setGrpOrder(nextOrderNumber);
			
			addrGroupService.insertAddrGroup(addrGroupVO);
			
			// 신규 추가한 그룹아이디
			addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
			addrVO.setBookmark("N");
		}	    
		else {
			// 그룹미지정, 자주보내는 번호 구분처리
			if("bookmark".equals (mjonMsgVO.getAddrGrpId())) {
				// 자주보내는 번호
				addrVO.setAddrGrpId("0");
				addrVO.setBookmark("Y");
			} 
			else {
				addrVO.setAddrGrpId(mjonMsgVO.getAddrGrpId());
				addrVO.setBookmark("N");
			}   					
		}
		
		List<AddrVO> addrDataInfo = new ArrayList<AddrVO>();
		
		if(addrBefCnt < 100000) { // 기존 등록된 주소록이 10만건 미만이면
			
			//받는사람 리스트 건수 체크해주기
			if(sumAddrCnt > 100000) {
				
				modelAndView.addObject("message", "주소록은 총 10만개까지만 등록이 가능합니다.");
				modelAndView.addObject("result", "addrTotFail");
				return modelAndView;
				
			}else {
				
				//주소록 등록 VO 담아주기
				String[] addrNm = mjonMsgVO.getNameList();	//치환 이름 리스트
		    	String[] addrPhoneNo = mjonMsgVO.getCallToList();	//받는사람 연락처 리스트
		    	String[] addrInfo1 = mjonMsgVO.getRep1List();		//치환 문자1 리스트
		    	String[] addrInfo2 = mjonMsgVO.getRep2List();		//치환 문자2 리스트
		    	String[] addrInfo3 = mjonMsgVO.getRep3List();		//치환 문자3 리스트
		    	String[] addrInfo4 = mjonMsgVO.getRep4List();		//치환 문자4 리스트
				
				for(int i=0; i < addrNewCnt; i++) {
					
					AddrVO tempAddrVO = new AddrVO();
					if(addrNm.length > 0 && addrNm[i].length() > 0) {
						tempAddrVO.setAddrNm(addrNm[i]);
					}
					
					tempAddrVO.setAddrPhoneNo(addrPhoneNo[i]);
					
					if(addrInfo1[i].equals("-")) {
						tempAddrVO.setAddrInfo1(null);
					}else {
						tempAddrVO.setAddrInfo1(addrInfo1[i]);
					}
					
					if(addrInfo2[i].equals("-")) {
						tempAddrVO.setAddrInfo2(null);
					}else {
						tempAddrVO.setAddrInfo2(addrInfo2[i]);
					}
					
					if(addrInfo3[i].equals("-")) {
						tempAddrVO.setAddrInfo3(null);
					}else {
						tempAddrVO.setAddrInfo3(addrInfo3[i]);
					}

					if(addrInfo4[i].equals("-")) {
						tempAddrVO.setAddrInfo4(null);
					}else {
						tempAddrVO.setAddrInfo4(addrInfo4[i]);
					}
					
					tempAddrVO.setMberId(userId);
					tempAddrVO.setFrstRegisterId(userId);
					tempAddrVO.setAddrGrpId(addrVO.getAddrGrpId());
					tempAddrVO.setBookmark(addrVO.getBookmark());

					AddrVO addrVO2 = new AddrVO();
					addrVO2.setMberId(userId);
					addrVO2.setAddrGrpId(addrVO.getAddrGrpId());
					addrVO2.setBookmark(addrVO.getBookmark());
					addrVO2.setAddrPhoneNo(addrPhoneNo[i]);	// 연락처
					int usedCnt = 0;
					//int usedCnt = addrService.selectDuplAddrCnt(addrVO2);
					if(usedCnt > 0) {
						dupliCnt++;
					}
					else {
    					//주소록 리스트에 데이터 추가해 주기
    					addrDataInfo.add(tempAddrVO);
					}
					
				}
				
				//주소록에 데이터 추가해 주기
				int resultCnt = 0;
				if(addrDataInfo.size() > 0) {
					// 주소록 그룹별 중복 연락처 삭제
					addrVO.setMberId(userId);
					
					// 주소록 대량등록 By Temp 주소록 All
					resultCnt = addrService.insertAddrByTempAddrAll(addrDataInfo, addrVO);
					
		    		addrBefAfterCnt = addrService.selectAddrTotalCount(addrVO);
		    		
		    		resultCnt = addrBefAfterCnt - addrBefCnt; 
		    		dupliCnt = addrNewCnt - resultCnt;					
				}				
				
				modelAndView.addObject("message", "주소록 등록이 완료되었습니다.");
				modelAndView.addObject("dupliCnt", dupliCnt);
				modelAndView.addObject("resultCnt", resultCnt);
				modelAndView.addObject("result", "success");
				
			}
			
		}else {
		
			modelAndView.addObject("message", "주소록은 총 10만개까지만 등록이 가능합니다.");
			modelAndView.addObject("result", "addrTotFail");
			
		}
		
		return modelAndView;
		
	}	
	
	/**
	 * 문자 통합검색 욕설 및 금지어 필터 체크
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectSwearWordFilterAjax.do"})
	public ModelAndView selectSwearWordFilterAjax(
			MjonMsgDataVO mjonMsgDataVO, 
			HttpServletRequest req,
			ModelMap model) throws Exception {

		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");
		
		/*
		 * 검색 키워드에서 한글, 영문, 숫자 이외의 특수기호를 입력하는 경우 오류 발생시킴
		 * 해킹 시도에서 특수문자를 이용하는 경우가 있어서 추가하였음
		 * 2023-04-24 우영두
		 * 
		 * */
		String keyword = mjonMsgDataVO.getSearchKeyword();
		keyword = keyword.replaceAll("[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9 ]", "");
		
		if(!keyword.equals("")) {
			
			modelAndView.addObject("status", "wordFail");
			modelAndView.addObject("message", "잘못된 검색어 입니다.");
			return modelAndView;
		}
		
		//욕설 및 금지 단어 리스트 불러오기
		int resultSwearCnt = letterService.selectSwearWordSearchCnt(mjonMsgDataVO.getSearchKeyword());
		
		if(resultSwearCnt > 0) {
			
			modelAndView.addObject("status", "wordFail");
			modelAndView.addObject("message", "금지어가 포함된 검색어입니다.");
			
		}else {
			
			modelAndView.addObject("status", "success");
			
		}
		
		return modelAndView;
	}
	
	
	
	/**
     * 엑셀 불러오기 레이어 팝업 화면
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/excelCallAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/excelCallAjax.do"})
	public String excelCallAjax(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, CateCode cateCode, ModelMap model) throws Exception{
		
		
	return "web/msgdata/ExcelCallAjax";
		
	}	
	
	/* 테스트 발송 팝업 */
	@RequestMapping(value="/web/pop/testSendPop.do")
    public String testSendPop(@ModelAttribute("searchVO") MjonMsgDataVO searchVO, HttpServletRequest request, Model model) throws Exception {
		
		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
    	String author = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getAuthority());
    	
		String msgpreview = request.getParameter("msgpreview");
		String mmsSubject = request.getParameter("mmsSubject");
		String callFrom = request.getParameter("callFrom");
		String eachPrice = request.getParameter("eachPrice");
		model.addAttribute("msgpreview", msgpreview);
		model.addAttribute("mmsSubject", mmsSubject);
		model.addAttribute("callFrom", callFrom);
		model.addAttribute("eachPrice", eachPrice);
		model.addAttribute("searchVO", searchVO);

		MberManageVO mberManageVO = new MberManageVO(); 
		
		if(!userId.equals("") && !author.equals("ROLE_ADMIN")) {
			
			mberManageVO = mjonMsgDataService.selectMberManageInfo(userId);
			searchVO.setUserId(userId);
			
		}
		
		//3.사용자 개인단가 정보가 0이 아니면 개인단가 사용, 없으면 시스템 기본 단가 사용
		BigDecimal userMoney = new BigDecimal(mberManageVO.getUserMoney()).setScale(2, RoundingMode.HALF_EVEN);
		String userPoint = mberManageVO.getUserPoint();
		
		model.addAttribute("mberManageVO", mberManageVO);
		model.addAttribute("userMoney", userMoney);
		model.addAttribute("userPoint", userPoint);
		
		//0.이벤트 진행중이 회원 정보 불러오기.
		//이벤트 회원 정보 테이블에서 대상자의 정보를 불러온다.
		MjonEventVO mjonEventVO = new MjonEventVO();
		mjonEventVO.setMberId(userId);
		MjonEventVO eventMberInfo = mjonEventService.selectEventMsgMberDefaultInfo(mjonEventVO);
		
		model.addAttribute("eventMberInfo", eventMberInfo);
		
 		return "/web/pop/testSendPop";
    }
	
	/**
	 * 문자 발송 - 엑셀파일 불러오기
	 * @param body
	 * @param uploadFile
	 * @param search
	 * @param result
	 * @param model
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/web/mjon/msgdata/excelCallProc.do")
	@ResponseBody
	public Object excelProc(@RequestBody(required = false) String body, 
			List<MultipartFile> uploadFile, 
			BindingResult result, Model model, 
			MultipartHttpServletRequest request) throws Exception {
		
		JsonResult jr = new JsonResult();
		jr.setSuccess(false);
		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
		
		//String sReturn = super.checkReferer(model, request, "", "", "/sms/mms.do", "/sms/sms.do");
		String sReturn = "";
		if (!StringUtil.isEmpty(sReturn)) {
			jr.setMessage("올바르지 않은 요청입니다.");
			return jr;
		}
		
		//mime : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
		//		 application/vnd.ms-excel
		if (uploadFile.get(0).getSize() > 0 
				&& (uploadFile.get(0).getContentType().indexOf("spreadsheetml") > -1) 
				|| uploadFile.get(0).getContentType().indexOf("ms-excel") > -1 
				|| uploadFile.get(0).getOriginalFilename().split("[.]")[1].indexOf("xlsx") > -1 
				|| uploadFile.get(0).getOriginalFilename().split("[.]")[1].indexOf("xls") > -1) {
			String col = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
			String[] cols = col.split(",");
			//List<HashMap<String, String>> excel = ExcelUploadUtil.readExcel(request, super.getConfig().getUploadPathTemp(), cols, 2);
			
			//List<HashMap<String, String>> excel = null;
			String UploadPathTemp = "/temp";
			//List<HashMap<String, String>> excel = ExcelUploadUtil.readExcel(request, super.getConfig().getUploadPathTemp(), cols, 2);

			//List<HashMap<String, String>> excel = ExcelUploadUtil.readExcel(request, UploadPathTemp, cols, 2);
			
			
			OPCPackage opcPackage = OPCPackage.open(uploadFile.get(0).getInputStream());
			XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
			
            String errMessage = "";
            String cellValue  = "";
            if(sheet.getLastRowNum() > 5000) { //
            	errMessage = "5000줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
            	jr.setMessage(errMessage);
            	return jr;
            }
            
			//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
			String phoneRegExp = "^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";            
            
            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
            PhoneVO pVO = new PhoneVO();
            for(int i=1; i< sheet.getLastRowNum() + 1; i++){ //먼저 밸리데이션 체크(1줄은 생략)
            	XSSFRow row = sheet.getRow(i); //열읽기
            	if(null == row) { 
                    continue;
                }
            	
            	HashMap<String, String> jm = new HashMap<>();
				jm.put("group", ""); //그룹 빈칸세팅
            	// 행의 두번째 열(이름부터 받아오기) 
                XSSFCell cell = null;
                for(int j = 0 ; j < 6; j++){ //행읽기(6행까지나 2행까지만 필요)
                	cellValue = "";
                	cell = row.getCell(j); //이름/핸드폰/집사무실/메모1/메모2/메모3
                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
                    	
                    }
                	if(null != cell){
                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
                			case  Cell.CELL_TYPE_NUMERIC:
                			cell.setCellType(Cell.CELL_TYPE_STRING);
                		}
                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
                    }
                	
                	if(j == 0) {
                		//이름
                		jm.put("name", cellValue);
                	}
                	if(j == 1) {
                		//전화번호
                		if(cellValue.matches(phoneRegExp)) {
                			jm.put("receive", cellValue);
                		}
                	}
                	if(j == 2) {
                		//집사무실
                		jm.put("item2", cellValue);
                	}
                	if(j == 3) {
                		//메모1
                		jm.put("item3", cellValue);
                	}
                	if(j == 4) {
                		//메모2
                		jm.put("item4", cellValue);
                	}
                	if(j == 5) {
                		//메모3
                		jm.put("item5", cellValue);
                	}
                }
                if(null != jm.get("receive")) {
                	json.add(jm);
                }
                
            }
            
			//json 형식에 맞게 변환
			//[{phone: '전화번호', name: '주소록이름', group: '주소록 그룹 이름', item2: '집/사무실', item3: '메모1', item4: '메모2', item5: '메모3'}, {...}]
			/*List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
			PhoneVO pVO = new PhoneVO();*/
			
			//TODO : 데이터 유효성 판단? 
			/*for (HashMap<String, String> map : excel) {
				HashMap<String, String> jm = new HashMap<>();
				//핸드폰
				pVO.setNo(StringUtil.getString(map.get(cols[1])).trim());
				if (StringUtil.isEmpty(pVO.getNo()))
					continue;
				jm.put("receive", pVO.getNo());
				
				//이름
				jm.put("name", StringUtil.getString(map.get(cols[0])).trim());
				//그룹
				jm.put("group", "");
				
				//항목2(집/사무실) - 주의 : 옵션 항목이므로 전화번호가 없어도 스킵하면 안됨
				pVO.setNo(StringUtil.getString(map.get(cols[2])).trim());
				jm.put("item2", pVO.getNo());
				//항목3
				jm.put("item3", StringUtil.getString(map.get(cols[3])).trim());
				//항목4
				jm.put("item4", StringUtil.getString(map.get(cols[4])).trim());
				//항목5
				jm.put("item5", StringUtil.getString(map.get(cols[5])).trim());
				
				json.add(jm);
			}*/
			
			jr.setData(json);
			jr.setSuccess(true);
			jr.setMessage("");
		}
		return jr;
	}
	
	
	/**
     * 발송관리 엑셀다운로드 기능 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgsent/msgSentExcelDownLoadAjax.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/recieveCallToListExcelDownAjax.do"})
	public void recieveCallToListExcelDownAjax(MjonMsgVO mjonMsgVO, 
			@RequestParam Map<?, ?> commandMap,
			RedirectAttributes redirectAttributes, 
			HttpServletRequest request,
			HttpServletResponse response ,
			ModelMap model) throws Exception{
	
		//로그인 권한정보 불러오기
		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());

    	if(!userId.equals("")) {
    		
    		mjonMsgVO.setUserId(userId);
    		
    	}else {
    		
    		/*modelAndView.addObject("message", "로그인 후 이용이 가능합니다.");
    		modelAndView.addObject("result", "fail");
    		
    		return modelAndView;*/
    		
    	}
    	
    	// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
		SXSSFWorkbook wb = new SXSSFWorkbook(100);
		String fileName ="recieveAddr";		// 저장 파일명
		String sheetTitle = "recieveAddr" ; 		// 셀 제목
		Sheet sheet = wb.createSheet(sheetTitle);
		Cell cell = null;
		Row row = null;
		
		CellStyle style = wb.createCellStyle();
		style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setBorderTop(CellStyle.BORDER_THIN);
		
		// 정렬
		style.setAlignment(CellStyle.ALIGN_CENTER); //가운데 정렬
		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //높이 가운데 정렬
		
		Font font = wb.createFont();
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
		
		
		String type = "";
		String fCnt = "";
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		
		try{ 
			
			{//화면 리스트
				
  				row = sheet.createRow(0);
  				
  				//sheet.setColumnWidth(0, 3000); // 번호
				sheet.setColumnWidth(0, 10000); // 휴대폰 번호
				sheet.setColumnWidth(1, 10000); // 이름
				sheet.setColumnWidth(2, 10000); // 치환문자1
				sheet.setColumnWidth(3, 10000); // 치환문자2
				sheet.setColumnWidth(4, 10000); // 치환문자3
				sheet.setColumnWidth(5, 10000); // 치환문자4
				
				/*cell = row.createCell(0);
				cell.setCellValue("번호");
				cell.setCellStyle(style);*/
				
				cell = row.createCell(0);
				cell.setCellValue("휴대폰");
				cell.setCellStyle(style);
				
				cell = row.createCell(1);
				cell.setCellValue("이름");
				cell.setCellStyle(style);
				
				cell = row.createCell(2);
				cell.setCellValue("[*1*]");
				cell.setCellStyle(style);
				
				cell = row.createCell(3);
				cell.setCellValue("[*2*]");
				cell.setCellStyle(style);
				
				cell = row.createCell(4);
				cell.setCellValue("[*3*]");
				cell.setCellStyle(style);
				
				cell = row.createCell(5);
				cell.setCellValue("[*4*]");
				cell.setCellStyle(style);
					
			} 
				
			int listCnt = mjonMsgVO.getCallToList().length;
			
			String[] phoneList = mjonMsgVO.getCallToList();
			String[] nameList = mjonMsgVO.getNameList();
			String[] rep1List = mjonMsgVO.getRep1List();
			String[] rep2List = mjonMsgVO.getRep2List();
			String[] rep3List = mjonMsgVO.getRep3List();
			String[] rep4List = mjonMsgVO.getRep4List();
			
			for(int i=0; i < listCnt; i++) {
					
				int excelLen = 0;
				row = sheet.createRow(i+1);
				excelLen = 6;
					
				for(int j=0 ; j < excelLen ; j++) {
					cell = row.createCell(j);
					cell.setCellStyle(style);
					
					//if(j==0) cell.setCellValue(i+1); //번호
					if(j==0) cell.setCellValue(phoneList[i]); 	//휴대폰 번호
					if(j==1) cell.setCellValue(nameList[i]); 	//이름
					if(j==2) {
						
						String rep1 = rep1List[i];
						if(!rep1.equals("")) {
							
							cell.setCellValue(rep1.replaceAll("§", ",")); 	//치환문자1
							
						}
						
					}
					if(j==3) {
						
						String rep2 = rep2List[i];
						if(!rep2.equals("")) {
							
							cell.setCellValue(rep2.replaceAll("§", ",")); 	//치환문자2
							
						}
						
					}
					if(j==4) {
						
						String rep3 = rep3List[i];
						if(!rep3.equals("")) {
							
							cell.setCellValue(rep3.replaceAll("§", ",")); 	//치환문자3
							
						}
						
					}
					if(j==5) {
						
						String rep4 = rep4List[i];
						if(!rep4.equals("")) {
							
							cell.setCellValue(rep4.replaceAll("§", ",")); 	//치환문자4
							
						}
						
					}
							
				}
			}
			response.setHeader("Set-Cookie", "fileDownload=true; path=/");
			SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyyMMdd_HHmmss", Locale.KOREA );
			Date currentTime = new Date ();
			String mTime = mSimpleDateFormat.format ( currentTime );
			fileName = fileName+"("+mTime+")";
			
			response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
			wb.write(response.getOutputStream());
		}catch(Exception e) {
  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  			response.setHeader("Content-Type","text/html; charset=utf-8");
  			OutputStream out = null;
  			try {
  				out = response.getOutputStream();
  				byte[] data = new String("fail..").getBytes();
  				out.write(data, 0, data.length);
  			} catch(Exception ignore) {
  				ignore.printStackTrace();
  			} finally {
  				if(out != null) try { out.close(); } catch(Exception ignore) {}
  			}
  		}finally {
  			// 디스크 적었던 임시파일을 제거합니다.
  			wb.dispose();
  			try { wb.close(); } catch(Exception ignore) {}
  		}
    	
		
	}
	
	
    /**
     * 베스트 문자샘플 화면 
     * @param searchVO
     * @param model
     * @return	"/web/mjon/msgdata/selectBestMsgDataView.do"
     * @throws Exception
     */
	@RequestMapping(value= {"/web/mjon/msgdata/selectBestMsgDataView.do"})
	public String selectBestMsgDataView(@ModelAttribute("searchVO") LetterVO searchVO, 
			HttpServletRequest request,
			ModelMap model,
			RedirectAttributes redirectAttributes) throws Exception{
		
		//문자온 소개 태그 조회
		searchVO.setTagDiv("2");
		List<LetterVO> mainTagList = letterService.selectMainTagWebList(searchVO);
		
		model.addAttribute("mainTagList", mainTagList);
		
		//베스트샘플 키워드 조회
		searchVO.setTagDiv("1");
		if("".equals(searchVO.getBestTagType()) || searchVO.getBestTagType() == null) {
			searchVO.setBestTagType("S");
		}
		List<LetterVO> bestMsgDataList = letterService.selectMainTagWebList(searchVO);
		//첫 메뉴 이동시 키워드가 없어서, 단문/장문/그림 탭 이동 시 키워드를 파라미터로 넘겨주기 위한 과정
		LetterVO frsLetterVO = letterService.selectFrsKeyword(searchVO);
		if("".equals(searchVO.getBestSearchKeyword()) || searchVO.getBestSearchKeyword() == null){
			searchVO.setBestSearchKeyword(frsLetterVO.getTagNm().replace("문자", ""));
		}
		model.addAttribute("bestMsgDataList", bestMsgDataList);
		
		return "web/msgdata/MsgDataBestView";
	}
	
	/**
	 * 베스트 문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectBestMsgDataListAjax.do"})
	public String selectBestMsgDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			ModelMap model, 
			RedirectAttributes redirectAttributes) throws Exception {
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit((int)letterVO.getPageUnit());
		}

		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());

		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		String letterType = letterVO.getLetterType();
		
		// 문자 종류 정보가 없으면 단문문자로 셋팅
		if(letterType == null || letterType.equals("")) {
			
			letterVO.setLetterType("S");
			
		}
		//키워드에 문자 제거
		letterVO.setBestSearchKeyword(letterVO.getBestSearchKeyword().replace("문자", ""));
		// 장/단문 문자 리스트
		List<?> resultLetterList = mjonMsgDataService.selectBestMsgDataList(letterVO);
		model.addAttribute("resultLetterList", resultLetterList);
		paginationInfo.setTotalRecordCount( resultLetterList.size()> 0 ? ((Long)((EgovMap)resultLetterList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/BestMsgDataListAjax";
	}
	
	/**
	 * 베스트 그림 문자샘플 리스트 화면 불러오기
	 *
	 * @param letterVO
	 * @param 
	 * @param sessionVO
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value= {"/web/mjon/msgdata/selectBestPhotoMsgDataListAjax.do"})
	public String selectBestPhotoMsgDataListAjax(
			@ModelAttribute("searchVO") LetterVO letterVO, 
			ModelMap model, 
			RedirectAttributes redirectAttributes) throws Exception {
		
		//그림 문자 리스트 불러오기
		//LetterVO letterVO = new LetterVO();
		if(letterVO.getPageUnit() != 10) {
			letterVO.setPageUnit((int)letterVO.getPageUnit());
		}
		
		/** pageing */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(letterVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(letterVO.getPageUnit());
		paginationInfo.setPageSize(letterVO.getPageSize());
		
		letterVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		letterVO.setLastIndex(paginationInfo.getLastRecordIndex());
		letterVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		letterVO.setLetterType("P");
		
		//키워드에 문자 제거
		letterVO.setBestSearchKeyword(letterVO.getBestSearchKeyword().replace("문자", ""));
		// 장/단문 문자 리스트
		List<?> resultLetterList = mjonMsgDataService.selectBestPhotoMsgDataList(letterVO);
		model.addAttribute("resultLetterList", resultLetterList);
		paginationInfo.setTotalRecordCount( resultLetterList.size()> 0 ? ((Long)((EgovMap)resultLetterList.get(0)).get("totCnt")).intValue() : 0);
		model.addAttribute("paginationInfo", paginationInfo);
		model.addAttribute("letterVO", letterVO);
		
		return "web/msgdata/BestPhotoMsgDataListAjax";
	}
	
	
	/**
     * 문자발송 사용자 첨부 이미지 리사이즈 처리 Ajax
     * @param mjonMsgDataVO
     * @param model
     * @return modelAndView
     * @throws Exception
     */
	@RequestMapping(value = {"/web/mjon/msgdata/insertAtchImageResizeAjax.do"})
	public ModelAndView insertAtchImageResizeAjax(final MultipartHttpServletRequest multiRequest
			, MjonMsgDataVO mjonMsgDataVO
			, RedirectAttributes redirectAttributes
			, HttpServletRequest request) throws Exception {
		
		//LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("jsonView");

		try {
			String atchFileId = "";
			String isThumbFile = "";
			String imagePath = "";
			final Map<String, MultipartFile> files = multiRequest.getFileMap();
			String KeyStr = "RESIZEIMG_";
			
			
			Date now = new Date();
			SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd");
			String fdlDate = formatDate.format(now);

			
			//로컬 과 개발서버의 이미지 저장 경로 분기처리
			if(request.getServerName().equals("localhost")) {
				
				imagePath = fileSaveDir+ "/file/MMS/" + fdlDate;
				
			}else {
				
				imagePath = fileSaveDir+"/file/MMS/" + fdlDate;
				
			}
			
			
			if (!files.isEmpty()) {
				List<FileVO> result = fileUtil.parseImageFileResizeInf(files, KeyStr, 0, atchFileId, imagePath, isThumbFile);
				atchFileId = fileMngService.insertFileInfs(result);
				
				FileVO tmpVO = new FileVO();
				tmpVO.setAtchFileId(atchFileId); //insert 한 파일의 정보를 가지고 옴
				
				
				FileVO fileVO = new FileVO();
				fileVO = fileMngService.selectFileInf(tmpVO);
				
				//저장한 파일의 경로 + 파일명
				String filefullPath = fileVO.getFileStreCours() +"/"+ fileVO.getStreFileNm() + "." + fileVO.getFileExtsn();

				//문자전송 내용 입력 화면 및 미리보기에 보여주기 위한 이미지 경로 생성
				String imgSrc ="/cmm/fms/getImage2.do?atchFileId="+ atchFileId +"&fileSn=0"; 
				
				modelAndView.addObject("atchFileId", atchFileId);
				modelAndView.addObject("filefullPath", filefullPath);
				modelAndView.addObject("fileName", fileVO.getStreFileNm());
				modelAndView.addObject("imgSrc", imgSrc);
				
				modelAndView.addObject("result", "success");
				modelAndView.addObject("message", "이미지 리사이즈 업로드가 완료되었습니다.");
			}
			
		}catch(Exception e) {
			logger.error(e.getMessage(), e);
    		modelAndView.addObject("result", "fail");
    		modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
		}
		
		return modelAndView;
	}
	
	public boolean getNameRepLenChk(String type, String value) {
		
		boolean rtnValue = true;
		
		if(type.equals("name")) {
			
			String tmpNm = value;
			int nmLen = tmpNm.length();
			
			if(nmLen > 12) {
				
				rtnValue = false;
				
			}
			
		}else if(type.equals("rep")) {
			
			String tmpRep = value;
			int repLen = tmpRep.length();
			
			if(repLen > 20) {
				
				rtnValue = false;
				
			}
			
		}
		
		return rtnValue;
	}

}
