Bläddra i källkod

Merge remote-tracking branch 'origin/develop' into jsh77b

tsit14 5 år sedan
förälder
incheckning
9b94d19d6a

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

@@ -541,5 +541,51 @@ public interface TsaPlanDao {
 	 * @since 2021. 4. 6
 	 */
 	void createPlanAttendBenefitCopy(Plan param);
+	
+	/**
+	 * 기획전 댓글 목록
+	 *
+	 * @param 
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	Collection<Plan> getPlanReplyList(Plan param);
+	
+	/**
+	 * 기획전 리스트 카운트 조회
+	 * @param  param
+	 * @return int
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	int getPlanReplyListCount(Plan param);
+	
+	/**
+	 * 기획전 댓글 사진 목록
+	 *
+	 * @param 
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	Collection<Plan> getPlanReplyAttachList(Plan param);
+	
+	/**
+	 * 기획전 댓글 삭제
+	 * @param 
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	void deleteReply(Plan param);
+	
+	/**
+	 * 기획전 댓글 이미지 삭제
+	 * @param 
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	void deleteReplyAttach(Plan param);
+	
 
 }

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

@@ -1672,7 +1672,55 @@ public class TsaPlanService {
 		return planDao.getPlanAttendBenefitList(plan);
 	}
 
+	/**
+	 * 기획전 댓글 목록
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	public Collection<Plan> getPlanReplyList(Plan param) {
+		return planDao.getPlanReplyList(param);
+	}
 	
+	/**
+	 * 기획전 리스트 카운트 조회
+	 * @param  param
+	 * @return int
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	public int getPlanReplyListCount(Plan param) {
+		return planDao.getPlanReplyListCount(param);
+	}
 
+	/**
+	 * 기획전 댓글 사진 목록
+	 *
+	 * @param 
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	public Collection<Plan> getPlanReplyAttachList(Plan param){
+		return planDao.getPlanReplyAttachList(param);
+	}
 
+	/**
+	 * 기획전 댓글 삭제
+	 * @param 
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteReply(Collection<Plan> paramList) {
+		
+		for (Plan plan : paramList) {
+			planDao.deleteReply(plan);
+			planDao.deleteReplyAttach(plan);
+		}
+	}
+		
+		
 }

+ 74 - 0
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -1945,6 +1945,80 @@ public class TsaMarketingController extends TsaBaseController {
 
 		return mav;
 	}
+	
+	/**
+	 * 기획전 댓글 팝업 화면
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	@GetMapping("/planning/reply/form")
+	public ModelAndView planReplyListForm(Plan param) {
+		ModelAndView mav = new ModelAndView();
+
+		// 기획전 상세 정보
+		mav.addObject("planInfo", planService.getPlanDetailInfo(param));
+
+		mav.setViewName("marketing/PlanReplyListForm");
+
+		return mav;
+	}
+	
+	/**
+	 * 기획전 댓글 리스트
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	@PostMapping("/planning/reply/list")
+	@ResponseBody
+	public GagaMap planReplyL(@RequestBody Plan param) {
+		GagaMap result = new GagaMap();
+
+		// 기획전 상세 정보
+		param.setPageable(new TscPageRequest(param.getPageNo() - 1, param.getPageSize()));
+		param.getPageable().setTotalCount(planService.getPlanReplyListCount(param));
+
+		Collection<Plan> planReplyList = planService.getPlanReplyList(param);
+			
+		result.set("pageing", param);
+		result.set("planReplyList", planReplyList);
+		return result;
+	}
+	
+	/**
+	 * 기획전 댓글 삭제
+	 *
+	 * @param
+	 * @return 기획전 댓글 삭제
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	@PostMapping("/planning/reply/delete")
+	@ResponseBody
+	public GagaResponse deleteReply(@RequestBody Collection<Plan> paramList) {
+		planService.deleteReply(paramList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+	
+	/**
+	 * 기획전 댓글 상세 팝업 화면
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 24
+	 */
+	@GetMapping("/planning/reply/detail/form")
+	public ModelAndView planReplyDetailForm(Plan param) {
+		ModelAndView mav = new ModelAndView();
+		mav.addObject("attachList", planService.getPlanReplyAttachList(param));
+		mav.addObject("replyInfo", planService.getPlanReplyList(param));
+		mav.setViewName("marketing/PlanReplyDetailForm");
+
+		return mav;
+	}
 
 	/**
 	 * 기획전 코너 목록

+ 2 - 0
src/main/java/com/style24/persistence/domain/Batch.java

@@ -19,6 +19,8 @@ public class Batch extends TscBaseDomain {
 	private String bizGb;		// 업무구분
 	private String batchFrq;	// 배치주기
 	private String batchDesc;	// 배치설명
+	private String batchUrl;	// 배치URL
+	private String batchStat;	// 배치상태
 	private String useYn;		// 사용여부
 
 	// 배치 목록 검색조건

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

@@ -82,6 +82,11 @@ public class Counsel extends TscBaseDomain {
 		return this.custNm;
 	}
 
+	public String getCellPhnno() {
+		this.cellPhnno = CryptoUtils.decryptAES(this.cellPhnno);
+		return this.cellPhnno;
+	}
+
 	public String getEmail() {
 		this.email = CryptoUtils.decryptAES(this.email);
 		return this.email;
@@ -96,7 +101,7 @@ public class Counsel extends TscBaseDomain {
 	}
 
 	public String getMaskingCellPhnno() {
-		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.phoneNo(cellPhnno) : cellPhnno;
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.phoneNo(getCellPhnno()) : getCellPhnno();
 	}
 
 	public String getMaskingEmail() {

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

@@ -6,6 +6,9 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.style24.admin.biz.dao.TsaPlanDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.util.CryptoUtils;
+import com.style24.core.support.util.MaskingUtils;
 import com.style24.persistence.TscBaseDomain;
 import com.style24.persistence.TscPageRequest;
 
@@ -109,6 +112,15 @@ public class Plan extends TscBaseDomain{
 		private String cateNm;		// 카테고리명
 		private String cateNo;		// 카테고리번호
 		
+		// 댓글
+		private String entryDt;
+		private String entryVal1;
+		private Integer entryCustNo;
+		private Integer custNo;
+		private String custNm;
+		private Integer planEntrySq;
+		private String sysFile;
+		
 		// 기획전 응모
 		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 		private String[] planQtitle;
@@ -317,4 +329,12 @@ public class Plan extends TscBaseDomain{
 		List<Plan> multiPlanGoodsContentVal9; 
 		@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 		List<Plan> multiPlanGoodsContentVal10; 
+		// 암호화 대상 복호화 처리
+		public String getCustNm() {
+			this.custNm = CryptoUtils.decryptAES(this.custNm);
+			return this.custNm;
+		}
+		public String getMaskingCustNm() {
+			return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.name(getCustNm()) : getCustNm();
+		}
 }

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

@@ -2979,7 +2979,7 @@
 	<!-- 동영상  수정 -->
 	<update id="updateGoodsVideo" parameterType="GoodsVideo">
 		/* TsaGoods.saveGoodsVideo */
-		UPDATE TB_VIDEO SET
+		UPDATE TB_GOODS_VIDEO SET
 		           DISP_YN = #{dispYn}
 		         , VIDEO_GB = #{videoGb}
 		         , KMC_KEY = #{kmcKey}

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

@@ -1352,6 +1352,61 @@
 		  AND BAS_DAYS = #{basDays}
 	</insert>
 	
+	<select id="getPlanReplyList" parameterType="Plan" resultType="Plan">
+		/* TsaPlan.getPlanReplyList */
+		SELECT Z.*
+		FROM(
+		      SELECT @rownum := @rownum + 1 AS RNUM
+		             ,A.*
+		       FROM(
+		             SELECT  P.PLAN_SQ 
+		                   , PE.ENTRY_DT 
+		                   , PE.ENTRY_VAL1 
+		                   , PE.ENTRY_CUST_NO AS CUST_NO
+		                   , PE.PLAN_ENTRY_SQ 
+		                   , C.CUST_NM
+		             FROM TB_PLAN P INNER JOIN TB_PLAN_ENTRY PE
+		                              ON P.PLAN_SQ = PE.PLAN_SQ
+		                             INNER JOIN TB_CUSTOMER C
+		                              ON PE.ENTRY_CUST_NO = C.CUST_NO 
+		                            JOIN ( SELECT @rownum := 0) R
+		             WHERE P.PLAN_SQ = #{planSq}
+		             <if test="planEntrySq != null and planEntrySq != ''">
+		              AND   PE.PLAN_ENTRY_SQ = #{planEntrySq}  
+		             </if>
+		             ORDER  BY PLAN_ENTRY_SQ DESC
+		<include refid="getListPagingCondition_sql"/>
+	</select>
+	
+	<select id="getPlanReplyListCount" parameterType="Plan" resultType="int">
+		/* TsaPlan.getPlanReplyListCount */
+		SELECT COUNT(*) AS CNT
+		FROM TB_PLAN P INNER JOIN TB_PLAN_ENTRY PE
+		                 ON P.PLAN_SQ = PE.PLAN_SQ
+		WHERE P.PLAN_SQ = #{planSq}
+	</select>
+	
+	<select id="getPlanReplyAttachList" parameterType="Plan" resultType="Plan">
+		/* TsaPlan.getPlanReplyAttachList */
+		SELECT  PEA.PLAN_ENTRY_AT_SQ 
+		      , PEA.SYS_FILE_NM AS SYS_FILE
+		FROM TB_PLAN_ENTRY PE INNER JOIN TB_PLAN_ENTRY_ATTACH PEA 
+		                      ON PE.PLAN_ENTRY_SQ = PEA.PLAN_ENTRY_SQ 
+		WHERE PE.PLAN_ENTRY_SQ = #{planEntrySq}
+		AND PE.PLAN_ENTRY_SQ = PEA.PLAN_ENTRY_SQ
+	</select>
+	
+	<delete id="deleteReply" parameterType="Plan">
+		/* TsaPlan.deleteReply */
+		DELETE FROM TB_PLAN_ENTRY
+		WHERE PLAN_ENTRY_SQ = #{planEntrySq}
+	</delete>
+	
+	<delete id="deleteReplyAttach" parameterType="Plan">
+		/* TsaPlan.deleteReplyAttach */
+		DELETE FROM TB_PLAN_ENTRY_ATTACH
+		WHERE PLAN_ENTRY_SQ = #{planEntrySq}
+	</delete>
 </mapper>
 
 

+ 8 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaSystem.xml

@@ -781,6 +781,8 @@
 		     , BIZ_GB
 		     , BATCH_FRQ
 		     , BATCH_DESC
+		     , BATCH_URL
+		     , BATCH_STAT
 		     , USE_YN
 		FROM   TB_BATCH
 		WHERE  1 = 1
@@ -809,6 +811,7 @@
 		     , BIZ_GB
 		     , BATCH_FRQ
 		     , BATCH_DESC
+		     , BATCH_URL
 		     , USE_YN
 		     , REG_NO
 		     , REG_DT
@@ -821,6 +824,7 @@
 		     , #{bizGb}
 		     , #{batchFrq}
 		     , #{batchDesc}
+		     , #{batchUrl}
 		     , #{useYn}
 		     , #{regNo}
 		     , NOW()
@@ -832,6 +836,7 @@
 		     , BIZ_GB = #{bizGb}
 		     , BATCH_FRQ = #{batchFrq}
 		     , BATCH_DESC = #{batchDesc}
+		     , BATCH_URL = #{batchUrl}
 		     , USE_YN = #{useYn}
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()
@@ -851,6 +856,9 @@
 		FROM   TB_BATCH B
 		     , TB_BATCH_LOG BL
 		WHERE  B.BATCH_ID = BL.BATCH_ID
+		<if test="batchId != null and batchId != ''">
+		AND    B.BATCH_ID = #{batchId}
+		</if>
 		<if test="bizGb != null and bizGb != ''">
 		AND    B.BIZ_GB = #{bizGb}
 		</if>

+ 1 - 0
src/main/resources/config/application-locd.yml

@@ -19,6 +19,7 @@ logging:
 domain:
     admin: //ldadmin.style24.com
     front: //ldfront.style24.com
+    batch: //ldbatch.style24.com
     image: //ldimage.style24.com
     uximage: //ldadmin.style24.com
 

+ 5 - 4
src/main/resources/config/application-locp.yml

@@ -17,10 +17,11 @@ logging:
     config: classpath:log/logback-locp.xml
     
 domain:
-    admin: //lpadmin.wivismall.com
-    wivis: //lpfront.wivismall.com
-    image: //image.wivismall.com/speedy_image-wivismall
-    uximage: //lpadmin.wivismall.com
+    admin: //lpadmin.style24.com
+    front: //lpfront.style24.com
+    batch: //lpbatch.style24.com
+    image: //lpimage.style24.com
+    uximage: //lpadmin.style24.com
 
 upload:
     dext.target.path: /WIDE/workspace/files/data/style24/dext

+ 2 - 1
src/main/resources/config/application-run.yml

@@ -28,7 +28,8 @@ logging.config: classpath:log/logback-run.xml
 
 domain:
     admin: //bos.style24.com
-    style24: //www.style24.com
+    front: //www.style24.com
+    batch: //batch.style24.com
     image: //image.istyle24.com/Upload
     uximage: //bos.style24.com
 

+ 1 - 2
src/main/resources/config/application-style.yml

@@ -30,10 +30,9 @@ logging:
 
 domain:
     admin: //bos.style24.com
-    style24: //www.style24.com
     front: //www.style24.com
+    batch: //batch.style24.com
     image: //image.istyle24.com/Upload
-    cdnimage: //image.istyle24.com/Upload
     uximage: //bos.style24.com
 
 upload:

+ 1 - 0
src/main/webapp/WEB-INF/views/customer/GoodsQnaForm.html

@@ -175,6 +175,7 @@
 			headerName: "답변일시", field: "ansDt", width: 150, cellClass: 'text-center',
 			cellRenderer: function (params) { return gagaAgGrid.toDateTimeFormat(params.value); }
 		},
+		{headerName: "답변의뢰여부", field: "ansTransYn", width: 100, cellClass: 'text-center'},
 		{
 			headerName: "답변의뢰업체", field: "ansCompCd", width: 150, cellClass: 'text-center',
 			cellRenderer: function (params) { return gagaAgGrid.lookupValue(supplyCompList, params.value); }

+ 8 - 4
src/main/webapp/WEB-INF/views/display/MainContentsPopupForm.html

@@ -266,7 +266,7 @@
 					html += '	style="display:none;"';
 				}
 				html += '>';
-				html += '	<input type="hidden" name="htmlDesc'+i+'" id="htmlDesc'+i+'" value="'+result[i].html+'">';
+				html += '	<input type="hidden" name="htmlDesc'+i+'" id="htmlDesc'+i+'" value="'+result[i].html.replaceAll("\"","\'")+'">';
 				html += '	<th>오픈배너<br>HTML</th>';
 				html += '	<td class="padT10"><div class="tabJrContArea">';
 				html += '		<textarea class="textareaR3 summernote" name="openBannerDesc'+i+'" id="openBannerDesc'+i+'" ></textarea>';
@@ -440,6 +440,13 @@
 			let idx = $(this).find('[name=tableIdx]').val();
 			let bannerCateType = $("#mcTable"+idx).find('input:radio[name=cateType'+idx+']:checked').val();
 
+			if(bannerCateType=='OPEN'){
+				let htmlDesc = $("#mcTable"+idx).find('input[name=htmlDesc'+idx+']').val();
+				var snOptions1 = gagaSn.getToolbarOptions('media');
+				gagaSn.createSummernote(snOptions1, '#openBannerDesc'+idx);
+				// gagaSn.setContents('#openBannerDesc'+idx, '');
+				$('#openBannerDesc'+idx).summernote('code', htmlDesc);
+			}
 			// if(bannerCateType=='OPEN'){
 			// 	let bannerType = $("#mcTable"+idx).find('input:radio[name=openBannerType'+idx+']:checked').val();
 			// 	if(bannerType=='HTML'){
@@ -448,9 +455,6 @@
 			// 		$('#openBannerDesc'+idx).summernote('code', htmlDesc);
 			// 	}
 			// }
-			let htmlDesc = $("#mcTable"+idx).find('input[name=htmlDesc'+idx+']').val();
-			gagaSn.setContents('#openBannerDesc'+idx, '');
-			$('#openBannerDesc'+idx).summernote('code', htmlDesc);
 		});
 	}
 

