Bläddra i källkod

기획전 임시 커밋

sowon4187 5 år sedan
förälder
incheckning
6abedf3db0

+ 58 - 0
src/main/java/com/style24/admin/biz/dao/TsaPlanDao.java

@@ -0,0 +1,58 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import org.springframework.stereotype.Repository;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Coupon;
+import com.style24.persistence.domain.Plan;
+
+/**
+ * 기획전 Dao
+ *
+ * @author sowon
+ * @since 2021. 2. 4
+ */
+
+@ShopDs
+@Repository
+public interface TsaPlanDao {
+	/**
+	 * 기획전 코너 전체 조회
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 4
+	 */
+	Collection<Plan> getPlanAllList(Plan param);
+	
+	/**
+	 * 기획전 웹 등록
+	 *
+	 * @param 기획전 등록 정보
+	 * @author rladbwnd5
+	 * @since 2019. 12. 31
+	 */
+	void createPlanWebInfo(Plan param);
+	
+	/**
+	 * 기획전 목록
+	 *
+	 * @param 검색조건
+	 * @return
+	 * @author sowon
+	 * @since 2019. 12. 27
+	 */
+	Collection<Plan> getPlanList(Plan param);
+	
+	/**
+	 * 기획전 리스트 카운트 조회
+	 * @param  param
+	 * @return int
+	 * @author sowon
+	 * @since 2021. 2. 5
+	 */
+	int getPlanListCnt(Plan param);
+}

+ 213 - 0
src/main/java/com/style24/admin/biz/service/TsaPlanService.java

@@ -0,0 +1,213 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaPlanDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.session.TscSession;
+import com.style24.persistence.domain.Coupon;
+import com.style24.persistence.domain.Plan;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 기획전 Service
+ * 
+ * @author sowon
+ * @since 2021. 02. 04
+ */
+@Service
+@Slf4j
+public class TsaPlanService {
+
+	@Autowired
+	private TsaPlanDao planDao;
+	
+	/**
+	 * 기획전 코너 전체 조회
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 4
+	 */
+	public Collection<Plan> getPlanAllList(Plan param) {
+		return planDao.getPlanAllList(param);
+	}
+	
+	/**
+	 * 기획전 웹 등록
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2019. 12. 31
+	 */
+	@Transactional("shopTxnManager")
+	public void createPlanWebInfo(Plan param) {
+		param.setRegNo(TsaSession.getInfo().getUserNo());
+		param.setUpdNo(TsaSession.getInfo().getUserNo());
+		planDao.createPlanWebInfo(param);
+
+		log.debug("planSq : {}", param.getPlanSq());
+
+		// 웹용 소스
+//		if (StringUtils.isNotBlank(param.getFsrcPc())) {
+//			createPlanFsrcPc(param);
+//		}
+
+//		// 모바일용 소스
+//		if (StringUtils.isNotBlank(param.getFsrcMobile())) {
+//			createPlanFsrcMobile(param);
+//		}
+//
+//		//기획전 응모이벤트
+//		if (StringUtils.isNotBlank(param.getPrivacyPolicy())) {
+//			int i = 0;
+//			for (String planQtitle : param.getPlanQtitle()) {
+//				TsaPlanQuestAnswer planQuestAnswer = new TsaPlanQuestAnswer();
+//				planQuestAnswer.setPlanSq(param.getPlanSq());
+//				planQuestAnswer.setPlanQtitle(planQtitle);
+//				planQuestAnswer.setAttachYn(param.getAttachYn()[i]);
+//				planQuestAnswer.setQuestNo(i);
+//				planQuestAnswer.setRegId(param.getRegId());
+//				planQuestAnswer.setUpdId(param.getUpdId());
+//				marketingDao.savePlanQuestion(planQuestAnswer);
+//				i++;
+//			}
+//		}
+
+	}
+	/*
+	 * 기획전 웹용 소스 등록
+	 */
+//	@Transactional("shopTxnManager")
+//	public Plan createPlanFsrcPc(Plan param) {
+//		int fsrcPcTotalCnt = param.getFsrcPc().toCharArray().length;
+//		int byteCnt = 1500;
+//
+//		// 기존 소스 삭제
+//		param.setFrontGb("P");
+//		planDao.deletePlanFsrcInfo(param);
+//		if (fsrcPcTotalCnt > byteCnt) { // 4000 바이트 이상 일 때 파싱.
+//			StringBuilder sbStr = new StringBuilder(4000);
+//
+//			int cnt = 0;
+//			int getCnt = 0;
+//			int tempCnt = 1500;
+//
+//			for (char ch : param.getFsrcPc().toCharArray()) {
+//				getCnt++;
+//				sbStr.append(ch);
+//
+//				if (getCnt == tempCnt || getCnt == fsrcPcTotalCnt) {
+//					TsaPlan planPc = new TsaPlan();
+//					planPc.setPlanSq(param.getPlanSq());
+//					planPc.setFrontGb("P");
+//					planPc.setSeq(cnt + 1);
+//					planPc.setRegId(param.getRegId());
+//					planPc.setFsrc(sbStr.toString());
+//
+//					// 초기화
+//					sbStr.delete(0, tempCnt);
+//					cnt++;
+//					tempCnt += byteCnt;
+//
+//					marketingDao.savePlanFsrcInfo(planPc);
+//				}
+//
+//			}
+//		} else {
+//			TsaPlan planPc = new TsaPlan();
+//			planPc.setPlanSq(param.getPlanSq());
+//			planPc.setFrontGb("P");
+//			planPc.setSeq(1);
+//			planPc.setRegId(param.getRegId());
+//			planPc.setFsrc(param.getFsrcPc());
+//
+//			marketingDao.savePlanFsrcInfo(planPc);
+//		}
+//		return param;
+//	}
+//
+//	/*
+//	 * 기획전 모바일 소스 등록
+//	 */
+//	@Transactional("shopTxnManager")
+//	public TsaPlan createPlanFsrcMobile(TsaPlan param) {
+//		int fsrcMobileTotalCnt = param.getFsrcMobile().toCharArray().length;
+//		int byteCnt = 1500;
+//
+//		// 기존 소스 삭제
+//		param.setFrontGb("M");
+//		marketingDao.deletePlanFsrcInfo(param);
+//		if (fsrcMobileTotalCnt > byteCnt) { // 4000 바이트 이상 일 때 파싱.
+//			StringBuilder sbStr = new StringBuilder(4000);
+//
+//			int cnt = 0;
+//			int getCnt = 0;
+//			int tempCnt = 1500;
+//
+//			for (char ch : param.getFsrcMobile().toCharArray()) {
+//				getCnt++;
+//				sbStr.append(ch);
+//
+//				if (getCnt == tempCnt || getCnt == fsrcMobileTotalCnt) {
+//					TsaPlan planMobile = new TsaPlan();
+//					planMobile.setPlanSq(param.getPlanSq());
+//					planMobile.setFrontGb("M");
+//					planMobile.setSeq(++cnt);
+//					planMobile.setRegId(param.getRegId());
+//					planMobile.setFsrc(sbStr.toString());
+//
+//					// 초기화
+//					sbStr.delete(0, tempCnt);
+//					//					cnt++;
+//					tempCnt += byteCnt;
+//
+//					marketingDao.savePlanFsrcInfo(planMobile);
+//				}
+//			}
+//		} else {
+//			TsaPlan planMobile = new TsaPlan();
+//			planMobile.setPlanSq(param.getPlanSq());
+//			planMobile.setFrontGb("M");
+//			planMobile.setSeq(1);
+//			planMobile.setRegId(param.getRegId());
+//			planMobile.setFsrc(param.getFsrcMobile());
+//
+//			marketingDao.savePlanFsrcInfo(planMobile);
+//		}
+//		return param;
+//	}
+	
+	/**
+	 * 기획전 목록
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 5
+	 */
+	public Collection<Plan> getPlanList(Plan param) {
+		return planDao.getPlanList(param);
+	}
+	
+	/**
+	 * 기획전 목록 카운트 조회
+	 * @param  param
+	 * @return int
+	 * @author sowon
+	 * @since 2021. 2. 5
+	 */
+	public int getPlanListCnt(Plan param) {
+		return planDao.getPlanListCnt(param);
+	}
+
+
+}

+ 120 - 41
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -24,6 +24,7 @@ import com.style24.admin.biz.service.TsaCommonService;
 import com.style24.admin.biz.service.TsaCouponService;
 import com.style24.admin.biz.service.TsaFreegiftPromotionService;
 import com.style24.admin.biz.service.TsaMorebetterService;
+import com.style24.admin.biz.service.TsaPlanService;
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.biz.service.TsaReviewService;
 import com.style24.admin.biz.service.TsaSystemService;
@@ -32,6 +33,7 @@ import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.biz.service.TscPointService;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.core.support.session.TscSession;
 import com.style24.persistence.TscPageRequest;
 import com.style24.persistence.domain.CardPromotion;
 import com.style24.persistence.domain.CardPromotionTarget;
@@ -44,6 +46,7 @@ import com.style24.persistence.domain.MoreBetter;
 import com.style24.persistence.domain.MoreBetterBurden;
 import com.style24.persistence.domain.MoreBetterGoods;
 import com.style24.persistence.domain.MoreBetterSection;
+import com.style24.persistence.domain.Plan;
 import com.style24.persistence.domain.Point;
 import com.style24.persistence.domain.Review;
 import com.style24.persistence.domain.User;
