Explorar o código

Merge remote-tracking branch '112.172.147.34/style' into ST24PRJ-4(회수상품정보,금액정보노출)

jsh77b %!s(int64=4) %!d(string=hai) anos
pai
achega
81013068dd

+ 46 - 0
src/main/java/com/style24/persistence/domain/GoodsVideo.java

@@ -0,0 +1,46 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+
+/**
+ * 상품 동영상 Domain
+ *
+ * @author eskim
+ * @since 2020. 11. 16
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsVideo extends TscBaseDomain {
+
+	private Integer videoSq;
+	private String goodsCd;
+	private String videoGb;	// 비디오 구분 M: mp4, Y:유투브
+	private String kmcKey;	// 
+	private String kufKey;
+	private String dispYn;
+	
+	private String brandEnm; // 브랜드영문명
+	private String goodsNm;
+	private String goodsNum;
+	private String supplyGoodsCd;
+	private String excelFileNm;
+	private String stDate;
+	private String edDate;
+	
+	private String search; // 키워드 종류
+	private String condition; // 키워드 종류별 값
+	private String brandList;
+	private String roleCd;
+	private String supplyCompCd;
+	
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiBrand;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] conditionList;
+
+}

+ 178 - 8
src/main/java/com/style24/persistence/mybatis/shop/TssGoods.xml

@@ -2248,7 +2248,7 @@
 
 		<!-- 상품별 전시카테고리 삭제-->
 	<delete id="deleteGoodsCategory" parameterType="GoodsCategory">
-		/* TsaGoods.deleteGoodsCategory */
+		/* TssGoods.deleteGoodsCategory */
 		DELETE
 		FROM TB_CATE_GOODS
 		WHERE GOODS_CD = #{goodsCd}
@@ -3027,7 +3027,7 @@
 
   <!-- 구상 상품등록/저장 -->
   <insert id="saveGoodsCompose" parameterType="GoodsCompose">
