Bladeren bron

Merge branch 'develop' of http://112.172.147.34:4936/style24/style24.admin into develop

jsshin 5 jaren geleden
bovenliggende
commit
16e3840bcc
49 gewijzigde bestanden met toevoegingen van 3033 en 440 verwijderingen
  1. 81 0
      src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java
  2. 1 1
      src/main/java/com/style24/admin/biz/dao/TsaMailTemplateDao.java
  3. 3 3
      src/main/java/com/style24/admin/biz/dao/TsaPlanDao.java
  4. 30 0
      src/main/java/com/style24/admin/biz/dao/TsaPollDao.java
  5. 1 1
      src/main/java/com/style24/admin/biz/service/TsaBusinessService.java
  6. 184 13
      src/main/java/com/style24/admin/biz/service/TsaDisplayService.java
  7. 1 1
      src/main/java/com/style24/admin/biz/service/TsaMailTemplateService.java
  8. 7 8
      src/main/java/com/style24/admin/biz/service/TsaPlanService.java
  9. 37 0
      src/main/java/com/style24/admin/biz/service/TsaPollService.java
  10. 119 0
      src/main/java/com/style24/admin/biz/web/TsaDisplayController.java
  11. 57 26
      src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
  12. 1 0
      src/main/java/com/style24/persistence/domain/Brand.java
  13. 1 0
      src/main/java/com/style24/persistence/domain/BrandGroup.java
  14. 1 1
      src/main/java/com/style24/persistence/domain/Category.java
  15. 37 0
      src/main/java/com/style24/persistence/domain/Contents.java
  16. 22 0
      src/main/java/com/style24/persistence/domain/MainDisplay.java
  17. 6 6
      src/main/java/com/style24/persistence/domain/Poll.java
  18. 36 30
      src/main/java/com/style24/persistence/mybatis/shop/TsaBusiness.xml
  19. 276 2
      src/main/java/com/style24/persistence/mybatis/shop/TsaDsiplay.xml
  20. 1 1
      src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml
  21. 10 7
      src/main/java/com/style24/persistence/mybatis/shop/TsaPlan.xml
  22. 66 1
      src/main/java/com/style24/persistence/mybatis/shop/TsaPoll.xml
  23. 0 3
      src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml
  24. 13 29
      src/main/webapp/WEB-INF/views/business/BrandForm.html
  25. 159 47
      src/main/webapp/WEB-INF/views/business/BrandGroupPopupForm.html
  26. 1 1
      src/main/webapp/WEB-INF/views/business/BrandPopupForm.html
  27. 455 0
      src/main/webapp/WEB-INF/views/display/MainContentsPopupForm.html
  28. 632 0
      src/main/webapp/WEB-INF/views/display/MainListForm.html
  29. 8 8
      src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html
  30. 4 3
      src/main/webapp/WEB-INF/views/goods/GoodsNaverPriceForm.html
  31. 1 1
      src/main/webapp/WEB-INF/views/marketing/PlanCornerCopyForm.html
  32. 3 6
      src/main/webapp/WEB-INF/views/marketing/PlanCornerListForm.html
  33. 97 82
      src/main/webapp/WEB-INF/views/marketing/PlanDetailPopupForm.html
  34. 17 18
      src/main/webapp/WEB-INF/views/marketing/PlanListForm.html
  35. 38 21
      src/main/webapp/WEB-INF/views/marketing/PlanPopupForm.html
  36. 38 23
      src/main/webapp/WEB-INF/views/marketing/PollListForm.html
  37. 67 0
      src/main/webapp/WEB-INF/views/marketing/PollVoteRatePopupForm.html
  38. BIN
      src/main/webapp/image/icon_checkN.png
  39. BIN
      src/main/webapp/image/icon_checkND.png
  40. BIN
      src/main/webapp/image/icon_checkY.png
  41. BIN
      src/main/webapp/image/icon_checkYD.png
  42. BIN
      src/main/webapp/image/icon_radioND.png
  43. BIN
      src/main/webapp/image/icon_radioY.png
  44. BIN
      src/main/webapp/image/icon_radioYD.png
  45. 47 47
      src/main/webapp/ux/css/admin.ui.css
  46. 397 0
      src/main/webapp/ux/css/dropzone.css
  47. 34 1
      src/main/webapp/ux/js/admin.popup.js
  48. 43 48
      src/main/webapp/ux/js/admin.ui.js
  49. 1 1
      src/main/webapp/ux/plugins/summernote/summernote.js

+ 81 - 0
src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java

@@ -217,4 +217,85 @@ public interface TsaDisplayDao {
 	 */
 	void updateCategoryGoodsDispOrd(CategoryGoods categoryGoods);
 
+	/**
+	 * 메인전시관리 카테고리 목록
+	 * @param category - 카테고리 정보
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	Collection<Category> getMainCategoryList(Category category);
+
+	/**
+	 * 메인전시 레이아웃 목록
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	Collection<MainDisplay> getMainLayoutList(MainDisplay mainDisplay);
+
+	/**
+	 * 메인전시 레이아웃 삭제
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	void deleteMainLayout(MainDisplay mainDisplay);
+
+	/**
+	 * 메인전시 레이아웃 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	void saveMainLayout(MainDisplay mainDisplay);
+
+	/**
+	 * 메인전시 컨텐츠 설명
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	String getContentsDesc(String contentsLoc);
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 리스트
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	Collection<Contents> getContentsPreviewList(Contents contents);
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 삭제
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	void deleteContentsPreview(Contents contents);
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	void saveContentsPreview(Contents contents);
+
+	/**
+	 * 메인전시 컨텐츠 삭제
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	void deleteContents(Contents contents);
+
+	/**
+	 * 메인전시 컨텐츠 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	void saveContents(Contents contents);
+
 }

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

@@ -102,4 +102,4 @@ public interface TsaMailTemplateDao {
 	 */
 	void deleteMktmailList(MktmailManagement mktMailManagement);
 
-}
+}

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