+ 22 - 7
src/main/webapp/WEB-INF/views/marketing/PlanListForm.html

@@ -176,12 +176,15 @@
 			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:'replyYn'	, width:300 , cellClass: 'text-center',
+			cellRenderer: function(params) {
+				if(params.value === 'Y'){
+					return '<a href="javascript:void(0);">' + params.value + '</a>';
+				}else{
+					return params.value;
+				}
+			}
+		},
 		{headerName: "전시순서"		, field:'dispOrd'	, width:100, cellClass: 'text-right' },
 		{headerName: "진행시작일시"		, field:'dispStdt'	, width:150, cellClass: 'text-center'},
 		{headerName: "진행종료일시"		, field:'dispEddt'	, width:150, cellClass: 'text-center'},
@@ -199,10 +202,11 @@
 	// 셀 클릭 이벤트
 	gridOptions.onCellClicked = function(event) {
 		var field = event.colDef.field;
-		if (field != 'planSq' && field != 'planNm')
+		if (field != 'planSq' && field != 'planNm' && field != 'replyYn')
 			return;
 
 		fnBindDetail(field, event.data); // 바인딩
+
 	}
 	
 	// 바인딩
@@ -214,6 +218,10 @@
 		if (field == 'planNm') { // 기획전 관리 팝업
 			fnEventCornerPopup(rowData.planSq);
 		}
