hehih 2024-09-19
주소록 그룹삭제 기능 수정 -> grp 테이블에 delete y 처리 후 select에서 where delete='N' 만 가져오게 수정
가져오게 수정
@259f27d6cc57493b2e81f8c66277e5750b8fdb5c
src/main/java/itn/let/mjo/addr/service/AddrVO.java
--- src/main/java/itn/let/mjo/addr/service/AddrVO.java
+++ src/main/java/itn/let/mjo/addr/service/AddrVO.java
@@ -1,138 +1,140 @@
-package itn.let.mjo.addr.service;
-
-import java.util.List;
-
-import itn.com.cmm.ComDefaultVO;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class AddrVO extends ComDefaultVO{
-
-	private static final long serialVersionUID = 1L;
-	
-	private int totcnt = 0;
-	
-	private String addrId;						// 주소록ID
-	private String addrGrpId;					// 주소록그룹ID
-	private String[] addrGrpIds;				// 주소록그룹IDs	
-	private String mberId;						// 일반회원ID
-	private String addrNm;						// 주소록 이름
-	private String addrPhoneNo;					// 휴대폰번호
-	private String addrInfo1;					// 치환1
-	private String addrInfo2;					// 치환2
-	private String addrInfo3;					// 치환3
-	private String addrInfo4;					// 치환4
-	private String addrComment;					// 메모
-	private String deleteYn;					// 삭제여부
-	private String addrGrpNm;					// 주소록 그룹명
-	private String grpDelete;					// 그룹삭제여부
-	private String type;						// 구분
-	private String bookmark;					// 자주보내는번호
-	private String recvStatus;					// 수신여부(S:직접등록, Y:수신승인, W:수신대기, N:수신거부)
-	private String[] mergeGrps;					// 합칠 그룹들 id
-	private String[] sendGrps;					// 내보낼 그룹들 id
-	private String[] copyAddrs;					// 내보낼 주소록들 id
-	
-	private String[] addrIds;
-	private String[] addrPhones;
-	private String[] addrNms;
-	private String[] addrInfo1s;
-	private String[] addrInfo2s;
-	private String[] addrInfo3s;
-	private String[] addrInfo4s;
-	
-	private String searchAddrGrpId;
-	private String startKeyword;
-	private String searchStartDate;
-	private String searchEndDate;
-	
-	private String[] excelDownTitles;
-	
-	@SuppressWarnings("rawtypes")
-	private List addrIdList;
-	
-	String[] phoneList;
-	String[] nameList;
-	String[] info1List;
-	String[] info2List;
-	String[] info3List;
-	String[] info4List;
-	String[] memoList;	
-	
-	private int dupliCnt;
-	
-
-	public String getFieldValue(String field) {
-		if("addrPhoneNo".equals(field)) {
-			return this.addrPhoneNo;
-		} else if("addrNm".equals(field)) {
-			return this.addrNm;
-		} else if("addrGrpNm".equals(field)) {
-			return this.addrGrpNm;
-		} else if("addrComment".equals(field)) {
-			return this.addrComment;
-		} else if("addrInfo1".equals(field)) {
-			return this.addrInfo1;
-		} else if("addrInfo2".equals(field)) {
-			return this.addrInfo2;
-		} else if("addrInfo3".equals(field)) {
-			return this.addrInfo3;
-		} else if("addrInfo4".equals(field)) {
-			return this.addrInfo4;
-		}
-		return "";
-	}
-
-	
-	public String getHeaderName(String field) {
-		if("addrPhoneNo".equals(field)) {
-			return "휴대폰번호";
-		} else if("addrNm".equals(field)) {
-			return "이름";
-		} else if("addrGrpNm".equals(field)) {
-			return "주소록그룹명";
-		} else if("addrComment".equals(field)) {
-			return "메모";
-		} else if("addrInfo1".equals(field)) {
-			return "[*1*]";
-		} else if("addrInfo2".equals(field)) {
-			return "[*2*]";
-		} else if("addrInfo3".equals(field)) {
-			return "[*3*]";
-		} else if("addrInfo4".equals(field)) {
-			return "[*4*]";
-		}
-		return "";
-	}
-
-
-	
-	private String addrGroupNm;
-	private String addrPhone;
-	private String addrName;
-	private String addrRep1;
-	private String addrRep2;
-	private String addrRep3;
-	private String addrRep4;
-
-
-    private int page = 1;  // 기본 값 설정
-    private int size = 10; // 기본 값 설정
-    private int offset; // 기본 값 설정
-    private String name;
-    private String phone;
-    private String rep1;
-    private String rep2;
-    private String rep3;
-    private String rep4;
-    
-    private int batchSize;
-    private int lastProcessedId;
-    
-    
-    
-
-	
-}
+package itn.let.mjo.addr.service;
+
+import java.util.List;
+
+import itn.com.cmm.ComDefaultVO;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class AddrVO extends ComDefaultVO{
+
+	private static final long serialVersionUID = 1L;
+	
+	private int totcnt = 0;
+	
+	private String addrId;						// 주소록ID
+	private String addrGrpId;					// 주소록그룹ID
+	private String[] addrGrpIds;				// 주소록그룹IDs	
+	private String mberId;						// 일반회원ID
+	private String addrNm;						// 주소록 이름
+	private String addrPhoneNo;					// 휴대폰번호
+	private String addrInfo1;					// 치환1
+	private String addrInfo2;					// 치환2
+	private String addrInfo3;					// 치환3
+	private String addrInfo4;					// 치환4
+	private String addrComment;					// 메모
+	private String deleteYn;					// 삭제여부
+	private String addrGrpNm;					// 주소록 그룹명
+	private String grpDelete;					// 그룹삭제여부
+	private String type;						// 구분
+	private String bookmark;					// 자주보내는번호
+	private String recvStatus;					// 수신여부(S:직접등록, Y:수신승인, W:수신대기, N:수신거부)
+	private String[] mergeGrps;					// 합칠 그룹들 id
+	private String[] sendGrps;					// 내보낼 그룹들 id
+	private String[] copyAddrs;					// 내보낼 주소록들 id
+	
+	private String[] addrIds;
+	private String[] addrPhones;
+	private String[] addrNms;
+	private String[] addrInfo1s;
+	private String[] addrInfo2s;
+	private String[] addrInfo3s;
+	private String[] addrInfo4s;
+	
+	private String searchAddrGrpId;
+	private String startKeyword;
+	private String searchStartDate;
+	private String searchEndDate;
+	
+	private String[] excelDownTitles;
+	
+	@SuppressWarnings("rawtypes")
+	private List addrIdList;
+	
+	String[] phoneList;
+	String[] nameList;
+	String[] info1List;
+	String[] info2List;
+	String[] info3List;
+	String[] info4List;
+	String[] memoList;	
+	
+	private int dupliCnt;
+	
+
+	public String getFieldValue(String field) {
+		if("addrPhoneNo".equals(field)) {
+			return this.addrPhoneNo;
+		} else if("addrNm".equals(field)) {
+			return this.addrNm;
+		} else if("addrGrpNm".equals(field)) {
+			return this.addrGrpNm;
+		} else if("addrComment".equals(field)) {
+			return this.addrComment;
+		} else if("addrInfo1".equals(field)) {
+			return this.addrInfo1;
+		} else if("addrInfo2".equals(field)) {
+			return this.addrInfo2;
+		} else if("addrInfo3".equals(field)) {
+			return this.addrInfo3;
+		} else if("addrInfo4".equals(field)) {
+			return this.addrInfo4;
+		}
+		return "";
+	}
+
+	
+	public String getHeaderName(String field) {
+		if("addrPhoneNo".equals(field)) {
+			return "휴대폰번호";
+		} else if("addrNm".equals(field)) {
+			return "이름";
+		} else if("addrGrpNm".equals(field)) {
+			return "주소록그룹명";
+		} else if("addrComment".equals(field)) {
+			return "메모";
+		} else if("addrInfo1".equals(field)) {
+			return "[*1*]";
+		} else if("addrInfo2".equals(field)) {
+			return "[*2*]";
+		} else if("addrInfo3".equals(field)) {
+			return "[*3*]";
+		} else if("addrInfo4".equals(field)) {
+			return "[*4*]";
+		}
+		return "";
+	}
+
+
+	
+	private String addrGroupNm;
+	private String addrPhone;
+	private String addrName;
+	private String addrRep1;
+	private String addrRep2;
+	private String addrRep3;
+	private String addrRep4;
+
+
+    private int page = 1;  // 기본 값 설정
+    private int size = 10; // 기본 값 설정
+    private int offset; // 기본 값 설정
+    private String name;
+    private String phone;
+    private String rep1;
+    private String rep2;
+    private String rep3;
+    private String rep4;
+    
+    private int batchSize;
+    private int lastProcessedId;
+    private int startIndex;
+    private int endIndex;
+    
+    
+    
+
+	
+}
src/main/java/itn/let/mjo/addr/service/impl/AddrDAO.java
--- src/main/java/itn/let/mjo/addr/service/impl/AddrDAO.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrDAO.java
@@ -1,296 +1,296 @@
-package itn.let.mjo.addr.service.impl;
-
-import java.util.List;
-
-import org.springframework.stereotype.Repository;
-
-import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
-import itn.let.mjo.addr.service.AddrVO;
-
-/**
- * 주소록 관리를 위한 데이터 접근 클래스
- * @author ITN
- * @since 2021.04.08
- * @version 1.0
- * @see
- *
- * <pre>
- * << 개정이력(Modification Information) >>
- *   수정일      수정자          수정내용
- *  -------    --------    ---------------------------
- *  2021.04.08  ITN          최초 생성
- *  </pre>
- */
-@Repository("AddrDAO")
-public class AddrDAO extends EgovAbstractDAO {
-	
-	/**
-	 * 주소록 목록
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrList(AddrVO addrVO) throws Exception {
-		return (List<AddrVO>) list("AddrDAO.selectAddrList", addrVO);
-	}
-	
-	public int selectAddrListCount(AddrVO addrVO) throws Exception{
-		return (int)select("AddrDAO.selectAddrListCount", addrVO);
-	}
-	
-	/**
-	 * 주소록 목록(속도개선)
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrNewList(AddrVO addrVO) throws Exception {
-		return (List<AddrVO>) list("AddrDAO.selectAddrNewList", addrVO);
-	}
-	
-	/**
-	 * 주소록 상세보기
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public AddrVO selectAddrDetail(AddrVO addrVO) throws Exception {
-		return (AddrVO) select("AddrDAO.selectAddrDetail", addrVO);
-	}
-	
-	
-	/**
-	 * 주소록 등록
-	 * @param addrVO
-	 * @throws Exception
-	 */
-	public void insertAddr(AddrVO addrVO) throws Exception {
-		insert("AddrDAO.insertAddr", addrVO);
-	}
-
-	/**
-	 * 주소록 수정
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int updateAddr(AddrVO addrVO) throws Exception {
-		return update("AddrDAO.updateAddr", addrVO);
-	}
-	
-	/**
-	 * 주소록 그룹 수정
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int updateAddrGrp(AddrVO addrVO) throws Exception {
-		return update("AddrDAO.updateAddrGrp", addrVO);
-	}	
-	
-	
-	/**
-	 * 주소록 수정
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int updateMemoAddr(AddrVO addrVO) throws Exception {
-		return update("AddrDAO.updateMemoAddr", addrVO);
-	}	
-	
-	
-	
-	/**
-	 * 주소록 수정 By Admin
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int updateAddrByAdmin(AddrVO addrVO) throws Exception {
-		return update("AddrDAO.updateAddrByAdmin", addrVO);
-	}	
-	
-	/**
-	 * 주소록 삭제
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int deleteAddr(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddr", addrVO);
-	}
-
-	/**
-	 * 주소록 삭제 By Admin
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int deleteAddrByAdmin(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddrByAdmin", addrVO);
-	}
-	
-	/**
-	 * 주소록 삭제 By Admin By Grpid
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int deleteAddrByAdminByGrpid(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddrByAdminByGrpid", addrVO);
-	}
-		
-	
-	/**
-	 * 자주찾는번호 주소록 리스트 불러오기
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrBasicGrpList(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectAddrBasicGrpList", addrVO);
-	}
-
-	
-	/**
-	 * 주소록 전체 개수 조회
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int selectAddrTotalCount(AddrVO addrVO) throws Exception{
-		return (int)select("AddrDAO.selectAddrTotalCount", addrVO);
-	}
-
-	/**
-	 * 주소록 복사하기 (select insert)
-	 * @param addrVO
-	 * @throws Exception
-	 */
-	public void insertCopyAddr(AddrVO addrVO) throws Exception{
-		update("AddrDAO.insertCopyAddr", addrVO);
-	}
-
-	/**
-	 * 그룹 합치기 - 주소록 데이터 그룹id 변경
-	 * @param addrVO
-	 * @throws Exception
-	 */
-	public void updateAddrsGrp(AddrVO addrVO) throws Exception{
-		update("AddrDAO.updateAddrsGrp", addrVO);
-	}
-	
-	/**
-	 * 주소록 등록 총 건수 및 정보 불러오기
-	 * @param addrVO
-	 * @throws Exception
-	 */
-	public List<?> selectAddrTotCntInfByUserId(AddrVO addrVO) throws Exception{
-		
-		return (List<?>) list("AddrDAO.selectAddrTotCntInfByUserId", addrVO);
-	}
-	
-	public int insertAddrList(List<AddrVO> addrList) throws Exception{
-		
-		return update("AddrDAO.insertAddrList", addrList);
-	}
-
-	public int selectDuplAddrCnt(AddrVO addrVO) throws Exception{
-		return (Integer)select("AddrDAO.selectDuplAddrCnt", addrVO);
-	}
-
-	
-	/**
-	 * 주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도)
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectPhoneNumInAddrGroup(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectPhoneNumInAddrGroup", addrVO);
-	}
-
-	public void insertCopyAddrs(AddrVO addrVO) throws Exception{
-		insert("AddrDAO.insertCopyAddrs", addrVO);
-	}
-	
-	/**
-	 * 선택한 주소록 문자전송 화면으로 보내기
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrDataList(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectAddrDataList", addrVO);
-	}
-
-	// 주소록 그룹별 중복 연락처 삭제
-	public int deleteAddrDupliList(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddrDupliList", addrVO);
-	}
-
-	// 주소록 그룹별 중복 연락처 삭제
-	public int deleteAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddrDupliListByGrpnm", addrVO);
-	}
-	
-	// 주소록 전체 중복 연락처 중 한개만 남기고 삭제
-	public int deleteAddrDupliListByAll(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteAddrDupliListByAll", addrVO);
-	}
-	
-	// 주소록 그룹별 중복 연락처 리스트 불러오기
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrDupliList(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectAddrDupliList", addrVO);
-	}
-	
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrDupliListByGrpnm(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectAddrDupliListByGrpnm", addrVO);
-	}
-	
-	// 주소록 전체 중복 연락처 수
-	public int selectAddrDupliListByAllCnt(AddrVO addrVO) throws Exception{
-		return (Integer)select("AddrDAO.selectAddrDupliListByAllCnt", addrVO);
-	}
-	
-	// 주소록 전체 중복 연락처 목록
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectAddrDupliListByAll(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectAddrDupliListByAll", addrVO);
-	}
-	
-	// TEMP 주소록 중복 연락처 목록
-	@SuppressWarnings("unchecked")
-	public List<AddrVO> selectTempAddrDupliList(AddrVO addrVO) throws Exception{
-		return (List<AddrVO>) list("AddrDAO.selectTempAddrDupliList", addrVO);
-	}
-	
-	// TEMP 주소록 삭제
-	public int deleteTempAddr(AddrVO addrVO) throws Exception {
-		return delete("AddrDAO.deleteTempAddr", addrVO);
-	}	
-	
-	// TEMP 주소록 대량등록
-	public int insertTempAddrList(List<AddrVO> addrList) throws Exception{
-		return update("AddrDAO.insertTempAddrList", addrList);
-	}
-	
-	// 주소록 대량등록 By Temp 주소록
-	public int insertAddrByTempAddr(AddrVO addrVO) throws Exception {
-		return update("AddrDAO.insertAddrByTempAddr", addrVO);
-	}
-
-	public int getAddrCount(AddrVO addrVO) {
-		return (Integer)select("AddrDAO.getAddrCount", addrVO);
-	}
-
-	
-}
+package itn.let.mjo.addr.service.impl;
+
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
+import itn.let.mjo.addr.service.AddrVO;
+
+/**
+ * 주소록 관리를 위한 데이터 접근 클래스
+ * @author ITN
+ * @since 2021.04.08
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *   수정일      수정자          수정내용
+ *  -------    --------    ---------------------------
+ *  2021.04.08  ITN          최초 생성
+ *  </pre>
+ */
+@Repository("AddrDAO")
+public class AddrDAO extends EgovAbstractDAO {
+	
+	/**
+	 * 주소록 목록
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrList(AddrVO addrVO) throws Exception {
+		return (List<AddrVO>) list("AddrDAO.selectAddrList", addrVO);
+	}
+	
+	public int selectAddrListCount(AddrVO addrVO) throws Exception{
+		return (int)select("AddrDAO.selectAddrListCount", addrVO);
+	}
+	
+	/**
+	 * 주소록 목록(속도개선)
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrNewList(AddrVO addrVO) throws Exception {
+		return (List<AddrVO>) list("AddrDAO.selectAddrNewList", addrVO);
+	}
+	
+	/**
+	 * 주소록 상세보기
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public AddrVO selectAddrDetail(AddrVO addrVO) throws Exception {
+		return (AddrVO) select("AddrDAO.selectAddrDetail", addrVO);
+	}
+	
+	
+	/**
+	 * 주소록 등록
+	 * @param addrVO
+	 * @throws Exception
+	 */
+	public void insertAddr(AddrVO addrVO) throws Exception {
+		insert("AddrDAO.insertAddr", addrVO);
+	}
+
+	/**
+	 * 주소록 수정
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int updateAddr(AddrVO addrVO) throws Exception {
+		return update("AddrDAO.updateAddr", addrVO);
+	}
+	
+	/**
+	 * 주소록 그룹 수정
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int updateAddrGrp(AddrVO addrVO) throws Exception {
+		return update("AddrDAO.updateAddrGrp", addrVO);
+	}	
+	
+	
+	/**
+	 * 주소록 수정
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int updateMemoAddr(AddrVO addrVO) throws Exception {
+		return update("AddrDAO.updateMemoAddr", addrVO);
+	}	
+	
+	
+	
+	/**
+	 * 주소록 수정 By Admin
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int updateAddrByAdmin(AddrVO addrVO) throws Exception {
+		return update("AddrDAO.updateAddrByAdmin", addrVO);
+	}	
+	
+	/**
+	 * 주소록 삭제
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int deleteAddr(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddr", addrVO);
+	}
+
+	/**
+	 * 주소록 삭제 By Admin
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int deleteAddrByAdmin(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddrByAdmin", addrVO);
+	}
+	
+	/**
+	 * 주소록 삭제 By Admin By Grpid
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int deleteAddrByAdminByGrpid(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddrByAdminByGrpid", addrVO);
+	}
+		
+	
+	/**
+	 * 자주찾는번호 주소록 리스트 불러오기
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrBasicGrpList(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectAddrBasicGrpList", addrVO);
+	}
+
+	
+	/**
+	 * 주소록 전체 개수 조회
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int selectAddrTotalCount(AddrVO addrVO) throws Exception{
+		return (int)select("AddrDAO.selectAddrTotalCount", addrVO);
+	}
+
+	/**
+	 * 주소록 복사하기 (select insert)
+	 * @param addrVO
+	 * @throws Exception
+	 */
+	public void insertCopyAddr(AddrVO addrVO) throws Exception{
+		update("AddrDAO.insertCopyAddr", addrVO);
+	}
+
+	/**
+	 * 그룹 합치기 - 주소록 데이터 그룹id 변경
+	 * @param addrVO
+	 * @throws Exception
+	 */
+	public void updateAddrsGrp(AddrVO addrVO) throws Exception{
+		update("AddrDAO.updateAddrsGrp", addrVO);
+	}
+	
+	/**
+	 * 주소록 등록 총 건수 및 정보 불러오기
+	 * @param addrVO
+	 * @throws Exception
+	 */
+	public List<?> selectAddrTotCntInfByUserId(AddrVO addrVO) throws Exception{
+		
+		return (List<?>) list("AddrDAO.selectAddrTotCntInfByUserId", addrVO);
+	}
+	
+	public int insertAddrList(List<AddrVO> addrList) throws Exception{
+		
+		return update("AddrDAO.insertAddrList", addrList);
+	}
+
+	public int selectDuplAddrCnt(AddrVO addrVO) throws Exception{
+		return (Integer)select("AddrDAO.selectDuplAddrCnt", addrVO);
+	}
+
+	
+	/**
+	 * 주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도)
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectPhoneNumInAddrGroup(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectPhoneNumInAddrGroup", addrVO);
+	}
+
+	public void insertCopyAddrs(AddrVO addrVO) throws Exception{
+		insert("AddrDAO.insertCopyAddrs", addrVO);
+	}
+	
+	/**
+	 * 선택한 주소록 문자전송 화면으로 보내기
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrDataList(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectAddrDataList", addrVO);
+	}
+
+	// 주소록 그룹별 중복 연락처 삭제
+	public int deleteAddrDupliList(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddrDupliList", addrVO);
+	}
+
+	// 주소록 그룹별 중복 연락처 삭제
+	public int deleteAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddrDupliListByGrpnm", addrVO);
+	}
+	
+	// 주소록 전체 중복 연락처 중 한개만 남기고 삭제
+	public int deleteAddrDupliListByAll(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteAddrDupliListByAll", addrVO);
+	}
+	
+	// 주소록 그룹별 중복 연락처 리스트 불러오기
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrDupliList(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectAddrDupliList", addrVO);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrDupliListByGrpnm(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectAddrDupliListByGrpnm", addrVO);
+	}
+	
+	// 주소록 전체 중복 연락처 수
+	public int selectAddrDupliListByAllCnt(AddrVO addrVO) throws Exception{
+		return (Integer)select("AddrDAO.selectAddrDupliListByAllCnt", addrVO);
+	}
+	
+	// 주소록 전체 중복 연락처 목록
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectAddrDupliListByAll(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectAddrDupliListByAll", addrVO);
+	}
+	
+	// TEMP 주소록 중복 연락처 목록
+	@SuppressWarnings("unchecked")
+	public List<AddrVO> selectTempAddrDupliList(AddrVO addrVO) throws Exception{
+		return (List<AddrVO>) list("AddrDAO.selectTempAddrDupliList", addrVO);
+	}
+	
+	// TEMP 주소록 삭제
+	public int deleteTempAddr(AddrVO addrVO) throws Exception {
+		return delete("AddrDAO.deleteTempAddr", addrVO);
+	}	
+	
+	// TEMP 주소록 대량등록
+	public int insertTempAddrList(List<AddrVO> addrList) throws Exception{
+		return update("AddrDAO.insertTempAddrList", addrList);
+	}
+	
+	// 주소록 대량등록 By Temp 주소록
+	public int insertAddrByTempAddr(AddrVO addrVO) throws Exception {
+		return update("AddrDAO.insertAddrByTempAddr", addrVO);
+	}
+
+	public int getAddrCount(AddrVO addrVO) {
+		return (Integer)select("AddrDAO.getAddrCount", addrVO);
+	}
+
+	
+}
src/main/java/itn/let/mjo/addr/service/impl/AddrGroupDAO.java
--- src/main/java/itn/let/mjo/addr/service/impl/AddrGroupDAO.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrGroupDAO.java
@@ -1,120 +1,124 @@
-package itn.let.mjo.addr.service.impl;
-
-import java.util.List;
-
-import org.springframework.stereotype.Repository;
-
-import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
-import itn.let.mjo.addr.service.AddrGroupVO;
-
-/**
- * 주소록 관리를 위한 데이터 접근 클래스
- * @author ITN
- * @since 2021.04.08
- * @version 1.0
- * @see
- *
- * <pre>
- * << 개정이력(Modification Information) >>
- *   수정일      수정자          수정내용
- *  -------    --------    ---------------------------
- *  2021.04.08  ITN          최초 생성
- *  </pre>
- */
-@Repository("AddrGroupDAO")
-public class AddrGroupDAO extends EgovAbstractDAO {
-	
-	/**
-	 * 주소록 그룹 목록
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	@SuppressWarnings("unchecked")
-	public List<AddrGroupVO> selectAddrGroupList(AddrGroupVO addrGroupVO) throws Exception {
-		return (List<AddrGroupVO>) list("AddrGroupDAO.selectAddrGroupList", addrGroupVO);
-	}
-	
-	/**
-	 * 주소록 그룹 상세보기
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	public AddrGroupVO selectAddrGroupDetail(AddrGroupVO addrGroupVO) throws Exception {
-		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupDetail", addrGroupVO);
-	}
-
-	// 주소록 그룹 카운트 조회(전체)
-	public AddrGroupVO selectAddrGroupTotCnt(AddrGroupVO addrGroupVO) throws Exception {
-		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupTotCnt", addrGroupVO);
-	}		
-	
-	// 주소록 그룹 카운트 조회(그룹미지정)
-	public AddrGroupVO selectAddrGroupNogrpCnt(AddrGroupVO addrGroupVO) throws Exception {
-		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupNogrpCnt", addrGroupVO);
-	}		
-	
-	// 주소록 그룹 카운트 조회(자주보내는 번호)
-	public AddrGroupVO selectAddrGroupBookmarkCnt(AddrGroupVO addrGroupVO) throws Exception {
-		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupBookmarkCnt", addrGroupVO);
-	}			
-
-	/**
-	 * 주소록 그룹 등록
-	 * @param addrGroupVO
-	 * @throws Exception
-	 */
-	public String insertAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
-		return (String) insert("AddrGroupDAO.insertAddrGroup", addrGroupVO);
-	}
-	
-	
-	/**
-	 * 주소록 그룹 수정
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int updateAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
-		return update("AddrGroupDAO.updateAddrGroup", addrGroupVO);
-	}
-	
-	/**
-	 * 주소록 그룹 삭제
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int deleteAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
-		return delete("AddrGroupDAO.deleteAddrGroup", addrGroupVO);
-	}
-	
-	/**
-	 * 주소록 그룹 삭제
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	public int deleteAddrGroupByAdmin(AddrGroupVO addrGroupVO) throws Exception {
-		return delete("AddrGroupDAO.deleteAddrGroupByAdmin", addrGroupVO);
-	}	
-	
-	/**
-	 * 주소록그룹명 중복체크
-	 * @param addrGroupVO
-	 * @return
-	 */
-	public int selectDuplAddrGroupCnt(AddrGroupVO addrGroupVO) throws Exception{
-		return (Integer)select("AddrGroupDAO.selectDuplAddrGroupCnt", addrGroupVO);
-	}
- 
-	/**
-	 * 주소록 그룹 다음 순서번호 확인
-	 * @param addrGroupVO
-	 * @return
-	 */
-	public int selectMaxOrderNumber(AddrGroupVO addrGroupVO) throws Exception{
-		return (Integer)select("AddrGroupDAO.selectMaxOrderNumber", addrGroupVO);
-	}
-}
+package itn.let.mjo.addr.service.impl;
+
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
+import itn.let.mjo.addr.service.AddrGroupVO;
+
+/**
+ * 주소록 관리를 위한 데이터 접근 클래스
+ * @author ITN
+ * @since 2021.04.08
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *   수정일      수정자          수정내용
+ *  -------    --------    ---------------------------
+ *  2021.04.08  ITN          최초 생성
+ *  </pre>
+ */
+@Repository("AddrGroupDAO")
+public class AddrGroupDAO extends EgovAbstractDAO {
+	
+	/**
+	 * 주소록 그룹 목록
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AddrGroupVO> selectAddrGroupList(AddrGroupVO addrGroupVO) throws Exception {
+		return (List<AddrGroupVO>) list("AddrGroupDAO.selectAddrGroupList", addrGroupVO);
+	}
+	
+	/**
+	 * 주소록 그룹 상세보기
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	public AddrGroupVO selectAddrGroupDetail(AddrGroupVO addrGroupVO) throws Exception {
+		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupDetail", addrGroupVO);
+	}
+
+	// 주소록 그룹 카운트 조회(전체)
+	public AddrGroupVO selectAddrGroupTotCnt(AddrGroupVO addrGroupVO) throws Exception {
+		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupTotCnt", addrGroupVO);
+	}		
+	
+	// 주소록 그룹 카운트 조회(그룹미지정)
+	public AddrGroupVO selectAddrGroupNogrpCnt(AddrGroupVO addrGroupVO) throws Exception {
+		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupNogrpCnt", addrGroupVO);
+	}		
+	
+	// 주소록 그룹 카운트 조회(자주보내는 번호)
+	public AddrGroupVO selectAddrGroupBookmarkCnt(AddrGroupVO addrGroupVO) throws Exception {
+		return (AddrGroupVO) select("AddrGroupDAO.selectAddrGroupBookmarkCnt", addrGroupVO);
+	}			
+
+	/**
+	 * 주소록 그룹 등록
+	 * @param addrGroupVO
+	 * @throws Exception
+	 */
+	public String insertAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
+		return (String) insert("AddrGroupDAO.insertAddrGroup", addrGroupVO);
+	}
+	
+	
+	/**
+	 * 주소록 그룹 수정
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int updateAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
+		return update("AddrGroupDAO.updateAddrGroup", addrGroupVO);
+	}
+	
+	/**
+	 * 주소록 그룹 삭제
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int deleteAddrGroup(AddrGroupVO addrGroupVO) throws Exception {
+		return delete("AddrGroupDAO.deleteAddrGroup", addrGroupVO);
+	}
+	
+	/**
+	 * 주소록 그룹 삭제
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	public int deleteAddrGroupByAdmin(AddrGroupVO addrGroupVO) throws Exception {
+		return delete("AddrGroupDAO.deleteAddrGroupByAdmin", addrGroupVO);
+	}	
+	
+	/**
+	 * 주소록그룹명 중복체크
+	 * @param addrGroupVO
+	 * @return
+	 */
+	public int selectDuplAddrGroupCnt(AddrGroupVO addrGroupVO) throws Exception{
+		return (Integer)select("AddrGroupDAO.selectDuplAddrGroupCnt", addrGroupVO);
+	}
+ 
+	/**
+	 * 주소록 그룹 다음 순서번호 확인
+	 * @param addrGroupVO
+	 * @return
+	 */
+	public int selectMaxOrderNumber(AddrGroupVO addrGroupVO) throws Exception{
+		return (Integer)select("AddrGroupDAO.selectMaxOrderNumber", addrGroupVO);
+	}
+
+	public void deleteAddrGroup_advc(AddrGroupVO addrGroupVO) {
+		update("AddrGroupDAO.deleteAddrGroup_advc", addrGroupVO);
+	}
+}
src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
--- src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
+++ src/main/java/itn/let/mjo/addr/service/impl/AddrServiceImpl.java
@@ -1,657 +1,634 @@
-package itn.let.mjo.addr.service.impl;
-
-import java.nio.charset.Charset;
-import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Resource;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Service;
-
-import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
-import egovframework.rte.fdl.idgnr.EgovIdGnrService;
-import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
-import itn.com.cmm.LoginVO;
-import itn.let.mail.service.StatusResponse;
-import itn.let.mjo.addr.service.AddrGroupVO;
-import itn.let.mjo.addr.service.AddrService;
-import itn.let.mjo.addr.service.AddrTransHistVO;
-import itn.let.mjo.addr.service.AddrVO;
-
-/**
- * 주소록 관리를 위한 서비스 구현 클래스
- * @author ITN
- * @since 2021.04.08
- * @version 1.0
- * @see
- *
- * <pre>
- * << 개정이력(Modification Information) >>
- *   수정일      수정자          수정내용
- *  -------    --------    ---------------------------
- *  2021.04.08  ITN          최초 생성
- *  </pre>
- */
-@Service("AddrService")
-public class AddrServiceImpl  extends EgovAbstractServiceImpl implements AddrService {
-
-	@Resource(name = "AddrDAO")
-	private AddrDAO addrDAO;
-
-	@Resource(name = "AddrGroupDAO")
-	private AddrGroupDAO addrGroupDAO;
-	
-	@Resource(name = "AddrTransHistDAO")
-	private AddrTransHistDAO addrTransHistDAO;
-
-	@Resource(name = "egovAddrTransHistIdGnrService")
-    private EgovIdGnrService idgenAddrTransHistId;
-
-
-
-    private static final String PHONE_REGEX = "^(01[016789]-?\\d{3,4}-?\\d{4})$";
-    private static final Pattern PHONE_PATTERN = Pattern.compile(PHONE_REGEX);
-    private static final Charset EUC_KR = Charset.forName("EUC-KR");
-//    private static final int MAX_ADDR_CNT = 500000;
-    //임시 500만개
-    private static final int MAX_SINGLE_ENTRY_CNT = 350000;
-    private static final int MAX_ADDR_CNT = 10000000;
-    private static final int BATCH_SIZE = 5000;
-    private static final int THREAD_COUNT = 3;
-	
-	
-	public List<AddrVO> selectAddrList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrList(addrVO);
-	}
-	
-	@Override
-	public int selectAddrListCount(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrListCount(addrVO);
-	}
-	
-	public List<AddrVO> selectAddrNewList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrNewList(addrVO);
-	}	
-	
-	public AddrVO selectAddrDetail(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDetail(addrVO);
-	}
-	
-	public void insertAddr(AddrVO addrVO) throws Exception {
-		addrDAO.insertAddr(addrVO);
-	}
-	
-	public int updateAddr(AddrVO addrVO) throws Exception{
-		return  addrDAO.updateAddr(addrVO);
-	}
-	
-	public int updateAddrGrp(AddrVO addrVO) throws Exception{
-		return  addrDAO.updateAddrGrp(addrVO);
-	}	
-	
-	public int updateMemoAddr(AddrVO addrVO) throws Exception{
-		return  addrDAO.updateMemoAddr(addrVO);
-	}
-	
-	public int updateAddrByAdmin(AddrVO addrVO) throws Exception{
-		return  addrDAO.updateAddrByAdmin(addrVO);
-	}	
-	
-	public int deleteAddr(AddrVO addrVO) throws Exception{
-		return  addrDAO.deleteAddr(addrVO);
-	}
-	
-	public int deleteAddrByAdmin(AddrVO addrVO) throws Exception{
-		return  addrDAO.deleteAddrByAdmin(addrVO);
-	}	
-
-	public int deleteAddrByAdminAll(AddrVO addrVO) throws Exception{
-		int rtnCount = 0;
-		
-		for (String addrId : addrVO.getAddrIds()) {
-			addrVO.setAddrId(addrId);
-			rtnCount += addrDAO.deleteAddrByAdmin(addrVO);
-		}
-
-		return  rtnCount;
-	}	
-	
-	public int deleteAddrByAdminByGrpid(AddrVO addrVO) throws Exception{
-		return  addrDAO.deleteAddrByAdminByGrpid(addrVO);
-	}	
-	
-	public int deleteAddrByAdminByGrpidAll(AddrVO addrVO) throws Exception{
-		int rtnCount = 0;
-		
-		for (String addrGrpId : addrVO.getAddrGrpIds()) {
-			addrVO.setAddrGrpId(addrGrpId);
-			rtnCount += addrDAO.deleteAddrByAdminByGrpid(addrVO);
-		}
-
-		return  rtnCount;
-	}	
-	
-	@Override
-	public List<AddrVO> selectAddrBasicGrpList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrBasicGrpList(addrVO);
-	}
-
-	@Override
-	public int selectAddrTotalCount(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrTotalCount(addrVO);
-	}
-
-	@Override
-	public void insertCopyAddr(AddrVO addrVO) throws Exception {
-		addrDAO.insertCopyAddr(addrVO);
-	}
-
-	@Override
-	public String updateAddrAnotherMember(AddrVO addrVO, AddrGroupVO addrGroupVO, 
-			AddrTransHistVO addrTransHistVO) throws Exception {
-
-		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "HHmmss", Locale.KOREA );
-		Date currentTime = new Date ();
-		String mTime = mSimpleDateFormat.format ( currentTime );
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-    	addrVO.setMberId(user.getId());
-    	addrTransHistVO.setSendMberId(user.getId());
-    	
-    	String successCd ="";
-		int listSize = addrVO.getSendGrps().length;
-		
-		for(int i=0; i<listSize; i++ ) {
-			
-			try {
-				
-				/**
-				 * 1. 이전할 주소록그룹명_시분초 로 받는 회원의 새 주소록 그룹을 만듦
-				 */
-				//전송할 그룹의 id를 검색해 올 아이디로 set
-				addrGroupVO.setAddrGrpId(addrVO.getSendGrps()[i]);
-				
-				//vo에 db조회해온 상세데이터를 set함  - 주소록명 가지고오기 위함
-				addrGroupVO = addrGroupDAO.selectAddrGroupDetail(addrGroupVO);
-				
-	
-				
-				AddrGroupVO recvAddrGroupVO = new AddrGroupVO();
-				
-				//보낼 주소록그룹의 정보를 세팅
-				recvAddrGroupVO.setMberId(addrTransHistVO.getRecvMberId());
-				//기존 그룹명_(시분초) 로 새로운 그룹의 이름을 정함
-				recvAddrGroupVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm()+"_"+mTime); 
-				
-				String newGrpId = addrGroupDAO.insertAddrGroup(recvAddrGroupVO);
-				
-				/**
-				 * 2. 주소록그룹ID를 가진 주소록들을 가져와 받는 유저의 주소록 insert
-				 */
-			
-				AddrVO recvAddrVO = new AddrVO();
-				//보낼 주소록 정보를 set
-				recvAddrVO.setMberId(addrVO.getMberId());
-				recvAddrVO.setAddrGrpId(addrVO.getSendGrps()[i]);
-				recvAddrVO.setRecordCountPerPage(100000);
-				recvAddrVO.setFirstIndex(0);
-				
-				List<AddrVO> recvAddrList = addrDAO.selectAddrList(recvAddrVO);
-				
-				for(int j=0; j<recvAddrList.size(); j++) {
-					try {
-						recvAddrList.get(j).setRecvStatus("W");
-						
-						recvAddrList.get(j).setMberId(addrTransHistVO.getRecvMberId());
-						//새로만든 그룹의 아이디를 세팅
-						recvAddrList.get(j).setAddrGrpId(newGrpId);
-						addrDAO.insertAddr(recvAddrList.get(j));
-						
-					}catch(Exception e) {
-						e.printStackTrace();
-					}
-					
-				}
-				
-				/**
-				 * 3. 주소록 이전 히스토리 테이블에 등록 
-				 */
-				addrTransHistVO.setAddrGrpId(newGrpId);
-				addrTransHistVO.setAddrTransHistId(idgenAddrTransHistId.getNextStringId());
-				addrTransHistVO.setSendAddrCnt(recvAddrList.size());
-				
-				addrTransHistDAO.insertAddrTransHist(addrTransHistVO);
-				
-				if(i==0) successCd = "Y";
-				if(i!=0) successCd += ",Y";
-				
-			} catch(Exception e) {
-				e.printStackTrace();
-				
-				if(i==0) successCd = "N";
-				if(i!=0) successCd += ",N";
-			}
-			
-		}
-		
-	
-		
-		return successCd;
-	}
-	
-	//주소록 등록 총 건수 및 정보 불러오기
-	public List<?> selectAddrTotCntInfByUserId(AddrVO addrVO) throws Exception{
-		
-		return addrDAO.selectAddrTotCntInfByUserId(addrVO);
-	}
-	
-	//문자발송에서 수신자 리스트를 주소록에 등록하기
-	public int insertAddrList(List<AddrVO> addrList) throws Exception{
-		
-		return addrDAO.insertAddrList(addrList);
-	}
-	
-	@Override
-	public int selectDuplAddrCnt(AddrVO addrVO) throws Exception {
-		return addrDAO.selectDuplAddrCnt(addrVO);
-	}
-	
-	//주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도)
-	public List<?> selectPhoneNumInAddrGroup(AddrVO addrVO) throws Exception{
-		return addrDAO.selectPhoneNumInAddrGroup(addrVO);
-	}
-
-	//선택한 주소록 문자전송 화면으로 보내기
-	@Override
-	public List<AddrVO> selectAddrDataList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDataList(addrVO);
-	}
-
-	// 주소록 그룹별 중복 연락처 삭제
-	public int deleteAddrDupliList(AddrVO addrVO) throws Exception {
-		int rtnCnt = 0;
-		
-		for (int i = 0; i < 20; i++) {
-			// 주소록 그룹별 중복 연락처 목록
-			List<AddrVO> addrDupliList = selectAddrDupliList(addrVO);
-			
-			if (addrDupliList.size() > 0) {
-				rtnCnt += addrDAO.deleteAddrDupliList(addrVO);
-			}
-			else {
-				break;
-			}
-		}		
-		
-		return rtnCnt;
-	}
-
-	// 주소록 그룹별 중복 연락처 삭제
-	public int deleteAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
-		int rtnCnt = 0;
-		
-		for (int i = 0; i < 20; i++) {
-			// 주소록 그룹별 중복 연락처 목록
-			List<AddrVO> addrDupliList = selectAddrDupliListByGrpnm(addrVO);
-			
-			if (addrDupliList.size() > 0) {
-				rtnCnt += addrDAO.deleteAddrDupliListByGrpnm(addrVO);
-			}
-			else {
-				break;
-			}
-		}		
-		
-		return rtnCnt;
-	}	
-	
-	// 주소록 전체 중복 연락처 중 한개만 남기고 삭제
-	public int deleteAddrDupliListByAll(AddrVO addrVO) throws Exception {
-		int rtnCnt = 0;
-		
-		for (int i = 0; i < 20; i++) {
-			if (selectAddrDupliListByAllCnt(addrVO) > 0) {
-				rtnCnt += addrDAO.deleteAddrDupliListByAll(addrVO);
-			}
-			else {
-				break;
-			}
-		}		
-		
-		return rtnCnt;
-	}		
-	
-	
-	// 주소록 그룹별 중복 연락처 리스트 불러오기
-	@Override
-	public List<AddrVO> selectAddrDupliList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDupliList(addrVO);
-	}
-
-	// 주소록 그룹별 중복 연락처 리스트 불러오기
-	@Override
-	public List<AddrVO> selectAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDupliListByGrpnm(addrVO);
-	}
-	
-	// 주소록 전체 중복 연락처 수
-	@Override
-	public int selectAddrDupliListByAllCnt(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDupliListByAllCnt(addrVO);
-	}	
-	
-	// 주소록 전체 중복 연락처 목록
-	@Override
-	public List<AddrVO> selectAddrDupliListByAll(AddrVO addrVO) throws Exception {
-		return addrDAO.selectAddrDupliListByAll(addrVO);
-	}
-	
-	// TEMP 주소록 중복 연락처 목록
-	@Override
-	public List<AddrVO> selectTempAddrDupliList(AddrVO addrVO) throws Exception {
-		return addrDAO.selectTempAddrDupliList(addrVO);
-	}
-	
-	// TEMP 주소록 삭제
-	public int deleteTempAddr(AddrVO addrVO) throws Exception{
-		return  addrDAO.deleteTempAddr(addrVO);
-	}	
-	
-	// TEMP 주소록 대량등록
-	public int insertTempAddrList(List<AddrVO> addrList) throws Exception{
-		return addrDAO.insertTempAddrList(addrList);
-	}	
-
-	// 주소록 대량등록 By Temp 주소록
-	public int insertAddrByTempAddr(AddrVO addrVO) throws Exception {
-		return addrDAO.insertAddrByTempAddr(addrVO);
-	}
-	
-	// 주소록 대량등록 By Temp 주소록 All
-	public int insertAddrByTempAddrAll(List<AddrVO> addrList, AddrVO addrVO) throws Exception{
-		int rtnVal = 0;
-
-        // Step 1. TEMP 주소록 삭제
-        deleteTempAddr(addrVO);
-        
-        // Step 2. TEMP 주소록 대량등록
-		insertTempAddrList(addrList);
-		
-		// Step 3. 주소록 대량등록 By Temp 주소록
-		rtnVal = insertAddrByTempAddr(addrVO);
-		
-		return rtnVal;
-	}
-
-	@Override
-	public StatusResponse addrMassInsertByTempAjax_advc(List<AddrVO> addrListVO, String userId) throws Exception {
-		
-	
-    	
-		// data init
-    	// For-each loop
-		for (AddrVO addr : addrListVO) { addr.setMberId(userId); }
-
-		
-		
-		if(addrListVO.size() > MAX_SINGLE_ENTRY_CNT) {
-			return new StatusResponse(
-					HttpStatus.BAD_REQUEST
-					, "주소록은 한번에 100만개까지만 등록이 가능합니다."
-					, LocalDateTime.now()
-					);
-			
-		}
-		// step1 현재 주소록 갯수 조회
-
-		//회원별 주소록 전체 갯수 조회
-		int addrBefCnt = addrDAO.selectAddrTotalCount(addrListVO.get(0));    		
-		int addrNewCnt = addrListVO.size();	//신규 추가할 주소록 갯수
-		int sumAddrCnt = addrBefCnt + addrNewCnt;	
-
-		// step1-1 총 갯수가 (주소록 갯수 + 신규 주소록)50만건 체크
-		if(sumAddrCnt > MAX_ADDR_CNT) {
-			return new StatusResponse(
-							HttpStatus.BAD_REQUEST
-							, "주소록은 총 1000만개까지만 등록이 가능합니다."
-							, LocalDateTime.now()
-							);
-					
-		}
-
-		// step2 신규 주소록 생성 및 북마크 체크
-		// 		=> AddrGrpId
-		//
-		if ("NEW".equals(addrListVO.get(0).getAddrGrpId())) {
-			
-			AddrGroupVO addrGroupVO = new AddrGroupVO();
-			addrGroupVO.setMberId(userId);
-			addrGroupVO.setAddrGrpNm(addrListVO.get(0).getAddrGrpNm());
-			// 정렬순서
-			
-			int nextOrderNumber = addrGroupDAO.selectMaxOrderNumber(addrGroupVO);
-			addrGroupVO.setGrpOrder(nextOrderNumber);
-			
-			addrGroupDAO.insertAddrGroup(addrGroupVO);
-			
-			// 신규 추가한 그룹아이디
-    		for (AddrVO addr : addrListVO) { addr.setAddrGrpId(addrGroupVO.getAddrGrpId()); }
-    		
-		}
-		else if ("bookmark".equals(addrListVO.get(0).getAddrGrpId())) 
-		{
-    		for (AddrVO addr : addrListVO) { addr.setBookmark("Y"); addr.setAddrGrpId("0"); }
-		} 
-		else 
-		{
-			for (AddrVO addr : addrListVO) { addr.setBookmark("N"); }
-		} 
-		
-		// step4-1 true 
-		// 		=> 폰번호 빼고 바이트 체크해서 20byte만 짜르고 넣기
-		// 		=> 폰번호는 유효성 체크 하기
-
-        long startTime = System.currentTimeMillis();
-		// 유효성 체크 및 하이픈 제거, 유효하지 않은 번호는 리스트에서 제거
-		// 나머지 필드들 20byte (euc-kr) 체크 후 넘으면 자르기
-		AtomicInteger invalid = new AtomicInteger(0); // 스레드-안전(thread-safe)하게 정수 값을 업데이트할 수 있는 기능을 제공
-		addrListVO.removeIf(addr -> {
-			String phoneNo = addr.getAddrPhoneNo();
-//			phoneNo = phoneNo != null ? phoneNo.replaceAll("-", "") : "";
-//			System.out.println("phoneNo : "+ phoneNo);
-			if (isValidPhoneNumber(phoneNo)) {
-				addr.setAddrPhoneNo(phoneNo); // 하이픈이 제거된 유효한 번호 설정
-				trimFieldsBytes(addr); // 다른 필드들에 대한 20바이트 체크 및 자르기
-				return false; // 유효한 번호는 제거하지 않음
-			} else {
-//				System.out.println(phoneNo + " is an invalid phone number. Removing from list.");
-		        invalid.getAndIncrement(); // 유효하지 않은 번호 개수 증가
-				return true; // 유효하지 않은 번호는 제거
-			}
-        });
-
-
-        long endTime = System.currentTimeMillis();
-        double executionTime = (endTime - startTime) / 1000.0;
-        System.out.println(" number chk Execution time: " + executionTime + " seconds");
-		
-        startTime = System.currentTimeMillis();
-        System.out.println("addrListVO.size() : "+ addrListVO.size());
-
-    	try {
-	        if(addrListVO.size() > 0) {
-	    		// 등록 
-	        	// 배치 제거 
-	        	// 참고 http://wiki.iten.co.kr:9999/doku.php?id=%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8:%EB%AC%B8%EC%9E%90%EC%98%A8_%EA%B0%9C%EC%84%A0:03.%ED%85%8C%EC%8A%A4%ED%8A%B8:%EC%A3%BC%EC%86%8C%EB%A1%9D_30%EB%A7%8C%EA%B1%B4#%EB%B9%84%EA%B5%90_%ED%91%9C
-	            // Batch insert
-//                batchInsertAddrListAsync(addrListVO);
-	    		addrDAO.insertAddrList(addrListVO);
-	        	
-	        }
-
-		} catch (Exception e) {
-			// TODO: handle exception
-			e.printStackTrace();
-			return new StatusResponse(
-					HttpStatus.BAD_REQUEST
-					, "배치오류"
-					, LocalDateTime.now()
-					);
-		}
-        endTime = System.currentTimeMillis();
-        executionTime = (endTime - startTime) / 1000.0;
-        System.out.println("INSERT Execution time: " + executionTime + " seconds");
-		
-		
-		// 중복체크 dupliCnt
-		
-		
-        // 현재 시간 가져오기
-        LocalDateTime now = LocalDateTime.now();
-        
-        // 원하는 포맷 설정
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-        
-        // 포맷된 시간 문자열로 변환
-        String formattedDateTime = now.format(formatter);
-        
-        // 출력
-        System.out.println(formattedDateTime);
-		//
-		String message = "저장에 성공했습니다.\n저장 : " + addrListVO.size() + "건"
-//			+", 중복 : " + invalid.dupliCnt + "건"
-			+", INERT 총 시간 : " + executionTime+ "초"
-			+", 현재시간 : " + formattedDateTime;
-
-		return new StatusResponse(
-				HttpStatus.OK
-				, message
-				, addrListVO.get(0).getAddrGrpId()
-				);
-	}
-
-
-    private void batchInsertAddrListAsync(List<AddrVO> addrListVO) throws InterruptedException {
-        int totalSize = addrListVO.size();
-        int batchCount = (totalSize + BATCH_SIZE - 1) / BATCH_SIZE;
-        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
-
-        for (int i = 0; i < batchCount; i++) {
-            final int startIndex = i * BATCH_SIZE;
-            final int endIndex = Math.min(startIndex + BATCH_SIZE, totalSize);
-            final List<AddrVO> batchList = addrListVO.subList(startIndex, endIndex);
-
-            executor.submit(() -> {
-                try {
-                    long startTime = System.currentTimeMillis();
-                    addrDAO.insertAddrList(batchList);
-                    long endTime = System.currentTimeMillis();
-                    double executionTime = (endTime - startTime) / 1000.0;
-                    System.out.println("Batch " + (startIndex / BATCH_SIZE + 1) + "/" + batchCount + " Execution time: " + executionTime + " seconds");
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            });
-        }
-
-        executor.shutdown();
-        executor.awaitTermination(1, TimeUnit.HOURS);
-    }
-
-	public static boolean isValidPhoneNumber(String phoneNo) {
-        if (phoneNo == null || phoneNo.isEmpty()) {
-            return false;
-        }
-        Matcher matcher = PHONE_PATTERN.matcher(phoneNo);
-        return matcher.matches();
-    }
-	
-
-    public static void trimFieldsBytes(AddrVO addr) {
-        addr.setAddrInfo1(trimToBytes(addr.getAddrInfo1(), 20));
-        addr.setAddrInfo2(trimToBytes(addr.getAddrInfo2(), 20));
-        addr.setAddrInfo3(trimToBytes(addr.getAddrInfo3(), 20));
-        addr.setAddrInfo4(trimToBytes(addr.getAddrInfo4(), 20));
-        addr.setAddrComment(trimToBytes(addr.getAddrComment(), 250));
-        addr.setAddrNm(trimToBytes(addr.getAddrNm(), 20));
-    }
-
-    // maxBytes만큼 글자수 처리해서 리턴
-    public static String trimToBytes(String str, int maxBytes) {
-        if (str == null) {
-            return null;
-        }
-        byte[] bytes = str.getBytes(EUC_KR);
-        if (bytes.length <= maxBytes) {
-            return str;
-        }
-        int len = maxBytes;
-        while (len > 0 && bytes[len - 1] < 0) {
-            len--; // 바이트 배열을 maxBytes로 자를 때, 잘못된 분할을 피하기 위해 문자 경계 확인
-        }
-        return new String(bytes, 0, len, EUC_KR);
-    }
-    
-
-    private final ExecutorService executorService = Executors.newFixedThreadPool(3);
-
-
-    public void deleteAddr_advc(AddrGroupVO addrGroupVO) throws Exception {
-
-        addrGroupDAO.deleteAddrGroup(addrGroupVO);
-
-        AddrVO addrVO = new AddrVO();
-        addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
-        addrVO.setGrpDelete("Y");
-        addrVO.setMberId(addrGroupVO.getMberId());
-
-
-//        boolean hasMoreData = true;
-//
-//        while (hasMoreData) {
-//            // 1. addrVO에 마지막으로 처리된 ID와 배치 크기를 설정
-//            addrVO.setBatchSize(50000);
-//        
-
-	
-	        // 2. 현재 배치에서 삭제된 레코드 수를 확인
-//	        int affectedRows = addrDAO.deleteAddr(addrVO);
-	
-//	        // 3. 더 이상 삭제할 데이터가 없으면 종료
-//	        if (affectedRows < BATCH_SIZE) {
-//	            hasMoreData = false;
-//	        } 
-//        }
-
-        addrDAO.deleteAddr(addrVO);
-    }
-
-	@Override
-	public int getAddrCount(AddrGroupVO addrGroupVO) throws Exception {
-
-		AddrVO addrVO = new AddrVO();
-		addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
-		addrVO.setMberId(addrGroupVO.getMberId());
-		
-		int aa = addrDAO.getAddrCount(addrVO);
-		
-		System.out.println("aa : "+ aa);
-		
-		return aa; 
-	}
-    
-}
+package itn.let.mjo.addr.service.impl;
+
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+
+import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
+import egovframework.rte.fdl.idgnr.EgovIdGnrService;
+import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
+import itn.com.cmm.LoginVO;
+import itn.let.mail.service.StatusResponse;
+import itn.let.mjo.addr.service.AddrGroupVO;
+import itn.let.mjo.addr.service.AddrService;
+import itn.let.mjo.addr.service.AddrTransHistVO;
+import itn.let.mjo.addr.service.AddrVO;
+
+/**
+ * 주소록 관리를 위한 서비스 구현 클래스
+ * @author ITN
+ * @since 2021.04.08
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *   수정일      수정자          수정내용
+ *  -------    --------    ---------------------------
+ *  2021.04.08  ITN          최초 생성
+ *  </pre>
+ */
+@Service("AddrService")
+public class AddrServiceImpl  extends EgovAbstractServiceImpl implements AddrService {
+
+	@Resource(name = "AddrDAO")
+	private AddrDAO addrDAO;
+
+	@Resource(name = "AddrGroupDAO")
+	private AddrGroupDAO addrGroupDAO;
+	
+	@Resource(name = "AddrTransHistDAO")
+	private AddrTransHistDAO addrTransHistDAO;
+
+	@Resource(name = "egovAddrTransHistIdGnrService")
+    private EgovIdGnrService idgenAddrTransHistId;
+
+
+
+    private static final String PHONE_REGEX = "^(01[016789]-?\\d{3,4}-?\\d{4})$";
+    private static final Pattern PHONE_PATTERN = Pattern.compile(PHONE_REGEX);
+    private static final Charset EUC_KR = Charset.forName("EUC-KR");
+//    private static final int MAX_ADDR_CNT = 500000;
+    //임시 500만개
+    private static final int MAX_SINGLE_ENTRY_CNT = 350000;
+    private static final int MAX_ADDR_CNT = 10000000;
+    private static final int BATCH_SIZE = 5000;
+    private static final int THREAD_COUNT = 3;
+	
+	
+	public List<AddrVO> selectAddrList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrList(addrVO);
+	}
+	
+	@Override
+	public int selectAddrListCount(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrListCount(addrVO);
+	}
+	
+	public List<AddrVO> selectAddrNewList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrNewList(addrVO);
+	}	
+	
+	public AddrVO selectAddrDetail(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDetail(addrVO);
+	}
+	
+	public void insertAddr(AddrVO addrVO) throws Exception {
+		addrDAO.insertAddr(addrVO);
+	}
+	
+	public int updateAddr(AddrVO addrVO) throws Exception{
+		return  addrDAO.updateAddr(addrVO);
+	}
+	
+	public int updateAddrGrp(AddrVO addrVO) throws Exception{
+		return  addrDAO.updateAddrGrp(addrVO);
+	}	
+	
+	public int updateMemoAddr(AddrVO addrVO) throws Exception{
+		return  addrDAO.updateMemoAddr(addrVO);
+	}
+	
+	public int updateAddrByAdmin(AddrVO addrVO) throws Exception{
+		return  addrDAO.updateAddrByAdmin(addrVO);
+	}	
+	
+	public int deleteAddr(AddrVO addrVO) throws Exception{
+		return  addrDAO.deleteAddr(addrVO);
+	}
+	
+	public int deleteAddrByAdmin(AddrVO addrVO) throws Exception{
+		return  addrDAO.deleteAddrByAdmin(addrVO);
+	}	
+
+	public int deleteAddrByAdminAll(AddrVO addrVO) throws Exception{
+		int rtnCount = 0;
+		
+		for (String addrId : addrVO.getAddrIds()) {
+			addrVO.setAddrId(addrId);
+			rtnCount += addrDAO.deleteAddrByAdmin(addrVO);
+		}
+
+		return  rtnCount;
+	}	
+	
+	public int deleteAddrByAdminByGrpid(AddrVO addrVO) throws Exception{
+		return  addrDAO.deleteAddrByAdminByGrpid(addrVO);
+	}	
+	
+	public int deleteAddrByAdminByGrpidAll(AddrVO addrVO) throws Exception{
+		int rtnCount = 0;
+		
+		for (String addrGrpId : addrVO.getAddrGrpIds()) {
+			addrVO.setAddrGrpId(addrGrpId);
+			rtnCount += addrDAO.deleteAddrByAdminByGrpid(addrVO);
+		}
+
+		return  rtnCount;
+	}	
+	
+	@Override
+	public List<AddrVO> selectAddrBasicGrpList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrBasicGrpList(addrVO);
+	}
+
+	@Override
+	public int selectAddrTotalCount(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrTotalCount(addrVO);
+	}
+
+	@Override
+	public void insertCopyAddr(AddrVO addrVO) throws Exception {
+		addrDAO.insertCopyAddr(addrVO);
+	}
+
+	@Override
+	public String updateAddrAnotherMember(AddrVO addrVO, AddrGroupVO addrGroupVO, 
+			AddrTransHistVO addrTransHistVO) throws Exception {
+
+		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "HHmmss", Locale.KOREA );
+		Date currentTime = new Date ();
+		String mTime = mSimpleDateFormat.format ( currentTime );
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+    	addrVO.setMberId(user.getId());
+    	addrTransHistVO.setSendMberId(user.getId());
+    	
+    	String successCd ="";
+		int listSize = addrVO.getSendGrps().length;
+		
+		for(int i=0; i<listSize; i++ ) {
+			
+			try {
+				
+				/**
+				 * 1. 이전할 주소록그룹명_시분초 로 받는 회원의 새 주소록 그룹을 만듦
+				 */
+				//전송할 그룹의 id를 검색해 올 아이디로 set
+				addrGroupVO.setAddrGrpId(addrVO.getSendGrps()[i]);
+				
+				//vo에 db조회해온 상세데이터를 set함  - 주소록명 가지고오기 위함
+				addrGroupVO = addrGroupDAO.selectAddrGroupDetail(addrGroupVO);
+				
+	
+				
+				AddrGroupVO recvAddrGroupVO = new AddrGroupVO();
+				
+				//보낼 주소록그룹의 정보를 세팅
+				recvAddrGroupVO.setMberId(addrTransHistVO.getRecvMberId());
+				//기존 그룹명_(시분초) 로 새로운 그룹의 이름을 정함
+				recvAddrGroupVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm()+"_"+mTime); 
+				
+				String newGrpId = addrGroupDAO.insertAddrGroup(recvAddrGroupVO);
+				
+				/**
+				 * 2. 주소록그룹ID를 가진 주소록들을 가져와 받는 유저의 주소록 insert
+				 */
+			
+				AddrVO recvAddrVO = new AddrVO();
+				//보낼 주소록 정보를 set
+				recvAddrVO.setMberId(addrVO.getMberId());
+				recvAddrVO.setAddrGrpId(addrVO.getSendGrps()[i]);
+				recvAddrVO.setRecordCountPerPage(100000);
+				recvAddrVO.setFirstIndex(0);
+				
+				List<AddrVO> recvAddrList = addrDAO.selectAddrList(recvAddrVO);
+				
+				for(int j=0; j<recvAddrList.size(); j++) {
+					try {
+						recvAddrList.get(j).setRecvStatus("W");
+						
+						recvAddrList.get(j).setMberId(addrTransHistVO.getRecvMberId());
+						//새로만든 그룹의 아이디를 세팅
+						recvAddrList.get(j).setAddrGrpId(newGrpId);
+						addrDAO.insertAddr(recvAddrList.get(j));
+						
+					}catch(Exception e) {
+						e.printStackTrace();
+					}
+					
+				}
+				
+				/**
+				 * 3. 주소록 이전 히스토리 테이블에 등록 
+				 */
+				addrTransHistVO.setAddrGrpId(newGrpId);
+				addrTransHistVO.setAddrTransHistId(idgenAddrTransHistId.getNextStringId());
+				addrTransHistVO.setSendAddrCnt(recvAddrList.size());
+				
+				addrTransHistDAO.insertAddrTransHist(addrTransHistVO);
+				
+				if(i==0) successCd = "Y";
+				if(i!=0) successCd += ",Y";
+				
+			} catch(Exception e) {
+				e.printStackTrace();
+				
+				if(i==0) successCd = "N";
+				if(i!=0) successCd += ",N";
+			}
+			
+		}
+		
+	
+		
+		return successCd;
+	}
+	
+	//주소록 등록 총 건수 및 정보 불러오기
+	public List<?> selectAddrTotCntInfByUserId(AddrVO addrVO) throws Exception{
+		
+		return addrDAO.selectAddrTotCntInfByUserId(addrVO);
+	}
+	
+	//문자발송에서 수신자 리스트를 주소록에 등록하기
+	public int insertAddrList(List<AddrVO> addrList) throws Exception{
+		
+		return addrDAO.insertAddrList(addrList);
+	}
+	
+	@Override
+	public int selectDuplAddrCnt(AddrVO addrVO) throws Exception {
+		return addrDAO.selectDuplAddrCnt(addrVO);
+	}
+	
+	//주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도)
+	public List<?> selectPhoneNumInAddrGroup(AddrVO addrVO) throws Exception{
+		return addrDAO.selectPhoneNumInAddrGroup(addrVO);
+	}
+
+	//선택한 주소록 문자전송 화면으로 보내기
+	@Override
+	public List<AddrVO> selectAddrDataList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDataList(addrVO);
+	}
+
+	// 주소록 그룹별 중복 연락처 삭제
+	public int deleteAddrDupliList(AddrVO addrVO) throws Exception {
+		int rtnCnt = 0;
+		
+		for (int i = 0; i < 20; i++) {
+			// 주소록 그룹별 중복 연락처 목록
+			List<AddrVO> addrDupliList = selectAddrDupliList(addrVO);
+			
+			if (addrDupliList.size() > 0) {
+				rtnCnt += addrDAO.deleteAddrDupliList(addrVO);
+			}
+			else {
+				break;
+			}
+		}		
+		
+		return rtnCnt;
+	}
+
+	// 주소록 그룹별 중복 연락처 삭제
+	public int deleteAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
+		int rtnCnt = 0;
+		
+		for (int i = 0; i < 20; i++) {
+			// 주소록 그룹별 중복 연락처 목록
+			List<AddrVO> addrDupliList = selectAddrDupliListByGrpnm(addrVO);
+			
+			if (addrDupliList.size() > 0) {
+				rtnCnt += addrDAO.deleteAddrDupliListByGrpnm(addrVO);
+			}
+			else {
+				break;
+			}
+		}		
+		
+		return rtnCnt;
+	}	
+	
+	// 주소록 전체 중복 연락처 중 한개만 남기고 삭제
+	public int deleteAddrDupliListByAll(AddrVO addrVO) throws Exception {
+		int rtnCnt = 0;
+		
+		for (int i = 0; i < 20; i++) {
+			if (selectAddrDupliListByAllCnt(addrVO) > 0) {
+				rtnCnt += addrDAO.deleteAddrDupliListByAll(addrVO);
+			}
+			else {
+				break;
+			}
+		}		
+		
+		return rtnCnt;
+	}		
+	
+	
+	// 주소록 그룹별 중복 연락처 리스트 불러오기
+	@Override
+	public List<AddrVO> selectAddrDupliList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDupliList(addrVO);
+	}
+
+	// 주소록 그룹별 중복 연락처 리스트 불러오기
+	@Override
+	public List<AddrVO> selectAddrDupliListByGrpnm(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDupliListByGrpnm(addrVO);
+	}
+	
+	// 주소록 전체 중복 연락처 수
+	@Override
+	public int selectAddrDupliListByAllCnt(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDupliListByAllCnt(addrVO);
+	}	
+	
+	// 주소록 전체 중복 연락처 목록
+	@Override
+	public List<AddrVO> selectAddrDupliListByAll(AddrVO addrVO) throws Exception {
+		return addrDAO.selectAddrDupliListByAll(addrVO);
+	}
+	
+	// TEMP 주소록 중복 연락처 목록
+	@Override
+	public List<AddrVO> selectTempAddrDupliList(AddrVO addrVO) throws Exception {
+		return addrDAO.selectTempAddrDupliList(addrVO);
+	}
+	
+	// TEMP 주소록 삭제
+	public int deleteTempAddr(AddrVO addrVO) throws Exception{
+		return  addrDAO.deleteTempAddr(addrVO);
+	}	
+	
+	// TEMP 주소록 대량등록
+	public int insertTempAddrList(List<AddrVO> addrList) throws Exception{
+		return addrDAO.insertTempAddrList(addrList);
+	}	
+
+	// 주소록 대량등록 By Temp 주소록
+	public int insertAddrByTempAddr(AddrVO addrVO) throws Exception {
+		return addrDAO.insertAddrByTempAddr(addrVO);
+	}
+	
+	// 주소록 대량등록 By Temp 주소록 All
+	public int insertAddrByTempAddrAll(List<AddrVO> addrList, AddrVO addrVO) throws Exception{
+		int rtnVal = 0;
+
+        // Step 1. TEMP 주소록 삭제
+        deleteTempAddr(addrVO);
+        
+        // Step 2. TEMP 주소록 대량등록
+		insertTempAddrList(addrList);
+		
+		// Step 3. 주소록 대량등록 By Temp 주소록
+		rtnVal = insertAddrByTempAddr(addrVO);
+		
+		return rtnVal;
+	}
+
+	@Override
+	public StatusResponse addrMassInsertByTempAjax_advc(List<AddrVO> addrListVO, String userId) throws Exception {
+		
+	
+    	
+		// data init
+    	// For-each loop
+		for (AddrVO addr : addrListVO) { addr.setMberId(userId); }
+
+		
+		
+		if(addrListVO.size() > MAX_SINGLE_ENTRY_CNT) {
+			return new StatusResponse(
+					HttpStatus.BAD_REQUEST
+					, "주소록은 한번에 100만개까지만 등록이 가능합니다."
+					, LocalDateTime.now()
+					);
+			
+		}
+		// step1 현재 주소록 갯수 조회
+
+		//회원별 주소록 전체 갯수 조회
+		int addrBefCnt = addrDAO.selectAddrTotalCount(addrListVO.get(0));    		
+		int addrNewCnt = addrListVO.size();	//신규 추가할 주소록 갯수
+		int sumAddrCnt = addrBefCnt + addrNewCnt;	
+
+		// step1-1 총 갯수가 (주소록 갯수 + 신규 주소록)50만건 체크
+		if(sumAddrCnt > MAX_ADDR_CNT) {
+			return new StatusResponse(
+							HttpStatus.BAD_REQUEST
+							, "주소록은 총 1000만개까지만 등록이 가능합니다."
+							, LocalDateTime.now()
+							);
+					
+		}
+
+		// step2 신규 주소록 생성 및 북마크 체크
+		// 		=> AddrGrpId
+		//
+		if ("NEW".equals(addrListVO.get(0).getAddrGrpId())) {
+			
+			AddrGroupVO addrGroupVO = new AddrGroupVO();
+			addrGroupVO.setMberId(userId);
+			addrGroupVO.setAddrGrpNm(addrListVO.get(0).getAddrGrpNm());
+			// 정렬순서
+			
+			int nextOrderNumber = addrGroupDAO.selectMaxOrderNumber(addrGroupVO);
+			addrGroupVO.setGrpOrder(nextOrderNumber);
+			
+			addrGroupDAO.insertAddrGroup(addrGroupVO);
+			
+			// 신규 추가한 그룹아이디
+    		for (AddrVO addr : addrListVO) { addr.setAddrGrpId(addrGroupVO.getAddrGrpId()); }
+    		
+		}
+		else if ("bookmark".equals(addrListVO.get(0).getAddrGrpId())) 
+		{
+    		for (AddrVO addr : addrListVO) { addr.setBookmark("Y"); addr.setAddrGrpId("0"); }
+		} 
+		else 
+		{
+			for (AddrVO addr : addrListVO) { addr.setBookmark("N"); }
+		} 
+		
+		// step4-1 true 
+		// 		=> 폰번호 빼고 바이트 체크해서 20byte만 짜르고 넣기
+		// 		=> 폰번호는 유효성 체크 하기
+
+        long startTime = System.currentTimeMillis();
+		// 유효성 체크 및 하이픈 제거, 유효하지 않은 번호는 리스트에서 제거
+		// 나머지 필드들 20byte (euc-kr) 체크 후 넘으면 자르기
+		AtomicInteger invalid = new AtomicInteger(0); // 스레드-안전(thread-safe)하게 정수 값을 업데이트할 수 있는 기능을 제공
+		addrListVO.removeIf(addr -> {
+			String phoneNo = addr.getAddrPhoneNo();
+//			phoneNo = phoneNo != null ? phoneNo.replaceAll("-", "") : "";
+//			System.out.println("phoneNo : "+ phoneNo);
+			if (isValidPhoneNumber(phoneNo)) {
+				addr.setAddrPhoneNo(phoneNo); // 하이픈이 제거된 유효한 번호 설정
+				trimFieldsBytes(addr); // 다른 필드들에 대한 20바이트 체크 및 자르기
+				return false; // 유효한 번호는 제거하지 않음
+			} else {
+//				System.out.println(phoneNo + " is an invalid phone number. Removing from list.");
+		        invalid.getAndIncrement(); // 유효하지 않은 번호 개수 증가
+				return true; // 유효하지 않은 번호는 제거
+			}
+        });
+
+
+        long endTime = System.currentTimeMillis();
+        double executionTime = (endTime - startTime) / 1000.0;
+        System.out.println(" number chk Execution time: " + executionTime + " seconds");
+		
+        startTime = System.currentTimeMillis();
+        System.out.println("addrListVO.size() : "+ addrListVO.size());
+
+    	try {
+	        if(addrListVO.size() > 0) {
+	    		// 등록 
+	        	// 배치 제거 
+	        	// 참고 http://wiki.iten.co.kr:9999/doku.php?id=%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8:%EB%AC%B8%EC%9E%90%EC%98%A8_%EA%B0%9C%EC%84%A0:03.%ED%85%8C%EC%8A%A4%ED%8A%B8:%EC%A3%BC%EC%86%8C%EB%A1%9D_30%EB%A7%8C%EA%B1%B4#%EB%B9%84%EA%B5%90_%ED%91%9C
+	            // Batch insert
+//                batchInsertAddrListAsync(addrListVO);
+	    		addrDAO.insertAddrList(addrListVO);
+	        	
+	        }
+
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+			return new StatusResponse(
+					HttpStatus.BAD_REQUEST
+					, "배치오류"
+					, LocalDateTime.now()
+					);
+		}
+        endTime = System.currentTimeMillis();
+        executionTime = (endTime - startTime) / 1000.0;
+        System.out.println("INSERT Execution time: " + executionTime + " seconds");
+		
+		
+		// 중복체크 dupliCnt
+		
+		
+        // 현재 시간 가져오기
+        LocalDateTime now = LocalDateTime.now();
+        
+        // 원하는 포맷 설정
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        
+        // 포맷된 시간 문자열로 변환
+        String formattedDateTime = now.format(formatter);
+        
+        // 출력
+        System.out.println(formattedDateTime);
+		//
+		String message = "저장에 성공했습니다.\n저장 : " + addrListVO.size() + "건"
+//			+", 중복 : " + invalid.dupliCnt + "건"
+			+", INERT 총 시간 : " + executionTime+ "초"
+			+", 현재시간 : " + formattedDateTime;
+
+		return new StatusResponse(
+				HttpStatus.OK
+				, message
+				, addrListVO.get(0).getAddrGrpId()
+				);
+	}
+
+
+    private void batchInsertAddrListAsync(List<AddrVO> addrListVO) throws InterruptedException {
+        int totalSize = addrListVO.size();
+        int batchCount = (totalSize + BATCH_SIZE - 1) / BATCH_SIZE;
+        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
+
+        for (int i = 0; i < batchCount; i++) {
+            final int startIndex = i * BATCH_SIZE;
+            final int endIndex = Math.min(startIndex + BATCH_SIZE, totalSize);
+            final List<AddrVO> batchList = addrListVO.subList(startIndex, endIndex);
+
+            executor.submit(() -> {
+                try {
+                    long startTime = System.currentTimeMillis();
+                    addrDAO.insertAddrList(batchList);
+                    long endTime = System.currentTimeMillis();
+                    double executionTime = (endTime - startTime) / 1000.0;
+                    System.out.println("Batch " + (startIndex / BATCH_SIZE + 1) + "/" + batchCount + " Execution time: " + executionTime + " seconds");
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            });
+        }
+
+        executor.shutdown();
+        executor.awaitTermination(1, TimeUnit.HOURS);
+    }
+
+	public static boolean isValidPhoneNumber(String phoneNo) {
+        if (phoneNo == null || phoneNo.isEmpty()) {
+            return false;
+        }
+        Matcher matcher = PHONE_PATTERN.matcher(phoneNo);
+        return matcher.matches();
+    }
+	
+
+    public static void trimFieldsBytes(AddrVO addr) {
+        addr.setAddrInfo1(trimToBytes(addr.getAddrInfo1(), 20));
+        addr.setAddrInfo2(trimToBytes(addr.getAddrInfo2(), 20));
+        addr.setAddrInfo3(trimToBytes(addr.getAddrInfo3(), 20));
+        addr.setAddrInfo4(trimToBytes(addr.getAddrInfo4(), 20));
+        addr.setAddrComment(trimToBytes(addr.getAddrComment(), 250));
+        addr.setAddrNm(trimToBytes(addr.getAddrNm(), 20));
+    }
+
+    // maxBytes만큼 글자수 처리해서 리턴
+    public static String trimToBytes(String str, int maxBytes) {
+        if (str == null) {
+            return null;
+        }
+        byte[] bytes = str.getBytes(EUC_KR);
+        if (bytes.length <= maxBytes) {
+            return str;
+        }
+        int len = maxBytes;
+        while (len > 0 && bytes[len - 1] < 0) {
+            len--; // 바이트 배열을 maxBytes로 자를 때, 잘못된 분할을 피하기 위해 문자 경계 확인
+        }
+        return new String(bytes, 0, len, EUC_KR);
+    }
+    
+
+    private final ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+
+    public void deleteAddr_advc(AddrGroupVO addrGroupVO) throws Exception {
+        addrGroupDAO.deleteAddrGroup_advc(addrGroupVO);
+    }
+
+	@Override
+	public int getAddrCount(AddrGroupVO addrGroupVO) throws Exception {
+
+		AddrVO addrVO = new AddrVO();
+		addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
+		addrVO.setMberId(addrGroupVO.getMberId());
+		
+		int aa = addrDAO.getAddrCount(addrVO);
+		
+		System.out.println("aa : "+ aa);
+		
+		return aa; 
+	}
+    
+}
src/main/java/itn/let/mjo/addr/web/AddrController.java
--- src/main/java/itn/let/mjo/addr/web/AddrController.java
+++ src/main/java/itn/let/mjo/addr/web/AddrController.java
@@ -1,2277 +1,2276 @@
-package itn.let.mjo.addr.web;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-
-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.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.ui.ModelMap;
-import org.springframework.web.bind.annotation.ModelAttribute;
-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.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.security.userdetails.util.EgovUserDetailsHelper;
-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.util.RedirectUrlMaker;
-import itn.com.cmm.util.StringUtil;
-import itn.com.utl.fcc.service.EgovStringUtil;
-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.AddrTransHistVO;
-import itn.let.mjo.addr.service.AddrVO;
-import itn.let.mjo.msgdata.service.PhoneVO;
-
-/**
- * 주소록 관한 controller 클래스를 정의한다.
- * @author ITN
- * @since 2021.04.08
- * @version 1.0
- * @see
- *
- * <pre>
- * << 개정이력(Modification Information) >>
- *
- *   수정일      수정자           수정내용
- *  -------    --------    ---------------------------
- *   2021.04.08  ITN          최초 생성
- *
- * </pre>
- */
-@Controller
-public class AddrController {
-
-	
-	@Resource (name = "AddrService")
-	private AddrService addrService;
-	
-	@Resource (name = "AddrGroupService")
-	private AddrGroupService addrGroupService;
-	
-	/** EgovMessageSource */
-	@Resource(name="egovMessageSource")
-	EgovMessageSource egovMessageSource;
-	
-	
-	/**
-	 * 주소록 리스트
-	 * @param addrVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/selectAddrList.do")
-	public String selectAddrList(@ModelAttribute("searchVO") AddrVO addrVO
-			,ModelMap model) throws Exception {
-		
-		if(addrVO.getPageUnit() != 10) {
-			addrVO.setPageUnit(addrVO.getPageUnit());
-		}
-
-		/** pageing */
-		PaginationInfo paginationInfo = new PaginationInfo();
-		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
-		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
-		paginationInfo.setPageSize(addrVO.getPageSize());
-		
-		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
-		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
-		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
-		
-		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrVO.setSearchSortCnd("addrId");
-			addrVO.setSearchSortOrd("asc");
-		}
-		
-		// 기간검색 설정
-    	Calendar mon = Calendar.getInstance();    
-    	mon.add(Calendar.WEEK_OF_MONTH , -2);    
-    	String before2Week = new java.text.SimpleDateFormat("yyyy-MM-dd").format(mon.getTime());    
-    	if (null == addrVO.getSearchStartDate() || addrVO.getSearchStartDate().equals("")) {
-    		addrVO.setSearchStartDate(before2Week);
-    	}				
-		
-		List<AddrVO> addrList = addrService.selectAddrNewList(addrVO);
-		
-		int totCnt = 0;
-		 if(addrList.size() > 0) {
- 			totCnt = addrList.get(0).getTotcnt();
- 		}
-		 
-		paginationInfo.setTotalRecordCount(totCnt);
-		model.addAttribute("addrList", addrList);
-		model.addAttribute("paginationInfo", paginationInfo);
-		
-		return "/uss/ion/addr/AddrList";
-	}
-   
-	
-	/**
-	 * 주소록 등록 페이지 이동
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/registAddr.do")
-	public String registAddr(ModelMap model) throws Exception {
-		
-		return "/uss/ion/addr/AddrRegist";
-	}
-	
-	
-	/**
-	 * 주소록 추가 로직
-	 * @param addrVO
-	 * @param redirectAttributes
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/insertAddr.do")
-	public String insertAddr(AddrVO addrVO
-			,RedirectAttributes redirectAttributes
-			,HttpServletRequest request) throws Exception {
-		
-		try {
-			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-
-			if( addrVO.getMberId() == null || "".equals(addrVO.getMberId()) ) {
-				addrVO.setMberId(user.getId());
-			}
-			
-			// 자주 보내는 번호
-			if("bookmark".equals(addrVO.getAddrGrpId())) {
-				addrVO.setBookmark("Y");
-				addrVO.setAddrGrpId("0");
-			}
-			
-			// 주소록 그룹 내 휴대폰번호 중복체크
-			int usedCnt = addrService.selectDuplAddrCnt(addrVO);
-			if (usedCnt > 0) {
-				redirectAttributes.addFlashAttribute("message", "해당 그룹내 중복된 휴대폰 번호가 있습니다.");
-			}
-			else {
-				addrService.insertAddr(addrVO);
-				redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.insert"));
-			}
-			
-		}catch (Exception e) {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.insert"));
-		}
-		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/uss/ion/addr/selectAddrList.do");
-		return redirectUrlMaker.getRedirectUrl();
-		
-	}
-	
-
-	/**
-	 * 주소록 수정 로직
-	 * 
-	 * @param addrVO
-	 * @param redirectAttributes
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/updateAddrByAdminAjax.do")
-	public ModelAndView updateAddrByAdminAjax(AddrVO addrVO
-			,RedirectAttributes redirectAttributes
-			,HttpServletRequest request
-			) throws Exception{
-		
-		ModelAndView modelAndView =  new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		try {
-			
-			addrService.updateAddrByAdmin(addrVO);
-			
-		}
-		catch(Exception e) {
-			System.out.println("");
-			isSuccess = false;
-			msg = "에러메시지 : " + e.getMessage();			
-			e.printStackTrace();
-		}		
-		
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		
-		return modelAndView;
-	}
-	
-	
-	/**
-	 * 주소록 수정 페이지 이동
-	 * 
-	 * @param addrVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/editAddr.do")
-	public String editAddr(AddrVO addrVO
-			, ModelMap model ) throws Exception {
-		
-		AddrVO addrInfo = addrService.selectAddrDetail(addrVO);
-		
-		model.addAttribute("addrInfo", addrInfo);
-		
-		return "/uss/ion/addr/AddrEdit";
-	}
-	
-	/**
-	 * 주소록 삭제 로직
-	 * 
-	 * @param request
-	 * @param addrVO
-	 * @param redirectAttributes
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/deleteAddr.do")
-	public String deleteAddr (HttpServletRequest request, @ModelAttribute("searchVO") AddrVO addrVO
-			,RedirectAttributes redirectAttributes
-			,ModelMap model) throws Exception {
-		
-		int result = addrService.deleteAddrByAdminAll(addrVO); 
-		
-		if (result > 0) {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
-		} else {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.delete"));
-		}
-		redirectAttributes.addAttribute("pageIndex", addrVO.getPageIndex());
-		redirectAttributes.addAttribute("searchCondition", addrVO.getSearchCondition());
-		redirectAttributes.addAttribute("searchKeyword", addrVO.getSearchKeyword());
-		
-		return "redirect:/uss/ion/addr/selectAddrList.do";
-	}
-
-
-	
-	
-	/**
-	 * 주소록 타 회원으로 이전(복사) 처리 
-	 * @param addrVO
-	 * @param addrGroupVO
-	 * @param addrTransHistVO
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/transAddrGroupAjax.do")
-	public ModelAndView transAddrGroupAjax(AddrVO addrVO, AddrGroupVO addrGroupVO, AddrTransHistVO addrTransHistVO) throws Exception {
-		ModelAndView modelAndView =  new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		try {
-			String successCd = addrService.updateAddrAnotherMember(addrVO, addrGroupVO, addrTransHistVO);
-			
-			modelAndView.addObject("status", "success");
-			modelAndView.addObject("result", successCd);
-			
-		}catch(Exception e) {
-			e.printStackTrace();
-			modelAndView.addObject("status", "fail");
-			return modelAndView;
-		}
-
-		return modelAndView;
-	}
-	
-	
-
-	/**
-	 * 주소록 사용자 화면 껍데기
-	 * @param addrVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/selectAddrList.do")
-	public String selectAddrWebList(@ModelAttribute("searchVO") AddrVO addrVO
-			,AddrGroupVO addrGroupVO, ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
-		
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-		if(userId == "") {
-			/*redirectAttributes.addFlashAttribute("fail", true);*/
-			//redirectAttributes.addFlashAttribute("message", "문자온 서비스는 로그인 후 이용 가능합니다.");
-			return "redirect:/web/user/login/login.do";
-		}
-		
-		return "/web/addr/AddrList";
-	}
-	
-	
-	
-	/**
-	 * 사용자 주소록 리스트 Ajax
-	 * @param request
-	 * @param model
-	 * @param addrVO
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/selectAddrAjax.do")
-	public String selectAddrAjax(HttpServletRequest request, ModelMap model, 
-			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
-		
-		//로그인 권한정보 불러오기
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-		
-		if(userId != "") {
-			addrVO.setMberId(userId);
-		} else {
-			return "/web/addr/AddrListAjax";
-		}
-		
-		if(addrVO.getPageUnit() != 10) {
-			addrVO.setPageUnit(addrVO.getPageUnit());
-		}
-		
-		/** pageing */
-		PaginationInfo paginationInfo = new PaginationInfo();
-		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
-		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
-		paginationInfo.setPageSize(addrVO.getPageSize());
-		
-		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
-		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
-		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
-		
-		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrVO.setSearchSortCnd("addrId");
-			addrVO.setSearchSortOrd("asc");
-		}
-		
-		List<AddrVO> addrList = addrService.selectAddrList(addrVO);
-		
-		int totCnt = 0;
-		 if(addrList.size() > 0) {
-			totCnt = addrList.get(0).getTotcnt();
-		}
-		 
-		paginationInfo.setTotalRecordCount(totCnt);
-		
-		model.addAttribute("paginationInfo", paginationInfo);
-		model.addAttribute("addrList", addrList);
-		model.addAttribute("startKeyword",addrVO.getStartKeyword());
-		model.addAttribute("userId", userId);
-		
-		return "/web/addr/AddrListAjax";
-	}
-	
-	
-
-	@RequestMapping("/web/mjon/addr/addrListforExcelAjax.do")
-	public String AddrListforExcel(HttpServletRequest request, ModelMap model, 
-			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
-			
-			return "/web/addr/addrListforExcel";
-	}
-	/**
-	 * 사용자 주소록 중복 리스트 Ajax
-	 * @param request
-	 * @param model
-	 * @param addrVO
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/selectAddrDupliAjax.do")
-	public String selectAddrDupliAjax(HttpServletRequest request, ModelMap model, 
-			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
-		
-		//로그인 권한정보 불러오기
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-		
-		if(userId != "") {
-			addrVO.setMberId(userId);
-		} 
-		
-		if(addrVO.getPageUnit() != 10) {
-			addrVO.setPageUnit(addrVO.getPageUnit());
-		}
-		
-		/** pageing */
-		PaginationInfo paginationInfo = new PaginationInfo();
-		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
-		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
-		paginationInfo.setPageSize(addrVO.getPageSize());
-		
-		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
-		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
-		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
-		
-		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrVO.setSearchSortCnd("addrId");
-			addrVO.setSearchSortOrd("asc");
-		}
-		
-		List<AddrVO> addrDupliList = addrService.selectAddrDupliListByAll(addrVO);
-		
-		int totCnt = 0;
-		 if(addrDupliList.size() > 0) {
-			totCnt = addrDupliList.get(0).getTotcnt();
-		}
-		 
-		paginationInfo.setTotalRecordCount(totCnt);
-		
-		model.addAttribute("paginationInfo2", paginationInfo);
-		model.addAttribute("addrDupliList", addrDupliList);
-		
-		return "/web/addr/AddrListDupliAjax";
-	}	
-
-	@RequestMapping("/web/mjon/addr/selectAddrPrint.do")
-	public String selectAddrPrint(@RequestParam("cellCheck2") String[] cellCheck, 
-			AddrVO addrVO, 
-			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 != "") {
-			addrVO.setMberId(userId);
-		} 
-		
-		addrVO.setRecordCountPerPage(100000);
-		addrVO.setFirstIndex(0);
-		
-		List<AddrVO> addrList = addrService.selectAddrList(addrVO);
-		 
-		String chk = "";
-		
-		for(int i=0; i<cellCheck.length; i++ ) {
-			chk += cellCheck[i] + ",";
-		}
-		
-		
-		model.addAttribute("chk", chk);
-		model.addAttribute("addrList", addrList);
-		
-		return "/web/addr/AddrListPrint";
-	}
-	
-	/**
-	 * 주소록 상세정보 ajax
-	 * @param addrCheck
-	 * @param request
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/selectAddrDetailAjax.do")
-	public ModelAndView selectAddrDetailAjax(HttpServletRequest request, 
-			AddrVO addrVO, Model model) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-
-		boolean isSuccess = true;
-		String msg = "";		
-		AddrVO addrInfo = null;
-		
-		try {
-			
-			addrInfo = addrService.selectAddrDetail(addrVO);
-
-		} catch (Exception e) {
-			isSuccess = false;
-			msg = e.getMessage();
-		}
-		
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		modelAndView.addObject("addrInfo", addrInfo);
-		
-		return modelAndView;
-		
-	}
-	
-	
-	/**
-	 * 주소록 그룹 삭제 로직 ajax
-	 * 
-	 * @param request
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/deleteAddrAjax.do")
-	public ModelAndView deleteAddrAjax(@RequestParam(value="addrCheck", defaultValue="0") String[] addrCheck, HttpServletRequest request, 
-			AddrVO addrVO, Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrVO.setLastUpdusrId(user.getId());
-		addrVO.setMberId(user.getId());
-		
-		//단일삭제
-		if(!"".equals(addrVO.getAddrId())) {
-			addrCheck[0] = addrVO.getAddrId();
-		}
-		
-		for(String id:addrCheck) {
-			try {
-				addrVO.setAddrId(id);
-//				addrService.deleteAddr(addrVO);
-				System.out.println("??????");
-				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		
-		return modelAndView;
-		
-	}
-
-	
-	
-	/**
-	 * 주소록 등록 로직 (ajax)
-	 * @param addrVO
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/insertAddrAjax.do")
-	public ModelAndView insertAddrAjax(HttpServletRequest request, ModelMap model, 
-			AddrVO addrVO
-			) throws Exception {
-		ModelAndView mv = new ModelAndView();
-		mv.setViewName("jsonView");
-		
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-		addrVO.setMberId(userId);
-
-		if("bookmark".equals(addrVO.getAddrGrpId())) {
-			addrVO.setBookmark("Y");
-			addrVO.setAddrGrpId("0");
-		}
-
-		int usedCnt = addrService.selectDuplAddrCnt(addrVO);
-		if(usedCnt > 0) {
-			mv.addObject("result","dupl");
-		}else {
-			if(userId != "") {
-				try {
-					addrService.insertAddr(addrVO);
-					mv.addObject("result","success");
-				} catch (Exception e) {
-					e.printStackTrace();
-					mv.addObject("result","fail");
-				}
-				
-			} else {
-				mv.addObject("result","fail");
-			}
-		}
-		return mv;
-	}
-	
-	
-	/**
-	 * 주소록 다중수정 ajax
-	 * @param addrCheck
-	 * @param request
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/updateAddrListAjax.do")
-	public ModelAndView updateAddrListAjax(HttpServletRequest request, 
-			AddrVO addrVO, Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrVO.setLastUpdusrId(user.getId());
-		addrVO.setMberId(user.getId());
-		
-		int listSize = addrVO.getAddrIds().length;
-
-		for(int i=0; i<listSize; i++) {
-			try {
-				// JSP 2023.04.07 => 주소록그룹 수정 추가
-				if (addrVO.getAddrGrpIds()[i].equals("bookmark")) {
-					// 자주보내는 번호
-					addrVO.setAddrGrpId("0");
-					addrVO.setBookmark("Y");					
-				}
-				else {
-					addrVO.setAddrGrpId(addrVO.getAddrGrpIds()[i]);
-					addrVO.setBookmark("N");
-				}
-				
-				addrVO.setAddrId(addrVO.getAddrIds()[i]);
-			
-				if(addrVO.getAddrPhones().length > 0) { 
-					addrVO.setAddrPhoneNo(addrVO.getAddrPhones()[i]);
-				}
-				else {
-					addrVO.setAddrPhoneNo(null);
-				}				
-				
-				if(addrVO.getAddrNms().length > 0) { 
-					addrVO.setAddrNm(addrVO.getAddrNms()[i]);
-				}
-				else {
-					addrVO.setAddrNm(null);
-				}
-				
-				if(!addrVO.getAddrInfo1s()[i].equals(null) || !"".equals(addrVO.getAddrInfo1s()[i])) {
-					addrVO.setAddrInfo1(addrVO.getAddrInfo1s()[i]);
-				}else {
-					addrVO.setAddrInfo1("");
-				}
-				
-				if(!addrVO.getAddrInfo2s()[i].equals(null) || !"".equals(addrVO.getAddrInfo2s()[i])) {
-					addrVO.setAddrInfo2(addrVO.getAddrInfo2s()[i]);
-				}else {
-					addrVO.setAddrInfo2("");
-				}
-				
-				if(!addrVO.getAddrInfo3s()[i].equals(null) || !"".equals(addrVO.getAddrInfo3s()[i])) {
-					addrVO.setAddrInfo3(addrVO.getAddrInfo3s()[i]);
-				}else {
-					addrVO.setAddrInfo3("");
-				}
-				
-				if(!addrVO.getAddrInfo4s()[i].equals(null) || !"".equals(addrVO.getAddrInfo4s()[i])) {
-					addrVO.setAddrInfo4(addrVO.getAddrInfo4s()[i]);
-				}else {
-					addrVO.setAddrInfo4("");
-				}
-				
-				addrService.updateAddr(addrVO);
-				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		return modelAndView;
-	}
-	
-	
-	/**
-	 * 주소록 다중수정 ajax
-	 * @param addrCheck
-	 * @param request
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/updateAddrAjax.do")
-	public ModelAndView updateAddrAjax(@RequestParam("addrCheck") String[] addrCheck, HttpServletRequest request, 
-			AddrVO addrVO, Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrVO.setLastUpdusrId(user.getId());
-		addrVO.setMberId(user.getId());
-		
-		for(String id:addrCheck) {
-			try {
-				
-				if("0".equals (addrVO.getAddrGrpId())) {
-					addrVO.setBookmark("Y");
-				} else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
-					addrVO.setBookmark("N");
-				}
-				
-				addrVO.setAddrId(id);
-				addrService.updateMemoAddr(addrVO);
-				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		
-		return modelAndView;
-		
-	}
-	
-
-	/**
-	 * 주소록 그룹이동 ajax
-	 * @param addrCheck
-	 * @param request
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/updateAddrMoveGrpAjax.do")
-	public ModelAndView updateAddrMoveGrpAjax(@RequestParam("addrCheck") String[] addrCheck, 
-			@RequestParam("addrPhoneNos") String[] addrPhoneNos,
-			HttpServletRequest request, 
-			AddrVO addrVO, Model model,
-			RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrVO.setLastUpdusrId(user.getId());
-		addrVO.setMberId(user.getId());
-		
-		// 그룹미지정, 자주보내는 번호 구분처리
-		if("0".equals (addrVO.getAddrGrpId())) {
-			// 그룹미지정
-			addrVO.setBookmark("N");
-		}
-		else if("bookmark".equals (addrVO.getAddrGrpId())) {
-			// 자주보내는 번호
-			addrVO.setBookmark("Y");
-			addrVO.setAddrGrpId("0");
-		} 
-		else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
-			addrVO.setBookmark("N");
-		}
-		
-		/**
-		 * 보내려는 그룹에 등록되어있는 전화번호를 변수에 담아둠
-		 */
-		List<?> addrPhoneList = addrService.selectPhoneNumInAddrGroup(addrVO);
-		
-		String phoneNos = ""; 
-		for(int i=0; i<addrPhoneList.size(); i++) {
-			if(i == 0) {
-				phoneNos = ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
-			} else {
-				phoneNos = phoneNos + "," + ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
-			}
-		}
-		
-		/**
-		 * 2. 넘어온 주소록 id를  db조회하여 리스트로 받아옴
-		 */
-		String duplYn = "N";
-		for(String phoneNo:addrPhoneNos) {
-			if(phoneNos != null && phoneNos.contains(phoneNo)) {
-				modelAndView.addObject("result","dupl");
-				duplYn = "Y";
-				break;
-			}
-		}
-		
-		if(duplYn == "N") {
-			for(String id:addrCheck) {
-				
-				try {
-					addrVO.setAddrId(id);
-					addrService.updateAddrGrp(addrVO);
-					
-					modelAndView.addObject("result", "success");
-				} catch (Exception e) {
-					e.printStackTrace();
-					modelAndView.addObject("result", "fail");
-					return modelAndView;
-				}
-			}
-		} 
-		
-		return modelAndView;
-		
-	}
-	
-	
-	/**
-	 * 주소록 복사 ajax
-	 * @param addrCheck
-	 * @param request
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/insertCopyAddrAjax.do")
-	public ModelAndView insertCopyAddrAjax(@RequestParam("addrCheck") String[] addrCheck, 
-			@RequestParam("addrPhoneNos") String[] addrPhoneNos,
-			HttpServletRequest request, 
-			AddrVO addrVO, Model model,
-			RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrVO.setMberId(user.getId());
-		
-		// 그룹미지정, 자주보내는 번호 구분처리
-		if("0".equals (addrVO.getAddrGrpId())) {
-			// 그룹미지정
-			addrVO.setBookmark("N");
-		}
-		else if("bookmark".equals (addrVO.getAddrGrpId())) {
-			// 자주보내는 번호
-			addrVO.setBookmark("Y");
-			addrVO.setAddrGrpId("0");
-		} 					
-		else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
-			addrVO.setBookmark("N");
-		}		
-		
-		/**
-		 * 복사하려는 그룹에 등록되어있는 전화번호를 변수에 담아둠
-		 */
-		List<?> addrPhoneList = addrService.selectPhoneNumInAddrGroup(addrVO);
-		
-		String phoneNos = ""; 
-		for(int i=0; i<addrPhoneList.size(); i++) {
-			if(i == 0) {
-				phoneNos = ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
-			} else {
-				phoneNos = phoneNos + "," + ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
-			}
-		}
-		
-		/**
-		 * 2. 넘어온 주소록 id를  db조회하여 리스트로 받아옴
-		 */
-		String duplYn = "N";
-		for(String phoneNo:addrPhoneNos) {
-			if(phoneNos != null && phoneNos.contains(phoneNo)) {
-				modelAndView.addObject("result","dupl");
-				duplYn = "Y";
-				break;
-			}
-		}
-		
-		if(duplYn == "N") {
-			for(String id:addrCheck) {
-				try {
-					addrVO.setAddrId(id);
-					addrService.insertCopyAddr(addrVO);
-					
-					modelAndView.addObject("result", "success");
-				} catch (Exception e) {
-					e.printStackTrace();
-					modelAndView.addObject("result", "fail");
-					return modelAndView;
-				}
-			}
-		}
-		return modelAndView;
-		
-	}
-
-	
-	/**
-	 * 주소록 그룹 내 휴대폰번호 중복체크
-	 *
-	 * @param addrVO
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/selectDuplAddrAjax.do")
-	public ModelAndView selectDuplAddrAjax(AddrVO addrVO) throws Exception {
-		ModelAndView mv =  new ModelAndView();
-		mv.setViewName("jsonView");
-		
-		int usedCnt = addrService.selectDuplAddrCnt(addrVO);
-		
-		mv.addObject("usedCnt", usedCnt);
-		
-		return mv;
-	}
-	
-	
-	/**
-	 * 주소록 폰주소록 가이드 이동
-	 * 
-	 * @param addrVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/mjon/addr/addrMobGuide.do")
-	public String addrMobGuide(ModelMap model) throws Exception {
-		
-		return "/web/addr/AddrMobGuide";
-	}
-	
-	
-
-	/**
-	 * 선택한 주소록을 문자전송 화면으로 보내기
-	 * @param addrVO
-	 * @param req
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping(value= {"/web/mjon/addr/selectAddrDataListAjax.do"})
-	public ModelAndView selectAddrDataListAjax(
-			AddrVO addrVO, 
-			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 {
-    		
-    		addrVO.setMberId(userId);
-    		
-    	}
-		
-    	
-		List<String> addrIdList = addrVO.getAddrIdList();
-		List<String> tempList = new ArrayList<String>();
-		
-		for(String seqStr : addrIdList) {
-			
-			String seqId = seqStr.replace("[", "");
-			seqId = seqId.replace("]", "");
-			
-			tempList.add(seqId);
-		}
-		
-		addrVO.setAddrIdList(tempList);
-		
-		List<AddrVO> resultList = addrService.selectAddrDataList(addrVO);
-		
-		
-		if(resultList == null) {
-			modelAndView.addObject("status", "emptyList");
-			modelAndView.addObject("message", "가져온 주소록 목록이 없습니다.");
-			
-		}else {
-			
-			modelAndView.addObject("status", "success");
-			modelAndView.addObject("resultList", resultList);
-			modelAndView.addObject("resultListCnt", resultList.size());
-			
-		}
-		
-		return modelAndView;
-	}
-	
-	
-	
-
-	//주소록 엑셀 다운로드 
-	@RequestMapping("/web/mjon/addr/addrExcelDownload.do")
-	public void addrExcelDownload(@RequestParam("cellCheck") String[] cellCheck,
-		AddrVO addrVO, 
-		HttpServletRequest request,
-		HttpServletResponse response ,
-		ModelMap model) throws Exception {
-		
-		addrVO.setRecordCountPerPage(100000);
-		addrVO.setFirstIndex(0);
-		
-		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrVO.setSearchSortCnd("addrId");
-			addrVO.setSearchSortOrd("asc");
-		}
-		
-		LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();
-	
-		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
-		SXSSFWorkbook wb = new SXSSFWorkbook(100);
-		CellStyle styleHeader = wb.createCellStyle();
-		styleHeader.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
-		styleHeader.setBorderLeft(CellStyle.BORDER_THIN);
-		styleHeader.setBorderRight(CellStyle.BORDER_THIN);
-		styleHeader.setBorderTop(CellStyle.BORDER_THIN);
-		
-		CellStyle styleList = wb.createCellStyle();
-		
-		Font font = wb.createFont();
-		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
-		
-		Cell cell = null;
-		Row row = null;
-		
-		String fileName ="주소록";
-		
-		String sheetTitle = ""; 
-		try{
-			if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-				addrVO.setSearchSortOrd("desc");
-			}
-			addrVO.setMberId(loginVO.getId());
-			List<AddrVO> addrList = addrService.selectAddrList(addrVO);
-			{ 
-				// row, cell 개수 순서대로 증가용 필드
-				int rowNumber = 0;
-				int celNumber = 0;
-				//화면 리스트
-				sheetTitle = "주소록" ; //제목
-				Sheet sheet = wb.createSheet(sheetTitle);
-				row = sheet.createRow(rowNumber++);
-				row = sheet.createRow(rowNumber++);		//줄추가
-	
-				//cell = row.createCell(celNumber++);
-				//cell.setCellValue("번호");
-				//cell.setCellStyle(style);
-				
-				int y = 0;
-				for(String field : cellCheck) {
-					//셀 칼럼 크기 설정
-					sheet.setColumnWidth(y, 4000);
-
-					cell = row.createCell(celNumber++);
-					cell.setCellValue(addrVO.getHeaderName(field));
-					cell.setCellStyle(styleHeader);
-					
-					y++;
-				}
-	
-				for(int i=0; i < addrList.size(); i++){
-					row = sheet.createRow(rowNumber++);		//줄추가
-					celNumber = 0;
-					//cell = row.createCell(celNumber++);
-					//cell.setCellStyle(style);
-					//cell.setCellValue(i+1); //번호
-	
-					for(String field : cellCheck) {
-						cell = row.createCell(celNumber++);
-						cell.setCellStyle(styleList);
-						cell.setCellValue(((AddrVO)addrList.get(i)).getFieldValue(field));
-					}
-				}
-			}
-			
-			response.setHeader("Set-Cookie", "fileDownload=true; path=/");
-			SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", 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 body
-	 * @param uploadFile
-	 * @param search
-	 * @param result
-	 * @param model
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping(value = "/web/mjon/addr/sendExelFilePhoneNumAjax.do")
-	@ResponseBody
-	public Object sendExelFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
-		
-		JsonResult jr = new JsonResult();
-		jr.setSuccess(false);
-		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
-		
-		//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;
-			//System.out.println("fileNameSplitCnt : " + fileNameSplitCnt);
-			
-			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[2345678]{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;
-	            int errMemoCnt = 0;
-	            
-		        
-	            //엑셀 확장자에 따른 처리 로직 분리
-				if(Ext.equals("xls")) {
-					
-					HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
-				    HSSFSheet sheet = workbook.getSheetAt(0);
-				    
-				    if(sheet.getLastRowNum() > 20000) { //
-		            	errMessage = "2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
-		            	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 < 7; j++){ //행읽기(6행까지나 2행까지만 필요)
-		                	cellValue = "";
-		                	cell = row.getCell(j); //이름/핸드폰/info1/info2/info3/info4/메모
-		                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면  
-		                		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) {
-		                		// 문자열에서 숫자만 추출
-		                		cellValue = getOnlyNumber(cellValue);
-
-		                		//전화번호
-		                		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("info1", cellValue);
-		                		}else {
-		                			errRep1Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 3) {
-		                		//치환2
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info2", cellValue);
-		                		}else {
-		                			errRep2Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 4) {
-		                		//치환3
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info3", cellValue);
-		                		}else {
-		                			errRep3Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 5) {
-		                		//치환4
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info4", cellValue);
-		                		}else {
-		                			errRep4Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}		                	
-		                	if(j == 6) {
-		                		//메모
-		                		boolean repChk = getNameRepLenChk("memo", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("memo", cellValue);
-		                		}else {
-		                			errMemoCnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                }
-		                if(null != jm.get("phone")) {
-		                	json.add(jm);
-		                }
-		                
-		            }
-		            
-		            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt + errMemoCnt;
-		            
-		            jr.setData(json);
-					jr.setSuccess(true);
-					
-					if(resultErrCnt > 0) {
-						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ resultErrCnt +" 건 있습니다.");
-					}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 > 20001) {
-		            	System.out.println("totRowDataCnt : " + totRowDataCnt);
-		            	errMessage = "2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
-		            	jr.setSuccess(false);
-		            	jr.setMessage(errMessage);
-		            	return jr;
-		            }
-		            
-		            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
-		            PhoneVO pVO = new PhoneVO();
-		            System.out.println("sheet.getLastRowNum() : " + sheet.getLastRowNum());
-		            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 < 7; j++){ //행읽기(6행까지나 2행까지만 필요)
-		                	cellValue = "";
-		                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5/메모
-		                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면
-		                		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) {
-		                		// 문자열에서 숫자만 추출
-		                		cellValue = getOnlyNumber(cellValue);
-		                		
-		                		//전화번호
-		                		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("info1", cellValue);
-		                		}else {
-		                			errRep1Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 3) {
-		                		//치환2
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info2", cellValue);
-		                		}else {
-		                			errRep2Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 4) {
-		                		//치환3
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info3", cellValue);
-		                		}else {
-		                			errRep3Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	if(j == 5) {
-		                		//치환4
-		                		boolean repChk = getNameRepLenChk("rep", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("info4", cellValue);
-		                		}else {
-		                			errRep4Cnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}		                			                	
-		                	if(j == 6) {
-		                		//메모
-		                		boolean repChk = getNameRepLenChk("memo", cellValue);
-		                		
-		                		if(repChk && errSts) {
-		                			jm.put("memo", cellValue);
-		                		}else {
-		                			errMemoCnt++;
-		                			errSts = false;
-		                			break;
-		                		}
-		                	}
-		                	
-		                }
-		                if(null != jm.get("phone") && errSts) {
-		                	json.add(jm);
-		                }
-		                
-		            }
-		            
-		            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
-		            
-		            jr.setData(json);
-					jr.setSuccess(true);
-					
-					if(resultErrCnt > 0) {
-						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ resultErrCnt +" 건 있습니다.");
-					}else {
-						jr.setMessage("");
-					}
-				}	//xlsx 처리 끝
-				
-			}
-			else {
-				
-				String ttt = files.get(0).getSize() + "_" + 
-				files.get(0).getContentType()  + "_" + 
- 				files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1];
-					
-				jr.setSuccess(false);
-				jr.setMessage("엑셀파일 인식오류.");
-				//jr.setMessage("엑셀파일 인식오류" + ttt);			
-			}			
-		}
-		else {
-			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/addr/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;
-				}
-				
-				BufferedReader reader = new BufferedReader(new InputStreamReader(multiRequest.getFile("file0").getInputStream()));
-				
-				String line = null;
-				String[] splitedStr = null;
-				String[] tempStr = null;
-				int errPhoneCnt = 0;
-				int totRowNum = 0;
-				
-				//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
-				String phoneRegExp = "^(050[2345678]{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("\\,");
-					if(tempStr.length > 1) {
-						splitedStr = line.split("\\,");
-					}else {
-						splitedStr = line.split("\t");;
-					}
-
-					for (int i = 0; i < splitedStr.length; i++) {
-						splitedStr[i] = splitedStr[i].trim();
-						if(i == 0) {
-							//이름
-							jm.put("name", splitedStr[i]);							
-						}
-						if(i == 1) {
-	                		// 문자열에서 숫자만 추출
-							splitedStr[i] = getOnlyNumber(splitedStr[i]);
-	                		
-							if(splitedStr[i].matches(phoneRegExp)) {
-								//휴대폰 번호
-								jm.put("phone", splitedStr[i]);
-							}else {
-		    	            	errPhoneCnt++;
-	                		}
-						}
-	                	if(i == 2) {
-	                		//info1
-	                		jm.put("info1", splitedStr[i]);
-	                	}
-	                	if(i == 3) {
-	                		//info2
-	                		jm.put("info2", splitedStr[i]);
-	                	}
-	                	if(i == 4) {
-	                		//info3
-	                		jm.put("info3", splitedStr[i]);
-	                	}
-	                	if(i == 5) {
-	                		//info4
-	                		jm.put("info4", splitedStr[i]);
-	                	}		                			                							
-	                	if(i == 6) {
-	                		//메모
-	                		jm.put("memo", splitedStr[i]);
-	                	}
-					}
-					
-					if(jm.get("phone") != null) {
-						json.add(jm);
-					}
-
-					totRowNum++;
-				} // end while
-				jr.setData(json);
-				jr.setSuccess(true);
-				
-	            if (totRowNum > 20000) {
-	            	jr.setMessage("20000");
-	            }
-	            else {
-					if(errPhoneCnt > 0) {
-						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ errPhoneCnt +" 건 있습니다.");
-					}else {
-						jr.setMessage("");
-					}
-	            }
-			}
-			
-		}
-		
-		return jr;
-	}
-
-	
-    /**
-     * 주소록 대량등록 저장
-     * @param searchVO
-     * @param model
-     * @return	"/web/mjon/addr/addrMassInsertByTempAjax.do"
-     * @throws Exception
-     */
-	@RequestMapping(value= {"/web/mjon/addr/addrMassInsertByTempAjax.do"})
-	public ModelAndView addrMassInsertByTempAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
-			RedirectAttributes redirectAttributes, 
-			ModelMap model) throws Exception{
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-
-		//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
-		String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
-        
-		String charset = "euc-kr";
-		boolean isSuccess = true;
-		String msg = "";
-		int resultCnt = 0;
-		int dupliCnt = 0; 	// 중복 데이터 수
-        int errPhoneCnt = 0;		
-        List<AddrVO> addrMassDupliList = new ArrayList<AddrVO>();	// 중복 휴대폰번호
-		
-		try {
-			
-			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-	    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-	    	
-        	if(userId.equals("")) {
-        		isSuccess = false;
-    			modelAndView.addObject("isSuccess", isSuccess);        		
-        		modelAndView.addObject("msg", "로그인 후 이용이 가능합니다.");
-    			return modelAndView;
-        	}
-        	else {
-        		addrVO.setMberId(userId);
-        	}
-        	
-    		//회원별 주소록 전체 갯수 조회
-        	int addrBefAfterCnt = 0;
-    		int addrBefCnt = addrService.selectAddrTotalCount(addrVO);    		
-    		int addrNewCnt = addrVO.getPhoneList().length;	//신규 추가할 주소록 갯수
-    		int sumAddrCnt = addrBefCnt + addrNewCnt;			//기존 + 신규 주소록 합산
-    		
-    		// 신규 주소록 여부 체크
-    		if (addrVO.getAddrGrpId().equals("NEW")) {
-    			
-    			AddrGroupVO addrGroupVO = new AddrGroupVO();
-    			addrGroupVO.setMberId(userId);
-    			addrGroupVO.setAddrGrpNm(addrVO.getAddrGrpNm());
-    			// 정렬순서
-    			int nextOrderNumber = addrGroupService.selectMaxOrderNumber(addrGroupVO);
-    			addrGroupVO.setGrpOrder(nextOrderNumber);
-    			
-    			addrGroupService.insertAddrGroup(addrGroupVO);
-    			
-    			// 신규 추가한 그룹아이디
-    			addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
-    		}	    		
-    		
-			// 그룹미지정, 자주보내는 번호 구분처리
-			if("bookmark".equals (addrVO.getAddrGrpId())) {
-				// 자주보내는 번호
-				addrVO.setBookmark("Y");
-				addrVO.setAddrGrpId("0");
-			} 
-			else {
-				addrVO.setBookmark("N");
-			}     		
-    		
-			// 2024.01.24 10만건  -> 50만건으로 증설 요청으로 인한 증설
-    		List<AddrVO> addrDataInfo = new ArrayList<AddrVO>();
-    		if(addrBefCnt < 500000) { // 기존 등록된 주소록이 10만건 미만이면
-    			
-    			//받는사람 리스트 건수 체크해주기
-    			if(sumAddrCnt > 500000) {
-        			isSuccess = false;
-        			msg = "주소록은 총 50만개까지만 등록이 가능합니다.";
-    			}
-    			else {
-    				for(int i=0; i < addrNewCnt; i++) {
-    					AddrVO tempAddrVO = new AddrVO();
-
-    					if(addrVO.getNameList().length > 0) { 
-	    					if(addrVO.getNameList()[i].equals("-")) {
-	    						tempAddrVO.setAddrNm(null);
-	    					}else {
-	    						String tmpNm = addrVO.getNameList()[i].trim().replaceAll("§", ",");
-	    						int nmLen = tmpNm.getBytes(charset).length;
-	    						
-	    						if(nmLen >= 20) {
-	    							//isSuccess = false;
-	    							//msg = "이름 항목의 내용(\" " + tmpNm + " \")이 길이를 초과하여 입력되었습니다. 12글자 이하로 입력해 주세요.";
-	    							//break;
-	    							
-	    							tempAddrVO.setAddrNm(subStringBytes(addrVO.getNameList()[i].replaceAll("§", ","), 20, 2));
-	    						}else {
-	    							tempAddrVO.setAddrNm(addrVO.getNameList()[i].trim().replaceAll("§", ","));
-	    						}
-	    						
-	    					}
-    					}
-    					else {
-    						tempAddrVO.setAddrNm(null);
-    					}
-    					
-    					if(addrVO.getPhoneList().length > 0) { 
-	    					if(addrVO.getPhoneList()[i].equals("-")) {
-	    						tempAddrVO.setAddrPhoneNo(null);
-	    					}else {
-	    						tempAddrVO.setAddrPhoneNo(addrVO.getPhoneList()[i].trim().replaceAll("§", ","));
-	    					}
-    					}
-    					else {
-    						tempAddrVO.setAddrPhoneNo(null);
-    					}
-    					
-    					if(addrVO.getInfo1List().length > 0) { 
-	    					if(addrVO.getInfo1List()[i].equals("-")) {
-	    						tempAddrVO.setAddrInfo1(null);
-	    					}else {
-	    						
-	    						String tmpInfo1 = addrVO.getInfo1List()[i].replaceAll("§", ",");
-	    						int info1Len = tmpInfo1.getBytes(charset).length;
-	    						
-	    						if(info1Len >= 40) {
-	    							//isSuccess = false;
-	    							//msg = "[*1*] 항목의 내용(\" " + tmpInfo1 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
-	    							//break;
-	    							tempAddrVO.setAddrInfo1(subStringBytes(addrVO.getInfo1List()[i].replaceAll("§", ","), 40, 2));
-	    						}else {
-	    							tempAddrVO.setAddrInfo1(addrVO.getInfo1List()[i].replaceAll("§", ","));
-	    						}
-	    					}
-    					}
-    					else {
-    						tempAddrVO.setAddrInfo1(null);
-    					}
-    					
-    					if(addrVO.getInfo2List().length > 0) { 
-        					if(addrVO.getInfo2List()[i].equals("-")) {
-        						tempAddrVO.setAddrInfo2(null);
-        					}else {
-        						String tmpInfo2 = addrVO.getInfo2List()[i].replaceAll("§", ",");
-        						int info2Len = tmpInfo2.getBytes(charset).length;
-        						
-        						if(info2Len >= 40) {
-        							//isSuccess = false;
-        							//msg = "[*2*] 항목의 내용(\" " + tmpInfo2 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
-        							//break;
-        							
-        							tempAddrVO.setAddrInfo2(subStringBytes(addrVO.getInfo2List()[i].replaceAll("§", ","), 40, 2));
-        						}else {
-        							tempAddrVO.setAddrInfo2(addrVO.getInfo2List()[i].replaceAll("§", ","));
-        						}
-        						
-        					}
-    					}
-    					else {
-    						tempAddrVO.setAddrInfo2(null);
-    					}    					
-
-    					if(addrVO.getInfo3List().length > 0) { 
-        					if(addrVO.getInfo3List()[i].equals("-")) {
-        						tempAddrVO.setAddrInfo3(null);
-        					}else {
-        						String tmpInfo3 = addrVO.getInfo3List()[i].replaceAll("§", ",");
-        						int info3Len = tmpInfo3.getBytes(charset).length;
-        						
-        						if(info3Len >= 40) {
-        							//isSuccess = false;
-        							//msg = "[*3*] 항목의 내용(\" " + tmpInfo3 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
-        							//break;
-	    							
-        							tempAddrVO.setAddrInfo3(subStringBytes(addrVO.getInfo3List()[i].replaceAll("§", ","), 40, 2));
-        						}else {
-        							tempAddrVO.setAddrInfo3(addrVO.getInfo3List()[i].replaceAll("§", ","));
-        						}
-        					}
-    					}
-    					else {
-    						tempAddrVO.setAddrInfo3(null);
-    					}    					    					
-    					
-    					if(addrVO.getInfo4List().length > 0) { 
-        					if(addrVO.getInfo4List()[i].equals("-")) {
-        						tempAddrVO.setAddrInfo4(null);
-        					}else {
-        						String tmpInfo4 = addrVO.getInfo4List()[i].replaceAll("§", ",");
-        						int info4Len = tmpInfo4.getBytes(charset).length;
-        						
-        						if(info4Len >= 40) {
-        							//isSuccess = false;
-        							//msg = "[*4*] 항목의 내용(\" " + tmpInfo4 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
-        							//break;
-        							
-        							tempAddrVO.setAddrInfo4(subStringBytes(addrVO.getInfo4List()[i].replaceAll("§", ","), 40, 2));
-        						}else {
-        							tempAddrVO.setAddrInfo4(addrVO.getInfo4List()[i].replaceAll("§", ","));
-        						}
-        					}
-    					}
-    					else {
-    						tempAddrVO.setAddrInfo4(null);
-    					}    					    					
-
-    					if(addrVO.getMemoList().length > 0) { 
-        					if(addrVO.getMemoList()[i].equals("-")) {
-        						tempAddrVO.setAddrComment(null);
-        					}else {
-        						String tmpComment = addrVO.getMemoList()[i].replaceAll("§", ",");
-        						int commLen = tmpComment.getBytes(charset).length;
-        						
-        						if(commLen >= 200) {
-        							//isSuccess = false;
-        							//msg = "메모 항목의 내용(\" " + tmpComment + " \")이 길이를 초과하여 입력되었습니다. 100글자 이하로 입력해 주세요.";
-        							//break;
-        							
-        							tempAddrVO.setAddrComment(subStringBytes(addrVO.getMemoList()[i].replaceAll("§", ","), 200, 2));
-        						}else {
-        							tempAddrVO.setAddrComment(addrVO.getMemoList()[i].replaceAll("§", ","));
-        						}
-        					}
-    					}
-    					else {
-    						tempAddrVO.setAddrComment(null);
-    					}
-    					
-    					tempAddrVO.setMberId(userId);
-    					tempAddrVO.setFrstRegisterId(userId);
-    					tempAddrVO.setAddrGrpId(addrVO.getAddrGrpId());		// 그룹 지정
-
-    					// 그룹미지정, 자주보내는 번호 구분처리
-    					if("Y".equals (addrVO.getBookmark())) {
-    						// 자주보내는 번호
-    						tempAddrVO.setBookmark("Y");
-    						tempAddrVO.setAddrGrpId("0");
-    					} 
-    					else {
-    						tempAddrVO.setBookmark("N");
-    					} 
-    					
-    					AddrVO addrVO2 = new AddrVO();
-    					addrVO2.setMberId(userId);
-    					addrVO2.setAddrGrpId(addrVO.getAddrGrpId());		// 그룹 지정
-    					addrVO2.setAddrPhoneNo(addrVO.getPhoneList()[i]);	// 연락처
-    					
-    					// 휴대폰 유효성 검사
-    					boolean isPhoneNoErr = true;
-						if(addrVO.getPhoneList()[i].matches(phoneRegExp)) {
-							isPhoneNoErr = false;	// 유효성 통과
-						}else {
-	    	            	errPhoneCnt++;
-                		}
-						
-    					//int usedCnt = addrService.selectDuplAddrCnt(addrVO2);
-    					if(isPhoneNoErr == false) {
-	    					//주소록 리스트에 데이터 추가해 주기
-	    					addrDataInfo.add(tempAddrVO);
-    					}
-    				}
-    				
-    				System.out.println("======================================================");
-    				System.out.println("+++++++++++++++++++++++++ isSuccess ::: "+isSuccess);
-    				System.out.println("======================================================");
-    				
-    				//주소록에 데이터 추가해 주기
-    				if (isSuccess == true && addrDataInfo.size() > 0) {
-    					// 주소록 대량등록 By Temp 주소록 All
-    					resultCnt = addrService.insertAddrByTempAddrAll(addrDataInfo, addrVO);
-    					
-    					addrBefAfterCnt = addrService.selectAddrTotalCount(addrVO);
-    		    		
-    					addrMassDupliList = addrService.selectTempAddrDupliList(addrVO);
-    					
-    		    		resultCnt = addrBefAfterCnt - addrBefCnt; 
-    		    		dupliCnt = addrNewCnt - resultCnt;
-    				}
-    			}
-    		}
-    		else {
-    			isSuccess = false;
-    			msg = "주소록은 총 50만개까지만 등록이 가능합니다.";
-    		}
-    	}
-		catch(Exception e) {
-			
-			isSuccess = false;
-    		msg = "주소록 저장에 오류가 발생하였습니다. 시스템 관리자에게 문의 바랍니다.";
-    		System.out.println("==============================================");
-    		System.out.println("+++++++++++++++++++ addrMassInsertByTempAjax Error ::: "+e.getMessage());
-    		System.out.println("==============================================");
-    		
-    	}
-			
-		modelAndView.addObject("isSuccess", isSuccess);        		
-		modelAndView.addObject("msg", msg);
-		modelAndView.addObject("resultCnt", resultCnt);
-		modelAndView.addObject("dupliCnt", dupliCnt);
-		modelAndView.addObject("errPhoneCnt", errPhoneCnt);
-		modelAndView.addObject("addrMassDupliList", addrMassDupliList);
-
-		return modelAndView;
-	} 
-	
-	/* 바이트 자르기
-	UTF-8일 경우
-	subStringBytes("블라블라블라라", 10, 3);
-	EUC-KR일 경우
-	subStringBytes("블라블라블라라", 10, 2);
-	*/
-	public String subStringBytes(String str, int byteLength, int sizePerLetter) {
-		  int retLength = 0;
-		  int tempSize = 0;
-		  int asc;
-		  if (str == null || "".equals(str) || "null".equals(str)) {
-		    str = "";
-		  }
-		 
-		  int length = str.length();
-		 
-		  for (int i = 1; i <= length; i++) {
-		    asc = (int) str.charAt(i - 1);
-		    if (asc > 127) {
-		      if (byteLength >= tempSize + sizePerLetter) {
-		        tempSize += sizePerLetter;
-		        retLength++;
-		      }
-		    } else {
-		      if (byteLength > tempSize) {
-		        tempSize++;
-		        retLength++;
-		      }
-		    }
-		  }
-		 
-	  return str.substring(0, retLength);
-	}
-
-
-	
-    /**
-     * 주소록 그룹 목록
-     * @param searchVO
-     * @param model
-     * @return	"/web/mjon/addr/addrGroupListAjax.do"
-     * @throws Exception
-     */
-	@RequestMapping(value= {"/web/mjon/addr/addrGroupListAjax.do"})
-	public ModelAndView addrGroupListAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, 
-			RedirectAttributes redirectAttributes, 
-			ModelMap model) throws Exception{
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		List<AddrGroupVO> addrGroupList = null;
-		
-		try {
-			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-			if(userId != "") {
-				addrGroupVO.setMberId(userId);
-
-		    	if(addrGroupVO.getPageUnit() != 10) {
-		    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
-				}
-				
-				if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-					addrGroupVO.setSearchSortCnd("grpOrder");
-					addrGroupVO.setSearchSortOrd("desc");
-				}
-
-				addrGroupVO.setSiteId("web");
-				addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
-			}			
-    	}
-		catch(Exception e) {
-			isSuccess = false;
-    		msg = e.getMessage();
-    	}
-			
-		modelAndView.addObject("isSuccess", isSuccess);        		
-		modelAndView.addObject("msg", msg);
-		model.addAttribute("addrGroupList", addrGroupList);
-
-		return modelAndView;
-	} 	
-	
-    /**
-     * 주소록 그룹별 중복 연락처 목록
-     * @param searchVO
-     * @param model
-     * @return	"/web/mjon/addr/addrDupliListAjax.do"
-     * @throws Exception
-     */
-	@RequestMapping(value= {"/web/mjon/addr/addrDupliListAjax.do"})
-	public ModelAndView addrDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
-			RedirectAttributes redirectAttributes, 
-			ModelMap model) throws Exception{
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		List<AddrVO> addrDupliList = null;
-		
-		try {
-			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-			if(userId != "") {
-				addrVO.setMberId(userId);
-				
-				// 주소록 그룹별 중복 연락처 목록
-				addrDupliList = addrService.selectAddrDupliList(addrVO);
-			}
-    	}
-		catch(Exception e) {
-			isSuccess = false;
-    		msg = e.getMessage();
-    	}
-			
-		modelAndView.addObject("isSuccess", isSuccess);        		
-		modelAndView.addObject("msg", msg);
-		model.addAttribute("addrDupliList", addrDupliList);
-
-		return modelAndView;
-	} 	
-	
-    /**
-     * 주소록 그룹별 중복 연락처 삭제
-     * @param searchVO
-     * @param model
-     * @return	"/web/mjon/addr/deleteAddrDupliList.do"
-     * @throws Exception
-     */
-	@RequestMapping(value= {"/web/mjon/addr/deleteAddrDupliListAjax.do"})
-	public ModelAndView deleteAddrDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
-			RedirectAttributes redirectAttributes, 
-			ModelMap model) throws Exception{
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		try {
-			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-			if(userId != "") {
-				addrVO.setMberId(userId);
-
-				// 주소록 그룹별 중복 연락처 삭제
-				addrService.deleteAddrDupliList(addrVO);
-			}
-			else {
-				isSuccess = false;
-	    		msg = "로그인후 이용하세요.";				
-			}
-    	}
-		catch(Exception e) {
-			isSuccess = false;
-    		msg = e.getMessage();
-    	}
-			
-		modelAndView.addObject("isSuccess", isSuccess);        		
-		modelAndView.addObject("msg", msg);
-
-		return modelAndView;
-	} 		
-	
-	
-    /**
-     * 주소록 그룹별 중복 연락처 삭제
-     * @param searchVO
-     * @param model
-     * @return	"/web/mjon/addr/deleteAddrByAllDupliListAjax.do"
-     * @throws Exception
-     */
-	@RequestMapping(value= {"/web/mjon/addr/deleteAddrByAllDupliListAjax.do"})
-	public ModelAndView deleteAddrByAllDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
-			RedirectAttributes redirectAttributes, 
-			ModelMap model) throws Exception{
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		try {
-			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-			if(userId != "") {
-				addrVO.setMberId(userId);
-
-				// 주소록 그룹별 중복 연락처 삭제
-				addrService.deleteAddrDupliListByAll(addrVO);
-			}
-			else {
-				isSuccess = false;
-	    		msg = "로그인후 이용하세요.";				
-			}
-    	}
-		catch(Exception e) {
-			isSuccess = false;
-    		msg = e.getMessage();
-    	}
-			
-		modelAndView.addObject("isSuccess", isSuccess);        		
-		modelAndView.addObject("msg", msg);
-
-		return modelAndView;
-	} 	
-	
-	
-
-	public boolean getNameRepLenChk(String type, String value) {
-		
-		boolean rtnValue = true;
-		
-		// JSPark 2023.02.17 : 글자길이체크 주석처리 => 저장시 절삭하기 때문 
-		/*
-		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;
-				
-			}
-			
-		}else if(type.equals("memo")) {
-			
-			String tmpRep = value;
-			int repLen = tmpRep.length();
-			
-			if(repLen > 120) {
-				
-				rtnValue = false;
-				
-			}
-			
-		}
-		*/
-		
-		return rtnValue;
-	}
-	
-	// 문자열에서 숫자만 추출
-	public String getOnlyNumber(String str) {
-		//String str = "aaa1234, ^&*2233pp";
-		
-		String intStr = str.replaceAll("[^\\d]", "");
-		
-		return intStr;
-	}
+package itn.let.mjo.addr.web;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+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.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+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.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.security.userdetails.util.EgovUserDetailsHelper;
+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.util.RedirectUrlMaker;
+import itn.com.cmm.util.StringUtil;
+import itn.com.utl.fcc.service.EgovStringUtil;
+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.AddrTransHistVO;
+import itn.let.mjo.addr.service.AddrVO;
+import itn.let.mjo.msgdata.service.PhoneVO;
+
+/**
+ * 주소록 관한 controller 클래스를 정의한다.
+ * @author ITN
+ * @since 2021.04.08
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *
+ *   수정일      수정자           수정내용
+ *  -------    --------    ---------------------------
+ *   2021.04.08  ITN          최초 생성
+ *
+ * </pre>
+ */
+@Controller
+public class AddrController {
+
+	
+	@Resource (name = "AddrService")
+	private AddrService addrService;
+	
+	@Resource (name = "AddrGroupService")
+	private AddrGroupService addrGroupService;
+	
+	/** EgovMessageSource */
+	@Resource(name="egovMessageSource")
+	EgovMessageSource egovMessageSource;
+	
+	
+	/**
+	 * 주소록 리스트
+	 * @param addrVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/selectAddrList.do")
+	public String selectAddrList(@ModelAttribute("searchVO") AddrVO addrVO
+			,ModelMap model) throws Exception {
+		
+		if(addrVO.getPageUnit() != 10) {
+			addrVO.setPageUnit(addrVO.getPageUnit());
+		}
+
+		/** pageing */
+		PaginationInfo paginationInfo = new PaginationInfo();
+		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
+		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
+		paginationInfo.setPageSize(addrVO.getPageSize());
+		
+		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
+		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
+		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
+		
+		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrVO.setSearchSortCnd("addrId");
+			addrVO.setSearchSortOrd("asc");
+		}
+		
+		// 기간검색 설정
+    	Calendar mon = Calendar.getInstance();    
+    	mon.add(Calendar.WEEK_OF_MONTH , -2);    
+    	String before2Week = new java.text.SimpleDateFormat("yyyy-MM-dd").format(mon.getTime());    
+    	if (null == addrVO.getSearchStartDate() || addrVO.getSearchStartDate().equals("")) {
+    		addrVO.setSearchStartDate(before2Week);
+    	}				
+		
+		List<AddrVO> addrList = addrService.selectAddrNewList(addrVO);
+		
+		int totCnt = 0;
+		 if(addrList.size() > 0) {
+ 			totCnt = addrList.get(0).getTotcnt();
+ 		}
+		 
+		paginationInfo.setTotalRecordCount(totCnt);
+		model.addAttribute("addrList", addrList);
+		model.addAttribute("paginationInfo", paginationInfo);
+		
+		return "/uss/ion/addr/AddrList";
+	}
+   
+	
+	/**
+	 * 주소록 등록 페이지 이동
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/registAddr.do")
+	public String registAddr(ModelMap model) throws Exception {
+		
+		return "/uss/ion/addr/AddrRegist";
+	}
+	
+	
+	/**
+	 * 주소록 추가 로직
+	 * @param addrVO
+	 * @param redirectAttributes
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/insertAddr.do")
+	public String insertAddr(AddrVO addrVO
+			,RedirectAttributes redirectAttributes
+			,HttpServletRequest request) throws Exception {
+		
+		try {
+			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+
+			if( addrVO.getMberId() == null || "".equals(addrVO.getMberId()) ) {
+				addrVO.setMberId(user.getId());
+			}
+			
+			// 자주 보내는 번호
+			if("bookmark".equals(addrVO.getAddrGrpId())) {
+				addrVO.setBookmark("Y");
+				addrVO.setAddrGrpId("0");
+			}
+			
+			// 주소록 그룹 내 휴대폰번호 중복체크
+			int usedCnt = addrService.selectDuplAddrCnt(addrVO);
+			if (usedCnt > 0) {
+				redirectAttributes.addFlashAttribute("message", "해당 그룹내 중복된 휴대폰 번호가 있습니다.");
+			}
+			else {
+				addrService.insertAddr(addrVO);
+				redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.insert"));
+			}
+			
+		}catch (Exception e) {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.insert"));
+		}
+		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/uss/ion/addr/selectAddrList.do");
+		return redirectUrlMaker.getRedirectUrl();
+		
+	}
+	
+
+	/**
+	 * 주소록 수정 로직
+	 * 
+	 * @param addrVO
+	 * @param redirectAttributes
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/updateAddrByAdminAjax.do")
+	public ModelAndView updateAddrByAdminAjax(AddrVO addrVO
+			,RedirectAttributes redirectAttributes
+			,HttpServletRequest request
+			) throws Exception{
+		
+		ModelAndView modelAndView =  new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		try {
+			
+			addrService.updateAddrByAdmin(addrVO);
+			
+		}
+		catch(Exception e) {
+			System.out.println("");
+			isSuccess = false;
+			msg = "에러메시지 : " + e.getMessage();			
+			e.printStackTrace();
+		}		
+		
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		
+		return modelAndView;
+	}
+	
+	
+	/**
+	 * 주소록 수정 페이지 이동
+	 * 
+	 * @param addrVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/editAddr.do")
+	public String editAddr(AddrVO addrVO
+			, ModelMap model ) throws Exception {
+		
+		AddrVO addrInfo = addrService.selectAddrDetail(addrVO);
+		
+		model.addAttribute("addrInfo", addrInfo);
+		
+		return "/uss/ion/addr/AddrEdit";
+	}
+	
+	/**
+	 * 주소록 삭제 로직
+	 * 
+	 * @param request
+	 * @param addrVO
+	 * @param redirectAttributes
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/deleteAddr.do")
+	public String deleteAddr (HttpServletRequest request, @ModelAttribute("searchVO") AddrVO addrVO
+			,RedirectAttributes redirectAttributes
+			,ModelMap model) throws Exception {
+		
+		int result = addrService.deleteAddrByAdminAll(addrVO); 
+		
+		if (result > 0) {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
+		} else {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.delete"));
+		}
+		redirectAttributes.addAttribute("pageIndex", addrVO.getPageIndex());
+		redirectAttributes.addAttribute("searchCondition", addrVO.getSearchCondition());
+		redirectAttributes.addAttribute("searchKeyword", addrVO.getSearchKeyword());
+		
+		return "redirect:/uss/ion/addr/selectAddrList.do";
+	}
+
+
+	
+	
+	/**
+	 * 주소록 타 회원으로 이전(복사) 처리 
+	 * @param addrVO
+	 * @param addrGroupVO
+	 * @param addrTransHistVO
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/transAddrGroupAjax.do")
+	public ModelAndView transAddrGroupAjax(AddrVO addrVO, AddrGroupVO addrGroupVO, AddrTransHistVO addrTransHistVO) throws Exception {
+		ModelAndView modelAndView =  new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		try {
+			String successCd = addrService.updateAddrAnotherMember(addrVO, addrGroupVO, addrTransHistVO);
+			
+			modelAndView.addObject("status", "success");
+			modelAndView.addObject("result", successCd);
+			
+		}catch(Exception e) {
+			e.printStackTrace();
+			modelAndView.addObject("status", "fail");
+			return modelAndView;
+		}
+
+		return modelAndView;
+	}
+	
+	
+
+	/**
+	 * 주소록 사용자 화면 껍데기
+	 * @param addrVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/selectAddrList.do")
+	public String selectAddrWebList(@ModelAttribute("searchVO") AddrVO addrVO
+			,AddrGroupVO addrGroupVO, ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
+		
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+		if(userId == "") {
+			/*redirectAttributes.addFlashAttribute("fail", true);*/
+			//redirectAttributes.addFlashAttribute("message", "문자온 서비스는 로그인 후 이용 가능합니다.");
+			return "redirect:/web/user/login/login.do";
+		}
+		
+		return "/web/addr/AddrList";
+	}
+	
+	
+	
+	/**
+	 * 사용자 주소록 리스트 Ajax
+	 * @param request
+	 * @param model
+	 * @param addrVO
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/selectAddrAjax.do")
+	public String selectAddrAjax(HttpServletRequest request, ModelMap model, 
+			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
+		
+		//로그인 권한정보 불러오기
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+		
+		if(userId != "") {
+			addrVO.setMberId(userId);
+		} else {
+			return "/web/addr/AddrListAjax";
+		}
+		
+		if(addrVO.getPageUnit() != 10) {
+			addrVO.setPageUnit(addrVO.getPageUnit());
+		}
+		
+		/** pageing */
+		PaginationInfo paginationInfo = new PaginationInfo();
+		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
+		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
+		paginationInfo.setPageSize(addrVO.getPageSize());
+		
+		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
+		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
+		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
+		
+		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrVO.setSearchSortCnd("addrId");
+			addrVO.setSearchSortOrd("asc");
+		}
+		
+		List<AddrVO> addrList = addrService.selectAddrList(addrVO);
+		
+		int totCnt = 0;
+		 if(addrList.size() > 0) {
+			totCnt = addrList.get(0).getTotcnt();
+		}
+		 
+		paginationInfo.setTotalRecordCount(totCnt);
+		
+		model.addAttribute("paginationInfo", paginationInfo);
+		model.addAttribute("addrList", addrList);
+		model.addAttribute("startKeyword",addrVO.getStartKeyword());
+		model.addAttribute("userId", userId);
+		
+		return "/web/addr/AddrListAjax";
+	}
+	
+	
+
+	@RequestMapping("/web/mjon/addr/addrListforExcelAjax.do")
+	public String AddrListforExcel(HttpServletRequest request, ModelMap model, 
+			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
+			
+			return "/web/addr/addrListforExcel";
+	}
+	/**
+	 * 사용자 주소록 중복 리스트 Ajax
+	 * @param request
+	 * @param model
+	 * @param addrVO
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/selectAddrDupliAjax.do")
+	public String selectAddrDupliAjax(HttpServletRequest request, ModelMap model, 
+			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
+		
+		//로그인 권한정보 불러오기
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+		
+		if(userId != "") {
+			addrVO.setMberId(userId);
+		} 
+		
+		if(addrVO.getPageUnit() != 10) {
+			addrVO.setPageUnit(addrVO.getPageUnit());
+		}
+		
+		/** pageing */
+		PaginationInfo paginationInfo = new PaginationInfo();
+		paginationInfo.setCurrentPageNo(addrVO.getPageIndex());
+		paginationInfo.setRecordCountPerPage(addrVO.getPageUnit());
+		paginationInfo.setPageSize(addrVO.getPageSize());
+		
+		addrVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
+		addrVO.setLastIndex(paginationInfo.getLastRecordIndex());
+		addrVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
+		
+		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrVO.setSearchSortCnd("addrId");
+			addrVO.setSearchSortOrd("asc");
+		}
+		
+		List<AddrVO> addrDupliList = addrService.selectAddrDupliListByAll(addrVO);
+		
+		int totCnt = 0;
+		 if(addrDupliList.size() > 0) {
+			totCnt = addrDupliList.get(0).getTotcnt();
+		}
+		 
+		paginationInfo.setTotalRecordCount(totCnt);
+		
+		model.addAttribute("paginationInfo2", paginationInfo);
+		model.addAttribute("addrDupliList", addrDupliList);
+		
+		return "/web/addr/AddrListDupliAjax";
+	}	
+
+	@RequestMapping("/web/mjon/addr/selectAddrPrint.do")
+	public String selectAddrPrint(@RequestParam("cellCheck2") String[] cellCheck, 
+			AddrVO addrVO, 
+			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 != "") {
+			addrVO.setMberId(userId);
+		} 
+		
+		addrVO.setRecordCountPerPage(100000);
+		addrVO.setFirstIndex(0);
+		
+		List<AddrVO> addrList = addrService.selectAddrList(addrVO);
+		 
+		String chk = "";
+		
+		for(int i=0; i<cellCheck.length; i++ ) {
+			chk += cellCheck[i] + ",";
+		}
+		
+		
+		model.addAttribute("chk", chk);
+		model.addAttribute("addrList", addrList);
+		
+		return "/web/addr/AddrListPrint";
+	}
+	
+	/**
+	 * 주소록 상세정보 ajax
+	 * @param addrCheck
+	 * @param request
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/selectAddrDetailAjax.do")
+	public ModelAndView selectAddrDetailAjax(HttpServletRequest request, 
+			AddrVO addrVO, Model model) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+
+		boolean isSuccess = true;
+		String msg = "";		
+		AddrVO addrInfo = null;
+		
+		try {
+			
+			addrInfo = addrService.selectAddrDetail(addrVO);
+
+		} catch (Exception e) {
+			isSuccess = false;
+			msg = e.getMessage();
+		}
+		
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		modelAndView.addObject("addrInfo", addrInfo);
+		
+		return modelAndView;
+		
+	}
+	
+	
+	/**
+	 * 주소록 그룹 삭제 로직 ajax
+	 * 
+	 * @param request
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/deleteAddrAjax.do")
+	public ModelAndView deleteAddrAjax(@RequestParam(value="addrCheck", defaultValue="0") String[] addrCheck, HttpServletRequest request, 
+			AddrVO addrVO, Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrVO.setLastUpdusrId(user.getId());
+		addrVO.setMberId(user.getId());
+		
+		//단일삭제
+		if(!"".equals(addrVO.getAddrId())) {
+			addrCheck[0] = addrVO.getAddrId();
+		}
+		
+		for(String id:addrCheck) {
+			try {
+				addrVO.setAddrId(id);
+				addrService.deleteAddr(addrVO);
+				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		
+		return modelAndView;
+		
+	}
+
+	
+	
+	/**
+	 * 주소록 등록 로직 (ajax)
+	 * @param addrVO
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/insertAddrAjax.do")
+	public ModelAndView insertAddrAjax(HttpServletRequest request, ModelMap model, 
+			AddrVO addrVO
+			) throws Exception {
+		ModelAndView mv = new ModelAndView();
+		mv.setViewName("jsonView");
+		
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+		addrVO.setMberId(userId);
+
+		if("bookmark".equals(addrVO.getAddrGrpId())) {
+			addrVO.setBookmark("Y");
+			addrVO.setAddrGrpId("0");
+		}
+
+		int usedCnt = addrService.selectDuplAddrCnt(addrVO);
+		if(usedCnt > 0) {
+			mv.addObject("result","dupl");
+		}else {
+			if(userId != "") {
+				try {
+					addrService.insertAddr(addrVO);
+					mv.addObject("result","success");
+				} catch (Exception e) {
+					e.printStackTrace();
+					mv.addObject("result","fail");
+				}
+				
+			} else {
+				mv.addObject("result","fail");
+			}
+		}
+		return mv;
+	}
+	
+	
+	/**
+	 * 주소록 다중수정 ajax
+	 * @param addrCheck
+	 * @param request
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/updateAddrListAjax.do")
+	public ModelAndView updateAddrListAjax(HttpServletRequest request, 
+			AddrVO addrVO, Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrVO.setLastUpdusrId(user.getId());
+		addrVO.setMberId(user.getId());
+		
+		int listSize = addrVO.getAddrIds().length;
+
+		for(int i=0; i<listSize; i++) {
+			try {
+				// JSP 2023.04.07 => 주소록그룹 수정 추가
+				if (addrVO.getAddrGrpIds()[i].equals("bookmark")) {
+					// 자주보내는 번호
+					addrVO.setAddrGrpId("0");
+					addrVO.setBookmark("Y");					
+				}
+				else {
+					addrVO.setAddrGrpId(addrVO.getAddrGrpIds()[i]);
+					addrVO.setBookmark("N");
+				}
+				
+				addrVO.setAddrId(addrVO.getAddrIds()[i]);
+			
+				if(addrVO.getAddrPhones().length > 0) { 
+					addrVO.setAddrPhoneNo(addrVO.getAddrPhones()[i]);
+				}
+				else {
+					addrVO.setAddrPhoneNo(null);
+				}				
+				
+				if(addrVO.getAddrNms().length > 0) { 
+					addrVO.setAddrNm(addrVO.getAddrNms()[i]);
+				}
+				else {
+					addrVO.setAddrNm(null);
+				}
+				
+				if(!addrVO.getAddrInfo1s()[i].equals(null) || !"".equals(addrVO.getAddrInfo1s()[i])) {
+					addrVO.setAddrInfo1(addrVO.getAddrInfo1s()[i]);
+				}else {
+					addrVO.setAddrInfo1("");
+				}
+				
+				if(!addrVO.getAddrInfo2s()[i].equals(null) || !"".equals(addrVO.getAddrInfo2s()[i])) {
+					addrVO.setAddrInfo2(addrVO.getAddrInfo2s()[i]);
+				}else {
+					addrVO.setAddrInfo2("");
+				}
+				
+				if(!addrVO.getAddrInfo3s()[i].equals(null) || !"".equals(addrVO.getAddrInfo3s()[i])) {
+					addrVO.setAddrInfo3(addrVO.getAddrInfo3s()[i]);
+				}else {
+					addrVO.setAddrInfo3("");
+				}
+				
+				if(!addrVO.getAddrInfo4s()[i].equals(null) || !"".equals(addrVO.getAddrInfo4s()[i])) {
+					addrVO.setAddrInfo4(addrVO.getAddrInfo4s()[i]);
+				}else {
+					addrVO.setAddrInfo4("");
+				}
+				
+				addrService.updateAddr(addrVO);
+				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		return modelAndView;
+	}
+	
+	
+	/**
+	 * 주소록 다중수정 ajax
+	 * @param addrCheck
+	 * @param request
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/updateAddrAjax.do")
+	public ModelAndView updateAddrAjax(@RequestParam("addrCheck") String[] addrCheck, HttpServletRequest request, 
+			AddrVO addrVO, Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrVO.setLastUpdusrId(user.getId());
+		addrVO.setMberId(user.getId());
+		
+		for(String id:addrCheck) {
+			try {
+				
+				if("0".equals (addrVO.getAddrGrpId())) {
+					addrVO.setBookmark("Y");
+				} else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
+					addrVO.setBookmark("N");
+				}
+				
+				addrVO.setAddrId(id);
+				addrService.updateMemoAddr(addrVO);
+				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		
+		return modelAndView;
+		
+	}
+	
+
+	/**
+	 * 주소록 그룹이동 ajax
+	 * @param addrCheck
+	 * @param request
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/updateAddrMoveGrpAjax.do")
+	public ModelAndView updateAddrMoveGrpAjax(@RequestParam("addrCheck") String[] addrCheck, 
+			@RequestParam("addrPhoneNos") String[] addrPhoneNos,
+			HttpServletRequest request, 
+			AddrVO addrVO, Model model,
+			RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrVO.setLastUpdusrId(user.getId());
+		addrVO.setMberId(user.getId());
+		
+		// 그룹미지정, 자주보내는 번호 구분처리
+		if("0".equals (addrVO.getAddrGrpId())) {
+			// 그룹미지정
+			addrVO.setBookmark("N");
+		}
+		else if("bookmark".equals (addrVO.getAddrGrpId())) {
+			// 자주보내는 번호
+			addrVO.setBookmark("Y");
+			addrVO.setAddrGrpId("0");
+		} 
+		else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
+			addrVO.setBookmark("N");
+		}
+		
+		/**
+		 * 보내려는 그룹에 등록되어있는 전화번호를 변수에 담아둠
+		 */
+		List<?> addrPhoneList = addrService.selectPhoneNumInAddrGroup(addrVO);
+		
+		String phoneNos = ""; 
+		for(int i=0; i<addrPhoneList.size(); i++) {
+			if(i == 0) {
+				phoneNos = ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
+			} else {
+				phoneNos = phoneNos + "," + ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
+			}
+		}
+		
+		/**
+		 * 2. 넘어온 주소록 id를  db조회하여 리스트로 받아옴
+		 */
+		String duplYn = "N";
+		for(String phoneNo:addrPhoneNos) {
+			if(phoneNos != null && phoneNos.contains(phoneNo)) {
+				modelAndView.addObject("result","dupl");
+				duplYn = "Y";
+				break;
+			}
+		}
+		
+		if(duplYn == "N") {
+			for(String id:addrCheck) {
+				
+				try {
+					addrVO.setAddrId(id);
+					addrService.updateAddrGrp(addrVO);
+					
+					modelAndView.addObject("result", "success");
+				} catch (Exception e) {
+					e.printStackTrace();
+					modelAndView.addObject("result", "fail");
+					return modelAndView;
+				}
+			}
+		} 
+		
+		return modelAndView;
+		
+	}
+	
+	
+	/**
+	 * 주소록 복사 ajax
+	 * @param addrCheck
+	 * @param request
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/insertCopyAddrAjax.do")
+	public ModelAndView insertCopyAddrAjax(@RequestParam("addrCheck") String[] addrCheck, 
+			@RequestParam("addrPhoneNos") String[] addrPhoneNos,
+			HttpServletRequest request, 
+			AddrVO addrVO, Model model,
+			RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrVO.setMberId(user.getId());
+		
+		// 그룹미지정, 자주보내는 번호 구분처리
+		if("0".equals (addrVO.getAddrGrpId())) {
+			// 그룹미지정
+			addrVO.setBookmark("N");
+		}
+		else if("bookmark".equals (addrVO.getAddrGrpId())) {
+			// 자주보내는 번호
+			addrVO.setBookmark("Y");
+			addrVO.setAddrGrpId("0");
+		} 					
+		else if(addrVO.getAddrGrpId() != null && !"".equals(addrVO.getAddrGrpId())) {
+			addrVO.setBookmark("N");
+		}		
+		
+		/**
+		 * 복사하려는 그룹에 등록되어있는 전화번호를 변수에 담아둠
+		 */
+		List<?> addrPhoneList = addrService.selectPhoneNumInAddrGroup(addrVO);
+		
+		String phoneNos = ""; 
+		for(int i=0; i<addrPhoneList.size(); i++) {
+			if(i == 0) {
+				phoneNos = ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
+			} else {
+				phoneNos = phoneNos + "," + ((AddrVO)addrPhoneList.get(i)).getAddrPhoneNo();
+			}
+		}
+		
+		/**
+		 * 2. 넘어온 주소록 id를  db조회하여 리스트로 받아옴
+		 */
+		String duplYn = "N";
+		for(String phoneNo:addrPhoneNos) {
+			if(phoneNos != null && phoneNos.contains(phoneNo)) {
+				modelAndView.addObject("result","dupl");
+				duplYn = "Y";
+				break;
+			}
+		}
+		
+		if(duplYn == "N") {
+			for(String id:addrCheck) {
+				try {
+					addrVO.setAddrId(id);
+					addrService.insertCopyAddr(addrVO);
+					
+					modelAndView.addObject("result", "success");
+				} catch (Exception e) {
+					e.printStackTrace();
+					modelAndView.addObject("result", "fail");
+					return modelAndView;
+				}
+			}
+		}
+		return modelAndView;
+		
+	}
+
+	
+	/**
+	 * 주소록 그룹 내 휴대폰번호 중복체크
+	 *
+	 * @param addrVO
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/selectDuplAddrAjax.do")
+	public ModelAndView selectDuplAddrAjax(AddrVO addrVO) throws Exception {
+		ModelAndView mv =  new ModelAndView();
+		mv.setViewName("jsonView");
+		
+		int usedCnt = addrService.selectDuplAddrCnt(addrVO);
+		
+		mv.addObject("usedCnt", usedCnt);
+		
+		return mv;
+	}
+	
+	
+	/**
+	 * 주소록 폰주소록 가이드 이동
+	 * 
+	 * @param addrVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/mjon/addr/addrMobGuide.do")
+	public String addrMobGuide(ModelMap model) throws Exception {
+		
+		return "/web/addr/AddrMobGuide";
+	}
+	
+	
+
+	/**
+	 * 선택한 주소록을 문자전송 화면으로 보내기
+	 * @param addrVO
+	 * @param req
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping(value= {"/web/mjon/addr/selectAddrDataListAjax.do"})
+	public ModelAndView selectAddrDataListAjax(
+			AddrVO addrVO, 
+			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 {
+    		
+    		addrVO.setMberId(userId);
+    		
+    	}
+		
+    	
+		List<String> addrIdList = addrVO.getAddrIdList();
+		List<String> tempList = new ArrayList<String>();
+		
+		for(String seqStr : addrIdList) {
+			
+			String seqId = seqStr.replace("[", "");
+			seqId = seqId.replace("]", "");
+			
+			tempList.add(seqId);
+		}
+		
+		addrVO.setAddrIdList(tempList);
+		
+		List<AddrVO> resultList = addrService.selectAddrDataList(addrVO);
+		
+		
+		if(resultList == null) {
+			modelAndView.addObject("status", "emptyList");
+			modelAndView.addObject("message", "가져온 주소록 목록이 없습니다.");
+			
+		}else {
+			
+			modelAndView.addObject("status", "success");
+			modelAndView.addObject("resultList", resultList);
+			modelAndView.addObject("resultListCnt", resultList.size());
+			
+		}
+		
+		return modelAndView;
+	}
+	
+	
+	
+
+	//주소록 엑셀 다운로드 
+	@RequestMapping("/web/mjon/addr/addrExcelDownload.do")
+	public void addrExcelDownload(@RequestParam("cellCheck") String[] cellCheck,
+		AddrVO addrVO, 
+		HttpServletRequest request,
+		HttpServletResponse response ,
+		ModelMap model) throws Exception {
+		
+		addrVO.setRecordCountPerPage(100000);
+		addrVO.setFirstIndex(0);
+		
+		if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrVO.setSearchSortCnd("addrId");
+			addrVO.setSearchSortOrd("asc");
+		}
+		
+		LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();
+	
+		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
+		SXSSFWorkbook wb = new SXSSFWorkbook(100);
+		CellStyle styleHeader = wb.createCellStyle();
+		styleHeader.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
+		styleHeader.setBorderLeft(CellStyle.BORDER_THIN);
+		styleHeader.setBorderRight(CellStyle.BORDER_THIN);
+		styleHeader.setBorderTop(CellStyle.BORDER_THIN);
+		
+		CellStyle styleList = wb.createCellStyle();
+		
+		Font font = wb.createFont();
+		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
+		
+		Cell cell = null;
+		Row row = null;
+		
+		String fileName ="주소록";
+		
+		String sheetTitle = ""; 
+		try{
+			if("".equals(addrVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+				addrVO.setSearchSortOrd("desc");
+			}
+			addrVO.setMberId(loginVO.getId());
+			List<AddrVO> addrList = addrService.selectAddrList(addrVO);
+			{ 
+				// row, cell 개수 순서대로 증가용 필드
+				int rowNumber = 0;
+				int celNumber = 0;
+				//화면 리스트
+				sheetTitle = "주소록" ; //제목
+				Sheet sheet = wb.createSheet(sheetTitle);
+				row = sheet.createRow(rowNumber++);
+				row = sheet.createRow(rowNumber++);		//줄추가
+	
+				//cell = row.createCell(celNumber++);
+				//cell.setCellValue("번호");
+				//cell.setCellStyle(style);
+				
+				int y = 0;
+				for(String field : cellCheck) {
+					//셀 칼럼 크기 설정
+					sheet.setColumnWidth(y, 4000);
+
+					cell = row.createCell(celNumber++);
+					cell.setCellValue(addrVO.getHeaderName(field));
+					cell.setCellStyle(styleHeader);
+					
+					y++;
+				}
+	
+				for(int i=0; i < addrList.size(); i++){
+					row = sheet.createRow(rowNumber++);		//줄추가
+					celNumber = 0;
+					//cell = row.createCell(celNumber++);
+					//cell.setCellStyle(style);
+					//cell.setCellValue(i+1); //번호
+	
+					for(String field : cellCheck) {
+						cell = row.createCell(celNumber++);
+						cell.setCellStyle(styleList);
+						cell.setCellValue(((AddrVO)addrList.get(i)).getFieldValue(field));
+					}
+				}
+			}
+			
+			response.setHeader("Set-Cookie", "fileDownload=true; path=/");
+			SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", 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 body
+	 * @param uploadFile
+	 * @param search
+	 * @param result
+	 * @param model
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping(value = "/web/mjon/addr/sendExelFilePhoneNumAjax.do")
+	@ResponseBody
+	public Object sendExelFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
+		
+		JsonResult jr = new JsonResult();
+		jr.setSuccess(false);
+		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
+		
+		//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;
+			//System.out.println("fileNameSplitCnt : " + fileNameSplitCnt);
+			
+			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[2345678]{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;
+	            int errMemoCnt = 0;
+	            
+		        
+	            //엑셀 확장자에 따른 처리 로직 분리
+				if(Ext.equals("xls")) {
+					
+					HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
+				    HSSFSheet sheet = workbook.getSheetAt(0);
+				    
+				    if(sheet.getLastRowNum() > 20000) { //
+		            	errMessage = "2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
+		            	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 < 7; j++){ //행읽기(6행까지나 2행까지만 필요)
+		                	cellValue = "";
+		                	cell = row.getCell(j); //이름/핸드폰/info1/info2/info3/info4/메모
+		                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면  
+		                		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) {
+		                		// 문자열에서 숫자만 추출
+		                		cellValue = getOnlyNumber(cellValue);
+
+		                		//전화번호
+		                		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("info1", cellValue);
+		                		}else {
+		                			errRep1Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 3) {
+		                		//치환2
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info2", cellValue);
+		                		}else {
+		                			errRep2Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 4) {
+		                		//치환3
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info3", cellValue);
+		                		}else {
+		                			errRep3Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 5) {
+		                		//치환4
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info4", cellValue);
+		                		}else {
+		                			errRep4Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}		                	
+		                	if(j == 6) {
+		                		//메모
+		                		boolean repChk = getNameRepLenChk("memo", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("memo", cellValue);
+		                		}else {
+		                			errMemoCnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                }
+		                if(null != jm.get("phone")) {
+		                	json.add(jm);
+		                }
+		                
+		            }
+		            
+		            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt + errMemoCnt;
+		            
+		            jr.setData(json);
+					jr.setSuccess(true);
+					
+					if(resultErrCnt > 0) {
+						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ resultErrCnt +" 건 있습니다.");
+					}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 > 20001) {
+		            	System.out.println("totRowDataCnt : " + totRowDataCnt);
+		            	errMessage = "2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
+		            	jr.setSuccess(false);
+		            	jr.setMessage(errMessage);
+		            	return jr;
+		            }
+		            
+		            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+		            PhoneVO pVO = new PhoneVO();
+		            System.out.println("sheet.getLastRowNum() : " + sheet.getLastRowNum());
+		            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 < 7; j++){ //행읽기(6행까지나 2행까지만 필요)
+		                	cellValue = "";
+		                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5/메모
+		                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면
+		                		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) {
+		                		// 문자열에서 숫자만 추출
+		                		cellValue = getOnlyNumber(cellValue);
+		                		
+		                		//전화번호
+		                		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("info1", cellValue);
+		                		}else {
+		                			errRep1Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 3) {
+		                		//치환2
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info2", cellValue);
+		                		}else {
+		                			errRep2Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 4) {
+		                		//치환3
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info3", cellValue);
+		                		}else {
+		                			errRep3Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	if(j == 5) {
+		                		//치환4
+		                		boolean repChk = getNameRepLenChk("rep", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("info4", cellValue);
+		                		}else {
+		                			errRep4Cnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}		                			                	
+		                	if(j == 6) {
+		                		//메모
+		                		boolean repChk = getNameRepLenChk("memo", cellValue);
+		                		
+		                		if(repChk && errSts) {
+		                			jm.put("memo", cellValue);
+		                		}else {
+		                			errMemoCnt++;
+		                			errSts = false;
+		                			break;
+		                		}
+		                	}
+		                	
+		                }
+		                if(null != jm.get("phone") && errSts) {
+		                	json.add(jm);
+		                }
+		                
+		            }
+		            
+		            int resultErrCnt = errPhoneCnt + errNameCnt + errRep1Cnt + errRep2Cnt + errRep3Cnt + errRep4Cnt;
+		            
+		            jr.setData(json);
+					jr.setSuccess(true);
+					
+					if(resultErrCnt > 0) {
+						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ resultErrCnt +" 건 있습니다.");
+					}else {
+						jr.setMessage("");
+					}
+				}	//xlsx 처리 끝
+				
+			}
+			else {
+				
+				String ttt = files.get(0).getSize() + "_" + 
+				files.get(0).getContentType()  + "_" + 
+ 				files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1];
+					
+				jr.setSuccess(false);
+				jr.setMessage("엑셀파일 인식오류.");
+				//jr.setMessage("엑셀파일 인식오류" + ttt);			
+			}			
+		}
+		else {
+			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/addr/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;
+				}
+				
+				BufferedReader reader = new BufferedReader(new InputStreamReader(multiRequest.getFile("file0").getInputStream()));
+				
+				String line = null;
+				String[] splitedStr = null;
+				String[] tempStr = null;
+				int errPhoneCnt = 0;
+				int totRowNum = 0;
+				
+				//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
+				String phoneRegExp = "^(050[2345678]{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("\\,");
+					if(tempStr.length > 1) {
+						splitedStr = line.split("\\,");
+					}else {
+						splitedStr = line.split("\t");;
+					}
+
+					for (int i = 0; i < splitedStr.length; i++) {
+						splitedStr[i] = splitedStr[i].trim();
+						if(i == 0) {
+							//이름
+							jm.put("name", splitedStr[i]);							
+						}
+						if(i == 1) {
+	                		// 문자열에서 숫자만 추출
+							splitedStr[i] = getOnlyNumber(splitedStr[i]);
+	                		
+							if(splitedStr[i].matches(phoneRegExp)) {
+								//휴대폰 번호
+								jm.put("phone", splitedStr[i]);
+							}else {
+		    	            	errPhoneCnt++;
+	                		}
+						}
+	                	if(i == 2) {
+	                		//info1
+	                		jm.put("info1", splitedStr[i]);
+	                	}
+	                	if(i == 3) {
+	                		//info2
+	                		jm.put("info2", splitedStr[i]);
+	                	}
+	                	if(i == 4) {
+	                		//info3
+	                		jm.put("info3", splitedStr[i]);
+	                	}
+	                	if(i == 5) {
+	                		//info4
+	                		jm.put("info4", splitedStr[i]);
+	                	}		                			                							
+	                	if(i == 6) {
+	                		//메모
+	                		jm.put("memo", splitedStr[i]);
+	                	}
+					}
+					
+					if(jm.get("phone") != null) {
+						json.add(jm);
+					}
+
+					totRowNum++;
+				} // end while
+				jr.setData(json);
+				jr.setSuccess(true);
+				
+	            if (totRowNum > 20000) {
+	            	jr.setMessage("20000");
+	            }
+	            else {
+					if(errPhoneCnt > 0) {
+						jr.setMessage("올바르지 않은 휴대폰 번호가 "+ errPhoneCnt +" 건 있습니다.");
+					}else {
+						jr.setMessage("");
+					}
+	            }
+			}
+			
+		}
+		
+		return jr;
+	}
+
+	
+    /**
+     * 주소록 대량등록 저장
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/addrMassInsertByTempAjax.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/addrMassInsertByTempAjax.do"})
+	public ModelAndView addrMassInsertByTempAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+
+		//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
+		String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
+        
+		String charset = "euc-kr";
+		boolean isSuccess = true;
+		String msg = "";
+		int resultCnt = 0;
+		int dupliCnt = 0; 	// 중복 데이터 수
+        int errPhoneCnt = 0;		
+        List<AddrVO> addrMassDupliList = new ArrayList<AddrVO>();	// 중복 휴대폰번호
+		
+		try {
+			
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+	    	String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+	    	
+        	if(userId.equals("")) {
+        		isSuccess = false;
+    			modelAndView.addObject("isSuccess", isSuccess);        		
+        		modelAndView.addObject("msg", "로그인 후 이용이 가능합니다.");
+    			return modelAndView;
+        	}
+        	else {
+        		addrVO.setMberId(userId);
+        	}
+        	
+    		//회원별 주소록 전체 갯수 조회
+        	int addrBefAfterCnt = 0;
+    		int addrBefCnt = addrService.selectAddrTotalCount(addrVO);    		
+    		int addrNewCnt = addrVO.getPhoneList().length;	//신규 추가할 주소록 갯수
+    		int sumAddrCnt = addrBefCnt + addrNewCnt;			//기존 + 신규 주소록 합산
+    		
+    		// 신규 주소록 여부 체크
+    		if (addrVO.getAddrGrpId().equals("NEW")) {
+    			
+    			AddrGroupVO addrGroupVO = new AddrGroupVO();
+    			addrGroupVO.setMberId(userId);
+    			addrGroupVO.setAddrGrpNm(addrVO.getAddrGrpNm());
+    			// 정렬순서
+    			int nextOrderNumber = addrGroupService.selectMaxOrderNumber(addrGroupVO);
+    			addrGroupVO.setGrpOrder(nextOrderNumber);
+    			
+    			addrGroupService.insertAddrGroup(addrGroupVO);
+    			
+    			// 신규 추가한 그룹아이디
+    			addrVO.setAddrGrpId(addrGroupVO.getAddrGrpId());
+    		}	    		
+    		
+			// 그룹미지정, 자주보내는 번호 구분처리
+			if("bookmark".equals (addrVO.getAddrGrpId())) {
+				// 자주보내는 번호
+				addrVO.setBookmark("Y");
+				addrVO.setAddrGrpId("0");
+			} 
+			else {
+				addrVO.setBookmark("N");
+			}     		
+    		
+			// 2024.01.24 10만건  -> 50만건으로 증설 요청으로 인한 증설
+    		List<AddrVO> addrDataInfo = new ArrayList<AddrVO>();
+    		if(addrBefCnt < 500000) { // 기존 등록된 주소록이 10만건 미만이면
+    			
+    			//받는사람 리스트 건수 체크해주기
+    			if(sumAddrCnt > 500000) {
+        			isSuccess = false;
+        			msg = "주소록은 총 50만개까지만 등록이 가능합니다.";
+    			}
+    			else {
+    				for(int i=0; i < addrNewCnt; i++) {
+    					AddrVO tempAddrVO = new AddrVO();
+
+    					if(addrVO.getNameList().length > 0) { 
+	    					if(addrVO.getNameList()[i].equals("-")) {
+	    						tempAddrVO.setAddrNm(null);
+	    					}else {
+	    						String tmpNm = addrVO.getNameList()[i].trim().replaceAll("§", ",");
+	    						int nmLen = tmpNm.getBytes(charset).length;
+	    						
+	    						if(nmLen >= 20) {
+	    							//isSuccess = false;
+	    							//msg = "이름 항목의 내용(\" " + tmpNm + " \")이 길이를 초과하여 입력되었습니다. 12글자 이하로 입력해 주세요.";
+	    							//break;
+	    							
+	    							tempAddrVO.setAddrNm(subStringBytes(addrVO.getNameList()[i].replaceAll("§", ","), 20, 2));
+	    						}else {
+	    							tempAddrVO.setAddrNm(addrVO.getNameList()[i].trim().replaceAll("§", ","));
+	    						}
+	    						
+	    					}
+    					}
+    					else {
+    						tempAddrVO.setAddrNm(null);
+    					}
+    					
+    					if(addrVO.getPhoneList().length > 0) { 
+	    					if(addrVO.getPhoneList()[i].equals("-")) {
+	    						tempAddrVO.setAddrPhoneNo(null);
+	    					}else {
+	    						tempAddrVO.setAddrPhoneNo(addrVO.getPhoneList()[i].trim().replaceAll("§", ","));
+	    					}
+    					}
+    					else {
+    						tempAddrVO.setAddrPhoneNo(null);
+    					}
+    					
+    					if(addrVO.getInfo1List().length > 0) { 
+	    					if(addrVO.getInfo1List()[i].equals("-")) {
+	    						tempAddrVO.setAddrInfo1(null);
+	    					}else {
+	    						
+	    						String tmpInfo1 = addrVO.getInfo1List()[i].replaceAll("§", ",");
+	    						int info1Len = tmpInfo1.getBytes(charset).length;
+	    						
+	    						if(info1Len >= 40) {
+	    							//isSuccess = false;
+	    							//msg = "[*1*] 항목의 내용(\" " + tmpInfo1 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
+	    							//break;
+	    							tempAddrVO.setAddrInfo1(subStringBytes(addrVO.getInfo1List()[i].replaceAll("§", ","), 40, 2));
+	    						}else {
+	    							tempAddrVO.setAddrInfo1(addrVO.getInfo1List()[i].replaceAll("§", ","));
+	    						}
+	    					}
+    					}
+    					else {
+    						tempAddrVO.setAddrInfo1(null);
+    					}
+    					
+    					if(addrVO.getInfo2List().length > 0) { 
+        					if(addrVO.getInfo2List()[i].equals("-")) {
+        						tempAddrVO.setAddrInfo2(null);
+        					}else {
+        						String tmpInfo2 = addrVO.getInfo2List()[i].replaceAll("§", ",");
+        						int info2Len = tmpInfo2.getBytes(charset).length;
+        						
+        						if(info2Len >= 40) {
+        							//isSuccess = false;
+        							//msg = "[*2*] 항목의 내용(\" " + tmpInfo2 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
+        							//break;
+        							
+        							tempAddrVO.setAddrInfo2(subStringBytes(addrVO.getInfo2List()[i].replaceAll("§", ","), 40, 2));
+        						}else {
+        							tempAddrVO.setAddrInfo2(addrVO.getInfo2List()[i].replaceAll("§", ","));
+        						}
+        						
+        					}
+    					}
+    					else {
+    						tempAddrVO.setAddrInfo2(null);
+    					}    					
+
+    					if(addrVO.getInfo3List().length > 0) { 
+        					if(addrVO.getInfo3List()[i].equals("-")) {
+        						tempAddrVO.setAddrInfo3(null);
+        					}else {
+        						String tmpInfo3 = addrVO.getInfo3List()[i].replaceAll("§", ",");
+        						int info3Len = tmpInfo3.getBytes(charset).length;
+        						
+        						if(info3Len >= 40) {
+        							//isSuccess = false;
+        							//msg = "[*3*] 항목의 내용(\" " + tmpInfo3 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
+        							//break;
+	    							
+        							tempAddrVO.setAddrInfo3(subStringBytes(addrVO.getInfo3List()[i].replaceAll("§", ","), 40, 2));
+        						}else {
+        							tempAddrVO.setAddrInfo3(addrVO.getInfo3List()[i].replaceAll("§", ","));
+        						}
+        					}
+    					}
+    					else {
+    						tempAddrVO.setAddrInfo3(null);
+    					}    					    					
+    					
+    					if(addrVO.getInfo4List().length > 0) { 
+        					if(addrVO.getInfo4List()[i].equals("-")) {
+        						tempAddrVO.setAddrInfo4(null);
+        					}else {
+        						String tmpInfo4 = addrVO.getInfo4List()[i].replaceAll("§", ",");
+        						int info4Len = tmpInfo4.getBytes(charset).length;
+        						
+        						if(info4Len >= 40) {
+        							//isSuccess = false;
+        							//msg = "[*4*] 항목의 내용(\" " + tmpInfo4 + " \")이 길이를 초과하여 입력되었습니다. 20글자 이하로 입력해 주세요.";
+        							//break;
+        							
+        							tempAddrVO.setAddrInfo4(subStringBytes(addrVO.getInfo4List()[i].replaceAll("§", ","), 40, 2));
+        						}else {
+        							tempAddrVO.setAddrInfo4(addrVO.getInfo4List()[i].replaceAll("§", ","));
+        						}
+        					}
+    					}
+    					else {
+    						tempAddrVO.setAddrInfo4(null);
+    					}    					    					
+
+    					if(addrVO.getMemoList().length > 0) { 
+        					if(addrVO.getMemoList()[i].equals("-")) {
+        						tempAddrVO.setAddrComment(null);
+        					}else {
+        						String tmpComment = addrVO.getMemoList()[i].replaceAll("§", ",");
+        						int commLen = tmpComment.getBytes(charset).length;
+        						
+        						if(commLen >= 200) {
+        							//isSuccess = false;
+        							//msg = "메모 항목의 내용(\" " + tmpComment + " \")이 길이를 초과하여 입력되었습니다. 100글자 이하로 입력해 주세요.";
+        							//break;
+        							
+        							tempAddrVO.setAddrComment(subStringBytes(addrVO.getMemoList()[i].replaceAll("§", ","), 200, 2));
+        						}else {
+        							tempAddrVO.setAddrComment(addrVO.getMemoList()[i].replaceAll("§", ","));
+        						}
+        					}
+    					}
+    					else {
+    						tempAddrVO.setAddrComment(null);
+    					}
+    					
+    					tempAddrVO.setMberId(userId);
+    					tempAddrVO.setFrstRegisterId(userId);
+    					tempAddrVO.setAddrGrpId(addrVO.getAddrGrpId());		// 그룹 지정
+
+    					// 그룹미지정, 자주보내는 번호 구분처리
+    					if("Y".equals (addrVO.getBookmark())) {
+    						// 자주보내는 번호
+    						tempAddrVO.setBookmark("Y");
+    						tempAddrVO.setAddrGrpId("0");
+    					} 
+    					else {
+    						tempAddrVO.setBookmark("N");
+    					} 
+    					
+    					AddrVO addrVO2 = new AddrVO();
+    					addrVO2.setMberId(userId);
+    					addrVO2.setAddrGrpId(addrVO.getAddrGrpId());		// 그룹 지정
+    					addrVO2.setAddrPhoneNo(addrVO.getPhoneList()[i]);	// 연락처
+    					
+    					// 휴대폰 유효성 검사
+    					boolean isPhoneNoErr = true;
+						if(addrVO.getPhoneList()[i].matches(phoneRegExp)) {
+							isPhoneNoErr = false;	// 유효성 통과
+						}else {
+	    	            	errPhoneCnt++;
+                		}
+						
+    					//int usedCnt = addrService.selectDuplAddrCnt(addrVO2);
+    					if(isPhoneNoErr == false) {
+	    					//주소록 리스트에 데이터 추가해 주기
+	    					addrDataInfo.add(tempAddrVO);
+    					}
+    				}
+    				
+    				System.out.println("======================================================");
+    				System.out.println("+++++++++++++++++++++++++ isSuccess ::: "+isSuccess);
+    				System.out.println("======================================================");
+    				
+    				//주소록에 데이터 추가해 주기
+    				if (isSuccess == true && addrDataInfo.size() > 0) {
+    					// 주소록 대량등록 By Temp 주소록 All
+    					resultCnt = addrService.insertAddrByTempAddrAll(addrDataInfo, addrVO);
+    					
+    					addrBefAfterCnt = addrService.selectAddrTotalCount(addrVO);
+    		    		
+    					addrMassDupliList = addrService.selectTempAddrDupliList(addrVO);
+    					
+    		    		resultCnt = addrBefAfterCnt - addrBefCnt; 
+    		    		dupliCnt = addrNewCnt - resultCnt;
+    				}
+    			}
+    		}
+    		else {
+    			isSuccess = false;
+    			msg = "주소록은 총 50만개까지만 등록이 가능합니다.";
+    		}
+    	}
+		catch(Exception e) {
+			
+			isSuccess = false;
+    		msg = "주소록 저장에 오류가 발생하였습니다. 시스템 관리자에게 문의 바랍니다.";
+    		System.out.println("==============================================");
+    		System.out.println("+++++++++++++++++++ addrMassInsertByTempAjax Error ::: "+e.getMessage());
+    		System.out.println("==============================================");
+    		
+    	}
+			
+		modelAndView.addObject("isSuccess", isSuccess);        		
+		modelAndView.addObject("msg", msg);
+		modelAndView.addObject("resultCnt", resultCnt);
+		modelAndView.addObject("dupliCnt", dupliCnt);
+		modelAndView.addObject("errPhoneCnt", errPhoneCnt);
+		modelAndView.addObject("addrMassDupliList", addrMassDupliList);
+
+		return modelAndView;
+	} 
+	
+	/* 바이트 자르기
+	UTF-8일 경우
+	subStringBytes("블라블라블라라", 10, 3);
+	EUC-KR일 경우
+	subStringBytes("블라블라블라라", 10, 2);
+	*/
+	public String subStringBytes(String str, int byteLength, int sizePerLetter) {
+		  int retLength = 0;
+		  int tempSize = 0;
+		  int asc;
+		  if (str == null || "".equals(str) || "null".equals(str)) {
+		    str = "";
+		  }
+		 
+		  int length = str.length();
+		 
+		  for (int i = 1; i <= length; i++) {
+		    asc = (int) str.charAt(i - 1);
+		    if (asc > 127) {
+		      if (byteLength >= tempSize + sizePerLetter) {
+		        tempSize += sizePerLetter;
+		        retLength++;
+		      }
+		    } else {
+		      if (byteLength > tempSize) {
+		        tempSize++;
+		        retLength++;
+		      }
+		    }
+		  }
+		 
+	  return str.substring(0, retLength);
+	}
+
+
+	
+    /**
+     * 주소록 그룹 목록
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/addrGroupListAjax.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/addrGroupListAjax.do"})
+	public ModelAndView addrGroupListAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, 
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		List<AddrGroupVO> addrGroupList = null;
+		
+		try {
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+			if(userId != "") {
+				addrGroupVO.setMberId(userId);
+
+		    	if(addrGroupVO.getPageUnit() != 10) {
+		    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
+				}
+				
+				if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+					addrGroupVO.setSearchSortCnd("grpOrder");
+					addrGroupVO.setSearchSortOrd("desc");
+				}
+
+				addrGroupVO.setSiteId("web");
+				addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
+			}			
+    	}
+		catch(Exception e) {
+			isSuccess = false;
+    		msg = e.getMessage();
+    	}
+			
+		modelAndView.addObject("isSuccess", isSuccess);        		
+		modelAndView.addObject("msg", msg);
+		model.addAttribute("addrGroupList", addrGroupList);
+
+		return modelAndView;
+	} 	
+	
+    /**
+     * 주소록 그룹별 중복 연락처 목록
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/addrDupliListAjax.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/addrDupliListAjax.do"})
+	public ModelAndView addrDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		List<AddrVO> addrDupliList = null;
+		
+		try {
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+			if(userId != "") {
+				addrVO.setMberId(userId);
+				
+				// 주소록 그룹별 중복 연락처 목록
+				addrDupliList = addrService.selectAddrDupliList(addrVO);
+			}
+    	}
+		catch(Exception e) {
+			isSuccess = false;
+    		msg = e.getMessage();
+    	}
+			
+		modelAndView.addObject("isSuccess", isSuccess);        		
+		modelAndView.addObject("msg", msg);
+		model.addAttribute("addrDupliList", addrDupliList);
+
+		return modelAndView;
+	} 	
+	
+    /**
+     * 주소록 그룹별 중복 연락처 삭제
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/deleteAddrDupliList.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/deleteAddrDupliListAjax.do"})
+	public ModelAndView deleteAddrDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		try {
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+			if(userId != "") {
+				addrVO.setMberId(userId);
+
+				// 주소록 그룹별 중복 연락처 삭제
+				addrService.deleteAddrDupliList(addrVO);
+			}
+			else {
+				isSuccess = false;
+	    		msg = "로그인후 이용하세요.";				
+			}
+    	}
+		catch(Exception e) {
+			isSuccess = false;
+    		msg = e.getMessage();
+    	}
+			
+		modelAndView.addObject("isSuccess", isSuccess);        		
+		modelAndView.addObject("msg", msg);
+
+		return modelAndView;
+	} 		
+	
+	
+    /**
+     * 주소록 그룹별 중복 연락처 삭제
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/deleteAddrByAllDupliListAjax.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/deleteAddrByAllDupliListAjax.do"})
+	public ModelAndView deleteAddrByAllDupliListAjax(@ModelAttribute("searchVO") AddrVO addrVO, 
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		try {
+			LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+			String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+			if(userId != "") {
+				addrVO.setMberId(userId);
+
+				// 주소록 그룹별 중복 연락처 삭제
+				addrService.deleteAddrDupliListByAll(addrVO);
+			}
+			else {
+				isSuccess = false;
+	    		msg = "로그인후 이용하세요.";				
+			}
+    	}
+		catch(Exception e) {
+			isSuccess = false;
+    		msg = e.getMessage();
+    	}
+			
+		modelAndView.addObject("isSuccess", isSuccess);        		
+		modelAndView.addObject("msg", msg);
+
+		return modelAndView;
+	} 	
+	
+	
+
+	public boolean getNameRepLenChk(String type, String value) {
+		
+		boolean rtnValue = true;
+		
+		// JSPark 2023.02.17 : 글자길이체크 주석처리 => 저장시 절삭하기 때문 
+		/*
+		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;
+				
+			}
+			
+		}else if(type.equals("memo")) {
+			
+			String tmpRep = value;
+			int repLen = tmpRep.length();
+			
+			if(repLen > 120) {
+				
+				rtnValue = false;
+				
+			}
+			
+		}
+		*/
+		
+		return rtnValue;
+	}
+	
+	// 문자열에서 숫자만 추출
+	public String getOnlyNumber(String str) {
+		//String str = "aaa1234, ^&*2233pp";
+		
+		String intStr = str.replaceAll("[^\\d]", "");
+		
+		return intStr;
+	}
 }
(No newline at end of file)
src/main/java/itn/let/mjo/addr/web/AddrGroupController.java
--- src/main/java/itn/let/mjo/addr/web/AddrGroupController.java
+++ src/main/java/itn/let/mjo/addr/web/AddrGroupController.java
@@ -1,1229 +1,1252 @@
-package itn.let.mjo.addr.web;
-
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.ui.ModelMap;
-import org.springframework.web.bind.annotation.ModelAttribute;
-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.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.support.RedirectAttributes;
-
-import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
-import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
-import itn.com.cmm.EgovMessageSource;
-import itn.com.cmm.LoginVO;
-import itn.com.cmm.util.RedirectUrlMaker;
-import itn.com.utl.fcc.service.EgovStringUtil;
-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.msgsent.service.MjonMsgSentService;
-import itn.let.mjo.msgsent.service.MjonMsgSentVO;
-import itn.let.mjo.pay.service.KmcVO;
-import itn.let.uat.uia.service.AuthCertVO;
-import itn.let.uat.uia.web.KmcCertChecker;
-import itn.let.uss.umt.service.EgovMberManageService;
-import itn.let.uss.umt.service.MberManageVO;
-
-/**
- * 주소록 그룹에 관한 controller 클래스를 정의한다.
- * @author ITN
- * @since 2021.05.21
- * @version 1.0
- * @see
- *
- * <pre>
- * << 개정이력(Modification Information) >>
- *
- *   수정일      수정자           수정내용
- *  -------    --------    ---------------------------
- *   2021.04.08  ITN          최초 생성
- *
- * </pre>
- */
-@Controller
-public class AddrGroupController {
-	@Resource(name = "MjonMsgSentService")
-    private MjonMsgSentService mjonMsgSentService;
-	
-	@Resource (name = "AddrGroupService")
-	private AddrGroupService addrGroupService;
-	
-	@Resource (name = "AddrService")
-	private AddrService addrService;
-	
-	/** EgovMessageSource */
-	@Resource(name="egovMessageSource")
-	EgovMessageSource egovMessageSource;
-	
-	/** mberManageService */
-	@Resource(name = "mberManageService")
-	private EgovMberManageService mberManageService;
-	
-	/**
-	 * 주소록 그룹 리스트
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/selectAddrGroupList.do")
-	public String selectAddrGroupList(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			,ModelMap model) throws Exception {
-		
-		if(addrGroupVO.getPageUnit() != 10) {
-			addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
-		}
-		
-		/** pageing */
-		PaginationInfo paginationInfo = new PaginationInfo();
-		paginationInfo.setCurrentPageNo(addrGroupVO.getPageIndex());
-		paginationInfo.setRecordCountPerPage(addrGroupVO.getPageUnit());
-		paginationInfo.setPageSize(addrGroupVO.getPageSize());
-		
-		addrGroupVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
-		addrGroupVO.setLastIndex(paginationInfo.getLastRecordIndex());
-		addrGroupVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
-		
-		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrGroupVO.setSearchSortCnd("addrGrpId");
-			addrGroupVO.setSearchSortOrd("desc");
-		}
-		
-		addrGroupVO.setSiteId("admin");
-		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
-		
-		int totCnt = 0;
-		if(addrGroupList.size() > 0) {
-			totCnt = addrGroupList.get(0).getTotcnt();
-		}
-		
-		paginationInfo.setTotalRecordCount(totCnt);
-		model.addAttribute("addrGroupList", addrGroupList);
-	 	model.addAttribute("paginationInfo", paginationInfo);
-		
-		
-		return "/uss/ion/addr/AddrGroupList";
-		
-	}
-	
-	
-	/**
-	 * 주소록 그룹 리스트
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/selectAddrGroupListAjax.do")
-	public ModelAndView selectAddrGroupListAdminAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, AddrVO addrVO
-			,ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrGroupVO.setSearchSortCnd("grpOrder");
-			addrGroupVO.setSearchSortOrd("desc");
-		}
-		
-		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
-		
-		modelAndView.addObject("addrGroupList", addrGroupList);
-		modelAndView.addObject("addrGroupListCnt", addrGroupList.size());
-		return modelAndView;
-		
-	}
-	
-
-	
-	/**
-	 * 주소록 그룹 리스트
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/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(userId != "") {
-			addrGroupVO.setMberId(userId);
-			addrVO.setMberId(userId);
-		} else {
-			redirectAttributes.addFlashAttribute("fail", true);
-			return "redirect:/web/user/login/login.do";
-		}
-		
-
-    	if(addrGroupVO.getPageUnit() != 10) {
-    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
-		}
-		
-		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
-			addrGroupVO.setSearchSortCnd("grpOrder");
-			addrGroupVO.setSearchSortOrd("desc");
-		}
-
-		addrGroupVO.setSiteId("web");
-		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
-
-		/*
-		 * JSPark 2023.08.30 => Ajax 로 변경		
-		//회원별 주소록 전체 갯수 조회
-		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("addrBookmarkList", addrBookmarkList);
-		model.addAttribute("addrNoGrpList", addrNoGrpList);
-		*/
-		
-		model.addAttribute("addrGroupList", addrGroupList);		
-		model.addAttribute("userId", userId);
-		
-		return "/web/addr/AddrGroupListAjax";
-		
-	}
-	
-	
-	/**
-	 * 주소록 합치기 팝업 리스트
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/selectAddrGroupMergetAjax.do")
-	public ModelAndView selectAddrGroupMergetAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, AddrVO addrVO
-			, 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 != "") {
-			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);
-		
-		model.addAttribute("addrGroupList", addrGroupList);
-		modelAndView.addObject("status", "success");
-		
-		return modelAndView;
-		
-	}
-	
-	
-	
-	/**
-	 * 주소록 그룹 등록 페이지 이동
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/registAddrGroup.do")
-	public String registAddrGroup(AddrGroupVO addrGroupVO, ModelMap model) throws Exception {
-		
-		model.addAttribute("addrGroupVO", addrGroupVO);
-		return "/uss/ion/addr/AddrGroupRegist";
-	}
-	
-	
-
-	/**
-	 * 주소록 그룹 등록 로직
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/insertAddrGroup.do")
-	public String insertAddrGroup(AddrGroupVO addrGroupVO
-			,RedirectAttributes redirectAttributes
-			,HttpServletRequest request) throws Exception {
-		
-		try {
-			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-
-			if( addrGroupVO.getMberId() == null || "".equals(addrGroupVO.getMberId()) ) {
-				addrGroupVO.setMberId(user.getId());
-			}
-			
-			//주소록 그룹 이름 불러오기(중복체크 용)
-			MjonMsgSentVO mjonMsgSentVO = new MjonMsgSentVO();
-			mjonMsgSentVO.setUserId(addrGroupVO.getMberId());
-			mjonMsgSentVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm());
-			List<AddrGroupVO> resultAddrGrpList = mjonMsgSentService.selectAddrGrpNmList(mjonMsgSentVO);
-			if(resultAddrGrpList.size() > 0) { //기존 같은 이름의 그룹이 있으면 해당 그룹에 연락처를 추가해줌
-				redirectAttributes.addFlashAttribute("message", "같은 이름의 그룹명이 있습니다.");
-			}
-			else {
-				addrGroupService.insertAddrGroup(addrGroupVO);
-				redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.insert"));
-			}
-		}catch (Exception e) {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.insert"));
-		}
-		
-		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/uss/ion/addr/selectAddrGroupList.do");
-		return redirectUrlMaker.getRedirectUrl();
-	}
-	
-	
-	/**
-	 * 주소록 그룹 등록 로직 (ajax)
-	 * @param addrGroupVO
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/insertAddrGroupAjax.do")
-	public ModelAndView insertAddrGroup(HttpServletRequest request, ModelMap model, 
-			AddrGroupVO addrGroupVO
-			) throws Exception {
-		ModelAndView mv = new ModelAndView();
-		mv.setViewName("jsonView");
-		
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-		addrGroupVO.setMberId(userId);
-		
-		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
-		if(usedCnt > 0) {
-			mv.addObject("result","dupl");
-		}else {
-			if(userId != "") {
-				try {
-					addrGroupService.insertAddrGroup(addrGroupVO);
-					mv.addObject("result","success");
-				} catch (Exception e) {
-					e.printStackTrace();
-					mv.addObject("result","fail");
-				}
-			} else {
-				mv.addObject("result","fail");
-			}
-		}
-		return mv;
-	}
-	
-	/**
-	 * 주소록 그룹 중복체크 로직 (ajax)
-	 * @param addrGroupVO
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/getAddrGroupDuplCheckAjax.do")
-	public ModelAndView getAddrGroupDuplCheckAjax(HttpServletRequest request, ModelMap model, 
-			AddrGroupVO addrGroupVO
-			) throws Exception {
-		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
-		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
-		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
-		System.out.println(" :: addrGrpNm :: "+ addrGroupVO.getAddrGrpNm());
-		
-		ModelAndView mv = new ModelAndView();
-		mv.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		boolean isDupl = false;
-		String msg = "";
-		
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-
-		try {		
-			addrGroupVO.setMberId(userId);
-			
-			int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
-			if(usedCnt > 0) {
-				isDupl = true;
-			}
-		}
-		catch(Exception e) {
-			isSuccess = false;
-			msg = e.getMessage();
-		}	
-		
-		mv.addObject("isSuccess", isSuccess);
-		mv.addObject("isDupl", isDupl);
-		mv.addObject("msg", msg);
-		
-		return mv;
-	}	
-	
-	
-	/**
-	 * 주소록 등록 페이지(ajax)
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/selectAddrGroupAjax.do")
-	public String selectAddrGroupAjax(HttpServletRequest request, ModelMap model, 
-			AddrGroupVO addrGroupVO, AddrVO addrVO, RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		//로그인 권한정보 불러오기
-		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
-		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
-		
-		if(userId != "") {
-			addrGroupVO.setMberId(userId);
-			addrVO.setMberId(userId);
-		} else {
-			redirectAttributes.addFlashAttribute("fail", true);
-			return "redirect:/web/user/login/login.do";
-		}
-		
-    	if(addrGroupVO.getPageUnit() != 10) {
-    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
-		}
-		
-		addrGroupVO.setSiteId("web");
-		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
-		
-		model.addAttribute("addrGroupList", addrGroupList);
-		
-		
-		return "/web/addr/AddrGroupSelectAjax";
-	}
-
-	// 주소록 그룹 카운트 조회(전체) Ajax
-	@RequestMapping("/web/addr/selectAddrGroupTotCntAjax.do")
-	public ModelAndView selectAddrGroupTotCntAjax(HttpServletRequest request, 
-			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			, Model model) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		int addrTotCnt = 0;
-		
-        try{		
-			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-			addrGroupVO.setMberId(user.getId());
-			
-			addrGroupVO = addrGroupService.selectAddrGroupTotCnt(addrGroupVO);
-			if (addrGroupVO != null) {
-				addrTotCnt = addrGroupVO.getAddrTotCnt();
-			}
-		}
-		catch(Exception e) {
-			isSuccess = false;
-			msg = e.getMessage();
-		}	
-        
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		modelAndView.addObject("addrTotCnt", addrTotCnt);
-		
-		return modelAndView;
-	}	
-	
-	// 주소록 그룹 카운트 조회(전체) Ajax
-	@RequestMapping("/web/addr/selectAddrGroupNogrpCntAjax.do")
-	public ModelAndView selectAddrGroupNogrpCntAjax(HttpServletRequest request, 
-			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			, Model model) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		int nogrpCnt = 0;
-		
-        try{		
-			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-			addrGroupVO.setMberId(user.getId());
-			
-			addrGroupVO = addrGroupService.selectAddrGroupNogrpCnt(addrGroupVO);
-			if (addrGroupVO != null) {
-				nogrpCnt = addrGroupVO.getNogrpCnt();
-			}
-		}
-		catch(Exception e) {
-			isSuccess = false;
-			msg = e.getMessage();
-		}	
-        
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		modelAndView.addObject("nogrpCnt", nogrpCnt);
-		
-		return modelAndView;
-	}	
-	
-	// 주소록 그룹 카운트 조회(전체) Ajax
-	@RequestMapping("/web/addr/selectAddrGroupBookmarkCntAjax.do")
-	public ModelAndView selectAddrGroupBookmarkCntAjax(HttpServletRequest request, 
-			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			, Model model) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		int bookmarkCnt = 0;
-		
-        try{		
-			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-			addrGroupVO.setMberId(user.getId());
-			
-			addrGroupVO = addrGroupService.selectAddrGroupBookmarkCnt(addrGroupVO);
-			if (addrGroupVO != null) {
-				bookmarkCnt = addrGroupVO.getBookmarkCnt();
-			}
-		}
-		catch(Exception e) {
-			isSuccess = false;
-			msg = e.getMessage();
-		}	
-        
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		modelAndView.addObject("bookmarkCnt", bookmarkCnt);
-		
-		return modelAndView;
-	}	
-	
-	/**
-	 * 주소록 그룹 수정 로직
-	 * 
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param request
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/updateAddrGroupAjax.do")
-	public ModelAndView updateAddrGroupAjax(AddrGroupVO addrGroupVO
-			,RedirectAttributes redirectAttributes
-			,HttpServletRequest request
-			,HttpServletResponse response
-			) throws Exception{
-		
-		ModelAndView modelAndView =  new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		boolean isSuccess = true;
-		String msg = "";
-		
-		try {		
-			//주소록 그룹 이름 불러오기(중복체크 용)
-			MjonMsgSentVO mjonMsgSentVO = new MjonMsgSentVO();
-			mjonMsgSentVO.setUserId(addrGroupVO.getMberId());
-			mjonMsgSentVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm());
-			List<AddrGroupVO> resultAddrGrpList = mjonMsgSentService.selectAddrGrpNmList(mjonMsgSentVO);
-			if(resultAddrGrpList.size() > 0) { //기존 같은 이름의 그룹이 있으면 해당 그룹에 연락처를 추가해줌
-				isSuccess = false;
-				msg = "같은 이름의 그룹명이 있습니다.";
-			}
-			else {
-				addrGroupService.updateAddrGroup(addrGroupVO);
-			}
-		}
-		catch(Exception e) {
-			isSuccess = false;
-			msg = "에러메시지 : " + e.getMessage();			
-			e.printStackTrace();
-		}		
-		
-		modelAndView.addObject("isSuccess", isSuccess);
-		modelAndView.addObject("msg", msg);
-		
-		return modelAndView;
-		
-	}
-
-	
-	/**
-	 * 주소록 그룹 수정 로직 Ajax
-	 * 
-	 * @param request
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/updateAddrGroupAjax.do")
-	public ModelAndView updateAddrGroupAjax(@RequestParam("addrGrpNms") String[] addrGrpNms, 
-			@RequestParam("addrGrpIds") String[] addrGrpIds,
-			HttpServletRequest request, 
-			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrGroupVO.setLastUpdusrId(user.getId());
-		addrGroupVO.setMberId(user.getId());
-
-		boolean dupl = false;
-		for (int i=0; i<addrGrpNms.length; i++) { 
-			String str1 = addrGrpNms[i]; 
-			for (int j=0; j<addrGrpNms.length; j++) { 
-				if (i == j) continue; 
-				String str2 = addrGrpNms[j]; 
-				if (str1.equals(str2)) { 
-					dupl = true;
-					break;
-				}
-			}
-		}
-		
-		if(dupl) {
-			modelAndView.addObject("result", "dupl");
-		} else {
-			for(int i=0; i<addrGrpIds.length; i++) {
-				try {
-					addrGroupVO.setAddrGrpNm(addrGrpNms[i]);
-					addrGroupVO.setAddrGrpId(addrGrpIds[i]);
-					addrGroupVO.setGrpOrder(i+1);
-					addrGroupService.updateAddrGroup(addrGroupVO);
-					
-					
-				} catch (Exception e) {
-					e.printStackTrace();
-					modelAndView.addObject("result", "fail");
-					return modelAndView;
-				}
-			}
-		}
-		return modelAndView;
-		
-	}
- 
-
-	
-	/**
-	 * 주소록 그룹 수정 페이지 이동
-	 * 
-	 * @param addrGroupVO
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/editAddrGroup.do")
-	public String editAddrGroup(AddrGroupVO addrGroupVO
-			, ModelMap model ) throws Exception {
-		
-		model.addAttribute("searchVO", addrGroupVO);
-		model.addAttribute("addrGrpInfo", addrGroupService.selectAddrGroupDetail(addrGroupVO));
-		
-		return "/uss/ion/addr/AddrGroupEdit";
-	}
-	
-
-	/**
-	 * 주소록 그룹 삭제 로직
-	 * 
-	 * @param request
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/uss/ion/addr/deleteAddrGroup.do")
-	public String deleteAddrGroup(HttpServletRequest request, @ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			,RedirectAttributes redirectAttributes
-			,ModelMap model) throws Exception {
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		
-		addrGroupVO.setLastUpdusrId(user.getUniqId());
-		
-		// 1. 그룹 삭제
-		// 2. 그룹에 소속된 주소록 삭제
-		int result = addrGroupService.deleteAddrGroupByAdminAll(addrGroupVO); 
-		
-		if (result > 0) {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
-		} else {
-			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.delete"));
-		}
-		redirectAttributes.addAttribute("pageIndex", addrGroupVO.getPageIndex());
-		redirectAttributes.addAttribute("searchCondition", addrGroupVO.getSearchCondition());
-		redirectAttributes.addAttribute("searchKeyword", addrGroupVO.getSearchKeyword());
-		
-		return "redirect:/uss/ion/addr/selectAddrGroupList.do";
-	}
- 
-
-	/**
-	 * 주소록 그룹 삭제 로직 Ajax
-	 * 
-	 * @param request
-	 * @param addrGroupVO
-	 * @param redirectAttributes
-	 * @param model
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping("/web/addr/deleteAddrGroupAjax.do")
-	public ModelAndView deleteAddrGroupAjax(@RequestParam("grpCheck") String[] grpCheck, HttpServletRequest request, 
-			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrGroupVO.setLastUpdusrId(user.getId());
-		addrGroupVO.setMberId(user.getId());
-		
-		for(String id:grpCheck) {
-			try {
-				
-//				id = "13026";
-				addrGroupVO.setAddrGrpId(id);
-				addrGroupVO.setMberId(user.getId());
-				int tot = addrService.getAddrCount(addrGroupVO);
-				addrGroupVO.setTotCnt(tot);
-				
-				addrService.deleteAddr_advc(addrGroupVO);
-				
-				
-/*				addrGroupVO.setAddrGrpId(id);
-				addrGroupService.deleteAddrGroup(addrGroupVO); 
-				
-				addrVO.setAddrGrpId(id);
-				addrVO.setGrpDelete("Y");
-				addrVO.setMberId(user.getId());
-				addrVO.setLastUpdusrId(user.getId());
-				addrService.deleteAddr(addrVO);
-*/				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		
-		return modelAndView;
-		
-	}
- 
-	/**
-	 * 주소록 그룹명 중복체크
-	 *
-	 * @param addrGroupVO
-	 * @return
-	 * @throws Exception
-	 */
-	@RequestMapping(value= {"/uss/ion/addr/duplAddrGroupAjax.do","/web/addr/selectDuplAddrGroupNameAjax.do"})
-	@ResponseBody
-	public ModelAndView selectDuplAddrGroupAjax(AddrGroupVO addrGroupVO
-			,HttpServletRequest request
-			,ModelMap model
-		) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
-		
-		if(usedCnt > 0) {
-			modelAndView.addObject("result1", "dupl");
-		} else {
-			modelAndView.addObject("result1", "success");
-		}
-		modelAndView.addObject("status1", "success");
-		
-		return modelAndView;
-	}
-	
-	/**
-	 * 주소록 합치기
-	 * @param addrGrpNewNm
-	 * @param request
-	 * @param addrGroupVO
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	
-	@RequestMapping("/web/addr/mergeAddrGroupAjax.do")
-	public ModelAndView mergeAddrGroupAjax(@RequestParam("addrGrpNewNm") String addrGrpNewNm
-			,HttpServletRequest request 
-			,@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			,AddrVO addrVO
-			,Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrGroupVO.setLastUpdusrId(user.getId());
-		addrGroupVO.setMberId(user.getId());
-		addrGroupVO.setFrstRegisterId(user.getId());
-		addrGroupVO.setAddrGrpNm(addrGrpNewNm);
-		
-		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
-		
-		if(usedCnt > 0) {
-			modelAndView.addObject("result", "dupl");
-		}else {
-			addrVO.setMberId(user.getId());
-			addrVO.setLastUpdusrId(user.getId());
-			
-			try {
-				addrGroupService.mergeAddrGroupAjax(addrGroupVO, addrVO);
-				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		
-		
-		return modelAndView;
-		
-	}
-	
-	
-	
-	
-	/**
-	 * 주소록 그룹 복사하기
-	 * @param addrGrpNewNm
-	 * @param request
-	 * @param addrGroupVO
-	 * @param addrVO
-	 * @param model
-	 * @param redirectAttributes
-	 * @return
-	 * @throws Exception
-	 */
-	
-	@RequestMapping("/web/addr/copyAddrGroupAjax.do")
-	public ModelAndView copyAddrGroupAjax(@RequestParam("addrGrpNewNm") String addrGrpNewNm
-			,HttpServletRequest request 
-			,@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
-			,AddrVO addrVO
-			,Model model
-			,RedirectAttributes redirectAttributes
-			) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView();
-		modelAndView.setViewName("jsonView");
-		
-		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
-		addrGroupVO.setLastUpdusrId(user.getId());
-		addrGroupVO.setMberId(user.getId());
-		addrGroupVO.setFrstRegisterId(user.getId());
-		addrGroupVO.setAddrGrpNm(addrGrpNewNm);
-		
-		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
-		
-		if(usedCnt > 0) {
-			modelAndView.addObject("result", "dupl");
-		}else {
-			addrVO.setMberId(user.getId());
-			addrVO.setLastUpdusrId(user.getId());
-			
-			try {
-				addrGroupService.copyAddrGroupAjax(addrGroupVO, addrVO);
-				
-				modelAndView.addObject("result", "success");
-			} catch (Exception e) {
-				e.printStackTrace();
-				modelAndView.addObject("result", "fail");
-				return modelAndView;
-			}
-		}
-		
-		
-		return modelAndView;
-		
-	}
-	
-	
-	// 주소록 내보내기 kmc본인인증
-		@RequestMapping(value = "/web/addr/kmcPopupAddrSubmitPramAjax.do")
-		public ModelAndView kmcPopupIdPwPramAjax(@ModelAttribute("mberManageVO") MberManageVO mberManageVO,
-				HttpServletRequest request) throws Exception {
-
-			ModelAndView modelAndView = new ModelAndView();
-			modelAndView.setViewName("jsonView");
-
-			try {
-				KmcCertChecker kmcCertCheck = new KmcCertChecker();
-
-				// mberId null일경우 ""로
-				mberManageVO.setMberId(EgovStringUtil.isNullToString(mberManageVO.getMberId()));
-
-				// kmc 본인인증 실/개발 서버 구분
-				String serverNm = "";
-				if (request.getServerName().contains("219.240.88.15") || request.getServerName().contains("localhost")) {
-					serverNm = request.getScheme() + "://219.240.88.15:8095";
-				} else {
-					serverNm = request.getScheme() + "://www.munjaon.co.kr";
-				}
-
-				AuthCertVO certVO = kmcCertCheck.authCertCheckEight(serverNm + "/web/cop/kmc/authRequestAddrSubmitAjax.do",
-						mberManageVO.getMberId());
-
-				modelAndView.addObject("tr_cert", certVO.getTr_cert());
-				modelAndView.addObject("tr_url", certVO.getTr_url());
-				modelAndView.addObject("tr_add", certVO.getTr_add());
-
-				modelAndView.addObject("result", "success");
-
-			} catch (Exception e) {
-				modelAndView.addObject("result", "fail");
-				modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
-			}
-
-			return modelAndView;
-		}
-
-		/**
-		 * 아이디 비밀번호 찾기 kmc 본인인증(PG사 전송화면)
-		 *
-		 * @param
-		 * @return
-		 * @throws Exception
-		 */
-
-		@RequestMapping("/web/cop/kmc/authRequestAddrSubmitAjax.do")
-		public String authRequestFindIdPwAjax(HttpServletRequest request, ModelMap model,
-				@RequestParam Map<String, Object> commandMap, @ModelAttribute("searchVO") KmcVO kmcVO,
-				RedirectAttributes redirectAttributes) throws Exception {
-
-			String errMessage = ""; // 에러메세지
-
-			String rec_cert = ""; // 결과값(암호화)
-			String certNum = ""; // certNum
-
-			rec_cert = request.getParameter("rec_cert").trim();
-			certNum = request.getParameter("certNum").trim();
-
-			kmcVO.setRecCert(rec_cert);
-			kmcVO.setCertNum(certNum);
-			// 파라미터 유효성 검증
-			if (rec_cert.length() == 0 || certNum.length() == 0) {
-				errMessage = "비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			// 변수선언
-			// --------------------------------------------------------------------------------------------------------
-			String k_certNum = ""; // 파라미터로 수신한 요청번호
-			k_certNum = certNum;
-			String date = ""; // 요청일시
-			String CI = ""; // 연계정보(CI)
-			String DI = ""; // 중복가입확인정보(DI)
-			String phoneNo = ""; // 휴대폰번호
-			String phoneCorp = ""; // 이동통신사
-			String birthDay = ""; // 생년월일
-			String gender = ""; // 성별
-			String nation = ""; // 내국인
-			String name = ""; // 성명
-			String M_name = ""; // 미성년자 성명
-			String M_birthDay = ""; // 미성년자 생년월일
-			String M_Gender = ""; // 미성년자 성별
-			String M_nation = ""; // 미성년자 내외국인
-			String result = ""; // 결과값
-
-			String certMet = ""; // 인증방법
-			String ip = ""; // ip주소
-			String plusInfo = "";
-
-			String encPara = "";
-			String encMsg1 = "";
-			String encMsg2 = "";
-			String msgChk = "";
-
-			com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager();
-
-			// 02. 1차 복호화
-			// 수신된 certNum를 이용하여 복호화
-			rec_cert = seed.getDec(rec_cert, k_certNum);
-
-			// 03. 1차 파싱
-			int inf1 = rec_cert.indexOf("/", 0);
-			int inf2 = rec_cert.indexOf("/", inf1 + 1);
-
-			encPara = rec_cert.substring(0, inf1); // 암호화된 통합 파라미터
-			encMsg1 = rec_cert.substring(inf1 + 1, inf2); // 암호화된 통합 파라미터의 Hash값
-
-			// 04. 위변조 검증
-			encMsg2 = seed.getMsg(encPara);
-			kmcVO.setEncMsg2(encMsg2);
-			if (encMsg2.equals(encMsg1)) {
-				msgChk = "Y";
-			}
-
-			if (!"Y".equals(msgChk)) {
-				errMessage = "비정상접근입니다.";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			// 05. 2차 복호화
-			rec_cert = seed.getDec(encPara, k_certNum);
-			kmcVO.setRecCert(rec_cert);
-			// 06. 2차 파싱
-			int info1 = rec_cert.indexOf("/", 0);
-			int info2 = rec_cert.indexOf("/", info1 + 1);
-			int info3 = rec_cert.indexOf("/", info2 + 1);
-			int info4 = rec_cert.indexOf("/", info3 + 1);
-			int info5 = rec_cert.indexOf("/", info4 + 1);
-			int info6 = rec_cert.indexOf("/", info5 + 1);
-			int info7 = rec_cert.indexOf("/", info6 + 1);
-			int info8 = rec_cert.indexOf("/", info7 + 1);
-			int info9 = rec_cert.indexOf("/", info8 + 1);
-			int info10 = rec_cert.indexOf("/", info9 + 1);
-			int info11 = rec_cert.indexOf("/", info10 + 1);
-			int info12 = rec_cert.indexOf("/", info11 + 1);
-			int info13 = rec_cert.indexOf("/", info12 + 1);
-			int info14 = rec_cert.indexOf("/", info13 + 1);
-			int info15 = rec_cert.indexOf("/", info14 + 1);
-			int info16 = rec_cert.indexOf("/", info15 + 1);
-			int info17 = rec_cert.indexOf("/", info16 + 1);
-			int info18 = rec_cert.indexOf("/", info17 + 1);
-
-			certNum = rec_cert.substring(0, info1);
-			kmcVO.setCertNum(certNum);
-			date = rec_cert.substring(info1 + 1, info2);
-			kmcVO.setDate(date);
-			CI = rec_cert.substring(info2 + 1, info3);
-			kmcVO.setCI(CI);
-			phoneNo = rec_cert.substring(info3 + 1, info4);
-			kmcVO.setPhoneNo(phoneNo);
-			phoneCorp = rec_cert.substring(info4 + 1, info5);
-			kmcVO.setPhoneCorp(phoneCorp);
-			birthDay = rec_cert.substring(info5 + 1, info6);
-			kmcVO.setBirthDay(birthDay);
-			gender = rec_cert.substring(info6 + 1, info7);
-			kmcVO.setGender(gender);
-			nation = rec_cert.substring(info7 + 1, info8);
-			kmcVO.setNation(nation);
-			name = rec_cert.substring(info8 + 1, info9);
-			kmcVO.setName(name);
-			result = rec_cert.substring(info9 + 1, info10);
-			kmcVO.setResult(result);
-			certMet = rec_cert.substring(info10 + 1, info11);
-			kmcVO.setCertMet(certMet);
-			ip = rec_cert.substring(info11 + 1, info12);
-			kmcVO.setIp(ip);
-			M_name = rec_cert.substring(info12 + 1, info13);
-			kmcVO.setMName(M_name);
-			M_birthDay = rec_cert.substring(info13 + 1, info14);
-			kmcVO.setMBirthDay(M_birthDay);
-			M_Gender = rec_cert.substring(info14 + 1, info15);
-			kmcVO.setMGender(M_Gender);
-			M_nation = rec_cert.substring(info15 + 1, info16);
-			kmcVO.setMNation(M_nation);
-			plusInfo = rec_cert.substring(info16 + 1, info17);
-			kmcVO.setPlusInfo(plusInfo);
-			DI = rec_cert.substring(info17 + 1, info18);
-			kmcVO.setDI(DI);
-
-			// 07. CI, DI 복호화
-			CI = seed.getDec(CI, k_certNum);
-			kmcVO.setCI(CI);
-			DI = seed.getDec(DI, k_certNum);
-			kmcVO.setDI(DI);
-
-			if ("Y".equals(result)) {
-
-			}
-
-			// --------------------------------------------------------------
-			String regex = "";
-			if (certNum.length() == 0 || certNum.length() > 40) {
-				errMessage = "요청번호 비정상.";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[0-9]*";
-			if (date.length() != 14 || !paramChk(regex, date)) {
-				errMessage = "요청일시";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[A-Z]*";
-			if (certMet.length() != 1 || !paramChk(regex, certMet)) {
-				errMessage = "본인인증방법 비정상" + certMet;
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[0-9]*";
-			if ((phoneNo.length() != 10 && phoneNo.length() != 11) || !paramChk(regex, phoneNo)) {
-				errMessage = "휴대폰번호 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[A-Z]*";
-			if (phoneCorp.length() != 3 || !paramChk(regex, phoneCorp)) {
-				errMessage = "이동통신사 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[0-9]*";
-			if (birthDay.length() != 8 || !paramChk(regex, birthDay)) {
-				errMessage = "생년월일 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[0-9]*";
-			if (gender.length() != 1 || !paramChk(regex, gender)) {
-				errMessage = "성별 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[0-9]*";
-			if (nation.length() != 1 || !paramChk(regex, nation)) {
-				errMessage = "내/외국인 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[\\sA-Za-z가-�R.,-]*";
-			if (name.length() > 60 || !paramChk(regex, name)) {
-				errMessage = "성명 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[A-Z]*";
-			if (result.length() != 1 || !paramChk(regex, result)) {
-				errMessage = "결과값 비정상";
-				return returnPage(model, errMessage, kmcVO);
-			}
-
-			regex = "[\\sA-Za-z가-?.,-]*";
-			if (M_name.length() != 0) {
-				if (M_name.length() > 60 || !paramChk(regex, M_name)) {
-					errMessage = "미성년자 성명 비정상";
-					return returnPage(model, errMessage, kmcVO);
-				}
-			}
-
-			regex = "[0-9]*";
-			if (M_birthDay.length() != 0) {
-				if (M_birthDay.length() != 8 || !paramChk(regex, M_birthDay)) {
-					errMessage = "미성년자 생년월일  비정상";
-					return returnPage(model, errMessage, kmcVO);
-				}
-			}
-
-			regex = "[0-9]*";
-			if (M_Gender.length() != 0) {
-				if (M_Gender.length() != 1 || !paramChk(regex, M_Gender)) {
-					errMessage = "미성년자 성별 비정상";
-					return returnPage(model, errMessage, kmcVO);
-				}
-			}
-
-			regex = "[0-9]*";
-			if (M_nation.length() != 0) {
-				if (M_nation.length() != 1 || !paramChk(regex, M_nation)) {
-					errMessage = "미성년자 내/외국인 비정상";
-					return returnPage(model, errMessage, kmcVO);
-				}
-			}
-
-			// KMC 본인인증 로그
-			AuthCertVO certVO = new AuthCertVO();
-
-			certVO.setMberId(kmcVO.getPlusInfo());
-			certVO.setCertNum(kmcVO.getCertNum());
-			certVO.setCertDate(kmcVO.getDate());
-			certVO.setCertDi(kmcVO.getDI());
-			certVO.setCertPhone(kmcVO.getPhoneNo());
-			certVO.setCertNation(kmcVO.getNation());
-			certVO.setCertName(kmcVO.getName());
-			certVO.setCertResult(kmcVO.getResult());
-			certVO.setCertType("KMC_주소록내보내기");
-			certVO.setCertIpaddr(kmcVO.getIp());
-			certVO.setBirthDay(kmcVO.getBirthDay());
-			certVO.setSexdstnCode(kmcVO.getGender());
-
-			// 디비 테이블에 저장하기
-			mberManageService.insertCertInfoLog(certVO);
-
-			model.addAttribute("kmcVO", kmcVO);
-			return "web/addr/AddrSubmitKmcReqPage";
-		}
-		
-		
-		
-		
-		// 파라미터 유효성 검증 --------------------------------------------
-		public Boolean paramChk(String patn, String param) {
-			Pattern pattern = Pattern.compile(patn);
-			Matcher matcher = pattern.matcher(param);
-			boolean b = matcher.matches();
-			return b;
-		}
-
-		// 파라미터 유효성 검증 --------------------------------------------
-		public String returnPage(ModelMap model, String errMessage, KmcVO kmcVO) {
-			kmcVO.setErrMessage(errMessage);
-			model.addAttribute("kmcVO", kmcVO);
-			return "web/cop/nicepay/payRequestAjax";
-		}
-	
-
-}
+package itn.let.mjo.addr.web;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+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.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
+import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
+import itn.com.cmm.EgovMessageSource;
+import itn.com.cmm.LoginVO;
+import itn.com.cmm.util.RedirectUrlMaker;
+import itn.com.utl.fcc.service.EgovStringUtil;
+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.msgsent.service.MjonMsgSentService;
+import itn.let.mjo.msgsent.service.MjonMsgSentVO;
+import itn.let.mjo.pay.service.KmcVO;
+import itn.let.uat.uia.service.AuthCertVO;
+import itn.let.uat.uia.web.KmcCertChecker;
+import itn.let.uss.umt.service.EgovMberManageService;
+import itn.let.uss.umt.service.MberManageVO;
+
+/**
+ * 주소록 그룹에 관한 controller 클래스를 정의한다.
+ * @author ITN
+ * @since 2021.05.21
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *
+ *   수정일      수정자           수정내용
+ *  -------    --------    ---------------------------
+ *   2021.04.08  ITN          최초 생성
+ *
+ * </pre>
+ */
+@Controller
+public class AddrGroupController {
+	@Resource(name = "MjonMsgSentService")
+    private MjonMsgSentService mjonMsgSentService;
+	
+	@Resource (name = "AddrGroupService")
+	private AddrGroupService addrGroupService;
+	
+	@Resource (name = "AddrService")
+	private AddrService addrService;
+	
+	/** EgovMessageSource */
+	@Resource(name="egovMessageSource")
+	EgovMessageSource egovMessageSource;
+	
+	/** mberManageService */
+	@Resource(name = "mberManageService")
+	private EgovMberManageService mberManageService;
+	
+	/**
+	 * 주소록 그룹 리스트
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/selectAddrGroupList.do")
+	public String selectAddrGroupList(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			,ModelMap model) throws Exception {
+		
+		if(addrGroupVO.getPageUnit() != 10) {
+			addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
+		}
+		
+		/** pageing */
+		PaginationInfo paginationInfo = new PaginationInfo();
+		paginationInfo.setCurrentPageNo(addrGroupVO.getPageIndex());
+		paginationInfo.setRecordCountPerPage(addrGroupVO.getPageUnit());
+		paginationInfo.setPageSize(addrGroupVO.getPageSize());
+		
+		addrGroupVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
+		addrGroupVO.setLastIndex(paginationInfo.getLastRecordIndex());
+		addrGroupVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
+		
+		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrGroupVO.setSearchSortCnd("addrGrpId");
+			addrGroupVO.setSearchSortOrd("desc");
+		}
+		
+		addrGroupVO.setSiteId("admin");
+		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
+		
+		int totCnt = 0;
+		if(addrGroupList.size() > 0) {
+			totCnt = addrGroupList.get(0).getTotcnt();
+		}
+		
+		paginationInfo.setTotalRecordCount(totCnt);
+		model.addAttribute("addrGroupList", addrGroupList);
+	 	model.addAttribute("paginationInfo", paginationInfo);
+		
+		
+		return "/uss/ion/addr/AddrGroupList";
+		
+	}
+	
+	
+	/**
+	 * 주소록 그룹 리스트
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/selectAddrGroupListAjax.do")
+	public ModelAndView selectAddrGroupListAdminAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, AddrVO addrVO
+			,ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrGroupVO.setSearchSortCnd("grpOrder");
+			addrGroupVO.setSearchSortOrd("desc");
+		}
+		
+		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
+		
+		modelAndView.addObject("addrGroupList", addrGroupList);
+		modelAndView.addObject("addrGroupListCnt", addrGroupList.size());
+		return modelAndView;
+		
+	}
+	
+
+	
+	/**
+	 * 주소록 그룹 리스트
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/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(userId != "") {
+			addrGroupVO.setMberId(userId);
+			addrVO.setMberId(userId);
+		} else {
+			redirectAttributes.addFlashAttribute("fail", true);
+			return "redirect:/web/user/login/login.do";
+		}
+		
+
+    	if(addrGroupVO.getPageUnit() != 10) {
+    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
+		}
+		
+		if("".equals(addrGroupVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
+			addrGroupVO.setSearchSortCnd("grpOrder");
+			addrGroupVO.setSearchSortOrd("desc");
+		}
+
+		addrGroupVO.setSiteId("web");
+		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
+
+		
+//		 * JSPark 2023.08.30 => Ajax 로 변경		
+		//회원별 주소록 전체 갯수 조회
+//		int addrTotalCount = addrService.selectAddrTotalCount(addrVO);
+		addrVO.setType("bookmark");
+		List<AddrVO> addrBookmarkList = addrService.selectAddrBasicGrpList(addrVO);
+
+		addrVO.setType("noGrp");
+		List<AddrVO> addrNoGrpList = addrService.selectAddrBasicGrpList(addrVO);
+		
+		int totalGrpCount = addrGroupList.stream()
+			    .mapToInt(group -> {
+			        String grpCountStr = group.getGrpCount();
+			        if (grpCountStr != null && !grpCountStr.isEmpty()) {
+			            try {
+			                return Integer.parseInt(grpCountStr);
+			            } catch (NumberFormatException e) {
+			                // 파싱에 실패한 경우 0을 반환하거나 예외 처리를 합니다.
+			                return 0;
+			            }
+			        } else {
+			            return 0;
+			        }
+			    })
+			    .sum();
+
+			// 결과 출력
+
+		System.out.println("totalGrpCount :: "+ totalGrpCount);
+		
+		int addrTotalCount = (addrNoGrpList.size() >0 ? addrNoGrpList.get(0).getTotcnt() : 0)
+				+ (addrBookmarkList.size() >0 ? addrBookmarkList.get(0).getTotcnt() : 0)
+				+ totalGrpCount
+				;		
+
+		model.addAttribute("addrTotalCount", addrTotalCount);
+	 	model.addAttribute("addrBookmarkCnt", addrBookmarkList.size() >0 ? addrBookmarkList.get(0).getTotcnt() : 0);
+		model.addAttribute("addrNoGrpCnt", addrNoGrpList.size() >0 ? addrNoGrpList.get(0).getTotcnt() : 0);
+		
+		model.addAttribute("addrGroupList", addrGroupList);		
+		model.addAttribute("userId", userId);
+		
+		return "/web/addr/AddrGroupListAjax";
+		
+	}
+	
+	
+	/**
+	 * 주소록 합치기 팝업 리스트
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/selectAddrGroupMergetAjax.do")
+	public ModelAndView selectAddrGroupMergetAjax(@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, AddrVO addrVO
+			, 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 != "") {
+			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);
+		
+		model.addAttribute("addrGroupList", addrGroupList);
+		modelAndView.addObject("status", "success");
+		
+		return modelAndView;
+		
+	}
+	
+	
+	
+	/**
+	 * 주소록 그룹 등록 페이지 이동
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/registAddrGroup.do")
+	public String registAddrGroup(AddrGroupVO addrGroupVO, ModelMap model) throws Exception {
+		
+		model.addAttribute("addrGroupVO", addrGroupVO);
+		return "/uss/ion/addr/AddrGroupRegist";
+	}
+	
+	
+
+	/**
+	 * 주소록 그룹 등록 로직
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/insertAddrGroup.do")
+	public String insertAddrGroup(AddrGroupVO addrGroupVO
+			,RedirectAttributes redirectAttributes
+			,HttpServletRequest request) throws Exception {
+		
+		try {
+			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+
+			if( addrGroupVO.getMberId() == null || "".equals(addrGroupVO.getMberId()) ) {
+				addrGroupVO.setMberId(user.getId());
+			}
+			
+			//주소록 그룹 이름 불러오기(중복체크 용)
+			MjonMsgSentVO mjonMsgSentVO = new MjonMsgSentVO();
+			mjonMsgSentVO.setUserId(addrGroupVO.getMberId());
+			mjonMsgSentVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm());
+			List<AddrGroupVO> resultAddrGrpList = mjonMsgSentService.selectAddrGrpNmList(mjonMsgSentVO);
+			if(resultAddrGrpList.size() > 0) { //기존 같은 이름의 그룹이 있으면 해당 그룹에 연락처를 추가해줌
+				redirectAttributes.addFlashAttribute("message", "같은 이름의 그룹명이 있습니다.");
+			}
+			else {
+				addrGroupService.insertAddrGroup(addrGroupVO);
+				redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.insert"));
+			}
+		}catch (Exception e) {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.insert"));
+		}
+		
+		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/uss/ion/addr/selectAddrGroupList.do");
+		return redirectUrlMaker.getRedirectUrl();
+	}
+	
+	
+	/**
+	 * 주소록 그룹 등록 로직 (ajax)
+	 * @param addrGroupVO
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/insertAddrGroupAjax.do")
+	public ModelAndView insertAddrGroup(HttpServletRequest request, ModelMap model, 
+			AddrGroupVO addrGroupVO
+			) throws Exception {
+		ModelAndView mv = new ModelAndView();
+		mv.setViewName("jsonView");
+		
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+		addrGroupVO.setMberId(userId);
+		
+		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
+		if(usedCnt > 0) {
+			mv.addObject("result","dupl");
+		}else {
+			if(userId != "") {
+				try {
+					addrGroupService.insertAddrGroup(addrGroupVO);
+					mv.addObject("result","success");
+				} catch (Exception e) {
+					e.printStackTrace();
+					mv.addObject("result","fail");
+				}
+			} else {
+				mv.addObject("result","fail");
+			}
+		}
+		return mv;
+	}
+	
+	/**
+	 * 주소록 그룹 중복체크 로직 (ajax)
+	 * @param addrGroupVO
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/getAddrGroupDuplCheckAjax.do")
+	public ModelAndView getAddrGroupDuplCheckAjax(HttpServletRequest request, ModelMap model, 
+			AddrGroupVO addrGroupVO
+			) throws Exception {
+		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
+		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
+		System.out.println(" :: /web/addr/getAddrGroupDuplCheckAjax.do :: ");
+		System.out.println(" :: addrGrpNm :: "+ addrGroupVO.getAddrGrpNm());
+		
+		ModelAndView mv = new ModelAndView();
+		mv.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		boolean isDupl = false;
+		String msg = "";
+		
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+
+		try {		
+			addrGroupVO.setMberId(userId);
+			
+			int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
+			if(usedCnt > 0) {
+				isDupl = true;
+			}
+		}
+		catch(Exception e) {
+			isSuccess = false;
+			msg = e.getMessage();
+		}	
+		
+		mv.addObject("isSuccess", isSuccess);
+		mv.addObject("isDupl", isDupl);
+		mv.addObject("msg", msg);
+		
+		return mv;
+	}	
+	
+	
+	/**
+	 * 주소록 등록 페이지(ajax)
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/selectAddrGroupAjax.do")
+	public String selectAddrGroupAjax(HttpServletRequest request, ModelMap model, 
+			AddrGroupVO addrGroupVO, AddrVO addrVO, RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		//로그인 권한정보 불러오기
+		LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
+		String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId());
+		
+		if(userId != "") {
+			addrGroupVO.setMberId(userId);
+			addrVO.setMberId(userId);
+		} else {
+			redirectAttributes.addFlashAttribute("fail", true);
+			return "redirect:/web/user/login/login.do";
+		}
+		
+    	if(addrGroupVO.getPageUnit() != 10) {
+    		addrGroupVO.setPageUnit(addrGroupVO.getPageUnit());
+		}
+		
+		addrGroupVO.setSiteId("web");
+		List<AddrGroupVO> addrGroupList = addrGroupService.selectAddrGroupList(addrGroupVO);
+		
+		model.addAttribute("addrGroupList", addrGroupList);
+		
+		
+		return "/web/addr/AddrGroupSelectAjax";
+	}
+
+	// 주소록 그룹 카운트 조회(전체) Ajax
+	@RequestMapping("/web/addr/selectAddrGroupTotCntAjax.do")
+	public ModelAndView selectAddrGroupTotCntAjax(HttpServletRequest request, 
+			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			, Model model) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		int addrTotCnt = 0;
+		
+        try{		
+			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+			addrGroupVO.setMberId(user.getId());
+			
+			addrGroupVO = addrGroupService.selectAddrGroupTotCnt(addrGroupVO);
+			if (addrGroupVO != null) {
+				addrTotCnt = addrGroupVO.getAddrTotCnt();
+			}
+		}
+		catch(Exception e) {
+			isSuccess = false;
+			msg = e.getMessage();
+		}	
+        
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		modelAndView.addObject("addrTotCnt", addrTotCnt);
+		
+		return modelAndView;
+	}	
+	
+	// 주소록 그룹 카운트 조회(전체) Ajax
+	@RequestMapping("/web/addr/selectAddrGroupNogrpCntAjax.do")
+	public ModelAndView selectAddrGroupNogrpCntAjax(HttpServletRequest request, 
+			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			, Model model) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		int nogrpCnt = 0;
+		
+        try{		
+			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+			addrGroupVO.setMberId(user.getId());
+			
+			addrGroupVO = addrGroupService.selectAddrGroupNogrpCnt(addrGroupVO);
+			if (addrGroupVO != null) {
+				nogrpCnt = addrGroupVO.getNogrpCnt();
+			}
+		}
+		catch(Exception e) {
+			isSuccess = false;
+			msg = e.getMessage();
+		}	
+        
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		modelAndView.addObject("nogrpCnt", nogrpCnt);
+		
+		return modelAndView;
+	}	
+	
+	// 주소록 그룹 카운트 조회(전체) Ajax
+	@RequestMapping("/web/addr/selectAddrGroupBookmarkCntAjax.do")
+	public ModelAndView selectAddrGroupBookmarkCntAjax(HttpServletRequest request, 
+			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			, Model model) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		int bookmarkCnt = 0;
+		
+        try{		
+			LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+			addrGroupVO.setMberId(user.getId());
+			
+			addrGroupVO = addrGroupService.selectAddrGroupBookmarkCnt(addrGroupVO);
+			if (addrGroupVO != null) {
+				bookmarkCnt = addrGroupVO.getBookmarkCnt();
+			}
+		}
+		catch(Exception e) {
+			isSuccess = false;
+			msg = e.getMessage();
+		}	
+        
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		modelAndView.addObject("bookmarkCnt", bookmarkCnt);
+		
+		return modelAndView;
+	}	
+	
+	/**
+	 * 주소록 그룹 수정 로직
+	 * 
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/updateAddrGroupAjax.do")
+	public ModelAndView updateAddrGroupAjax(AddrGroupVO addrGroupVO
+			,RedirectAttributes redirectAttributes
+			,HttpServletRequest request
+			,HttpServletResponse response
+			) throws Exception{
+		
+		ModelAndView modelAndView =  new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		boolean isSuccess = true;
+		String msg = "";
+		
+		try {		
+			//주소록 그룹 이름 불러오기(중복체크 용)
+			MjonMsgSentVO mjonMsgSentVO = new MjonMsgSentVO();
+			mjonMsgSentVO.setUserId(addrGroupVO.getMberId());
+			mjonMsgSentVO.setAddrGrpNm(addrGroupVO.getAddrGrpNm());
+			List<AddrGroupVO> resultAddrGrpList = mjonMsgSentService.selectAddrGrpNmList(mjonMsgSentVO);
+			if(resultAddrGrpList.size() > 0) { //기존 같은 이름의 그룹이 있으면 해당 그룹에 연락처를 추가해줌
+				isSuccess = false;
+				msg = "같은 이름의 그룹명이 있습니다.";
+			}
+			else {
+				addrGroupService.updateAddrGroup(addrGroupVO);
+			}
+		}
+		catch(Exception e) {
+			isSuccess = false;
+			msg = "에러메시지 : " + e.getMessage();			
+			e.printStackTrace();
+		}		
+		
+		modelAndView.addObject("isSuccess", isSuccess);
+		modelAndView.addObject("msg", msg);
+		
+		return modelAndView;
+		
+	}
+
+	
+	/**
+	 * 주소록 그룹 수정 로직 Ajax
+	 * 
+	 * @param request
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/updateAddrGroupAjax.do")
+	public ModelAndView updateAddrGroupAjax(@RequestParam("addrGrpNms") String[] addrGrpNms, 
+			@RequestParam("addrGrpIds") String[] addrGrpIds,
+			HttpServletRequest request, 
+			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrGroupVO.setLastUpdusrId(user.getId());
+		addrGroupVO.setMberId(user.getId());
+
+		boolean dupl = false;
+		for (int i=0; i<addrGrpNms.length; i++) { 
+			String str1 = addrGrpNms[i]; 
+			for (int j=0; j<addrGrpNms.length; j++) { 
+				if (i == j) continue; 
+				String str2 = addrGrpNms[j]; 
+				if (str1.equals(str2)) { 
+					dupl = true;
+					break;
+				}
+			}
+		}
+		
+		if(dupl) {
+			modelAndView.addObject("result", "dupl");
+		} else {
+			for(int i=0; i<addrGrpIds.length; i++) {
+				try {
+					addrGroupVO.setAddrGrpNm(addrGrpNms[i]);
+					addrGroupVO.setAddrGrpId(addrGrpIds[i]);
+					addrGroupVO.setGrpOrder(i+1);
+					addrGroupService.updateAddrGroup(addrGroupVO);
+					
+					
+				} catch (Exception e) {
+					e.printStackTrace();
+					modelAndView.addObject("result", "fail");
+					return modelAndView;
+				}
+			}
+		}
+		return modelAndView;
+		
+	}
+ 
+
+	
+	/**
+	 * 주소록 그룹 수정 페이지 이동
+	 * 
+	 * @param addrGroupVO
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/editAddrGroup.do")
+	public String editAddrGroup(AddrGroupVO addrGroupVO
+			, ModelMap model ) throws Exception {
+		
+		model.addAttribute("searchVO", addrGroupVO);
+		model.addAttribute("addrGrpInfo", addrGroupService.selectAddrGroupDetail(addrGroupVO));
+		
+		return "/uss/ion/addr/AddrGroupEdit";
+	}
+	
+
+	/**
+	 * 주소록 그룹 삭제 로직
+	 * 
+	 * @param request
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/uss/ion/addr/deleteAddrGroup.do")
+	public String deleteAddrGroup(HttpServletRequest request, @ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			,RedirectAttributes redirectAttributes
+			,ModelMap model) throws Exception {
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		
+		addrGroupVO.setLastUpdusrId(user.getUniqId());
+		
+		// 1. 그룹 삭제
+		// 2. 그룹에 소속된 주소록 삭제
+		int result = addrGroupService.deleteAddrGroupByAdminAll(addrGroupVO); 
+		
+		if (result > 0) {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
+		} else {
+			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("fail.common.delete"));
+		}
+		redirectAttributes.addAttribute("pageIndex", addrGroupVO.getPageIndex());
+		redirectAttributes.addAttribute("searchCondition", addrGroupVO.getSearchCondition());
+		redirectAttributes.addAttribute("searchKeyword", addrGroupVO.getSearchKeyword());
+		
+		return "redirect:/uss/ion/addr/selectAddrGroupList.do";
+	}
+ 
+
+	/**
+	 * 주소록 그룹 삭제 로직 Ajax
+	 * 
+	 * @param request
+	 * @param addrGroupVO
+	 * @param redirectAttributes
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/web/addr/deleteAddrGroupAjax.do")
+	public ModelAndView deleteAddrGroupAjax(@RequestParam("grpCheck") String[] grpCheck, HttpServletRequest request, 
+			@ModelAttribute("searchVO") AddrGroupVO addrGroupVO, Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrGroupVO.setLastUpdusrId(user.getId());
+		addrGroupVO.setMberId(user.getId());
+		
+		for(String id:grpCheck) {
+			try {
+				
+				addrGroupVO.setAddrGrpId(id);
+				addrGroupVO.setMberId(user.getId());
+				addrGroupVO.setLastUpdusrId(user.getId());
+//				int tot = addrService.getAddrCount(addrGroupVO);
+//				addrGroupVO.setTotCnt(tot);
+				
+				addrService.deleteAddr_advc(addrGroupVO);
+				
+				
+/*				addrGroupVO.setAddrGrpId(id);
+				addrGroupService.deleteAddrGroup(addrGroupVO); 
+				
+				addrVO.setAddrGrpId(id);
+				addrVO.setGrpDelete("Y");
+				addrVO.setMberId(user.getId());
+				addrVO.setLastUpdusrId(user.getId());
+				addrService.deleteAddr(addrVO);
+*/				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		
+		return modelAndView;
+		
+	}
+ 
+	/**
+	 * 주소록 그룹명 중복체크
+	 *
+	 * @param addrGroupVO
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping(value= {"/uss/ion/addr/duplAddrGroupAjax.do","/web/addr/selectDuplAddrGroupNameAjax.do"})
+	@ResponseBody
+	public ModelAndView selectDuplAddrGroupAjax(AddrGroupVO addrGroupVO
+			,HttpServletRequest request
+			,ModelMap model
+		) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
+		
+		if(usedCnt > 0) {
+			modelAndView.addObject("result1", "dupl");
+		} else {
+			modelAndView.addObject("result1", "success");
+		}
+		modelAndView.addObject("status1", "success");
+		
+		return modelAndView;
+	}
+	
+	/**
+	 * 주소록 합치기
+	 * @param addrGrpNewNm
+	 * @param request
+	 * @param addrGroupVO
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	
+	@RequestMapping("/web/addr/mergeAddrGroupAjax.do")
+	public ModelAndView mergeAddrGroupAjax(@RequestParam("addrGrpNewNm") String addrGrpNewNm
+			,HttpServletRequest request 
+			,@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			,AddrVO addrVO
+			,Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrGroupVO.setLastUpdusrId(user.getId());
+		addrGroupVO.setMberId(user.getId());
+		addrGroupVO.setFrstRegisterId(user.getId());
+		addrGroupVO.setAddrGrpNm(addrGrpNewNm);
+		
+		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
+		
+		if(usedCnt > 0) {
+			modelAndView.addObject("result", "dupl");
+		}else {
+			addrVO.setMberId(user.getId());
+			addrVO.setLastUpdusrId(user.getId());
+			
+			try {
+				addrGroupService.mergeAddrGroupAjax(addrGroupVO, addrVO);
+				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		
+		
+		return modelAndView;
+		
+	}
+	
+	
+	
+	
+	/**
+	 * 주소록 그룹 복사하기
+	 * @param addrGrpNewNm
+	 * @param request
+	 * @param addrGroupVO
+	 * @param addrVO
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 * @throws Exception
+	 */
+	
+	@RequestMapping("/web/addr/copyAddrGroupAjax.do")
+	public ModelAndView copyAddrGroupAjax(@RequestParam("addrGrpNewNm") String addrGrpNewNm
+			,HttpServletRequest request 
+			,@ModelAttribute("searchVO") AddrGroupVO addrGroupVO
+			,AddrVO addrVO
+			,Model model
+			,RedirectAttributes redirectAttributes
+			) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView();
+		modelAndView.setViewName("jsonView");
+		
+		LoginVO user = (LoginVO) EgovUserDetailsHelper.getAuthenticatedUser();
+		addrGroupVO.setLastUpdusrId(user.getId());
+		addrGroupVO.setMberId(user.getId());
+		addrGroupVO.setFrstRegisterId(user.getId());
+		addrGroupVO.setAddrGrpNm(addrGrpNewNm);
+		
+		int usedCnt = addrGroupService.selectDuplAddrGroupCnt(addrGroupVO);
+		
+		if(usedCnt > 0) {
+			modelAndView.addObject("result", "dupl");
+		}else {
+			addrVO.setMberId(user.getId());
+			addrVO.setLastUpdusrId(user.getId());
+			
+			try {
+				addrGroupService.copyAddrGroupAjax(addrGroupVO, addrVO);
+				
+				modelAndView.addObject("result", "success");
+			} catch (Exception e) {
+				e.printStackTrace();
+				modelAndView.addObject("result", "fail");
+				return modelAndView;
+			}
+		}
+		
+		
+		return modelAndView;
+		
+	}
+	
+	
+	// 주소록 내보내기 kmc본인인증
+		@RequestMapping(value = "/web/addr/kmcPopupAddrSubmitPramAjax.do")
+		public ModelAndView kmcPopupIdPwPramAjax(@ModelAttribute("mberManageVO") MberManageVO mberManageVO,
+				HttpServletRequest request) throws Exception {
+
+			ModelAndView modelAndView = new ModelAndView();
+			modelAndView.setViewName("jsonView");
+
+			try {
+				KmcCertChecker kmcCertCheck = new KmcCertChecker();
+
+				// mberId null일경우 ""로
+				mberManageVO.setMberId(EgovStringUtil.isNullToString(mberManageVO.getMberId()));
+
+				// kmc 본인인증 실/개발 서버 구분
+				String serverNm = "";
+				if (request.getServerName().contains("219.240.88.15") || request.getServerName().contains("localhost")) {
+					serverNm = request.getScheme() + "://219.240.88.15:8095";
+				} else {
+					serverNm = request.getScheme() + "://www.munjaon.co.kr";
+				}
+
+				AuthCertVO certVO = kmcCertCheck.authCertCheckEight(serverNm + "/web/cop/kmc/authRequestAddrSubmitAjax.do",
+						mberManageVO.getMberId());
+
+				modelAndView.addObject("tr_cert", certVO.getTr_cert());
+				modelAndView.addObject("tr_url", certVO.getTr_url());
+				modelAndView.addObject("tr_add", certVO.getTr_add());
+
+				modelAndView.addObject("result", "success");
+
+			} catch (Exception e) {
+				modelAndView.addObject("result", "fail");
+				modelAndView.addObject("message", "기타 시스템 오류 : " + e.getMessage());
+			}
+
+			return modelAndView;
+		}
+
+		/**
+		 * 아이디 비밀번호 찾기 kmc 본인인증(PG사 전송화면)
+		 *
+		 * @param
+		 * @return
+		 * @throws Exception
+		 */
+
+		@RequestMapping("/web/cop/kmc/authRequestAddrSubmitAjax.do")
+		public String authRequestFindIdPwAjax(HttpServletRequest request, ModelMap model,
+				@RequestParam Map<String, Object> commandMap, @ModelAttribute("searchVO") KmcVO kmcVO,
+				RedirectAttributes redirectAttributes) throws Exception {
+
+			String errMessage = ""; // 에러메세지
+
+			String rec_cert = ""; // 결과값(암호화)
+			String certNum = ""; // certNum
+
+			rec_cert = request.getParameter("rec_cert").trim();
+			certNum = request.getParameter("certNum").trim();
+
+			kmcVO.setRecCert(rec_cert);
+			kmcVO.setCertNum(certNum);
+			// 파라미터 유효성 검증
+			if (rec_cert.length() == 0 || certNum.length() == 0) {
+				errMessage = "비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			// 변수선언
+			// --------------------------------------------------------------------------------------------------------
+			String k_certNum = ""; // 파라미터로 수신한 요청번호
+			k_certNum = certNum;
+			String date = ""; // 요청일시
+			String CI = ""; // 연계정보(CI)
+			String DI = ""; // 중복가입확인정보(DI)
+			String phoneNo = ""; // 휴대폰번호
+			String phoneCorp = ""; // 이동통신사
+			String birthDay = ""; // 생년월일
+			String gender = ""; // 성별
+			String nation = ""; // 내국인
+			String name = ""; // 성명
+			String M_name = ""; // 미성년자 성명
+			String M_birthDay = ""; // 미성년자 생년월일
+			String M_Gender = ""; // 미성년자 성별
+			String M_nation = ""; // 미성년자 내외국인
+			String result = ""; // 결과값
+
+			String certMet = ""; // 인증방법
+			String ip = ""; // ip주소
+			String plusInfo = "";
+
+			String encPara = "";
+			String encMsg1 = "";
+			String encMsg2 = "";
+			String msgChk = "";
+
+			com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager();
+
+			// 02. 1차 복호화
+			// 수신된 certNum를 이용하여 복호화
+			rec_cert = seed.getDec(rec_cert, k_certNum);
+
+			// 03. 1차 파싱
+			int inf1 = rec_cert.indexOf("/", 0);
+			int inf2 = rec_cert.indexOf("/", inf1 + 1);
+
+			encPara = rec_cert.substring(0, inf1); // 암호화된 통합 파라미터
+			encMsg1 = rec_cert.substring(inf1 + 1, inf2); // 암호화된 통합 파라미터의 Hash값
+
+			// 04. 위변조 검증
+			encMsg2 = seed.getMsg(encPara);
+			kmcVO.setEncMsg2(encMsg2);
+			if (encMsg2.equals(encMsg1)) {
+				msgChk = "Y";
+			}
+
+			if (!"Y".equals(msgChk)) {
+				errMessage = "비정상접근입니다.";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			// 05. 2차 복호화
+			rec_cert = seed.getDec(encPara, k_certNum);
+			kmcVO.setRecCert(rec_cert);
+			// 06. 2차 파싱
+			int info1 = rec_cert.indexOf("/", 0);
+			int info2 = rec_cert.indexOf("/", info1 + 1);
+			int info3 = rec_cert.indexOf("/", info2 + 1);
+			int info4 = rec_cert.indexOf("/", info3 + 1);
+			int info5 = rec_cert.indexOf("/", info4 + 1);
+			int info6 = rec_cert.indexOf("/", info5 + 1);
+			int info7 = rec_cert.indexOf("/", info6 + 1);
+			int info8 = rec_cert.indexOf("/", info7 + 1);
+			int info9 = rec_cert.indexOf("/", info8 + 1);
+			int info10 = rec_cert.indexOf("/", info9 + 1);
+			int info11 = rec_cert.indexOf("/", info10 + 1);
+			int info12 = rec_cert.indexOf("/", info11 + 1);
+			int info13 = rec_cert.indexOf("/", info12 + 1);
+			int info14 = rec_cert.indexOf("/", info13 + 1);
+			int info15 = rec_cert.indexOf("/", info14 + 1);
+			int info16 = rec_cert.indexOf("/", info15 + 1);
+			int info17 = rec_cert.indexOf("/", info16 + 1);
+			int info18 = rec_cert.indexOf("/", info17 + 1);
+
+			certNum = rec_cert.substring(0, info1);
+			kmcVO.setCertNum(certNum);
+			date = rec_cert.substring(info1 + 1, info2);
+			kmcVO.setDate(date);
+			CI = rec_cert.substring(info2 + 1, info3);
+			kmcVO.setCI(CI);
+			phoneNo = rec_cert.substring(info3 + 1, info4);
+			kmcVO.setPhoneNo(phoneNo);
+			phoneCorp = rec_cert.substring(info4 + 1, info5);
+			kmcVO.setPhoneCorp(phoneCorp);
+			birthDay = rec_cert.substring(info5 + 1, info6);
+			kmcVO.setBirthDay(birthDay);
+			gender = rec_cert.substring(info6 + 1, info7);
+			kmcVO.setGender(gender);
+			nation = rec_cert.substring(info7 + 1, info8);
+			kmcVO.setNation(nation);
+			name = rec_cert.substring(info8 + 1, info9);
+			kmcVO.setName(name);
+			result = rec_cert.substring(info9 + 1, info10);
+			kmcVO.setResult(result);
+			certMet = rec_cert.substring(info10 + 1, info11);
+			kmcVO.setCertMet(certMet);
+			ip = rec_cert.substring(info11 + 1, info12);
+			kmcVO.setIp(ip);
+			M_name = rec_cert.substring(info12 + 1, info13);
+			kmcVO.setMName(M_name);
+			M_birthDay = rec_cert.substring(info13 + 1, info14);
+			kmcVO.setMBirthDay(M_birthDay);
+			M_Gender = rec_cert.substring(info14 + 1, info15);
+			kmcVO.setMGender(M_Gender);
+			M_nation = rec_cert.substring(info15 + 1, info16);
+			kmcVO.setMNation(M_nation);
+			plusInfo = rec_cert.substring(info16 + 1, info17);
+			kmcVO.setPlusInfo(plusInfo);
+			DI = rec_cert.substring(info17 + 1, info18);
+			kmcVO.setDI(DI);
+
+			// 07. CI, DI 복호화
+			CI = seed.getDec(CI, k_certNum);
+			kmcVO.setCI(CI);
+			DI = seed.getDec(DI, k_certNum);
+			kmcVO.setDI(DI);
+
+			if ("Y".equals(result)) {
+
+			}
+
+			// --------------------------------------------------------------
+			String regex = "";
+			if (certNum.length() == 0 || certNum.length() > 40) {
+				errMessage = "요청번호 비정상.";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[0-9]*";
+			if (date.length() != 14 || !paramChk(regex, date)) {
+				errMessage = "요청일시";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[A-Z]*";
+			if (certMet.length() != 1 || !paramChk(regex, certMet)) {
+				errMessage = "본인인증방법 비정상" + certMet;
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[0-9]*";
+			if ((phoneNo.length() != 10 && phoneNo.length() != 11) || !paramChk(regex, phoneNo)) {
+				errMessage = "휴대폰번호 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[A-Z]*";
+			if (phoneCorp.length() != 3 || !paramChk(regex, phoneCorp)) {
+				errMessage = "이동통신사 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[0-9]*";
+			if (birthDay.length() != 8 || !paramChk(regex, birthDay)) {
+				errMessage = "생년월일 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[0-9]*";
+			if (gender.length() != 1 || !paramChk(regex, gender)) {
+				errMessage = "성별 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[0-9]*";
+			if (nation.length() != 1 || !paramChk(regex, nation)) {
+				errMessage = "내/외국인 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[\\sA-Za-z가-�R.,-]*";
+			if (name.length() > 60 || !paramChk(regex, name)) {
+				errMessage = "성명 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[A-Z]*";
+			if (result.length() != 1 || !paramChk(regex, result)) {
+				errMessage = "결과값 비정상";
+				return returnPage(model, errMessage, kmcVO);
+			}
+
+			regex = "[\\sA-Za-z가-?.,-]*";
+			if (M_name.length() != 0) {
+				if (M_name.length() > 60 || !paramChk(regex, M_name)) {
+					errMessage = "미성년자 성명 비정상";
+					return returnPage(model, errMessage, kmcVO);
+				}
+			}
+
+			regex = "[0-9]*";
+			if (M_birthDay.length() != 0) {
+				if (M_birthDay.length() != 8 || !paramChk(regex, M_birthDay)) {
+					errMessage = "미성년자 생년월일  비정상";
+					return returnPage(model, errMessage, kmcVO);
+				}
+			}
+
+			regex = "[0-9]*";
+			if (M_Gender.length() != 0) {
+				if (M_Gender.length() != 1 || !paramChk(regex, M_Gender)) {
+					errMessage = "미성년자 성별 비정상";
+					return returnPage(model, errMessage, kmcVO);
+				}
+			}
+
+			regex = "[0-9]*";
+			if (M_nation.length() != 0) {
+				if (M_nation.length() != 1 || !paramChk(regex, M_nation)) {
+					errMessage = "미성년자 내/외국인 비정상";
+					return returnPage(model, errMessage, kmcVO);
+				}
+			}
+
+			// KMC 본인인증 로그
+			AuthCertVO certVO = new AuthCertVO();
+
+			certVO.setMberId(kmcVO.getPlusInfo());
+			certVO.setCertNum(kmcVO.getCertNum());
+			certVO.setCertDate(kmcVO.getDate());
+			certVO.setCertDi(kmcVO.getDI());
+			certVO.setCertPhone(kmcVO.getPhoneNo());
+			certVO.setCertNation(kmcVO.getNation());
+			certVO.setCertName(kmcVO.getName());
+			certVO.setCertResult(kmcVO.getResult());
+			certVO.setCertType("KMC_주소록내보내기");
+			certVO.setCertIpaddr(kmcVO.getIp());
+			certVO.setBirthDay(kmcVO.getBirthDay());
+			certVO.setSexdstnCode(kmcVO.getGender());
+
+			// 디비 테이블에 저장하기
+			mberManageService.insertCertInfoLog(certVO);
+
+			model.addAttribute("kmcVO", kmcVO);
+			return "web/addr/AddrSubmitKmcReqPage";
+		}
+		
+		
+		
+		
+		// 파라미터 유효성 검증 --------------------------------------------
+		public Boolean paramChk(String patn, String param) {
+			Pattern pattern = Pattern.compile(patn);
+			Matcher matcher = pattern.matcher(param);
+			boolean b = matcher.matches();
+			return b;
+		}
+
+		// 파라미터 유효성 검증 --------------------------------------------
+		public String returnPage(ModelMap model, String errMessage, KmcVO kmcVO) {
+			kmcVO.setErrMessage(errMessage);
+			model.addAttribute("kmcVO", kmcVO);
+			return "web/cop/nicepay/payRequestAjax";
+		}
+	
+
+}
src/main/resources/egovframework/sqlmap/let/mjo/addr/AddrGroup_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/mjo/addr/AddrGroup_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/addr/AddrGroup_SQL_Mysql.xml
@@ -1,183 +1,204 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
-<sqlMap namespace="AddrGroup">
-	<typeAlias  alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
-	<typeAlias  alias="addrGroupVO" type="itn.let.mjo.addr.service.AddrGroupVO"/>
-
-	<!-- 주소록 그룹 목록 조회 -->
-	<select id="AddrGroupDAO.selectAddrGroupList" parameterClass="addrGroupVO" resultClass="addrGroupVO">
-		SELECT
-			COUNT(1) OVER() 					AS	totCnt
-			,A.ADDR_GRP_ID 						AS	addrGrpId
-			,A.MBER_ID 							AS	mberId
-			,A.ADDR_GRP_NM 						AS	addrGrpNm
-			,A.FRST_REGIST_PNTTM				AS	frstRegistPnttm
-			,A.DELETE_YN						AS	deleteYn
-			,IFNULL(a.GRP_ORDER, '0')			AS	grpOrder
-			,(SELECT COUNT(1) FROM MJ_ADDR WHERE ADDR_GRP_ID = A.ADDR_GRP_ID)	AS	grpCount
-		FROM 
-			MJ_ADDR_GRP A
-		LEFT OUTER JOIN 
-			MJ_ADDR_TRANS_HIST B
-		ON
-			A.ADDR_GRP_ID = B.ADDR_GRP_ID
-		WHERE 
-			(B.RECV_STATUS = 'Y' OR B.RECV_STATUS IS NULL)
-		<isNotEmpty property="mberId">
-			AND A.MBER_ID = #mberId#
-		</isNotEmpty>
-		<isNotEmpty property="searchKeyword">
-	 		<isEqual property="searchCondition" compareValue="">
-	 			AND ( A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				OR A.ADDR_GRP_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				)
-	 		</isEqual>
-			<isEqual property="searchCondition" compareValue="1">
-				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-			<isEqual property="searchCondition" compareValue="2">
-				AND A.ADDR_GRP_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-	 	</isNotEmpty>
-		GROUP BY A.ADDR_GRP_ID
-        <isNotEqual property="siteId" compareValue="admin">
-			ORDER BY A.GRP_ORDER
-			<isNotEmpty property="searchSortCnd">
-			,$searchSortCnd$
-			</isNotEmpty> 		
-		</isNotEqual>		
-        <isEqual property="siteId" compareValue="admin">
-			ORDER BY A.ADDR_GRP_ID DESC
-			<isNotEmpty property="searchSortCnd">
-			,$searchSortCnd$
-			</isNotEmpty> 		
-		</isEqual>		
-
-		<isEqual property="siteId" compareValue="admin">
-			LIMIT #recordCountPerPage# OFFSET #firstIndex#
-		</isEqual>		
-	</select>
-	
-	<!-- 주소록 그룹 상세  조회 -->
-	<select id="AddrGroupDAO.selectAddrGroupDetail" parameterClass="addrGroupVO" resultClass="addrGroupVO">
-		SELECT
-			a.ADDR_GRP_ID 	AS addrGrpId
-			,a.MBER_ID 		AS mberId
-			,a.ADDR_GRP_NM  AS addrGrpNm
-		FROM 
-			MJ_ADDR_GRP a
-		WHERE 1=1
-		AND a.ADDR_GRP_ID = #addrGrpId#
-	</select>
-
-	<select id="AddrGroupDAO.selectAddrGroupTotCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
-		/* AddrGroupDAO.selectAddrGroupTotCnt */
-		SELECT 
-			COUNT(0) AS addrTotCnt
-		FROM	MJ_ADDR A
-		WHERE A.MBER_ID = #mberId#
-			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-			AND A.DELETE_YN = 'N'
-	</select>
-		
-	<!-- 주소록 그룹 카운트 조회(그룹미지정) -->
-	<select id="AddrGroupDAO.selectAddrGroupNogrpCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
-		SELECT 
-			COUNT(0) AS nogrpCnt
-		FROM MJ_ADDR A 
-		WHERE A.MBER_ID = #mberId#
-			AND A.ADDR_GRP_ID = '0'
-			AND A.BOOKMARK = 'N'
-			AND A.DELETE_YN = 'N'
-	</select>
-
-	<!-- 주소록 그룹 카운트 조회(그룹미지정) -->
-	<select id="AddrGroupDAO.selectAddrGroupBookmarkCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
-		SELECT 
-			COUNT(0) AS bookmarkCnt
-		FROM MJ_ADDR A 
-		WHERE A.MBER_ID = #mberId#
-			AND A.BOOKMARK = 'Y'
-			AND A.DELETE_YN = 'N'
-	</select>
-				
-	<!-- 주소록 그룹 등록 -->
-	<insert id="AddrGroupDAO.insertAddrGroup" parameterClass="addrGroupVO">
-		INSERT INTO MJ_ADDR_GRP (
-			MBER_ID
-			,ADDR_GRP_NM
-			,GRP_ORDER
-			,FRST_REGIST_PNTTM
-			,FRST_REGISTER_ID
-		)VALUES(
-			#mberId#
-			,#addrGrpNm#
-			,#grpOrder#
-			,NOW()
-			,#frstRegisterId#
-		)
-		<selectKey keyProperty="addrGrpId" resultClass="String">
-			SELECT LAST_INSERT_ID()
-		</selectKey>
-	</insert>
-	
-	<!-- 주소록 그룹수정 -->
-	<update id="AddrGroupDAO.updateAddrGroup" parameterClass="addrGroupVO">
-		UPDATE
-			MJ_ADDR_GRP
-		SET
-			ADDR_GRP_NM       = #addrGrpNm#
-			,GRP_ORDER		  = #grpOrder#
-			,LAST_UPDT_PNTTM  = NOW()
-			,LAST_UPDUSR_ID   = #lastUpdusrId#
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_GRP_ID = #addrGrpId#
-	</update>
-	
-	<!-- 주소록 그룹삭제 -->
-	<delete id="AddrGroupDAO.deleteAddrGroup" parameterClass="addrGroupVO">
-		DELETE FROM 
-			MJ_ADDR_GRP
-		WHERE
-			MBER_ID = #mberId#
-		<isEmpty property="mergeGrps">
-		AND
-			ADDR_GRP_ID = #addrGrpId#
-		</isEmpty>
-		<isNotEmpty property="mergeGrps">
-		AND
-			ADDR_GRP_ID in (#mergeGrps#) 
-		</isNotEmpty>
-	</delete>
-	
-	<!-- 주소록 그룹삭제 By Admin -->
-	<delete id="AddrGroupDAO.deleteAddrGroupByAdmin" parameterClass="addrGroupVO">
-		DELETE FROM 
-			MJ_ADDR_GRP
-		WHERE ADDR_GRP_ID = #addrGrpId#
-	</delete>	
-	
-	<!-- 주소록 그룹명 중복확인 -->
-	<select id="AddrGroupDAO.selectDuplAddrGroupCnt" parameterClass="addrGroupVO" resultClass="int">
-		SELECT 
-			COUNT(1) usedCnt
-		FROM 
-			MJ_ADDR_GRP
-		WHERE 
-			ADDR_GRP_NM = #addrGrpNm#
-		AND
-			MBER_ID = #mberId#
-	</select>
-	
-	<!-- 주소록 그룹 다음 순서번호 확인 -->
-	<select id="AddrGroupDAO.selectMaxOrderNumber" parameterClass="addrGroupVO" resultClass="int">
-		SELECT 
-			IFNULL(MAX(GRP_ORDER),0)+1 nextOrderNumber
-		FROM 
-			MJ_ADDR_GRP
-		WHERE 
-			MBER_ID = #mberId#
-	</select>
-</sqlMap>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
+<sqlMap namespace="AddrGroup">
+	<typeAlias  alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
+	<typeAlias  alias="addrGroupVO" type="itn.let.mjo.addr.service.AddrGroupVO"/>
+
+	<!-- 주소록 그룹 목록 조회 -->
+	<select id="AddrGroupDAO.selectAddrGroupList" parameterClass="addrGroupVO" resultClass="addrGroupVO">
+		/* AddrGroupDAO.selectAddrGroupList */
+		SELECT
+			COUNT(1) OVER() 					AS	totCnt
+			,A.ADDR_GRP_ID 						AS	addrGrpId
+			,A.MBER_ID 							AS	mberId
+			,A.ADDR_GRP_NM 						AS	addrGrpNm
+			,A.FRST_REGIST_PNTTM				AS	frstRegistPnttm
+			,A.DELETE_YN						AS	deleteYn
+			,IFNULL(a.GRP_ORDER, '0')			AS	grpOrder
+			,(SELECT COUNT(1) FROM MJ_ADDR WHERE ADDR_GRP_ID = A.ADDR_GRP_ID)	AS	grpCount
+		FROM 
+			MJ_ADDR_GRP A
+		LEFT OUTER JOIN 
+			MJ_ADDR_TRANS_HIST B
+		ON
+			A.ADDR_GRP_ID = B.ADDR_GRP_ID
+		WHERE 
+			(B.RECV_STATUS = 'Y' OR B.RECV_STATUS IS NULL)
+		<isNotEmpty property="mberId">
+			AND A.MBER_ID = #mberId#
+		</isNotEmpty>
+			AND A.DELETE_YN  = 'N'
+		<isNotEmpty property="searchKeyword">
+	 		<isEqual property="searchCondition" compareValue="">
+	 			AND ( A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				OR A.ADDR_GRP_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				)
+	 		</isEqual>
+			<isEqual property="searchCondition" compareValue="1">
+				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+			<isEqual property="searchCondition" compareValue="2">
+				AND A.ADDR_GRP_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+	 	</isNotEmpty>
+		GROUP BY A.ADDR_GRP_ID
+        <isNotEqual property="siteId" compareValue="admin">
+			ORDER BY A.GRP_ORDER
+			<isNotEmpty property="searchSortCnd">
+			,$searchSortCnd$
+			</isNotEmpty> 		
+		</isNotEqual>		
+        <isEqual property="siteId" compareValue="admin">
+			ORDER BY A.ADDR_GRP_ID DESC
+			<isNotEmpty property="searchSortCnd">
+			,$searchSortCnd$
+			</isNotEmpty> 		
+		</isEqual>		
+
+		<isEqual property="siteId" compareValue="admin">
+			LIMIT #recordCountPerPage# OFFSET #firstIndex#
+		</isEqual>		
+	</select>
+	
+	<!-- 주소록 그룹 상세  조회 -->
+	<select id="AddrGroupDAO.selectAddrGroupDetail" parameterClass="addrGroupVO" resultClass="addrGroupVO">
+		SELECT
+			a.ADDR_GRP_ID 	AS addrGrpId
+			,a.MBER_ID 		AS mberId
+			,a.ADDR_GRP_NM  AS addrGrpNm
+		FROM 
+			MJ_ADDR_GRP a
+		WHERE 1=1
+		AND a.ADDR_GRP_ID = #addrGrpId#
+	</select>
+
+	<select id="AddrGroupDAO.selectAddrGroupTotCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
+		/* AddrGroupDAO.selectAddrGroupTotCnt */
+		SELECT 
+			COUNT(0) AS addrTotCnt
+		FROM	MJ_ADDR A
+		WHERE A.MBER_ID = #mberId#
+			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+			AND A.DELETE_YN = 'N'
+	</select>
+		
+	<!-- 주소록 그룹 카운트 조회(그룹미지정) -->
+	<select id="AddrGroupDAO.selectAddrGroupNogrpCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
+		/* AddrGroupDAO.selectAddrGroupNogrpCnt */
+		SELECT 
+			COUNT(0) AS nogrpCnt
+		FROM MJ_ADDR A 
+		WHERE A.MBER_ID = #mberId#
+			AND A.ADDR_GRP_ID = '0'
+			AND A.BOOKMARK = 'N'
+			AND A.DELETE_YN = 'N'
+	</select>
+
+	<!-- 주소록 그룹 카운트 조회(그룹미지정) -->
+	<select id="AddrGroupDAO.selectAddrGroupBookmarkCnt" parameterClass="addrGroupVO" resultClass="addrGroupVO">
+		SELECT 
+			COUNT(0) AS bookmarkCnt
+		FROM MJ_ADDR A 
+		WHERE A.MBER_ID = #mberId#
+			AND A.BOOKMARK = 'Y'
+			AND A.DELETE_YN = 'N'
+	</select>
+				
+	<!-- 주소록 그룹 등록 -->
+	<insert id="AddrGroupDAO.insertAddrGroup" parameterClass="addrGroupVO">
+		INSERT INTO MJ_ADDR_GRP (
+			MBER_ID
+			,ADDR_GRP_NM
+			,GRP_ORDER
+			,FRST_REGIST_PNTTM
+			,FRST_REGISTER_ID
+		)VALUES(
+			#mberId#
+			,#addrGrpNm#
+			,#grpOrder#
+			,NOW()
+			,#frstRegisterId#
+		)
+		<selectKey keyProperty="addrGrpId" resultClass="String">
+			SELECT LAST_INSERT_ID()
+		</selectKey>
+	</insert>
+	
+	<!-- 주소록 그룹수정 -->
+	<update id="AddrGroupDAO.updateAddrGroup" parameterClass="addrGroupVO">
+		UPDATE
+			MJ_ADDR_GRP
+		SET
+			ADDR_GRP_NM       = #addrGrpNm#
+			,GRP_ORDER		  = #grpOrder#
+			,LAST_UPDT_PNTTM  = NOW()
+			,LAST_UPDUSR_ID   = #lastUpdusrId#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_GRP_ID = #addrGrpId#
+	</update>
+	
+	<!-- 주소록 그룹삭제 -->
+	<delete id="AddrGroupDAO.deleteAddrGroup" parameterClass="addrGroupVO">
+		DELETE FROM 
+			MJ_ADDR_GRP
+		WHERE
+			MBER_ID = #mberId#
+		<isEmpty property="mergeGrps">
+		AND
+			ADDR_GRP_ID = #addrGrpId#
+		</isEmpty>
+		<isNotEmpty property="mergeGrps">
+		AND
+			ADDR_GRP_ID in (#mergeGrps#) 
+		</isNotEmpty>
+	</delete>
+	
+	<!-- 주소록 그룹삭제 -->
+	<delete id="AddrGroupDAO.deleteAddrGroup_advc" parameterClass="addrGroupVO">
+		/* AddrGroupDAO.deleteAddrGroup_advc*/
+		
+		
+		UPDATE
+			MJ_ADDR_GRP
+		SET
+			DELETE_YN       = 'Y'
+			,LAST_UPDT_PNTTM  = NOW()
+			,LAST_UPDUSR_ID   = #lastUpdusrId#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_GRP_ID = #addrGrpId#
+		
+	</delete>
+	
+	<!-- 주소록 그룹삭제 By Admin -->
+	<delete id="AddrGroupDAO.deleteAddrGroupByAdmin" parameterClass="addrGroupVO">
+		DELETE FROM 
+			MJ_ADDR_GRP
+		WHERE ADDR_GRP_ID = #addrGrpId#
+	</delete>	
+	
+	<!-- 주소록 그룹명 중복확인 -->
+	<select id="AddrGroupDAO.selectDuplAddrGroupCnt" parameterClass="addrGroupVO" resultClass="int">
+		SELECT 
+			COUNT(1) usedCnt
+		FROM 
+			MJ_ADDR_GRP
+		WHERE 
+			ADDR_GRP_NM = #addrGrpNm#
+		AND
+			MBER_ID = #mberId#
+	</select>
+	
+	<!-- 주소록 그룹 다음 순서번호 확인 -->
+	<select id="AddrGroupDAO.selectMaxOrderNumber" parameterClass="addrGroupVO" resultClass="int">
+		SELECT 
+			IFNULL(MAX(GRP_ORDER),0)+1 nextOrderNumber
+		FROM 
+			MJ_ADDR_GRP
+		WHERE 
+			MBER_ID = #mberId#
+	</select>
+</sqlMap>
src/main/resources/egovframework/sqlmap/let/mjo/addr/Addr_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/mjo/addr/Addr_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/addr/Addr_SQL_Mysql.xml
@@ -1,1361 +1,1366 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
-<sqlMap namespace="Addr">
-	<typeAlias  alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
-	<typeAlias  alias="addrVO" type="itn.let.mjo.addr.service.AddrVO"/>
-	<typeAlias  alias="addrTransHistVO" type="itn.let.mjo.addr.service.AddrTransHistVO"/>
-
-	<!-- 주소록 목록 조회 -->
-	<select id="AddrDAO.selectAddrList" parameterClass="addrVO" resultClass="addrVO">
-		/*	AddrDAO.selectAddrList	*/
-		SELECT		
-		/*
-			1 			AS totCnt
-			*/			
-			COUNT(1) OVER() 			AS totCnt
-			,A.ADDR_ID					AS addrId
-			,A.ADDR_GRP_ID				AS addrGrpId
-			,A.MBER_ID					AS mberId
-			,A.ADDR_NM					AS addrNm
-			,A.ADDR_PHONE_NO			AS addrPhoneNo
-			,A.ADDR_INFO1				AS addrInfo1
-			,A.ADDR_INFO2				AS addrInfo2
-			,A.ADDR_INFO3				AS addrInfo3
-			,A.ADDR_INFO4				AS addrInfo4
-			,A.ADDR_COMMENT				AS addrComment
-			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
-			,A.FRST_REGISTER_ID			AS frstRegisterId
-			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
-			,A.LAST_UPDUSR_ID			AS lastUpdusrId
-			,A.DELETE_YN				AS deleteYn
-			,A.BOOKMARK					AS bookmark
-			,CASE
-				WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N' 
-				THEN '그룹미지정'
-				WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
-				THEN '자주보내는 번호'
-				ELSE B.ADDR_GRP_NM
-			END AS addrGrpNm
-		FROM
-			MJ_ADDR A
-		LEFT OUTER JOIN 
-			MJ_ADDR_GRP B
-		ON 
-			A.ADDR_GRP_ID = B.ADDR_GRP_ID
-		LEFT OUTER JOIN 
-			MJ_ADDR_TRANS_HIST C
-		ON
-			B.ADDR_GRP_ID = C.ADDR_GRP_ID
-		WHERE 1=1
-		<isNotEmpty property="mberId">
-			AND A.MBER_ID = #mberId#
-		</isNotEmpty>		
-		
-		AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
-		
-		<isNotEmpty property="addrIdList">
-			<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
-				#addrIdList[]#
-			</iterate>
-		</isNotEmpty>		
-		
-		AND      A.ADDR_GRP_ID in (
-							        select addr_grp_id
-									from mj_addr_grp	
-									where 1=1
-										<isNotEmpty property="mberId">
-											AND MBER_ID = #mberId#
-										</isNotEmpty>
-										AND ADDR_GRP_ID = #searchAddrGrpId#			
-		        )				
-
-		<isNotEmpty property="searchKeyword">
-	 		<isEqual property="searchCondition" compareValue="">
-	 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				)
-	 		</isEqual>
-			<isEqual property="searchCondition" compareValue="1">
-				AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-			<isEqual property="searchCondition" compareValue="2">
-				AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-			<isEqual property="searchCondition" compareValue="3">
-				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>			
-	 	</isNotEmpty>
-	 	<isNotEmpty property="searchAddrGrpId">
-	 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
-	 		AND A.BOOKMARK = 'Y'
-	 		</isEqual>
-	 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
-	 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
-	 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
-	 			</isEqual>
-	 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
-	 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
- 				</isNotEqual>
-	 		</isNotEqual>
-	 	</isNotEmpty>
-		<isEqual property="startKeyword" compareValue="1">
-			AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="2">
-			AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="3">
-			AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="4">
-			AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="5">
-			AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="6">
-			AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="7">
-			AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="8">
-			AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="9">
-			AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="10">
-			AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="11">
-			AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="12">
-			AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="13">
-			AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="14">
-			AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="a">
-	 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="0">
-			AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
-		</isEqual>
-		ORDER BY 1=1
-		<isNotEmpty property="searchSortCnd">
-			,$searchSortCnd$
-		</isNotEmpty>
-		<isNotEmpty property="searchSortOrd">
-		 	$searchSortOrd$
-		</isNotEmpty>
-		LIMIT #recordCountPerPage# OFFSET #firstIndex#
-	</select>
-		
-	<!-- 주소록 목록 조회 -->
-	<select id="AddrDAO.selectAddrListCount" parameterClass="addrVO" resultClass="int">
-		/*	AddrDAO.selectAddrListCount	*/
-		SELECT			
-			COUNT(1)  			AS totCnt			
-		FROM
-			MJ_ADDR A
-		LEFT OUTER JOIN 
-			MJ_ADDR_TRANS_HIST C
-		ON
-			A.ADDR_GRP_ID = C.ADDR_GRP_ID
-		WHERE 1=1
-		<isNotEmpty property="mberId">
-			AND A.MBER_ID = #mberId#
-		</isNotEmpty>		
-		
-		AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
-		
-		<isNotEmpty property="addrIdList">
-			<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
-				#addrIdList[]#
-			</iterate>
-		</isNotEmpty>		
-		
-		AND      A.ADDR_GRP_ID in (
-							        select addr_grp_id
-									from mj_addr_grp	
-									where 1=1
-										<isNotEmpty property="mberId">
-											AND MBER_ID = #mberId#
-										</isNotEmpty>
-										<isNotEmpty property="addrGrpId">
-											AND ADDR_GRP_ID = #addrGrpId#
-										</isNotEmpty>			
-		        )		
-		
-		<isNotEmpty property="searchKeyword">
-	 		<isEqual property="searchCondition" compareValue="">
-	 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-	 				)
-	 		</isEqual>
-			<isEqual property="searchCondition" compareValue="1">
-				AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-			<isEqual property="searchCondition" compareValue="2">
-				AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>
-			<isEqual property="searchCondition" compareValue="3">
-				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-			</isEqual>			
-	 	</isNotEmpty>
-	 	<isNotEmpty property="searchAddrGrpId">
-	 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
-	 		AND A.BOOKMARK = 'Y'
-	 		</isEqual>
-	 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
-	 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
-	 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
-	 			</isEqual>
-	 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
-	 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
- 				</isNotEqual>
-	 		</isNotEqual>
-	 	</isNotEmpty>
-		<isEqual property="startKeyword" compareValue="1">
-			AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="2">
-			AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="3">
-			AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="4">
-			AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="5">
-			AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="6">
-			AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="7">
-			AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="8">
-			AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="9">
-			AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="10">
-			AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="11">
-			AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="12">
-			AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="13">
-			AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="14">
-			AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="a">
-	 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
-		</isEqual>
-		<isEqual property="startKeyword" compareValue="0">
-			AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
-		</isEqual>		
-	</select>	
-	
-	<!-- 주소록 목록 조회(속도개선) -->
-	<select id="AddrDAO.selectAddrNewList" parameterClass="addrVO" resultClass="addrVO">
-		SELECT
-		  	(
-				SELECT COUNT(0) FROM mj_addr A
-				LEFT OUTER JOIN 
-					MJ_ADDR_GRP B
-				ON 
-					A.ADDR_GRP_ID = B.ADDR_GRP_ID
-				LEFT OUTER JOIN 
-					MJ_ADDR_TRANS_HIST C
-				ON
-					B.ADDR_GRP_ID = C.ADDR_GRP_ID
-				WHERE 1=1
-				AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
-				<isNotEmpty property="mberId">
-					AND A.MBER_ID = #mberId#
-				</isNotEmpty>		
-				<isNotEmpty property="searchStartDate">
-					<![CDATA[ 
-						AND A.FRST_REGIST_PNTTM >= DATE_FORMAT(#searchStartDate#, '%Y-%m-%d')
-					]]>
-				</isNotEmpty>
-				<isNotEmpty property="searchEndDate">
-					<![CDATA[ 
-						AND A.FRST_REGIST_PNTTM <= DATE_ADD(DATE_FORMAT(#searchEndDate#, '%Y-%m-%d')  , INTERVAL 1 DAY) 
-					]]>
-				</isNotEmpty>				
-				<isNotEmpty property="addrIdList">
-					<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
-						#addrIdList[]#
-					</iterate>
-				</isNotEmpty>		
-				<isNotEmpty property="addrGrpId">
-					AND A.ADDR_GRP_ID = #addrGrpId#
-				</isNotEmpty>
-				<isNotEmpty property="searchKeyword">
-			 		<isEqual property="searchCondition" compareValue="">
-			 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-			 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-			 				)
-			 		</isEqual>
-					<isEqual property="searchCondition" compareValue="1">
-						AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-					</isEqual>
-					<isEqual property="searchCondition" compareValue="2">
-						AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-					</isEqual>
-					<isEqual property="searchCondition" compareValue="3">
-						AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-					</isEqual>			
-			 	</isNotEmpty>
-			 	<isNotEmpty property="searchAddrGrpId">
-			 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
-			 		AND A.BOOKMARK = 'Y'
-			 		</isEqual>
-			 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
-			 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
-			 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
-			 			</isEqual>
-			 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
-			 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
-		 				</isNotEqual>
-			 		</isNotEqual>
-			 	</isNotEmpty>
-				<isEqual property="startKeyword" compareValue="1">
-					AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="2">
-					AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="3">
-					AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="4">
-					AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="5">
-					AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="6">
-					AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="7">
-					AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="8">
-					AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="9">
-					AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="10">
-					AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="11">
-					AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="12">
-					AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="13">
-					AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="14">
-					AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="a">
-			 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
-				</isEqual>
-				<isEqual property="startKeyword" compareValue="0">
-					AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
-				</isEqual>
-		  	) totCnt 
-			,M.addrId
-			,M.addrGrpId
-			,M.mberId
-			,M.addrNm
-			,M.addrPhoneNo
-			,M.addrInfo1
-			,M.addrInfo2
-			,M.addrInfo3
-			,M.addrInfo4
-			,M.addrComment
-			,M.frstRegistPnttm
-			,M.frstRegisterId
-			,M.lastUpdtPnttm
-			,M.lastUpdusrId
-			,M.deleteYn
-			,M.bookmark
-			,M.addrGrpNm
-	  	FROM (
-			SELECT
-				A.ADDR_ID					AS addrId
-				,A.ADDR_GRP_ID				AS addrGrpId
-				,A.MBER_ID					AS mberId
-				,A.ADDR_NM					AS addrNm
-				,A.ADDR_PHONE_NO			AS addrPhoneNo
-				,A.ADDR_INFO1				AS addrInfo1
-				,A.ADDR_INFO2				AS addrInfo2
-				,A.ADDR_INFO3				AS addrInfo3
-				,A.ADDR_INFO4				AS addrInfo4
-				,A.ADDR_COMMENT				AS addrComment
-				,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
-				,A.FRST_REGISTER_ID			AS frstRegisterId
-				,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
-				,A.LAST_UPDUSR_ID			AS lastUpdusrId
-				,A.DELETE_YN				AS deleteYn
-				,A.BOOKMARK					AS bookmark
-				,CASE
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N' 
-					THEN '그룹미지정'
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
-					THEN '자주보내는 번호'
-					ELSE B.ADDR_GRP_NM
-				END AS addrGrpNm
-			FROM
-				MJ_ADDR A
-			LEFT OUTER JOIN 
-				MJ_ADDR_GRP B
-			ON 
-				A.ADDR_GRP_ID = B.ADDR_GRP_ID
-			LEFT OUTER JOIN 
-				MJ_ADDR_TRANS_HIST C
-			ON
-				B.ADDR_GRP_ID = C.ADDR_GRP_ID
-			WHERE 1=1
-			AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
-			<isNotEmpty property="mberId">
-				AND A.MBER_ID = #mberId#
-			</isNotEmpty>		
-			<isNotEmpty prepend="AND" property="searchStartDate">
-				<![CDATA[ 
-					A.FRST_REGIST_PNTTM >= DATE_FORMAT(#searchStartDate#, '%Y-%m-%d')
-				]]>
-			</isNotEmpty>
-			<isNotEmpty prepend="AND" property="searchEndDate">
-				<![CDATA[ 
-					DATE_FORMAT(A.FRST_REGIST_PNTTM, '%Y-%m-%d') <= DATE_ADD(DATE_FORMAT(#searchEndDate#, '%Y-%m-%d')  , INTERVAL 1 DAY) 
-				]]>
-			</isNotEmpty>							
-			<isNotEmpty property="addrIdList">
-				<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
-					#addrIdList[]#
-				</iterate>
-			</isNotEmpty>		
-			<isNotEmpty property="addrGrpId">
-				AND A.ADDR_GRP_ID = #addrGrpId#
-			</isNotEmpty>
-			<isNotEmpty property="searchKeyword">
-		 		<isEqual property="searchCondition" compareValue="">
-		 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-		 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-		 				)
-		 		</isEqual>
-				<isEqual property="searchCondition" compareValue="1">
-					AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
-				</isEqual>
-				<isEqual property="searchCondition" compareValue="2">
-					AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
-				</isEqual>
-				<isEqual property="searchCondition" compareValue="3">
-					AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
-				</isEqual>			
-		 	</isNotEmpty>
-		 	<isNotEmpty property="searchAddrGrpId">
-		 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
-		 		AND A.BOOKMARK = 'Y'
-		 		</isEqual>
-		 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
-		 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
-		 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
-		 			</isEqual>
-		 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
-		 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
-	 				</isNotEqual>
-		 		</isNotEqual>
-		 	</isNotEmpty>
-			<isEqual property="startKeyword" compareValue="1">
-				AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="2">
-				AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="3">
-				AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="4">
-				AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="5">
-				AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="6">
-				AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="7">
-				AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="8">
-				AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="9">
-				AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="10">
-				AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="11">
-				AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="12">
-				AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="13">
-				AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="14">
-				AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="a">
-		 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
-			</isEqual>
-			<isEqual property="startKeyword" compareValue="0">
-				AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
-			</isEqual>
-
-			ORDER BY 1=1
-			<isNotEmpty property="searchSortCnd">
-				,$searchSortCnd$
-			</isNotEmpty>
-			<isNotEmpty property="searchSortOrd">
-			 	$searchSortOrd$
-			</isNotEmpty>
-			LIMIT #recordCountPerPage# OFFSET #firstIndex#
-		) M	
-	</select>	
-	
-	<!-- 회원별 주소록 전체 갯수 조회 -->
-	<select id="AddrDAO.selectAddrTotalCount" parameterClass="addrVO" resultClass="int">
-		SELECT
-			COUNT(A.ADDR_ID)	AS	totCnt 
-		FROM
-			MJ_ADDR A
-		WHERE
-			A.MBER_ID = #mberId#
-			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-			AND A.DELETE_YN = 'N'
-	</select>
-	
-	<!-- 주소록 상세  조회 -->
-	<select id="AddrDAO.selectAddrDetail" parameterClass="addrVO" resultClass="addrVO">
-		SELECT
-			A.ADDR_ID					AS addrId
-			,A.ADDR_GRP_ID				AS addrGrpId
-			,A.MBER_ID					AS mberId
-			,A.ADDR_NM					AS addrNm
-			,A.ADDR_PHONE_NO			AS addrPhoneNo
-			,A.ADDR_INFO1				AS addrInfo1
-			,A.ADDR_INFO2				AS addrInfo2
-			,A.ADDR_INFO3				AS addrInfo3
-			,A.ADDR_INFO4				AS addrInfo4
-			,A.ADDR_COMMENT				AS addrComment
-			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
-			,A.FRST_REGISTER_ID			AS frstRegisterId
-			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
-			,A.LAST_UPDUSR_ID			AS lastUpdusrId
-			,A.DELETE_YN				AS deleteYn
-			,A.BOOKMARK					AS bookmark
-			,b.ADDR_GRP_NM				AS addrGrpNm
-		FROM 
-			MJ_ADDR a
-		LEFT OUTER JOIN 
-			MJ_ADDR_GRP b
-		ON 
-			a.ADDR_GRP_ID = b.ADDR_GRP_ID
-		WHERE 
-			a.ADDR_ID = #addrId#
-	</select>
-	
-	
-	<!-- 주소록 등록 -->
-	<insert id="AddrDAO.insertAddr" parameterClass="addrVO">
-		INSERT INTO MJ_ADDR (
-			<isNotEmpty property="addrGrpId">
-			ADDR_GRP_ID,
-			</isNotEmpty>
-			MBER_ID
-			,ADDR_NM
-			,ADDR_PHONE_NO
-			,ADDR_INFO1
-			,ADDR_INFO2
-			,ADDR_INFO3
-			,ADDR_INFO4
-			,ADDR_COMMENT
-			,FRST_REGIST_PNTTM
-			,FRST_REGISTER_ID
-			<isNotEmpty property="bookmark">
-			,BOOKMARK
-			</isNotEmpty>
-			<isNotEmpty property="recvStatus">
-			,RECV_STATUS
-			</isNotEmpty>
-		)VALUES(
-			<isNotEmpty property="addrGrpId">
-			#addrGrpId#,
-			</isNotEmpty>
-			#mberId#
-			,#addrNm#
-			,#addrPhoneNo#
-			,#addrInfo1#
-			,#addrInfo2#
-			,#addrInfo3#
-			,#addrInfo4#
-			,#addrComment#
-			,NOW()
-			,#frstRegisterId#
-			<isNotEmpty property="bookmark">
-			,#bookmark#
-			</isNotEmpty>
-			<isNotEmpty property="recvStatus">
-			,#recvStatus#
-			</isNotEmpty>
-		)
-	</insert>
-	
-	
-	<!-- 주소록 수정 -->
-	<update id="AddrDAO.updateAddr" parameterClass="addrVO">
-		UPDATE
-			MJ_ADDR
-		SET
-		<isNotEmpty property="addrGrpId">
-			ADDR_GRP_ID			= #addrGrpId#,
-		</isNotEmpty>
-		<isNotEmpty property="addrPhoneNo">
-			ADDR_PHONE_NO		= #addrPhoneNo#,
-		</isNotEmpty>
-		ADDR_NM				= #addrNm#,
-		ADDR_INFO1			= #addrInfo1#,
-		ADDR_INFO2			= #addrInfo2#,
-		ADDR_INFO3			= #addrInfo3#,
-		ADDR_INFO4			= #addrInfo4#,
-		<isNotEmpty property="addrComment">
-			ADDR_COMMENT		= #addrComment#,
-		</isNotEmpty>			
-		<isNotEmpty property="bookmark">
-			BOOKMARK			= #bookmark#,
-		</isNotEmpty>			
-			LAST_UPDT_PNTTM	= NOW(),
-			LAST_UPDUSR_ID		= #lastUpdusrId#
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_ID = #addrId#
-	</update>
-	
-	<!-- 주소록 그룹 수정 -->
-	<update id="AddrDAO.updateAddrGrp" parameterClass="addrVO">
-		UPDATE
-			MJ_ADDR
-		SET
-			ADDR_GRP_ID			= #addrGrpId#,
-			BOOKMARK			= #bookmark#,
-			LAST_UPDT_PNTTM	= NOW(),
-			LAST_UPDUSR_ID		= #lastUpdusrId#
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_ID = #addrId#
-	</update>	
-	
-	<!-- 주소록 메모 수정 -->
-	<update id="AddrDAO.updateMemoAddr" parameterClass="addrVO">
-		UPDATE
-			MJ_ADDR
-		SET
-			ADDR_COMMENT		= #addrComment#
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_ID = #addrId#
-	</update>	
-	
-	
-	
-	<!-- 주소록 수정 By Admin -->
-	<update id="AddrDAO.updateAddrByAdmin" parameterClass="addrVO">
-		UPDATE
-			MJ_ADDR
-		SET
-		<isNotEmpty property="addrGrpId">
-			ADDR_GRP_ID			= #addrGrpId#,
-		</isNotEmpty>
-		<isNotEmpty property="addrNm">
-			ADDR_NM				= #addrNm#,
-		</isNotEmpty>
-		<isNotEmpty property="addrPhoneNo">
-			ADDR_PHONE_NO		= #addrPhoneNo#,
-		</isNotEmpty>
-		<isNotEmpty property="addrInfo1">
-			ADDR_INFO1			= #addrInfo1#,
-		</isNotEmpty>
-		<isNotEmpty property="addrInfo2">
-			ADDR_INFO2			= #addrInfo2#,
-		</isNotEmpty>
-		<isNotEmpty property="addrInfo3">
-			ADDR_INFO3			= #addrInfo3#,
-		</isNotEmpty>
-		<isNotEmpty property="addrInfo4">
-			ADDR_INFO4			= #addrInfo4#,
-		</isNotEmpty>
-		<isNotEmpty property="addrComment">
-			ADDR_COMMENT		= #addrComment#,
-		</isNotEmpty>			
-		<isNotEmpty property="bookmark">
-			BOOKMARK			= #bookmark#,
-		</isNotEmpty>			
-			LAST_UPDT_PNTTM	= NOW(),
-			LAST_UPDUSR_ID		= #lastUpdusrId#
-		WHERE
-			ADDR_ID = #addrId#
-	</update>	
-	
-	
-	<!-- 주소록 합치기, 이동 -->
-	<update id="AddrDAO.updateAddrsGrp" parameterClass="addrVO">
-		UPDATE
-			MJ_ADDR
-		SET
-			ADDR_GRP_ID			= #addrGrpId#,
-			LAST_UPDT_PNTTM		= NOW(),
-			LAST_UPDUSR_ID		= #lastUpdusrId#
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_GRP_ID 
-		IN
-		<iterate  property="mergeGrps" open="(" close=")" conjunction=",">
-			#mergeGrps[]#
-		</iterate>
-		
-	</update>
-	
-
-	
-	<!-- 주소록 삭제 -->
-	<delete id="AddrDAO.deleteAddr" parameterClass="addrVO">
-		DELETE FROM 
-			MJ_ADDR
-		WHERE
-			MBER_ID = #mberId#
-		<isEqual property="grpDelete" compareValue="Y">
-		AND
-			ADDR_GRP_ID = #addrGrpId#
-		</isEqual>
-		<isNotEqual property="grpDelete" compareValue="Y">
-		AND
-			ADDR_ID = #addrId#
-		</isNotEqual>
-		<isNotEmpty property="batchSize">
-   			LIMIT #batchSize#
-    	</isNotEmpty>
-	</delete>
-	
-	<!-- 주소록 삭제 -->
-	<select id="AddrDAO.getAddrCount" parameterClass="addrVO" resultClass="int">
-		
-		select
-			count(*)
-		FROM 
-			MJ_ADDR
-		WHERE
-			MBER_ID = #mberId#
-		<isNotEmpty property="addrGrpId">
-		AND
-			ADDR_GRP_ID = #addrGrpId#
-		</isNotEmpty>
-	</select>
-	
-	<!-- 주소록 삭제 By Admin -->
-	<delete id="AddrDAO.deleteAddrByAdmin" parameterClass="addrVO">
-		DELETE FROM 
-			MJ_ADDR
-		WHERE ADDR_ID = #addrId#
-	</delete>	
-	
-	<!-- 주소록 삭제 By Admin By Grpid -->
-	<delete id="AddrDAO.deleteAddrByAdminByGrpid" parameterClass="addrVO">
-		DELETE FROM 
-			MJ_ADDR
-		WHERE ADDR_GRP_ID = #addrGrpId#
-	</delete>	
-		
-	<!-- 주소록 기본 그룹 조회 (자주보내는번호, 그룹미지정)-->
-	<select id="AddrDAO.selectAddrBasicGrpList" parameterClass="addrVO" resultClass="addrVO">
-		SELECT
-			COUNT(1) OVER() 		AS totCnt
-			,A.ADDR_ID				AS addrId
-			,A.ADDR_GRP_ID			AS addrGrpId
-			,A.MBER_ID				AS mberId
-			,A.ADDR_NM				AS addrNm
-			,A.ADDR_PHONE_NO		AS addrPhoneNo
-			,A.ADDR_INFO1			AS addrInfo1
-			,A.ADDR_INFO2			AS addrInfo2
-			,A.ADDR_INFO3			AS addrInfo3
-			,A.ADDR_INFO4			AS addrInfo4
-			,A.ADDR_COMMENT			AS addrComment
-			,A.FRST_REGIST_PNTTM	AS frstRegistPnttm
-			,A.FRST_REGISTER_ID		AS frstRegisterId
-			,A.LAST_UPDT_PNTTM		AS lastUpdtPnttm
-			,A.LAST_UPDUSR_ID		AS lastUpdusrId
-			,A.DELETE_YN			AS deleteYn
-			,A.BOOKMARK				AS bookmark
-			,B.ADDR_GRP_NM			AS addrGrpNm
-		FROM
-			MJ_ADDR A
-		LEFT OUTER JOIN 
-			MJ_ADDR_GRP B
-		ON 
-			A.ADDR_GRP_ID = B.ADDR_GRP_ID
-		WHERE
-			A.MBER_ID = #mberId#
-		<isEqual property="type" compareValue="bookmark">
-		AND
-			A.BOOKMARK = 'Y'
-		</isEqual>
-		<isEqual property="type" compareValue="noGrp">
-			AND 
-				A.ADDR_GRP_ID = '0' 
-				
-			AND 
-				A.BOOKMARK = 'N'
-		</isEqual>
-		ORDER BY 1=1
-		<isNotEmpty property="searchSortCnd">
-			,$searchSortCnd$
-		</isNotEmpty>
-		<isNotEmpty property="searchSortOrd">
-		 	$searchSortOrd$
-		</isNotEmpty>
-	</select>
-	
-	
-	<update id="AddrDAO.insertCopyAddr" parameterClass="addrVO">
-		INSERT INTO MJ_ADDR (
-			ADDR_GRP_ID
-			,MBER_ID
-			,ADDR_NM
-			,ADDR_PHONE_NO
-			,ADDR_INFO1
-			,ADDR_INFO2
-			,ADDR_INFO3
-			,ADDR_INFO4
-			,ADDR_COMMENT
-			,FRST_REGIST_PNTTM
-			,FRST_REGISTER_ID
-			<isNotEmpty property="bookmark">
-				,BOOKMARK
-			</isNotEmpty>
-			)
-		SELECT	
-			#addrGrpId#	AS ADDR_GRP_ID
-			,MBER_ID
-			,ADDR_NM
-			,ADDR_PHONE_NO
-			,ADDR_INFO1
-			,ADDR_INFO2
-			,ADDR_INFO3
-			,ADDR_INFO4
-			,ADDR_COMMENT
-			,NOW()
-			,MBER_ID
-			<isNotEmpty property="bookmark">
-				,#bookmark#
-			</isNotEmpty>
-		FROM	MJ_ADDR
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_ID = #addrId#
-	</update>
-	
-	<!-- /주소록 등록 갯수 및 정보 불러오기/ -->
-	<select id="AddrDAO.selectAddrTotCntInfByUserId" parameterClass="addrVO" resultClass="egovMap">
-	
-		SELECT COUNT(MBER_ID) OVER() AS totCnt,
-		       ADDR_ID AS addrId,
-		       ADDR_GRP_ID AS addrGrpId,
-		       MBER_ID AS mberId,
-		       ADDR_NM AS addrnm,
-		       ADDR_PHONE_NO AS addrPhoneNo,
-		       ADDR_INFO1 AS addrInfo1,
-		       ADDR_INFO2 AS addrInfo2,
-		       ADDR_INFO3 AS addrInfo3,
-		       ADDR_INFO4 AS addrInfo4,
-		       ADDR_COMMENT AS addrComment,
-		       BOOKMARK AS bookmark,
-		       FRST_REGIST_PNTTM AS frstRegistPnttm,
-		       LAST_UPDT_PNTTM AS lastUpdtPnttm
-		FROM   MJ_ADDR a
-		WHERE  a.MBER_ID = #mberId#
-		AND    delete_yn = 'N'
-	
-	</select>
-	
-	<insert id="AddrDAO.insertAddrList" parameterClass="java.util.List">
-		/* AddrDAO.insertAddrList */
-		INSERT INTO MJ_ADDR
-		(
-			MBER_ID,
-			ADDR_GRP_ID,
-			ADDR_NM,
-			ADDR_PHONE_NO,
-			ADDR_INFO1,
-			ADDR_INFO2,
-			ADDR_INFO3,
-			ADDR_INFO4,
-			DELETE_YN,
-			BOOKMARK,
-			ADDR_COMMENT,
-			FRST_REGISTER_ID
-		)
-		<iterate prepend="VALUES" conjunction=",">
-		(
-	          #[].mberId#,
-	          #[].addrGrpId#,
-	          #[].addrNm#,
-	          #[].addrPhoneNo#,
-	          #[].addrInfo1#,
-	          #[].addrInfo2#,
-	          #[].addrInfo3#,
-	          #[].addrInfo4#,
-	          'N',
-	          #[].bookmark#,
-	          #[].addrComment#,
-	          #[].frstRegisterId#
-          )
-		</iterate>
-	
-	</insert>
-	
-	<!-- 주소록 그룹명 중복확인 -->
-	<select id="AddrDAO.selectDuplAddrCnt" parameterClass="addrVO" resultClass="int">
-		SELECT 
-			COUNT(1) usedCnt
-		FROM 
-			MJ_ADDR
-		WHERE 
-			ADDR_GRP_ID = #addrGrpId#
-			AND MBER_ID = #mberId#
-			AND ADDR_PHONE_NO = #addrPhoneNo#
-			<isNotEmpty property="bookmark">
-		 		<isEqual property="bookmark" compareValue="Y">
-		 		AND IFNULL(BOOKMARK, 'N') = 'Y'
-		 		</isEqual>			
-			</isNotEmpty>			
-			<isEmpty property="bookmark">
-		 		AND IFNULL(BOOKMARK, 'N') = 'N'			
-			</isEmpty>						 
-	</select>
-
-		
-	<!-- 주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도) -->
-	<select id="AddrDAO.selectPhoneNumInAddrGroup" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 
-			ADDR_PHONE_NO AS addrPhoneNo
-		FROM 
-			MJ_ADDR
-		WHERE 
-			ADDR_GRP_ID = #addrGrpId#
-			AND MBER_ID = #mberId#
-			AND BOOKMARK = #bookmark#
-	</select>
-	
-	<update id="AddrDAO.insertCopyAddrs" parameterClass="addrVO">
-		INSERT INTO MJ_ADDR (
-			ADDR_GRP_ID
-			,MBER_ID
-			,ADDR_NM
-			,ADDR_PHONE_NO
-			,ADDR_INFO1
-			,ADDR_INFO2
-			,ADDR_INFO3
-			,ADDR_INFO4
-			,ADDR_COMMENT
-			,FRST_REGIST_PNTTM
-			,FRST_REGISTER_ID
-			)
-		SELECT	
-			#addrGrpId#	AS ADDR_GRP_ID
-			,MBER_ID
-			,ADDR_NM
-			,ADDR_PHONE_NO
-			,ADDR_INFO1
-			,ADDR_INFO2
-			,ADDR_INFO3
-			,ADDR_INFO4
-			,ADDR_COMMENT
-			,NOW()
-			,MBER_ID
-		FROM	MJ_ADDR
-		WHERE
-			MBER_ID = #mberId#
-		AND
-			ADDR_GRP_ID IN
-		<iterate  property="copyAddrs" open="(" close=")" conjunction=",">
-			#copyAddrs[]#
-		</iterate>
-	</update>
-	
-	<!-- 문자페이지로 전송할 데이터만 추려오기 -->
-	<select id="AddrDAO.selectAddrDataList" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 
-			COUNT(1) OVER() 			AS totCnt
-			,A.ADDR_ID					AS addrId
-			,A.ADDR_GRP_ID				AS addrGrpId
-			,A.MBER_ID					AS mberId
-			,A.ADDR_NM					AS addrNm
-			,A.ADDR_PHONE_NO			AS addrPhoneNo
-			,A.ADDR_INFO1				AS addrInfo1
-			,A.ADDR_INFO2				AS addrInfo2
-			,A.ADDR_INFO3				AS addrInfo3
-			,A.ADDR_INFO4				AS addrInfo4
-			,A.ADDR_COMMENT				AS addrComment
-			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
-			,A.FRST_REGISTER_ID			AS frstRegisterId
-			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
-			,A.LAST_UPDUSR_ID			AS lastUpdusrId
-			,A.DELETE_YN				AS deleteYn
-			,A.BOOKMARK					AS bookmark
-		FROM 
-			MJ_ADDR A
-		WHERE 
-			A.MBER_ID = #mberId#
-		<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
-			#addrIdList[]#
-		</iterate>
-		ORDER BY A.ADDR_NM ASC
-	</select>
-
-	<!-- 주소록 그룹별 중복 연락처 삭제 -->
-	<delete id="AddrDAO.deleteAddrDupliList" parameterClass="addrVO">
-		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
-			SELECT 			
-				M.ADDR_ID
-			FROM (			
-				SELECT 
-					A.ADDR_ID
-					, A.ADDR_PHONE_NO
-					, COUNT(0) AS DUPLI_CNT						
-				FROM MJ_ADDR A
-				LEFT OUTER JOIN MJ_ADDR_GRP B
-					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-				WHERE A.MBER_ID = #mberId#
-				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-				AND A.DELETE_YN = 'N'					
-				GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
-			) M
-			WHERE M.DUPLI_CNT > 1		
-		)
-	</delete>
-	
-	<!-- 주소록 그룹별 중복 연락처 리스트 불러오기 -->
-	<select id="AddrDAO.selectAddrDupliList" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 			
-			M.ADDR_GRP_NM AS addrGrpNm
-			, COUNT(0) AS dupliCnt
-		FROM (					
-			SELECT 
-				A.ADDR_ID
-				,CASE
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N'
-					THEN '그룹미지정'
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
-					THEN '자주보내는 번호'
-					ELSE B.ADDR_GRP_NM 
-				END ADDR_GRP_NM
-				,A.ADDR_PHONE_NO
-				,COUNT(0) AS DUPLI_CNT
-			FROM MJ_ADDR A
-			LEFT OUTER JOIN MJ_ADDR_GRP B
-				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-			WHERE A.MBER_ID = #mberId#
-			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-			AND A.DELETE_YN = 'N'
-			GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
-		) M
-		WHERE M.DUPLI_CNT > 1
-		GROUP BY M.ADDR_GRP_NM
-	</select>	
-	
-	<!-- 주소록 그룹별 중복 연락처 삭제 -->
-	<delete id="AddrDAO.deleteAddrDupliListByGrpnm" parameterClass="addrVO">
-		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
-			SELECT 			
-				M.ADDR_ID
-			FROM (					
-				SELECT 
-					A.ADDR_ID
-					,COUNT(0) AS DUPLI_CNT				
-				FROM MJ_ADDR A
-				LEFT OUTER JOIN MJ_ADDR_GRP B
-					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-					WHERE A.MBER_ID = #mberId#
-					AND A.ADDR_GRP_ID = #addrGrpId#
-					AND A.BOOKMARK = #bookmark#							
-				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-				AND A.DELETE_YN = 'N'
-				GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
-			) M
-			WHERE M.DUPLI_CNT > 1		
-		)	
-
-	</delete>
-		
-	<!-- 주소록 그룹별 중복 연락처 리스트 불러오기 -->
-	<select id="AddrDAO.selectAddrDupliListByGrpnm" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 			
-			M.ADDR_GRP_NM AS addrGrpNm
-			, COUNT(0) AS dupliCnt
-		FROM (					
-			SELECT 
-				A.ADDR_ID
-				,CASE
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N'
-					THEN '그룹미지정'
-					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
-					THEN '자주보내는 번호'
-					ELSE B.ADDR_GRP_NM 
-				END ADDR_GRP_NM
-				,A.ADDR_PHONE_NO
-				,COUNT(0) AS DUPLI_CNT				
-			FROM MJ_ADDR A
-			LEFT OUTER JOIN MJ_ADDR_GRP B
-				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-			WHERE A.MBER_ID = #mberId#
-			AND A.ADDR_GRP_ID = #addrGrpId#
-			AND A.BOOKMARK = #bookmark#		
-			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-			AND A.DELETE_YN = 'N'
-			GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
-		) M
-		WHERE M.DUPLI_CNT > 1
-		GROUP BY M.ADDR_GRP_NM	
-	</select>
-	
-	
-	<!-- 주소록 전체 중복 연락처 중 한개만 남기고 삭제 -->
-	<delete id="AddrDAO.deleteAddrDupliListByAll" parameterClass="addrVO">
-		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
-			SELECT 		
-				M.ADDR_ID	
-			FROM (			
-				SELECT 
-					A.ADDR_ID
-					, A.ADDR_PHONE_NO
-					, COUNT(0) AS DUPLI_CNT				
-				FROM MJ_ADDR A
-				LEFT OUTER JOIN MJ_ADDR_GRP B
-					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-				WHERE A.MBER_ID = #mberId#
-				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-				AND A.DELETE_YN = 'N'
-				GROUP BY A.ADDR_PHONE_NO
-				ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
-			) M
-			WHERE M.DUPLI_CNT > 1
-		)
-
-	</delete>	
-	
-	<!-- 주소록 전체 중복 연락처 수 -->
-	<select id="AddrDAO.selectAddrDupliListByAllCnt" parameterClass="addrVO" resultClass="int">
-		SELECT 		
-			COUNT(0) AS totCnt
-		FROM (			
-			SELECT 
-				A.ADDR_ID
-				, A.ADDR_PHONE_NO
-				, COUNT(0) AS DUPLI_CNT				
-			FROM MJ_ADDR A
-			LEFT OUTER JOIN MJ_ADDR_GRP B
-				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-			WHERE A.MBER_ID = #mberId#
-			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-			AND A.DELETE_YN = 'N'
-			GROUP BY A.ADDR_PHONE_NO
-			ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
-		) M
-		WHERE M.DUPLI_CNT > 1
-	</select>	
-	
-	<!-- 주소록 전체 중복 연락처 목록 -->
-	<select id="AddrDAO.selectAddrDupliListByAll" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 
-			COUNT(1) OVER() 			AS totCnt
-			, A2.ADDR_ID				AS addrId
-			, A2.ADDR_NM				AS addrNm
-			, A2.ADDR_GRP_ID			AS addrGrpId
-			,CASE
-				WHEN A2.ADDR_GRP_ID = 0 AND A2.BOOKMARK = 'N'
-				THEN '그룹미지정'
-				WHEN A2.ADDR_GRP_ID = 0 AND A2.BOOKMARK = 'Y'
-				THEN '자주보내는 번호'
-				ELSE B2.ADDR_GRP_NM
-			END addrGrpNm		
-			, A2.ADDR_PHONE_NO	AS addrPhoneNo
-		FROM MJ_ADDR A2
-		LEFT OUTER JOIN MJ_ADDR_GRP B2
-			ON A2.ADDR_GRP_ID = B2.ADDR_GRP_ID
-		WHERE A2.MBER_ID = #mberId#
-		AND A2.ADDR_PHONE_NO IN 
-		(
-			SELECT 		
-				M.ADDR_PHONE_NO
-			FROM (			
-				SELECT 
-					A.ADDR_ID
-					, A.ADDR_PHONE_NO
-					, COUNT(0) AS DUPLI_CNT				
-				FROM MJ_ADDR A
-				LEFT OUTER JOIN MJ_ADDR_GRP B
-					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
-				WHERE A.MBER_ID = #mberId#
-				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
-				AND A.DELETE_YN = 'N'
-				GROUP BY A.ADDR_PHONE_NO
-				ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
-			) M
-			WHERE M.DUPLI_CNT > 1
-		)
-		ORDER BY A2.ADDR_PHONE_NO ASC, ADDR_GRP_NM ASC	
-		LIMIT #recordCountPerPage# OFFSET #firstIndex#
-	</select>
-	
-	<!-- TEMP 주소록 중복 연락처 목록 -->
-	<select id="AddrDAO.selectTempAddrDupliList" parameterClass="addrVO" resultClass="addrVO">
-		SELECT 
-			ADDR_NM AS addrNm
-			, ADDR_PHONE_NO AS addrPhoneNo 
-		FROM TEMP_MJ_ADDR
-		WHERE MBER_ID = #mberId#
-			AND ADDR_GRP_ID = #addrGrpId# 
-			AND BOOKMARK = #bookmark# 
-			AND ADDR_PHONE_NO IN 
-			(
-				SELECT ADDR_PHONE_NO FROM MJ_ADDR 
-				WHERE MBER_ID = #mberId#
-					AND ADDR_GRP_ID = #addrGrpId# 
-					AND BOOKMARK = #bookmark# 
-			)
-		ORDER BY ADDR_PHONE_NO ASC
-	</select>
-		
-	<!-- TEMP 주소록 삭제 -->
-	<delete id="AddrDAO.deleteTempAddr" parameterClass="addrVO">
-		DELETE FROM TEMP_MJ_ADDR WHERE MBER_ID = #mberId#
-	</delete>
-	
-	<!-- TEMP 주소록 대량등록 -->
-	<insert id="AddrDAO.insertTempAddrList" parameterClass="java.util.List">
-		
-		INSERT INTO TEMP_MJ_ADDR
-		(
-			MBER_ID,
-			ADDR_GRP_ID,
-			ADDR_NM,
-			ADDR_PHONE_NO,
-			ADDR_INFO1,
-			ADDR_INFO2,
-			ADDR_INFO3,
-			ADDR_INFO4,
-			DELETE_YN,
-			BOOKMARK,
-			ADDR_COMMENT,
-			FRST_REGISTER_ID
-		)VALUES
-		<iterate conjunction=",">
-	       	(
-	          #[].mberId#,
-	          #[].addrGrpId#,
-	          #[].addrNm#,
-	          #[].addrPhoneNo#,
-	          #[].addrInfo1#,
-	          #[].addrInfo2#,
-	          #[].addrInfo3#,
-	          #[].addrInfo4#,
-	          'N',
-	          #[].bookmark#,
-	          #[].addrComment#,
-	          #[].frstRegisterId#
-	       )
-	    </iterate>
-	</insert>	
-	
-	<!-- 주소록 대량등록 By Temp 주소록 -->
-	<insert id="AddrDAO.insertAddrByTempAddr" parameterClass="addrVO">
-		INSERT INTO MJ_ADDR (
-			ADDR_GRP_ID
-			, MBER_ID
-			, ADDR_NM
-			, ADDR_PHONE_NO
-			, ADDR_INFO1
-			, ADDR_INFO2
-			, ADDR_INFO3
-			, ADDR_INFO4
-			, ADDR_COMMENT
-			, FRST_REGIST_PNTTM
-			, FRST_REGISTER_ID
-			, LAST_UPDT_PNTTM
-			, LAST_UPDUSR_ID
-			, DELETE_YN
-			, BOOKMARK
-			, RECV_STATUS
-		) 
-		SELECT 
-			ADDR_GRP_ID
-			, MBER_ID
-			, ADDR_NM
-			, ADDR_PHONE_NO
-			, ADDR_INFO1
-			, ADDR_INFO2
-			, ADDR_INFO3
-			, ADDR_INFO4
-			, ADDR_COMMENT
-			, FRST_REGIST_PNTTM
-			, FRST_REGISTER_ID
-			, LAST_UPDT_PNTTM
-			, LAST_UPDUSR_ID
-			, DELETE_YN
-			, BOOKMARK
-			, RECV_STATUS
-		FROM TEMP_MJ_ADDR
-		WHERE MBER_ID = #mberId#
-			AND ADDR_GRP_ID = #addrGrpId# 
-			AND BOOKMARK = #bookmark# 
-			AND ADDR_PHONE_NO NOT IN 
-			(
-				SELECT ADDR_PHONE_NO FROM MJ_ADDR 
-				WHERE MBER_ID = #mberId#
-					AND ADDR_GRP_ID = #addrGrpId# 
-					AND BOOKMARK = #bookmark# 
-			)  
-	</insert>	
-		
-	
-</sqlMap>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
+<sqlMap namespace="Addr">
+	<typeAlias  alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
+	<typeAlias  alias="addrVO" type="itn.let.mjo.addr.service.AddrVO"/>
+	<typeAlias  alias="addrTransHistVO" type="itn.let.mjo.addr.service.AddrTransHistVO"/>
+
+	<!-- 주소록 목록 조회 -->
+	<select id="AddrDAO.selectAddrList" parameterClass="addrVO" resultClass="addrVO">
+		/*	AddrDAO.selectAddrList	*/
+		SELECT		
+		/*
+			1 			AS totCnt
+			*/			
+			COUNT(1) OVER() 			AS totCnt
+			,A.ADDR_ID					AS addrId
+			,A.ADDR_GRP_ID				AS addrGrpId
+			,A.MBER_ID					AS mberId
+			,A.ADDR_NM					AS addrNm
+			,A.ADDR_PHONE_NO			AS addrPhoneNo
+			,A.ADDR_INFO1				AS addrInfo1
+			,A.ADDR_INFO2				AS addrInfo2
+			,A.ADDR_INFO3				AS addrInfo3
+			,A.ADDR_INFO4				AS addrInfo4
+			,A.ADDR_COMMENT				AS addrComment
+			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
+			,A.FRST_REGISTER_ID			AS frstRegisterId
+			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
+			,A.LAST_UPDUSR_ID			AS lastUpdusrId
+			,A.DELETE_YN				AS deleteYn
+			,A.BOOKMARK					AS bookmark
+			,CASE
+				WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N' 
+				THEN '그룹미지정'
+				WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
+				THEN '자주보내는 번호'
+				ELSE B.ADDR_GRP_NM
+			END AS addrGrpNm
+		FROM
+			MJ_ADDR A
+		LEFT OUTER JOIN 
+			MJ_ADDR_GRP B
+		ON 
+			A.ADDR_GRP_ID = B.ADDR_GRP_ID
+			AND B.DELETE_YN ='N'
+		LEFT OUTER JOIN 
+			MJ_ADDR_TRANS_HIST C
+		ON
+			B.ADDR_GRP_ID = C.ADDR_GRP_ID
+		WHERE 1=1
+		<isNotEmpty property="mberId">
+			AND A.MBER_ID = #mberId#
+		</isNotEmpty>		
+		
+		AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
+		
+		<isNotEmpty property="addrIdList">
+			<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
+				#addrIdList[]#
+			</iterate>
+		</isNotEmpty>		
+		
+		AND      A.ADDR_GRP_ID in (
+							        select addr_grp_id
+									from mj_addr_grp	
+									where 1=1
+										<isNotEmpty property="mberId">
+											AND MBER_ID = #mberId#
+										</isNotEmpty>
+										<isNotEmpty property="searchAddrGrpId">
+											AND ADDR_GRP_ID = #searchAddrGrpId#
+										</isNotEmpty>			
+		        )				
+
+		<isNotEmpty property="searchKeyword">
+	 		<isEqual property="searchCondition" compareValue="">
+	 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				)
+	 		</isEqual>
+			<isEqual property="searchCondition" compareValue="1">
+				AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+			<isEqual property="searchCondition" compareValue="2">
+				AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+			<isEqual property="searchCondition" compareValue="3">
+				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>			
+	 	</isNotEmpty>
+	 	<isNotEmpty property="searchAddrGrpId">
+	 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
+	 		AND A.BOOKMARK = 'Y'
+	 		</isEqual>
+	 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
+	 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
+	 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
+	 			</isEqual>
+	 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
+	 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
+ 				</isNotEqual>
+	 		</isNotEqual>
+	 	</isNotEmpty>
+		<isEqual property="startKeyword" compareValue="1">
+			AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="2">
+			AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="3">
+			AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="4">
+			AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="5">
+			AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="6">
+			AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="7">
+			AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="8">
+			AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="9">
+			AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="10">
+			AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="11">
+			AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="12">
+			AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="13">
+			AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="14">
+			AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="a">
+	 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="0">
+			AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
+		</isEqual>
+		ORDER BY 1=1
+		<isNotEmpty property="searchSortCnd">
+			,$searchSortCnd$
+		</isNotEmpty>
+		<isNotEmpty property="searchSortOrd">
+		 	$searchSortOrd$
+		</isNotEmpty>
+		LIMIT #recordCountPerPage# OFFSET #firstIndex#
+	</select>
+		
+	<!-- 주소록 목록 조회 -->
+	<select id="AddrDAO.selectAddrListCount" parameterClass="addrVO" resultClass="int">
+		/*	AddrDAO.selectAddrListCount	*/
+		SELECT			
+			COUNT(1)  			AS totCnt			
+		FROM
+			MJ_ADDR A
+		LEFT OUTER JOIN 
+			MJ_ADDR_TRANS_HIST C
+		ON
+			A.ADDR_GRP_ID = C.ADDR_GRP_ID
+		WHERE 1=1
+		<isNotEmpty property="mberId">
+			AND A.MBER_ID = #mberId#
+		</isNotEmpty>		
+		
+		AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
+		
+		<isNotEmpty property="addrIdList">
+			<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
+				#addrIdList[]#
+			</iterate>
+		</isNotEmpty>		
+		
+		AND      A.ADDR_GRP_ID in (
+							        select addr_grp_id
+									from mj_addr_grp	
+									where 1=1
+										<isNotEmpty property="mberId">
+											AND MBER_ID = #mberId#
+										</isNotEmpty>
+										<isNotEmpty property="addrGrpId">
+											AND ADDR_GRP_ID = #addrGrpId#
+										</isNotEmpty>			
+		        )		
+		
+		<isNotEmpty property="searchKeyword">
+	 		<isEqual property="searchCondition" compareValue="">
+	 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+	 				)
+	 		</isEqual>
+			<isEqual property="searchCondition" compareValue="1">
+				AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+			<isEqual property="searchCondition" compareValue="2">
+				AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>
+			<isEqual property="searchCondition" compareValue="3">
+				AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+			</isEqual>			
+	 	</isNotEmpty>
+	 	<isNotEmpty property="searchAddrGrpId">
+	 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
+	 		AND A.BOOKMARK = 'Y'
+	 		</isEqual>
+	 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
+	 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
+	 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
+	 			</isEqual>
+	 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
+	 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
+ 				</isNotEqual>
+	 		</isNotEqual>
+	 	</isNotEmpty>
+		<isEqual property="startKeyword" compareValue="1">
+			AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="2">
+			AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="3">
+			AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="4">
+			AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="5">
+			AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="6">
+			AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="7">
+			AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="8">
+			AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="9">
+			AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="10">
+			AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="11">
+			AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="12">
+			AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="13">
+			AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="14">
+			AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="a">
+	 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
+		</isEqual>
+		<isEqual property="startKeyword" compareValue="0">
+			AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
+		</isEqual>		
+	</select>	
+	
+	<!-- 주소록 목록 조회(속도개선) -->
+	<select id="AddrDAO.selectAddrNewList" parameterClass="addrVO" resultClass="addrVO">
+		SELECT
+		  	(
+				SELECT COUNT(0) FROM mj_addr A
+				LEFT OUTER JOIN 
+					MJ_ADDR_GRP B
+				ON 
+					A.ADDR_GRP_ID = B.ADDR_GRP_ID
+				LEFT OUTER JOIN 
+					MJ_ADDR_TRANS_HIST C
+				ON
+					B.ADDR_GRP_ID = C.ADDR_GRP_ID
+				WHERE 1=1
+				AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
+				<isNotEmpty property="mberId">
+					AND A.MBER_ID = #mberId#
+				</isNotEmpty>		
+				<isNotEmpty property="searchStartDate">
+					<![CDATA[ 
+						AND A.FRST_REGIST_PNTTM >= DATE_FORMAT(#searchStartDate#, '%Y-%m-%d')
+					]]>
+				</isNotEmpty>
+				<isNotEmpty property="searchEndDate">
+					<![CDATA[ 
+						AND A.FRST_REGIST_PNTTM <= DATE_ADD(DATE_FORMAT(#searchEndDate#, '%Y-%m-%d')  , INTERVAL 1 DAY) 
+					]]>
+				</isNotEmpty>				
+				<isNotEmpty property="addrIdList">
+					<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
+						#addrIdList[]#
+					</iterate>
+				</isNotEmpty>		
+				<isNotEmpty property="addrGrpId">
+					AND A.ADDR_GRP_ID = #addrGrpId#
+				</isNotEmpty>
+				<isNotEmpty property="searchKeyword">
+			 		<isEqual property="searchCondition" compareValue="">
+			 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+			 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+			 				)
+			 		</isEqual>
+					<isEqual property="searchCondition" compareValue="1">
+						AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+					</isEqual>
+					<isEqual property="searchCondition" compareValue="2">
+						AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+					</isEqual>
+					<isEqual property="searchCondition" compareValue="3">
+						AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+					</isEqual>			
+			 	</isNotEmpty>
+			 	<isNotEmpty property="searchAddrGrpId">
+			 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
+			 		AND A.BOOKMARK = 'Y'
+			 		</isEqual>
+			 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
+			 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
+			 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
+			 			</isEqual>
+			 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
+			 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
+		 				</isNotEqual>
+			 		</isNotEqual>
+			 	</isNotEmpty>
+				<isEqual property="startKeyword" compareValue="1">
+					AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="2">
+					AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="3">
+					AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="4">
+					AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="5">
+					AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="6">
+					AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="7">
+					AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="8">
+					AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="9">
+					AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="10">
+					AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="11">
+					AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="12">
+					AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="13">
+					AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="14">
+					AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="a">
+			 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
+				</isEqual>
+				<isEqual property="startKeyword" compareValue="0">
+					AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
+				</isEqual>
+		  	) totCnt 
+			,M.addrId
+			,M.addrGrpId
+			,M.mberId
+			,M.addrNm
+			,M.addrPhoneNo
+			,M.addrInfo1
+			,M.addrInfo2
+			,M.addrInfo3
+			,M.addrInfo4
+			,M.addrComment
+			,M.frstRegistPnttm
+			,M.frstRegisterId
+			,M.lastUpdtPnttm
+			,M.lastUpdusrId
+			,M.deleteYn
+			,M.bookmark
+			,M.addrGrpNm
+	  	FROM (
+			SELECT
+				A.ADDR_ID					AS addrId
+				,A.ADDR_GRP_ID				AS addrGrpId
+				,A.MBER_ID					AS mberId
+				,A.ADDR_NM					AS addrNm
+				,A.ADDR_PHONE_NO			AS addrPhoneNo
+				,A.ADDR_INFO1				AS addrInfo1
+				,A.ADDR_INFO2				AS addrInfo2
+				,A.ADDR_INFO3				AS addrInfo3
+				,A.ADDR_INFO4				AS addrInfo4
+				,A.ADDR_COMMENT				AS addrComment
+				,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
+				,A.FRST_REGISTER_ID			AS frstRegisterId
+				,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
+				,A.LAST_UPDUSR_ID			AS lastUpdusrId
+				,A.DELETE_YN				AS deleteYn
+				,A.BOOKMARK					AS bookmark
+				,CASE
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N' 
+					THEN '그룹미지정'
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
+					THEN '자주보내는 번호'
+					ELSE B.ADDR_GRP_NM
+				END AS addrGrpNm
+			FROM
+				MJ_ADDR A
+			LEFT OUTER JOIN 
+				MJ_ADDR_GRP B
+			ON 
+				A.ADDR_GRP_ID = B.ADDR_GRP_ID
+			LEFT OUTER JOIN 
+				MJ_ADDR_TRANS_HIST C
+			ON
+				B.ADDR_GRP_ID = C.ADDR_GRP_ID
+			WHERE 1=1
+			AND	(C.RECV_STATUS = 'Y' OR C.RECV_STATUS IS NULL)
+			<isNotEmpty property="mberId">
+				AND A.MBER_ID = #mberId#
+			</isNotEmpty>		
+			<isNotEmpty prepend="AND" property="searchStartDate">
+				<![CDATA[ 
+					A.FRST_REGIST_PNTTM >= DATE_FORMAT(#searchStartDate#, '%Y-%m-%d')
+				]]>
+			</isNotEmpty>
+			<isNotEmpty prepend="AND" property="searchEndDate">
+				<![CDATA[ 
+					DATE_FORMAT(A.FRST_REGIST_PNTTM, '%Y-%m-%d') <= DATE_ADD(DATE_FORMAT(#searchEndDate#, '%Y-%m-%d')  , INTERVAL 1 DAY) 
+				]]>
+			</isNotEmpty>							
+			<isNotEmpty property="addrIdList">
+				<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
+					#addrIdList[]#
+				</iterate>
+			</isNotEmpty>		
+			<isNotEmpty property="addrGrpId">
+				AND A.ADDR_GRP_ID = #addrGrpId#
+			</isNotEmpty>
+			<isNotEmpty property="searchKeyword">
+		 		<isEqual property="searchCondition" compareValue="">
+		 			AND ( A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+		 				OR A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+		 				)
+		 		</isEqual>
+				<isEqual property="searchCondition" compareValue="1">
+					AND A.ADDR_PHONE_NO LIKE CONCAT ('%', #searchKeyword#,'%')
+				</isEqual>
+				<isEqual property="searchCondition" compareValue="2">
+					AND A.ADDR_NM LIKE CONCAT ('%', #searchKeyword#,'%')
+				</isEqual>
+				<isEqual property="searchCondition" compareValue="3">
+					AND A.MBER_ID LIKE CONCAT ('%', #searchKeyword#,'%')
+				</isEqual>			
+		 	</isNotEmpty>
+		 	<isNotEmpty property="searchAddrGrpId">
+		 		<isEqual property="searchAddrGrpId" compareValue="bookmark">
+		 		AND A.BOOKMARK = 'Y'
+		 		</isEqual>
+		 		<isNotEqual property="searchAddrGrpId" compareValue="bookmark">
+		 			<isEqual property="searchAddrGrpId" compareValue="noGrp">
+		 				AND A.ADDR_GRP_ID = '0' AND A.BOOKMARK = 'N'
+		 			</isEqual>
+		 			<isNotEqual property="searchAddrGrpId" compareValue="noGrp">
+		 				AND A.ADDR_GRP_ID = #searchAddrGrpId#
+	 				</isNotEqual>
+		 		</isNotEqual>
+		 	</isNotEmpty>
+			<isEqual property="startKeyword" compareValue="1">
+				AND (A.ADDR_NM RLIKE '^(ㄱ|ㄲ)' OR (A.ADDR_NM <![CDATA[>=]]> '가' AND A.ADDR_NM <![CDATA[<]]> '나')) 
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="2">
+				AND (A.ADDR_NM RLIKE '^(ㄴ)' OR (A.ADDR_NM <![CDATA[>=]]> '나' AND A.ADDR_NM <![CDATA[<]]> '다')) 
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="3">
+				AND (A.ADDR_NM RLIKE '^(ㄷ|ㄸ)' OR (A.ADDR_NM <![CDATA[>=]]> '다' AND A.ADDR_NM <![CDATA[<]]> '라'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="4">
+				AND (A.ADDR_NM RLIKE '^(ㄹ)' OR (A.ADDR_NM <![CDATA[>=]]> '라' AND A.ADDR_NM <![CDATA[<]]> '마'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="5">
+				AND (A.ADDR_NM RLIKE '^(ㅁ)' OR (A.ADDR_NM <![CDATA[>=]]> '마' AND A.ADDR_NM <![CDATA[<]]> '바'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="6">
+				AND (A.ADDR_NM RLIKE '^(ㅂ|ㅃ)' OR (A.ADDR_NM <![CDATA[>=]]> '바' AND A.ADDR_NM <![CDATA[<]]> '사')) 
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="7">
+				AND (A.ADDR_NM RLIKE '^(ㅅ|ㅆ)' OR (A.ADDR_NM <![CDATA[>=]]> '사' AND A.ADDR_NM <![CDATA[<]]> '아'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="8">
+				AND (A.ADDR_NM RLIKE '^(ㅇ)' OR (A.ADDR_NM <![CDATA[>=]]> '아' AND A.ADDR_NM <![CDATA[<]]> '자'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="9">
+				AND (A.ADDR_NM RLIKE '^(ㅈ|ㅉ)' OR (A.ADDR_NM <![CDATA[>=]]> '자' AND A.ADDR_NM <![CDATA[<]]> '차'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="10">
+				AND (A.ADDR_NM RLIKE '^(ㅊ)' OR (A.ADDR_NM <![CDATA[>=]]> '차' AND A.ADDR_NM <![CDATA[<]]> '카'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="11">
+				AND (A.ADDR_NM RLIKE '^(ㅋ)' OR (A.ADDR_NM <![CDATA[>=]]> '카' AND A.ADDR_NM <![CDATA[<]]> '타'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="12">
+				AND (A.ADDR_NM RLIKE '^(ㅌ)' OR (A.ADDR_NM <![CDATA[>=]]> '타' AND A.ADDR_NM <![CDATA[<]]> '파'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="13">
+				AND (A.ADDR_NM RLIKE '^(ㅍ)' OR (A.ADDR_NM <![CDATA[>=]]> '파' AND A.ADDR_NM <![CDATA[<]]> '하'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="14">
+				AND (A.ADDR_NM RLIKE '^(ㅎ)' OR (A.ADDR_NM <![CDATA[>=]]> '하' AND A.ADDR_NM <![CDATA[<=]]> '힣'))
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="a">
+		 		AND (A.ADDR_NM <![CDATA[>=]]> 'a' AND A.ADDR_NM <![CDATA[<=]]> 'z')
+			</isEqual>
+			<isEqual property="startKeyword" compareValue="0">
+				AND (A.ADDR_NM <![CDATA[>=]]> '0' AND A.ADDR_NM <![CDATA[<=]]>'9')
+			</isEqual>
+
+			ORDER BY 1=1
+			<isNotEmpty property="searchSortCnd">
+				,$searchSortCnd$
+			</isNotEmpty>
+			<isNotEmpty property="searchSortOrd">
+			 	$searchSortOrd$
+			</isNotEmpty>
+			LIMIT #recordCountPerPage# OFFSET #firstIndex#
+		) M	
+	</select>	
+	
+	<!-- 회원별 주소록 전체 갯수 조회 -->
+	<select id="AddrDAO.selectAddrTotalCount" parameterClass="addrVO" resultClass="int">
+		SELECT
+			COUNT(A.ADDR_ID)	AS	totCnt 
+		FROM
+			MJ_ADDR A
+		WHERE
+			A.MBER_ID = #mberId#
+			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+			AND A.DELETE_YN = 'N'
+	</select>
+	
+	<!-- 주소록 상세  조회 -->
+	<select id="AddrDAO.selectAddrDetail" parameterClass="addrVO" resultClass="addrVO">
+		SELECT
+			A.ADDR_ID					AS addrId
+			,A.ADDR_GRP_ID				AS addrGrpId
+			,A.MBER_ID					AS mberId
+			,A.ADDR_NM					AS addrNm
+			,A.ADDR_PHONE_NO			AS addrPhoneNo
+			,A.ADDR_INFO1				AS addrInfo1
+			,A.ADDR_INFO2				AS addrInfo2
+			,A.ADDR_INFO3				AS addrInfo3
+			,A.ADDR_INFO4				AS addrInfo4
+			,A.ADDR_COMMENT				AS addrComment
+			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
+			,A.FRST_REGISTER_ID			AS frstRegisterId
+			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
+			,A.LAST_UPDUSR_ID			AS lastUpdusrId
+			,A.DELETE_YN				AS deleteYn
+			,A.BOOKMARK					AS bookmark
+			,b.ADDR_GRP_NM				AS addrGrpNm
+		FROM 
+			MJ_ADDR a
+		LEFT OUTER JOIN 
+			MJ_ADDR_GRP b
+		ON 
+			a.ADDR_GRP_ID = b.ADDR_GRP_ID
+		WHERE 
+			a.ADDR_ID = #addrId#
+	</select>
+	
+	
+	<!-- 주소록 등록 -->
+	<insert id="AddrDAO.insertAddr" parameterClass="addrVO">
+		INSERT INTO MJ_ADDR (
+			<isNotEmpty property="addrGrpId">
+			ADDR_GRP_ID,
+			</isNotEmpty>
+			MBER_ID
+			,ADDR_NM
+			,ADDR_PHONE_NO
+			,ADDR_INFO1
+			,ADDR_INFO2
+			,ADDR_INFO3
+			,ADDR_INFO4
+			,ADDR_COMMENT
+			,FRST_REGIST_PNTTM
+			,FRST_REGISTER_ID
+			<isNotEmpty property="bookmark">
+			,BOOKMARK
+			</isNotEmpty>
+			<isNotEmpty property="recvStatus">
+			,RECV_STATUS
+			</isNotEmpty>
+		)VALUES(
+			<isNotEmpty property="addrGrpId">
+			#addrGrpId#,
+			</isNotEmpty>
+			#mberId#
+			,#addrNm#
+			,#addrPhoneNo#
+			,#addrInfo1#
+			,#addrInfo2#
+			,#addrInfo3#
+			,#addrInfo4#
+			,#addrComment#
+			,NOW()
+			,#frstRegisterId#
+			<isNotEmpty property="bookmark">
+			,#bookmark#
+			</isNotEmpty>
+			<isNotEmpty property="recvStatus">
+			,#recvStatus#
+			</isNotEmpty>
+		)
+	</insert>
+	
+	
+	<!-- 주소록 수정 -->
+	<update id="AddrDAO.updateAddr" parameterClass="addrVO">
+		UPDATE
+			MJ_ADDR
+		SET
+		<isNotEmpty property="addrGrpId">
+			ADDR_GRP_ID			= #addrGrpId#,
+		</isNotEmpty>
+		<isNotEmpty property="addrPhoneNo">
+			ADDR_PHONE_NO		= #addrPhoneNo#,
+		</isNotEmpty>
+		ADDR_NM				= #addrNm#,
+		ADDR_INFO1			= #addrInfo1#,
+		ADDR_INFO2			= #addrInfo2#,
+		ADDR_INFO3			= #addrInfo3#,
+		ADDR_INFO4			= #addrInfo4#,
+		<isNotEmpty property="addrComment">
+			ADDR_COMMENT		= #addrComment#,
+		</isNotEmpty>			
+		<isNotEmpty property="bookmark">
+			BOOKMARK			= #bookmark#,
+		</isNotEmpty>			
+			LAST_UPDT_PNTTM	= NOW(),
+			LAST_UPDUSR_ID		= #lastUpdusrId#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_ID = #addrId#
+	</update>
+	
+	<!-- 주소록 그룹 수정 -->
+	<update id="AddrDAO.updateAddrGrp" parameterClass="addrVO">
+		UPDATE
+			MJ_ADDR
+		SET
+			ADDR_GRP_ID			= #addrGrpId#,
+			BOOKMARK			= #bookmark#,
+			LAST_UPDT_PNTTM	= NOW(),
+			LAST_UPDUSR_ID		= #lastUpdusrId#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_ID = #addrId#
+	</update>	
+	
+	<!-- 주소록 메모 수정 -->
+	<update id="AddrDAO.updateMemoAddr" parameterClass="addrVO">
+		UPDATE
+			MJ_ADDR
+		SET
+			ADDR_COMMENT		= #addrComment#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_ID = #addrId#
+	</update>	
+	
+	
+	
+	<!-- 주소록 수정 By Admin -->
+	<update id="AddrDAO.updateAddrByAdmin" parameterClass="addrVO">
+		UPDATE
+			MJ_ADDR
+		SET
+		<isNotEmpty property="addrGrpId">
+			ADDR_GRP_ID			= #addrGrpId#,
+		</isNotEmpty>
+		<isNotEmpty property="addrNm">
+			ADDR_NM				= #addrNm#,
+		</isNotEmpty>
+		<isNotEmpty property="addrPhoneNo">
+			ADDR_PHONE_NO		= #addrPhoneNo#,
+		</isNotEmpty>
+		<isNotEmpty property="addrInfo1">
+			ADDR_INFO1			= #addrInfo1#,
+		</isNotEmpty>
+		<isNotEmpty property="addrInfo2">
+			ADDR_INFO2			= #addrInfo2#,
+		</isNotEmpty>
+		<isNotEmpty property="addrInfo3">
+			ADDR_INFO3			= #addrInfo3#,
+		</isNotEmpty>
+		<isNotEmpty property="addrInfo4">
+			ADDR_INFO4			= #addrInfo4#,
+		</isNotEmpty>
+		<isNotEmpty property="addrComment">
+			ADDR_COMMENT		= #addrComment#,
+		</isNotEmpty>			
+		<isNotEmpty property="bookmark">
+			BOOKMARK			= #bookmark#,
+		</isNotEmpty>			
+			LAST_UPDT_PNTTM	= NOW(),
+			LAST_UPDUSR_ID		= #lastUpdusrId#
+		WHERE
+			ADDR_ID = #addrId#
+	</update>	
+	
+	
+	<!-- 주소록 합치기, 이동 -->
+	<update id="AddrDAO.updateAddrsGrp" parameterClass="addrVO">
+		UPDATE
+			MJ_ADDR
+		SET
+			ADDR_GRP_ID			= #addrGrpId#,
+			LAST_UPDT_PNTTM		= NOW(),
+			LAST_UPDUSR_ID		= #lastUpdusrId#
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_GRP_ID 
+		IN
+		<iterate  property="mergeGrps" open="(" close=")" conjunction=",">
+			#mergeGrps[]#
+		</iterate>
+		
+	</update>
+	
+
+	
+	<!-- 주소록 삭제 -->
+	<delete id="AddrDAO.deleteAddr" parameterClass="addrVO">
+		DELETE FROM 
+			MJ_ADDR
+		WHERE
+			MBER_ID = #mberId#
+		<isEqual property="grpDelete" compareValue="Y">
+		AND
+			ADDR_GRP_ID = #addrGrpId#
+		</isEqual>
+		<isNotEqual property="grpDelete" compareValue="Y">
+		AND
+			ADDR_ID = #addrId#
+		</isNotEqual>
+<!-- 		<isNotEmpty property="batchSize"> -->
+<!--    			LIMIT #batchSize# -->
+<!--     	</isNotEmpty> -->
+	</delete>
+	
+	
+	<!-- 주소록 삭제 -->
+	<select id="AddrDAO.getAddrCount" parameterClass="addrVO" resultClass="int">
+		
+		select
+			count(*)
+		FROM 
+			MJ_ADDR
+		WHERE
+			MBER_ID = #mberId#
+		<isNotEmpty property="addrGrpId">
+		AND
+			ADDR_GRP_ID = #addrGrpId#
+		</isNotEmpty>
+	</select>
+	
+	<!-- 주소록 삭제 By Admin -->
+	<delete id="AddrDAO.deleteAddrByAdmin" parameterClass="addrVO">
+		DELETE FROM 
+			MJ_ADDR
+		WHERE ADDR_ID = #addrId#
+	</delete>	
+	
+	<!-- 주소록 삭제 By Admin By Grpid -->
+	<delete id="AddrDAO.deleteAddrByAdminByGrpid" parameterClass="addrVO">
+		DELETE FROM 
+			MJ_ADDR
+		WHERE ADDR_GRP_ID = #addrGrpId#
+	</delete>	
+		
+	<!-- 주소록 기본 그룹 조회 (자주보내는번호, 그룹미지정)-->
+	<select id="AddrDAO.selectAddrBasicGrpList" parameterClass="addrVO" resultClass="addrVO">
+		/* AddrDAO.selectAddrBasicGrpList */
+		SELECT
+			COUNT(1) OVER() 		AS totCnt
+			,A.ADDR_ID				AS addrId
+			,A.ADDR_GRP_ID			AS addrGrpId
+			,A.MBER_ID				AS mberId
+			,A.ADDR_NM				AS addrNm
+			,A.ADDR_PHONE_NO		AS addrPhoneNo
+			,A.ADDR_INFO1			AS addrInfo1
+			,A.ADDR_INFO2			AS addrInfo2
+			,A.ADDR_INFO3			AS addrInfo3
+			,A.ADDR_INFO4			AS addrInfo4
+			,A.ADDR_COMMENT			AS addrComment
+			,A.FRST_REGIST_PNTTM	AS frstRegistPnttm
+			,A.FRST_REGISTER_ID		AS frstRegisterId
+			,A.LAST_UPDT_PNTTM		AS lastUpdtPnttm
+			,A.LAST_UPDUSR_ID		AS lastUpdusrId
+			,A.DELETE_YN			AS deleteYn
+			,A.BOOKMARK				AS bookmark
+			,B.ADDR_GRP_NM			AS addrGrpNm
+		FROM
+			MJ_ADDR A
+		LEFT OUTER JOIN 
+			MJ_ADDR_GRP B
+		ON 
+			A.ADDR_GRP_ID = B.ADDR_GRP_ID
+		WHERE
+			A.MBER_ID = #mberId#
+		<isEqual property="type" compareValue="bookmark">
+		AND
+			A.BOOKMARK = 'Y'
+		</isEqual>
+		<isEqual property="type" compareValue="noGrp">
+			AND 
+				A.ADDR_GRP_ID = '0' 
+				
+			AND 
+				A.BOOKMARK = 'N'
+		</isEqual>
+		ORDER BY 1=1
+		<isNotEmpty property="searchSortCnd">
+			,$searchSortCnd$
+		</isNotEmpty>
+		<isNotEmpty property="searchSortOrd">
+		 	$searchSortOrd$
+		</isNotEmpty>
+	</select>
+	
+	
+	<update id="AddrDAO.insertCopyAddr" parameterClass="addrVO">
+		INSERT INTO MJ_ADDR (
+			ADDR_GRP_ID
+			,MBER_ID
+			,ADDR_NM
+			,ADDR_PHONE_NO
+			,ADDR_INFO1
+			,ADDR_INFO2
+			,ADDR_INFO3
+			,ADDR_INFO4
+			,ADDR_COMMENT
+			,FRST_REGIST_PNTTM
+			,FRST_REGISTER_ID
+			<isNotEmpty property="bookmark">
+				,BOOKMARK
+			</isNotEmpty>
+			)
+		SELECT	
+			#addrGrpId#	AS ADDR_GRP_ID
+			,MBER_ID
+			,ADDR_NM
+			,ADDR_PHONE_NO
+			,ADDR_INFO1
+			,ADDR_INFO2
+			,ADDR_INFO3
+			,ADDR_INFO4
+			,ADDR_COMMENT
+			,NOW()
+			,MBER_ID
+			<isNotEmpty property="bookmark">
+				,#bookmark#
+			</isNotEmpty>
+		FROM	MJ_ADDR
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_ID = #addrId#
+	</update>
+	
+	<!-- /주소록 등록 갯수 및 정보 불러오기/ -->
+	<select id="AddrDAO.selectAddrTotCntInfByUserId" parameterClass="addrVO" resultClass="egovMap">
+	
+		SELECT COUNT(MBER_ID) OVER() AS totCnt,
+		       ADDR_ID AS addrId,
+		       ADDR_GRP_ID AS addrGrpId,
+		       MBER_ID AS mberId,
+		       ADDR_NM AS addrnm,
+		       ADDR_PHONE_NO AS addrPhoneNo,
+		       ADDR_INFO1 AS addrInfo1,
+		       ADDR_INFO2 AS addrInfo2,
+		       ADDR_INFO3 AS addrInfo3,
+		       ADDR_INFO4 AS addrInfo4,
+		       ADDR_COMMENT AS addrComment,
+		       BOOKMARK AS bookmark,
+		       FRST_REGIST_PNTTM AS frstRegistPnttm,
+		       LAST_UPDT_PNTTM AS lastUpdtPnttm
+		FROM   MJ_ADDR a
+		WHERE  a.MBER_ID = #mberId#
+		AND    delete_yn = 'N'
+	
+	</select>
+	
+	<insert id="AddrDAO.insertAddrList" parameterClass="java.util.List">
+		/* AddrDAO.insertAddrList */
+		INSERT INTO MJ_ADDR
+		(
+			MBER_ID,
+			ADDR_GRP_ID,
+			ADDR_NM,
+			ADDR_PHONE_NO,
+			ADDR_INFO1,
+			ADDR_INFO2,
+			ADDR_INFO3,
+			ADDR_INFO4,
+			DELETE_YN,
+			BOOKMARK,
+			ADDR_COMMENT,
+			FRST_REGISTER_ID
+		)
+		<iterate prepend="VALUES" conjunction=",">
+		(
+	          #[].mberId#,
+	          #[].addrGrpId#,
+	          #[].addrNm#,
+	          #[].addrPhoneNo#,
+	          #[].addrInfo1#,
+	          #[].addrInfo2#,
+	          #[].addrInfo3#,
+	          #[].addrInfo4#,
+	          'N',
+	          #[].bookmark#,
+	          #[].addrComment#,
+	          #[].frstRegisterId#
+          )
+		</iterate>
+	
+	</insert>
+	
+	<!-- 주소록 그룹명 중복확인 -->
+	<select id="AddrDAO.selectDuplAddrCnt" parameterClass="addrVO" resultClass="int">
+		SELECT 
+			COUNT(1) usedCnt
+		FROM 
+			MJ_ADDR
+		WHERE 
+			ADDR_GRP_ID = #addrGrpId#
+			AND MBER_ID = #mberId#
+			AND ADDR_PHONE_NO = #addrPhoneNo#
+			<isNotEmpty property="bookmark">
+		 		<isEqual property="bookmark" compareValue="Y">
+		 		AND IFNULL(BOOKMARK, 'N') = 'Y'
+		 		</isEqual>			
+			</isNotEmpty>			
+			<isEmpty property="bookmark">
+		 		AND IFNULL(BOOKMARK, 'N') = 'N'			
+			</isEmpty>						 
+	</select>
+
+		
+	<!-- 주소록 한 그룹에 속한 주소록의 전화번호 조회(중복체크용도) -->
+	<select id="AddrDAO.selectPhoneNumInAddrGroup" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 
+			ADDR_PHONE_NO AS addrPhoneNo
+		FROM 
+			MJ_ADDR
+		WHERE 
+			ADDR_GRP_ID = #addrGrpId#
+			AND MBER_ID = #mberId#
+			AND BOOKMARK = #bookmark#
+	</select>
+	
+	<update id="AddrDAO.insertCopyAddrs" parameterClass="addrVO">
+		INSERT INTO MJ_ADDR (
+			ADDR_GRP_ID
+			,MBER_ID
+			,ADDR_NM
+			,ADDR_PHONE_NO
+			,ADDR_INFO1
+			,ADDR_INFO2
+			,ADDR_INFO3
+			,ADDR_INFO4
+			,ADDR_COMMENT
+			,FRST_REGIST_PNTTM
+			,FRST_REGISTER_ID
+			)
+		SELECT	
+			#addrGrpId#	AS ADDR_GRP_ID
+			,MBER_ID
+			,ADDR_NM
+			,ADDR_PHONE_NO
+			,ADDR_INFO1
+			,ADDR_INFO2
+			,ADDR_INFO3
+			,ADDR_INFO4
+			,ADDR_COMMENT
+			,NOW()
+			,MBER_ID
+		FROM	MJ_ADDR
+		WHERE
+			MBER_ID = #mberId#
+		AND
+			ADDR_GRP_ID IN
+		<iterate  property="copyAddrs" open="(" close=")" conjunction=",">
+			#copyAddrs[]#
+		</iterate>
+	</update>
+	
+	<!-- 문자페이지로 전송할 데이터만 추려오기 -->
+	<select id="AddrDAO.selectAddrDataList" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 
+			COUNT(1) OVER() 			AS totCnt
+			,A.ADDR_ID					AS addrId
+			,A.ADDR_GRP_ID				AS addrGrpId
+			,A.MBER_ID					AS mberId
+			,A.ADDR_NM					AS addrNm
+			,A.ADDR_PHONE_NO			AS addrPhoneNo
+			,A.ADDR_INFO1				AS addrInfo1
+			,A.ADDR_INFO2				AS addrInfo2
+			,A.ADDR_INFO3				AS addrInfo3
+			,A.ADDR_INFO4				AS addrInfo4
+			,A.ADDR_COMMENT				AS addrComment
+			,A.FRST_REGIST_PNTTM		AS frstRegistPnttm
+			,A.FRST_REGISTER_ID			AS frstRegisterId
+			,A.LAST_UPDT_PNTTM			AS lastUpdtPnttm
+			,A.LAST_UPDUSR_ID			AS lastUpdusrId
+			,A.DELETE_YN				AS deleteYn
+			,A.BOOKMARK					AS bookmark
+		FROM 
+			MJ_ADDR A
+		WHERE 
+			A.MBER_ID = #mberId#
+		<iterate prepend="AND A.ADDR_ID IN " open="(" close=")" conjunction="," property="addrIdList">
+			#addrIdList[]#
+		</iterate>
+		ORDER BY A.ADDR_NM ASC
+	</select>
+
+	<!-- 주소록 그룹별 중복 연락처 삭제 -->
+	<delete id="AddrDAO.deleteAddrDupliList" parameterClass="addrVO">
+		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
+			SELECT 			
+				M.ADDR_ID
+			FROM (			
+				SELECT 
+					A.ADDR_ID
+					, A.ADDR_PHONE_NO
+					, COUNT(0) AS DUPLI_CNT						
+				FROM MJ_ADDR A
+				LEFT OUTER JOIN MJ_ADDR_GRP B
+					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+				WHERE A.MBER_ID = #mberId#
+				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+				AND A.DELETE_YN = 'N'					
+				GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
+			) M
+			WHERE M.DUPLI_CNT > 1		
+		)
+	</delete>
+	
+	<!-- 주소록 그룹별 중복 연락처 리스트 불러오기 -->
+	<select id="AddrDAO.selectAddrDupliList" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 			
+			M.ADDR_GRP_NM AS addrGrpNm
+			, COUNT(0) AS dupliCnt
+		FROM (					
+			SELECT 
+				A.ADDR_ID
+				,CASE
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N'
+					THEN '그룹미지정'
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
+					THEN '자주보내는 번호'
+					ELSE B.ADDR_GRP_NM 
+				END ADDR_GRP_NM
+				,A.ADDR_PHONE_NO
+				,COUNT(0) AS DUPLI_CNT
+			FROM MJ_ADDR A
+			LEFT OUTER JOIN MJ_ADDR_GRP B
+				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+			WHERE A.MBER_ID = #mberId#
+			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+			AND A.DELETE_YN = 'N'
+			GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
+		) M
+		WHERE M.DUPLI_CNT > 1
+		GROUP BY M.ADDR_GRP_NM
+	</select>	
+	
+	<!-- 주소록 그룹별 중복 연락처 삭제 -->
+	<delete id="AddrDAO.deleteAddrDupliListByGrpnm" parameterClass="addrVO">
+		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
+			SELECT 			
+				M.ADDR_ID
+			FROM (					
+				SELECT 
+					A.ADDR_ID
+					,COUNT(0) AS DUPLI_CNT				
+				FROM MJ_ADDR A
+				LEFT OUTER JOIN MJ_ADDR_GRP B
+					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+					WHERE A.MBER_ID = #mberId#
+					AND A.ADDR_GRP_ID = #addrGrpId#
+					AND A.BOOKMARK = #bookmark#							
+				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+				AND A.DELETE_YN = 'N'
+				GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
+			) M
+			WHERE M.DUPLI_CNT > 1		
+		)	
+
+	</delete>
+		
+	<!-- 주소록 그룹별 중복 연락처 리스트 불러오기 -->
+	<select id="AddrDAO.selectAddrDupliListByGrpnm" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 			
+			M.ADDR_GRP_NM AS addrGrpNm
+			, COUNT(0) AS dupliCnt
+		FROM (					
+			SELECT 
+				A.ADDR_ID
+				,CASE
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'N'
+					THEN '그룹미지정'
+					WHEN A.ADDR_GRP_ID = 0 AND A.BOOKMARK = 'Y'
+					THEN '자주보내는 번호'
+					ELSE B.ADDR_GRP_NM 
+				END ADDR_GRP_NM
+				,A.ADDR_PHONE_NO
+				,COUNT(0) AS DUPLI_CNT				
+			FROM MJ_ADDR A
+			LEFT OUTER JOIN MJ_ADDR_GRP B
+				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+			WHERE A.MBER_ID = #mberId#
+			AND A.ADDR_GRP_ID = #addrGrpId#
+			AND A.BOOKMARK = #bookmark#		
+			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+			AND A.DELETE_YN = 'N'
+			GROUP BY A.ADDR_GRP_ID, A.BOOKMARK, A.ADDR_PHONE_NO
+		) M
+		WHERE M.DUPLI_CNT > 1
+		GROUP BY M.ADDR_GRP_NM	
+	</select>
+	
+	
+	<!-- 주소록 전체 중복 연락처 중 한개만 남기고 삭제 -->
+	<delete id="AddrDAO.deleteAddrDupliListByAll" parameterClass="addrVO">
+		DELETE FROM MJ_ADDR WHERE ADDR_ID IN (
+			SELECT 		
+				M.ADDR_ID	
+			FROM (			
+				SELECT 
+					A.ADDR_ID
+					, A.ADDR_PHONE_NO
+					, COUNT(0) AS DUPLI_CNT				
+				FROM MJ_ADDR A
+				LEFT OUTER JOIN MJ_ADDR_GRP B
+					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+				WHERE A.MBER_ID = #mberId#
+				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+				AND A.DELETE_YN = 'N'
+				GROUP BY A.ADDR_PHONE_NO
+				ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
+			) M
+			WHERE M.DUPLI_CNT > 1
+		)
+
+	</delete>	
+	
+	<!-- 주소록 전체 중복 연락처 수 -->
+	<select id="AddrDAO.selectAddrDupliListByAllCnt" parameterClass="addrVO" resultClass="int">
+		SELECT 		
+			COUNT(0) AS totCnt
+		FROM (			
+			SELECT 
+				A.ADDR_ID
+				, A.ADDR_PHONE_NO
+				, COUNT(0) AS DUPLI_CNT				
+			FROM MJ_ADDR A
+			LEFT OUTER JOIN MJ_ADDR_GRP B
+				ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+			WHERE A.MBER_ID = #mberId#
+			AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+			AND A.DELETE_YN = 'N'
+			GROUP BY A.ADDR_PHONE_NO
+			ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
+		) M
+		WHERE M.DUPLI_CNT > 1
+	</select>	
+	
+	<!-- 주소록 전체 중복 연락처 목록 -->
+	<select id="AddrDAO.selectAddrDupliListByAll" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 
+			COUNT(1) OVER() 			AS totCnt
+			, A2.ADDR_ID				AS addrId
+			, A2.ADDR_NM				AS addrNm
+			, A2.ADDR_GRP_ID			AS addrGrpId
+			,CASE
+				WHEN A2.ADDR_GRP_ID = 0 AND A2.BOOKMARK = 'N'
+				THEN '그룹미지정'
+				WHEN A2.ADDR_GRP_ID = 0 AND A2.BOOKMARK = 'Y'
+				THEN '자주보내는 번호'
+				ELSE B2.ADDR_GRP_NM
+			END addrGrpNm		
+			, A2.ADDR_PHONE_NO	AS addrPhoneNo
+		FROM MJ_ADDR A2
+		LEFT OUTER JOIN MJ_ADDR_GRP B2
+			ON A2.ADDR_GRP_ID = B2.ADDR_GRP_ID
+		WHERE A2.MBER_ID = #mberId#
+		AND A2.ADDR_PHONE_NO IN 
+		(
+			SELECT 		
+				M.ADDR_PHONE_NO
+			FROM (			
+				SELECT 
+					A.ADDR_ID
+					, A.ADDR_PHONE_NO
+					, COUNT(0) AS DUPLI_CNT				
+				FROM MJ_ADDR A
+				LEFT OUTER JOIN MJ_ADDR_GRP B
+					ON A.ADDR_GRP_ID = B.ADDR_GRP_ID
+				WHERE A.MBER_ID = #mberId#
+				AND	(A.RECV_STATUS = 'Y' OR A.RECV_STATUS = 'S' OR A.RECV_STATUS IS NULL)
+				AND A.DELETE_YN = 'N'
+				GROUP BY A.ADDR_PHONE_NO
+				ORDER BY A.ADDR_PHONE_NO ASC, B.ADDR_GRP_ID ASC
+			) M
+			WHERE M.DUPLI_CNT > 1
+		)
+		ORDER BY A2.ADDR_PHONE_NO ASC, ADDR_GRP_NM ASC	
+		LIMIT #recordCountPerPage# OFFSET #firstIndex#
+	</select>
+	
+	<!-- TEMP 주소록 중복 연락처 목록 -->
+	<select id="AddrDAO.selectTempAddrDupliList" parameterClass="addrVO" resultClass="addrVO">
+		SELECT 
+			ADDR_NM AS addrNm
+			, ADDR_PHONE_NO AS addrPhoneNo 
+		FROM TEMP_MJ_ADDR
+		WHERE MBER_ID = #mberId#
+			AND ADDR_GRP_ID = #addrGrpId# 
+			AND BOOKMARK = #bookmark# 
+			AND ADDR_PHONE_NO IN 
+			(
+				SELECT ADDR_PHONE_NO FROM MJ_ADDR 
+				WHERE MBER_ID = #mberId#
+					AND ADDR_GRP_ID = #addrGrpId# 
+					AND BOOKMARK = #bookmark# 
+			)
+		ORDER BY ADDR_PHONE_NO ASC
+	</select>
+		
+	<!-- TEMP 주소록 삭제 -->
+	<delete id="AddrDAO.deleteTempAddr" parameterClass="addrVO">
+		DELETE FROM TEMP_MJ_ADDR WHERE MBER_ID = #mberId#
+	</delete>
+	
+	<!-- TEMP 주소록 대량등록 -->
+	<insert id="AddrDAO.insertTempAddrList" parameterClass="java.util.List">
+		
+		INSERT INTO TEMP_MJ_ADDR
+		(
+			MBER_ID,
+			ADDR_GRP_ID,
+			ADDR_NM,
+			ADDR_PHONE_NO,
+			ADDR_INFO1,
+			ADDR_INFO2,
+			ADDR_INFO3,
+			ADDR_INFO4,
+			DELETE_YN,
+			BOOKMARK,
+			ADDR_COMMENT,
+			FRST_REGISTER_ID
+		)VALUES
+		<iterate conjunction=",">
+	       	(
+	          #[].mberId#,
+	          #[].addrGrpId#,
+	          #[].addrNm#,
+	          #[].addrPhoneNo#,
+	          #[].addrInfo1#,
+	          #[].addrInfo2#,
+	          #[].addrInfo3#,
+	          #[].addrInfo4#,
+	          'N',
+	          #[].bookmark#,
+	          #[].addrComment#,
+	          #[].frstRegisterId#
+	       )
+	    </iterate>
+	</insert>	
+	
+	<!-- 주소록 대량등록 By Temp 주소록 -->
+	<insert id="AddrDAO.insertAddrByTempAddr" parameterClass="addrVO">
+		INSERT INTO MJ_ADDR (
+			ADDR_GRP_ID
+			, MBER_ID
+			, ADDR_NM
+			, ADDR_PHONE_NO
+			, ADDR_INFO1
+			, ADDR_INFO2
+			, ADDR_INFO3
+			, ADDR_INFO4
+			, ADDR_COMMENT
+			, FRST_REGIST_PNTTM
+			, FRST_REGISTER_ID
+			, LAST_UPDT_PNTTM
+			, LAST_UPDUSR_ID
+			, DELETE_YN
+			, BOOKMARK
+			, RECV_STATUS
+		) 
+		SELECT 
+			ADDR_GRP_ID
+			, MBER_ID
+			, ADDR_NM
+			, ADDR_PHONE_NO
+			, ADDR_INFO1
+			, ADDR_INFO2
+			, ADDR_INFO3
+			, ADDR_INFO4
+			, ADDR_COMMENT
+			, FRST_REGIST_PNTTM
+			, FRST_REGISTER_ID
+			, LAST_UPDT_PNTTM
+			, LAST_UPDUSR_ID
+			, DELETE_YN
+			, BOOKMARK
+			, RECV_STATUS
+		FROM TEMP_MJ_ADDR
+		WHERE MBER_ID = #mberId#
+			AND ADDR_GRP_ID = #addrGrpId# 
+			AND BOOKMARK = #bookmark# 
+			AND ADDR_PHONE_NO NOT IN 
+			(
+				SELECT ADDR_PHONE_NO FROM MJ_ADDR 
+				WHERE MBER_ID = #mberId#
+					AND ADDR_GRP_ID = #addrGrpId# 
+					AND BOOKMARK = #bookmark# 
+			)  
+	</insert>	
+		
+	
+</sqlMap>
src/main/webapp/WEB-INF/jsp/web/addr/AddrGroupListAjax.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/AddrGroupListAjax.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/AddrGroupListAjax.jsp
@@ -1,905 +1,905 @@
-<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
-<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
-
-<script src="/publish/js/content.js"></script>
-<script type="text/javascript">
-var successHtml="";
-
-$(document).ready(function(){
-	
-	// 주소록 그룹 카운트(전체)
-	getAddrGroupTotCnt();
-
-	//주소록 그룹 카운트(그룹미지정)
-	getAddrGroupNogrpCnt();
-
-	//주소록 그룹 카운트(자주보내는 번호)
-	getAddrGroupBookmarkCnt();
-	
-}); 
-
-// 주소록 그룹 카운트(전체)
-function getAddrGroupTotCnt() {
-	$.ajax({
-        type: "POST",
-        url: "/web/addr/selectAddrGroupTotCntAjax.do",
-        data: {},
-        dataType:'json',
-        async: true,
-        success: function (data) {
-        	console.log('data : ', data);
-			if (data.isSuccess) {
-				$("#addrTotCnt").html(numberWithCommas(data.addrTotCnt));
-			} 
-			else {
-				//alert("Msg : " + data.msg);
-			}
-		},
-        error: function (e) { 
-        	//alert("ERROR : " + JSON.stringify(e)); 
-        }
-    });				
-}	
-
-//주소록 그룹 카운트(그룹미지정)
-function getAddrGroupNogrpCnt() {
-	$.ajax({
-        type: "POST",
-        url: "/web/addr/selectAddrGroupNogrpCntAjax.do",
-        data: {},
-        dataType:'json',
-        async: true,
-        success: function (data) {
-			if (data.isSuccess) {
-				$("#nogrpCnt").html(data.nogrpCnt);
-			} 
-			else {
-				//alert("Msg : " + data.msg);
-			}
-		},
-        error: function (e) { 
-        	//alert("ERROR : " + JSON.stringify(e)); 
-        }
-    });				
-}	
-
-//주소록 그룹 카운트(자주보내는 번호)
-function getAddrGroupBookmarkCnt() {
-	$.ajax({
-        type: "POST",
-        url: "/web/addr/selectAddrGroupBookmarkCntAjax.do",
-        data: {},
-        dataType:'json',
-        async: true,
-        success: function (data) {
-			if (data.isSuccess) {
-				$("#bookmarkCnt").html(data.bookmarkCnt);
-			} 
-			else {
-				//alert("Msg : " + data.msg);
-			}
-		},
-        error: function (e) { 
-        	//alert("ERROR : " + JSON.stringify(e)); 
-        }
-    });				
-}	
-
-// 주소록 그룹 리스트 띄우기
-function listAddrGroupAjax() {
-	var form = document.searchAddrGrpForm;
-	
-	var sendData = $(document.searchAddrGrpForm).serializeArray() ;
-	$("#adr1_left").load("/web/addr/selectAddrGroupListAjax.do", sendData ,function(response, status, xhr){});
-}
-
-// 주소록 그룹 지우기(선택삭제)
-function deleteAddrGroup() {
-	var form = document.addrGrpListForm;
-	if($("input:checkbox[name='grpCheck']").is(":checked")==true){	
-		if(confirm("그룹을 삭제하시겠습니까?\n그룹 내 전체 주소가 삭제되며 복구할 수 없습니다.")) {
-			fn_loadAddActive();
-			var data = new FormData(form);
-			$.ajax({
-				cache : false,
-				url : "<c:url value='/web/addr/deleteAddrGroupAjax.do'/>", 
-				type : 'POST', 
-				data : data,
-				dataType:'json',
-				processData: false,
-				contentType: false,
-				success : function(returnData, status){
-					if(status == "success") {
-						if("fail"==returnData.result){
-							alert(returnData.message);
-							return;
-						}
-						alert("삭제되었습니다.");
-						listAddrGrp();
-						addrGroupLoadAjax();
-						addrLoadAjax();
-						
-					}else{ alert("ERROR!");return;} 
-				},
-				error: function (e) { alert("삭제  실패하였습니다."); console.log("ERROR : ", e); },
-                beforeSend: function(xmlHttpRequest) {
-                },
-                complete: function(xhr, textStatus) {
-            		fn_loadRemoveActive();
-                }
-			});
-		}
-	}else{
-		alert("선택된 그룹이  없습니다.");
-		return false;
-	}
-	
-}
-
-// 체크박스 전체선택
-function fnCheckAll() {
-	var checkField = document.addrGrpListForm.grpCheck;
-	if(document.addrGrpListForm.groupAll.checked) {
-		if(checkField) {
-			if(checkField.length > 1) {
-				for(var i=0; i < checkField.length; i++) {
-					checkField[i].checked = true;
-				}
-			} else {
-				checkField.checked = true;
-			}
-		}
-	} else {
-		if(checkField) {
-			if(checkField.length > 1) {
-				for(var j=0; j < checkField.length; j++) {
-					checkField[j].checked = false;
-				}
-			} else {
-				checkField.checked = false;
-			}
-		}
-	}
-	tooltipCheck();
-}
-
-// 주소록 그룹 합치기 레이어 열기 
-function mergeAddrGroupLayer(){
-	var form = document.addrGrpListForm;
-	var html = "";
-	var index = 0;
- 	if($("input:checkbox[name='grpCheck']:checked").length > 1){
-		
-		$('input:checkbox[name="grpCheck"]').each(function() {
-			if(this.checked){
-				var id = $(this).attr('id');
-				var idNum = id.substr(5);
-				
-				html += '<li name="liIndex" class="'+$("#addrGrpId"+idNum).val()+'" id="liIndex'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
-				index++;
-			}
-		});
-		//초기화
-		$('#selGroup').empty();
-		$('#selGroup').append(html);
-		
-	}else{
-		alert("합치실 그룹을 두개 이상 선택하세요.");
-		return false;
-	}
-		
-}
-
-
-//주소록 그룹 복사 레이어 열기 
-function copyAddrGroupLayer(){
-	var form = document.addrGrpListForm;
-	var html = "";
-	var index = 0;
- 	if($("input:checkbox[name='grpCheck']:checked").length > 0){
-		
-		$('input:checkbox[name="grpCheck"]').each(function() {
-			if(this.checked){
-				var id = $(this).attr('id');
-				var idNum = id.substr(5);
-				
-				html += '<li name="li4Index" class="'+$("#addrGrpId"+idNum).val()+'" id="li4Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi4('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
-				index++;
-			}
-		});
-		//초기화
-		$('#selGroup3').empty();
-		$('#selGroup3').append(html);
-		
-	}else{
-		alert("복사할 그룹을 한 개 이상 선택하세요.");
-		return false;
-	}
-		
-}
-
-
-// 합치기 레이어 내 리스트 세팅
-function removeLi(idx) {
-	var liCount = $("li[name=liIndex]").length;
-	if(liCount > 2) {
-		$("#liIndex"+idx).remove();
-	} else {
-		alert("합치실 그룹은 최소 두 개 이상이어야 합니다");
-	}
-}
-
-//내보내기 레이어 내 리스트 세팅
-function removeLi2(idx) {
-	var liCount = $("li[name=li2Index]").length;
-	if(liCount > 1) {
-		$("#li2Index"+idx).remove();
-		$(".checkGroupCount").text(liCount-1);
-	} else {
-		alert("내보낼 그룹은 최소 한 개 이상이어야 합니다");
-	}
-	
-}
-
-//합치기 레이어 내 리스트 세팅
-function removeLi4(idx) {
-	var liCount = $("li[name=li4Index]").length;
-	if(liCount > 1) {
-		$("#li4Index"+idx).remove();
-	} else {
-		alert("복사할 그룹은 한 개 이상이어야 합니다");
-	}
-}
-
-
-// 툴팁 삭제/삽입
-function tooltipCheck() {
-	//그룹합치기 툴팁
-	if($("input:checkbox[name='grpCheck']:checked").length < 2){
-		$(".group_join").removeAttr("data-tooltip");
-	} else {
-		$(".group_join").attr("data-tooltip", "adr_popup02");
-	}
-	
-	//그룹복사 툴팁
-	if($("input:checkbox[name='grpCheck']:checked").length < 1){
-		$(".group_copy").removeAttr("data-tooltip");
-	} else {
-		$(".group_copy").attr("data-tooltip", "adr_popup05");
-	}
-}
-
-
-// 그룹 합치기 
-function addrGroupMerge() {
-	var form = document.addrGrpMergeForm;
-	var mergeGrpArray = new Array();
-	
-	$('.selGroup li').each(function (idx, item) {
-		mergeGrpArray.push($(item).attr('class'));
-	});
-	form.mergeGrps.value = mergeGrpArray;
-	
-	// 그룹을 합치겠습니까?\n기존의 그룹 및 중복연락처는 삭제됩니다.
-	if(confirm("그룹을 합치겠습니까?\n기존의 그룹은 삭제됩니다.")) {
-		var data = new FormData(form);
-		$.ajax({
-			cache : false,
-			url : "<c:url value='/web/addr/mergeAddrGroupAjax.do'/>", 
-			type : 'POST', 
-			data : data,
-			dataType:'json',
-			processData: false,
-			contentType: false,
-			success : function(returnData, status){
-				if(status == "success") {
-					if("fail"==returnData.result){
-						alert(returnData.message);
-						return;
-					} else if("dupl" == returnData.result) {
-						alert("이미 존재하는 그룹명입니다.");
-						return;
-					}
-					alert("합치기가 완료되었습니다.");
-
-					location.reload();
-					
-				}else{ alert("ERROR!");return;} 
-			},
-			error: function (e) { alert("그룹 합치기가  실패하였습니다."); console.log("ERROR : ", e); }
-		});
-	}
-	
-}
-
-//그룹 복사하기
-function addrGroupCopy() {
-	var form = document.addrGrpCopyForm;
-	var copyAddrArray = new Array();
-	
-	$('.selGroup3 li').each(function (idx, item) {
-		copyAddrArray.push($(item).attr('class'));
-	});
-	form.copyAddrs.value = copyAddrArray;
-	
-	
-	if(confirm("그룹을 복사하시겠습니까?")) {
-		var data = new FormData(form);
-		$.ajax({
-			cache : false,
-			url : "<c:url value='/web/addr/copyAddrGroupAjax.do'/>", 
-			type : 'POST', 
-			data : data,
-			dataType:'json',
-			processData: false,
-			contentType: false,
-			success : function(returnData, status){
-				if(status == "success") {
-					if("fail"==returnData.result){
-						alert(returnData.message);
-						return;
-					} else if("dupl" == returnData.result) {
-						alert("이미 존재하는 그룹명입니다.");
-						return;
-					}
-					alert("정상적으로 처리되었습니다.");
-
-					location.reload();
-					
-				}else{ alert("ERROR!");return;} 
-			},
-			error: function (e) { alert("그룹 복사  실패하였습니다."); console.log("ERROR : ", e); }
-		});
-	}
-	
-	
-}
-
-//그룹 다중수정모드 및 수정 프로세스
-function editAddrGroups() {
-	if($('.addrGrpNms').attr("type") == "hidden") {
-		$('.groupsName').hide();
-		$('.editAddrGrpBtn').html("저장");
-		$('.cancelAddrGrpBtn').show();
-		$('.addrGrpNms').attr("type","text");
-		$('#orderBtn').show();
-	} else {
-		if(confirm("수정하시겠습니까?")) {
-			var addrGrpNms = $("input[name=addrGrpNms]");
-			for(var i = 0; i < addrGrpNms.length; i++){
-				if(addrGrpNms[i].value == ''){
-					alert("그룹명을 입력해주세요.")
-					return false;
-				}
-			}
-			var form = document.addrGrpListForm;
-			var data = new FormData(form);
-			$.ajax({
-				cache : false,
-				url : "<c:url value='/web/addr/updateAddrGroupAjax.do'/>", 
-				type : 'POST', 
-				data : data,
-				dataType:'json',
-				processData: false,
-				contentType: false,
-				success : function(returnData, status){
-					if(status == "success") {
-						if("fail"==returnData.result){
-							alert(returnData.message);
-							return;
-						} else if("dupl"==returnData.result) {
-							alert("중복된 주소록그룹명이 존재합니다");
-							return;
-						} 
-						alert("정상적으로 처리되었습니다.");
-						location.reload();
-						
-					}else{ alert("ERROR!");return;} 
-				},
-				error: function (e) { alert("그룹 수정  실패하였습니다."); console.log("ERROR : ", e); }
-			});
-		}
-	}
-}
-
-// 그룹 다중수정모드 취소
-function cancelAddrGroupEdit() {
-	/*
-	$('.groupsName').show();
-	$('.cancelAddrGrpBtn').hide();
-	$('.editAddrGrpBtn').html("편집");
-	$('.addrGrpNms').attr("type","hidden");
-	$('#orderBtn').hide();
-	*/
-	listAddrGrp();
-}
-
-// 그룹을 클릭해서 주소록 목록에 노출하기
-function openThisGroup(id) {
-	var form = document.searchAddrOpenForm;
-	
-	if (id == 'bookmark') {
-		//자주보내는번호 검색
-		form.searchAddrGrpId.value="bookmark";
-	} else if (id != '') {
-		//id가 넘어오면 해당 그룹id만 검색
-		form.searchAddrGrpId.value = id;
-	} else if (id == 'noGrp') {
-		form.searchAddrGrpId.value = "noGrp";
-	} else {
-		form.searchAddrGrpId.value = "";
-	}
-	
-	var sendData = $(document.searchAddrOpenForm).serializeArray() ;
-	$("#adr1_right").load("/web/mjon/addr/selectAddrAjax.do", sendData, function(response, status, xhr){});
-}
-
-// 주소록 전송할 아이디가 유효한지 체크
-function validateId() {
-	var recvId = $("#recvId").val();
-	var form = document.duplIdCheckForm;
-	
-	if($("input:checkbox[name='grpCheck']").is(":checked")==false){	
-		alert("선택된 그룹이  없습니다.");
-		return false;
-	}
-	
-	if(recvId == "" || recvId == null) {
-		alert("아이디를 입력해주세요.")	
-		return;
-	}
-	form.checkId.value = recvId;
-	
-	var data = new FormData(form);
-	$.ajax({
-		cache : false,
-		url : "<c:url value='/uss/umt/user/EgovIdDplctCnfirmAjax.do'/>", 
-		type : 'POST', 
-		data : data,
-		dataType:'json',
-		processData: false,
-		contentType: false,
-		success : function(returnData, status){
-			if(status == "success") {
-				if(returnData.usedCnt < 1){
-					alert("일치하는 아이디가 없습니다.");
-					return;
-				}else if(returnData.usedCnt > 0){
-					//체크한 그룹들을 html로 그리기
-					sendAddrGroupLayer();
-					
-					$(".groupSendLayer").attr("data-tooltip", "adr_popup03");
-					$("#idCheckSuccess").trigger("click");
-				}
-			}else{ alert("ERROR!");return;} 
-		},
-		error: function (e) { alert("조회에  실패하였습니다."); console.log("ERROR : ", e); }
-	});
-	
-}
-
-// 그룹 내보내기 레이어 띄우기 
-function sendAddrGroupLayer() {
-	var form = document.addrGrpListForm;
-	var html = "";
-	var index = 0;
-	successHtml = "";	//내보내기 최종레이어의 초기화
- 	if($("input:checkbox[name='grpCheck']:checked").length > 0){
-		
-		$('input:checkbox[name="grpCheck"]').each(function() {
-			if(this.checked){
-				var id = $(this).attr('id');
-				var idNum = id.substr(5);
-				
-				html += '<li name="li2Index" class="'+$("#addrGrpId"+idNum).val()+'" id="li2Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi2('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
-				successHtml += '<li name="li3Index" id="li3Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<p id=sendCondition'+index+'></p></li>';
-				index++;
-			}
-		});
-		//초기화
-		$('#selGroup2').empty();
-		$('#selGroup2').append(html);
-		$(".recvId").text($("#recvId").val());
-		$(".checkGroupCount").text($("input:checkbox[name='grpCheck']:checked").length);
-	}
-}
-
-//휴대폰 본인인증 팝업
-function kmcPopUp() {
-	//KMC팝업에 정보 미리 삽입
-	var kmcPopUpForm = $("form[name=reqKMCISForm]").serialize() ;
-	
-	$.ajax({
-        url : "<c:url value='/web/addr/kmcPopupAddrSubmitPramAjax.do' />", 
-        type : 'POST', 
-        data : kmcPopUpForm,
-        dataType:'json',
-        success : function(returnData, status){
-        	if(status == "success") {
-        		if (returnData.result=="success"){
-            		$("#tr_cert").val(returnData.tr_cert);
-            		$("#tr_url").val(returnData.tr_url);
-            		$("#tr_add").val(returnData.tr_add);
-            		
-            		openKMCISWindow();        			
-        		}else{
-        			alert(returnData.message);
-        		}
-
-          	}else{ alert("실패");return;} 
-        },
- 
-        error : function(request , status, error){
-        	alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
-        }
-    });
-	
-}
-
-// 주소록 내보내기
-function sendAddrGroup() {
-	
-	var form = document.addrGrpSendForm;
-	var sendGrpArray = new Array();
-	var resultStatus = new Array();
-	var successSendGroup = 0;
-	var html = ""; 
-	$('.selGroup2 li').each(function (idx, item) {
-		sendGrpArray.push($(item).attr('class'));
-	});
-	form.sendGrps.value = sendGrpArray;
-	
-	form.recvMberId.value = $("#recvId").val();
-	
-	/* if(confirm("그룹을 내보내겠습니까?")) { */
-		var data = new FormData(form);
-		$.ajax({
-			cache : false,
-			url : "<c:url value='/web/mjon/addr/transAddrGroupAjax.do'/>", 
-			type : 'POST', 
-			data : data,
-			dataType:'json',
-			processData: false,
-			contentType: false,
-			success : function(returnData, status){
-				if(status == "success") {
-					if("fail"==returnData.result){
-						console.log(returnData.message);
-						return;
-					}
-					
-					resultStatus =  returnData.result.split(',');
-					
-					$("#resultSendList").html(successHtml);
-					
-					
-					for(var i=0; i<resultStatus.length; i++) {
-						if(resultStatus[i] == 'Y'){
-							successSendGroup ++;
-							$("#sendCondition"+i).html("전송완료");
-						} else {
-							$("#sendCondition"+i).html("전송실패");
-						}
-					}
-					
-					$(".successSendGroup").text(successSendGroup);
-					
-					$("#sendCheckCloseBtn").trigger("click");
-					$("#sendSuccessLayer").trigger("click");
-					
-				}else{ alert("ERROR!");return;} 
-			},
-			error: function (e) { alert("그룹 전송  실패하였습니다."); console.log("ERROR : ", e); }
-		});
-	/* } */
-	
-}
-
-//주소록 내보내기 히스토리 목록
-function listAddrTransHistAjax(pageNo) {
-	var form = document.searchAddrTransHistForm;
-	form.pageIndex.value = pageNo;
-	
-	if($('#addrTransHistPageUnit').val() != undefined) {
-		form.pageUnit.value = $('#addrTransHistPageUnit').val();
-	}
-	
-	var sendData = $(document.searchAddrTransHistForm).serializeArray();
-	$("#addrTransHistListDiv").load("/web/mjon/addr/selectAddrTransHistListAjax.do", sendData, function(response, status, xhr){
-        //리스트 스크롤 처리해주기
-      /*
-        $(".tb_wrap").mCustomScrollbar({
-           axis: 'y',
-           scrollbarPosition: "outside",
-           theme: "dark",
-           autoHideScrollbar: false
-        });
-        */
-	});
-	
-	$("#addrTransHistListLayer").trigger("click");
-	
-	
-}
-
-</script>
-
-<script language=javascript>
-
-   window.name = "kmcis_web_sample";
-   
-   var KMCIS_window;
-
-   function openKMCISWindow(){    
-
-    var UserAgent = navigator.userAgent;
-    /* 모바일 접근 체크*/
-    // 모바일일 경우 (변동사항 있을경우 추가 필요)
-    if (UserAgent.match(/iPhone|iPod|Android|Windows CE|BlackBerry|Symbian|Windows Phone|webOS|Opera Mini|Opera Mobi|POLARIS|IEMobile|lgtelecom|nokia|SonyEricsson/i) != null || UserAgent.match(/LG|SAMSUNG|Samsung/) != null) {
-   		 document.reqKMCISForm.target = 'KMCISWindow';  // 모바일
-	  } 
-	  
-	  // 모바일이 아닐 경우
-	  else {
-   		KMCIS_window = window.open('', 'KMCISWindow', 'width=425, height=550, resizable=0, scrollbars=no, status=0, titlebar=0, toolbar=0, left=435, top=250' );
-   		
-   		if(KMCIS_window == null){
-  			alert(" ※ 윈도우 XP SP2 또는 인터넷 익스플로러 7 사용자일 경우에는 \n    화면 상단에 있는 팝업 차단 알림줄을 클릭하여 팝업을 허용해 주시기 바랍니다. \n\n※ MSN,야후,구글 팝업 차단 툴바가 설치된 경우 팝업허용을 해주시기 바랍니다.");
-      }
-   		
-   		document.reqKMCISForm.target = 'KMCISWindow';
-	  }
-	  
-	  document.reqKMCISForm.action = 'https://www.kmcert.com/kmcis/web/kmcisReq.jsp';
-	  document.reqKMCISForm.submit();
-	  
-  }
-   
-</script>
-
-<form name="searchAddrGrpForm" id="searchAddrGrpForm" method="post" onsubmit="return false;">
-	<div class="search_group_top">
-		<label for="" class="label">그룹명 검색</label>
-		<input type="text" name="searchKeyword" id="searchKeyword" placeholder="그룹명을 입력하세요" onfocus="this.placeholder=''" onblur="this.placeholder='그룹명을 입력하세요'" class="inputLight">
-		<input type="hidden" name="searchCondition" id="searchCondition" value="2" />
-		<input type="hidden" name="searchAddrGrpId" id="searchAddrGrpId" />
-		<button type="button" onclick="listAddrGroupAjax(); return false;"><img src="/publish/images/popup/search.png" alt="검색"></button>
-	</div>
-</form>
-
-<div class="adrBox">
-	<form name="addrGrpInsertForm" id="addrGrpInsertForm" method="post" onsubmit="return false;">
-		<div class="search_group_middle">
-			<label for="" class="label">새 그룹 추가</label>
-			<input type="text" name="addrGrpNm" id="addrGrpNm"  placeholder="새 그룹명 입력(40Byte 이내)" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력(40Byte 이내)'" class="inputLight" maxlength="24">
-			<button type="button" onclick="insertAddrGroupAjax(); return false;" class="btnType">추가</button>
-		</div>
-	</form>
-	<form name="addrGrpListForm" id="addrGrpListForm" method="post" onsubmit="return false;">
-		<div class="adr_cb_wrap check_group_all">
-			<div style="margin-right: 2px;">
-				<label for="groupAll" class="label">전체 선택</label>
-				<input type="checkbox" name="groupAll" id="groupAll" value="1" onClick="fnCheckAll();">
-			</div>
-			<p class="open" onclick="openThisGroup('');"><img src="/publish/images/content/open_folder.png" alt="폴더 열림">전체[<span class="c_002c9a fwMd" id="addrTotCnt"></span>/최대 500,000]</p>
-		</div>
-		<div class="adr1_btnWrap">
-			<div>
-				<button type="button" class="btnType btnType21 editAddrGrpBtn" onclick="editAddrGroups();">편집</button>
-				<button type="button" class="btnType btnType7 cancelAddrGrpBtn" onclick="cancelAddrGroupEdit();" style="display:none;">취소</button>
-			</div>
-			<div id="orderBtn" style="display:none;">
-				<button type="button" class="btn_top"><img src="/publish/images/content/adress_up2.png"></button>
-				<button type="button" class="btn_up"><img src="/publish/images/content/adress_up1.png"></button>
-				<button type="button" class="btn_down"><img src="/publish/images/content/adress_down1.png"></button>
-				<button type="button" class="btn_botom"><img src="/publish/images/content/adress_down2.png"></button>
-			</div>
-		</div>
-		<div class="adr1_list">
-			<!-- 고정그룹 : 그룹미지정 -->
-			<div class="adr_cb_wrap list_fixed">
-				<label for="group1" class="label"></label>
-				<input type="checkbox" id="group1" disabled="disabled">
-				<p onclick="openThisGroup('noGrp');"><img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">그룹미지정[<span id="nogrpCnt"></span>명]</p>
-			</div>
-			<!-- 고정그룹 : 자주보내는번호 -->
-			<div class="adr_cb_wrap list_fixed">
-				<label for="group2" class="label"></label>
-				<input type="checkbox" id="group2" disabled="disabled">
-				<p onclick="openThisGroup('bookmark');"><img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">자주보내는 번호[<span id="bookmarkCnt"></span>명]
-			</div>
-			<c:forEach var="addrGroupList" items="${addrGroupList}" varStatus="status">
-				<div class="adr_cb_wrap list_switch">
-					<div>
-						<label for="group${status.index+3}" class="label"><c:out value="${addrGroupList.addrGrpNm}" /></label>
-						<input type="checkbox" name="grpCheck" id="group${status.index+3}" onclick="tooltipCheck();" value="${addrGroupList.addrGrpId}">
-					</div>
-					<p  onclick="openThisGroup('<c:out value="${addrGroupList.addrGrpId}" />');">
-						<img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">
-						<input type="hidden" name="addrGrpNms" class="addrGrpNms" id="addrGrpNm${status.index+3}" value="${addrGroupList.addrGrpNm}" maxlength="20"/>
-						<span class="groupsName"><c:out value="${addrGroupList.addrGrpNm}" />[<span><c:out value="${addrGroupList.grpCount}" /></span>명]
-					</p>
-					<input type="hidden" name="addrGrpIds" id="addrGrpId${status.index+3}" value="${addrGroupList.addrGrpId}" />
-					<input type="hidden" id="grpCount${status.index+3}" value="${addrGroupList.grpCount}" />
-				</div>
-			</c:forEach>
-		</div>
-		<div class="adr1_btnWrap_bottom">
-			<button type="button" onclick="deleteAddrGroup(); return false;" class="btnType group_remove"><i class="remove_img"></i>그룹삭제</button>
-			<button type="button" onclick="javascript:mergeAddrGroupLayer(); return false;" class="btnType group_join">그룹 합치기</button>
-			<button type="button" onclick="copyAddrGroupLayer(); return false;" class="btnType group_copy">그룹복사</button>
-		</div>
-		
-	 	<!-- Workaround to avoid corrupted XHR2 request body in IE10 / IE11 -->
-	 	<input type="hidden" name="_dontcare">
-	</form>
- 	<%----%>
-	<div class="adr1_exprot clearfix">
-		<p>주소록 내보내기</p>
-		<button type="button" onclick="listAddrTransHistAjax(1); return false;" class="send_address"><i></i>보낸 주소록</button>
-		<input type="hidden" id="addrTransHistListLayer" data-tooltip="adr_popup08" />
-	</div>
-	<div class="search_group_bottom">
-		<label for="" class="label">받는사람 아이디 입력</label>
-		<input type="text" id="recvId" placeholder="보낼 아이디 입력" onfocus="this.placeholder=''" onblur="this.placeholder='보낼 아이디 입력'"  class="inputLight">
-		<button type="button" onclick="validateId();"  class="btnType">내보내기</button>
-		<input type="hidden" class="groupSendLayer" id="idCheckSuccess" data-tooltip="adr_popup03" />
-	</div>
-	<%----%> 
-</div>
-
-<!-- 그룹 합치기 팝업 data-tooltip:adr_popup02 -->
-<form name="addrGrpMergeForm" id="addrGrpMergeForm" method="post" onsubmit="return false;">
-	<input type="hidden" name="mergeGrps" id="mergeGrps" />
-	<div class="tooltip-wrap">
-		<div class="popup-com adr_layer adr_popup02" tabindex="0" data-tooltip-con="adr_popup02" data-focus="adr_popup02" data-focus-prev="adr_popup02-close" style="width: 510px;">
-			<div class="popup_heading">
-				<p>그룹 합치기</p>
-				<button type="button" class="tooltip-close" data-focus="adr_popup02-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-			</div>
-			<div class="layer_in">
-				<div class="gorup_join_cont">
-					<div class="select_group">
-						<p>선택그룹</p>
-						<ul id="selGroup" class="selGroup"></ul>
-					</div>
-					<div class="group_input">
-						<div class="input_left">그룹이름</div>
-						<div class="input_right">
-							<label for="" class="label">새 그룹명 입력</label>
-							<input type="text" name="addrGrpNewNm" placeholder="새 그룹명 입력" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력'" class="inputLight">
-						</div>
-					</div>
-				</div>	
-				<div class="popup_btn_wrap2">
-					<button type="button" onclick="addrGroupMerge();">저장</button>
-					<button type="button" class="tooltip-close" data-focus="adr_popup02-close" data-focus-next="adr_popup02">취소</button>
-				</div>
-			</div>
-		</div>
-	</div><!--// 그룹 합치기 팝업 -->
-</form>
-
-<!-- 그룹 내보내기 팝업 data-tooltip:adr_popup03 -->
-<form name="addrGrpSendForm" id="addrGrpSendForm" method="post" onsubmit="return false;">
-	<input type="hidden" name="sendGrps" id="sendGrps" />
-	<input type="hidden" name="recvMberId" id="recvMberId" />
-	<div class="tooltip-wrap">
-		<div class="popup-com adr_layer adr_popup03" tabindex="0" data-tooltip-con="adr_popup03" data-focus="adr_popup03" data-focus-prev="adr_popup03-close" style="width: 510px;">
-			<div class="popup_heading">
-				<p>그룹 내보내기</p>
-				<button type="button" id="sendCheckCloseBtn" class="tooltip-close" data-focus="adr_popup03-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-			</div>
-			<div class="layer_in">
-				<p class="adr_pop_title"><span class="c_222 recvId"></span>님께 <span class="c_e40000">총 <span class="checkGroupCount"></span>개의 주소록</span>을 전송하겠습니까?</p>
-				<div class="gorup_join_cont">
-					<div class="select_group">
-						<p>선택그룹</p>
-						<ul id="selGroup2" class="selGroup2"></ul>
-					</div>
-				</div>	
-				<div class="popup_btn_wrap2">
-					<button type="button" onclick="kmcPopUp();">확인</button>
-					<button type="button" class="tooltip-close" data-focus="adr_popup03-close" data-focus-next="adr_popup03">취소</button>
-				</div>
-			</div>
-		</div>
-	</div>
-</form>
-<!--// 그룹 내보내기 팝업 -->
-   
-<!-- 그룹 내보내기(결과) 팝업 data-tooltip:adr_popup04 -->
-<div class="tooltip-wrap">
-	<input type="hidden" class="sendSuccessLayer" id="sendSuccessLayer" data-tooltip="adr_popup04" />
-	<div class="popup-com adr_layer adr_popup04" tabindex="0" data-tooltip-con="adr_popup04" data-focus="adr_popup04" data-focus-prev="adr_popup04-close" style="width: 510px;">
-		<div class="popup_heading">
-			<p>그룹 내보내기</p>
-			<button type="button" class="tooltip-close" data-focus="adr_popup04-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-		</div>
-		<div class="layer_in">
-			<p class="adr_pop_title"><span class="c_222 recvId"></span>님께 <span class="c_e40000">총  <span class="successSendGroup"></span>개의 주소록</span>을 전송하였습니다</p>
-			<div class="gorup_join_cont">
-				<div class="select_group2">
-					<ul id="resultSendList">
-					</ul>
-				</div>
-				<p class="select_group_info">※ 발신된 주소록은 10일 이내 수신해야 합니다.</p>
-			</div>	
-			<div class="popup_btn_wrap2">
-				<button type="button" class="tooltip-close check_btn_pop" data-focus="adr_popup04-close" data-focus-next="adr_popup04">확인</button>
-			</div>
-		</div>
-	</div>
-</div><!--// 그룹 내보내기(결과) 팝업 -->
-
-
-
-<!-- 그룹 복사 팝업 data-tooltip:adr_popup05 -->
-<form name="addrGrpCopyForm" id="addrGrpCopyForm" method="post" onsubmit="return false;">
-	<input type="hidden" name="copyAddrs" id="copyAddrs" />
-	<div class="tooltip-wrap">
-		<div class="popup-com adr_layer adr_popup05" tabindex="0" data-tooltip-con="adr_popup05" data-focus="adr_popup05" data-focus-prev="adr_popup05-close" style="width: 510px;">
-			<div class="popup_heading">
-				<p>그룹 복사</p>
-				<button type="button" class="tooltip-close" data-focus="adr_popup05-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-			</div>
-			<div class="layer_in">
-				<div class="gorup_join_cont">
-					<div class="select_group">
-						<p>선택그룹</p>
-						<ul id="selGroup3" class="selGroup3"></ul>
-					</div>
-					<div class="group_input">
-						<div class="input_left">그룹이름</div>
-						<div class="input_right">
-							<label for="" class="label">새 그룹명 입력</label>
-							<input type="text" id="addrGrpNewNm" name="addrGrpNewNm" placeholder="새 그룹명 입력" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력'" class="inputLight">
-						</div>
-					</div>
-				</div>	
-				<div class="popup_btn_wrap2">
-					<button type="button" onclick="addrGroupCopy();">저장</button>
-					<button type="button" class="tooltip-close" data-focus="adr_popup05-close" data-focus-next="adr_popup05">취소</button>
-				</div>
-			</div>
-		</div>
-	</div><!--// 그룹 합치기 팝업 -->
-</form>
-
-
-
-<!-- 주소록 내보내기 관리 data-tooltip:adr_popup08 -->
-<div class="tooltip-wrap">
-	<div class="popup-com adr_layer adr_popup08" tabindex="0" data-tooltip-con="adr_popup08" data-focus="adr_popup08" data-focus-prev="adr_popup08-close" style="width: 920px;height:456px;">
-		<div class="popup_heading">
-			<p>주소록 내보내기 관리</p>
-			<button type="button" class="tooltip-close" data-focus="adr_popup08-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-		</div>
-		<div class="layer_in" style="padding: 30px 30px 40px 30px;">
-			<div id="addrTransHistListDiv"></div>
-		</div>
-	</div>
-</div><!--// 주소록 내보내기 관리 팝업 -->
-
-<form name="searchAddrOpenForm" id="searchAddrOpenForm" method="post" onsubmit="return false;">
-	<input type="hidden" name="searchAddrGrpId" id="searchAddrGrpId" />
-</form>
-<form name="duplIdCheckForm" id="duplIdCheckForm" method="post" onsubmit="return false;">
-	<input type="hidden" name="checkId" id="checkId" />
-</form>
-
-<form name="searchAddrTransHistForm" id="searchAddrTransHistForm" method="post" onsubmit="return false;">
-	<input name="pageIndex" type="hidden" />
-	<input name="pageUnit" type="hidden" value="10"/>
-</form>
-
-<form name="reqKMCISForm" id="reqKMCISForm" mehtod="post">
-	<input type="hidden" name="tr_cert" id="tr_cert" value = "${tr_cert}">
-    <input type="hidden" name="tr_url"  id="tr_url" value = "${tr_url}">
-    <input type="hidden" name="tr_add"  id="tr_add" value = "${tr_add}">
-	<input type="hidden" name="mberId"  id="mberId" value= "${userId}">
-</form>
-
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
+
+<script src="/publish/js/content.js"></script>
+<script type="text/javascript">
+var successHtml="";
+
+$(document).ready(function(){
+	
+	// 주소록 그룹 카운트(전체)
+// 	getAddrGroupTotCnt();
+
+	//주소록 그룹 카운트(그룹미지정)
+// 	getAddrGroupNogrpCnt();
+
+	//주소록 그룹 카운트(자주보내는 번호)
+// 	getAddrGroupBookmarkCnt();
+	
+}); 
+
+// 주소록 그룹 카운트(전체)
+function getAddrGroupTotCnt() {
+	$.ajax({
+        type: "POST",
+        url: "/web/addr/selectAddrGroupTotCntAjax.do",
+        data: {},
+        dataType:'json',
+        async: true,
+        success: function (data) {
+        	console.log('data : ', data);
+			if (data.isSuccess) {
+				$("#addrTotCnt").html(numberWithCommas(data.addrTotCnt));
+			} 
+			else {
+				//alert("Msg : " + data.msg);
+			}
+		},
+        error: function (e) { 
+        	//alert("ERROR : " + JSON.stringify(e)); 
+        }
+    });				
+}	
+
+//주소록 그룹 카운트(그룹미지정)
+function getAddrGroupNogrpCnt() {
+	$.ajax({
+        type: "POST",
+        url: "/web/addr/selectAddrGroupNogrpCntAjax.do",
+        data: {},
+        dataType:'json',
+        async: true,
+        success: function (data) {
+			if (data.isSuccess) {
+				$("#nogrpCnt").html(data.nogrpCnt);
+			} 
+			else {
+				//alert("Msg : " + data.msg);
+			}
+		},
+        error: function (e) { 
+        	//alert("ERROR : " + JSON.stringify(e)); 
+        }
+    });				
+}	
+
+//주소록 그룹 카운트(자주보내는 번호)
+function getAddrGroupBookmarkCnt() {
+	$.ajax({
+        type: "POST",
+        url: "/web/addr/selectAddrGroupBookmarkCntAjax.do",
+        data: {},
+        dataType:'json',
+        async: true,
+        success: function (data) {
+			if (data.isSuccess) {
+				$("#bookmarkCnt").html(data.bookmarkCnt);
+			} 
+			else {
+				//alert("Msg : " + data.msg);
+			}
+		},
+        error: function (e) { 
+        	//alert("ERROR : " + JSON.stringify(e)); 
+        }
+    });				
+}	
+
+// 주소록 그룹 리스트 띄우기
+function listAddrGroupAjax() {
+	var form = document.searchAddrGrpForm;
+	
+	var sendData = $(document.searchAddrGrpForm).serializeArray() ;
+	$("#adr1_left").load("/web/addr/selectAddrGroupListAjax.do", sendData ,function(response, status, xhr){});
+}
+
+// 주소록 그룹 지우기(선택삭제)
+function deleteAddrGroup() {
+	var form = document.addrGrpListForm;
+	if($("input:checkbox[name='grpCheck']").is(":checked")==true){	
+		if(confirm("그룹을 삭제하시겠습니까?\n그룹 내 전체 주소가 삭제되며 복구할 수 없습니다.")) {
+			fn_loadAddActive();
+			var data = new FormData(form);
+			$.ajax({
+				cache : false,
+				url : "<c:url value='/web/addr/deleteAddrGroupAjax.do'/>", 
+				type : 'POST', 
+				data : data,
+				dataType:'json',
+				processData: false,
+				contentType: false,
+				success : function(returnData, status){
+					if(status == "success") {
+						if("fail"==returnData.result){
+							alert(returnData.message);
+							return;
+						}
+						alert("삭제되었습니다.");
+						listAddrGrp();
+						addrGroupLoadAjax();
+						addrLoadAjax();
+						
+					}else{ alert("ERROR!");return;} 
+				},
+				error: function (e) { alert("삭제  실패하였습니다."); console.log("ERROR : ", e); },
+                beforeSend: function(xmlHttpRequest) {
+                },
+                complete: function(xhr, textStatus) {
+            		fn_loadRemoveActive();
+                }
+			});
+		}
+	}else{
+		alert("선택된 그룹이  없습니다.");
+		return false;
+	}
+	
+}
+
+// 체크박스 전체선택
+function fnCheckAll() {
+	var checkField = document.addrGrpListForm.grpCheck;
+	if(document.addrGrpListForm.groupAll.checked) {
+		if(checkField) {
+			if(checkField.length > 1) {
+				for(var i=0; i < checkField.length; i++) {
+					checkField[i].checked = true;
+				}
+			} else {
+				checkField.checked = true;
+			}
+		}
+	} else {
+		if(checkField) {
+			if(checkField.length > 1) {
+				for(var j=0; j < checkField.length; j++) {
+					checkField[j].checked = false;
+				}
+			} else {
+				checkField.checked = false;
+			}
+		}
+	}
+	tooltipCheck();
+}
+
+// 주소록 그룹 합치기 레이어 열기 
+function mergeAddrGroupLayer(){
+	var form = document.addrGrpListForm;
+	var html = "";
+	var index = 0;
+ 	if($("input:checkbox[name='grpCheck']:checked").length > 1){
+		
+		$('input:checkbox[name="grpCheck"]').each(function() {
+			if(this.checked){
+				var id = $(this).attr('id');
+				var idNum = id.substr(5);
+				
+				html += '<li name="liIndex" class="'+$("#addrGrpId"+idNum).val()+'" id="liIndex'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
+				index++;
+			}
+		});
+		//초기화
+		$('#selGroup').empty();
+		$('#selGroup').append(html);
+		
+	}else{
+		alert("합치실 그룹을 두개 이상 선택하세요.");
+		return false;
+	}
+		
+}
+
+
+//주소록 그룹 복사 레이어 열기 
+function copyAddrGroupLayer(){
+	var form = document.addrGrpListForm;
+	var html = "";
+	var index = 0;
+ 	if($("input:checkbox[name='grpCheck']:checked").length > 0){
+		
+		$('input:checkbox[name="grpCheck"]').each(function() {
+			if(this.checked){
+				var id = $(this).attr('id');
+				var idNum = id.substr(5);
+				
+				html += '<li name="li4Index" class="'+$("#addrGrpId"+idNum).val()+'" id="li4Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi4('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
+				index++;
+			}
+		});
+		//초기화
+		$('#selGroup3').empty();
+		$('#selGroup3').append(html);
+		
+	}else{
+		alert("복사할 그룹을 한 개 이상 선택하세요.");
+		return false;
+	}
+		
+}
+
+
+// 합치기 레이어 내 리스트 세팅
+function removeLi(idx) {
+	var liCount = $("li[name=liIndex]").length;
+	if(liCount > 2) {
+		$("#liIndex"+idx).remove();
+	} else {
+		alert("합치실 그룹은 최소 두 개 이상이어야 합니다");
+	}
+}
+
+//내보내기 레이어 내 리스트 세팅
+function removeLi2(idx) {
+	var liCount = $("li[name=li2Index]").length;
+	if(liCount > 1) {
+		$("#li2Index"+idx).remove();
+		$(".checkGroupCount").text(liCount-1);
+	} else {
+		alert("내보낼 그룹은 최소 한 개 이상이어야 합니다");
+	}
+	
+}
+
+//합치기 레이어 내 리스트 세팅
+function removeLi4(idx) {
+	var liCount = $("li[name=li4Index]").length;
+	if(liCount > 1) {
+		$("#li4Index"+idx).remove();
+	} else {
+		alert("복사할 그룹은 한 개 이상이어야 합니다");
+	}
+}
+
+
+// 툴팁 삭제/삽입
+function tooltipCheck() {
+	//그룹합치기 툴팁
+	if($("input:checkbox[name='grpCheck']:checked").length < 2){
+		$(".group_join").removeAttr("data-tooltip");
+	} else {
+		$(".group_join").attr("data-tooltip", "adr_popup02");
+	}
+	
+	//그룹복사 툴팁
+	if($("input:checkbox[name='grpCheck']:checked").length < 1){
+		$(".group_copy").removeAttr("data-tooltip");
+	} else {
+		$(".group_copy").attr("data-tooltip", "adr_popup05");
+	}
+}
+
+
+// 그룹 합치기 
+function addrGroupMerge() {
+	var form = document.addrGrpMergeForm;
+	var mergeGrpArray = new Array();
+	
+	$('.selGroup li').each(function (idx, item) {
+		mergeGrpArray.push($(item).attr('class'));
+	});
+	form.mergeGrps.value = mergeGrpArray;
+	
+	// 그룹을 합치겠습니까?\n기존의 그룹 및 중복연락처는 삭제됩니다.
+	if(confirm("그룹을 합치겠습니까?\n기존의 그룹은 삭제됩니다.")) {
+		var data = new FormData(form);
+		$.ajax({
+			cache : false,
+			url : "<c:url value='/web/addr/mergeAddrGroupAjax.do'/>", 
+			type : 'POST', 
+			data : data,
+			dataType:'json',
+			processData: false,
+			contentType: false,
+			success : function(returnData, status){
+				if(status == "success") {
+					if("fail"==returnData.result){
+						alert(returnData.message);
+						return;
+					} else if("dupl" == returnData.result) {
+						alert("이미 존재하는 그룹명입니다.");
+						return;
+					}
+					alert("합치기가 완료되었습니다.");
+
+					location.reload();
+					
+				}else{ alert("ERROR!");return;} 
+			},
+			error: function (e) { alert("그룹 합치기가  실패하였습니다."); console.log("ERROR : ", e); }
+		});
+	}
+	
+}
+
+//그룹 복사하기
+function addrGroupCopy() {
+	var form = document.addrGrpCopyForm;
+	var copyAddrArray = new Array();
+	
+	$('.selGroup3 li').each(function (idx, item) {
+		copyAddrArray.push($(item).attr('class'));
+	});
+	form.copyAddrs.value = copyAddrArray;
+	
+	
+	if(confirm("그룹을 복사하시겠습니까?")) {
+		var data = new FormData(form);
+		$.ajax({
+			cache : false,
+			url : "<c:url value='/web/addr/copyAddrGroupAjax.do'/>", 
+			type : 'POST', 
+			data : data,
+			dataType:'json',
+			processData: false,
+			contentType: false,
+			success : function(returnData, status){
+				if(status == "success") {
+					if("fail"==returnData.result){
+						alert(returnData.message);
+						return;
+					} else if("dupl" == returnData.result) {
+						alert("이미 존재하는 그룹명입니다.");
+						return;
+					}
+					alert("정상적으로 처리되었습니다.");
+
+					location.reload();
+					
+				}else{ alert("ERROR!");return;} 
+			},
+			error: function (e) { alert("그룹 복사  실패하였습니다."); console.log("ERROR : ", e); }
+		});
+	}
+	
+	
+}
+
+//그룹 다중수정모드 및 수정 프로세스
+function editAddrGroups() {
+	if($('.addrGrpNms').attr("type") == "hidden") {
+		$('.groupsName').hide();
+		$('.editAddrGrpBtn').html("저장");
+		$('.cancelAddrGrpBtn').show();
+		$('.addrGrpNms').attr("type","text");
+		$('#orderBtn').show();
+	} else {
+		if(confirm("수정하시겠습니까?")) {
+			var addrGrpNms = $("input[name=addrGrpNms]");
+			for(var i = 0; i < addrGrpNms.length; i++){
+				if(addrGrpNms[i].value == ''){
+					alert("그룹명을 입력해주세요.")
+					return false;
+				}
+			}
+			var form = document.addrGrpListForm;
+			var data = new FormData(form);
+			$.ajax({
+				cache : false,
+				url : "<c:url value='/web/addr/updateAddrGroupAjax.do'/>", 
+				type : 'POST', 
+				data : data,
+				dataType:'json',
+				processData: false,
+				contentType: false,
+				success : function(returnData, status){
+					if(status == "success") {
+						if("fail"==returnData.result){
+							alert(returnData.message);
+							return;
+						} else if("dupl"==returnData.result) {
+							alert("중복된 주소록그룹명이 존재합니다");
+							return;
+						} 
+						alert("정상적으로 처리되었습니다.");
+						location.reload();
+						
+					}else{ alert("ERROR!");return;} 
+				},
+				error: function (e) { alert("그룹 수정  실패하였습니다."); console.log("ERROR : ", e); }
+			});
+		}
+	}
+}
+
+// 그룹 다중수정모드 취소
+function cancelAddrGroupEdit() {
+	/*
+	$('.groupsName').show();
+	$('.cancelAddrGrpBtn').hide();
+	$('.editAddrGrpBtn').html("편집");
+	$('.addrGrpNms').attr("type","hidden");
+	$('#orderBtn').hide();
+	*/
+	listAddrGrp();
+}
+
+// 그룹을 클릭해서 주소록 목록에 노출하기
+function openThisGroup(id) {
+	var form = document.searchAddrOpenForm;
+	
+	if (id == 'bookmark') {
+		//자주보내는번호 검색
+		form.searchAddrGrpId.value="bookmark";
+	} else if (id != '') {
+		//id가 넘어오면 해당 그룹id만 검색
+		form.searchAddrGrpId.value = id;
+	} else if (id == 'noGrp') {
+		form.searchAddrGrpId.value = "noGrp";
+	} else {
+		form.searchAddrGrpId.value = "";
+	}
+	
+	var sendData = $(document.searchAddrOpenForm).serializeArray() ;
+	$("#adr1_right").load("/web/mjon/addr/selectAddrAjax.do", sendData, function(response, status, xhr){});
+}
+
+// 주소록 전송할 아이디가 유효한지 체크
+function validateId() {
+	var recvId = $("#recvId").val();
+	var form = document.duplIdCheckForm;
+	
+	if($("input:checkbox[name='grpCheck']").is(":checked")==false){	
+		alert("선택된 그룹이  없습니다.");
+		return false;
+	}
+	
+	if(recvId == "" || recvId == null) {
+		alert("아이디를 입력해주세요.")	
+		return;
+	}
+	form.checkId.value = recvId;
+	
+	var data = new FormData(form);
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/uss/umt/user/EgovIdDplctCnfirmAjax.do'/>", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if(returnData.usedCnt < 1){
+					alert("일치하는 아이디가 없습니다.");
+					return;
+				}else if(returnData.usedCnt > 0){
+					//체크한 그룹들을 html로 그리기
+					sendAddrGroupLayer();
+					
+					$(".groupSendLayer").attr("data-tooltip", "adr_popup03");
+					$("#idCheckSuccess").trigger("click");
+				}
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("조회에  실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+// 그룹 내보내기 레이어 띄우기 
+function sendAddrGroupLayer() {
+	var form = document.addrGrpListForm;
+	var html = "";
+	var index = 0;
+	successHtml = "";	//내보내기 최종레이어의 초기화
+ 	if($("input:checkbox[name='grpCheck']:checked").length > 0){
+		
+		$('input:checkbox[name="grpCheck"]').each(function() {
+			if(this.checked){
+				var id = $(this).attr('id');
+				var idNum = id.substr(5);
+				
+				html += '<li name="li2Index" class="'+$("#addrGrpId"+idNum).val()+'" id="li2Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<button type="button" onclick="removeLi2('+ index +');"><img src="/publish/images/content/close_btn.png" alt="선택 그룹 취소"></button></li>';
+				successHtml += '<li name="li3Index" id="li3Index'+index+'">'+$("#addrGrpNm"+idNum).val()+' [<span>'+$("#grpCount"+idNum).val()+'</span>명]<p id=sendCondition'+index+'></p></li>';
+				index++;
+			}
+		});
+		//초기화
+		$('#selGroup2').empty();
+		$('#selGroup2').append(html);
+		$(".recvId").text($("#recvId").val());
+		$(".checkGroupCount").text($("input:checkbox[name='grpCheck']:checked").length);
+	}
+}
+
+//휴대폰 본인인증 팝업
+function kmcPopUp() {
+	//KMC팝업에 정보 미리 삽입
+	var kmcPopUpForm = $("form[name=reqKMCISForm]").serialize() ;
+	
+	$.ajax({
+        url : "<c:url value='/web/addr/kmcPopupAddrSubmitPramAjax.do' />", 
+        type : 'POST', 
+        data : kmcPopUpForm,
+        dataType:'json',
+        success : function(returnData, status){
+        	if(status == "success") {
+        		if (returnData.result=="success"){
+            		$("#tr_cert").val(returnData.tr_cert);
+            		$("#tr_url").val(returnData.tr_url);
+            		$("#tr_add").val(returnData.tr_add);
+            		
+            		openKMCISWindow();        			
+        		}else{
+        			alert(returnData.message);
+        		}
+
+          	}else{ alert("실패");return;} 
+        },
+ 
+        error : function(request , status, error){
+        	alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
+        }
+    });
+	
+}
+
+// 주소록 내보내기
+function sendAddrGroup() {
+	
+	var form = document.addrGrpSendForm;
+	var sendGrpArray = new Array();
+	var resultStatus = new Array();
+	var successSendGroup = 0;
+	var html = ""; 
+	$('.selGroup2 li').each(function (idx, item) {
+		sendGrpArray.push($(item).attr('class'));
+	});
+	form.sendGrps.value = sendGrpArray;
+	
+	form.recvMberId.value = $("#recvId").val();
+	
+	/* if(confirm("그룹을 내보내겠습니까?")) { */
+		var data = new FormData(form);
+		$.ajax({
+			cache : false,
+			url : "<c:url value='/web/mjon/addr/transAddrGroupAjax.do'/>", 
+			type : 'POST', 
+			data : data,
+			dataType:'json',
+			processData: false,
+			contentType: false,
+			success : function(returnData, status){
+				if(status == "success") {
+					if("fail"==returnData.result){
+						console.log(returnData.message);
+						return;
+					}
+					
+					resultStatus =  returnData.result.split(',');
+					
+					$("#resultSendList").html(successHtml);
+					
+					
+					for(var i=0; i<resultStatus.length; i++) {
+						if(resultStatus[i] == 'Y'){
+							successSendGroup ++;
+							$("#sendCondition"+i).html("전송완료");
+						} else {
+							$("#sendCondition"+i).html("전송실패");
+						}
+					}
+					
+					$(".successSendGroup").text(successSendGroup);
+					
+					$("#sendCheckCloseBtn").trigger("click");
+					$("#sendSuccessLayer").trigger("click");
+					
+				}else{ alert("ERROR!");return;} 
+			},
+			error: function (e) { alert("그룹 전송  실패하였습니다."); console.log("ERROR : ", e); }
+		});
+	/* } */
+	
+}
+
+//주소록 내보내기 히스토리 목록
+function listAddrTransHistAjax(pageNo) {
+	var form = document.searchAddrTransHistForm;
+	form.pageIndex.value = pageNo;
+	
+	if($('#addrTransHistPageUnit').val() != undefined) {
+		form.pageUnit.value = $('#addrTransHistPageUnit').val();
+	}
+	
+	var sendData = $(document.searchAddrTransHistForm).serializeArray();
+	$("#addrTransHistListDiv").load("/web/mjon/addr/selectAddrTransHistListAjax.do", sendData, function(response, status, xhr){
+        //리스트 스크롤 처리해주기
+      /*
+        $(".tb_wrap").mCustomScrollbar({
+           axis: 'y',
+           scrollbarPosition: "outside",
+           theme: "dark",
+           autoHideScrollbar: false
+        });
+        */
+	});
+	
+	$("#addrTransHistListLayer").trigger("click");
+	
+	
+}
+
+</script>
+
+<script language=javascript>
+
+   window.name = "kmcis_web_sample";
+   
+   var KMCIS_window;
+
+   function openKMCISWindow(){    
+
+    var UserAgent = navigator.userAgent;
+    /* 모바일 접근 체크*/
+    // 모바일일 경우 (변동사항 있을경우 추가 필요)
+    if (UserAgent.match(/iPhone|iPod|Android|Windows CE|BlackBerry|Symbian|Windows Phone|webOS|Opera Mini|Opera Mobi|POLARIS|IEMobile|lgtelecom|nokia|SonyEricsson/i) != null || UserAgent.match(/LG|SAMSUNG|Samsung/) != null) {
+   		 document.reqKMCISForm.target = 'KMCISWindow';  // 모바일
+	  } 
+	  
+	  // 모바일이 아닐 경우
+	  else {
+   		KMCIS_window = window.open('', 'KMCISWindow', 'width=425, height=550, resizable=0, scrollbars=no, status=0, titlebar=0, toolbar=0, left=435, top=250' );
+   		
+   		if(KMCIS_window == null){
+  			alert(" ※ 윈도우 XP SP2 또는 인터넷 익스플로러 7 사용자일 경우에는 \n    화면 상단에 있는 팝업 차단 알림줄을 클릭하여 팝업을 허용해 주시기 바랍니다. \n\n※ MSN,야후,구글 팝업 차단 툴바가 설치된 경우 팝업허용을 해주시기 바랍니다.");
+      }
+   		
+   		document.reqKMCISForm.target = 'KMCISWindow';
+	  }
+	  
+	  document.reqKMCISForm.action = 'https://www.kmcert.com/kmcis/web/kmcisReq.jsp';
+	  document.reqKMCISForm.submit();
+	  
+  }
+   
+</script>
+
+<form name="searchAddrGrpForm" id="searchAddrGrpForm" method="post" onsubmit="return false;">
+	<div class="search_group_top">
+		<label for="" class="label">그룹명 검색</label>
+		<input type="text" name="searchKeyword" id="searchKeyword" placeholder="그룹명을 입력하세요" onfocus="this.placeholder=''" onblur="this.placeholder='그룹명을 입력하세요'" class="inputLight">
+		<input type="hidden" name="searchCondition" id="searchCondition" value="2" />
+		<input type="hidden" name="searchAddrGrpId" id="searchAddrGrpId" />
+		<button type="button" onclick="listAddrGroupAjax(); return false;"><img src="/publish/images/popup/search.png" alt="검색"></button>
+	</div>
+</form>
+
+<div class="adrBox">
+	<form name="addrGrpInsertForm" id="addrGrpInsertForm" method="post" onsubmit="return false;">
+		<div class="search_group_middle">
+			<label for="" class="label">새 그룹 추가</label>
+			<input type="text" name="addrGrpNm" id="addrGrpNm"  placeholder="새 그룹명 입력(40Byte 이내)" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력(40Byte 이내)'" class="inputLight" maxlength="24">
+			<button type="button" onclick="insertAddrGroupAjax(); return false;" class="btnType">추가</button>
+		</div>
+	</form>
+	<form name="addrGrpListForm" id="addrGrpListForm" method="post" onsubmit="return false;">
+		<div class="adr_cb_wrap check_group_all">
+			<div style="margin-right: 2px;">
+				<label for="groupAll" class="label">전체 선택</label>
+				<input type="checkbox" name="groupAll" id="groupAll" value="1" onClick="fnCheckAll();">
+			</div>
+			<p class="open" onclick="openThisGroup('');"><img src="/publish/images/content/open_folder.png" alt="폴더 열림">전체[<span class="c_002c9a fwMd" id="addrTotCnt">${addrTotalCount }</span>/최대 1,000,000]</p>
+		</div>
+		<div class="adr1_btnWrap">
+			<div>
+				<button type="button" class="btnType btnType21 editAddrGrpBtn" onclick="editAddrGroups();">편집</button>
+				<button type="button" class="btnType btnType7 cancelAddrGrpBtn" onclick="cancelAddrGroupEdit();" style="display:none;">취소</button>
+			</div>
+			<div id="orderBtn" style="display:none;">
+				<button type="button" class="btn_top"><img src="/publish/images/content/adress_up2.png"></button>
+				<button type="button" class="btn_up"><img src="/publish/images/content/adress_up1.png"></button>
+				<button type="button" class="btn_down"><img src="/publish/images/content/adress_down1.png"></button>
+				<button type="button" class="btn_botom"><img src="/publish/images/content/adress_down2.png"></button>
+			</div>
+		</div>
+		<div class="adr1_list">
+			<!-- 고정그룹 : 그룹미지정 -->
+			<div class="adr_cb_wrap list_fixed">
+				<label for="group1" class="label"></label>
+				<input type="checkbox" id="group1" disabled="disabled">
+				<p onclick="openThisGroup('noGrp');"><img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">그룹미지정[<span id="nogrpCnt"><c:out value="${addrNoGrpCnt}" /></span>명]</p>
+			</div>
+			<!-- 고정그룹 : 자주보내는번호 -->
+			<div class="adr_cb_wrap list_fixed">
+				<label for="group2" class="label"></label>
+				<input type="checkbox" id="group2" disabled="disabled">
+				<p onclick="openThisGroup('bookmark');"><img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">자주보내는 번호[<span id="bookmarkCnt"><c:out value="${addrBookmarkCnt }"/></span>명]
+			</div>
+			<c:forEach var="addrGroupList" items="${addrGroupList}" varStatus="status">
+				<div class="adr_cb_wrap list_switch">
+					<div>
+						<label for="group${status.index+3}" class="label"><c:out value="${addrGroupList.addrGrpNm}" /></label>
+						<input type="checkbox" name="grpCheck" id="group${status.index+3}" onclick="tooltipCheck();" value="${addrGroupList.addrGrpId}">
+					</div>
+					<p  onclick="openThisGroup('<c:out value="${addrGroupList.addrGrpId}" />');">
+						<img src="/publish/images/content/close_folder2.png" alt="폴더 닫힘">
+						<input type="hidden" name="addrGrpNms" class="addrGrpNms" id="addrGrpNm${status.index+3}" value="${addrGroupList.addrGrpNm}" maxlength="20"/>
+						<span class="groupsName"><c:out value="${addrGroupList.addrGrpNm}" />[<span><c:out value="${addrGroupList.grpCount}" /></span>명]
+					</p>
+					<input type="hidden" name="addrGrpIds" id="addrGrpId${status.index+3}" value="${addrGroupList.addrGrpId}" />
+					<input type="hidden" id="grpCount${status.index+3}" value="${addrGroupList.grpCount}" />
+				</div>
+			</c:forEach>
+		</div>
+		<div class="adr1_btnWrap_bottom">
+			<button type="button" onclick="deleteAddrGroup(); return false;" class="btnType group_remove"><i class="remove_img"></i>그룹삭제</button>
+			<button type="button" onclick="javascript:mergeAddrGroupLayer(); return false;" class="btnType group_join">그룹 합치기</button>
+			<button type="button" onclick="copyAddrGroupLayer(); return false;" class="btnType group_copy">그룹복사</button>
+		</div>
+		
+	 	<!-- Workaround to avoid corrupted XHR2 request body in IE10 / IE11 -->
+	 	<input type="hidden" name="_dontcare">
+	</form>
+ 	<%----%>
+	<div class="adr1_exprot clearfix">
+		<p>주소록 내보내기</p>
+		<button type="button" onclick="listAddrTransHistAjax(1); return false;" class="send_address"><i></i>보낸 주소록</button>
+		<input type="hidden" id="addrTransHistListLayer" data-tooltip="adr_popup08" />
+	</div>
+	<div class="search_group_bottom">
+		<label for="" class="label">받는사람 아이디 입력</label>
+		<input type="text" id="recvId" placeholder="보낼 아이디 입력" onfocus="this.placeholder=''" onblur="this.placeholder='보낼 아이디 입력'"  class="inputLight">
+		<button type="button" onclick="validateId();"  class="btnType">내보내기</button>
+		<input type="hidden" class="groupSendLayer" id="idCheckSuccess" data-tooltip="adr_popup03" />
+	</div>
+	<%----%> 
+</div>
+
+<!-- 그룹 합치기 팝업 data-tooltip:adr_popup02 -->
+<form name="addrGrpMergeForm" id="addrGrpMergeForm" method="post" onsubmit="return false;">
+	<input type="hidden" name="mergeGrps" id="mergeGrps" />
+	<div class="tooltip-wrap">
+		<div class="popup-com adr_layer adr_popup02" tabindex="0" data-tooltip-con="adr_popup02" data-focus="adr_popup02" data-focus-prev="adr_popup02-close" style="width: 510px;">
+			<div class="popup_heading">
+				<p>그룹 합치기</p>
+				<button type="button" class="tooltip-close" data-focus="adr_popup02-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+			</div>
+			<div class="layer_in">
+				<div class="gorup_join_cont">
+					<div class="select_group">
+						<p>선택그룹</p>
+						<ul id="selGroup" class="selGroup"></ul>
+					</div>
+					<div class="group_input">
+						<div class="input_left">그룹이름</div>
+						<div class="input_right">
+							<label for="" class="label">새 그룹명 입력</label>
+							<input type="text" name="addrGrpNewNm" placeholder="새 그룹명 입력" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력'" class="inputLight">
+						</div>
+					</div>
+				</div>	
+				<div class="popup_btn_wrap2">
+					<button type="button" onclick="addrGroupMerge();">저장</button>
+					<button type="button" class="tooltip-close" data-focus="adr_popup02-close" data-focus-next="adr_popup02">취소</button>
+				</div>
+			</div>
+		</div>
+	</div><!--// 그룹 합치기 팝업 -->
+</form>
+
+<!-- 그룹 내보내기 팝업 data-tooltip:adr_popup03 -->
+<form name="addrGrpSendForm" id="addrGrpSendForm" method="post" onsubmit="return false;">
+	<input type="hidden" name="sendGrps" id="sendGrps" />
+	<input type="hidden" name="recvMberId" id="recvMberId" />
+	<div class="tooltip-wrap">
+		<div class="popup-com adr_layer adr_popup03" tabindex="0" data-tooltip-con="adr_popup03" data-focus="adr_popup03" data-focus-prev="adr_popup03-close" style="width: 510px;">
+			<div class="popup_heading">
+				<p>그룹 내보내기</p>
+				<button type="button" id="sendCheckCloseBtn" class="tooltip-close" data-focus="adr_popup03-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+			</div>
+			<div class="layer_in">
+				<p class="adr_pop_title"><span class="c_222 recvId"></span>님께 <span class="c_e40000">총 <span class="checkGroupCount"></span>개의 주소록</span>을 전송하겠습니까?</p>
+				<div class="gorup_join_cont">
+					<div class="select_group">
+						<p>선택그룹</p>
+						<ul id="selGroup2" class="selGroup2"></ul>
+					</div>
+				</div>	
+				<div class="popup_btn_wrap2">
+					<button type="button" onclick="kmcPopUp();">확인</button>
+					<button type="button" class="tooltip-close" data-focus="adr_popup03-close" data-focus-next="adr_popup03">취소</button>
+				</div>
+			</div>
+		</div>
+	</div>
+</form>
+<!--// 그룹 내보내기 팝업 -->
+   
+<!-- 그룹 내보내기(결과) 팝업 data-tooltip:adr_popup04 -->
+<div class="tooltip-wrap">
+	<input type="hidden" class="sendSuccessLayer" id="sendSuccessLayer" data-tooltip="adr_popup04" />
+	<div class="popup-com adr_layer adr_popup04" tabindex="0" data-tooltip-con="adr_popup04" data-focus="adr_popup04" data-focus-prev="adr_popup04-close" style="width: 510px;">
+		<div class="popup_heading">
+			<p>그룹 내보내기</p>
+			<button type="button" class="tooltip-close" data-focus="adr_popup04-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+		</div>
+		<div class="layer_in">
+			<p class="adr_pop_title"><span class="c_222 recvId"></span>님께 <span class="c_e40000">총  <span class="successSendGroup"></span>개의 주소록</span>을 전송하였습니다</p>
+			<div class="gorup_join_cont">
+				<div class="select_group2">
+					<ul id="resultSendList">
+					</ul>
+				</div>
+				<p class="select_group_info">※ 발신된 주소록은 10일 이내 수신해야 합니다.</p>
+			</div>	
+			<div class="popup_btn_wrap2">
+				<button type="button" class="tooltip-close check_btn_pop" data-focus="adr_popup04-close" data-focus-next="adr_popup04">확인</button>
+			</div>
+		</div>
+	</div>
+</div><!--// 그룹 내보내기(결과) 팝업 -->
+
+
+
+<!-- 그룹 복사 팝업 data-tooltip:adr_popup05 -->
+<form name="addrGrpCopyForm" id="addrGrpCopyForm" method="post" onsubmit="return false;">
+	<input type="hidden" name="copyAddrs" id="copyAddrs" />
+	<div class="tooltip-wrap">
+		<div class="popup-com adr_layer adr_popup05" tabindex="0" data-tooltip-con="adr_popup05" data-focus="adr_popup05" data-focus-prev="adr_popup05-close" style="width: 510px;">
+			<div class="popup_heading">
+				<p>그룹 복사</p>
+				<button type="button" class="tooltip-close" data-focus="adr_popup05-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+			</div>
+			<div class="layer_in">
+				<div class="gorup_join_cont">
+					<div class="select_group">
+						<p>선택그룹</p>
+						<ul id="selGroup3" class="selGroup3"></ul>
+					</div>
+					<div class="group_input">
+						<div class="input_left">그룹이름</div>
+						<div class="input_right">
+							<label for="" class="label">새 그룹명 입력</label>
+							<input type="text" id="addrGrpNewNm" name="addrGrpNewNm" placeholder="새 그룹명 입력" onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명 입력'" class="inputLight">
+						</div>
+					</div>
+				</div>	
+				<div class="popup_btn_wrap2">
+					<button type="button" onclick="addrGroupCopy();">저장</button>
+					<button type="button" class="tooltip-close" data-focus="adr_popup05-close" data-focus-next="adr_popup05">취소</button>
+				</div>
+			</div>
+		</div>
+	</div><!--// 그룹 합치기 팝업 -->
+</form>
+
+
+
+<!-- 주소록 내보내기 관리 data-tooltip:adr_popup08 -->
+<div class="tooltip-wrap">
+	<div class="popup-com adr_layer adr_popup08" tabindex="0" data-tooltip-con="adr_popup08" data-focus="adr_popup08" data-focus-prev="adr_popup08-close" style="width: 920px;height:456px;">
+		<div class="popup_heading">
+			<p>주소록 내보내기 관리</p>
+			<button type="button" class="tooltip-close" data-focus="adr_popup08-close"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+		</div>
+		<div class="layer_in" style="padding: 30px 30px 40px 30px;">
+			<div id="addrTransHistListDiv"></div>
+		</div>
+	</div>
+</div><!--// 주소록 내보내기 관리 팝업 -->
+
+<form name="searchAddrOpenForm" id="searchAddrOpenForm" method="post" onsubmit="return false;">
+	<input type="hidden" name="searchAddrGrpId" id="searchAddrGrpId" />
+</form>
+<form name="duplIdCheckForm" id="duplIdCheckForm" method="post" onsubmit="return false;">
+	<input type="hidden" name="checkId" id="checkId" />
+</form>
+
+<form name="searchAddrTransHistForm" id="searchAddrTransHistForm" method="post" onsubmit="return false;">
+	<input name="pageIndex" type="hidden" />
+	<input name="pageUnit" type="hidden" value="10"/>
+</form>
+
+<form name="reqKMCISForm" id="reqKMCISForm" mehtod="post">
+	<input type="hidden" name="tr_cert" id="tr_cert" value = "${tr_cert}">
+    <input type="hidden" name="tr_url"  id="tr_url" value = "${tr_url}">
+    <input type="hidden" name="tr_add"  id="tr_add" value = "${tr_add}">
+	<input type="hidden" name="mberId"  id="mberId" value= "${userId}">
+</form>
+
Add a comment
List