-    /* TsaGoods.saveGoodsCompose */
+    /* TssGoods.saveGoodsCompose */
     INSERT INTO TB_GOODS_COMPOSE (
                GOODS_CD
              , COMPS_GOODS_CD
@@ -3074,7 +3074,7 @@
 
   <!-- 구성상품 목록 -->
   <select id="getGoodsDetailComposeList" parameterType="Goods" resultType="GoodsCompose">
-    /* TsaGoods.getGoodsDetailComposeList */
+    /* TssGoods.getGoodsDetailComposeList */
     SELECT A.GOODS_CD
          , A.GOODS_TYPE
          , FN_GET_CODE_NM('G056', A.GOODS_TYPE) AS GOODS_TYPE_NM
@@ -3108,7 +3108,7 @@
 
   <!-- 자사브랜드, 업체 연관정보 확인  -->
   <select id="getBrandSupplyCount" parameterType="Brand" resultType="int">
-    /* TsaGoods.getBrandSupplyCount */
+    /* TssGoods.getBrandSupplyCount */
     SELECT  COUNT(*)
     FROM TB_BRAND B
     INNER JOIN TB_BRAND_SUPPLY BS ON B.BRAND_CD  = BS.BRAND_CD
@@ -3120,7 +3120,7 @@
 
 	<!-- WMS입고상품 목록 건수 -->
 	<select id="getGoodsWmsIncomelotListCount" parameterType="WmsGoods" resultType="int">
-		/* TsaGoods.getGoodsWmsIncomelotListCount */
+		/* TssGoods.getGoodsWmsIncomelotListCount */
 		SELECT COUNT(*)
 		  FROM TB_WMS_GOODS A
 		 INNER JOIN TB_BRAND B ON A.BRAND_NO = B.BRAND_NO
@@ -3150,7 +3150,7 @@
 
 	<!-- WMS입고상품 목록 -->
 	<select id="getGoodsWmsIncomelotList" parameterType="WmsGoods" resultType="WmsGoods">
-		/* TsaGoods.getGoodsWmsIncomelotList */
+		/* TssGoods.getGoodsWmsIncomelotList */
 		SELECT Q.* FROM (
 		    SELECT Z.* FROM (
 		        SELECT A.* FROM (
@@ -3231,7 +3231,7 @@
 
 	<!-- WMS입고단품목록 건수 -->
 	<select id="getGoodsWmsIncomelotSkuListCount" parameterType="IfIncomelot" resultType="int">
-		/* TsaGoods.getGoodsWmsIncomelotSkuListCount */
+		/* TssGoods.getGoodsWmsIncomelotSkuListCount */
 		SELECT COUNT(*)
 		FROM (
 		    SELECT A.LOTNO
@@ -3298,7 +3298,7 @@
 
 	<!-- WMS입고단품목록 -->
 	<select id="getGoodsWmsIncomelotSkuList" parameterType="IfIncomelot" resultType="IfIncomelot">
-		/* TsaGoods.getGoodsWmsIncomelotSkuList */
+		/* TssGoods.getGoodsWmsIncomelotSkuList */
 		SELECT Q.*
 		  FROM (
 		        SELECT Z.*
@@ -3367,4 +3367,174 @@
 		        ) Q
 		 LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
 	</select>
+	
+	<!-- 상품 동영상 조회 -->
+	<select id="getGoodsVideoList" parameterType="GoodsVideo" resultType="GoodsVideo">
+		/* TssGoods.getGoodsVideoList */
+		SELECT A.VIDEO_SQ
+		     , A.GOODS_CD
+		     , D.BRAND_ENM
+		     , A.VIDEO_GB
+		     , A.KMC_KEY
+		     , A.KUF_KEY
+		     , A.DISP_YN
+		     , A.REG_NO
+		     , FN_GET_USER_NM(A.REG_NO) AS REG_NM
+		     , DATE_FORMAT(A.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		     , A.UPD_NO
+		     , FN_GET_USER_NM(A.UPD_NO) AS UPD_NM
+		     , DATE_FORMAT(A.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		FROM TB_GOODS_VIDEO A
+		INNER JOIN TB_GOODS C ON A.GOODS_CD = C.GOODS_CD
+		INNER JOIN TB_BRAND D ON C.BRAND_CD = D.BRAND_CD
+		WHERE 1 = 1
+		<if test='goodsCd != null and goodsCd != "" '>
+		AND A.GOODS_CD = #{goodsCd}
+		</if>
+		<if test='goodsNm != null and goodsNm != "" '>
+		AND C.GOODS_NM = #{goodsNm}
+		</if>
+		<if test='goodsNum != null and goodsNum != "" '>
+		AND C.GOODS_NUM = #{goodsNum}
+		</if>
+		<if test='kmcKey != null and kmcKey != "" '>
+		AND A.KMC_KEY = #{kmcKey}
+		</if>
+		<if test='supplyGoodsCd != null and supplyGoodsCd != "" '>
+		AND C.SUPPLY_GOODS_CD = #{supplyGoodsCd}
+		</if>
+		<if test='brandEnm != null and brandEnm != "" '>
+		AND (
+		     D.BRAND_ENM LIKE CONCAT(#{brandEnm},'%')
+		     OR
+		     D.BRAND_KNM LIKE CONCAT(#{brandEnm},'%')
+		    )
+		</if>
+		<if test='stDate != null and stDate != "" '>
+		<![CDATA[
+		AND A.REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d')
+		]]>
+		</if>
+		<if test='edDate != null and edDate != "" '>
+		<![CDATA[
+		AND A.REG_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		]]>
+		</if>
+		<if test='conditionList != null and conditionList.length>0'>
+		    <choose>
+		      <when test='search != null and search == "searchGoodsCd"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       A.GOODS_CD LIKE CONCAT(UPPER(#{item}),'%')
+		      </foreach>
+		     )
+		      </when>
+		      <when test='search != null and search == "searchGoodsNm"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(C.GOODS_NM) LIKE CONCAT('%', UPPER(#{item}),'%')
+		      </foreach>
+		     )
+		      </when>
+		       <when test='search != null and search == "searchGoodsNum"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(C.GOODS_NUM) LIKE CONCAT('%', UPPER(#{item}),'%')
+		      </foreach>
+		     )
+		      </when>
+		      <when test='search != null and search == "searchSupplyGoodsCd"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(C.SUPPLY_GOODS_CD) LIKE CONCAT('%', UPPER(#{item}),'%')
+		      </foreach>
+		     )
+		      </when>
+		      <when test='search != null and search == "searchExtendGoodsCd"'>
+		AND 1 = 1
+		      </when>
+		      <when test='search != null and search == "searchMasterGoodsCd"'>
+		AND 1 = 1
+		      </when>
+		      <otherwise>
+		AND 1 = 1
+		      </otherwise>
+		    </choose>
+		</if>
+		<if test="multiBrand != null and multiBrand != ''">
+		AND C.BRAND_CD IN
+		    <foreach collection="multiBrand" item="item" index="index"  open="(" close=")" separator=",">
+		#{item}
+		    </foreach>
+		</if>
+		
+		<if test="supplyCompCd != null and supplyCompCd != ''">
+        AND C.SUPPLY_COMP_CD = #{supplyCompCd}
+        </if>
+		<if test='roleCd != null and roleCd == "G001_B000" '>
+        AND C.SELF_GOODS_YN = 'N'    -- 입점상품
+        </if>
+        <if test='roleCd != null and roleCd == "G001_E000" '>
+        AND C.SELF_GOODS_YN = 'Y'     -- 자사상품
+        </if>
+        
+		ORDER BY A.VIDEO_SQ DESC
+	</select>
+
+	<!-- 상품 동영상 노출안함으로 변경 -->
+	<update id="updateNotUseGoodsVideo" parameterType="GoodsVideo">
+		/* TssGoods.updateNotUseGoodsVideo */
+		UPDATE TB_GOODS_VIDEO
+		SET DISP_YN = 'N'
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		WHERE VIDEO_SQ = #{videoSq}
+	</update>
+
+	<!-- 동영상  등록 -->
+	<insert id="createGoodsVideo" parameterType="GoodsVideo">
+		/* TssGoods.createGoodsVideo */
+		INSERT INTO TB_GOODS_VIDEO
+		    (
+		           VIDEO_SQ
+		         , GOODS_CD
+		         , VIDEO_GB
+		         , KMC_KEY
+		         , KUF_KEY
+		         , DISP_YN
+		         , REG_NO
+		         , REG_DT
+		         , UPD_NO
+		         , UPD_DT
+		    )
+		    VALUES (
+		           #{videoSq}
+		         , #{goodsCd}
+		         , #{videoGb}
+		         , CASE WHEN LENGTH(#{kmcKey}) = 0 THEN NULL ELSE #{kmcKey} END
+		         , #{kufKey}
+		         , #{dispYn}
+		         , #{regNo}
+		         , NOW()
+		         , #{updNo}
+		         , NOW()
+		    )
+		ON DUPLICATE KEY UPDATE
+		       DISP_YN = #{dispYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 동영상  수정 -->
+	<update id="updateGoodsVideo" parameterType="GoodsVideo">
+		/* TssGoods.saveGoodsVideo */
+		UPDATE TB_GOODS_VIDEO SET
+		           DISP_YN = #{dispYn}
+		         , VIDEO_GB = #{videoGb}
+		         , KMC_KEY = CASE WHEN LENGTH(#{kmcKey}) = 0 THEN NULL ELSE #{kmcKey} END
+		         , UPD_NO = #{updNo}
+		         , UPD_DT = NOW()
+		WHERE VIDEO_SQ = #{videoSq}
+	</update>
+	
 </mapper>

+ 6 - 8
src/main/java/com/style24/persistence/mybatis/shop/TssLogin.xml

@@ -78,19 +78,17 @@
 		FROM   TB_USER A
 		WHERE  USER_ID = #{userId}
 		AND    (ROLE_CD LIKE 'G001_B%'
-		        OR ROLE_CD LIKE 'G001_E%'
-		        OR ROLE_CD LIKE 'G001_D%'
-		        OR ROLE_CD LIKE 'G001_F%') /*입점업체벤더담당자, 촬영업체담당자, 제휴채널담당자, 직송매장담당자*/
-		AND    USE_YN = 'Y'
-		AND    (
-		        ROLE_CD LIKE 'G001_B%'
-		        AND
+				AND
 		        EXISTS (SELECT 1
 		                FROM   TB_SUPPLY_VENDOR
 		                WHERE  SUPPLY_VENDOR_CD = A.ROLE_REF_VAL
 		                AND    USE_YN = 'Y'
 		               )
-		       )
+		        OR ROLE_CD LIKE 'G001_E%'
+		        OR ROLE_CD LIKE 'G001_D%'
+		        OR ROLE_CD LIKE 'G001_F%') /*입점업체벤더담당자, 촬영업체담당자, 제휴채널담당자, 직송매장담당자*/
+		AND    USE_YN = 'Y'
+		
 	</select>
 	
 	<!-- 로그인실패 남기기 -->

+ 38 - 0
src/main/java/com/style24/scm/biz/dao/TssGoodsDao.java

@@ -19,6 +19,7 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSafeNo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsSupplyPrice;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.IfIncomelot;
 import com.style24.persistence.domain.IfProductSku;
 import com.style24.persistence.domain.Itemkind;
@@ -766,4 +767,41 @@ public interface TssGoodsDao {
 	 * @since 2021. 11. 25
 	 */
 	Collection<WmsGoods> getGoodsWmsIncomelotSkuList(IfIncomelot ifIncomelot);
+	
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo);
+
+	/**
+	 * 상품 동영상 사용안함으로 변경
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateNotUseGoodsVideo(GoodsVideo goodsVideo);
+
+	/**
+	 * 동영상 등록
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void createGoodsVideo(GoodsVideo goodsVideo);
+
+	/**
+	 * 동영상 수정
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateGoodsVideo(GoodsVideo goodsVideo);
 }

+ 118 - 0
src/main/java/com/style24/scm/biz/service/TssGoodsService.java

@@ -38,6 +38,7 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSafeNo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsSupplyPrice;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.IfIncomelot;
 import com.style24.persistence.domain.IfProductSku;
 import com.style24.persistence.domain.Itemkind;
@@ -4258,6 +4259,9 @@ public class TssGoodsService {
 		goods.setPrePpntUsableYn("N");
 		goods.setPreMpntUsableYn("N");
 
+		// 2021.12.07 card007 입점업체 상품등록에 유통구분 자사정보로 등록되어 입점-위탁으로 변경 처리
+		goods.setDistributionGb("G065_20");		// 입점-위탁
+
 		//log.info("[createGoodsDetail 22 ] goods=>{}", goods);
 		// 기본정보 생성
 		goodsDao.createGoods(goods); // 상품기본 저장
@@ -4836,4 +4840,118 @@ public class TssGoodsService {
 	public Collection<WmsGoods> getGoodsWmsIncomelotSkuList(IfIncomelot ifIncomelot) {
 		return goodsDao.getGoodsWmsIncomelotSkuList(ifIncomelot);
 	}
+	
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	public Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo) {
+		return goodsDao.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 삭제로 변경
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void updateNotUseGoodsVideo(Collection<GoodsVideo> goodsVideos) {
+		for (GoodsVideo goodsVideo : goodsVideos) {
+			goodsVideo.setUpdNo(TssSession.getInfo().getUserNo());
+			goodsDao.updateNotUseGoodsVideo(goodsVideo);
+		}
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @param video
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsVideo(GoodsVideo goodsVideo) {
+		GoodsSearch goodsSearch = new GoodsSearch();
+		goodsSearch.setGoodsCd(goodsVideo.getGoodsCd());
+		goodsSearch.setRoleCd(goodsVideo.getRoleCd());
+		goodsSearch.setSupplyCompCd(goodsVideo.getSupplyCompCd());
+		
+		int goodsCnt = goodsDao.getGoodsListCount(goodsSearch);
+		if (goodsCnt <= 0) {
+			throw new IllegalStateException(goodsVideo.getGoodsCd() + "의 상품코드를 확인해 주세요.");
+		}
+		goodsVideo.setRegNo(TssSession.getInfo().getUserNo());
+		goodsVideo.setUpdNo(TssSession.getInfo().getUserNo());
+
+		if (goodsVideo.getVideoSq() == null || goodsVideo.getVideoSq() == 0) {
+
+			if ("Y".equals(goodsVideo.getVideoGb())) {
+				Collection<GoodsVideo> goodsVideoList = goodsDao.getGoodsVideoList(goodsVideo);
+				if (goodsVideoList != null && goodsVideoList.size() > 0) {
+					GoodsVideo orgingGoodsVideo = goodsVideoList.iterator().next();
+					goodsVideo.setVideoSq(orgingGoodsVideo.getVideoSq());
+				}
+			}
+			goodsDao.createGoodsVideo(goodsVideo);
+
+		} else {
+			goodsDao.updateGoodsVideo(goodsVideo);
+		}
+	}
+
+	/**
+	 * 상품동영상 엑셀파일 등록
+	 *
+	 * @param dataList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public int saveExcelGoodsVideo(Collection<GagaMap> dataList, GoodsVideo gVideo) {
+
+		int cnt = 0;
+
+		for (GagaMap map : dataList) {
+			GoodsVideo goodsVideo = mapper.convertValue(map, GoodsVideo.class);
+
+			GoodsSearch goodsSearch = new GoodsSearch();
+			goodsSearch.setGoodsCd(goodsVideo.getGoodsCd());
+			goodsSearch.setRoleCd(gVideo.getRoleCd());
+			goodsSearch.setSupplyCompCd(gVideo.getSupplyCompCd());
+			
+			int goodsCnt = goodsDao.getGoodsListCount(goodsSearch);
+			if (goodsCnt <= 0) {
+				throw new IllegalStateException(goodsVideo.getGoodsCd() + "의 상품코드를 확인해 주세요.");
+			}
+
+			Collection<GoodsVideo> goodsVideoList = goodsDao.getGoodsVideoList(goodsVideo);
+			if (goodsVideoList != null && goodsVideoList.size() > 0) {
+				GoodsVideo orgingGoodsVideo = goodsVideoList.iterator().next();
+				goodsVideo.setUpdNo(TssSession.getInfo().getUserNo());
+				goodsVideo.setVideoGb("Y");
+				goodsVideo.setDispYn(orgingGoodsVideo.getDispYn());
+				goodsDao.updateGoodsVideo(goodsVideo);
+
+			} else {
+				goodsVideo.setUpdNo(TssSession.getInfo().getUserNo());
+				goodsVideo.setRegNo(TssSession.getInfo().getUserNo());
+				goodsVideo.setDispYn("Y");
+				goodsVideo.setVideoGb("Y");
+				goodsDao.createGoodsVideo(goodsVideo);
+			}
+
+			cnt++;
+		}
+
+		return cnt;
+	}
 }

+ 129 - 0
src/main/java/com/style24/scm/biz/web/TssGoodsController.java

@@ -50,6 +50,7 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSafeNo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsSupplyPrice;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.IfIncomelot;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
@@ -2217,4 +2218,132 @@ public class TssGoodsController extends TssBaseController {
 
 		return result;
 	}
+	
+	/**
+	 * 상품 동영상관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@GetMapping("/video/form")
+	public ModelAndView videoForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		String selfYn = "Y";
+		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	//입점업체담당자
+			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
+			selfYn = "N";
+		} else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {	// 촬영업체
+			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
+			selfYn = "Y";
+		}
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, selfYn));
+		
+		mav.setViewName("goods/GoodsVideoForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/list")
+	@ResponseBody
+	public Collection<GoodsVideo> getGoodsVideoList(@RequestBody GoodsVideo goodsVideo) {
+
+		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	//입점업체담당자
+			goodsVideo.setSupplyCompCd(TssSession.getInfo().getSupplyCompCd());
+		}
+		
+		goodsVideo.setRoleCd(TssSession.getInfo().getRoleCd());
+		
+		// multi row 검색관련 처리
+		if (!StringUtils.isBlank(goodsVideo.getCondition())) {
+			goodsVideo.setConditionList(goodsVideo.getCondition().replaceAll("\r", "").trim().split("\n"));
+
+		}
+
+		if (!StringUtils.isBlank(goodsVideo.getBrandList())) {
+			try {
+				String[] arrBrandCd = mapper.readValue(goodsVideo.getBrandList(), String[].class);
+				goodsVideo.setMultiBrand(arrBrandCd);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
+			}
+		}
+
+		return goodsService.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 미노출 변경
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/update/notUse")
+	@ResponseBody
+	public GagaResponse updateNotUseGoodsVideo(@RequestBody Collection<GoodsVideo> goodsVideos) {
+		goodsService.updateNotUseGoodsVideo(goodsVideos);
+		return super.ok(message.getMessage("SUCC_0009"));
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/save")
+	@ResponseBody
+	public GagaResponse saveGoodsVideo(@RequestBody GoodsVideo goodsVideo) {
+				
+		goodsVideo.setRoleCd(TssSession.getInfo().getRoleCd());
+		goodsVideo.setSupplyCompCd(TssSession.getInfo().getSupplyCompCd());
+		
+		goodsService.saveGoodsVideo(goodsVideo);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품동영상 엑셀 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/excel/save")
+	@ResponseBody
+	public GagaResponse saveExcelGoodsVideo(@RequestBody GoodsVideo goodsVideo) throws Exception {
+
+		goodsVideo.setRoleCd(TssSession.getInfo().getRoleCd());
+		goodsVideo.setSupplyCompCd(TssSession.getInfo().getSupplyCompCd());
+		
+		String[] cellName = null;
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		cellName = new String[2];
+		cellName[0] = "goodsCd";
+		cellName[1] = "kmcKey";
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		Collection<GagaMap> dataList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goodsVideo.getExcelFileNm()), 0, cellName);
+
+		int cnt = goodsService.saveExcelGoodsVideo(dataList, goodsVideo);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goodsVideo.getExcelFileNm()));
+
+		return super.ok(cnt + " 건 처리되었습니다.");
+	}
 }

+ 420 - 0
src/main/webapp/WEB-INF/views/goods/GoodsVideoForm.html

@@ -0,0 +1,420 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsVideoForm.html
+ * @desc    : 상품동영상관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.16   eskim       최초 작성
+  *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<!-- //TITLE -->
+			<div class="panelContent">
+			
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/video/list'}">
+				
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:62%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드<em class="required" title="필수"></em></th>
+						<td colspan="5">
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" >[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<span id="multiBrand"></span>
+						</td>
+						
+						<th rowspan="2">키워드</th>
+						<td rowspan="2">
+							<select name="search" id="search">
+								<option value="searchGoodsCd">상품코드</option>
+								<option value="searchGoodsNm">상품명</option>
+								<option value="searchGoodsNum">품번</option>
+								<option value="searchSupplyGoodsCd">업체상품코드</option>
+							</select>
+							<textarea class="textareaR2 w50p" name="condition" id="condition"></textarea>
+						</td>
+						
+					</tr>
+					<tr>
+						<th>등록일</th>
+						<td id="sellTerms">
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit">초기화</button>
+						<button type="button" class="btn btn-success btn-lg" id="btnSearch">조회</button>
+					</li>
+				</ul>
+			</form>
+			</div>
+		</div>
+		<!-- //검색조건 영역 -->
+		
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li class="left">
+					<button type="button" class="btn btn-danger btn-lg" id="btnNotUse">노출안함</button>
+				</li>
+				<li  class="right">
+					<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF002');">상품동영상등록 양식다운로드</button>
+					<button type="button" class="btn btn-info btn-lg" id="btnExcReg">엑셀등록</button>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 450px;" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+		<!-- 등록/수정 -->
+		<div class="panelStyle">
+			<form id="detailForm" name="detailForm">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<td colspan='6'>동영상등록(상세)</td>
+					</tr>
+					<tr>
+						<th>상품코드<em class="required" title="필수"></em></th>
+						<td>
+							<input name="videoSq"  data-valid-name="상품동영상일련번호" type="hidden"/>
+							<input type="text" class="w150" name="goodsCd" maxlength="20" required="required" data-valid-name="상품코드"/>
+						</td>
+						<th>동영상구분<em class="required" title="필수"></em></th>
+						<td>
+							<select name="videoGb" id="videoGb" required="required" data-valid-name="동영상구분" onchange="fnVideoGb();">
+								<!-- <option value="">[선택]</option> -->
+								<option value="Y" selected="selected">[Y] 유투브</option>
+								<option value="M">[M] MP4</option>
+							</select>
+						</td>
+						<th>노출여부<em class="required" title="필수"></em></th>
+						<td>
+							<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYn" value="Y" checked="checked">Y</label>
+							<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYn" value="N">N</label>
+						</td>
+					</tr>
+					<tr id="youtubeArea">
+						<th>동영상URL<em class="required" title="필수"></em></th>
+						<td class="infoTxt" colspan="5">
+							<em><i class="fa fa-info-circle"></i>유투브의 경우 빨간색 표시로 되어있는 값만 넣으세요.</em><br/>
+							예시 : https://www.youtube.com/embed/<em><strong>5YqYG71bQ3s</strong></em>?showinfo=0&amp;rel=0&amp;vp=hd1080&amp;fs=0&amp;wmode=opaque&amp;enablejsapi=1
+							<br/>
+							<input type="text" class="w400" id="kmcKey" name="kmcKey" maxlength="100" >
+							<button type="button" class="btn btn-dark btn-lg" onclick="cfnOpenGoodsVideoPopup('filmVideoView','kmcKey', '#detailForm', $('#videoGb').val());">미리보기</button>
+						</td>
+					</tr>
+					<tr id="fileArea" style="display:none;">
+						<th>파일첨부<em class="required" title="필수"></em></th>
+						<td class="infoTxt" colspan="5">
+							<div class="uFile w300">
+								<input id="file" name="file" type="file" class="uFileInput w300"/>
+								<label for="file" class="uFileLabel">파일선택</label>
+								<input type="hidden" name="kufKey"/>
+								<input type="hidden" name="kmcKey"/>
+							</div>
+							<div id="keyArea">미디어키 : <input type="text" class="w200"  name="hkmcKey" disabled> upload키 : <input type="text" class="w200"  name="hkufKey" disabled></div>
+							<button type="button" class="btn btn-dark btn-lg" onclick="cfnOpenGoodsVideoPopup('filmVideoView','kmcKey', '#detailForm', $('#videoGb').val());">미리보기</button>
+							
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-info btn-lg" id="btnNew">신규</button>
+						<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
+					</li>
+				</ul>
+			</form>
+		</div>
+	</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.kollus.js"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var videoGbList = {'Y':'유투브', 'M':'MP4'};
+	// specify the columns
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "브랜드명", field: "brandEnm", width: 120, cellClass: 'text-center'},
+		{headerName: "상품동영상일련번호", field: "goodsVideoSq", width: 120, cellClass: 'text-center', hide: true},
+		{headerName: "상품코드", field: "goodsCd", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}	
+		},
+ 		{headerName: "동영상구분", field: "videoGb", width: 100, cellClass: 'text-center',
+			cellRenderer: function (params) { return !gagajf.isNull(params.value) ? "["+params.value+"] "+gagaAgGrid.lookupValue(videoGbList, params.value) : '';}
+		},
+		{headerName: "동영상정보", field: "kmcKey", width: 300, cellClass: 'text-center'},
+		{headerName: "노출여부", field: "dispYn", width: 80, cellClass: 'text-center'},
+		{headerName: "등록일자", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regNm", width: 150, cellClass: 'text-center'},
+		{headerName: "수정일자", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updNm", width: 150, cellClass: 'text-center'},
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	
+	// 상품코드 셀 클릭
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field == "goodsCd"){
+			var formId = '#detailForm';
+			$(formId + " input[name=videoSq]").val(event.data.videoSq);
+			$(formId + " input[name=goodsCd]").val(event.data.goodsCd);
+			$(formId + " select[name=videoGb]").val(event.data.videoGb);
+			$(formId + " input[name=kmcKey]").val(event.data.kmcKey);
+			$(formId + " input[name=kufKey]").val(event.data.kufKey);
+			$(formId + " input[name=hkmcKey]").val(event.data.kmcKey);
+			$(formId + " input[name=hkufKey]").val(event.data.kufKey);
+			$(formId + " input:radio[name=dispYn]:input[value="+event.data.dispYn+"]").click();
+			$(formId + " input[name=goodsCd]").prop("disabled", true);
+			$(formId + " select[name=videoGb]").prop("disabled", true);
+			
+			$(formId).closest("div").show();
+			if ("Y" == event.data.videoGb){
+				$('#youtubeArea').show();
+				$('#fileArea').hide();
+			}else{
+				$('#youtubeArea').hide();
+				$('#fileArea').show();
+				$('.uFile').hide();
+				$('#keyArea').show();
+			}
+		}
+	}
+	
+	// 신규 버튼 클릭
+	$("#btnNew").on('click', function() {
+		$("#detailForm")[0].reset();
+		$("#detailForm input[name=videoSq]").val('');
+		$("#detailForm input[name=goodsCd]").prop("disabled", false);
+		$("#detailForm select[name=videoGb]").prop("disabled", false);
+		$('#youtubeArea').show();
+		$('#fileArea').hide();
+	});
+
+	// 엑셀등록
+	$("#btnExcReg").on('click', function() {
+		cfnExcelUploadPopup('','fnExcelUpoadCallback');
+	});
+	
+	var fnExcelUpoadCallback = function(data){
+		
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/video/excel/save', jsonData, fnSaveCallback);
+		
+	}
+	
+	// 동영상구분 변경시
+	var fnVideoGb = function(){
+		if ("Y" == $("#detailForm select[name=videoGb]").val()){
+			$('#youtubeArea').show();
+			$('#fileArea').hide();
+			$('.uFile').hide();
+			$('#keyArea').hide();
+		}else{
+			$('#youtubeArea').hide();
+			$('#fileArea').show();
+			$('.uFile').show();
+			$('#keyArea').hide();
+		}
+	}
+	
+	// 조회
+	$('#btnSearch').on('click', function() {
+		
+		if(!fnConditionCheck()) return;
+		
+		// Fetch data
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		$("#btnNew").click();
+	});
+	
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		
+		if (event.keyCode === 13) return false;
+		
+		var form = document.searchForm;
+
+		var searchFlag = false;
+		var cnt = 0;
+
+		for (i = 0; i < form.elements.length; i++ ) {
+			var el = form.elements[i];
+
+			if ($(el).prop("type") == "text" || $(el).prop("type") == "textarea" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+				if (!(el.value == null || el.value == "")) {
+					cnt++;
+				}
+			}
+		}
+		if(cnt > 0) searchFlag = true;
+
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		// 기간 값 체크
+		if (!fnCalendarDateValidation('#sellTerms', 'stDate', 'edDate')){
+			return false;
+		}
+
+		return true;
+	}
+	
+	// 검색조건 초기화
+	$('#btnInit').on('click', function() {
+		$("#searchForm")[0].reset();
+		$("#multiBrand").empty();
+	});
+	
+	// 선택상품 사용안함
+	$("#btnNotUse").on('click', function() {
+		var selectRowData = gagaAgGrid.selectedRowData(gridOptions);
+		if(selectRowData.length>0){
+			mcxDialog.confirm('선택한 상품동영상을 미노출처리 하시겠습니까?', {
+				cancelBtnText: "취소",
+				sureBtnText: "확인",
+				sureBtnClick: function(){
+					var jsonData = JSON.stringify(selectRowData);
+					gagajf.ajaxJsonSubmit('/goods/video/update/notUse', jsonData, fnSaveCallback);
+				}
+			})
+		}else{
+			mcxDialog.alert("선택된 상품동영상이 없습니다.");
+		}
+	});
+	
+	// 동영상 저장
+	$("#btnSave").on('click', function() {
+		
+		var formId = '#detailForm';
+		var videoSq = $(formId + " input[name=videoSq]").val();
+		var goodsCd = $(formId + " input[name=goodsCd]").val();
+		var videoGb = $(formId + " select[name=videoGb]").val();
+		var kmcKey = $(formId + " input[name=kmcKey]").val();
+		var kufKey = $(formId + " input[name=kufKey]").val();
+		var dispYn = $(formId + " input:radio[name=dispYn]:checked").val();
+		
+		if(goodsCd==''){
+			gagajf.alertMessage(formId + " input[name=goodsCd]", 'input');
+			return;
+		}
+		if(videoGb==''){
+			gagajf.alertMessage(formId + " select[name=videoGb]", 'select');
+			return;
+		}
+		/* if(kmcKey==''){
+			gagajf.alertMessage(formId + " input[name=kmcKey]", 'input');
+			return;
+		} */
+		
+		if(kmcKey.indexOf("http")>-1){
+			mcxDialog.alert('동영상 정보를 확인해 주세요.');
+			return;
+		}
+		
+		mcxDialog.confirm('저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {videoSq : videoSq
+							,goodsCd : goodsCd
+							,videoGb : videoGb
+							,kmcKey : kmcKey
+							,kufKey : kufKey
+							,dispYn : dispYn
+							};
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/video/save', jsonData, fnSaveCallback);
+			}
+		})
+	});
+	
+	var fnSaveCallback = function() {
+		$('#btnSearch').click();
+	}
+	
+	// 동영상파일 선택 시
+	$('#detailForm input[name=file]').on('change', function() {
+		var file = this.files[0];
+		gagaKollus.upload('Goods', file, $('input[name=kufKey]'));
+	});
+	
+	//업체변경시
+	$('#searchForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+
+		//$("#searchForm select[name=brandCd] option:gt(0)").remove();
+		//cfnCreateCombo(actionUrl, $('#searchForm select[name=brandCd]'), "[전체]", brandCd);
+		cfnCreateMultiCombo(actionUrl,"multiBrand",  "[전체]",null, 'Y');
+	});
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', true);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		
+		//$('#btnSearch').click();
+	});
+/*]]>*/
+</script>
+
+</html>