Jelajahi Sumber

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

gagamel 5 tahun lalu
induk
melakukan
d3a10eac5f
68 mengubah file dengan 6568 tambahan dan 152 penghapusan
  1. 16 0
      style24.admin/pom.xml
  2. 12 1
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaBusinessDao.java
  3. 44 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java
  4. 149 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java
  5. 9 9
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaRendererDao.java
  6. 12 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaBusinessService.java
  7. 61 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java
  8. 417 2
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java
  9. 11 11
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaRendererService.java
  10. 202 0
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaCommonController.java
  11. 297 3
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java
  12. 14 14
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaRendererController.java
  13. 18 17
      style24.admin/src/main/java/com/style24/persistence/domain/Goods.java
  14. 20 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsDesc.java
  15. 67 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsHst.java
  16. 2 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsNotiInfo.java
  17. 2 0
      style24.admin/src/main/java/com/style24/persistence/domain/NotiInfo.java
  18. 24 0
      style24.admin/src/main/java/com/style24/persistence/domain/SearchData.java
  19. 48 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaBusiness.xml
  20. 58 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCommon.xml
  21. 473 5
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml
  22. 2 2
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml
  23. 112 0
      style24.admin/src/main/webapp/WEB-INF/views/common/ExcelUploadPopupForm.html
  24. 1929 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html
  25. 9 7
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsListForm.html
  26. 15 4
      style24.admin/src/main/webapp/WEB-INF/views/goods/NotiinfoForm.html
  27. 480 0
      style24.admin/src/main/webapp/smartEditor/SEditorSkin.html
  28. 334 0
      style24.admin/src/main/webapp/smartEditor/css/default.css
  29. 30 0
      style24.admin/src/main/webapp/smartEditor/css/style.css
  30. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/XPButtonUploadText_61x22.png
  31. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bg_qmark.gif
  32. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bg_tool.gif
  33. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_confirm.gif
  34. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_expand.gif
  35. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_html.gif
  36. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_cancel.gif
  37. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_cell_adjust.gif
  38. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_close.gif
  39. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_confirm.gif
  40. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_find_next.gif
  41. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_find_next_strong.gif
  42. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_img.gif
  43. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_replace.gif
  44. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_replace_all.gif
  45. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_layer_tab.gif
  46. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_qmark.gif
  47. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_search.gif
  48. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_set.gif
  49. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_set_blank.gif
  50. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/btn_set_original.gif
  51. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bx_character.gif
  52. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bx_find.gif
  53. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bx_table.gif
  54. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/bx_url.gif
  55. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/img/vr_layer_character.gif
  56. 109 0
      style24.admin/src/main/webapp/smartEditor/js/Husky.SE_Basic.js
  57. 126 0
      style24.admin/src/main/webapp/smartEditor/js/HuskyEZCreator.js
  58. 80 0
      style24.admin/src/main/webapp/smartEditor/js/SE_CustomPlugins.js
  59. 172 0
      style24.admin/src/main/webapp/smartEditor/js/jindo.min.js
  60. 10 0
      style24.admin/src/main/webapp/smartEditor/se_blank.html
  61. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/swfupload/img/my_img.gif
  62. 49 0
      style24.admin/src/main/webapp/smartEditor/swfupload/js/handlers.js
  63. 980 0
      style24.admin/src/main/webapp/smartEditor/swfupload/js/swfupload.js
  64. TEMPAT SAMPAH
      style24.admin/src/main/webapp/smartEditor/swfupload/swf/swfupload.swf
  65. 41 0
      style24.admin/src/main/webapp/smartEditor/swfupload/swfupload_proc.jsp
  66. 34 0
      style24.admin/src/main/webapp/smartEditor/write.html
  67. 99 76
      style24.admin/src/main/webapp/ux/css/admin.ui.css
  68. 1 1
      style24.admin/src/main/webapp/ux/js/admin.popup.js

+ 16 - 0
style24.admin/pom.xml

@@ -69,6 +69,22 @@
 			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-excel-1.7.1-RELEASE.jar</systemPath>
 		</dependency>
 		<!-- \\\ WEB-INF lib -->
+		<dependency>
+			<groupId>servlets.com</groupId>
+			<artifactId>cos</artifactId>
+			<version>05Nov2002</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-fileupload</groupId>
+			<artifactId>commons-fileupload</artifactId>
+			<version>1.4</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.6</version>
+		</dependency>
+		
 	</dependencies>
 	
 	<build>

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

@@ -4,6 +4,7 @@ import java.util.Collection;
 
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Aflink;
+import com.style24.persistence.domain.Brand;
 import com.style24.persistence.domain.DeliveryLoc;
 import com.style24.persistence.domain.SellStore;
 import com.style24.persistence.domain.ShipCompany;
@@ -11,7 +12,7 @@ import com.style24.persistence.domain.SupplyCompany;
 
 /**
  * 영업관리 Dao
- * 
+ *
  * @author gagamel
  * @since 2020. 10. 14
  */
@@ -126,4 +127,14 @@ public interface TsaBusinessDao {
 	 */
 	void deleteShipCompany(ShipCompany shipComp);
 
+	/**
+	 * 브랜드 목록
+	 *
+	 * @param brand - 브랜드 정보
+	 * @return 브랜드 목록
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<Brand> getBrandList(Brand brand);
+
 }

+ 44 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java

@@ -0,0 +1,44 @@
+package com.style24.admin.biz.dao;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.SearchData;
+
+/**
+ * 공용 Dao
+ *
+ * @author eskim
+ * @since 2020. 10. 22
+ */
+@ShopDs
+public interface TsaCommonDao {
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 삭제
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void deleteExceluploadSearCh(SearchData searchData);
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createExceluploadSearch(SearchData searchData);
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성 - dummy 컬럼 포함
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createExceluploadSearchByAll(SearchData searchData);
+
+
+
+}

+ 149 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java

@@ -5,6 +5,9 @@ import java.util.Collection;
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Color;
 import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsDesc;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
@@ -119,4 +122,150 @@ public interface TsaGoodsDao {
 	 */
 	Collection<GagaMap> getGoodsInfoExcelList(GoodsSearch goodsSearch);
 
+	/**
+	 * 상품 이미지 필수 항목 입력 여부 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<Goods> getGoodsImgsYn(Goods goods);
+
+	/**
+	 * 상품 상세
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Goods getGoods(Goods goods);
+
+	/**
+	 * 상품 상세 정보 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<GoodsDesc> getGoodsDescList(GoodsDesc goodsDesc);
+
+	/**
+	 * 상품 정보 이력
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 08. 12
+	 */
+	Collection<GoodsHst> getGoodsHstList(Goods goods);
+
+//	/**
+//	 * 상품 옵션 조회
+//	 *
+//	 * @param goods
+//	 * @return
+//	 * @author eskim
+//	 * @since 2019. 08. 14
+//	 */
+//	Collection<TsaStock> getGoodsSizeList(TsaGoods goods);
+
+
+	/**
+	 * 상품 고시 조회
+	 *
+	 * @param goodsNotiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 12
+	 */
+	Collection<GoodsNotiInfo> getGoodsNotiInfoList(GoodsNotiInfo goodsNotiInfo);
+
+//	/**
+//	 * 구성상품 목록
+//	 *
+//	 * @param goodsNotiInfo
+//	 * @return
+//	 * @author eskim
+//	 * @since 2020. 06. 16
+//	 */
+//	Collection<GoodsExtend> getGoodsDetailExtendList(Goods goods);
+
+	/**
+	 * 상품 기본 정보 이력 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createGoodsHst(Goods goods);
+
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void updateGoodsState(Goods goods);
+
+	/**
+	 * 상품 품목변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void updateGoodItemKindCd(Goods goods);
+
+	/**
+	 * 상품 자동 검색어 조회
+	 *
+	 * @param goodsCd
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	String getGoodsSnm(String goodsCd);
+	
+	/**
+	 * 상품검색어 수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void updateGoodsSnm(Goods goods);
+	
+	/**
+	 * 상품 품목변경 고시정보 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	Collection<GoodsNotiInfo> getNewNotiInfo(Goods goods);
+	
+	/**
+	 * 상품 품목변경 고시정보 삭제
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void deleteGoodsNotiInfo(Goods goods);
+	
+	/**
+	 * 상품 고시 정보 수정
+	 *
+	 * @param goodsNotiInfo
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void saveGoodsNotiInfo(GoodsNotiInfo goodsNotiInfo);
+
+
 }

+ 9 - 9
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaRendererDao.java

@@ -80,15 +80,15 @@ public interface TsaRendererDao {
 	 */
 	Collection<CommonCode> getBrandList(Brand brand);
 
-//	/**
-//	 * 권한별 브랜드 목록
-//	 * @param userId - 사용자ID
-//	 * @return
-//	 * @author eskim
-//	 * @since 2019. 6.17
-//	 */
-//	Collection<CommonCode> getAuthBrandList(String userId);
-//
+	/**
+	 * 권한별 브랜드 목록
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author eskim
+	 * @since 2019. 6.17
+	 */
+	Collection<CommonCode> getAuthBrandList(int userNo);
+
 //	/**
 //	 * 출고처 목록
 //	 * @param params - 출고처 정보

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

@@ -11,6 +11,7 @@ import com.style24.admin.biz.dao.TsaBusinessDao;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.Aflink;
+import com.style24.persistence.domain.Brand;
 import com.style24.persistence.domain.DeliveryLoc;
 import com.style24.persistence.domain.SellStore;
 import com.style24.persistence.domain.ShipCompany;
@@ -192,4 +193,15 @@ public class TsaBusinessService {
 		}
 	}
 
+	/**
+	 * 브랜드 목록 조회
+	 *
+	 * @param brand - 브랜드 정보
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Collection<Brand> getBrandList(Brand brand) {
+		return businessDao.getBrandList(brand);
+	}
+
 }

+ 61 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java

@@ -0,0 +1,61 @@
+package com.style24.admin.biz.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.admin.biz.dao.TsaCommonDao;
+import com.style24.persistence.domain.SearchData;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 공용 Service
+ *
+ * @author eskim
+ * @since 2020. 10. 20
+ */
+@Service
+@Slf4j
+public class TsaCommonService {
+
+	@Autowired
+	private TsaCommonDao commonDao;
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 삭제
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void deleteExceluploadSearCh(SearchData searchData) {
+		commonDao.deleteExceluploadSearCh(searchData);
+	}
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void createExceluploadSearch(SearchData searchData) {
+		commonDao.createExceluploadSearch(searchData);
+	}
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성 - dummy 컬럼 포함
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void createExceluploadSearchByAll(SearchData searchData) {
+		commonDao.createExceluploadSearchByAll(searchData);
+	}
+
+
+}

+ 417 - 2
style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java

@@ -1,5 +1,6 @@
 package com.style24.admin.biz.service;
 
+import java.io.IOException;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -12,17 +13,23 @@ import com.style24.admin.biz.dao.TsaGoodsDao;
 import com.style24.admin.support.env.TsaConstants;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Brand;
 import com.style24.persistence.domain.Color;
 import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsDesc;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.SearchData;
 
 import lombok.extern.slf4j.Slf4j;
 
 import com.gagaframework.excel.GagaExcelUtil;
 import com.gagaframework.excel.env.GagaExcelConstants;
 import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUtil;
 import com.gagaframework.web.util.GagaStringUtil;
 
 /**
@@ -44,6 +51,12 @@ public class TsaGoodsService {
 	@Autowired
 	private TsaGoodsDao goodsDao;
 
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaCommonService commonService;
+
 	/**
 	 * 품목 목록
 	 * @param itemkind
@@ -231,10 +244,10 @@ public class TsaGoodsService {
 					} else {
 
 						if (!StringUtils.isEmpty(gagaMap.get("IMG_PATH6"))) {
-							gagaMap.set("IMG_PATH1", targetPath + gagaMap.get("IMG_PATH6").toString().replace("/1000/", "/100/"));
+							gagaMap.set("IMG_PATH1", targetPath + gagaMap.get("IMG_PATH6").toString());
 
 						} else {
-							gagaMap.set("IMG_PATH1", targetPath + gagaMap.get("IMG_PATH1").toString().replace("/1000/", "/100/"));
+							gagaMap.set("IMG_PATH1", targetPath + gagaMap.get("IMG_PATH1").toString());
 						}
 					}
 				}
@@ -276,4 +289,406 @@ public class TsaGoodsService {
 		}
 	}
 
+	/**
+	 * 상품 이미지 등록여부 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 21
+	 */
+	public Collection<Goods> getGoodsImgsYn(Goods goods) {
+		return goodsDao.getGoodsImgsYn(goods);
+	}
+
+	/**
+	 * 상품 상세
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Goods getGoods(Goods goods) {
+		// 상품기본정보
+		Goods resultGoods = goodsDao.getGoods(goods);
+
+		// 상품 상세
+		return this.getGoodsDesc(resultGoods);
+	}
+
+	/**
+	 * 상품 상세 조회
+	 *
+	 * @param resultGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private Goods getGoodsDesc(Goods resultGoods) {
+
+		GoodsDesc goods = new GoodsDesc();
+		goods.setGoodsCd(resultGoods.getGoodsCd());
+
+		//		goods.setDescGb("10");
+		//		String goodsDesc = this.getGoodsDescList(goods);
+		//		resultGoods.setGoodsDesc(goodsDesc);
+
+		// 상품 상세 pc 상단
+		goods.setDescGb("20");
+		String goodsPcTopDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsPcTopDesc(goodsPcTopDesc);
+
+		// 상품 상세  pc 하단
+		goods.setDescGb("30");
+		String goodsPcDownDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsPcDownDesc(goodsPcDownDesc);
+
+		// 상품 상세 mobile 상단
+		goods.setDescGb("40");
+		String goodsMobileTopDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsMobileTopDesc(goodsMobileTopDesc);
+
+		// 상품 상세 mpbile 하단
+		goods.setDescGb("50");
+		String goodsMobileDownDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsMobileDownDesc(goodsMobileDownDesc);
+
+		return resultGoods;
+	}
+
+	/**
+	 * 상품 상세구분별 컨텐츠 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private String getGoodsDescList(GoodsDesc goodsDesc) {
+		Collection<GoodsDesc> goodsDescList = goodsDao.getGoodsDescList(goodsDesc);
+		StringBuilder goodsDescSb = new StringBuilder();
+		if (goodsDescList != null && !goodsDescList.isEmpty()) {
+			for (GoodsDesc tmpGoodsDesc : goodsDescList) {
+				goodsDescSb.append(tmpGoodsDesc.getGoodsDesc());
+			}
+		}
+		return goodsDescSb.toString();
+	}
+
+	/**
+	 * 상품 정보 이력 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 12
+	 */
+	public Collection<GoodsHst> getGoodsHstList(Goods goods) {
+		return goodsDao.getGoodsHstList(goods);
+	}
+
+//	/**
+//	 * 상품 옵션 조회
+//	 *
+//	 * @param goods
+//	 * @return
+//	 * @author eskim
+//	 * @since 2019. 12. 12
+//	 */
+//	public Collection<TsaStock> getGoodsSizeList(TsaGoods goods) {
+//		return goodsDao.getGoodsSizeList(goods);
+//	}
+
+	/**
+	 * 상품 정보고시 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Collection<GoodsNotiInfo> getGoodsNotiInfoList(GoodsNotiInfo goodsNotiInfo) {
+		return goodsDao.getGoodsNotiInfoList(goodsNotiInfo);
+	}
+
+//	/**
+//	 * 구성상품 목록
+//	 *
+//	 * @param goods
+//	 * @return
+//	 * @author eskim
+//	 * @since 2020. 06. 16
+//	 */
+//	public Collection<GoodsExtend> getGoodsDetailExtendList(Goods goods) {
+//		return goodsDao.getGoodsDetailExtendList(goods);
+//	}
+
+
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 01. 17
+	 */
+	@Transactional("shopTxnManager")
+	public void updateGoodsState(Goods goods) {
+		if (goods == null || (goods.getArrGoodsCd() == null && goods.getArrGoodsCd().length <= 0)) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		goods.setRegNo(TsaSession.getInfo().getUserNo());
+		goods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		if (goods.getArrGoodsCd().length > 0) {
+			for (String goodsCd : goods.getArrGoodsCd()) {
+
+				goods.setGoodsCd(goodsCd);
+				// 이력생성
+				goodsDao.createGoodsHst(goods);
+
+				if ("formalGb".equals(goods.getProcJob())) {
+					// 상품브랜드 조회
+					Goods originGoods = goodsDao.getGoods(goods);
+					// 브랜드 확인
+					goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
+					goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
+					Brand brand = new Brand();
+					brand.setBrandCd(originGoods.getBrandCd());
+					Collection<Brand> brandList = businessService.getBrandList(brand);
+					if (brandList != null && !brandList.isEmpty()) {
+						float pntPrate = 0;
+						float pntMrate = 0;
+						for (Brand tmpBrand : brandList) {
+							if ("G009_10".equals(goods.getFormalGb())) {
+								pntPrate = tmpBrand.getPntPrate10();
+								pntMrate = tmpBrand.getPntMrate10();
+							} else {
+								pntPrate = tmpBrand.getPntPrate20();
+								pntMrate = tmpBrand.getPntMrate20();
+							}
+						}
+						goods.setPntPrate(pntPrate); // 포인트적립율(PC)
+						goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+					}
+				} else if ("goodsStat".equals(goods.getProcJob())) {
+					// 상품브랜드 조회
+					Goods originGoods = goodsDao.getGoods(goods);
+
+					// 승인일
+					if (!goods.getGoodsStat().equals(originGoods.getGoodsStat()) && "G008_90".equals(goods.getGoodsStat())) {
+						goods.setChGoodsStatYn("Y");
+					}
+				}
+				// 상품정보 변경
+				goodsDao.updateGoodsState(goods);
+			}
+
+		} else {
+
+			// 이력생성
+			goodsDao.createGoodsHst(goods);
+			if ("formalGb".equals(goods.getProcJob())) {
+				// 상품브랜드 조회
+				Goods originGoods = goodsDao.getGoods(goods);
+				// 브랜드 확인
+				goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
+				goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
+				Brand brand = new Brand();
+				brand.setBrandCd(originGoods.getBrandCd());
+				Collection<Brand> brandList = businessService.getBrandList(brand);
+				if (brandList != null && !brandList.isEmpty()) {
+					float pntPrate = 0;
+					float pntMrate = 0;
+					for (Brand tmpBrand : brandList) {
+						if ("G009_10".equals(goods.getFormalGb())) {
+							pntPrate = tmpBrand.getPntPrate10();
+							pntMrate = tmpBrand.getPntMrate10();
+						} else {
+							pntPrate = tmpBrand.getPntPrate20();
+							pntMrate = tmpBrand.getPntMrate20();
+						}
+					}
+					goods.setPntPrate(pntPrate); // 포인트적립율(PC)
+					goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+				}
+			}
+			// 상품정보 변경
+			goodsDao.updateGoodsState(goods);
+		}
+	}
+
+	/**
+	 * 엑셀조회용 상품 저장
+	 *
+	 * @param procJob : goodsExcelUpload
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	@Transactional("shopTxnManager")
+	public void saveExceluploadGoods(Collection<Goods> goodsList, String excelFilename) {
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		if (goodsList == null || goodsList.isEmpty()) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		int index = 0;
+		String goodsCdFlag = "";
+		String goodsNumFlag = "";
+		for (Goods goods : goodsList) {
+
+			if (!StringUtils.isEmpty(goodsCdFlag) && !StringUtils.isEmpty(goodsNumFlag)) {
+				throw new IllegalStateException("상품코드와 원코드 중 한 개의 셀에만 값을 입력해서 조회하세요.");
+			}
+
+			if (!StringUtils.isEmpty(goods.getSupplyCompCd())) {
+				goods.setGoodsCd(goods.getSupplyCompCd());
+			}
+
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(goods.getRegNo());
+			searchData.setSearchCd(goods.getGoodsCd());
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearch(searchData);
+			index++;
+		}
+	}
+
+	/**
+	 * 파일 삭제
+	 *
+	 * @param targetPath
+	 * @param excelFilename
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private void deleteExceluploadFile(String targetPath, String excelFilename) {
+		// 파일 삭제
+		try {
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
+		} catch (IOException e) {
+			// Nothing Do
+		}
+	}
+
+	/**
+	 * 상품 품목 변경 저장
+	 *
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@Transactional("shopTxnManager")
+	//@CacheEvict(value = "cate", allEntries = true)
+	public void saveItemKindChange(Collection<Goods> goodsList) {
+		for (Goods goods : goodsList) {
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setItemkindCd(goods.getItemkindCd().toUpperCase());
+			// 품목확인
+			Itemkind itemkind = new Itemkind();
+			itemkind.setItemkindCd(goods.getItemkindCd());
+			itemkind.setUseYn("Y");
+			Collection<Itemkind> itemkindList = goodsDao.getItemkindList(itemkind);
+			if (itemkindList == null || itemkindList.isEmpty()) {
+				throw new IllegalStateException(goods.getGoodsCd() + " 상품의 품목코드를 확인해주세요.");
+			}
+
+			// 상품이력
+			goodsDao.createGoodsHst(goods);
+			// 품목변경
+			goodsDao.updateGoodItemKindCd(goods);
+
+			// 검색어 변경
+			String goodsSnm = goodsDao.getGoodsSnm(goods.getGoodsCd());
+			Goods tmpGoods = goodsDao.getGoods(goods);
+			if (tmpGoods != null && !StringUtils.isEmpty(tmpGoods.getGoodsSnm1())) {
+				String[] arrGoodsSnm = tmpGoods.getGoodsSnm1().split(";");
+				StringBuilder tempGoodsSnm = new StringBuilder();
+				for (String loopGoodsSnm : arrGoodsSnm) {
+					if (goodsSnm.toUpperCase().indexOf(loopGoodsSnm.toUpperCase()) <= -1) {
+						tempGoodsSnm.append(loopGoodsSnm).append(";");
+					}
+				}
+				goods.setGoodsSnm(tempGoodsSnm.toString() + goodsSnm);
+
+			} else {
+				goods.setGoodsSnm(goodsSnm);
+			}
+			goodsDao.updateGoodsSnm(goods);
+
+			Collection<GoodsNotiInfo> goodsNotiInfoList = goodsDao.getNewNotiInfo(goods);
+			goodsDao.deleteGoodsNotiInfo(goods);
+
+			for (GoodsNotiInfo goodsNotiInfo : goodsNotiInfoList) {
+				goodsNotiInfo.setRegNo(TsaSession.getInfo().getUserNo());
+				goodsNotiInfo.setUpdNo(TsaSession.getInfo().getUserNo());
+				goodsNotiInfo.setGoodsCd(goods.getGoodsCd());
+				goodsDao.saveGoodsNotiInfo(goodsNotiInfo);
+			}
+
+			this.saveGoodsCategory(goods);
+		}
+	}
+
+	/**
+	 * 상품 품목 기준 카테고리 저장
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 4. 21.
+	 */
+	private void saveGoodsCategory(Goods goods) {
+
+//		GoodsCategory goodsCategory = new GoodsCategory();
+//		goodsCategory.setRegId(TsaSession.getInfo().getUserId());
+//		goodsCategory.setUpdId(TsaSession.getInfo().getUserId());
+//		goodsCategory.setGoodsCd(goods.getGoodsCd());
+//		displayService.deleteGoodsCategory(goodsCategory);
+//
+//		Collection<ItemkindCategory> itemkindCategoryList = displayService.getItemkindCategoryList(goods.getItemkindCd());
+//		for ItemkindCategory itemkindCategory : itemkindCategoryList) {
+//			Category category = new Category();
+//			category.setCateGb(itemkindCategory.getCateGb());
+//			category.setCateCd(itemkindCategory.getCateCd());
+//			category = displayService.getCategory4srch(category);
+//
+//			CategoryGoods categoryGoods = new CategoryGoods();
+//			categoryGoods.setRegNo(TsaSession.getInfo().getUserNo());
+//			categoryGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+//			String[] goodsCdArr = {goods.getGoodsCd()};
+//			categoryGoods.setGoodsCdArr(goodsCdArr);
+//			if (category.getCateGb() != null) {
+//				categoryGoods.setNcateGb(String.valueOf(category.getCateGb()));
+//			}
+//			if (category.getCateType() != null) {
+//				categoryGoods.setNcateType(String.valueOf(category.getCateType()));
+//			}
+//			if (category.getCateCd() != null) {
+//				categoryGoods.setNcateCd(String.valueOf(category.getCateCd()));
+//			}
+//			if (category.getTcateCd() != null) {
+//				categoryGoods.setNtcateCd(String.valueOf(category.getTcateCd()));
+//			}
+//			if (category.getMcateCd() != null) {
+//				categoryGoods.setNmcateCd(String.valueOf(category.getMcateCd()));
+//			}
+//			if (category.getScateCd() != null) {
+//				categoryGoods.setNscateCd(String.valueOf(category.getScateCd()));
+//			}
+//			if (category.getDcateCd() != null) {
+//				categoryGoods.setNdcateCd(String.valueOf(category.getDcateCd()));
+//			}
+//			displayService.moveCategoryGoods(categoryGoods);
+//		}
+	}
 }

+ 11 - 11
style24.admin/src/main/java/com/style24/admin/biz/service/TsaRendererService.java

@@ -285,17 +285,17 @@ public class TsaRendererService {
 //		return rendererDao.getBrandList(brand);
 //	}
 //
-//	/**
-//	 * 권한별 브랜드 목록
-//	 * @param adminId - 사용자ID
-//	 * @return
-//	 * @author eskim
-//	 * @since 2019. 6. 17
-//	 */
-//	public Collection<CommonCode> getAuthBrandList(String userId) {
-//		return rendererDao.getAuthBrandList(userId);
-//	}
-//
+	/**
+	 * 권한별 브랜드 목록
+	 * @param adminId - 사용자ID
+	 * @return
+	 * @author eskim
+	 * @since 2019. 6. 17
+	 */
+	public Collection<CommonCode> getAuthBrandList(int userNo) {
+		return rendererDao.getAuthBrandList(userNo);
+	}
+
 //	/**
 //	 * 출고처 목록
 //	 * @param params - 출고처 정보

+ 202 - 0
style24.admin/src/main/java/com/style24/admin/biz/web/TsaCommonController.java

@@ -0,0 +1,202 @@
+package com.style24.admin.biz.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.support.controller.TsaBaseController;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUploadUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.gagaframework.web.util.GagaFtpUtil;
+import com.gagaframework.web.util.GagaUploadedFileInfo;
+
+/**
+ * 공통 Controller
+ *
+ * @author renderer
+ * @since 2020. 10. 22
+ */
+@Controller
+@RequestMapping("/common")
+@Slf4j
+public class TsaCommonController extends TsaBaseController {
+
+
+	@Autowired
+	private Environment env;
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * Download a file
+	 *
+	 * @param request - HttpServletRequest
+	 * @param downloadFile - 다운로드할 파일
+	 * @return
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@GetMapping("/file/download")
+	@ResponseBody
+	public ResponseEntity<InputStreamResource> downloadFile(HttpServletRequest request, @RequestParam("downloadFile") String downloadFile) throws IOException {
+		String fileName = StringUtils.replace(downloadFile, "../", "");
+		log.debug("fileName: {}", fileName);
+
+		String downloadPath = env.getProperty("download.path");
+		log.debug("downLoadPath :{}", downloadPath);
+
+		String fileNameWithPath = GagaFileUtil.getConcatenationPath(downloadPath, fileName);
+		log.debug("fileNameWithPath: {}", fileNameWithPath);
+
+		return GagaFileUtil.writeFile(request, fileNameWithPath);
+	}
+
+	/**
+	 * Upload a file
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param policy - 업로드 정책
+	 * @param file - MultipartFile
+	 * @return 업로드한 파일의 정보
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@PostMapping("/file/upload")
+	@ResponseBody
+	public GagaUploadedFileInfo uploadFile(@RequestParam(value = "subDir") String subDir, @RequestParam(value = "policy", required = false) String policy, MultipartFile file) throws IOException {
+		if (StringUtils.isEmpty(policy)) {
+			policy = "default";
+		}
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload." + policy + ".target.path"), subDir);
+
+		GagaFileUploadUtil fuUtil = new GagaFileUploadUtil(targetPath, Long.parseLong(env.getProperty("upload." + policy + ".max.size")), env.getProperty("upload." + policy + ".allow.extension"), env.getProperty("upload." + policy + ".view"));
+
+		GagaUploadedFileInfo ufInfo = fuUtil.uploadFile(file);
+		if (!"excel".equals(policy)) {
+			// 운영서버에서만 FTP로 파일 업로드
+			String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+			if ("run".equals(profiles) || "locp".equals(profiles)) {
+				GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+
+				File srcFile = new File(GagaFileUtil.getConcatenationPath(targetPath, ufInfo.getNewFileName()));
+				ftpUtil.upload(srcFile, "/" + subDir);
+				ftpUtil.close();
+			}
+		}
+		return ufInfo;
+	}
+
+	/**
+	 * Delete a file
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param fileNm - 파일명
+	 * @return
+	 * @throws IOException
+	 * @author sasa004
+	 * @since 2020. 04. 06
+	 */
+	@PostMapping("/file/delete")
+	@ResponseBody
+	public void deleteFile(@RequestParam(value = "subDir") String subDir, @RequestParam(value = "fileNm", required = false) String fileNm) throws IOException {
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), subDir);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, fileNm));
+
+		// 운영서버이면 FTP 파일 삭제
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		if ("run".equals(profiles) || "locp".equals(profiles)) {
+			GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+			log.debug("targetPath : " + targetPath);
+			ftpUtil.delete("/" + subDir, fileNm);
+			ftpUtil.close();
+		}
+	}
+
+	/**
+	 * Upload files
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param files - MultipartFile List
+	 * @return 업로드한 파일의 정보
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@PostMapping("/files/upload")
+	@ResponseBody
+	public Collection<GagaUploadedFileInfo> uploadFiles(@RequestParam(value = "subDir") String subDir, List<MultipartFile> files) throws IOException {
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), subDir);
+		GagaFileUploadUtil fuUtil = new GagaFileUploadUtil(targetPath);
+
+		Collection<GagaUploadedFileInfo> ufList = fuUtil.uploadFiles(files);
+		log.debug("ufList: {}", ufList);
+
+		// 운영서버에서만 FTP로 파일 업로드
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		if ("run".equals(profiles) || "locp".equals(profiles)) {
+			if (ufList != null && !ufList.isEmpty()) {
+				GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+
+				for (GagaUploadedFileInfo ufInfo : ufList) {
+					File srcFile = new File(GagaFileUtil.getConcatenationPath(targetPath, ufInfo.getNewFileName()));
+					ftpUtil.upload(srcFile, "/" + subDir);
+				}
+
+				ftpUtil.close();
+			}
+		}
+
+		return ufList;
+	}
+
+	/**
+	 * 엑셀 업로드 팝업
+	 *
+	 * @param procJob - 업무명
+	 * @param callBackFun - 콜백함수
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 6
+	 */
+	@GetMapping("/excel/upload/popup/form")
+	public ModelAndView excelUploadPopupForm(@RequestParam(value = "procJob") String procJob, @RequestParam(value = "callBackFun", required = false) String callBackFun) {
+		ModelAndView mav = new ModelAndView();
+
+		GagaMap params = new GagaMap();
+		params.setString("procJob", procJob);
+		params.setString("callBackFun", callBackFun);
+
+		mav.addObject("params", params);
+
+		mav.setViewName("common/ExcelUploadPopupForm");
+
+		return mav;
+	}
+}

+ 297 - 3
style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java

@@ -1,5 +1,6 @@
 package com.style24.admin.biz.web;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 import javax.servlet.http.HttpServletRequest;
@@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.style24.admin.biz.service.TsaGoodsService;
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
@@ -24,14 +26,19 @@ import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.TsaPageRequest;
 import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
 
 import lombok.extern.slf4j.Slf4j;
 
+import com.gagaframework.excel.GagaExcelUtil;
 import com.gagaframework.web.parameter.GagaMap;
 import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.rest.server.GagaResponseStatus;
 import com.gagaframework.web.util.GagaDateUtil;
 import com.gagaframework.web.util.GagaFileUtil;
 
@@ -284,7 +291,7 @@ public class TsaGoodsController extends TsaBaseController {
 		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
 		// 품목
 		mav.addObject("itemkindList", rendererService.getAllItemkindList());
-		// 상품구분
+		// 상품유형
 		mav.addObject("goodsTypeList", rendererService.getAvailCommonCodeList("G056"));
 		// MD
 		mav.addObject("brandMdList", rendererService.getBrandMdList());
@@ -310,7 +317,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdId(TsaSession.getInfo().getUserId());
+			goodsSearch.setMdId(Integer.toString(TsaSession.getInfo().getUserNo()));
 		}
 
 		// multi row 검색관련 처리
@@ -350,7 +357,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdId(TsaSession.getInfo().getUserId());
+			goodsSearch.setMdId(Integer.toString(TsaSession.getInfo().getUserNo()));
 		}
 		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 
