Browse Source

Merge branch 'develop' into eskim

eskim 5 years ago
parent
commit
0e07cc4be8
20 changed files with 1475 additions and 553 deletions
  1. 49 1
      src/main/java/com/style24/admin/biz/dao/TsaCouponDao.java
  2. 28 0
      src/main/java/com/style24/admin/biz/dao/TsaCustomerDao.java
  3. 98 86
      src/main/java/com/style24/admin/biz/service/TsaCouponService.java
  4. 33 0
      src/main/java/com/style24/admin/biz/service/TsaCustomerService.java
  5. 30 6
      src/main/java/com/style24/admin/biz/web/TsaCustomerController.java
  6. 9 2
      src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
  7. 48 4
      src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java
  8. 21 2
      src/main/java/com/style24/persistence/domain/Coupon.java
  9. 6 0
      src/main/java/com/style24/persistence/domain/CustomerSearch.java
  10. 78 13
      src/main/java/com/style24/persistence/mybatis/shop/TsaCoupon.xml
  11. 168 13
      src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml
  12. 37 39
      src/main/webapp/WEB-INF/views/customer/CellphoneChangePopupForm.html
  13. 127 97
      src/main/webapp/WEB-INF/views/customer/CustomerActiveListForm.html
  14. 92 61
      src/main/webapp/WEB-INF/views/customer/CustomerDormantListForm.html
  15. 39 7
      src/main/webapp/WEB-INF/views/customer/CustomerSecedeListForm.html
  16. 43 45
      src/main/webapp/WEB-INF/views/customer/EmailPopupForm.html
  17. 36 38
      src/main/webapp/WEB-INF/views/customer/LmsPopupForm.html
  18. 325 82
      src/main/webapp/WEB-INF/views/marketing/CouponPopupForm.html
  19. 199 55
      src/main/webapp/WEB-INF/views/order/ExchangeRequestForm.html
  20. 9 2
      src/main/webapp/WEB-INF/views/order/OrderDetailForm.html

+ 49 - 1
src/main/java/com/style24/admin/biz/dao/TsaCouponDao.java

@@ -211,9 +211,57 @@ public interface TsaCouponDao {
 
 	/**
 	 * 동일 쿠폰명이 존재하는지 확인
-	 * @param param
+	 * @param cpnId
 	 * @author xodud1202
 	 * @since 2021. 01. 26
 	 */
 	ArrayList<CustCoupon> getRandomCouponInfo(int cpnId);
+
+	/**
+	 * 쿠폰사용가능고객등급
+	 * @param params
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	void createCouponCustGubun(Coupon params);
+
+	/**
+	 * 쿠폰사용가능고객등급
+	 * @param params
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	void createCouponCustGrade(Coupon params);
+
+	/**
+	 * 쿠폰사용가능결제수단
+	 * @param params
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	void createCouponPayType(Coupon params);
+
+	/**
+	 * 쿠폰사용가능고객구분 조회
+	 * @param cpnId
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	ArrayList<Coupon> getCouponCustGbList(int cpnId);
+
+	/**
+	 * 쿠폰사용가능고객등급 조회
+	 * @param cpnId
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	ArrayList<Coupon> getCouponCustGradeList(int cpnId);
+
+	/**
+	 * 쿠폰사용가능결제수단 조회
+	 * @param cpnId
+	 * @author bin2107
+	 * @since 2021. 02. 02
+	 */
+	ArrayList<Coupon> getCouponPayTypeList(int cpnId);
 }

+ 28 - 0
src/main/java/com/style24/admin/biz/dao/TsaCustomerDao.java

@@ -28,6 +28,15 @@ import java.util.Collection;
 @Repository
 public interface TsaCustomerDao {
 
+	/**
+	 * 활동회원 건수
+	 * @param customerSearch - 검색조건
+	 * @return int
+	 * @author jsshin
+	 * @since 2021. 2. 01
+	 */
+	int getCustomerActiveListCount(CustomerSearch customerSearch);
+
 	/**
 	 * 활동회원 목록
 	 * @param customerSearch - 검색조건
@@ -180,6 +189,15 @@ public interface TsaCustomerDao {
 	 */
 	Collection<CustContactHst> getCustomerContactList(Integer custNo);
 
+	/**
+	 * 탈퇴회원 목록 건수
+	 * @param customerSearch - 검색조건
+	 * @return Collection<Customer>
+	 * @author jsshin
+	 * @since 2021. 02. 01
+	 */
+	int getCustomerSecedeListCount(CustomerSearch customerSearch);
+
 	/**
 	 * 탈퇴회원 목록
 	 * @param customerSearch - 검색조건
@@ -189,6 +207,15 @@ public interface TsaCustomerDao {
 	 */
 	Collection<Customer> getCustomerSecedeList(CustomerSearch customerSearch);
 
+	/**
+	 * 휴면회원 목록 건수
+	 * @param customerSearch - 검색조건
+	 * @return Collection<Customer>
+	 * @author jsshin
+	 * @since 2021. 02. 01
+	 */
+	int getCustomerDormantListCount(CustomerSearch customerSearch);
+
 	/**
 	 * 휴면회원 목록
 	 * @param customerSearch - 검색조건
@@ -201,4 +228,5 @@ public interface TsaCustomerDao {
 	void createException();
 
 
+
 }

+ 98 - 86
src/main/java/com/style24/admin/biz/service/TsaCouponService.java

@@ -44,107 +44,86 @@ public class TsaCouponService {
 		params.setRegNo(TsaSession.getInfo().getUserNo());
 		params.setUpdNo(TsaSession.getInfo().getUserNo());
 
-		couponDao.couponInsert(params);
+		if(cpnId != 0) {    //수정모드일때
 
-		Gson gson = new Gson();
-		Integer sequence;
-		// 적용대상 - 공급업체
-		Collection<CouponRefval> supplyCompList = gson.fromJson(params.getSupplyCompList() , new TypeToken<Collection<CouponRefval>>(){}.getType());
-		for(CouponRefval supplyComp : supplyCompList) {
-			sequence = null;
-
-			if(supplyComp.getCpnRefvalSq() != null && supplyComp.getCpnRefvalSq() > 0){
-				sequence = supplyComp.getCpnRefvalSq();
-			}
-
-			supplyComp.setCpnId(cpnId);
-			supplyComp.setCpnRefvalSq(sequence);
-			supplyComp.setCpnTarget("G260_13");
-			supplyComp.setRefVal(supplyComp.getSupplyCompCd());
-			supplyComp.setRegNo(TsaSession.getInfo().getUserNo());
-			supplyComp.setUpdNo(TsaSession.getInfo().getUserNo());
-			couponDao.saveCouponRefVal(supplyComp);
-		}
-		// 적용대상 - 브랜드
-		Collection<CouponRefval> brandList = gson.fromJson(params.getBrandList() , new TypeToken<Collection<CouponRefval>>(){}.getType());
-		for(CouponRefval brand : brandList) {
-			sequence = null;
+		}else{	//등록모드일때
+			params.setCpnStat("G232_10");
+			couponDao.couponInsert(params);
 
-			if(brand.getCpnRefvalSq() != null && brand.getCpnRefvalSq() > 0){
-				sequence = brand.getCpnRefvalSq();
+			for(int i=0; i<params.getUsableCustGbArr().length; i++){
+				params.setUsableCustGb(params.getUsableCustGbArr()[i]);
+				couponDao.createCouponCustGubun(params);
 			}
 
-			brand.setCpnId(cpnId);
-			brand.setCpnRefvalSq(sequence);
-			brand.setCpnTarget("G260_12");
-			brand.setRefVal(brand.getBrandCd());
-			brand.setRegNo(TsaSession.getInfo().getUserNo());
-			brand.setUpdNo(TsaSession.getInfo().getUserNo());
+			for(int i=0; i<params.getUsableCustGradeArr().length; i++){
+				params.setUsableCustGrade(params.getUsableCustGradeArr()[i]);
+				couponDao.createCouponCustGrade(params);
+			}
 
-			couponDao.saveCouponRefVal(brand);
+			for(int i=0; i<params.getPayTypeArr().length; i++){
+				params.setPayType(params.getPayTypeArr()[i]);
+				couponDao.createCouponPayType(params);
+			}
 		}
-		// 적용대상 - 적용상품
-		Collection<CouponRefval> applyGoodsList = gson.fromJson(params.getApplyGoodsList() , new TypeToken<Collection<CouponRefval>>(){}.getType());
-		for(CouponRefval applyGoods : applyGoodsList ) {
-			sequence = null;
 
-			if(applyGoods.getCpnRefvalSq() != null && applyGoods.getCpnRefvalSq() > 0){
-				sequence = applyGoods.getCpnRefvalSq();
-			}
-			applyGoods.setCpnId(cpnId);
-			applyGoods.setCpnRefvalSq(sequence);
-			applyGoods.setCpnTarget("G260_10");
-			applyGoods.setRefVal(applyGoods.getGoodsCd());
-			applyGoods.setRegNo(TsaSession.getInfo().getUserNo());
-			applyGoods.setUpdNo(TsaSession.getInfo().getUserNo());
-
-			couponDao.saveCouponRefVal(applyGoods);
+		// 공급업체 등록
+		for(CouponRefval compRefval : params.getSupplyCompList()){
+			compRefval.setCpnId(params.getCpnId());
+			compRefval.setCpnTarget("G260_13");
+			compRefval.setRefVal(compRefval.getSupplyCompCd());
+			compRefval.setRegNo(params.getRegNo());
+			compRefval.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponRefVal(compRefval);
 		}
-		// 적용대상 - 카테고리
-		Collection<CouponRefval> cateList = gson.fromJson(params.getCateList() , new TypeToken<Collection<CouponRefval>>(){}.getType());
-		for(CouponRefval cate : cateList ) {
-			sequence = null;
 
-			if(cate.getCpnRefvalSq() != null && cate.getCpnRefvalSq() > 0){
-				sequence = cate.getCpnRefvalSq();
-			}
-			cate.setCpnId(cpnId);
-			cate.setCpnRefvalSq(sequence);
-			cate.setCpnTarget("G260_11");
-			cate.setRefVal(cate.getCateNo());
-			cate.setRefFormalGb(cate.getFormalGb());
-			cate.setRefBrandCd(cate.getBrandCd());		// ag-grid 브랜드코드
-			cate.setRegNo(TsaSession.getInfo().getUserNo());
-			cate.setUpdNo(TsaSession.getInfo().getUserNo());
-
-			couponDao.saveCouponRefVal(cate);
+		// 브랜드 등록
+		for(CouponRefval brandRefval : params.getBrandList()){
+			brandRefval.setCpnId(params.getCpnId());
+			brandRefval.setCpnTarget("G260_12");
+			brandRefval.setRefVal(brandRefval.getBrandCd());
+			brandRefval.setRegNo(params.getRegNo());
+			brandRefval.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponRefVal(brandRefval);
 		}
-		// 적용대상 - 제외상품
-		Collection<CouponRefval> exceptGoodsList = gson.fromJson(params.getExceptGoodsList() , new TypeToken<Collection<CouponRefval>>(){}.getType());
-		for(CouponRefval exceptGoods: exceptGoodsList ) {
-			sequence = null;
 
-			if(exceptGoods.getCpnRefvalSq() != null && exceptGoods.getCpnRefvalSq() > 0){
-				sequence = exceptGoods.getCpnRefvalSq();
-			}
+		// 적용상품
+		for(CouponRefval applyGoodsRefval : params.getApplyGoodsList()){
+			applyGoodsRefval.setCpnId(params.getCpnId());
+			applyGoodsRefval.setCpnTarget("G260_10");
+			applyGoodsRefval.setRefVal(applyGoodsRefval.getGoodsCd());
+			applyGoodsRefval.setRegNo(params.getRegNo());
+			applyGoodsRefval.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponRefVal(applyGoodsRefval);
+		}
 
-			exceptGoods.setCpnId(cpnId);
-			exceptGoods.setCpnRefvalSq(sequence);
-			exceptGoods.setCpnTarget("G260_14");
-			exceptGoods.setRefVal(exceptGoods.getGoodsCd());
-			exceptGoods.setRegNo(TsaSession.getInfo().getUserNo());
-			exceptGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+		// 카테고리
+		for(CouponRefval cateRefval : params.getCateList()){
+			cateRefval.setCpnId(params.getCpnId());
+			cateRefval.setCpnTarget("G260_11");
+			cateRefval.setRefVal(cateRefval.getCateNo());
+			cateRefval.setFormalGb(cateRefval.getFormalGb());
+			cateRefval.setBrandCd(cateRefval.getBrandCd());
+			cateRefval.setRegNo(params.getRegNo());
+			cateRefval.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponRefVal(cateRefval);
+		}
 
-			couponDao.saveCouponRefVal(exceptGoods);
+		// 제외상품
+		for(CouponRefval exceptGoodsRefval : params.getExceptGoodsList()){
+			exceptGoodsRefval.setCpnId(params.getCpnId());
+			exceptGoodsRefval.setCpnTarget("G260_14");
+			exceptGoodsRefval.setRefVal(exceptGoodsRefval.getGoodsCd());
+			exceptGoodsRefval.setRegNo(params.getRegNo());
+			exceptGoodsRefval.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponRefVal(exceptGoodsRefval);
 		}
-		// 입점업체분담율
-		Collection<CouponBurden> burdenList = gson.fromJson(params.getBurdenList() , new TypeToken<Collection<CouponBurden>>(){}.getType());
-		for(CouponBurden burden: burdenList ) {
-			burden.setCpnId(cpnId);
-			burden.setRegNo(TsaSession.getInfo().getUserNo());
-			burden.setUpdNo(TsaSession.getInfo().getUserNo());
 
-			couponDao.saveCouponBurden(burden);
+		// 입점업체분담율
+		for(CouponBurden couponBurden : params.getBurdenList()){
+			couponBurden.setCpnId(params.getCpnId());
+			couponBurden.setRegNo(params.getRegNo());
+			couponBurden.setUpdNo(params.getUpdNo());
+			couponDao.saveCouponBurden(couponBurden);
 		}
 
 		// 수정모드이고 변경된 쿠폰상태가 대기 , 중지 인경우 고객이 발급받은 내용도 변경
@@ -420,4 +399,37 @@ public class TsaCouponService {
 	public void saveCouponIssue(CustCoupon coupon) {
 		couponDao.saveCouponCustPub(coupon);
 	}
+
+	/**
+	 * 쿠폰사용가능고객구분 조회
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021-02-02
+	 */
+	public ArrayList<Coupon> getCouponCustGbList(int cpnId) {
+		return couponDao.getCouponCustGbList(cpnId);
+	}
+
+	/**
+	 * 쿠폰사용가능고객등급 조회
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021-02-02
+	 */
+	public ArrayList<Coupon> getCouponCustGradeList(int cpnId) {
+		return couponDao.getCouponCustGradeList(cpnId);
+	}
+
+	/**
+	 * 쿠폰사용가능결제수단 조회
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021-02-02
+	 */
+	public ArrayList<Coupon> getCouponPayTypeList(int cpnId) {
+		return couponDao.getCouponPayTypeList(cpnId);
+	}
 }

+ 33 - 0
src/main/java/com/style24/admin/biz/service/TsaCustomerService.java