@@ -96,6 +99,10 @@ public class TsaMarketingController extends TsaBaseController {
 
 	@Autowired
 	private TsaCardPromotionService cardPromotionService;
+	
+	@Autowired
+	private TsaPlanService planService;
+
 
 	/**
 	 * 상품평관리 화면
@@ -853,50 +860,15 @@ public class TsaMarketingController extends TsaBaseController {
 	 */
 	@PostMapping("/morebetter/changeStat")
 	@ResponseBody
-	public GagaMap updateMorebetterStat(@RequestBody MoreBetter moreBetter) {
-		GagaMap map = new GagaMap();
-
-		try{
-			log.info("getTmtbStat :::{}",moreBetter.getTmtbStat());
-			MoreBetterGoods moreBetterGoods = new MoreBetterGoods();
-
-			if("G232_11".equals(moreBetter.getTmtbStat())){
-				moreBetterGoods.setMultiSupplyCompCd(moreBetter.getMultiSupplyCompCd());
-				moreBetterGoods.setMultiBrand(moreBetter.getMultiBrand());
-				moreBetterGoods.setMultiApplyGoods(moreBetter.getMultiApplyGoods());
-				moreBetterGoods.setMultiExceptGoods(moreBetter.getMultiExceptGoods());
-
-				// TMTB_GOODS_TEMP TABLE TRUNCATE -> 다른 다다에서 사용중인 상품 조회 -> INSERT
-				moreBetterGoods.setApplyGoodsList(moreBetter.getApplyGoodsList());
-				moreBetterGoods.setSectionGb(moreBetter.getSectionGb());
-				morebetterService.createMorebetterGoodsTemp(moreBetterGoods);
-
-				// 다른 다다에서 사용중인 상품 조회
-				Collection<MoreBetterGoods> duplicateGoodsList = morebetterService.getMorebetterDuplicateList(moreBetterGoods);
-
-				// 조회 건수 있으면 -> 해당 상품코드 엑셀로 던져주기
-				if(duplicateGoodsList.size() > 0){
-					map.set("duplicateYn","Y");
-					map.set("duplicateGoodsList",duplicateGoodsList);
-					map.set("message", message.getMessage("FAIL_0001"));
-				}else{
-					// 조회 건수 없으면 -> 저장으로 넘어감
-					map.set("duplicateYn","N");
-					morebetterService.saveMoreBetterDetail(moreBetter);
-					//morebetterService.updateMorebetterStat(moreBetter);
-					map.set("message", message.getMessage("SUCC_0002"));
-				}
-			}else{
-				morebetterService.updateMorebetterStat(moreBetter);
-				map.set("message", message.getMessage("SUCC_0002"));
-			}
-		} catch(Exception e) {
+	public GagaResponse updateMorebetterStat(@RequestBody MoreBetter moreBetter) {
+		try {
+			morebetterService.updateMorebetterStat(moreBetter);
+		} catch (Exception e) {
 			e.printStackTrace();
-			map.set("message", message.getMessage("FAIL_0001"));
-			return map;
+			return super.error(message.getMessage("FAIL_0001"));
 		}
 
-		return map;
+		return super.ok(message.getMessage("SUCC_0003"));
 	}
 
 	/**
@@ -1257,4 +1229,111 @@ public class TsaMarketingController extends TsaBaseController {
 	 *   카드관련 작업 종료 - eskim
 	 */
 
+	/**
+	 *   기획전 작업 시작 - sowon
+	 */
+
+	/**
+	 * 기획전 관리
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 3
+	 */
+	@GetMapping("/planning/form")
+	public ModelAndView planListForm() {
+		ModelAndView mav = new ModelAndView();		
+		// 사이트 목록
+		mav.addObject("siteCdList", rendererService.getCommonCodeList("G000"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		mav.setViewName("marketing/PlanListForm");
+		return mav;
+	}
+	
+	/**
+	 * 기획전 웹 등록/수정 화면
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 04
+	 */
+	@GetMapping("/planning/webdetail/form")
+	public ModelAndView planWebDetailForm(Plan param) {
+		ModelAndView mav = new ModelAndView();
+
+		if (param.getMode().equals("N")) { // 신규 일 때
+			// 기획전 전체 목록
+			mav.addObject("planList", planService.getPlanAllList(param));
+
+		} //else { // 상세 일 때
+//			mav.addObject("planInfo", marketingService.getPlanWebDetailInfo(param));
+//
+//			mav.addObject("fsrcPc", marketingService.getPlanFsrcPcList(param));
+//
+//			mav.addObject("fsrcMobile", marketingService.getPlanFsrcMobileList(param));
+//
+//			mav.addObject("planQuestionList", marketingService.getPlanQuestionList(param));
+//
+//			mav.addObject("brandList", rendererService.getSupplyCompanyBrandList("W"));
+//		}
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getCommonCodeList("G000"));
+
+		// 공급업체 목록
+//		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+//
+//		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+//
+//		// 회원구분 목록
+//		mav.addObject("custGbList", rendererService.getCommonCodeList("G100", "Y"));
+//
+//		// 회원등급 목록
+//		mav.addObject("custGradeList", rendererService.getCommonCodeList("G110", "Y"));
+		mav.addObject("mode", param.getMode());
+		mav.setViewName("marketing/PlanWebDetailPopupForm");
+		return mav;
+	}
+	
+	/**
+	 * 기획전 웹 등록
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 4
+	 */
+	@PostMapping("/planning/webdetail/create")
+	@ResponseBody
+	public GagaResponse createPlanWebInfo(@RequestBody Plan param) {
+		planService.createPlanWebInfo(param);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	
+	/**
+	 * 기획전관리 목록
+	 *
+	 * @param
+	 * @return 기획전 목록
+	 * @author sowon
+	 * @since 2021. 2. 5
+	 */
+	@PostMapping("/planning/list")
+	@ResponseBody
+	public GagaMap getPlanList(@RequestBody Plan param) {
+		GagaMap result = new GagaMap();
+		Collection<Plan> planList = planService.getPlanList(param);
+
+		param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		param.setPageable(new TscPageRequest(param.getPageNo() - 1, param.getPageSize()));
+		param.getPageable().setTotalCount(planService.getPlanListCnt(param));
+		result.set("pageing", param);
+		result.set("planList", planList);
+
+		//log.debug("dataList: {}", planList);
+
+		return result;
+	}
+
 }

+ 144 - 0
src/main/java/com/style24/persistence/domain/Plan.java

@@ -0,0 +1,144 @@
+package com.style24.persistence.domain;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 기획전 Domain
+ *
+ * @author sowon
+ * @since 2021. 02. 04
+ */
+
+@SuppressWarnings("serial")
+@Data
+public class Plan extends TscBaseDomain{
+	// 기획전
+		private long planSq;				//기획전일련번호(SeqPlan sequence)
+		private String planNm;				//기획전명
+		private String planGb;				//기획전구분(P:기획전private String  E:이벤트)
+		private String custGb;				//고객구분
+		private String custGrade;			//회원등급
+		private String planSnm;				//검색어
+		private String templateType;		//템플릿유형(H:Htmlprivate String  T:텍스트)
+		private String siteCd;				//사이트코드(공통코드g000)
+		private String frontGb;				//프론트구분(A:All, P:웹, M:모바일)
+		private String dispStdt;			//기획전 시작일시
+		private String dispEddt;			//기획전 종료일시
+		private String mainPimg;			//메인이미지(Pc)
+		private String mainMimg;			//메인이미지(모바일)
+		private String dtlPimg;				//상세이미지(Pc)
+		private String dtlMimg;				//상세이미지(모바일)
+		private String orgMainPimg;			//원본메인이미지(Pc)
+		private String orgMainMimg;			//원본메인이미지(모바일)
+		private String orgDtlPimg;			//원본상세이미지(Pc)
+		private String orgDtlMimg;			//원본상세이미지(모바일)
+		private String orgMainPimgDelYn;	//원본메인이미지(Pc) 삭제여부
+		private String orgMainMimgDelYn;	//원본메인이미지(모바일) 삭제여부
+		private String orgDtlPimgDelYn;		//원본상세이미지(Pc) 삭제여부
+		private String orgDtlMimgDelYn;		//원본상세이미지(모바일) 삭제여부
+		private String dtlTitle1;			//상세제목1
+		private String dtlTitle2;			//상세제목2
+		private String cateCd;				//카테고리코드(대/중/소/세카테고리)
+		private String cateDispYn;			//카테고리전시여부(Y:전시)
+		private String replyYn;				//댓글여부(Y:댓글)
+		private String replyLoc;			//댓글위치(U:상품리스트상단 D:상품리스트하단)
+		private String replyImg;			//댓글이미지
+		private String orgReplyImg;			//원본댓글이미지
+		private String replyTitle1;			//댓글제목1
+		private String replyTitle2;			//댓글제목2
+		private String devUrl;				//호출 URL
+		private String orgReplyImgDelYn;	//원본댓글이미지 삭제여부
+		private String cornerNmDispYn;		//코너명노출여부(Y:노출)
+		private String goodsLimitYn;		//상품등록제한여부(Y:상품등록제한)
+		private String goodsLimitQty;		//상품등록제한수(상품등록제한여부가 "Y"일 떄)
+		private String delYn;				//삭제여부(Y:삭제)
+		private String openYn;				//오픈여부(Y:오픈)
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private long[] dispOrdArr;			// 표시순서 배열
+		private long dispOrd;				//표시순서
+		private long readCnt;				//조회수
+		private Integer pollSq;				//투표일련번호
+		private String badgeNm;				//뱃지이름
+		private String badgeFcolor;			//뱃지글자컬러
+		private String badgeBcolor;			//뱃지배경컬러
+		private String privacyPolicy;		//개인정보수집동의정책
+
+		// 기획전 소스
+		private long seq;					//일련번호
+		private String fsrc;				//프론트소스
+		private String fsrcPc;				//프론트소스(pc)	/ 화면용
+		private String fsrcMobile;			//프론트소스(모바일)	/ 화면용
+
+		// 기획전 상세
+		private long planDtlSq;				//기획전상세일련번호(SEQ_PLAN_DTL sequence)
+		private long copyPlanDtlSq;			//복사할 상세 일련번호
+		private long copyPlanSq;			//복사할 일련번호
+		private String copyMode;			//복사 선택(CORNER:코너복사, PLAN:기획전복사)
+		private String cornerDispType;		//코너노출유형(공통코드G045) (2:2컷 , 3:3컷, 4:4컷)
+		private String cornerNm;			//코너 명
+		private String planDtlStat;			//기획전상세상태(공통코드G044)
+
+		// 기획전 응모
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] planQtitle;
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] attachYn;
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] planAnswerSq;
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] answer;
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] sysFileNm;
+
+		//private Collection<TsaPlanQuestAnswer> planQuestAnswerList; // 고시항목
+
+		// 검색
+		private String startSearchDate;		// 진행기간 시작일
+		private String startSearchTime;		// 진행기간 시작시간
+		private String endSearchDate;		// 진행기간 종료일
+		private String endSearchTime;		// 진행기간 종료시간
+		private String excelFileNm;			// 엑셀 파일 명
+		private int startRow;				// 페이징 시작
+		private int endRow;					// 피이징 종료
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] siteCds;			// 사이트
+
+		// 코너 상품
+		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+		private String[] goodsCdArr;		// 상품 코드 배열
+		private String goodsCd;				// 상품 코드
+		private String goodsNm;				// 상품 명
+		private String imgType;				// 이미지 타입
+		private String imgPath1;			// 이미지 경로1
+		private String imgPath2;			// 이미지 경로2
+		private String imgPath4;			// 이미지 경로4
+		private String imgPath5;			// 이미지 경로5
+		private String imgPath6;			// 이미지 경로6
+		private String goodsStat;			// 상품 상태
+		private String dcRate;				// 할인율
+		private String listPrice;			// 최소 소비자가
+		private String tagPrice;			// tag 가
+		private String currPrice;			// 판매가
+		private String supplyCompCd;		// 업체코드
+		private String supplyCompNm;		// 업체명
+		private String formalGb;			// 정상/이월 여부
+		private String currStockQty;		// 재고
+		private String pageYn;				// 페이징 사용 여부
+		private String changeGb;			// 순서변경 updown 구분
+
+		// 기획전 팝업
+		private String callBackFun;			// 콜백함수명
+		private String popupDispStdt;		//기획전 시작일시
+		private String popupDispEddt;		//기획전 종료일시
+		
+		// Pagination
+		private TscPageRequest pageable;
+		private int pageNo = 1;
+		private int pageSize = 50;
+		private int pageUnit = 10;
+}