@@ -371,6 +378,293 @@ public class TsaGoodsController extends TsaBaseController {
 		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
 	}
 
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 17
+	 */
+	@PostMapping("/state/update")
+	@ResponseBody
+	public GagaMap updateGoodsState(@RequestBody Goods goods) {
+		log.info("updateGoodsState goods={}", goods);
+		GagaMap result = new GagaMap();
+		result.set("status", GagaResponseStatus.SUCCESS.getCode()); // 200
+		result.set("procJob", goods.getProcJob());
+		// result.set("message", message.getMessage("SUCC_0001"));
+
+		String returnGoods = "";
+		String resultFlag = "SUCC";
+
+		if (!"G001_0000".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A000".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A001".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A100".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A101".equals(TsaSession.getInfo().getRoleCd())) {
+			throw new IllegalStateException("권한이 없습니다.");
+		}
+
+		// 상품 상태 변경일 경우 체크
+		if ("goodsStat".equals(goods.getProcJob()) && ("G008_40".equals(goods.getGoodsStat()) || "G008_90".equals(goods.getGoodsStat()))) {
+
+			// 이미지
+			Collection<Goods> goodsList = goodsService.getGoodsImgsYn(goods);
+
+			for (Goods tmpGoods : goodsList) {
+				if ("N".equals(tmpGoods.getGoodsImageYn())) {
+					returnGoods += tmpGoods.getGoodsCd() + ",";
+				} else {
+
+					// 택가/판매가 입력 여부 확인
+					Goods dataGoods = goodsService.getGoods(tmpGoods);
+					if (dataGoods == null) {
+						returnGoods += tmpGoods.getGoodsCd() + ",";
+						continue;
+					}
+					if (dataGoods.getListPrice() <= 0 || dataGoods.getCurrPrice() <= 0) {
+						returnGoods += tmpGoods.getGoodsCd() + ",";
+						continue;
+					}
+					// 사이즈 등록 여부 확인
+//					Stock stock = new Stock();
+//					stock.setGoodsCd(tmpGoods.getGoodsCd());
+//					int stockCnt = goodsService.getGoodsSizeCount(stock);
+//					if (stockCnt <= 0) {
+//						returnGoods += tmpGoods.getGoodsCd() + ",";
+//						continue;
+//					}
+
+					//고시정보
+//					GoodsNotiInfo goodsNotiInfo = new GoodsNotiInfo();
+//					goodsNotiInfo.setGoodsCd(tmpGoods.getGoodsCd());
+//					goodsNotiInfo.setSupplyCompCd(tmpGoods.getSupplyCompCd());
+//					goodsNotiInfo.setNiClsfCd(tmpGoods.getNiClsfCd());
+//					Collection<GoodsNotiInfo> goodsNotiInfoList = goodsService.getGoodsNotiInfoList(goodsNotiInfo);
+//					if (goodsNotiInfoList == null || goodsNotiInfoList.isEmpty()) {
+//						returnGoods += tmpGoods.getGoodsCd() + ",";
+//					} else {
+//						for (GoodsNotiInfo tmpGoodsNotiInfo : goodsNotiInfoList) {
+//							if ("Y".equals(tmpGoodsNotiInfo.getReqYn()) || "Y".equals(tmpGoodsNotiInfo.getDispYn())) {
+//								if (StringUtils.isEmpty(tmpGoodsNotiInfo.getNiContent())) {
+//									returnGoods += tmpGoods.getGoodsCd() + ",";
+//									break;
+//								}
+//							}
+//						}
+//					}
+				}
+			}
+
+			if (returnGoods.length() > 0) {
+				returnGoods = returnGoods.substring(0, returnGoods.lastIndexOf(","));
+				returnGoods = returnGoods.replaceAll(",", ",<br/>");
+				resultFlag = "FAIL";
+				result.set("resultFlag", resultFlag);
+				result.set("returnGoods", returnGoods);
+				return result;
+			}
+		}
+
+		goodsService.updateGoodsState(goods);
+
+		result.set("resultFlag", resultFlag);
+		result.set("returnGoods", returnGoods);
+		return result;
+	}
+
+	/**
+	 * 엑셀조회용 상품 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/search/excelupload/save")
+	@ResponseBody
+	public GagaResponse saveExceluploadGoods(@RequestBody Goods goods) throws Exception {
+
+		int cnt = 0;
+		ObjectMapper mapper = new ObjectMapper();
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = {"goodsCd", "supplyGoodsCd"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()), 0, cellName, 0);
+
+		Collection<Goods> goodsList = new ArrayList<>();
+		for (GagaMap map : ecxelGoodsList) {
+			Goods tmpGoods = mapper.convertValue(map, Goods.class);
+			tmpGoods.setRegNo(TsaSession.getInfo().getUserNo());
+			tmpGoods.setProcJob(goods.getProcJob());
+			goodsList.add(tmpGoods);
+			cnt++;
+		}
+
+		goodsService.saveExceluploadGoods(goodsList, goods.getExcelFileNm());
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()));
+
+		return super.ok("");
+	}
+
+	/**
+	 * 상품 상세 화면
+	 *
+	 * @param mode - 모드(U:수정)
+	 * @param goodsCode - 상품코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@GetMapping("/detail/form")
+	@ResponseBody
+	public ModelAndView detailForm(Goods goods) {
+		ModelAndView mav = new ModelAndView();
+
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// 정보고시 분류
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+		// 사용자 브랜드 조회
+		mav.addObject("authBrandList", rendererService.getAuthBrandList(TsaSession.getInfo().getUserNo()));
+		// 상품타입
+		mav.addObject("goodsTypeList", rendererService.getAvailCommonCodeList("G056"));
+		// 상품구분
+		mav.addObject("goodsGbList", rendererService.getAvailCommonCodeList("G073"));
+		// 색상
+		Color color = new Color();
+		mav.addObject("colorList", rendererService.getColorList(color));
+
+		mav.addObject("params", goods);
+
+		mav.setViewName("goods/GoodsDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 상세 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 11
+	 */
+	@PostMapping("/detail")
+	@ResponseBody
+	public Goods getGoodsDetail(Goods goods) {
+		return goodsService.getGoods(goods);
+	}
+
+	/**
+	 * 상품 이력 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 12
+	 */
+	@GetMapping("/detail/hst/list")
+	@ResponseBody
+	public Collection<GoodsHst> getGoodsDetailHstList(Goods goods) {
+		return goodsService.getGoodsHstList(goods);
+	}
+
+//	/**
+//	 * 컬러 옵셥 재고
+//	 *
+//	 * @param goods
+//	 * @return
+//	 * @author eskim
+//	 * @since 2019. 12. 12
+//	 */
+//	@PostMapping("/detail/sizeStock/form")
+//	public ModelAndView getGoodsDetailSizeStockForm(Goods goods) {
+//
+//		ModelAndView mav = new ModelAndView();
+//		mav.addObject("goods", goodsService.getGoods(goods));
+//		mav.addObject("goodsSizeList", goodsService.getGoodsSizeList(goods));
+//		// mav.addObject("params", goodsService.getGoods(goods));
+//		// 사용여부
+//		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+//
+//		mav.setViewName("goods/GoodsDetailSizeStockForm");
+//
+//		return mav;
+//	}
+
+	/**
+	 * 상품 정보고시 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 12
+	 */
+	@PostMapping("/detail/notiInfo/list")
+	@ResponseBody
+	public Collection<GoodsNotiInfo> getGoodsDetailNotiInfoList(Goods goods) {
+
+		GoodsNotiInfo goodsInfo = new GoodsNotiInfo();
+		goodsInfo.setGoodsCd(goods.getGoodsCd());
+		goodsInfo.setNiClsfCd(goods.getNiClsfCd());
+		goodsInfo.setSupplyCompCd(goods.getSupplyCompCd());
+
+		return goodsService.getGoodsNotiInfoList(goodsInfo);
+	}
+
+//	/**
+//	 * 구성상품 목록
+//	 *
+//	 * @param goods
+//	 * @return
+//	 * @author eskim
+//	 * @since 2020. 06. 16
+//	 */
+//	@GetMapping("/detail/extend/list")
+//	@ResponseBody
+//	public Collection<GoodsExtend> getGoodsDetailExtendList(Goods goods) {
+//		return goodsService.getGoodsDetailExtendList(goods);
+//	}
+
+	/**
+	 * 상품 품목 변경 저장
+	 *
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@PostMapping("/itemKind/change/save")
+	@ResponseBody
+	public GagaResponse saveItemKindChange(@RequestBody Collection<Goods> goodsList) {
+		goodsService.saveItemKindChange(goodsList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
 	/**
 	 * 상품 대량 등록 화면
 	 *

+ 14 - 14
style24.admin/src/main/java/com/style24/admin/biz/web/TsaRendererController.java

@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.persistence.domain.Color;
 import com.style24.persistence.domain.CommonCode;
 
 import lombok.extern.slf4j.Slf4j;
@@ -120,20 +121,19 @@ public class TsaRendererController extends TsaBaseController {
 //		return rendererService.getAvailCommonCodeList(cdGb);
 //	}
 //
-//	/**
-//	 * 업체별 색상 목록
-//	 * @param cdGb - 공통그룹코드
-//	 * @return
-//	 * @author eskim
-//	 * @since 2020. 01. 22
-//	 */
-//	@GetMapping("/avail/color/list/{supplyCompCd}")
-//	@ResponseBody
-//	public Collection<AdmCommonCode> getColorList(@PathVariable String supplyCompCd) {
-//		AdmColor color = new AdmColor();
-//		color.setSupplyCompCd(supplyCompCd);
-//		return rendererService.getColorList(color);
-//	}
+	/**
+	 * 업체별 색상 목록
+	 * @param cdGb - 공통그룹코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 22
+	 */
+	@GetMapping("/avail/color/list")
+	@ResponseBody
+	public Collection<CommonCode> getColorList() {
+		Color color = new Color();
+		return rendererService.getColorList(color);
+	}
 //
 //	/**
 //	 * MD별 브랜드 목록

+ 18 - 17
style24.admin/src/main/java/com/style24/persistence/domain/Goods.java