+		
+		if (field == 'replyYn') { // 기획전(이벤트) 댓글 팝업
+			fnEventReplyPopup(rowData.planSq);
+		}
 	}
 	
 
@@ -234,6 +242,13 @@
 		var actionUrl = "/marketing/planning/corner/list/form?planSq=" + planSq;
 		cfnOpenModalPopup(actionUrl, 'popupCorner');
 	}
+	
+	// 기획전 댓글 관리 팝업
+	var fnEventReplyPopup = function(planSq) {
+		var actionUrl = "/marketing/planning/reply/form?planSq=" + planSq;
+		cfnOpenModalPopup(actionUrl, 'popupReply');
+	}
+
 
 	// 미리보기
 	var fnPreview = function(planSq) {

+ 125 - 0
src/main/webapp/WEB-INF/views/marketing/PlanReplyDetailForm.html

@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ReviewDetailForm.html
+ * @desc    : 리뷰 상세 팝업 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.04.22   gagamel     최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="1200" id="popupReviewDetail">
+	<div class="panelStyle">
+		<!-- TITLE -->
+		<div class="panelTitle">
+			<strong>댓글 상세</strong>
+			<button type="button" class="close" onclick="uifnPopupClose('popupReviewDetail');"><em class="fa fa-times"></em></button>
+		</div>
+		<!-- //TITLE -->
+		
+		<!-- CONTENT -->
+		<div class="panelContent">
+			<form id="reviewDetailForm" name="reviewDetailForm" action="#" th:method="post" >
+				
+				<div class="reviewWrap">
+					<div class="user_review">
+						<!-- 리뷰 파일 -->
+						<dl class="rvPic">
+							<dt>이미지</dt>
+							<dd>
+								<div class="picList" id="divPicList">
+									<th:block th:if="${attachList != null}" th:each="oneData, status : ${attachList}">
+										<a  href="javascript:void(0);" onclick="fnPopupOpen('layer_review_pic', this);">
+											<span th:style="${'background-image:url(' + @environment.getProperty('domain.image') + oneData.sysFile + ');'}">사진</span>
+										</a>
+									</th:block>
+								</div>
+							</dd>
+						</dl>
+						
+						<dl class="rvTxt">
+							<dt>댓글</dt>
+							<th:block th:each="oneData, status : ${replyInfo}">
+							<dd style="width: 100%;" th:utext="${oneData.entryVal1}"></dd>
+							</th:block>
+						</dl>
+					</div>
+				</div>
+			</form>
+		</div>
+	</div>
+</div>
+
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	
+	
+	// 팝업 열기
+	function fnPopupOpen(id,el,kind) {
+		$("#"+id).removeClass("off");	//레이어 Open
+		$("#"+id).find(".picList li").removeClass("on");
+		let onIdx = $(el).index();
+		$("#"+id).find(".picList li").eq(onIdx).addClass("on");
+		let picTot = $("#"+id).find(".picList li").length - 1;
+		//console.log(onIdx +', '+ picTot);
+		if (onIdx == 0) {
+			$("#"+id).find("button.prev").addClass("off");
+		}
+		if (onIdx == picTot) {
+			$("#"+id).find("button.next").addClass("off");
+		}
+	}
+	
+	// 팝업 닫기 버튼 //uifnPopupClose 함수로 닫으면 remove 되어서 테스트 불가능하며 임시로 사용, 추후 바꾸세요
+	$("#layer_review_pic .btnClose").click(function() {
+		$("#layer_review_pic").addClass("off"); //레이어 닫기
+		$("#layer_review_pic").find("button.btnArr").removeClass("off"); //버튼 초기화
+	});
+	
+	// 팝업 레이어 : 이전 버튼
+	function fnPicPrev(id){
+		let onIdx = $("#"+id).find(".picList li.on").index() - 1;
+		let picTot = $("#"+id).find(".picList li").length - 1;
+		//console.log(onIdx +', '+ picTot);
+		if (onIdx >= 0 ) {
+			$("#"+id).find(".picList li").removeClass("on");
+			$("#"+id).find(".picList li").eq(onIdx).addClass("on");
+		}
+		//화살표버튼
+		if (onIdx <= 0) {
+			$("#"+id).find("button.prev").addClass("off");
+		}
+		if (onIdx < picTot) {
+			$("#"+id).find("button.next").removeClass("off");
+		}
+	}
+
+	// 팝업 레이어 : 다음 버튼
+	function fnPicNext(id){
+		let onIdx = $("#"+id).find(".picList li.on").index() + 1;
+		let picTot = $("#"+id).find(".picList li").length - 1;
+		//console.log(onIdx +', '+ picTot);
+		if (onIdx <= picTot) {
+			$("#"+id).find(".picList li").removeClass("on");
+			$("#"+id).find(".picList li").eq(onIdx).addClass("on");
+		}
+		//화살표버튼
+		if (onIdx >= picTot) {
+			$("#"+id).find("button.next").addClass("off");
+		}
+		if (onIdx > 0 ) {
+			$("#"+id).find("button.prev").removeClass("off");
+		}
+	}
+
+/*]]>*/
+</script>
+
+</html>

+ 193 - 0
src/main/webapp/WEB-INF/views/marketing/PlanReplyListForm.html

@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PlanCornerListForm.html
+ * @desc    : 기획전 코너 관리 화면 Page
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2019.12.30   rladbwnd5   최초 작성
+ *******************************************************************************
+ -->
+
+<div class="modalPopup" data-width="1200" data-height="800"
+	id="popupPlanReply">
+
+	<div class="panelStyle" style="height: 750px;">
+		<div class="panelTitle">
+			<strong>기획전 댓글관리</strong>
+			<button type="button" class="close"
+				onclick="uifnPopupClose('popupPlanReply')">
+				<i class="fa fa-times"></i>
+			</button>
+		</div>
+
+		<div class="panelContent">
+			<form th:object="${planInfo}" id="planReplyListForm"
+				name="planReplyListForm" action="#"
+				th:action="@{'/marketing/planning/reply/list'}" th:method="post">
+				<input type="hidden" th:field="*{planSq}" /> <input type="hidden"
+					th:field="*{planDtlSq}" />
+				<table class="frmStyle" style="margin-bottom: 10px;">
+					<colgroup>
+						<col style="width: 10%;" />
+						<col style="width: 10%;" />
+						<col style="width: 10%;" />
+						<col style="width: 20%;" />
+						<col style="width: 10%;" />
+						<col style="width: 15%;" />
+						<col style="width: 10%;" />
+						<col style="width: 15%;" />
+					</colgroup>
+					<tr>
+						<th>기획전번호</th>
+						<td><label th:text="*{planSq}" id="planSq"></label></td>
+						<th>기획전명</th>
+						<td><label th:text="*{planNm}" id="planNm"></label></td>
+						<th>기획전시작일</th>
+						<td><label th:text="*{dispStdt}" id="dispStdt"></label></td>
+						<th>기획전종료일</th>
+						<td><label th:text="*{dispEddt}" id="dispEddt"></label></td>
+					</tr>
+				</table>
+
+				<div class="panelContent">
+					<ul class="panelBar">
+						<li>
+							<button type="button" class="btn btn-danger btn-lg"	onclick="fnReplyDelete();">삭제</button>
+							<button type="button" class="btn btn-default btn-lg" onclick="fnReplyExelDown();">엑셀 다운로드</button>
+						</li>
+						<li class="right">검색결과 : <strong><span
+								id="gridRowTotalCount">0</span> 건</strong>&nbsp; 쪽번호 <span id="pgNo">0</span>/<strong
+							id="endPgNo">0</strong>&nbsp;&nbsp; <select id="pageSize"
+							name="pageSize">
+								<option value="50" selected="selected">50개씩 보기</option>
+								<option value="100">100개씩 보기</option>
+								<option value="500">500개씩 보기</option>
+								<option value="1000">1000개씩 보기</option>
+						</select> <input type="hidden" name="pageNo" id="pageNo" value="1" />
+						</li>
+					</ul>
+					<div id="gridListReply"	style="width: 100%; max-height: 600px; height: 600px;"	class="ag-theme-balham"></div>
+					<ul class="panelBar">
+						<li class="center">
+							<div class="tablePaging" id="planReplyPagination"></div>
+						</li>
+					</ul>
+				</div>
+			</form>
+		</div>
+
+
+	</div>
+</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var planInfo = [[${planInfo}]];
+	var planReplyList = [[${planReplyList}]];
+	
+	var columnDefsReply = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: '회원번호', field: 'custNo', width: 200, cellClass: 'text-center', hide: true},
+		{
+			headerName: '회원명', field: 'maskingCustNm', width: 200, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				if (gagajf.isNull(params.value)) return '';
+				return '<a href="javascript:void(0);">' + params.value + '</a>';	
+			}
+		},
+		{headerName: '참가일련번호', field: 'planEntrySq', width: 200, cellClass: 'text-center', hide: true},
+		{headerName: "댓글내용"	, field:'entryVal1'		, width:700, cellClass: 'text-left',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "등록일"		, field:'entryDt'			, width:200,  cellClass: 'text-left'},
+	];
+
+	var gridOptionsReply = gagaAgGrid.getGridOptions(columnDefsReply);
+	gridOptionsReply.rowSelection = 'multiple';
+	//gridOptionsReply.rowHeight = 45; //이미지가 있을경우 높이 지정해야함.
+	gridOptionsReply.suppressRowClickSelection = true;
+
+	// 셀 클릭 이벤트
+	gridOptionsReply.onCellClicked = function(event) {
+		if (event.colDef.field == 'maskingCustNm') {
+			cfnOpenCustDetailPopup(event.data.custNo);
+		}else if(event.colDef.field == 'entryVal1'){
+			fnOpenCustReplyPopup(event.data.planEntrySq,event.data.planSq);
+		}
+	}
+	
+	// 삭제클릭시
+	var fnReplyDelete = function() {
+		var selectedData = gagaAgGrid.selectedRowData(gridOptionsReply);
+
+		if (selectedData.length < 1) {
+			mcxDialog.alert('선택 된 댓글이 업습니다.');
+			return;
+		}
+
+		mcxDialog.confirm('선택된 댓글을 삭제하시겠습니까?',{
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(selectedData);
+
+				gagajf.ajaxJsonSubmit('/marketing/planning/reply/delete', jsonData, function() {
+					fnReplySearch();
+				});
+			}
+		});
+	}
+
+	
+	// 댓글 이미지 팝업
+	var fnOpenCustReplyPopup = function(planEntrySq,planSq) {
+		var actionUrl = "/marketing/planning/reply/detail/form?planEntrySq=" + planEntrySq + "&planSq=" +planSq;
+		cfnOpenModalPopup(actionUrl,'popupPlanReplyDetail');
+	} 
+	
+	//페이징 
+	$('#planReplyListForm select[name=pageSize]').on('change', function() {
+		$("#planReplyListForm input[name=pageNo]").val('1');
+		fnReplySearch($("#planReplyListForm input[name=searchGb]").val());
+	});
+	
+	// 댓글 조회
+	var fnReplySearch = function() {
+		gagaPaging.init('planReplyListForm', fnSearchCallBack, 'planReplyPagination', $('#pageSize').val());
+		gagaPaging.load($("#planReplyListForm input[name=pageNo]").val());
+	}
+	
+	// 엑셀다운로드
+	var fnReplyExelDown = function() {
+		gagaAgGrid.exportToExcel('댓글 목록', gridOptionsReply);
+	}
+	
+	var fnSearchCallBack = function(result){
+		$('#planReplyListForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#planReplyListForm').find('#pageNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#planReplyListForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#planReplyListForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptionsReply.api.setRowData(result.planReplyList);
+		
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+
+	
+	$(document).ready(function() {
+		gagaAgGrid.createGrid('gridListReply', gridOptionsReply);
+		fnReplySearch();
+		
+	});
+
+
+/*]]>*/
+</script>
+</html>

+ 66 - 4
src/main/webapp/WEB-INF/views/system/BatchForm.html

@@ -29,6 +29,8 @@
 		<div class="panelStyle">
 			<!-- Search -->
 			<form id="searchForm" name="searchForm" action="#" th:action="@{'/system/batch/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+				<input type="hidden" name="batchId"/>
+				
 				<table class="frmStyle" aria-describedby="검색조건">
 					<colgroup>
 						<col style="width:10%;"/>
@@ -138,6 +140,12 @@
 									<textarea class="textareaR2" name="batchDesc"></textarea>
 								</td>
 							</tr>
+							<tr>
+								<th>배치URL</th>
+								<td colspan="3">
+									<input type="text" name="batchUrl" placeholder="" maxlength="100"/>
+								</td>
+							</tr>
 							<tr>
 								<th>사용여부<em class="required" title="필수"></em></th>
 								<td colspan="3">
@@ -179,7 +187,7 @@
 		},
 		{headerName: "배치명", field: "batchNm", width: 200},
 		{
-			headerName: "업무구분", field: "bizGb", width: 80, cellClass: 'text-center',
+			headerName: "업무구분", field: "bizGb", width: 100, cellClass: 'text-center',
 			cellRenderer: function (params) { return gagaAgGrid.lookupValue(bizGbList, params.value); }
 		},
 		{
@@ -192,7 +200,25 @@
 				return batchFrqNm;
 			}
 		},