@@ -41,6 +41,17 @@ public class TsaCustomerService {
 	@Autowired
 	private TscCustomerService coreCustomerService;
 
+	/**
+	 * 활동회원 건수
+	 * @param customerSearch - 검색조건
+	 * @return int
+	 * @author jsshin
+	 * @since 2021. 2. 01
+	 */
+	public int getCustomerActiveListCount(CustomerSearch customerSearch) {
+		return  customerDao.getCustomerActiveListCount(customerSearch);
+	}
+
 	/**
 	 * 활동회원 목록
 	 * @param customerSearch - 검색조건
@@ -298,6 +309,17 @@ public class TsaCustomerService {
 		coreCustomerService.createCustomerContactHistory(custContactHst);
 	}
 
+	/**
+	 * 탈퇴회원 목록 건수
+	 * @param customerSearch - 검색조건
+	 * @return Collection<Customer>
+	 * @author jsshin
+	 * @since 2021. 02. 01
+	 */
+	public int getCustomerSecedeListCount(CustomerSearch customerSearch) {
+		return customerDao.getCustomerSecedeListCount(customerSearch);
+	}
+
 	/**
 	 * 탈퇴회원 목록
 	 * @param customerSearch - 검색조건
@@ -309,6 +331,17 @@ public class TsaCustomerService {
 		return customerDao.getCustomerSecedeList(customerSearch);
 	}
 
+	/**
+	 * 휴면회원 목록 건수
+	 * @param customerSearch - 검색조건
+	 * @return Collection<Customer>
+	 * @author jsshin
+	 * @since 2021. 02. 01
+	 */
+	public int getCustomerDormantListCount(CustomerSearch customerSearch) {
+		return customerDao.getCustomerDormantListCount(customerSearch);
+	}
+
 	/**
 	 * 휴면회원 목록
 	 * @param customerSearch - 검색조건

+ 30 - 6
src/main/java/com/style24/admin/biz/web/TsaCustomerController.java

@@ -12,6 +12,7 @@ import com.style24.admin.biz.service.TsaSystemService;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.session.TscSession;
 import com.style24.core.support.util.CryptoUtils;
+import com.style24.persistence.TscPageRequest;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.CustContactHst;
 import com.style24.persistence.domain.CustGrade;
@@ -309,9 +310,17 @@ public class TsaCustomerController extends TsaBaseController {
 	 */
 	@PostMapping("/active/list")
 	@ResponseBody
-	public Collection<Customer> getCustomerActiveList(@RequestBody CustomerSearch customerSearch) {
+	public GagaMap getCustomerActiveList(@RequestBody CustomerSearch customerSearch) {
+		GagaMap result = new GagaMap();
+		customerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		log.info("customerSearch.toString() {}", customerSearch.toString());
+		customerSearch.setPageable(new TscPageRequest(customerSearch.getPageNo()-1, customerSearch.getPageSize()));
+		customerSearch.getPageable().setTotalCount(customerService.getCustomerActiveListCount(customerSearch));
 		TscSession.setAttribute("maskingYn", TsaSession.getInfo().getMaskingYn());
-		return customerService.getCustomerActiveList(customerSearch);
+
+		result.set("pageing", customerSearch);
+		result.set("custList", customerService.getCustomerActiveList(customerSearch));
+		return result;
 	}
 
 	/**
@@ -902,9 +911,17 @@ public class TsaCustomerController extends TsaBaseController {
 	 */
 	@PostMapping("/secede/list")
 	@ResponseBody
-	public Collection<Customer> getCustomerSecedeList(@RequestBody CustomerSearch customerSearch) {
+	public GagaMap getCustomerSecedeList(@RequestBody CustomerSearch customerSearch) {
+		GagaMap result = new GagaMap();
+		customerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		customerSearch.setPageable(new TscPageRequest(customerSearch.getPageNo() - 1, customerSearch.getPageSize()));
+		customerSearch.getPageable().setTotalCount(customerService.getCustomerSecedeListCount(customerSearch));
+
 		TscSession.setAttribute("maskingYn", TsaSession.getInfo().getMaskingYn());
-		return customerService.getCustomerSecedeList(customerSearch);
+		result.set("pageing", customerSearch);
+		result.set("custList", customerService.getCustomerSecedeList(customerSearch));
+
+		return result;
 	}
 
 	/**
@@ -934,9 +951,16 @@ public class TsaCustomerController extends TsaBaseController {
 	 */
 	@PostMapping("/dormant/list")
 	@ResponseBody
-	public Collection<Customer>getCustomerDormantList(@RequestBody CustomerSearch customerSearch) {
+	public GagaMap getCustomerDormantList(@RequestBody CustomerSearch customerSearch) {
+		GagaMap result = new GagaMap();
+		customerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		customerSearch.setPageable(new TscPageRequest(customerSearch.getPageNo() - 1, customerSearch.getPageSize()));
+		customerSearch.getPageable().setTotalCount(customerService.getCustomerDormantListCount(customerSearch));
 		TscSession.setAttribute("maskingYn", TsaSession.getInfo().getMaskingYn());
-		return customerService.getCustomerDormantList(customerSearch);
+
+		result.set("pageing", customerSearch);
+		result.set("custList", customerService.getCustomerDormantList(customerSearch));
+		return result;
 	}
 
 

+ 9 - 2
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -429,7 +429,8 @@ public class TsaMarketingController extends TsaBaseController {
 		// 쿠폰 유형 조회
 		mav.addObject("cpnTypeList", rendererService.getCommonCodeList("G230", "Y"));
 		// 사용가능 고객구분 조회
-		mav.addObject("usableCustGbList", rendererService.getCommonCodeList("G100"));
+		String[] exceptCds1 = {"G100_00"};
+		mav.addObject("usableCustGbList", rendererService.getCommonCodeList("G100", "Y", exceptCds1));
 		// 사용가능 고객등급 조회
 		mav.addObject("usableCustGradeList", rendererService.getCommonCodeList("G110"));
 		// 재발급 여부 조회
@@ -463,6 +464,12 @@ public class TsaMarketingController extends TsaBaseController {
 			mav.addObject("cpnDtlBurdenList", couponService.getCouponBurdenList(cpnId));
 			// 시리얼 및 난수 쿠폰 조회
 			mav.addObject("randomCpnList", couponService.getRandomCouponInfo(cpnId));
+			// 쿠폰사용가능고객구분 조회
+			mav.addObject("cpnCustGbList", couponService.getCouponCustGbList(cpnId));
+			// 쿠폰사용가능고객등급 조회
+			mav.addObject("cpnCustGradeList", couponService.getCouponCustGradeList(cpnId));
+			// 쿠폰사용가능결제수단 조회
+			mav.addObject("cpnPayTypeList", couponService.getCouponPayTypeList(cpnId));
 		}
 
 		//issueCnt = 3;
@@ -1092,7 +1099,7 @@ public class TsaMarketingController extends TsaBaseController {
 
 	/**
 	 * 카드무이자할부 저장
-	 * @param point - 포인트 정보
+	 * @param cardPromotion - 포인트 정보
 	 * @return ModelAndView
 	 * @author eskim
 	 * @since 2021. 2. 1

+ 48 - 4
src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java

@@ -454,12 +454,13 @@ public class TsaOrderChangeController extends TsaBaseController {
 	 * @since 2021. 01. 14
 	 */
 	@GetMapping("/exchange/request/form")
-	public ModelAndView exchangeRequestFrom(@RequestParam(value = "ordNo") int ordNo) {
+	public ModelAndView exchangeRequestFrom(@RequestParam(value = "ordNo") int ordNo, @RequestParam(value = "ordChgSq") int ordChgSq) {
 
 		Order order = new Order();
 		ModelAndView mav = new ModelAndView();
 
 		order.setOrdNo(ordNo);
+		order.setOrdChgSq(ordChgSq);
 
 		// 교환가능 주문상세상탭값 설정
 		String[] ordDtlStatArr = new String[3];
@@ -469,13 +470,18 @@ public class TsaOrderChangeController extends TsaBaseController {
 		order.setOrdDtlStatArr(ordDtlStatArr);
 
 		Collection<Order> cancelRequestTargetList = orderChangeService.getCancelRequestTargetList(order);
-
 		Collection<Order> orderInfoList = orderService.getOrderInfoList(order);
 
+		if (ordChgSq > 0) {
+			Collection<Order> exchangeInfoList = orderChangeService.getExchangeInfo(order);
+			mav.addObject("exchangeInfoList"		, exchangeInfoList);								// 교환정보
+		}
+
 		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G689"));	// 교환사유
 		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);							// 교환요청대상 목록
 		mav.addObject("orderInfoList"				, orderInfoList);									// 주문정보
-		mav.addObject("ordNo"						, ordNo);
+		mav.addObject("ordNo"						, ordNo);											// 주문번호
+		mav.addObject("ordChgSq"					, ordChgSq);										// 주문변경번호
 		mav.addObject("orderDelvAddrInfo"			, orderService.getDeliveryAddrList(order));			// 배송정보
 		mav.addObject("TelExcNoList"				, rendererService.getAvailCommonCodeList("G095"));	// 전화번호국번
 		mav.addObject("PhnExcNoList"				, rendererService.getAvailCommonCodeList("G096"));	// (휴대전화)번호국번
@@ -490,7 +496,7 @@ public class TsaOrderChangeController extends TsaBaseController {
 	 *
 	 * @param Collection<OrderChange>
 	 * @return
-	 * @author card007
+	 * @author card007rtn
 	 * @since 2021. 01. 22
 	 */
 	@PostMapping("/exchangeRequest")
@@ -523,6 +529,44 @@ public class TsaOrderChangeController extends TsaBaseController {
 		return result;
 	}
 
+	/**
+	 * 교환신청 (관리자)
+	 *
+	 * @param Collection<OrderChange>
+	 * @return
+	 * @author card007rtn
+	 * @since 2021. 01. 22
+	 */
+	@PostMapping("/exchangeCancelRequest")
+	@ResponseBody
+	public GagaMap orderExchangeCancelRequest(@RequestBody OrderChange excReq) {
+		GagaMap result = new GagaMap();
+		result.set("status", GagaResponseStatus.FAIL.getCode());
+
+		// 교환요청 데이터 확인
+		if (excReq == null) {
+			result.set("message", message.getMessage("FAIL_1001"));
+			return result;
+		}
+
+		// 세션 회원번호 설정
+		int userNo = TsaSession.getInfo().getUserNo();
+		excReq.setUpdNo(userNo);
+		excReq.setRegNo(userNo);
+
+		// 교환처리
+		result = orderChangeService.exchangeCancel(excReq);
+
+		// 처리 결과 코드에 따른 메세지 설정
+		if (result.get("status").equals(GagaResponseStatus.SUCCESS.getCode())) {
+			result.set("message", message.getMessage("SUCC_0004"));
+		} else {
+			result.set("message", message.getMessage("FAIL_0004"));
+		}
+
+		return result;
+	}
+
 	/**
 	 * 취소요청 (ADMIN, NAPY, 외부몰) (배치) (사용안함)
 	 * 

+ 21 - 2
src/main/java/com/style24/persistence/domain/Coupon.java

@@ -5,6 +5,7 @@ import com.style24.persistence.TscBaseDomain;
 import com.style24.persistence.TscPageRequest;
 import lombok.Data;
 
+import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -60,16 +61,34 @@ public class Coupon extends TscBaseDomain {
     private String rdCpnNm;                 // 랜덤쿠폰 사용키 (시리얼명 or 난수)
 
     // 그리드 파라미터
-    private String supplyCompList;          // 공급업체 리스트
+    /*private String supplyCompList;          // 공급업체 리스트
     private String brandList;               // 브랜드 리스트
     private String applyGoodsList;          // 적용상품 리스트
     private String exceptGoodsList;         // 제외상품 리스트
     private String cateList;                // 카테고리 리스트
-    private String burdenList;              // 업체 분담율 리스트
+    private String burdenList;              // 업체 분담율 리스트*/
+    List<CouponRefval> supplyCompList;          // 공급업체 리스트
+    List<CouponRefval> brandList;               // 브랜드 리스트
+    List<CouponRefval> applyGoodsList;          // 적용상품 리스트
+    List<CouponRefval> exceptGoodsList;         // 제외상품 리스트
+    List<CouponRefval> cateList;                // 카테고리 리스트
+    List<CouponBurden> burdenList;              // 업체 분담율 리스트
 
     // TB_COUPON_BAN_GOODS
     private int    cpnBanGoodsSq;           //  제외상품시퀀스
 
+    // 사용가능고객구분
+    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+    private String[] usableCustGbArr;
+
+    // 사용가능고객등급
+    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+    private String[] usableCustGradeArr;
+
+    // 결제수단
+    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+    private String[] payTypeArr;
+
     // Pagination
     private TscPageRequest pageable;
     private int pageNo = 1;

+ 6 - 0
src/main/java/com/style24/persistence/domain/CustomerSearch.java

@@ -1,6 +1,7 @@
 package com.style24.persistence.domain;
 
 import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
 import lombok.Data;
 
 /**
@@ -33,4 +34,9 @@ public class CustomerSearch extends TscBaseDomain {
 	private String email;
 	private String custId;
 
+	private TscPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+
 }

+ 78 - 13
src/main/java/com/style24/persistence/mybatis/shop/TsaCoupon.xml

@@ -102,13 +102,11 @@
 	</select>
 
 	<!-- 쿠폰 등록 -->
-	<insert id="couponInsert" parameterType="Coupon">
+	<insert id="couponInsert" parameterType="Coupon" keyProperty="cpnId">
 		/* TsaCoupon.couponInsert*/
-		<selectKey keyProperty="cpnId" resultType="int" order="AFTER">
-			SELECT LAST_INSERT_ID()
-		</selectKey>
 		INSERT INTO TB_COUPON (
-		    CPN_NM
+		    CPN_ID
+		  , CPN_NM
 		  , SITE_CD
 		  , AF_LINK_CD
 		  , CPN_TYPE
@@ -146,7 +144,8 @@
 		  , BUY_EDDT
 		  , NEW_CUST_YN
 		) VALUES (
-		    #{cpnNm}
+		   #{cpnId}
+		  , #{cpnNm}
 		  , #{siteCd}
 		  , #{afLinkCd}
 		  , #{cpnType}
@@ -303,13 +302,11 @@
 	</select>
 
 	<!-- 쿠폰 적용대상 등록 -->
-	<insert id="saveCouponRefVal" parameterType="Coupon">
+	<insert id="saveCouponRefVal" parameterType="CouponRefval" keyProperty="cpnRefvalSq">
 		/* TsaCoupon.saveCouponRefVal */
 		INSERT INTO TB_COUPON_REFVAL (
 		    CPN_ID
-		  <if test='cpnRefvalSq != null and cpnRefvalSq > 0'>
 		  , CPN_REFVAL_SQ
-		  </if>
 		  , CPN_TYPE
 		  , CPN_TARGET
 		  , REF_VAL
@@ -325,9 +322,7 @@
 		  , UPD_DT
 		)
 		SELECT CPN_ID
-		     <if test="cpnRefvalSq != null and cpnRefvalSq > 0">
 			 , #{cpnRefvalSq}
-			 </if>
 			 , CPN_TYPE
 			 , #{cpnTarget}
 			 , #{refVal}
@@ -471,11 +466,9 @@
 		/* TsaCoupon.getCouponRefvalExceptGoodsList */
 		SELECT B.BRAND_CD
 			 , B.BRAND_ENM
-		     , C.SUPPLY_COMP_NM
 			 , A.CPN_REFVAL_SQ
 		  FROM TB_COUPON_REFVAL A
 		 INNER JOIN TB_BRAND B ON A.REF_VAL = B.BRAND_CD
-		 INNER JOIN TB_SUPPLY_COMPANY C ON B.SUPPLY_COMP_CD = C.SUPPLY_COMP_CD
 		 WHERE A.CPN_ID = #{cpnId}
 		   AND A.CPN_TARGET = #{cpnTarget}
 		   AND A.DEL_YN = 'N'
@@ -674,4 +667,76 @@
 		AND C.CUST_NO = CC.CUST_NO
 		WHERE RC.CPN_ID = #{cpnId}
 	</select>
+
+	<insert id="createCouponCustGubun" parameterType="Coupon">
+		/* TsaCoupon.createCouponCustGubun */
+		INSERT INTO TB_COUPON_CUST_GBN (
+				 CPN_ID
+				, USABLE_CUST_GB
+				, REG_NO
+				, REG_DT
+		) VALUES (
+				#{cpnId}
+				, #{usableCustGb}
+				, #{regNo}
+				, CURRENT_TIMESTAMP()
+		)
+	</insert>
+
+	<insert id="createCouponCustGrade" parameterType="Coupon">
+		/* TsaCoupon.createCouponCustGrade */
+		INSERT INTO TB_COUPON_CUST_GRADE (
+			CPN_ID
+			, USABLE_CUST_GRADE
+			, REG_NO
+			, REG_DT
+		) VALUES (
+			#{cpnId}
+			, #{usableCustGrade}
+			, #{regNo}
+			, CURRENT_TIMESTAMP()
+		)
+	</insert>
+
+	<insert id="createCouponPayType" parameterType="Coupon">
+		/* TsaCoupon.createCouponPayType */
+		INSERT INTO TB_COUPON_PAYTYPE (
+			CPN_ID
+			, PAY_TYPE
+			, REG_NO
+			, REG_DT
+		) VALUES (
+			 #{cpnId}
+			 , #{payType}
+			 , #{regNo}
+			 , CURRENT_TIMESTAMP()
+		)
+	</insert>
+
+	<!-- 쿠폰사용가능고객구분 조회-->
+	<select id="getCouponCustGbList" parameterType="int" resultType="Coupon">
+		/* TsaCoupon.getCouponCustGbList */
+		SELECT CPN_ID
+			 , USABLE_CUST_GB
+		FROM TB_COUPON_CUST_GBN
+		WHERE CPN_ID = #{cpnId}
+	</select>
+
+	<!-- 쿠폰사용가능고객등급 조회-->
+	<select id="getCouponCustGradeList" parameterType="int" resultType="Coupon">
+		/* TsaCoupon.getCouponCustGradeList */
+		SELECT CPN_ID
+			 , USABLE_CUST_GRADE
+		FROM TB_COUPON_CUST_GRADE
+		WHERE CPN_ID = #{cpnId}
+	</select>
+
+	<!-- 쿠폰사용가능결제수단 조회-->
+	<select id="getCouponPayTypeList" parameterType="int" resultType="Coupon">
+		/* TsaCoupon.getCouponPayTypeList */
+		SELECT CPN_ID
+			 , PAY_TYPE
+		FROM TB_COUPON_PAYTYPE
+		WHERE CPN_ID = #{cpnId}
+	</select>
 </mapper>

+ 168 - 13
src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml

@@ -2,9 +2,85 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.style24.admin.biz.dao.TsaCustomerDao">
 
+	<!-- 페이징을 위한 select절 상단 -->
+	<sql id="selectForPagingHeader">
+		SELECT *
+		FROM (
+	</sql>
+
+	<!-- 페이징을 위한 select절 하단 -->
+	<sql id="selectForPagingFooter">
+		) ORIGINAL
+		WHERE NUMB BETWEEN #{pageable.startRow} AND #{pageable.endRow}
+	</sql>
+
+	<!-- 활동회원목록 -->
+	<select id="getCustomerActiveListCount" parameterType="CustomerSearch" resultType="int">
+		/* TsaCustomer.getCustomerActiveListCount */
+		SELECT COUNT(*) AS CNT
+		FROM   TB_CUSTOMER
+		WHERE  CUST_STAT = 'G104_10'
+		<if test="searchGb == 'custNo'">
+		AND    CUST_NO = #{searchTxt}
+		</if>
+		<if test="searchGb == 'custNm'">
+		AND    LOWER(CUST_NM) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		</if>
+		<if test="searchGb == 'email'">
+		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		</if>
+		<if test="searchGb == 'custId'">
+		AND    LOWER(CUST_ID) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		</if>
+		<if test="siteCd != null and siteCd != ''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="cellPhnno != null and cellPhnno != ''">
+		AND    CELL_PHNNO = #{cellPhnno}
+		</if>
+		<if test="custGb != null and custGb != ''">
+		AND    CUST_GB = #{custGb}
+		</if>
+		<if test="custGrade != null and custGrade != ''">
+		AND    CUST_GRADE = #{custGrade}
+		</if>
+		<if test="managedRsn != null and managedRsn != ''">
+		AND    MANAGED_RSN = #{managedRsn}
+		</if>
+		<if test="smsAgreeYn != null and smsAgreeYn != ''">
+		AND   SMS_AGREE_YN = #{smsAgreeYn}
+		</if>
+		<if test="emailAgreeYn != null and emailAgreeYn != ''">
+		AND   EMAIL_AGREE_YN = #{emailAgreeYn}
+		</if>
+		<if test="appAgreeYn != null and appAgreeYn != ''">
+		AND   APP_AGREE_YN = #{appAgreeYn}
+		</if>
+		<if test="stDate != null and edDate != '' and stDate != null and edDate != ''">
+		     <if test="searchDateGb == 'joinDt'">
+		AND   JOIN_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		AND   JOIN_DT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		     </if>
+		     <if test="searchDateGb == 'loginLdt'">
+		AND   LOGIN_LDT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		AND   LOGIN_LDT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		     </if>
+		</if>
+		<if test="custNm != null and custNm != ''">
+		AND    LOWER(CUST_NM) LIKE CONCAT('%',LOWER(#{custNm}),'%')
+		</if>
+		<if test="email != null and email != ''">
+		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{eamil}),'%')
+		</if>
+		<if test="custId != null and custId != ''">
+		AND    CUST_ID = #{custId}
+		</if>
+	</select>
+
 	<!-- 활동회원목록 -->
 	<select id="getCustomerActiveList" parameterType="CustomerSearch" resultType="Customer">
 		/* TsaCustomer.getCustomerActiveList */
+		<include refid="selectForPagingHeader"/>
 		SELECT CUST_NO
 		     , CUST_ID
 		     , CUST_NM
@@ -51,10 +127,16 @@
 		     , SECEDE_RSN
 		     , SECEDE_DTL_RSN
 		     , DATE_FORMAT(SECEDE_DT, '%Y%m%d%H%i%S') AS SECEDE_DT
-		     , FN_GET_USER_NM(REG_NO)              AS REG_NM
-		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S') AS REG_DT
-		     , FN_GET_USER_NM(UPD_NO)              AS UPD_NM
-		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S') AS UPD_DT
+		     , FN_GET_USER_NM(REG_NO)                 AS REG_NM
+		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S')    AS REG_DT
+		     , FN_GET_USER_NM(UPD_NO)                 AS UPD_NM
+		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S')    AS UPD_DT
+		     <if test="searchDateGb == 'joinDt'">
+		     , RANK() OVER(ORDER BY JOIN_DT DESC)     AS NUMB
+		     </if>
+		     <if test="searchDateGb == 'loginLdt'">
+		     , RANK() OVER(ORDER BY LOGIN_LDT DESC)   AS NUMB
+		     </if>
 		FROM   TB_CUSTOMER
 		WHERE  CUST_STAT = 'G104_10'
 		<if test="searchGb == 'custNo'">
@@ -112,6 +194,7 @@
 		<if test="custId != null and custId != ''">
 		AND    CUST_ID = #{custId}
 		</if>
+		<include refid="selectForPagingFooter"/>
 	</select>
 
 	<!--회원정보 수정-->
@@ -657,8 +740,43 @@
 	</select>
 
 	<!-- 탈퇴회원목록 -->
+	<select id="getCustomerSecedeListCount" parameterType="CustomerSearch" resultType="int">
+		/* TsaCustomer.getCustomerSecedeListCount */
+		SELECT COUNT(*) AS CNT
+		FROM   TB_SECEDE_CUST
+		WHERE  CUST_STAT = 'G104_30'
+		<if test="searchTxt != null and searchTxt != ''">
+		    <if test="searchGb == 'custNo'">
+		AND    CUST_NO = #{searchTxt}
+		    </if>
+		    <if test="searchGb == 'custNm'">
+		AND    LOWER(CUST_NM) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		    <if test="searchGb == 'email'">
+		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		    <if test="searchGb == 'custNo'">
+		AND    LOWER(CUST_NO) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		</if>
+		<if test="siteCd != null and siteCd != ''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="cellPhnno != null and cellPhnno != ''">
+		AND    CELL_PHNNO = #{cellPhnno}
+		</if>
+		<if test="secedeRsn != null and secedeRsn != ''">
+		AND    SECEDE_RSN = #{secedeRsn}
+		</if>
+		<if test="stDate != null and stDate != '' and edDate != null and edDate != ''">
+		AND    SECEDE_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		AND    SECEDE_DT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		</if>
+	</select>
+
 	<select id="getCustomerSecedeList" parameterType="CustomerSearch" resultType="Customer">
 		/* TsaCustomer.getSecedeCustomerList */
+		<include refid="selectForPagingHeader"/>
 		SELECT CUST_NO
 		     , CUST_ID
 		     , CUST_NM
@@ -705,10 +823,11 @@
 		     , SECEDE_RSN
 		     , SECEDE_DTL_RSN
 		     , DATE_FORMAT(SECEDE_DT, '%Y%m%d%H%i%S') AS SECEDE_DT
-		     , FN_GET_USER_NM(REG_NO)              AS REG_NM
-		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S') AS REG_DT
-		     , FN_GET_USER_NM(UPD_NO)              AS UPD_NM
-		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S') AS UPD_DT
+		     , FN_GET_USER_NM(REG_NO)                 AS REG_NM
+		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S')    AS REG_DT
+		     , FN_GET_USER_NM(UPD_NO)                 AS UPD_NM
+		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S')    AS UPD_DT
+		     , RANK() OVER(ORDER BY SECEDE_DT DESC)   AS NUMB
 		FROM   TB_SECEDE_CUST
 		WHERE  CUST_STAT = 'G104_30'
 		<if test="searchTxt != null and searchTxt != ''">
@@ -738,11 +857,45 @@
 		AND    SECEDE_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
 		AND    SECEDE_DT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
 		</if>
+		<include refid="selectForPagingFooter"/>
+	</select>
+
+	<!-- 휴면회원목록 -->
+	<select id="getCustomerDormantListCount" parameterType="CustomerSearch" resultType="int">
+		/* TsaCustomer.getCustomerDormantListCount */
+		SELECT COUNT(*) AS CNT
+		FROM   TB_DORMANT_CUST
+		WHERE  CUST_STAT = 'G104_20'
+		<if test="searchTxt != null and searchTxt != ''">
+		    <if test="searchGb == 'custNo'">
+		AND    CUST_NO = #{searchTxt}
+		    </if>
+		    <if test="searchGb == 'custNm'">
+		AND    LOWER(CUST_NM) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		    <if test="searchGb == 'email'">
+		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		    <if test="searchGb == 'custNo'">
+		AND    LOWER(CUST_NO) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </if>
+		</if>
+		<if test="siteCd != null and siteCd != ''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="cellPhnno != null and cellPhnno != ''">
+		AND    CELL_PHNNO = #{cellPhnno}
+		</if>
+		<if test="stDate != null and stDate != '' and edDate != null and edDate != ''">
+		AND    DORMANT_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		AND    DORMANT_DT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		</if>
 	</select>
 
 	<!-- 휴면회원목록 -->
 	<select id="getCustomerDormantList" parameterType="CustomerSearch" resultType="Customer">
 		/* TsaCustomer.getDormantCustomerList */
+		<include refid="selectForPagingHeader"/>
 		SELECT CUST_NO
 		     , CUST_ID
 		     , CUST_NM
@@ -788,12 +941,13 @@
 		     , DATE_FORMAT(MANAGED_DT, '%Y%m%d%H%i%S') AS MANAGED_DT
 		     , SECEDE_RSN
 		     , SECEDE_DTL_RSN
-		     , DATE_FORMAT(SECEDE_DT, '%Y%m%d%H%i%S') AS SECEDE_DT
-		     , FN_GET_USER_NM(REG_NO)              AS REG_NM
-		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S') AS REG_DT
-		     , FN_GET_USER_NM(UPD_NO)              AS UPD_NM
-		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S') AS UPD_DT
+		     , DATE_FORMAT(SECEDE_DT, '%Y%m%d%H%i%S')  AS SECEDE_DT
+		     , FN_GET_USER_NM(REG_NO)                  AS REG_NM
+		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S')     AS REG_DT
+		     , FN_GET_USER_NM(UPD_NO)                  AS UPD_NM
+		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S')     AS UPD_DT
 		     , DATE_FORMAT(DORMANT_DT, '%Y%m%d%H%i%S') AS DORMANT_DT
+		     , RANK() OVER(ORDER BY DORMANT_DT DESC)   AS NUMB
 		FROM   TB_DORMANT_CUST
 		WHERE  CUST_STAT = 'G104_20'
 		<if test="searchTxt != null and searchTxt != ''">
@@ -820,6 +974,7 @@
 		AND    DORMANT_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
 		AND    DORMANT_DT <![CDATA[<]]> DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
 		</if>
+		<include refid="selectForPagingFooter"/>
 	</select>
 
 	<insert id="createException">

+ 37 - 39
src/main/webapp/WEB-INF/views/customer/CellphoneChangePopupForm.html

@@ -14,7 +14,7 @@
  * 1.0  2021.01.25   jsshin     최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="800">
+<div class="modelessPopup" data-width="800">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
@@ -24,45 +24,43 @@
 		<!-- //TITLE -->
 		<!-- CONTENT -->
 		<div class="panelContent">
-			<div class="panelStyle">
-				<form id="cellPhoneForm" name="cellPhoneForm">
-					<input type="hidden" id="custNo" name="custNo">
-					<table class="frmStyle">
-						<colgroup>
-							<col style="width:1%"/>
-							<col style="width:40%"/>
-						</colgroup>
-						<tbody>
-						<tr>
-							<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>인증번호 확인 후 번호변경가능 </span>
-							<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>변경 할 휴대폰번호 입력 후 전송</span> <br/>
-							<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>인증번호는 6자리 입니다.</span><br/>
-							<th>기존휴대전화번호<em class="star"></em></th>
-							<td>
-								<input type="text" class="w150" name="orgCellPhone" maxlength="13" readonly="readonly"/>
-							</td>
-							<th>변경할휴대전화번호<em class="star"></em></th>
-							<td>
-								<input type="text" class="w150" name="cellPhnno" required="required" maxlength="13" data-valid-name="휴대전화번호" />
-							</td>
-						</tr>
-						<tr id="trCertNo" style="display: none">
-							<th>인증번호</th>
-							<td>
-								<input type="text" class="w200" name="certNo" placeholder="인증번호 입력" style="display:none;">
-							</td>
-						</tr>
-						</tbody>
-					</table>
-				</form>
-			</div>
-			<ul class="panelBar">
-				<li class="right">
-					<button type="button" id="btnSendCustCrtfdNo" class="btn btn-success btn-lg" >인증번호발송</button>
-					<button type="button" id="btnCustCertNo" class="btn btn-success btn-lg" style="display: none">확인(번호변경)</button>
-				</li>
-			</ul>
+			<form id="cellPhoneForm" name="cellPhoneForm">
+				<input type="hidden" id="custNo" name="custNo">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:1%"/>
+						<col style="width:40%"/>
+					</colgroup>
+					<tbody>
+					<tr>
+						<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>인증번호 확인 후 번호변경가능 </span>
+						<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>변경 할 휴대폰번호 입력 후 전송</span> <br/>
+						<span class="infoTxt cBlue"><i class="fa fa-info-circle"></i>인증번호는 6자리 입니다.</span><br/>
+						<th>기존휴대전화번호<em class="star"></em></th>
+						<td>
+							<input type="text" class="w150" name="orgCellPhone" maxlength="13" readonly="readonly"/>
+						</td>
+						<th>변경할휴대전화번호<em class="star"></em></th>
+						<td>
+							<input type="text" class="w150" name="cellPhnno" required="required" maxlength="13" data-valid-name="휴대전화번호" />
+						</td>
+					</tr>
+					<tr id="trCertNo" style="display: none">
+						<th>인증번호</th>
+						<td>
+							<input type="text" class="w200" name="certNo" placeholder="인증번호 입력" style="display:none;">
+						</td>
+					</tr>
+					</tbody>
+				</table>
+			</form>
 		</div>
+		<ul class="panelBar">
+			<li class="right">
+				<button type="button" id="btnSendCustCrtfdNo" class="btn btn-success btn-lg" >인증번호발송</button>
+				<button type="button" id="btnCustCertNo" class="btn btn-success btn-lg" style="display: none">확인(번호변경)</button>
+			</li>
+		</ul>
 		<!-- //CONTENT -->
 	</div>
 </div>

+ 127 - 97
src/main/webapp/WEB-INF/views/customer/CustomerActiveListForm.html

@@ -26,109 +26,128 @@
 	<!-- //메뉴 설명 -->
 
 	<!-- 검색조건 영역 -->
-	<div class="panelStyle">
-		<form id="searchForm" name="searchForm" action="#" th:action="@{'/customer/active/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
-			<table class="frmStyle" aria-describedby="검색조건">
-				<colgroup>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col style="width:10%;"/>
-					<col style="width:15%;"/>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col/>
-				</colgroup>
-				<tbody>
-				<tr>
-					<th class="dashR">검색구분</th>
-					<td class="dashR">
-						<select name="searchGb">
-							<option value="">선택</option>
-							<option value="custNm">회원명 </option>
-							<option value="email">이메일</option>
-							<option value="custId">아이디</option>
-						</select>
-						<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
-					</td>
+	<div class="panelContent">
+		<form id="custActiveForm" name="custActiveForm" action="#" th:action="@{'/customer/active/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+		<div class="panelStyle">
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:15%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col/>
+					</colgroup>
+					<tbody>
+					<tr>
+						<th class="dashR">검색구분</th>
+						<td class="dashR">
+							<select name="searchGb">
+								<option value="">선택</option>
+								<option value="custNm">회원명 </option>
+								<option value="email">이메일</option>
+								<option value="custId">아이디</option>
+							</select>
+							<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
+						</td>
 
-					<th class="dashR">사이트</th>
-					<td class="dashR">
-						<select name="siteCd">
-							<option value="">전체</option>
-							<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
-					<th class="dashR">수신여부</th>
-					<td class="dashR">
-						<label class="chkBox">
-							<input type="checkbox" name='emailAgreeYn' value='Y'/> 메일 수신여부
-						</label>
-						<label class="chkBox">
-							<input type="checkbox" name='smsAgreeYn' value='Y'/> SMS 수신여부
-						</label>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">회원구분</th>
-					<td class="dashR">
-						<select name="custGb">
-							<option value="">전체</option>
-							<option th:if="${custGbList}" th:each="oneData, status : ${custGbList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
+						<th class="dashR">사이트</th>
+						<td class="dashR">
+							<select name="siteCd">
+								<option value="">전체</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">수신여부</th>
+						<td class="dashR">
+							<label class="chkBox">
+								<input type="checkbox" name='emailAgreeYn' value='Y'/> 메일 수신여부
+							</label>
+							<label class="chkBox">
+								<input type="checkbox" name='smsAgreeYn' value='Y'/> SMS 수신여부
+							</label>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">회원구분</th>
+						<td class="dashR">
+							<select name="custGb">
+								<option value="">전체</option>
+								<option th:if="${custGbList}" th:each="oneData, status : ${custGbList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
 
-					<th class="dashR">회원등급</th>
-					<td class="dashR">
-						<select name="custGrade">
-							<option value="">전체</option>
-							<option th:if="${custGradeList}" th:each="oneData, status : ${custGradeList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
+						<th class="dashR">회원등급</th>
+						<td class="dashR">
+							<select name="custGrade">
+								<option value="">전체</option>
+								<option th:if="${custGradeList}" th:each="oneData, status : ${custGradeList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
 
-					<th class="dashR">관리대상</th>
-					<td class="dashR">
-						<select name="managedRsn">
-							<option value="">전체</option>
-							<option th:if="${managedRsnList}" th:each="oneData, status : ${managedRsnList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">휴대폰번호</th>
-					<td class="dashR" colspan="5">
-						<input type="text" class="w200" name="cellPhnno" id="cellPhnno"/>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">조회일자</th>
-					<td class="dashR" colspan="5" >
-						<select name="searchDateGb">
-							<option value="joinDt">가입일자</option>
-							<option value="loginLdt">로그인일자</option>
-						</select>
-						<span id="terms"></span>
-					</td>
-				</tr>
-				</tbody>
-			</table>
+						<th class="dashR">관리대상</th>
+						<td class="dashR">
+							<select name="managedRsn">
+								<option value="">전체</option>
+								<option th:if="${managedRsnList}" th:each="oneData, status : ${managedRsnList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">휴대폰번호</th>
+						<td class="dashR" colspan="5">
+							<input type="text" class="w200" name="cellPhnno" id="cellPhnno"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">조회일자</th>
+						<td class="dashR" colspan="5" >
+							<select name="searchDateGb">
+								<option value="joinDt">가입일자</option>
+								<option value="loginLdt">로그인일자</option>
+							</select>
+							<span id="terms"></span>
+						</td>
+					</tr>
+					</tbody>
+				</table>
 
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" onclick="$('#custActiveForm')[0].reset();">초기화</button>
+					</li>
+				</ul>
+		</div>
+		<!-- //검색조건 영역 -->
+
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li class="right">
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="50" selected="selected">50개씩 보기</option>
+						<option value="100">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
 			<ul class="panelBar">
 				<li class="center">
-					<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
+					<div class="tablePaging" id="custListPagination"></div>
 				</li>
 			</ul>
+		</div>
 		</form>
 	</div>
-	<!-- //검색조건 영역 -->
-
-	<!-- 리스트 영역 -->
-	<div class="panelStyle">
-		<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
-	</div>
-	<!-- //리스트 영역 -->
 </div>
-
+<script type="text/javascript" th:src="@{'/ux/plugins/gaga/gaga.paging.js?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 	/*<![CDATA[*/
 
@@ -205,22 +224,22 @@
 	});
 
 	//엔터키 조회
-	$('#searchForm input[name=cellPhnno], #searchForm input[name=searchNm]').on('keypress' ,function (event) {
+	$('#custActiveForm input[name=cellPhnno], #custActiveForm input[name=searchNm]').on('keypress' ,function (event) {
 		if (event.which === 13) {
 			fnSearch();
 		}
 	});
 
 	// 휴대폰 자동 하이픈
-	$('#searchForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
+	$('#custActiveForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
 		cfnCellPhonnHypen(this);
 	});
 
 	// 유효성 확인
 	var fnValidationCheck = function () {
 		// 입력 값 체크
-		const $searchGb = $('#searchForm select[name=searchGb]');	// 검색구분
-		const $searchTxt = $('#searchForm input[name=searchTxt]');	// 검색내용
+		const $searchGb = $('#custActiveForm select[name=searchGb]');	// 검색구분
+		const $searchTxt = $('#custActiveForm input[name=searchTxt]');	// 검색내용
 		let isSearchVaild = true;
 		let validationMessage;
 
@@ -261,9 +280,20 @@
 		if (!validation) {
 			return;
 		}
-		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		//gagaAgGrid.fetch($('#custActiveForm').prop('action'), gridOptions, '#custActiveForm');
+		gagaPaging.init('custActiveForm', fnSearchCallBack, 'custListPagination', $('#custActiveForm select[name=pageSize]').val());
+		gagaPaging.load($('#custActiveForm input[name=pageNo]').val());
 	};
 
+	var fnSearchCallBack = function (result) {
+		$('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#custActiveForm input[name=pageNo]').val(result.pageing.pageable.pageNo.addComma());
+		$('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+
+		gridOptions.api.setRowData(result.custList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	};
 
 	$(document).ready(function() {
 		// 공통 달력 생성

+ 92 - 61
src/main/webapp/WEB-INF/views/customer/CustomerDormantListForm.html

@@ -26,67 +26,86 @@
 	<!-- //메뉴 설명 -->
 
 	<!-- 검색조건 영역 -->
-	<div class="panelStyle">
-		<form id="searchForm" name="searchForm" action="#" th:action="@{'/customer/dormant/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
-			<table class="frmStyle" aria-describedby="검색조건">
-				<colgroup>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col style="width:10%;"/>
-					<col style="width:15%;"/>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col/>
-				</colgroup>
-				<tbody>
-				<tr>
-					<th class="dashR">검색구분</th>
-					<td class="dashR">
-						<select name="searchGb">
-							<option value="">선택</option>
-							<option value="custNm">회원명 </option>
-							<option value="email">이메일</option>
-							<option value="custId">아이디</option>
+	<div class="panelContent">
+		<form id="custDormantForm" name="custDormantForm" action="#" th:action="@{'/customer/dormant/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<div class="panelStyle">
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:15%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col/>
+					</colgroup>
+					<tbody>
+					<tr>
+						<th class="dashR">검색구분</th>
+						<td class="dashR">
+							<select name="searchGb">
+								<option value="">선택</option>
+								<option value="custNm">회원명 </option>
+								<option value="email">이메일</option>
+								<option value="custId">아이디</option>
+							</select>
+							<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
+						</td>
+						<th class="dashR">사이트</th>
+						<td class="dashR">
+							<select name="siteCd">
+								<option value="">전체</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">휴대폰번호(숫자만)</th>
+						<td class="dashR">
+							<input type="text" class="w200" name="cellPhnno" id="cellPhnno" maxlength="13"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">휴면일</th>
+						<td class="dashR" colspan="5" id="terms">
+						</td>
+					</tr>
+					</tbody>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" onclick="$('#custDormantForm')[0].reset();">초기화</button>
+					</li>
+				</ul>
+			</div>
+			<!-- //검색조건 영역 -->
+			<!-- 리스트 영역 -->
+			<div class="panelStyle">
+				<ul class="panelBar">
+					<li class="right">
+						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+						쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+						<select id="pageSize" name="pageSize">
+							<option value="50" selected="selected">50개씩 보기</option>
+							<option value="100">100개씩 보기</option>
+							<option value="500">500개씩 보기</option>
+							<option value="1000">1000개씩 보기</option>
 						</select>
-						<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
-					</td>
-					<th class="dashR">사이트</th>
-					<td class="dashR">
-						<select name="siteCd">
-							<option value="">전체</option>
-							<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
-					<th class="dashR">휴대폰번호(숫자만)</th>
-					<td class="dashR">
-						<input type="text" class="w200" name="cellPhnno" id="cellPhnno" maxlength="13"/>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">휴면일</th>
-					<td class="dashR" colspan="5" id="terms">
-					</td>
-				</tr>
-				</tbody>
-			</table>
-
-			<ul class="panelBar">
-				<li class="center">
-					<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
-				</li>
-			</ul>
+						<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+					</li>
+				</ul>
+				<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="custListPagination"></div>
+					</li>
+				</ul>
+			</div>
+			<!-- //리스트 영역 -->
 		</form>
 	</div>
-	<!-- //검색조건 영역 -->
-
-	<!-- 리스트 영역 -->
-	<div class="panelStyle">
-		<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
-	</div>
-	<!-- //리스트 영역 -->
 </div>
 
+<script type="text/javascript" th:src="@{'/ux/plugins/gaga/gaga.paging.js?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 	/*<![CDATA[*/
 	// 사이트목록
@@ -126,22 +145,22 @@
 	});
 
 	//엔터키 조회
-	$('#searchForm input[name=cellPhnno], #searchForm input[name=searchNm]').on('keypress', function (event) {
+	$('#custDormantForm input[name=cellPhnno], #custDormantForm input[name=searchNm]').on('keypress', function (event) {
 		if (event.which === 13) {
 			fnSearch();
 		}
 	});
 
 	// 휴대폰 자동 하이픈
-	$('#searchForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
+	$('#custDormantForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
 		cfnCellPhonnHypen(this);
 	});
 
 	// 유효성 확인
 	var fnValidationCheck = function () {
 		// 입력 값 체크
-		const $searchGb = $('#searchForm select[name=searchGb]');	// 검색구분
-		const $searchTxt = $('#searchForm input[name=searchTxt]');	// 검색내용
+		const $searchGb = $('#custDormantForm select[name=searchGb]');	// 검색구분
+		const $searchTxt = $('#custDormantForm input[name=searchTxt]');	// 검색내용
 		let isSearchVaild = true;
 		let validationMessage;
 
@@ -181,7 +200,19 @@
 		if (!validation) {
 			return;
 		}
-		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		//gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		gagaPaging.init('custDormantForm', fnSearchCallBack, 'custListPagination', $('#custDormantForm select[name=pageSize]').val());
+		gagaPaging.load($('#custDormantForm input[name=pageNo]').val());
+	};
+
+	var fnSearchCallBack = function (result) {
+		$('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#custDormantForm input[name=pageNo]').val(result.pageing.pageable.pageNo.addComma());
+		$('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+
+		gridOptions.api.setRowData(result.custList);
+		gagaPaging.createPagination(result.pageing.pageable);
 	};
 
 	$(document).ready(function() {

+ 39 - 7
src/main/webapp/WEB-INF/views/customer/CustomerSecedeListForm.html

@@ -27,7 +27,7 @@
 
 	<!-- 검색조건 영역 -->
 	<div class="panelStyle">
-		<form id="searchForm" name="searchForm" action="#" th:action="@{'/customer/secede/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+		<form id="custSecedeForm" name="custSecedeForm" action="#" th:action="@{'/customer/secede/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
 			<table class="frmStyle" aria-describedby="검색조건">
 				<colgroup>
 					<col style="width:10%;"/>
@@ -82,7 +82,7 @@
 			<ul class="panelBar">
 				<li class="center">
 					<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
+					<button type="button" class="btn btn-gray btn-lg" onclick="$('#custSecedeForm')[0].reset();">초기화</button>
 				</li>
 			</ul>
 		</form>
@@ -91,11 +91,30 @@
 
 	<!-- 리스트 영역 -->
 	<div class="panelStyle">
+		<ul class="panelBar">
+			<li class="right">
+				검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+				쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+				<select id="pageSize" name="pageSize">
+					<option value="50" selected="selected">50개씩 보기</option>
+					<option value="100">100개씩 보기</option>
+					<option value="500">500개씩 보기</option>
+					<option value="1000">1000개씩 보기</option>
+				</select>
+				<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+			</li>
+		</ul>
 		<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
+		<ul class="panelBar">
+			<li class="center">
+				<div class="tablePaging" id="custListPagination"></div>
+			</li>
+		</ul>
 	</div>
 	<!-- //리스트 영역 -->
 </div>
 
+<script type="text/javascript" th:src="@{'/ux/plugins/gaga/gaga.paging.js?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 	/*<![CDATA[*/
 	// 사이트목록
@@ -135,22 +154,22 @@
 	});
 
 	//엔터키 조회
-	$('#searchForm input[name=cellPhnno], #searchForm input[name=searchNm]').on('keypress', function (event) {
+	$('#custSecedeForm input[name=cellPhnno], #custSecedeForm input[name=searchNm]').on('keypress', function (event) {
 		if (event.which === 13) {
 			fnSearch();
 		}
 	});
 
 	// 휴대폰 자동 하이픈
-	$('#searchForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
+	$('#custSecedeForm input[name=cellPhnno]').on('input keyup keydown paste change', function () {
 		cfnCellPhonnHypen(this);
 	});
 
 	// 유효성 확인
 	var fnValidationCheck = function () {
 		// 입력 값 체크
-		const $searchGb = $('#searchForm select[name=searchGb]');	// 검색구분
-		const $searchTxt = $('#searchForm input[name=searchTxt]');	// 검색내용
+		const $searchGb = $('#custSecedeForm select[name=searchGb]');	// 검색구분
+		const $searchTxt = $('#custSecedeForm input[name=searchTxt]');	// 검색내용
 		let isSearchVaild = true;
 		let validationMessage;
 
@@ -190,7 +209,20 @@
 		if (!validation) {
 			return;
 		}
-		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		//gagaAgGrid.fetch($('#custSecedeForm').prop('action'), gridOptions, '#custSecedeForm');
+
+		gagaPaging.init('custSecedeForm', fnSearchCallBack, 'custListPagination', $('#custSecedeForm select[name=pageSize]').val());
+		gagaPaging.load($('#custSecedeForm input[name=pageNo]').val());
+	};
+
+	var fnSearchCallBack = function (result) {
+		$('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#custSecedeForm input[name=pageNo]').val(result.pageing.pageable.pageNo.addComma());
+		$('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+
+		gridOptions.api.setRowData(result.custList);
+		gagaPaging.createPagination(result.pageing.pageable);
 	};
 
 	$(document).ready(function() {

+ 43 - 45
src/main/webapp/WEB-INF/views/customer/EmailPopupForm.html

@@ -14,7 +14,7 @@
  * 1.0  2021.01.21   jsshin     최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="800">
+<div class="modelessPopup" data-width="800">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
@@ -24,51 +24,49 @@
 		<!-- //TITLE -->
 		<!-- CONTENT -->
 		<div class="panelContent">
-			<div class="panelStyle">
-				<form id="emailForm" name="emailForm">
-					<input type="hidden" name="sendEmail" th:value="${sendEmail}"/>
-					<input type="hidden" name="email"/>
-					<table class="frmStyle">
-						<colgroup>
-							<col style="width:1%"/>
-							<col style="width:40%"/>
-						</colgroup>
-						<tbody>
-						<tr >
-							<th>보내는사람</th>
-							<td>
-								<span name="sendEmail" th:text="${sendEmail}"></span>
-							</td>
-						</tr>
-						<tr>
-							<th>받는사람</th>
-							<td>
-								<span name="email"></span>
-							</td>
-						</tr>
-						<tr>
-							<th>제목<em class="star"></em></th>
-							<td>
-								<input type="text" class="w150" name="title" value="" required="required" data-valid-name="제목"/>
-							</td>
-						</tr>
-						<tr>
-							<th>내용<em class="star"></em></th>
-							<td>
-								<textarea class="textareaR4" style="resize: none;" name ="content" ></textarea>
-							</td>
-						</tr>
-						</tbody>
-					</table>
-				</form>
-			</div>
-			<ul class="panelBar">
-				<li class="right">
-					<button type="button" class="btn btn-success btn-lg" id="btnSendEmail">발송</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="uifnPopupClose('popupEmailForm')">취소</button>
-				</li>
-			</ul>
+			<form id="emailForm" name="emailForm">
+				<input type="hidden" name="sendEmail" th:value="${sendEmail}"/>
+				<input type="hidden" name="email"/>
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:1%"/>
+						<col style="width:40%"/>
+					</colgroup>
+					<tbody>
+					<tr >
+						<th>보내는사람</th>
+						<td>
+							<span name="sendEmail" th:text="${sendEmail}"></span>
+						</td>
+					</tr>
+					<tr>
+						<th>받는사람</th>
+						<td>
+							<span name="email"></span>
+						</td>
+					</tr>
+					<tr>
+						<th>제목<em class="star"></em></th>
+						<td>
+							<input type="text" class="w150" name="title" value="" required="required" data-valid-name="제목"/>
+						</td>
+					</tr>
+					<tr>
+						<th>내용<em class="star"></em></th>
+						<td>
+							<textarea class="textareaR4" style="resize: none;" name ="content" ></textarea>
+						</td>
+					</tr>
+					</tbody>
+				</table>
+			</form>
 		</div>
+		<ul class="panelBar">
+			<li class="right">
+				<button type="button" class="btn btn-success btn-lg" id="btnSendEmail">발송</button>
+				<button type="button" class="btn btn-gray btn-lg" onclick="uifnPopupClose('popupEmailForm')">취소</button>
+			</li>
+		</ul>
 		<!-- //CONTENT -->
 	</div>
 </div>

+ 36 - 38
src/main/webapp/WEB-INF/views/customer/LmsPopupForm.html

@@ -14,7 +14,7 @@
  * 1.0  2021.01.21   jsshin     최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="800">
+<div class="modelessPopup" data-width="800">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
@@ -24,44 +24,42 @@
 		<!-- //TITLE -->
 		<!-- CONTENT -->
 		<div class="panelContent">
-			<div class="panelStyle">
-				<form id="lmsForm" name="lmsForm">
-					<table class="frmStyle">
-						<colgroup>
-							<col style="width:1%"/>
-							<col style="width:40%"/>
-						</colgroup>
-						<tbody>
-						<tr >
-							<th>수신자번호<em class="required" title="필수"></em></th>
-							<td>
-								<input type="text" class="w150" name="cellPhnno" data-valid-name="수신번호"  required="required"  maxlength="13"/>
-							</td>
-						</tr>
-						<tr>
-							<th>발신자번호<em class="required" title="필수"></em></th>
-							<td>
-								<input type="text" class="w150" name="callBack" th:value="${callBack}" maxlength="11" readonly="readonly"/>
-							</td>
-						</tr>
-						<tr>
-							<th>메시지<em class="required" title="필수"></em></th>
-							<td>
-								<textarea class="textareaR4"  style="resize: none;" name ="content" ></textarea>
-								<span name="count">0</span> / 2000 byte
-							</td>
-						</tr>
-						</tbody>
-					</table>
-				</form>
-			</div>
-			<ul class="panelBar">
-				<li class="right">
-					<button type="button" class="btn btn-success btn-lg" id="btnSendSms">발송</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="uifnPopupClose('popupLmsForm')">취소</button>
-				</li>
-			</ul>
+			<form id="lmsForm" name="lmsForm">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:1%"/>
+						<col style="width:40%"/>
+					</colgroup>
+					<tbody>
+					<tr >
+						<th>수신자번호<em class="required" title="필수"></em></th>
+						<td>
+							<input type="text" class="w150" name="cellPhnno" data-valid-name="수신번호"  required="required"  maxlength="13"/>
+						</td>
+					</tr>
+					<tr>
+						<th>발신자번호<em class="required" title="필수"></em></th>
+						<td>
+							<input type="text" class="w150" name="callBack" th:value="${callBack}" maxlength="11" readonly="readonly"/>
+						</td>
+					</tr>
+					<tr>
+						<th>메시지<em class="required" title="필수"></em></th>
+						<td>
+							<textarea class="textareaR4"  style="resize: none;" name ="content" ></textarea>
+							<span name="count">0</span> / 2000 byte
+						</td>
+					</tr>
+					</tbody>
+				</table>
+			</form>
 		</div>
+		<ul class="panelBar">
+			<li class="right">
+				<button type="button" class="btn btn-success btn-lg" id="btnSendSms">발송</button>
+				<button type="button" class="btn btn-gray btn-lg" onclick="uifnPopupClose('popupLmsForm')">취소</button>
+			</li>
+		</ul>
 		<!-- //CONTENT -->
 	</div>
 </div>

+ 325 - 82
src/main/webapp/WEB-INF/views/marketing/CouponPopupForm.html

@@ -73,33 +73,30 @@
 										<tr class="dcCdGb" style="display:none;">
 											<th>할인쿠폰유형<em class="required" title="필수"></em></th>
 											<td class="normalCol">
-												<input type="hidden" id="dcCd" required="required"  data-valid-name="할인쿠폰유형">
+												<input type="hidden" id="dcCd" data-valid-name="할인쿠폰유형">
 												<label class="rdoBtn" th:if="${dcCdList}" th:each="oneData, status : ${dcCdList}"> <input type="radio" name="dcCdGb"  th:text="${oneData.cdNm}" th:value="${oneData.cd}"/></label>
 											</td>
 											<th class="randomCpnArea">난수생성수량<em class="required" title="필수"></em></th>
 											<td class="randomCpnArea">
-												<input type="text" name="randomCpnQty" class="w300" required="required" data-valid-name="난수생성수량" data-valid-type="numeric">
+												<input type="text" name="randomCpnQty" class="w300" data-valid-name="난수생성수량" data-valid-type="numeric">
 											</td>
 										</tr>
 										<tr class="serialCpnArea" style="display:none;">
 											<th>시리얼쿠폰키워드<em class="required" title="필수"></em></th>
 											<td>
-												<input type="text" name="serialCpnNm" class="w300" maxlength="10" required="required" data-valid-name="시리얼쿠폰키워드">
+												<input type="text" name="serialCpnNm" class="w300" maxlength="10" data-valid-name="시리얼쿠폰키워드">
 											</td>
 											<th>시리얼쿠폰발급수량<em class="required" title="필수"></em></th>
 											<td>
-												<input type="text" name="serialCpnQty" class="w300" required="required" data-valid-name="시리얼쿠폰발급수량" data-valid-type="numeric">
+												<input type="text" name="serialCpnQty" class="w300" data-valid-name="시리얼쿠폰발급수량" data-valid-type="numeric">
 											</td>
 										</tr>
 										<tr>
 											<th>사용가능고객구분<em class="required" title="필수"></em></th>
 											<td>
-												<!--<select name="usableCustGb" id="usableCustGb" required="required" data-valid-name="사용가능고객구분">
-													<option th:if="${usableCustGbList}" th:each="oneData , status : ${usableCustGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
-												</select>-->
-												<input type="hidden" name="usableCustGb"/>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGb" id="chkUsableCustGb10" value="G100_10">일반회원</label>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGb" id="chkUsableCustGb20" value="G100_20">임직원</label>
+												<label class="chkBox" th:if="${usableCustGbList}" th:each="oneData, status : ${usableCustGbList}">
+													<input type="checkbox" name="usableCustGbArr" th:value="${oneData.cd}" th:text="${oneData.cdNm}"/>
+												</label>
 											</td>
 											<th>사이트<em class="required" title="필수"></em></th>
 											<td>
@@ -111,16 +108,9 @@
 										<tr>
 											<th>사용고객등급구분<em class="required" title="필수"></em></th>
 											<td>
-												<!--<select name="usableCustGrade" id="usableCustGrade" required="required" data-valid-name="사용고객등급구분">
-													<option value="ALL">[전체]</option>
-													<option th:if="${usableCustGradeList}" th:each="oneData , status : ${usableCustGradeList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
-												</select>-->
-												<input type="hidden" name="usableCustGrade"/>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGrade" id="chkUsableCustGrade10" value="G110_10">VIP</label>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGrade" id="chkUsableCustGrade20" value="G110_20">GOLD</label>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGrade" id="chkUsableCustGrade30" value="G110_30">SILVER</label>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGrade" id="chkUsableCustGrade40" value="G110_40">BRONZE</label>
-												<label class="chkBox"><input type="checkbox" name="chkUsableCustGrade" id="chkUsableCustGrade50" value="G110_50">WELCOME</label>
+												<label class="chkBox" th:if="${usableCustGradeList}" th:each="oneData, status : ${usableCustGradeList}">
+													<input type="checkbox" name="usableCustGradeArr" th:value="${oneData.cd}" th:text="${oneData.cdNm}"/>
+												</label>
 											</td>
 											<th>만료알림여부<em class="required" title="필수"></em></th>
 											<td>
@@ -177,8 +167,9 @@
 											<td>
 												<input type="hidden" id="downEddt" name="downEddt" required="required" data-valid-name="다운로드종료일시">
 												<input type="text" class="schDate w100" name="downEdDay" id="downEdDay" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
-												<select name="downEdHH" id="downEdHH">
+												<select name="downEdHH" id="downEdHH" onclick="fnChangeEdHH(this);">
 													<option th:if="${hhList}" th:each="oneData , status : ${hhList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
+													<option th:text="24시" th:value="24"></option>
 												</select>
 												<select name="downEdMM" id="downEdMM">
 													<option th:if="${mmList}" th:each="oneData , status : ${mmList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
@@ -221,8 +212,9 @@
 											<td class="availDateTr">
 												<input type="hidden" id="availEddt" name="availEddt" data-valid-name="유효기간종료일시">
 												<input type="text" class="schDate w100" name="availEdDay" id="availEdDay" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
-												<select name="availEdHH" id="availEdHH">
+												<select name="availEdHH" id="availEdHH" onclick="fnChangeEdHH(this);">
 													<option th:if="${hhList}" th:each="oneData , status : ${hhList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
+													<option th:text="24시" th:value="24"></option>
 												</select>
 												<select name="availEdMM" id="availEdMM">
 													<option th:if="${mmList}" th:each="oneData , status : ${mmList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
@@ -241,7 +233,7 @@
 										<tr>
 											<th class="buyDateTr">첫구매기간시작일시<em class="required" title="필수"></em></th>
 											<td class="buyDateTr">
-												<input type="hidden" id="buyEddt" name="buyEddt" data-valid-name="첫구매기간종료일시">
+												<input type="hidden" name="buyStdt" id="buyStdt" data-valid-name="첫구매기간시작일시">
 												<input type="text" class="schDate w100" name="buyStDay" id="buyStDay" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
 												<select name="buyStHH" id="buyStHH">
 													<option th:if="${hhList}" th:each="oneData , status : ${hhList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
@@ -251,10 +243,11 @@
 												</select>
 											<th class="buyDateTr">첫구매기간종료일시<em class="required" title="필수"></em></th>
 											<td class="buyDateTr">
-												<input type="hidden" name="buyStdt" id="buyStdt" data-valid-name="첫구매기간시작일시">
+												<input type="hidden" id="buyEddt" name="buyEddt" data-valid-name="첫구매기간종료일시">
 												<input type="text" class="schDate w100" name="buyEdDay" id="buyEdDay" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
-												<select name="buyEdHH" id="buyEdHH">
+												<select name="buyEdHH" id="buyEdHH" onclick="fnChangeEdHH(this);">
 													<option th:if="${hhList}" th:each="oneData , status : ${hhList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
+													<option th:text="24시" th:value="24"></option>
 												</select>
 												<select name="buyEdMM" id="buyEdMM">
 													<option th:if="${mmList}" th:each="oneData , status : ${mmList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
@@ -285,8 +278,9 @@
 											<td class="custJoinDateTr">
 												<input type="hidden" id="custJoinEddt" name="custJoinEddt" data-valid-name="신규회원기간종료일시">
 												<input type="text" class="schDate w100" name="custJoinEdDay" id="custJoinEdDay" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
-												<select name="custJoinEdHH" id="custJoinEdHH">
+												<select name="custJoinEdHH" id="custJoinEdHH" onclick="fnChangeEdHH(this);">
 													<option th:if="${hhList}" th:each="oneData , status : ${hhList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
+													<option th:text="24시" th:value="24"></option>
 												</select>
 												<select name="custJoinEdMM" id="custJoinEdMM">
 													<option th:if="${mmList}" th:each="oneData , status : ${mmList}" th:text="${oneData.cdNm}" th:value="${oneData.cd}"></option>
@@ -332,21 +326,14 @@
 												</select>
 											</td>
 										</tr>-->
-										<!--<tr class="payTypeTr" style="display: none;">
+										<tr class="payTypeTr" style="display: none;">
 											<th>결제수단<em class="required" title="필수"></em></th>
 											<td colspan="5">
-												<select name="payType" id="payType" data-valid-name="결제수단">
-													<option value="">[전체]</option>
-													<option th:if="${payTypeList}" th:each="oneData , status : ${payTypeList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
-												</select>
+												<label class="chkBox" th:if="${payTypeList}" th:each="oneData, status : ${payTypeList}">
+													<input type="checkbox" name="payTypeArr" th:value="${oneData.cd}" th:text="${oneData.cdNm}"/>
+												</label>
 											</td>
 										</tr>
-										<tr>
-											<th>멀티결제수단</th>
-											<td colspan="5">
-
-											</td>
-										</tr>-->
 										<tr>
 											<th>쿠폰상태<em class="required" title="필수"></em></th>
 											<td>
@@ -505,6 +492,10 @@
 	var randomCpnList = [[${randomCpnList}]];
 	var issueCnt = [[${issueCnt}]];
 
+	var cpnCustGbList = [[${cpnCustGbList}]];
+	var cpnCustGradeList = [[${cpnCustGradeList}]];
+	var cpnPayTypeList = [[${cpnPayTypeList}]];
+
 	// 공통코드 리스트
 	var ibSupplyComList = gagajf.convertToArray([[${ibSupplyCompList}]]);
 	var formalGbList = gagajf.convertToArray([[${formalGbList}]]);
@@ -546,7 +537,7 @@
 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
 		{ headerName : "브랜드ID" , field: "brandCd" , width: 120, cellClass : 'text-center'} ,
 		{ headerName : "브랜드명" , field: "brandEnm" , width: 120, cellClass: 'text-center'} ,
-		{ headerName : "공급업체명", field: "supplyCompNm" , width: 150, cellClass: 'text-center' } ,
+		//{ headerName : "공급업체명", field: "supplyCompNm" , width: 150, cellClass: 'text-center' } ,
 		{ headerName: "쿠폰대상일련번호"  , field: "cpnRefvalSq" , width: 120 , cellClass: 'text-center' , hide:true}
 	];
 
@@ -627,6 +618,27 @@
 	brandGridOptions.rowSelection = "multiple";
 	inComGridOptions.stopEditingWhenGridLosesFocus = true;
 
+	// 종료시간 클릭시
+	var fnChangeEdHH = function (obj){
+		var selectId = obj.id;
+		var changeId = "";
+		if(selectId == "downEdHH"){
+			changeId = "downEdMM";
+		}else if(selectId == "availEdHH"){
+			changeId = "availEdMM";
+		}else if(selectId == "buyEdHH"){
+			changeId = "buyEdMM";
+		}else{
+			changeId = "custJoinEdMM";
+		}
+		if(obj.value == 24) {
+			$("#CouponForm #"+changeId+" option").hide();
+			$('#CouponForm #'+changeId+' option:first').show().prop("selected", true);
+		} else {
+			$("#CouponForm #"+changeId+" option").show();
+		}
+	};
+
 	// 총발행 제한수량 -> 제한없음 처리
 	$("#CouponForm #chkBoxTotPubQty").bind('click', function (){
 		var chkBox= document.getElementById('chkNoLimitTotPubLimitQty').checked;
@@ -674,34 +686,100 @@
 	});
 
 	// 쿠폰 등록 버튼 클릭시
-
 	function fnCouponCreate(){
 		mcxDialog.confirm('저장하시겠습니까?' , {
 			cancelBtnText:"취소",
 			sureBtnText:"확인",
 			sureBtnClick: function () {
-				var chkUsableCustGb = document.getElementsByName("chkUsableCustGb");
-				var chkUsableCustGrade = document.getElementsByName("chkUsableCustGrade");
-				var usableCustGb = "";
-				var usableCustGrade = "";
-
-				for(let i=0; i<chkUsableCustGb.length; i++){
-					if(chkUsableCustGb[i].checked == true){
-						usableCustGb += chkUsableCustGb[i].value+"|";
-					}
+				gagajf.removeCommaAtNumberFormattedInput('#CouponForm');
+				// 필수값들 셋팅
+				setReqValue();
+				// 필수값 validation 체크
+				if (!gagajf.validation('#CouponForm')) {
+					return false;
 				}
-				for(let i=0; i<chkUsableCustGrade.length; i++){
-					if(chkUsableCustGrade[i].checked == true){
-						usableCustGrade += chkUsableCustGrade[i].value+"|";
-					}
+				// 데이터 validation 체크
+				if(!checkValidation()) {
+					return false;
+				}
+
+				var usableCustGbArr = [];
+				var chkCustGb  = $('#CouponForm input:checkbox[name=usableCustGbArr]:checked');
+				for(let i=0; i< chkCustGb.length; i++){
+					usableCustGbArr.push(chkCustGb.eq(i).val());
+				}
+
+				var usableCustGradeArr = [];
+				var chkCustGrade = $('#CouponForm input:checkbox[name=usableCustGradeArr]:checked');
+				for(let i=0; i< chkCustGrade.length; i++){
+					usableCustGradeArr.push(chkCustGrade.eq(i).val());
+				}
+
+				var payTypeArr = [];
+				var chkPayType = $('#CouponForm input:checkbox[name=payTypeArr]:checked');
+				for(let i=0; i< chkPayType.length; i++){
+					payTypeArr.push(chkPayType.eq(i).val());
 				}
 
-				$("#CouponForm input[name=usableCustGb]").val(usableCustGb);
-				$("#CouponForm input[name=usableCustGrade]").val(usableCustGrade);
+				var data = {
+						cpnId : $('#CouponForm input[name=cpnId]').val()
+						,cpnNm : $('#CouponForm input[name=cpnNm]').val()
+						,siteCd : $('#CouponForm select[name=siteCd]').val()
+						,afLinkCd : $('#CouponForm select[name=afLinkCd]').val()
+						,cpnType : $('input:radio[name="rdoCpnType"]:checked').val()
+						,applyScope : $('input:radio[name="rdoApplyScope"]:checked').val()
+						,dcWay : $('input:radio[name="rdoDcWay"]:checked').val()
+						,dcPval : $('#CouponForm input[name=dcPval]').val()
+						,dcMval : $('#CouponForm input[name=dcMval]').val()
+						,dcAval : $('#CouponForm input[name=dcAval]').val()
+						,maxDcAmt : $('#CouponForm input[name=maxDcAmt]').val()
+						,pdGb : $('#CouponForm select[name=pdGb]').val()
+						,availStdt : $('#CouponForm input[name=availStdt]').val()
+						,availEddt : $('#CouponForm input[name=availEddt]').val()
+						,availDays : $('#CouponForm input[name=availDays]').val()
+						,custPubLimitQty : $('#CouponForm input[name=custPubLimitQty]').val()
+						,totPubLimitQty : $('#CouponForm input[name=totPubLimitQty]').val()
+						,onePubQtyy : $('#CouponForm input[name=onePubQtyy]').val()
+						,downStdt : $('#CouponForm input[name=downStdt]').val()
+						,downEddt : $('#CouponForm input[name=downEddt]').val()
+						,buyLimitAmt : $('#CouponForm input[name=buyLimitAmt]').val()
+						,cpnStat : $('#CouponForm select[name=cpnStat]').val()
+						,endAlimYn : $('#CouponForm select[name=endAlimYn]').val()
+						,firstOrdYn : $('#CouponForm select[name=firstOrdYn]').val()
+						,downAblYn : $('#CouponForm select[name=downAblYn]').val()
+						,custJoinStdt : $('#CouponForm input[name=custJoinStdt]').val()
+						,custJoinEddt : $('#CouponForm input[name=custJoinEddt]').val()
+						,buyStdt : $('#CouponForm input[name=buyStdt]').val()
+						,buyEddt : $('#CouponForm input[name=buyEddt]').val()
+						,newCustYn : $('#CouponForm select[name=newCustYn]').val()
+						,afChannel : $('#CouponForm select[name=afChannel]').val()
+						,dcCdGb : $('input:radio[name="dcCdGb"]:checked').val()
+						,rdCpnNm : $('input:radio[name="rdCpnNm"]:checked').val()
+						,supplyCompList : gagaAgGrid.getAllRowData(supplyGridOptions)
+						,brandList : gagaAgGrid.getAllRowData(brandGridOptions)
+						,applyGoodsList : gagaAgGrid.getAllRowData(goodsGridOptions)
+						,exceptGoodsList : gagaAgGrid.getAllRowData(excepGoodsGridOptions)
+						,cateList : gagaAgGrid.getAllRowData(cateGridOptions)
+						,burdenList : gagaAgGrid.getAllRowData(inComGridOptions)
+						,usableCustGbArr : usableCustGbArr
+						,usableCustGradeArr : usableCustGradeArr
+						,payTypeArr : payTypeArr
+				};
+
+				var jsonData = JSON.stringify(data);
+
+				gagajf.ajaxJsonSubmit($('#CouponForm').prop('action'), jsonData, fnCouponSaveCollback);
+
 			}
 		});
 	}
 
+	var fnCouponSaveCollback = function (result){
+		console.log('AAAAAA');
+		uifnPopupClose('CouponRegForm');
+		$('#btnSearch').trigger('click');
+	}
+
 	function fnCouponCreate2(){
 		mcxDialog.confirm('저장하시겠습니까?' , {
 			cancelBtnText:"취소",
@@ -761,6 +839,28 @@
 	}
 
 	function checkValidation(){
+		// 사용가능고객구분 체크박스 체크
+		var usableCustGbCnt = $('#CouponForm input:checkbox[name=usableCustGbArr]').length;
+		if(usableCustGbCnt<1){
+			mcxDialog.alert("사용가능고객구분을 체크해주세요.");
+			$('#CouponForm input:checkbox[name=usableCustGbArr]').focus();
+			return;
+		}
+		// 사용가능고객등급 체크박스 체크
+		var usableCustGradeCnt = $('#CouponForm input:checkbox[name=usableCustGradeArr]').length;
+		if(usableCustGradeCnt<1){
+			mcxDialog.alert("사용가능고객등급을 체크해주세요.");
+			$('#CouponForm input:checkbox[name=usableCustGradeArr]').focus();
+			return;
+		}
+		// 결제수단 체크박스 체크
+		var payTypeCnt = $('#CouponForm input:checkbox[name=payTypeArr]').length;
+		if(payTypeCnt<1){
+			mcxDialog.alert("사용가능고객등급을 체크해주세요.");
+			$('#CouponForm input:checkbox[name=payTypeArr]').focus();
+			return;
+		}
+
 		//신규가입 지급한다면 validation 체크
 		if( $('#newCustYn option:selected').val() == "Y" ){
 			var fromDate = $('#CouponForm input[name=custJoinStdt]').val();
@@ -923,12 +1023,12 @@
 
 		// 주문서 쿠폰 선택시 결제수단 노출
 		if(radioValue == 'G230_20') {
-			//$('#CouponForm .payTypeTr').show();
-			//$('#CouponForm #payType').attr('required' , true);
+			$('#CouponForm .payTypeTr').show();
+			$('#CouponForm #payType').attr('required' , true);
 			$("#CouponForm .dcCdGb").show();		// 할인쿠폰유형 노출
 		} else {
-			//$('#CouponForm .payTypeTr').hide();
-			//$('#CouponForm #payType').attr('required' , false );
+			$('#CouponForm .payTypeTr').hide();
+			$('#CouponForm #payType').attr('required' , false );
 			$("#CouponForm .dcCdGb").hide();		// 할인쿠폰유형 숨김
 			$("#CouponForm input:radio[name='dcCdGb']:radio[value='G233_00']").prop('checked', true);		// 주문서 쿠폰이 아닐 경우 일반 쿠폰으로 설정
 		}
@@ -1371,23 +1471,66 @@
 		// 적용범위값 세팅
 		$('#CouponForm #applyScope').val($('#CouponForm input:radio[name="rdoApplyScope"]:checked').val());
 		// 다운로드기간 세팅
-		$('#CouponForm #downStdt').val($('#CouponForm #downStDay').val() + " " + $('#CouponForm #downStHH').val() + ":" + $('#CouponForm #downStMM').val() + ":00");
-		$('#CouponForm #downEddt').val($('#CouponForm #downEdDay').val() + " " + $('#CouponForm #downEdHH').val() + ":" + $('#CouponForm #downEdMM').val() + ":59");
+		let downStdt = "";
+		let downEddt = "";
+		downStdt = $('#CouponForm input[name=downStDay]').val()+$('#CouponForm select[name=downStHH]').val()+$('#CouponForm select[name=downStMM]').val()+'00';
+		if($('#CouponForm select[name=downEdHH]').val() == "24"){
+			downEddt = $('#CouponForm input[name=downEdDay]').val()+'235959';
+		}else{
+			downEddt = $('#CouponForm input[name=downEdDay]').val()+$('#CouponForm select[name=downEdHH]').val()+$('#CouponForm select[name=downEdMM]').val()+'00';
+		}
+		downStdt = downStdt.replace(/[^0-9]/g, '');
+		downEddt = downEddt.replace(/[^0-9]/g, '');
+		$('#CouponForm #downStdt').val(downStdt);
+		$('#CouponForm #downEddt').val(downEddt);
+
 		// 유효기간 세팅
+		let availStdt = "";
+		let availEddt = "";
 		if($("#CouponForm #pdGb").val() == 'P') {
-			$('#CouponForm #availStdt').val($('#CouponForm #availStDay').val() + " " + $('#CouponForm #availStHH').val() + ":" + $('#CouponForm #availStMM').val() + ":00");
-			$('#CouponForm #availEddt').val($('#CouponForm #availEdDay').val() + " " + $('#CouponForm #availEdHH').val() + ":" + $('#CouponForm #availEdMM').val() + ":59");
+			availStdt = $('#CouponForm input[name=availStDay]').val()+$('#CouponForm select[name=availStHH]').val()+$('#CouponForm select[name=availStMM]').val()+'00';
+			if($('#CouponForm select[name=availEdHH]').val() == "24"){
+				availEddt = $('#CouponForm input[name=availEdDay]').val()+'235959';
+			}else{
+				availEddt = $('#CouponForm input[name=availEdDay]').val()+$('#CouponForm select[name=availEdHH]').val()+$('#CouponForm select[name=availEdMM]').val()+'00';
+			}
+			availStdt = availStdt.replace(/[^0-9]/g, '');
+			availEddt = availEddt.replace(/[^0-9]/g, '');
+			$('#CouponForm #availStdt').val(availStdt);
+			$('#CouponForm #availEddt').val(availEddt);
 			$('#CouponForm #availDays').val('');
 		} else {
 			$('#CouponForm #availStdt').val('');
 			$('#CouponForm #availEddt').val('');
 		}
+
 		// 첫구매기간세팅
-		$('#CouponForm #buyStdt').val($('#CouponForm #buyStDay').val() + " " + $('#CouponForm #buyStHH').val() + ":" + $('#CouponForm #buyStMM').val() + ":00");
-		$('#CouponForm #buyEddt').val($('#CouponForm #buyEdDay').val() + " " + $('#CouponForm #buyEdHH').val() + ":" + $('#CouponForm #buyEdMM').val() + ":59");
+		let buyStdt = "";
+		let buyEddt = "";
+		buyStdt = $('#CouponForm input[name=buyStDay]').val()+$('#CouponForm select[name=buyStHH]').val()+$('#CouponForm select[name=buyStMM]').val()+'00';
+		if($('#CouponForm select[name=buyEdHH]').val() == "24"){
+			buyEddt = $('#CouponForm input[name=buyEdDay]').val()+'235959';
+		}else{
+			buyEddt = $('#CouponForm input[name=buyEdDay]').val()+$('#CouponForm select[name=buyEdHH]').val()+$('#CouponForm select[name=buyEdMM]').val()+'00';
+		}
+		buyStdt = buyStdt.replace(/[^0-9]/g, '');
+		buyEddt = buyEddt.replace(/[^0-9]/g, '');
+		$('#CouponForm #buyStdt').val(buyStdt);
+		$('#CouponForm #buyEddt').val(buyEddt);
+
 		// 신규회원기간 세팅
-		$('#CouponForm #custJoinStdt').val($('#CouponForm #custJoinStDay').val() + " " + $('#CouponForm #custJoinStHH').val() + ":" + $('#CouponForm #custJoinStMM').val() + ":00");
-		$('#CouponForm #custJoinEddt').val($('#CouponForm #custJoinEdDay').val() + " " + $('#CouponForm #custJoinEdHH').val() + ":" + $('#CouponForm #custJoinEdMM').val() + ":59");
+		let custJoinStdt = "";
+		let custJoinEddt = "";
+		custJoinStdt = $('#CouponForm input[name=custJoinStDay]').val()+$('#CouponForm select[name=custJoinStHH]').val()+$('#CouponForm select[name=custJoinStMM]').val()+'00';
+		if($('#CouponForm select[name=custJoinEdHH]').val() == "24"){
+			custJoinEddt = $('#CouponForm input[name=custJoinEdDay]').val()+'235959';
+		}else{
+			custJoinEddt = $('#CouponForm input[name=custJoinEdDay]').val()+$('#CouponForm select[name=custJoinEdHH]').val()+$('#CouponForm select[name=custJoinEdMM]').val()+'00';
+		}
+		custJoinStdt = custJoinStdt.replace(/[^0-9]/g, '');
+		custJoinEddt = custJoinEddt.replace(/[^0-9]/g, '');
+		$('#CouponForm #custJoinStdt').val(custJoinStdt);
+		$('#CouponForm #custJoinEddt').val(custJoinEddt);
 
 		// 할인쿠폰 유형에 따른 총 발행수량 수정 (주문서 쿠폰이고 난수쿠폰일 경우)
 		if($('#CouponForm #cpnType').val() == "G230_20" && $('#CouponForm input:radio[name="dcCdGb"]:checked').val() == "G233_20") {
@@ -1402,29 +1545,35 @@
 		}
 
 		// 적용대상 - 공급처 그리드 전체값 세팅
-		var supplyAllData = gagaAgGrid.getAllRowData(supplyGridOptions);
+		/*var supplyAllData = gagaAgGrid.getAllRowData(supplyGridOptions);
 		var jsonSupplyCompData = JSON.stringify(supplyAllData);
-		$('#CouponForm #supplyCompList').val(jsonSupplyCompData);
+		$('#CouponForm #supplyCompList').val(jsonSupplyCompData);*/
+		$('#CouponForm #supplyCompList').val(gagaAgGrid.getAllRowData(supplyGridOptions));
 		// 적용대상 - 브랜드 그리드 전체값 세팅
-		var brandAllData = gagaAgGrid.getAllRowData(brandGridOptions);
+		/*var brandAllData = gagaAgGrid.getAllRowData(brandGridOptions);
 		var jsonBrandData = JSON.stringify(brandAllData);
-		$('#CouponForm #brandList').val(jsonBrandData);
+		$('#CouponForm #brandList').val(jsonBrandData);*/
+		$('#CouponForm #brandList').val(gagaAgGrid.getAllRowData(brandGridOptions));
 		// // 적용대상 - 카테고리 그리드 전체값 세팅
-		var cateAllData = gagaAgGrid.getAllRowData(cateGridOptions);
+		/*var cateAllData = gagaAgGrid.getAllRowData(cateGridOptions);
 		var jsonCateData = JSON.stringify(cateAllData);
-		$('#CouponForm #cateList').val(jsonCateData);
+		$('#CouponForm #cateList').val(jsonCateData);*/
+		$('#CouponForm #cateList').val(gagaAgGrid.getAllRowData(cateGridOptions));
 		// 적용대상 - 적용상품 그리드 전체값 세팅
-		var goodsAllData = gagaAgGrid.getAllRowData(goodsGridOptions);
+		/*var goodsAllData = gagaAgGrid.getAllRowData(goodsGridOptions);
 		var jsonGoodsData = JSON.stringify(goodsAllData);
-		$('#CouponForm #applyGoodsList').val(jsonGoodsData);
+		$('#CouponForm #applyGoodsList').val(jsonGoodsData);*/
+		$('#CouponForm #applyGoodsList').val(gagaAgGrid.getAllRowData(goodsGridOptions));
 		// 적용대상 - 제외상품 그리드 전체값 세팅
-		var exceptGoodsAllData = gagaAgGrid.getAllRowData(excepGoodsGridOptions);
+		/*var exceptGoodsAllData = gagaAgGrid.getAllRowData(excepGoodsGridOptions);
 		var jsonExceptGoodsData = JSON.stringify(exceptGoodsAllData);
-		$('#CouponForm #excepGoodsList').val(jsonExceptGoodsData);
+		$('#CouponForm #excepGoodsList').val(jsonExceptGoodsData);*/
+		$('#CouponForm #excepGoodsList').val(gagaAgGrid.getAllRowData(excepGoodsGridOptions));
 		// 입점업체분담율 그리드 전체값 세팅
-		var inCompBurdenAllData = gagaAgGrid.getAllRowData(inComGridOptions);
+		/*var inCompBurdenAllData = gagaAgGrid.getAllRowData(inComGridOptions);
 		var jsonInCompBurdenData = JSON.stringify(inCompBurdenAllData);
-		$('#CouponForm #burdenList').val(jsonInCompBurdenData);
+		$('#CouponForm #burdenList').val(jsonInCompBurdenData);*/
+		$('#CouponForm #burdenList').val(gagaAgGrid.getAllRowData(inComGridOptions));
 
 	}
 
@@ -1444,13 +1593,17 @@
 			$('input[name=rdoDcWay]').eq(0).attr("checked", true);
 			$('input[name=rdoApplyScope]').eq(0).attr("checked", true)
 			$('#CouponForm #availEdHH option:last').attr("selected", "selected");
-			$('#CouponForm #availEdMM option:last').attr("selected", "selected");
+			$('#CouponForm #availEdMM option').hide();
+			$('#CouponForm #availEdMM option:first').show().prop("selected", true);
 			$('#downEdHH option:last').attr("selected", "selected");
-			$('#downEdMM option:last').attr("selected", "selected");
+			$('#downEdMM option').hide();
+			$('#downEdMM option:first').show().prop("selected", true);
 			$('#custJoinEdHH option:last').attr("selected", "selected");
-			$('#custJoinEdMM option:last').attr("selected", "selected");
+			$('#custJoinEdMM option').hide();
+			$('#custJoinEdMM option:first').show().prop("selected", true);
 			$('#buyEdHH option:last').attr("selected", "selected");
-			$('#buyEdMM option:last').attr("selected", "selected");
+			$('#buyEdMM option').hide();
+			$('#buyEdMM option:first').show().prop("selected", true);
 			$("#CouponForm #afChannel option:first").attr("selected" , "selected");
 			$("#CouponForm .normalCol").attr("colspan", "5");
 			$("#CouponForm .randomCpnArea").hide();
@@ -1463,6 +1616,48 @@
 				$('#CouponForm .dcCdCheck1').hide();
 			}
 		} else {
+			if(cpnCustGbList.length > 0){
+				var chkboxCnt = $('#CouponForm input:checkbox[name=usableCustGbArr]').length;
+				var dataCnt = cpnCustGbList.length;
+				for(let i=0; i<chkboxCnt; i++){
+					for(let j=0; j<dataCnt; j++){
+						var data = cpnCustGbList[j].usableCustGb;
+						if($('#CouponForm input:checkbox[name=usableCustGbArr]').eq(i).val() == data){
+							$('#CouponForm input:checkbox[name=usableCustGbArr]').eq(i).prop('checked', true);
+							$("#CouponForm input:checkbox[name=usableCustGbArr]").eq(i).parent().addClass('checked');
+						}
+					}
+				}
+			}
+
+			if(cpnCustGradeList.length > 0){
+				var chkboxCnt = $('#CouponForm input:checkbox[name=usableCustGradeArr]').length;
+				var dataCnt = cpnCustGradeList.length;
+				for(let i=0; i<chkboxCnt; i++){
+					for(let j=0; j<dataCnt; j++){
+						var data = cpnCustGradeList[j].usableCustGrade;
+						if($('#CouponForm input:checkbox[name=usableCustGradeArr]').eq(i).val() == data){
+							$('#CouponForm input:checkbox[name=usableCustGradeArr]').eq(i).prop('checked', true);
+							$("#CouponForm input:checkbox[name=usableCustGradeArr]").eq(i).parent().addClass('checked');
+						}
+					}
+				}
+			}
+
+			if(cpnPayTypeList.length > 0){
+				var chkboxCnt = $('#CouponForm input:checkbox[name=payTypeArr]').length;
+				var dataCnt = cpnPayTypeList.length;
+				for(let i=0; i<chkboxCnt; i++){
+					for(let j=0; j<dataCnt; j++){
+						var data = cpnPayTypeList[j].payType;
+						if($('#CouponForm input:checkbox[name=payTypeArr]').eq(i).val() == data){
+							$('#CouponForm input:checkbox[name=payTypeArr]').eq(i).prop('checked', true);
+							$("#CouponForm input:checkbox[name=payTypeArr]").eq(i).parent().addClass('checked');
+						}
+					}
+				}
+			}
+
 			// 수정모드시 그리드 세팅
 			inComGridOptions.api.setRowData(cpnDtlBurdenList);
 			supplyGridOptions.api.setRowData(cpnDtlRefvalSupplyCompList);
@@ -1552,6 +1747,54 @@
 				}
 			}
 
+			// 쿠폰다운 날짜
+			let edDtArr;
+			if(!gagajf.isNull(cpnDetail.downEddt)){
+				edDtArr = cpnDetail.downEddt.split(" ");
+				if(edDtArr[1] == "23:59:59") {
+					edHour = "24";
+					edMinute = "00";
+					$("#CouponForm #downEdMM option").hide();
+					$('#CouponForm #downEdMM option:first').show().prop("selected", true);
+				}
+			}
+
+			// 유효 날짜
+			let availEdDtArr;
+			if(!gagajf.isNull(cpnDetail.availEddt)){
+				availEdDtArr = cpnDetail.availEddt.split(" ");
+				if(availEdDtArr[1] == "23:59:59") {
+					edHour = "24";
+					edMinute = "00";
+					$("#CouponForm #availEdMM option").hide();
+					$('#CouponForm #availEdMM option:first').show().prop("selected", true);
+				}
+			}
+
+			// 첫구매 날짜
+			let firstBuyEdDtArr;
+			if(!gagajf.isNull(cpnDetail.buyEddt)){
+				firstBuyEdDtArr = cpnDetail.buyEddt.split(" ");
+				if(firstBuyEdDtArr[1] == "23:59:59") {
+					edHour = "24";
+					edMinute = "00";
+					$("#CouponForm #buyEdMM option").hide();
+					$('#CouponForm #buyEdMM option:first').show().prop("selected", true);
+				}
+			}
+
+			// 신규가입 날짜
+			let custJoinEdDtArr;
+			if(!gagajf.isNull(cpnDetail.custJoinEddt)){
+				custJoinEdDtArr = cpnDetail.custJoinEddt.split(" ");
+				if(custJoinEdDtArr[1] == "23:59:59") {
+					edHour = "24";
+					edMinute = "00";
+					$("#CouponForm #custJoinEdMM option").hide();
+					$('#CouponForm #custJoinEdMM option:first').show().prop("selected", true);
+				}
+			}
+
 			/*
 			$("#CouponForm input:checkbox[name='cpnCreateType']").parent("label").addClass("formControl");
 			$("#CouponForm input:checkbox[name='cpnCreateType']").parent("label").prop('disabled', true);

+ 199 - 55
src/main/webapp/WEB-INF/views/order/ExchangeRequestForm.html

@@ -33,7 +33,8 @@
 				<div id="gridDelvCdList" style="width:100%; height: 140px;" class="ag-theme-balham"></div>
 				
 				<div style="text-align:right; padding-bottom:5px; padding-top:5px;">
-					<button type="button" class="btn btn-success" id="fnExchangeRequestSubmit" onclick="fnExchange()">요청</button>
+					<button type="button" class="btn btn-success" th:unless="${ordChgSq > 0}" id="fnExchangeRequestSubmit" onclick="fnExchange()">교환요청</button>
+					<button type="button" class="btn btn-success" th:if="${ordChgSq > 0}" id="fnExchangeCancelRequestSubmit" onclick="fnExchangeCancel()">교환철회</button>
 				</div>
 				
 				<table class="frmStyle">
@@ -46,20 +47,21 @@
 					<tbody>
 						<tr>
 							<th>교환사유 <i class="star"></i></th>
-							<td>
+							<td th:unless="${ordChgSq > 0}">
 								<select name="selectChgReason" onchange="fnChangeChgReason($(this).val());">
 									<option value="">[선택하세요]</option>
 									<option th:if="${chgReasonList}" th:each="oneData, status : ${chgReasonList}" th:value="|${oneData.cd}:${oneData.cdNm}|" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
 								</select>
 							</td>
+							<td th:if="${ordChgSq > 0}" th:id="chgReason"></td>
 							<th>귀책사유</th>
 							<td><span id="imputeReason"></span></td>
 						</tr>
 						<tr>
 							<th>회수방법</th>
 							<td>
-								<label class="rdoBtn"><input type="radio" name="wdGb" th:id="wdGb" value="W" onclick="fnChangeQty()" checked="checked"/>회수요청<span></span></label>
-								<label class="rdoBtn"><input type="radio" name="wdGb" th:id="wdGb" value="D" onclick="fnChangeQty()"/>직접발송<span></span></label>
+								<label class="rdoBtn"><input type="radio" name="wdGb" th:id="wdGb" value="W" onclick="fnChangeWdGb(this)"/>회수요청<span></span></label>
+								<label class="rdoBtn"><input type="radio" name="wdGb" th:id="wdGb" value="D" onclick="fnChangeWdGb(this)"/>직접발송<span></span></label>
 							</td>
 							<th>추가배송비</th>
 							<td id="addDelvFee"></td>
@@ -73,8 +75,8 @@
 					</tbody>
 				</table>
 				
-				<h4>회수지 정보</h4>
-				<table class="frmStyle">
+				<h4 class="chger">회수지 정보</h4>
+				<table class="frmStyle chger">
 					<colgroup>
 						<col style="width:160px;" />
 						<col style="width:320px;" />
@@ -90,7 +92,7 @@
 							<th>회수지주소 <i class="star"></i></th>
 							<td colspan="3">
 								<input type="text" name ="chgerZipcode" class="w100" readonly="readonly"/>
-								<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('withdraw');">우편번호찾기</button>
+								<button type="button" class="btn btn-info" th:unless="${ordChgSq > 0}" onclick="fnOpenDaumAddr('withdraw');">우편번호찾기</button>
 								<input type="text" name ="chgerBaseAddr" class="w300"/>
 								<input type="text" name ="chgerDtlAddr" class="w300"/>
 							</td>
@@ -102,8 +104,8 @@
 									<option value="">[선택하세요]</option>
 									<option th:if="${TelExcNoList}" th:each="oneData, status : ${TelExcNoList}" th:value="${oneData.cd}" th:text="${oneData.cd}"></option>
 								</select>
-								- <input type="text" name ="chgerTelno2" class="w60" value="0000" />
-								- <input type="text" name ="chgerTelno3" class="w60" value="0000" />
+								- <input type="text" name ="chgerTelno2" class="w60"/>
+								- <input type="text" name ="chgerTelno3" class="w60"/>
 							</td>
 							<th>휴대전화 <i class="star"></i></th>
 							<td>
@@ -111,8 +113,8 @@
 									<option value="">[선택하세요]</option>
 									<option th:if="${PhnExcNoList}" th:each="oneData, status : ${PhnExcNoList}" th:value="${oneData.cd}" th:text="${oneData.cd}"></option>
 								</select>
-								- <input type="text" name ="chgerPhnno2" class="w60" value="0000" />
-								- <input type="text" name ="chgerPhnno3" class="w60" value="0000" />
+								- <input type="text" name ="chgerPhnno2" class="w60"/>
+								- <input type="text" name ="chgerPhnno3" class="w60"/>
 							</td>
 						</tr>
 						<tr>
@@ -141,7 +143,7 @@
 						<th>교환지주소 <i class="star"></i></th>
 						<td colspan="3">
 							<input type="text" name ="recipZipcode" class="w100" readonly="readonly"/>
-							<button type="button" class="btn btn-info" onclick="fnOpenDaumAddr('exchange');">우편번호찾기</button>
+							<button type="button" class="btn btn-info" th:unless="${ordChgSq > 0}" onclick="fnOpenDaumAddr('exchange');">우편번호찾기</button>
 							<input type="text" name ="recipBaseAddr" class="w300"/>
 							<input type="text" name ="recipDtlAddr" class="w300"/>
 						</td>
@@ -153,8 +155,8 @@
 								<option value="">[선택하세요]</option>
 								<option th:if="${TelExcNoList}" th:each="oneData, status : ${TelExcNoList}" th:value="${oneData.cd}" th:text="${oneData.cd}"></option>
 							</select>
-							- <input type="text" name ="recipTelno2" class="w60" value="0000" />
-							- <input type="text" name ="recipTelno3" class="w60" value="0000" />
+							- <input type="text" name ="recipTelno2" class="w60"/>
+							- <input type="text" name ="recipTelno3" class="w60"/>
 						</td>
 						<th>휴대전화 <i class="star"></i></th>
 						<td>
@@ -162,8 +164,8 @@
 								<option value="">[선택하세요]</option>
 								<option th:if="${PhnExcNoList}" th:each="oneData, status : ${PhnExcNoList}" th:value="${oneData.cd}" th:text="${oneData.cd}"></option>
 							</select>
-							- <input type="text" name ="recipPhnno2" class="w60" value="0000" />
-							- <input type="text" name ="recipPhnno3" class="w60" value="0000" />
+							- <input type="text" name ="recipPhnno2" class="w60"/>
+							- <input type="text" name ="recipPhnno3" class="w60"/>
 						</td>
 					</tr>
 					<tr>
@@ -184,16 +186,32 @@
 /*<![CDATA[*/
 var cancelRequestTargetList = [[${cancelRequestTargetList}]];				// 교환대상목록
 var ordNo 					= [[${ordNo}]];									// 주문번호
+var ordChgSq 				= [[${ordChgSq}]];								// 주문변경번호
 var orderInfoList 			= [[${orderInfoList}]];							// 주문기본정보
 var payMeans 				= orderInfoList[0].payMeans;					// 결제수단
 var orderDelvAddrInfo		= [[${orderDelvAddrInfo}]];						// 회수지정보
 var addDelvFee				= 0;											// 추가배송비
 var addDelvFeeList			= [];											// 추가배송비정보
 var exchangeRequestList		= [];											// 교환요청목록
+var exchangeInfoList;														// 교환정보
+var wdGb;																	// 회수방법
+var chgerRtnMemo;															// 반품메모
+var delvMemo;																// 배송메모
 
 var temp1 = true;
 var temp2 = true;
 
+// 변경요청정보 승인, 철회
+if (ordChgSq > 0) {
+	exchangeInfoList		= [[${exchangeInfoList}]];						// 교환정보
+	chgReason				= exchangeInfoList[0].chgReason;				// 변경사유코드
+	chgReasonNm				= exchangeInfoList[0].chgReasonNm;				// 변경사유코드명
+	chgMemo					= exchangeInfoList[0].chgMemo;					// 변경사유메모
+	chgerRtnMemo			= exchangeInfoList[0].chgerRtnMemo;				// 반품메모
+	delvMemo				= exchangeInfoList[0].delvMemo;					// 배송메모
+	wdGb					= exchangeInfoList[0].wdGb;						// 회수방법
+}
+
 // 1. 주문정보(교환대상)
 var columnExchangeReqList = [
 	{
@@ -274,26 +292,33 @@ var columnExchangeReqList = [
 				, width			: 100
 				, cellClass		: "text-center"
 				, cellRenderer	: function (params) {
-					var optArr			= params.data.optCd2s.split(',');
-					var ordChgOpt = params.data.ordChgOpt;
-
-					var strVal			= '';
-					strVal += '<select class="ordChgOpt" name="ordChgOpt" ordDtlNo="' + params.data.ordDtlNo + '" ordDtlItemSq="' + params.data.ordDtlItemSq + '" onchange="fnChangeOption(this)">';
-					
-					if (gagajf.isNull(ordChgOpt)) {
-						strVal += '<option value="">선택</option>';
+					if (ordChgSq > 0) {
+						$.each(exchangeInfoList, function(idx, item) {
+							if (params.data.itemCd == item.itemCd && params.data.optCd1 == item.optCd1) {
+								strVal = item.optCd2;
+							}
+						});
 					} else {
-						strVal += '<option value="" selected>선택</option>';
-					}
-
-					$.each(optArr, function(idx,item){
-						if (ordChgOpt == item) {
-							strVal += '<option value="' + item + '" selected>' + item + '</option>';
+						var optArr = params.data.optCd2s.split(',');
+						var ordChgOpt = params.data.ordChgOpt;
+						
+						var strVal = '';
+						strVal += '<select class="ordChgOpt" name="ordChgOpt" ordDtlNo="' + params.data.ordDtlNo + '" ordDtlItemSq="' + params.data.ordDtlItemSq + '" onchange="fnChangeOption(this)">';
+						
+						if (gagajf.isNull(ordChgOpt)) {
+							strVal += '<option value="">선택</option>';
 						} else {
-							strVal += '<option value="' + item + '">' + item + '</option>';
+							strVal += '<option value="" selected>선택</option>';
 						}
-					});
-
+						
+						$.each(optArr, function (idx, item) {
+							if (ordChgOpt == item) {
+								strVal += '<option value="' + item + '" selected>' + item + '</option>';
+							} else {
+								strVal += '<option value="' + item + '">' + item + '</option>';
+							}
+						});
+					}
 					return strVal;
 				}
 			},
@@ -304,23 +329,31 @@ var columnExchangeReqList = [
 				, width			: 100
 				, cellClass		: 'text-center'
 				, cellRenderer	: function (params) {
-					var ordQty 			= parseInt(params.data.ordQty);
-					var cnclRtnQty 		= parseInt(params.data.cnclRtnQty);
-					var ordReqChgQty 	= parseInt(params.data.ordReqChgQty);
-					var ordCanChgQty 	= ordQty - (cnclRtnQty +  ordReqChgQty);
-					
-					var strVal 			= "";
-					strVal += '<select class="ordCanChgQty ' + params.data.ordDtlNo + '" name="chgQty" ordDtlNo="'+params.data.ordDtlNo+'" onchange="fnChangeQty(this)">';
-					
-					for (i=0 ; i<=ordCanChgQty ; i++) {
-						if (i == params.data.chgQty) {
-							strVal += "	<option value='"+i+"' selected>"+i+"</option>";
-						} else {
-							strVal += "	<option value='"+i+"'>"+i+"</option>";
+					if (ordChgSq > 0) {
+						$.each(exchangeInfoList, function(idx, item) {
+							if (params.data.itemCd == item.itemCd && params.data.optCd1 == item.optCd1) {
+								strVal = item.chgQty;
+							}
+						});
+					} else {
+						var ordQty = parseInt(params.data.ordQty);
+						var cnclRtnQty = parseInt(params.data.cnclRtnQty);
+						var ordReqChgQty = parseInt(params.data.ordReqChgQty);
+						var ordCanChgQty = ordQty - (cnclRtnQty + ordReqChgQty);
+						
+						var strVal = "";
+						strVal += '<select class="ordCanChgQty ' + params.data.ordDtlNo + '" name="chgQty" ordDtlNo="' + params.data.ordDtlNo + '" onchange="fnChangeQty(this)">';
+						
+						for (i = 0; i <= ordCanChgQty; i++) {
+							if (i == params.data.chgQty) {
+								strVal += "	<option value='" + i + "' selected>" + i + "</option>";
+							} else {
+								strVal += "	<option value='" + i + "'>" + i + "</option>";
+							}
 						}
+						
+						strVal += "</select>";
 					}
-				
-					strVal += "</select>";
 					return strVal;
 				}
 			}
@@ -521,7 +554,7 @@ var gridOptionsDelvCdList = gagaAgGrid.getGridOptions(columnDelvCdList);
 //현재 사유는 회사 입니다.
 var isCustomer = false;
 
-//  사유
+//  사유 변경
 var fnChangeChgReason = function(reasonCd){
 	var arrReasonCd = reasonCd.split(":");
 	var customerReasonArr = ['G689_10', 'G689_30'];
@@ -620,8 +653,13 @@ var fnExchange = function () {
 		}
 	
 		var chgerPhnno 		= chgerPhnno1 + '-' + chgerPhnno2 + '-' + chgerPhnno3;
-		var chgerTelno 		= chgerTelno1 + '-' + chgerTelno2 + '-' + chgerTelno3;
 		var chgerEmail 		= orderInfoList[0].ordEmail;
+		var chgerTelno;
+		if (gagajf.isNull(chgerTelno1) && gagajf.isNull(chgerTelno2) && gagajf.isNull(chgerTelno3)) {
+			chgerTelno 		= '';
+		} else {
+			chgerTelno 		= chgerTelno1 + '-' + chgerTelno2 + '-' + chgerTelno3;
+		}
 	}
 
 	// 교환지정보 설정
@@ -657,10 +695,15 @@ var fnExchange = function () {
 	if (gagajf.isNull(recipPhnno3)) {
 		mcxDialog.alert("휴대전화를 입력하세요."); return;
 	}
-	
+
 	var recipPhnno 		= recipPhnno1 + '-' + recipPhnno2 + '-' + recipPhnno3;
-	var recipTelno 		= recipTelno1 + '-' + recipTelno2 + '-' + recipTelno3;
 	var recipEmail 		= orderInfoList[0].ordEmail;
+	var recipTelno;
+	if (gagajf.isNull(recipTelno1) && gagajf.isNull(recipTelno2) && gagajf.isNull(recipTelno3)) {
+		recipTelno 		= '';
+	} else {
+		recipTelno 		= recipTelno1 + '-' + recipTelno2 + '-' + recipTelno3;
+	}
 	
 	var jsonObj = {
 		"ordNo"				: $('#exchangeRequestFrm input[name=ordNo]').val()
@@ -708,6 +751,31 @@ var fnExchange = function () {
 	});
 }
 
+// 교환철회 처리
+var fnExchangeCancel = function() {
+	let data = {};
+	data.ordChgSq = ordChgSq;
+	data.ordNo = ordNo;
+
+	let jsonData = JSON.stringify(data);
+
+	mcxDialog.confirm('요청번호 [' + ordChgSq + '] 에 대한 요청철회 처리를 하시겠습니까?', {
+		cancelBtnText		: "취소",
+		sureBtnClick		: function(){
+			// 교환 실행
+			gagajf.ajaxJsonSubmit(
+				'/orderChange/exchangeCancelRequest/'
+				, jsonData
+				, function() {
+					uifnPopupClose('popupOrderDetail');
+					fnReOpenOrderDetailPopup();
+					uifnPopupClose('popupExchangeRequestForm');
+				}
+			);
+		}
+	});
+}
+
 // 우편번호 DAUM을 이용한 우편번호 팝업 레이어
 var fnOpenDaumAddr = function(loc) {
 	let daumZip = new daum.Postcode({
@@ -734,7 +802,14 @@ var fnOpenDaumAddr = function(loc) {
 
 // 회수지정보 설정
 var fnSetChger = function(){
-	var data = orderDelvAddrInfo[0];
+	var data;
+	
+	if (ordChgSq > 0) {
+		data = exchangeInfoList[0];
+	} else {
+		data = orderDelvAddrInfo[0];
+	}
+	
 	var spRecipPhnno = (data.recipPhnno != null) ? data.recipPhnno.split('-') : null;
 	var spRecipTelno = (data.recipTelno != null) ? data.recipTelno.split('-') : null;
 	
@@ -742,6 +817,7 @@ var fnSetChger = function(){
 	$("#exchangeRequestFrm input[name=chgerZipcode]").val(data.recipZipcode);
 	$("#exchangeRequestFrm input[name=chgerBaseAddr]").val(data.recipBaseAddr);
 	$("#exchangeRequestFrm input[name=chgerDtlAddr]").val(data.recipDtlAddr);
+	$("#exchangeRequestFrm textarea[name=chgerRtnMemo]").val(data.chgerRtnMemo);
 	
 	if (spRecipPhnno) {
 		$("#exchangeRequestFrm select[name=chgerPhnno1]").val(spRecipPhnno[0]);
@@ -758,7 +834,14 @@ var fnSetChger = function(){
 
 // 교환지정보 설정
 var fnSetExchangeAddr = function(){
-	var data = orderDelvAddrInfo[0];
+	var data;
+	
+	if (ordChgSq > 0) {
+		data = exchangeInfoList[0];
+	} else {
+		data = orderDelvAddrInfo[0];
+	}
+	
 	var spRecipPhnno = (data.recipPhnno != null) ? data.recipPhnno.split('-') : null;
 	var spRecipTelno = (data.recipTelno != null) ? data.recipTelno.split('-') : null;
 	
@@ -821,6 +904,8 @@ var fnChangeQty = function(param) {
 			}
 		} else if (item.chgQty > 0) {
 			exchangeRequestTargetList.push(item);
+		} else if (ordChgSq > 0 && item.ordCanChgQty > 0) {
+			exchangeRequestTargetList.push(item);
 		}
 	});
 
@@ -867,7 +952,22 @@ var fnAddDelvFee = function (exchangeRequestTargetList) {
 		gridOptionsDelvCdList.api.setRowData();
 	}
 	
-	$('#addDelvFee').text(addDelvFee + '원');
+	$('#addDelvFee').text(addDelvFee.addComma() + '원');
+}
+
+// 회수방법 라디오 클릭 이벤트
+var fnChangeWdGb = function(param) {
+	let wdGb = $(param).val();
+
+	// 회수지정보 히든 처리
+	if (wdGb == 'D') {
+		$('.chger').css('display', 'none');
+	} else {
+		$('.chger').css('display', '');
+	}
+
+	// 추가배송비 계산
+	fnChangeQty();
 }
 
 $(document).ready(function() {
@@ -886,6 +986,50 @@ $(document).ready(function() {
 	
 	// 4. 교환지정보설정
 	fnSetExchangeAddr();
+	
+	// 5. 회수방법 라디오 체크 처리
+	if (wdGb == 'D') {
+		$('input:radio[name="wdGb"]:radio[value="D"]').prop('checked', true);
+	} else {
+		$('input:radio[name="wdGb"]:radio[value="W"]').prop('checked', true);
+	}
+	
+	// 교환철회 처리
+	if (ordChgSq > 0) {
+		// 5. 교환사유설정
+		$('#chgReason').text(chgReasonNm);
+		
+		// 6. 교환요청메모설정
+		$('#chgMemo').text(chgMemo);
+		
+		// 7. 귀책사유 설정
+		fnChangeChgReason(chgReason);
+		
+		// 8. 데이터 Disabled 처리
+		$('input:radio[name=wdGb]').attr('disabled', true);				// 8-1. 회수방법
+		$('#chgMemo').attr('readOnly', true);							// 8-2. 요청메모
+		$('input[name=chgerNm]').attr('readOnly', true);				// 8-3. 회수지정보 > 보내는사람
+		$('input[name=chgerBaseAddr]').attr('readOnly', true);			// 8-4. 회수지정보 > 기본주소
+		$('input[name=chgerDtlAddr]').attr('readOnly', true);			// 8-5. 회수지정보 > 상세주소
+		$('select[name=chgerTelno1]').attr('disabled', true);			// 8-6. 회수지정보 > 일반전화
+		$('input[name=chgerTelno2]').attr('readOnly', true);			// 8-6. 회수지정보 > 일반전화
+		$('input[name=chgerTelno3]').attr('readOnly', true);			// 8-6. 회수지정보 > 일반전화
+		$('select[name=chgerPhnno1]').attr('disabled', true);			// 8-7. 회수지정보 > 휴대전화
+		$('input[name=chgerPhnno2]').attr('readOnly', true);			// 8-7. 회수지정보 > 휴대전화
+		$('input[name=chgerPhnno3]').attr('readOnly', true);			// 8-7. 회수지정보 > 휴대전화
+		$('#chgerRtnMemo').attr('readOnly', true);						// 8-8. 회수지정보 > 반품메모
+		$('input[name=recipNm]').attr('readOnly', true);				// 8-9. 교환지정보 > 받는사람
+		$('input[name=recipBaseAddr]').attr('readOnly', true);			// 8-10. 교환지정보 > 기본주소
+		$('input[name=recipDtlAddr]').attr('readOnly', true);			// 8-11. 교환지정보 > 상세주소
+		$('select[name=recipTelno1]').attr('disabled', true);			// 8-12. 교환지정보 > 일반전화
+		$('input[name=recipTelno2]').attr('readOnly', true);			// 8-12. 교환지정보 > 일반전화
+		$('input[name=recipTelno3]').attr('readOnly', true);			// 8-12. 교환지정보 > 일반전화
+		$('select[name=recipPhnno1]').attr('disabled', true);			// 8-13. 교환지정보 > 휴대전화
+		$('input[name=recipPhnno2]').attr('readOnly', true);			// 8-13. 교환지정보 > 휴대전화
+		$('input[name=recipPhnno3]').attr('readOnly', true);			// 8-13. 교환지정보 > 휴대전화
+		$('#delvMemo').prop('readOnly', true);							// 8-14. 교환지정보 > 배송메모
+		
+	}
 });
 </script>
 </html>

+ 9 - 2
src/main/webapp/WEB-INF/views/order/OrderDetailForm.html

@@ -618,7 +618,7 @@ var columnDefsOrderChangeInfo = [
 				rtnStr = '<a href="javascript:void(0);" onclick="fnCancelRequest(\'' + params.value + '\');">' + params.value + '</a>';
 			} else if (params.data.chgStat == 'G685_40') {
 				rtnStr = '<a href="javascript:void(0);" onclick="fnReturnRequest(\'' + params.value + '\');">' + params.value + '</a>';
-			} else if (params.data.chgStat == 'G685_30') {
+			} else if (params.data.chgStat == 'G685_30' || params.data.chgStat == 'G685_33') {
 				rtnStr = '<a href="javascript:void(0);" onclick="fnExchangeRequest(\'' + params.value + '\');">' + params.value + '</a>';
 			} else {
 				rtnStr = params.value;
@@ -644,6 +644,13 @@ var columnDefsOrderChangeInfo = [
 		}
 	},
 	{headerName: "변경사유"		, field: "chgReasonNm"	, width: 100	, cellClass: 'text-center'},
+	{
+		headerName: "회수구분", field: "wdGb", width: 100, cellClass: 'text-center',
+		cellRenderer: function (params) {
+			console.log(params);
+			return params.value == 'W' ? '회수요청' : '직접배송'; 
+		}
+	},
 	{headerName: "요청메모"		, field: "chgMemo"		, width: 150	, cellClass: 'text-center'},
 	{headerName: "변경자명"		, field: "chgerNm"		, width: 100	, cellClass: 'text-center'},
 	{headerName: "변경자핸드폰"		, field: "chgerPhnno"	, width: 120	, cellClass: 'text-center', editable: true},
@@ -656,7 +663,7 @@ var columnDefsOrderChangeInfo = [
 			var rtnStr = ""
 			
 			// 회수지수정가능(교환요청, 반품요청)
-			if (!params.data.wdGb != 'D' && (params.data.chgStat == 'G685_30' || params.data.chgStat == 'G685_40')) {
+			if (params.data.wdGb != 'D' && (params.data.chgStat == 'G685_30' || params.data.chgStat == 'G685_33' || params.data.chgStat == 'G685_40')) {
 				
 				rtnStr += params.value;			
 				rtnStr += "<button type=\"button\" style=\"margin-left:10px\" class=\"btn btn-info\" onclick=\"fnOpenDaumAddr('" + params.node.rowIndex + "', 'CLAIM');\">POST</button>";