@@ -70,35 +70,36 @@ public class Goods extends TscBaseDomain {
 	private String brandEnm;		//브랜드영문명
 	private String brandGrpNm;		//브랜드그룹명
 
-//	private String goodsDesc;
-//	private String goodsPcTopDesc;
-//	private String goodsPcDownDesc;
-//	private String goodsMobileTopDesc;
-//	private String goodsMobileDownDesc;
-//	private String chkDescKeep = "N";
+	private String goodsDesc;
+	private String goodsPcTopDesc;
+	private String goodsPcDownDesc;
+	private String goodsMobileTopDesc;
+	private String goodsMobileDownDesc;
+	private String chkDescKeep = "N";
 //
-//	private String chDataYn = "N";
-//	private String chImgYn = "N";
-//	private String chNotiYn = "N";
-//	private String chStockDataYn = "N";
+	private String chDataYn = "N";
+	private String chImgYn = "N";
+	private String chNotiYn = "N";
+	private String chStockDataYn = "N";
+	private String chGoodsStatYn = "N";
 	private String stockQtySum;
 	private String goodsImageYn;
 	private String itemkindNm;
-//	private String niClsfCd;
+	private String niClsfCd;
 //	private Integer currPriceOrg;
 //
 	private String imgType;
 	private String imgPath1;
 	private String imgPath6;
-//
-//	private String niClsfNm;
+	private String niClsfNm;
+	private String goodsTypeNm;
 //
 //	private String goodsRegMsg;
-//	private String procJob;
-//	private String excelFileNm;
+	private String procJob;
+	private String excelFileNm;
 //	private String searchGb;
-//
-//	private String blankFlag;
+
+	private String blankFlag;
 //
 //	private Integer sizeCurrStockQty;
 //	private Integer sizeBaseStockQty;

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

@@ -0,0 +1,20 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 상세 설명 Domain
+ * @author eskim
+ * @since 2020. 10. 22
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsDesc extends TscBaseDomain {
+
+	private String goodsCd;
+	private String descGb;
+	private int seq;
+	private String goodsDesc;
+}

+ 67 - 0
style24.admin/src/main/java/com/style24/persistence/domain/GoodsHst.java

@@ -0,0 +1,67 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 이력 Domain
+ *
+ * @author eskim
+ * @since 2020. 10. 23
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsHst extends TscBaseDomain {
+
+	private Integer goodsHstSq;		//상품이력일련번호
+	private String goodsCd;		//상품이력. 상품 수정에 의한 발생
+	private String brandCd;		//브랜드코드
+	private String itemkindCd;		//품목코드
+	private String goodsNm;		//상품명
+	private String goodsTnm;		//상품타이틀명
+	private String goodsSnm;		//상품검색명
+	private String goodsSnm1;		//상품검색명1(사용자등록용)
+	private String colorCd;		//색상코드
+	private String styleYear;		//스타일연도
+	private String seasonCd;		//시즌코드(공통코드G006)
+	private String sexGb;		//성별구분(공통코드G007)
+	private String goodsNum;		//품번(자사상품만 사용)
+	private String shapeCd;		//스타일모양코드(없으면 X)
+	private String goodsType;		//상품타입(공통코드G056)
+	private int listPrice;		//정상가(최초판매가)
+	private int currPrice;		//현재판매가
+	private int currBprice;		//변경전현재판매가
+	private String priceUpdDt;		//가격변경일시
+	private float dcRate;		//할인율
+	private String goodsStat;		//상품상태(공통코드G008)
+	private String dispYn;		//노출여부
+	private String goodsGb;		//해외구매대행/병행수입 상품일 경우 주문 시 통관부호 입력 란이 추가되어야 한다
+	private String distributionGb;		//유통구분(공콩코드 G065)
+	private String selfGoodsYn;		//자사상품여부
+	private String supplyCompCd;		//공급업체코드
+	private String supplyGoodsCd;		//공급업체상품코드(원코드)
+	private String ageGrpCd;		//상품연령대(공통코드 G023)
+	private int delvFee;		//배송비
+	private int minOrdAmt;		//무료배송비최소구매금액
+	private float pntPrate;		//포인트적립율(PC)
+	private float pntMrate;		//포인트적립율(모바일)
+	private float sellFeeRate;		//판매수수료율
+	private String formalGb;		//정상이월구분(공통코드G009)
+	private String changeableYn;		//교환가능여부
+	private String returnableYn;		//반품가능여부
+	private String changeFeeFreeYn;		//교환배송비무료여부
+	private String returnFeeFreeYn;		//반품배송비무료여부
+	private String prePpntUsableYn;		//선포인트사용가능여부(PC)
+	private String preMpntUsableYn;		//선포인트사용가능여부(모바일)
+	private int minOrdQty;		//최소주문수량
+	private int maxOrdQty;		//최대주문수량
+	private int dayMaxOrdQty;		//ID당1일최대구매수량
+	private String frstCfrmDt;		//최초승인일시
+	private String makeNm;		//제조국(원산지)
+	private String makeYmd;		//제조연월일
+	private String taxGb;		//과세구분(10:과세, 20:비과세)
+	private String erpPriceLinkYn;		//ERP가격연계여부(자사상품만 사용. Y:연계)
+	private String erpStockLinkYn;		//ERP재고연계여부(자사상품만 사용. Y:연계)
+
+}

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

@@ -19,6 +19,8 @@ public class GoodsNotiInfo extends TscBaseDomain {
 	private String niItemCd;
 	private String niContent;
 	private int dispOrd;
+	private String dispYn;
+	private String reqYn;
 
 	private String niItemNm;
 	private String supplyCompCd;

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

@@ -22,6 +22,8 @@ public class NotiInfo extends TscBaseDomain {
 	private String niItemNm;
 	private String niContent;
 	private Integer dispOrd;
+	private String reqYn;
+	private String dispYn;
 
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] arrNiClsfCd;

+ 24 - 0
style24.admin/src/main/java/com/style24/persistence/domain/SearchData.java

@@ -0,0 +1,24 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 엑셀조회를 위한 SEARCH_DATA Domain
+ *
+ * @author eskim
+ * @since 2020. 10. 22
+ */
+@SuppressWarnings("serial")
+@Data
+public class SearchData extends TscBaseDomain {
+
+	private String searchCd;
+	private int dispOrd;
+	private String procJob;
+	private String dummy1;
+	private String dummy2;
+	private String dummy3;
+
+}

+ 48 - 0
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaBusiness.xml

@@ -464,4 +464,52 @@
 		WHERE  SHIP_COMP_CD=  #{shipCompCd}
 	</update>
 
+	<!-- 브랜드 목록 -->
+	<select id="getBrandList" parameterType="Brand" resultType="Brand">
+		/* TsaBusiness.getBrandList */
+		SELECT A.BRAND_CD                         /*브랜드코드*/
+		     , A.BRAND_ENM                        /*브랜드영문명*/
+		     , A.BRAND_KNM                        /*브랜드한글명*/
+		     , A.BRAND_GRP_NM                     /*브랜드그룹명*/
+		     , A.SUPPLY_COMP_CD                   /*업체코드*/
+		     , B.SUPPLY_COMP_NM                   /*업체명*/
+		     , A.DELV_LOC_CD                      /*출고처코드*/
+		     , C.DELV_LOC_NM                      /*출고처명*/
+		     , A.ERP_BRAND_CD                     /*ERP브랜드 코드*/
+		     , A.DELV_FEE                         /*기본배송비*/
+		     , A.MIN_ORD_AMT                      /*무료배송비기준*/
+		     , A.SELL_FEE_RATE                    /*판매수수료율*/
+		     , A.USE_YN                           /*사용여부*/
+		     , A.PNT_PRATE10                        /*포인트적립율(PC)*/
+		     , A.PNT_MRATE10                        /*포인트적립율(모바일)*/
+		     , A.PNT_PRATE20                        /*포인트적립율(PC)*/
+		     , A.PNT_MRATE20                        /*포인트적립율(모바일)*/
+		     , A.DISP_ORD
+		     , A.SELF_YN
+		FROM TB_BRAND A
+		INNER JOIN TB_SUPPLY_COMPANY B ON A.SUPPLY_COMP_CD = B.SUPPLY_COMP_CD
+		LEFT OUTER JOIN TB_DELIVERY_LOC C ON A.DELV_LOC_CD = C.DELV_LOC_CD
+		WHERE  1 = 1
+		<if test='supplyCompCd != null and supplyCompCd != ""'>
+		AND    A.SUPPLY_COMP_CD = #{supplyCompCd}
+		</if>
+		<if test='erpBrandCd != null and erpBrandCd != ""'>
+		AND    A.ERP_BRAND_CD =  #{erpBrandCd}
+		</if>
+		<if test='brandCd != null and brandCd != ""'>
+		AND    A.BRAND_CD = #{brandCd}
+		</if>
+		<if test='brandEnm != null and brandEnm != ""'>
+		AND    (
+		        A.BRAND_ENM LIKE CONCAT('%',#{brandEnm},'%')
+		        OR
+		        A.BRAND_KNM LIKE CONCAT('%',#{brandEnm},'%')
+		       )
+		</if>
+		<if test='useYn != null and useYn != ""'>
+		AND    A.USE_YN = #{useYn}
+		</if>
+		ORDER BY A.SELF_YN DESC, A.SUPPLY_COMP_CD, A.DISP_ORD
+	</select>
+	
 </mapper>

+ 58 - 0
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCommon.xml

@@ -0,0 +1,58 @@
+<?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.TsaCommonDao">
+
+	<!-- 엑셀조회를 위한 SEARCH 테이블 삭제  -->
+	<delete id="deleteExceluploadSearCh" parameterType="SearchData">
+		/* TsaCommon.deleteExceluploadSearCh */
+		DELETE
+		FROM   TB_SEARCH_DATA
+		WHERE  REG_NO = #{regNo}
+	</delete>
+
+	<!-- 엑셀조회를 위한 SEARCH 테이블  생성 -->
+	<insert id="createExceluploadSearch" parameterType="SearchData">
+		/* TsaCommon.createExceluploadSearch */
+		INSERT INTO TB_SEARCH_DATA (
+		        REG_NO
+		      , SEARCH_CD
+		      , DISP_ORD
+		 )
+		 SELECT #{regNo}
+		      , #{searchCd}
+		      , (SELECT COUNT(*) + 100
+		         FROM   TB_SEARCH_DATA
+		         WHERE  REG_NO = #{regNo})
+		 FROM   DUAL
+		 WHERE  (SELECT COUNT(*) FROM TB_SEARCH_DATA WHERE SEARCH_CD = #{searchCd} AND REG_NO = #{regNo}) = 0
+	</insert>
+	
+	<!-- 엑셀조회를 위한 SEARCH 테이블  생성 - dummy 컬럼 포함 -->
+	<insert id="createExceluploadSearchByAll" parameterType="SearchData">
+		/* TsaCommon.createExceluploadSearchByAll */
+		INSERT INTO TB_SEARCH_DATA (
+		        REG_NO
+		      , SEARCH_CD
+		      , DISP_ORD
+		      , DUMMY1
+		      , DUMMY2
+		      , DUMMY3
+		 )
+		 SELECT #{regNo}
+		      , #{searchCd}
+		      , (SELECT COUNT(*) + 100
+		         FROM   TB_SEARCH_DATA
+		         WHERE  REG_NO = #{regNo})
+		      , #{dummy1}
+		      , #{dummy2}
+		      , #{dummy3}
+		 FROM   DUAL
+		 WHERE  (SELECT COUNT(*) FROM TB_SEARCH_DATA
+		         WHERE SEARCH_CD = #{searchCd}
+		         AND DUMMY1 = #{dummy1}
+		         AND DUMMY2 = #{dummy2}
+		         AND DUMMY3 = #{dummy3}
+		         AND REG_NO = #{regNo}) = 0
+	</insert>
+	
+</mapper>

+ 473 - 5
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml

@@ -150,6 +150,8 @@
 		     , FN_GET_CODE_NM('G005', B.NI_ITEM_CD) AS NI_ITEM_NM
 		     , B.NI_CONTENT
 		     , B.DISP_ORD
+		     , B.REQ_YN
+		     , B.DISP_YN
 		FROM TB_NOTI_INFO B
 		WHERE B.SUPPLY_COMP_CD = CASE #{supplyCompCd} 
 		                         WHEN 'S0001' THEN 'S0001'
@@ -223,7 +225,7 @@
 		                           SELECT SEARCH_CD
 		                                , MIN(DISP_ORD) AS TMP_DISP_ORD
 		                           FROM TB_SEARCH_DATA
-		                           WHERE REG_NO = #{regId}
+		                           WHERE REG_NO = #{regNo}
 		                           GROUP BY SEARCH_CD) T
 		                   ) SD
 		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
@@ -331,7 +333,7 @@
 		                           SELECT SEARCH_CD
 		                                , MIN(DISP_ORD) AS TMP_DISP_ORD
 		                           FROM TB_SEARCH_DATA
-		                           WHERE REG_NO = #{regId}
+		                           WHERE REG_NO = #{regNo}
 		                           GROUP BY SEARCH_CD) T
 		                   ) SD
 		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
@@ -352,7 +354,7 @@
 		        ORDER BY G.REG_DT DESC, G.GOODS_CD
 		        </if>
 		        <if test="searchGb != null and searchGb =='EXCEL'">
-		        ORDER BY GS.TMP_DISP_ORD
+		        ORDER BY SD.TMP_DISP_ORD
 		        </if>
 		<include refid="getListPagingContion_sql"/>
 	</select>
@@ -649,7 +651,7 @@
 		                   SELECT SEARCH_CD
 		                        , MIN(DISP_ORD) AS TMP_DISP_ORD
 		                   FROM TB_SEARCH_DATA
-		                   WHERE REG_NO = #{regId}
+		                   WHERE REG_NO = #{regNo}
 		                   GROUP BY SEARCH_CD) T
 		          ) SD
 		           ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
@@ -670,8 +672,474 @@
 		ORDER BY G.REG_DT DESC
 		</if>
 		<if test="searchGb == null or searchGb =='EXCEL'">
-		ORDER BY GS.TMP_DISP_ORD
+		ORDER BY SD.TMP_DISP_ORD
 		</if>
 	</select>
 	
+	<!-- 상품 정보 -->
+	<select id="getGoods" parameterType="Goods" resultType="Goods">
+		/* TsaGoods.getGoods */
+		SELECT G.GOODS_CD
+		     , G.GOODS_NM
+		     , G.GOODS_TNM
+		     , G.GOODS_SNM
+		     , G.GOODS_SNM1
+		     , G.BRAND_CD
+		     , B.BRAND_GRP_NM
+		     , G.ITEMKIND_CD
+		     , G.STYLE_YEAR
+		     , G.SEASON_CD
+		     , G.SEX_GB
+		     , G.GOODS_NUM
+		     , G.COLOR_CD
+		     , G.GOODS_TYPE
+		     , G.LIST_PRICE
+		     , G.CURR_PRICE
+		     , G.CURR_BPRICE
+		     , DATE_FORMAT(G.PRICE_UPD_DT, '%Y%m%d%H%i%S') AS PRICE_UPD_DT
+		     , G.DC_RATE
+		     , G.GOODS_STAT
+		     , G.SELF_GOODS_YN
+		     , G.DISP_YN
+		     , G.GOODS_GB
+		     , G.DISTRIBUTION_GB
+		     /*, (SELECT COLOR_GRP_FILE 
+		        FROM TB_COLOR TC 
+		        WHERE TC.COLOR_CD = G.COLOR_CD) AS COLOR_GRP_FILE */
+		     , G.SUPPLY_COMP_CD
+		     , G.SUPPLY_GOODS_CD
+		     , G.AGE_GRP_CD
+		     , G.DELV_FEE
+		     , G.MIN_ORD_AMT
+		     , G.PNT_PRATE
+		     , G.PNT_MRATE
+		     , G.SELL_FEE_RATE
+		     , G.FORMAL_GB
+		     , G.RETURNABLE_YN
+		     , G.PRE_PPNT_USABLE_YN
+		     , G.PRE_MPNT_USABLE_YN
+		     , G.MIN_ORD_QTY
+		     , G.MAX_ORD_QTY
+		     , G.DAY_MAX_ORD_QTY
+		     , G.ERP_STOCK_LINK_YN
+		     , G.ERP_PRICE_LINK_YN
+		     , G.MAKE_NM
+		     , G.MAKE_YMD
+		     , G.TAX_GB
+		     , G.GOODS_TYPE
+		     , FN_GET_CODE_NM('G056', G.GOODS_TYPE) AS GOODS_TYPE_NM
+		     , DATE_FORMAT(G.FRST_CFRM_DT, '%Y%m%d%H%i%S') AS FRST_CFRM_DT
+		     , (SELECT I.NI_CLSF_CD FROM TB_ITEMKIND I WHERE I.ITEMKIND_CD = G.ITEMKIND_CD) AS NI_CLSF_CD
+		     , GI.IMG_TYPE
+		     , GI.IMG_PATH1
+		     , GI.IMG_PATH6
+		     , CASE WHEN IMG_PATH1 IS NULL THEN
+		           'N'
+		       ELSE
+		           'Y'
+		       END AS GOODS_IMAGE_YN
+		     , (SELECT B.CD_NM 
+		       FROM TB_ITEMKIND A
+		          , TB_COMMON_CODE B 
+		       WHERE A.ITEMKIND_CD = G.ITEMKIND_CD 
+		       AND A.NI_CLSF_CD = B.CD 
+		       AND B.CD_GB = 'G004') AS  NI_CLSF_NM
+		     , FN_GET_USER_NM(G.UPD_NO) AS UPD_NM  
+		FROM TB_GOODS G
+		INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		LEFT OUTER JOIN TB_GOODS_IMG GI ON G.GOODS_CD = GI.GOODS_CD
+		WHERE 1 = 1 
+		<choose>
+		<when test="goodsCd != null and goodsCd != ''">
+		AND G.GOODS_CD = #{goodsCd}
+		</when>
+		<otherwise>
+		AND G.SUPPLY_COMP_CD = #{supplyCompCd}
+		AND G.SUPPLY_GOODS_CD = #{supplyGoodsCd}
+		</otherwise>
+		</choose>
+	</select>
+	
+	<!-- 상품 상세 정보 조회 -->
+	<select id="getGoodsDescList" parameterType="GoodsDesc" resultType="GoodsDesc">
+		/* TsaGoods.getGoodsDescList */
+		SELECT GOODS_CD
+		     , DESC_GB
+		     , SEQ
+		     , GOODS_DESC
+		FROM TB_GOODS_DESC
+		WHERE GOODS_CD = #{goodsCd}
+		AND DESC_GB = #{descGb}
+		ORDER BY SEQ
+	</select>
+	
+	<!-- 상품 고시정보 조회 -->
+	<select id="getGoodsNotiInfoList" parameterType="GoodsNotiInfo" resultType="GoodsNotiInfo">
+		/* TsaGoods.getGoodsNotiInfoList */
+		SELECT C.GOODS_CD
+		     , C.NI_CLSF_CD
+		     , FN_GET_CODE_NM('G005', C.NI_ITEM_CD) AS NI_ITEM_NM
+		     , C.NI_ITEM_CD
+		     , C.NI_CONTENT
+		     , C.DISP_ORD
+		     , A.DISP_YN
+		     , A.REQ_YN
+		FROM TB_GOODS_NOTI_INFO C
+		INNER JOIN TB_NOTI_INFO A ON C.NI_CLSF_CD = A.NI_CLSF_CD
+		                          AND C.NI_ITEM_CD = A.NI_ITEM_CD
+		                          AND A.SUPPLY_COMP_CD = CASE #{supplyCompCd} 
+		                                                 WHEN 'S0001' THEN 'S0001'
+		                                                 WHEN 'S0002' THEN 'S0002'
+		                                                 ELSE 'E' END
+		WHERE C.GOODS_CD = #{goodsCd}
+		AND C.NI_CLSF_CD = #{niClsfCd}
+		ORDER BY C.DISP_ORD
+	</select>
+	
+	<!-- 상품 기본정보 이력 생성 -->
+	<insert id="createGoodsHst" parameterType="Goods">
+		/* TsaGoods.createGoodsHst */
+		INSERT INTO TB_GOODS_HST 
+		(       GOODS_CD
+		      , BRAND_CD
+		      , ITEMKIND_CD
+		      , GOODS_NM
+		      , GOODS_TNM
+		      , GOODS_SNM
+		      , GOODS_SNM1
+		      , COLOR_CD
+		      , STYLE_YEAR
+		      , SEASON_CD
+		      , SEX_GB
+		      , GOODS_NUM
+		      , GOODS_TYPE
+		      , LIST_PRICE
+		      , CURR_PRICE
+		      , CURR_BPRICE
+		      , PRICE_UPD_DT
+		      , DC_RATE
+		      , GOODS_STAT
+		      , DISP_YN
+		      , GOODS_GB
+		      , DISTRIBUTION_GB
+		      , SELF_GOODS_YN
+		      , SUPPLY_COMP_CD
+		      , SUPPLY_GOODS_CD
+		      , AGE_GRP_CD
+		      , DELV_FEE
+		      , MIN_ORD_AMT
+		      , PNT_PRATE
+		      , PNT_MRATE
+		      , SELL_FEE_RATE
+		      , FORMAL_GB
+		      , CHANGEABLE_YN
+		      , RETURNABLE_YN
+		      , CHANGE_FEE_FREE_YN
+		      , RETURN_FEE_FREE_YN
+		      , PRE_PPNT_USABLE_YN
+		      , PRE_MPNT_USABLE_YN
+		      , MIN_ORD_QTY
+		      , MAX_ORD_QTY
+		      , DAY_MAX_ORD_QTY
+		      , FRST_CFRM_DT
+		      , MAKE_NM
+		      , MAKE_YMD
+		      , TAX_GB
+		      , ERP_PRICE_LINK_YN
+		      , ERP_STOCK_LINK_YN
+		      , REG_NO
+		      , REG_DT
+		      , UPD_NO
+		      , UPD_DT
+		)
+		SELECT GOODS_CD            
+		     , BRAND_CD            
+		     , ITEMKIND_CD         
+		     , GOODS_NM            
+		     , GOODS_TNM           
+		     , GOODS_SNM           
+		     , GOODS_SNM1          
+		     , COLOR_CD            
+		     , STYLE_YEAR          
+		     , SEASON_CD           
+		     , SEX_GB              
+		     , GOODS_NUM           
+		     , GOODS_TYPE          
+		     , LIST_PRICE          
+		     , CURR_PRICE          
+		     , CURR_BPRICE         
+		     , PRICE_UPD_DT        
+		     , DC_RATE             
+		     , GOODS_STAT          
+		     , DISP_YN             
+		     , GOODS_GB            
+		     , DISTRIBUTION_GB     
+		     , SELF_GOODS_YN       
+		     , SUPPLY_COMP_CD      
+		     , SUPPLY_GOODS_CD     
+		     , AGE_GRP_CD          
+		     , DELV_FEE            
+		     , MIN_ORD_AMT         
+		     , PNT_PRATE           
+		     , PNT_MRATE           
+		     , SELL_FEE_RATE       
+		     , FORMAL_GB           
+		     , CHANGEABLE_YN       
+		     , RETURNABLE_YN       
+		     , CHANGE_FEE_FREE_YN  
+		     , RETURN_FEE_FREE_YN  
+		     , PRE_PPNT_USABLE_YN  
+		     , PRE_MPNT_USABLE_YN  
+		     , MIN_ORD_QTY         
+		     , MAX_ORD_QTY         
+		     , DAY_MAX_ORD_QTY     
+		     , FRST_CFRM_DT        
+		     , MAKE_NM             
+		     , MAKE_YMD            
+		     , TAX_GB              
+		     , ERP_PRICE_LINK_YN   
+		     , ERP_STOCK_LINK_YN   
+		     , #{regNo}              
+		     , NOW()              
+		     , UPD_NO              
+		     , UPD_DT              
+		FROM TB_GOODS
+		WHERE GOODS_CD = #{goodsCd}
+	</insert>
+	
+	<!-- 상품  수정 항목 일괄변경 -->
+	<update id="updateGoodsState" parameterType="Goods">
+		/* TsaGoods.updateGoodsState */
+		UPDATE TB_GOODS SET
+		      UPD_NO = #{updNo}
+		    , UPD_DT = NOW()
+		<if test="goodsStat != null and goodsStat != ''" >
+		    , GOODS_STAT = #{goodsStat}
+		    , FRST_CFRM_DT = IF(#{chGoodsStatYn} = 'Y', COALESCE(FRST_CFRM_DT, NOW()) , FRST_CFRM_DT)
+		</if>
+		<if test="erpStockLinkYn != null and erpStockLinkYn != ''" >
+		    , ERP_STOCK_LINK_YN = #{erpStockLinkYn}
+		</if>
+		<if test="erpPriceLinkYn != null and erpPriceLinkYn != ''" >
+		    , ERP_PRICE_LINK_YN = #{erpPriceLinkYn}
+		</if>
+		<if test="formalGb != null and formalGb != ''" >
+		    , FORMAL_GB = #{formalGb}
+		    , PNT_PRATE = IFNULL(#{pntPrate}, PNT_PRATE)
+		    , PNT_MRATE = IFNULL(#{pntMrate}, PNT_MRATE)
+		</if>
+		<if test='procJob == "pntPrate" and pntPrate != null' >
+		    , PNT_PRATE = #{pntPrate}
+		</if>
+		<if test='procJob == "pntMrate"  and pntMrate != null' >
+		    , PNT_MRATE = #{pntMrate}
+		</if>
+		<if test="returnableYn != null and returnableYn != ''" >
+		    , RETURNABLE_YN = #{returnableYn}
+		</if>
+		<if test="changeableYn != null and changeableYn != ''" >
+		    , CHANGEABLE_YN = #{changeableYn}
+		</if>
+		<if test="prePpntUsableYn != null and prePpntUsableYn != ''" >
+		    , PRE_PPNT_USABLE_YN = #{prePpntUsableYn}
+		</if>
+		<if test="preMpntUsableYn != null and preMpntUsableYn != ''" >
+		    , PRE_MPNT_USABLE_YN = #{preMpntUsableYn}
+		</if>
+		<if test='procJob == "minOrdAmt"  and minOrdAmt != null and minOrdAmt != ""' >
+		    , MIN_ORD_AMT = #{minOrdAmt}
+		</if>
+		<if test='blankFlag != null and blankFlag == "Y"'>
+		    , GOODS_TNM = ''
+		</if>
+		<if test="goodsTnm != null and goodsTnm != ''" >
+		    , GOODS_TNM = #{goodsTnm}
+		</if>
+		<if test="minOrdQty != null and minOrdQty > 0" >
+		    , MIN_ORD_QTY = #{minOrdQty}
+		</if>
+		<if test="maxOrdQty != null and maxOrdQty > 0" >
+		    , MAX_ORD_QTY = #{maxOrdQty}
+		</if>
+		<if test="dayMaxOrdQty != null and dayMaxOrdQty > 0" >
+		    , DAY_MAX_ORD_QTY = #{dayMaxOrdQty}
+		</if>
+		WHERE GOODS_CD = #{goodsCd}
+	</update>
+	
+	<!-- 상품 이미지 필수  항목 입력 여부  조회 -->
+	<select id="getGoodsImgsYn" parameterType="Goods" resultType="Goods">
+		/* TsaGoods.getGoodsImgsYn */
+		SELECT A.GOODS_CD
+		     , A.SUPPLY_COMP_CD
+		     , (SELECT I.NI_CLSF_CD FROM TB_ITEMKIND I WHERE I.ITEMKIND_CD = A.ITEMKIND_CD) AS NI_CLSF_CD
+		     , CASE WHEN B.IMG_PATH1 IS NULL THEN
+		            'N'
+		       ELSE
+		            'Y'
+		       END AS GOODS_IMAGE_YN
+		FROM TB_GOODS A
+		LEFT OUTER JOIN TB_GOODS_IMG B ON A.GOODS_CD = B.GOODS_CD
+		WHERE 1 = 1
+		<choose>
+		<when test="goodsCd != null and goodsCd != ''">
+		AND A.GOODS_CD  = #{goodsCd}
+		</when>
+		<otherwise>
+		AND A.GOODS_CD IN
+		    <foreach collection="arrGoodsCd" item="item" index="index"  open="(" close=")" separator=",">
+		#{item}
+		    </foreach>
+		</otherwise>
+		</choose>
+	</select>
+	
+	<!-- 상품 정보 이력 -->
+	<select id="getGoodsHstList" parameterType="Goods" resultType="GoodsHst">
+		/*TsaGoods.getGoodsHstList*/
+		SELECT CURR_PRICE
+		     , CURR_BPRICE
+		     , GOODS_NM
+		     , GOODS_TNM
+		     , GOODS_SNM
+		     , FORMAL_GB
+		     , GOODS_STAT
+		     , ERP_STOCK_LINK_YN
+		     , CHANGEABLE_YN
+		     , PRE_PPNT_USABLE_YN
+		     , PRE_MPNT_USABLE_YN
+		     , GOODS_SNM1
+		     , ITEMKIND_CD
+		     , DISP_YN
+		     , DATE_FORMAT(FRST_CFRM_DT, '%Y%m%d%H%i%S') AS FRST_CFRM_DT
+		     , UPD_NO
+		     , FN_GET_USER_NM(UPD_NO) AS UPD_NM
+		     , DATE_FORMAT(UPD_DT, '%Y%m%d%H%i%S') AS UPD_DT
+		     , REG_NO
+		     , FN_GET_USER_NM(REG_NO) AS REG_NM
+		     , DATE_FORMAT(REG_DT, '%Y%m%d%H%i%S') AS REG_DT
+		FROM TB_GOODS_HST
+		WHERE GOODS_CD = #{goodsCd}
+		ORDER BY REG_DT DESC
+	</select>
+	
+	<!-- 상품 품목 변경 -->
+	<update id="updateGoodItemKindCd" parameterType="Goods">
+		/* TsaGoods.updateGoodItemKindCd */
+		UPDATE TB_GOODS
+		SET ITEMKIND_CD = #{itemkindCd}
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		WHERE GOODS_CD = #{goodsCd}
+	</update >
+	
+	<!-- 상품 자동 검색어 조회-->
+	<select id="getGoodsSnm" parameterType="String" resultType="String">
+		/* TsaGoods.getGoodsSnm */
+		SELECT UPPER(CONCAT(
+		       G.GOODS_CD,';',
+		       REPLACE(G.GOODS_NM,' ',''),';',
+		       B.BRAND_ENM,';',
+		       B.BRAND_KNM,';',
+		       B.BRAND_GRP_NM,';',
+		       G.STYLE_YEAR,';',
+		       FN_GET_CODE_NM('G006',G.SEASON_CD),';',
+		       FN_GET_CODE_NM('G007',G.SEX_GB),';',
+		       G.COLOR_CD,';',
+		       C.COLOR_ENM,';',
+		       C.COLOR_KNM,';',
+		       REPLACE(I.ITEMKIND_NM,'>',';')
+		       )) AS GOODS_SNM
+		FROM TB_GOODS G
+		INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		LEFT OUTER JOIN TB_ITEMKIND I ON G.ITEMKIND_CD = I.ITEMKIND_CD
+		LEFT OUTER JOIN TB_COLOR C ON G.COLOR_CD = C.COLOR_CD
+		WHERE G.GOODS_CD = #{goodsCd}
+	</select>
+	
+	<!-- 상품검색어 수정 -->
+	<update id="updateGoodsSnm" parameterType="Goods">
+		/* TsaGoods.updateGoodsSnm */
+		UPDATE TB_GOODS A
+		SET UPD_ID = #{updId}
+		  , UPD_DT = SYSDATE
+		  , GOODS_SNM = #{goodsSnm} 
+		WHERE GOODS_CD = #{goodsCd}
+	</update>
+	
+	<!-- 상품 품목변경 고시정보 조회  -->
+	<select id="getNewNotiInfo" parameterType="Goods" resultType="GoodsNotiInfo">
+		/* TsaGoods.getNewNotiInfo */
+		SELECT D.NI_CLSF_CD
+		     , NVL(C.NI_ITEM_CD, D.NI_ITEM_CD) AS NI_ITEM_CD
+		     , NVL(C.NI_CONTENT, D.NI_CONTENT) AS NI_CONTENT
+		     , D.DISP_ORD
+		FROM (
+		       SELECT NI_ITEM_CD
+		            , NI_CONTENT 
+		       FROM TB_GOODS_NOTI_INFO
+		       WHERE GOODS_CD = #{goodsCd}
+		   ) C
+		   , (
+		       SELECT A.NI_CLSF_CD
+		          , A.NI_ITEM_CD
+		          , A.NI_CONTENT
+		          , A.DISP_ORD
+		       FROM TB_NOTI_INFO A
+		          , TB_ITEMKIND B
+		       WHERE A.NI_CLSF_CD = B.NI_CLSF_CD
+		       AND A.SUPPLY_COMP_CD = #{supplyCompCd}
+		       AND B.ITEMKIND_CD = #{itemkindCd}
+		   ) D
+		WHERE D.NI_ITEM_CD = C.NI_ITEM_CD (+)
+		ORDER BY D.DISP_ORD
+	</select>
+	
+	<!-- 상품 품목변경 고시정보 삭제  -->
+	<delete id="deleteGoodsNotiInfo" parameterType="Goods">
+		/* TsaGoods.deleteGoodsNotiInfo */
+		DELETE FROM TB_GOODS_NOTI_INFO
+		WHERE GOODS_CD = #{goodsCd}
+	</delete>
+	
+	<!-- 상품 고시 정보  저장 -->
+	<update id="saveGoodsNotiInfo" parameterType="GoodsNotiInfo">
+		/* TsaGoods.saveGoodsNotiInfo */
+		MERGE INTO TB_GOODS_NOTI_INFO
+		USING DUAL
+		ON    (
+		       GOODS_CD = #{goodsCd}
+		   AND NI_CLSF_CD = #{niClsfCd}
+		   AND NI_ITEM_CD = #{niItemCd}
+		      )
+		WHEN MATCHED THEN
+		    UPDATE
+		    SET NI_CONTENT = #{niContent}
+		      , UPD_ID = #{updId}
+		      , UPD_DT = SYSDATE
+		WHEN NOT MATCHED THEN
+		    INSERT (
+		           GOODS_CD
+		         , NI_CLSF_CD
+		         , NI_ITEM_CD
+		         , NI_CONTENT
+		         , DISP_ORD
+		         , REG_ID
+		         , REG_DT
+		         , UPD_ID
+		         , UPD_DT
+		    )
+		    VALUES (
+		           #{goodsCd}
+		         , #{niClsfCd}
+		         , #{niItemCd}
+		         , #{niContent}
+		         , #{dispOrd}
+		         , #{regId}
+		         , SYSDATE
+		         , #{updId}
+		         , SYSDATE
+		    )
+	</update>
+	
 </mapper>

+ 2 - 2
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml

@@ -164,14 +164,14 @@
 	</select>
 
 	<!-- 권한별 브랜드 목록 -->
-	<select id="getAuthBrandList" parameterType="String" resultType="CommonCode">
+	<select id="getAuthBrandList" parameterType="int" resultType="CommonCode">
 		/* TsaRenderer.getAuthBrandList */
 		SELECT A.BRAND_CD  AS CD
 		     , A.BRAND_ENM AS CD_NM
 		FROM   TB_BRAND A
 		INNER JOIN TB_BRAND_MD B ON A.BRAND_CD = B.BRAND_CD
 		WHERE  A.USE_YN = 'Y'
-		AND    B.MD_ID = #{userId}
+		AND    B.MD_ID = #{userNo}
 		GROUP  BY A.BRAND_CD, A.BRAND_ENM
 		ORDER  BY A.BRAND_CD
 	</select>

+ 112 - 0
style24.admin/src/main/webapp/WEB-INF/views/common/ExcelUploadPopupForm.html

@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ExcelUploadPopupForm.html
+ * @desc    : 엑셀 업로드 팝업 Page
+ *============================================================================
+ * Pastelmall
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.10.22   eskim       최초 작성
+ *******************************************************************************
+ -->	
+	<div class="modalPopup" data-width="600">
+		<div class="panelStyle">
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<strong>엑셀업로드</strong>
+				<button type="button" class="close" onclick="uiPopupClose('popupExcelUpload')"><i class="fa fa-times"></i></button>
+			</div>
+			<!-- //TITLE -->
+			<!-- CONTENT -->
+			<div class="panelContent">
+			<form id="excelPopupForm" name="excelPopupForm"  action="">
+			<input type="hidden" name="procJob" id="procJob" th:value="${params.procJob}"/>
+			<input type="hidden" name="callBackFun" id="callBackFun" th:value="${params.callBackFun}"/>
+				<table class="frmStyle">
+				<colgroup>
+					<col style="width:20%;"/>
+					<col/>
+					<col style="width:20%;"/>
+				</colgroup>
+				<tbody>
+					<tr>
+						<th>파일</th>
+						<td><div class="uFile w300">
+								<input id="excelFile" name="excelFile" type="file" class="uFileInput"/>
+								<label for="excelFile" class="uFileLabel">파일선택</label>
+								<input type="hidden" name="OrgFileNm"/>
+								<input type="hidden" name="NewFileNm"/>
+							</div>
+						</td>
+					</tr>
+				</tbody>
+				</table>
+				<!-- 버튼 배치 영역 -->
+				<ul class="panelBar">
+					<li class="right">
+						<button type="button" class="btn btn-success btn-lg" id="btnExcelUploadSave">저장</button>
+					</li>	
+				</ul>
+				<!-- //버튼 배치 영역 -->
+			</form>
+			</div>
+		</div>
+		<!-- //CONTENT -->
+	</div>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	
+	//첨부파일 등록
+	$('#excelPopupForm input[name=excelFile]').on('change', function() {
+		var file = this.files[0];
+	
+		if (typeof(file) == 'undefined'){
+			return;
+		}
+		
+		gagajf.ajaxFileUpload('/common/file/upload?subDir=/excel'
+				, file
+				, function(result) {
+					$('#excelPopupForm input[name=OrgFileNm]').val(result.newFileName);
+					$('#excelPopupForm input[name=NewFileNm]').val(result.newFileName);
+				}
+				, 'excel'
+		);
+	});
+	
+	//저장
+	$('#btnExcelUploadSave').on('click', function (){
+		
+		if(gagajf.isNull($("#excelPopupForm input[name=OrgFileNm]").val())){
+			mcxDialog.alert("파일을 첨부해 주세요.");
+			$("#excelPopupForm input[name=excelFile]").focus();
+			return false;
+		}
+		
+		var callback = $('#excelPopupForm input[name=callBackFun]').val();
+		if( typeof callback != 'undefined' && callback){
+			var data = {procJob : $('#excelPopupForm input[name=procJob]').val()
+						, callBackFun : $('#excelPopupForm input[name=callBackFun]').val()
+						, excelFileNm : $('#excelPopupForm input[name=NewFileNm]').val()
+						};
+			var jsonData = JSON.stringify(data);
+			if (typeof callback == 'function') {
+				callback(jsonData);
+			}else{
+				if( callback ) {
+					if( callback.indexOf("(") == -1 ) eval( callback +"(" + jsonData+")");
+					else eval( callback(jsonData) );
+				}
+			}
+			uiPopupClose('popupExcelUpload');
+		}
+	});	
+	
+/*]]>*/
+</script>
+</html>

+ 1929 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html

@@ -0,0 +1,1929 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsDetailForm.html
+ * @desc    : 상품 상세 팝업
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.10.23   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div class="modalPopup" data-width="1500"> <!-- data-width="1500" data-height="870" -->
+		<div class="panelStyle">
+			<div class="panelTitle">
+				<h2>상품상세</h2>
+				<button type="button" class="close" onclick="fnGoodsDetailClose()"><i class="fa fa-times"></i></button>
+			</div>
+			<div class="panelContent">
+			<form id="goodsDetailForm" name="goodsDetailForm" action="#" th:method="post">
+				<input type="hidden" id="mode" name="mode" th:value="${params.mode}"/>
+				<input type="hidden" id="goodsCd" name="goodsCd" th:value="${params.goodsCd}"/>
+				<input type="hidden" id="niClsfCd" name="niClsfCd"/>
+				<input type="hidden" id="selfGoodsYn" name="selfGoodsYn"/>
+				<input type="hidden" id="notiList" name="notiList" />
+				<input type="hidden" id="chDataYn" name="chDataYn" />
+				<input type="hidden" id="chStockDataYn" name="chStockDataYn" />
+				<input type="hidden" id="goodsImageYn" name="goodsImageYn" />
+				<input type="hidden" id="niClsfNm" name="niClsfNm" />
+				<input type="hidden" id="uploadGoodsUrl" name="uploadGoodsUrl" th:value="${@environment.getProperty('upload.goods.view')}"/>
+				<input type="hidden" id="goodsType" name="goodsType" />
+				<input type="hidden" id="extmallGoodsPriceList" name="extmallGoodsPriceList" />
+				<input type="hidden" id="goodsExtendList" name="goodsExtendList" />
+				<table class="frmStyle">
+					<colgroup>
+						<col width="11%"/>
+						<col/>
+						<col width="11%"/>
+						<col width="14%"/>
+						<col width="11%"/>
+						<col width="14%"/>
+						<col width="11%"/>
+						<col width="14%"/>
+					</colgroup>
+					<tr>
+						<th>브랜드명<em class="required" title="필수"></em></th>
+						<td colspan="3">
+							<select name="selSupplyCompCd" id="selSupplyCompCd" disabled="disabled" class="w40p">
+								<option value="">[선택]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="selBrandCd" id="selBrandCd" disabled="disabled"  class="w40p">
+								<option value="">[선택]</option>
+							</select>
+	
+							<input type="hidden" name="supplyCompCd" id="supplyCompCd" />
+							<input type="hidden" name="brandGrpNm" id="brandGrpNm" />
+							<input type="hidden" name="brandCd" id="brandCd" />
+						</td>
+						<th>상품코드<em class="required" title="필수"></em></th>
+						<td><div id="goodsCdTxt"></div></td>
+						<th>원코드</th>
+						<td><span id="supplyGoodsCdTxt"></span></td>
+					</tr>
+				</table>
+				<!-- TABS SPACE -->
+				<div class="tabs">
+					<!-- TABS NAVI -->
+					<div class="tabsNav">
+						<ul>
+							<li class="on"><a href="#goodstab1">기본정보</a></li>
+							<li><a href="#goodstab2">옵션/재고정보</a></li>
+							<li><a href="#goodstab3">상품상세정보</a></li>
+							<li id="goodsNotiTab"><a href="#goodstab4">고시정보</a></li>
+							<li id="goodsExtmallTab"><a href="#goodstab5">외부몰가격정보</a></li>
+							<li id="goodsExtendTab" style="display:none;"><a href="#goodstab6">구성상품</a></li>
+							<li><a href="#goodstab7">변경이력</a></li>
+						</ul>
+					</div>
+					<!-- //TABS NAVI -->
+					<!-- TABS CONTENTS -->
+					<ul class="tabsCont" th:with="uxImgUrl=${@environment.getProperty('domain.uximage')}">
+						<!-- TAB1 : 기본정보 -->
+						<li class="tab on" id="goodstab1">
+							<!-- TAB1 CONTENTS AREA -->
+							<div class="panelStyle">
+								<table class="frmStyle">
+									<colgroup>
+										<col width="10%"/>
+										<col width="15%"/>
+										<col width="15%"/>
+										<col width="15%"/>
+										<col width="15%"/>
+										<col width="15%"/>
+										<col/>
+									</colgroup>
+									<tbody>
+									<tr>
+										<td rowspan="4" style="text-align:center" th:with="uploadGoodsUrl=${@environment.getProperty('upload.goods.view')}">
+										<img id="goodsImgUrl" src="" width="100px"/>
+										<input type="hidden" name="imgPath1" id="imgPath1" />
+										</td>
+										<th>상품타이틀</th>
+										<td colspan="5">
+											<input type="text" class="w80p" id="goodsTnm" name="goodsTnm" maxlength=""></input>
+											<span class="byteChk"><em class="cBlue" id="goodsTnmLen">0</em>/200 bytes</span>
+											<input type="hidden" id="goodsTnmOrg" name="goodsTnmOrg"/>
+										</td>
+									</tr>
+									<tr>
+										<th>상품명<em class="required" title="필수"></em></th>
+										<td colspan="5">
+											<input type="text" class="w80p" id="goodsNm" name="goodsNm"></input>
+											<span class="byteChk"><em class="cBlue" id="goodsNmLen">0</em>/200 bytes</span>
+											<input type="hidden" id="goodsNmOrg" name="goodsNmOrg"/>
+										</td>
+									</tr>
+									<tr>
+										<th>사용자검색어</th>
+										<td colspan="5">
+											<input type="text" class="w60p" id="goodsSnm1" name="goodsSnm1"></input>
+											<span class="byteChk"><em class="cBlue" id="goodsSnm1Len">0</em>/200 bytes</span><font class="cBlue padL10"><b>* 여러개설정할경우 ; 구분자 사용 / 공백은 자동삭제처리</b></font>
+											<input type="hidden" id="goodsSnm1Org" name="goodsSnm1Org"/>
+										</td>
+									</tr>
+									<tr>
+										<th>검색어</th>
+										<td colspan="5">
+											<textarea class="textareaR2 w100p" id="goodsSnmTxt" name="goodsSnmTxt" disabled="disabled"></textarea>
+											<!-- <input type="text" class="w100p" id="goodsSnmTxt" name="goodsSnmTxt" disabled="disabled"></input> -->
+											<input type="hidden" id="goodsSnm" name="goodsSnm"></input>
+										</td>
+									</tr>
+									<tr>
+										<td class="aC cRed" style="font-weight:bold;"><span id="goodsTypeNm"></span></td> <!-- 상품타입노출 -->
+										<th>정상/이월 구분<em class="required" title="필수"></em></th>
+										<td>
+											<label class="rdoBtn" th:if="${formalGbList}" th:each="oneData, status : ${formalGbList}" ><input type="radio" id="formalGb" name="formalGb" th:value="${oneData.cd}" th:text="${oneData.cdNm}" /></label>
+											<input type="hidden" id="formalGbOrg" name="formalGbOrg"/>
+										</td>
+										<th>상품상태<em class="required" title="필수"></em></th>
+										<td>
+											<select  name="goodsStat" id="goodsStat">
+											<option value="">[선택]</option>
+											<option th:if="${goodsStatList}" th:each="oneData, status : ${goodsStatList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+											<input type="hidden" id="goodsStatOrg" name="goodsStatOrg"/>
+										</td>
+										<th>색상</th>
+										<td>
+											<select class="w90p"  name="colorCd" id="colorCd" disabled="disabled">
+											<option th:if="${colorList}" th:each="oneData, status : ${colorList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+										</td>
+									</tr>
+									<tr>
+										<td rowspan="10">&nbsp;</td>
+										<th>시즌<em class="required" title="필수"></em></th>
+										<td >
+											<select  name="seasonCd" id="seasonCd">
+												<option value="">[선택]</option>
+												<option th:if="${seasonList}" th:each="oneData, status : ${seasonList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+											<input type="hidden" id="seasonCdOrg" name="seasonCdOrg"/>
+										</td>
+										<th>성별<em class="required" title="필수"></em></th>
+										<td>
+											<select  name="sexGb" id="sexGb">
+												<option value="">[선택]</option>
+												<option th:if="${sexGbList}" th:each="oneData, status : ${sexGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+											<input type="hidden" id="sexGbOrg" name="sexGbOrg"/>
+										</td>
+										<th>스타일년도</th>
+										<td><span id="styleYearTxt"></span></td>
+									</tr>
+									<tr id="erplinkarea">
+										<th>원산지</th>
+										<td><span id="makeNmTxt"></span></td>
+										<th>ERP가격연동여부<em class="required" title="필수"></em></th>
+										<td>
+											<label class="rdoBtn"><input type="radio" name="erpPriceLinkYn" id="erpPriceLinkYnY" value="Y"/>Y</label>
+											<label class="rdoBtn"><input type="radio" name="erpPriceLinkYn" id="erpPriceLinkYnN" value="N"/>N</label>
+											<input type="hidden" id="erpPriceLinkYnOrg" name="erpPriceLinkYnOrg"/>
+										</td>
+										<th>상품구분<em class="required" title="필수"></em></th>
+										<td>
+											<select  name="goodsGb" id="goodsGb">
+												<option value="">[선택]</option>
+												<option th:if="${goodsGbList}" th:each="oneData, status : ${goodsGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+											<input type="hidden" id="goodsGbOrg" name="goodsGbOrg"/>
+										</td>
+									</tr>
+									<tr>
+										<th>정상가</th>
+										<td class="aR"><span id="listPriceTxt"></span> 원
+											<input type="hidden" id="listPrice" name="listPrice"/>
+										</td>
+										<th>판매가<em class="required" title="필수"></em></th>
+										<td><input type="text" class="w80p aR" id="currPrice" name="currPrice" maxlength="10" data-valid-type="integer"/> 원
+											<input type="hidden" id="currPriceOrg" name="currPriceOrg"/>
+										</td>
+										<th>가격변경일</th>
+										<td colspan="3"><span id="priceUpdDtTxt"></span></td>
+									</tr>
+									<tr>
+										<th>할인율</th>
+										<td class="aR" ><span id="dcRateTxt"></span> %  <input type="hidden" id="dcRate" name="dcRate"/></td>
+										<td colspan="5"></td>
+									</tr>
+									<tr id="selfGoodsNSellFeeRate">
+										<th>최초승인일</th>
+										<td><span id="frstCfrmDtTxt"></span></td>
+										<th>판매수수료율<em class="required" title="필수"></em></th>
+										<td><span id="sellFeeRateTxt"></span> %</td>
+										<th>자사몰 노출여부<em class="required" title="필수"></em></th>
+										<td>
+											<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYnY" value="Y"  checked/>Y</label>
+											<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYnn" value="N"/>N</label>
+											<input type="hidden" id="dispYnOrg" name="dispYnOrg"/>
+										</td>
+									</tr>
+									<tr>
+										<th>품목코드<em class="required" title="필수"></em></th>
+										<td colspan="3">
+											<select  name="itemkindCd" id="itemkindCd" th:disabled="${sessionInfo.roleCd != 'G001_0000' AND sessionInfo.roleCd != 'G001_A000' AND sessionInfo.roleCd != 'G001_A101' AND sessionInfo.roleCd != 'G001_A100' AND sessionInfo.roleCd != 'G001_A001'}">
+												<option th:if="${itemkindList}" th:each="oneData, status : ${itemkindList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+											</select>
+											<input type="hidden" id="orgItemkindCd" name="orgItemkindCd"/>
+											<th:block th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001' }">
+											<button type="button" class="btn btn-success btn-lg" id="btnGoodsItemkindChange">품목변경</button>
+											</th:block>
+										</td>
+										<th>기본배송비</th>
+										<td>
+											<input type="text" class="w100 aR" id="delvFee" name="delvFee"  disabled="disabled"/> 원
+										</td>
+									</tr>
+									<tr>
+										<th>PC포인트<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w50 aR" id="pntPrate" name="pntPrate" data-valid-type="integer" maxlength="3"/> % /&nbsp;
+											<input type="hidden" id="pntPrateOrg" name="pntPrateOrg"/>
+											<label class="rdoBtn"><input type="radio" name="prePpntUsableYn" id="prePpntUsableYnY" value="Y"/>Y</label>
+											<label class="rdoBtn"><input type="radio" name="prePpntUsableYn" id="prePpntUsableYnN" value="N"/>N</label>
+											<input type="hidden" id="prePpntUsableYnOrg" name="prePpntUsableYnOrg"/>
+										</td>
+										<th>모바일포인트<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w50 aR" id="pntMrate" name="pntMrate" data-valid-type="integer" maxlength="3"/> % /&nbsp;
+											<input type="hidden" id="pntMrateOrg" name="pntMrateOrg"/>
+											<label class="rdoBtn"><input type="radio" name="preMpntUsableYn" id="preMpntUsableYnY" value="Y"/>Y</label>
+											<label class="rdoBtn"><input type="radio" name="preMpntUsableYn" id="preMpntUsableYnN" value="N"/>N</label>
+											<input type="hidden" id="preMpntUsableYnOrg" name="preMpntUsableYnOrg"/>
+										</td>
+										<th>무료배송비기준<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w100 aR" id="minOrdAmt" name="minOrdAmt" data-valid-type="real" maxlength="10"/> 원
+											<input type="hidden" id="minOrdAmtOrg" name="minOrdAmtOrg"/>
+										</td>
+									</tr>
+									<tr>
+										<th>최소주문수량<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w100 aR" id="minOrdQty" name="minOrdQty" data-valid-type="integer" maxlength="5"/>
+											<input type="hidden" id="minOrdQtyOrg" name="minOrdQtyOrg"/>
+										</td>
+										<th>최대주문수량<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w100 aR" id="maxOrdQty" name="maxOrdQty" data-valid-type="integer" maxlength="5"/>
+											<input type="hidden" id="maxOrdQtyOrg" name="maxOrdQtyOrg"/>
+										</td>
+										<th>ID당1일최대구매수량<em class="required" title="필수"></em></th>
+										<td>
+											<input type="text" class="w100 aR" id="dayMaxOrdQty" name="dayMaxOrdQty" data-valid-type="integer" maxlength="5"/>
+											<input type="hidden" id="dayMaxOrdQtyOrg" name="dayMaxOrdQtyOrg"/>
+										</td>
+									</tr>
+									</tbody>
+								</table>
+							</div>
+							<!-- //TAB1  CONTENTS AREA -->
+						</li>
+						<!-- //TAB1 -->
+						<!-- TAB2 : 옵셥/재고 -->
+						<li class="tab" id="goodstab2">
+							<!-- TAB2 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- <ul class="notice cBlue">
+									<li><strong>상품 이미지 사이즈</strong> : <em><strong>600 × 600</strong> px</em></li>
+								</ul> -->
+								<div id="sizeStockArea"></div>
+							</div>
+							<!-- //TAB2 CONTENTS AREA -->
+						</li>
+						<!-- //TAB2 : 이미지/옵셥/재고 -->
+						<!-- TAB3 : 상품상세 -->
+						<li class="tab" id="goodstab3">
+							<!-- TAB3 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- TABS SPACE -->
+								<div class="tabsJr">
+									<!-- TABS CONTENT -->
+									<ul class="tabsJrCont">
+										<!-- TAB -->
+										<li class="tabJr on" id="goodstab11">
+											<!-- TAB11 CONTENTS AREA -->
+											<table class="frmStyle">
+											<colgroup>
+												<col width="12%"/>
+												<col/>
+											</colgroup>
+											<tr>
+												<th>상세설명</th>
+												<td><label class="chkBox"><input type="checkbox" name="chkDescKeep" checked="checked" value="Y">정보유지<span></span></label>
+												</td>
+											</tr>
+											<!-- <tr>
+												<th>상세</th>
+												<td><div class="tabJrContArea">
+													<textarea name="goodsDesc" id="goodsDesc" rows="5" cols="50"  style="width:1050px; height: 180px;"></textarea>
+													</div>
+												</td>
+											</tr> -->
+											<tr>
+												<th>상위(PC)</th>
+												<td><div class="tabJrContArea">
+													<textarea name="goodsPcTopDesc" id="goodsPcTopDesc" rows="5" cols="50" style="width:1050px; height: 150px;"></textarea>
+													</div>
+												</td>
+											</tr>
+											<tr>
+												<th>상위(MOBILE)</th>
+												<td><div class="tabJrContArea">
+													<textarea name="goodsMobileTopDesc" id="goodsMobileTopDesc" rows="5" cols="50" style="width:1050px; height: 150px;"></textarea>
+													</div>
+												</td>
+											</tr>
+											<tr>
+												<th>하위(PC)</th>
+												<td><div class="tabJrContArea">
+													<textarea name="goodsPcDownDesc" id="goodsPcDownDesc" rows="5" cols="50" class="w100p" style="width:1050px; height: 150px;"></textarea>
+													</div>
+												</td>
+											</tr>
+											<tr>
+												<th>하위(MOBILE)</th>
+												<td><div class="tabJrContArea">
+													<textarea name="goodsMobileDownDesc" id="goodsMobileDownDesc" rows="5" cols="50" style="width:1050px; height: 150px;"></textarea>
+													</div>
+												</td>
+											</tr>
+											</table>
+										</li>
+										<!-- //TAB -->
+									</ul>
+									<!-- //TAB CONTENT -->
+								</div>
+								<!-- //TABS SPACE -->
+							</div>
+							<!-- //TAB3 CONTENTS AREA -->
+						</li>
+						<!-- //TAB3 : 상품상세 -->
+						<!-- TAB4 : 고시정보 -->
+						<li class="tab" id="goodstab4">
+							<!-- TAB5 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- TABS SPACE -->
+								<table class="frmStyle">
+									<colgroup>
+										<col style="width:10%"/>
+										<col/>
+									</colgroup>
+									<tr>
+										<th>Details (상품상세정보 고시)<em class="required" title="필수"></em></th>
+										<td>
+											<select id="selNiClsfCd" name="selNiClsfCd"  class="w40p">
+												<option value="">[선택]</option>
+												<option th:if="${niClsfCdList}" th:each="oneData, status : ${niClsfCdList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
+											</select>
+											<button type="button" class="btn btn-dark btn-lg" id="btnNotinfo">선택</button>
+											<span class="padL10" id='itemkindNoti'></span>
+										</td>
+									</tr>
+								</table>
+								<hr/>
+								<div id="notiArea"></div>
+								<!-- //TABS SPACE -->
+							</div>
+							<!-- //TAB4 CONTENTS AREA -->
+						</li>
+						<!-- //TAB4 : 고시정보 -->
+						<!-- TAB5 : 추가정보 -->
+						<li class="tab" id="goodstab5">
+							<!-- TAB6 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- 내용 삽입 -->
+								<div id="gridGoodsExtMallPriceList" style="height: 550px;" class="ag-theme-balham"></div>
+								<!-- 내용 삽입 -->
+							</div>
+							<!-- //TAB6 CONTENTS AREA -->
+						</li>
+						<!-- //TAB5 : 추가정보 -->
+						<!-- TAB6 : 구성상품 -->
+						<li class="tab" id="goodstab6">
+							<!-- TAB6 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- 내용 삽입 -->
+								<div class="padB20 aR" id="goodsExtendBtnArea">
+									<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF003');">양식다운로드</button>
+									<button type="button" class="btn btn-success btn-lg" id="btnGoodsDealSearchExcel">엑셀조회</button>
+									<button type="button" class="btn btn-base btn-lg" onclick="fnOpenGoodsDetailPopup()">상품조회</button>
+								</div>
+								<div id="gridGoodsExtendList" style="height: 500px;" class="ag-theme-balham lh60"></div>
+								<!-- 내용 삽입 -->
+							</div>
+							<!-- //TAB6 CONTENTS AREA -->
+						</li>
+						<!-- //TAB7 : 추가정보 -->
+						<!-- TAB5 : 이력정보 -->
+						<li class="tab" id="goodstab5">
+							<!-- TAB8 CONTENTS AREA -->
+							<div class="panelStyle">
+								<!-- 내용 삽입 -->
+								<div id="gridGoodsHstoryList" style="height: 550px;" class="ag-theme-balham"></div>
+								<!-- 내용 삽입 -->
+							</div>
+							<!-- //TAB5 CONTENTS AREA -->
+						</li>
+						<!-- //TAB5 : 추가정보 -->
+					</ul>
+					<!-- //TABS CONTENTS -->
+					<!-- TABS BUTTON AREA -->
+					<ul class="panelBar marT10">
+						<li class="left">
+							<button type="button" class="btn btnLeft btn-base btn-lg" id="btnGoodsDetailPreview">미리보기</button>
+							<button type="button" class="btn btnLeft btn-base btn-lg" id="btnGoodsDetailImg">이미지보기</button>
+						</li>
+						<li class="right">
+							<th:block th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">
+							<button type="button" class="btn btnRight btn-success btn-lg" id="btnGoodsDetailSave">저장</button>
+							</th:block>
+						</li>	
+					</ul>
+					<!-- //TABS BUTTON AREA -->
+				</div>
+				<!-- //TABS SPACE -->
+			</form>
+			</div>	<!--  class=panelContent -->
+		</div>	<!--  class=panelStyle -->
+	</div> <!--  class=modalPopup -->
+<script type="text/javascript" src="/smartEditor/js/HuskyEZCreator.js?v=2019122801" charset="utf-8"></script>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.smarteditor.js?v=2019122801"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var formalGbList = gagajf.convertToArray([[${formalGbList}]]);
+	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
+	var itemkindList = gagajf.convertToArray([[${itemkindList}]]);
+	var authBrandList = [[${authBrandList}]];
+	var useYnList = gagajf.convertToArray([[${useYnList}]]);
+	var goodsTypeList = gagajf.convertToArray([[${goodsTypeList}]]);
+	var uploadGoodsUrl = [[${@environment.getProperty('upload.goods.view')}]];
+	// Get a SmartEditor options
+	var seOptions = gagaSe.getEditorOptions();
+	
+	// specify the columns - 상품변경이력
+	var columnGoodsHstoryDefs = [
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "변경일자", field: "regDt", width: 130, cellClass: 'text-center' ,
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmm").format("YYYY-MM-DD HH:mm") : '';
+			}
+		},
+		{headerName: "변경자", field: "regNm", width: 100, cellClass: 'text-center'},
+		{headerName: "판매가", field: "currPrice" , width: 100, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma();}
+		},
+		{headerName: "변경전판매가", field: "currBprice" , width: 100, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma(); }
+		},
+		{headerName: "상품상태", field: "goodsStat" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsStatList, params.newValue); }
+		},
+		{headerName: "상품명", field: "goodsNm" , width: 180, cellClass: 'text-left'},
+		{headerName: "상품타이틀", field: "goodsTnm" , width: 180, cellClass: 'text-left'},
+		/* {headerName: "상품검색어", field: "goodsSnm" , width: 180, cellClass: 'text-left'}, */
+		{headerName: "정상이월구분", field: "formalGb" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(formalGbList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(formalGbList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(formalGbList, params.newValue); }
+		},
+		{headerName: "품목", field: "itemkindCd" , width: 180, cellClass: 'text-left',
+			cellEditorParams: { values: gagaAgGrid.extractValues(itemkindList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(itemkindList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(itemkindList, params.newValue); }
+		},
+		{headerName: "최초승인일자", field: "frstCfrmDt", 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: "erpStockLinkYn" , width: 100, cellClass: 'text-center'},
+		{headerName: "자사몰노출여부", field: "dispYn" , width: 120, cellClass: 'text-center'},
+		{headerName: "사용자검색어", field: "goodsSnm1" , width: 150, cellClass: 'text-left'},
+		{headerName: "검색어", field: "goodsSnm" , width: 450, cellClass: 'text-left', tooltipField: "goodsSnm"}
+	];
+	
+	// specify the columns - 구성상품
+	var columnGoodsExtendDefs = [
+		{headerName: "정렬", field: "dispOrd", width: 70 ,hide: false, cellClass: 'text-center',  rowDrag: true },
+		{headerName: "CRUD", field: "crud", width: 75, minWidth: 75, hide: true},
+		//{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "이미지", field: "imgPath1", width: 100, height: 60, cellClass: 'text-center'
+			,cellRenderer: function(params) {
+				if (params.data.imgType == "A"){
+					if(!gagajf.isNull(params.data.imgPath6)){
+						return '<img width="60" src="'+ uploadGoodsUrl+params.data.imgPath6.replace("/1000/","/100/") + '" alt=""  onerror="this.src=\'/image/no.gif\';"/>';
+					}else{
+						return '<img width="60" src="'+ uploadGoodsUrl+params.value.replace("/1000/","/100/") + '" alt=""  onerror="this.src=\'/image/no.gif\';"/>';
+					}	
+				}else{
+					if(!gagajf.isNull(params.data.imgPath6)){
+						return '<img width="60" src="'+ params.data.imgPath1 + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+					}else{
+						return '<img width="60" src="'+ params.value + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+					}
+					
+				}
+			}
+		},
+		{headerName: "상품타입", field: "goodsType" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsTypeList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsTypeList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsTypeList, params.newValue); }
+		},
+		{headerName: "구성상품코드", field: "extendGoodsCd" , width: 130, cellClass: 'text-center'},
+		{headerName: "구성상품코드명", field: "extendGoodsCdNm" , width: 200, cellClass: 'text-left'},
+		//{headerName: "순서", field: "dispOrd" , width: 80, cellClass: 'text-right',editable: true, required: true},
+		{headerName: "수량", field: "qty" , width: 100, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma();}
+		},
+		{headerName: "판매가", field: "currPrice" , width: 100, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma();}
+		},
+		{headerName: "상품판매가", field: "extendCurrPrice" , width: 150, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma();}
+		},
+		/* {headerName: "상품임직원판매가", field: "extendStaffCurrPrice" , width: 150, cellClass: 'text-right'
+			,valueFormatter: function(params) { return Number(params.value).addComma();}
+		}, */
+		{headerName: "기준여부(품목-카테고리)", field: "baseYn", width: 180, cellClass: 'text-center'},
+		{headerName: "전시여부", field: "useYn", width: 100, cellClass: 'text-center',editable: true,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), required: true },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
+		{headerName: "옵션명(딜상품용)", field: "extendGoodsOptNm" , width: 200, cellClass: 'text-left',editable: true, required: true},
+		{headerName: "상품상태", field: "goodsStat" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsStatList, params.newValue); }
+		},
+		{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: "regId", width: 100, 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: "updId", width: 100, cellClass: 'text-center'}
+	];
+
+	// Get GridOptions
+	var gridGoodsHstoryOptions = gagaAgGrid.getGridOptions(columnGoodsHstoryDefs);
+	gridGoodsHstoryOptions.enableBrowserTooltips = true;
+	
+	var gridGoodsExtendOptions = gagaAgGrid.getGridOptions(columnGoodsExtendDefs);
+	// 드래그
+	gridGoodsExtendOptions.suppressRowClickSelection = true;
+	gridGoodsExtendOptions.rowDragManaged = true;
+	//gridGoodsExtendOptions.rowDeselection = true;
+	//gridGoodsExtendOptions.enableMultiRowDragging = true;
+	//gridGoodsExtendOptions.rowSelection = 'multiple';
+	
+	gridGoodsExtendOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+	
+	//기준여부 표시
+	gridGoodsExtendOptions.getRowStyle = function(params) {
+		if ("Y" == params.data.baseYn) {
+			return { background: '#1ab394' };
+		}
+	}
+	
+	
+
+	// 상품상세 조회
+	var fnGoodsDeailSearch = function() {
+
+		$('#goodsDetailForm').find('.tabs .tabsNav li a').attr("style", "color:#888;");
+
+		var params = new Object();
+		params.mode = $('#goodsDetailForm input[name=mode]').val();
+		params.goodsCd = $('#goodsDetailForm input[name=goodsCd]').val();
+
+		cfnAjaxSubmit("/goods/detail", "json", fnGoodDetailSearchCallback, params);
+	}
+
+	var fnGoodDetailSearchCallback = function(result) {
+
+		$('#goodsDetailForm').find(".tabsNav > li").removeClass('on');
+		$('#goodsDetailForm').find(".tabsNav > li").eq(0).addClass('on');
+		$('#goodsDetailForm').find(".tabsCont > li").removeClass('on');
+		$('#goodsDetailForm').find(".tabsCont > li").eq(0).addClass('on');
+
+		if (result != null){
+			//기본정보
+			$('#goodsDetailForm select[name=selSupplyCompCd]').val(result.supplyCompCd);
+			$('#goodsDetailForm input[name=supplyCompCd]').val(result.supplyCompCd);
+			$('#goodsDetailForm input[name=brandCd]').val(result.brandCd);
+			fnBrand(result.supplyCompCd, result.brandCd);
+
+			$('#goodsDetailForm').find('#goodsCdTxt').html(result.goodsCd);
+			$('#goodsDetailForm').find('#supplyGoodsCdTxt').html(result.supplyGoodsCd);
+
+			$("#goodsDetailForm input[name=goodsImageYn]").val(result.goodsImageYn);
+			$("#goodsDetailForm input[name=niClsfCd]").val(result.niClsfCd);
+			$("#goodsDetailForm select[name=selNiClsfCd]").val(result.niClsfCd);
+			$("#goodsDetailForm input[name=selfGoodsYn]").val(result.selfGoodsYn);
+			$('#goodsDetailForm').find('#goodsNumTxt').html(result.goodsNum);
+			$('#goodsDetailForm input[name=goodsNum]').val(result.goodsNum);
+			$('#goodsDetailForm select[name=goodsStat]').val(result.goodsStat);
+			$("#goodsDetailForm input[name=goodsStatOrg]").val(result.goodsStat);
+			$('#goodsDetailForm').find('#brandGrpNmTxt').html(result.brandGrpNm);
+
+			$('#goodsDetailForm select[name=colorCd]').val(result.colorCd);
+			//cfnCreateCombo("/renderer/avail/color/list", $('#goodsDetailForm select[name=colorCd]'), "[선택]", result.colorCd);
+
+			$('#goodsDetailForm select[name=itemkindCd]').val(result.itemkindCd);
+			$('#goodsDetailForm input[name=orgItemkindCd]').val(result.itemkindCd);
+			$('#goodsDetailForm select[name=seasonCd]').val(result.seasonCd);
+			$('#goodsDetailForm input[name=seasonCdOrg]').val(result.seasonCd);
+			$('#goodsDetailForm select[name=sexGb]').val(result.sexGb);
+			$('#goodsDetailForm input[name=sexGbOrg]').val(result.sexGb);
+			$('#goodsDetailForm').find('#makeNmTxt').html(result.makeNm);
+			$('#goodsDetailForm').find('#styleYearTxt').html(result.styleYear);
+			$('#goodsDetailForm select[name=goodsGb]').val(result.goodsGb);
+			$('#goodsDetailForm input[name=goodsGbOrg]').val(result.goodsGb);
+
+			$("#goodsDetailForm input[name=goodsNm]").val(result.goodsNm);
+			$('#goodsDetailForm input[name=goodsNmOrg]').val(result.goodsNm);
+			fnDataLengthCheck('goodsNm');
+			$("#goodsDetailForm input[name=goodsTnm]").val(result.goodsTnm);
+			$('#goodsDetailForm input[name=goodsTnmOrg]').val(result.goodsTnm);
+			fnDataLengthCheck('goodsTnm');
+			$("#goodsDetailForm input[name=goodsSnm1]").val(result.goodsSnm1);
+			$("#goodsDetailForm input[name=goodsSnm1Org]").val(result.goodsSnm1);
+			fnDataLengthCheck('goodsSnm1');
+			$("#goodsDetailForm textarea[name=goodsSnmTxt]").val(result.goodsSnm);
+			$("#goodsDetailForm input[name=goodsSnm]").val(result.goodsSnm);
+			$('#goodsDetailForm').find('#listPriceTxt').html(result.listPrice.addComma());
+			$('#goodsDetailForm input[name=listPrice]').val(result.listPrice);
+			$('#goodsDetailForm input[name=currPrice]').val(result.currPrice.addComma());
+			$('#goodsDetailForm input[name=currPriceOrg]').val(result.currPrice);
+			$('#goodsDetailForm').find('#dcRateTxt').html(result.dcRate);
+			$('#goodsDetailForm input[name=dcRate]').val(result.dcRate);
+			$('#goodsDetailForm').find('#priceUpdDtTxt').html(!gagajf.isNull(result.priceUpdDt) ? result.priceUpdDt.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '');
+			$('#goodsDetailForm').find('#frstCfrmDtTxt').html(!gagajf.isNull(result.frstCfrmDt) ? result.frstCfrmDt.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '');
+
+			$("#goodsDetailForm input[type=radio]").parent().removeClass("checked");
+			$("#goodsDetailForm input[type=radio]").removeAttr('checked');
+			
+			if (result.formalGb == "G009_20"){
+				$("#goodsDetailForm input:radio[name=formalGb]:input[value='G009_20']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=formalGb]:input[value='G009_10']").trigger('click');
+			}
+			if (result.erpPriceLinkYn == "Y"){
+				$("#goodsDetailForm input:radio[name=erpPriceLinkYn]:input[value='Y']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=erpPriceLinkYn]:input[value='N']").trigger('click');
+			}
+			if (result.dispYn == "Y"){
+				$("#goodsDetailForm input:radio[name=dispYn]:input[value='Y']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=dispYn]:input[value='N']").trigger('click');
+			}
+			$('#goodsDetailForm').find('#sellFeeRateTxt').html(result.sellFeeRate);
+			
+			if (result.prePpntUsableYn == "Y"){
+				$("#goodsDetailForm input:radio[name=prePpntUsableYn]:input[value='Y']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=prePpntUsableYn]:input[value='N']").trigger('click');
+			}
+			if (result.preMpntUsableYn == "Y"){
+				$("#goodsDetailForm input:radio[name=preMpntUsableYn]:input[value='Y']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=preMpntUsableYn]:input[value='N']").trigger('click');
+			}
+			if (result.changeableYn == "Y"){
+				$("#goodsDetailForm input:radio[name=changeableYn]:input[value='Y']").trigger('click');
+			}else{
+				$("#goodsDetailForm input:radio[name=changeableYn]:input[value='N']").trigger('click');
+			}
+
+			$("#goodsDetailForm input[name=formalGbOrg]").val(result.formalGb);
+			$("#goodsDetailForm input[name=erpPriceLinkYnOrg]").val(result.erpPriceLinkYn);
+			$("#goodsDetailForm input[name=dispYnOrg]").val(result.dispYn);
+			$("#goodsDetailForm input[name=prePpntUsableYnOrg]").val(result.prePpntUsableYn);
+			$("#goodsDetailForm input[name=preMpntUsableYnOrg]").val(result.preMpntUsableYn);
+			$("#goodsDetailForm input[name=changeableYnOrg]").val(result.changeableYn);
+
+			$("#goodsDetailForm input[type=radio][checked]").addClass("checked");
+			//$("#goodsDetailForm input[type=radio][checked]").parent("label").addClass("checked");
+
+			//입점상품일 경우
+			if (result.selfGoodsYn == "N"){
+				$('#goodsDetailForm').find('#erplinkarea').hide();
+				$("#goodsDetailForm").find("#selfGoodsDpTitle").html('원코드');
+				$("#goodsDetailForm").find("#selfGoodsDpTxt").html('<div id="supplyGoodsCdTxt"></div>');
+				$('#goodsDetailForm').find('#supplyGoodsCdTxt').html(result.supplyGoodsCd);
+			}
+			$('#goodsDetailForm input[name=delvFee]').val(result.delvFee.addComma());
+			$('#goodsDetailForm input[name=pntPrate]').val(result.pntPrate);
+			$('#goodsDetailForm input[name=pntPrateOrg]').val(result.pntPrate);
+			$('#goodsDetailForm input[name=pntMrate]').val(result.pntMrate);
+			$('#goodsDetailForm input[name=pntMrateOrg]').val(result.pntMrate);
+			$('#goodsDetailForm input[name=minOrdAmt]').val(result.minOrdAmt.addComma());
+			$('#goodsDetailForm input[name=minOrdAmtOrg]').val(result.minOrdAmt);
+			$('#goodsDetailForm input[name=minOrdQty]').val(result.minOrdQty);
+			$('#goodsDetailForm input[name=minOrdQtyOrg]').val(result.minOrdQty);
+			$('#goodsDetailForm input[name=maxOrdQty]').val(result.maxOrdQty);
+			$('#goodsDetailForm input[name=maxOrdQtyOrg]').val(result.maxOrdQty);
+			$('#goodsDetailForm input[name=dayMaxOrdQty]').val(result.dayMaxOrdQty);
+			$('#goodsDetailForm input[name=dayMaxOrdQtyOrg]').val(result.dayMaxOrdQty);
+			
+			$('#goodsDetailForm input[name=goodsType]').val(result.goodsType);
+			$("#goodsDetailForm").find("#goodsTypeNm").html(result.goodsTypeNm);
+			
+			//상품상세
+			gagaSe.setContents('goodsPcTopDesc', result.goodsPcTopDesc);
+			gagaSe.setContents('goodsMobileTopDesc', result.goodsMobileTopDesc);
+			gagaSe.setContents('goodsPcDownDesc', result.goodsPcDownDesc);
+			gagaSe.setContents('goodsMobileDownDesc', result.goodsMobileDownDesc);
+
+			if (!gagajf.isNull(result.niClsfNm)){
+				$('#goodsDetailForm').find('#itemkindNoti').html('품목기준 고시분류 : ' + result.niClsfNm);
+				$('#goodsDetailForm input[name=niClsfNm]').val(result.niClsfNm);
+				var objNotiInfo = $("#goodsDetailForm select[name=selNiClsfCd] option");
+				for(var i=0;i<objNotiInfo.length; i++ ){
+					if (objNotiInfo.eq(i).text() == result.niClsfNm){
+						objNotiInfo.eq(i).prop("selected","true");
+					}
+				}
+			}
+
+			var goodsImg = "";
+			var goodsImgPath1 = "";
+			if (result.imgType == "G030_A"){
+				if (!gagajf.isNull(result.imgPath6)){
+					goodsImg = result.imgPath6;
+					goodsImgPath1 = result.imgPath6;
+				}else{
+					goodsImg = result.imgPath1;
+					goodsImgPath1 = result.imgPath1;
+				}
+				
+			}else{
+				if (!gagajf.isNull(result.imgPath6)){
+					goodsImg = uploadGoodsUrl+result.imgPath6;
+					goodsImgPath1 = result.imgPath6;
+				}else{
+					goodsImg = uploadGoodsUrl+result.imgPath1;
+					goodsImgPath1 = result.imgPath1;
+				}
+			}
+			$('#goodsDetailForm').find('#goodsImgUrl').attr('src',goodsImg);
+			$('#goodsDetailForm input[name=imgPath1]').val(goodsImgPath1);
+			$("#goodsDetailForm input[type=checkbox][checked]").parent("label").addClass("checked");
+
+			//품목변경 권한 관련 처리
+			//md권한
+			if(sessRoleCd == "G001_A101" || sessRoleCd == "G001_B000"){
+				var roleFlag = "N";
+				$.each(authBrandList, function(idx, item) {
+					if (result.brandCd == item.cd ){
+						roleFlag = "Y";
+						return false;
+					}
+				});
+				if (roleFlag == "N"){
+					$('#goodsDetailForm select[name=itemkindCd]').attr('disabled',true);
+					$('#goodsDetailForm #btnGoodsItemkindChange').addClass('off');
+				}
+			}
+
+			//상품 구분에 따른 컬럼 사용여부처리 start
+			//세트
+			if ("G056_S" == result.goodsType){
+				$('#goodsDetailForm #erplinkarea').addClass('off');
+				if (result.selfGoodsYn == "Y") $('#goodsDetailForm #goodsExtendTab').css('display','block');
+				$('#goodsDetailForm #goodsNotiTab').css('display','none');
+			}else if ("G056_D" == result.goodsType){
+				$('#goodsDetailForm #erplinkarea').addClass('off');
+				$('#goodsDetailForm #erplinkarea').addClass('off');
+				if (result.selfGoodsYn == "Y") $('#goodsDetailForm #goodsExtendTab').css('display','block');
+				$('#goodsDetailForm #goodsNotiTab').css('display','none');
+			}
+			
+			//상품 구분에 따른 컬럼 사용여부처리 end
+			
+			var params = new Object();
+			params.mode = $('#goodsDetailForm input[name=mode]').val();
+			params.goodsCd = result.goodsCd;
+			params.brandCd = result.brandCd;
+			params.supplyCompCd = result.supplyCompCd;
+			params.niClsfCd = result.niClsfCd;
+			params.goodsType = result.goodsType;
+			params.erpPriceLinkYn = result.erpPriceLinkYn;
+
+			//옵셥 재고(ajax html)
+			//fnGoodsDetailSizeStockSearch(params);
+			//정보고시
+			fnGoodsDetailNotiInfoSearch(params);
+			
+			//구성상품
+			if ("G056_S" == result.goodsType || "G056_D" == result.goodsType){
+				fnGoodsExtendListSearch(params);
+			}
+			//이력
+			fnGoodsDetailHstSearch();
+
+		}
+	}
+
+	//옵셥 재고
+	var fnGoodsDetailSizeStockSearch = function(params) {
+		cfnAjaxSubmit("/goods/detail/sizeStock/form", "html", "sizeStockArea", params);
+	}
+
+	//정보고시
+	var fnGoodsDetailNotiInfoSearch = function(params) {
+		cfnAjaxSubmit("/goods/detail/notiInfo/list", "json", fnGoodsDetailNotiInfoSearchCallback, params);
+	}
+	
+	//구성상품
+	var fnGoodsExtendListSearch = function(params) {
+		if ("G056_S" == params.goodsType){	//세트
+			gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'currPrice', false);
+			gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'useYn', false);
+			gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'extendGoodsOptNm', false);
+			
+			$('#goodsExtendBtnArea').addClass("off");
+		}else{	//딜
+			gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'qty', false);
+			gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'extendCurrPrice', false);
+			//gagaAgGrid.showOrHideColumn(gridGoodsExtendOptions, 'extendStaffCurrPrice', false);
+		}
+		gagaAgGrid.fetch("/goods/detail/extend/list?goodsCd=" + params.goodsCd , gridGoodsExtendOptions);
+	}	
+	
+	//이력
+	var fnGoodsDetailHstSearch = function() {
+		gagaAgGrid.fetch("/goods/detail/hst/list?goodsCd=" + $('#goodsDetailForm input[name=goodsCd]').val() , gridGoodsHstoryOptions);
+	}
+	
+	//정보고시 콜백
+	var fnGoodsDetailNotiInfoSearchCallback = function(result) {
+		if (result == null) return;
+
+		var notiHtml = "";
+		var idx = 0;
+		$('#goodsDetailForm').find('#notiArea').html('');
+		notiHtml += '<table class="frmStyle">';
+		notiHtml += '<colgroup><col style="width:20%"/><col/><col style="width:5%"/><col style="width:5%"/></colgroup>';
+		notiHtml += '<tbody id="infoContents">\n';
+		notiHtml += '<tr><th>고시항목</th><th>고시내용</th><th>필수여부</th><th>전시여부</th></tr>';
+		result.forEach(function(info){
+			notiHtml += '<tr><th>'+ gagajf.convNull(info.niItemNm, '') +'<input type="hidden" name="niItemCd" value="'+ gagajf.convNull(info.niItemCd, '') +'" />\n<input type="hidden" name="dispOrd" value="'+ gagajf.convNull(info.dispOrd, '') +'" /></th>';
+			notiHtml += '<td><input type="text" name="niContent" value="'+ gagajf.convNull(info.niContent, '') +'"/></td>\n';
+			notiHtml += '<td class="aC">'+gagajf.convNull(info.reqYn, '')+'<input type="hidden" name="reqYn" value="'+ gagajf.convNull(info.reqYn, '') +'"/></td>\n';
+			notiHtml += '<td class="aC">'+gagajf.convNull(info.dispYn, '')+'<input type="hidden" name="dispYn" value="'+ gagajf.convNull(info.dispYn, '') +'"/></td>\n';
+			notiHtml += '</tr>\n';
+		});
+		notiHtml += '</tbody></table>';
+
+		$('#goodsDetailForm').find('#notiArea').append(notiHtml);
+
+		//고시정보탭 변경여부
+		$('#goodsDetailForm').find('#goodstab4').find("input, select, textarea").on('change', function() {
+			$('#goodsDetailForm').find('.tabs .tabsNav li:eq(3) a').attr("style", "color:red;");
+		});
+	}
+
+	//상품명 길이표시
+	$("#goodsDetailForm input[name=goodsNm]").bind('focus focusout input keyup keydown paste change', function () {
+		fnDataLengthCheck('goodsNm');
+	});
+
+	//상품타이틀 길이표시
+	$("#goodsDetailForm input[name=goodsTnm]").bind('focus focusout input keyup keydown paste change', function () {
+		fnDataLengthCheck('goodsTnm');
+	});
+	
+	//사용자검색어 길이표시
+	$("#goodsDetailForm input[name=goodsSnm1]").bind('focus focusout input keyup keydown paste change', function () {
+		fnDataLengthCheck('goodsSnm1');
+	});
+
+	//판매가 변경시 할인율 계산
+	$("#goodsDetailForm input[name=currPrice]").bind('focusout paste', function () {
+		fnCurrPriceCheck();
+	});
+
+	//판매가의 할인율 확인
+	var fnCurrPriceCheck = function(){
+		var dcRate = 0;
+
+		var tagPrice = $("#goodsDetailForm input[name=tagPrice]").val().removeComma();
+		var currPrice = $("#goodsDetailForm input[name=currPrice]").val().removeComma();
+		//dcRate = Math.round(100 - Math.floor((Number(currPrice) / Number(tagPrice) * 100)*100)/100);
+		dcRate = 100 - (Number((Number(currPrice) / Number(tagPrice)).toFixed(2)) *100)
+
+		$("#goodsDetailForm").find("#dcRateTxt").html(dcRate);
+		$("#goodsDetailForm input[name=dcRate]").val(dcRate);
+
+	}
+
+	//판매가의 할인율 확인
+	/* var fnCurrPriceCheck_org = function(){
+		var dcRate = 0;
+
+		var tagPrice = $("#goodsDetailForm input[name=tagPrice]").val().removeComma();
+		var currPrice = $("#goodsDetailForm input[name=currPrice]").val().removeComma();
+		//dcRate = Math.round(100 - Math.floor((Number(currPrice) / Number(tagPrice) * 100)*100)/100);
+		dcRate = 100 - (Number((Number(currPrice) / Number(tagPrice)).toFixed(2)) *100)
+
+		if (dcRate < 0){
+			mcxDialog.alert('할인율이 0보다 작습니다.\n판매가를 확인해주세요.', function(){
+				$("#goodsDetailForm input[name=currPrice]").focus();
+			});
+			return false;
+		}else if (dcRate >= 90){
+			gagaAlert.confirm("할인율이 90%이상입니다. 계속하시겠습니까?", function(){
+				$("#goodsDetailForm").find("#dcRateTxt").html(dcRate);
+				$("#goodsDetailForm input[name=dcRate]").val(dcRate);
+				return true;
+			},
+			function(){
+				$('#goodsDetailForm input[name=currPrice]').val($('#goodsDetailForm input[name=currPriceOrg]').val().addComma());
+				return false;
+			});
+
+		}else{
+			$("#goodsDetailForm").find("#dcRateTxt").html(dcRate);
+			$("#goodsDetailForm input[name=dcRate]").val(dcRate);
+			return true;
+		}
+	} */
+
+	// 브랜드 조회
+	var fnBrand = function(supplyCompCd, brandCd) {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + supplyCompCd;
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#goodsDetailForm select[name=selBrandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#goodsDetailForm select[name=selBrandCd]'), "[선택]", brandCd);
+
+	}
+
+	//데이터 길이 확인
+	var fnDataLengthCheck = function(id){
+		var maximumByte = 200;
+		var strLenEng = $('#goodsDetailForm').find('#'+id).val().length;
+		var cbyteStr = 0;
+		var liLenStr = 0;
+		for (i = 0; i < strLenEng; i++) {
+			var lsOneChar = $('#goodsDetailForm').find('#'+id).val().charAt(i);
+			if (lsOneChar == "\n" || lsOneChar == "\'") {
+				cbyteStr += 5; //엔터면 5를 더한다
+			} else if (lsOneChar == "\"") {
+				cbyteStr += 6; //쌍따옴표면 6를 더한다
+			} else if (escape(lsOneChar).length > 4) {
+				cbyteStr += 3; //한글이면 3를 더한다
+			} else {
+				cbyteStr++; //한글아니면 1을 다한다
+			}
+			if (cbyteStr <= maximumByte) {
+				liLenStr = i + 1;
+			}
+		}
+
+		// 사용자가 입력한 값이 제한 값을 초과하는지를 검사한다.
+		if (parseInt(cbyteStr) > parseInt(maximumByte)) {
+			mcxDialog.alertC('허용된 글자수가 초과되었습니다.\n초과된 부분은 자동으로 삭제됩니다.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsDetailForm').find('#'+id).focus();
+				}
+			});
+			var str = $('#goodsDetailForm').find('#'+id).val().substr(0, liLenStr);
+			$('#goodsDetailForm').find('#'+id).val(str);
+			var cbyteStr = 0;
+			for (i = 0; i < $('#goodsDetailForm').find('#'+id).val().length; i++) {
+				var lsOneChar = $('#goodsDetailForm').find('#'+id).val().charAt(i);
+				if (lsOneChar == "\n" || lsOneChar == "\'") {
+					cbyteStr += 5; //엔터면 5를 더한다
+				} else if (lsOneChar == "\"") {
+					cbyteStr += 6; //쌍따옴표면 6를 더한다
+				} else if (escape(lsOneChar).length > 4) {
+					cbyteStr += 3; //한글이면 3를 더한다
+				} else {
+					cbyteStr++; //한글아니면 1을 다한다
+				}
+			}
+		}
+
+		$('#goodsDetailForm').find('#'+id+'Len').text(cbyteStr);
+	}
+
+	//상품저장 버튼 클릭 시
+	$('#btnGoodsDetailSave').click(function() {
+
+		var optCheck = false;
+		var idx = 0;
+
+		//상품상태가 승인대기나 승인 완료일 경우
+		if($("#goodsDetailForm select[name=goodsStat]").val() == "G008_40" || $("#goodsDetailForm select[name=goodsStat]").val() == "G008_90"){
+
+			// SUPER관리자, 어드민관리자, 계정관리자. 총괄관리자, MD 를 제외하고 승인처리 할수 없음
+			if ("G001_0000" != sessRoleCd && "G001_A000" != sessRoleCd && "G001_A001" != sessRoleCd && "G001_A100" != sessRoleCd && "G001_A101" != sessRoleCd ){
+				if ($("#goodsDetailForm select[name=goodsStat]").val() == "G008_90" &&  $("#goodsDetailForm select[name=goodsStatOrg]").val() != "G008_90"){
+					mcxDialog.alert(" '승인완료' 상태로 변경할 권한이 없습니다.");
+					return false;
+				}
+				
+			}
+			//teg가 등록되지 않은 상품은 상태변경 불가
+			if(Number($("#goodsDetailForm input[name=tagPrice]").val()) == 0){
+				mcxDialog.alertC("TAG가 등록되지 않은 상품은 '승인대기'나 '승인완료' 상태로 변경할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm select[name=goodsStat]").focus();
+					}
+				});
+				return false;
+			}
+
+			//판매가가 0인  상품은 상태변경 불가
+			if((gagajf.isNull($("#goodsDetailForm input[name=currPrice]").val()) || $("#goodsDetailForm input[name=currPrice]").val() == 0)){
+				mcxDialog.alertC("판매가가 등록되지 않은 상품은 '승인대기'나 '승인완료' 상태로 변경할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm select[name=goodsStat]").focus();
+					}
+				});
+				return;
+			}
+
+			//사이즈정보가 등록되지 않은 상품은 상태변경 불가
+			if($("#goodsDetailForm #sizeStockArea").find("#optionList tr").length == 0){
+				mcxDialog.alertC("사이즈정보가 등록되지 않은 상품은 '승인대기'나 '승인완료' 상태로 변경할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm select[name=goodsStat]").focus();
+					}
+				});
+				return;
+			}
+
+			//이미지가 등록되지 않은 상품은 상태변경 불가
+			if($("#goodsDetailForm input[name=goodsImageYn]").val() == "N"){
+				mcxDialog.alertC("이미지가 등록되지 않은 상품은 '승인대기'나 '승인완료' 상태로 변경할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm select[name=goodsStat]").focus();
+					}
+				});
+				return;
+			}
+
+			//고시정보가 등록되지 않은 상품은 상태변경 불가 - 일반상품만 체크
+			if ("N" == $("#goodsDetailForm input[name=goodsType]").val()){
+				if($("#goodsDetailForm #notiArea").find("#infoContents tr").length == 0){
+					mcxDialog.alertC("고시정보가 등록되지 않은 상품은 '승인대기'나 '승인완료' 상태로 변경할 수 없습니다.", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$("#goodsDetailForm select[name=goodsStat]").focus();
+						}
+					});
+					return;
+				}
+
+				idx = 0;
+
+				$("#goodsDetailForm #notiArea").find("#infoContents tr").each(function() {
+					if ("Y" == $(this).find("input[name=reqYn]").val() ||  "Y" == $(this).find("input[name=dispYn]").val()){
+						if (gagajf.isNull($(this).find("input[name=niContent]").val())){
+							optCheck = true;
+							mcxDialog.alertC("고시정보를 입력해주세요.");
+							return false;
+						}
+					}
+					idx++;
+				});
+	
+			}
+		}
+
+		if(optCheck) {
+			return false;
+		}
+
+		//상품명
+		if(gagajf.isNull($("#goodsDetailForm input[name=goodsNm]").val())){
+			mcxDialog.alertC("상품명을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=goodsNm]").focus();
+				}
+			});
+			return;
+		}
+
+		//상품상태
+		if(gagajf.isNull($("#goodsDetailForm select[name=goodsStat]").val())){
+			mcxDialog.alertC("상품상태를 선택해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm select[name=goodsStat]").focus();
+				}
+			});
+			return;
+		}
+
+		//성별
+		if(gagajf.isNull($("#goodsDetailForm select[name=sexGb]").val())){
+			mcxDialog.alertC("성별을 선택해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm select[name=sexGb]").focus();
+				}
+			});
+			return;
+		}
+
+		//시즌
+		if(gagajf.isNull($("#goodsDetailForm select[name=seasonCd]").val())){
+			mcxDialog.alertC("시즌을 선택해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm select[name=seasonCd]").focus();
+				}
+			});
+			return;
+		}
+
+		//판매가
+		if(gagajf.isNull($("#goodsDetailForm input[name=currPrice]").val())) {
+			mcxDialog.alertC("판매가를 올바르게 입력해주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=currPrice]").focus();
+				}
+			});
+			return false;
+		}
+		
+		/* if(Number($("#goodsDetailForm input[name=currPrice]").val().removeComma()) < 1000) {
+			mcxDialog.alertC("판매가는 1000원 이상을 입력하셔야 합니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=currPrice]").focus();
+				}
+			});
+		} */
+
+		// 포인트
+		if ( gagajf.isNull($("#goodsDetailForm input[name=pntPrate]").val())) {
+			mcxDialog.alertC("PC 포인트를 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=pntPrate]").focus();
+				}
+			});
+			return false;
+		}
+		if ( gagajf.isNull($("#goodsDetailForm input[name=pntMrate]").val())) {
+			mcxDialog.alertC("MOBILE 포인트를 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=pntMrate]").focus();
+				}
+			});
+			return false;
+		}
+
+		// 주문수량
+		if ( gagajf.isNull($("#goodsDetailForm input[name=minOrdQty]").val())) {
+			mcxDialog.alertC("최소주문 수량을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=minOrdQty]").focus();
+				}
+			});
+			return false;
+		}
+		if (Number($("#goodsDetailForm input[name=minOrdQty]").val()) <= 0) {
+			mcxDialog.alertC("최소주문 수량을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=minOrdQty]").focus();
+				}
+			});
+			return false;
+		}
+		if ( gagajf.isNull($("#goodsDetailForm input[name=maxOrdQty]").val())) {
+			mcxDialog.alertC("최대주문 수량을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=maxOrdQty]").focus();
+				}
+			});
+			return false;
+		}
+		if (Number($("#goodsDetailForm input[name=maxOrdQty]").val()) <= 0) {
+			mcxDialog.alertC("최대주문 수량을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=maxOrdQty]").focus();
+				}
+			});
+			return false;
+		}
+
+		if(Number($("#goodsDetailForm input[name=minOrdQty]").val()) > Number($("#goodsDetailForm input[name=maxOrdQty]").val())){
+			mcxDialog.alertC("최소주문수량은 최대주문수량보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=minOrdQty]").focus();
+				}
+			});
+			return false;
+		}
+
+		// 무료배송비
+		if ( gagajf.isNull($("#goodsDetailForm input[name=minOrdAmt]").val())) {
+			mcxDialog.alertC("무료 배송 금액을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=minOrdAmt]").focus();
+				}
+			});
+			return false;
+		}
+		if (Number($("#goodsDetailForm input[name=minOrdAmt]").val().removeComma()) <= 0) {
+			mcxDialog.alertC("무료 배송 금액을 입력해 주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=minOrdAmt]").focus();
+				}
+			});
+			return false;
+		}
+
+		//if (optCheck) return false;
+
+		idx = 0;
+
+		//재고 옵션 관련 확인
+		$("#goodsDetailForm input[name=chStockDataYn]").val('N');
+
+		$("#optionList tr").each(function() {
+			var sizeNm = $(this).find("input[name=sizeNm]").val();
+			var hidSizeNm = $(this).find("input[name=hidSizeNm]").val();
+			var baseOnStockQty = $(this).find("input[name=baseOnStockQty]").val();
+			var hidBaseOnStockQty = $(this).find("input[name=hidBaseOnStockQty]").val();
+			var baseOffStockQty = $(this).find("input[name=baseOffStockQty]").val();
+			var hidBaseOffStockQty = $(this).find("input[name=hidBaseOfftockQty]").val();
+			var baseShopStockQty = $(this).find("input[name=baseShopStockQty]").val();
+			var hidBaseShopStockQty = $(this).find("input[name=hidBaseShopStockQty]").val();
+			var basePcStockQty = $(this).find("input[name=basePcStockQty]").val();
+			var hidBasePcStockQty = $(this).find("input[name=hidBasePcStockQty]").val();
+			var baseMoStockQty = $(this).find("input[name=baseMoStockQty]").val();
+			var hidBaseMoStockQty = $(this).find("input[name=hidBaseMotockQty]").val();
+			var baseAppStockQty = $(this).find("input[name=baseAppStockQty]").val();
+			var hidBaseAppStockQty = $(this).find("input[name=hidBaseAppStockQty]").val();
+			var dispOrd = $(this).find("input[name=dispOrd]").val();
+			var hidDispOrd = $(this).find("input[name=hidDispOrd]").val();
+			var soldoutYn = $(this).find("select[name=soldoutYn]").val();
+			var hidSoldoutYn = $(this).find("input[name=hidSoldoutYn]").val();
+			var hidSoldoutDt = $(this).find("input[name=hidSoldoutDt]").val();
+			var hidSoldoutDt3day = $(this).find("input[name=hidSoldoutDt3day]").val();
+
+			var editCurrOnStockQty = $(this).find("input[name=editCurrOnStockQty]").val();	// 입점 확인용
+			var currOnStockQty = $(this).find("input[name=currOnStockQty]").val();	// 입점 확인용 (hidden)
+			
+			if(gagajf.isNull(dispOrd)){
+				optCheck = true;
+				mcxDialog.alertC("우선순위를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=dispOrd]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+
+			//ERP재고연동여부가 'Y'일 경우 수정여부 확인
+		/* 	if ( $('#goodsDetailForm input[name=erpStockLinkYn]:checked').val() == "Y"){
+				if (Number(editCurrStockQty) != Number(currStockQty) ){
+					optCheck = true;
+					mcxDialog.alertC("ERP가용재고가 변경되었습니다.<br/>확인해주세요", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$("#optionList tr").find("input[name=erpStockLinkYn]").eq(idx).focus();
+						}
+					});
+					return false;
+				}
+			} */
+
+			// 입점만 체크
+			if ("N" == $('#goodsDetailForm input[name=selfGoodsYn]').val()){
+				
+				if(gagajf.isNull(editCurrOnStockQty)){
+					optCheck = true;
+					mcxDialog.alertC("온라인 재고를 입력해주세요", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$("#optionList tr").find("input[name=editCurrOnStockQty]").eq(idx).focus();
+						}
+					});
+					return false;
+				}
+			}
+			
+			if(gagajf.isNull(baseOnStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("온라인 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=baseOnStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+			
+			if(gagajf.isNull(baseOffStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("오프라인 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=baseOffStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+			
+			if(gagajf.isNull(baseShopStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("직송 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=baseShopStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+			
+			if(gagajf.isNull(basePcStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("PC 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=basePcStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+			
+			if(gagajf.isNull(baseMoStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("모바일 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=baseMoStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+			
+			if(gagajf.isNull(baseAppStockQty)){
+				optCheck = true;
+				mcxDialog.alertC("APP 안전재고를 입력해주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#optionList tr").find("input[name=baseAppStockQty]").eq(idx).focus();
+					}
+				});
+				return false;
+			}
+
+			// 품절로 인한 soldout은 3일(당일 포함)동안 품절 풀 수 없음
+			if (soldoutYn != hidSoldoutYn && hidSoldoutYn == "Y" && !gagajf.isNull(hidSoldoutDt)){
+				var date = new Date();
+				var after3Day = date.before(0, 0, 3).format("YYYYMMDD");
+				if (hidSoldoutDt > after3Day) {
+					optCheck = true;
+					mcxDialog.alertC("주문품절로 인한 품절건은 "+hidSoldoutDt3day+" 에 수정할 수 있습니다.", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$("#optionList tr").find("select[name=soldoutYn]").eq(idx).focus();
+						}
+					});
+					return false;
+				}
+			}
+
+			if (sizeNm != hidSizeNm){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (editCurrOnStockQty != currOnStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (baseOnStockQty != hidBaseOnStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (baseOffStockQty != hidBaseOffStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (baseShopStockQty != hidBaseShopStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (basePcStockQty != hidBasePcStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (baseMoStockQty != hidBaseMoStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+			
+			if (baseAppStockQty != hidBaseAppStockQty){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+
+			if (dispOrd != hidDispOrd){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+
+			if (soldoutYn != hidSoldoutYn){
+				$("#goodsDetailForm input[name=chStockDataYn]").val('Y');
+			}
+
+			//$(this).find("input[name=currStockQty]").val(editCurrStockQty);	//DB 저장을 위해
+			idx++;
+		});
+
+		if(optCheck) {
+			return false;
+		}
+
+		var dcRate = 0;
+		var tagPrice = $("#goodsDetailForm input[name=tagPrice]").val().removeComma();
+		var currPrice = $("#goodsDetailForm input[name=currPrice]").val().removeComma();
+		dcRate =  100 - Math.floor(Number(currPrice) / Number(tagPrice) * 100);	//절사
+		//dcRate = 100 - Math.floor(Number((Number(currPrice) / Number(tagPrice)).toFixed(2)) *100);
+ 
+			
+		if (dcRate < 0){
+			mcxDialog.alertC('할인율이 0보다 작습니다.\n판매가를 확인해주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm input[name=currPrice]").focus();
+				}
+			});
+			return false;
+		}else if (dcRate >= 90){
+			gagaAlert.confirm("할인율이 90%이상입니다. 계속하시겠습니까?", function(){
+				fnNoticheck();
+			},
+			function(){
+				optCheck = true;
+			});
+
+		}else{
+			$("#goodsDetailForm").find("#dcRateTxt").html(dcRate);
+			$("#goodsDetailForm input[name=dcRate]").val(dcRate);
+			
+		}
+
+		
+		if (optCheck) return false;
+		
+		if (!fnExtendGoodsCheck()) return false;
+		
+		//fnNoticheck();
+
+		if($("#goodsDetailForm input:checkbox[name=chkDescKeep]").is(':checked')){
+			gagaAlert.confirm("'정보유지' 체크박스가 선택되어 있어 '상품상세설명' 항목이 저장되지 않습니다. 저장을 원하시면 체크를 해제하세요. 계속하시겠습니까?", function(){
+				fnGoodsSave();
+			},
+			function(){
+				optCheck = true;
+			});
+		}else{
+			fnGoodsSave();
+		}
+		
+		if (optCheck) return false;
+		
+		
+	});
+
+	//고시정보 관련 체크
+	var fnExtendGoodsCheck = function(){
+		if ($("#goodsDetailForm input[name=goodsType]").val() == "G056_N"){
+			return true;	
+		}
+		
+		var allData = gagaAgGrid.getAllRowData(gridGoodsExtendOptions);
+		var comSupplyCompCd = '';
+		var comSelfGoodsYn = '';
+		//기준여부 Y  존재하는지 확인
+		var checkBaseYn = false;
+		optCheck = false;
+		$.each(allData, function(index, item) {
+			if (index == 0){
+				comSelfGoodsYn = item.selfGoodsYn;
+				comSupplyCompCd = item.supplyCompCd;
+			}
+			
+			if (item.baseYn == "Y"){
+				checkBaseYn = true;
+			}
+			
+			if (comSelfGoodsYn != item.selfGoodsYn){
+				optCheck = true;
+				mcxDialog.alertC("구상상품중 자사/입점상품 구분값이 다릅니다.\n확인해 주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						gridGoodsExtendOptions.api.setFocusedCell(index, "goodsCd", null);
+					}
+				});	
+				return false;
+			}else{
+				if (comSelfGoodsYn == "N" && (comSupplyCompCd != item.supplyCompCd)){
+					optCheck = true;
+					mcxDialog.alertC("구상상품중 입점은 같은 업체 상품만 가능합니다.\n확인해 주세요", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							gridGoodsExtendOptions.api.setFocusedCell(index, "goodsCd", null);
+						}
+					});	
+					return false;
+				}
+			}
+			
+		});
+		
+		if(optCheck) {
+			return false;
+		}
+		
+		if (!checkBaseYn){
+			mcxDialog.alert('구성상품중 기준여부를 선택해 주세요.');
+			return false;
+		}
+		
+		return true;
+	}
+
+	//저장처리
+	var fnGoodsSave = function(){
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				//gagaSe.getContents('goodsDesc');
+				gagaSe.getContents('goodsPcTopDesc');
+				gagaSe.getContents('goodsMobileTopDesc');
+				gagaSe.getContents('goodsPcDownDesc');
+				gagaSe.getContents('goodsMobileDownDesc');
+
+				fnGoodsDeailNotiSave();
+
+				if (fnChangeCheck()){
+					$("#goodsDetailForm input[name=chDataYn]").val('Y');
+				}else{
+					$("#goodsDetailForm input[name=chDataYn]").val('N');
+				}
+				
+				/* var changedPriceData = gagaAgGrid.getChangedData(gridGoodsExtmallPriceOptions);
+				var jsonDataPrice = JSON.stringify(changedPriceData);
+				$('#goodsDetailForm input[name=extmallGoodsPriceList]').val(jsonDataPrice); */
+				
+				//구성상품
+				var allData = gagaAgGrid.getAllRowData(gridGoodsExtendOptions);
+				//var allData = gagaAgGrid.getChangedData(gridGoodsExtendOptions);
+				/* var changedData = [];
+
+				$.each(allData, function(idx, item) {
+					//item.dispOrd = idx+1;
+					changedData.push(item);
+				}); */
+				
+				var jsonData = JSON.stringify(allData);
+				$('#goodsDetailForm input[name=goodsExtendList]').val(jsonData);
+				
+				
+				$('#goodsDetailForm input[name=goodsNm]').val($('#goodsDetailForm input[name=goodsNm]').val().trim().replace(/\n|\r/g, "<br/>").replace(/\"/gi, "&quot;").replace(/\'/gi, "&#39;"));
+				$('#goodsDetailForm input[name=goodsTnm]').val($('#goodsDetailForm input[name=goodsTnm]').val().trim().replace(/\n|\r/g, "<br/>").replace(/\"/gi, "&quot;").replace(/\'/gi, "&#39;"));
+				$('#goodsDetailForm input[name=goodsSnm1]').val($('#goodsDetailForm input[name=goodsSnm1]').val().trim().replace(/\n|\r/g, "<br/>").replace(/\"/gi, "&quot;").replace(/\'/gi, "&#39;"));
+
+				gagajf.ajaxFormSubmit("/goods/detail/save", "#goodsDetailForm", fnGoodsSaveCallBack);  //fnGoodsDeailSearch   fnGoodsDeailNotiSave
+			}
+		});
+	}
+
+	//미리보기 클릭 시
+	$('#btnGoodsDetailPreview').click(function(e) {
+		cfnOpenFrontGoodsPopup($('#goodsDetailForm input[name=goodsCd]').val(), $('#goodsDetailForm input[name=siteCd]').val());
+	});
+
+	//이미지 클릭 시
+	$('#btnGoodsDetailImg').click(function(e) {
+		cfnOpenGoodsImagePopup($('#goodsDetailForm input[name=goodsCd]').val());
+	});
+	
+	//창종료
+	var fnGoodsDetailClose = function(){
+		uiPopupClose('popupGoodsDetail');
+	}
+
+	//저장후 callback
+	var fnGoodsSaveCallBack = function(){
+		var goodsCd = $('#goodsDetailForm input[name=goodsCd]').val();
+		fnGoodsDetailClose();
+		cfnOpenGoodsDetailPopup('U', goodsCd);
+	}
+
+	//고시정보 저장을 위한 데이터 처리
+	var fnGoodsDeailNotiSave = function(){
+
+		var goodsCd = $('#goodsDetailForm input[name=goodsCd]').val();
+		var goodsInfoList = [];
+
+		var index = 0;
+		$("#goodsDetailForm").find("#infoContents tr").each(function() {
+			if (index > 0){
+				var goodsInfo = {goodsCd: goodsCd
+						, niClsfCd : $('#goodsDetailForm input[name=niClsfCd]').val()
+						, niItemCd : $(this).find("input[name=niItemCd]").val()
+						, niContent : $(this).find("input[name=niContent]").val()
+						, dispOrd : $(this).find("input[name=dispOrd]").val()
+						};
+				goodsInfoList.push(goodsInfo);	
+			}
+			index++;
+		});
+
+		$("#goodsDetailForm input[name=notiList]").val(JSON.stringify(goodsInfoList));
+	}
+
+	//상품기본정보 변경여부 확인
+	var fnChangeCheck = function(){
+		
+		//상품타이틀
+		if ($("#goodsDetailForm input[name=goodsTnmOrg]").val() != $("#goodsDetailForm input[name=goodsTnm]").val()){
+			return true;
+		}
+		//사용자검색어
+		if ($("#goodsDetailForm input[name=goodsSnm1Org]").val() != $("#goodsDetailForm input[name=goodsSnm1]").val()){
+			return true;
+		}
+		//상품명
+		if ($("#goodsDetailForm input[name=goodsNmOrg]").val() != $("#goodsDetailForm input[name=goodsNm]").val()){
+			return true;
+		}
+		//상품정상이월구분
+		if ($("#goodsDetailForm input[name=goodsType]").val() != 'N' || $("#goodsDetailForm input[name=selfGoodsYn]").val() == 'N'){
+			if ($("#goodsDetailForm input[name=formalGbOrg]").val() != $("input:radio[name=formalGb]:checked").val()){
+				return true;
+			}
+		}
+		
+		//상품상태
+		if ($("#goodsDetailForm input[name=goodsStatOrg]").val() != $("#goodsDetailForm select[name=goodsStat]").val()){
+			return true;
+		}
+		//시즌
+		if ($("#goodsDetailForm input[name=seasonCdOrg]").val() != $("#goodsDetailForm select[name=seasonCd]").val()){
+			return true;
+		}
+		//성별
+		if ($("#goodsDetailForm input[name=sexGbOrg]").val() != $("#goodsDetailForm select[name=sexGb]").val()){
+			return true;
+		}
+		//판매가
+		if ($("#goodsDetailForm input[name=currPriceOrg]").val() != $("#goodsDetailForm input[name=currPrice]").val().removeComma()){
+			return true;
+		}
+		
+		//자사일경우만
+		if($("#goodsDetailForm input[name=selfGoodsYn]").val() == 'Y' ){
+			//ERP재고연동여부
+			if ($("#goodsDetailForm input[name=erpStockLinkYnOrg]").val() != $("input[name=erpStockLinkYn]:checked").val()){
+				return true;
+			}
+			//ERP가격연동여부
+			if ($("#goodsDetailForm input[name=erpPriceLinkYnOrg]").val() != $("input[name=erpPriceLinkYn]:checked").val()){
+				return true;
+			}
+		}
+		//자사몰 노출여부
+		if ($("#goodsDetailForm input[name=dispYnOrg]").val() != $("input[name=dispYn]:checked").val()){
+			return true;
+		}
+		//PC포인트 
+		if ($("#goodsDetailForm input[name=pntPrateOrg]").val() != $("#goodsDetailForm input[name=pntPrate]").val()){
+			return true;
+		}
+		//PC 선포인트 사용여부
+		if ($("#goodsDetailForm input[name=prePpntUsableYnOrg]").val() != $("input[name=prePpntUsableYn]:checked").val()){
+			return true;
+		}
+		//MOBILE포인트
+		if ($("#goodsDetailForm input[name=pntMrateOrg]").val() != $("#goodsDetailForm input[name=pntMrate]").val()){
+			return true;
+		}
+		//MOBILE 선포인트 사용여부
+		if ($("#goodsDetailForm input[name=preMpntUsableYnOrg]").val() != $("input[name=preMpntUsableYn]:checked").val()){
+			return true;
+		}
+		//최소주문수량
+		if ($("#goodsDetailForm input[name=minOrdQtyOrg]").val() != $("#goodsDetailForm input[name=minOrdQty]").val()){
+			return true;
+		}
+		//최대주문수량
+		if ($("#goodsDetailForm input[name=maxOrdQtyOrg]").val() != $("#goodsDetailForm input[name=maxOrdQty]").val()){
+			return true;
+		}
+		//무료배송기준
+		if ($("#goodsDetailForm input[name=minOrdAmtOrg]").val() != $("#goodsDetailForm input[name=minOrdAmt]").val().removeComma()){
+			return true;
+		}
+
+		return false;
+	}
+
+	// 상품 고시 선택 버튼 클릭 시
+	$('#btnNotinfo').click(function(e) {
+
+		if(gagajf.isNull($("#goodsDetailForm select[name=selNiClsfCd]").val())) {
+			mcxDialog.alertC("상품정보제공 고시를 선택해주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm select[name=selNiClsfCd]").focus();
+				}
+			});
+			return false;
+		}
+
+		// 고시정보 수정은 맘대로 할수 있음 20200821 신현장 부장 확인
+		/* if ($("#goodsDetailForm input[name=niClsfCd]").val() != $("#goodsDetailForm select[name=selNiClsfCd]").val()){
+			mcxDialog.alertC("상품의 고시분류는 [" + $("#goodsDetailForm input[name=niClsfNm]").val() +"] 입니다."  , {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsDetailForm select[name=selNiClsfCd]").focus();
+				}
+			});
+			return false;
+		} */
+
+		var params = new Object();
+		params.supplyCompCd = $("#goodsDetailForm input[name=supplyCompCd]").val();
+		params.niClsfCd = $("#goodsDetailForm select[name=selNiClsfCd]").val();
+		params.goodsCd = $("#goodsDetailForm input[name=goodsCd]").val();
+		cfnAjaxSubmit("/goods/noti/goodsInfo/list", "json", fnGoodsDetailNotiInfoSearchCallback, params);
+
+	});
+
+	// 품목변경
+	$("#btnGoodsItemkindChange").on("click", function(){
+
+		if($("#goodsDetailForm  select[name=itemkindCd]").val() == $("#goodsDetailForm  input[name=orgItemkindCd]").val()){
+			mcxDialog.alert("품목코드가 변경되지 않았습니다.");
+			return false;
+		}
+
+		mcxDialog.confirm('품목변경 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = [{  goodsCd : $('#goodsDetailForm input[name=goodsCd]').val()
+						, itemkindCd : $("#goodsDetailForm  select[name=itemkindCd]").val()
+						, supplyCompCd : $("#goodsDetailForm  input[name=supplyCompCd]").val()
+						}];
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/itemKind/change/save', jsonData, fnGoodsDeailSearch);
+			}
+		});
+	});
+	
+	var fnOpenGoodsDetailPopup = function() {
+		cfnOpenGoodsPopup('fnGoodsDetailGoodsDeal');
+	}
+
+	// 상품추가
+	var fnGoodsDetailGoodsDeal = function(goodsData) {
+		if (goodsData.length < 1) return;
+		
+		// 기존상품
+		var oldGoodsDealList = gagaAgGrid.getAllRowData(gridGoodsExtendOptions);
+		var idx = oldGoodsDealList.length+1; 
+		
+		var isExist = false;
+		goodsData.forEach(function(goods){
+			isExist = false;
+
+			gridGoodsExtendOptions.api.forEachNode(function(rowNode, index) {
+
+				if (goods.goodsCd == rowNode.data.extendGoodsCd){
+					isExist = true;
+				}
+			});
+			
+			if (goods.goodsType != 'N'){
+				isExist = true;
+			}
+			if(!isExist){
+				
+				var data = { 
+						  goodsCd : $('#goodsDetailForm input[name=goodsCd]').val()
+						, extendGoodsCd: goods.goodsCd
+						, goodsType: $('#goodsDetailForm input[name=goodsType]').val()
+						, dispOrd: idx
+						, qty: 1
+						, extendCurrPrice: goods.currPrice
+						, extendStaffCurrPrice: goods.currPrice
+						, baseYn: 'N'
+						, goodsStat : goods.goodsStat
+						, useYn: 'Y'
+						, extendGoodsOptNm : goods.goodsNm
+						, extendGoodsCdNm : goods.goodsNm
+						, currPrice : goods.currPrice
+						, selfGoodsYn : goods.selfGoodsYn
+						, imgType : goods.imgType
+						, imgPath1 : goods.imgPath1
+						, imgPath6 : goods.imgPath6
+						};
+				gridGoodsExtendOptions.api.updateRowData({add: [data], addIndex: idx});
+				
+				idx++;
+			
+			}
+		});
+		gridGoodsExtendOptions.api.refreshCells();
+	}
+
+	//엑셀 상품 조회
+	$('#btnGoodsDealSearchExcel').on('click', function() {
+		cfnExcelUploadPopup('goodsDetailExcelUpload', 'goodsDetailExcelUpload');
+	});
+
+	var goodsDetailExcelUpload = function(result){
+		var data = {procJob : result.procJob
+			,excelFileNm : result.excelFileNm
+		};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, goodsDetailExcelUploadCallBack);
+	}
+
+	var goodsDetailExcelUploadCallBack = function(result){
+		gagajf.ajaxJsonSubmit('/goods/excel/upload/goods/list', '', fnGoodsDetailSearchExcel);
+	}
+	
+	var fnGoodsDetailSearchExcel = function(result){
+		fnGoodsDetailGoodsDeal(result.goodsExcelList);
+	}
+		
+	$("img").on("error", function () {
+		$(this).attr("src",  _uximgUrl+"/image/no.gif");
+	});
+	
+	$(document).ready(function() {
+
+		/* gagaSe.createSmartEditor(seOptions, 'goodsDesc'); */
+		gagaSe.createSmartEditor(seOptions, 'goodsPcTopDesc');
+		gagaSe.createSmartEditor(seOptions, 'goodsMobileTopDesc');
+		gagaSe.createSmartEditor(seOptions, 'goodsPcDownDesc');
+		gagaSe.createSmartEditor(seOptions, 'goodsMobileDownDesc');
+
+		gagaAgGrid.createGrid('gridGoodsHstoryList', gridGoodsHstoryOptions);
+		gagaAgGrid.createGrid('gridGoodsExtendList', gridGoodsExtendOptions);
+
+		fnGoodsDeailSearch();
+
+		//기본정보탭 변경여부
+		$('#goodsDetailForm').find('#goodstab1').find("input, select, textarea").on('change', function() {
+			$('#goodsDetailForm').find('.tabs .tabsNav li:eq(0) a').attr("style", "color:red;");
+		});
+
+	});
+	
+/*]]>*/
+</script>
+</html>

+ 9 - 7
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsListForm.html

@@ -58,7 +58,7 @@
 							</select>
 							<span id="multiBrand"></span>
 						</td>
-						<th>상품구분</th>
+						<th>상품타입</th>
 						<td>
 							<select name="goodsType" id="goodsType">
 								<option value="">[전체]</option>
@@ -234,6 +234,8 @@
 					<li class="center">
 						<div class="tablePaging" id="goodsListPagination"></div>
 					</li>
+				</ul>
+				<ul class="panelBar">
 					<li class="right">
 						<button type="button" class="btn btn-info btn-sm"  onclick="fnGoodsStatArea();" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">상태일괄적용</button>
 					</li>
@@ -352,15 +354,15 @@
 		},
 		{headerName: "이미지", field: "imgPath1", width: 100, height: 60, cellClass: 'text-center'
 			,cellRenderer: function(params) {
-				if (params.data.imgType != "B"){
-					return '<img width="60" src="'+ params.value + '" alt="" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \''+ params.value +'\')"/>';
-				}else{
+				if (params.data.imgType == "G030_A"){
 					if (gagajf.isNull(params.value)) {
-						
 						return '<img width="60" src="'+ params.data.imgPath6 + '" alt="" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \''+ params.data.imgPath6 +'\')"/>';
 					} else {
 						return '<img width="60" src="'+ params.value + '" alt="" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \''+ params.value +'\')"/>';
 					}
+					
+				}else{
+					return '<img width="60" src="'+ params.value + '" alt="" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \''+ params.value +'\')"/>';
 				}
 			}
 		},
@@ -454,7 +456,7 @@
 	}
 
 	gridOptions.getRowStyle = function(params) {
-		if ("00" == params.data.goodsStat  || "10" == params.data.goodsStat || "20" == params.data.goodsStat || "30" == params.data.goodsStat) {
+		if ("G008_00" == params.data.goodsStat  || "G008_10" == params.data.goodsStat || "G008_20" == params.data.goodsStat || "G008_30" == params.data.goodsStat) {
 			return { background: '#23c6c8' };
 		}
 	}
@@ -633,7 +635,7 @@
 					,excelFileNm : result.excelFileNm
 					};
 		var jsonData = JSON.stringify(data);
-		gagajf.ajaxJsonSubmit('/goods/search/goodslist/excelupload/save', jsonData, fnGoodsExcelUploadCallBack);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnGoodsExcelUploadCallBack);
 	}
 
 	var fnGoodsExcelUploadCallBack = function(result){

+ 15 - 4
style24.admin/src/main/webapp/WEB-INF/views/goods/NotiinfoForm.html

@@ -41,7 +41,7 @@
 				<li class="boxContentTop">
 					<table class="w100p">
 						<colgroup>
-							<col style="width:40%;"/>
+							<col style="width:39%;"/>
 							<col style="width:2%;"/>
 							<col/>
 							<col style="width:10%;"/>
@@ -81,7 +81,7 @@
 				return '<a href="javascript:void(0);">' + params.value + '</a>';
 			}	
 		},
-		{headerName: "상품 정보고시명", field: "niClsfNm", width: 450, cellClass: 'text-center',editable: true,
+		{headerName: "상품 정보고시명", field: "niClsfNm", width: 440, cellClass: 'text-center',editable: true,
 			editable : function(params){return params.data.crud=='C' ? true : false;}
 		},
 		{headerName: "등록일자", field: "regDt" , width: 150, cellClass: 'text-center', hide: true},
@@ -98,11 +98,22 @@
 			valueFormatter: function (params) { return gagaAgGrid.lookupValue(niItemCdList, params.value); },
 			valueParser: function (params) { return gagaAgGrid.lookupKey(niItemCdList, params.newValue); }
 		},
-		
-		{headerName: "내용", field: "niContent" , width: 550, cellClass: 'text-left' ,editable: true,
+		{headerName: "내용", field: "niContent" , width: 350, cellClass: 'text-left' ,editable: true,
 			cellEditor: 'textCellEditor',
 			cellEditorParams: { maxlength: 500, required: true }
 		},
+		{headerName: "필수여부", field: "reqYn" , width: 110, cellClass: 'text-center',editable: false,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), required: true },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
+		{headerName: "노출여부", field: "dispYn" , width: 110, cellClass: 'text-center',editable: true,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), required: true },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
 		{headerName: "노출순서", field: "dispOrd" , width: 110, cellClass: 'text-center',editable: true,
 			cellEditor: 'textCellEditor',
 			cellEditorParams: { maxlength: 3, validType: 'integer', required: true }

+ 480 - 0
style24.admin/src/main/webapp/smartEditor/SEditorSkin.html

@@ -0,0 +1,480 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Smart Editor&#8482;</title>
+<link href="/smartEditor/css/default.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="/smartEditor/js/jindo.min.js" charset="utf-8"></script>
+<script type="text/javascript" src="/smartEditor/js/Husky.SE_Basic.js" charset="utf-8"></script>
+<script type="text/javascript" src="/smartEditor/js/SE_CustomPlugins.js" charset="utf-8"></script>
+</head>
+<body>
+<div id="smart_editor" class="smart_editor">
+	<div id="smart_content"> <a href="#husky_iframe" class="skip">&raquo; 편집 도구모음 건너뛰기</a>
+		<div class="tool">
+			<ul class="type">
+				<li class="husky_seditor_ui_fontName">
+					<select class="husky_seditor_ui_fontName_select">
+						<option value="">글꼴</option>
+						<option value="dotum" style="font-family:Dotum">돋움</option>
+						<option value="gulim" style="font-family:Gulim">굴림</option>
+						<option value="batang" style="font-family:Batang">바탕</option>
+						<option value="arial" style="font-family:Arial">Arial</option>
+						<option value="arial black" style="font-family:'Arial Black'">Arial Black</option>
+						<option value="tahoma" style="font-family:Tahoma">Tahoma</option>
+						<option value="verdana" style="font-family:Verdana">Verdana</option>
+						<option value="sans-serif" style="font-family:Sans-serif">Sans-serif</option>
+						<option value="serif" style="font-family:Serif">Serif</option>
+						<option value="monospace" style="font-family:Monospace">Monospace</option>
+						<option value="cursive" style="font-family:Cursive">Cursive</option>
+						<option value="fantasy" style="font-family:Fantasy">Fantasy</option>
+					</select>
+				</li>
+				<li class="husky_seditor_ui_fontSize">
+					<select class="husky_seditor_ui_fontSize_select">
+						<option value="">크기</option>
+						<option value="9px" style="font-size:9px">9px</option>
+						<option value="10px" style="font-size:10px">10px</option>
+						<option value="11px" style="font-size:11px">11px</option>
+						<option value="12px" style="font-size:12px">12px</option>
+						<option value="13px" style="font-size:13px">13px</option>
+						<option value="14px" style="font-size:14px">14px</option>
+						<option value="16px" style="font-size:16px">16px</option>
+						<option value="18px" style="font-size:18px">18px</option>
+						<option value="24px" style="font-size:24px">24px</option>
+						<option value="32px" style="font-size:32px">32px</option>
+					</select>
+				</li>
+				<li class="husky_seditor_ui_lineHeight">
+					<select class="husky_seditor_ui_lineHeight_select">
+						<option value="">줄간격</option>
+						<option value="1">100%</option>
+						<option value="1.2">120%</option>
+						<option value="1.4">140%</option>
+						<option value="1.6">160%</option>
+						<option value="1.8">180%</option>
+						<option value="2">200%</option>
+					</select>
+				</li>
+			</ul>
+			<ul class="style">
+				<li class="bold husky_seditor_ui_bold">
+					<button type="button" title="굵은글꼴[Ctrl+B]"><span>굵은글꼴</span></button>
+				</li>
+				<li class="underline husky_seditor_ui_underline">
+					<button type="button" title="밑줄[Ctrl+U]"><span>밑줄</span></button>
+				</li>
+				<li class="italic husky_seditor_ui_italic">
+					<button type="button" title="기울임글꼴[Ctrl+I]"><span>기울임글꼴</span></button>
+				</li>
+				<li class="del husky_seditor_ui_lineThrough">
+					<button type="button" title="취소선[Ctrl+D]"><span>취소선</span></button>
+				</li>
+				<li class="fcolor husky_seditor_ui_fontColor">
+					<button type="button" title="글자색"><span>글자색</span></button>
+					<!-- 팔레트 레이어 -->
+					<div class="layer husky_seditor_fontcolor_layer" style="display:none;">
+						<ul class="palette husky_seditor_color_palette">
+							<li><button type="button" title="#ff0000" style="background:#ff0000"><span>#ff0000</span></button></li>
+							<li><button type="button" title="#ff6c00" style="background:#ff6c00"><span>#ff6c00</span></button></li>
+							<li><button type="button" title="#ffaa00" style="background:#ffaa00"><span>#ffaa00</span></button></li>
+							<li><button type="button" title="#ffef00" style="background:#ffef00"><span>#ffef00</span></button></li>
+							<li><button type="button" title="#a6cf00" style="background:#a6cf00"><span>#a6cf00</span></button></li>
+							<li><button type="button" title="#009e25" style="background:#009e25"><span>#009e25</span></button></li>
+							<li><button type="button" title="#00b0a2" style="background:#00b0a2"><span>#00b0a2</span></button></li>
+							<li><button type="button" title="#0075c8" style="background:#0075c8"><span>#0075c8</span></button></li>
+							<li><button type="button" title="#3a32c3" style="background:#3a32c3"><span>#3a32c3</span></button></li>
+							<li><button type="button" title="#7820b9" style="background:#7820b9"><span>#7820b9</span></button></li>
+							<li><button type="button" title="#ef007c" style="background:#ef007c"><span>#ef007c</span></button></li>
+							<li><button type="button" title="#000000" style="background:#000000"><span>#000000</span></button></li>
+							<li><button type="button" title="#252525" style="background:#252525"><span>#252525</span></button></li>
+							<li><button type="button" title="#464646" style="background:#464646"><span>#464646</span></button></li>
+							<li><button type="button" title="#636363" style="background:#636363"><span>#636363</span></button></li>
+							<li><button type="button" title="#7d7d7d" style="background:#7d7d7d"><span>#7d7d7d</span></button></li>
+							<li><button type="button" title="#9a9a9a" style="background:#9a9a9a"><span>#9a9a9a</span></button></li>
+							<li><button type="button" title="#ffe8e8" style="background:#ffe8e8"><span>#ffe8e8</span></button></li>
+							<li><button type="button" title="#f7e2d2" style="background:#f7e2d2"><span>#f7e2d2</span></button></li>
+							<li><button type="button" title="#f5eddc" style="background:#f5eddc"><span>#f5eddc</span></button></li>
+							<li><button type="button" title="#f5f4e0" style="background:#f5f4e0"><span>#f5f4e0</span></button></li>
+							<li><button type="button" title="#edf2c2" style="background:#edf2c2"><span>#edf2c2</span></button></li>
+							<li><button type="button" title="#def7e5" style="background:#def7e5"><span>#def7e5</span></button></li>
+							<li><button type="button" title="#d9eeec" style="background:#d9eeec"><span>#d9eeec</span></button></li>
+							<li><button type="button" title="#c9e0f0" style="background:#c9e0f0"><span>#c9e0f0</span></button></li>
+							<li><button type="button" title="#d6d4eb" style="background:#d6d4eb"><span>#d6d4eb</span></button></li>
+							<li><button type="button" title="#e7dbed" style="background:#e7dbed"><span>#e7dbed</span></button></li>
+							<li><button type="button" title="#f1e2ea" style="background:#f1e2ea"><span>#f1e2ea</span></button></li>
+							<li><button type="button" title="#acacac" style="background:#acacac"><span>#acacac</span></button></li>
+							<li><button type="button" title="#c2c2c2" style="background:#c2c2c2"><span>#c2c2c2</span></button></li>
+							<li><button type="button" title="#cccccc" style="background:#cccccc"><span>#cccccc</span></button></li>
+							<li><button type="button" title="#e1e1e1" style="background:#e1e1e1"><span>#e1e1e1</span></button></li>
+							<li><button type="button" title="#ebebeb" style="background:#ebebeb"><span>#ebebeb</span></button></li>
+							<li><button type="button" title="#ffffff" style="background:#ffffff"><span>#ffffff</span></button></li>
+							<li><button type="button" title="#e97d81" style="background:#e97d81"><span>#e97d81</span></button></li>
+							<li><button type="button" title="#e19b73" style="background:#e19b73"><span>#e19b73</span></button></li>
+							<li><button type="button" title="#d1b274" style="background:#d1b274"><span>#d1b274</span></button></li>
+							<li><button type="button" title="#cfcca2" style="background:#cfcca2"><span>#cfcca2</span></button></li>
+							<li><button type="button" title="#cfcca2" style="background:#cfcca2"><span>#cfcca2</span></button></li>
+							<li><button type="button" title="#61b977" style="background:#61b977"><span>#61b977</span></button></li>
+							<li><button type="button" title="#53aea8" style="background:#53aea8"><span>#53aea8</span></button></li>
+							<li><button type="button" title="#518fbb" style="background:#518fbb"><span>#518fbb</span></button></li>
+							<li><button type="button" title="#6a65bb" style="background:#6a65bb"><span>#6a65bb</span></button></li>
+							<li><button type="button" title="#9a54ce" style="background:#9a54ce"><span>#9a54ce</span></button></li>
+							<li><button type="button" title="#e573ae" style="background:#e573ae"><span>#e573ae</span></button></li>
+							<li><button type="button" title="#5a504b" style="background:#5a504b"><span>#5a504b</span></button></li>
+							<li><button type="button" title="#767b86" style="background:#767b86"><span>#767b86</span></button></li>
+							<li><button type="button" title="#00ffff" style="background:#00ffff"><span>#00ffff</span></button></li>
+							<li><button type="button" title="#00ff00" style="background:#00ff00"><span>#00ff00</span></button></li>
+							<li><button type="button" title="#a0f000" style="background:#a0f000"><span>#a0f000</span></button></li>
+							<li><button type="button" title="#ffff00" style="background:#ffff00"><span>#ffff00</span></button></li>
+							<li><button type="button" title="#951015" style="background:#951015"><span>#951015</span></button></li>
+							<li><button type="button" title="#6e391a" style="background:#6e391a"><span>#6e391a</span></button></li>
+							<li><button type="button" title="#785c25" style="background:#785c25"><span>#785c25</span></button></li>
+							<li><button type="button" title="#5f5b25" style="background:#5f5b25"><span>#5f5b25</span></button></li>
+							<li><button type="button" title="#4c511f" style="background:#4c511f"><span>#4c511f</span></button></li>
+							<li><button type="button" title="#1c4827" style="background:#1c4827"><span>#1c4827</span></button></li>
+							<li><button type="button" title="#0d514c" style="background:#0d514c"><span>#0d514c</span></button></li>
+							<li><button type="button" title="#1b496a" style="background:#1b496a"><span>#1b496a</span></button></li>
+							<li><button type="button" title="#2b285f" style="background:#2b285f"><span>#2b285f</span></button></li>
+							<li><button type="button" title="#45245b" style="background:#45245b"><span>#45245b</span></button></li>
+							<li><button type="button" title="#721947" style="background:#721947"><span>#721947</span></button></li>
+							<li><button type="button" title="#352e2c" style="background:#352e2c"><span>#352e2c</span></button></li>
+							<li><button type="button" title="#3c3f45" style="background:#3c3f45"><span>#3c3f45</span></button></li>
+							<li><button type="button" title="#00aaff" style="background:#00aaff"><span>#00aaff</span></button></li>
+							<li><button type="button" title="#0000ff" style="background:#0000ff"><span>#0000ff</span></button></li>
+							<li><button type="button" title="#a800ff" style="background:#a800ff"><span>#a800ff</span></button></li>
+							<li><button type="button" title="#ff00ff" style="background:#ff00ff"><span>#ff00ff</span></button></li>
+						</ul>
+					</div>
+					<!-- /팔레트 레이어 -->
+				</li>
+				<li class="bcolor husky_seditor_ui_bgColor">
+					<button type="button" title="배경색"><span>배경색</span></button>
+					<!-- 배경색 + 팔레트 레이어 -->
+					<div class="layer husky_seditor_bgcolor_layer" style="display:none;">
+						<ul class="background">
+							<li><button type="button" title="#000000" style="background:#000000; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#9334d8" style="background:#9334d8; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#ff0000" style="background:#ff0000; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#333333" style="background:#333333; color:#ffff00"><span>가나다</span></button></li>
+							<li><button type="button" title="#0000ff" style="background:#0000ff; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#ff6600" style="background:#ff6600; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#8e8e8e" style="background:#8e8e8e; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#009999" style="background:#009999; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#ffa700" style="background:#ffa700; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#ffdaed" style="background:#ffdaed; color:#000000"><span>가나다</span></button></li>
+							<li><button type="button" title="#e4ff75" style="background:#e4ff75; color:#000000"><span>가나다</span></button></li>
+							<li><button type="button" title="#cc9900" style="background:#cc9900; color:#ffffff"><span>가나다</span></button></li>
+							<li><button type="button" title="#99dcff" style="background:#99dcff; color:#000000"><span>가나다</span></button></li>
+							<li><button type="button" title="#a6ff4d" style="background:#a6ff4d; color:#000000"><span>가나다</span></button></li>
+							<li><button type="button" title="#ffffff" style="background:#ffffff; color:#000000"><span>가나다</span></button></li>
+						</ul>
+					</div>
+					<!-- /배경색 + 팔레트 레이어 -->
+				</li>
+				<li class="sup husky_seditor_ui_superscript">
+					<button type="button" title="윗첨자"><span>윗첨자</span></button>
+				</li>
+				<li class="sub husky_seditor_ui_subscript">
+					<button type="button" title="아래첨자"><span>아래첨자</span></button>
+				</li>
+			</ul>
+			<ul class="paragraph">
+				<li class="left husky_seditor_ui_justifyleft">
+					<button type="button" title="왼쪽정렬"><span>왼쪽정렬</span></button>
+				</li>
+				<li class="center husky_seditor_ui_justifycenter">
+					<button type="button" title="가운데정렬"><span>가운데정렬</span></button>
+				</li>
+				<li class="right husky_seditor_ui_justifyright">
+					<button type="button" title="오른쪽정렬"><span>오른쪽정렬</span></button>
+				</li>
+				<li class="justify husky_seditor_ui_justifyfull">
+					<button type="button" title="양쪽정렬"><span>양쪽정렬</span></button>
+				</li>
+				<li class="ol husky_seditor_ui_orderedlist">
+					<button type="button" title="순차목록"><span>순차목록</span></button>
+				</li>
+				<li class="ul husky_seditor_ui_unorderedlist">
+					<button type="button" title="비순차목록"><span>비순차목록</span></button>
+				</li>
+				<li class="outdent husky_seditor_ui_outdent">
+					<button type="button" title="내어쓰기[Shift+Tab]"><span>내어쓰기</span></button>
+				</li>
+				<li class="indent husky_seditor_ui_indent">
+					<button type="button" title="들여쓰기[Tab]"><span>들여쓰기</span></button>
+				</li>
+			</ul>
+			<ul class="extra">
+				<li class="blockquote husky_seditor_ui_quote" style="display:none;">
+					<button type="button" title="인용"><span>인용</span></button>
+					<!-- 인용 레이어 -->
+					<div class="layer husky_seditor_blockquote_layer" style="display:none">
+						<ul>
+							<li class="q1"><button type="button"><span>왼쪽 실선</span></button></li>
+							<li class="q2"><button type="button"><span>인용 부호</span></button></li>
+							<li class="q3"><button type="button"><span>실선</span></button></li>
+							<li class="q4"><button type="button"><span>실선 + 배경</span></button></li>
+							<li class="q5"><button type="button"><span>굵은 실선</span></button></li>
+							<li class="q6"><button type="button"><span>점선</span></button></li>
+							<li class="q7"><button type="button"><span>점선 + 배경</span></button></li>
+							<li class="q8"><button type="button"><span>적용 취소</span></button></li>
+						</ul>
+					</div>
+					<!-- /인용 레이어 -->
+				</li>
+				<li class="url husky_seditor_ui_hyperlink">
+					<button type="button" title="링크"><span>URL</span></button>
+					<!-- URL 레이어 -->
+					<div class="layer husky_seditor_hyperlink_layer" style="display:none;">
+						<fieldset>
+							<h3>하이퍼링크</h3>
+							<input name="" class="link" type="text" value="http://" title="URL" />
+							<p><input name="" id="target" type="checkbox" value="" /><label for="target">새창으로</label></p>
+						</fieldset>
+						<div class="btn_area">
+							<button type="button" class="confirm" title="확인"><span>확인</span></button>
+							<button type="button" class="cancel" title="취소"><span>취소</span></button>
+
+						</div>
+
+					</div>
+					<!-- /URL 레이어 -->
+				</li>
+				<li class="table husky_seditor_ui_table" >
+					<button type="button" title="표"><span>표</span></button>
+					<!-- 표 레이어 -->
+					<div class="layer husky_seditor_table_layer" style="display:none;">
+						<fieldset class="num">
+							<h3>칸 수 지정</h3>
+							<dl>
+								<dt>
+									<label for="row">행</label>
+								</dt>
+								<dd>
+									<input id="row" name="" type="text" maxlength="2" value="4" />
+									<button type="button" class="add"><span>1행추가</span></button>
+									<button type="button" class="del"><span>1행삭제</span></button>
+								</dd>
+								<dt>
+									<label for="col">열</label>
+								</dt>
+								<dd>
+									<input id="col" name="" type="text" maxlength="2" value="4" />
+									<button type="button" class="add"><span>1행추가</span></button>
+									<button type="button" class="del"><span>1행삭제</span></button>
+								</dd>
+							</dl>
+							<table border="1">
+								<tr>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+								</tr>
+								<tr>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+								</tr>
+								<tr>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+								</tr>
+								<tr>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+									<td>&nbsp;</td>
+								</tr>
+							</table>
+						</fieldset>
+						<fieldset class="color">
+							<h3>표 속성 지정</h3>
+							<dl>
+								<dt>
+									<label for="table_border_width">테두리 굵기</label>
+								</dt>
+								<dd>
+									<input id="table_border_width" name="" type="text" maxlength="2" value="1" />
+									<button type="button" class="add"><span>1px 더하기</span></button>
+									<button type="button" class="del"><span>1px 빼기</span></button>
+								</dd>
+								<dt>
+									<label for="table_border_color">테두리 색</label>
+								</dt>
+								<dd>
+									<span class="preview_palette"><button type="button" style="background:#cccccc;">색상찾기</button></span>
+									<input id="table_border_color" name="" type="text" maxlength="7" value="#CCCCCC" />
+									<button type="button" class="find_palette"><span>색상찾기</span></button>
+								</dd>
+								<dt>
+									<label for="table_bg_color">표 배경색</label>
+								</dt>
+								<dd>
+									<span class="preview_palette"><button type="button" style="background:#000000;">색상찾기</button></span>
+									<input id="table_bg_color" name="" type="text" maxlength="7" value="#000000" />
+									<button type="button" class="find_palette"><span>색상찾기</span></button>
+								</dd>
+							</dl>
+						</fieldset>
+						<div class="btn_area">
+							<button type="button" class="confirm" title="확인"><span>확인</span></button>
+							<button type="button" class="cancel" title="취소"><span>취소</span></button>
+						</div>
+					</div>
+					<!-- /표 레이어 -->
+				</li>
+				<li class="character husky_seditor_ui_sCharacter">
+					<button type="button" title="특수문자"><span>특수문자</span></button>
+					<!-- 특수문자 레이어 -->
+					<div class="layer husky_seditor_sCharacter_layer" style="display:none">
+						<h3>특수문자 삽입</h3>
+						<button type="button" class="close" title="특수문자 레이어 닫기"><span>특수문자 레이어 닫기</span></button>
+						<ul class="nav">
+							<li><a href="#character1" class="on">일반기호</a></li>
+							<li><a href="#character2">숫자와 단위</a></li>
+							<li><a href="#character3">원,괄호</a></li>
+							<li><a href="#character4">한글</a></li>
+							<li><a href="#character5">그리스,라틴어</a></li>
+							<li><a href="#character6">일본어</a></li>
+						</ul>
+						<ul style="display: block;" id="character1" class="list"></ul>
+						<ul style="display: none;" id="character2" class="list"></ul>
+						<ul style="display: none;" id="character3" class="list"></ul>
+						<ul style="display: none;" id="character4" class="list"></ul>
+						<ul style="display: none;" id="character5" class="list"></ul>
+						<ul style="display: none;" id="character6" class="list"></ul>
+						<p>
+							<label for="preview">선택한 기호</label>
+							<input id="preview" name="" type="text" />
+							<button type="button" title="확인"><span>확인</span></button>
+						</p>
+						<button type="button" class="close" title="특수문자 레이어 닫기"><span>특수문자 레이어 닫기</span></button>
+					</div>
+					<!-- /특수문자 레이어 -->
+				</li>
+				<li class="find husky_seditor_ui_findAndReplace" >
+					<button type="button" title="찾기"><span>찾기</span></button>
+					<!-- 찾기 바꾸기 레이어 -->
+					<div class="layer find husky_seditor_findAndReplace_layer" style="display:none">
+					<!-- class="layer find" | class="layer replace"-->
+						<h3>찾기/바꾸기</h3>
+						<button type="button" class="close" title="찾기/바꾸기 레이어 닫기"><span>찾기/바꾸기 레이어 닫기</span></button>
+						<div class="menu_tab">
+							<ul class="layer_tab">
+								<li class="tab1"><a href="#find" onclick="return false">찾기</a></li>
+								<li class="tab2"><a href="#replace" onclick="return false">바꾸기</a></li>
+							</ul>
+						</div>
+						<div class="container">
+							<div class="bx" id="find">
+								<fieldset>
+									<label for="keyword1">찾을단어</label>
+									<input id="keyword1" name="" type="text" />
+								</fieldset>
+								<span class="cap"></span> </div>
+							<div class="bx" id="replace">
+								<fieldset>
+									<label for="keyword2">찾을단어</label>
+									<input id="keyword2" name="" type="text" />
+									<br />
+									<label for="keyword3">바꿀단어</label>
+									<input id="keyword3" name="" type="text" />
+								</fieldset>
+							</div>
+						</div>
+						<div class="btn_area">
+							<button type="button" class="find_next" title="다음찾기"><span>다음찾기</span></button>
+							<button type="button" class="replace" title="바꾸기"><span>바꾸기</span></button>
+							<button type="button" class="replace_all" title="모두바꾸기"><span>모두바꾸기</span></button>
+							<button type="button" class="cancel" title="취소"><span>취소</span></button>
+						</div>
+						<button type="button" class="close" title="찾기/바꾸기 레이어 닫기"><span>찾기/바꾸기 레이어 닫기</span></button>
+					</div>
+					<!-- /찾기 바꾸기 레이어 -->
+				</li>
+			</ul>
+			<ul class="img_tool" >
+				<li class="img_ins husky_seditor_ui_ImgInsert">
+					<button type="button" title="그림 삽입" ><span>그림 삽입</span></button>
+					<div class="layer husky_seditor_ImgInsert_layer" style="display:none">
+						<h3>그림 삽입</h3>
+						<button type="button" class="close" title="그림 삽입 닫기"><span>그림 삽입 닫기</span></button>
+						<div class="container">
+							<div class="bx">
+								<fieldset>
+									<label for="img_url">경로</label>
+									<input id="img_url" name="img_url" type="text" value="" />
+									<br />
+									<label for="img_alt">설명</label>
+									<input id="img_alt" name="img_alt" type="text" value="" />
+								</fieldset>
+							</div>
+						</div>
+						<div class="btn_area">
+							<button type="button" class="confirm" title="확인"><span>확인</span></button>
+							<form style="display:inline;margin:0;padding:0;"><span id="spanButtonPlaceholder"></span></form>
+							<button type="button" class="cancel" title="취소"><span>취소</span></button>
+						</div>
+					</div>
+				</li>
+			</ul>
+			<button type="button" class="html husky_seditor_mode_toggle_button" title="HTML 편집기" style="width:45px"><span>HTML</span></button>
+		</div>
+		<hr />
+		<!-- 입력 -->
+		<div class="input_area husky_seditor_editing_area_container" style="min-height:400px;">
+			<iframe src="/smartEditor/se_blank.html" id="husky_iframe" name="husky_iframe" class="input_wysiwyg" frameborder="0" scrolling="yes" title="리치 에디터 - 편집기에서 빠져 나오시려면 ESC키를 누르세요" style="display:block;min-width:1078px;min-height:400px;"></iframe>
+			<textarea name="" rows="10" cols="20" title="HTML 편집 모드" class="input_syntax" style="display:none;">&lt;p&gt;&lt;/p&gt;</textarea>
+			<textarea name="" cols="" rows="" class="blind" title="데이터 전송을 위한 숨은 콘트롤" style="display:none;"></textarea>
+		</div>
+		<button type="button" class="input_control husky_seditor_editingArea_verticalResizer" title="입력창 크기 조절"><span>입력창 크기 조절</span></button>
+	</div>
+</div>
+
+<script type="text/javascript">
+//<![CDATA[
+function paste(url) {
+	$("img_url").value = url;
+}
+//]]>
+</script>
+<script type="text/javascript" src="/smartEditor/swfupload/js/swfupload.js" charset="utf-8"></script>
+<script type="text/javascript" src="/smartEditor/swfupload/js/handlers.js" charset="utf-8"></script>
+<script type="text/javascript">
+//<![CDATA[
+	var swfu;
+	window.onload = function() {
+		var settings = {
+			flash_url : "/smartEditor/swfupload/swf/swfupload.swf",
+			upload_url: "/swfupload_proc.jsp",
+			file_post_name : "Filedata",
+			file_size_limit : "5 MB",
+			file_types : "*.jpg;*.gif;*.jpeg;*.png;*.bmp",
+			file_types_description : "Web Image Files",
+			file_upload_limit : 0,
+			file_queue_limit : 1,
+			debug: false,
+
+			file_queue_error_handler : fileQueueError,
+			file_dialog_complete_handler : fileDialogComplete,
+			upload_error_handler : uploadError,
+			upload_success_handler : uploadSuccess,
+
+			button_image_url : "/smartEditor/swfupload/img/my_img.gif",
+			button_placeholder_id : "spanButtonPlaceholder",
+			button_width: 53,
+			button_height: 21,
+			button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
+			button_cursor: SWFUpload.CURSOR.HAND
+		};
+
+		swfu = new SWFUpload(settings);
+	};
+//]]>
+</script>
+</body>
+</html>

+ 334 - 0
style24.admin/src/main/webapp/smartEditor/css/default.css

@@ -0,0 +1,334 @@
+@charset "utf-8";
+/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) 200812 */
+
+/* Type Selector */
+#smart_editor *{margin:0; padding:0; font-style:normal; font-size:12px; font-family: Dotum, Gulim, AppleGothic, Sans-serif;}
+#smart_editor img,
+#smart_editor fieldset,
+#smart_editor button{ border:0;}
+#smart_editor button{ background:none; background-repeat:no-repeat; cursor:pointer; _cursor /**/:hand;}
+#smart_editor button *{ visibility:hidden;}
+#smart_editor legend{ position:absolute; width:0; height:0; font-size:0; line-height:0; overflow:hidden; visibility:hidden;}
+#smart_editor label{ cursor:pointer; _cursor /**/:hand;}
+#smart_editor hr{ display:none;}
+#smart_editor li{list-style:none;}
+
+/* Layout Selector */
+#smart_editor{ position:relative; background:#fff;}
+#smart_editor #smart_content{ position:relative; clear:both; margin:0 0 10px 0; border:1px solid #c2c2c2; *zoom:1;}
+#smart_editor #smart_footer{ position:relative; text-align:center; padding:10px 0;}
+
+/* Footer */
+#smart_editor #smart_footer *{ vertical-align:top;}
+#smart_editor #smart_footer button{ position:relative; width:67px; height:25px; margin:0 5px 0 0;}
+#smart_editor #smart_footer button.save_temp{ background:url(../img/btn_save_temp.gif) no-repeat;}
+#smart_editor #smart_footer button.preview{ background:url(../img/btn_preview.gif) no-repeat;}
+#smart_editor #smart_footer input{ margin:0;}
+#smart_editor #smart_footer input.reset{ width:67px; height:25px; border:0; background:url(../img/btn_cancel.gif) no-repeat; cursor:pointer; margin-left:5px;}
+
+/* Content > Input Area */
+#smart_editor a.skip{ position:relative; display:block; top:0; right:0; width:0; height:0; overflow:hidden; clear:both; zoom:1}
+#smart_editor a.skip:hover,
+#smart_editor a.skip:active,
+#smart_editor a.skip:focus{ position:relative; display:block; padding:5px; right:0; z-index:60; width:auto; height:auto; text-align:right; white-space:nowrap; color:#000; text-decoration:none; letter-spacing:-1px; _zoom:1;}
+
+#smart_editor .input_area{ position:relative; margin:10px; z-index:30; *zoom:1; height:400px;}
+#smart_editor .input_area iframe,
+#smart_editor .input_area textarea{ display:block; width:100%; position:relative; height:100%; border:0; overflow:auto;}
+#smart_editor .input_area iframe{}
+#smart_editor .input_area textarea{ *margin:0 -10px; _margin-bottom:-2px;}
+#smart_editor .input_area textarea.blind{ display:none;}
+#smart_editor .input_control{ position:relative; display:block; width:100%; clear:both; text-align:center; background:#fbfbfb url(../img/btn_expand.gif) no-repeat center center; cursor:n-resize;}
+#smart_editor .input_control span{ display:block; height:10px; border-top:1px solid #dfdfdf; visibility:visible; font-size:0; line-height:200%; white-space:nowrap; color:#fff;}
+
+#smart_editor .tool{ position:relative; overflow:visible; padding:5px 0 6px 0; *padding:5px 0 8px 0; z-index:40; clear:both; background:#f8f8f8 url(../img/bg_tool.gif) repeat-x left bottom; border:0; *zoom:1;}
+#smart_editor .tool:after{ content:""; display:block; clear:both;}
+#smart_editor .tool ul{ position:relative; overflow:visible; float:left; margin:0 5px 2px 0; z-index:2;}
+#smart_editor .tool ul.action{ width:43px;}
+#smart_editor .tool ul.type{ width:auto; white-space:nowrap;}
+#smart_editor .tool ul.style{ width:169px; z-index:3;}
+#smart_editor .tool ul.paragraph{ width:169px; z-index:2;}
+#smart_editor .tool ul.extra{ width:91px; z-index:1;}
+#smart_editor .tool ul.img_tool{ width:19px; z-index:1;}/*image button add*/
+#smart_editor .tool li{ position:relative; float:left; left:4px;}
+#smart_editor .tool li button{ width:21px; height:21px; background:url(../img/btn_set.gif) no-repeat 0 0; vertical-align:top;}
+#smart_editor .tool li button span{ position:absolute; top:0; left:0; width:0; height:0; overflow:hidden; visibility:hidden;}
+
+#smart_editor .tool li.style button span{ position:relative; display:block; width:auto; height:auto; padding:3px 0 0 5px; visibility:visible; text-align:left; letter-spacing:-1px;}
+#smart_editor .tool .type li{ float:none; display:inline; *top:1px;}
+#smart_editor .tool .type li select{ height:21px; width:62px;}
+#smart_editor .tool .html{ position:relative; right:7px; float:right; width:44px; height:23px; margin:-1px 0; background:url(../img/btn_html.gif) no-repeat 0 0;}
+#smart_editor .tool .html span{ position:absolute; top:0; left:0; width:0; height:0; overflow:hidden; visibility:hidden;}
+
+/* Content > Tool > Button Default */
+#smart_editor .tool li.undo button{ width:22px; background-position:0 0;}
+#smart_editor .tool li.redo button{ background-position:-22px 0;}
+#smart_editor .tool li.bold button{ width:22px; background-position:-43px 0;}
+#smart_editor .tool li.underline button{ background-position:-65px 0;}
+#smart_editor .tool li.italic button{ background-position:-86px 0;}
+#smart_editor .tool li.del button{ background-position:-107px 0;}
+#smart_editor .tool li.fcolor button{ background-position:-128px 0;}
+#smart_editor .tool li.bcolor button{ background-position:-149px 0;}
+#smart_editor .tool li.sup button{ background-position:-170px 0;}
+#smart_editor .tool li.sub button{ background-position:-191px 0;}
+#smart_editor .tool li.left button{ width:22px; background-position:-212px 0;}
+#smart_editor .tool li.center button{ background-position:-234px 0;}
+#smart_editor .tool li.right button{ background-position:-255px 0;}
+#smart_editor .tool li.justify button{ background-position:-276px 0;}
+#smart_editor .tool li.ol button{ background-position:-297px 0;}
+#smart_editor .tool li.ul button{ background-position:-318px 0;}
+#smart_editor .tool li.outdent button{ background-position:-339px 0;}
+#smart_editor .tool li.indent button{ background-position:-360px 0;}
+#smart_editor .tool li.blockquote button{ width:22px; background-position:-381px 0;}
+#smart_editor .tool li.url button{ width:26px; background-position:-403px 0;}
+#smart_editor .tool li.table button{ background-position:-429px 0;}
+#smart_editor .tool li.character button{ background-position:-450px 0;}
+#smart_editor .tool li.find button{ background-position:-471px 0;}
+#smart_editor .tool li.img_ins button{ background-position:-492px 0;}/*image button add*/
+#smart_editor .tool .html{ background-position:0 0;}
+
+/* Content > Tool > Button Hover */
+#smart_editor .tool li.undo button.hover{ width:22px; background-position:0 -21px;}
+#smart_editor .tool li.redo button.hover{ background-position:-22px -21px;}
+#smart_editor .tool li.bold button.hover{ width:22px; background-position:-43px -21px;}
+#smart_editor .tool li.underline button.hover{ background-position:-65px -21px;}
+#smart_editor .tool li.italic button.hover{ background-position:-86px -21px;}
+#smart_editor .tool li.del button.hover{ background-position:-107px -21px;}
+#smart_editor .tool li.fcolor button.hover{ background-position:-128px -21px;}
+#smart_editor .tool li.bcolor button.hover{ background-position:-149px -21px;}
+#smart_editor .tool li.sup button.hover{ background-position:-170px -21px;}
+#smart_editor .tool li.sub button.hover{ background-position:-191px -21px;}
+#smart_editor .tool li.left button.hover{ width:22px; background-position:-212px -21px;}
+#smart_editor .tool li.center button.hover{ background-position:-234px -21px;}
+#smart_editor .tool li.right button.hover{ background-position:-255px -21px;}
+#smart_editor .tool li.justify button.hover{ background-position:-276px -21px;}
+#smart_editor .tool li.ol button.hover{ background-position:-297px -21px;}
+#smart_editor .tool li.ul button.hover{ background-position:-318px -21px;}
+#smart_editor .tool li.outdent button.hover{ background-position:-339px -21px;}
+#smart_editor .tool li.indent button.hover{ background-position:-360px -21px;}
+#smart_editor .tool li.blockquote button.hover{ width:22px; background-position:-381px -21px;}
+#smart_editor .tool li.url button.hover{ width:26px; background-position:-403px -21px;}
+#smart_editor .tool li.table button.hover{ background-position:-429px -21px;}
+#smart_editor .tool li.character button.hover{ background-position:-450px -21px;}
+#smart_editor .tool li.find button.hover{ background-position:-471px -21px;}
+#smart_editor .tool li.img_ins button.hover{ background-position:-492px -21px;}/*image button add*/
+#smart_editor .tool .html.hover{ background-position:0 -23px;}
+
+/* Content > Tool > Button Active */
+#smart_editor .tool li.undo button.active{ width:22px; background-position:0 -42px;}
+#smart_editor .tool li.redo button.active{ background-position:-22px -42px;}
+#smart_editor .tool li.bold button.active{ width:22px; background-position:-43px -42px;}
+#smart_editor .tool li.underline button.active{ background-position:-65px -42px;}
+#smart_editor .tool li.italic button.active{ background-position:-86px -42px;}
+#smart_editor .tool li.del button.active{ background-position:-107px -42px;}
+#smart_editor .tool li.fcolor button.active{ background-position:-128px -42px;}
+#smart_editor .tool li.bcolor button.active{ background-position:-149px -42px;}
+#smart_editor .tool li.sup button.active{ background-position:-170px -42px;}
+#smart_editor .tool li.sub button.active{ background-position:-191px -42px;}
+#smart_editor .tool li.left button.active{ width:22px; background-position:-212px -42px;}
+#smart_editor .tool li.center button.active{ background-position:-234px -42px;}
+#smart_editor .tool li.right button.active{ background-position:-255px -42px;}
+#smart_editor .tool li.justify button.active{ background-position:-276px -42px;}
+#smart_editor .tool li.ol button.active{ background-position:-297px -42px;}
+#smart_editor .tool li.ul button.active{ background-position:-318px -42px;}
+#smart_editor .tool li.outdent button.active{ background-position:-339px -42px;}
+#smart_editor .tool li.indent button.active{ background-position:-360px -42px;}
+#smart_editor .tool li.blockquote button.active{ width:22px; background-position:-381px -42px;}
+#smart_editor .tool li.url button.active{ width:26px; background-position:-403px -42px;}
+#smart_editor .tool li.table button.active{ background-position:-429px -42px;}
+#smart_editor .tool li.character button.active{ background-position:-450px -42px;}
+#smart_editor .tool li.find button.active{ background-position:-471px -42px;}
+#smart_editor .tool li.img_ins button.active{ background-position:-492px -42px;}/*image button add*/
+#smart_editor .tool .html.active{ background-position:0 -46px;}
+
+/* Content > Tool > Button Off */
+#smart_editor .tool.off li.undo button,
+#smart_editor .tool li.undo button.off{ width:22px; background-position:0 -63px;}
+#smart_editor .tool.off li.redo button,
+#smart_editor .tool li.redo button.off{ background-position:-22px -63px;}
+#smart_editor .tool.off li.bold button{ width:22px; background-position:-43px -63px;}
+#smart_editor .tool.off li.underline button{ background-position:-65px -63px;}
+#smart_editor .tool.off li.italic button{ background-position:-86px -63px;}
+#smart_editor .tool.off li.del button{ background-position:-107px -63px;}
+#smart_editor .tool.off li.fcolor button{ background-position:-128px -63px;}
+#smart_editor .tool.off li.bcolor button{ background-position:-149px -63px;}
+#smart_editor .tool.off li.sup button{ background-position:-170px -63px;}
+#smart_editor .tool.off li.sub button{ background-position:-191px -63px;}
+#smart_editor .tool.off li.left button{ width:22px; background-position:-212px -63px;}
+#smart_editor .tool.off li.center button{ background-position:-234px -63px;}
+#smart_editor .tool.off li.right button{ background-position:-255px -63px;}
+#smart_editor .tool.off li.justify button{ background-position:-276px -63px;}
+#smart_editor .tool.off li.ol button{ background-position:-297px -63px;}
+#smart_editor .tool.off li.ul button{ background-position:-318px -63px;}
+#smart_editor .tool.off li.outdent button{ background-position:-339px -63px;}
+#smart_editor .tool.off li.indent button{ background-position:-360px -63px;}
+#smart_editor .tool.off li.blockquote button{ width:22px; background-position:-381px -63px;}
+#smart_editor .tool.off li.url button{ width:26px; background-position:-403px -63px;}
+#smart_editor .tool.off li.table button{ background-position:-429px -63px;}
+#smart_editor .tool.off li.character button{ background-position:-450px -63px;}
+#smart_editor .tool.off li.find button{ background-position:-471px -63px;}
+#smart_editor .tool.off li.img_ins button{ background-position:-492px -63px;}/*image button add*/
+#smart_editor .tool.off li button{ cursor:default;}
+#smart_editor .tool.off .html{ background-position:0 -46px;}
+
+/* Content > Tool > Layer */
+#smart_editor .tool .layer{ display:none; position:absolute; left:0; top:20px; background-color:#fbfbfb; border:1px solid #c5c5c5; border-right:1px solid #9f9f9f; border-bottom:1px solid #9f9f9f;}
+#smart_editor .tool .layer li{ float:none; left:0;}
+#smart_editor .tool .layer button{ margin:0 !important; width:auto; height:auto; background:none;}
+#smart_editor .tool .layer button span{ position:absolute; width:0; height:0; font-size:0; line-height:0; overflow:hidden; visibility:hidden;}
+#smart_editor .tool .btn_area{ position:relative; clear:both; text-align:center !important; padding:7px 0 12px 0; width:100%; white-space:nowrap; *zoom:1;}
+#smart_editor .tool .btn_area *{ vertical-align:top;}
+#smart_editor .tool button.close{ position:absolute; top:4px; right:3px; width:21px; height:20px; background:url(../img/btn_layer_close.gif) no-repeat center center !important;}
+#smart_editor .tool button.close span{ position:absolute; width:0; height:0; overflow:hidden; visibility:hidden;}
+#smart_editor .tool .layer .btn_area button{ *margin:0 2px !important;}
+#smart_editor .tool .layer .btn_area button.confirm{ width:38px; height:21px; background:url(../img/btn_layer_confirm.gif) no-repeat;}
+#smart_editor .tool .layer .btn_area button.cancel{ width:38px; height:21px; background:url(../img/btn_layer_cancel.gif) no-repeat;}
+
+#smart_editor .tool li.fcolor .layer{ width:218px !important; height:auto !important; background-image:none !important; overflow:hidden;}
+#smart_editor .tool .layer .palette{ width:210px; position:relative; left:7px; padding:8px 0 7px 0; margin:0;}
+#smart_editor .tool .layer .palette li{ float:left; margin:0 1px 1px 0; font-size:0; line-height:0;}
+#smart_editor .tool .layer .palette button{ position:relative; overflow:hidden; width:11px; height:11px;}
+
+#smart_editor .tool li.bcolor .layer { width:218px; overflow:hidden;}
+#smart_editor .tool .layer .background{ width:210px; position:relative; left:7px; margin:0 0 -2px 0; padding:8px 0 0 0; *padding-bottom:8px; _padding-bottom:4px;}
+#smart_editor .tool .layer .background li{ float:left; margin:0 5px 2px 0;}
+#smart_editor .tool .layer .background button{ position:relative; overflow:hidden; width:65px; height:19px; text-align:left; padding:4px;}
+#smart_editor .tool .layer .background button span{ position:relative; visibility:visible; font-size:12px; line-height:normal; width:auto; height:auto;}
+
+#smart_editor .tool li.style .layer{ padding:4px 2px; _overflow:hidden; filter:progid:DXImageTransform.Microsoft.Shadow(color=#dddddd,direction=135,strength=2);}
+#smart_editor .tool li.style .layer li{ position:relative; background:#fbfbfb;}
+#smart_editor .tool li.style .layer li button{ display:block; width:134px; position:relative;}
+#smart_editor .tool li.style .layer li button span{ display:block; width:130px; text-align:left; letter-spacing:normal;}
+#smart_editor .tool li.style .layer li.h3 button span{ padding:3px 0 1px 4px; height:15px; _height /**/:19px; font-size:16px; font-weight:bold;}
+#smart_editor .tool li.style .layer li.h4 button span{ padding:3px 0 2px 4px; height:13px; _height /**/:18px; font-size:14px; font-weight:bold;}
+#smart_editor .tool li.style .layer li.h5 button span{ padding:3px 0 1px 4px; height:11px; _height /**/:15px; font-size:12px; font-weight:bold;}
+#smart_editor .tool li.style .layer li.h6 button span{ padding:3px 0 1px 4px; height:11px; _height /**/:15px; font-size:12px;}
+#smart_editor .tool li.style .layer li.p button span{ padding:3px 0 1px 4px; height:11px; _height /**/:15px; font-size:12px; color:#5d5d5d;}
+#smart_editor .tool li.style .layer li button.hover{ background:#c1f471; *height:1%;}
+
+#smart_editor .tool li.blockquote .layer{ padding:6px 5px 6px 7px; left:0; width:288px;}
+#smart_editor .tool li.blockquote .layer ul{ *zoom:1; margin:0;}
+#smart_editor .tool li.blockquote .layer ul:after{ content:""; display:block; clear:both;}
+#smart_editor .tool li.blockquote .layer li{ position:relative; float:left; overflow:hidden; width:32px; height:34px; margin:0 2px 0 0; border:1px solid #cdcecc; background-image:url(../img/btn_qmark.gif); background-repeat:no-repeat;}
+#smart_editor .tool li.blockquote .layer li.q1{ background-position:0 0;}
+#smart_editor .tool li.blockquote .layer li.q2{ background-position:-32px 0;}
+#smart_editor .tool li.blockquote .layer li.q3{ background-position:-64px 0;}
+#smart_editor .tool li.blockquote .layer li.q4{ background-position:-96px 0;}
+#smart_editor .tool li.blockquote .layer li.q5{ background-position:-128px 0;}
+#smart_editor .tool li.blockquote .layer li.q6{ background-position:-160px 0;}
+#smart_editor .tool li.blockquote .layer li.q7{ background-position:-192px 0;}
+#smart_editor .tool li.blockquote .layer li.q8{ background-position:-224px 0;}
+#smart_editor .tool li.blockquote .layer li button{ width:32px; height:34px;}
+
+#smart_editor .tool li.url .layer{ width:231px; height:125px; background-image:url(../img/bx_url.gif); background-repeat:no-repeat; background-position:10px 14px;}
+#smart_editor .tool li.url .layer fieldset{ position:absolute; width:212px; left:10px; top:14px;}
+#smart_editor .tool li.url .layer fieldset h3{ position:absolute; top:-4px; left:15px; color:#404040; visibility:visible; font-size:12px; line-height:normal; width:auto; height:auto; background:none; margin:0; padding:0; font-weight:normal;}
+#smart_editor .tool li.url .layer fieldset input.link{ position:absolute; left:12px; top:19px; width:179px; padding:2px 0 1px 6px; *margin:-1px 0; font-size:11px; height:13px; border:1px solid #818181; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+#smart_editor .tool li.url .layer fieldset p{ position:absolute; left:12px; top:44px;}
+#smart_editor .tool li.url .layer fieldset p input{ width:13px; height:13px; vertical-align:middle; margin-right:3px;}
+#smart_editor .tool li.url .layer .btn_area{ position:absolute; bottom:12px; padding:0;}
+
+#smart_editor .tool li.table .layer{ width:242px; height:239px; background-image:url(../img/bx_table.gif); background-repeat:no-repeat; background-position:10px 14px;}
+#smart_editor .tool li.table .layer fieldset{ position:absolute; width:222px; left:10px;}
+#smart_editor .tool li.table .layer fieldset h3{ position:absolute; top:-4px; left:15px; color:#404040; visibility:visible; font-size:12px; line-height:normal; width:auto; height:auto; background:none; margin:0; padding:0; font-weight:normal;}
+
+#smart_editor .tool li.table .layer fieldset dl{ position:absolute; left:10px;}
+#smart_editor .tool li.table .layer fieldset dt{ float:left; padding:3px 0 0 0; height:20px; white-space:nowrap; letter-spacing:-1px;}
+#smart_editor .tool li.table .layer fieldset dd{ float:right; position:relative;}
+#smart_editor .tool li.table .layer fieldset dd button.add,
+#smart_editor .tool li.table .layer fieldset dd button.del{ position:absolute; left:27px; width:15px; height:8px; background:url(../img/btn_layer_cell_adjust.gif) no-repeat;}
+#smart_editor .tool li.table .layer fieldset dd button.add{ top:1px;}
+#smart_editor .tool li.table .layer fieldset dd button.del{ top:9px; background-position:0 -8px;}
+#smart_editor .tool li.table .layer fieldset dd .preview_palette{ display:block; float:left; margin:0 3px 0 0; padding:2px; position:relative; border:1px solid #c8c9c6; width:14px; height:14px; overflow:hidden;}
+#smart_editor .tool li.table .layer fieldset dd .preview_palette button{ width:14px; height:14px; font-size:500px; line-height:0;}
+#smart_editor .tool li.table .layer fieldset dd .find_palette{ width:33px; height:20px; background:url(../img/btn_search.gif) no-repeat;}
+
+#smart_editor .tool li.table .layer fieldset.num{ top:14px;}
+#smart_editor .tool li.table .layer fieldset.num dl{ top:18px; width:60px;}
+#smart_editor .tool li.table .layer fieldset.num dt{ height:20px;}
+#smart_editor .tool li.table .layer fieldset.num dd{ height:23px;}
+#smart_editor .tool li.table .layer fieldset.num dt label{ font-size:11px; color:#333;}
+#smart_editor .tool li.table .layer fieldset.num dd input{ padding:3px 0 0 6px; *margin:-1px 0; width:35px; height:13px; font-size:11px; border:1px solid #818181; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+
+#smart_editor .tool li.table .layer fieldset.color{ top:96px;}
+#smart_editor .tool li.table .layer fieldset.color dl{ top:18px; width:210px;}
+#smart_editor .tool li.table .layer fieldset.color dt{ height:23px;}
+#smart_editor .tool li.table .layer fieldset.color dd{ height:26px; width:146px;}
+#smart_editor .tool li.table .layer fieldset.color dt label{ font-size:11px; color:#333;}
+#smart_editor .tool li.table .layer fieldset.color dd input{ padding:3px 0 0 6px; *margin:-1px 0; font-size:11px; border:1px solid #818181; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+#smart_editor .tool li.table .layer fieldset.color dd input#table_border_width{ width:35px; height:13px;}
+#smart_editor .tool li.table .layer fieldset.color dd input#table_border_color,
+#smart_editor .tool li.table .layer fieldset.color dd input#table_bg_color{ width:70px; height:15px; *margin-right:3px;}
+
+#smart_editor .tool li.table .layer table{ position:absolute; top:18px; left:75px; width:137px; height:40px; table-layout:fixed;}
+#smart_editor .tool li.table .layer table *{ font-size:0; line-height:0;}
+#smart_editor .tool li.table .layer table th,
+#smart_editor .tool li.table .layer table td{ text-align:center;}
+#smart_editor .tool li.table .layer .btn_area{ position:absolute; bottom:12px; padding:0; z-index:1;}
+
+#smart_editor .tool li.table .layer .palette{ display:none; position:absolute; z-index:2; left:11px; width:204px; padding:8px 7px 7px 7px; _padding-right:6px; background-color:#fbfbfb; border:1px solid #c5c5c5; border-right:1px solid #9f9f9f; border-bottom:1px solid #9f9f9f;}
+#smart_editor .tool li.table .layer.p1 .palette{ display:block; top:163px;}
+#smart_editor .tool li.table .layer.p2 .palette{ display:block; top:189px;}
+
+#smart_editor .tool li.character .layer{ width:433px; height:242px; overflow:hidden;}
+#smart_editor .tool li.character .layer ul{ margin:0;}
+#smart_editor .tool li.character .layer h3{position:absolute; width:0; height:0; overflow:hidden; visibility:hidden;}
+#smart_editor .tool li.character .layer .nav{ position:absolute; top:11px; left:-1px; overflow:hidden; white-space:nowrap;}
+#smart_editor .tool li.character .layer .nav li{ display:inline; margin:0 -4px 0 0; padding:0 8px; background:url(../img/vr_layer_character.gif) no-repeat 0 0;}
+#smart_editor .tool li.character .layer .nav li a{ color:#444; text-decoration:none; letter-spacing:-1px;}
+#smart_editor .tool li.character .layer .nav li a:hover,
+#smart_editor .tool li.character .layer .nav li a:active,
+#smart_editor .tool li.character .layer .nav li a:focus{ text-decoration:underline;}
+#smart_editor .tool li.character .layer .nav li a.on{ font-weight:bold; color:#004790; display:inline;}
+#smart_editor .tool li.character .layer .list{ position:absolute; left:7px; top:30px; width:421px; height:172px; background:url(../img/bx_character.gif) no-repeat;}
+#smart_editor .tool li.character .layer .list li{ position:relative; top:1px; left:1px; float:left; width:20px; height:18px; margin:0 1px 1px 0;}
+#smart_editor .tool li.character .layer .list li button{ width:20px; height:18px;}
+#smart_editor .tool li.character .layer .list li button.hover{ border:2px solid #27c11a;}
+#smart_editor .tool li.character .layer .list li button span{ overflow:visible; font-size:12px; width:auto; height:auto; position:relative; visibility:visible; line-height:normal;}
+#smart_editor .tool li.character .layer p{ position:absolute; top:212px; left:7px;}
+#smart_editor .tool li.character .layer p *{ vertical-align:top;}
+#smart_editor .tool li.character .layer p label{ position:relative; top:4px; margin:0 7px 0 0; color:#333; letter-spacing:-1px;}
+#smart_editor .tool li.character .layer p input{ padding:3px 0 0 4px; margin:0 4px 0 0; width:300px; _width /**/:306px; height:16px; _height /**/:20px; border:1px solid #acacac; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+#smart_editor .tool li.character .layer p button{ position:relative; *top:1px; width:38px; height:21px; background:url(../img/btn_layer_confirm.gif) no-repeat;}
+#smart_editor .tool li.character .layer p button span{ position:absolute; width:0; height:0; overflow:hidden; visibility:hidden;}
+
+#smart_editor .tool li.find .layer{ width:242px;}
+#smart_editor .tool li.find .layer h3{ background:#f2f2f2; color:#333; height:21px; margin:0 0 11px 0; padding:7px 0 0 5px;}
+#smart_editor .tool li.find .layer .menu_tab{ position:relative; z-index:20; width:100%; *zoom:1;}
+#smart_editor .tool li.find .layer .menu_tab:after{ content:""; display:block; clear:both;}
+#smart_editor .tool li.find .layer .layer_tab{ position:relative; left:10px; padding:0; margin:0; clear:both;}
+#smart_editor .tool li.find .layer .layer_tab li{ position:relative; z-index:1; float:left; margin-right:1px; background:url(../img/btn_layer_tab.gif) no-repeat 0 0;}
+#smart_editor .tool li.find .layer .layer_tab li a{ position:relative; display:block; float:left; left:2px; height:15px; padding:4px 9px 0 5px; color:#404040; text-decoration:none; background:url(../img/btn_layer_tab.gif) no-repeat right 0;}
+#smart_editor .tool li.find .layer.find .layer_tab li.tab1,
+#smart_editor .tool li.find .layer.replace .layer_tab li.tab2{ top:-1px; margin-bottom:-1px;}
+#smart_editor .tool li.find .layer.find .layer_tab li.tab1 a,
+#smart_editor .tool li.find .layer.replace .layer_tab li.tab2 a{ height:18px;}
+#smart_editor .tool li.find .layer .container{ position:relative; z-index:1; clear:both; top:-2px;}
+#smart_editor .tool li.find .layer .container .bx{ display:none; position:relative; width:222px; left:10px; clear:both; z-index:1; background:url(../img/bx_find.gif) no-repeat;}
+#smart_editor .tool li.find .layer.find .container #find,
+#smart_editor .tool li.find .layer.replace .container #replace{ display:block;}
+
+#smart_editor .tool li.find .layer .bx fieldset{ position:relative; padding:13px 0 17px 11px;}
+#smart_editor .tool li.find .layer .bx fieldset *{ vertical-align:top;}
+#smart_editor .tool li.find .layer .bx label{ position:relative; top:4px; margin:0 7px 0 0; font-size:11px; letter-spacing:-1px; color:#333;}
+#smart_editor .tool li.find .layer .bx input{ padding:3px 0 0 4px; width:144px; _width /**/:150px; height:14px; _height /**/:19px; border:1px solid #acacac; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+#smart_editor .tool li.find .layer .bx .cap{ position:absolute; left:0; bottom:0; display:block; width:222px; height:2px; _margin:0 0 -1px 0; overflow:hidden; background:#fff url(../img/bx_find.gif) no-repeat left bottom; font-size:0; line-height:0;}
+#smart_editor .tool li.find .layer .bx#replace fieldset{ height:45px; _height /**/:75px;}
+#smart_editor .tool li.find .layer .bx#replace fieldset #keyword2{ margin-bottom:6px;}
+#smart_editor .tool li.find .layer .btn_area button{ display:none; *margin:0 2px !important;}
+#smart_editor .tool li.find .layer.find .btn_area .find_next{ display:inline; width:62px; height:21px; background:url(../img/btn_layer_find_next_strong.gif) no-repeat;}
+#smart_editor .tool li.find .layer.replace .btn_area .find_next{ display:inline; width:55px; height:21px; background:url(../img/btn_layer_find_next.gif) no-repeat;}
+#smart_editor .tool li.find .layer.replace .btn_area .replace{ display:inline; width:48px; height:21px; background:url(../img/btn_layer_replace.gif) no-repeat;}
+#smart_editor .tool li.find .layer.replace .btn_area .replace_all{ display:inline; width:69px; height:21px; background:url(../img/btn_layer_replace_all.gif) no-repeat;}
+#smart_editor .tool li.find .layer .btn_area .cancel{ display:inline;}
+
+/*image button add*/
+#smart_editor .tool li.img_ins .layer{ width:242px;}
+#smart_editor .tool li.img_ins .layer h3{ background:#f2f2f2; color:#333; height:21px; margin:0 0 11px 0; padding:7px 0 0 5px;}
+#smart_editor .tool li.img_ins .layer .bx fieldset{ position:relative; padding:13px 0 17px 11px;}
+#smart_editor .tool li.img_ins .layer .bx fieldset *{ vertical-align:top;}
+#smart_editor .tool li.img_ins .layer .bx label{ position:relative; top:4px; margin:0 7px 0 0; font-size:11px; letter-spacing:-1px; color:#333;}
+#smart_editor .tool li.img_ins .layer .bx input{ padding:3px 0 0 4px; width:184px; _width /**/:190px; height:14px; _height /**/:19px; border:1px solid #acacac; border-right:1px solid #dadada; border-bottom:1px solid #dadada;}
+#smart_editor .tool li.img_ins .layer .bx fieldset{ height:45px; _height /**/:75px;}
+#smart_editor .tool li.img_ins .layer .bx fieldset #img_url{ margin-bottom:6px;}
+#smart_editor .tool li.img_ins .layer .btn_area .my_img_upload{ display:inline; width:53px; height:21px; background:url(../img/btn_layer_img.gif) no-repeat;}

+ 30 - 0
style24.admin/src/main/webapp/smartEditor/css/style.css

@@ -0,0 +1,30 @@
+@charset "utf-8";
+/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) 200812 */
+
+html,
+body{ height:100%;}
+
+#smartInput{ margin:0 10px 0 0;}
+.smartOutput{ font-size:12px; line-height:1.6; font-family:Dotum, AppleGothic, Sans-serif;} /* 스마트 에디터의 풍부한 표현이 정상적으로 출력되도록 하려면 콘텐츠가 출력되는 곳에 이 클래스를 적용하여야 한다. 예를 들면 게시물 읽기 페이지의 본문이 이에 해당된다. */
+
+.smartOutput p{ margin-top:7px; margin-bottom:7px;}
+
+.smartOutput blockquote.q1,
+.smartOutput blockquote.q2,
+.smartOutput blockquote.q3,
+.smartOutput blockquote.q4,
+.smartOutput blockquote.q5,
+.smartOutput blockquote.q6,
+.smartOutput blockquote.q7{ padding:10px; margin-left:15px; margin-right:15px;}
+
+.smartOutput blockquote.q1{ padding:0 10px; border-left:2px solid #ccc;}
+.smartOutput blockquote.q2{ padding:0 10px; background:url(../img/bg_qmark.gif) no-repeat;}
+.smartOutput blockquote.q3{ border:1px solid #d9d9d9;}
+.smartOutput blockquote.q4{ border:1px solid #d9d9d9; background:#fbfbfb;}
+.smartOutput blockquote.q5{ border:2px solid #707070;}
+.smartOutput blockquote.q6{ border:1px dashed #707070;}
+.smartOutput blockquote.q7{ border:1px dashed #707070; background:#fbfbfb;}
+
+.smartOutput sup{ font:10px Tahoma;}
+.smartOutput sub{ font:10px Tahoma;}
+.smartOutput table td{ padding:4px;}

TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/XPButtonUploadText_61x22.png


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bg_qmark.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bg_tool.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_confirm.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_expand.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_html.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_cancel.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_cell_adjust.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_close.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_confirm.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_find_next.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_find_next_strong.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_img.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_replace.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_replace_all.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_layer_tab.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_qmark.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_search.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_set.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_set_blank.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/btn_set_original.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bx_character.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bx_find.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bx_table.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/bx_url.gif


TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/img/vr_layer_character.gif


File diff ditekan karena terlalu besar
+ 109 - 0
style24.admin/src/main/webapp/smartEditor/js/Husky.SE_Basic.js


+ 126 - 0
style24.admin/src/main/webapp/smartEditor/js/HuskyEZCreator.js

@@ -0,0 +1,126 @@
+if(typeof window.nhn=='undefined') window.nhn = {};
+if (!nhn.husky) nhn.husky = {};
+
+/**
+ * @fileOverview This file contains application creation helper function, which would load up an HTML(Skin) file and then execute a specified create function.
+ * @name HuskyEZCreator.js
+ */
+nhn.husky.EZCreator = new (function(){
+	this.nBlockerCount = 0;
+
+	this.createInIFrame = function(htOptions){
+		if(arguments.length == 1){
+			var oAppRef = htOptions.oAppRef;
+			var elPlaceHolder = htOptions.elPlaceHolder;
+			var sSkinURI = htOptions.sSkinURI;
+			var fCreator = htOptions.fCreator;
+			var fOnAppLoad = htOptions.fOnAppLoad;
+			var bUseBlocker = htOptions.bUseBlocker;
+			var htParams = htOptions.htParams;
+		}else{
+			// for backward compatibility only
+			var oAppRef = arguments[0];
+			var elPlaceHolder = arguments[1];
+			var sSkinURI = arguments[2];
+			var fCreator = arguments[3];
+			var fOnAppLoad = arguments[4];
+			var bUseBlocker = arguments[5];
+			var htParams = arguments[6];
+		}
+
+		if(bUseBlocker) nhn.husky.EZCreator.showBlocker();
+
+		var attachEvent = function(elNode, sEvent, fHandler){
+			if(elNode.addEventListener){
+				elNode.addEventListener(sEvent, fHandler, false);
+			}else{
+				elNode.attachEvent("on"+sEvent, fHandler);
+			}
+		}
+
+		if(!elPlaceHolder){
+			alert("Placeholder is required!");
+			return;
+		}
+
+		if(typeof(elPlaceHolder) != "object")
+			elPlaceHolder = document.getElementById(elPlaceHolder);
+
+		var elIFrame;
+		try{
+			elIFrame = document.createElement("<IFRAME id='the_iframe' frameborder=0 scrolling=no'>");
+		}catch(e){
+			elIFrame = document.createElement("IFRAME");
+			elIFrame.setAttribute("id", "the_iframe");
+//			elIFrame.setAttribute("onload", "calcHeight()");
+			elIFrame.setAttribute("frameborder", "0");
+			elIFrame.setAttribute("scrolling", "no");
+		}
+		elIFrame.style.width = "1px";
+		elIFrame.style.height = "1px";
+		elIFrame.style.minHeight = "467px";
+
+		elPlaceHolder.parentNode.insertBefore(elIFrame, elPlaceHolder.nextSibling);
+
+		attachEvent(elIFrame, "load", function(){
+			fCreator = elIFrame.contentWindow[fCreator] || elIFrame.contentWindow.createSEditorInIFrame;
+
+			try{
+				elIFrame.contentWindow.document.body.style.margin = "0";
+				elIFrame.contentWindow.document.body.style.padding = "1";
+			}catch(e){
+				nhn.husky.EZCreator.hideBlocker(true);
+				elIFrame.style.border = "5px solid red";
+				elIFrame.style.width = "500px";
+				elIFrame.style.height = "500px";
+				alert("Failed to access "+sSkinURI);
+				return;
+			}
+
+			var oApp = fCreator(elIFrame, elPlaceHolder, htParams);
+			oApp.elPlaceHolder = elPlaceHolder;
+
+			oAppRef[oAppRef.length] = oApp;
+			if(!oAppRef.getById) oAppRef.getById = {};
+
+			if(elPlaceHolder.id){
+				oApp.sAppId = elPlaceHolder.id;
+				oAppRef.getById[elPlaceHolder.id] = oApp;
+			}
+			oApp.run({fnOnAppReady:fOnAppLoad});
+
+			nhn.husky.EZCreator.hideBlocker();
+		});
+
+		elIFrame.src = sSkinURI;
+	};
+
+	this.showBlocker = function(){
+		if(this.nBlockerCount<1){
+			var elBlocker = document.createElement("DIV");
+			elBlocker.style.position = "absolute";
+			elBlocker.style.top = 0;
+			elBlocker.style.left = 0;
+			elBlocker.style.backgroundColor = "#FFFFFF";
+			elBlocker.style.width = "100%";
+
+			document.body.appendChild(elBlocker);
+
+			nhn.husky.EZCreator.elBlocker = elBlocker;
+		}
+
+		nhn.husky.EZCreator.elBlocker.style.height = Math.max(document.body.scrollHeight, document.body.clientHeight)+"px";
+
+		this.nBlockerCount++;
+	};
+
+	this.hideBlocker = function(bForce){
+		if(!bForce){
+			if(--this.nBlockerCount > 0) return;
+		}
+
+		this.nBlockerCount = 0;
+
+		if(nhn.husky.EZCreator.elBlocker) nhn.husky.EZCreator.elBlocker.style.display = "none";
+	}
+})();

+ 80 - 0
style24.admin/src/main/webapp/smartEditor/js/SE_CustomPlugins.js

@@ -0,0 +1,80 @@
+function SE_RegisterCustomPlugins(oEditor, elAppContainer){
+//	oEditor.registerPlugin(new nhn.husky.SE_ToolbarToggler(elAppContainer));
+	oEditor.registerPlugin(new nhn.husky.SE_ImgInsert(elAppContainer));
+}
+
+// Sample plugin. Use CTRL+T to toggle the toolbar
+nhn.husky.SE_ToolbarToggler = $Class({
+	name : "SE_ToolbarToggler",
+
+	$init : function(oAppContainer){
+		this._assignHTMLObjects(oAppContainer);
+	},
+
+	_assignHTMLObjects : function(oAppContainer){
+		oAppContainer = $(oAppContainer) || document;
+		this.toolbarArea = cssquery.getSingle(".tool", oAppContainer);
+	},
+
+	$ON_MSG_APP_READY : function(){
+		this.oApp.exec("SE_TOGGLE_TOOLBAR", []);
+		this.oApp.exec("REGISTER_HOTKEY", ["ctrl+t", "SE_TOGGLE_TOOLBAR", []]);
+	},
+
+	$ON_SE_TOGGLE_TOOLBAR : function(){
+		this.toolbarArea.style.display = (this.toolbarArea.style.display == "none")?"block":"none";
+		this.oApp.exec("MSG_EDITING_AREA_SIZE_CHANGED", []);
+	}
+});
+
+//image insertion plugin (by gojeong)
+nhn.husky.SE_ImgInsert = $Class({
+	name : "SE_ImgInsert",
+
+	$init : function(elAppContainer){
+		this._assignHTMLObjects(elAppContainer);
+	},
+
+	_assignHTMLObjects : function(elAppContainer){
+		this.oImageInsertLayer = cssquery.getSingle("DIV.husky_seditor_ImgInsert_layer", elAppContainer);
+		this.oBtnConfirm = cssquery.getSingle("BUTTON.confirm", this.oImageInsertLayer);
+		this.oBtnCancel = cssquery.getSingle("BUTTON.cancel", this.oImageInsertLayer);
+		this.oBtnClose = cssquery.getSingle("BUTTON.close", this.oImageInsertLayer);
+
+		var oTmp = cssquery("INPUT", this.oImageInsertLayer);
+		this.oUrlInput = oTmp[0];
+		this.oAltInput = oTmp[1];
+	},
+
+	$ON_MSG_APP_READY : function(){
+		this.oApp.exec("REGISTER_UI_EVENT", ["ImgInsert", "click", "SE_TOGGLE_IMGINSERT_LAYER"]);
+		this.oApp.registerBrowserEvent(this.oBtnConfirm, "mousedown", "SE_APPLY_IMAGEINSERT");
+		this.oApp.registerBrowserEvent(this.oBtnCancel, "mousedown", "SE_CLOSE_IMAGEINSERT");
+		this.oApp.registerBrowserEvent(this.oBtnClose, "mousedown", "SE_CLOSE_IMAGEINSERT");
+	},
+
+	$ON_SE_APPLY_IMAGEINSERT : function() {
+		var sURL = this.oUrlInput.value;
+		this.oSelection = this.oApp.getSelection();
+		if (sURL != "") {
+			var str = "<img src='" + sURL + "' alt='" + this.oAltInput.value + "' />";
+			this.oSelection.pasteHTML(str);
+			this.oUrlInput.value = "";
+			this.oAltInput.value = "";
+			this.oApp.exec("HIDE_ACTIVE_LAYER");
+		} else {
+			alert("input file path!");
+			this.oUrlInput.focus();
+		}
+	},
+
+	$ON_SE_CLOSE_IMAGEINSERT : function() {
+		this.oUrlInput.value = "";
+		this.oAltInput.value = "";
+		this.oApp.exec("HIDE_ACTIVE_LAYER");
+	},
+
+	$ON_SE_TOGGLE_IMGINSERT_LAYER : function(){
+		this.oApp.exec("TOGGLE_TOOLBAR_ACTIVE_LAYER", [this.oImageInsertLayer]);
+	}
+});

File diff ditekan karena terlalu besar
+ 172 - 0
style24.admin/src/main/webapp/smartEditor/js/jindo.min.js


+ 10 - 0
style24.admin/src/main/webapp/smartEditor/se_blank.html

@@ -0,0 +1,10 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Smart Editor&#8482; WYSIWYG Mode [반드시 필요한 에디터의 빈 페이지 파일 입니다]</title>
+<link href="/smartEditor/css/style.css" rel="stylesheet" type="text/css" />
+<!-- <link rel="stylesheet" type="text/css" href="/ux/css/sisunfront/css_ko.css"/> -->
+</head>
+<body id="smartInput" class="smartOutput">
+</body>
+</html>

TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/swfupload/img/my_img.gif


+ 49 - 0
style24.admin/src/main/webapp/smartEditor/swfupload/js/handlers.js

@@ -0,0 +1,49 @@
+function fileDialogComplete(numFilesSelected, numFilesQueued) {
+	try {
+		if (numFilesQueued > 0) {
+			this.startUpload();
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+}
+
+function uploadSuccess(file, serverData) {
+	try {
+		if (serverData.substring(0, 7) === "FILENM:") {
+			paste(serverData.substring(7));
+		} else {
+			alert(serverData);
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+}
+
+function fileQueueError(file, errorCode, message) {
+	try {
+		if (errorCode == SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
+			alert("한 번에 최대 " + swfu.getSetting("file_queue_limit") + "개 파일을 올릴 수 있습니다.");
+		} else if (errorCode == SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE) {
+			alert("파일 크기가 0입니다.");
+		} else if (errorCode == SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT) {
+			alert("파일 크기는 최대 " + swfu.getSetting("file_size_limit") + "를 넘을 수 없습니다.");
+		} else if (errorCode == SWFUpload.QUEUE_ERROR.INVALID_FILETYPE) {
+			alert("허용되지 않는 파일 형식입니다.");
+		} 
+	} catch (ex) {
+		this.debug(ex);
+	}
+}
+
+function uploadError(file, errorCode, message) {
+	try {
+		if (errorCode == SWFUpload.QUEUE_ERROR.UPLOAD_LIMIT_EXCEEDED) {
+			alert("총 최대 " + swfu.getSetting("file_upload_limit") + "개 파일만 올릴 수 있습니다.");
+		} else {
+			alert("업로드에 실패했습니다.");
+		} 
+	} catch (ex) {
+		this.debug(ex);
+	}
+}

+ 980 - 0
style24.admin/src/main/webapp/smartEditor/swfupload/js/swfupload.js

@@ -0,0 +1,980 @@
+/**
+ * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
+ *
+ * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
+ *
+ * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz�n and Mammon Media and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+
+
+/* ******************* */
+/* Constructor & Init  */
+/* ******************* */
+var SWFUpload;
+
+if (SWFUpload == undefined) {
+	SWFUpload = function (settings) {
+		this.initSWFUpload(settings);
+	};
+}
+
+SWFUpload.prototype.initSWFUpload = function (settings) {
+	try {
+		this.customSettings = {};	// A container where developers can place their own settings associated with this instance.
+		this.settings = settings;
+		this.eventQueue = [];
+		this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
+		this.movieElement = null;
+
+
+		// Setup global control tracking
+		SWFUpload.instances[this.movieName] = this;
+
+		// Load the settings.  Load the Flash movie.
+		this.initSettings();
+		this.loadFlash();
+		this.displayDebugInfo();
+	} catch (ex) {
+		delete SWFUpload.instances[this.movieName];
+		throw ex;
+	}
+};
+
+/* *************** */
+/* Static Members  */
+/* *************** */
+SWFUpload.instances = {};
+SWFUpload.movieCount = 0;
+SWFUpload.version = "2.2.0 2009-03-25";
+SWFUpload.QUEUE_ERROR = {
+	QUEUE_LIMIT_EXCEEDED	  		: -100,
+	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
+	ZERO_BYTE_FILE			  		: -120,
+	INVALID_FILETYPE		  		: -130
+};
+SWFUpload.UPLOAD_ERROR = {
+	HTTP_ERROR				  		: -200,
+	MISSING_UPLOAD_URL	      		: -210,
+	IO_ERROR				  		: -220,
+	SECURITY_ERROR			  		: -230,
+	UPLOAD_LIMIT_EXCEEDED	  		: -240,
+	UPLOAD_FAILED			  		: -250,
+	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
+	FILE_VALIDATION_FAILED	  		: -270,
+	FILE_CANCELLED			  		: -280,
+	UPLOAD_STOPPED					: -290
+};
+SWFUpload.FILE_STATUS = {
+	QUEUED		 : -1,
+	IN_PROGRESS	 : -2,
+	ERROR		 : -3,
+	COMPLETE	 : -4,
+	CANCELLED	 : -5
+};
+SWFUpload.BUTTON_ACTION = {
+	SELECT_FILE  : -100,
+	SELECT_FILES : -110,
+	START_UPLOAD : -120
+};
+SWFUpload.CURSOR = {
+	ARROW : -1,
+	HAND : -2
+};
+SWFUpload.WINDOW_MODE = {
+	WINDOW : "window",
+	TRANSPARENT : "transparent",
+	OPAQUE : "opaque"
+};
+
+// Private: takes a URL, determines if it is relative and converts to an absolute URL
+// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
+SWFUpload.completeURL = function(url) {
+	if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
+		return url;
+	}
+	
+	var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
+	
+	var indexSlash = window.location.pathname.lastIndexOf("/");
+	if (indexSlash <= 0) {
+		path = "/";
+	} else {
+		path = window.location.pathname.substr(0, indexSlash) + "/";
+	}
+	
+	return /*currentURL +*/ path + url;
+	
+};
+
+
+/* ******************** */
+/* Instance Members  */
+/* ******************** */
+
+// Private: initSettings ensures that all the
+// settings are set, getting a default value if one was not assigned.
+SWFUpload.prototype.initSettings = function () {
+	this.ensureDefault = function (settingName, defaultValue) {
+		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
+	};
+	
+	// Upload backend settings
+	this.ensureDefault("upload_url", "");
+	this.ensureDefault("preserve_relative_urls", false);
+	this.ensureDefault("file_post_name", "Filedata");
+	this.ensureDefault("post_params", {});
+	this.ensureDefault("use_query_string", false);
+	this.ensureDefault("requeue_on_error", false);
+	this.ensureDefault("http_success", []);
+	this.ensureDefault("assume_success_timeout", 0);
+	
+	// File Settings
+	this.ensureDefault("file_types", "*.*");
+	this.ensureDefault("file_types_description", "All Files");
+	this.ensureDefault("file_size_limit", 0);	// Default zero means "unlimited"
+	this.ensureDefault("file_upload_limit", 0);
+	this.ensureDefault("file_queue_limit", 0);
+
+	// Flash Settings
+	this.ensureDefault("flash_url", "swfupload.swf");
+	this.ensureDefault("prevent_swf_caching", true);
+	
+	// Button Settings
+	this.ensureDefault("button_image_url", "");
+	this.ensureDefault("button_width", 1);
+	this.ensureDefault("button_height", 1);
+	this.ensureDefault("button_text", "");
+	this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
+	this.ensureDefault("button_text_top_padding", 0);
+	this.ensureDefault("button_text_left_padding", 0);
+	this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
+	this.ensureDefault("button_disabled", false);
+	this.ensureDefault("button_placeholder_id", "");
+	this.ensureDefault("button_placeholder", null);
+	this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
+	this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
+	
+	// Debug Settings
+	this.ensureDefault("debug", false);
+	this.settings.debug_enabled = this.settings.debug;	// Here to maintain v2 API
+	
+	// Event Handlers
+	this.settings.return_upload_start_handler = this.returnUploadStart;
+	this.ensureDefault("swfupload_loaded_handler", null);
+	this.ensureDefault("file_dialog_start_handler", null);
+	this.ensureDefault("file_queued_handler", null);
+	this.ensureDefault("file_queue_error_handler", null);
+	this.ensureDefault("file_dialog_complete_handler", null);
+	
+	this.ensureDefault("upload_start_handler", null);
+	this.ensureDefault("upload_progress_handler", null);
+	this.ensureDefault("upload_error_handler", null);
+	this.ensureDefault("upload_success_handler", null);
+	this.ensureDefault("upload_complete_handler", null);
+	
+	this.ensureDefault("debug_handler", this.debugMessage);
+
+	this.ensureDefault("custom_settings", {});
+
+	// Other settings
+	this.customSettings = this.settings.custom_settings;
+	
+	// Update the flash url if needed
+	if (!!this.settings.prevent_swf_caching) {
+		this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
+	}
+	
+	if (!this.settings.preserve_relative_urls) {
+		//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url);	// Don't need to do this one since flash doesn't look at it
+		this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
+		this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
+	}
+	
+	delete this.ensureDefault;
+};
+
+// Private: loadFlash replaces the button_placeholder element with the flash movie.
+SWFUpload.prototype.loadFlash = function () {
+	var targetElement, tempParent;
+
+	// Make sure an element with the ID we are going to use doesn't already exist
+	if (document.getElementById(this.movieName) !== null) {
+		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
+	}
+
+	// Get the element where we will be placing the flash movie
+	targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
+
+	if (targetElement == undefined) {
+		throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
+	}
+
+	// Append the container and load the flash
+	tempParent = document.createElement("div");
+	tempParent.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
+	targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
+
+	// Fix IE Flash/Form bug
+	if (window[this.movieName] == undefined) {
+		window[this.movieName] = this.getMovieElement();
+	}
+	
+};
+
+// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
+SWFUpload.prototype.getFlashHTML = function () {
+	// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
+	return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
+				'<param name="wmode" value="', this.settings.button_window_mode, '" />',
+				'<param name="movie" value="', this.settings.flash_url, '" />',
+				'<param name="quality" value="high" />',
+				'<param name="menu" value="false" />',
+				'<param name="allowScriptAccess" value="always" />',
+				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
+				'</object>'].join("");
+};
+
+// Private: getFlashVars builds the parameter string that will be passed
+// to flash in the flashvars param.
+SWFUpload.prototype.getFlashVars = function () {
+	// Build a string from the post param object
+	var paramString = this.buildParamString();
+	var httpSuccessString = this.settings.http_success.join(",");
+	
+	// Build the parameter string
+	return ["movieName=", encodeURIComponent(this.movieName),
+			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
+			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
+			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
+			"&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
+			"&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
+			"&amp;params=", encodeURIComponent(paramString),
+			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
+			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
+			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
+			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
+			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
+			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
+			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
+			"&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
+			"&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
+			"&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
+			"&amp;buttonText=", encodeURIComponent(this.settings.button_text),
+			"&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
+			"&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
+			"&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
+			"&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
+			"&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
+			"&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
+		].join("");
+};
+
+// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
+// The element is cached after the first lookup
+SWFUpload.prototype.getMovieElement = function () {
+	if (this.movieElement == undefined) {
+		this.movieElement = document.getElementById(this.movieName);
+	}
+
+	if (this.movieElement === null) {
+		throw "Could not find Flash element";
+	}
+	
+	return this.movieElement;
+};
+
+// Private: buildParamString takes the name/value pairs in the post_params setting object
+// and joins them up in to a string formatted "name=value&amp;name=value"
+SWFUpload.prototype.buildParamString = function () {
+	var postParams = this.settings.post_params; 
+	var paramStringPairs = [];
+
+	if (typeof(postParams) === "object") {
+		for (var name in postParams) {
+			if (postParams.hasOwnProperty(name)) {
+				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
+			}
+		}
+	}
+
+	return paramStringPairs.join("&amp;");
+};
+
+// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
+// all references to the SWF, and other objects so memory is properly freed.
+// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
+// Credits: Major improvements provided by steffen
+SWFUpload.prototype.destroy = function () {
+	try {
+		// Make sure Flash is done before we try to remove it
+		this.cancelUpload(null, false);
+		
+
+		// Remove the SWFUpload DOM nodes
+		var movieElement = null;
+		movieElement = this.getMovieElement();
+		
+		if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
+			// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
+			for (var i in movieElement) {
+				try {
+					if (typeof(movieElement[i]) === "function") {
+						movieElement[i] = null;
+					}
+				} catch (ex1) {}
+			}
+
+			// Remove the Movie Element from the page
+			try {
+				movieElement.parentNode.removeChild(movieElement);
+			} catch (ex) {}
+		}
+		
+		// Remove IE form fix reference
+		window[this.movieName] = null;
+
+		// Destroy other references
+		SWFUpload.instances[this.movieName] = null;
+		delete SWFUpload.instances[this.movieName];
+
+		this.movieElement = null;
+		this.settings = null;
+		this.customSettings = null;
+		this.eventQueue = null;
+		this.movieName = null;
+		
+		
+		return true;
+	} catch (ex2) {
+		return false;
+	}
+};
+
+
+// Public: displayDebugInfo prints out settings and configuration
+// information about this SWFUpload instance.
+// This function (and any references to it) can be deleted when placing
+// SWFUpload in production.
+SWFUpload.prototype.displayDebugInfo = function () {
+	this.debug(
+		[
+			"---SWFUpload Instance Info---\n",
+			"Version: ", SWFUpload.version, "\n",
+			"Movie Name: ", this.movieName, "\n",
+			"Settings:\n",
+			"\t", "upload_url:               ", this.settings.upload_url, "\n",
+			"\t", "flash_url:                ", this.settings.flash_url, "\n",
+			"\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
+			"\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
+			"\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
+			"\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
+			"\t", "file_post_name:           ", this.settings.file_post_name, "\n",
+			"\t", "post_params:              ", this.settings.post_params.toString(), "\n",
+			"\t", "file_types:               ", this.settings.file_types, "\n",
+			"\t", "file_types_description:   ", this.settings.file_types_description, "\n",
+			"\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
+			"\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
+			"\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
+			"\t", "debug:                    ", this.settings.debug.toString(), "\n",
+
+			"\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
+
+			"\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
+			"\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
+			"\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
+			"\t", "button_width:             ", this.settings.button_width.toString(), "\n",
+			"\t", "button_height:            ", this.settings.button_height.toString(), "\n",
+			"\t", "button_text:              ", this.settings.button_text.toString(), "\n",
+			"\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
+			"\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
+			"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
+			"\t", "button_action:            ", this.settings.button_action.toString(), "\n",
+			"\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
+
+			"\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
+			"Event Handlers:\n",
+			"\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
+			"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
+			"\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
+			"\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
+			"\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
+			"\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
+			"\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
+			"\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
+			"\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
+			"\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
+		].join("")
+	);
+};
+
+/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
+	the maintain v2 API compatibility
+*/
+// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
+SWFUpload.prototype.addSetting = function (name, value, default_value) {
+    if (value == undefined) {
+        return (this.settings[name] = default_value);
+    } else {
+        return (this.settings[name] = value);
+	}
+};
+
+// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
+SWFUpload.prototype.getSetting = function (name) {
+    if (this.settings[name] != undefined) {
+        return this.settings[name];
+	}
+
+    return "";
+};
+
+
+
+// Private: callFlash handles function calls made to the Flash element.
+// Calls are made with a setTimeout for some functions to work around
+// bugs in the ExternalInterface library.
+SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
+	argumentArray = argumentArray || [];
+	
+	var movieElement = this.getMovieElement();
+	var returnValue, returnString;
+
+	// Flash's method if calling ExternalInterface methods (code adapted from MooTools).
+	try {
+		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
+		returnValue = eval(returnString);
+	} catch (ex) {
+		throw "Call to " + functionName + " failed";
+	}
+	
+	// Unescape file post param values
+	if (returnValue != undefined && typeof returnValue.post === "object") {
+		returnValue = this.unescapeFilePostParams(returnValue);
+	}
+
+	return returnValue;
+};
+
+/* *****************************
+	-- Flash control methods --
+	Your UI should use these
+	to operate SWFUpload
+   ***************************** */
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFile causes a File Selection Dialog window to appear.  This
+// dialog only allows 1 file to be selected.
+SWFUpload.prototype.selectFile = function () {
+	this.callFlash("SelectFile");
+};
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFiles causes a File Selection Dialog window to appear/ This
+// dialog allows the user to select any number of files
+// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
+// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
+// for this bug.
+SWFUpload.prototype.selectFiles = function () {
+	this.callFlash("SelectFiles");
+};
+
+
+// Public: startUpload starts uploading the first file in the queue unless
+// the optional parameter 'fileID' specifies the ID 
+SWFUpload.prototype.startUpload = function (fileID) {
+	this.callFlash("StartUpload", [fileID]);
+};
+
+// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
+// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
+// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
+SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
+	if (triggerErrorEvent !== false) {
+		triggerErrorEvent = true;
+	}
+	this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
+};
+
+// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
+// If nothing is currently uploading then nothing happens.
+SWFUpload.prototype.stopUpload = function () {
+	this.callFlash("StopUpload");
+};
+
+/* ************************
+ * Settings methods
+ *   These methods change the SWFUpload settings.
+ *   SWFUpload settings should not be changed directly on the settings object
+ *   since many of the settings need to be passed to Flash in order to take
+ *   effect.
+ * *********************** */
+
+// Public: getStats gets the file statistics object.
+SWFUpload.prototype.getStats = function () {
+	return this.callFlash("GetStats");
+};
+
+// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
+// change the statistics but you can.  Changing the statistics does not
+// affect SWFUpload accept for the successful_uploads count which is used
+// by the upload_limit setting to determine how many files the user may upload.
+SWFUpload.prototype.setStats = function (statsObject) {
+	this.callFlash("SetStats", [statsObject]);
+};
+
+// Public: getFile retrieves a File object by ID or Index.  If the file is
+// not found then 'null' is returned.
+SWFUpload.prototype.getFile = function (fileID) {
+	if (typeof(fileID) === "number") {
+		return this.callFlash("GetFileByIndex", [fileID]);
+	} else {
+		return this.callFlash("GetFile", [fileID]);
+	}
+};
+
+// Public: addFileParam sets a name/value pair that will be posted with the
+// file specified by the Files ID.  If the name already exists then the
+// exiting value will be overwritten.
+SWFUpload.prototype.addFileParam = function (fileID, name, value) {
+	return this.callFlash("AddFileParam", [fileID, name, value]);
+};
+
+// Public: removeFileParam removes a previously set (by addFileParam) name/value
+// pair from the specified file.
+SWFUpload.prototype.removeFileParam = function (fileID, name) {
+	this.callFlash("RemoveFileParam", [fileID, name]);
+};
+
+// Public: setUploadUrl changes the upload_url setting.
+SWFUpload.prototype.setUploadURL = function (url) {
+	this.settings.upload_url = url.toString();
+	this.callFlash("SetUploadURL", [url]);
+};
+
+// Public: setPostParams changes the post_params setting
+SWFUpload.prototype.setPostParams = function (paramsObject) {
+	this.settings.post_params = paramsObject;
+	this.callFlash("SetPostParams", [paramsObject]);
+};
+
+// Public: addPostParam adds post name/value pair.  Each name can have only one value.
+SWFUpload.prototype.addPostParam = function (name, value) {
+	this.settings.post_params[name] = value;
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: removePostParam deletes post name/value pair.
+SWFUpload.prototype.removePostParam = function (name) {
+	delete this.settings.post_params[name];
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: setFileTypes changes the file_types setting and the file_types_description setting
+SWFUpload.prototype.setFileTypes = function (types, description) {
+	this.settings.file_types = types;
+	this.settings.file_types_description = description;
+	this.callFlash("SetFileTypes", [types, description]);
+};
+
+// Public: setFileSizeLimit changes the file_size_limit setting
+SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
+	this.settings.file_size_limit = fileSizeLimit;
+	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
+};
+
+// Public: setFileUploadLimit changes the file_upload_limit setting
+SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
+	this.settings.file_upload_limit = fileUploadLimit;
+	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
+};
+
+// Public: setFileQueueLimit changes the file_queue_limit setting
+SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
+	this.settings.file_queue_limit = fileQueueLimit;
+	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
+};
+
+// Public: setFilePostName changes the file_post_name setting
+SWFUpload.prototype.setFilePostName = function (filePostName) {
+	this.settings.file_post_name = filePostName;
+	this.callFlash("SetFilePostName", [filePostName]);
+};
+
+// Public: setUseQueryString changes the use_query_string setting
+SWFUpload.prototype.setUseQueryString = function (useQueryString) {
+	this.settings.use_query_string = useQueryString;
+	this.callFlash("SetUseQueryString", [useQueryString]);
+};
+
+// Public: setRequeueOnError changes the requeue_on_error setting
+SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
+	this.settings.requeue_on_error = requeueOnError;
+	this.callFlash("SetRequeueOnError", [requeueOnError]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
+	if (typeof http_status_codes === "string") {
+		http_status_codes = http_status_codes.replace(" ", "").split(",");
+	}
+	
+	this.settings.http_success = http_status_codes;
+	this.callFlash("SetHTTPSuccess", [http_status_codes]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
+	this.settings.assume_success_timeout = timeout_seconds;
+	this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
+};
+
+// Public: setDebugEnabled changes the debug_enabled setting
+SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
+	this.settings.debug_enabled = debugEnabled;
+	this.callFlash("SetDebugEnabled", [debugEnabled]);
+};
+
+// Public: setButtonImageURL loads a button image sprite
+SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
+	if (buttonImageURL == undefined) {
+		buttonImageURL = "";
+	}
+	
+	this.settings.button_image_url = buttonImageURL;
+	this.callFlash("SetButtonImageURL", [buttonImageURL]);
+};
+
+// Public: setButtonDimensions resizes the Flash Movie and button
+SWFUpload.prototype.setButtonDimensions = function (width, height) {
+	this.settings.button_width = width;
+	this.settings.button_height = height;
+	
+	var movie = this.getMovieElement();
+	if (movie != undefined) {
+		movie.style.width = width + "px";
+		movie.style.height = height + "px";
+	}
+	
+	this.callFlash("SetButtonDimensions", [width, height]);
+};
+// Public: setButtonText Changes the text overlaid on the button
+SWFUpload.prototype.setButtonText = function (html) {
+	this.settings.button_text = html;
+	this.callFlash("SetButtonText", [html]);
+};
+// Public: setButtonTextPadding changes the top and left padding of the text overlay
+SWFUpload.prototype.setButtonTextPadding = function (left, top) {
+	this.settings.button_text_top_padding = top;
+	this.settings.button_text_left_padding = left;
+	this.callFlash("SetButtonTextPadding", [left, top]);
+};
+
+// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
+SWFUpload.prototype.setButtonTextStyle = function (css) {
+	this.settings.button_text_style = css;
+	this.callFlash("SetButtonTextStyle", [css]);
+};
+// Public: setButtonDisabled disables/enables the button
+SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
+	this.settings.button_disabled = isDisabled;
+	this.callFlash("SetButtonDisabled", [isDisabled]);
+};
+// Public: setButtonAction sets the action that occurs when the button is clicked
+SWFUpload.prototype.setButtonAction = function (buttonAction) {
+	this.settings.button_action = buttonAction;
+	this.callFlash("SetButtonAction", [buttonAction]);
+};
+
+// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
+SWFUpload.prototype.setButtonCursor = function (cursor) {
+	this.settings.button_cursor = cursor;
+	this.callFlash("SetButtonCursor", [cursor]);
+};
+
+/* *******************************
+	Flash Event Interfaces
+	These functions are used by Flash to trigger the various
+	events.
+	
+	All these functions a Private.
+	
+	Because the ExternalInterface library is buggy the event calls
+	are added to a queue and the queue then executed by a setTimeout.
+	This ensures that events are executed in a determinate order and that
+	the ExternalInterface bugs are avoided.
+******************************* */
+
+SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
+	// Warning: Don't call this.debug inside here or you'll create an infinite loop
+	
+	if (argumentArray == undefined) {
+		argumentArray = [];
+	} else if (!(argumentArray instanceof Array)) {
+		argumentArray = [argumentArray];
+	}
+	
+	var self = this;
+	if (typeof this.settings[handlerName] === "function") {
+		// Queue the event
+		this.eventQueue.push(function () {
+			this.settings[handlerName].apply(this, argumentArray);
+		});
+		
+		// Execute the next queued event
+		setTimeout(function () {
+			self.executeNextEvent();
+		}, 0);
+		
+	} else if (this.settings[handlerName] !== null) {
+		throw "Event handler " + handlerName + " is unknown or is not a function";
+	}
+};
+
+// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
+// we must queue them in order to garentee that they are executed in order.
+SWFUpload.prototype.executeNextEvent = function () {
+	// Warning: Don't call this.debug inside here or you'll create an infinite loop
+
+	var  f = this.eventQueue ? this.eventQueue.shift() : null;
+	if (typeof(f) === "function") {
+		f.apply(this);
+	}
+};
+
+// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
+// properties that contain characters that are not valid for JavaScript identifiers. To work around this
+// the Flash Component escapes the parameter names and we must unescape again before passing them along.
+SWFUpload.prototype.unescapeFilePostParams = function (file) {
+	var reg = /[$]([0-9a-f]{4})/i;
+	var unescapedPost = {};
+	var uk;
+
+	if (file != undefined) {
+		for (var k in file.post) {
+			if (file.post.hasOwnProperty(k)) {
+				uk = k;
+				var match;
+				while ((match = reg.exec(uk)) !== null) {
+					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
+				}
+				unescapedPost[uk] = file.post[k];
+			}
+		}
+
+		file.post = unescapedPost;
+	}
+
+	return file;
+};
+
+// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
+SWFUpload.prototype.testExternalInterface = function () {
+	try {
+		return this.callFlash("TestExternalInterface");
+	} catch (ex) {
+		return false;
+	}
+};
+
+// Private: This event is called by Flash when it has finished loading. Don't modify this.
+// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
+SWFUpload.prototype.flashReady = function () {
+	// Check that the movie element is loaded correctly with its ExternalInterface methods defined
+	var movieElement = this.getMovieElement();
+
+	if (!movieElement) {
+		this.debug("Flash called back ready but the flash movie can't be found.");
+		return;
+	}
+
+	this.cleanUp(movieElement);
+	
+	this.queueEvent("swfupload_loaded_handler");
+};
+
+// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
+// This function is called by Flash each time the ExternalInterface functions are created.
+SWFUpload.prototype.cleanUp = function (movieElement) {
+	// Pro-actively unhook all the Flash functions
+	try {
+		if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
+			this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
+			for (var key in movieElement) {
+				try {
+					if (typeof(movieElement[key]) === "function") {
+						movieElement[key] = null;
+					}
+				} catch (ex) {
+				}
+			}
+		}
+	} catch (ex1) {
+	
+	}
+
+	// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
+	// it doesn't display errors.
+	window["__flash__removeCallback"] = function (instance, name) {
+		try {
+			if (instance) {
+				instance[name] = null;
+			}
+		} catch (flashEx) {
+		
+		}
+	};
+
+};
+
+
+/* This is a chance to do something before the browse window opens */
+SWFUpload.prototype.fileDialogStart = function () {
+	this.queueEvent("file_dialog_start_handler");
+};
+
+
+/* Called when a file is successfully added to the queue. */
+SWFUpload.prototype.fileQueued = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queued_handler", file);
+};
+
+
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
+};
+
+/* Called after the file dialog has closed and the selected files have been queued.
+	You could call startUpload here if you want the queued files to begin uploading immediately. */
+SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
+	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
+};
+
+SWFUpload.prototype.uploadStart = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("return_upload_start_handler", file);
+};
+
+SWFUpload.prototype.returnUploadStart = function (file) {
+	var returnValue;
+	if (typeof this.settings.upload_start_handler === "function") {
+		file = this.unescapeFilePostParams(file);
+		returnValue = this.settings.upload_start_handler.call(this, file);
+	} else if (this.settings.upload_start_handler != undefined) {
+		throw "upload_start_handler must be a function";
+	}
+
+	// Convert undefined to true so if nothing is returned from the upload_start_handler it is
+	// interpretted as 'true'.
+	if (returnValue === undefined) {
+		returnValue = true;
+	}
+	
+	returnValue = !!returnValue;
+	
+	this.callFlash("ReturnUploadStart", [returnValue]);
+};
+
+
+
+SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
+};
+
+SWFUpload.prototype.uploadError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_error_handler", [file, errorCode, message]);
+};
+
+SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
+};
+
+SWFUpload.prototype.uploadComplete = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_complete_handler", file);
+};
+
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
+   internal debug console.  You can override this event and have messages written where you want. */
+SWFUpload.prototype.debug = function (message) {
+	this.queueEvent("debug_handler", message);
+};
+
+
+/* **********************************
+	Debug Console
+	The debug console is a self contained, in page location
+	for debug message to be sent.  The Debug Console adds
+	itself to the body if necessary.
+
+	The console is automatically scrolled as messages appear.
+	
+	If you are using your own debug handler or when you deploy to production and
+	have debug disabled you can remove these functions to reduce the file size
+	and complexity.
+********************************** */
+   
+// Private: debugMessage is the default debug_handler.  If you want to print debug messages
+// call the debug() function.  When overriding the function your own function should
+// check to see if the debug setting is true before outputting debug information.
+SWFUpload.prototype.debugMessage = function (message) {
+	if (this.settings.debug) {
+		var exceptionMessage, exceptionValues = [];
+
+		// Check for an exception object and print it nicely
+		if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
+			for (var key in message) {
+				if (message.hasOwnProperty(key)) {
+					exceptionValues.push(key + ": " + message[key]);
+				}
+			}
+			exceptionMessage = exceptionValues.join("\n") || "";
+			exceptionValues = exceptionMessage.split("\n");
+			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
+			SWFUpload.Console.writeLine(exceptionMessage);
+		} else {
+			SWFUpload.Console.writeLine(message);
+		}
+	}
+};
+
+SWFUpload.Console = {};
+SWFUpload.Console.writeLine = function (message) {
+	var console, documentForm;
+
+	try {
+		console = document.getElementById("SWFUpload_Console");
+
+		if (!console) {
+			documentForm = document.createElement("form");
+			document.getElementsByTagName("body")[0].appendChild(documentForm);
+
+			console = document.createElement("textarea");
+			console.id = "SWFUpload_Console";
+			console.style.fontFamily = "monospace";
+			console.setAttribute("wrap", "off");
+			console.wrap = "off";
+			console.style.overflow = "auto";
+			console.style.width = "700px";
+			console.style.height = "350px";
+			console.style.margin = "5px";
+			documentForm.appendChild(console);
+		}
+
+		console.value += message + "\n";
+
+		console.scrollTop = console.scrollHeight - console.clientHeight;
+	} catch (ex) {
+		alert("Exception: " + ex.name + " Message: " + ex.message);
+	}
+};