@@ -34,7 +34,7 @@ public interface TsaPlanDao {
 	 * @author rladbwnd5
 	 * @since 2019. 12. 31
 	 */
-	void createPlanWebInfo(Plan param);
+	void createPlanInfo(Plan param);
 	
 	/**
 	 * 기획전 목록
@@ -53,7 +53,7 @@ public interface TsaPlanDao {
 	 * @author sowon
 	 * @since 2021. 2. 5
 	 */
-	int getPlanListCnt(Plan param);
+	int getPlanListCount(Plan param);
 	
 	/**
 	 * 기획전 삭제
@@ -99,7 +99,7 @@ public interface TsaPlanDao {
 	 * @author sowon
 	 * @since 2021. 2. 8
 	 */
-	void updatePlanWebInfo(Plan param);
+	void updatePlanInfo(Plan param);
 	
 	/**
 	 * 기획전 복사

+ 30 - 0
src/main/java/com/style24/admin/biz/dao/TsaPollDao.java

@@ -54,6 +54,36 @@ public interface TsaPollDao {
 	 * @since 2021. 2. 19
 	 */
 	Collection<Poll> getPollList(Poll poll);
+	
+	/**
+	 * POLL 투표자 목록
+	 *
+	 * @param Poll
+	 * @return Poll목록
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	Collection<Poll> getPollVoterList(Poll poll);
+	
+	/**
+	 * POLL 보기 조회
+	 *
+	 * @param Poll
+	 * @return Poll 보기 
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	Collection<Poll> getPollQuestion(Poll poll);
+	
+	/**
+	 * POLL ANSWER 조회
+	 *
+	 * @param Poll
+	 * @return Poll ANSWER 
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	Collection<Poll> getPollAnswer(Poll poll);
 
 
 }

+ 1 - 1
src/main/java/com/style24/admin/biz/service/TsaBusinessService.java

@@ -271,7 +271,7 @@ public class TsaBusinessService {
 		} else { // 수정
 			businessDao.updateBrand(brand);
 		}
-
+		log.info("brand ={}", brand);
 		if (brandSupplyList != null && !brandSupplyList.isEmpty()) {
 			for(Brand brandSupply: brandSupplyList){
 				brandSupply.setRegNo(TsaSession.getInfo().getUserNo());

+ 184 - 13
src/main/java/com/style24/admin/biz/service/TsaDisplayService.java

@@ -1,18 +1,21 @@
 package com.style24.admin.biz.service;
 
-import java.util.Collection;
-
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.style24.admin.biz.dao.TsaDisplayDao;
+import com.style24.admin.support.security.session.TsaSession;
 import com.style24.persistence.domain.*;
-import org.apache.commons.lang3.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import com.style24.admin.biz.dao.TsaDisplayDao;
-import com.style24.admin.support.security.session.TsaSession;
-
-import lombok.extern.slf4j.Slf4j;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
 
 /**
  * 전시 Service
@@ -30,6 +33,9 @@ public class TsaDisplayService {
 	@Autowired
 	private TsaCommonService commonService;
 
+	@Autowired
+	private Environment env;
+
 	/**
 	 * 카테고리 목록
 	 * @param category - 카테고리 정보
@@ -190,20 +196,20 @@ public class TsaDisplayService {
 		goodsCategory.setRegNo(TsaSession.getInfo().getUserNo());
 		goodsCategory.setUpdNo(TsaSession.getInfo().getUserNo());
 
-		if(StringUtils.isNotEmpty(goodsCategory.getGoodsCds())){
+		if(!StringUtils.isEmpty(goodsCategory.getGoodsCds())){
 			String[] goodsCdArr = goodsCategory.getGoodsCds().split(",");
 			for (String goodsCd : goodsCdArr) {
 				goodsCategory.setGoodsCd(goodsCd);
 				int cnt = 0;
 				for (String cateCd : goodsCategory.getCateCdArr()) {
-					if(StringUtils.isNotEmpty(cateCd)){
+					if(!StringUtils.isEmpty(cateCd)){
 						//goodsCategory.setCateCd(cateCd);
 						//goodsCategory.setCateGb(goodsCategory.getCateGbArr()[cnt]);
 						//goodsCategory.setCateType(goodsCategory.getCateTypeArr()[cnt]);
 						//displayDao.saveGoodsCategory(goodsCategory);
 
 						if(!"G031_20".equals(goodsCategory.getCateType())){
-							if(StringUtils.isNotEmpty(goodsCategory.getCateCd1Arr()[cnt])){
+							if(!StringUtils.isEmpty(goodsCategory.getCateCd1Arr()[cnt])){
 								String[] cate1Array = goodsCategory.getCateCd1Arr()[cnt] .split(",");
 								if(cate1Array[1].equals("Y")){
 									goodsCategory.setCateCd(cate1Array[0]);
@@ -211,7 +217,7 @@ public class TsaDisplayService {
 								}
 							}
 
-							if(StringUtils.isNotEmpty(goodsCategory.getCateCd2Arr()[cnt])){
+							if(!StringUtils.isEmpty(goodsCategory.getCateCd2Arr()[cnt])){
 								String[] cate2Array = goodsCategory.getCateCd2Arr()[cnt] .split(",");
 								if(cate2Array[1].equals("Y")){
 									goodsCategory.setCateCd(cate2Array[0]);
@@ -219,7 +225,7 @@ public class TsaDisplayService {
 								}
 							}
 
-							if(StringUtils.isNotEmpty(goodsCategory.getCateCd3Arr()[cnt])){
+							if(!StringUtils.isEmpty(goodsCategory.getCateCd3Arr()[cnt])){
 								String[] cate3Array = goodsCategory.getCateCd3Arr()[cnt].split(",");
 								if(cate3Array[1].equals("Y")){
 									goodsCategory.setCateCd(cate3Array[0]);
@@ -227,7 +233,7 @@ public class TsaDisplayService {
 								}
 							}
 
-							if(StringUtils.isNotEmpty(goodsCategory.getCateCd4Arr()[cnt])){
+							if(!StringUtils.isEmpty(goodsCategory.getCateCd4Arr()[cnt])){
 								String[] cate4Array = goodsCategory.getCateCd4Arr()[cnt].split(",");
 								if(cate4Array[1].equals("Y")){
 									goodsCategory.setCateCd(cate4Array[0]);
@@ -405,4 +411,169 @@ public class TsaDisplayService {
 		}
 	}
 
+	/**
+	 * 메인전시관리 카테고리 목록
+	 * @param category - 카테고리 정보
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	public Collection<Category> getMainCategoryList(Category category) {
+		return displayDao.getMainCategoryList(category);
+	}
+
+	/**
+	 * 메인전시 레이아웃 목록
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	public Collection<MainDisplay> getMainLayoutList(MainDisplay mainDisplay) {
+		return displayDao.getMainLayoutList(mainDisplay);
+	}
+
+	/**
+	 * 메인전시 레이아웃 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@Transactional("shopTxnManager")
+	public void saveMainLayout(Collection<MainDisplay> mainDisplayList) {
+		for(MainDisplay mainDisplay: mainDisplayList){
+			log.info("mainDisplay.getContentsLoc()::::{}",mainDisplay.getContentsLoc());
+			if(mainDisplay != null && mainDisplay.getContentsLoc() != null){
+				displayDao.deleteMainLayout(mainDisplay);
+				break;
+			}
+		}
+
+		for(MainDisplay mainDisplay: mainDisplayList){
+			log.info("mainDisplay.getCateNo()::::{}",mainDisplay.getCateNo());
+			// 이미지 변경 시
+			if(mainDisplay.getNewSysFileNm() != null && mainDisplay.getNewSysFileNm() != ""){
+				String bannerUploadPath = env.getProperty("upload.default.target.path");
+				bannerUploadPath = GagaFileUtil.getConcatenationPath(bannerUploadPath, "display/main");
+				String newFilename = "MAIN_LAYOUT_" + mainDisplay.getContentsLoc() + "_" + GagaDateUtil.getTodayDateTime() + "." + StringUtils.getFilenameExtension(mainDisplay.getNewSysFileNm());
+
+				// 기존이미지 삭제
+				try{
+					GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(bannerUploadPath, mainDisplay.getOrgFileNm()));
+				}catch (IOException e){
+					//  nothing
+					log.info("[saveBanner MAIN_LAYOUT 기존 이미지 삭제중 error]");
+					//e.printStackTrace();
+				}
+
+				File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(bannerUploadPath, newFilename)));
+				File file = new File(GagaFileUtil.getConcatenationPath(bannerUploadPath, mainDisplay.getNewSysFileNm()));
+
+				// Rename a file
+				file.renameTo(uniqueFile);
+
+				mainDisplay.setOrgFileNm(newFilename);
+				mainDisplay.setSysFileNm(newFilename);
+			}
+			mainDisplay.setRegNo(TsaSession.getInfo().getUserNo());
+			mainDisplay.setUpdNo(TsaSession.getInfo().getUserNo());
+			displayDao.saveMainLayout(mainDisplay);
+		}
+	}
+
+	/**
+	 * 메인전시 컨텐츠 설명
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	public String getContentsDesc(String contentsLoc) {
+		return displayDao.getContentsDesc(contentsLoc);
+	}
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 리스트
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	public Collection<Contents> getContentsPreviewList(Contents contents) {
+		return displayDao.getContentsPreviewList(contents);
+	}
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	@Transactional("shopTxnManager")
+	public void saveContentsPreview(Collection<Contents> contentsList) {
+		for (Contents contents : contentsList) {
+			if (contents != null && contents.getContentsLoc() != null) {
+				displayDao.deleteContentsPreview(contents);
+				break;
+			}
+		}
+		int ind = 1;
+		for (Contents contents : contentsList) {
+			if (contents != null && contents.getDispStdt() != null && !contents.getDispStdt().equals("")) {
+				int cnt = 1;
+				for (String newImgFile : contents.getNewImgFileArr()) {
+					//이미지 변경이 일어났을 경우
+					if (newImgFile != null && !newImgFile.equals("")) {
+						String imgInd = String.valueOf(ind);
+						if (ind < 10) {
+							imgInd = "0" + imgInd;
+						}
+						String bannerUploadPath = env.getProperty("upload.default.target.path");
+						bannerUploadPath = bannerUploadPath + "/display/";
+						String yearMonth = GagaDateUtil.getToday().substring(0, 6);
+						bannerUploadPath = GagaFileUtil.getConcatenationPath(bannerUploadPath, "contents");
+						File newFile = new File(GagaFileUtil.getConcatenationPath(bannerUploadPath, newImgFile));
+						bannerUploadPath = GagaFileUtil.getConcatenationPath(bannerUploadPath, yearMonth);
+						String newFilename = "CONTENS_" + GagaDateUtil.getTodayDateTime() + "_" + imgInd + "." + StringUtils.getFilenameExtension(newImgFile);
+						File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(bannerUploadPath, newFilename)));
+						// Rename a file
+						File path = new File(bannerUploadPath);
+						if (!path.exists()) {
+							path.mkdir();
+						}
+						newFile.renameTo(uniqueFile);
+						if (cnt == 1) {
+							contents.setImgPath1("/contents/" + yearMonth + "/" + newFilename);
+						} else if (cnt == 2) {
+							contents.setImgPath2("/contents/" + yearMonth + "/" + newFilename);
+						} else if (cnt == 3) {
+							contents.setImgPath3("/contents/" + yearMonth + "/" + newFilename);
+						} else if (cnt == 4) {
+							contents.setImgPath4("/contents/" + yearMonth + "/" + newFilename);
+						}
+						ind++;
+
+					}
+					cnt++;
+				}
+				contents.setRegNo(TsaSession.getInfo().getUserNo());
+				contents.setUpdNo(TsaSession.getInfo().getUserNo());
+				displayDao.saveContentsPreview(contents);
+			}
+		}
+	}
+
+	/**
+	 * 메인전시 컨텐츠 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	@Transactional("shopTxnManager")
+	public void saveContents(Contents contents){
+		contents.setRegNo(TsaSession.getInfo().getUserNo());
+		contents.setUpdNo(TsaSession.getInfo().getUserNo());
+		for(String contentsLoc : contents.getContentsLocArr()) {
+			contents.setContentsLoc(contentsLoc);
+			displayDao.deleteContents(contents);
+			displayDao.saveContents(contents);
+		}
+	}
 }

+ 1 - 1
src/main/java/com/style24/admin/biz/service/TsaMailTemplateService.java

@@ -380,4 +380,4 @@ public class TsaMailTemplateService {
 	}
 	
 
-}
+}

+ 7 - 8
src/main/java/com/style24/admin/biz/service/TsaPlanService.java

@@ -60,11 +60,11 @@ public class TsaPlanService {
 	 * @since 2021. 2. 8
 	 */
 	@Transactional("shopTxnManager")
-	public void createPlanWebInfo(Plan param) {
+	public void createPlanInfo(Plan param) {
 		Plan plan = new Plan();
 		param.setRegNo(TsaSession.getInfo().getUserNo());
 		param.setUpdNo(TsaSession.getInfo().getUserNo());
-		planDao.createPlanWebInfo(param);
+		planDao.createPlanInfo(param);
 		
 		String[] brand = param.getMultiBrand();
 		// 기획전 브랜드 insert
@@ -237,8 +237,8 @@ public class TsaPlanService {
 	 * @author sowon
 	 * @since 2021. 2. 5
 	 */
-	public int getPlanListCnt(Plan param) {
-		return planDao.getPlanListCnt(param);
+	public int getPlanListCount(Plan param) {
+		return planDao.getPlanListCount(param);
 	}
 	
 	/**
@@ -265,7 +265,7 @@ public class TsaPlanService {
 	 * @author sowon
 	 * @since 2021. 2. 8
 	 */
-	public Plan getPlanWebDetailInfo(Plan param) {
+	public Plan getPlanDetailInfo(Plan param) {
 		Collection<Plan> planList = planDao.getPlanList(param);
 		Plan planInfo = new Plan();
 
@@ -345,7 +345,7 @@ public class TsaPlanService {
 	 * @since 2021. 2. 8
 	 */
 	@Transactional("shopTxnManager")
-	public void updatePlanWebInfo(Plan param) {
+	public void updatePlanInfo(Plan param) {
 		Plan plan = new Plan();
 		log.debug("param {}", param);
 		String targetPath = env.getProperty("upload.default.target.path") + "/planning";
@@ -405,7 +405,7 @@ public class TsaPlanService {
 		}
 		
 		// 최종업데이트 
-		planDao.updatePlanWebInfo(param);
+		planDao.updatePlanInfo(param);
 
 		// 웹용 소스
 //		if (StringUtils.isNotBlank(param.getFsrcPc())) {
@@ -634,7 +634,6 @@ public class TsaPlanService {
 		for (Plan cornerInfo : paramList) {
 			cornerInfo.setRegNo(TsaSession.getInfo().getUserNo());
 			cornerInfo.setUpdNo(TsaSession.getInfo().getUserNo());
-
 			planDao.savePlanCornerInfo(cornerInfo);
 		}
 

+ 37 - 0
src/main/java/com/style24/admin/biz/service/TsaPollService.java

@@ -1,6 +1,9 @@
 package com.style24.admin.biz.service;
 
 import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -81,6 +84,40 @@ public class TsaPollService {
 	public Collection<Poll> getPollList(Poll poll) {
 		return pollDao.getPollList(poll);
 	}
+	
+	/**
+	 * POLL 투표자 목록
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	public Collection<Poll> getPollVoterList(Poll poll) {
+		return pollDao.getPollVoterList(poll);
+	}
+	
+	/**
+	 * POLL 보기 목록
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	public Collection<Poll> getPollQuestion(Poll poll) {
+		return pollDao.getPollAnswer(poll);
+	}
+	
+	/**
+	 * POLL ANSWER조회
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	public Collection<Poll> getPollAnswer(Poll poll) {
+		return pollDao.getPollAnswer(poll);
+	}
+	
 
 
 }

+ 119 - 0
src/main/java/com/style24/admin/biz/web/TsaDisplayController.java

@@ -4,6 +4,7 @@ import java.util.Collection;
 
 import com.gagaframework.web.parameter.GagaMap;
 import com.gagaframework.web.util.GagaDateUtil;
+import com.style24.admin.biz.service.TsaBusinessService;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.persistence.TscPageRequest;
 import com.style24.persistence.domain.*;
@@ -43,6 +44,9 @@ public class TsaDisplayController extends TsaBaseController {
 	@Autowired
 	private TsaDisplayService displayService;
 
+	@Autowired
+	private TsaBusinessService businessService;
+
 	/**
 	 * 카테고리관리 화면
 	 * @return
@@ -485,4 +489,119 @@ public class TsaDisplayController extends TsaBaseController {
 		displayService.updateCategoryGoodsDispOrd(categoryGoods);
 		return super.ok(message.getMessage("SUCC_0009"));
 	}
+
+	/**
+	 * 메인전시관리 화면
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@GetMapping("/main/form")
+	public ModelAndView mainListForm() {
+		ModelAndView mav = new ModelAndView();
+		Category category = new Category();
+		Brand brand = new Brand();
+		category.setClsLvl(1);
+		mav.addObject("mainCategoryList", displayService.getMainCategoryList(category));
+		brand.setUseYn("Y");
+		brand.setSelfYn("Y");
+		mav.addObject("brandCdList", businessService.getBrandList(brand));
+		mav.addObject("contentsLocList", rendererService.getAvailCommonCodeList("G028"));
+
+		mav.setViewName("display/MainListForm");
+		return mav;
+	}
+
+	/**
+	 * 메인전시 카테고리 목록
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@PostMapping("/main/category/list")
+	@ResponseBody
+	public Collection<Category> getMainCategoryList(@RequestBody Category category) {
+		return displayService.getMainCategoryList(category);
+	}
+
+	/**
+	 * 메인전시 레이아웃 목록
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@PostMapping("/main/layout/list")
+	@ResponseBody
+	public Collection<MainDisplay> getMainLayoutList(@RequestBody MainDisplay mainDisplay) {
+		return displayService.getMainLayoutList(mainDisplay);
+	}
+
+	/**
+	 * 메인전시 레이아웃 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@PostMapping("/main/layout/save")
+	@ResponseBody
+	public GagaResponse saveMainLayout(@RequestBody Collection<MainDisplay> mainDisplayList) {
+		displayService.saveMainLayout(mainDisplayList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 메인전시 컨텐츠 수정 팝업
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 22
+	 */
+	@GetMapping("/main/contents/popup/form")
+	public ModelAndView mainContentsPopupForm(@RequestParam(value = "cateNo") String cateNo, @RequestParam(value = "contentsLoc") String contentsLoc) {
+		ModelAndView mav = new ModelAndView();
+		mav.addObject("cateNo", cateNo);
+		mav.addObject("contentsLoc", contentsLoc);
+		mav.addObject("contentsDesc", displayService.getContentsDesc(contentsLoc));
+		mav.addObject("contentsLocList", rendererService.getAvailCommonCodeList("G028"));
+		mav.setViewName("display/MainContentsPopupForm");
+		return mav;
+	}
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 리스트
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	@PostMapping("/contents/preview/list")
+	@ResponseBody
+	public Collection<Contents> getContentsPreviewList(@RequestBody Contents contents) {
+		return displayService.getContentsPreviewList(contents);
+	}
+
+	/**
+	 * 메인전시 컨텐츠 미리보기 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	@PostMapping("/contents/preview/save")
+	@ResponseBody
+	public GagaResponse saveContentsPreview(@RequestBody Collection<Contents> contentsList) {
+		displayService.saveContentsPreview(contentsList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 메인전시 컨텐츠 저장
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 2. 23
+	 */
+	@PostMapping("/contents/save")
+	@ResponseBody
+	public GagaResponse saveContents(@RequestBody Contents contents) {
+		log.info("controller saveContents contents::: {}",contents);
+		displayService.saveContents(contents);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
 }

+ 57 - 26
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -36,6 +36,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;
@@ -1566,8 +1567,8 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon
 	 * @since 2021. 2. 04
 	 */
-	@GetMapping("/planning/webdetail/form")
-	public ModelAndView planWebDetailForm(Plan param) {
+	@GetMapping("/planning/detail/form")
+	public ModelAndView planDetailForm(Plan param) {
 		ModelAndView mav = new ModelAndView();
 
 		if (param.getMode().equals("N")) { // 신규 일 때
@@ -1581,10 +1582,10 @@ public class TsaMarketingController extends TsaBaseController {
 			mav.addObject("usableCustGbList", rendererService.getAvailCommonCodeList("G100"));
 			
 			// 상위제휴채널 조회
-			mav.addObject("upperAfLinkCdList", rendererService.getCommonCodeList("G053"));
+			mav.addObject("upperAfLinkCdList", rendererService.getAvailCommonCodeList("G053"));
 
 		} else if(param.getMode().equals("U")){ // 상세 일 때
-			mav.addObject("planInfo", planService.getPlanWebDetailInfo(param));
+			mav.addObject("planInfo", planService.getPlanDetailInfo(param));
 
 			mav.addObject("fsrcPc", planService.getPlanFsrcPcList(param));
 
@@ -1602,7 +1603,7 @@ public class TsaMarketingController extends TsaBaseController {
 			mav.addObject("usableCustGbList", rendererService.getAvailCommonCodeList("G100"));
 						
 			// 상위제휴채널 조회
-			mav.addObject("upperAfLinkCdList", rendererService.getCommonCodeList("G053"));
+			mav.addObject("upperAfLinkCdList", rendererService.getAvailCommonCodeList("G053"));
 
 			//mav.addObject("planQuestionList", planService.getPlanQuestionList(param));
 
@@ -1610,7 +1611,7 @@ public class TsaMarketingController extends TsaBaseController {
 		}
 
 		// 사이트 목록
-		mav.addObject("siteList", rendererService.getCommonCodeList("G000"));
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
 
 		// 공급업체 목록
 //		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
@@ -1622,10 +1623,10 @@ public class TsaMarketingController extends TsaBaseController {
 //		mav.addObject("custGbList", rendererService.getCommonCodeList("G100", "Y"));
 		
 		// 사용가능 고객등급 조회
-		mav.addObject("usableCustGradeList", rendererService.getCommonCodeList("G110"));
+		mav.addObject("usableCustGradeList", rendererService.getAvailCommonCodeList("G110"));
 		
 		mav.addObject("mode", param.getMode());
-		mav.setViewName("marketing/PlanWebDetailPopupForm");
+		mav.setViewName("marketing/PlanDetailPopupForm");
 		return mav;
 	}
 	
@@ -1636,10 +1637,10 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon
 	 * @since 2021. 2. 4
 	 */
-	@PostMapping("/planning/webdetail/create")
+	@PostMapping("/planning/detail/create")
 	@ResponseBody
-	public GagaResponse createPlanWebInfo(@RequestBody Plan param) {
-		planService.createPlanWebInfo(param);
+	public GagaResponse createPlanInfo(@RequestBody Plan param) {
+		planService.createPlanInfo(param);
 		return super.ok(message.getMessage("SUCC_0001"));
 	}
 	
@@ -1663,7 +1664,7 @@ public class TsaMarketingController extends TsaBaseController {
 		
 //		param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 		param.setPageable(new TscPageRequest(param.getPageNo() - 1, param.getPageSize()));
-		param.getPageable().setTotalCount(planService.getPlanListCnt(param));
+		param.getPageable().setTotalCount(planService.getPlanListCount(param));
 		
 		
 		Collection<Plan> planList = planService.getPlanList(param);
@@ -1685,7 +1686,7 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon
 	 * @since 2021. 2. 16
 	 */
-	@PostMapping("/planning/listPop")
+	@PostMapping("/planning/list/detail/popup")
 	@ResponseBody
 	public Collection<Plan> getPlanListPop(@RequestBody Plan param) {
 		//param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
@@ -1715,10 +1716,10 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon		
 	 * @since 2021. 2. 8
 	 */
-	@PostMapping("/plan/webdetail/update")
+	@PostMapping("/plan/detail/update")
 	@ResponseBody
-	public GagaResponse updatePlanWebInfo(@RequestBody Plan param) {
-		planService.updatePlanWebInfo(param);
+	public GagaResponse updatePlanInfo(@RequestBody Plan param) {
+		planService.updatePlanInfo(param);
 		return super.ok(message.getMessage("SUCC_0002"));
 	}
 	
@@ -1784,7 +1785,7 @@ public class TsaMarketingController extends TsaBaseController {
 		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y"));
 
 		// 기획전 상세 정보
-		mav.addObject("planInfo", planService.getPlanWebDetailInfo(param));
+		mav.addObject("planInfo", planService.getPlanDetailInfo(param));
 
 
 		mav.setViewName("marketing/PlanCornerListForm");
@@ -1833,12 +1834,12 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon
 	 * @since 2021. 2. 16
 	 */
-	@GetMapping("/planning/corner/plandtlsq")
-	@ResponseBody
-	public long getPlanDtlSq(Plan param) {
-		return planService.getPlanDtlSq(param);
-	}
-	
+//	@GetMapping("/planning/corner/plandtlsq")
+//	@ResponseBody
+//	public long getPlanDtlSq(Plan param) {
+//		return planService.getPlanDtlSq(param);
+//	}
+//	
 	/**
 	 * 기획전 코너 삭제
 	 *
@@ -1983,7 +1984,7 @@ public class TsaMarketingController extends TsaBaseController {
 	 * @author sowon
 	 * @since 2021. 2. 18
 	 */
-	@GetMapping("/planning/webdetail/template/form")
+	@GetMapping("/planning/detail/template/form")
 	public ModelAndView planTemplateForm(Plan param) {
 		ModelAndView mav = new ModelAndView();
 
@@ -2071,11 +2072,41 @@ public class TsaMarketingController extends TsaBaseController {
 	@PostMapping("/poll/list")
 	@ResponseBody
 	public Collection<Poll> getPollList(@RequestBody Poll poll) {
-		Collection<Poll> pollList = pollService.getPollList(poll);
-		return pollList;
+		return pollService.getPollList(poll);
 	}
 	
+	/**
+	 * POLL 투표자 목록
+	 *
+	 * @param POLL 조회 정보
+	 * @return POLL 목록
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	@PostMapping("/poll/voter/list")
+	@ResponseBody
+	public Collection<Poll> getPollVoterList(@RequestBody Poll poll) {
+		Collection<Poll> pollList = pollService.getPollVoterList(poll);
+		return pollList;
+	}
 	
+	/**
+	 * POLL detail 투표율
+	 * 
+	 * @param POLL 투표율
+	 * @return POLL 목록
+	 * @author sowon
+	 * @since 2021. 2. 22
+	 */
+	@GetMapping("/poll/voter/list/popup/form")
+	public ModelAndView pollVoterRate(Poll param) {
+		ModelAndView mav = new ModelAndView();
+		mav.addObject("pollQList", pollService.getPollQuestion(param));
+		mav.addObject("pollAList", pollService.getPollAnswer(param));
+		mav.setViewName("marketing/PollVoteRatePopupForm");
+		return mav;
+	}
+
 
 
 }

+ 1 - 0
src/main/java/com/style24/persistence/domain/Brand.java

@@ -23,6 +23,7 @@ public class Brand extends TscBaseDomain {
 	private String brandKnm;		// 브랜드한글명
 	//private String dispNmLang;		// 노출명언어
 	//private String rgbCd;			// RGB코드(front 브랜드메인 GNB 색상)
+	private int brandGroupNo;		// 브랜드그룹번호
 	private String brandGroupNm;	// 브랜드그룹명
 	private String supplyCompCd;	// 공급업체코드
 	private String supplyCompNm;	// 공급업체명

+ 1 - 0
src/main/java/com/style24/persistence/domain/BrandGroup.java

@@ -32,6 +32,7 @@ public class BrandGroup extends TscBaseDomain {
 	private String multiGb;			// 멀티 셀렉트 구분
 	private String searchBrandGroupNo;
 	private String searchBrandGroupNm;
+	private String type;			// S:조회용, C:브랜드관리화면에서 호출, 브랜드그룹등록영역 노출
 
 	/* 브랜드검색 Multi CheckBox 항목*/
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)

+ 1 - 1
src/main/java/com/style24/persistence/domain/Category.java

@@ -35,7 +35,7 @@ public class Category extends TscBaseDomain {
 	private String dispYn;		// 노출여부
 	private String useYn;		// 사용여부
 
-//	private String clocPrefix;      // 메인전시 컨텐츠 위치 프리픽스
+	private String clocPrefix;      // 메인전시 컨텐츠 위치 프리픽스
 //	private String brandGrpNm;
 
 	// 검색조건

+ 37 - 0
src/main/java/com/style24/persistence/domain/Contents.java

@@ -0,0 +1,37 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+import lombok.Data;
+
+@SuppressWarnings("serial")
+@Data
+public class Contents extends TscBaseDomain {
+    private Integer preContentsSq;
+    private Integer contentsSq;
+    private Integer cateNo;
+    private String contentsLoc;
+    private String contentsType;
+    private String dispStdt;
+    private String dispEddt;
+    private Integer dispOrd;
+    private String contentsYn;
+    private String imgPath1;
+    private String imgPath2;
+    private String imgPath3;
+    private String imgPath4;
+    private String strVar1;
+    private String strVar2;
+    private String strVar3;
+    private String strVar4;
+    private String strTitle1;
+    private String strTitle2;
+    private String strTitle3;
+    private String strTitle4;
+    private String useYn;
+
+    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+    private String[] contentsLocArr;
+    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+    private String[] newImgFileArr;
+}

+ 22 - 0
src/main/java/com/style24/persistence/domain/MainDisplay.java

@@ -0,0 +1,22 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+import lombok.Data;
+import sun.applet.Main;
+
+import java.util.List;
+
+@SuppressWarnings("serial")
+@Data
+public class MainDisplay extends TscBaseDomain {
+    private Integer cateNo;
+    private String contentsLoc;
+    private Integer dispOrd;
+    private String contentsYn;
+    private Integer colCnt;
+    private Integer colNo;
+    private String orgFileNm;
+    private String sysFileNm;
+    private String newSysFileNm;
+}

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

@@ -1,6 +1,8 @@
 package com.style24.persistence.domain;
 
 
+import com.style24.core.support.session.TscSession;
+import com.style24.core.support.util.MaskingUtils;
 import com.style24.persistence.TscBaseDomain;
 
 import lombok.Data;
@@ -44,6 +46,7 @@ public class Poll extends TscBaseDomain{
 	private String pollQval9;		// 투표문항참고값9
 	private String pollQval10;		// 투표문항참고값10
 	private Integer dispOrd;		// 표시 순서
+	private String pollQtypeNm;	// 문제유형 이름
 	
 	//poll_answer
 	private String ansCustNo;		// 투표회원번호
@@ -56,13 +59,10 @@ public class Poll extends TscBaseDomain{
 	
 	private Integer voteCnt;		// 투표수
 	private Integer voteRate;		// 투표율
-	
-	
-	
-	
-	
-	
+	private Integer numbers;		// 투표율 구하기위한 변수선언 
+	private String name;			// 투표율 구하기위한 변수선언 
 	private String voterNm;			// 투표자명
 	private String voteDt;			// 투표일시
+	
 
 }

+ 36 - 30
src/main/java/com/style24/persistence/mybatis/shop/TsaBusiness.xml

@@ -496,9 +496,9 @@
 		     , A.PNT_MRATE20                 /*포인트적립율(모바일)*/
 		     , A.DISP_ORD                    /*표시순서*/
 		     , (CASE WHEN D.DISP_NM_LANG = 'EN' THEN D.BRAND_GROUP_ENM ELSE D.BRAND_GROUP_KNM END) AS BRAND_GROUP_NM
-		     , A.BRAND_NO
+		     , A.BRAND_GROUP_NO
 		FROM   TB_BRAND A
-		INNER JOIN TB_BRAND_GROUP D ON A.BRAND_NO = D.BRAND_GROUP_NO
+		INNER JOIN TB_BRAND_GROUP D ON A.BRAND_GROUP_NO = D.BRAND_GROUP_NO
 		                            AND D.USE_YN = 'Y'
 		<if test='supplyCompCd != null and supplyCompCd != ""'>
 		INNER JOIN TB_BRAND_SUPPLY C ON A.BRAND_CD = C.BRAND_CD
@@ -517,6 +517,19 @@
 		<if test='brandCd != null and brandCd != ""'>
 		AND    A.BRAND_CD = #{brandCd}
 		</if>
+		<if test="searchTxt != null and searchTxt != ''">
+		AND    (
+		        UPPER(A.BRAND_ENM) LIKE CONCAT('%',UPPER(#{searchTxt}),'%')
+		        OR
+		        UPPER(A.BRAND_KNM) LIKE CONCAT('%',UPPER(#{searchTxt}),'%')
+		        OR
+		        UPPER(A.BRAND_CD) LIKE CONCAT('%',UPPER(#{searchTxt}),'%')
+		        OR
+		        UPPER(D.BRAND_GROUP_KNM) LIKE CONCAT('%',UPPER(#{searchTxt}),'%')
+		        OR
+		        UPPER(D.BRAND_GROUP_ENM) LIKE CONCAT('%',UPPER(#{searchTxt}),'%')
+		       )
+		</if>
 		<if test="multiBrandCd != null and multiBrandCd.length > 0">
 		AND    A.BRAND_CD IN
 		    <foreach collection="multiBrandCd" item="item" index="index"  open="(" close=")" separator=",">
@@ -662,15 +675,19 @@
 	</select>
 	
 	<!-- 브랜드 등록 -->
-	<insert id="createBrand" parameterType="Brand" keyProperty="brandCd">
+	<insert id="createBrand" parameterType="Brand" >
 		/* TsaBusiness.createBrand */
+		<selectKey keyProperty="brandCd" resultType="String" order="BEFORE">
+			 (SELECT CONCAT(#{brandGb},IFNULL(LPAD(CAST(SUBSTRING(MAX(BRAND_CD),2) AS UNSIGNED) + 1,4,'0'),'0000'))
+		        FROM   TB_BRAND Z
+		        WHERE  BRAND_CD LIKE CONCAT(#{brandGb},'%')
+		       )
+		</selectKey>
+		
 		INSERT INTO TB_BRAND (
 		       BRAND_CD
 		     , BRAND_ENM
 		     , BRAND_KNM
-		     , BRAND_GRP_NM
-		     , DISP_NM_LANG
-		     , RGB_CD
 		     , DISTRIBUTION_GB
 		     , SELF_YN
 		     , ERP_BRAND_CD
@@ -678,25 +695,19 @@
 		     , PNT_MRATE10
 		     , PNT_PRATE20
 		     , PNT_MRATE20
-		     , LOGO_FILE_NM
 		     , DISP_ORD
 		     , USE_YN
 		     , BRAND_NO
+		     , BRAND_GROUP_NO
 		     , REG_NO
 		     , REG_DT
 		     , UPD_NO
 		     , UPD_DT
 		)
 		VALUES (
-		       (SELECT CONCAT(#{brandGb},IFNULL(LPAD(CAST(SUBSTRING(MAX(BRAND_CD),2) AS UNSIGNED) + 1,4,'0'),'0000'))
-		        FROM   TB_BRAND Z
-		        WHERE  BRAND_CD LIKE CONCAT(#{brandGb},'%')
-		       )
+		       #{brandCd}
 		     , #{brandEnm}
 		     , #{brandKnm}
-		     , #{brandGrpNm}
-		     , #{dispNmLang}
-		     , #{rgbCd}
 		     , #{distributionGb}
 		     , CASE WHEN #{distributionGb} IN ('G065_10','G065_11','G065_12') THEN 'Y'
 		            ELSE 'N'
@@ -706,15 +717,15 @@
 		     , IFNULL(#{pntMrate10},0)
 		     , IFNULL(#{pntPrate20},0)
 		     , IFNULL(#{pntMrate20},0)
-		     , #{logoFileNm}
 		     , #{dispOrd}
 		     , #{useYn}
-		     , (SELECT CASE WHEN MAX(BRAND_NO) IS NULL THEN 40000   /* AS-IS 최대 수보다 크게 설정해야 함 */
+		     , (SELECT CASE WHEN MAX(BRAND_NO) IS NULL THEN 30000   /* AS-IS 최대 수보다 크게 설정해야 함 */
 		               ELSE (MAX(BRAND_NO) + 1) END
 		        FROM   TB_BRAND Z
 		        WHERE  1 = 1
-		        AND BRAND_NO > 40000                  /* AS-IS 최대 수보다 크게 크게 설정해야 함*/
+		        AND BRAND_NO > 29999                  /* AS-IS 최대 수보다 크게 크게 설정해야 함*/
 		       ) 
+		     , #{brandGroupNo}
 		     , #{regNo}
 		     , NOW()
 		     , #{updNo}
@@ -728,9 +739,6 @@
 		UPDATE TB_BRAND
 		SET    BRAND_ENM = #{brandEnm}
 		     , BRAND_KNM = #{brandKnm}
-		     , BRAND_GRP_NM = #{brandGrpNm}
-		     , DISP_NM_LANG = #{dispNmLang}
-		     , RGB_CD = #{rgbCd}
 		     , DISTRIBUTION_GB = #{distributionGb}
 		     , SELF_YN = CASE WHEN #{distributionGb} IN ('G065_10','G065_11','G065_12') THEN 'Y'
 		                      ELSE 'N'
@@ -740,9 +748,9 @@
 		     , PNT_MRATE10 = IFNULL(#{pntMrate10},0)
 		     , PNT_PRATE20 = IFNULL(#{pntPrate20},0)
 		     , PNT_MRATE20 = IFNULL(#{pntMrate20},0)
-		     , LOGO_FILE_NM = #{logoFileNm}
 		     , DISP_ORD = #{dispOrd}
 		     , USE_YN = #{useYn}
+		     , BRAND_GROUP_NO = #{brandGroupNo}
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()
 		WHERE  BRAND_CD = #{brandCd}
@@ -1052,7 +1060,7 @@
 	</select>
 	
 	<!-- 브랜드 그룹 등록 -->
-	<insert id="createBrandGroup" parameterType="BrandGroup" keyProperty="BrandGroup">
+	<insert id="createBrandGroup" parameterType="BrandGroup" >
 		/* TsaBusiness.createBrandGroup */
 		INSERT INTO TB_BRAND_GROUP (
 		       BRAND_GROUP_NO
@@ -1061,23 +1069,23 @@
 		     , DISP_NM_LANG
 		     , RGB_CD
 		     , LOGO_FILE_NM
-		     , DISP_ORD
-		     , USE_YN
 		     , REG_NO
 		     , REG_DT
 		     , UPD_NO
 		     , UPD_DT
 		)
 		VALUES (
-		       (SELECT MAX(BRAND_GROUP_NO) + 1 FROM TB_BRAND_GROUP)
+		       (SELECT CASE WHEN MAX(BRAND_GROUP_NO) IS NULL THEN 30000
+		               ELSE (MAX(BRAND_GROUP_NO) + 1) END
+		        FROM   TB_BRAND_GROUP Z
+		        WHERE  1 = 1
+		        AND BRAND_GROUP_NO > 29999
+		       ) 
 		     , #{brandGroupEnm}
 		     , #{brandGroupKnm}
 		     , #{dispNmLang}
 		     , #{rgbCd}
 		     , #{logoFileNm}
-		     , #{dispOrd}
-		     , #{useYn}
-		     , (SELECT MAX(BRAND_GROUP_NO) + 1 FROM TB_BRAND_GROUP)
 		     , #{regNo}
 		     , NOW()
 		     , #{updNo}
@@ -1094,8 +1102,6 @@
 		     , DISP_NM_LANG = #{dispNmLang}
 		     , RGB_CD = #{rgbCd}
 		     , LOGO_FILE_NM = #{logoFileNm}
-		     , DISP_ORD = #{dispOrd}
-		     , USE_YN = #{useYn}
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()
 		WHERE  BRAND_GROUP_NO = #{brandGroupNo}

+ 276 - 2
src/main/java/com/style24/persistence/mybatis/shop/TsaDsiplay.xml

@@ -1125,10 +1125,10 @@
 			SET A.DISP_ORD = DISP_ORD - 1
 		</if>
 		<if test="changeGb != null and changeGb =='min'">
-			SET A.DISP_ORD = (SELECT DISP_ORD FROM (SELECT MIN(DISP_ORD) AS DISP_ORD FROM TB_CATE_GOODS B WHERE CATE_NO = 1127) TMP)
+			SET A.DISP_ORD = (SELECT DISP_ORD FROM (SELECT MIN(DISP_ORD) AS DISP_ORD FROM TB_CATE_GOODS B WHERE CATE_NO = #{cateNo}) TMP)
 		</if>
 		<if test="changeGb != null and changeGb =='max'">
-			SET A.DISP_ORD = (SELECT DISP_ORD FROM (SELECT MAX(DISP_ORD) AS DISP_ORD FROM TB_CATE_GOODS B WHERE CATE_NO = 1127) TMP)
+			SET A.DISP_ORD = (SELECT DISP_ORD FROM (SELECT MAX(DISP_ORD) AS DISP_ORD FROM TB_CATE_GOODS B WHERE CATE_NO = #{cateNo}) TMP)
 		</if>
 		WHERE A.CATE_NO = #{cateNo}
 		<choose>
@@ -1159,4 +1159,278 @@
 		WHERE	CATE_NO = #{cateNo}
 		AND 	GOODS_CD = #{goodsCd}
 	</update>
+
+	<!-- 메인전시관리 카테고리 리스트 -->
+	<select id="getMainCategoryList" parameterType="Category" resultType="Category">
+		/* TsaDisplay.getMainCategoryList */
+		SELECT	CATE_NO
+			 ,CATE_NM
+			 ,DISP_ORD
+			 ,LEAF_YN
+			 ,CLOC_PREFIX
+		FROM(
+		<choose>
+			<when test="clsLvl==1">
+				SELECT	CATE1_NO	AS CATE_NO
+						,CATE1_NM	AS CATE_NM
+						,MIN(DISP_ORD) AS DISP_ORD
+						,MIN(CASE WHEN LEAF_CATE_NO = CATE1_NO THEN 'Y' ELSE 'N' END) AS LEAF_YN
+						,CLOC_PREFIX
+				FROM	VW_MAIN_CATEGORY
+				GROUP BY CATE1_NO, CATE1_NM, CLOC_PREFIX
+			</when>
+			<when test="clsLvl==2">
+				SELECT	CATE2_NO	AS CATE_NO
+						,CATE2_NM	AS CATE_NM
+						,MIN(DISP_ORD) AS DISP_ORD
+						,MIN(CASE WHEN LEAF_CATE_NO = CATE2_NO THEN 'Y' ELSE 'N' END) AS LEAF_YN
+						,CLOC_PREFIX
+				FROM	VW_MAIN_CATEGORY
+				WHERE	CATE1_NO = #{cateNo}
+				GROUP BY CATE2_NO, CATE2_NM, CLOC_PREFIX
+			</when>
+		</choose>
+		) A
+		ORDER BY DISP_ORD, CATE_NO
+	</select>
+
+	<!-- 메인전시관리 레이아웃 -->
+	<select id="getMainLayoutList" parameterType="MainDisplay" resultType="MainDisplay">
+		/* TsaDisplay.getMainLayoutList */
+		SELECT	CATE_NO
+				,CONTENTS_LOC
+				,DISP_ORD
+				,CONTENTS_YN
+				,COL_CNT
+				,COL_NO
+				,ORG_FILE_NM
+				,SYS_FILE_NM
+		FROM	TB_MAIN_LAYOUT
+		WHERE	CATE_NO = #{cateNo}
+		ORDER BY DISP_ORD, COL_NO
+	</select>
+
+	<!-- 메인전시관리 삭제 -->
+	<delete id="deleteMainLayout" parameterType="MainDisplay">
+		/* TsaDisplay.deleteMainLayout */
+		DELETE FROM TB_MAIN_LAYOUT
+		WHERE CATE_NO = #{cateNo}
+		<if test='contentsLoc!=null and contentsLoc!=""'>
+			AND SUBSTR(CONTENTS_LOC, 0, 4) = SUBSTR(#{contentsLoc}, 0, 4)
+		</if>
+	</delete>
+
+	<!-- 메인전시관리 저장 -->
+	<insert id="saveMainLayout" parameterType="MainDisplay">
+		/* TsaDisplay.saveMainLayout */
+		INSERT INTO TB_MAIN_LAYOUT
+		(
+			CATE_NO
+			,CONTENTS_LOC
+			,DISP_ORD
+			,CONTENTS_YN
+			,COL_CNT
+			,COL_NO
+			,ORG_FILE_NM
+			,SYS_FILE_NM
+			,REG_NO
+			,REG_DT
+			,UPD_NO
+			,UPD_DT
+		)
+		VALUES
+		(
+		 	#{cateNo}
+		 	,#{contentsLoc}
+		 	,#{dispOrd}
+			,#{contentsYn}
+			,#{colCnt}
+			,#{colNo}
+			,#{orgFileNm}
+			,#{sysFileNm}
+			,#{regNo}
+			,NOW()
+			,#{updNo}
+			,NOW()
+		)
+	</insert>
+
+	<!-- 컨텐츠 설명 조회 -->
+	<select id="getContentsDesc" parameterType="String" resultType="String">
+		/* TsaDisplay.getContentsDesc */
+		SELECT	IFNULL(CD_DESC, '') AS CONTENTS_DESC
+		FROM	TB_COMMON_CODE
+		WHERE	CD = #{contentsLoc}
+	</select>
+
+	<!-- 컨텐츠 미리보기 리스트 조회 -->
+	<select id="getContentsPreviewList" parameterType="Contents" resultType="Contents">
+		/* TsaDisplay.getContentsPreviewList */
+		SELECT PRE_CONTENTS_SQ
+			 , CATE_NO
+			 , CONTENTS_LOC
+			 , CONTENTS_TYPE
+			 , DISP_STDT
+			 , DISP_EDDT
+			 , DISP_ORD
+			 , IMG_PATH1
+			 , IMG_PATH2
+			 , IMG_PATH3
+			 , IMG_PATH4
+			 , STR_VAR1
+			 , STR_VAR2
+			 , STR_VAR3
+			 , STR_VAR4
+			 , STR_TITLE1
+			 , STR_TITLE2
+			 , STR_TITLE3
+			 , STR_TITLE4
+			 , USE_YN
+			 , REG_NO
+			 , REG_DT
+			 , UPD_NO
+			 , UPD_DT
+		FROM TB_CONTENTS_PREVIEW
+		WHERE CATE_NO = #{cateNo}
+		  AND CONTENTS_LOC = #{contentsLoc}
+		ORDER BY DISP_ORD
+	</select>
+
+	<!-- 메인전시 컨텐츠 미리보기 삭제 -->
+	<delete id="deleteContentsPreview" parameterType="Contents">
+		/* TsaDisplay.deleteContentsPreview */
+		DELETE FROM TB_CONTENTS_PREVIEW
+		WHERE 	CATE_NO = #{cateNo}
+		AND 	CONTENTS_LOC = #{contentsLoc}
+	</delete>
+
+	<!-- 메인전시 컨텐츠 미리보기 저장 -->
+	<insert id="saveContentsPreview" parameterType="Contents" keyProperty="preContentsSq">
+		/* TsaDisplay.saveContentsPreview */
+		INSERT INTO TB_CONTENTS_PREVIEW
+		(
+			PRE_CONTENTS_SQ
+			, CATE_NO
+			, CONTENTS_LOC
+			, CONTENTS_TYPE
+			, DISP_STDT
+			, DISP_EDDT
+			, DISP_ORD
+			, IMG_PATH1
+			, IMG_PATH2
+			, IMG_PATH3
+			, IMG_PATH4
+			, STR_VAR1
+			, STR_VAR2
+			, STR_VAR3
+			, STR_VAR4
+			, STR_TITLE1
+			, STR_TITLE2
+			, STR_TITLE3
+			, STR_TITLE4
+			, USE_YN
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		)
+		VALUES
+		(
+			#{preContentsSq}
+			,#{cateNo}
+			,#{contentsLoc}
+			,#{contentsType}
+			,DATE_FORMAT(#{dispStdt}, '%Y-%m-%d %H:%i:%S')
+			,DATE_FORMAT(#{dispEddt}, '%Y-%m-%d %H:%i:%S')
+			,(SELECT DISP_ORD FROM (SELECT IFNULL((MAX(DISP_ORD) + 1), 1) AS DISP_ORD FROM	TB_CONTENTS_PREVIEW	WHERE CATE_NO = #{cateNo} AND CONTENTS_LOC = #{contentsLoc}) TMP)
+			,#{imgPath1}
+			,#{imgPath2}
+			,#{imgPath3}
+			,#{imgPath4}
+			,#{strVar1}
+			,#{strVar2}
+			,#{strVar3}
+			,#{strVar4}
+			,#{strTitle1}
+			,#{strTitle2}
+			,#{strTitle3}
+			,#{strTitle4}
+			,#{useYn}
+			,#{regNo}
+			,NOW()
+			,#{updNo}
+			,NOW()
+		)
+	</insert>
+
+	<!-- 메인전시 컨텐츠 삭제 -->
+	<delete id="deleteContents" parameterType="Contents">
+		/* TsaDisplay.deleteContents */
+		DELETE FROM TB_CONTENTS
+		WHERE 	CATE_NO = #{cateNo}
+		  AND 	CONTENTS_LOC = #{contentsLoc}
+	</delete>
+
+	<!-- 메인전시 컨텐츠 저장 -->
+	<insert id="saveContents" parameterType="Contents">
+		/* TsaDisplay.saveContents */
+		<selectKey keyProperty="contentsSq" resultType="int" order="AFTER">
+			SELECT LAST_INSERT_ID()
+		</selectKey>
+		INSERT INTO TB_CONTENTS
+		(
+			CONTENTS_SQ
+		 	, CATE_NO
+			, CONTENTS_LOC
+			, CONTENTS_TYPE
+			, DISP_STDT
+			, DISP_EDDT
+			, DISP_ORD
+			, IMG_PATH1
+			, IMG_PATH2
+			, IMG_PATH3
+			, IMG_PATH4
+			, STR_VAR1
+			, STR_VAR2
+			, STR_VAR3
+			, STR_VAR4
+			, STR_TITLE1
+			, STR_TITLE2
+			, STR_TITLE3
+			, STR_TITLE4
+			, USE_YN
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		)
+		SELECT
+		     #{contentsSq}
+			 , CATE_NO
+			 , CONTENTS_LOC
+			 , CONTENTS_TYPE
+			 , DISP_STDT
+			 , DISP_EDDT
+			 , DISP_ORD
+			 , IMG_PATH1
+			 , IMG_PATH2
+			 , IMG_PATH3
+			 , IMG_PATH4
+			 , STR_VAR1
+			 , STR_VAR2
+			 , STR_VAR3
+			 , STR_VAR4
+			 , STR_TITLE1
+			 , STR_TITLE2
+			 , STR_TITLE3
+			 , STR_TITLE4
+			 , USE_YN
+			 , #{regNo}
+			 , NOW()
+			 , #{updNo}
+			 , NOW()
+		FROM	TB_CONTENTS_PREVIEW
+		WHERE	CONTENTS_LOC = #{contentsLoc}
+		AND 	CATE_NO = #{cateNo}
+	</insert>
 </mapper>

+ 1 - 1
src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml

@@ -3352,7 +3352,7 @@
 	</select>
 	
 	<!-- 광고 키워드 저장 -->
-	<insert id="saveAdKeyword" parameterType="AdKeyword">
+	<insert id="saveAdKeyword" parameterType="AdKeyword"   keyProperty="adKeywordSq">
 		/* TsaGoods.saveAdKeyword */
 		INSERT INTO TB_AD_KEYWORD (
 		       AD_KEYWORD_SQ

+ 10 - 7
src/main/java/com/style24/persistence/mybatis/shop/TsaPlan.xml

@@ -3,8 +3,8 @@
 <mapper namespace="com.style24.admin.biz.dao.TsaPlanDao">
 
 	<!-- 기획전 등록 -->
-	<insert id="createPlanWebInfo" parameterType="Plan">
-		/* TsaMarketing.createPlanWebInfo */
+	<insert id="createPlanInfo" parameterType="Plan">
+		/* TsaMarketing.createPlanInfo */
 		<selectKey keyProperty="planSq" resultType="Integer" order="AFTER">
 			SELECT LAST_INSERT_ID()	/* 기획전 일련번호  */
 		</selectKey>
@@ -154,8 +154,8 @@
 	</select>
 	
 	<!-- 기획전 리스트 카운트 조회-->
-	<select id="getPlanListCnt" parameterType="Plan" resultType="int">
-		/* TsaMarketing.getPlanListCnt */
+	<select id="getPlanListCount" parameterType="Plan" resultType="int">
+		/* TsaMarketing.getPlanListCount */
 		SELECT COUNT(1)
 		  FROM TB_PlAN
 		 WHERE 1=1
@@ -297,8 +297,8 @@
 	</select>
 	
 	<!-- 기획전 수정 -->
-	<update id="updatePlanWebInfo" parameterType="Plan">
-		/* TsaMarketing.updatePlanWebInfo */
+	<update id="updatePlanInfo" parameterType="Plan">
+		/* TsaMarketing.updatePlanInfo */
 		UPDATE TB_PLAN
 		   SET PLAN_GB = #{planGb}
 		     <!-- , CUST_GB = #{custGb} -->
@@ -659,6 +659,9 @@
 	<!-- 기획전 코너 저장 -->
 	<insert id="savePlanCornerInfo" parameterType="Plan">
 		/* TsaMarketing.savePlanCornerInfo */
+		<selectKey keyProperty="planDtlSq" resultType="Integer" order="AFTER">
+			SELECT LAST_INSERT_ID()	/* 기획전 일련번호  */
+		</selectKey>
 		INSERT INTO
 			      TB_PLAN_DETAIL (
 			            PLAN_SQ         
@@ -674,7 +677,7 @@
                       , UPD_NO          
 			      )
 			   VALUES (
-			    	   #{planSq}                                         
+			    	   #{planSq}                                        
                      , #{planDtlSq}                                      
                      , DATE_FORMAT(#{dispStdt} , '%Y-%m-%d %H:%i:%s')     
                      , DATE_FORMAT(#{dispEddt} , '%Y-%m-%d %H:%i:%s')   

+ 66 - 1
src/main/java/com/style24/persistence/mybatis/shop/TsaPoll.xml

@@ -111,6 +111,7 @@
 	
 	<!-- POLL 목록 -->
 	<select id="getPollList" parameterType="Poll" resultType="Poll">
+		/* TsaPoll.getPollList */
 		 SELECT   M.POLL_SQ                                                                                                     
 				, M.POLL_TITLE                                                                                                 
 				, M.DUP_PARTI_YN                                                                                               
@@ -133,6 +134,7 @@
 				, M.POLL_QVAL8                                                                                                 
 				, M.POLL_QVAL9                                                                                                 
 				, M.POLL_QVAL10    
+				, M.POLL_QTYPE_NM
 		 FROM
 		 (		      
 			SELECT A.POLL_SQ
@@ -146,7 +148,7 @@
 			      , A.REG_DT 
 			      , B.POLL_QSQ 
 			      , B.POLL_QTITLE 
-			      , CASE B.POLL_QTYPE WHEN 10 THEN '단수형' WHEN 20 THEN '복수형' WHEN 30 THEN '단답형' ELSE '서술형' END AS POLL_QTYPE
+			      , CASE B.POLL_QTYPE WHEN 10 THEN '단수형' WHEN 20 THEN '복수형' WHEN 30 THEN '단답형' ELSE '서술형' END AS POLL_QTYPE_NM
 			      , B.POLL_QVAL1 
 			      , B.POLL_QVAL2 
 			      , B.POLL_QVAL3 
@@ -157,6 +159,7 @@
 			      , B.POLL_QVAL8
 			      , B.POLL_QVAL9
 			      , B.POLL_QVAL10
+			      , B.POLL_QTYPE
 			FROM   TB_POLL A LEFT JOIN TB_POLL_QUESTION B ON A.POLL_SQ = B.POLL_SQ 
 			WHERE 1=1
 		  		 AND A.DEL_YN = 'N'
@@ -196,4 +199,66 @@
 			)M
 	
 	</select>
+	
+	<!-- POLL관리 투표자 목록 조회 -->
+	<select id="getPollVoterList" parameterType="Poll" resultType="Poll">
+		/* TsaPoll.getPollVoterList */
+		SELECT B.CUST_NM          AS VOTER_NM    
+		     , A.ANS_CUST_NO      AS ANS_CUST_NO 
+		     , A.REG_DT			  AS VOTE_DT   
+		     , A.DUMMY		      AS DUMMY  
+		FROM   TB_POLL_ANSWER A
+		     , TB_CUSTOMER B
+		WHERE  A.ANS_CUST_NO = B.CUST_NO
+		AND    A.POLL_QSQ = #{pollQsq}
+		ORDER  BY B.CUST_NM
+	</select>
+	
+	<!-- POLL QUESTION 보기 조회 -->
+	<select id="getPollQuestion" parameterType="Poll" resultType="Poll">
+		/* TsaPoll.getPollQuestion */
+		SELECT POLL_QSQ 
+		      ,POLL_QTITLE 
+		      ,POLL_QTYPE 
+		      ,POLL_QVAL1 
+		      ,POLL_QVAL2
+		      ,POLL_QVAL3 
+		      ,POLL_QVAL4 
+		      ,POLL_QVAL5 
+		      ,POLL_QVAL6 
+		      ,POLL_QVAL7 
+		      ,POLL_QVAL8 
+		      ,POLL_QVAL9 
+		      ,POLL_QVAL10 
+		FROM TB_POLL_QUESTION
+		WHERE POLL_QSQ = #{pollQsq}
+	</select>
+	
+	<!-- POLL ANSWER 조회 -->
+	<select id="getPollAnswer" parameterType="Poll" resultType="Poll">
+		/* TsaPoll.getPollAnswer */
+			SELECT M.NAME
+				  ,COUNT(M.NAME) AS VOTE_CNT
+				  ,M.POLL_QSQ
+				  ,M.POLL_QTYPE
+				  ,(COUNT(M.NAME)/CNT)*100 AS VOTE_RATE
+			FROM 
+			(
+				SELECT
+				  A.POLL_QSQ
+				  ,SUBSTRING_INDEX(SUBSTRING_INDEX(A.DUMMY , '|', NUMBERS.N), '|', -1) NAME
+				  ,A.POLL_QTYPE  
+				  ,COUNT(*) OVER(PARTITION BY POLL_QSQ)  AS CNT
+				FROM
+					  (SELECT 1 N UNION ALL
+					   SELECT 2 UNION ALL SELECT 3 UNION ALL
+					   SELECT 4 UNION ALL SELECT 5 UNION ALL
+					   SELECT 6 UNION ALL SELECT 7 UNION ALL
+					   SELECT 8 UNION ALL SELECT 9 UNION ALL
+					   SELECT 10 ) NUMBERS 
+				   INNER JOIN TB_POLL_ANSWER A ON CHAR_LENGTH(A.DUMMY)-CHAR_LENGTH(REPLACE(A.DUMMY, '|', ''))>=NUMBERS.N-1
+				WHERE POLL_QSQ = #{pollQsq}
+			)M
+			GROUP BY NAME,M.POLL_QSQ,M.POLL_QTYPE
+	</select>
 </mapper>

+ 0 - 3
src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml

@@ -158,9 +158,6 @@
 		<if test='supplyCompCd != null and supplyCompCd != ""'>
 		AND    C.SUPPLY_COMP_CD = #{supplyCompCd}
 		</if>
-		<if test='brandGrpNm != null and brandGrpNm != ""'>
-		AND    A.BRAND_GRP_NM = #{brandGrpNm}
-		</if>
 		<if test='useYn != null and useYn != ""'>
 		AND    A.USE_YN = #{useYn}
 		</if>

+ 13 - 29
src/main/webapp/WEB-INF/views/business/BrandForm.html

@@ -279,6 +279,7 @@
 		},
 		{headerName: "브랜드영문명", field: "brandEnm", width: 150, cellClass: 'text-center'},
 		{headerName: "브랜드국문명", field: "brandKnm", width: 150, cellClass: 'text-center'},
+		{headerName: "브랜드그룹번호", field: "brandGroupNo", width: 150, cellClass: 'text-center'},
 		{headerName: "브랜드그룹명", field: "brandGroupNm", width: 150, cellClass: 'text-center'},
 		/*{
 			headerName: "공급업체", field: "supplyCompCd", width: 150, cellClass: 'text-center',
@@ -320,7 +321,7 @@
 	let columnDefs2 = [
 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
 		{headerName: "공급업체코드", field: "supplyCompCd", width: 150, cellClass: 'text-center'},
-		{headerName: "공급업체명", field: "supplyCompNm", width: 150}
+		{headerName: "공급업체명", field: "supplyCompNm", width: 300}
 	];
 	
 	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
@@ -342,7 +343,8 @@
 		//$("#detailForm input:radio[name=dispNmLang]:input[value=" + event.data.dispNmLang + "]").click();
 		//$("#detailForm input[name=rgbCd]").val(event.data.rgbCd);
 		$("#detailForm input[name=brandKnm]").val(event.data.brandKnm);
-		//$("#detailForm input[name=brandGrpNm]").val(event.data.brandGrpNm);
+		$("#detailForm input[name=brandGroupNm]").val(event.data.brandGroupNm);
+		$("#detailForm input[name=brandGroupNo]").val(event.data.brandGroupNo);
 		$("#detailForm input[name=erpBrandCd]").val(event.data.erpBrandCd);
 		$("#detailForm select[name=distributionGb]").val(event.data.distributionGb);
 		//$("#detailForm input[name=supplyCompCd]").val(event.data.supplyCompCd);
@@ -565,9 +567,12 @@
 	
 	//브랜드그룹 등록및 선택
 	$("#btnBrandGroup").on("click", function() {
-		var actionUrl = "/business/brand/group/popup/form?callbackFn=callBackBrandGroup";
-		cfnOpenModalPopup(actionUrl, 'popupBrandGroup'); 
+		cfnOpenBrandGroupListPopup("callBackBrandGroup", "S", "C");
 	});
+	var callBackBrandGroup = function(result) {
+		$("#detailForm input[name=brandGroupNm]").val(result[0].brandGroupNm);
+		$("#detailForm input[name=brandGroupNo]").val(result[0].brandGroupNo);
+	}
 	
 	// 브랜드담당MD 수정
 	$("#btnUpdateBrandMd").on("click", function() {
@@ -675,7 +680,7 @@
 		$("#detailForm select[name=brandGb]").removeAttr("disabled");
 		//$('#detailForm select[name=delvLocCd]').empty().append('<option value="">[선택]</option>');
 		//$('#detailForm select[name=delvFeeCd]').empty().append('<option value="">[선택]</option>');
-		
+		$("#detailForm input[name=brandGroupNo]").val("");
 		$("#detailForm input[type=checkbox]").removeClass("checked");
 		$("#detailForm input[type=checkbox]").parent("label").removeClass("checked");
 		
@@ -730,30 +735,9 @@
 		if (!gagajf.validation('#detailForm'))
 			return false;
 		
-		// RGB 체크
-		if (!gagajf.isNull($('#detailForm input[name=rgbCd]')) ){
-			
-			var rgbCd = $('#detailForm input[name=rgbCd]').val();
-			if (rgbCd.indexOf('#') >= 0){
-				
-				mcxDialog.alertC("'#은 입력하지 마세요.", {
-					sureBtnText: "확인",
-					sureBtnClick: function() {
-						$("#detailForm input[name=rgbCd]").focus();
-					}
-				});
-				return false;
-			}
-			
-			if (rgbCd.length != 6){
-				mcxDialog.alertC("6자리로 입력해 주세요", {
-					sureBtnText: "확인",
-					sureBtnClick: function() {
-						$("#detailForm input[name=rgbCd]").focus();
-					}
-				});
-				return false;
-			}
+		if (gagajf.isNull($('#detailForm input[name=brandGroupNo]').val())){
+			mcxDialog.alert("브랜드그룹을 선택해 주세요.");
+			return false;
 		}
 		
 		//공급업체

+ 159 - 47
src/main/webapp/WEB-INF/views/business/BrandGroupPopupForm.html

@@ -14,7 +14,7 @@
  * 1.0  2021.02.19   eskim       최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="800" id="popupBrandGroup">
+<div class="modalPopup" data-width="900" id="popupBrandGroup">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
@@ -24,40 +24,38 @@
 		<!-- //TITLE -->
 		
 		<!-- 검색 조건 -->
-		<div class="panelContent">
-			<form id="searchBrandGroupForm" name="searchBrandGroupForm" action="#" th:action="@{'/business/brand/group/list'}" onsubmit="$('#btnSearchBrandGroup').trigger('click'); return false;">
-				<table class="frmStyle" aria-describedby="검색조건">
-					<colgroup>
-						<col style="width:15%;"/>
-						<col style="width:35%;"/>
-						<col style="width:15%;"/>
-						<col/>
-					</colgroup>
-					<tbody>
-						<tr>
-							<th>브랜드그룹코드<i class="required" title="필수"></i></th>
-							<td>
-								<textarea class="textareaR3" name="searchBrandGroupNo" id="searchBrandGroupNo"></textarea>
-							</td>
-							<th>브랜드그룹명<i class="required" title="필수"></i></th>
-							<td>
-								<textarea class="textareaR3" name="searchBrandGroupNm" id="searchBrandGroupNm"></textarea>
-							</td>
-						</tr>
-					</tbody>
-				</table>
-				<ul class="panelBar">
-					<li class="center">
-						<button type="button" class="btn btn-base btn-lg" id="btnSearchBrandGroup">조회</button>
-					</li>
-				</ul>
-			</form>
-		</div>
+		<div class="panelContent" >
+		<form id="searchBrandGroupForm" name="searchBrandGroupForm" action="#" th:action="@{'/business/brand/group/list'}" onsubmit="$('#btnSearchBrandGroup').trigger('click'); return false;">
+			
+			<table class="frmStyle" aria-describedby="검색조건">
+				<colgroup>
+					<col style="width:15%;"/>
+					<col style="width:35%;"/>
+					<col style="width:15%;"/>
+					<col/>
+				</colgroup>
+				<tbody>
+					<tr>
+						<th>브랜드그룹코드<i class="required" title="필수"></i></th>
+						<td>
+							<textarea class="textareaR3" name="searchBrandGroupNo" id="searchBrandGroupNo"></textarea>
+						</td>
+						<th>브랜드그룹명<i class="required" title="필수"></i></th>
+						<td>
+							<textarea class="textareaR3" name="searchBrandGroupNm" id="searchBrandGroupNm"></textarea>
+						</td>
+					</tr>
+				</tbody>
+			</table>
+			<ul class="panelBar">
+				<li class="center">
+					<button type="button" class="btn btn-base btn-lg" id="btnSearchBrandGroup">조회</button>
+				</li>
+			</ul>
+		</form>
 		<!-- //검색 조건 -->
 		<!-- 리스트 영역 -->
-		<div class="panelContent">
-			<div id="gridBrandGroupList" style="width: 100%; height: 300px" class="ag-theme-balham"></div>
-		</div>
+		<div id="gridBrandGroupList" style="width: 100%; height: 250px" class="ag-theme-balham"></div>
 		<!-- 버튼 배치 영역 -->
 		<ul class="panelBar">
 			<li class="right">
@@ -65,8 +63,10 @@
 			</li>
 		</ul>
 		<!-- //리스트 영역 -->
+		<th:block th:if="${params.type == 'C'}">
 		<div class="panelContent">
-			<form id="brandGroupForm" name="detailForm" action="#" th:action="@{'/business/brand/group/save'}">
+			<form id="brandGroupForm" name="searchBrandGroupForm" action="#" th:action="@{'/business/brand/group/save'}">
+			<input type="hidden" name="mode" value="N"/>
 			<table class="frmStyle" aria-describedby="등록/수정 폼">
 				<colgroup>
 					<col style="width:10%;"/>
@@ -77,7 +77,7 @@
 				<tr>
 					<th>브랜드그룹코드</th>
 					<td>
-						<input type="text" class="w100" name="brandGroupCd" placeholder="자동생성" maxlength="5" readonly="readonly"/>
+						<input type="text" class="w100" name="brandGroupNo" placeholder="자동생성" maxlength="5" readonly="readonly"/>
 					</td>
 					<th>브랜드 그룹명노출언어<i class="required" title="필수"></i></th>
 						<td>
@@ -96,13 +96,13 @@
 					</td>
 				</tr>
 				<tr>
-					<th>RGB코드</th>
+					<th>RGB코드<i class="required" title="필수"></i></th>
 					<td  colspan="3">
 						<input type="text" class="w100 aR" name="rgbCd" maxlength="6" data-valid-name="REG코드" />
-						<span class="marL10 cRed"><i class="fa fa-info-circle" aria-hidden="true"></i> 브랜드메인 GBN 배경색으로 적용, 미 입력시 기본색상으로 설정됩니다.</span>
+						<!-- <span class="marL10 cRed"><i class="fa fa-info-circle" aria-hidden="true"></i> 브랜드메인 GBN 배경색으로 적용, 미 입력시 기본색상으로 설정됩니다.</span> -->
 					</td>
 				</tr>
-				<tr id="brandImgArea" class="on">
+				<tr style="height:100px">
 					<th>브랜드이미지</th>
 					<td colspan="3">
 						<div class="uFile w300">
@@ -113,29 +113,35 @@
 							<input type="hidden" name="newSysFileNm" id="newSysFileNm"/>
 						</div>
 						<input type="hidden" name="uploadDefaultUrl" id="uploadDefaultUrl" th:value="${@environment.getProperty('upload.default.view') + '/display/'}"/>
-						<div id="imgView" class="off">
+						<span id="imgView" class="off">
 							<img id="bannerPreViewUrl" src="" style="height:100px"/>
-						</div>
+						</span>
 					</td>
 				</tr>
-				
 			</table>
 			</form>
-		</div>
+		</div>	
 		<!-- 버튼 배치 영역 -->
 		<ul class="panelBar">
 			<li class="right">
+				<button type="button" class="btn btn-info btn-lg" id="btnBrandGroupNew">신규</button>
 				<button type="button" class="btn btn-success btn-lg" id="btnBrandGroupSave">저장</button>
 			</li>
 		</ul>
+		</th:block>
+		</div>
 	</div>
-
+</div>
 <script th:inline="javascript">
 /*<![CDATA[*/
 	let headerSelection = false;
 	let columnDefsMdList = [
 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: headerSelection, checkboxSelection: true, filter: false},
-		{headerName: "브랜드그룹번호", field: "brandGroupNo", width: 120, cellClass: 'text-center'},
+		{headerName: "브랜드그룹번호", field: "brandGroupNo", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
 		{headerName: "브랜드그룹국문명", field: "brandGroupKnm", width: 150, cellClass: 'text-center'},
 		{headerName: "브랜드그룹영문명", field: "brandGroupEnm", width: 150, cellClass: 'text-center'},
 		{headerName: "전시브랜드그룹명", field: "brandGroupNm", width: 150, cellClass: 'text-center'}
@@ -146,9 +152,37 @@
 
 	// Row double click
 	gridOptionsBrandGroupList.onRowDoubleClicked = function(event) {
-		$('#btnConfirmBrand').trigger('click');
+		$('#btnConfirmBrandGroup').trigger('click');
 	}
 
+	// Cell click
+	gridOptionsBrandGroupList.onCellClicked = function(event) {
+		if (event.colDef.field != 'brandGroupNo')
+			return;
+		
+		$("#brandGroupForm input[name=mode]").val("U");
+		$("#brandGroupForm input[name=brandGroupNo]").val(event.data.brandGroupNo);
+		$("#brandGroupForm input[name=brandGroupEnm]").val(event.data.brandGroupEnm);
+		$("#brandGroupForm input[name=brandGroupKnm]").val(event.data.brandGroupKnm);
+		$("#brandGroupForm input:radio[name=dispNmLang]:input[value=" + event.data.dispNmLang + "]").click();
+		$("#brandGroupForm input[name=rgbCd]").val(event.data.rgbCd);
+		//$("#brandGroupForm input:radio[name=useYn]:input[value=" + event.data.useYn + "]").click();
+		//$("#brandGroupForm input[name=dispOrd]").val(event.data.dispOrd);
+		
+		 var brandImg = event.data.logoFileNm;
+		if(!gagajf.isNull(brandImg)){
+			$("#logoFileNm").val(brandImg);
+			$("#bannerPreViewUrl").attr('src', $("#uploadDefaultUrl").val()+brandImg);
+			$("#imgView").removeClass("off").addClass("on");
+		}else {
+			$("#logoFileNm").val('');
+			$("#orgFileNm").val('');
+			$("#bannerPreViewUrl").attr('src', '');
+		}
+		$('#brandGroupForm input[name=file]').closest('div').find('label').text('파일선택'); 
+		
+	}
+	
 	// 조회
 	$('#btnSearchBrandGroup').on('click', function() {
 		
@@ -166,7 +200,7 @@
 		var selectedData = gagaAgGrid.selectedRowData(gridOptionsBrandGroupList);
 		
 		if (selectedData.length == 0) {
-			mcxDialog.alert('선택된 브랜드가 없습니다.');
+			mcxDialog.alert('선택된 그룹브랜드가 없습니다.');
 			return false;
 		}
 		
@@ -190,6 +224,84 @@
 		}
 	});
 	
+	//이미지 클릭시 미리보기
+	$("#bannerPreViewUrl").click(function(){
+		cfnOpenImagePreViewPopup('bannerPreimgView',$('#bannerPreViewUrl').attr('src'));
+	});
+	
+	//첨부파일 등록
+	$('#brandGroupForm input[name=file]').on('change', function() {
+		var file = this.files[0];
+		file.name = 'test';
+		if (typeof(file) == 'undefined'){
+			return;
+		}
+		
+		gagajf.ajaxFileUpload('/common/file/upload?subDir=/display'
+				, file
+				, function(result) {
+					$('#brandGroupForm input[name=newSysFileNm]').val(result.newFileName);
+					$('#brandGroupForm input[name=sysFileNm]').val(result.newFileName);
+					$("#bannerPreViewUrl").attr('src', $("#uploadDefaultUrl").val()+result.newFileName);
+					$("#imgView").removeClass("off").addClass("on");
+				}
+				, 'image'
+		);
+	});
+	
+	// 저장
+	$("#btnBrandGroupSave").on("click", function() {
+		// 입력 값 체크
+		if (!gagajf.validation('#brandGroupForm'))
+			return false;
+		
+		// RGB 체크
+		if (!gagajf.isNull($('#brandGroupForm input[name=rgbCd]')) ){
+			
+			var rgbCd = $('#brandGroupForm input[name=rgbCd]').val();
+			if (rgbCd.indexOf('#') >= 0){
+				
+				mcxDialog.alertC("'#은 입력하지 마세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#brandGroupForm input[name=rgbCd]").focus();
+					}
+				});
+				return false;
+			}
+			
+			if (rgbCd.length != 6){
+				mcxDialog.alertC("6자리로 입력해 주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#brandGroupForm input[name=rgbCd]").focus();
+					}
+				});
+				return false;
+			}
+		}
+		
+		
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				gagajf.ajaxFormSubmit($('#brandGroupForm').prop('action'), '#brandGroupForm', function() {
+				});
+			}
+		});
+	});
+	
+	
+	// 신규 버튼 클릭
+	$("#btnBrandGroupNew").on("click", function() {
+		$("#brandGroupForm")[0].reset();
+		$("#brandGroupForm input[name=mode]").val("N");
+		$("#orgFileNm").val('');
+		$("#bannerPreViewUrl").attr('src', '');
+		$("#logoFileNm").val('');
+	});
+	
 	$(document).ready(function() {
 		// Create a agGrid
 		gagaAgGrid.createGrid('gridBrandGroupList', gridOptionsBrandGroupList);
@@ -197,6 +309,6 @@
 /*]]>*/
 </script>
 
-</div>
+
 
 </html>

+ 1 - 1
src/main/webapp/WEB-INF/views/business/BrandPopupForm.html

@@ -88,7 +88,7 @@
 		{headerName: "브랜드번호", field: "brandCd", width: 120, cellClass: 'text-center'},
 		{headerName: "브랜드국문명", field: "brandEnm", width: 150, cellClass: 'text-center'},
 		{headerName: "브랜드영문명", field: "brandKnm", width: 150, cellClass: 'text-center'},
-		{headerName: "브랜드그룹명", field: "brandGrpNm", width: 150, cellClass: 'text-center'}
+		{headerName: "브랜드그룹명", field: "brandGroupNm", width: 150, cellClass: 'text-center'}
 	];
 
 	let gridOptionsBrandList = gagaAgGrid.getGridOptions(columnDefsMdList);

+ 455 - 0
src/main/webapp/WEB-INF/views/display/MainContentsPopupForm.html

@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : MainContentsPopupForm.html
+ * @desc    : 메인전시 컨텐츠 수정 팝업 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.2.23    bin2107     최초 작성
+ *******************************************************************************
+ -->
+	<div class="modalPopup" data-width="1200" >
+		<div class="panelStyle">
+			<div class="panelTitle">
+				<h2 id="popTitle" th:text="${contentsLoc}"></h2>
+				<button type="button" class="close" onclick="fnMainContentsPopupFormClose()"><i class="fa fa-times"></i></button>
+			</div>
+			<div class="panelContent">
+				<ul class="panelBar">
+					<li class="aL">
+						<span class="cBlue">* 상단으로 드래그&amp;드랍하여 순서 변경 가능합니다.</span>
+					</li>
+					<li class="aR">
+						<button type="button" class="btn btn btn-base btn-sm" id="btnPopAddRow">컨텐츠 추가</button>
+						<button type="button" class="btn btn btn-dark btn-sm" id="btnPopSave">임시저장</button>
+						<input type="hidden" name="uploadDefaultUrlPop" id="uploadDefaultUrlPop" th:value="${@environment.getProperty('upload.image.view') + '/display/contents/'}"/>
+					</li>
+				</ul>
+			</div>
+			<form style="height:600px; width:1100px; overflow:auto; margin-left:40px; border-style: solid; border-width: 1px;" id="popSortable">
+			</form>
+		</div>
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var cateNo = [[${cateNo}]];
+	var contentsLoc = [[${contentsLoc}]];
+	var contentsLocArr = gagajf.convertToArray([[${contentsLocList}]]);
+	var tdWidth = $("#sortable").find("td").width();
+	var tdDeleteWidth = parseInt(tdWidth/11, 10);
+	tdWidth = tdWidth - tdDeleteWidth;
+
+	// 컨텐츠 미리보기 리스트
+	var fnGetContentsPreviewList = function() {
+		$("#popSortable").html('');
+		var data = {cateNo : cateNo
+			,contentsLoc : contentsLoc
+		};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/display/contents/preview/list', jsonData, fnCreatePopLayout);
+	}
+
+	var fnCreatePopLayout = function(result) {
+		var html = '';
+		for(var i=0; i<result.length; i++){
+			var dispStdt = result[i].dispStdt.split(" ");
+			var dispEddt = result[i].dispEddt.split(" ");
+			html += '<table class="frmStyle" style="margin-bottom:30px">';
+			html += '<colgroup>';
+			html += '<col style="width:10%;"/>';
+			html += '<col style="width:55%;"/>';
+			html += '<col/>';
+			html += '</colgroup>';
+			html += '<thead><tr><th>전시일시</th><td><input name="dispStdt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="노출시작일" data-valid-type="calendar" value="'+dispStdt[0]+'"/>';
+			html += '<select name="stTimeHour" required="required" data-valid-name="노출기간 시작시간">';
+			html += fnCreateTimeOption(24, dispStdt[1].split(":")[0]);
+			html += '</select>';
+			html += '<select name="stTimeMin" required="required" data-valid-name="노출기간 시작시간">';
+			html += fnCreateTimeOption(60, dispStdt[1].split(":")[1]);
+			html += '</select>';
+			html += '<span> ~ </span>';
+			html += '<input name="dispEddt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="노출종료일" data-valid-type="calendar" value="'+dispEddt[0]+'"/>';
+			html += '<select name="edTimeHour" required="required" data-valid-name="노출기간 종료시간">';
+			html += fnCreateTimeOption(24, dispEddt[1].split(":")[0]);
+			html += '</select>';
+			html += '<select name="edTimeMin" required="required" data-valid-name="노출기간 종료시간">';
+			html += fnCreateTimeOption(60, dispEddt[1].split(":")[1]);
+			html += '</select>';
+			html += '<input name="dispOrd" type="text" class="w80"placeholder="전시순서" style="margin-left:5px; text-align:center"/>';
+			html += '</td>';
+			html += '<td class="aL"><button type="button" class="btn btn-base btn-lg" onclick="fnAddTitlePopRow(this);">타이틀추가</button>';
+			html += '<button type="button" class="btn btn-base btn-lg" onclick="fnAddImgPopRow(this);">이미지추가</button>';
+			html += '<button type="button" class="btn btn-base btn-lg" onclick="fnAddLinkPopRow(this);">링크추가</button>';
+			html += '<button type="button" class="btn btn-danger btn-lg" onclick="fnDeleteContentsRow(this);">삭제</button></td>';
+			html += '</tr></thead><tbody>';
+			for(var j=1; j<5; j++){
+				var strTitle = eval("result["+i+"].strTitle" + j);
+				var imgPath = eval("result["+i+"].imgPath" + j);
+				var strVar = eval("result["+i+"].strVar" + j);
+				if(strTitle!=null && strTitle!='null' && strTitle!='' ){
+					html += fnAddTitlePopRow(strTitle);
+				}
+				if(imgPath!=null && imgPath!='null' && imgPath!='' ){
+					html += fnAddImgPopRow(imgPath);
+				}
+				if(strVar!=null && strVar!='null' && strVar!='' ){
+					html += fnAddLinkPopRow(strVar);
+				}
+			}
+			html += '</tbody></table>';
+		}
+		$("#popSortable").append(html);
+		$("#popSortable").sortable();
+		$('.schDate').datepicker("destroy");
+		$('.schDate').datepicker({
+			changeMonth: true,
+			changeYear: true,
+			defaultDate: $('.schDate').val()
+		});
+	}
+	/**
+	 * 컨텐츠 추가 버튼
+	 */
+	$("#btnPopAddRow").on("click", function (){
+		var html = '<table class="frmStyle" style="margin-bottom:30px">';
+		html += '<colgroup>';
+		html += '<col style="width:10%;"/>';
+		html += '<col style="width:55%;"/>';
+		html += '<col/>';
+		html += '</colgroup>';
+		html += '<thead><tr><th>전시일시</th><td><input name="dispStdt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="노출시작일" data-valid-type="calendar"/>';
+		html += '<select name="stTimeHour" required="required" data-valid-name="노출기간 시작시간">';
+		html += fnCreateTimeOption(24);
+		html += '</select>';
+		html += '<select name="stTimeMin" required="required" data-valid-name="노출기간 시작시간">';
+		html += fnCreateTimeOption(60);
+		html += '</select>';
+		html += '<span> ~ </span>';
+		html += '<input name="dispEddt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="노출종료일" data-valid-type="calendar"/>';
+		html += '<select name="edTimeHour" required="required" data-valid-name="노출기간 종료시간">';
+		html += fnCreateTimeOption(24,23);
+		html += '</select>';
+		html += '<select name="edTimeMin" required="required" data-valid-name="노출기간 종료시간">';
+		html += fnCreateTimeOption(60,59);
+		html += '</select>';
+		html += '<input name="dispOrd" type="text" class="w80"placeholder="전시순서" style="margin-left:5px; text-align:center"/>';
+		html += '</td>';
+		html += '<td class="aL"><button type="button" class="btn btn-base btn-lg" onclick="fnAddTitlePopRow(this);">타이틀추가</button>';
+		html += '<button type="button" class="btn btn-base btn-lg" onclick="fnAddImgPopRow(this);">이미지추가</button>';
+		html += '<button type="button" class="btn btn-base btn-lg" onclick="fnAddLinkPopRow(this);">링크추가</button>';
+		html += '<button type="button" class="btn btn-danger btn-lg" onclick="fnDeleteContentsRow(this);">삭제</button></td>';
+		html += '</tr></thead><tbody></tbody></table>';
+		$("#popSortable").prepend(html);
+		$("#popSortable").sortable();
+		$('.schDate').datepicker("destroy");
+		$('.schDate').datepicker({
+			changeMonth: true,
+			changeYear: true,
+			defaultDate: $('.schDate').val()
+		});
+	});
+
+	/**
+	 * 임시저장
+	 */
+	var dataArr = [];
+	$("#btnPopSave").on("click", function (){
+		if(!gagajf.checkRequired("#popSortable")){
+			return;
+		}
+		var titleBool = true;
+		$("#popSortable").find('input[name=title]').each(function(idx, title) {
+			if ($(title).val()==''){
+				titleBool = false;
+				$(title).focus();
+				gagajf.alertMessage($(title), 'input');
+				return;
+			}
+		});
+		if(!titleBool){
+			return false;
+		}
+		dataArr = [];
+		$("#popSortable table").each(function(){
+			var newImgFileArr = [];
+			var imgPath1 = '';
+			var imgPath2 = '';
+			var imgPath3 = '';
+			var imgPath4 = '';
+			var strVar1 = '';
+			var strVar2 = '';
+			var strVar3 = '';
+			var strVar4 = '';
+			var strTitle1 = '';
+			var strTitle2 = '';
+			var strTitle3 = '';
+			var strTitle4 = '';
+			var i = 1;
+			$(this).find('input[name=imgPath]').each(function(){
+				eval("imgPath" + i + "='"+$(this).val()+"'");
+				i++;
+			});
+			$(this).find('input[name=newImgFile]').each(function(){
+				newImgFileArr.push($(this).val());
+			});
+			i = 1;
+			$(this).find('input[name=title]').each(function(){
+				var title = $(this).val().replace(/[\']/gi, "\\'");
+				eval("strTitle" + i + "='"+title+"'");
+				i++;
+			});
+			i = 1;
+			$(this).find('input[name=link]').each(function(){
+				_mall = [[${@environment.getProperty('domain.front')}]];
+				var val = $(this).val();
+				val = val.replace('https:'+_mall, '');
+				val = val.replace('http:'+_mall, '');
+				val = val.replace(_mall, '');
+				eval("strVar" + i + "='"+val+"'");
+				i++;
+			});
+
+			var dispStdt = $(this).find("[name=dispStdt]").val().replace(/[^0-9]/g, '') + "" +$(this).find("[name=stTimeHour]").val().replace('시', '') + "" +$(this).find("[name=stTimeMin]").val().replace('분', '') + "00";
+			var dispEddt = $(this).find("[name=dispEddt]").val().replace(/[^0-9]/g, '') + "" +$(this).find("[name=edTimeHour]").val().replace('시', '') + "" +$(this).find("[name=edTimeMin]").val().replace('분', '') + "59";
+
+			var dispOrd = $(this).find("[name=dispOrd]").val();
+
+			var data = {cateNo : cateNo
+				, contentsLoc : contentsLoc
+				, dispStdt : dispStdt
+				, dispEddt : dispEddt
+				, newImgFileArr : newImgFileArr
+				, imgPath1 : imgPath1
+				, imgPath2 : imgPath2
+				, imgPath3 : imgPath3
+				, imgPath4 : imgPath4
+				, strVar1 : strVar1
+				, strVar2 : strVar2
+				, strVar3 : strVar3
+				, strVar4 : strVar4
+				, strTitle1 : strTitle1
+				, strTitle2 : strTitle2
+				, strTitle3 : strTitle3
+				, strTitle4 : strTitle4
+				, useYn : 'Y'
+				, dispOrd : dispOrd
+			};
+
+			dataArr.push(data);
+		});
+		if(dataArr.length==0){
+			var data = {cateNo : cateNo
+				, contentsLoc : contentsLoc
+			};
+			dataArr.push(data);
+		}else{
+			var dataArrSort = [];
+			dataArr.forEach(function(item, index){
+				if(dataArr[index].dispOrd>0){
+					for(var i=1; i<dataArr.length; i++){
+						if(i>index){
+							if(dataArr[index].dispOrd==dataArr[i].dispOrd){
+								dataArr[i].dispOrd = Number(dataArr[i].dispOrd) + 1;
+							}
+						}
+					}
+				}
+			});
+			dataArr.forEach(function(item, index){
+				if(dataArr[index].dispOrd != ''){
+					dataArrSort[dataArr[index].dispOrd-1] = item;
+				}
+			});
+			dataArr.forEach(function(item, index){
+				if(dataArr[index].dispOrd == ''){
+					var empty = false;
+					for(var i=0; i<dataArrSort.length; i++){
+						if(typeof dataArrSort[i] == 'undefined'){
+							dataArrSort[i] = item;
+							empty = true;
+							break;
+						}
+					};
+					if(!empty){
+						dataArrSort.push(item);
+					}
+				}
+			});
+			dataArr = dataArrSort;
+		}
+
+		var jsonData = JSON.stringify(dataArr);
+		mcxDialog.confirm('컨텐츠를 저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				gagajf.ajaxJsonSubmit('/display/contents/preview/save', jsonData, fnGetContentsPreviewList);
+			}
+		});
+	});
+
+	/**
+	 * 파일첨부
+	 */
+	var fnPopFileUpload = function (obj, ind){
+		var file = obj.files[0];
+		file.name = 'test';
+		if (typeof(file) == 'undefined'){
+			return;
+		}
+		// 파일 업로드
+		gagajf.ajaxFileUpload('/common/file/upload?subDir=/display/contents'
+				, file
+				, function(result) {
+					$(obj).closest('div').find('input:hidden[name=newImgFile]').val(result.newFileName);
+					$("#bannerPreViewUrlPop_"+ind).attr('src', $("#uploadDefaultUrlPop").val()+result.newFileName);
+					$("#imgViewPop_"+ind).removeClass("off").addClass("on");
+				}
+				, 'image'
+		);
+	}
+
+	/**
+	 * 링크추가
+	 */
+	var fnAddLinkPopRow = function (param){
+		var val = typeof param=='object'?'#':param;
+		var html = '<tr name="linkPopRow">';
+		html += '<th>링크 (없으면 #)</th>';
+		html += '<td><input name="link" type="text" maxlength="200" required="required" data-valid-name="링크" value="'+val+'"/></td>';
+		html += '<td class="aL"><button type="button" class="btn icn" onclick="fnDeleteTrRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button></td>';
+		html += '</tr>';
+		if(typeof param == 'object'){
+			if($(param).closest("table").find("tbody").find("tr[name=linkPopRow]").length>3){
+				mcxDialog.alert("링크는 4개까지 등록 가능합니다");
+				return;
+			}
+			$(param).closest("table").find("tbody").append(html);
+		}else{
+			return html;
+		}
+	}
+
+	/**
+	 * 이미지 추가
+	 */
+	var imgIndex = 0;
+	var fnAddImgPopRow = function (param){
+		var src = '';
+		var imgPath = '';
+		if(typeof param!='object'){
+			src = $("#uploadDefaultUrlPop").val().replace('/contents/', '')+param;
+			imgPath = param;
+		}
+		var html = '<tr name="imgPopRow">';
+		html += '<th>이미지';
+		html += '</th>';
+		html += '<td><div class="uFile w300">';
+		html += '<input id="filePop_'+imgIndex+'" name="file" type="file" class="uFileInput w300" onchange="fnPopFileUpload(this, '+imgIndex+')"/>';
+		html += '<label for="filePop_'+imgIndex+'" class="uFileLabel">파일선택</label>';
+		html += '<input type="hidden" name="imgPath" value="'+imgPath+'"/>';
+		html += '<input type="hidden" name="newImgFile" value="" />';
+		html += '</div>';
+		html += '<div id="imgViewPop_'+imgIndex+'" class=';
+		if(src!=''){
+			html += '"on">';
+		}else{
+			html += '"off">';
+		}
+		html += '<img id="bannerPreViewUrlPop_'+imgIndex+'" src="'+src+'" style="height:100px; max-width:500px;"  onclick="cfnOpenImagePreViewPopup(\'bannerPreimgViewPop\',$(this).attr(\'src\'));"/>';
+		html += '</div></td>';
+		html += '<td class="aL"><button type="button" class="btn icn" onclick="fnDeleteTrRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button></td>';
+		html += '</tr>';
+		if(typeof param == 'object'){
+			if($(param).closest("table").find("tbody").find("tr[name=imgPopRow]").length>3){
+				mcxDialog.alert("이미지는 4개까지 등록 가능합니다");
+				return;
+			}
+			imgIndex++;
+			$(param).closest("table").find("tbody").append(html);
+		}else{
+			imgIndex++;
+			return html;
+		}
+	}
+
+	/**
+	 * 타이틀추가
+	 */
+	var fnAddTitlePopRow = function (param){
+		var val = typeof param=='object'?'':param;
+		var html = '<tr name="titlePopRow">';
+		html += '<th>타이틀</th>';
+		html += '<td><input name="title" type="text" maxlength="200" data-valid-name="타이틀" value="'+val+'"/></td>';
+		html += '<td class="aL"><button type="button" class="btn icn" onclick="fnDeleteTrRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button></td>';
+		html += '</tr>';
+		if(typeof param == 'object'){
+			if($(param).closest("table").find("tbody").find("tr[name=titlePopRow]").length>3){
+				mcxDialog.alert("타이틀은 4개까지 등록 가능합니다");
+				return;
+			}
+			$(param).closest("table").find("tbody").append(html);
+		}else{
+			return html;
+		}
+	}
+
+	// 컨텐츠 행삭제
+	var fnDeleteContentsRow = function (obj){
+		$(obj).closest("table").remove();
+	}
+
+	// 행삭제
+	var fnDeleteTrRow = function (obj){
+		$(obj).closest("tr").remove();
+	}
+
+	// 컨텐츠 추가 날짜 설정
+	var fnCreateTimeOption = function(val, sel) {
+		var html = '';
+		for(var i=0; i<val; i++){
+			var time = 0;
+			if(i<10){
+				time = '0'+i;
+			}else {
+				time = i;
+			}
+			var select = false;
+			if(sel==time){
+				select = true;
+			}
+			if(val==24){
+				time += '시';
+			}else if(val==60){
+				time += '분';
+			}
+			html += '<option value="'+time+'"';
+			if(select){
+				html += 'selected="selected"';
+			}
+			html += '>'+time+'</option>';
+		}
+		return html;
+	}
+
+	// 창닫기
+	var fnMainContentsPopupFormClose = function (){
+		uifnPopupClose('popupMainContents');
+	}
+
+	$(document).ready(function() {
+		$("#popTitle").text("["+contentsLoc+"] "+gagaAgGrid.lookupValue(contentsLocArr, contentsLoc));
+		$("#popSortable").disableSelection();
+		fnGetContentsPreviewList();
+	});
+/*]]>*/
+</script>
+
+</html>

+ 632 - 0
src/main/webapp/WEB-INF/views/display/MainListForm.html

@@ -0,0 +1,632 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : MainListForm.html
+ * @desc    : 메인전시관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.2.22    bin2107     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+		
+		<!-- 검색조건 영역 START -->
+		<div class="panelStyle">
+			<form id="searchForm" name="searchForm" action="#">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width: 25%;"/>
+						<col style="width: 25%;"/>
+						<col style="width: 25%;"/>
+						<col style="width: 25%;"/>
+					</colgroup>
+					<tr>
+						<th>대분류</th>
+						<td>
+							<select name="cate1No" id="cate1No" onchange="fnGetMainDisplayList('cate1');">
+								<option value="">[선택]</option>
+								<option th:if="${mainCategoryList}" th:each="oneData, status:${mainCategoryList}" th:value="${oneData.cateNo+','+oneData.leafYn}" th:text="${'['+oneData.cateNo+']'+oneData.cateNm}"></option>
+							</select>
+						</td>
+						<th>중분류</th>
+						<td>
+							<select name="cate2No" id="cate2No" onchange="fnGetMainDisplayList('cate2');">
+								<option value="">[선택]</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+			</form>
+		</div>
+		<!-- 검색조건 영역 END -->
+
+		<!-- 리스트 영역 START -->
+		<div class="panelStyle">
+			<div class="boxTitle"></div>
+			<form id="mainDisplayForm">
+				<ul class="boxContent">
+					<li class="boxContentTop">
+						<div class="panelContent" style="overflow: hidden;">
+							<th:block th:if="${sessionInfo.roleCd == 'G001_0000'}">
+								<ul class="panelBar">
+									<li>
+										<span class="btnLeft" style="">
+											<span style="padding:5.5px 15px; background:#d8eafc !important; border-top:1px solid #ddd; border-bottom:0.5px solid #dae0fd; font-weight: bold;">추가 열</span>
+											<select id="addColCnt" required="required">
+												<th:block th:each="num: ${#numbers.sequence(1,10)}">
+												<option th:value="${num}"  th:text="${num}"></option>
+												</th:block>
+											</select>
+											<button type="button" class="btn btn-base btn-lg" id="btnAddRow">행 추가</button>
+										</span>
+									</li>
+									<li class="right">
+										<span class="btnRight" style="">
+											<span><button type="button" class="btn btn-success btn-lg" id="btnSave">레이아웃 저장</button></span>
+										</span>
+									</li>
+								</ul>
+							</th:block>
+							<ul class="panelBar">
+								<th:block th:if="${sessionInfo.roleCd == 'G001_0000'}">
+									<li>
+										<span class="cBlue">* 마우스 드래그&드랍으로 레이아웃 순서 변경 가능하며 X 버튼으로 삭제 가능합니다.</span>
+									</li>
+								</th:block>
+								<li id="viewUl" class="off aC">
+									<span>
+										<input name="viewDate" id="viewDate" type="text" class="w80 schDate" maxlength="10" data-valid-name="미리보기일자" data-valid-type="calendar"/>
+										<select id="viewTimeHour" name="viewTimeHour" data-valid-name="미리보기 시간">
+											<th:block th:each="num, index  : ${#numbers.sequence(0,24)}">
+											<option  th:value="${#numbers.formatInteger(num,2)}" th:text="|${#numbers.formatInteger(num,2)}시|" >시간</option>
+											</th:block>
+										</select>
+										<select id="viewTimeMin" name="viewTimeMin" 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 name="viewTime" id="viewTime" type="hidden" data-valid-name="미리보기 시간" />
+										<input type="hidden" name="uploadDefaultUrl" id="uploadDefaultUrl" th:value="${@environment.getProperty('upload.image.view') + '/display/main/'}"/>
+									</span>
+									<span>
+										<button type="button" class="btn btn-info btn-lg" id="btnView">미리보기</button>
+										<button type="button" class="btn btn-default btn-lg" id="btnAllUpd">일괄적용</button>
+									</span>
+								</li>
+								<th:block th:if="${sessionInfo.roleCd == 'G001_0000'}">
+									<li class="right">
+										<span class="cRed">* 레이아웃 저장 버튼 클릭 시 수정 및 삭제 된 레이아웃이 즉시 적용 됩니다.</span>
+									</li>
+								</th:block>
+							</ul>
+						</div>
+						<table class="frmStyle" id="mainSortable">
+							<tbody>
+								<tr style="height:150px;">
+									<td colspan="8" style="text-align: center">
+										<span>카테고리를 선택해 주세요.</span>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+				</ul>
+			</form>
+		</div>
+		<!-- 리스트 영역 END -->
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var roleCd = [[${sessionInfo.roleCd}]];
+	var tdWidth = 800;
+	//var mainCategoryList = [[${mainCategoryList}]];
+	var brandCdList = [[${brandCdList}]];
+	var contentsLocArr = gagajf.convertToArray([[${contentsLocList}]]);
+
+	/**
+	* 대분류/중분류 선택시
+	*/
+	var fnGetMainDisplayList = function (cate){
+		if(cate=='cate1'){
+			$("#searchForm select[name=cate2No]").html('<option value="">[선택]</option>');
+		}
+		$("#viewUl").addClass("off");
+		var val = $("#searchForm select[name=cate1No]").val();
+		if(gagajf.isNull(val)||val.split(',')[0]=='0'){
+			var html = '<tbody><tr style="height:170px;"><td colspan="8" style="text-align:center;"><span>카테고리를 선택해 주세요</span></td></tr></tbody>';
+			$("#mainSortable").html(html);
+		}else{
+			$("#mainSortable").html('');
+			if(val.split(',')[1]=='N' && gagajf.isNull($("#searchForm select[name=cate2No]").val())){
+				$("#searchForm select[name=cate2No]").html('<option value="">[선택]</option>');
+				var data = {
+					cateNo : val.split(',')[0]
+					,clsLvl : 2
+				};
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/display/main/category/list', jsonData, fnCate2NoCallBack);
+			}else{
+				$("#viewUl").removeClass("off");
+				var cateNo = val.split(',')[0];
+				if(!gagajf.isNull($("#searchForm select[name=cate2No]").val())){
+					cateNo = $("#searchForm select[name=cate2No]").val().split(',')[0];
+				}
+				var data = {
+					cateNo : cateNo
+				};
+				var jsonData = JSON.stringify(data);
+				// 레이아웃 조회 로직
+				gagajf.ajaxJsonSubmit('/display/main/layout/list', jsonData, fnLayoutCallBack);
+			}
+		}
+	}
+
+	/**
+	 * 레이아웃 조회
+	 */
+	var fnLayoutCallBack = function (result){
+		var html = '';
+		var imgSrc = '';
+		var orgFileNm = '';
+		var sysFileNm = '';
+		var onOff = 'off';
+		var cate1No = $("#searchForm select[name=cate1No]").val().split(',')[0];
+
+		for(var i=0; i<result.length; i++){
+			var colCnt = result[i].colCnt;
+			var colNo = result[i].colNo
+			var colspan = parseInt(5/Number(colCnt), 10);
+			var colspanAdd = 5 - (colspan * colCnt);
+			var tdSize = 10;
+
+			if(colCnt>5){
+				tdSize = parseInt((colCnt/2), 10)+1;
+				colspan = parseInt(5/(colCnt/2), 10);
+				colspanAdd = 5 - (colspan * parseInt((colCnt/2), 10));
+			}
+
+			if(colCnt==1 || colNo==1){
+				html += '<tbody><tr style="height:170px;">';
+			}else if(colNo==tdSize){
+				html += '<tr style="height:170px;">';
+			}
+
+			if(colNo>=tdSize){
+				colspanAdd = (5 - (colspan * Math.round(colCnt/2))) + parseInt(colCnt/2, 10);
+			}
+			html += '<td colspan="';
+			colspanAdd -= (colNo-1);
+			if(colspanAdd>0){
+				html += colspan + 1;
+			}else{
+				html += colspan;
+			}
+
+			var maxWidth = parseInt(tdWidth/Number(colCnt), 10);
+			if(colCnt>5){
+				maxWidth = parseInt(tdWidth/(Number(colCnt)/tdSize), 10);
+			}
+			html += '" style="text-align:center; max-width:'+maxWidth+'px;">';
+			html += '<div><span style="font-weight:bold">'+result[i].contentsLoc+'</span></div><div><span>[ '+gagaAgGrid.lookupValue(contentsLocArr, result[i].contentsLoc)+' ]</span></div>';
+			if(result[i].contentsYn=='C'){
+				html += '<button type="button" class="btn btn-success btn-lg" onclick="fnChangeContents(this);">수정</button>';
+				html += '<button type="button" class="btn btn-default btn-lg" onclick="fnUpdateContents(\''+result[i].contentsLoc+'\');">적용</button>';
+			}else if(result[i].contentsYn=='G' || result[i].contentsYn=='A'){
+				if(result[i].contentsYn=='A'){
+					html += '<button type="button" class="btn btn-success btn-lg" onclick="fnChangeContents(this);">수정</button>';
+					html += '<button type="button" class="btn btn-default btn-lg" onclick="fnUpdateContents(\''+result[i].contentsLoc+'\');">적용</button>';
+					html += '<br/>';
+				}
+				html += '<button type="button" class="btn btn-success btn-lg" onclick="fnSearchCategory(\''+result[i].contentsLoc+'\');">상품관리</button>';
+			}
+			html += '<input type="hidden" name="contentsLoc" value="'+result[i].contentsLoc+'"/>';
+			html += '<input type="hidden" name="colCnt" value="'+result[i].colCnt+'"/>';
+			html += '<input type="hidden" name="colNo" value="'+result[i].colNo+'"/>';
+			html += '<input type="hidden" name="contentsYn" value="'+result[i].contentsYn+'"/>';
+			html += '</td>';
+			if(colNo=='1'){
+				if(result[i].orgFileNm!=null && result[i].orgFileNm!='null' && result[i].orgFileNm!="" ){
+					orgFileNm = result[i].orgFileNm;
+					sysFileNm = result[i].sysFileNm;
+					imgSrc = $("#uploadDefaultUrl").val()+orgFileNm;
+					onOff = 'on';
+				}else{
+					orgFileNm = '';
+					sysFileNm = '';
+					imgSrc = '';
+					onOff = 'off';
+				}
+			}
+			if(tdSize==10){
+				if(colCnt==1 || colNo==colCnt){
+					html += '<td name="imgTd" style="width:300px;">';
+					html += '<div id="imgView_'+i+'" class="'+onOff+'">';
+					html += '<img id="bannerPreViewUrl_'+i+'" src="'+imgSrc+'" style="width:300px; height:120px"  onclick="cfnOpenImagePreViewPopup(\'bannerPreimgViewPop\',\''+imgSrc+'\');"/>';
+					html += '</div>';
+					html += '<div class="uFile w300">';
+					html += '<input id="file_'+i+'" name="file" type="file" class="uFileInput w300" onchange="fnFileUpload(this, '+i+');"/>';
+					html += '<label for="file_'+i+'" class="uFileLabel">파일선택</label>';
+					html += '<input type="hidden" name="orgFileNm" value="'+orgFileNm+'"/>';
+					html += '<input type="hidden" name="sysFileNm" value="'+sysFileNm+'"/>';
+					html += '<input type="hidden" name="newSysFileNm" value=""/>';
+					html += '</div>';
+					html += '</td>';
+					html += '<td name="deleteTd" style="max-width:50px;">';
+					if(roleCd=='G001_0000'){
+						html += '<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>';
+					}
+					html += '</td></tr></tbody>';
+				}
+			}else{
+				if(colNo==(tdSize-1)){
+					html += '<td name="imgTd" rowspan="2" style="width:300px;">';
+					html += '<div id="imgView_'+i+'" class="'+onOff+'">';
+					html += '<img id="bannerPreViewUrl_'+i+'" src="'+imgSrc+'" style="width:300px; height:120px"  onclick="cfnOpenImagePreViewPopup(\'bannerPreimgViewPop\',\''+imgSrc+'\');"/>';
+					html += '</div>';
+					html += '<div class="uFile w300">';
+					html += '<input id="file_'+i+'" name="file" type="file" class="uFileInput w300" onchange="fnFileUpload(this, '+i+');"/>';
+					html += '<label for="file_'+i+'" class="uFileLabel">파일선택</label>';
+					html += '<input type="hidden" name="orgFileNm" value="'+orgFileNm+'"/>';
+					html += '<input type="hidden" name="sysFileNm" value="'+sysFileNm+'"/>';
+					html += '<input type="hidden" name="newSysFileNm" value=""/>';
+					html += '</div>';
+					html += '</td>';
+					html += '<td name="deleteTd" rowspan="2" style="max-width:50px;">';
+					if(roleCd=='G001_0000'){
+						html += '<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>';
+					}
+					html += '</td></tr>';
+				}else if(colNo==colCnt){
+					html += '</tr></tbody>';
+				}
+			}
+		}
+
+		$("#mainSortable").html(html);
+		if(roleCd=='G001_0000'){
+			$("#mainSortable").sortable();
+		}
+	}
+
+	/**
+	 * 중분류 리스트
+	 */
+	var fnCate2NoCallBack = function (result){
+		var html = '<option value="">[선택]</option>';
+		for (var i=0; i<result.length; i++){
+			html += '<option value="'+result[i].cateNo+','+result[i].leafYn+'">['+result[i].cateNo+']'+result[i].cateNm+'</option>';
+		}
+		$("#searchForm select[name=cate2No]").html(html);
+		// grid 높이 조절
+		//uifnFitGrid();
+	}
+
+	/**
+	* 레이아웃 행추가 버튼
+	*/
+	$("#btnAddRow").on("click", function (){
+		console.log('[행추가 start]');
+		var val = $("#searchForm select[name=cate1No]").val();
+		var cate1No = val.split(',')[0];
+		//console.log('val>>'+val);
+		//console.log('cate1No>>'+cate1No);
+		//console.log('leafYn>>>'+val.split(',')[1]);
+
+		if(gagajf.isNull(val) || cate1No=='0' || val.split(',')[1]=='N' && gagajf.isNull($("#searchForm select[name=cate2No]").val())){
+			mcxDialog.alert('카테고리를 선택해 주세요.');
+			return;
+		}
+
+		var html = '';
+		var colCnt = $("#addColCnt").val();
+		var colspan = parseInt(5/Number(colCnt), 10);
+		var tdSize = 10;
+		if(colCnt>5){
+			tdSize = parseInt(colCnt/2, 10) + 1;
+			colspan = parseInt(5/parseInt(colCnt/2, 10), 10);
+		}
+		var contentsLocHtml = '<option value="">[선택]</option>';
+		var contentsLocList = [[${contentsLocList}]];
+		var clocPrefix ='';
+		var mainCategoryList = [[${mainCategoryList}]];
+
+		$.each(mainCategoryList, function(idx, data) {
+			if(cate1No==data.cateNo){
+				clocPrefix = data.clocPrefix;
+			}
+		});
+
+		if(cate1No=='100'){
+			contentsLocHtml += '<option value="SGNB001">[SGNB001] STYLE24MALL > GNB > TOP배너</option>';
+			contentsLocHtml += '<option value="STAB001">[STAB001] STYLE24MALL > GNB > 카테고리탭</option>';
+			contentsLocHtml += '<option value="SKEY001">[SKEY001] STYLE24MALL > GNB > 검색어</option>';
+		}
+		if(cate1No=='101'){
+			contentsLocHtml += '<option value="SGNB002">[SGNB001] STYLE24MALL > GNB > TOP배너(모바일)</option>';
+			contentsLocHtml += '<option value="STAB001">[STAB001] STYLE24MALL > GNB > 카테고리탭</option>';
+			contentsLocHtml += '<option value="SKEY001">[SKEY001] STYLE24MALL > GNB > 검색어</option>';
+		}
+		for(var i=0; i<contentsLocList.length; i++){
+			var contentsLocCd = contentsLocList[i].cd;
+			contentsLocCd = contentsLocCd.replace(/[0-9]/g, "");
+			if(contentsLocCd==clocPrefix){
+				contentsLocHtml += '<option value="'+contentsLocList[i].cd+'">['+contentsLocList[i].cd+'] '+contentsLocList[i].cdNm+'</option>';
+			}
+		}
+
+		for(var j=0; j<colCnt; j++){
+			var colNo = (j+1);
+			var colspanAdd = 5 - (colspan * colCnt);
+			var maxWidth = parseInt(tdWidth/Number(colCnt), 10);
+			if(colCnt>5){
+				maxWidth = parseInt(tdWidth/(Number(colCnt)/tdSize), 10);
+				colspanAdd = 5 - (colspan * parseInt(colCnt/2, 10));
+			}
+			if(colCnt==1 || colNo==1){
+				html += '<tbody><tr style="height:170px;">';
+			}else if(colNo==tdSize){
+				html += '<tr style="height:170px;">';
+			}
+			if(colNo>=tdSize){
+				colspanAdd = (5 - (colspan * Math.round(colCnt/2))) + parseInt(colCnt/2, 10);
+			}
+			html += '<td colspan="';
+			colspanAdd -= j;
+			if(colspanAdd>0){
+				html += colspan + 1;
+			}else{
+				html += colspan;
+			}
+
+			html += '" style="text-align:center; max-width:'+maxWidth+'px;">';
+			html += '<div>';
+			html += '<select name="contentsLocEdit" required="required" style="max-width:80px;" data-valid-name="컨텐츠 위치">'+contentsLocHtml+'</select>';
+			html += '</div>';
+			html += '<select name="contentsYn" required="required" style="max-width:80px;" data-valid-name="컨텐츠 타입"><option value="C">[C] 컨텐츠</option><option value="G">[G] 상품</option><option value="A">[A] 컨텐츠 + 상품</option></select>';
+			html += '<input type="hidden" name="contentsLoc" value=""/>';
+			html += '<input type="hidden" name="colCnt" value="'+colCnt+'"/>';
+			html += '<input type="hidden" name="colNo" value="'+colNo+'"/>';
+			html += '<input type="hidden" name="contentsYn" value=""/>';
+			html += '</td>';
+			var i = $("#mainSortable tbody").length;
+			if(tdSize==10){
+				if(colCnt==1 || colNo==colCnt){
+					html += '<td name="imgTd" style="width:300px;">';
+					html += '<div class="uFile w300">';
+					html += '<input id="file_'+i+'" name="file" type="file" class="uFileInput w300" onchange="fnFileUpload(this, '+i+');"/>';
+					html += '<label for="file_'+i+'" class="uFileLabel">파일선택</label>';
+					html += '<input type="hidden" name="orgFileNm"/>';
+					html += '<input type="hidden" name="sysFileNm"/>';
+					html += '<input type="hidden" name="newSysFileNm"/>';
+					html += '</div>';
+					html += '<div id="imgView_'+i+'" class="off">';
+					html += '<img id="bannerPreViewUrl_'+i+'" src="" style="width:300px; height:120px"/>';
+					html += '</div>';
+					html += '</td>';
+					html += '<td name="deleteTd" style="max-width:50px;">';
+					if(roleCd=='G001_0000'){
+						html += '<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>';
+					}
+					html += '</td></tr><tbody>';
+				}
+			}else{
+				if(colNo==(tdSize-1)){
+					html += '<td name="imgTd" rowspan="2" style="width:300px;">';
+					html += '<div class="uFile w300">';
+					html += '<input id="file_'+i+'" name="file" type="file" class="uFileInput w300" onchange="fnFileUpload(this, '+i+');"/>';
+					html += '<label for="file_'+i+'" class="uFileLabel">파일선택</label>';
+					html += '<input type="hidden" name="orgFileNm"/>';
+					html += '<input type="hidden" name="sysFileNm"/>';
+					html += '<input type="hidden" name="newSysFileNm" value=""/>';
+					html += '</div>';
+					html += '<div id="imgView_'+i+'" class="off">';
+					html += '<img id="bannerPreViewUrl_'+i+'" src="" style="width:300px; height:120px"/>';
+					html += '</div>';
+					html += '</td>';
+					html += '<td name="deleteTd" rowspan="2" style="max-width:50px;">';
+					if(roleCd=='G001_0000'){
+						html += '<button type="button" class="btn icn" onclick="fnDeleteRow(this);"><i class="fa fa-times" aria-hidden="true"></i></button>';
+					}
+					html += '</td></tr>';
+				}else if(colNo==colCnt){
+					html += '</tr></tbody>';
+				}
+			}
+		}
+		$("#mainSortable").prepend(html);
+		if(roleCd=='G001_0000'){
+			$("#mainSortable").sortable();
+		}
+		//uifnFitGrid();
+	});
+
+	/**
+	* 레이아웃 행 삭제
+	*/
+	var fnDeleteRow = function (obj){
+		$(obj).closest("tbody").remove();
+	}
+
+	/**
+	 * 레이아웃 저장
+	 */
+	$("#btnSave").on("click",function(){
+		var val = $("#searchForm select[name=cate1No]").val();
+		if(gagajf.isNull(val) || (val.split(',')[1]=='N' && gagajf.isNull($("#searchForm select[name=cate2No]").val())) ){
+			mcxDialog.alert('카테고리를 선택해 주세요.');
+			return;
+		}
+		if(!gagajf.validation("#mainDisplayForm")){
+			return;
+		}
+		var cateNo = '';
+		var cateNm = '';
+		if(val.split(',')[1]=='Y'){
+			cateNo = val.split(',')[0];
+		}else{
+			cateNo = $("#searchForm select[name=cate2No]").val().split(',')[0];
+		}
+		var dataArr = [];
+		var contentLocArr = [];
+		var contentLocCheck = true;
+		$("#mainSortable tbody").each(function(ind){
+			var orgFileNm = $(this).find('input:hidden[name="orgFileNm"]').val();
+			var sysFileNm = $(this).find('input:hidden[name="sysFileNm"]').val();
+			var newSysFileNm = $(this).find('input:hidden[name="newSysFileNm"]').val();
+			$(this).find('td').each(function(index){
+				if($(this).attr("name")!="imgTd" && $(this).attr("name")!="deleteTd"){
+					if($(this).find('input:hidden[name="contentsLoc"]').val()==''){
+						if(contentLocArr.indexOf($(this).find('select[name="contentsLocEdit"]').val())>-1){
+							$(this).find('select[name="contentsLocEdit"]').focus();
+							contentLocCheck = false;
+							return;
+						}else{
+							$(this).find('input:hidden[name="contentsLoc"]').val($(this).find('select[name="contentsLocEdit"]').val());
+							contentLocArr.push($(this).find('input:hidden[name="contentsLoc"]').val());
+						}
+					}else{
+						if(contentLocArr.indexOf($(this).find('input:hidden[name="contentsLoc"]').val())>-1){
+							contentLocCheck = false;
+							return;
+						}else{
+							contentLocArr.push($(this).find('input:hidden[name="contentsLoc"]').val());
+						}
+					}
+					if($(this).find('input:hidden[name="contentsYn"]').val()==''){
+						$(this).find('input:hidden[name="contentsYn"]').val($(this).find('select[name="contentsYn"]').val());
+					}
+					var data = {cateNo : cateNo
+						, contentsLoc : $(this).find('input:hidden[name="contentsLoc"]').val()
+						, colCnt : $(this).find('input:hidden[name="colCnt"]').val()
+						, colNo : $(this).find('input:hidden[name="colNo"]').val()
+						, contentsYn : $(this).find('input:hidden[name="contentsYn"]').val()
+						, dispOrd : (ind+1)
+						, orgFileNm : orgFileNm
+						, sysFileNm : sysFileNm
+						, newSysFileNm : newSysFileNm
+					};
+					dataArr.push(data);
+				}
+			});
+			if(!contentLocCheck){
+				return;
+			}
+		});
+		if(!contentLocCheck){
+			mcxDialog.alert('위치코드가 중복 되었습니다.');
+			return;
+		}
+		if(dataArr.length==0){
+			mcxDialog.alert("저장할 데이터가 없습니다.");
+			return;
+		}
+
+		var jsonData = JSON.stringify(dataArr);
+		mcxDialog.confirm('레이아웃을 저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				gagajf.ajaxJsonSubmit('/display/main/layout/save', jsonData, fnGetMainDisplayList);
+			}
+		});
+	});
+
+	/**
+	 * 레이아웃 수정 버튼 > 팝업
+	 */
+	var fnChangeContents = function (obj){
+		var val = $("#searchForm select[name=cate1No]").val();
+		var cateNo = '';
+		if(val.split(',')[1]=='Y'){
+			cateNo = val.split(',')[0];
+		}else{
+			cateNo = $("#searchForm select[name=cate2No]").val().split(',')[0];
+		}
+		var contentsLoc = $(obj).closest("td").find('input:hidden[name="contentsLoc"]').val();
+		console.log('fnChangeContents contentsLoc>>> '+contentsLoc);
+		cfnOpenMainContentsPopup(cateNo, contentsLoc);
+	}
+
+	/**
+	 * 개별 적용 버튼
+	 */
+	var fnUpdateContents = function (contentsLoc){
+		mcxDialog.confirm('컨텐츠를 적용 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var val = $("#searchForm select[name=cate1No]").val();
+				var cateNo = '';
+				if(val.split(',')[1]=='Y'){
+					cateNo = val.split(',')[0];
+				}else{
+					cateNo = $("#searchForm select[name=cate2No]").val().split(',')[0];
+				}
+				var data = { contentsLocArr : [contentsLoc]
+					,cateNo : cateNo
+				};
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/display/contents/save', jsonData);
+			}
+		});
+	}
+
+	/**
+	 * 일괄적용 버튼
+	 */
+	$("#btnAllUpd").on("click", function(){
+		mcxDialog.confirm('컨텐츠를 일괄적용 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var val = $("#searchForm select[name=cate1No]").val();
+				var cateNo = '';
+				if(val.split(',')[1]=='Y'){
+					cateNo = val.split(',')[0];
+				}else{
+					cateNo = $("#searchForm select[name=cate2No]").val().split(',')[0];
+				}
+				var contentsLocArr = [];
+				$("input:hidden[name=contentsLoc]").each(function(){
+					contentsLocArr.push($(this).val());
+				});
+
+				var data = { contentsLocArr : contentsLocArr
+					,cateNo : cateNo
+				};
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/display/contents/save', jsonData);
+			}
+		});
+	});
+
+	$(document).ready(function() {
+		var today = new Date(_today);
+		var yesterDay = new Date(today.getFullYear(), today.getMonth(), today.getDate()+1).format("YYYY-MM-DD");
+		$("#viewDate").val(yesterDay);
+		$("#viewTimeHour").val("09");
+		// Create a agGrid
+		$("#mainSortable").disableSelection();
+		//uifnFitGrid();
+	});
+/*]]>*/
+</script>
+
+</html>

+ 8 - 8
src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html

@@ -423,19 +423,19 @@
 											</colgroup>
 											<tr>
 												<th>타이틀</th>
-												<td><input type="text" class= "w100p" id="goodsTitlesDesc" name="goodsTitlesDesc" maxlength="100" />
+												<td class="padT10"><input type="text" class= "w100p" id="goodsTitlesDesc" name="goodsTitlesDesc" maxlength="100" />
 												</td>
 											</tr>
 											<tr>
 												<th>내용</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR3 summernote" name="goodsContentsDesc" id="goodsContentsDesc"></textarea>
 													</div>
 												</td>
 											</tr>
 											<tr>
 												<th>상품 특징</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR3 summernote" name="goodsCharacterDesc" id="goodsCharacterDesc"></textarea>
 													</div>
 												</td>
@@ -453,35 +453,35 @@
 											</colgroup>
 											<tr>
 												<th>상품상세</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR4 summernote" name="goodsDesc" id="goodsDesc"></textarea>
 													</div>
 												</td>
 											</tr>
 											<tr>
 												<th>상위(PC)</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR4 summernote" name="goodsPcTopDesc" id="goodsPcTopDesc"></textarea>
 													</div>
 												</td>
 											</tr>
 											<tr>
 												<th>상위(MOBILE)</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR4 summernote" name="goodsMobileTopDesc" id="goodsMobileTopDesc"></textarea>
 													</div>
 												</td>
 											</tr>
 											<tr>
 												<th>하위(PC)</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR4 summernote" name="goodsPcDownDesc" id="goodsPcDownDesc"></textarea>
 													</div>
 												</td>
 											</tr>
 											<tr>
 												<th>하위(MOBILE)</th>
-												<td><div class="tabJrContArea">
+												<td class="padT10"><div class="tabJrContArea">
 													<textarea class="textareaR4 summernote" name="goodsMobileDownDesc" id="goodsMobileDownDesc"></textarea>
 													</div>
 												</td>

+ 4 - 3
src/main/webapp/WEB-INF/views/goods/GoodsNaverPriceForm.html

@@ -25,6 +25,7 @@
 		</div>
 		<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/naver/price/list'}">
 		<input type="hidden" id="searchGb" name="searchGb" />
+		<input type="hidden" id="search" name="search" value="searchGoodsCd"/>
  		<!-- 패널 영역1 -->
 		<div class="panelStyle" >
 			<!-- TITLE -->
@@ -56,9 +57,9 @@
 						</td>
 						<th rowspan="3">키워드</th>
 						<td rowspan="3">
-							<select name="search" id="search">
+							<!-- <select name="search" id="search">
 								<option value="searchGoodsCd">상품코드</option>
-							</select>
+							</select> -->
 							<textarea class="textareaR3 w150" name="condition" id="condition"></textarea>
 						</td>
 					</tr>
@@ -251,7 +252,7 @@
 		for (i = 0; i < form.elements.length; i++ ) {
 			var el = form.elements[i];
 
-			if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+			if ($(el).prop("type") == "text"  || $(el).prop("type") == "textarea"  || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
 				if (!(el.value == null || el.value == "")) {
 					cnt++;
 				}

+ 1 - 1
src/main/webapp/WEB-INF/views/marketing/PlanCornerCopyForm.html

@@ -207,7 +207,7 @@
 						fnCornerSearch();
 					} else {
 						fnSearch();						
-						uifnPopupClose('popupEventWebDetail');
+						uifnPopupClose('popupEventDetail');
 					}
 					uifnPopupClose('popupCornerCopy')
 				});

+ 3 - 6
src/main/webapp/WEB-INF/views/marketing/PlanCornerListForm.html

@@ -206,12 +206,9 @@
 			mcxDialog.alert('추가 된 코너를 저장 후 코너를 추가하세요.');
 			return;
 		} else {
-			var actionUrl = '/marketing/planning/corner/plandtlsq?planSq=' + planSq;
-			$.get(actionUrl
-						, function(planDtlSq) {
-								var data = { planDtlSq: planDtlSq, planSq:planSq, cornerNm:'',cornerDispType: 4 + '컷', startSearchDate: _today, startSearchTime: stdt[1], endSearchDate: eddt[0], endSearchTime: eddt[1]};
-								gagaAgGrid.addRowData(gridOptionsCorner, data, "planDtlSq");
-					});
+	
+			var data = { planDtlSq: '', planSq:planSq, cornerNm:'',cornerDispType: 6 + '컷', startSearchDate: _today, startSearchTime: stdt[1], endSearchDate: eddt[0], endSearchTime: eddt[1]};
+			gagaAgGrid.addRowData(gridOptionsCorner, data);
 		}
 
 	});

+ 97 - 82
src/main/webapp/WEB-INF/views/marketing/PlanWebDetailPopupForm.html → src/main/webapp/WEB-INF/views/marketing/PlanDetailPopupForm.html

@@ -3,7 +3,7 @@
 	xmlns:th="http://www.thymeleaf.org">
 <!--
  *******************************************************************************
- * @source  : PlanWebDetailForm.html
+ * @source  : PlanDetailForm.html
  * @desc    : 웹 수정 / 웹 등록 팝업 화면 Page
  *============================================================================
  * SISUN
@@ -14,16 +14,16 @@
  * 1.0  2020.02.04   sowon   최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="1100" id="planWebRegisterFormDiv">
+<div class="modalPopup" data-width="1100" id="planRegisterFormDiv">
 	<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>
+			<h2 th:text="${'기획전 ' + (mode == 'N' ? '등록' : '수정')}"></h2>
+			<button type="button" class="close" onclick="uifnPopupClose('planRegisterFormDiv')"><i class="fa fa-times"></i></button>
 		</div>
 		
 	<!-- 기획전 웹 수정 -->
 		<div class="panelContent" th:if="${mode == 'U'}">
-		<form th:object="${planInfo}" id="planWebUpdateForm" name="planWebUpdateForm" action="#" th:action="@{'/system/user/save'}" th:method="post">
+		<form th:object="${planInfo}" id="planUpdateForm" name="planUpdateForm" action="#" th:method="post">
 			<input type="hidden" name="mode" th:value="${mode}"/>
 			<input type="hidden" name="planSq" th:value="*{planSq}"/>
 
@@ -271,7 +271,7 @@
 			<div style='margin: 13px;'>
 			<ul class="panelBar">
 				<li class="right" th:if="${mode == 'U'}">
-					<button type="button" class="btn btn-success btn-lg" onclick="fnPlanSave('#planWebUpdateForm');">저장</button>
+					<button type="button" class="btn btn-success btn-lg" onclick="fnPlanSave('#planUpdateForm');">저장</button>
 				</li>
 			</ul>
 			</div>
@@ -281,22 +281,25 @@
 	
 		<!-- 기획전 웹 등록 -->
 		<div class="panelContent" th:if="${mode == 'N'}">
-			<form id="planWebRegisterForm" name="planWebRegisterForm" action="#" th:action="@{'/system/user/save'}" th:method="post">
+			<form id="planRegisterForm" name="planRegisterForm" action="#" th:action="@{'/system/user/save'}" th:method="post">
 			<input type="hidden" name="mode" th:value="${mode}"/>
 			<div>
 				<table class="frmStyle">
 					<colgroup>
-						<col style="width: 150px;"/>
+						<col style="width:13%;"/>
 						<col/>
 					</colgroup>
 					<tr>
 						<th>기존 기획전</th>
 						<td>
-							<select name="planSq" id="planSq">
+							<!-- <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>
+							</select> -->
+							<input type="text" class="w100" name="searchTxt" id="searchTxt" maxlength="20" readonly="readonly"/>
+							<input type="hidden" class="w100" name="planSq_Hideen" id="planSq_Hideen" maxlength="20"/>
+							<button type="button" class="btn icn" id="btnPopupSearchPlan"><i class="fa fa-search"></i></button>
+							<button type="button" class="btn btn-primary btn-lg" onclick="fnPlanCopyPopup();">기획전 복사</button>
 						</td>
 					</tr>
 				</table>
@@ -534,7 +537,7 @@
 				</div>
 				<ul class="panelBar">
 					<li class="right" th:if="${mode == 'N'}">
-						<button type="button" class="btn btn-info btn-lg" onclick="fnPlanSave('#planWebRegisterForm');">저장</button>
+						<button type="button" class="btn btn-info btn-lg" onclick="fnPlanSave('#planRegisterForm');">저장</button>
 					</li>
 				</ul>
 			</form>
@@ -580,14 +583,25 @@
 	
 	//템플릿 유형 설정
 	var fnPlanTemplatePopup = function () {
-		var actionUrl = "/marketing/planning/webdetail/template/form?mode=C";
+		var actionUrl = "/marketing/planning/detail/template/form?mode=C";
 		cfnOpenModalPopup(actionUrl,'popupPlanTemplate');
 	}
 	
+	// 기존 기획전 조회 선택시
+	$('#btnPopupSearchPlan').on('click', function(result) {
+		cfnOpenPlanPopup('popupPlan');
+		
+	});
+	
+	var popupPlan = function (result) {
+		$("#planSq_Hideen").val(result[0].planSq);
+		$("#searchTxt").val("[" + result[0].planSq + "] " +result[0].planNm);
+		
+	}
 
 	// 기획전 복사
 	var fnPlanCopyPopup = function() {
-		var planSq = $('#planWebRegisterForm select[name=planSq]').val();
+		var planSq = $("#planSq_Hideen").val(); 
 
 		if (gagajf.isNull(planSq)) {
 			mcxDialog.alert('복사할 기획전을 선택하세요.');
@@ -609,11 +623,11 @@
 
 	// 기획전 복사 callback
 	var fnCopyCallback = function(result) {
-		uifnPopupClose('planWebRegisterFormDiv');
+		uifnPopupClose('planRegisterFormDiv');
 		fnPlanListSearch();
 
-		var actionUrl = "/marketing/planning/webdetail/form?mode=U&planSq=" + result.planSq;
-		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+		var actionUrl = "/marketing/planning/detail/form?mode=U&planSq=" + result.planSq;
+		cfnOpenModalPopup(actionUrl,'popupPlan');
 	}
 
 	var fnPlanSave = function(formId) {
@@ -711,7 +725,7 @@
 			return;
 		}
 
-		//var jsonData = JSON.stringify($("#planWebRegisterForm").serializeObject());
+		//var jsonData = JSON.stringify($("#planRegisterForm").serializeObject());
 		
 		let allBrandData = gagaAgGrid.getAllRowData(gridOptionsFGBrandList);
 		var multiBrand = [];
@@ -726,7 +740,7 @@
 		});
 		
 		// 기획전 등록
-		if (formId == '#planWebRegisterForm') {
+		if (formId == '#planRegisterForm') {
 			mcxDialog.confirm('등록 하시겠습니까?', {
 				cancelBtnText: "취소",
 				sureBtnText: "확인",
@@ -737,37 +751,37 @@
 							,brandList : allBrandData
 							,multiCate : multiCate
 							,CateList : allCateData
-						    ,mode : $('#planWebRegisterForm input[name=mode]').val()
-						    ,planSq : $('#planWebRegisterForm input[name=planSq]').val()
-							,planGb	: $('#planWebRegisterForm select[name=planGb]').val()
-							,templateType :	$('#planWebRegisterForm select[name=templateType]').val()
-							,frontGb : $('#planWebRegisterForm select[name=frontGb]').val()
-							,planNm : $('#planWebRegisterForm input[name=planNm]').val()
-							,startSearchDate : $('#planWebRegisterForm input[name=startSearchDate]').val()
-							,startSearchHour : $('#planWebRegisterForm input[name=startSearchHour]').val()
-							,startSearchMin : $('#planWebRegisterForm input[name=startSearchMin]').val()
-							,endSearchDate : $('#planWebRegisterForm input[name=endSearchDate]').val()
-							,endSearchHour : $('#planWebRegisterForm input[name=endSearchHour]').val()
-							,endSearchMin : $('#planWebRegisterForm input[name=endSearchMin]').val()
-							,dispStdt : $('#planWebRegisterForm input[name=dispStdt]').val()
-							,dispEddt : $('#planWebRegisterForm input[name=dispEddt]').val()
-							,dtlTitle1 : $('#planWebRegisterForm input[name=dtlTitle1]').val()
-							,cornerNmDispYn :  $('#planWebRegisterForm select[name=cornerNmDispYn]').val()
-							,openYn :  $('#planWebRegisterForm select[name=openYn]').val()
-							,siteCd :$('#planWebRegisterForm select[name=siteCd]').val()
-							,dispOrd : $('#planWebRegisterForm input[name=dispOrd]').val()
-							,replyYn : $('#planWebRegisterForm select[name=replyYn]').val()
-							,mainPimg :$('#planWebRegisterForm input[name=mainPimg]').val()
-							,mainMimg : $('#planWebRegisterForm input[name=mainMimg]').val()
-							,fsrcPc :  $('#planWebRegisterForm input[name=fsrcPc]').val()
-							,fsrcMobile : $('#planWebRegisterForm input[name=fsrcMobile]').val()
+						    ,mode : $('#planRegisterForm input[name=mode]').val()
+						    ,planSq : $('#planRegisterForm input[name=planSq]').val()
+							,planGb	: $('#planRegisterForm select[name=planGb]').val()
+							,templateType :	$('#planRegisterForm select[name=templateType]').val()
+							,frontGb : $('#planRegisterForm select[name=frontGb]').val()
+							,planNm : $('#planRegisterForm input[name=planNm]').val()
+							,startSearchDate : $('#planRegisterForm input[name=startSearchDate]').val()
+							,startSearchHour : $('#planRegisterForm input[name=startSearchHour]').val()
+							,startSearchMin : $('#planRegisterForm input[name=startSearchMin]').val()
+							,endSearchDate : $('#planRegisterForm input[name=endSearchDate]').val()
+							,endSearchHour : $('#planRegisterForm input[name=endSearchHour]').val()
+							,endSearchMin : $('#planRegisterForm input[name=endSearchMin]').val()
+							,dispStdt : $('#planRegisterForm input[name=dispStdt]').val()
+							,dispEddt : $('#planRegisterForm input[name=dispEddt]').val()
+							,dtlTitle1 : $('#planRegisterForm input[name=dtlTitle1]').val()
+							,cornerNmDispYn :  $('#planRegisterForm select[name=cornerNmDispYn]').val()
+							,openYn :  $('#planRegisterForm select[name=openYn]').val()
+							,siteCd :$('#planRegisterForm select[name=siteCd]').val()
+							,dispOrd : $('#planRegisterForm input[name=dispOrd]').val()
+							,replyYn : $('#planRegisterForm select[name=replyYn]').val()
+							,mainPimg :$('#planRegisterForm input[name=mainPimg]').val()
+							,mainMimg : $('#planRegisterForm input[name=mainMimg]').val()
+							,fsrcPc :  $('#planRegisterForm input[name=fsrcPc]').val()
+							,fsrcMobile : $('#planRegisterForm input[name=fsrcMobile]').val()
 						}	
 					
 					var jsonData =  JSON.stringify(data);
-					gagajf.ajaxJsonSubmit("/marketing/planning/webdetail/create", jsonData, fnPlanWebDetailCallBack); 
-					uifnPopupClose('planWebRegisterFormDiv');
+					gagajf.ajaxJsonSubmit("/marketing/planning/detail/create", jsonData, fnPlanDetailCallBack); 
+					uifnPopupClose('planRegisterFormDiv');
 					fnPlanListSearch();
-					//fnPlanWebDetailClose();
+					//fnPlanDetailClose();
 				}
 			});
 		} else { // 기획전 수정
@@ -781,39 +795,39 @@
 							,brandList : allBrandData
 							,multiCate : multiCate
 							,CateList : allCateData
-						    ,mode : $('#planWebUpdateForm input[name=mode]').val()
-						    ,planSq : $('#planWebUpdateForm input[name=planSq]').val()
-							,planGb	: $('#planWebUpdateForm select[name=planGb]').val()
-							,templateType :	$('#planWebUpdateForm select[name=templateType]').val()
-							,frontGb : $('#planWebUpdateForm select[name=frontGb]').val()
-							,planNm : $('#planWebUpdateForm input[name=planNm]').val()
-							,startSearchDate : $('#planWebUpdateForm input[name=startSearchDate]').val()
-							,startSearchHour : $('#planWebUpdateForm input[name=startSearchHour]').val()
-							,startSearchMin : $('#planWebUpdateForm input[name=startSearchMin]').val()
-							,endSearchDate : $('#planWebUpdateForm input[name=endSearchDate]').val()
-							,endSearchHour : $('#planWebUpdateForm input[name=endSearchHour]').val()
-							,endSearchMin : $('#planWebUpdateForm input[name=endSearchMin]').val()
-							,dispStdt : $('#planWebUpdateForm input[name=dispStdt]').val()
-							,dispEddt : $('#planWebUpdateForm input[name=dispEddt]').val()
-							,dtlTitle1 : $('#planWebUpdateForm input[name=dtlTitle1]').val()
-							,cornerNmDispYn :  $('#planWebUpdateForm select[name=cornerNmDispYn]').val()
-							,openYn :  $('#planWebUpdateForm select[name=openYn]').val()
-							,siteCd :$('#planWebUpdateForm select[name=siteCd]').val()
-							,dispOrd : $('#planWebUpdateForm input[name=dispOrd]').val()
-							,replyYn : $('#planWebUpdateForm select[name=replyYn]').val()
-							,mainPimg :$('#planWebUpdateForm input[name=mainPimg]').val()
-							,mainMimg : $('#planWebUpdateForm input[name=mainMimg]').val()
-							,fsrcPc :  $('#planWebUpdateForm input[name=fsrcPc]').val()
-							,fsrcMobile : $('#planWebUpdateForm input[name=fsrcMobile]').val()
+						    ,mode : $('#planUpdateForm input[name=mode]').val()
+						    ,planSq : $('#planUpdateForm input[name=planSq]').val()
+							,planGb	: $('#planUpdateForm select[name=planGb]').val()
+							,templateType :	$('#planUpdateForm select[name=templateType]').val()
+							,frontGb : $('#planUpdateForm select[name=frontGb]').val()
+							,planNm : $('#planUpdateForm input[name=planNm]').val()
+							,startSearchDate : $('#planUpdateForm input[name=startSearchDate]').val()
+							,startSearchHour : $('#planUpdateForm input[name=startSearchHour]').val()
+							,startSearchMin : $('#planUpdateForm input[name=startSearchMin]').val()
+							,endSearchDate : $('#planUpdateForm input[name=endSearchDate]').val()
+							,endSearchHour : $('#planUpdateForm input[name=endSearchHour]').val()
+							,endSearchMin : $('#planUpdateForm input[name=endSearchMin]').val()
+							,dispStdt : $('#planUpdateForm input[name=dispStdt]').val()
+							,dispEddt : $('#planUpdateForm input[name=dispEddt]').val()
+							,dtlTitle1 : $('#planUpdateForm input[name=dtlTitle1]').val()
+							,cornerNmDispYn :  $('#planUpdateForm select[name=cornerNmDispYn]').val()
+							,openYn :  $('#planUpdateForm select[name=openYn]').val()
+							,siteCd :$('#planUpdateForm select[name=siteCd]').val()
+							,dispOrd : $('#planUpdateForm input[name=dispOrd]').val()
+							,replyYn : $('#planUpdateForm select[name=replyYn]').val()
+							,mainPimg :$('#planUpdateForm input[name=mainPimg]').val()
+							,mainMimg : $('#planUpdateForm input[name=mainMimg]').val()
+							,fsrcPc :  $('#planUpdateForm input[name=fsrcPc]').val()
+							,fsrcMobile : $('#planUpdateForm input[name=fsrcMobile]').val()
 						}	
 					
 					
-					var actionUrl = '/marketing/plan/webdetail/update';
+					var actionUrl = '/marketing/plan/detail/update';
 					var jsonData =  JSON.stringify(data);
-					gagajf.ajaxJsonSubmit(actionUrl, jsonData, fnPlanWebDetailCallBack); 
-						uifnPopupClose('planWebRegisterFormDiv');
+					gagajf.ajaxJsonSubmit(actionUrl, jsonData, fnPlanDetailCallBack); 
+						uifnPopupClose('planRegisterFormDiv');
 						fnPlanListSearch();
-						//fnPlanWebDetailClose();
+						//fnPlanDetailClose();
 				}
 			});
 		}
@@ -889,8 +903,8 @@
 		$(obj).closest('div').find('input[name="attachYn"]').val(val);
 	}
 
-	var fnPlanWebDetailCallBack = function() {
-		uifnPopupClose('planWebRegisterForm');
+	var fnPlanDetailCallBack = function() {
+		uifnPopupClose('planRegisterForm');
 		fnPlanListSearch();
 		
 	}
@@ -900,6 +914,7 @@
 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
 		{headerName: "브랜드ID", field: "brandCd", width: 110, cellClass: 'text-center'},
 		{headerName: "브랜드명", field: "brandEnm", width: 120, cellClass: 'text-center'},
+		{headerName: "브랜드그룹명", field: "brandGrpNm", width: 150, cellClass: 'text-center'},
 		{headerName: "", field: "brandKnm", width: 150, cellClass: 'text-center'},
 		/* {headerName: "적용대상", field: "targetGb", width: 150, cellClass: 'text-center', hide: true},
 		{headerName: "시퀀스", field: "tmtbGoodsSq", width: 150, cellClass: 'text-center', hide: true},
@@ -1005,13 +1020,13 @@
 		gagaAgGrid.createGrid("gridFGCateList", gridOptionsFGCateList);
 		
 		 if (mode =='U') {
-			/* $('#planWebDetailForm input[name=badgeFcolor]').spectrum({
+			/* $('#planDetailForm input[name=badgeFcolor]').spectrum({
 				preferredFormat: "hex",
 				showInput: true,
 				allowEmpty: true
 			});
 
-			$('#planWebDetailForm input[name=badgeBcolor]').spectrum({
+			$('#planDetailForm input[name=badgeBcolor]').spectrum({
 				preferredFormat: "hex",
 				showInput: true,
 				allowEmpty: true
@@ -1021,9 +1036,9 @@
 			gridOptionsFGCateList.api.setRowData(planCateList);
 
 			if (planInfo.goodsLimitYn == 'N') {
-				$('#planWebDetailForm input[name=goodsLimitQty]').hide();
+				$('#planDetailForm input[name=goodsLimitQty]').hide();
 			} else {
-				$('#planWebDetailForm input[name=goodsLimitQty]').show();
+				$('#planDetailForm input[name=goodsLimitQty]').show();
 			}
 
 			// 썸머노트 값 설정
@@ -1038,13 +1053,13 @@
 			}
 
 		} else {
-			/* $('#planWebRegisterForm input[name=badgeFcolor]').spectrum({
+			/* $('#planRegisterForm input[name=badgeFcolor]').spectrum({
 				preferredFormat: "hex",
 				showInput: true,
 				allowEmpty: true
 			});
 
-			$('#planWebRegisterForm input[name=badgeBcolor]').spectrum({
+			$('#planRegisterForm input[name=badgeBcolor]').spectrum({
 				preferredFormat: "hex",
 				showInput: true,
 				allowEmpty: true

+ 17 - 18
src/main/webapp/WEB-INF/views/marketing/PlanListForm.html

@@ -15,11 +15,10 @@
  -->
 <div id="main">
 	<div class="main-title"></div>
-
-	<div class="panelStyle">
-		<form id="planListSearchForm" name="planListSearchForm" action="#"
+<form id="planListSearchForm" name="planListSearchForm" action="#"
 			th:action="@{'/marketing/planning/list'}"
 			onsubmit="$('#btnSearch').trigger('click'); return false;">
+	<div class="panelStyle">
 			<table class="frmStyle">
 				<colgroup>
 					<col style="width: 5%;" />
@@ -114,7 +113,7 @@
 			</li>
 			<li class="right">
 				<button type="button" class="btn btn-primary btn-lg"
-					onclick="fnPlanWebRegisterPopup();">등록</button> 검색결과 : <strong><span
+					onclick="fnPlanRegisterPopup();">등록</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">
@@ -160,6 +159,12 @@
 			valueFormatter: function (params) { return gagaAgGrid.lookupValue(planGbList, params.value); },
 			valueParser: function (params) { return gagaAgGrid.lookupKey(planGbList, params.newValue); }
 		},
+		{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:'frontGb'	, width:120, cellClass: 'text-center',
 			cellEditor: 'agRichSelectCellEditor',
 			cellEditorParams: { values: gagaAgGrid.extractValues(wmGbList) },
@@ -174,12 +179,6 @@
 			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) },
@@ -212,7 +211,7 @@
 	// 바인딩
 	var fnBindDetail = function(field, rowData) {
 		if (field == 'planSq') { // 기획전 웹수정 팝업
-			fnEventWebDetailPopup(rowData.planSq);
+			fnEventDetailPopup(rowData.planSq);
 		}
 
 		if (field == 'planNm') { // 기획전 관리 팝업
@@ -222,15 +221,15 @@
 	
 
 	// 웹 등록 팝업
-	var fnPlanWebRegisterPopup = function() {
-		var actionUrl = "/marketing/planning/webdetail/form?mode=N";
-		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+	var fnPlanRegisterPopup = function() {
+		var actionUrl = "/marketing/planning/detail/form?mode=N";
+		cfnOpenModalPopup(actionUrl,'popupPlanDetail');
 	} 
 
 	// 웹 수정 팝업
-	var fnEventWebDetailPopup = function(planSq) {
-		var actionUrl = "/marketing/planning/webdetail/form?mode=U&planSq=" + planSq;
-		cfnOpenModalPopup(actionUrl,'popupPlanWebDetail');
+	var fnEventDetailPopup = function(planSq) {
+		var actionUrl = "/marketing/planning/detail/form?mode=U&planSq=" + planSq;
+		cfnOpenModalPopup(actionUrl,'popupPlanDetail');
 	}
 	
 	// 이벤트 코너 관리 팝업
@@ -348,7 +347,7 @@
 	}
 	
 	var fnSearchCallBack = function(result){
-
+		console.log(result.pageing.pageable.totalCount.addComma());
 		$('#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());

+ 38 - 21
src/main/webapp/WEB-INF/views/marketing/PlanPopupForm.html

@@ -27,7 +27,7 @@
 
 		<div class="panelContent">
 			<form id="popupPlanSearchForm" name="popupPlanSearchForm" action="#"
-				th:action="@{'/marketing/planning/listPop'}"
+				th:action="@{'/marketing/planning/list/detail/popup'}"
 				onsubmit="$('#btnPlanPopupSearch').trigger('click'); return false;">
 				<table class="frmStyle">
 					<colgroup>
@@ -92,13 +92,11 @@
 
 						<tr>
 							<th>진행기간</th>
-							<td colspan="3" id="popupPlanTerms"></td>
-
-							
-
+							<td colspan="5" id="popupPlanTerms"></td>
+<!-- 
 							<th>등록자</th>
 							<td><input type="text" name="regId" id="regId" />
-							</td>
+							</td> -->
 						</tr>
 					</tbody>
 				</table>
@@ -144,29 +142,48 @@
 		$('#popupPlanSearchForm')[0].reset();
 	}
 
-	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:'planSq'	, width:100, cellClass: 'text-center'},
- 		{headerName: "기획전명"		, field:'planNm'	, width:300, cellClass: 'text-left'},
- 		{headerName: "서브제목"		, field:'dtlTitle1'	, width:300 , cellClass: 'text-center'},
+	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:'siteCd'	, width:100, cellClass: 'text-center',
- 			cellEditor: 'agRichSelectCellEditor',
+			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:'planGb'	, width:100, cellClass: 'text-center'},
-		{headerName: "기획전템플릿유형"	, field:'templateType'	, width:100, cellClass: 'text-center'},
-		/* {headerName: "전시순서"		, field:'dispOrd'	, width:100, cellClass: 'text-right' }, */
+		{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:'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:'frontGb'	, width:120, cellClass: 'text-center'	},
-		{headerName: "오픈여부"		, field:'openYn'	, width:80 , cellClass: 'text-center'},
 		{headerName: "등록자"			, field:'regNm'		, width:100, cellClass: 'text-center'},
-		{headerName: "등록일"			, field:'regDt'		, width:150, cellClass: 'text-center'},
+		{headerName: "등록일"			, field:'regDt'		, width:150, cellClass: 'text-center'}
 	];
 
 	var gridOptionsPopupPlan = gagaAgGrid.getGridOptions(columnDefs);

+ 38 - 23
src/main/webapp/WEB-INF/views/marketing/PollListForm.html

@@ -20,10 +20,11 @@
 
 		<div class="panelStyle">
 			<form id="PollsearchForm" name="PollsearchForm" action="#" th:action="@{'/marketing/poll/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<input type="hidden" name="maskingYn" value="Y"/>
 				<table class="frmStyle">
 					<colgroup>
 						<col style="width:10%;"/>
-						<col style="width:30%;"/>
+						<col style="width:10%;"/>
 						<col style="width:10%;"/>
 						<col style="width:30%;"/>
 						<col style="width:10%;"/>
@@ -31,21 +32,20 @@
 					</colgroup>
 					<tbody>
 						<tr>
-							<th>등록기간</th>
-							<td id="terms" colspan="3"></td>
-						</tr>
-						<tr>
-							<th>POLL 제목</th>
-							<td>
-								<input type="text" name="pollTitle" id="pollTitle"/>
-							</td>
-
 							<th>사이트</th>
 							<td>
 								<select name="siteCd">
 									<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}|"></option>
 								</select>
 							</td>
+							<th>POLL 제목</th>
+							<td>
+								<input type="text" name="pollTitle" id="pollTitle"/>
+							</td>
+						</tr>
+						<tr>
+							<th>등록기간</th>
+							<td id="terms" colspan="3"></td>
 						</tr>
 					</tbody>
 				</table>
@@ -59,15 +59,20 @@
 		</div>
 
 		<div class="panelStyle">
-			<ul class="lrStyle">
-				<li class="aR">
-					<h4 class="btnLeft" id="pollQtitle">투표자수</h4>
+			<ul class="division">
+				<li style="width:60%">
+					<div class="panelBar">
+						<h4>POLL 목록</h4>
+					</div>
+					<div id="gridListPoll" style="width: 100%; height: 500px; float: left;" class="ag-theme-balham"></div>
+				</li>
+				<li style="width:40%">
+					<div class="panelBar">
+						<h4 id="pollQtitle">투표자 수</h4>
+					</div>
+					<div id="gridListVote" style="width: 100%; height: 500px; float: right;" class="ag-theme-balham"></div>
 				</li>
 			</ul>
-			<div class="panelContent" style="padding-bottom: 530px;">
-				<div id="gridListPoll" style="width: 60%; height: 500px; float: left;" class="ag-theme-balham"></div>
-				<div id="gridListVote" style="width: 38%; height: 500px; float: right;" class="ag-theme-balham"></div>
-			</div>
 		</div>
 
 		<div class="panelStyle">
@@ -87,7 +92,7 @@
 						<table class="frmStyle">
 							<colgroup>
 								<col style="width:5%;"/>
-								<col style="";/>
+								<col style=""/>
 								<col style=""/>
 								<col style=""/>
 								<col style=""/>
@@ -129,7 +134,7 @@
 										<input name="dispEdTime" id="edTime" type="hidden" data-valid-name="투표기간 종료시간" value='235959' />
 									</td>
 
-									<th>사이트<i class="star"></i></th>
+									<th>사이트</th>
 									<td>
 										<select name="siteCd">
 											<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}|"></option>
@@ -211,7 +216,7 @@
 	</div>
 
 <!-- 문항 Start --------------------------------------------------------------->
-<table class="frmStyle" style="display: none;">
+<table class="frmStyle" style="display: none;" id="rowQuestion">
 	<tr id="trRowQuestion">
 	<td>
 		<input type="checkbox" name="chkIdx" style="margin-left: 10px; top: 50%;  left: 0;  width: 18px; height: 18px; transform: translate(0,-50%);"/>
@@ -275,9 +280,10 @@
 		{headerName: 'POLL번호'	, field:'pollSq'	, width:100, cellClass: 'text-center'
 			, cellRenderer: function(params) { return fnSetColumn(params); }
 		},
-		{headerName: 'POLL제목'	, field:'pollTitle'	, width:230, cellClass: 'text-left'
+		{headerName: 'POLL제목'	, field:'pollTitle'	, width:200, cellClass: 'text-left'
 			, cellRenderer: function(params) { return fnSetColumn(params); }
 		},
+		 {headerName: '문항유형'		, field:'pollQtypeNm', width:100, cellClass: 'text-center'},
 		 {headerName: '문항제목'		, field:'pollQtitle', width:230, cellClass: 'text-center'},
 		 {headerName: '등록일'		, field:'regDt'	, width:80, cellClass: 'text-center'},
 		/*{headerName: '투표율'		, field:'voteRate'	, width:80, cellClass: 'text-center'
@@ -287,6 +293,7 @@
 
 	var columnDefsVote = [
 		{headerName: '투표자명'		, field:'voterNm'	, width:150, cellClass: 'text-center'},
+		{headerName: '답변'	, field:'dummy'	, width:200, cellClass: 'text-center'},
 		{headerName: '투표자회원번호'	, field:'ansCustNo'	, width:200, cellClass: 'text-center'},
 		{headerName: '투표일시'		, field:'voteDt'	, width:200, cellClass: 'text-center'},
 	];
@@ -317,6 +324,7 @@
 			}
 		}
 	}
+		
 
 	// 셀 클릭 시
 	var selectPoll = [];
@@ -325,8 +333,13 @@
 			$('#registerForm input[name=pollTitle]').focus();
 			fnAllDeleteQuestion();
 			fnSetDetail(event);
-		} else if (event.colDef.field == 'voteCnt') {
+		} else if (event.colDef.field == 'pollQtitle') {
 			fnSearchVote(event.data);
+		} else if (event.colDef.field == 'pollQtypeNm'){
+			if(event.data.pollQtypeNm == '단수형' || event.data.pollQtypeNm == '복수형'){
+				var actionUrl = "/marketing/poll/voter/list/popup/form?pollQsq=" + event.data.pollQsq +"&pollQtype=" + event.data.pollQtype;
+				cfnOpenModalPopup(actionUrl, 'pollVoteRatePopup');
+			}
 		}
 	}
 
@@ -389,7 +402,7 @@
 			$("#partiCnt").attr("disabled",false);
 		}else{
 			$("#partiCnt").attr("disabled",true);
-		}2ㅣ
+		}
 	}
 
 	// 검색
@@ -405,8 +418,10 @@
 		}else{
 			$("#partiCnt").attr("disabled",true);
 		}
+		
 	})
 	
+	
 	// 유효성
 	function validationPoll() {
 		if($('#registerForm input[name=pollTitle]').val() == ''){

+ 67 - 0
src/main/webapp/WEB-INF/views/marketing/PollVoteRatePopupForm.html

@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PollVoteRatePopup.html
+ * @desc    : Poll 투표율 확인 page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.22   sowon     최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="960" data-height="400" id="popupPollVoteRate">
+	<div id="panel" class="panelStyle">
+		<!-- TITLE -->
+		<div class="panelTitle">
+			<h2>POLL 투표율</h2>
+			<button type="button" class="close"
+				onclick="uifnPopupClose('popupPollVoteRate');">
+				<em class="fa fa-times"></em>
+			</button>
+		</div>
+		<!-- //TITLE -->
+
+		<!-- CONTENT -->
+		<div class="panelContent">
+				<div class="boxTitle"></div>
+				<input type="hidden" name="pollSq" />
+				<ul class="boxContent">
+					<li class="boxContentTop">
+						<table class="frmStyle" style="overflow:auto;">
+							<colgroup>
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+								<col width="">
+							</colgroup>
+							<tbody>
+								<tr>
+									<th>문항</th>
+									<th>투표수(명)</th>
+									<th>투표율</th>
+								</tr>								
+								<tr th:each="list : ${pollAList}" align="center">
+									<td>[[${list.name}]]</td>
+									<td>[[${list.voteCnt}]]</td>
+									<td><label>[[${list.voteRate}]]%</label></td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="boxContentBtnB"><span class="btnRight"> </span></li>
+				</ul>
+
+			</div>
+		</div>
+	</div>

BIN
src/main/webapp/image/icon_checkN.png


BIN
src/main/webapp/image/icon_checkND.png


BIN
src/main/webapp/image/icon_checkY.png


BIN
src/main/webapp/image/icon_checkYD.png


BIN
src/main/webapp/image/icon_radioND.png


BIN
src/main/webapp/image/icon_radioY.png


BIN
src/main/webapp/image/icon_radioYD.png


+ 47 - 47
src/main/webapp/ux/css/admin.ui.css

@@ -1,4 +1,6 @@
-@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700"); @import url("https://fonts.googleapis.com/css?family=Roboto:400,300,500,700"); html,body {position:relative; height:100%;}
+@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700");
+@import url("https://fonts.googleapis.com/css?family=Roboto:400,300,500,700");
+html,body {position:relative; height:100%;}
 html, body, header, div, ul, ol, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, label, a, p, form, input, textarea, table, hr, span, em {margin:0; padding:0; box-sizing:border-box;}
 body {overflow-x:hidden; font-family:"open sans", "Roboto", "Malgun Gothic", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size:12px; background-color:#f3f3f4;}
 h1, h2, h3, h4, h5, h6 {display:inline-block;}
@@ -16,7 +18,7 @@ input.btn-sm {padding:1px 6px;}
 input[type=text] {width:100%;}
 input[type=text], input[type=file], input[type=date], [type=password], textarea {padding:4px 3px 4px 5px; color:inherit; border-radius:1px; vertical-align:middle; margin:1px 3px 2px 0;}
 input[type=date],input[type=time],input[type=datetime-local],input[type=month] {-webkit-appearance:listbox;}
-input[readonly="readonly"], input[disabled="disabled"], input[readonly="readonly"]:before, input[disabled="disabled"]:before, select[readonly="readonly"], select[disabled="disabled"],textarea[readonly="readonly"] ,textarea[disabled="disabled"] {background-color:#eee !important;}
+input[readonly="readonly"], input[disabled="disabled"], select[readonly="readonly"], select[disabled="disabled"],textarea[readonly="readonly"] ,textarea[disabled="disabled"] {background-color:#eee !important;}
 button, select {text-transform:none;}
 button,[type=button],[type=reset],[type=submit] {margin:0; -webkit-appearance:button; border-radius:0; cursor:pointer; background-color:transparent; border-color:transparent;}
 button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner {padding:0; border-style:none;}
@@ -80,11 +82,11 @@ html,body,#wrapper,#container {min-height:100%; height:100%;}
 
 /* 로그인 :alert */
 .alertBox {position:relative; padding:10px 40px 10px 10px; margin-bottom:10px; border:1px solid; border-radius:.25rem; line-height:22px;}
-.alertBox .alertClose {position:absolute; top:0; right:5px; padding:0 10px; height:40px; text-indent:-9999px; background:url('../../image/btn_sltClose.png') no-repeat 50% 50%;}
-.alertBox .alertClose:hover {background:url('../../image/btn_sltCloseOn.png') no-repeat 50% 50%;}
+.alertBox .alertClose {position:absolute; top:0; right:5px; width:30px; height:40px; text-indent:-9999px; background:url('/image/btn_sltClose.png') no-repeat 50% 50%;}
+.alertBox .alertClose:hover {background:url('/image/btn_sltCloseOn.png') no-repeat 50% 50%;}
 .alert-success {color:#155724; background-color:#d4edda; border-color:#c3e6cb;}
 .alert-info {color:#0c5460; background-color:#d1ecf1; border-color:#bee5eb;}
-.alert-warning {color:#856404; background-color:#fff3cd; border-color:#ffeeba;}
+.alert-warning {color:#856404; background-color:#fff3cd; border-color:#f8e7b4;}
 .alert-danger {color:#721c24; background-color:#f8d7da; border-color:#f5c6cb;}
 
 /* header--------------- */
@@ -118,12 +120,13 @@ header a, header button {color:#fff;}
 #lnb-wrapper {position:fixed; top:60px; left:-260px; width:260px; height:100%; vertical-align:top; overflow-y:auto; transition:left .3s; -webkit-transition:left .3s; background-color:#2f4050;}
 #lnb-wrapper:after{content:''; position:absolute; top:0; left:0; z-index:-1; width:100%; height:100%;}
 #lnb-wrapper.on {left:0;}
-#lnb {margin-bottom:100px; width:260px;}
+#lnb {margin-bottom:100px;}
 #lnb a {display:block; color:#a7b1c2;}
+#lnb a::selection {background:none;}
 #lnb a:hover {color:#fff;}
 #lnb a.on {color:#fff;}
-#lnb .dep2 {padding:14px 20px 14px 35px; background:url('../../image/icon_dep2.png') 10px 50% no-repeat, url('../../image/icon_depArr2.png') 222px 50% no-repeat; background-color:#233646; cursor:pointer;}
-#lnb .dep2.on {display:block; background:url('../../image/icon_dep2On.png') 10px 50% no-repeat, url('../../image/icon_depArr2On.png') 222px 50% no-repeat; background-color:#233646;}
+#lnb .dep2 {padding:14px 20px 14px 35px; background:url('/image/icon_dep2.png') 10px 50% no-repeat, url('/image/icon_depArr2.png') right 15px top 50% no-repeat; background-color:#233646; cursor:pointer;}
+#lnb .dep2.on {display:block; background:url('/image/icon_dep2On.png') 10px 50% no-repeat, url('/image/icon_depArr2On.png') right 15px top 50% no-repeat; background-color:#233646;}
 #lnb .dep3 {padding:5px 0 10px 10px; border-left:4px solid #8597eb; cursor:pointer;}
 #lnb .dep3 a {padding:10px; cursor:pointer;}
 #lnb .dep4 {padding:5px 0 10px 20px; cursor:pointer;}
@@ -153,7 +156,7 @@ header a, header button {color:#fff;}
 .panelStyle h2 {margin-right:10px; font-size:14px; font-weight:bold;}
 .panelStyle h3 {margin-right:10px; font-size:12px; font-weight:normal; line-height:25px;}
 .panelStyle h3 i {padding-right:5px}
-.panelStyle h4 {padding-left:23px; height:31px; line-height:31px; background:url('../../image/icon_h4.png') no-repeat 3px 50%; color:#666;}
+.panelStyle h4 {padding-left:23px; height:31px; line-height:31px; background:url('/image/icon_h4.png') no-repeat 3px 50%; color:#666;}
 .panelStyle .panelBar {display:table; width:100%; padding-bottom:10px;}
 .panelStyle .panelBar h4 {margin-bottom:0;}
 .panelStyle .panelBar > li {display:table-cell;}
@@ -198,7 +201,7 @@ header a, header button {color:#fff;}
 .tabsNav .ui-tabs-active a {background-color:#fff; color:#222; border:1px solid #ccc; border-bottom:2px solid #fff;}
 .tab-del {position:absolute; top:1px; right:1px; padding:4px 6px; color:gray; cursor:pointer; border-top-right-radius:.25rem;}
 .tab-del:hover {color:#f40552;}
-a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !important;}
+a, button, .ui-state-active, .ui-state-focus, .ui-state-hover, input[type=range] {outline:0 !important;}
 .tabsNav .ui-corner-top a {padding:0 35px 0 20px}
 
 /* tabsJr 영역 --------------- */
@@ -215,7 +218,7 @@ a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !import
 .tabJr.on {display:block;}
 .tabJrContArea {vertical-align:middle;}
 
-/* modal, modeless popup --------------- */
+/* MODAL, MODELESS POPUP --------------- */
 .modalPopup{display:none; position:fixed; left:0; top:0; z-index:11; width:100%; height:100%; background:rgba(0,0,0,0.5);}
 .modalPopup > .panelStyle{position:absolute; top:50%; left:50%; z-index:11; -ms-transform:translate(-50%, -50%); transform:translate(-50%, -50%); margin:0; border:1px solid #79797a; border-radius:3px;}
 .modalPopup > .panelStyle .close {position:absolute; top:0; right:0; font-size:18px; padding:5px 15px 8px;}
@@ -238,12 +241,10 @@ a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !import
 .videoPopup .close {position:absolute; top:-20px; right:-20px; z-index:1; width:40px; height:40px; line-height:20px; font-size:20px; border:1px solid #666; border-radius:50px; background-color:#fff;}
 .videoPopup iframe{width:100%; height:100%}
 
-
 #btnTop {display:none; position:fixed; right:0; bottom:50px; width:40px; line-height:10px; font-size:10px; background:#fff; border:1px solid #ddd; border-right:none; padding:3px 0 5px 0; box-shadow:5px 5px 5px -4px rgba(0, 0, 0, 0.07); color:#1c84c6;}
 #btnTop i {width:100%; font-size:12px;}
 #btnTop:hover {padding-right:30px; width:70px; font-weight:bold;}
 
-
 /* 컨텐트 스크롤--------------- */
 .xScroll {overflow-x:auto;}
 .yScroll {overflow-y:auto;}
@@ -256,22 +257,21 @@ a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !import
 .frmStyle th {padding:0 15px; height:36px; line-height:24px; white-space:nowrap; text-align:center; background:#e9ecfb;}
 .frmStyle td {padding:0 10px 0 10px; line-height:36px; position:relative; border-top:1px solid #eee; border-right:1px solid #eee;}
 
-/* 체크박스&라디오박스 공통--------------- */
-input[type=radio] {position:absolute; top:50%; left:0; width:18px; height:18px; transform:translate(0,-50%); -ms-transform:translate(0,-50%);}
+/* 체크박스 & 라디오버튼 : 공통--------------- */
 label.chkBox, label.rdoBtn {position:relative; display:inline-block; padding-left:26px; height:22px; line-height:22px; vertical-align:middle; cursor:pointer;}
-/* 체크박스 :전체선택 버튼--------------- */
-input[type=checkbox] {position:absolute; top:0; left:0; width:0; height:0;}
-input[type=button].chkBox {margin-left:-2px; padding-left:24px; height:22px; vertical-align:middle; background:url('../../image/icon_checkN.png') no-repeat 0 50%;}
-
-/* 체크박스--------------- */
-label.chkBox::before {position:absolute; top:2px; left:0; content:''; width:16px; height:16px; border:1px solid #dbdbdb; background:#fff;}
-label.chkBox.checked::after {position:absolute; top:6px; left:3px; content:''; width:8px; height:4px; border-bottom:3px solid #676a6c; border-left:3px solid #676a6c; -webkit-transform:rotate(-45deg); transform:rotate(-45deg);}
-label.chkBox .formControl::before {background:#eee;}
-
-/* 라디오버튼--------------- */
-input[type=radio]::before {position:absolute; top:0; left:0; content:''; width:16px; height:16px; border:1px solid #dbdbdb; border-radius:50%; background:#fff;}
-input[type=radio]:checked::after {position:absolute; top:5px; left:5px; content:''; width:8px; height:8px; border-radius:50%; background:#676a6c;}
-input[type=radio].formControl::before {background:#eee;}
+label.chkBox input, label.rdoBtn input{position:absolute; top:2px; left:0; width:0; height:0; border:none;}
+/* 체크박스 */
+label.chkBox::after {content:''; position:absolute;top:0; left:0;width:22px; height:22px;}
+label.chkBox input::after{content:''; position:absolute; top:0; left:0; width:18px; height:18px;background:url('/image/icon_checkN.png') no-repeat 0 0;}
+label.chkBox input:checked::after{background:url('/image/icon_checkY.png') no-repeat 0 0;}
+label.chkBox input[disabled='disabled']::after, label.chkBox input[readonly='readonly']::after{background:url('/image/icon_checkND.png') no-repeat 0 0;}
+label.chkBox input[disabled='disabled']:checked::after, label.chkBox input[readonly='readonly']:checked::after{background:url('/image/icon_checkYD.png') no-repeat 0 0;}
+/* 라디오버튼 */
+label.rdoBtn::after {content:''; position:absolute;top:0; left:0;width:22px; height:22px;}
+label.rdoBtn input::after{content:''; position:absolute; top:0; left:0; width:18px; height:18px;background:url('/image/icon_radioN.png') no-repeat 0 0;}
+label.rdoBtn input:checked::after{background:url('/image/icon_radioY.png') no-repeat 0 0;}
+label.rdoBtn input[disabled='disabled']::after, label.rdoBtn input[readonly='readonly']::after{background:url('/image/icon_radioND.png') no-repeat 0 0;}
+label.rdoBtn input[disabled='disabled']:checked::after, label.rdoBtn input[readonly='readonly']:checked::after{background:url('/image/icon_radioYD.png') no-repeat 0 0;}
 
 /* 토글 스위치--------------- */
 .switchBox{ display:inline-block;position:relative; width:60px; height:28px; vertical-align:middle;border-radius:25px;overflow:hidden;}
@@ -384,8 +384,8 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .mSelected li {float:left; margin:2px 5px 3px; line-height:24px; padding:0 7px; background:#dbedf9; -ms-user-select:none; -moz-user-select:-moz-none; -webkit-user-select:none; user-select:none;}
 .mSelected li.srchFld {margin:0; padding:0; background:none;}
 .mSelected .srchFld input {width:25px; margin:0; padding:0; border:none; outline:none;}
-.mSelected a {border:none !important; float:right; margin-left:3px; padding:0 3px; width:15px; line-height:22px; text-indent:-9999px; background:url('../../image/btn_sltClose.png') no-repeat 100% 50%;}
-.mSelected a:hover {background:url('../../image/btn_sltCloseOn.png') no-repeat 100% 50%;}
+.mSelected a {border:none !important; float:right; margin-left:3px; padding:0 3px; width:15px; line-height:22px; text-indent:-9999px; background:url('/image/btn_sltClose.png') no-repeat 100% 50%;}
+.mSelected a:hover {background:url('/image/btn_sltCloseOn.png') no-repeat 100% 50%;}
 .mSelecting {display:none; overflow-y:auto; overflow-x:hidden; position:absolute; top:100%; left:-1px; z-index:1; width:100%; max-height:156px; line-height:30px; border:1px solid #e5e6e7; background:#fff;}
 .mSelecting li {margin:0 10px; cursor:pointer;}
 
@@ -401,7 +401,7 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .lrStyle .uFile {margin-top:2px;}
 .uFileInput {position:absolute; top:0; width:100%; margin:0 !important; padding:0 !important; line-height:28px; border:none !important;}
 .uFileLabel {position:absolute; top:0; right:0; left:0; z-index:1; margin:0; padding:0 7px; width:cals(100% - 7px); line-height:28px; height:28px; background-color:#fff; border-radius:1px; overflow:hidden; white-space:nowrap;}
-.uFileLabel::after {position:absolute; top:0; right:0; bottom:0; width:30px; z-index:3; line-height:28px; content:" "; border-left:1px solid #dbdbdb; background:#eee url('../../image/icon_upload.png') no-repeat 50% 50%;}
+.uFileLabel::after {position:absolute; top:0; right:0; bottom:0; width:30px; z-index:3; line-height:28px; content:" "; border-left:1px solid #dbdbdb; background:#eee url('/image/icon_upload.png') no-repeat 50% 50%;}
 
 /* badge --------------- */
 .badge {float:right; margin-top:2px; padding:0 5px; min-width:9px; line-height:18px; color:#fff; font-size:12px; font-weight:600; border-radius:3px; text-align:center; text-shadow:1px 1px 1px rgba(0,0,0,0.4); letter-spacing:-0.5px;}
@@ -411,7 +411,7 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .badge-success {background-color:#2fa4e7;}
 .badge-info {background-color:#23c6c8;}
 .badge.circle {border-radius:50px;}
-.dep3 .badge {position:relative; top:-28px; right:20px;}
+.dep3 .badge {position:relative; top:-28px; right:15px;}
 
 /* badge-등급 ------------*/
 .badgeLevel{overflow:hidden;display:inline-block;margin:5px 0 0;padding:0;width:50px;height:50px;line-height:46px;font-size:30px;font-weight:bold;border-radius:100%;text-align:center;vertical-align:top;box-sizing:border-box;}
@@ -422,7 +422,7 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .badgeLevel.black{background-color:#333;border:1px solid #333;color:#fff;}
 
 /* tag */
-.tagNum {display:inline-block; margin-left:5px; padding:0 3px 0 2px; min-width:13px; line-height:16px; font-weight:normal; color:#fc5555; background:#fff; border-radius:5px;}
+.tagNum {display:inline-block; margin-left:5px; padding:0 3px; min-width:16px; line-height:16px; font-weight:normal; color:#fc5555; background:#fff; border-radius:5px;}
 
 /* footer --------------- */
 footer {position:absolute; bottom:0; left:0; width:100%; height:40px; background-color:#fff; border-top:1px solid #e7eaec; line-height:39px; font-size:13px;}
@@ -445,8 +445,8 @@ footer .f-right {float:right; padding-right:20px; line-height:38px;}
 .imgCard img {margin-right:15px;}
 .imgCard li:nth-of-type(2) {padding-top:20px; max-width:150px; line-height:24px}
 .imgCard p {font-size:12px;}
-.imgCard .cardClose {position:absolute; top:0; right:0; width:24px; background:url('../../image/btn_sltClose.png') no-repeat 50% 50%; text-indent:-9999px;}
-.imgCard .cardClose:hover {background:#f1f1f1 url('../../image/btn_sltCloseOn.png') no-repeat 50% 50%;}
+.imgCard .cardClose {position:absolute; top:0; right:0; width:24px; background:url('/image/btn_sltClose.png') no-repeat 50% 50%; text-indent:-9999px;}
+.imgCard .cardClose:hover {background:#f1f1f1 url('/image/btn_sltCloseOn.png') no-repeat 50% 50%;}
 .verticalTop {vertical-align:top;}
 
 /* 조회용 이미지 카드 */
@@ -454,14 +454,14 @@ footer .f-right {float:right; padding-right:20px; line-height:38px;}
 .cardArea2 ul, .cardArea2 .box {vertical-align:top; position:relative; display:inline-block; margin:10px; border:1px solid #dbdbdb; max-width:300px;}
 .cardArea2 li {display:table-cell; line-height:26px; vertical-align:middle;}
 .cardArea2 li:nth-of-type(2) {padding:0 10px;}
-.cardArea2 .cardDel {position:absolute; top:0; right:0; background:url('../../image/btn_sltClose.png') no-repeat 50% 50%; text-indent:-9999px;}
-.cardArea2 .cardDel:hover {background:#f1f1f1 url('../../image/btn_sltCloseOn.png') no-repeat 50% 50%;}
+.cardArea2 .cardDel {position:absolute; top:0; right:0; background:url('/image/btn_sltClose.png') no-repeat 50% 50%; text-indent:-9999px;}
+.cardArea2 .cardDel:hover {background:#f1f1f1 url('/image/btn_sltCloseOn.png') no-repeat 50% 50%;}
 
 /* 테이블 외부 안내문구 */
 .panelStyle > .notice {margin:0 0 15px ;}
 .panelContent > .notice {margin:15px 0;}
 .notice em {color:red;}
-.notice li, p.dot {padding-left:20px; background:url('../../image/dot_bk.png') no-repeat 5px 10px; line-height:24px;}
+.notice li, p.dot {padding-left:20px; background:url('/image/dot_bk.png') no-repeat 5px 10px; line-height:24px;}
 p.dot .btn {margin-left:10px !important;}
 p.dot em {color:red;}
 
@@ -485,14 +485,14 @@ p.dot em {color:red;}
 
 /* 유의사항 안내 */
 .infoBox {margin:0 20px 20px; padding:7px 10px; border-top:2px solid #dfe2e3; border-bottom:2px solid #dfe2e3; background:#fff}
-.infoBox p {padding-left:25px; line-height:20px; font-size:12px; background:url('../../image/dot_bk.png') no-repeat 10px 50%; background-size:3px auto;}
+.infoBox p {padding-left:25px; line-height:20px; font-size:12px; background:url('/image/dot_bk.png') no-repeat 10px 50%; background-size:3px auto;}
 
 /* 검색결과 안내문 */
 .srchNotice {padding-bottom:7px; font-weight:normal; font-size:14px;}
 .srchNotice em {color:red;}
 
 /* 필수입력항목 */
-.required {display:inline-block; position:relative; top:-3px; width:12px; height:7px; background:url('../../image/icon_required.png') no-repeat 0 50%;}
+.required {display:inline-block; position:relative; top:0; width:12px; height:7px; background:url('/image/icon_required.png') no-repeat 0 50%;}
 
 
 /* COLOR DESIGN -------------------------------------*/
@@ -648,8 +648,8 @@ hr {border:0; padding-bottom:10px;}/* 기본 여백 :10px */
 /*-- 회원추가 --------------*/
 .memAddWrap {line-height:26px; padding:3px 0;}
 .memAdd {margin-right:15px; padding:2px 27px 2px 0; position:relative; line-height:24px; height:24px; white-space:nowrap;}
-.memAdd button {position:absolute; top:3px; right:0; bottom:0; width:18px; height:18px; border:1px solid #dbdbdb; border-radius:3px; text-indent:-9999px; background:#eee url('../../image/btn_sltClose.png') no-repeat 50% 50%;}
-.memAdd button:hover {background:#eee url('../../image/btn_sltCloseOn.png') no-repeat 50% 50%;}
+.memAdd button {position:absolute; top:3px; right:0; bottom:0; width:18px; height:18px; border:1px solid #dbdbdb; border-radius:3px; text-indent:-9999px; background:#eee url('/image/btn_sltClose.png') no-repeat 50% 50%;}
+.memAdd button:hover {background:#eee url('/image/btn_sltCloseOn.png') no-repeat 50% 50%;}
 
 /*-- Date Picker --------------*/ /* 20200521 수정 */
 table.mtz-monthpicker {border:1px solid #ddd; border-top:none;}
@@ -659,8 +659,8 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none;}
 .ui-datepicker .ui-datepicker-today,
 .ui-datepicker .ui-state-highlight {background:#fff7cf !important;}
 .ui-datepicker .ui-state-active {border:1px solid red !important;}
-.ui-datepicker .ui-datepicker-prev {position:absolute; top:3px; left:3px; width:30px; line-height:30px; text-indent:-9999px; background:url('../../image/icon_prev.png') no-repeat 50% 50%;}
-.ui-datepicker .ui-datepicker-next {position:absolute; top:3px; right:3px; width:30px; line-height:30px; text-indent:-9999px; background:url('../../image/icon_next.png') no-repeat 50% 50%;}
+.ui-datepicker .ui-datepicker-prev {position:absolute; top:3px; left:3px; width:30px; line-height:30px; text-indent:-9999px; background:url('/image/icon_prev.png') no-repeat 50% 50%;}
+.ui-datepicker .ui-datepicker-next {position:absolute; top:3px; right:3px; width:30px; line-height:30px; text-indent:-9999px; background:url('/image/icon_next.png') no-repeat 50% 50%;}
 .ui-datepicker .ui-datepicker-calendar {padding:5px; border:1px solid #ddd; border-top:none; text-align:center;}
 .ui-datepicker .ui-datepicker-calendar th{padding:5px 0}
 .ui-datepicker-week-end {text-align:center;}
@@ -816,12 +816,12 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none;}
 /* 카테고리 Sort */
 .categoryOrder {margin-bottom:15px; background:#fcfcfc;}
 .categoryOrder li {clear:both; padding-left:15px; line-height:40px; cursor:move; border-top:1px dashed red; }
-.categoryOrder li button.on {background-image:url(../../image/icon_cate_minus.png);}
-/* .categoryOrder li:after {content:''; position:absolute; top:8px; left:-10px; width:21px; height:21px; background:url(../../image/line_cate.png)} */
+.categoryOrder li button.on {background-image:url(/image/icon_cate_minus.png);}
+/* .categoryOrder li:after {content:''; position:absolute; top:8px; left:-10px; width:21px; height:21px; background:url(/image/line_cate.png)} */
 .categoryOrder li:before{position:relative; content:''; width:1px; height:100%; background:#ddd;}
 .categoryOrder li ol{display:none}
 /* .categoryOrder ol:last-child li {background-image:none !important} */
-.categoryOrder button{position:relative; z-index:200; padding:0 15px 0; margin:0; line-height:40px; cursor:pointer; background-image:url(../../image/icon_cate_plus.png); background-repeat:no-repeat; background-position:0 0;}
+.categoryOrder button{position:relative; z-index:200; padding:0 15px 0; margin:0; line-height:40px; cursor:pointer; background-image:url(/image/icon_cate_plus.png); background-repeat:no-repeat; background-position:0 0;}
 
 /* 메인 공지팝업 */
 .noticeWrap{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);width:800px;background-color:#fff;}

+ 397 - 0
src/main/webapp/ux/css/dropzone.css

@@ -0,0 +1,397 @@
+/*
+ * The MIT License
+ * Copyright (c) 2012 Matias Meno <m@tias.me>
+ */
+@-webkit-keyframes passing-through {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30%, 70% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); }
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-40px);
+    -moz-transform: translateY(-40px);
+    -ms-transform: translateY(-40px);
+    -o-transform: translateY(-40px);
+    transform: translateY(-40px); } }
+@-moz-keyframes passing-through {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30%, 70% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); }
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-40px);
+    -moz-transform: translateY(-40px);
+    -ms-transform: translateY(-40px);
+    -o-transform: translateY(-40px);
+    transform: translateY(-40px); } }
+@keyframes passing-through {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30%, 70% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); }
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-40px);
+    -moz-transform: translateY(-40px);
+    -ms-transform: translateY(-40px);
+    -o-transform: translateY(-40px);
+    transform: translateY(-40px); } }
+@-webkit-keyframes slide-in {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); } }
+@-moz-keyframes slide-in {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); } }
+@keyframes slide-in {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(40px);
+    -moz-transform: translateY(40px);
+    -ms-transform: translateY(40px);
+    -o-transform: translateY(40px);
+    transform: translateY(40px); }
+  30% {
+    opacity: 1;
+    -webkit-transform: translateY(0px);
+    -moz-transform: translateY(0px);
+    -ms-transform: translateY(0px);
+    -o-transform: translateY(0px);
+    transform: translateY(0px); } }
+@-webkit-keyframes pulse {
+  0% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); }
+  10% {
+    -webkit-transform: scale(1.1);
+    -moz-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    -o-transform: scale(1.1);
+    transform: scale(1.1); }
+  20% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); } }
+@-moz-keyframes pulse {
+  0% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); }
+  10% {
+    -webkit-transform: scale(1.1);
+    -moz-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    -o-transform: scale(1.1);
+    transform: scale(1.1); }
+  20% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); } }
+@keyframes pulse {
+  0% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); }
+  10% {
+    -webkit-transform: scale(1.1);
+    -moz-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    -o-transform: scale(1.1);
+    transform: scale(1.1); }
+  20% {
+    -webkit-transform: scale(1);
+    -moz-transform: scale(1);
+    -ms-transform: scale(1);
+    -o-transform: scale(1);
+    transform: scale(1); } }
+.dropzone, .dropzone * {
+  box-sizing: border-box; }
+
+.dropzoneWrap{margin:7px 0} /*추가*/
+.dropzone {
+  min-height: 150px;
+  border: 1px dashed #bbbbbb;
+  background: white;
+  /*padding: 10px;*/ }
+  .dropzone.dz-clickable {
+    cursor: pointer; }
+    .dropzone.dz-clickable * {
+      cursor: default; }
+    .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
+      cursor: pointer; }
+  .dropzone.dz-started .dz-message {
+    display: none; }
+  .dropzone.dz-drag-hover {
+    border-style: solid; }
+    .dropzone.dz-drag-hover .dz-message {
+      opacity: 0.5; }
+  .dropzone .dz-message {
+    text-align: center;
+    line-height:150px;}
+    .dropzone .dz-message .dz-button {
+      background: none;
+      color: inherit;
+      border: none;
+      padding: 0;
+      font: inherit;
+      cursor: pointer;
+      outline: inherit; }
+  .dropzone .dz-preview {
+    position: relative;
+    display: inline-block;
+    vertical-align: top;
+    margin: 16px;
+    min-height: 100px; }
+    .dropzone .dz-preview:hover {
+      z-index: 1000; }
+      .dropzone .dz-preview:hover .dz-details {
+        opacity: 1; }
+    .dropzone .dz-preview.dz-file-preview .dz-image {
+      border-radius: 20px;
+      background: #999;
+      background: linear-gradient(to bottom, #eee, #ddd); }
+    .dropzone .dz-preview.dz-file-preview .dz-details {
+      opacity: 1; }
+    .dropzone .dz-preview.dz-image-preview {
+      background: white; }
+      .dropzone .dz-preview.dz-image-preview .dz-details {
+        -webkit-transition: opacity 0.2s linear;
+        -moz-transition: opacity 0.2s linear;
+        -ms-transition: opacity 0.2s linear;
+        -o-transition: opacity 0.2s linear;
+        transition: opacity 0.2s linear; }
+    .dropzone .dz-preview .dz-remove {
+      font-size: 14px;
+      text-align: center;
+      display: block;
+      cursor: pointer;
+      border: none; }
+      .dropzone .dz-preview .dz-remove:hover {
+        text-decoration: underline; }
+    .dropzone .dz-preview:hover .dz-details {
+      opacity: 1; }
+    .dropzone .dz-preview .dz-details {
+      z-index: 20;
+      position: absolute;
+      top: 0;
+      left: 0;
+      opacity: 0;
+      font-size: 13px;
+      min-width: 100%;
+      max-width: 100%;
+      padding: 2em 1em;
+      text-align: center;
+      color: rgba(0, 0, 0, 0.9);
+      line-height: 150%; }
+      .dropzone .dz-preview .dz-details .dz-size {
+        margin-bottom: 1em;
+        font-size: 16px; }
+      .dropzone .dz-preview .dz-details .dz-filename {
+        white-space: nowrap; }
+        .dropzone .dz-preview .dz-details .dz-filename:hover span {
+          border: 1px solid rgba(200, 200, 200, 0.8);
+          background-color: rgba(255, 255, 255, 0.8); }
+        .dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
+          overflow: hidden;
+          text-overflow: ellipsis; }
+          .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
+            border: 1px solid transparent; }
+      .dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
+        background-color: rgba(255, 255, 255, 0.4);
+        padding: 0 0.4em;
+        border-radius: 3px; }
+    .dropzone .dz-preview:hover .dz-image img {
+      -webkit-transform: scale(1.05, 1.05);
+      -moz-transform: scale(1.05, 1.05);
+      -ms-transform: scale(1.05, 1.05);
+      -o-transform: scale(1.05, 1.05);
+      transform: scale(1.05, 1.05);
+      -webkit-filter: blur(8px);
+      filter: blur(8px); }
+    .dropzone .dz-preview .dz-image {
+      border-radius: 20px;
+      overflow: hidden;
+      width: 120px;
+      height: 120px;
+      position: relative;
+      display: block;
+      z-index: 10; }
+      .dropzone .dz-preview .dz-image img {
+        display: block; }
+    .dropzone .dz-preview.dz-success .dz-success-mark {
+      -webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
+      animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); }
+    .dropzone .dz-preview.dz-error .dz-error-mark {
+      opacity: 1;
+      -webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
+      -o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
+      animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); }
+    .dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
+      pointer-events: none;
+      opacity: 0;
+      z-index: 500;
+      position: absolute;
+      display: block;
+      top: 50%;
+      left: 50%;
+      margin-left: -27px;
+      margin-top: -27px; }
+      .dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
+        display: block;
+        width: 54px;
+        height: 54px; }
+    .dropzone .dz-preview.dz-processing .dz-progress {
+      opacity: 1;
+      -webkit-transition: all 0.2s linear;
+      -moz-transition: all 0.2s linear;
+      -ms-transition: all 0.2s linear;
+      -o-transition: all 0.2s linear;
+      transition: all 0.2s linear; }
+    .dropzone .dz-preview.dz-complete .dz-progress {
+      opacity: 0;
+      -webkit-transition: opacity 0.4s ease-in;
+      -moz-transition: opacity 0.4s ease-in;
+      -ms-transition: opacity 0.4s ease-in;
+      -o-transition: opacity 0.4s ease-in;
+      transition: opacity 0.4s ease-in; }
+    .dropzone .dz-preview:not(.dz-processing) .dz-progress {
+      -webkit-animation: pulse 6s ease infinite;
+      -moz-animation: pulse 6s ease infinite;
+      -ms-animation: pulse 6s ease infinite;
+      -o-animation: pulse 6s ease infinite;
+      animation: pulse 6s ease infinite; }
+    .dropzone .dz-preview .dz-progress {
+      opacity: 1;
+      z-index: 1000;
+      pointer-events: none;
+      position: absolute;
+      height: 16px;
+      left: 50%;
+      top: 50%;
+      margin-top: -8px;
+      width: 80px;
+      margin-left: -40px;
+      background: rgba(255, 255, 255, 0.9);
+      -webkit-transform: scale(1);
+      border-radius: 8px;
+      overflow: hidden; }
+      .dropzone .dz-preview .dz-progress .dz-upload {
+        background: #333;
+        background: linear-gradient(to bottom, #666, #444);
+        position: absolute;
+        top: 0;
+        left: 0;
+        bottom: 0;
+        width: 0;
+        -webkit-transition: width 300ms ease-in-out;
+        -moz-transition: width 300ms ease-in-out;
+        -ms-transition: width 300ms ease-in-out;
+        -o-transition: width 300ms ease-in-out;
+        transition: width 300ms ease-in-out; }
+    .dropzone .dz-preview.dz-error .dz-error-message {
+      display: block; }
+    .dropzone .dz-preview.dz-error:hover .dz-error-message {
+      opacity: 1;
+      pointer-events: auto; }
+    .dropzone .dz-preview .dz-error-message {
+      pointer-events: none;
+      z-index: 1000;
+      position: absolute;
+      display: block;
+      display: none;
+      opacity: 0;
+      -webkit-transition: opacity 0.3s ease;
+      -moz-transition: opacity 0.3s ease;
+      -ms-transition: opacity 0.3s ease;
+      -o-transition: opacity 0.3s ease;
+      transition: opacity 0.3s ease;
+      border-radius: 8px;
+      font-size: 13px;
+      top: 130px;
+      left: -10px;
+      width: 140px;
+      background: #be2626;
+      background: linear-gradient(to bottom, #be2626, #a92222);
+      padding: 0.5em 1.2em;
+      color: white; }
+      .dropzone .dz-preview .dz-error-message:after {
+        content: '';
+        position: absolute;
+        top: -6px;
+        left: 64px;
+        width: 0;
+        height: 0;
+        border-left: 6px solid transparent;
+        border-right: 6px solid transparent;
+        border-bottom: 6px solid #be2626; }

+ 34 - 1
src/main/webapp/ux/js/admin.popup.js

@@ -579,7 +579,7 @@ var cfnOpenCouponRetrievePopup = function(sName, oParam) {
  * @author : yujung
  */
 var cfnOpenPlanPopup = function(callbackfun) {
-	var actionUrl = "/marketing/plan/list/popup";
+	var actionUrl = "/marketing/planning/list/popup";
 	if (typeof(callbackfun) != 'undefined') actionUrl += "?callBackFun=" + callbackfun;
 
 	cfnOpenModalPopup(actionUrl,'popupPlan');
@@ -691,6 +691,23 @@ var cfnOpenBrandListPopup = function(callbackfn, multiGb, searchTxt) {
 	cfnOpenModalPopup(actionUrl, "popupBrandList");
 }
 
+/**
+ * @type   : function
+ * @access : public
+ * @desc   : 브랜드 그룹 목록 팝업
+ * <pre>
+ *     cfnOpenBrandGroupListPopup('fnResult', 'S', 'S');
+ * </pre>
+ * @since  : 2021/02/23
+ * @author : eskim
+ */
+var cfnOpenBrandGroupListPopup = function(callbackfn, multiGb, type) {
+	var actionUrl = '/business/brand/group/popup/form?callbackFn=' + callbackfn;
+	if (typeof(multiGb) != 'undefined' && multiGb != null && multiGb == "M") actionUrl += "&multiGb=" + multiGb; else actionUrl += "&multiGb=S";
+	if (typeof(type) != 'undefined' && type != null && type == "C") actionUrl += "&type=" + type; else actionUrl += "&type=S";
+	cfnOpenModalPopup(actionUrl, "popupBrandGroup");
+}
+
 /**
  * @type   : function
  * @access : public
@@ -856,3 +873,19 @@ var cfnOpenGoodsDispOrdChangePopup = function(callbackfun, params) {
 	if (typeof(params) != 'undefined') actionUrl += "&" + params;
 	cfnOpenModalPopup(actionUrl,'popupGoodsDispOrdChange');
 }
+
+/**
+ * @type   : function
+ * @access : public
+ * @desc   : 메인전시 컨텐츠 수정 팝업 오픈
+ * <pre>
+ *     cfnOpenMainContentsPopup(cateCd, contentsLoc);
+ * </pre>
+ * @since  : 2021/02/23
+ * @author : bin2107
+ */
+var cfnOpenMainContentsPopup = function(cateNo, contentsLoc) {
+	var actionUrl = "/display/main/contents/popup/form?cateNo="+cateNo+"&contentsLoc=" + contentsLoc;
+	//uifnPopClose('popupMainContents');
+	cfnOpenModalPopup(actionUrl, 'popupMainContents');
+}

+ 43 - 48
src/main/webapp/ux/js/admin.ui.js

@@ -174,60 +174,55 @@ $(document).ready(function(){
 	});
 
 	$(document).on("click", ".chkBox", function(e){
-		let cntId = $(this).parent().parent("ul").attr("data-count-id");
-		let cntLen;
-
-		if ( $(this).find("input").is('[id]') ){ // ---------------전체선택ID
-			let $id = $(this).find("input").attr("id");
-			if ( $(this).hasClass("checked") ) { //체크된 경우
-				$("input[id="+$id+"]").parent("label").removeClass("checked");
-				$("input[id="+$id+"]").prop("checked", false);
-				$("input[name="+$id+"]").parent("label").removeClass("checked");
-				$("input[name="+$id+"]").prop("checked", false);
-			} else {
-				$("input[id="+$id+"]").parent("label").addClass("checked");
-				$("input[id="+$id+"]").prop("checked", true);
-				$("input[name="+$id+"]").parent("label").addClass("checked");
-				$("input[name="+$id+"]").prop("checked", true);
-			};
-			//선택된 개수 출력 (checkBoxList)
-			if (cntId != undefined ) {
-				cntLen =  $("input[name="+$id+"]:checked").length; //체크된 개수
-				$("#"+cntId).text(cntLen);
-			};
-			return false;
+		if (  !$(this).children("input").is("[disabled]")  && !$(this).children("input").is("[readonly]") ) {
 
-		} else {	// ---------------개별선택
-			let $name = $(this).find("input").attr("name");
-			let totLen = $("input[name="+$name+"]").length; //전체 개수
-			if ( $(this).hasClass("checked")) {
-				$(this).removeClass("checked");
-				$(this).find("input").prop("checked", false);
-				$("input[id="+$name+"]").prop("checked", false);
-				$("input[id="+$name+"]").parent("label").removeClass("checked");
-			} else {
-				$(this).addClass("checked");
-				$(this).find("input").prop("checked", true);
-				cntLen =  $("input[name="+$name+"]:checked").length; //체크된 개수
-				if (totLen == cntLen ){
-					$("input[id="+$name+"]").prop("checked", true);
-					$("input[id="+$name+"]").parent("label").addClass("checked");
-				}
-			};
-			//선택된 개수 출력 (checkBoxList)
-			if (cntId != undefined ) {
-				cntLen =  $("input[name="+$name+"]:checked").length; //체크된 개수
-				if (totLen > cntLen ) {
+			let cntId = $(this).parent().parent("ul").attr("data-count-id");
+			let cntLen;
+
+			if ( $(this).children("input").is('[id]') ){ // ---------------전체선택ID
+				let $id = $(this).children("input").attr("id");
+				if ( $(this).children("input").is(":checked") ) { //체크된 경우
+					$("input[id="+$id+"]").prop("checked", false);
+					$("input[name="+$id+"]").prop("checked", false);
+				} else {
+					$("input[id="+$id+"]").prop("checked", true);
+					$("input[name="+$id+"]").prop("checked", true);
+				};
+				//선택된 개수 출력 (checkBoxList)
+				if (cntId != undefined ) {
+					cntLen =  $("input[name="+$id+"]:checked").length; //체크된 개수
 					$("#"+cntId).text(cntLen);
-				} else if  (totLen == cntLen ) {
-					$("#"+cntId).text(totLen);
 				};
+				return false;
+
+			} else {	// ---------------개별선택
+				let $name = $(this).find("input").attr("name");
+				let totLen = $("input[name="+$name+"]").length; //전체 개수
+				if ( $(this).children("input").is(":checked") ) {
+					$(this).find("input").prop("checked", false);
+					$("input[id="+$name+"]").prop("checked", false); //전체선택 체크 해제
+				} else {
+					//$(this).addClass("checked");
+					$(this).find("input").prop("checked", true);
+					cntLen =  $("input[name="+$name+"]:checked").length; //체크된 개수
+					if (totLen == cntLen ){
+						$("input[id="+$name+"]").prop("checked", true); //전체선택 체크
+					}
+				};
+				//선택된 개수 출력 (checkBoxList)
+				if (cntId != undefined ) {
+					cntLen =  $("input[name="+$name+"]:checked").length; //체크된 개수
+					if (totLen > cntLen ) {
+						$("#"+cntId).text(cntLen);
+					} else if  (totLen == cntLen ) {
+						$("#"+cntId).text(totLen);
+					};
+				};
+				return false;
 			};
-			return false;
-		};
+		}
 	});
 
-
 	/* CheckBox List : More(+) 버튼 */
 	$(document).on("click", ".checkBoxList .more", function(){
 		var thisI = $(this).find("i");

+ 1 - 1
src/main/webapp/ux/plugins/summernote/summernote.js

@@ -6694,7 +6694,7 @@ var Codeview_CodeView = /*#__PURE__*/function () {
       var value = this.purify(dom.value(this.$codable, this.options.prettifyHtml) || dom.emptyPara);
       var isChange = this.$editable.html() !== value;
       this.$editable.html(value);
-      this.$editable.height(this.options.height ? this.$codable.height() : 'auto');
+    //  this.$editable.height(this.options.height ? this.$codable.height() : 'auto');
       this.$editor.removeClass('codeview');
 
       if (isChange) {