+		{headerName: "상태", field: "batchStat", width: 80, cellClass: 'text-center', hide: true},
+		{
+			headerName: "실행", field: "btnNm", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				let btnNm = '';
+				if (params.data.useYn == 'N') {
+					btnNm = '미사용';
+				} else {
+					if (gagajf.isNull(params.data.batchStat) || params.data.batchStat == 'F') {
+						btnNm = '<button type="button" class="btn btn-base btn-lg" onclick="fnExcuteBatch(\'' + params.data.batchId + '\',\'' + params.data.batchStat + '\',\'' + params.data.batchUrl + '\');">실행</button>';
+					} else {
+						btnNm = '실행중';
+					}
+				}
+				return btnNm;
+			}
+		},
 		{headerName: "배치설명", field: "batchDesc", width: 400, hide: true},
+		{headerName: "배치URL", field: "batchUrl", width: 200},
 		{headerName: "사용여부", field: "useYn", width: 80, cellClass: 'text-center'}
 	];
 	
@@ -233,9 +259,10 @@
 
 	// Cell Click
 	gridOptions1.onCellClicked = function(event) {
-		if (event.colDef.field != 'batchId')
-			return;
-
+		if (event.colDef.field != 'batchId') {
+			return false;
+		}
+		
 		$('#detailForm input[name=mode]').val('U');
 		$('#detailForm input[name=batchId]').val(event.data.batchId);
 		$('#detailForm input[name=batchId]').attr('readonly', true);
@@ -243,6 +270,7 @@
 		$('#detailForm select[name=bizGb]').val(event.data.bizGb);
 		$('#detailForm select[name=batchFrq]').val(event.data.batchFrq);
 		$('#detailForm textarea[name=batchDesc]').val(event.data.batchDesc);
+		$('#detailForm input[name=batchUrl]').val(event.data.batchUrl);
 
 		if (event.data.useYn == 'Y') {
 			$("#detailForm input:checkbox[name=chkUseYn]").prop('checked', true);
@@ -253,6 +281,34 @@
 		}
 		
 		$('#detailForm input:checkbox[name=chkUseYn]').attr('readonly', false);
+		
+		// 배치로그 조회
+		fnGetBatchLogByBatchId(event.data.batchId);
+	}
+	
+	// 배치 실행
+	var fnExcuteBatch = function(batchId, batchStat, batchUrl) {
+		if (batchStat == 'I') {
+			mcxDialog.alert("실행중입니다. 종료되면 실행해 주세요.");
+			return false;
+		}
+		
+		if (gagajf.isNull(batchUrl)) {
+			mcxDialog.alert("배치URL 정보가 없습니다. 등록 후 실행해 주세요.");
+			return false;
+		}
+		
+		mcxDialog.confirm("배치는 몇 분이 소요될 수 있으며 나중에 확인하셔야 할 수도 있습니다.<br/>계속 진행하시겠습니까?", {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				let actionUrl = [[${@environment.getProperty('domain.batch')}]] + batchUrl;
+				$.get(actionUrl, function(result) {
+					// 배치로그 조회
+					fnGetBatchLogByBatchId(batchId);
+				});
+			}
+		});
 	}
 
 	// 조회
@@ -295,6 +351,12 @@
 			}
 		});
 	});
+	
+	// 배치로그 조회
+	var fnGetBatchLogByBatchId = function(batchId) {
+		$('#searchForm input[name=batchId]').val(batchId);
+		gagaAgGrid.fetch('/system/batch/log/list', gridOptions2, '#searchForm');
+	}
 
 	$(document).ready(function() {
 		cfnCreateCalendar('#terms', 'batchStdt', 'batchEddt');