TEMPAT SAMPAH
style24.admin/src/main/webapp/smartEditor/swfupload/swf/swfupload.swf


+ 41 - 0
style24.admin/src/main/webapp/smartEditor/swfupload/swfupload_proc.jsp

@@ -0,0 +1,41 @@
+<%@ page language="java" contentType="text/html;charset=utf-8" %>
+<%@ page import="com.gagaframework.web.util.GagaFileUtil" %>
+<%@ page import="com.oreilly.servlet.MultipartRequest" %>
+<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
+
+<%
+    String contentType = request.getContentType();
+    if (contentType == null || !contentType.startsWith("multipart/form-data")) {
+        return;
+    }
+
+    String serverType = System.getProperty("spring.profiles.active");
+    String seUploadPath = "";
+    String seViewUrl = "";
+
+    if (serverType.equals("locd") || serverType.equals("locp")) {
+        seUploadPath = "/WIDE/workspace/files/data/smartEditor";
+        seViewUrl = "//ldimage.pastelmall.com";
+    } else if (serverType.equals("dev")) {
+        seUploadPath = "/data/files/smartEditor";
+        seViewUrl = "//" + serverType + ".image.pastelmall.com";
+    } else if (serverType.equals("qas") || serverType.equals("run")) {
+        seUploadPath = "/data/files/smartEditor";
+        seViewUrl = "//image.pastelmall.com";
+    }
+
+    System.out.println("seUploadPath: " + seUploadPath);
+    System.out.println("seViewUrl: " + seViewUrl);
+
+    MultipartRequest multipartRequest = new MultipartRequest(request
+            , seUploadPath
+            , 50000000
+            , "utf-8"
+            , new DefaultFileRenamePolicy()
+    );
+
+    String objImage = GagaFileUtil.getConcatenationPath(seViewUrl, "smartEditor", multipartRequest.getFilesystemName("Filedata"));
+    System.out.println("objImage: " + objImage);
+
+    out.clear();
+%>FILENM:<%=objImage%>

