浏览代码

소셜관리 중간 커밋

sowon4187 5 年之前
父节点
当前提交
65937fe1a6

+ 49 - 0
src/main/java/com/style24/admin/biz/dao/TsaSocialDao.java

@@ -0,0 +1,49 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import org.springframework.stereotype.Repository;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Social;
+
+/**
+ * 소셜관리 Dao
+ *
+ * @author sowon
+ * @since 2021. 3. 3
+ */
+
+@ShopDs
+@Repository
+public interface TsaSocialDao {
+
+	/**
+	 * 소셜 저장
+	 *
+	 * @param 소셜 정보
+	 * @author sowon
+	 * @since 2021. 3. 3 
+	 */
+	void saveSocial(Social param);
+	
+	/**
+	 * 쇼셜 목록
+	 *
+	 * @param 
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	Collection<Social> getSocialList(Social params);
+	
+	/**
+	 * 쇼셜 갯수확인
+	 *
+	 * @param 
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	int getSocialCount(Social params);
+}

+ 68 - 0
src/main/java/com/style24/admin/biz/service/TsaSocialService.java

@@ -0,0 +1,68 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaSocialDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.persistence.domain.Plan;
+import com.style24.persistence.domain.Social;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 소셜관리 Service
+ * 
+ * @author sowon
+ * @since 2021. 03. 03
+ */
+@Service
+@Slf4j
+public class TsaSocialService {
+	
+	@Autowired
+	private TsaSocialDao socialDao;
+	
+	/**
+	 * 소셜 저장
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	@Transactional("shopTxnManager")
+	public void saveSocial(Social param) {
+		Integer userNo = TsaSession.getInfo().getUserNo();
+		param.setRegNo(userNo);
+		param.setUpdNo(userNo);
+
+		socialDao.saveSocial(param);
+	}
+	
+	
+	/**
+	 * 쇼셜 목록
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	public Collection<Social> getSocialList(Social params) {
+		return socialDao.getSocialList(params);
+	}
+	
+	/**
+	 * 소셜 목록 카운트 조회
+	 * @param  param
+	 * @return int
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	public int getSocialCount(Social param) {
+		return socialDao.getSocialCount(param);
+	}
+
+}

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

@@ -33,6 +33,7 @@ import com.style24.admin.biz.service.TsaPlanService;
 import com.style24.admin.biz.service.TsaPollService;
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.biz.service.TsaReviewService;
+import com.style24.admin.biz.service.TsaSocialService;
 import com.style24.admin.biz.service.TsaSystemService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
@@ -102,6 +103,9 @@ public class TsaMarketingController extends TsaBaseController {
 	@Autowired
 	private TscCouponService coreCouponService;
 	
+	@Autowired
+	private TsaSocialService socialService;
+	
 	@Value("${upload.default.target.path}")
 	private String uploadTargetPath;
 
@@ -2257,6 +2261,85 @@ public class TsaMarketingController extends TsaBaseController {
 		mav.setViewName("marketing/PollVoteRatePopupForm");
 		return mav;
 	}
+	
+	/**
+	 *   poll 작업 종료 - sowon
+	 */
+	
+	
+	/**
+	 *   소셜관리 작업 시작 - sowon
+	 */
+	
+	/**
+	 * 소셜쇼핑관리 화면
+	 *
+	 * @param
+	 * @author sowon
+	 * @since 2021. 3. 3 
+	 */
+	@GetMapping(value = "/social/form")
+	@ResponseBody
+	public ModelAndView socialShoppingListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트코드 G000
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 사용여부 G002
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+
+		// 소셜 유형 G062
+		mav.addObject("socialTypeList", rendererService.getAvailCommonCodeList("G062"));
+
+		// 기획전 전체 목록
+		Plan plan = new Plan();
+		mav.addObject("planList", planService.getPlanAllList(plan));
+
+		mav.setViewName("marketing/SocialShoppingListForm");
+		return mav;
+	}
+	
+	/**
+	 * 소셜 저장
+	 *
+	 * @param 소셜 정보
+	 * @return
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	@PostMapping("/social/save")
+	@ResponseBody
+	public GagaResponse saveSocial(@RequestBody Social param) {
+		log.debug("param : {}", param);
+		socialService.saveSocial(param);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+
+	/**
+	 * 소셜 목록
+	 *
+	 * @param 
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 3
+	 */
+	@PostMapping("/social/list")
+	@ResponseBody
+	public GagaMap getSocialList(@RequestBody Social params) {
+		GagaMap result = new GagaMap();
+		
+		Collection<Social> socialList = socialService.getSocialList(params);
+		
+		params.setPageable(new TscPageRequest(params.getPageNo() - 1, params.getPageSize()));
+		params.getPageable().setTotalCount(socialService.getSocialCount(params));
+
+		result.set("pageing", params);
+		result.set("socialList", socialList);
+		return result;
+	}
+	
 
 
 

+ 72 - 0
src/main/java/com/style24/persistence/domain/Social.java

@@ -0,0 +1,72 @@
+package com.style24.persistence.domain;
+
+
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 소셜관리 Domain
+ *
+ * @author sowon
+ * @since 2021. 03. 03
+ */
+
+@SuppressWarnings("serial")
+@Data
+public class Social extends TscBaseDomain{
+		// SOCIAL
+		private Integer socialSq;			// 소셜일련번호
+		private String socialNm;		// 소셜명
+		private String socialType;		// 소셜유형
+		private String siteCd;			// 사이트코드
+		private String frontGb;			// 프론튿구분
+		private String socialStdt;		// 소셜시작시간
+		private String socialEddt;		// 소셜종료시간
+		private String socialTnm;		// 소셜타이틀명
+		private String useYn;			// 사용여부
+		private String applyGb;			// 적용구분
+		
+		private String regNm;
+		// PLAN
+		private Integer planSq;			// 기획전 일련번호
+		
+		
+
+		// SOCIAL GOODS
+		private Integer scgoodsSq;		// 소셜상품일련번호(SEQ_SCGOODS sequence)
+		private String goodsCd;			// 상품코드(상품)
+		private String currBprice;		// 변경전현재판매가
+		private String currAprice;		// 변경후현재판매가
+		private String dcBrate;			// 변경전할인율
+		private String dcArate;			// 변경후할인율
+		private String pntBprate;		// 변경전포인트적립율(PC)
+		private String pntAprate;		// 변경후포인트적립율(PC)
+		private String pntBmrate;		// 변경전포인트적립율(모바일)
+		private String pntAmrate;		// 변경후포인트적립율(모바일)
+		private String erpPriceLinkYn;	// erp가격연계여부(자사품만 사용, y연계)
+		private String dispOrd;			// 표시순서
+		private String delYn;			// 삭제여부(Y:삭제)
+
+		// GOODS
+		private String currPrice;		// 현재 판매가
+		private String dcRate;			// 할인율
+		private String pntPrate;		// PC 포인트 적립율
+		private String pntMrate;		// MOBILE 포인트 적립율
+
+		
+
+		private String excelFileNm;		// 엑셀파일명
+		// 검색
+		private String stDate;	// 시작일시
+		private String edDate;	// 종료일시
+		
+		
+		// Pagination
+		private TscPageRequest pageable;
+		private int pageNo = 1;
+		private int pageSize = 50;
+		private int pageUnit = 10;
+		
+}

+ 130 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaSocial.xml

@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.style24.admin.biz.dao.TsaSocialDao">
+	<!-- 소셜 저장 -->
+	<insert id="saveSocial" parameterType="Social">
+		/* TsaSocial.saveSocial */
+		INSERT INTO TB_SOCIAL
+				(
+				  SOCIAL_NM
+				, SOCIAL_TYPE
+				, SITE_CD
+				, FRONT_GB
+				, SOCIAL_STDT
+				, SOCIAL_EDDT
+				, SOCIAL_TNM
+				, USE_YN
+				, APPLY_GB
+				, PLAN_SQ
+				, REG_NO
+				, REG_DT
+				, UPD_NO
+				, UPD_DT
+				)
+		VALUES(
+				#{socialNm}
+		      , #{socialType}
+		      , #{siteCd}
+		      , #{frontGb}
+		      , #{socialStdt}
+		      , #{socialEddt}
+		      , #{socialTnm}
+		      , #{useYn}
+		      , #{applyGb}
+		      , #{planSq}
+		      , #{regNo}
+		      , now()
+		      , #{updNo}
+		      , now()
+		     )
+		   ON
+		     DUPLICATE KEY 
+		UPDATE 
+		   SOCIAL_NM=#{socialNm}
+		 , SOCIAL_TYPE=#{socialType}
+		 , SITE_CD=#{siteCd}
+		 , FRONT_GB=#{frontGb}
+		 , SOCIAL_STDT=  #{socialStdt}
+		 , SOCIAL_EDDT= #{socialEddt}
+		 , SOCIAL_TNM= #{socialTnm}
+		 , USE_YN= #{useYn}
+		 , APPLY_GB=#{applyGb}
+		 , PLAN_SQ=#{planSq}
+		 , UPD_NO=#{updNo}
+		 , UPD_DT=now()
+	</insert>
+	
+		<!-- 쇼셜 목록 -->
+	<select id="getSocialList" parameterType="Social" resultType="Social">
+		/* TsaSocial.getSocialList */
+		SELECT Z.*
+		FROM (
+				 SELECT @rownum := @rownum + 1 AS RNUM
+				 	         ,A.*
+				 	   FROM (
+								SELECT SOCIAL_SQ                                                    
+								     , SOCIAL_NM                                                    
+								     , SOCIAL_TNM                                                   
+								     , SOCIAL_TYPE                                                  
+								     , SITE_CD                                                      
+								     , FRONT_GB                                                     
+								     , SOCIAL_STDT													
+								     , SOCIAL_EDDT 
+								     , PLAN_SQ                                                      
+								     , USE_YN  
+								     , APPLY_GB 
+								     , REG_DT
+								     , REG_NO
+								     , FN_GET_USER_NM(REG_NO)                AS REG_NM
+								FROM   TB_SOCIAL JOIN ( SELECT @rownum := 0) R
+								WHERE  1 = 1
+								<include refid="getPlanListCondition_sql"/>
+								ORDER  BY SOCIAL_SQ DESC
+			<include refid="getListPagingCondition_sql"/>
+	</select>
+	
+	<select id="getSocialCount" parameterType="Social" resultType="int">
+		/* TsaSocial.getSocialCount */
+		SELECT count(*) AS CNT
+		FROM TB_SOCIAL	
+	</select>
+	
+	<sql id="getPlanListCondition_sql">
+		<if test ="siteCd != null and siteCd !=''">
+		AND    SITE_CD = #{siteCd}
+		</if>
+		<if test="useYn != null and useYn != ''">
+		AND    USE_YN = #{useYn}
+		</if>
+		<if test="socialSq != null and socialSq != ''">
+		AND    SOCIAL_SQ = #{socialSq}
+		</if>
+		<if test="socialType != null and socialType != ''">
+		AND    SOCIAL_TYPE = #{socialType}
+		</if>	
+		<if test="frontGb != null and frontGb != ''">
+		AND    FRONT_GB = #{frontGb}
+		</if>
+		<if test="socialStdt != null and socialStdt != ''">
+		AND    DISP_EDDT <![CDATA[>=]]> DATE_FORMAT(#{socialStdt}, '%Y-%m-%d %H:%i:%S')
+		</if>
+		<if test="socialEddt != null and socialEddt != ''">
+		AND    DISP_STDT <![CDATA[<=]]> DATE_FORMAT(#{socialEddt}, '%Y-%m-%d %H:%i:%S')
+		</if>
+	</sql>
+	
+	<sql id="getListPagingCondition_sql">
+		<choose>
+			<when test="pageable != null">
+				) A
+				)Z
+				WHERE RNUM BETWEEN  #{pageable.startRow} AND #{pageable.endRow}
+			</when>
+			<otherwise>
+				) A
+				)Z
+			</otherwise>
+		</choose>
+	</sql>
+
+</mapper>

+ 750 - 0
src/main/webapp/WEB-INF/views/marketing/SocialShoppingListForm.html

@@ -0,0 +1,750 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PlanListForm.html
+ * @desc    : 기획전관리 Page
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.3.3   	 sowon		   최초 작성
+ *******************************************************************************
+ -->
+<div id="main">
+	<div class="main-title">
+	</div>
+
+	<div class="panelStyle">
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/marketing/social/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<table class="frmStyle">
+				<colgroup>
+					<col style="width:5%;"/>
+					<col style="width:20%;"/>
+					<col style="width:5%;"/>
+					<col style="width:20%;"/>
+					<col style="width:5%;"/>
+					<col style="width:10%;"/>
+					<col style="width:5%;"/>
+					<col style="width:10%;"/>
+					<col/>
+				</colgroup>
+				<tbody>
+					<tr>
+						<th>진행기간</th>
+						<td colspan="7" id="terms"></td>
+					</tr>
+					<tr>
+						<th>소셜번호</th>
+						<td>
+							<input type="text" name="socualSq" id="socualSq"/>
+						</td>
+
+						<th>등록자</th>
+						<td>
+							<input type="text" name="regId" id="regId"/>
+						</td>
+
+						<th>사용여부</th>
+						<td>
+							<select name="useYn">
+								<option value="">전체</option>
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>사이트</th>
+						<td>
+							<select name="siteCd">
+								<option value="">선택</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th>웹/모바일구분</th>
+						<td>
+							<select name="frontGb">
+								<option value="A">ALL</option>
+								<option value="P">웹</option>
+								<option value="M">모바일</option>
+							</select>
+						</td>
+
+						<th>소셜유형</th>
+						<td>
+							<select name="socialType">
+								<option value="">선택</option>
+								<option th:if="${socialTypeList}" th:each="oneData, status : ${socialTypeList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+				</tbody>
+			</table>
+			<ul class="panelBar">
+				<li class="center">
+					<input type="button" value="초기화" class="btn btn-gray btn-lg" id="btnReset" onclick="fnReset();"/>
+				<input type="button" value="조회" class="btn btn-base btn-lg" id="btnSearch" onclick="fnSearch();"/>
+				</li>
+			</ul>
+		
+
+
+			<div class="panelContent">
+				<ul class="panelBar">
+					<li class="right">
+						 검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp; 쪽번호 <span id="pgNo">0</span>/
+								<strong id="endPgNo">0</strong>&nbsp;&nbsp; <select id="pageSize" name="pageSize">
+									<option value="50" selected="selected">50개씩 보기</option>
+									<option value="100">100개씩 보기</option>
+									<option value="500">500개씩 보기</option>
+									<option value="1000">1000개씩 보기</option>
+								</select> <input type="hidden" name="pageNo" id="pageNo" value="1" />
+					</li>
+				</ul>
+			
+				<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>
+				
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="socialListPagination"></div>
+					</li>
+				</ul>
+			</div>
+	</form>
+</div>
+
+	<!-- TABS AREA -->
+	<div class="tabs">
+		<ul class="tabsNav">
+			<li class="on"><a href="#tab-1">기본정보</a></li>
+			<li class="off"><a href="#tab-2">소셜상품</a></li>
+		</ul>
+
+		<ul class="tabsCont">
+			<!-- 기본 정보 -->
+			<li class="tab on" id="tab-1">
+					<div class="panelStyle">
+						<!-- 버튼 배치 영역 -->
+						<ul class="panelBar">
+							<li class="right">
+								<button type="button" class="btn btn-info btn-lg" onclick="$('#detailForm')[0].reset(); $('.tabsNav li').eq(1).addClass('off');">신규</button>
+							<button type="button" class="btn btn-success btn-lg" onclick="fnSocialSaveValid();">저장</button>
+							</li>
+						</ul>
+						<!-- //버튼 배치 영역 -->
+						
+					</div>
+
+					<div class="panelStyle" style="border-top: #fff">
+						<form id="detailForm" name="detailForm" action="#" th:action="@{'/marketing/event/save'}">
+							<table class="frmStyle">
+								<colgroup>
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+									<col style="width:''">
+								</colgroup>
+								<tr>
+									<th>소셜번호</th>
+									<td>
+										<input type="text" name="socialSq" id="socialSq" readonly="readonly"/>
+									</td>
+									
+									<th>사이트</th>
+									<td>
+										<select name="siteCd" required="required" data-valid-name="사이트">
+											<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+										</select>
+									</td>
+									
+									<th>사용여부</th>
+									<td>
+										<select name="useYn" required="required" data-valid-name="사용여부">
+											<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+										</select>
+									</td>
+
+									<th>웹/모바일구분</th>
+									<td>
+										<select name="frontGb" required="required" data-valid-name="웹/모바일구분">
+											<option value="A">ALL</option>
+											<option value="P">웹</option>
+											<option value="M">모바일</option>
+										</select>
+									</td>
+								</tr>
+								<tr>
+									<th>소셜명</th>
+									<td colspan="3">
+										<input type="text" name="socialNm" id="socialNm" required="required" data-valid-name="소셜명"/>
+									</td>
+									<th>소셜타이틀명</th>
+									<td colspan="3">
+										<input type="text" name="socialTnm" id="socialTnm"/>
+									</td>
+								</tr>
+								<tr>
+									<th>소셜유형</th>
+									<td colspan="3">
+										<select name="socialType" required="required" data-valid-name="소셜유형">
+											<option th:if="${socialTypeList}" th:each="oneData, status : ${socialTypeList}" th:value="${oneData.cd}" th:text="|${oneData.cdNm}|"></option>
+										</select>
+										 <span id="planSpan">
+											<button type="button" class="btn btn-base btn-lg" id="btnSearchPlan">기획전 조회</button>
+											<input type="text" name="socialPlanSq" readonly="readonly"/>
+											<input type="hidden" name="planSq"/>
+										</span>
+									</td>
+									
+									<th>진행기간</th>
+									<td>
+										<input name="stDate" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="진행시작일자" />
+										<select id="stTimeHour" required="required" data-valid-name="진행기간 시작시간">
+											<th:block th:each="num, index  : ${#numbers.sequence(0,23)}">
+											<option  th:value="${#numbers.formatInteger(num,2)}" th:text="|${#numbers.formatInteger(num,2)}시|" >시간</option>
+											</th:block>
+										</select>
+										 ~ 
+										<input name="edDate" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="진행종료일자" />
+										<select id="edTimeHour" required="required" data-valid-name="진행기간 종료시간">
+											<th:block th:each="num: ${#numbers.sequence(0,23)}">
+											<option  th:value="${#numbers.formatInteger(num,2)}"  th:text="|${#numbers.formatInteger(num,2)}시|" th:selected="${#numbers.formatInteger(num,2)}==23 ? 'true'">시</option>
+											</th:block>
+										</select>
+										
+										<input type="hidden" name="socialStdt"/>
+										<input type="hidden" name="socialEddt"/>
+									</td>
+									
+									<th>적용구분</th>
+									<td>
+										<select name="applyGb" required="required" data-valid-name="적용구분">
+											<option value="P">대기</option>
+											<option value="A">적용</option>
+											<option value="F">종료</option>
+										</select>
+									</td>
+									
+								</tr>
+							</table>
+						</form>
+					</div>			
+					<div class="panelStyle" style="border-top: #fff">		
+					
+					</div>
+				</li>
+			
+			<!-- 소셜 상품 -->
+			<li class="tab" id="tab-2">
+				<div class="panelStyle">	
+						<span class="btnLeft">
+							<select name="priceGb" id="priceGb">
+								<option value="">선택</option>
+								<option value="currAprice">판매가</option>
+								<option value="dcArate">할인율</option>
+								<option value="pntAprate">PC 포인트</option>
+								<option value="pntAmrate">MOBILE 포인트</option>
+							</select>
+							
+							<input type="text" class="w100 aR" id="price" name="price" data-valid-type="numeric"/>
+							
+							<button type="button" class="btn btn-default btn-lg" onclick="fnPriceApply();">일괄적용</button>
+						</span> 
+						<ul class="panelBar">
+							<li class="right">
+								<button type="button" class="btn btn-default btn-lg" onclick="fnOpenGoodsPopup();">상품추가</button>
+								<button type="button" class="btn btn-default btn-lg" onclick="fnDeleteGoods();">상품삭제</button>
+								<button type="button" class="btn btn-default btn-lg" onclick="fnSocialGoodsExcelUpload();">엑셀상품추가</button>
+								<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF011');">엑셀상품추가 양식 다운로드</button>
+								<button type="button" class="btn btn-success btn-lg" onclick="fnSocialGoodsSave();">저장</button>
+								<button type="button" class="btn btn-success btn-lg" onclick="fnSocialSaveValid();">저장</button>
+							</li>
+						</ul>
+					<div class="panelStyle">	
+						<div id="gridGoodsList" style="width: 100%; height: 500px;"  class="ag-theme-balham"></div>
+					</div>
+					
+					
+					<!-- <li class="boxContentBtnB" style="margin-top: 10px;">
+						<span class="btnRight">
+							<button type="button" class="btn btn-success btn-lg" onclick="">즉시적용</button>
+						</span>
+					</li> -->
+				</div>
+			</li>
+
+		</ul>
+	</div>
+
+</div>
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var siteList = gagajf.convertToArray([[${siteList}]]);
+	var socialTypeList = ([[${socialTypeList}]]);
+	var wmGbList = {"A":"ALL", "P":"웹", "M":"모바일"};
+	var applyList = {"P":"대기", "A":"적용", "F":"종료"};
+
+	var columnDefs = [
+		{headerName: "사이트"		, field:'siteCd'		, width:100, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(siteList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(siteList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(siteList, params.newValue); }
+		},
+		{headerName: "소셜번호"		, field:'socialSq'		, width:100, cellClass: 'text-center'},
+		{headerName: "소셜명"		, field:'socialNm'		, width:300, cellClass: 'text-center',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "소셜타이틀명"	, field:'socialTnm'		, width:200, cellClass: 'text-center'},
+		{headerName: "진행시작일시"	, field:'socialStdt'	, width:150, cellClass: 'text-center'},
+		{headerName: "진행종료일시"	, field:'socialEddt'	, width:150, cellClass: 'text-center'},
+		{headerName: "프론트구분"	, field:'frontGb'		, width:120, cellClass: 'text-center',
+			 valueFormatter: function (params) { return gagaAgGrid.lookupValue(wmGbList, params.value); }
+		},
+		{headerName: "소셜유형"		, field:'socialType'	, width:150, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(socialTypeList, params.value); }
+		},
+		{headerName: "사용여부"		, field:'useYn'			, width:80 , cellClass: 'text-center'},
+		{headerName: "적용구분"	, field:'applyGb'	, width:100, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(applyList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(applyList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(applyList, params.newValue); }
+		},
+		{headerName: "등록자"		, field:'regNm'			, width:100, cellClass: 'text-center'},
+		{headerName: "등록일"		, field:'regDt'			, width:150, cellClass: 'text-center'},
+	];
+
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 셀 클릭 이벤트
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field != 'socialNm')
+			return;
+
+		$('.tabsNav li').eq(0).trigger('click');
+		fnBindDetail(event.data); // 바인딩
+	}
+
+	// 바인딩
+	var fnBindDetail = function(data) {
+		fnSearchSocialGoodsList(data.socialSq);
+		fnSetDate(data);
+	}
+	
+	// 데이터 설정
+	var fnSetDate = function(data) {
+		var formId = '#detailForm';
+		
+		$('.tabsNav li').eq(1).removeClass('off');
+		
+		// 기본정보 입력
+		$(formId + ' input[name=socialSq]').val(data.socialSq);
+		$(formId + ' input[name=socialNm]').val(data.socialNm);
+		$(formId + ' input[name=socialTnm]').val(data.socialTnm);
+		$(formId + ' select[name=siteCd]').val(data.siteCd);
+		$(formId + ' select[name=useYn]').val(data.useYn);
+		$(formId + ' select[name=frontGb]').val(data.frontGb);
+		$(formId + ' select[name=socialType]').val(data.socialType);
+		$(formId + ' select[name=planSq]').val(data.planSq);
+		$(formId + ' select[name=socialType]').trigger('change');
+		
+		// 진행 기간 설정
+		var stDate = data.socialStdt.split(" ")[0];
+		var edDate = data.socialEddt.split(" ")[0];
+		var stTime = data.socialStdt.split(" ")[1].replaceAll(":", "");
+		var edTime = data.socialEddt.split(" ")[1].replaceAll(":", "");
+		
+		// 진행 시작 기간 설정
+		$(formId + ' input[name=stDate]').val(stDate);
+		$('#stTimeHour').val(stTime.substring(0,2));
+		
+		// 진행 종료 기간 설정
+		$(formId + ' input[name=edDate]').val(edDate);
+		$('#edTimeHour').val(edTime.substring(0,2));
+	}
+	
+	// 소셜 기본정보 저장
+	var fnSocialSaveValid = function() {
+		var formId = '#detailForm';
+		
+		if (!gagajf.validation(formId))
+			return;
+		
+		// 날짜 유효성 체크
+		var stDate = $(formId + ' input[name=stDate]').val().replaceAll("-", "");
+		var edDate = $(formId + ' input[name=edDate]').val().replaceAll("-", "");
+		var stTime = $('#stTimeHour').val().replaceAll(":", "");
+		var edTime = $('#edTimeHour').val().replaceAll(":", "");
+		var toDate = _today.replaceAll("-", "");
+		
+		var socialSq = $(formId + ' input[name=socialSq]').val();
+		var planSq = $(formId + ' input[name=planSq]').val();
+		
+		var msg = '저장';
+		if (gagajf.isNull(socialSq)) {
+			msg = '등록';
+			// 신규
+			if (Number(stDate) < Number(toDate)) {
+				mcxDialog.alert('시작일자는 오늘포함 이후로 등록해주세요.');
+				return;
+			}
+			
+			if (Number(edDate) < Number(toDate)) {
+				mcxDialog.alert('종료일자는 오늘포함 이후로 등록해주세요.');
+				return;
+			}
+		}
+		
+		if (Number(stDate) > Number(edDate)) {
+			mcxDialog.alert('종료일자는 시작일자 보다 클 수 없습니다.');
+			return;
+		}
+		
+		if (Number(stDate) == Number(edDate)) {
+			if (Number(stTime) > Number(edTime)) {
+				mcxDialog.alert('시작시간은 종료시간보다 클 수 없습니다.');
+				return;
+			}
+			
+			if (Number(stTime) == Number(edTime)) {
+				mcxDialog.alert('같은 날 시작시간과 종료시간은 같을 수 없습니다.');
+				return;
+			}
+		}
+		
+		$(formId + ' input[name=socialStdt]').val($(formId + ' input[name=stDate]').val() + ' ' + stTime);
+		$(formId + ' input[name=socialEddt]').val($(formId + ' input[name=edDate]').val() + ' ' + edTime);
+		
+		//fnPlanCheck(planSq, msg);
+		fnSocialSave(msg);
+	}
+	
+	// 기획전 체크
+	var fnPlanCheck = function(planSq, msg) {
+		if (gagajf.isNull(planSq)) {
+			fnSocialSave(msg);
+			return;
+		}
+		
+		var params = new Object();
+		params.planSq = planSq;
+		var jsonData = JSON.stringify(params);
+		
+		gagajf.ajaxJsonSubmit('marketing/social/list', jsonData, function(result) {
+			if (result.length > 0) {
+				
+				var checkFlag = false;
+				var socialSq = $('#detailForm input[name=socialSq]').val();
+				$(result).each(function(idx, data) {
+					if (data.socialSq != socialSq) checkFlag = true;
+				});
+				
+				if (checkFlag) {
+					mcxDialog.alert('선택한 기획전은 이미 다른 소셜에 적용되어있습니다.');
+					return;
+				}
+			} 
+			fnSocialSave(msg);
+		});
+	}
+	
+	// 소셜 저장
+	var fnSocialSave = function(msg) {
+		mcxDialog.confirm(msg +' 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var actionUrl = '/marketing/social/save';
+				gagajf.ajaxFormSubmit(actionUrl, '#detailForm', function() {
+					fnSearch();
+				});
+			}
+		});
+	}
+
+	// 검색
+	var fnSearch = function() {
+		$('.tabsNav li').eq(1).addClass('off');
+		$('.tabsNav li').eq(0).trigger('click');
+		
+		gagaPaging.init('searchForm', fnSearchCallBack, 'socialListPagination', $('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+	
+	var fnSearchCallBack = function(result){
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.socialList);
+		
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	var columnDefsGoods = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: "상품코드"				, field:'goodsCd'	, width:300 , cellClass: 'text-center',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: '적용 판매가'			, field:'currAprice', width:200 , cellClass: 'text-right', cellEditor: 'numericCellEditor', hide : true
+			, editable: function(params) { return gagajf.isNull(params.data.dcArate) ? true : false; } 
+			, cellRenderer: function(params) { return gagajf.isNull(params.value) ? '' : params.value.addComma(); }
+		}, // 변경 후 현재판매가
+		{headerName: '적용 할인율'			, field:'dcArate'	, width:200 , cellClass: 'text-right', cellEditor: 'numericCellEditor', hide : true
+			, editable: function(params) { return gagajf.isNull(params.data.currAprice) ? true : false; }
+		}, // 변경 후 할인율
+		{headerName: '적용 PC 포인트'		, field:'pntAprate'	, width:200 , cellClass: 'text-right', editable : true, cellEditor: 'numericCellEditor', hide : true }, // 변경 후 포인트적립율(PC)
+		{headerName: '적용 MOBILE 포인트'	, field:'pntAmrate'	, width:200 , cellClass: 'text-right', editable : true, cellEditor: 'numericCellEditor', hide : true }, // 변경 후 포인트적립율(모바일)
+		{headerName: '표시순서'				, field:'dispOrd'	, width:100 , cellClass: 'text-center', editable : true, cellEditor: 'numericCellEditor', hide : true},
+		{headerName: '삭제여부'				, field:'delYn'		, width:100 , cellClass: 'text-center', hide : true},
+	];
+
+	var gridOptionsGoods = gagaAgGrid.getGridOptions(columnDefsGoods);
+	gridOptionsGoods.rowSelection = 'multiple';
+	
+	// 소셜 상품 목록 검색
+	var fnSearchSocialGoodsList = function(socialSq) {
+		var actionUrl = 'marketing/social/goods/list';
+		var params = new Object();
+		params.socialSq = typeof socialSq == 'object' ? $('#detailForm input[name=socialSq]').val() : socialSq;
+		
+		var jsonData = JSON.stringify(params);
+		gagajf.ajaxJsonSubmit(actionUrl, jsonData, function(result) {
+			gridOptionsGoods.api.setRowData(result);
+		});
+	}
+	
+	// 적용가격 일괄적용
+	var fnPriceApply = function() {
+		var priceGb = $('#priceGb').val();
+		var price = $('#price').val();
+		var msg = '';
+		
+		// 선택 된 상품
+		var selectedGoodsList = gagaAgGrid.selectedRowData(gridOptionsGoods);
+		if (selectedGoodsList.length < 1) {
+			mcxDialog.alert('선택한 상품이 존재 하지않습니다.');
+			return;
+		}
+		
+		if (gagajf.isNull(priceGb)) {
+			mcxDialog.alert('일괄적용을 선택 하세요.');
+			$('#priceGb').focus();
+			return;
+		}
+		
+		if (gagajf.isNull(price)) {
+			mcxDialog.alert('할인 금액 및 율을 입력하세요.');
+			$('#price').focus();
+			return;
+		}
+
+		var msg = $("#priceGb option:selected").text() + '을(를) ' + $('#price').val() + '값으로 ';
+		mcxDialog.confirm(msg +'일괄적용 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				$(selectedGoodsList).each(function(idx, goods) {
+					
+					if (priceGb == 'currAprice') { // 판매가
+						goods.currAprice = price;
+						goods.dcArate = null;
+					} else if (priceGb == 'dcArate') { // 할인율
+						goods.dcArate = price;
+						goods.currAprice = null;
+					} else if (priceGb == 'pntAprate') { // pc 할인율
+						goods.pntAprate = price;
+					} else if (priceGb == 'pntAmrate') { // mobile 할인율
+						goods.pntAmrate = price;
+					}
+				});
+				
+				gridOptionsGoods.api.updateRowData({update: selectedGoodsList});
+			}
+		});
+	}
+	
+	// 상품 추가
+	var fnOpenGoodsPopup = function() {
+		var edDate = $('#detailForm input[name=socialEddt]').val().replaceAll("-", "");;
+		var toDate = _today.replaceAll("-", "");
+		
+		if (Number(toDate) < Number(edDate)) {
+			mcxDialog.alert("진행종료일자 전에만 상품추가가 가능합니다.");
+			return;
+		}
+		cfnOpenGoodsPopup('fnCreateGoods');
+	}
+	
+	// 상품 추가 콜백
+	var fnCreateGoods = function(result) {
+		if (result.length < 1) return;
+		
+		// 기존상품
+		var oldGoodsList = gagaAgGrid.getAllRowData(gridOptionsGoods);
+		var socialSq = $('#detailForm input[name=socialSq]').val();
+		
+		// 중복체크
+		var check = true;
+		var checkData = [];
+		$(oldGoodsList).each(function(idx) {
+			
+			$(result).each(function(newIdx) {
+				
+				if (oldGoodsList[idx].goodsCd == result[newIdx].goodsCd) {
+					check = false;
+					checkData.push(result[newIdx].goodsCd);
+				}
+			});
+		});
+		
+		if (!check) {
+			mcxDialog.alert('아래 중복상품이 존재 합니다.<br/>' + checkData.join(","));
+			return;
+			
+		} else {
+			if (gagajf.isNull(socialSq)) {
+				mcxDialog.alert('소셜을 선택 해주세요.');
+				return;
+			}
+			
+			for (var disp = 0; disp < result.length; disp++) {
+				var goods = { socialSq : Number(socialSq) ,
+							  scgoodsSq : Number(0) ,
+							  goodsCd : result[disp].goodsCd };
+				oldGoodsList.unshift(goods);
+			}
+		}
+		
+		gridOptionsGoods.api.setRowData(oldGoodsList);
+	}
+	
+	// 상품 삭제
+	var fnDeleteGoods = function() {
+		// 선택 상품
+		var selectedGoodsList = gagaAgGrid.selectedRowData(gridOptionsGoods);
+		
+		if (selectedGoodsList.length < 1) {
+			mcxDialog.alert('선택된 상품이 존재 하지않습니다.');
+			return;
+		}
+		
+		mcxDialog.confirm('선택하신 상품을 삭제하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				$(selectedGoodsList).each(function(idx, goods) {
+					goods.delYn = 'Y';
+				});
+				
+				var jsonData = JSON.stringify(selectedGoodsList);
+				gagajf.ajaxJsonSubmit('/marketing/social/goods/delete', jsonData, fnSearchSocialGoodsList);
+			}
+		});
+	}
+	
+	var fnSocialGoodsExcelUpload = function() {
+		cfnExcelUploadPopup('socialGoodsExcelUpload', 'socialGoodsExcelUpload');
+	}
+	
+	// 상품 엑셀 업로드
+	var socialGoodsExcelUpload = function(result) {
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					,socialSq : Number($('#detailForm input[name=socialSq]').val())
+					};
+		
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/marketing/social/goods/excelupload', jsonData, fnSearchSocialGoodsList);
+	}
+	
+	// 소셜 상품 저장
+	var fnSocialGoodsSave = function() {
+		var goodsList = gagaAgGrid.getAllRowData(gridOptionsGoods);
+		
+		if (goodsList.length < 1) {
+			mcxDialog.alert('상품이 존재 하지않습니다.');
+			return;
+		}
+		
+		var checkData = [];
+		var msg = '';
+		/* $(goodsList).each(function(idx, goods) {
+			if (goods.dcArate > 100) {
+				msg = '할인율은 100을 넘을 수 없습니다.';
+				return false;
+			}
+			
+			if (gagajf.isNull(goods.currAprice) && gagajf.isNull(goods.dcArate)) {
+				msg = '상품코드 : ' + goods.goodsCd + '<br/>판매가와 할인율 모두 값이 존재하지않습니다.';
+				return false;
+			}
+			
+		});
+		
+		if (!gagajf.isNull(msg)) {
+			mcxDialog.alert(msg);
+			return;
+		} */
+		
+		mcxDialog.confirm('저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(goodsList);
+				gagajf.ajaxJsonSubmit('/marketing/social/goods/save', jsonData, fnSearchSocialGoodsList);
+			}
+		});
+	}
+	
+	
+	$('#btnSearchPlan').on('click', function() {
+		cfnOpenPlanPopup('popupPlan');
+	});
+	
+	var popupPlan = function(result) {
+		$('#detailForm input[name=socialPlanSq]').val("[" + result[0].planSq + "] " +result[0].planNm);
+		$('#detailForm input[name=planSq]').val(result[0].planSq);
+	}
+	
+	$(document).ready(function() {
+		cfnCreateCalendar('#terms', 'stDate', 'edDate', false);
+
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		gagaAgGrid.createGrid('gridGoodsList', gridOptionsGoods);
+		//uifnFitGrid();
+		
+	});
+	
+	// copylight 처리
+	$('.tabsNav li').eq(1).on('click', function() {
+		timer = setInterval(function() { fnCheckClass(1); }, 50); 
+	});
+	
+	$('.tabsNav li').eq(0).on('click', function() {
+		timer = setInterval(function() { fnCheckClass(0); }, 50); 
+	});
+	
+	var fnCheckClass = function(flag) {
+		var tabClass = $('.tabsNav li').eq(flag).attr('class');
+		if (tabClass == 'on') {
+			/*  uifnFitGrid(); */
+			clearInterval(timer);
+		}
+	}
+	
+/*]]>*/
+</script>
+
+</html>