+ 258 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaPlan.xml

@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!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.TsaPlanDao">
+
+	<!-- 기획전 등록 -->
+	<insert id="createPlanWebInfo" parameterType="Plan">
+		/* TsaMarketing.createPlanWebInfo */
+		<selectKey keyProperty="planSq" resultType="Integer" order="AFTER">
+			SELECT LAST_INSERT_ID()	/* 기획전 일련번호  */
+		</selectKey>
+		INSERT INTO TB_PLAN (
+		       PLAN_SQ               
+		     , PLAN_NM               
+		     , PLAN_GB               
+		     <!-- , CUST_GB -->
+		    <!--  , CUST_GRADE -->
+		     <!-- , PLAN_SNM -->
+		     , TEMPLATE_TYPE         
+		     , SITE_CD               
+		     , FRONT_GB              
+		     , DISP_STDT             
+		     , DISP_EDDT             
+		     , MAIN_PIMG             
+		     , MAIN_MIMG             
+		     , DTL_PIMG              
+		     , DTL_MIMG              
+		     , DTL_TITLE1            
+		     <!-- , DTL_TITLE2 -->          
+		     <!-- , CATE_CD               
+		     , CATE_DISP_YN   -->        
+		     , REPLY_YN              
+		     , REPLY_LOC           
+		     , REPLY_IMG           
+		     , REPLY_TITLE1        
+		     , REPLY_TITLE2        
+		     , POLL_SQ             
+		     <!-- , PRIVACY_POLICY -->
+		     , DEV_URL             
+		     , CORNER_NM_DISP_YN   
+		     , GOODS_LIMIT_YN      
+		     , GOODS_LIMIT_QTY     
+		     , DEL_YN              
+		     , OPEN_YN             
+		     , DISP_ORD            
+		     , READ_CNT              
+		     , BADGE_NM              
+		     , BADGE_FCOLOR          
+		     , BADGE_BCOLOR          
+		     , REG_NO               
+		     , REG_DT                
+		     , UPD_NO                
+		     , UPD_DT                
+		   ) VALUES (
+		       #{planSq}
+		     , #{planNm}
+		     , #{planGb}
+		    <!--  , #{custGb} -->
+		     <!-- , #{custGrade} -->
+		     <!-- , #{planSnm} -->
+		     , #{templateType}
+		     , #{siteCd}
+		     , #{frontGb}
+		     , DATE_FORMAT(#{dispStdt} , '%Y-%m-%d %H:%i:%s')
+		     , DATE_FORMAT(#{dispEddt} , '%Y-%m-%d %H:%i:%s')
+		     , #{mainPimg}
+		     , #{mainMimg}
+		     , #{dtlPimg}
+		     , #{dtlMimg}
+		     , #{dtlTitle1}
+		     <!-- , #{cateCd}
+		     , NVL(#{cateDispYn}, 'N') -->
+		     , #{replyYn}
+		     , #{replyLoc}
+		     , #{replyImg}
+		     , #{replyTitle1}
+		     , #{replyTitle2}
+		     , #{pollSq}
+		     <!-- , #{privacyPolicy} -->
+		     , #{devUrl}
+		     , #{cornerNmDispYn}
+		     , IFNULL(#{goodsLimitYn}, 'N')
+		     , #{goodsLimitQty}
+		     , 'N'
+		     , #{openYn}
+		     , #{dispOrd}
+		     , 1
+		     , #{badgeNm}
+		     , #{badgeFcolor}
+		     , #{badgeBcolor}
+		     , #{regNo}
+		     , now() 
+		     , #{updNo}
+		     , now()
+		)
+	</insert>
+	
+	<!-- 기획전 목록 -->
+	<select id="getPlanList" parameterType="Plan" resultType="Plan">
+		/* TsaMarketing.getPlanList */
+		SELECT PLAN_SQ                
+		     , PLAN_NM                
+		     , PLAN_GB                
+		     <!-- , CUST_GB -->
+		     <!-- , CUST_GRADE -->
+		     <!-- , PLAN_SNM -->
+		     , TEMPLATE_TYPE          
+		     , SITE_CD                
+		     , FRONT_GB               
+		     , DISP_STDT    
+		     , DISP_EDDT   
+		     , MAIN_PIMG              
+		     , MAIN_MIMG              
+		     , DTL_PIMG               
+		     , DTL_MIMG               
+		     , DTL_TITLE1             
+		     <!-- , DTL_TITLE2 -->
+		     <!-- , CATE_CD -->
+		     <!-- , CATE_DISP_YN -->           
+		     , REPLY_YN               
+		     , REPLY_TITLE1           
+		     , REPLY_TITLE2           
+		     , REPLY_LOC              
+		     , REPLY_IMG              
+		     , POLL_SQ                
+		     <!-- , PRIVACY_POLICY -->
+		     , DEV_URL                
+		     , CORNER_NM_DISP_YN      
+		     , GOODS_LIMIT_YN         
+		     , GOODS_LIMIT_QTY        
+		     , DEL_YN                 
+		     , OPEN_YN                
+		     , DISP_ORD               
+		     , READ_CNT               
+		     , BADGE_NM               
+		     , BADGE_FCOLOR           
+		     , BADGE_BCOLOR           
+		     , FN_GET_USER_NM(REG_NO) AS REG_NM               
+		     , REG_DT
+		       AS REG_DT              
+		     , UPD_NO                 
+		     , UPD_DT              
+		FROM   TB_PLAN
+		WHERE  1=1
+		AND    DEL_YN = 'N'
+		<if test ="siteCd != null and siteCd !=''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="planSq != null and planSq != ''">
+		AND    PLAN_SQ = #{planSq}
+		</if>
+		<if test="planNm != null and planNm != ''">
+		AND    PLAN_NM LIKE UPPER('%' || #{planNm} || '%')
+		</if>
+		<if test="openYn != null and openYn != ''">
+		AND    OPEN_YN = #{openYn}
+		</if>
+		<if test="regNo != null and regNo != ''">
+		AND    REG_NO = #{regNo}
+		</if>
+		<if test="frontGb != null and frontGb != ''">
+		AND    FRONT_GB = #{frontGb}
+		</if>
+		<if test="planGb != null and planGb != ''">
+		AND    PLAN_GB = #{planGb}
+		</if>
+		<if test="templateType != null and templateType != ''">
+		AND    TEMPLATE_TYPE = #{templateType}
+		</if>
+		<if test="dispStdt != null and dispStdt != ''">
+		AND    DISP_EDDT <![CDATA[>=]]> DATE_FORMAT(#{dispStdt}, 'YYYY-MM-DD')
+		</if>
+		<if test="dispEddt != null and dispEddt != ''">
+		AND    DISP_STDT <![CDATA[<=]]> DATE_FORMAT(#{dispEddt}, 'YYYY-MM-DD') + 0.99999
+		</if>
+		<if test="popupDispStdt != null and popupDispStdt != ''">
+		AND    DISP_EDDT <![CDATA[>=]]> DATE_FORMAT(#{popupDispStdt}, 'YYYY-MM-DD')
+		</if>
+		<if test="popupDispEddt != null and popupDispEddt != ''">
+		AND    DISP_STDT <![CDATA[<=]]> DATE_FORMAT(#{popupDispEddt}, 'YYYY-MM-DD') + 0.99999
+		</if>
+		ORDER  BY PLAN_SQ DESC
+	</select>
+	
+	<!-- 기획전 리스트 카운트 조회-->
+	<select id="getPlanListCnt" parameterType="Plan" resultType="int">
+		/* TsaMarketing.getPlanListCnt */
+		SELECT COUNT(1)
+		  FROM TB_PlAN
+		 WHERE 1=1
+		<if test ="siteCd != null and siteCd !=''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="planSq != null and planSq != ''">
+		AND    PLAN_SQ = #{planSq}
+		</if>
+		<if test="planNm != null and planNm != ''">
+		AND    PLAN_NM LIKE UPPER('%' || #{planNm} || '%')
+		</if>
+		<if test="openYn != null and openYn != ''">
+		AND    OPEN_YN = #{openYn}
+		</if>
+		<if test="regNo != null and regNo != ''">
+		AND    REG_NO = #{regNo}
+		</if>
+		<if test="frontGb != null and frontGb != ''">
+		AND    FRONT_GB = #{frontGb}
+		</if>
+		<if test="planGb != null and planGb != ''">
+		AND    PLAN_GB = #{planGb}
+		</if>
+		<if test="templateType != null and templateType != ''">
+		AND    TEMPLATE_TYPE = #{templateType}
+		</if>
+		<if test="dispStdt != null and dispStdt != ''">
+		AND    DISP_EDDT <![CDATA[>=]]> DATE_FORMAT(#{dispStdt}, 'YYYY-MM-DD')
+		</if>
+		<if test="dispEddt != null and dispEddt != ''">
+		AND    DISP_STDT <![CDATA[<=]]> DATE_FORMAT(#{dispEddt}, 'YYYY-MM-DD') + 0.99999
+		</if>
+		<if test="popupDispStdt != null and popupDispStdt != ''">
+		AND    DISP_EDDT <![CDATA[>=]]> DATE_FORMAT(#{popupDispStdt}, 'YYYY-MM-DD')
+		</if>
+		<if test="popupDispEddt != null and popupDispEddt != ''">
+		AND    DISP_STDT <![CDATA[<=]]> DATE_FORMAT(#{popupDispEddt}, 'YYYY-MM-DD') + 0.99999
+		</if>
+	</select>
+	
+	
+	<!-- 기획전 전체 조회 -->
+	<select id="getPlanAllList" parameterType="Plan" resultType="Plan">
+		/* TsaPlan.getPlanAllList */
+		SELECT PLAN_SQ
+		     , PLAN_NM
+		FROM   TB_PLAN
+		WHERE  1=1
+		AND    DEL_YN = 'N'
+		<if test="planSq != null and planSq != ''">
+		AND    PLAN_SQ != #{planSq}
+		</if>
+		ORDER  BY PLAN_SQ DESC
+	</select>
+
+</mapper>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 357 - 0
src/main/webapp/WEB-INF/views/marketing/PlanListForm.html

@@ -0,0 +1,357 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PlanListForm.html
+ * @desc    : 기획전관리 Page
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.03   sowon        최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<div class="main-title">
+		</div>
+
+		<div class="panelStyle">
+			<form id="planListSearchForm" name="planListSearchForm" action="#" th:action="@{'/marketing/planning/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:5%;"/>
+						<col style="width:20%;"/>
+						<col style="width:5%;"/>
+						<col style="width:20%;"/>
+						<col style="width:5%;"/>
+						<col style="width:10%;"/>
+						<col style="width:5%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>사이트</th>
+							<td>
+								<select name="siteCd">
+									<option value="">전체</option>
+									<th:block th:if="${siteCdList}" th:each="oneData, status : ${siteCdList}" >
+										<option th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+									</th:block>
+								</select>
+							</td>
+							<th>기획전명</th>
+							<td>
+								<input type="text" name="planNm" id="planNm"/>
+							</td>
+							<th>기획전번호</th>
+							<td colspan="3">
+								<input type="text" name="planSq" id="planSq"/>
+							</td>
+							<th>오픈여부</th>
+							<td>
+								<select name="openYn">
+									<option value="">전체</option>
+									<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+								</select>
+							</td>
+							
+						</tr>
+						<tr>
+							<th>PC/모바일구분</th>
+							<td>
+								<select name="frontGb">
+									<option value="">ALL</option>
+									<option value="P">웹</option>
+									<option value="M">모바일</option>
+								</select>
+							</td>
+
+							<th>기획전구분</th>
+							<td>
+								<select name="planGb">
+									<option value="">전체</option>
+									<option value="P">기획전</option>
+									<option value="E">이벤트</option>
+								</select>
+							</td>
+							<th>기획전템플릿유형</th>
+							<td colspan="3">
+								<select name="templateType">
+									<option value="">전체</option>
+									<option value="H">HTML</option>
+									<option value="T">TEXT</option>
+								</select>
+							</td>
+							<th>등록자</th>
+							<td>
+								<input type="text" name="regId" id="regId"/>
+							</td>
+						</tr>
+
+						<tr>
+							<th>진행기간</th>
+							<td colspan="10" id="sellTerms"></td>
+						</tr>
+					</tbody>
+				</table>
+				
+				<ul class="panelBar">
+					<li class="center">
+					<input type="button" value="초기화" class="btn btn-gray btn-lg" id="btnInit"/>
+					<input type="button" value="조회" class="btn btn-base btn-lg" id="btnSearch"/>
+					</li>
+				</ul>
+			</form>
+		</div>
+
+
+	<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-danger btn-lg" onclick="fnSelectedDelete();">삭제</button>
+				</li>
+				<li class="right">
+					<button type="button" class="btn btn-primary btn-lg" onclick="fnPlanWebRegisterPopup();">등록</button>
+					검색결과 : <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: 500px;" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="planListPagination"></div>
+				</li>
+			</ul>
+		</div>
+	</div>
+
+<!-- 컬러 피커 -->
+<!-- <script src='https://bgrins.github.io/spectrum/spectrum.js'></script> -->
+<!-- <link rel='stylesheet' href='https://bgrins.github.io/spectrum/spectrum.css' /> -->
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	
+	var siteCdList = gagajf.convertToArray([[${siteCdList}]]);
+	var wmGbList = {"A":"ALL", "P":"웹", "M":"모바일"};
+	var templateTypeList = {"H":"HTML", "T":"TEXT"};
+	var planGbList = {"P":"기획전", "E":"이벤트"};
+
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: "미리보기"		, field:'plan'		, width:100, cellClass: 'text-center',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);" onclick="fnPreview(\'' + params.data.planSq + '\');">' + '미리보기' + '</a>'; }
+		},
+		{headerName: "기획전구분"		, field:'planGb'	, width:100, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(planGbList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(planGbList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(planGbList, params.newValue); }
+		},
+		{headerName: "프론트구분"	, field:'frontGb'	, width:120, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(wmGbList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(wmGbList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(wmGbList, params.newValue); }
+		},
+		{headerName: "오픈여부"		, field:'openYn'	, width:80 , cellClass: 'text-center'},
+		{headerName: "기획전번호"		, field:'planSq'	, width:100, cellClass: 'text-center',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "기획전명"		, field:'planNm'	, width:300, cellClass: 'text-left',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "서브제목"		, field:'dtlTitle1'	, width:300 , cellClass: 'text-center'},
+		{headerName: "사이트"			, field:'siteCd'	, width:100, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(siteCdList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(siteCdList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(siteCdList, params.newValue); }
+		},
+		{headerName: "기획전템플릿유형"	, field:'templateType'	, width:100, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(templateTypeList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(templateTypeList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(templateTypeList, params.newValue); }
+		},
+		{headerName: "전시순서"		, field:'dispOrd'	, width:100, cellClass: 'text-right' },
+		{headerName: "진행시작일시"		, field:'dispStdt'	, width:150, cellClass: 'text-center'},
+		{headerName: "진행종료일시"		, field:'dispEddt'	, width:150, cellClass: 'text-center'},
+		{headerName: "등록자"			, field:'regNm'		, width:100, cellClass: 'text-center'},
+		{headerName: "등록일"			, field:'regDt'		, width:150, cellClass: 'text-center'}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+
+	// 셀 클릭 이벤트
+	gridOptions.onCellClicked = function(event) {
+		var field = event.colDef.field;
+		if (field != 'planSq' && field != 'planNm')
+			return;
+
+		fnBindDetail(field, event.data); // 바인딩
+	}
+	
+	// 바인딩
+	var fnBindDetail = function(field, rowData) {
+		if (field == 'planSq') { // 기획전 웹수정 팝업
+			fnEventWebDetailPopup(rowData.planSq);
+		}
+
+		if (field == 'planNm') { // 기획전 관리 팝업
+			fnEventCornerPopup(rowData.planSq);
+		}
+	}
+	
+
+	// 웹 등록 팝업
+	var fnPlanWebRegisterPopup = function() {
+		var actionUrl = "/marketing/planning/webdetail/form?mode=N";
+		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+	}
+
+	// 웹 수정 팝업
+	var fnEventWebDetailPopup = function(planSq) {
+		var actionUrl = "/marketing/plan/webdetail/form?mode=U&planSq=" + planSq;
+		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+	}
+	
+	// 이벤트 코너 관리 팝업
+	var fnEventCornerPopup = function(planSq) {
+		var actionUrl = "/marketing/plan/corner/list/form?planSq=" + planSq;
+		cfnOpenModalPopup(actionUrl, 'popupCorner');
+	}
+
+	// 미리보기
+	var fnPreview = function(planSq) {
+		var _wmall = [[${@environment.getProperty('domain.pastel')}]];
+		window.open(_wmall + '/planning/detail/form?planSq=' + planSq + '&adminPreview=Y', '_blank');
+ 		//document.location.href = _PAGE_CUSTOMER_INFO;
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$('#planListSearchForm')[0].reset();
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#planListSearchForm input[name=pageNo]").val('1');
+		console.log("1");
+		fnPlanListSearch();
+	});
+
+	// 조회
+	var fnPlanListSearch = function() {
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('planListSearchForm', fnSearchCallBack, 'planListPagination', $('#pageSize').val());
+		gagaPaging.load($("#planListSearchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#planListSearchForm';
+		var form = document.planListSearchForm;
+
+		var searchFlag = false;
+		var cnt = 0;
+		
+		for (i = 0; i < form.elements.length; i++ ) {
+			var el = form.elements[i];
+			if ($(el).prop("type") == "text" || $(el).prop("type") == "textarea" || ($(el).prop("type") == "select-one" && 
+					el.name != "search" && el.name != "pageSize" && el.name != "beforSkipFlag")) {
+				if (!(el.value == null || el.value == "")) {
+					cnt++;
+				}
+			}
+		}		
+		if(cnt > 0) searchFlag = true;
+		
+		var fromDate = $('#planListSearchForm input[name=stDate]').val();
+		var toDate = $('#planListSearchForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#planListSearchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#planListSearchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	var fnSearchCallBack = function(result){
+
+		$('#planListSearchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#planListSearchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#planListSearchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#planListSearchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.planList);
+		
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	//페이징 
+	$('#planListSearchForm select[name=pageSize]').on('change', function() {
+		$("#planListSearchForm input[name=pageNo]").val('1');
+		fnPlanListSearch($("#planListSearchForm input[name=searchGb]").val());
+	});
+	
+	
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '기간', 'X');
+		var chkBeforSkipFlag = '&nbsp;&nbsp;<label class="chkBox"><input type="checkbox" name="beforSkipFlag" value="Y" >이전데이터 제외</label>';
+		$("#planListSearchForm").find('#sellTerms').append(chkBeforSkipFlag);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+
+</html>

+ 908 - 0
src/main/webapp/WEB-INF/views/marketing/PlanWebDetailPopupForm.html

@@ -0,0 +1,908 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PlanWebDetailForm.html
+ * @desc    : 웹 수정 / 웹 등록 팝업 화면 Page
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.02.04   sowon   최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="1510" data-height="865">
+	<div class="panelStyle" >
+		<div class="panelTitle">
+			<h2 th:text="${'기획전 웹 ' + (mode == 'N' ? '등록' : '수정')}">기획전 웹 수정</h2>
+			<button type="button" class="close" onclick="uifnPopupClose('popupPlanWebDetail')"><i class="fa fa-times"></i></button>
+		</div>
+		
+		<!-- 기획전 웹 등록 -->
+		<div class="panelContent" th:if="${mode == 'N'}">
+			<form id="planWebRegisterForm" name="planWebRegisterForm" action="#" th:action="@{'/system/user/save'}" th:method="post">
+			<input type="hidden" name="mode" th:value="${mode}"/>
+			<div style="margin-bottom:10px;">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width: 150px;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>기존 기획전</th>
+						<td>
+							<select name="planSq" id="planSq">
+								<option value="">선택</option>
+								<option th:if="${planList}" th:each="oneData, status : ${planList}" th:value="${oneData.planSq}" th:text="|[${oneData.planSq}]  ${oneData.planNm}|"></option>
+							</select>
+							<button type="button" class="btn btn-default btn-lg" onclick="fnPlanCopyPopup();">기획전복사</button>
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="cardArea" style="height: 750px;margin: -5px;">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%"/>
+						<col style="width:40%;"/>
+						<col style="width:10%;"/>
+						<col style="width:35%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th class="dashR">기획전구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="planGb" required="required" data-valid-name="기획전구분" onchange="fnChangePlanGb(this);">
+								<option value="">선택</option>
+								<option value="P">기획전</option>
+								<option value="E">이벤트</option>
+							</select>
+						</td>
+						<th class="dashR">기획전탬플릿유형<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<select name="templateType" required="required" data-valid-name="기획전탬플릿유형">
+								<option value="">선택</option>
+								<option value="H">HTML</option>
+								<option value="T">TEXT</option>
+							</select>
+						</td>
+					</tr>
+				<!-- 	<tr>
+						<th class="dashR">회원구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="custGb" required="required" data-valid-name="회원구분">
+								<option th:if="${custGbList}" th:each="oneData, status : ${custGbList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">회원등급<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<select name="custGrade" required="required" data-valid-name="회원등급">
+								<option value="0">전체</option>
+								<option th:if="${custGradeList}" th:each="oneData, status : ${custGradeList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr> -->
+					<tr>
+						<th class="dashR">프론트 구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="frontGb" id="frontGb" required="required" data-valid-name="프론트 구분">
+								<option value="">선택</option>
+								<option value="A">전체</option>
+								<option value="P">웹</option>
+								<option value="M">모바일</option>
+							</select>
+						</td>
+						<th class="dashR">기획전명<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="planNm" id="planNm" maxlength="50" required="required" data-valid-name="기획전명"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">진행기간<i class="star"></i></th>
+						<td class="dashR">
+							<input type="text" class="schDate w100" id="viewStartDtNew" name="startSearchDate" maxlength="10" required="required" data-valid-name="노출기간" />
+							<select name="startSearchHour" required="required" data-valid-name="진행기간 시작시간">
+								<th:block th:each="num, index  : ${#numbers.sequence(0,23)}">
+								<option  th:value="${#numbers.formatInteger(num,2)}" th:text="|${#numbers.formatInteger(num,2)}시|" >시간</option>
+								</th:block>
+							</select>
+							<select name="startSearchMin" required="required" data-valid-name="진행기간 시작시간">
+								<th:block th:each="num: ${#numbers.sequence(0,59)}">
+								<option  th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}분|" >분</option>
+								</th:block>
+							</select>
+							~
+							<input type="text" class="schDate w100" id="viewEndDtNew" name="endSearchDate" maxlength="10" required="required" data-valid-name="노출기간"/>
+							<select name="endSearchHour" required="required" data-valid-name="진행기간 종료시간">
+								<th:block th:each="num, index  : ${#numbers.sequence(0,23)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}시|" th:selected="${#numbers.formatInteger(num,2)}==23 ? 'true'">시간</option>
+								</th:block>
+							</select>
+							<select name="endSearchMin" required="required" data-valid-name="진행기간 종료시간">
+								<th:block th:each="num: ${#numbers.sequence(0,59)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}분|" th:selected="${#numbers.formatInteger(num,2)}==59 ? 'true'">분</option>
+								</th:block>
+							</select>
+							<input type="hidden" name="dispStdt" id="dispStdt"/>
+							<input type="hidden" name="dispEddt" id="dispEddt"/>
+						</td>
+						<th class="dashR">서브제목</th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="dtlTitle1" id="dtlTitle1"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">코너명노출 여부<i class="star"></i></th>
+						<td class="dashR">
+							<select name="cornerNmDispYn" required="required" data-valid-name="코너명노출 여부">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">오픈여부<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<select name="openYn" required="required" data-valid-name="오픈여부">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">사이트<i class="star"></i></th>
+						<td class="dashR">
+							<select name="siteCd" required="required" data-valid-name="사이트">
+								<option value="">선택</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">전시순서</th>
+						<td class="dashR" colspan="3">
+							<input type="text" class="w100 aR" name="dispOrd"/>
+						</td>
+					</tr>
+					<!-- <tr>
+						<th class="dashR">뱃지 타이틀</th>
+						<td class="dashR">
+							<input type="text" class="w500" name="badgeNm"/>
+						</td>
+
+						<th class="dashR">뱃지 배경색상</th>
+						<td class="dashR">
+							<input type="text" class="w100" name="badgeBcolor"/>
+						</td>
+
+						<th class="dashR">뱃지 글자색상</th>
+						<td class="dashR">
+							<input type="text" class="w100" name="badgeFcolor"/>
+						</td>
+					</tr> -->
+					<tr>
+						<th class="dashR">PC 메인 이미지<i id="pMimgStar"></i></th>
+						<td class="dashR" colspan="5">
+							<div class="uFile w400">
+								<input id="registerMainPimg" name="registerMainPimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerMainPimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="mainPimg" id="mainPimg" value=""/>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일 메인 이미지<i id="mMimgStar"></i></th>
+						<td class="dashR" colspan="5">
+							<div class="uFile w400">
+								<input id="registerMainMimg" name="registerMainMimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerMainMimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="mainMimg" id="mainMimg" value=""/>
+							</div>
+						</td>
+					</tr>
+					<!-- <tr>
+						<th class="dashR">PC 상세 이미지</th>
+						<td class="dashR" colspan="5">
+							<div class="uFile w400">
+								<input id="registerDtlPimg" name="registerDtlPimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerDtlPimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="dtlPimg" value=""/>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일 상세 이미지</th>
+						<td class="dashR" colspan="5">
+							<div class="uFile w400">
+								<input id="registerDtlMimg" name="registerDtlMimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerDtlMimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="dtlMimg" value=""/>
+							</div>
+						</td>
+					</tr> -->
+				</tbody>
+				<!-- <tbody id="questionEventInsert">
+					<tr>
+						<th class="dashR">개인정보 수집동의</th>
+						<td class="dashR" >
+							<div style="margin-top:5px;">
+								<textarea name="textareaR4" id="privacyPolicyRegister" style="width:720px;"></textarea>
+							</div>
+						</td>
+						<th class="dashR">입력항목</th>
+						<td class="dashR" colspan="5">
+							<div>
+								<input type="text" class="w200" name="planQtitle"/>
+								<label><input type="checkbox" onclick="fnAttachYnClick(this);" />첨부파일</label>
+								<button type="button" class="btn btn-base btn-lg" onclick="fnAddRow(this);">추가</button>
+								<input type="hidden" name="attachYn" value="N"/>
+							</div>
+						</td>
+					</tr>
+				</tbody> -->
+				<tbody>
+					<tr>
+						<th class="dashR">댓글여부</th>
+						<td class="dashR" colspan="5">
+							<select name="replyYn">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'N'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<!-- <th class="dashR">DEV URL</th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="devUrl" id="devUrl"/>
+						</td> -->
+					</tr>
+					<tr>
+						<th class="dashR">웹용소스</th>
+						<td class="dashR" colspan="5">
+							<div style="margin-top:5px;">
+								<!-- <textarea name="fsrcPc" id="fsrcPcRegister" rows="15" cols="95" style="width:1280px;"></textarea> -->
+								<textarea class="textareaR4" id="fsrcPcDetail"></textarea>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일용소스</th>
+						<td class="dashR" colspan="5">
+							<div style="margin-top:5px;">
+								<!-- <textarea name="fsrcMobile" id="fsrcMobileRegister" rows="15" cols="95" style="width:1280px;"></textarea> -->
+								<textarea class="textareaR4" id="fsrcMobileDetail"></textarea>
+							</div>
+						</td>
+					</tr>
+				</table>
+			</div>
+				<div style='margin: 13px;'>
+					<ul class="panelBar">
+						<li class="right" th:if="${mode == 'N'}">
+							<button type="button" class="btn btn-info btn-lg" onclick="fnPlanSave('#planWebRegisterForm');">저장</button>
+						</li>
+					</ul>
+				</div>
+			</form>
+		</div>
+	</div>
+</div>
+
+	<!-- 기획전 웹 수정 -->
+	<li class="mdPopContent" th:if="${mode == 'U'}">
+		<form th:object="${planInfo}" id="planWebDetailForm" name="planWebDetailForm" action="#" th:action="@{'/system/user/save'}" th:method="post">
+			<input type="hidden" name="mode" th:value="${mode}"/>
+			<input type="hidden" name="planSq" th:value="*{planSq}"/>
+
+			<div class="cardArea" style="height: 700px;margin: -5px;">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%"/>
+						<col style="width:40%;"/>
+						<col style="width:10%;"/>
+						<col style="width:35%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th class="dashR">기획전구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="planGb" id="planGb" th:field="*{planGb}" onchange="fnChangePlanGb(this);">
+								<option value="P">기획전</option>
+								<option value="E">이벤트</option>
+							</select>
+						</td>
+						<th class="dashR">기획전탬플릿유형<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<select name="templateType" th:field="*{templateType}">
+								<option value="">선택</option>
+								<option value="H">HTML</option>
+								<option value="T">TEXT</option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">회원구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="custGb" required="required" data-valid-name="회원구분" th:field="*{custGb}">
+								<option th:if="${custGbList}" th:each="oneData, status : ${custGbList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">회원등급<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<select name="custGrade" required="required" data-valid-name="회원등급" th:field="*{custGrade}">
+								<option value="0">전체</option>
+								<option th:if="${custGradeList}" th:each="oneData, status : ${custGradeList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">프론트 구분<i class="star"></i></th>
+						<td class="dashR">
+							<select name="frontGb" id="frontGb" th:field="*{frontGb}">
+								<option value="">선택</option>
+								<option value="A">전체</option>
+								<option value="P">웹</option>
+								<option value="M">모바일</option>
+							</select>
+						</td>
+						<th class="dashR">기획전명<i class="star"></i></th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="planNm" id="planNm" th:field="*{planNm}"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">진행기간<i class="star"></i></th>
+						<td class="dashR">
+							<input type="text" class="schDate w100" name="startSearchDate" maxlength="10" required="required" data-valid-name="노출기간" th:field="*{startSearchDate}"/>
+							<select name="startSearchHour" required="required" data-valid-name="진행기간 시작시간">
+								<th:block th:each="num, index  : ${#numbers.sequence(0,23)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}시|" th:selected="*{#strings.substring(dispStdt, 11, 13)} == ${#strings.toString(num)} ? 'true'">시간</option>
+								</th:block>
+							</select>
+							<select name="startSearchMin" required="required" data-valid-name="진행기간 시작시간">
+								<th:block th:each="num: ${#numbers.sequence(0,59)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}분|" th:selected="*{#strings.substring(dispStdt, 14, 16)} == ${#strings.toString(num)} ? 'true'">분</option>
+								</th:block>
+							</select>
+							~
+							<input type="text" class="schDate w100" name="endSearchDate" maxlength="10" required="required" data-valid-name="노출기간" th:field="*{endSearchDate}"/>
+							<select name="endSearchHour" required="required" data-valid-name="진행기간 종료시간">
+								<th:block th:each="num, index  : ${#numbers.sequence(0,23)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}시|" th:selected="*{#strings.substring(dispEddt, 11, 13)} == ${#strings.toString(num)} ? 'true'">시간</option>
+								</th:block>
+							</select>
+							<select name="endSearchMin" required="required" data-valid-name="진행기간 종료시간">
+								<th:block th:each="num: ${#numbers.sequence(0,59)}">
+								<option th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}분|" th:selected="*{#strings.substring(dispEddt, 14, 16)} == ${#strings.toString(num)} ? 'true'">분</option>
+								</th:block>
+							</select>
+							<input type="hidden" name="dispStdt" id="dispStdt"/>
+							<input type="hidden" name="dispEddt" id="dispEddt"/>
+						</td>
+						<th class="dashR">서브제목</th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="dtlTitle1" id="dtlTitle1" th:value="*{dtlTitle1}"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">코너명노출 여부<i class="star"></i></th>
+						<td class="dashR">
+							<select name="cornerNmDispYn" th:field="*{cornerNmDispYn}">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">오픈여부<i class="star"></i></th>
+						<td class="dashR">
+							<select name="openYn" th:field="*{openYn}">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'Y'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">전시순서</th>
+						<td class="dashR">
+							<input type="text" name="dispOrd" class="w100 aR" th:value="*{dispOrd}"/>
+						</td>
+						<th class="dashR">삭제여부<i class="star"></i></th>
+						<td class="dashR">
+							<select name="delYn" th:field="*{delYn}" required="required" data-valid-name="삭제여부">
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:selected="${oneData.cd} == 'N'" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">사이트<i class="star"></i></th>
+						<td class="dashR">
+							<select name="siteCd" th:field="*{siteCd}">
+								<option value="">선택</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">댓글여부</th>
+						<td class="dashR">
+							<select name="replyYn" th:field="*{replyYn}">
+								<option value="">선택</option>
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<!-- <tr>
+						<th class="dashR">뱃지 타이틀</th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="badgeNm" th:value="*{badgeNm}"/>
+						</td>
+						<th class="dashR">뱃지 배경색상</th>
+						<td class="dashR">
+							<input type="text" name="badgeBcolor" th:value="*{badgeBcolor}"/>
+						</td>
+						<th class="dashR">뱃지 글자색상</th>
+						<td class="dashR" colspan="3">
+							<input type="text" name="badgeFcolor" th:value="*{badgeFcolor}"/>
+						</td>
+					</tr> -->
+					<tr>
+						<th class="dashR">PC 메인 이미지<i id="pMimgStar"></i><br/>[삭제여부<label><input type="checkbox" name="orgMainPimgDelYn" value="Y"/></label>]</th>
+						<td class="dashR">
+							<div th:if=*{mainPimg} id="mainPimgView" style="float:left;">
+								<img id="PreMainPimgUrl" th:src="${@environment.getProperty('upload.image.view') + '/plan/'} + *{mainPimg}" style="max-width:720px;"/>
+							</div>
+						</td>
+						<td class="dashR" colspan="4">
+							<div class="uFile w400">
+								<input id="registerMainPimg" name="registerMainPimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerMainPimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="orgMainPimg" id="orgMainPimg" th:value="*{mainPimg}"/>
+								<input type="hidden" name="mainPimg" id="mainPimg"/>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일 메인 이미지<i id="mMimgStar"></i><br/>[삭제여부<label><input type="checkbox" name="orgMainMimgDelYn" value="Y"/></label>]</th>
+						<td class="dashR">
+							<div th:if=*{mainMimg} id="imgFileView" style="float:left;">
+								<img id="PreMainMimgUrl" th:src="${@environment.getProperty('upload.image.view') + '/plan/'} + *{mainMimg}" style="max-width:720px;"/>
+							</div>
+						</td>
+						<td class="dashR" colspan="4">
+							<div class="uFile w400">
+								<input id="registerMainMimg" name="registerMainMimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerMainMimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="orgMainMimg" id="orgMainMimg" th:value="*{mainMimg}"/>
+								<input type="hidden" name="mainMimg" id="mainMimg"/>
+							</div>
+						</td>
+					</tr>
+					<!-- <tr>
+						<th class="dashR">웹 상세 이미지<br/>[삭제여부<label><input type="checkbox" name="orgDtlPimgDelYn" value="Y"/></label>]</th>
+						<td class="dashR">
+							<div th:if=*{dtlPimg} id="DtlPimgView" style="float:left;">
+								<img id="PreDtlPimgUrl" th:src="${@environment.getProperty('upload.image.view') + '/plan/'} + *{dtlPimg}" style="width:100%;"/>
+							</div>
+						</td>
+						<td class="dashR" colspan="4">
+							<div class="uFile w400">
+								<input id="registerDtlPimg" name="registerDtlPimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerDtlPimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="orgDtlPimg" id="orgDtlPimg" th:value="*{dtlPimg}"/>
+								<input type="hidden" name="dtlPimg" id="dtlPimg"/>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일 상세 이미지<br/>[삭제여부<label><input type="checkbox" name="orgDtlMimgDelYn" value="Y"/></label>]</th>
+						<td class="dashR">
+							<div th:if=*{dtlMimg} id="DtlMimgView" style="float:left;">
+								<img id="PredtlMimgUrl" th:src="${@environment.getProperty('upload.image.view') + '/plan/'} + *{dtlMimg}" style="width:100%;"/>
+							</div>
+						</td>
+						<td class="dashR" colspan="4">
+							<div class="uFile w400">
+								<input id="registerDtlMimg" name="registerDtlMimg" type="file" accept="image/*" class="uFileInput w400"/>
+								<label for="registerDtlMimg" class="uFileLabel w400">파일선택</label>
+								<input type="hidden" name="orgDtlMimg" id="orgDtlMimg" th:value="*{dtlMimg}"/>
+								<input type="hidden" name="dtlMimg" id="dtlMimg"/>
+							</div>
+						</td>
+					</tr> -->
+				</tbody>
+				<tbody id="questionEventUpdate">
+					<tr>
+						<th class="dashR">개인정보 수집동의</th>
+						<td class="dashR">
+							<div style="margin-top:5px;">
+								<textarea name="privacyPolicy" id="privacyPolicyDetail" style="width:720px;">[[*{privacyPolicy}]]</textarea>
+							</div>
+						</td>
+						<th class="dashR">입력항목<div><button type="button" class="btn btn-primary btn-lg" th:onclick="'cfnOpenPlanAnswerPopup('+*{planSq}+');'">참여자</button></div></th>
+						<td class="dashR">
+							<th:bock th:if="${planQuestionList != null and !planQuestionList.empty}" th:each="oneData, status : ${planQuestionList}">
+								<div>
+									<input type="text" class="w200" name="planQtitle" th:value="${oneData.planQtitle}"/>
+									<label class="chkBox"><input type="checkbox" th:checked="${oneData.attachYn}=='Y'" onclick="fnAttachYnClick(this);" />첨부파일</label>
+									<th:block th:if="${status.first}">
+										<button type="button" class="btn btn-base btn-lg" onclick="fnAddRow(this);">추가</button>
+									</th:block>
+									<th:block th:unless="${status.first}">
+										<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>
+									</th:block>
+									<input type="hidden" name="attachYn" th:value="${oneData.attachYn}"/>
+								</div>
+							</th:bock>
+							<th:block th:unless="${planQuestionList != null and !planQuestionList.empty}">
+								<div>
+									<input type="text" class="w200" name="planQtitle" />
+									<label><input type="checkbox" onclick="fnAttachYnClick(this);" />첨부파일</label>
+									<button type="button" class="btn btn-base btn-lg" onclick="fnAddRow(this);">추가</button>
+									<input type="hidden" name="attachYn" th:value="N"/>
+								</div>
+							</th:block>
+						</td>
+					</tr>
+				</tbody>
+				<tbody>
+					<!-- <tr>
+						<th class="dashR">댓글여부</th>
+						<td class="dashR" colspan="5">
+							<select name="replyYn" th:field="*{replyYn}">
+								<option value="">선택</option>
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">DEV URL</th>
+						<td class="dashR" colspan="4">
+							<input type="text" name="devUrl" id="devUrl" th:value="*{devUrl}"/>
+						</td>
+					</tr> -->
+					<tr>
+						<th class="dashR">웹용소스</th>
+						<td class="dashR" colspan="5">
+							<div style="margin-top:5px;">
+								<textarea name="fsrcPc" id="fsrcPcDetail" rows="15" cols="95" style="width:1280px;"></textarea>
+							</div>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">모바일용소스</th>
+						<td class="dashR" colspan="5">
+							<div style="margin-top:5px;">
+								<textarea name="fsrcMobile" id="fsrcMobileDetail" rows="15" cols="95" style="width:1280px;"></textarea>
+							</div>
+						</td>
+					</tr>
+				</table>
+			</div>
+		</form>
+	</li>
+
+	<li class="mdPopBtnB aR" th:if="${mode == 'U'}">
+		<button type="button" class="btn btn-success btn-lg" onclick="fnPlanSave('#planWebDetailForm');">저장</button>
+	</li>
+
+</ul>
+
+<script type="text/javascript" src="/ux/plugins/summernote/summernote.js?v=2020103001"></script>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.summernote.js?v=2020103001"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	// 스마트에디터
+	//var seOptions = gagaSe.getEditorOptions();
+	var mode = [[${mode}]];
+	var planInfo = [[${planInfo}]];
+	var fsrcPc = [[${fsrcPc}]];
+	var fsrcMobile = [[${fsrcMobile}]];
+	var snOptions;
+
+	$(document).ready(function() {
+		snOptions = gagaSn.getToolbarOptions('media');
+		gagaSn.createSummernote(snOptions, '#fsrcPcDetail');
+		gagaSn.createSummernote(snOptions, '#fsrcMobileDetail');
+		
+		 if (mode =='U') {
+			/* $('#planWebDetailForm input[name=badgeFcolor]').spectrum({
+				preferredFormat: "hex",
+				showInput: true,
+				allowEmpty: true
+			});
+
+			$('#planWebDetailForm input[name=badgeBcolor]').spectrum({
+				preferredFormat: "hex",
+				showInput: true,
+				allowEmpty: true
+			}); */
+
+			if (planInfo.goodsLimitYn == 'N') {
+				$('#planWebDetailForm input[name=goodsLimitQty]').hide();
+			} else {
+				$('#planWebDetailForm input[name=goodsLimitQty]').show();
+			}
+
+			// 스마트에디터
+			//gagaSe.createSmartEditor(seOptions, 'fsrcPcDetail');
+			//gagaSe.createSmartEditor(seOptions, 'fsrcMobileDetail');
+
+			// 스마트에디어 값 설정
+			//gagaSe.setContents('fsrcPcDetail', fsrcPc.fsrc);
+			//gagaSe.setContents('fsrcMobileDetail', fsrcMobile.fsrc);
+
+			if($("#planGb").val()!='E'){
+				$("#questionEventInsert").hide();
+				$("#questionEventUpdate").hide();
+			}else{
+				gagaSn.createSummernote(snOptions, '#privacyPolicyRegister');
+			}
+
+		} else {
+			/* $('#planWebRegisterForm input[name=badgeFcolor]').spectrum({
+				preferredFormat: "hex",
+				showInput: true,
+				allowEmpty: true
+			});
+
+			$('#planWebRegisterForm input[name=badgeBcolor]').spectrum({
+				preferredFormat: "hex",
+				showInput: true,
+				allowEmpty: true
+			}); */
+
+			$("#viewStartDtNew").val(_today);
+			$("#viewEndDtNew").val(_today);
+
+			// 스마트에디터
+			//gagaSe.createSmartEditor(seOptions, 'fsrcPcRegister');
+			//gagaSe.createSmartEditor(seOptions, 'fsrcMobileRegister');
+
+			$("#questionEventInsert").hide();
+			$("#questionEventUpdate").hide();
+		} 
+		$('#frontGb').trigger('change');
+	});
+
+	// 카테고리 전시 여부
+	var fnCataCheck = function(is, formId) {
+		if (is.checked) {
+			$(formId + ' input[name=cateDispYn]').val('Y');
+			// 추후 카테고리 표시
+		} else {
+			$(formId + ' input[name=cateDispYn]').val('N');
+		}
+	}
+
+	// 상품제한여부
+	var fnGoodsCheck = function(is, formId) {
+		if (is.checked) {
+			$(formId + ' input[name=goodsLimitYn]').val('Y');
+			$(formId + ' input[name=goodsLimitQty]').show();
+			$(formId + ' input[name=goodsLimitQty]').focus();
+			// 추후 카테고리 표시
+		} else {
+			$(formId + ' input[name=goodsLimitYn]').val('N');
+			$(formId + ' input[name=goodsLimitQty]').hide();
+		}
+	}
+
+	var fnPlanCopyPopup = function() {
+		var planSq = $('#planWebRegisterForm select[name=planSq]').val();
+
+		if (gagajf.isNull(planSq)) {
+			mcxDialog.alert('복사할 기획전을 선택하세요.');
+			return;
+		}
+
+		mcxDialog.confirm('선택 된 기획전을 복사 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var actionUrl = '/marketing/plan/copy';
+				var data = {copyPlanSq : planSq};
+				var jsonData = JSON.stringify(data);
+
+				gagajf.ajaxJsonSubmit(actionUrl, jsonData, fnCopyCallback);
+			}
+		});
+	}
+
+	var fnCopyCallback = function(result) {
+		fnPlanWebDetailClose();
+		fnSearch();
+
+		var actionUrl = "/marketing/plan/webdetail/form?mode=U&planSq=" + result.planSq;
+		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+	}
+
+	var fnPlanSave = function(formId) {
+		if (!gagajf.validation(formId))
+			return;
+
+		// 날짜 유효성 체크
+		var stDate = $(formId + ' input[name=startSearchDate]').val().replaceAll("-", "");
+		var edDate = $(formId + ' input[name=endSearchDate]').val().replaceAll("-", "");
+		var toDate = _today.replaceAll("-", "");
+
+		if (Number(stDate) > Number(edDate)) {
+			mcxDialog.alert('종료일자는 시작일자 보다 클 수 없습니다.');
+			return;
+		}
+
+		if (Number(stDate) < Number(toDate) && mode == 'N') {
+			mcxDialog.alert('시작일자는 오늘포함 이후로 등록해주세요.');
+			return;
+		}
+
+		if (Number(edDate) < Number(toDate) && mode == 'N') {
+			mcxDialog.alert('종료일자는 오늘포함 이후로 등록해주세요.');
+			return;
+		}
+		
+		stDate = $(formId + ' input[name=startSearchDate]').val();
+		edDate = $(formId + ' input[name=endSearchDate]').val();
+		$(formId + ' input[name=dispStdt]').val(stDate + ' ' + $(formId + ' select[name=startSearchHour]').val() + ':' + $(formId + ' select[name=startSearchMin]').val() + ':00');
+		$(formId + ' input[name=dispEddt]').val(edDate + ' ' + $(formId + ' select[name=endSearchHour]').val() + ':' + $(formId + ' select[name=endSearchMin]').val() + ':59');
+
+		/* // 댓글여부에 따른 위치 체크
+		if ($('#replyYn').val() == 'Y') {
+			var replyLoc = $(':radio[name="replyLoc"]:checked').val();
+
+			if (typeof replyLoc == 'undefined') {
+				mcxDialog.alert('댓글 사용 시 댓글위치를 선택해야합니다.');
+				return;
+			}
+		} */
+
+		// poll 관리일련번호 유효성 체크
+		/* if (!gagajf.isNull($(formId + ' input[name=pollSq]').val())) {
+			gagajf.ajaxFormSubmit('/marketing/poll/list', formId, function(result) {
+				console.log(result);
+				if (result.length < 1) {
+					mcxDialog.alert('입력하신 투표 일련번호가 존재 하지않습니다.');
+					return;
+				}
+			});
+		} */
+
+		var privacyPolicy = '';
+		var frontGb = $('#frontGb').val();
+		if (mode =='U') {
+			//gagaSn.getContents('fsrcPcDetail');
+			//gagaSn.getContents('fsrcMobileDetail');
+			//if($("#planGb").val()=='E'){
+			//	privacyPolicy = gagaSn.getContents('privacyPolicyDetail');
+			//}
+
+			// 이미지 처리
+			if ((!$('input[name=orgMainPimgDelYn]').is(':checked') ? true : false) &&
+				(gagajf.isNull($(formId + ' input[name=mainPimg]').val()) == true)   ) {
+				$(formId + ' input[name=mainPimg]').val($(formId + ' input[name=orgMainPimg]').val());
+			}
+
+			if ((!$('input[name=orgMainMimgDelYn]').is(':checked') ? true : false) &&
+				(gagajf.isNull($(formId + ' input[name=mainMimg]').val()) == true)  ) {
+				$(formId + ' input[name=mainMimg]').val($(formId + ' input[name=orgMainMimg]').val());
+			}
+
+			if ((!$('input[name=orgDtlPimgDelYn]').is(':checked') ? true : false) &&
+				(gagajf.isNull($(formId + ' input[name=dtlPimg]').val()) == true)  ) {
+				$(formId + ' input[name=dtlPimg]').val($(formId + ' input[name=orgDtlPimg]').val());
+			}
+
+			if ((!$('input[name=orgDtlMimgDelYn]').is(':checked') ? true : false) &&
+				(gagajf.isNull($(formId + ' input[name=dtlMimg]').val()) == true)  ) {
+				$(formId + ' input[name=dtlMimg]').val($(formId + ' input[name=orgDtlMimg]').val());
+			}
+
+			if ((!$('input[name=orgReplyImgYn]').is(':checked') ? true : false) &&
+				(gagajf.isNull($(formId + ' input[name=replyImg]').val()) == true) ) {
+				$(formId + ' input[name=replyImg]').val($(formId + ' input[name=orgReplyImg]').val());
+			}
+		} else {
+			//gagaSn.getContents('fsrcPcRegister');
+			//gagaSn.getContents('fsrcMobileRegister');
+			//if($("#planGb").val()=='E'){
+			//	privacyPolicy = gagaSn.getContents('privacyPolicyRegister');
+			//}
+		}
+
+		if(!gagajf.isNull($(formId + ' input[name=planQtitle]').val()) && gagajf.isNull(privacyPolicy.replace(/<br>/gi, '').replace(/<p>/gi, '').replace(/<\/\p>/gi, ''))){
+			mcxDialog.alert('입력항목 등록 시 개인정보 수집동의를 입력해 주세요.');
+			return;
+		}
+
+		if (formId == '#planWebRegisterForm') {
+			mcxDialog.confirm('등록 하시겠습니까?', {
+				cancelBtnText: "취소",
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					gagajf.ajaxFormSubmit("/marketing/planning/webdetail/create", "#planWebRegisterForm", fnPlanWebDetailCallBack); 
+					//fnSearch();
+					fnPlanWebDetailClose();
+				}
+			});
+		} else {
+			mcxDialog.confirm('저장 하시겠습니까?', {
+				cancelBtnText: "취소",
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					var actionUrl = '/marketing/plan/webdetail/update';
+
+					gagajf.ajaxFormSubmit(actionUrl, formId, function() {
+						fnSearch();
+						fnPlanWebDetailClose();
+					});
+				}
+			});
+		}
+	}
+
+	// 이미지 첨부
+	$('input[name=registerMainPimg],input[name=registerMainMimg],input[name=registerDtlPimg],input[name=registerDtlMimg],input[name=registerReplyImg]').on('change', function() {
+		var name = $(this)[0].name;
+
+		var file = this.files[0];
+
+		gagajf.ajaxFileUpload('/common/file/upload?subDir=/plan'
+				, file
+				, function(result) {
+					if (name == 'registerMainPimg')
+						$('input[name=mainPimg]').val(result.newFileName);
+
+					if (name == 'registerMainMimg')
+						$('input[name=mainMimg]').val(result.newFileName);
+
+					if (name == 'registerDtlPimg')
+						$('input[name=dtlPimg]').val(result.newFileName);
+
+					if (name == 'registerDtlMimg')
+						$('input[name=dtlMimg]').val(result.newFileName);
+
+					if (name == 'registerReplyImg')
+						$('input[name=replyImg]').val(result.newFileName);
+				}
+				, 'image'
+		);
+	});
+
+
+	var fnChangePlanGb = function(obj) {
+		if($(obj).val()=='E'){
+			$("#questionEventInsert").show();
+			$("#questionEventUpdate").show();
+			if (mode =='U') {
+				if($("#privacyPolicyDetail").closest('div').children('#the_iframe').length==0){
+					gagaSn.createSummernote(snOptions, '#privacyPolicyDetail');
+				}
+			}else{
+				if($("#privacyPolicyRegister").closest('div').children('#the_iframe').length==0){
+					gagaSn.createSummernote(snOptions, '#privacyPolicyRegister');
+				}
+			}
+		}else{
+			$("#questionEventInsert").hide();
+			$("#questionEventUpdate").hide();
+		}
+	}
+
+	var fnAddRow = function(obj){
+		var html = '<div>';
+		html += '<input type="text" class="w200" name="planQtitle"/>';
+		html += '<label class="chkBox"><input type="checkbox" onclick="fnAttachYnClick(this);" />첨부파일</label>';
+		html += '<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>';
+		html += '<input type="hidden" name="attachYn" value="N"/>';
+		html += '</div>';
+		$(obj).closest('td').append(html);
+	}
+
+	var fnDeleteRow = function(obj){
+		$(obj).closest('div').remove();
+	}
+
+	var fnAttachYnClick = function(obj){
+		var val = 'N';
+		if($(obj).prop('checked')){
+			val = 'Y';
+		}
+		$(obj).closest('div').find('input[name="attachYn"]').val(val);
+	}
+
+	var fnPlanWebDetailCallBack = function() {
+		fnSearch();
+		$('.sp-container').remove();	// 컬러피커 제거
+		uifnPopClose('popupPlanWebDetail');
+	}
+/*]]>*/
+</script>
+
+</html>