+ 34 - 0
style24.admin/src/main/webapp/smartEditor/write.html

@@ -0,0 +1,34 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head></head>
+<body>
+
+<script type="text/javascript" src="js/HuskyEZCreator.js" charset="utf-8"></script>
+
+<form action="" method="post">
+	<textarea name="content" id="content" style="width:900px; height:300px;"></textarea>
+	<p>
+		<input type="button" onclick="javascript:_onSubmit(this)" value="submit"></input>
+	</p>
+</form>
+
+<script type="text/javascript">
+var oEditors = [];
+nhn.husky.EZCreator.createInIFrame({
+	oAppRef: oEditors,
+	elPlaceHolder: "content",
+	sSkinURI: "SEditorSkin.html",
+	fCreator: "createSEditorInIFrame"
+});
+
+function _onSubmit(elClicked) {
+	oEditors.getById["content"].exec("UPDATE_IR_FIELD", []);
+	alert($('content').value);
+	try {
+		//elClicked.form.submit();
+	} catch (e) {}
+}
+</script>
+
+</body>
+</html>

+ 99 - 76
style24.admin/src/main/webapp/ux/css/admin.ui.css

@@ -39,7 +39,7 @@ html,body,#wrapper,#container {min-height:100%; height:100%;}
 
 /* 로그인 --------------- */
 .loginBg {background:#f3f3f4; overflow:hidden;}
-.loginWrap  {width:500px; box-shadow:0 7px 7px -5px rgba(0, 0, 0, 0.1);}
+.loginWrap {width:500px; box-shadow:0 7px 7px -5px rgba(0, 0, 0, 0.1);}
 .loginWrap .loginBox input[type=text],
 .loginWrap .loginBox input[type=password]{padding:10px; width:100%; border:1px solid #ced4da; border-radius:.25rem;}
 .loginWrap .loginBox li:nth-of-type(2), .loginBox li:nth-of-type(3) {padding-bottom:10px;}
@@ -101,8 +101,8 @@ header a, header button {color:#fff;}
 .tooltip:hover .tooltiptext {visibility:visible;}
 
 /* LNB--------------- */
-#lnb-wrapper {position:fixed; top:60px; left:-260px; width:260px; height:100%;vertical-align:top; overflow-y:auto; transition:left .3s; -webkit-transition:left .3s;}
-#lnb-wrapper:after{content:'';position:absolute;top:0;left:0;z-index:-1;width:100%;height:100%;background-color:#2f4050;}
+#lnb-wrapper {position:fixed; top:60px; left:-260px; width:260px; height:100%; vertical-align:top; overflow-y:auto; transition:left .3s; -webkit-transition:left .3s;}
+#lnb-wrapper:after{content:''; position:absolute; top:0; left:0; z-index:-1; width:100%; height:100%; background-color:#2f4050;}
 #lnb-wrapper.on {left:0;}
 #lnb {margin-bottom:60px; width:260px;}
 #lnb a {display:block; color:#a7b1c2;}
@@ -129,7 +129,7 @@ header a, header button {color:#fff;}
 
 /* 패널영역 스타일--------------- */
 .panelStyle {position:relative; margin:0 20px 30px 20px; padding:15px 15px 0; background-color:#fff; border-top:2px solid #dfe2e3; box-shadow:0 7px 7px -5px rgba(0, 0, 0, 0.04);}
-.panelStyle::after, .frmStyle::after{position:relative;bottom:-5px;content:'';display:block;border:1px solid rgba(255,255,255,0);}
+.panelStyle::after, .frmStyle::after{position:relative; bottom:-5px; content:''; display:block; border:1px solid rgba(255,255,255,0);}
 .panelStyle .panelTitle {margin:-15px -15px 0; padding:0 20px; line-height:40px; border-bottom:1px solid #e7eaec;}
 .panelStyle .panelControl {position:absolute; top:0; right:15px; color:#c4c4c4;}
 .panelStyle .panelControl i {padding:10px 10px; cursor:pointer;}
@@ -139,17 +139,17 @@ header a, header button {color:#fff;}
 .panelStyle h3 i {padding-right:5px}
 .panelStyle h4 {padding-left:23px; height:31px; line-height:31px; background:url('../../image/icon_h4.png') no-repeat 3px 50%; color:#666;}
 .panelStyle .panelBar {display:table; width:100%; padding-bottom:10px;}
-.panelStyle .panelBar::after{display:block; clear:both; content:'';}
 .panelStyle .panelBar h4 {margin-bottom:0;}
 .panelStyle .panelBar > li {display:table-cell;}
 .panelStyle .panelBar > .center {text-align:center;}
 .panelStyle .panelBar > .right {text-align:right;}
+
 /* 패널 내부 테이블 여러개 배치 */
 .panelStyle .division + .panelBar {padding-bottom:15px;}
 .panelStyle .division {display:table; width:100%;}
 .panelStyle .division li {display:table-cell; padding-right:40px;}
 .panelStyle .division li:last-child {padding-right:0;}
-/* table, grid, button 상하 여백  */
+/* table, grid, button 상하 여백 */
 .frmStyle, .ag-theme-balham{margin-bottom:15px !important;}
 .frmStyle + .panelBar {padding-bottom:15px;}
 .ag-theme-balham {margin:10px 0 15px;}
@@ -197,31 +197,31 @@ a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !import
 .tabsJrCont::after {display:block}
 .tabJr {display:none;}
 .tabJr .panelStyle{margin:0; border-top:1px solid #ddd; min-height:20px; padding:20px 15px 0; box-shadow:0 -5px 7px -5px rgba(0, 0, 0, 0.05);}
-.tabJr.on {display:block; }
+.tabJr.on {display:block;}
 .tabJrContArea {vertical-align:middle;}
 
 /* modal, modeless popup --------------- */
-.modalPopup{display:none;position:fixed; left:0; top:0; z-index:11; width:100%; height:100%;background:rgba(0,0,0,0.5);}
-.modalPopup > .panelStyle{position:absolute;top:50%;left:50%;z-index:11;-ms-transform:translate(-50%, -50%);transform:translate(-50%, -50%);margin:0;border:1px solid #79797a;border-radius:3px;}
-.modalPopup > .panelStyle .close {position:absolute;top:0;right:0;font-size:18px;padding:5px 15px 8px;}
+.modalPopup{display:none; position:fixed; left:0; top:0; z-index:11; width:100%; height:100%; background:rgba(0,0,0,0.5);}
+.modalPopup > .panelStyle{position:absolute; top:50%; left:50%; z-index:11; -ms-transform:translate(-50%, -50%); transform:translate(-50%, -50%); margin:0; border:1px solid #79797a; border-radius:3px;}
+.modalPopup > .panelStyle .close {position:absolute; top:0; right:0; font-size:18px; padding:5px 15px 8px;}
 .modalPopup .tabs{ margin:0;}
 .modalPopup .tabs .panelStyle{box-shadow:none}
 .modalPopup .tab > .panelStyle{overflow-y:auto;}
 
 /*MODELESS POPUP --------------- */
-.modelessPopup{display:none;position:absolute;z-index:11;top:50%;left:50%;}
+.modelessPopup{display:none; position:absolute; z-index:11; top:50%; left:50%;}
 .modelessPopup.draggable {cursor:move;}
-.modelessPopup .panelStyle{margin:0;border:1px solid #ccc;border-radius:3px;}
-.modelessPopup .panelStyle .close {position:absolute;top:0;right:0;font-size:18px;padding:5px 15px 8px;}
+.modelessPopup .panelStyle{margin:0; border:1px solid #ccc; border-radius:3px;}
+.modelessPopup .panelStyle .close {position:absolute; top:0; right:0; font-size:18px; padding:5px 15px 8px;}
 .modelessPopup .tabs{ margin:0;}
-.modelessPopup .tabs  .panelStyle{box-shadow:none}
+.modelessPopup .tabs .panelStyle{box-shadow:none}
 .modelessPopup .tab > .panelStyle{overflow-y:auto;}
 
 /*VIDEO POPUP --------------- */
-.videoPopup {display:none;position:fixed;top:50%;left:50%;z-index:11;-ms-transform:translate(-50%, -50%);transform:translate(-50%, -50%);margin:0;border:1px solid #79797a;border-radius:3px;}
-.modalPopup::before{position:fixed; left:0; top:0; z-index:11; width:100%; height:100%;background:rgba(0,0,0,0.5);}
+.videoPopup {display:none; position:fixed; top:50%; left:50%; z-index:11; -ms-transform:translate(-50%, -50%); transform:translate(-50%, -50%); margin:0; border:1px solid #79797a; border-radius:3px;}
+.modalPopup::before{position:fixed; left:0; top:0; z-index:11; width:100%; height:100%; background:rgba(0,0,0,0.5);}
 .videoPopup .close {position:absolute; top:-20px; right:-20px; z-index:1; width:40px; height:40px; line-height:20px; font-size:20px; border:1px solid #666; border-radius:50px; background-color:#fff;}
-.videoPopup iframe{width:100%;height:100%}
+.videoPopup iframe{width:100%; height:100%}
 
 
 #btnTop {display:none; position:fixed; right:0; bottom:50px; width:40px; line-height:10px; font-size:10px; background:#fff; border:1px solid #ddd; border-right:none; padding:3px 0 5px 0; box-shadow:5px 5px 5px -4px rgba(0, 0, 0, 0.07); color:#1c84c6;}
@@ -244,7 +244,7 @@ a, button, .ui-state-active, .ui-state-focus, .ui-state-hover {outline:0 !import
 .frmStyle tr:last-child th {border-bottom:1px solid #dae0fd;}
 .frmStyle tr:last-child td {border-bottom:1px solid #eee;}
 .frmStyle th {padding:0 15px; height:36px; line-height:24px; white-space:nowrap; text-align:center; background:#e9ecfb;}
-.frmStyle td {padding:0 10px 0 10px; line-height:36px; position:relative;border-top:1px solid #eee; border-right:1px solid #eee;}
+.frmStyle td {padding:0 10px 0 10px; line-height:36px; position:relative; border-top:1px solid #eee; border-right:1px solid #eee;}
 .frmBtnT {padding-bottom:10px; overflow:auto;}
 .frmBtnB {padding-top:10px; overflow:auto;}
 
@@ -327,7 +327,6 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .btn + .btn {margin-left:6px;}
 .btn:first-child {margin-left:0;}
 
-
 /* 버튼 색상 */
 .btn-white {color:#555 !important; background-color:#fff !important; border:1px solid #ccc !important;}
 .btn-default {color:#555; background-color:#eee; border:1px solid #dcdcdc;}
@@ -343,6 +342,12 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .btn.icn {line-height:28px; height:28px; padding:0 8px; background-color:#eee; border:1px solid #dbdbdb;}
 .btn.icn i {padding-top:6px; width:12px; vertical-align:top; font-size:14px; text-align:center;}
 
+/* 페이징 --------------- */
+.tablePaging {	position:relative; 	display:inline-block;}
+.tablePaging a {display:inline-block; float:left; margin:0 5px; width:28px; height:28px; line-height:28px; text-align:center; border:1px solid #ccc; border-radius:50px;}
+.tablePaging a.arrow {background-color:rgba(0, 0, 0, 0.03); 	border-color:#ebebeb;}
+.tablePaging .num.on {background:#8597eb; color:#fff; border-color:#8597eb;}
+
 /* 다중 Select Box */
 .mSelectWrap select {display:none;}
 .mSelectBox {display:inline-block; position:relative; top:-1px; margin:2px 0 2px 0; padding:0 7px 0 0; width:100%; height:auto !important; min-height:29px; border:1px solid #e5e6e7; vertical-align:middle;}
@@ -370,7 +375,7 @@ td[rowspan] {border-bottom:1px solid #eee;}
 .uFileLabel::after {position:absolute; top:0; right:0; bottom:0; width:30px; z-index:3; line-height:28px; content:" "; border-left:1px solid #dbdbdb; background:#eee url('../../image/icon_upload.png') no-repeat 50% 50%;}
 
 /* badge --------------- */
-.badge {float:right; margin-top:2px; padding:0 5px; min-width:9px; line-height:18px; color:#fff; font-size:12px; font-weight:600; border-radius:3px; text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,0.4); letter-spacing:-0.5px;}
+.badge {float:right; margin-top:2px; padding:0 5px; min-width:9px; line-height:18px; color:#fff; font-size:12px; font-weight:600; border-radius:3px; text-align:center; text-shadow:1px 1px 1px rgba(0,0,0,0.4); letter-spacing:-0.5px;}
 .badge-warning {background-color:#ed7908;}
 .badge-primary {background-color:#1ab394;}
 .badge-danger {background-color:#ed5565;}
@@ -455,45 +460,63 @@ p.dot em {color:red;}
 
 /* COLOR DESIGN -------------------------------------*/
 /*Color :Base ---*/
-.color-base header, span.color-base {background:linear-gradient(135deg,#667eea 0,#764ba2 100%) !important;}
-.color-purple header, span.color-purple {background:#667eea !important;}
+.color-mPurple header,span.color-mPurple {background:linear-gradient(135deg,#667eea 0,#764ba2 100%) !important;}
+.color-purple header,span.color-purple {background:#667eea !important;}
 
 /*Color :Gray ---*/
-.color-mGray header, span.color-mGray {background:linear-gradient(to right,#6c757d 0%,#555 100%) !important;}
-.color-gray header, span.color-gray {background:#666 !important;}
-.color-mGray .frmStyle th, .color-mGray .tableStyle th, .color-gray .frmStyle th, .color-gray .tableStyle th {background:#eee !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
-.color-mGray #lnb .dep3, .color-gray #lnb .dep3 {border-color:#777 !important;}
+.color-mGray header,span.color-mGray {background:linear-gradient(to right,#6c757d 0%,#555 100%) !important;}
+.color-gray header,span.color-gray {background:#666 !important;}
+.color-mGray .frmStyle th,.color-mGray .tableStyle th,.color-gray .frmStyle th,.color-gray .tableStyle th {	background:#eee !important; 	border-top:1px solid #ddd; 	border-bottom:1px solid #ddd;}
+.color-mGray .tablePaging .num.on,.color-gray .tablePaging .num.on {	background:#888 !important; 	border-color:#888 !important;}
+.color-mGray #lnb .dep3,.color-gray #lnb .dep3 {border-color:#777 !important;}
+.color-mGray .tabsJrNav li.on a,.color-gray .tabsJrNav li.on a {color:#333;}
 
 /*Color :Blue ---*/
-.color-mBlue header, span.color-mBlue {background:linear-gradient(to right,#4481eb 0%,#04befe 100%) !important;}
-.color-blue header, span.color-blue {background:#0042a5 !important;}
-.color-mBlue .frmStyle th, .color-mBlue .tableStyle th, .color-blue .frmStyle th, .color-blue .tableStyle th {background:#d8eafc !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
-.color-mBlue #lnb .dep3, .color-blue #lnb .dep3 {border-color:#3e91de !important;}
+.color-mBlue header,span.color-mBlue {background:linear-gradient(to right,#4481eb 0%,#04befe 100%) !important;}
+.color-blue header,span.color-blue {background:#0042a5 !important;}
+.color-mBlue .frmStyle th,.color-mBlue .tableStyle th,.color-blue .frmStyle th,.color-blue .tableStyle th {	background:#d8eafc !important; 	border-top:1px solid #ddd; 	border-bottom:1px solid #ddd;}
+.color-mBlue .tablePaging .num.on,.color-blue .tablePaging .num.on {	background:#3e91de !important; 	border-color:#3e91de !important;}
+.color-mBlue #lnb .dep3,.color-blue #lnb .dep3 {border-color:#3e91de !important;}
+.color-mBlue .tabsJrNav li.on a,.color-blue .tabsJrNav li.on a {background:#d8eafc;}
+.color-mBlue .tabJr.on,.color-blue .tabJr.on {border-top:4px solid #d8eafc;}
+.color-mBlue .tabsJrNav li.on a,.color-blue .tabsJrNav li.on a {color:#333;}
 
 /*Color :Green ---*/
-.color-mGreen header, span.color-mGreen {background:linear-gradient(135deg,#00b09b 0,#96c93d 100%) !important;}
-.color-green header, span.color-green {background:#00b09b !important;}
-.color-mGreen .frmStyle th, .color-mGreen .tableStyle th, .color-green .frmStyle th, .color-green .tableStyle th {background:#e5f7f5 !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
-.color-mGreen #lnb .dep3, .color-green #lnb .dep3 {border-color:#00b09b !important;}
+.color-mGreen header,span.color-mGreen {background:linear-gradient(135deg,#00b09b 0,#96c93d 100%) !important;}
+.color-green header,span.color-green {background:#00b09b !important;}
+.color-mGreen .frmStyle th,.color-mGreen .tableStyle th,.color-green .frmStyle th,.color-green .tableStyle th {	background:#e5f7f5 !important; 	border-top:1px solid #ddd; 	border-bottom:1px solid #ddd;}
+.color-mGreen .tablePaging .num.on,.color-green .tablePaging .num.on {	background:rgba(0,176,155,0.8); 	border-color:rgba(0,176,155,0.8) !important;}
+.color-mGreen #lnb .dep3,.color-green #lnb .dep3 {border-color:#00b09b !important;}
+.color-mGreen .tabsJrNav li.on a,.color-green .tabsJrNav li.on a {background:#e5f7f5;}
+.color-mGreen .tabJr.on,.color-green .tabJr.on {border-top:4px solid #e5f7f5;}
+.color-mGreen .tabsJrNav li.on a,.color-green .tabsJrNav li.on a {color:#333;}
 
 /*Color :Pink ---*/
-.color-mPink header, span.color-mPink {background:linear-gradient(to right, rgb(242, 112, 156), rgb(255, 148, 114)) !important;}
-.color-pink header, span.color-pink {background:#feada6 !important;}
-.color-mPink .frmStyle th, .color-mPink .tableStyle th, .color-pink .frmStyle th, .color-pink .tableStyle th {background:#fff7f6 !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
-.color-mPink #lnb .dep3, .color-pink #lnb .dep3 {border-color:#feada6 !important;}
+.color-mPink header,span.color-mPink {background:linear-gradient(to right, rgb(242, 112, 156), rgb(255, 148, 114)) !important;}
+.color-pink header,span.color-pink {background:#feada6 !important;}
+.color-mPink .frmStyle th,.color-mPink .tableStyle th,.color-pink .frmStyle th,.color-pink .tableStyle th {background:#fff7f6 !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
+.color-mPink .tablePaging .num.on,.color-pink .tablePaging .num.on {background:#feada6; 	border-color:#feada6 !important;}
+.color-mPink #lnb .dep3,.color-pink #lnb .dep3 {border-color:#feada6 !important;}
+.color-mPink .tabsJrNav li.on a,.color-pink .tabsJrNav li.on a {background:#fff7f6;}
+.color-mPink .tabJr.on,.color-pink .tabJr.on {border-top:4px solid #fff7f6;}
+.color-mPink .tabsJrNav li.on a,
+.color-pink .tabsJrNav li.on a {color:#333;}
 
 /*Color : wivis ---*/
-.color-black header, span.color-black {background:#3E3E3E !important;}
-.color-black .header-logo {background:#000 !important;}
-.color-black .header-menu .menu a {background:#000 !important;}
-.color-black .header-menu .menu a.on {background:#fff !important; color:#000 !important;}
-.color-black #lnb-wrapper {background-color:#b2b2b2 !important;}
-.color-black #lnb .dep2 {background-color:#545454 !important;}
-.color-black #lnb .dep3 {border-color:#000 !important;}
-.color-black #lnb .dep3 {background:#fdfdfd !important;}
-.color-black #lnb .dep3 a {color:#111111 !important;}
-.color-black #lnb a {color:#fff !important;}
-.color-black .frmStyle th, .color-black .tableStyle th, .color-black .frmStyle th, .color-black .tableStyle th {background:#eee !important; border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
+.color-wivis header, span.color-wivis{background:#3E3E3E !important;}
+.color-wivis .header-logo{background:#000 !important;}
+.color-wivis .header-menu .menu a{background:#000 !important;}
+.color-wivis .header-menu .menu a.on{background:#fff !important; color:#000 !important;}
+.color-wivis #lnb-wrapper{background-color:#b2b2b2 !important;}
+.color-wivis #lnb .dep2{background-color:#545454 !important;}
+.color-wivis #lnb .dep3{border-color:#000 !important;}
+.color-wivis #lnb .dep3{background:#fdfdfd !important;  }
+.color-wivis #lnb .dep3 a{color:#111111 !important;}
+.color-wivis #lnb a{color:#fff !important;}
+.color-wivis .frmStyle th, .color-wivis .tableStyle th, .color-wivis .frmStyle th, .color-wivis .tableStyle th{	background:#eee !important; 	border-top:1px solid #ddd; border-bottom:1px solid #ddd;}
+.color-wivis .tablePaging .num.on, .color-wivis .tablePaging .num.on{background:#888 !important; 	border-color:#888 !important;}
+.color-wivis .tabsJrNav li.on a, .color-wivis .tabsJrNav li.on a{color:#333; background:#eee !important}
+.color-wivis .tabJr.on, .color-wivis .tabJr.on { border-top: 4px solid #eee;}
 
 /* 폰트 컬러, 폰트 두께 */
 .cBlue {color:#127fdc !important;}
@@ -592,7 +615,7 @@ hr {border:0; padding-bottom:10px;}/* 기본 여백 :10px */
 .memAdd button:hover {background:#eee url('../../image/btn_sltCloseOn.png') no-repeat 50% 50%;}
 
 /*-- Date Picker --------------*/ /* 20200521 수정 */
-table.mtz-monthpicker {border:1px solid #ddd; border-top:none; }
+table.mtz-monthpicker {border:1px solid #ddd; border-top:none;}
 .mtz-monthpicker-month {padding:7px; cursor:pointer;}
 .ui-datepicker-trigger {padding:0;}
 .ui-datepicker {z-index:800 !important; text-align:center; background:#fff;}
@@ -719,7 +742,7 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none; }
 .flexWrap.unit6 li{width: calc(16.6%);}
 .flexWrap .title{padding: 15px; font-weight: 600; border:1px solid #e7eaec; border-top:2px solid #e7eaec;}
 .flexWrap .title h5{font-size:15px; font-weight: bold;}
-.flexWrap .title span{float:right; padding:1px 8px;font-size: 10px; border-radius: 0.25em; }
+.flexWrap .title span{float:right; padding:1px 8px; font-size: 10px; border-radius: 0.25em;}
 .flexWrap .content{padding: 15px; border:1px solid #e7eaec; border-top:none;}
 .flexWrap .content em{font-size:30px; font-weight: 200;}
 .statText {margin-top:5px}
@@ -752,8 +775,8 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none; }
 
 /* 반응형:GNB 유저명,등급,로그아웃 --------------- */
 @media ( max-width:1370px ) {
- .header-info { display:none; }
- .header-info-sm { display:inline-block; }
+ .header-info { display:none;}
+ .header-info-sm { display:inline-block;}
 }
 
 /* 반응형 : dashboard(20200522) --------------- */
@@ -764,7 +787,7 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none; }
  .dashboard #lnb-wrapper{display:none;}
  .dashboard .header-menu{display:none;}
  .dashboard .tabs{margin-left:0; margin-right: 0;}
- .dashboard .tabs h2{position:relative;margin:10px 15px}
+ .dashboard .tabs h2{position:relative; margin:10px 15px}
  .dashboard .tabsNav li:first-child{margin-left:0}
  .dashboard .tabsNav li:last-child{margin-right:0}
  .dashboard .tabsNav li a{font-size:16px}
@@ -779,36 +802,36 @@ table.mtz-monthpicker {border:1px solid #ddd; border-top:none; }
 
 /* Fix Input Zoom on devices older than iPhone 5: */
 @media screen and (device-aspect-ratio: 2/3) {
-    select, textarea, input[type="text"], input[type="password"],
-    input[type="datetime"], input[type="datetime-local"],
-    input[type="date"], input[type="month"], input[type="time"],
-    input[type="week"], input[type="number"], input[type="email"],
-    input[type="url"]{ font-size: 16px; }
+  select, textarea, input[type="text"], input[type="password"],
+  input[type="datetime"], input[type="datetime-local"],
+  input[type="date"], input[type="month"], input[type="time"],
+  input[type="week"], input[type="number"], input[type="email"],
+  input[type="url"]{ font-size: 16px;}
 }
 
 /* Fix Input Zoom on iPhone 5, 5C, 5S, iPod Touch 5g */
 @media screen and (device-aspect-ratio: 40/71) {
-    select, textarea, input[type="text"], input[type="password"],
-    input[type="datetime"], input[type="datetime-local"],
-    input[type="date"], input[type="month"], input[type="time"],
-    input[type="week"], input[type="number"], input[type="email"],
-    input[type="url"]{ font-size: 16px; }
+  select, textarea, input[type="text"], input[type="password"],
+  input[type="datetime"], input[type="datetime-local"],
+  input[type="date"], input[type="month"], input[type="time"],
+  input[type="week"], input[type="number"], input[type="email"],
+  input[type="url"]{ font-size: 16px;}
 }
 
-/* Fix Input Zoom on iPhone 6, iPhone 6s, iPhone 7  */
+/* Fix Input Zoom on iPhone 6, iPhone 6s, iPhone 7 */
 @media screen and (device-aspect-ratio: 375/667) {
-    select, textarea, input[type="text"], input[type="password"],
-    input[type="datetime"], input[type="datetime-local"],
-    input[type="date"], input[type="month"], input[type="time"],
-    input[type="week"], input[type="number"], input[type="email"],
-    input[type="url"]{ font-size: 16px; }
+  select, textarea, input[type="text"], input[type="password"],
+  input[type="datetime"], input[type="datetime-local"],
+  input[type="date"], input[type="month"], input[type="time"],
+  input[type="week"], input[type="number"], input[type="email"],
+  input[type="url"]{ font-size: 16px;}
 }
 
-/* Fix Input Zoom on iPhone 6 Plus, iPhone 6s Plus, iPhone 7 Plus, iPhone 8, iPhone X, XS, XS Max  */
+/* Fix Input Zoom on iPhone 6 Plus, iPhone 6s Plus, iPhone 7 Plus, iPhone 8, iPhone X, XS, XS Max */
 @media screen and (device-aspect-ratio: 9/16) {
-    select, textarea, input[type="text"], input[type="password"],
-    input[type="datetime"], input[type="datetime-local"],
-    input[type="date"], input[type="month"], input[type="time"],
-    input[type="week"], input[type="number"], input[type="email"],
-    input[type="url"]{ font-size: 16px; }
+  select, textarea, input[type="text"], input[type="password"],
+  input[type="datetime"], input[type="datetime-local"],
+  input[type="date"], input[type="month"], input[type="time"],
+  input[type="week"], input[type="number"], input[type="email"],
+  input[type="url"]{ font-size: 16px;}
 }

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

@@ -91,7 +91,7 @@ var cfnOpenGoodsDetailPopup = function(mode, goodsCd) {
 	if (typeof(goodsCd) != "undefined") {
 		actionUrl += "&goodsCd=" + goodsCd;
 	}
-	uifnPopClose('popupGoodsDetail');
+	uiPopupClose('popupGoodsDetail');
 	cfnOpenModalPopup(actionUrl, 'popupGoodsDetail');
 }
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini