Просмотр исходного кода

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

jsh77b 5 лет назад
Родитель
Сommit
0495f7d3eb
34 измененных файлов с 2450 добавлено и 100 удалено
  1. 10 0
      src/main/java/com/style24/front/biz/dao/TsfCouponDao.java
  2. 18 0
      src/main/java/com/style24/front/biz/dao/TsfGoodsDao.java
  3. 12 0
      src/main/java/com/style24/front/biz/dao/TsfOrderChangeDao.java
  4. 27 0
      src/main/java/com/style24/front/biz/dao/TsfReviewDao.java
  5. 40 0
      src/main/java/com/style24/front/biz/service/TsfCouponService.java
  6. 44 3
      src/main/java/com/style24/front/biz/service/TsfGoodsService.java
  7. 58 0
      src/main/java/com/style24/front/biz/service/TsfOrderChangeService.java
  8. 19 0
      src/main/java/com/style24/front/biz/service/TsfPlanningService.java
  9. 37 0
      src/main/java/com/style24/front/biz/service/TsfReviewService.java
  10. 52 6
      src/main/java/com/style24/front/biz/web/TsfDisplayController.java
  11. 192 28
      src/main/java/com/style24/front/biz/web/TsfMypageController.java
  12. 49 4
      src/main/java/com/style24/front/biz/web/TsfPlanningController.java
  13. 7 1
      src/main/java/com/style24/persistence/domain/Cate4Srch.java
  14. 10 1
      src/main/java/com/style24/persistence/domain/Goods.java
  15. 2 0
      src/main/java/com/style24/persistence/domain/MainLayout.java
  16. 7 3
      src/main/java/com/style24/persistence/domain/Review.java
  17. 66 1
      src/main/java/com/style24/persistence/mybatis/shop/TsfCoupon.xml
  18. 1 1
      src/main/java/com/style24/persistence/mybatis/shop/TsfDisplay.xml
  19. 303 0
      src/main/java/com/style24/persistence/mybatis/shop/TsfGoods.xml
  20. 97 0
      src/main/java/com/style24/persistence/mybatis/shop/TsfOrderChange.xml
  21. 206 0
      src/main/java/com/style24/persistence/mybatis/shop/TsfReview.xml
  22. 2 1
      src/main/webapp/WEB-INF/views/web/common/fragments/HeadWeb.html
  23. 83 2
      src/main/webapp/WEB-INF/views/web/display/BrandMainFormWeb.html
  24. 273 0
      src/main/webapp/WEB-INF/views/web/display/CategoryMainFormWeb.html
  25. 1 1
      src/main/webapp/WEB-INF/views/web/goods/GoodsIncludeFormWeb.html
  26. 0 3
      src/main/webapp/WEB-INF/views/web/mypage/MypageCouponDetailPopWeb.html
  27. 3 2
      src/main/webapp/WEB-INF/views/web/mypage/MypageGiftcardFormWeb.html
  28. 23 21
      src/main/webapp/WEB-INF/views/web/mypage/MypageOrderDetailFormWeb.html
  29. 9 7
      src/main/webapp/WEB-INF/views/web/mypage/MypageOrderListFormWeb.html
  30. 562 0
      src/main/webapp/WEB-INF/views/web/mypage/MypageReviewCreateFormWeb.html
  31. 192 0
      src/main/webapp/WEB-INF/views/web/mypage/MypageReviewFormWeb.html
  32. 41 5
      src/main/webapp/WEB-INF/views/web/planning/PlanningDetailFormWeb.html
  33. 1 1
      src/main/webapp/ux/pc/css/common.css
  34. 3 9
      src/main/webapp/ux/style24_link.js

+ 10 - 0
src/main/java/com/style24/front/biz/dao/TsfCouponDao.java

@@ -88,6 +88,16 @@ public interface TsfCouponDao {
 	 */
 	Coupon getCouponDetailInfo(int cpnId);
 	
+	/**
+	 * 마이페이지 등급쿠폰 다운가능 쿠폰 정보 조회
+	 * 
+	 * @param coupon
+	 * @return Collection<Coupon>
+	 * @author sowon
+	 * @since 2021.03.24
+	 */
+	Collection<Coupon> getPlanCouponInfo(Coupon coupon);
+	
 	
 	
 }

+ 18 - 0
src/main/java/com/style24/front/biz/dao/TsfGoodsDao.java

@@ -305,4 +305,22 @@ public interface TsfGoodsDao {
 	 */
 	Collection<Goods> getRecentlyGoodsList(Goods goods);
 
+	/**
+	 * 컨텐츠카테고리상품 목록
+	 * @param cate - 카테고리 정보
+	 * @return
+	 * @author gagamel
+	 * @date 2021. 3. 25
+	 */
+	Collection<Goods> getContentsCategoryGoodsList(Cate4Srch cate);
+
+	/**
+	 * 컨텐츠카테고리 신규상품 목록
+	 * @param cate - 카테고리 정보
+	 * @return
+	 * @author gagamel
+	 * @date 2021. 3. 25
+	 */
+	Collection<Goods> getContentsCategoryNewGoodsList(Cate4Srch cate);
+
 }

+ 12 - 0
src/main/java/com/style24/front/biz/dao/TsfOrderChangeDao.java

@@ -5,6 +5,7 @@ import java.util.Collection;
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.GiftCard;
 import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
 import com.style24.persistence.domain.Point;
 
 /**
@@ -56,4 +57,15 @@ public interface TsfOrderChangeDao {
 	 */
 	Collection<Point> getUsedPointInfo(Order order);
 
+
+	/**
+	 * 마이페이지 취소/반품 환불 사전 정보 조회
+	 *
+	 * @param Order
+	 * @return Collection<Order>
+	 * @author card007
+	 * @since 2021. 03. 25
+	 */
+	Collection<Order> getRefundPreInfo(OrderChange orderChange);
+
 }

+ 27 - 0
src/main/java/com/style24/front/biz/dao/TsfReviewDao.java

@@ -60,6 +60,33 @@ public interface TsfReviewDao {
 	 * @since 2021. 3. 19
 	 */
 	Collection<Goods> getReviewOptionList(String goodsCd);
+	
+	/**
+	 * 마이페이지 작성가능한 리뷰 건수
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	int getCompleteReviewCount(Review review);
+	
+	/**
+	 * 마이페이지 작성가능한 리뷰 목록
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	Collection<Review> getCompleteReviewList(Review review);
+	
+	/**
+	 * 마이페이지 리뷰 등록
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	void saveMypageReview(Review review);
 
 
 }

+ 40 - 0
src/main/java/com/style24/front/biz/service/TsfCouponService.java

@@ -425,4 +425,44 @@ public class TsfCouponService {
 	}
 	
 	
+	/**
+	 * 기획전 쿠폰 다운 처리
+	 *
+	 * @param coupon
+	 * @return Collection<Coupon>
+	 * @author card007
+	 * @since 2021.02.25
+	 */
+	@Transactional("shopTxnManager")
+	public int getPlanCouponInfo(Coupon coupon) {
+		int count = 0;
+
+		Collection<Coupon> couponList = couponDao.getPlanCouponInfo(coupon);
+
+		for (Coupon tmpCoupon : couponList) {
+			//int downloadCnt = tmpCoupon.getDownloadCnt();
+			for (int i = 0; i < couponList.size(); i++) {
+				if(couponList.iterator().next().getOwnCoupon()==0) {
+					CustCoupon custCoupon = new CustCoupon();
+					custCoupon.setCustNo(tmpCoupon.getCustNo());
+					custCoupon.setCpnId(tmpCoupon.getCpnId());
+					custCoupon.setAvailStdt(tmpCoupon.getAvailStdt());
+					custCoupon.setAvailEddt(tmpCoupon.getAvailEddt());
+					custCoupon.setPubReason(TscConstants.PubReason.DOWNLOAD.value());
+					custCoupon.setEndAlimSendYn("N");		// 알림 발송 여부(발송되면 Y)
+					custCoupon.setRegNo(tmpCoupon.getCustNo());
+					custCoupon.setUpdNo(tmpCoupon.getCustNo());
+
+					coreCouponDao.saveCouponCustPub(custCoupon);
+
+					count++;
+
+				}
+			}
+		}
+
+		return count;
+	}
+
+	
 }

+ 44 - 3
src/main/java/com/style24/front/biz/service/TsfGoodsService.java

@@ -1,5 +1,6 @@
 package com.style24.front.biz.service;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 import org.apache.commons.lang3.StringUtils;
@@ -413,8 +414,7 @@ public class TsfGoodsService {
 
 		return result;
 	}
-	
-	
+
 	/**
 	 * 세트 상품 사이즈 선택 시 재고수량 가져오기
 	 *
@@ -466,7 +466,6 @@ public class TsfGoodsService {
 		}
 		result = ableOrderCnt;	//주문 가능 수량
 
-
 		if (returnFlag) {
 			return 0;
 		}
@@ -684,4 +683,46 @@ public class TsfGoodsService {
 		return goodsDao.getRecentlyGoodsList(goods);
 	}
 
+	/**
+	 * 컨텐츠카테고리상품 목록
+	 * @param cate - 카테고리 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 3. 25
+	 */
+	public Collection<Goods> getContentsCategoryGoodsList(Cate4Srch cate) {
+		cate.setSiteCd(TscConstants.Site.STYLE24.value());
+		cate.setFrontGb(TsfSession.getFrontGb());
+		cate.setCustGb(TsfSession.getCustGb());
+		cate.setCustNo(TsfSession.isLogin() ? TsfSession.getInfo().getCustNo() : 0);
+
+		Collection<Goods> goodsList = new ArrayList<>();
+
+		if (cate.getContentsLoc().equals("SCM001")) { // 신상품인 경우
+			goodsList = goodsDao.getContentsCategoryGoodsList(cate);
+
+			// 조회된 데이터가 없거나 건수가 20개 미만이면 신규상품(=정상상품) 조회
+			if (goodsList == null || goodsList.size() < 20) {
+				if (goodsList != null) {
+					// 제외상품 설정
+					StringBuilder sb = new StringBuilder();
+					for (Goods goods : goodsList) {
+						sb.append(goods.getGoodsCd()).append(",");
+					}
+					if (sb != null && !sb.toString().equals("")) {
+						cate.setExceptGoodsArr(sb.toString().substring(0, sb.toString().length() - 1).split(","));
+					}
+				}
+				goodsList.addAll(goodsDao.getContentsCategoryNewGoodsList(cate));
+			}
+		} else if (cate.getContentsLoc().equals("SCM002")) { // 베스트상품인 경우
+			// TODO: 추천솔루션
+
+			// 추천솔루션 데이터가 없으면 베스트로 등록된 상품 조회
+			goodsList = goodsDao.getContentsCategoryGoodsList(cate);
+		}
+
+		return goodsList;
+	}
+
 }

+ 58 - 0
src/main/java/com/style24/front/biz/service/TsfOrderChangeService.java

@@ -1,17 +1,21 @@
 package com.style24.front.biz.service;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import com.gagaframework.web.parameter.GagaMap;
 import com.style24.core.biz.service.TscOrderChangeService;
+import com.style24.core.support.env.TscConstants;
 import com.style24.front.biz.dao.TsfOrderChangeDao;
 import com.style24.persistence.domain.GiftCard;
 import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
 import com.style24.persistence.domain.Point;
 
 import lombok.extern.slf4j.Slf4j;
@@ -119,4 +123,58 @@ public class TsfOrderChangeService {
 		return orderChangeDao.getUsedPointInfo(order);
 	}
 
+	/**
+	 * 마이페이지 취소/반품 환불 사전 정보 조회
+	 *
+	 * @param Order
+	 * @return Collection<Order>
+	 * @author card007
+	 * @since 2021. 03. 25
+	 */
+	public GagaMap getRefundPreInfo(OrderChange orderChange) {
+		GagaMap result = new GagaMap();
+		List<Order> cnclReqList = new ArrayList<>();
+
+		// 취소/반품 신청 정보 설정
+		int[] ordDtlNoArr = orderChange.getOrdDtlNoArr();
+		int[] cnclRtnReqQtyArr = orderChange.getCnclRtnReqQtyArr();
+		List<Integer> ordDtlNoList = Arrays.stream(ordDtlNoArr).boxed().collect(Collectors.toList());
+
+		// 환불 사전 정보 조회
+		Collection<Order> cnclRtnList = orderChangeDao.getRefundPreInfo(orderChange);
+		Order cnclRtn = cnclRtnList.iterator().next();
+
+		// 전체 취소여부 설정
+		String allCanYn = "Y";
+		for (Order order : cnclRtnList) {
+			int index = ordDtlNoList.indexOf(order.getOrdDtlNo());
+			if ("Y".equals(allCanYn) && (index < 0 || cnclRtnReqQtyArr[index] != order.getOrdQty())) {
+				allCanYn = "N";
+			}
+		}
+
+		// 무통장입금 전 전체 취소여부 설정
+		String allCanYnBeforePayment = "N";
+		if ("Y".equals(allCanYn) && TscConstants.PayMeans.BANK_DEPOSIT.value().equals(cnclRtn.getPayMeans()) && TscConstants.PaymentStat.PAYMENT_WAIT.value().equals(cnclRtn.getPayStat())) {
+			allCanYnBeforePayment = "Y";
+		}
+		
+		// 전체 취소여부 및 취소/반품 수량 설정
+		for (Order order : cnclRtnList) {
+			// 변경 수량 설정
+			int index = ordDtlNoList.indexOf(order.getOrdDtlNo());
+			if (index >= 0) {
+				order.setOrdCanChgQty(cnclRtnReqQtyArr[index]);
+				order.setAllCanYn(allCanYn);
+				cnclReqList.add(order);
+			}
+		}
+		
+		
+		result.setString("allCanYn", allCanYnBeforePayment);
+		result.set("cnclReqList", cnclReqList);
+
+		return result;
+	}
+
 }

+ 19 - 0
src/main/java/com/style24/front/biz/service/TsfPlanningService.java

@@ -10,11 +10,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import com.style24.core.support.env.TscConstants;
 import com.style24.front.biz.dao.TsfPlanningDao;
 import com.style24.front.support.env.TsfConstants;
 import com.style24.front.support.security.session.TsfSession;
 import com.style24.persistence.domain.Cate4Srch;
 import com.style24.persistence.domain.Coupon;
+import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.Login;
 import com.style24.persistence.domain.Plan;
 import com.style24.persistence.domain.Point;
@@ -35,6 +37,9 @@ public class TsfPlanningService {
 	@Autowired
 	private TsfPlanningDao planningDao;
 	
+	@Autowired
+	private TsfCouponService couponService;
+	
 	/**
 	 * 기획전 카테고리 1deth 조회
 	 *
@@ -182,6 +187,20 @@ public class TsfPlanningService {
 	public Collection<Plan> getPlanGoods1Info(Plan plan) {
 		return planningDao.getPlanGoods1Info(plan);
 	}
+	
+	/**
+	 * 상품 쿠폰 다운 처리
+	 *
+	 * @param coupon
+	 * @return 
+	 * @author sowon
+	 * @since 2021.03.24
+	 */
+	@Transactional("shopTxnManager")
+	public int getPlanCouponDownInfo(Coupon coupon) {
+		return couponService.getPlanCouponInfo(coupon);
+	}
+
 
 
 	/**

+ 37 - 0
src/main/java/com/style24/front/biz/service/TsfReviewService.java

@@ -66,4 +66,41 @@ public class TsfReviewService {
 		 return reviewDao.getReviewOptionList(goodsCd);
 	}
 	
+	/**
+	 * 마이페이지 작성가능한 리뷰 건수
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	public int getCompleteReviewCount(Review review) {
+		return reviewDao.getCompleteReviewCount(review);
+	}
+	
+	/**
+	 * 마이페이지 작성가능한 리뷰 목록
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	public Collection<Review> getCompleteReviewList(Review review){
+		return reviewDao.getCompleteReviewList(review);
+	}
+	
+	/**
+	 * 마이페이지 리뷰 등록
+	 * @param review
+	 * @return 
+	 * @author sowon
+	 * @since 2021. 3. 25
+	 */
+	public void saveMypageReview(Review review) {
+		review.setDispYn("Y");
+		review.setDelYn("N");
+		review.setRegNo(review.getCustNo());
+		review.setUpdNo(review.getCustNo());
+		reviewDao.saveMypageReview(review);
+	}
+	
 }

+ 52 - 6
src/main/java/com/style24/front/biz/web/TsfDisplayController.java

@@ -7,6 +7,14 @@ import java.util.HashMap;
 
 import javax.servlet.http.HttpServletResponse;
 
+import com.style24.core.biz.service.TscLookbookService;
+import com.style24.persistence.domain.Lookbook;
+import com.style24.persistence.domain.MainLayout;
+import com.style24.persistence.domain.Contents;
+import com.style24.persistence.domain.GnbTab;
+import com.style24.persistence.domain.Cate4Srch;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.BrandGroup;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.mobile.device.Device;
@@ -20,14 +28,9 @@ import org.springframework.web.servlet.ModelAndView;
 import com.style24.core.biz.service.TscEnvsetService;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.front.biz.service.TsfDisplayService;
+import com.style24.front.biz.service.TsfGoodsService;
 import com.style24.front.support.controller.TsfBaseController;
 import com.style24.front.support.security.session.TsfSession;
-import com.style24.persistence.domain.BrandGroup;
-import com.style24.persistence.domain.Cate4Srch;
-import com.style24.persistence.domain.Contents;
-import com.style24.persistence.domain.GnbTab;
-import com.style24.persistence.domain.GoodsSearch;
-import com.style24.persistence.domain.MainLayout;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -51,6 +54,11 @@ public class TsfDisplayController extends TsfBaseController {
 	@Autowired
 	private TscEnvsetService envsetService;
 
+	@Autowired
+	private TsfGoodsService goodsService;
+	@Autowired
+	private TscLookbookService coreLookbookService;
+
 	/**
 	 * 몰 메인
 	 * @return
@@ -220,6 +228,16 @@ public class TsfDisplayController extends TsfBaseController {
 			if ("C".equals(brandMain.getContentsYn())) {
 				brandMain.setContentsList(displayService.getContentsList(contents));
 			}
+
+			// 룩북일때
+			if("SBM010".equals(brandMain.getContentsLoc()) || "SBMM010".equals(brandMain.getContentsLoc())){
+				Lookbook lookbookMst = new Lookbook();
+				Lookbook lookbook = new Lookbook();
+				lookbook.setBrandCd(paramMap.get("brandGroupNo"));
+				lookbook.setMainDispYn("Y");
+
+				brandMain.setLookbookList(coreLookbookService.getLookbookListForGoods(lookbook));
+			}
 			brandMainLayoutList.add(brandMain);
 		}
 		log.info("brandMainLayoutList::{}", brandMainLayoutList);
@@ -244,4 +262,32 @@ public class TsfDisplayController extends TsfBaseController {
 		return displayService.getGnbTabList(gnbTab);
 	}
 
+	/**
+	 * 카테고리 메인
+	 * @param cate - 카테고리 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 3. 25
+	 */
+	@GetMapping("/category/main/form")
+	public ModelAndView categoryMain(Cate4Srch cate) {
+		ModelAndView mav = new ModelAndView(super.getDeviceViewName("display/CategoryMainForm"));
+
+		// 기획전
+
+		// 신상품
+		cate.setContentsLoc("SCM001");
+		cate.setMaxRow(20);
+		mav.addObject("newGoodsList", goodsService.getContentsCategoryGoodsList(cate));
+
+		// 베스트품
+		cate.setContentsLoc("SCM002");
+		cate.setMaxRow(20);
+		mav.addObject("bestGoodsList", goodsService.getContentsCategoryGoodsList(cate));
+
+		mav.addObject("params", cate);
+
+		return mav;
+	}
+
 }

+ 192 - 28
src/main/java/com/style24/front/biz/web/TsfMypageController.java

@@ -1,5 +1,24 @@
 package com.style24.front.biz.web;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+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.servlet.ModelAndView;
+
 import com.gagaframework.web.parameter.GagaMap;
 import com.gagaframework.web.rest.server.GagaResponse;
 import com.gagaframework.web.rest.server.GagaResponseStatus;
@@ -24,6 +43,7 @@ import com.style24.front.biz.thirdparty.NiceCertify;
 import com.style24.front.support.controller.TsfBaseController;
 import com.style24.front.support.security.session.TsfSession;
 import com.style24.persistence.TscPageRequest;
+import com.style24.persistence.domain.Counsel;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.CustAccount;
 import com.style24.persistence.domain.Customer;
@@ -31,25 +51,10 @@ import com.style24.persistence.domain.GiftCard;
 import com.style24.persistence.domain.Order;
 import com.style24.persistence.domain.OrderChange;
 import com.style24.persistence.domain.Point;
+import com.style24.persistence.domain.Review;
 import com.style24.persistence.domain.WishList;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-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.servlet.ModelAndView;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * 마이페이지 Controller
@@ -237,13 +242,9 @@ public class TsfMypageController extends TsfBaseController {
 		ModelAndView mav = new ModelAndView();
 
 		// 페이징 처리 설정
-		// order.setPageable(new TscPageRequest(order.getPageNo() - 1, 5));
 		TscPageRequest pageable = new TscPageRequest((order.getPageNo() > 0 ? order.getPageNo() - 1 : 0), order.getPageSize(), order.getPageUnit());
 		pageable.setTotalCount(orderService.getPagingOrdNoListCount(order));
 		order.setPageable(pageable);
-		log.info("pageable: {}", pageable);
-		log.info("totalCount {}", pageable.getTotalCount());
-		log.info("order >>> {}", order);
 
 		// 페이징 처리 및 주문정보 조회
 		List<Integer> ordNoList = new ArrayList<>();
@@ -256,13 +257,9 @@ public class TsfMypageController extends TsfBaseController {
 			order.setOrdNoList(ordNoList.stream().mapToInt(Integer::intValue).toArray());
 		}
 
-		mav.addObject("orderList", orderService.getOrderListForMypage(order));
-		mav.addObject("orderInfo", order);
-
-		mav.setViewName(super.getDeviceViewName("mypage/MypageOrderList"));
+		map.set("orderList", orderService.getOrderListForMypage(order));
+		map.set("orderInfo", order);
 
-		map.set("mav", mav);
-		map.set("pageable", order.getPageable());
 		return map;
 	}
 
@@ -610,6 +607,75 @@ public class TsfMypageController extends TsfBaseController {
 		return result;
 	}
 
+	/**
+	 * 마이페이지 전체취소신청
+	 *
+	 * @param Collection<Order>
+	 * @return GagaMap
+	 * @author card007
+	 * @since 2021. 03. 22
+	 */
+	@SuppressWarnings("unchecked")
+	@PostMapping("/cancel/all")
+	@ResponseBody
+	public GagaMap cancelAll(@RequestBody OrderChange orderChange) {
+		if (orderChange == null) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		// TODO
+		// @ 결품취소로직 추가
+		// @ 주문취소시 상태값 체크
+		// @ 취소, 반품시 배송비 체크 로직 (선결제 로직)
+
+		// 1. 세션회원조회
+		int custNo = TsfSession.getInfo().getCustNo();
+		orderChange.setCustNo(custNo);
+
+		// 2. 환불 사전 정보 조회
+		GagaMap refundPreInfo = orderChangeService.getRefundPreInfo(orderChange);
+		List<Order> cnclReqList = (List<Order>) refundPreInfo.get("cnclReqList");
+		String allCanYn = refundPreInfo.getString("allCanYn");
+		
+
+		// 2. 환불금액계산
+		// 2021.01.19 취소신청정보를 목록 (주문상세번호, 취소/반품수량) 으로 표현
+		GagaMap result = coreOrderRefundService.cnclRtnRefundAmt(cnclReqList);
+
+		// 무통장입금전 전체취소 여부
+		
+
+		// 3. 주문변경 기본정보 설정
+		result.set("ordNo"			, orderChange.getOrdNo());				// 주문번호
+		result.set("ordChgSq"		, orderChange.getOrdChgSq());			// 주문변경번호
+		result.set("chgReason"		, orderChange.getChgReason());			// 변경사유
+		result.set("chgMemo"		, orderChange.getChgMemo());			// 변경메모
+
+		result.set("accountNo"		, orderChange.getAccountNo());			// 환불계좌번호
+		result.set("accountNm"		, orderChange.getAccountNm());			// 환불계좌예금주명
+		result.set("bankCd"			, orderChange.getBankCd());				// 환불계좌은행코드
+
+		result.set("allCanYn"		, allCanYn);							// 무통장입금전 전체취소 여부
+		result.set("isCustomer"		, orderChange.getIsCustomer());			// 변경사유 (고객, 회사)
+
+		// 4. 주문변경 회수지정보 추가
+		result.set("chgerNm"		, orderChange.getChgerNm());			// 변경자명
+		result.set("chgerEmail"		, orderChange.getChgerEmail());			// 변경자이메일주소
+		result.set("chgerPhnno"		, orderChange.getChgerPhnno());			// 변경자핸드폰번호
+		result.set("chgerTelno"		, orderChange.getChgerTelno());			// 변경자전화번호
+
+		result.set("reqGbn"			, orderChange.getReqGbn());				// 신청구분
+
+		// 5. 주문변경 DB 등록 (TB_ORDER_CHANGE, TB_ORDER_CHANGE_DETAIL)
+		coreOrderChangeService.cnclComplete(result, custNo);
+
+		result.set("status", GagaResponseStatus.SUCCESS.getCode());
+		result.set("message", "취소 처리 되었습니다.");
+		// result.set("message", message.getMessage("SUCC_0004"));
+
+		return result;
+	}
+
 	/**
 	 * 마이페이지 STYLE24 포인트화면
 	 *
@@ -720,7 +786,7 @@ public class TsfMypageController extends TsfBaseController {
 		return result;
 	}
 
-	/* 김소원 상품권 쿠폰 시작 */
+	/* 김소원 상품권 쿠폰 리뷰 시작 */
 	/**
 	 * 마이페이지 상품권화면
 	 *
@@ -826,6 +892,104 @@ public class TsfMypageController extends TsfBaseController {
 		mav.setViewName(super.getDeviceViewName("mypage/MypageCouponDetailPop"));
 		return mav;
 	}
+	
+	/**
+	 * 마이페이지 리뷰화면
+	 *
+	 * @return
+	 * @author sowon	
+	 * @since 2021. 03. 24
+	 */
+	@GetMapping("/review/form")
+	public ModelAndView mypageReviewForm(Review review) {
+		ModelAndView mav = new ModelAndView();
+		
+		review.setCustNo(TsfSession.getInfo().getCustNo());
+		review.setSiteCd(TscConstants.Site.STYLE24.value());
+		// 작성가능한 리뷰 카운트
+		mav.addObject("completeReviewCount", reviewService.getCompleteReviewCount(review));
+		// 작성가능한 리뷰 목록
+		//mav.addObject("completeReviewList", reviewService.getCompleteReviewList(review));
+		mav.setViewName(super.getDeviceViewName("mypage/MypageReviewForm"));
+
+		return mav;
+	}
+	
+	/**
+	 * 마이페이지 리뷰 목록
+	 * @param review
+	 * @return
+	 * @author sowon
+	 * @since 2021. 03. 25
+	 */
+	@PostMapping("/review/list")
+	@ResponseBody
+	public GagaMap getMypageReviewList(@RequestBody Review review) {
+
+		review.setSiteCd(TscConstants.Site.STYLE24.value());
+
+		GagaMap result = new GagaMap();
+
+		TscPageRequest pageable = new TscPageRequest((review.getPageNo() > 0 ? review.getPageNo() - 1 : 0), review.getPageSize(), review.getPageUnit());
+		pageable.setTotalCount(reviewService.getCompleteReviewCount(review));
+		review.setPageable(pageable);
+		log.info("pageable: {}", pageable);
+		log.info("totalCount {}", pageable.getTotalCount());
+		
+
+		if (TsfSession.isLogin()) {
+			review.setCustNo(TsfSession.getInfo().getCustNo());
+		}
+
+		result.set("paging", review);
+		result.set("completeReviewCount", reviewService.getCompleteReviewCount(review));
+		result.set("dataList", reviewService.getCompleteReviewList(review));
+
+		return result;
+	}
+	
+	/**
+	 * 마이페이지 리뷰작성화면
+	 *
+	 * @return
+	 * @author sowon	
+	 * @since 2021. 03. 25
+	 */
+	@GetMapping("/review/create/form/{ordNo}/{ordDtlNo}/{goodsCd}")
+	public ModelAndView mypageReviewCreateForm(@PathVariable(value = "ordNo") Integer ordNo,@PathVariable(value = "ordDtlNo") Integer ordDtlNo,@PathVariable(value = "goodsCd") String goodsCd) {
+		Review review = new Review();
+		ModelAndView mav = new ModelAndView();
+		
+		review.setCustNo(TsfSession.getInfo().getCustNo());
+		review.setSiteCd(TscConstants.Site.STYLE24.value());
+		review.setOrdNo(ordNo);
+		review.setOrdDtlNo(ordDtlNo);
+		review.setGoodsCd(goodsCd);
+		
+		mav.addObject("completeReviewList", reviewService.getCompleteReviewList(review));
+		
+		mav.setViewName(super.getDeviceViewName("mypage/MypageReviewCreateForm"));
+
+		return mav;
+	}
+	
+	/**
+	 * 마이페이지 리뷰 저장
+	 * @param review
+	 * @return
+	 * @author sowon
+	 * @since 2021. 03. 25
+	 */
+	@PostMapping("/review/save")
+	@ResponseBody
+	public GagaMap mypageReviewSave(@RequestBody Review review) {
+
+		GagaMap result = new GagaMap();
+		reviewService.saveMypageReview(review);
+		result.set("status", "200");
+
+		return result;
+	}
 
 	/*신주승 시작*/
 

+ 49 - 4
src/main/java/com/style24/front/biz/web/TsfPlanningController.java

@@ -14,21 +14,21 @@ import org.springframework.web.bind.annotation.RequestBody;
 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.bind.annotation.RestController;
 import org.springframework.web.servlet.ModelAndView;
 
 import com.gagaframework.web.parameter.GagaMap;
-import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.rest.server.GagaResponseStatus;
+import com.style24.core.biz.service.TscCustomerService;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.front.biz.service.TsfCouponService;
 import com.style24.front.biz.service.TsfPlanningService;
 import com.style24.front.support.controller.TsfBaseController;
-import com.style24.front.support.env.TsfConstants;
 import com.style24.front.support.security.session.TsfSession;
 import com.style24.persistence.domain.Cate4Srch;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.Customer;
-import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.Plan;
 import com.style24.persistence.domain.Review;
 
@@ -51,6 +51,9 @@ public class TsfPlanningController extends TsfBaseController {
 	@Autowired
 	private TsfPlanningService planningService;
 	
+	@Autowired
+	private TscCustomerService coreCustomerService;
+	
 	/**
 	 * 기획전 메인 화면
 	 * 
@@ -186,6 +189,48 @@ public class TsfPlanningController extends TsfBaseController {
 		mav.setViewName(super.getDeviceViewName("planning/PlanningDetailForm"));
 		return mav;
 	}
+	
+	/**
+	 * 기획전 쿠폰 다운로드. 고객이 상품쿠폰 다운로드 시 발급됨.
+	 *
+	 * @param params
+	 * @return
+	 * @throws Exception
+	 * @author sowon
+	 * @since 2021. 3. 24.
+	 */
+	@PostMapping(value = "/coupon/download")
+	@ResponseBody
+	public GagaMap createPlanCoupon(@RequestBody Coupon coupon) throws Exception {
+
+		GagaMap result = new GagaMap();
+
+		// 고객정보 조회
+		Customer customer = new Customer();
+		customer.setSiteCd(TscConstants.Site.STYLE24.value());
+		customer.setCustNo(TsfSession.getInfo().getCustNo());
+		customer.setCustStat(TscConstants.CustStat.ACTIVE.value());
+		customer = coreCustomerService.getCustomerInfo(customer);
+
+		// 고객정보 설정
+		coupon.setCustGb(customer.getCustGb());
+		coupon.setCustGrade(customer.getCustGrade());
+		coupon.setCustNo(customer.getCustNo());
+		// 등급쿠폰 다운 처리
+		int count = planningService.getPlanCouponDownInfo(coupon);
+
+		result.set("status", GagaResponseStatus.SUCCESS.getCode());
+
+		if (count == 0) {
+			result.set("message", message.getMessage("COUPON_0002"));
+		} else {
+			result.set("message", message.getMessage("COUPON_0001", new Object[] {count}));
+		}
+
+		return result;
+	}
+
+	
 	/**
 	 * 이벤트 메인 화면
 	 * 

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

@@ -35,8 +35,14 @@ public class Cate4Srch extends TscBaseDomain {
 	private String formalGb;
 	private String contentsLoc;
 
-	private Integer brandGroupNo;	// 브랜드그룹번호
+	private Integer brandGroupNo;		// 브랜드그룹번호
 
 	private String soldoutGoodsDispYn;
 
+	private Integer custNo;				// 고객번호
+	private String frontGb;				// 프론트구분
+	private String custGb;				// 고객구분
+	private int maxRow;					// 최대ROW수
+	private String[] exceptGoodsArr;	// 제외상품배열
+
 }

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

@@ -74,7 +74,7 @@ public class Goods extends TscBaseDomain {
 
 	private String colorCd;		//색상코드
 	private String colorNm;		//색상코드명
-	private String brandnm;		//브랜드명
+	private String brandNm;		//브랜드명
 	private Integer brandGroupNo;	//브랜드그룹번호
 	private String brandGroupNm;	//브랜드그룹명
 	private String goodsGbNm;		//상품구분명
@@ -155,6 +155,13 @@ public class Goods extends TscBaseDomain {
 	private String delvResDt;		// 예약판매 출고예정일
 	private int maxRownum;			// 조회건수
 
+	private String payDt;			// 구매일	
+	private String remainDt;		// 리뷰 남아있는시간
+	private String brandEnm;
+	private String brandKnm;
+	private Integer ordNo;			// 주문번호
+	private Integer ordDtlNo;		// 주문상세번호
+
 	//상품상세 구분(10:상품타이틀,20:상품타이틀내용,30:상품특징,40:상위컨텐츠,50:하위컨텐츠,60:상위컨텐츠-모바일,70:하위컨텐츠-모바일,80:상품상세(as-is,입점))
 	private String goodsTitle; 			// 10:상품타이틀
 	private String goodsTitleDesc;		// 20:상품타이틀내용
@@ -170,4 +177,6 @@ public class Goods extends TscBaseDomain {
 
 	private String todayGoodsSql;	// 오늘본상품SQL
 
+	private String likeIt;			// 위시리스트에담긴상품
+
 }

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

@@ -29,4 +29,6 @@ public class MainLayout extends TscBaseDomain {
     private Cate4Srch cate4Srch;
     private Collection<Contents> contentsList;
     private Collection<Goods> goodsList;
+    private Collection<Lookbook> lookbookList;
+
 }

+ 7 - 3
src/main/java/com/style24/persistence/domain/Review.java

@@ -80,6 +80,9 @@ public class Review extends TscBaseDomain {
 	private String goodsNm;			// 상품이름
 	private int currPrice;		// 현재가
 	private String fileGb;			// 첨부파일 종류
+	private int cnt;				// 리뷰 카운트
+	private String siteCd;
+	
 	// Masking
 	public String getMaskingCustId() {
 		return (this.custId != null) ?  MaskingUtils.id(this.custId) : this.custId;
@@ -93,8 +96,9 @@ public class Review extends TscBaseDomain {
 	@JsonInclude(JsonInclude.Include.NON_EMPTY)
 	private TscPageRequest pageable;
 
-	private int pageNo = 1;
-	private int pageSize = 10;
-	private int pageUnit = 10;
+	private int pageNo = 1;							// 페이지번호
+	private int pageSize = 10;						// 페이지목록수
+	private int pageUnit = 10;						// 페이지번호수
+	
 	
 }

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

@@ -235,7 +235,7 @@
 		                     , FN_GET_BENEFIT_PRICE(#{frontGb},G.GOODS_CD, G.CURR_PRICE,#{custGb}) AS CURR_PRICE
 		                FROM   TB_GOODS G
 		                     , TB_COUPON CP
-		                WHERE  G.GOODS_CD = #{goodsCd}
+		                WHERE G.GOODS_CD = #{goodsCd}
 		                <if test="cpnId != null and cpnId != ''">
 		                AND    CP.CPN_ID = #{cpnId}
 		                </if>
@@ -585,4 +585,69 @@
 		 AND A.CPN_ID = #{cpnId}
 	</select>
 	
+	<!-- 기획전 다운가능 쿠폰 정보 조회 -->
+	<select id="getPlanCouponInfo" parameterType="Coupon" resultType="Coupon">
+		/* TsfCoupon.getPlanCouponInfo */
+		SELECT Z.CUST_NO
+		     , Z.CPN_ID
+		     , Z.AVAIL_STDT
+		     , Z.AVAIL_EDDT
+		     , Z.END_ALIM_YN
+		     , Z.DOWNLOAD_CNT
+		     , Z.OWN_COUPON
+		  FROM (SELECT A.*
+					 , CASE WHEN A.CNT <![CDATA[<=]]> 0 THEN 0
+							WHEN A.CNT > (A.DN_ABLE_CNT * A.ONE_PUB_QTY) THEN (A.DN_ABLE_CNT * A.ONE_PUB_QTY)
+							ELSE A.CNT
+						END AS DOWNLOAD_CNT
+				  FROM (SELECT #{custNo} AS CUST_NO
+							 , C.CPN_ID
+							 , C.CPN_NM
+							 , C.CUST_PUB_LIMIT_QTY
+							 , C.ONE_PUB_QTY
+							 , IF(C.PD_GB = 'P', C.AVAIL_STDT, NOW()) AS AVAIL_STDT
+							 , IF(C.PD_GB = 'P', C.AVAIL_EDDT, CONCAT(CURRENT_DATE + INTERVAL C.AVAIL_DAYS DAY, ' 23:59:59')) AS AVAIL_EDDT
+				             , C.END_ALIM_YN
+							 , IFNULL(CC.CPN_CNT, 0) AS DN_CNT
+				             , IF(C.CUST_PUB_LIMIT_QTY = 0 OR C.CUST_PUB_LIMIT_QTY - CC.CPN_CNT > 0, 1, 0) AS DN_ABLE_CNT
+				             , IF(C.TOT_PUB_LIMIT_QTY > 0, C.TOT_PUB_LIMIT_QTY - CC2.CPN_CNT, 99999) AS CNT
+				             , (SELECT COUNT(*) FROM TB_CUST_COUPON TCC WHERE CPN_ID = #{cpnId} AND CUST_NO = #{custNo}) AS OWN_COUPON
+						  FROM TB_COUPON C
+						 INNER JOIN TB_COUPON_CUST_GBN CCGB
+							ON C.CPN_ID = CCGB.CPN_ID
+						   AND CCGB.USABLE_CUST_GB = #{custGb}
+						 INNER JOIN TB_COUPON_CUST_GRADE CCGR
+							ON C.CPN_ID = CCGR.CPN_ID
+						   AND CCGR.USABLE_CUST_GRADE = #{custGrade}
+						  LEFT OUTER JOIN (SELECT CPN_ID
+												, CUST_NO
+												, COUNT(*) AS CPN_CNT
+											 FROM TB_CUST_COUPON
+											GROUP BY CPN_ID, CUST_NO) CC
+							ON C.CPN_ID = CC.CPN_ID
+						   AND CC.CUST_NO = #{custNo}
+						  LEFT OUTER JOIN (SELECT CPN_ID
+												, COUNT(*) AS CPN_CNT
+											 FROM TB_CUST_COUPON
+											GROUP BY CPN_ID) CC2
+							ON C.CPN_ID = CC2.CPN_ID
+						 WHERE C.DOWN_ABL_YN = 'N'
+						    AND C.CPN_ID IN (
+						       					SELECT PCI.ITEM_VAL 
+						       					FROM TB_PLAN_CONTENTS_ITEM PCI 
+						       					WHERE PCI.ITEM_VAL = #{cpnId}
+						       				)
+						   AND NOW() BETWEEN C.DOWN_STDT AND C.DOWN_EDDT
+						   AND C.CPN_STAT = 'G232_11'  -- 진행
+						   AND CASE WHEN C.TOT_PUB_LIMIT_QTY = 0 THEN 1
+									WHEN C.TOT_PUB_LIMIT_QTY - CC2.CPN_CNT > 0 THEN 1
+									ELSE 0
+								END = 1
+						   AND IF(C.NEW_CUST_YN = 'Y', (SELECT COUNT(*) FROM TB_CUSTOMER WHERE CUST_NO = #{custNo} AND REG_DT BETWEEN C.CUST_JOIN_STDT AND C.CUST_JOIN_EDDT), 1) = 1
+						   AND IF(C.FIRST_ORD_YN = 'Y', (SELECT COUNT(*) FROM TB_ORDER WHERE CUST_NO = #{custNo} AND ORD_DT BETWEEN C.BUY_STDT AND C.BUY_EDDT), 0) = 0
+						) A
+				) Z
+		 <!-- WHERE Z.DOWNLOAD_CNT <![CDATA[>=]]> 0 -->
+	
+	</select>
 </mapper>

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

@@ -448,7 +448,7 @@
 		<if test="brandGroupNo != null and brandGroupNo !=''">
 			AND    BRAND_GROUP_NO  = #{brandGroupNo}
 		</if>
-		AND 	CONTENTS_LOC IN ('SMM001','SMM002','SMM005','SMM008','SBM004','SBM005','SBM006')
+		AND 	CONTENTS_LOC IN ('SMM001','SMM002','SMM005','SMM008','SBM004','SBM005','SBM006','SBM010')
 		ORDER BY DISP_ORD, COL_NO
 	</select>
 

+ 303 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsfGoods.xml

@@ -853,4 +853,307 @@
 		ORDER  BY A.DISP_ORD DESC
 	</select>
 	
+	<!-- 컨텐츠카테고리상품 목록 -->
+	<select id="getContentsCategoryGoodsList"  parameterType="Cate4Srch" resultType="Goods">
+		/* TsfGoods.getContentsCategoryGoodsList */
+		WITH TAB_GOODS AS (
+		    SELECT G.BRAND_GROUP_NM     /*브랜드그룹명*/
+		         , G.GOODS_CD           /*상품코드*/
+		         , G.GOODS_NM           /*상품명*/
+		         , G.GOODS_GB           /*상품구분*/
+		         , G.FOREIGN_BUY_YN     /*해외구매대행여부*/
+		         , G.PARALLEL_IMPORT_YN /*병행수입여부*/
+		         , G.ORDER_MADE_YN      /*주문제작여부*/
+		         , G.GOODS_TNM          /*상품타이틀명*/
+		         , G.MAIN_COLOR_CD      /*대표색상코드*/
+		         , G.LIST_PRICE         /*정상가(최초판매가)*/
+		         , G.CURR_PRICE         /*현재판매가*/
+		         , G.REG_DT             /*등록일시*/
+		         , G.NUMB
+		    FROM   (
+		            SELECT CASE WHEN BG.DISP_NM_LANG = 'EN' THEN
+		                            BG.BRAND_GROUP_ENM
+		                        ELSE
+		                            BG.BRAND_GROUP_KNM
+		                   END                                    AS BRAND_GROUP_NM /*브랜드그룹명*/
+		                 , G.GOODS_CD                                               /*상품코드*/
+		                 , G.GOODS_NM                                               /*상품명*/
+		                 , G.GOODS_GB                                               /*상품구분*/
+		                 , G.FOREIGN_BUY_YN                                         /*해외구매대행여부*/
+		                 , G.PARALLEL_IMPORT_YN                                     /*병행수입여부*/
+		                 , G.ORDER_MADE_YN                                          /*주문제작여부*/
+		                 , G.GOODS_TNM                                              /*상품타이틀명*/
+		                 , G.MAIN_COLOR_CD                                          /*대표색상코드*/
+		                 , G.LIST_PRICE                                             /*정상가(최초판매가)*/
+		                 , G.CURR_PRICE                                             /*현재판매가*/
+		                 , G.REG_DT                                                 /*등록일시*/
+		                 <choose>
+		                     <when test="contentsLoc == 'SCM002'"> <!-- 베스트 -->
+		                 , ROW_NUMBER() OVER(ORDER BY GS.SELL_WEEK_QTY DESC
+		                                            , G.GOODS_CD) AS NUMB
+		                     </when>
+		                     <otherwise>
+		                 , ROW_NUMBER() OVER(ORDER BY CG.DISP_ORD
+		                                            , G.REG_DT DESC
+		                                            , G.GOODS_CD) AS NUMB
+		                     </otherwise>
+		                 </choose>
+		            FROM   TB_CATE_4SRCH C4
+		                 , TB_CATE_GOODS CG
+		                 , TB_GOODS G
+		                 , TB_GOODS_STOCK S
+		                 , TB_BRAND B
+		                 , TB_BRAND_GROUP BG
+		            <if test="contentsLoc == 'SCM002'"> <!-- 베스트 -->
+		                 , TB_GOODS_SUMMARY GS
+		            </if> 
+		            WHERE  C4.LEAF_CATE_NO = CG.CATE_NO
+		            <choose>
+		                <when test="brandGroupNo != null and brandGroupNo != ''">
+		            AND    CG.BRAND_GROUP_NO = #{brandGroupNo}
+		                </when>
+		                <otherwise>
+		            AND    CG.BRAND_GROUP_NO = 0 /*브랜드메인에서 접근한 것이 아니면*/
+		                </otherwise>
+		            </choose>
+		            AND    CG.GOODS_CD = G.GOODS_CD
+		            AND    CG.GOODS_CD = S.GOODS_CD
+		            AND    G.BRAND_CD = B.BRAND_CD
+		            AND    B.BRAND_GROUP_NO = BG.BRAND_GROUP_NO
+		            <if test="contentsLoc == 'SCM002'"> <!-- 베스트 -->
+		            AND    CG.GOODS_CD = GS.GOODS_CD
+		            </if>
+		            AND    C4.SITE_CD = #{siteCd}
+		            AND    C4.CATE_GB = #{cateGb}
+		            AND    C4.CATE_TYPE = 'G031_20' /*컨텐츠카테고리*/
+		            AND    C4.CATE1_NO = #{cate1No}
+		            AND    C4.CONTENTS_LOC = #{contentsLoc}
+		            AND    G.GOODS_STAT = 'G008_90' /*승인완료상품*/
+		            AND    G.FORMAL_GB = 'G009_10' /*정상상품*/
+		            AND    S.STOCK_QTY <![CDATA[>]]> 0 /*재고있는상품*/
+		            AND    B.USE_YN = 'Y'
+		            AND    BG.USE_YN = 'Y'
+		           ) G
+		    WHERE  G.NUMB <![CDATA[<=]]> #{maxRow}
+		)
+		, TAB_GOODS_IMG AS (
+		    /* 상품의 이미지 */
+		    SELECT G.BRAND_GROUP_NM
+		         , G.GOODS_CD
+		         , G.GOODS_NM
+		         , G.GOODS_GB
+		         , G.FOREIGN_BUY_YN
+		         , G.PARALLEL_IMPORT_YN
+		         , G.ORDER_MADE_YN
+		         , G.GOODS_TNM
+		         , G.MAIN_COLOR_CD
+		         , G.LIST_PRICE
+		         , G.CURR_PRICE
+		         , G.REG_DT
+		         , CASE WHEN GI.DEFAULT_IMG_YN = 'Y' THEN GI.SYS_IMG_NM ELSE NULL END   AS SYS_IMG_NM
+		         , CASE WHEN GI.MOUSEOVER_IMG_YN = 'Y' THEN GI.SYS_IMG_NM ELSE NULL END AS SYS_IMG_NM2
+		    FROM   TAB_GOODS G
+		         , TB_GOODS_IMG GI
+		    WHERE  G.GOODS_CD = GI.GOODS_CD
+		    AND    G.MAIN_COLOR_CD = GI.COLOR_CD
+		)
+		, TAB_GOODS_VIDEO AS (
+		    /* 상품의 동영상 목록 */
+		    SELECT GOODS_CD
+		         , MAX(CASE WHEN RNUM = 1 THEN VIDEO_GB END)  AS VIDEO_GB_M
+		         , MAX(CASE WHEN RNUM = 1 THEN VIDEO_VAL END) AS VIDEO_VAL_M
+		         , MAX(CASE WHEN RNUM = 2 THEN VIDEO_GB END)  AS VIDEO_GB_S
+		         , MAX(CASE WHEN RNUM = 2 THEN VIDEO_VAL END) AS VIDEO_VAL_S
+		    FROM   (
+		            SELECT G.GOODS_CD
+		                 , V.VIDEO_GB
+		                 , V.VIDEO_VAL
+		                 , VD.REG_DT
+		                 , RANK() OVER(PARTITION BY G.GOODS_CD ORDER BY VD.REG_DT) AS RNUM
+		            FROM   TAB_GOODS G
+		                 , TB_VIDEO_DISPLOC VD
+		                 , TB_VIDEO V
+		            WHERE  G.GOODS_CD = VD.DISPLOC_VAL
+		            AND    VD.VIDEO_SQ = V.VIDEO_SQ
+		            AND    VD.DISPLOC_GB = 'G' /*상품*/
+		            AND    VD.DISP_YN = 'Y'
+		            AND    V.DISP_YN ='Y'
+		           ) Z
+		    GROUP  BY GOODS_CD
+		)
+		SELECT G.BRAND_GROUP_NM
+		     , G.GOODS_CD
+		     , FN_GET_GOODS_NM(G.GOODS_NM,G.GOODS_GB,G.FOREIGN_BUY_YN,G.PARALLEL_IMPORT_YN,G.ORDER_MADE_YN) AS GOODS_FULL_NM /*상품FULL명*/
+		     , G.GOODS_TNM
+		     , G.MAIN_COLOR_CD
+		     , G.LIST_PRICE
+		     , FN_GET_BENEFIT_PRICE(#{frontGb},G.GOODS_CD,G.CURR_PRICE,#{custGb})                           AS CURR_PRICE    /*현재판매가*/
+		     , G.SYS_IMG_NM
+		     , G.SYS_IMG_NM2
+		     , GV.VIDEO_GB_M
+		     , GV.VIDEO_VAL_M
+		     , GV.VIDEO_GB_S
+		     , GV.VIDEO_VAL_S
+		     <choose>
+		         <when test="custNo != null and custNo > 0"> <!-- 로그인 했으면 -->
+		     , IF(W.GOODS_CD,'','','likeit')                                                                AS LIKE_IT       /*위시리스트담긴상품*/
+		         </when>
+		         <otherwise>
+		     , ''                                                                                           AS LIKE_IT       /*위시리스트담긴상품*/
+		         </otherwise>
+		     </choose>
+		FROM   TAB_GOODS_IMG G
+		LEFT OUTER JOIN TAB_GOODS_VIDEO GV ON G.GOODS_CD = GV.GOODS_CD
+		<if test="custNo != null and custNo > 0"> <!-- 로그인 했으면 -->
+		LEFT OUTER JOIN TB_WISHLIST W ON G.GOODS_CD = W.GOODS_CD
+		                             AND W.CUST_NO = #{custNo}
+		</if>
+	</select>
+	
+	<!-- 컨텐츠카테고리 신규상품 목록 -->
+	<select id="getContentsCategoryNewGoodsList"  parameterType="Cate4Srch" resultType="Goods">
+		/* TsfGoods.getContentsCategoryNewGoodsList */
+		WITH TAB_GOODS AS (
+		    SELECT G.BRAND_GROUP_NM     /*브랜드그룹명*/
+		         , G.GOODS_CD           /*상품코드*/
+		         , G.GOODS_NM           /*상품명*/
+		         , G.GOODS_GB           /*상품구분*/
+		         , G.FOREIGN_BUY_YN     /*해외구매대행여부*/
+		         , G.PARALLEL_IMPORT_YN /*병행수입여부*/
+		         , G.ORDER_MADE_YN      /*주문제작여부*/
+		         , G.GOODS_TNM          /*상품타이틀명*/
+		         , G.MAIN_COLOR_CD      /*대표색상코드*/
+		         , G.LIST_PRICE         /*정상가(최초판매가)*/
+		         , G.CURR_PRICE         /*현재판매가*/
+		         , G.REG_DT             /*등록일시*/
+		         , G.NUMB
+		    FROM   (
+		            SELECT CASE WHEN BG.DISP_NM_LANG = 'EN' THEN
+		                            BG.BRAND_GROUP_ENM
+		                        ELSE
+		                            BG.BRAND_GROUP_KNM
+		                   END                                    AS BRAND_GROUP_NM /*브랜드그룹명*/
+		                 , G.GOODS_CD                                               /*상품코드*/
+		                 , G.GOODS_NM                                               /*상품명*/
+		                 , G.GOODS_GB                                               /*상품구분*/
+		                 , G.FOREIGN_BUY_YN                                         /*해외구매대행여부*/
+		                 , G.PARALLEL_IMPORT_YN                                     /*병행수입여부*/
+		                 , G.ORDER_MADE_YN                                          /*주문제작여부*/
+		                 , G.GOODS_TNM                                              /*상품타이틀명*/
+		                 , G.MAIN_COLOR_CD                                          /*대표색상코드*/
+		                 , G.LIST_PRICE                                             /*정상가(최초판매가)*/
+		                 , G.CURR_PRICE                                             /*현재판매가*/
+		                 , G.REG_DT                                                 /*등록일시*/
+		                 , ROW_NUMBER() OVER(ORDER BY G.REG_DT DESC
+		                                            , G.GOODS_CD) AS NUMB
+		            FROM   TB_CATE_4SRCH C4
+		                 , TB_CATE_GOODS CG
+		                 , TB_GOODS G
+		                 , TB_GOODS_STOCK GS
+		                 , TB_BRAND B
+		                 , TB_BRAND_GROUP BG
+		            WHERE  C4.LEAF_CATE_NO = CG.CATE_NO
+		            <choose>
+		                <when test="brandGroupNo != null and brandGroupNo != ''">
+		            AND    CG.BRAND_GROUP_NO = #{brandGroupNo}
+		                </when>
+		                <otherwise>
+		            AND    CG.BRAND_GROUP_NO = 0 /*브랜드메인에서 접근한 것이 아니면*/
+		                </otherwise>
+		            </choose>
+		            AND    CG.GOODS_CD = G.GOODS_CD
+		            AND    CG.GOODS_CD = GS.GOODS_CD
+		            AND    G.BRAND_CD = B.BRAND_CD
+		            AND    B.BRAND_GROUP_NO = BG.BRAND_GROUP_NO
+		            AND    C4.SITE_CD = #{siteCd}
+		            AND    C4.CATE_GB = #{cateGb}
+		            AND    C4.CATE_TYPE = 'G031_10' /*상품카테고리*/
+		            AND    C4.CATE1_NO = #{cate1No}
+		            <if test="exceptGoodsArr != null and exceptGoodsArr.length > 0">
+		            AND	   CG.GOODS_CD NOT IN
+		                <foreach collection="exceptGoodsArr" item="item" index="index"  open="(" close=")" separator=",">
+		                #{item}
+		                </foreach>
+		            </if>
+		            AND    G.GOODS_STAT = 'G008_90' /*승인완료상품*/
+		            AND    G.FORMAL_GB = 'G009_10' /*정상상품*/
+		            AND    GS.STOCK_QTY <![CDATA[>]]> 0 /*재고있는상품*/
+		            AND    B.USE_YN = 'Y'
+		            AND    BG.USE_YN = 'Y'
+		           ) G
+		    WHERE  G.NUMB <![CDATA[<=]]> #{maxRow}
+		)
+		, TAB_GOODS_IMG AS (
+		    /* 상품의 이미지 */
+		    SELECT G.BRAND_GROUP_NM
+		         , G.GOODS_CD
+		         , G.GOODS_NM
+		         , G.GOODS_GB
+		         , G.FOREIGN_BUY_YN
+		         , G.PARALLEL_IMPORT_YN
+		         , G.ORDER_MADE_YN
+		         , G.GOODS_TNM
+		         , G.MAIN_COLOR_CD
+		         , G.LIST_PRICE
+		         , G.CURR_PRICE
+		         , CASE WHEN GI.DEFAULT_IMG_YN = 'Y' THEN GI.SYS_IMG_NM ELSE NULL END   AS SYS_IMG_NM
+		         , CASE WHEN GI.MOUSEOVER_IMG_YN = 'Y' THEN GI.SYS_IMG_NM ELSE NULL END AS SYS_IMG_NM2
+		    FROM   TAB_GOODS G
+		         , TB_GOODS_IMG GI
+		    WHERE  G.GOODS_CD = GI.GOODS_CD
+		    AND    G.MAIN_COLOR_CD = GI.COLOR_CD
+		)
+		, TAB_GOODS_VIDEO AS (
+		    /* 상품의 동영상 목록 */
+		    SELECT GOODS_CD
+		         , MAX(CASE WHEN RNUM = 1 THEN VIDEO_GB END)  AS VIDEO_GB_M
+		         , MAX(CASE WHEN RNUM = 1 THEN VIDEO_VAL END) AS VIDEO_VAL_M
+		         , MAX(CASE WHEN RNUM = 2 THEN VIDEO_GB END)  AS VIDEO_GB_S
+		         , MAX(CASE WHEN RNUM = 2 THEN VIDEO_VAL END) AS VIDEO_VAL_S
+		    FROM   (
+		            SELECT G.GOODS_CD
+		                 , V.VIDEO_GB
+		                 , V.VIDEO_VAL
+		                 , VD.REG_DT
+		                 , RANK() OVER(PARTITION BY G.GOODS_CD ORDER BY VD.REG_DT) AS RNUM
+		            FROM   TAB_GOODS G
+		                 , TB_VIDEO_DISPLOC VD
+		                 , TB_VIDEO V
+		            WHERE  G.GOODS_CD = VD.DISPLOC_VAL
+		            AND    VD.VIDEO_SQ = V.VIDEO_SQ
+		            AND    VD.DISPLOC_GB = 'G' /*상품*/
+		            AND    VD.DISP_YN = 'Y'
+		            AND    V.DISP_YN ='Y'
+		           ) Z
+		    GROUP  BY GOODS_CD
+		)
+		SELECT G.BRAND_GROUP_NM
+		     , G.GOODS_CD
+		     , FN_GET_GOODS_NM(G.GOODS_NM,G.GOODS_GB,G.FOREIGN_BUY_YN,G.PARALLEL_IMPORT_YN,G.ORDER_MADE_YN) AS GOODS_FULL_NM /*상품FULL명*/
+		     , G.GOODS_TNM
+		     , G.MAIN_COLOR_CD
+		     , G.LIST_PRICE
+		     , FN_GET_BENEFIT_PRICE(#{frontGb},G.GOODS_CD,G.CURR_PRICE,#{custGb})                           AS CURR_PRICE    /*현재판매가*/
+		     , G.SYS_IMG_NM
+		     , G.SYS_IMG_NM2
+		     , GV.VIDEO_GB_M
+		     , GV.VIDEO_VAL_M
+		     , GV.VIDEO_GB_S
+		     , GV.VIDEO_VAL_S
+		     <choose>
+		         <when test="custNo != null and custNo > 0"> <!-- 로그인 했으면 -->
+		     , IF(W.GOODS_CD,'','','likeit')                                                                AS LIKE_IT       /*위시리스트담긴상품*/
+		         </when>
+		         <otherwise>
+		     , ''                                                                                           AS LIKE_IT       /*위시리스트담긴상품*/
+		         </otherwise>
+		     </choose>
+		FROM   TAB_GOODS_IMG G
+		LEFT OUTER JOIN TAB_GOODS_VIDEO GV ON G.GOODS_CD = GV.GOODS_CD
+		<if test="custNo != null and custNo > 0"> <!-- 로그인 했으면 -->
+		LEFT OUTER JOIN TB_WISHLIST W ON G.GOODS_CD = W.GOODS_CD
+		                             AND W.CUST_NO = #{custNo}
+		</if>
+	</select>
+	
 </mapper>

+ 97 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsfOrderChange.xml

@@ -70,6 +70,8 @@
 		     , OD.SHOT_DELV_YN
 		     , G1.SELF_GOODS_YN
 		     , CONCAT(B.BRAND_ENM, ' ', B.BRAND_KNM)			AS BRAND_NM
+		     , P.PAY_MEANS
+		     , P.PAY_STAT
 		  FROM TB_ORDER O
 		 INNER JOIN TB_ORDER_DETAIL OD
 		    ON O.ORD_NO = OD.ORD_NO
@@ -82,6 +84,10 @@
 		    ON ODI.ITEM_CD = G2.GOODS_CD
 		 INNER JOIN TB_BRAND B
 		    ON B.BRAND_CD = G1.BRAND_CD
+		 INNER JOIN TB_PAYMENT P
+		    ON OD.ORD_NO = P.ORD_NO
+		   AND P.PAY_STAT IN ('G016_30', 'G016_00')
+		   AND P.PAY_GB = 'O'
 		  LEFT OUTER JOIN (SELECT OD.ORD_DTL_NO
 								, SUM(OCD.CHG_QTY) AS ORD_REQ_CHG_QTY
 							 FROM TB_ORDER_CHANGE_DETAIL OCD
@@ -265,6 +271,97 @@
 		 ORDER BY OD.ORD_DTL_NO
 	</select>
 	
+	<!-- 취소/반품 환불 사전 정보 조회 -->
+	<select id="getRefundPreInfo" parameterType="OrderChange" resultType="Order">
+		/* TscOrderChange.getRefundPreInfo */
+		SELECT O.ORD_NO
+			 , OD.ORD_DTL_NO
+			 , OD.GOODS_CD
+			 , G1.GOODS_NM
+			 , ODI.ORD_DTL_ITEM_SQ
+			 , ODI.ITEM_CD
+			 , G2.GOODS_NM									AS ITEM_NM
+			 , ODI.ITEM_QTY
+			 , OD.ORD_QTY
+			 , OD.CNCL_RTN_QTY
+			 , OCD.ORD_REQ_CHG_QTY
+			 , ODI.ITEM_PRICE
+			 , ODI.OPT_ADD_PRICE
+			 , ODI.ORD_AMT
+			 , ODI.OPT_CD1
+			 , ODI.OPT_CD2
+			 , ODI.CPN1_DC_AMT
+			 , ODI.TMTB1_DC_AMT
+			 , ODI.TMTB2_DC_AMT
+			 , ODI.GOODS_CPN_DC_AMT
+			 , ODI.CART_CPN_DC_AMT
+			 , ODI.PNT_DC_AMT
+			 , ODI.PRE_PNT_DC_AMT
+			 , ODI.SAVE_PNT_AMT
+			 , ODI.GFCD_USE_AMT
+			 , ODI.CNCL_RTN_AMT
+			 , FN_GET_CODE_NM('G056', OD.GOODS_TYPE)		AS GOODS_TYPE_NM
+			 , ODI.ORD_DTL_STAT
+			 , FN_GET_CODE_NM('G013', ODI.ORD_DTL_STAT)		AS ORD_DTL_STAT_NM
+			 , DF.DELV_FEE
+			 , DFP.MIN_ORD_AMT
+			 , DFP.DELV_FEE									AS ORG_DELV_FEE
+			 , DFP.RTN_DELV_FEE
+			 , DFP.DELV_FEE + DFP.RTN_DELV_FEE				AS EXC_DELV_FEE
+			 , DFP.SUPPLY_COMP_CD
+			 , DFP.DELV_FEE_CD
+			 , P.PAY_STAT
+			 , P.PAY_STAT
+		  FROM TB_ORDER O
+		 INNER JOIN TB_ORDER_DETAIL OD
+		    ON O.ORD_NO = OD.ORD_NO
+		 INNER JOIN TB_ORDER_DETAIL_ITEM ODI
+		    ON O.ORD_NO = ODI.ORD_NO
+		   AND OD.ORD_DTL_NO = ODI.ORD_DTL_NO
+		 INNER JOIN TB_GOODS G1
+		    ON OD.GOODS_CD = G1.GOODS_CD
+		 INNER JOIN TB_GOODS G2
+		    ON ODI.ITEM_CD = G2.GOODS_CD
+		 INNER JOIN TB_PAYMENT P
+		    ON P.ORD_NO = O.ORD_NO
+		  LEFT OUTER JOIN (SELECT OD.ORD_DTL_NO
+								, SUM(OCD.CHG_QTY) AS ORD_REQ_CHG_QTY
+							 FROM TB_ORDER_CHANGE_DETAIL OCD
+							INNER JOIN TB_ORDER_DETAIL OD
+							   ON OCD.ORD_DTL_NO = OD.ORD_DTL_NO
+							WHERE OCD.DEL_YN = 'N'
+							  AND OCD.CHG_STAT IN ('G685_20', 'G685_30', 'G685_33', 'G685_40')
+							GROUP BY OCD.ORD_DTL_NO
+						  ) OCD
+		    ON OD.ORD_DTL_NO = OCD.ORD_DTL_NO
+		  LEFT OUTER JOIN (SELECT X.DELV_FEE_CD
+								, SUM(X.DELV_FEE) AS DELV_FEE
+							 FROM TB_DELIVERY_FEE X
+							WHERE X.DELV_FEE_GB = 'G018_10'
+							GROUP BY X.DELV_FEE_CD
+						  ) DF
+		    ON OD.DELV_FEE_CD = DF.DELV_FEE_CD
+		  LEFT OUTER JOIN TB_DELV_FEE_POLICY DFP
+		    ON DF.DELV_FEE_CD = DFP.DELV_FEE_CD
+		   AND DFP.USE_YN = 'Y'
+		<where>
+			<choose>
+				<when test='custNo != null and custNo != ""'>
+		   AND O.CUST_NO = #{custNo}
+				</when>
+				<otherwise>
+		   AND O.ORD_NO = #{ordNo}
+		   AND O.ORD_NM = #{orderNm}
+				</otherwise>
+			</choose>
+			<if test="ordNo != null and ordNo != ''">
+		   AND O.ORD_NO = #{ordNo}
+			</if>
+		   AND O.DISP_YN = 'Y'
+		</where>
+
+	</select>
+	
 	<!-- 사용 상품권 정보 조회 -->
 	<select id="getUsedGiftcardInfo" parameterType="Order" resultType="GiftCard">
 		/* TscOrderChange.getUsedGiftcardInfo */

+ 206 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsfReview.xml

@@ -276,4 +276,210 @@
 		WHERE R.GOODS_CD = #{goodsCd}
 	</select>
 
+	<!-- 마이페이지 작성가능한 리뷰 -->
+	<select id="getCompleteReviewList" parameterType="Review" resultType="Goods">
+		/* TsfReivew.getCompleteReviewList */
+		SELECT F.*
+			  , (SELECT MAX(SYS_IMG_NM) FROM TB_GOODS_IMG  WHERE GOODS_CD = F.GOODS_CD AND COLOR_CD = F.MAIN_COLOR_CD AND DEFAULT_IMG_YN = 'Y' ) AS SYS_IMG_NM
+		FROM
+		(
+			SELECT O.ORD_NO 
+			      ,O.ORD_NM
+			      ,DATE_FORMAT(O.PAY_DT, '%Y-%m-%d') AS PAY_DT 
+			      ,O.CUST_NO 
+			      ,OD.ORD_DTL_NO
+			      ,OD.ORD_EXCH_GB 
+			      ,OD.GOODS_CD 
+			      ,OD.REAL_ORD_AMT 
+			      ,OD.SAVE_PNT_AMT 
+			      ,OD.GFCD_USE_AMT 
+			      ,ODI.ORD_DTL_ITEM_SQ 
+			      ,ODI.ITEM_CD 
+			      ,ODI.OPT_CD 
+			      ,ODI.OPT_CD1
+			      ,ODI.OPT_CD2
+			      ,ODI.ITEM_QTY 
+			      ,ODI.ITEM_PRICE
+			      ,G.GOODS_NM 
+			      ,G.MAIN_COLOR_CD
+			      ,B.BRAND_ENM 
+			      ,I.ITEMKIND_NM 
+			      ,I.ITEMKIND_CD 
+			      ,I.SIZE_GB 
+			      ,DATEDIFF( DATE_ADD(O.PAY_DT,INTERVAL 90 DAY),NOW()) AS REMAIN_DT -- 남은시간
+			FROM TB_ORDER O INNER JOIN TB_ORDER_DETAIL OD ON O.ORD_NO = OD.ORD_NO 
+								 			 	AND OD.ORD_DTL_STAT = 'G013_70' -- 구매 확정인것만
+			                INNER JOIN TB_ORDER_DETAIL_ITEM ODI ON OD.ORD_DTL_NO = ODI.ORD_DTL_NO 
+			                  					 AND OD.ORD_DTL_NO = ODI.ORD_DTL_NO
+			                  	                 AND ODI.ORD_DTL_STAT = 'G013_70'
+			                INNER JOIN TB_GOODS G ON G.GOODS_CD = OD.GOODS_CD 
+			                INNER JOIN TB_BRAND B ON B.BRAND_CD = G.BRAND_CD
+			                LEFT JOIN TB_ITEMKIND I ON G.ITEMKIND_CD = I.ITEMKIND_CD 
+			WHERE 1=1
+				AND O.PAY_DT <![CDATA[>]]>  DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL -90 DAY), '%Y%M%D%H%I%S') <!--  60 일이내것만 -->
+				AND O.ORD_NO NOT IN (SELECT R.ORD_NO FROM TB_REVIEW R WHERE R.DEL_YN = 'N')
+				AND O.CUST_NO = #{custNo}
+				AND O.DISP_YN = 'Y'
+				AND O.SITE_CD = #{siteCd}
+				<if test="ordNo!=null and ordNo != ''">
+				AND O.ORD_NO = #{ordNo}
+				</if>
+				<if test="ordDtlNo!=null and ordDtlNo != ''">
+				AND OD.ORD_DTL_NO = #{ordDtlNo}
+				</if>
+				<if test="goodsCd!=null and goodsCd!=''">
+				AND G.GOODS_CD = #{goodsCd}
+				</if>
+			GROUP BY O.ORD_NO 
+			      ,O.ORD_NM 
+			      ,O.PAY_DT 
+			      ,O.CUST_NO 
+			      ,OD.ORD_DTL_NO
+			      ,OD.ORD_EXCH_GB 
+			      ,OD.GOODS_CD 
+			      ,OD.REAL_ORD_AMT 
+			      ,OD.SAVE_PNT_AMT 
+			      ,OD.GFCD_USE_AMT 
+			      ,ODI.ORD_DTL_ITEM_SQ 
+			      ,ODI.ITEM_CD 
+			      ,ODI.OPT_CD 
+			      ,ODI.OPT_CD1
+			      ,ODI.OPT_CD2
+			      ,ODI.ITEM_QTY 
+			      ,ODI.ITEM_PRICE
+			      ,G.GOODS_NM 
+			      ,G.MAIN_COLOR_CD
+			      ,B.BRAND_ENM 
+		)F
+		ORDER BY F.PAY_DT DESC
+	</select>
+	
+	<!-- 마이페이지 작성가능한 리뷰 -->
+	<select id="getCompleteReviewCount" parameterType="Review" resultType="int">
+		/* TsfReivew.getCompleteReviewCount */
+		SELECT  COUNT(*) AS CNT 
+		FROM
+		(
+			SELECT O.ORD_NO 
+			      ,O.ORD_NM 
+			      ,O.PAY_DT 
+			      ,O.CUST_NO 
+			      ,OD.ORD_DTL_NO
+			      ,OD.ORD_EXCH_GB 
+			      ,OD.GOODS_CD 
+			      ,OD.REAL_ORD_AMT 
+			      ,OD.SAVE_PNT_AMT 
+			      ,OD.GFCD_USE_AMT 
+			      ,ODI.ORD_DTL_ITEM_SQ 
+			      ,ODI.ITEM_CD 
+			      ,ODI.OPT_CD 
+			      ,ODI.OPT_CD1
+			      ,ODI.OPT_CD2
+			      ,ODI.ITEM_QTY 
+			      ,ODI.ITEM_PRICE
+			      ,G.GOODS_NM 
+			      ,G.MAIN_COLOR_CD
+			      ,B.BRAND_ENM 
+			      ,DATEDIFF( DATE_ADD(O.PAY_DT,INTERVAL 90 DAY),NOW()) AS DT -- 남은시간
+			FROM TB_ORDER O INNER JOIN TB_ORDER_DETAIL OD ON O.ORD_NO = OD.ORD_NO 
+								 			 AND OD.ORD_DTL_STAT = 'G013_70'--  구매 확정인것만
+			                INNER JOIN TB_ORDER_DETAIL_ITEM ODI ON OD.ORD_DTL_NO = ODI.ORD_DTL_NO 
+			                  					 AND OD.ORD_DTL_NO = ODI.ORD_DTL_NO
+			                  	                 AND ODI.ORD_DTL_STAT = 'G013_70'
+			                INNER JOIN TB_GOODS G ON G.GOODS_CD = OD.GOODS_CD 
+			                INNER JOIN TB_BRAND B ON B.BRAND_CD = G.BRAND_CD
+			WHERE 1=1
+				AND O.PAY_DT <![CDATA[>]]>  DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL -90 DAY), '%Y%M%D%H%I%S') <!--  60 일이내것만 -->
+				AND O.ORD_NO NOT IN (SELECT R.ORD_NO FROM TB_REVIEW R WHERE R.DEL_YN = 'N')
+				AND O.CUST_NO = #{custNo}
+				AND O.DISP_YN = 'Y'
+				AND O.SITE_CD = #{siteCd}
+			GROUP BY O.ORD_NO 
+			      ,O.ORD_NM 
+			      ,O.PAY_DT 
+			      ,O.CUST_NO 
+			      ,OD.ORD_DTL_NO
+			      ,OD.ORD_EXCH_GB 
+			      ,OD.GOODS_CD 
+			      ,OD.REAL_ORD_AMT 
+			      ,OD.SAVE_PNT_AMT 
+			      ,OD.GFCD_USE_AMT 
+			      ,ODI.ORD_DTL_ITEM_SQ 
+			      ,ODI.ITEM_CD 
+			      ,ODI.OPT_CD 
+			      ,ODI.OPT_CD1
+			      ,ODI.OPT_CD2
+			      ,ODI.ITEM_QTY 
+			      ,ODI.ITEM_PRICE
+			      ,G.GOODS_NM 
+			      ,G.MAIN_COLOR_CD
+			      ,B.BRAND_ENM 
+		)F
+		ORDER BY F.PAY_DT DESC
+	</select>
+	
+	<select id="saveMypageReview" parameterType="Review" resultType="Review">
+		/* TsfReivew.saveMypageReview */
+		INSERT INTO TB_REVIEW (
+						GOODS_CD
+					  , CUST_NO
+					  , ORD_NO
+					  , ORD_DTL_NO
+					  , REVIEW_TITLE
+					  , REVIEW_CONTENT
+					  , SCORE
+					  , HEIGHT
+					  , WEIGHT
+					  , SCORE_SIZE
+					  , SCORE_COLOR
+					  , SCORE_FIT
+					  , SCORE_THICK
+					  , SCORE_WEIGHT
+					  , SCORE_BALL
+					  , DISP_YN
+					  , DEL_YN
+					  , REG_NO
+					  , REG_DT
+					  , UPD_NO
+					  , UPD_DT
+					)
+					VALUES (
+					     	#{goodsCd}
+						  , #{custNo}
+						  , #{ordNo}
+						  , #{ordDtlNo}
+						  , #{reviewTitle}
+						  , #{reviewContent}
+						  , #{score}
+						  , #{height}
+						  , #{weight}
+						  , #{scoreSize}
+						  , #{scoreColor}
+						  , #{scoreFit}
+						  , #{scoreThick}
+						  , #{scoreWeight}
+						  , #{scoreBall}
+						  , #{dispYn}
+						  , #{delYn}
+						  , #{regNo}
+						  , now()
+						  , #{updNo}
+						  , now()
+					)
+					ON DUPLICATE KEY UPDATE
+					
+			                REVIEW_TITLE   =  #{reviewTitle}
+			               ,REVIEW_CONTENT =  #{reviewContent} 
+			               ,SCORE          =  #{score}           
+			               ,HEIGHT         =  #{height}          
+			               ,WEIGHT         =  #{weight}          
+			               ,SCORE_SIZE     =  #{scoreSize}       
+			               ,SCORE_COLOR    =  #{scoreColor}      
+			               ,SCORE_FIT      =  #{scoreFit}        
+			               ,SCORE_THICK    =  #{scoreThick}      
+			               ,SCORE_WEIGHT   =  #{scoreWeight}     
+			               ,SCORE_BALL     =  #{scoreBall}       
+			               ,UPD_DT         =  now()     
+			                           
+	</select>
 </mapper>

+ 2 - 1
src/main/webapp/WEB-INF/views/web/common/fragments/HeadWeb.html

@@ -57,7 +57,8 @@
 	<link rel="stylesheet" type="text/css" th:href="@{'/ux/pc/css/font.css?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" href="/ux/pc/css/font.css"/>
 	<link rel="stylesheet" type="text/css" th:href="@{'/ux/pc/css/common.css?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" href="/ux/pc/css/common.css"/>
 	<link rel="stylesheet" type="text/css" th:href="@{'/ux/pc/css/layout.css?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" href="/ux/pc/css/layout.css"/>
-
+	<link rel="stylesheet" type="text/css" th:href="@{'/ux/pc/css/main.css?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" href="/ux/pc/css/main.css"/>
+	
 	<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
 	<!--<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>-->
 	<script src="https://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

+ 83 - 2
src/main/webapp/WEB-INF/views/web/display/BrandMainFormWeb.html

@@ -113,16 +113,97 @@
 					</div>
 				</th:block>
 
+				<!-- LOOKBOOK -->
+				<th:block th:if="${contentsLoc=='010'}">
+					<div class="content br_lookbook" th:if="${brandMainLayoutData.lookbookList != null and !brandMainLayoutData.lookbookList.empty}">
+						<div class="cont_head">
+							<p class="displayH t_c" th:text="${contentsTitle}"></p>
+						</div>
+						<div class="cont_body">
+							<div class="swiper-container">
+								<div class="swiper-wrapper">
+									<th:block th:each="LookbookData, LookbookStat : ${brandMainLayoutData.lookbookList}">
+										<form >
+										</form>
+
+										<div class="swiper-slide">
+											<div class="bt_lb_item">
+												<img class="vLHTC lb_img" th:src="${@environment.getProperty('domain.image')+LookbookData.sysFileNm}" alt="BLUE-a" />
+												<th:block th:if="${LookbookData.lookbookGoodsList != null and !LookbookData.lookbookGoodsList.empty}" th:each="lookbookGoods, status : ${LookbookData.lookbookGoodsList}">
+													<div class="item_picker" th:style="${'left:'+lookbookGoods.xlim+'%; top:'+lookbookGoods.ylim+'%;'}">
+														<!--<button type="button" id="btn_lookbook_picker01" ><span class="ico ico_picker"></span></button>-->
+														<button type="button" th:onclick="fnGoodsPopup([[${lookbookGoods.sysImgNm}]],[[${lookbookGoods.brandGroupNm}]],[[${lookbookGoods.goodsNm}]],[[${lookbookGoods.listPrice}]],[[${lookbookGoods.currPrice}]],[[${lookbookGoods.dcRate}]],[[${lookbookGoods.goodsCd}]])"><span class="ico ico_picker"></span></button>
+														<!--id="btn_lookbook_picker01" <div class="pick_descr">
+															<a href="" th:text="${lookbookGoods.goodsNm}">
+															</a>
+														</div>-->
+													</div>
+												</th:block>
+											</div>
+										</div>
+									</th:block>
+								</div>
+								<div class="swiper-button-prev"></div>
+								<div class="swiper-button-next"></div>
+							</div>
+							<div class="swiper-pagination"></div>
+
+						</div>
+					</div>
+				</th:block>
+
 			</th:block>
 		</th:block>
 	</div>
 </div>
 
+	<!-- lookbook_picker_상품_팝업 -->
+	<div class="modal fade br_lookbook_popup" id="brLookbookPopup" tabindex="-1" role="dialog" aria-labelledby="br_lookbook_label" aria-hidden="true">
+		<div class="modal-dialog" role="document">
+			<div class="modal-content">
+				<div class="modal-header">
+					<h5 class="modal-title sr-only" id="br_lookbook_label">상품정보</h5>
+				</div>
+				<div class="modal-body">
+					<div class="itemsGrp">
+						<div class="item_prod"> <!-- 품절일때 sold_out 클래스 추가 요청 -->
+							<div class="item_state">
+								<div class="itemLink">
+									<div class="itemPic">
+										<img alt="BLACK-a" class=" vLHTC pd_img" src="">
+									</div>
+									<p class="itemBrand"></p>
+									<div class="itemName"></div>
+									<span class="itemPrice_original"></span>
+									<p class="itemPrice">
+										<span class="itemPercent"></span>
+									</p>
+									<button type="button" class="btn btn_default"><span>자세히 보기</span></button>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- //lookbook_picker_상품_팝업 -->
+
 <script th:inline="javascript">
 /*<![CDATA[*/
 var brandMainLayoutList = [[${brandMainLayoutList}]];
-console.log('brandMainLayoutList::'+brandMainLayoutList);
-
+//console.log('brandMainLayoutList::'+brandMainLayoutList);
+var goodsImgUrl = [[${@environment.getProperty('upload.goods.view')}]];
+var fnGoodsPopup = function(obj1,obj2,obj3,obj4,obj5,obj6,obj7){
+	$("#brLookbookPopup").modal("show");
+	$("#brLookbookPopup").find(".pd_img").attr('src',goodsImgUrl+'/'+obj1);
+	$("#brLookbookPopup").find(".itemBrand").text(obj2);
+	$("#brLookbookPopup").find(".itemName").text(obj3);
+	$("#brLookbookPopup").find(".itemPrice_original").text(obj4);
+	$("#brLookbookPopup").find(".itemPrice").text(obj5);
+	$("#brLookbookPopup").find(".itemPercent").text(obj6+'%');
+	$("#brLookbookPopup").find(".btn_default").attr('onclick','cfnGoToPage(_PAGE_GOODS_DETAIL+"'+obj7+'");');
+}
 $(document).ready( function() {
 
 	// 컨텐츠 호출

+ 273 - 0
src/main/webapp/WEB-INF/views/web/display/CategoryMainFormWeb.html

@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : MallMainFormWeb.html
+ * @desc    : 몰메인 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.03.25   gagamel     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+
+<div id="container" class="container dp"> 
+	<div class="breadcrumb"> 
+		<ul>
+			<li class="bread_home"><a href="javascript:void(0);" onclick="cfnGoToPage(_PAGE_MAIN);">홈</a></li>
+			<li class="bread_2depth cate1Nm">여성1</li>
+		</ul> 
+	</div>
+
+	<div class="wrap">
+		<div class="content dp_submain"> <!-- 페이지특정 클래스 = dp_list -->
+			<div class="cont_head">
+				<div>
+					<h3 class="cate1Nm">여성</h3>
+				</div>
+			</div>
+			<div class="cont_body">
+				<div class="dp_sum_slide dp_inner">
+					<div class="swiper-container">
+						<div class="swiper-wrapper">
+							<div class="swiper-slide">
+								<a href="">
+									<div class="img">
+										<img src="/images/pc/thumb/dp_submain_img01.jpg" alt="서브메인 썸네일"/>
+									</div>
+									<div class="txt">
+										<p class="subject">포근한 새해를 위한 필수템<br>겨울신상 세일</p>
+										<span>시간이 지나면서 빛을 더하는 아우터</span>
+									</div>
+								</a>
+							</div>
+							<div class="swiper-slide">
+								<a href="">
+									<div class="img">
+										<img src="/images/pc/thumb/dp_submain_img02.jpg" alt="서브메인 썸네일"/>
+									</div>
+									<div class="txt">
+										<p class="subject">겨울정기 가격제안전</p>
+										<span>전 브랜드 시즌오프 모아보기</span>
+									</div>
+								</a>
+							</div>
+							<div class="swiper-slide">
+								<a href="">
+									<div class="img">
+										<img src="/images/pc/thumb/dp_submain_img03.jpg" alt="서브메인 썸네일"/>
+									</div>
+									<div class="txt">
+										<p class="subject">추위를 물리치는 현명한 방법은?<br>패딩과 니트</p>
+										<span>모두에게  잘 어울리는 겨울 아이템</span>
+									</div>
+								</a>
+							</div>
+							<div class="swiper-slide">
+								<a href="">
+									<div class="img">
+										<img src="/images/pc/thumb/dp_submain_img03.jpg" alt="서브메인 썸네일"/>
+									</div>
+									<div class="txt">
+										<p class="subject">추위를 물리치는 현명한 방법은?<br>패딩과 니트</p>
+										<span>모두에게  잘 어울리는 겨울 아이템</span>
+									</div>
+								</a>
+							</div>
+							<div class="swiper-slide">
+								<a href="">
+									<div class="img">
+										<img src="/images/pc/thumb/dp_submain_img03.jpg" alt="서브메인 썸네일"/>
+									</div>
+									<div class="txt">
+										<p class="subject">추위를 물리치는 현명한 방법은?<br>패딩과 니트</p>
+										<span>모두에게  잘 어울리는 겨울 아이템</span>
+									</div>
+								</a>
+							</div>
+						</div>
+						<div class="swiper-controls">
+							<div class="swiper-scrollbar"></div>
+						</div>
+					</div>
+					<!-- Add Arrows -->
+					<div class="swiper-button-next"></div>
+					<div class="swiper-button-prev"></div>
+				</div>
+			</div>
+		</div>
+		
+		<div class="content wide dp_category">
+			<div class="cont_head">
+				<h3 class="displayH">카테고리 바로가기</h3>
+			</div>
+			<div class="cont_body">
+				<div class="">
+					<div class="dp_cate_list">
+					</div>
+				</div>
+			</div>
+		</div>
+		
+		<!-- 신상품 -->
+		<div class="content wide new_item" th:if="${newGoodsList != null}">
+			<div class="cont_head">
+				<h3 class="displayH">신상품</h3>
+			</div>
+			<div class="cont_body">
+				<div class="swiper-container post-trendy">
+					<div class="swiper-wrapper">
+						<div class="swiper-slide" th:each="item, status : ${newGoodsList}">
+							<div class="item_prod">
+								<div class="item_state">
+									<button type="button" class="itemLike" th:classappend="${item.likeIt}">관심상품 추가</button>
+									<a href="javascript:void(0);" class="itemLink" th:onclick="cfnGoToGoodsDetail([[${item.goodsCd}]], '', '', 'SCM001');">
+										<div class=" itemPic">
+											<img class="vLHTC pd_img" th:src="${@environment.getProperty('upload.goods.view') + '/' + item.sysImgNm}" th:alt="${item.goodsCd}"/>
+										</div>
+										<p class="itemBrand" th:text="${item.brandGroupNm}">BRAND NAME</p>
+										<div class="itemName" th:text="${item.goodsFullNm}">스타 착용 여성 퍼 아플리케 오버핏 투마일 웨어링 점퍼</div>
+										<p class="itemPrice" th:text="${#numbers.formatInteger(item.currPrice,3,'POINT') + '원'}">488,000원</p>
+										<div class="itemComment" th:if="${not #strings.isEmpty(item.goodsTnm)}" th:text="${item.goodsTnm}">#가을느낌 물씬!</div>
+									</a>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="swiper-pagination"></div>
+				<div class="swiper-button-prev"></div>
+				<div class="swiper-button-next"></div>
+			</div>
+		</div>
+		<!-- //신상품 -->
+		
+		<div class="content main_recomm" th:if="${bestGoodsList != null}">
+			<div class="cont_head">
+				<h3 class="displayH">베스트</h3>
+			</div>
+			<div class="cont_body">
+				<div class="list_content">
+					<div class="itemsGrp"> <!-- itemsGrp rank hot deal -->
+						<div class="item_prod" th:each="item, status : ${bestGoodsList}">
+							<div class="item_state" >
+								<button type="button" class="itemLike" th:classappend="${item.likeIt}">관심상품 추가</button>
+								<a href="javascript:void(0);" class="itemLink" th:onclick="cfnGoToGoodsDetail([[${item.goodsCd}]], '', '', 'SCM002');">
+									<div class="rank ranker"><span th:text="${status.index+1}">1</span></div>
+									<div class="itemPic">
+										<img class="vLHTC pd_img" th:src="${@environment.getProperty('upload.goods.view') + '/' + item.sysImgNm}" th:alt="${item.goodsCd}"/>
+									</div>
+									<p class="itemBrand" th:text="${item.brandGroupNm}">BRAND NAME</p>
+									<div class="itemName" th:text="${item.goodsFullNm}">남성 헤링본 기모 팬츠 헤링본 기모 팬츠</div>
+									<p class="itemPrice">
+										<span th:text="${#numbers.formatInteger(item.currPrice,3,'POINT') + '원'}">80,100</span>
+										<span class="itemPrice_original" th:if="${item.currPrice != item.listPrice}" th:text="${#numbers.formatInteger(item.listPrice,3,'POINT') + '원'}">89,000</span>
+										<span class="itemPercent" th:if="${item.currPrice != item.listPrice}" th:text="${(item.listPrice == 0 ? 0 : #numbers.formatDecimal((item.listPrice - item.currPrice) / (item.listPrice * 1.0) * 100, 1, 0)) + '%'}">10%</span>
+									</p>
+									<div class="itemComment" th:if="${not #strings.isEmpty(item.goodsTnm)}" th:text="${item.goodsTnm}">#주문 폭주 상품</div>
+								</a>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	$(document).ready(function() {
+		fnSetCategory1Depts();
+	});
+	
+	var submain_slide = new Swiper('.dp_sum_slide .swiper-container', {
+		slidesPerView: 4,
+		spaceBetween: 20,
+		freeMode:true,
+		scrollbar: {
+			el: '.dp_sum_slide .swiper-scrollbar',
+			hide: false,
+		},
+		navigation: {
+			nextEl: '.dp_sum_slide .swiper-button-next',
+			prevEl: '.dp_sum_slide .swiper-button-prev'
+		}
+	});
+
+	/* SLIDE - NEW ITEMS */
+	var dp_submain_newitem = new Swiper('.dp .new_item .swiper-container', {
+		watchSlidesProgress: true,
+		watchSlidesVisibility: true,
+		allowTouchMove: false,
+		speed : 1000,
+		autoplay: {
+			delay: 3000,
+			disableOnInteraction:false
+		},
+		navigation: {
+			nextEl: '.dp .new_item .swiper-button-next',
+			prevEl: '.dp .new_item .swiper-button-prev'
+		},
+		pagination: {
+			el: '.dp .new_item .swiper-pagination',
+			clickable: true
+		},
+		slidesPerView: 'auto',
+		spaceBetween: 22
+	});
+	
+	dp_submain_newitem.on('slideChange', function () {
+		var newitemIndex = dp_submain_newitem.activeIndex;
+		var slideWidth = $(".dp .new_item .swiper-slide-visible").eq(0).width() + 22;
+
+		$(".dp .new_item .swiper-slide").removeClass('scaleBig');
+		$(".dp .new_item .swiper-slide-visible").eq(0).addClass('scaleBig');
+		$(".dp .new_item .swiper-slide-visible").eq(3).addClass('scaleBig');
+		
+		$(".dp .new_item .swiper-wrapper").css("transform","translateX(-"+ (slideWidth * newitemIndex) +"px)");
+	});
+
+	dp_submain_newitem.on('reachEnd', function () {
+		var newitemIndex = dp_submain_newitem.activeIndex + 1;
+		var slideWidth = $(".dp .new_item .swiper-slide-visible").eq(0).width() + 22;
+		
+		$(".dp .new_item .swiper-slide").removeClass('scaleBig');
+		$(".dp .new_item .swiper-slide-visible").eq(1).addClass('scaleBig');
+		$(".dp .new_item .swiper-slide-visible").eq(4).addClass('scaleBig');
+
+		$(".dp .new_item .swiper-wrapper").css("transform","translateX(-"+ (slideWidth * newitemIndex) +"px)");
+	});
+	
+	// 카테고리1Depts 설정
+	var fnSetCategory1Depts = function() {
+		let allCate = [[${allCateList}]];
+		$.each(allCate, function(idx1, cate1) {
+			if ([[${params.cate1No}]] == cate1.cate1No) {
+				let tag = '<a href="javascript:void(0);" onclick="cfnGoToItemkindMain(\'' + cate1.cateGb + '\', ' + cate1.cate1No + ');">전체</a>\n';
+				if (cate1.leafYn == 'N' && cate1.cate2List.length > 0) {
+					$.each(cate1.cate2List, function(idx2, cate2) {
+						tag += '<a href="javascript:void(0);" onclick="cfnGoToItemkindMain(\'' + cate2.cateGb + '\',' + cate2.cate1No + ',' + cate2.cate2No + ');">' + cate2.cate2Nm + '</a>\n';
+					});
+				}
+				$('.dp_cate_list').html(tag);
+				$('.cate1Nm').html(cate1.cate1Nm);
+			}
+		});
+	}
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 1 - 1
src/main/webapp/WEB-INF/views/web/goods/GoodsIncludeFormWeb.html

@@ -97,7 +97,7 @@
 						<div class="item_prod" th:each="goodsInfo, status : ${goodsDealComposeList}" th:attr="aria-disabled=${(goodsInfo.stockQty <= 0)? 'true':''}, data-soldout=${(goodsInfo.stockQty <= 0)? 'true':''}">
 							<div class="item_state">
 								<a href="javascript:void(0);" class="itemLink" th:onclick="cfGoodsDeailDetail([[${goodsInfo.goodsCd}]],[[${goodsInfo.compsGoodsCd}]])">
-									<div class="rank detail">
+									<div class="shape ranker">
 										<span>상품<em class="number" th:text="${#numbers.formatInteger(status.count,2)}">01</em></span>
 									</div>
 									<div class="itemPic">

+ 0 - 3
src/main/webapp/WEB-INF/views/web/mypage/MypageCouponDetailPopWeb.html

@@ -36,21 +36,18 @@
                		</th:block>
                 </p>
                 
-                
                 <p><strong>카테고리</strong>
                 	<th:block th:each="CateData, CateStat : ${cpnDtlRefvalCateList}">
                 		[[${CateData.cateNm}]],
                 	</th:block>
                 </p>
                 
-                
                 <p><strong>상품</strong>
                 	<th:block th:each="GoodsData, GoodsStat : ${cpnDtlRefvalApplyGoodsList}">
                 		[[${GoodsData.goodsNm}]],
                 	</th:block>
                 </p>
                 
-                
                 <p><strong>제외상품</strong>
                 	<th:block th:each="ExceptData, ExceptStat : ${cpnDtlRefvalExceptGoodsList}">
                 		[[${ExceptData.goodsNm}]],

+ 3 - 2
src/main/webapp/WEB-INF/views/web/mypage/MypageGiftcardFormWeb.html

@@ -26,10 +26,11 @@
 				<div class="lnb">
 							<div class="lnb_tit">
 						<h2>마이페이지</h2>
-					</div>
-					<div class="lnb_list">
+						<div class="lnb_list">
 						<ul id="mypageLnbList"></ul>
 					</div>
+					</div>
+					
 				</div>
 				<div class="cont">
 					<div class="sec_head">

+ 23 - 21
src/main/webapp/WEB-INF/views/web/mypage/MypageOrderDetailFormWeb.html

@@ -54,6 +54,8 @@
 									<div class="goods_info">
 										<div class="order_desc">
 											<div class="goods_box">
+												<input type="hidden" name="ordDtlNoArr" th:value="${ordDtl.ordDtlNo}"/>
+												<input type="hidden" name="cnclRtnReqQtyArr" th:value="${ordDtl.ordQty - ordDtl.cnclRtnQty}"/>
 												<div class="gd_item">
 													<a href="javascript:void(0)" th:attr="goodsCd=${ordDtl.goodsCd}" onclick="fnGoToGoodsDetail(this)">
 														<span class="thumb">
@@ -73,7 +75,8 @@
 												<div class="gd_opt">
 													<div class="option_wrap">
 														<span class="title sr-only">주문 옵션</span>
-														<span class="option" th:text="|${ordDtl.optCd1} / ${ordDtl.optCd2}|"></span>
+														<span class="option" th:if="${ordDtl.goodsType == 'G056_S'}" th:each="option, status : ${ordDtl.colorNmArr}" th:text="|${ordDtl.itemNmArr[status.index]} / ${option} / ${ordDtl.optCd2Arr[status.index]}|"></span>
+														<span class="option" th:unless="${ordDtl.goodsType == 'G056_S'}" th:text="|${ordDtl.colorNm} / ${ordDtl.optCd2}|"></span>
 													</div>
 												</div>
 												<div class="gd_calc">
@@ -459,50 +462,49 @@
 	
 	// 전체취소 버튼 클릭 이벤트
 	var fnAllCancel = function() {
-		let cancelRequestList = [];
-
-		$.each(orderList[0].ordDtlList, function(idx, item) {
-			item.ordCanChgQty = (item.ordQty - item.cnclRtnQty);
-			cancelRequestList.push(item);
-		});
-		
 		// 환불계좌 체크
 		let accountNo = $('input[name=accountNo]').val();
 		let accountNm = $('input[name=accountNm]').val();
 		let bankCd = $('input[name=bankCd]').val();
-		
+
 		if (paymentInfo.payMeans == 'G014_20' && paymentInfo.payStat == 'G016_00' && (gagajf.isNull(accountNo) || gagajf.isNull(accountNm) || gagajf.isNull(bankCd))) {
 			// TODO
 			// 환불계좌 등록 팝업
 			
 			return false;
 		}
-		
+
 		// 취소요청 데이터 설정
-		let url = '/mypage/cancel';
+		let url = '/mypage/cancel/all';
 		
-		let allCanYn = '';
-		if (paymentInfo.payMeans == 'G014_20' && paymentInfo.payStat == 'G016_00') {
-			allCanYn = 'Y';
-		}
+		// 주문상세번호 설정
+		let ordDtlNoArr = [];
+		$.each($('input[name=ordDtlNoArr]'), function(idx, item) {
+			ordDtlNoArr.push($(item).val());
+		});
 		
+		// 취소 수량 설정
+		let cnclRtnReqQtyArr = [];
+		$.each($('input[name=cnclRtnReqQtyArr]'), function(idx, item) {
+			cnclRtnReqQtyArr.push($(item).val());
+		});
+
+		// 전체 취소 처리
 		let data = {};
 		data.ordNo = ordNo;
 		data.chgReason = 'G686_10';
 		data.accountNo = accountNo;
 		data.accountNm = accountNm;
 		data.bankCd = bankCd;
-		data.allCanYn = allCanYn;
 		data.isCustomer = 'Y';
 		data.reqGbn = 'cnclComplete';
-		data.cancelReqList = cancelRequestList;
+		data.ordDtlNoArr = ordDtlNoArr;
+		data.cnclRtnReqQtyArr = cnclRtnReqQtyArr;
 		
 		let jsonData = JSON.stringify(data);
-		console.log(jsonData);
+
 		gagajf.ajaxJsonSubmit(url, jsonData, function(result) {
-			// TODO
-			// 주문취소 콜백처리
-			console.log(result);
+			cfnGoToPage(_PAGE_MYPAGE_ORDER_LIST);
 		});
 	}
 </script>

+ 9 - 7
src/main/webapp/WEB-INF/views/web/mypage/MypageOrderListFormWeb.html

@@ -325,7 +325,7 @@
 		
 		gagajf.ajaxJsonSubmit(url, jsonData, function(result) {
 			$('#couponCnt').text(result.couponCnt);
-			$('#expiredSoonCouponCnt').text(result.expiredSoonCouponCnt + '장');
+			$('#expiredSoonCouponCnt').text(result.expiredSoonCouponCnt);
 		});
 	}
 	
@@ -364,6 +364,7 @@
 	var fnCreateOrderList = function(param) {
 		let tag = '';
 		let imageUrl = [[${@environment.getProperty('upload.goods.view')}]];
+		console.log(param);
 
 		if (param.orderList != null && param.orderList.length > 0) {
 			$.each(param.orderList, function (idx, order) {
@@ -405,13 +406,14 @@
 					tag += '					<div class="gd_opt">\n';
 					tag += '						<div class="option_wrap">\n';
 					tag += '							<span class="title sr-only">주문 옵션</span>\n';
-					$.each(ordDtl.colorNmArr, function (index2, option) {
-						if (ordDtl.goodsType == 'G056_S') {
+					// 세트아이템 옵션 처리
+					if (ordDtl.goodsType == 'G056_S') {
+						$.each(ordDtl.colorNmArr, function (index2, option) {
 							tag += '							<span class="option">' + ordDtl.itemNmArr[index2] + ' / ' + option + ' / ' + ordDtl.optCd2Arr[index2] + '</span>\n';
-						} else {
-							tag += '							<span class="option">' + option + ' / ' + ordDtl.optCd2Arr[index2] + '</span>\n';
-						}
-					});
+						});
+					} else {
+						tag += '							<span class="option">' + ordDtl.colorNm + ' / ' + ordDtl.optCd2 + '</span>\n';
+					}
 					tag += '						</div>\n';
 					tag += '					</div>\n';
 					tag += '					<div class="gd_calc">\n';

+ 562 - 0
src/main/webapp/WEB-INF/views/web/mypage/MypageReviewCreateFormWeb.html

@@ -0,0 +1,562 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/MypageLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : MypageReviewFormWeb.html
+ * @desc    : 마이페이지 > 리뷰 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.03.24   sowon     최초 작성
+ *******************************************************************************
+ -->
+<body>
+<th:block layout:fragment="content">
+		<div class="content myReviewWrite"> <!-- 페이지특정 클래스 = myReviewWrite -->
+				<div class="cont_body">
+					<!-- CONT-BODY -->
+					<div class="lnb">
+						<div class="lnb_tit">
+							<h2>마이페이지</h2>
+						</div>
+						<div class="lnb_list">
+							<ul id="mypageLnbList"></ul>
+						</div>
+					</div>
+					<div class="cont">
+						<div class="sec_head">
+							<h3 class="subH1">리뷰</h3>
+						</div>
+						<div class="sec_body">
+							<div class="com_info_txt">
+								<p class="tit">리뷰 안내</p>
+								<ul>
+									<li>일반 리뷰 작성 시 150P, 포토/영상 리뷰는 350P가 추가 적립됩니다!</li>
+									<li>월 최대 10,000 P까지 적립 가능합니다.(합산 후 월 1회 지급)</li>
+									<li>베스트 리뷰로 선정되면 10,000P가 추가 적립됩니다!</li>
+									<li>리뷰 작성시 욕설, 비방, 선정적인 내용등이 있을 경우 통보 없이 관리자에 의해 삭제 될 수 있습니다.</li>
+								</ul>
+							</div>
+							<th:block th:each="review, status : ${completeReviewList}" th:with="imageUrl=${@environment.getProperty('upload.goods.view')}">
+							<form class="form_wrap" id="reviewForm" th:action="@{'/mypage/review/save'}">
+								<input type="hidden" name="ordNo" th:value="${review.ordNo}">
+								<input type="hidden" name="ordDtlNo" th:value="${review.ordDtlNo}">
+								<input type="hidden" name="goodsCd" th:value="${review.goodsCd}">
+								<input type="hidden" name="custNo" th:value="${review.custNo}">
+								<h4 class="subH3">리뷰쓰기</h4>
+								<div class="part_goods">
+									<div class="goods_cont">
+										<!-- 주문상품 -->
+										
+										<div class="goods_info">
+											<div class="order_desc">
+												<div class="goods_box">
+													<div class="gd_item">	
+														<a href="">
+															<span class="thumb">
+																<img th:src="${imageUrl + '/' + review.sysImgNm}" width="100%" alt="">
+															</span>
+															<p>
+																<span class="buy_date"><em th:text="${review.payDt}"></em>&nbsp;구매</span>
+															</p>
+															<p>
+																<span class="brand" th:text="${review.brandEnm}"></span>
+																<!-- <span class="tag">STYLE24 일반배송</span> -->
+															</p>
+															<p>
+																<span class="name" th:text="${review.goodsNm}"></span>																
+															</p>
+														</a>
+													</div>
+													<div class="gd_opt">
+														<div class="option_wrap">
+															<span class="title sr-only">주문 옵션</span>
+															<span class="option">[[${review.optCd1}]]K&nbsp;/&nbsp;[[${review.optCd2}]]</span>
+														</div>
+													</div>
+												</div>
+											</div>
+										</div>
+										
+										<!-- //주문상품 -->
+									</div>
+								</div>			
+
+								<h4 class="subH3">별점 선택</h4>
+								<div class="tbl type1">
+									<table>
+										<colgroup>
+											<col width="170">
+											<col width="*">
+										</colgroup>   
+										<tr>
+											<th>
+												별점
+											</th>
+											<td>
+												<div class="input_starscore" id="star">
+													<input type="hidden" id="score" name="score">
+													<button type="button" id="starBtn"></button>
+													<button type="button" id="starBtn"></button>
+													<button type="button" id="starBtn"></button>
+													<button type="button" id="starBtn"></button>
+													<button type="button" id="starBtn"></button>
+												</div>
+											</td>
+										</tr>
+									</table>
+								</div>
+
+								<h4 class="subH3">키 / 몸무게</h4>
+								<div class="tbl type1">
+									<table>
+										<colgroup>
+											<col width="170">
+											<col width="*">
+										</colgroup>   
+										<tr>
+											<th>
+												키
+											</th>
+											<td>
+												<div class="input_my_physical">
+													<div class="form_field">
+														<div class="input_wrap">
+															<input type="text" class="form_control" placeholder="숫자만 입력해 주세요." data-valid-type="numeric" maxlength="3" id="height" name="height">
+															<span class="unit">cm</span>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<tr>
+											<th>
+												몸무게
+											</th>
+											<td>
+												<div class="input_my_physical">
+													<div class="form_field">
+														<div class="input_wrap">
+															<input type="text" class="form_control" placeholder="숫자만 입력해 주세요." data-valid-type="numeric" maxlength="3" id="weight" name="weight">
+															<span class="unit">kg</span>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+									</table>
+								</div>
+								
+								<!-- <th:block th:if="${review.sizeGb == 'T' or review.sizeGb == 'B' or review.sizeGb == 'S'}"> --> 
+								<h4 class="subH3">상품 평가</h4>
+								<div class="tbl type1">
+									<table>
+										<colgroup>
+											<col width="170">
+											<col width="*">
+										</colgroup>  
+										<!-- <th:block th:if="${review.sizeGb == 'T' or review.sizeGb == 'B' or review.sizeGb == 'S'}"> --> 
+										<tr>
+											<th>
+												사이즈
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreSize" id="rdi_review_size1" value="1">
+															<label for="rdi_review_size1"><span>작음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreSize" id="rdi_review_size2" value="2">
+															<label for="rdi_review_size2"><span>딱맞음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreSize" id="rdi_review_size3" value="3">
+															<label for="rdi_review_size3"><span>큼</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<tr>
+											<th>
+												컬러
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreColor" id="rdi_review_color1" value="1">
+															<label for="rdi_review_color1"><span>밝음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreColor" id="rdi_review_color2" value="2">
+															<label for="rdi_review_color2"><span>똑같음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreColor" id="rdi_review_color3" value="3">
+															<label for="rdi_review_color3"><span>어두움</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<!-- </th:block>
+										<th:block th:if="${review.sizeGb == 'T' or review.sizeGb == 'B'}"> --> 
+										<tr>
+											<th>
+												핏
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreFit" id="rdi_review_fit1" value="1">
+															<label for="rdi_review_fit1"><span>슬림</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreFit" id="rdi_review_fit2" value="2">
+															<label for="rdi_review_fit2"><span>레귤러</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreFit" id="rdi_review_fit3" value="3">
+															<label for="rdi_review_fit3"><span>오버</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<tr>
+											<th>
+												두께감
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreThick" id="rdi_review_thick1" value="1">
+															<label for="rdi_review_thick1"><span>얇음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreThick" id="rdi_review_thick2" value="2">
+															<label for="rdi_review_thick2"><span>적당함</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreThick" id="rdi_review_thick3" value="3">
+															<label for="rdi_review_thick3"><span>도톰함</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<!-- </th:block>
+										<th:block th:if="${review.sizeGb == 'S'}">  -->
+										<tr>
+											<th>
+												무게감
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreWeight" id="rdi_review_weight1" value="1">
+															<label for="rdi_review_weight1"><span>가벼움</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreWeight" id="rdi_review_weight2" value="2">
+															<label for="rdi_review_weight2"><span>적당함</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreWeight" id="rdi_review_weight3" value="3">
+															<label for="rdi_review_weight3"><span>무거움</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<tr>
+											<th>
+												볼너비
+											</th>
+											<td>
+												<div class="input_simple_review">
+													<div class="form_field">
+														<div>
+															<input type="radio" name="scoreBall" id="rdi_review_width1" value="1">
+															<label for="rdi_review_width1"><span>작음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreBall" id="rdi_review_width2" value="2">
+															<label for="rdi_review_width2"><span>딱맞음</span></label>
+														</div>
+														<div>
+															<input type="radio" name="scoreBall" id="rdi_review_width3" value="3">
+															<label for="rdi_review_width3"><span>큼</span></label>
+														</div>
+													</div>
+												</div>
+											</td>
+										</tr>
+										<!-- </th:block> -->
+									</table>
+								</div>
+								<!-- </th:block> -->
+								<h4 class="subH3">고객님의 리뷰가 다른 고객들에게 도움이 될 수 있어요!</h4>
+								<div class="tbl type1">
+									<table>
+										<colgroup>
+											<col width="170">
+											<col width="*">
+										</colgroup>   
+										<tr>
+											<th>
+												리뷰내용
+											</th>
+											<td>
+												<div class="input_txt_review">
+													<div class="form_field">
+														<div class="input_wrap">
+															<textarea class="doc_review" name="reviewContent" id="reviewContent" cols="30" rows="10" placeholder="·&nbsp;리뷰 내용은 최소 10자 이상 입력해 주세요.&#13;&#10;·&nbsp;상품과 무관하거나 스팸, 음란, 불법적인 내용의 리뷰는 통보 없이 삭제되며, 지급한 포인트는 회수 될 수 있습니다.&#13;&#10;·&nbsp;리뷰 등록 후 관리자 승인이 필요한 경우 바로 노출이 되지 않을 수 있습니다." style="resize: none;"></textarea>
+															<p class="txt_cnt"><span id="review_cnt" class="c_primary">0</span>/500</p>			
+														</div> 
+													</div>
+												</div>
+											</td>
+										</tr>
+										<tr>
+											<th>
+												포토/영상 첨부
+											</th>
+											<td>
+												<div class="form_field">
+													<div class="input_wrap">
+														<!-- 이미지첨부 -->
+														<div class="form_field">
+															<div class="imgUpload">
+																<label for="fileAdd" class="fileAdd">첫번째업로드</label>
+																<input type="file" id="fileAdd" name="files[]">
+																<input type="hidden" name="file1OrgFileNm"/>
+																<input type="hidden" name="file1SysFileNm"/>
+																<input type="hidden" name="file2OrgFileNm"/>
+																<input type="hidden" name="file2SysFileNm"/>
+																<input type="hidden" name="file3OrgFileNm"/>
+																<input type="hidden" name="file3SysFileNm"/>
+																<input type="hidden" name="file4OrgFileNm"/>
+																<input type="hidden" name="file4SysFileNm"/>
+																<input type="hidden" name="file5OrgFileNm"/>
+																<input type="hidden" name="file5SysFileNm"/>
+																<input type="hidden" name="file6OrgFileNm"/>
+																<input type="hidden" name="file6SysFileNm"/>
+																<input type="hidden" name="file7OrgFileNm"/>
+																<input type="hidden" name="file7SysFileNm"/>
+																<input type="hidden" name="file8OrgFileNm"/>
+																<input type="hidden" name="file8SysFileNm"/>
+																<input type="hidden" name="file9OrgFileNm"/>
+																<input type="hidden" name="file9SysFileNm"/>
+																<input type="hidden" name="file10OrgFileNm"/>
+																<input type="hidden" name="file10SysFileNm"/>
+																
+															</div>
+														</div>
+														<!-- //이미지첨부 -->
+													</div> 
+												</div>
+												<div class="txt_info">
+													<ul>
+														<li>
+															최대 10개까지 등록 가능
+														</li>
+													</ul>
+												</div>
+											</td>
+										</tr>
+									</table>
+								</div>							
+
+								<div class="btn_footer_area">
+									<button type="button" class="btn btn_default btn_md" onclick="reviewCancel()"><span>취소</span></button>
+									<button type="button" id="btn_review_registration" class="btn btn_dark btn_md" onclick="reviewCreate()"><span>리뷰 등록</span></button>
+								</div>		
+							</form>	
+							</th:block>						
+						</div>
+					</div>
+					<!-- // CONT-BODY -->					
+				</div>
+			</div>
+
+<script src="/ux/plugins/gaga/gaga.paging.js"></script>
+<script th:inline="javascript">
+let reviewList = [[${completeReviewList}]];
+// 별점 class="on"
+var $starEls = $('#star button#starBtn');
+var rate = 0;
+
+$starEls.each(function (index, el) {
+    $(el).on('click', function () {
+        rating(index);
+        $("#score").attr("value",index+1);
+    });
+});
+
+function rating(score) {
+    $starEls.each(function (i, el) {
+        if (i <= score) {
+            $(el).addClass('on');
+        } else {
+            $(el).removeClass('on');
+        }
+    });
+
+    rate = score + 1;
+}
+
+// 리뷰  취소
+var reviewCancel = function() {
+	
+	mcxDialog.confirm('취소하시겠습니까"?', {
+        cancelBtnText: "취소",
+        sureBtnText: "확인",
+        sureBtnClick: function(){
+        	cfnGoToPage(_PAGE_MYPAGE_REVIEW);
+        }
+    });
+}
+
+// 리뷰 등록
+var reviewCreate = function () {
+	
+	if($("#score").val()=='' || $("#score").val()==null){
+		mcxDialog.alert('별점을 선택하세요.');
+		return;
+	}
+	
+	if($("#reviewForm input[name=height]").val() == '' || $("#reviewForm input[name=height]").val() == null){
+		mcxDialog.alert('키를 입력하세요.');
+		return;
+	}
+	
+	if($("#reviewForm input[name=weight]").val() == '' || $("#reviewForm input[name=weight]").val() == null){
+		mcxDialog.alert('몸무게를 입력하세요.');
+		return;
+	}
+	
+	
+	if(reviewList[0].sizeGb == 'T' || reviewList[0].sizeGb == 'B' || reviewList[0].sizeGb == 'S'){
+		if($('#reviewForm input:radio[name=scoreSize]').prop('checked') == false){
+			mcxDialog.alert('상품 사이즈를 평가해주세요.');
+			return;
+		}
+		
+		if($('#reviewForm input:radio[name=scoreColor]').prop('checked') == false){
+			mcxDialog.alert('상품 컬러를 평가해주세요.');
+			return;
+		}
+	}
+	
+	if(reviewList[0].sizeGb == 'T' || reviewList[0].sizeGb == 'B'){
+		if($('#reviewForm input:radio[name=scoreFit]').prop('checked') == false){
+			mcxDialog.alert('상품 핏을 평가해주세요.');
+			return;
+		}
+		if($('#reviewForm input:radio[name=scoreThick]').prop('checked') == false){
+			mcxDialog.alert('상품 두께감을 평가해주세요.');
+			return;
+		}	
+	}
+	
+	if(reviewList[0].sizeGb == 'S' ){
+		if($('#reviewForm input:radio[name=scoreWeight]').prop('checked') == false){
+			mcxDialog.alert('상품 무게감을 평가해주세요.');
+			return;
+		}
+		
+		if($('#reviewForm input:radio[name=scoreBall]').prop('checked') == false){
+			mcxDialog.alert('상품 볼넓이를 평가해주세요.');
+			return;
+		}
+	}
+
+	if($('#reviewContent').val().length<10){
+		mcxDialog.alert("리뷰 내용을 10자 이상 입력해주세요.");
+		return;
+	}
+	
+	mcxDialog.confirm('리뷰를 등록하시겠습니까"?', {
+        cancelBtnText: "취소",
+        sureBtnText: "확인",
+        sureBtnClick: function(){
+        	gagajf.ajaxFormSubmit($('#reviewForm').prop('action'), '#reviewForm', fnSaveCallback);
+        }
+    });
+	
+}
+var fnSaveCallback = function (result) {
+	if(result.status == "200"){
+		mcxDialog.alert("상품 리뷰를 등록하였습니다.");
+		//포인트 예정금액 고지해야함
+		cfnGoToPage(_PAGE_MYPAGE_REVIEW);
+	}
+}
+
+
+// 글자 카운팅
+$('#reviewContent').keyup(function (e){
+    var content = $(this).val();
+    $('.txt_cnt').html('<span id="review_cnt" class="c_primary">'+content.length+'</span>/500');    //글자수 실시간 카운팅
+    
+
+    if (content.length > 500){
+    	mcxDialog.alert("최대 500자까지 입력 가능합니다.");
+        $(this).val(content.substring(0, 500));
+        $('.txt_cnt').html('<span id="review_cnt" class="c_primary">500</span>/500');
+    }
+});
+
+$('#fileAdd').on('change', function() { fnChooseFile(this); });
+
+var fnChooseFile = function(obj) {
+	// multiple 속성이 있으면 files에는 다수의 객체가 할당됨
+	var file = obj.files[0];
+	
+	if (!gagajf.isNull(file.size) && Number(file.size) > 10 * 1000000) {
+		mcxDialog.alertC('이미지는 최대 10MB 이하 파일만 가능합니다.', {
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				$(obj).parent('.imgUpload').find('.removes').trigger('click');
+			}
+		});
+		return false;
+	}
+	
+	// 파일 업로드
+	gagajf.ajaxFileUpload('/common/file/upload?subDir=/review'
+			, file
+			, function(result) {
+				// 업로드한 파일명 설정
+				$('input[name=' + obj.name + 'OrgFileNm]').val(result.oldFileName);
+				$('input[name=' + obj.name + 'SysFileNm]').val(result.newFileName);
+			}
+	);
+}
+
+$(document).ready(function() {
+	
+	// 마이페이지 LNB 설정
+	fnSetMypageLnbList(7);
+
+	// 마이페이지 location 설정
+	fnSetMypageLocation('리뷰', '_PAGE_MYPAGE_REVIEW');
+	
+});
+</script>
+</th:block>
+
+</body>
+</html>

+ 192 - 0
src/main/webapp/WEB-INF/views/web/mypage/MypageReviewFormWeb.html

@@ -0,0 +1,192 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/MypageLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : MypageReviewFormWeb.html
+ * @desc    : 마이페이지 > 리뷰 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.03.24   sowon     최초 작성
+ *******************************************************************************
+ -->
+<body>
+	<th:block layout:fragment="content">
+			<div class="content myReviewList"> <!-- 페이지특정 클래스 = myReviewList -->
+				<div class="cont_body">
+					<!-- CONT-BODY -->
+					<div class="lnb">
+					<div class="lnb_tit">
+						<h2>마이페이지</h2>
+					</div>
+					<div class="lnb_list">
+						<ul id="mypageLnbList"></ul>
+					</div>
+				</div>
+					<!-- <div class="lnb_list">
+						<ul id="mypageLnbList"></ul>
+					</div> -->
+					<div class="cont">
+						<div class="sec_head">
+							<h3 class="subH1">리뷰</h3>
+						</div>
+						<div class="sec_body">
+							<div class="com_info_txt">
+								<p class="tit">리뷰 안내</p>
+								<ul>
+									<li>일반 리뷰 작성 시 150P, 포토/영상 리뷰는 350P가 추가 적립됩니다!</li>
+									<li>월 최대 10,000 P까지 적립 가능합니다.(합산 후 월 1회 지급)</li>
+									<li>베스트 리뷰로 선정되면 10,000P가 추가 적립됩니다!</li>
+									<li>리뷰는 주문일 기준 90일간 작성이 가능합니다.</li>
+								</ul>
+							</div>
+							<div class="taps" id="tpasReview">
+								<div>
+									<ul>
+										<li id="completeReview"><a href="javascript:void(0);" >작성 가능한 리뷰<span th:text="'('+${#numbers.formatInteger(completeReviewCount,0,'COMMA')}+')'"></span></a></li>
+										<li id="alreadyReview"><a href="javascript:void(0);" >내가 쓴 리뷰<span>(2,405)</span></a></li>
+									</ul>
+								</div>
+							</div>
+							<div class="area_list" id="completeList">
+			
+								<!-- //주문번호 기준 상품 내역 -->	
+								<!-- 데이터 없을 시 -->
+																											
+							</div>
+									<div class="nodata">
+									<div class="txt_box">
+										<p>
+											작성 가능한 리뷰가 없습니다.<br>
+										</p>
+									</div>
+								</div>
+								<!-- //데이터 없을 시 -->		
+						</div>
+						<div class="sec_foot">
+							<div class="ui_row">
+								<ul class="pageNav" id="paging">
+								
+								</ul>
+							</div>
+						</div>
+						<form id="searchForm" name="searchForm" th:action="@{'/mypage/review/list'}" th:method="post">
+							<input type="hidden" name="pageNo" value="1" />
+							<input type="hidden" name="pageSize" value="10" />
+						</form>
+					</div>
+					<!-- // CONT-BODY -->					
+				</div>
+			</div>
+
+	<script src="/ux/plugins/gaga/gaga.paging.js"></script>
+	<script th:inline="javascript">
+	// 작성가능한 리뷰 클릭 시 
+	$("#completeReview").click(function() {
+		$("#alreadyReview").removeClass("active");
+		$("#completeReview").addClass("active");
+		
+	})
+	
+	$("#alreadyReview").click(function() {
+		$("#completeReview").removeClass("active");
+		$("#alreadyReview").addClass("active");
+		
+	})
+	
+	$(document).ready(function() {
+
+		// 마이페이지 LNB 설정
+		fnSetMypageLnbList(7);
+
+		// 마이페이지 location 설정
+		fnSetMypageLocation('리뷰', '_PAGE_MYPAGE_REVIEW');
+		
+		// Initialize a pagination
+		gagaPaging.init('searchForm', fnSearchCallback, 'paging', 10);
+		
+		// Load data
+		gagaPaging.load(1);
+		
+		// 작성가능한 리뷰표시
+		$("#completeReview").trigger('click');
+
+	
+	});
+	
+	// 주문 목록 조회 콜백
+	var fnSearchCallback = function(result) {
+		$('.nodata').css("display","none");
+		let imageUrl = [[${@environment.getProperty('upload.goods.view')}]];
+		$('#completeList').html('');
+		if (result.dataList != null && result.dataList.length > 0) {
+			$.each(result.dataList, function(idx, item) {
+				let html = '';
+				html += '<div class="part_goods">                                                                                                  ';
+				html += '	<div class="goods_cont">                                                                                              ';
+				html += '		<div class="goods_info">                                                                                          ';
+				html += '			<div class="order_desc">                                                                                      ';
+				html += '				<div class="goods_box">                                                                                   ';
+				html += '					<div class="gd_item">	                                                                              ';
+				html += '						<a href="">                                                                                       ';
+				html += '							<span class="thumb">                                                                          ';
+				html += '								<img th:src="' + imageUrl + '/' + item.sysImgNm + '"  width="100%" alt="">  ';
+				html += '							</span>                                                                                       ';
+				html += '							<p>                                                                                           ';
+				html += '								<span class="buy_date"><em>'+item.payDt+'</em>&nbsp;구매</span>             ';
+				html += '							</p>                                                                                          ';
+				html += '							<p>                                                                                           ';
+				html += '								<span class="brand">'+item.brandEnm+'</span>                               ';
+				html += '							</p>                                                                                          ';
+				html += '							<p>                                                                                           ';
+				html += '								<span class="name">'+item.goodsNm+'</span>									';
+				html += '							</p>                                                                                          ';
+				html += '						</a>                                                                                              ';
+				html += '					</div>                                                                                                ';
+				html += '					<div class="gd_opt">                                                                                  ';
+				html += '						<div class="option_wrap">                                                                         ';
+				html += '							<span class="title sr-only">주문 옵션</span>                                                      ';
+				html += '							<span class="option">'+item.optCd1+'&nbsp;/&nbsp;'+item.optCd2+'</span>     ';
+				html += '						</div>                                                                                            ';
+				html += '					</div>                                                                                                ';
+				html += '				</div>                                                                                                    ';
+				html += '				<div class="status_box">                                                                                  ';
+				html += '					<p>'+item.remainDt+'일 남음</p>                                                                                                  ';
+				html += '				</div>                                                                                                    ';
+				html += '				<div class="button_box">                                                                                  ';
+				html += '					<p><button type="button" class="btn btn_primary_line btn_sm" onclick="fnReviewCreate('+item.ordNo+','+item.ordDtlNo+','+item.goodsCd+')"><span>리뷰쓰기</span></button></p>           ';
+				html += '				</div>                                                                                                    ';
+				html += '			</div>                                                                                                        ';
+				html += '		</div>                                                                                                            ';
+				html += '	</div>                                                                                                                ';
+				html += '</div>                                                                                                                    ';
+				$('#completeList').append(html);
+			})
+		}else{
+			$('.nodata').css("display","block");
+		}
+
+		// Create pagination
+		gagaPaging.createPagination(result.paging.pageable);
+	}
+	
+	var fnReviewCreate = function(obj1,obj2,obj3) {
+		let ordNo = obj1;
+		let ordDtlNo = obj2;
+		let goodsCd = obj3;
+		
+
+		
+		cfnGoToPage(_PAGE_MYPAGE_CREATE_REVIEW + ordNo +'/'+ordDtlNo+'/'+goodsCd);
+		
+	}
+	</script>
+	</th:block>
+
+</body>
+</html>

+ 41 - 5
src/main/webapp/WEB-INF/views/web/planning/PlanningDetailFormWeb.html

@@ -193,7 +193,7 @@
 									<div class="swiper-slide">
 										<a th:onclick="planDetailSearch([[${PlanData.planSq}]])">
 											<div class="thumb">
-												<img th:src="${@environment.getProperty('domain.image')+'/planning/'+PlanData.mainPimg}" alt="${PlanData.planNm}">
+												<img th:src="${@environment.getProperty('domain.image')+PlanData.mainPimg}" alt="${PlanData.planNm}">
 											</div>
 											<div class="txt">
 												<span class="brand" th:if="${PlanData.cnt > 1}" th:text="${PlanData.brand}+' 외'"></span>
@@ -212,6 +212,8 @@
 				</th:block>
 			</div>
 		</div>
+		
+	<div class="modal fade dp_coupon_pop"  id="coupon_modal_02" tabindex="-1" role="dialog"	aria-labelledby="PopupBasicLabel" aria-hidden="true"></div>
 		<!-- // container -->
 <script th:inline="javascript">
 let review = [[${reviewInfo}]];
@@ -327,8 +329,7 @@ if(coupon != null || coupon != ''){
 		html += '						</p>';
 		html += '					</div>';
 		if (coupon[i].couponStat == '쿠폰받기') {
-			html += '					<button type="button"';
-			html += '						class="btn btn_dark btn_block btn_coupon_down">';  /* btn_coupon_done */
+			html += '					<button type="button" id="coupon_" class="btn btn_dark btn_block btn_coupon_down" onclick="fnPlanCouponDown('+coupon[i].cpnId+')">';  /* btn_coupon_done */
 			html += '						<span>쿠폰받기</span>';								/* 받기완료  */
 			html += '					</button>';			
 		}else{
@@ -376,7 +377,7 @@ if(image != null || image != ''){
 	
 	for (var i = 0; i < image.length; i++) {
 		html += '                	<div class="swiper-slide">';
-		html += '                    	<img alt="" src="'+ imgUrl +'/planning/'+image[i].itemVal +'">';
+		html += '                    	<img alt="" src="'+ imgUrl + image[i].itemVal +'">';
 		html += '                	</div>';
 	}
 	html += '            	</div>';
@@ -527,9 +528,44 @@ if(goods2 != null || goods2 != ''){
 		
 }
 
+//사용안내 모달
+var useInfoCoupon = function (id) {
+	 $.ajax( {
+		type		: "GET",
+		url 		: '/mypage/coupon/detailPop?cpnId='+ id,
+		dataType 	: 'html',
+		success 	: function(result) {
+			if (result != null) {
+				$("#coupon_modal_02").html(result);
+				$("#coupon_modal_02").modal("show");
+			}
+		}
+	});
+	
+	return false; 
+}
+
+// 쿠폰 다운로드
+	var fnPlanCouponDown = function(obj){
+	
+		if (!cfCheckLogin()) {
+			cfnGoToPage(_PAGE_LOGIN);
+			return false;
+		}
+		
+		let cpnId = obj;
+		gagajf.ajaxJsonSubmit(_PAGE_PLANNING_CPN_DOWNLOAD, JSON.stringify({cpnId: cpnId}), fnPlanCouponCallBack);
+	}
+	
+	// 쿠폰다운로드 콜백
+	var fnPlanCouponCallBack = function(result){
+		
+		// 화면 전환 필요		
+	}
+
 //세번째 자리 콤마찍기 (숫자만 포함, 소수점자리 구분)
 function comma(num){
-return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+	return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
 }
 
 

+ 1 - 1
src/main/webapp/ux/pc/css/common.css

@@ -1227,7 +1227,7 @@ input[type="file"] {
 .quick_menu_group .area > div:first-child span:first-child a{margin-left:0}
 .quick_menu_group .area > div:first-child span:first-child a:after{display:none}
 .quick_menu_group .area > div:first-child span a:after{position:absolute;top:13px;left:0;width:1px;height:13px;background:#959596;content:''}
-.quick_menu_group .inr a{margin-left:16px;color:#eeeeee;}
+.quick_menu_group .inr a{margin-left:16px;color:#eeeeee;}*/
 
 
 

+ 3 - 9
src/main/webapp/ux/style24_link.js

@@ -59,6 +59,7 @@ const _PAGE_MYPAGE_COUPON = _frontUrl + "/mypage/coupon/form";					// 마이페
 const _PAGE_MYPAGE_POINT = _frontUrl + "/mypage/point/form";					// 마이페이지 > 포인트
 const _PAGE_MYPAGE_GIFTCARD = _frontUrl + "/mypage/gift/card/form";				// 마이페이지 > 상품권
 const _PAGE_MYPAGE_REVIEW = _frontUrl + "/mypage/review/form";					// 마이페이지 > 리뷰
+const _PAGE_MYPAGE_CREATE_REVIEW = _frontUrl + "/mypage/review/create/form/";	// 마이페이지 > 리뷰 > 리뷰작성
 const _PAGE_MYPAGE_DELIVERY_ADDR = _frontUrl + "/mypage/delivery/addr/form";	// 마이페이지 > 배송지 관리
 const _PAGE_MYPAGE_WISHLIST = _frontUrl + "/mypage/wish/list/form";				// 마이페이지 > 위시리스트
 const _PAGE_MYPAGE_CUSTOMER = _frontUrl + "/mypage/customer/confirm/form";		// 마이페이지 > 내정보 관리 > 회원정보 확인
@@ -74,6 +75,7 @@ const _PAGE_WISHLIST_DEL = _frontUrl + "/mypage/wish/list/delete";				// 위시
 //== 기획전 ==/
 const _PAGE_PLANNING_MAIN = _frontUrl + "/planning/main/form"; 					// 기획전 메인
 const _PAGE_PLANNING_DETAIL = _frontUrl + "/planning/detail/form";				// 기획전 상세
+const _PAGE_PLANNING_CPN_DOWNLOAD = "/planning/coupon/download";			    // 상품쿠폰다운로드
 
 //== 핫딜==/
 const _PAGE_SOCIAL_MAIN = _frontUrl + "/social/main/form";						// 소설(핫딜) 메인
@@ -826,19 +828,11 @@ function cfnPutWishList(a) {
  * </pre>
  * @param  : cateGb - 카테고리구분. 필수
  * @param  : cate1No - 카테고리1번호. 필수
- * @param  : cate2No - 카테고리2번호. 옵션
- * @param  : cate3No - 카테고리3번호. 옵션
- * @param  : cate4No - 카테고리4번호. 옵션
- * @param  : cate5No - 카테고리5번호. 옵션
  * @since  : 2021/03/22
  * @author : gagamel
  */
-var cfnGoToCategoryMain = function(cateGb, cate1No, cate2No, cate3No, cate4No, cate5No) {
+var cfnGoToCategoryMain = function(cateGb, cate1No) {
 	var params = '?cateGb=' + cateGb + '&cate1No=' + cate1No;
-	if (typeof (cate2No) != 'undefined') params += '&cate2No=' + cate2No;
-	if (typeof (cate3No) != 'undefined') params += '&cate3No=' + cate3No;
-	if (typeof (cate4No) != 'undefined') params += '&cate4No=' + cate4No;
-	if (typeof (cate5No) != 'undefined') params += '&cate5No=' + cate5No;
 	cfnGoToPage(_PAGE_CATE_MAIN + params);
 }