Ver Fonte

Merge branch 'card007' into order

card007 há 5 anos atrás
pai
commit
b1f8076cd1

+ 39 - 1
src/main/java/com/style24/front/biz/web/TsfMypageController.java

@@ -418,7 +418,45 @@ public class TsfMypageController extends TsfBaseController {
 
 		return mav;
 	}
-	
+
+	/**
+	 * 교환신청
+	 *
+	 * @param OrderChange
+	 * @return GagaMap
+	 * @author card007
+	 * @since 2021. 04. 06
+	 */
+	@SuppressWarnings("unchecked")
+	@PostMapping("/exchange")
+	@ResponseBody
+	public GagaMap excReq(@RequestBody OrderChange orderChange) {
+		GagaMap result = new GagaMap();
+
+		// 교환요청 데이터 확인
+		if (orderChange == null) {
+			result.set("status", GagaResponseStatus.FAIL.getCode());
+			result.set("message", message.getMessage("FAIL_1001"));
+			return result;
+		}
+
+		// 세션 고객번호 설정
+		int custNo = TsfSession.getInfo().getCustNo();
+		orderChange.setUpdNo(custNo);
+		orderChange.setRegNo(custNo);
+
+		// 교환처리
+		result = coreOrderChangeService.exchReq(orderChange);
+
+		// 처리 결과 코드에 따른 메세지 설정
+		if (result.get("status").equals(GagaResponseStatus.SUCCESS.getCode())) {
+			result.set("message", message.getMessage("SUCC_0004"));
+		} else {
+			result.set("message", message.getMessage("FAIL_0004"));
+		}
+
+		return result;
+	}
 
 	/**
 	 * 마이페이지 등급쿠폰 다운 처리

+ 4 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsfOrder.xml

@@ -192,6 +192,7 @@
 		   AND OD.ORD_DTL_STAT = #{ordDtlStat}
 			</if>
 		   AND O.DISP_YN = 'Y'
+		   AND OD.ORD_DTL_STAT <![CDATA[<>]]> 'G013_25'
 		   AND OD.ORD_QTY - OD.CNCL_RTN_QTY > 0
 		</where>
 				) Z
@@ -382,6 +383,9 @@
 		 INNER JOIN TB_ORDER_DETAIL OD
 		    ON OD.DELV_ADDR_SQ = DA.DELV_ADDR_SQ
 		   AND OD.ORD_NO = #{ordNo}
+		<if test="supplyCompCd != null and supplyCompCd != ''">
+		   AND OD.SUPPLY_COMP_CD = #{supplyCompCd}
+		</if>
 		<if test="ordDtlNoArr != null">
 		   AND OD.ORD_DTL_NO IN
 			<foreach collection="ordDtlNoArr" item="item" index="index"  open="(" close=")" separator=",">

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

@@ -192,7 +192,7 @@
 		     , Z.ACCOUNT_NO
 		     , Z.ACCOUNT_NM
 		     , Z.RTN_DELV_FEE
-		     , Z.DELV_FEE
+		     , Z.EXC_DELV_FEE
 		  FROM (SELECT O.ORD_NO
 		             , DATE_FORMAT(O.ORD_DT, '%Y.%m.%d')                                      AS ORD_DT
 		             , OD.ORD_DTL_NO
@@ -239,7 +239,7 @@
 		             , CA.ACCOUNT_NO
 		             , IFNULL(CA.ACCOUNT_NM, O.ORD_NM)                                        AS ACCOUNT_NM
 		             , DFP.RTN_DELV_FEE
-		             , DFP.DELV_FEE
+		             , DFP.DELV_FEE + DFP.RTN_DELV_FEE                                        AS EXC_DELV_FEE
 		          FROM TB_ORDER O
 		         INNER JOIN TB_ORDER_DETAIL OD
 		            ON O.ORD_NO = OD.ORD_NO
@@ -291,7 +291,7 @@
 		        , Z.ORD_DTL_STAT, Z.ORD_QTY, Z.CNCL_RTN_QTY, Z.ORD_AMT, Z.REAL_ORD_AMT, Z.SAVE_PNT_AMT, Z.CNCL_RTN_AMT, Z.PNT_DC_AMT
 		        , Z.GFCD_USE_AMT, Z.SHIP_COMP_CD, Z.GIFT_PACK_YN, Z.SHIP_COMP_NM, Z.INVOICE_NO, Z.SUPPLY_COMP_CD, Z.DELV_FEE_CD
 		        , Z.SHOT_DELV_YN, Z.CHANGEABLE_YN, Z.SELF_GOODS_YN, Z.BRAND_NM, Z.ORD_REQ_CHG_QTY, Z.ORD_CAN_CHG_QTY, Z.BANK_CD
-		        , Z.ACCOUNT_NO, Z.ACCOUNT_NM, Z.RTN_DELV_FEE, Z.DELV_FEE
+		        , Z.ACCOUNT_NO, Z.ACCOUNT_NM, Z.RTN_DELV_FEE, Z.EXC_DELV_FEE
 		ORDER BY Z.ORD_DTL_NO
 	</select>
 	

+ 47 - 231
src/main/webapp/WEB-INF/views/web/mypage/ChangeOptionPopupFormWeb.html

@@ -5,61 +5,44 @@
 <div class="modal-body">
 	<div class="pop_cont">
 		<form class="form_wrap">
-			<div class="select_option_area">
-				<h6>옵션 변경 상품 선택</h6>
-				<div class="form_field">
-					<div th:if="${exchangeOptionInfo}" th:each="oneData, status : ${exchangeOptionInfo}">
-						<input th:id="|chk_exchange_item_${oneData.ordDtlItemSq}|" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}" type="checkbox" onclick="fnSelectOptionChange(this);"><label th:for="|chk_exchange_item_${oneData.ordDtlItemSq}|"><span th:text="|${oneData.itemNm} / ${oneData.colorNm} / ${oneData.optCd2}|"></span></label>
-					</div>
-				</div>
-			</div>
-			<div class="modify_option_area" id="modifyOptionArea" style="display:none">
+			<div class="modify_option_area" id="modifyOptionArea">
 				<th:block th:if="${exchangeOptionInfo}" th:each="oneData, status : ${exchangeOptionInfo}">
-					<th:block th:if="${chgQty > 0}" th:each="num, index  : ${#numbers.sequence(1,chgQty)}">
-						<div class="modify_box" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}" style="display:none">
-							<div class="name_blk" th:text="|${oneData.itemNm} / ${oneData.colorNm}|"></div>
-							<div class="select_blk">
-								<!-- 옵션교환 라디오 형태 -->
-								<div class="sel_radio" th:if="${oneData.selfGoodsYn == 'Y'}">
-									<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}">
-									<div th:class="|form_field ${oneData.ordDtlItemSq}|">
-										<div th:if="${oneData.optCd2Arr.length > 0}" th:each="option, idx : ${oneData.optCd2Arr}">
-											<input type="radio" th:name="|${oneData.ordDtlItemSq}_${num}|" th:id="|${oneData.ordDtlItemSq}_${option}_${num}|" th:value="${option}" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}" th:disabled="${#numbers.formatInteger(oneData.currStockQtyArr[idx.index], 0)} <= 0 or ${oneData.soldoutYnArr[idx.index] == 'Y'}" onclick="fnRadioOption(this);">
-											<label th:for="|${oneData.ordDtlItemSq}_${option}_${num}|"><span th:text="${option}"></span></label>
-										</div>
-									</div>
-								</div>
-								<!-- //옵션교환 라디오 형태 -->
-								<!-- 옵션교환 셀렉트박스 형태 -->
-								<div class="sel_select" th:unless="${oneData.selfGoodsYn == 'Y'}">
-									<div class="form_field">
-										<div class="select_custom exchange_option">
-											<div class="combo">
-												<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}">
-												<div class="select">옵션 선택</div>
-												<ul class="list">
-													<!-- 선택처리 class="selected" / 선택불가 aria-disabled="true" / 품절표기 data-soldout="true" 추가  -->
-													<li class="selected" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=''" onclick="fnSelectOption(this);">옵션 선택</li>
-													<th:block th:each="option, idx : ${oneData.optCd2Arr}">
-														<li th:if="${oneData.optCd2Arr.length} > 0 and (${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} <= 0 or ${oneData.soldoutYnArr[idx.index]} == 'Y')" th:text="${option}" aria-disabled="true" data-soldout="true" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=''" onclick="fnSelectOption(this);"></li>
-														<li th:if="${oneData.optCd2Arr.length} > 0 and ${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} > 0 and ${oneData.soldoutYnArr[idx.index]} == 'N'" th:text="${option}" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=${option}" onclick="fnSelectOption(this);"></li>
-													</th:block>
-												</ul>
-											</div>
-										</div>
+					<div class="modify_box" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}">
+						<div class="name_blk" th:text="|${oneData.itemNm} / ${oneData.colorNm}|"></div>
+						<div class="select_blk">
+							<!-- 옵션교환 라디오 형태 -->
+							<div class="sel_radio" th:if="${oneData.selfGoodsYn == 'Y'}">
+								<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}" th:value="${oneData.optCd2}">
+								<div th:class="|form_field ${oneData.ordDtlItemSq}|">
+									<div th:if="${oneData.optCd2Arr.length > 0}" th:each="option, idx : ${oneData.optCd2Arr}">
+										<input type="radio" th:name="${oneData.ordDtlItemSq}" th:id="|${oneData.ordDtlItemSq}_${option}|" th:value="${option}" th:disabled="${#numbers.formatInteger(oneData.currStockQtyArr[idx.index], 0)} <= 0 or ${oneData.soldoutYnArr[idx.index] == 'Y'}" th:checked="${option == oneData.optCd2}" onclick="fnRadioOption(this);">
+										<label th:for="|${oneData.ordDtlItemSq}_${option}|"><span th:text="${option}"></span></label>
 									</div>
 								</div>
-								<!-- //옵션교환 셀렉트박스 형태 -->
 							</div>
-							<div class="allcheck_blk" th:if="${num} == 1">
+							<!-- //옵션교환 라디오 형태 -->
+							<!-- 옵션교환 셀렉트박스 형태 -->
+							<div class="sel_select" th:unless="${oneData.selfGoodsYn == 'Y'}">
 								<div class="form_field">
-									<div>
-										<input th:id="|${oneData.ordDtlItemSq}_checkAll|" name="chk_exchange_all1" type="checkbox" checked="" onclick="fnSelectOptionChange();"><label th:for="|${oneData.ordDtlItemSq}_checkAll|"><span>선택 옵션으로 전체 교환</span></label>
+									<div class="select_custom exchange_option">
+										<div class="combo">
+											<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}" th:value="${oneData.optCd2}">
+											<div class="select" th:text="${oneData.optCd2}"></div>
+											<ul class="list">
+												<!-- 선택처리 class="selected" / 선택불가 aria-disabled="true" / 품절표기 data-soldout="true" 추가  -->
+<!--												<li class="selected" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, optCd2=''" onclick="fnSelectOption(this);">옵션 선택</li>-->
+												<th:block th:each="option, idx : ${oneData.optCd2Arr}">
+													<li th:if="${oneData.optCd2Arr.length} > 0 and (${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} <= 0 or ${oneData.soldoutYnArr[idx.index]} == 'Y')" th:classappend="${option == oneData.optCd2} ? 'selected'" th:text="${option}" aria-disabled="true" data-soldout="true" th:attr="optCd2=''" onclick="fnSelectOption(this);"></li>
+													<li th:if="${oneData.optCd2Arr.length} > 0 and ${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} > 0 and ${oneData.soldoutYnArr[idx.index]} == 'N'" th:classappend="${option == oneData.optCd2} ? 'selected'" th:text="${option}" th:attr="optCd2=${option}" onclick="fnSelectOption(this);"></li>
+												</th:block>
+											</ul>
+										</div>
 									</div>
 								</div>
 							</div>
+							<!-- //옵션교환 셀렉트박스 형태 -->
 						</div>
-					</th:block>
+					</div>
 				</th:block>
 			</div>
 		</form>
@@ -69,10 +52,8 @@
 	<button type="button" id="" class="btn btn_dark" onclick="fnSaveOption();"><span>옵션 저장</span></button>
 </div>
 <script th:inline="javascript">
-	let exchangeOptionInfo = [[${exchangeOptionInfo}]];
 	let oneData = [[${oneData}]];
 	let chgQty = [[${chgQty}]];
-	let checkedOrdDtlItemSqArr = [];
 
 	$(document).ready( function() {
 		// 셀렉트박스 활성화
@@ -81,206 +62,41 @@
 		});
 	});
 
-	// 구성상품 선택 및 전체 적용 클릭 이벤트
-	var fnSelectOptionChange = function() {
-		checkedOrdDtlItemSqArr = [];
-		let cnt = 0;
-		
-		// 체크 수량 조회
-		$.each($('.select_option_area .form_field input:checkbox'), function(idx, item) {
-			if ($(item).is(':checked')) {
-				checkedOrdDtlItemSqArr.push($(item).attr('ordDtlItemSq'));
-				cnt++;
-			}
-		});
-
-		// 옵션변경영역 처리
-		if (cnt > 0) {
-			$('#modifyOptionArea').css('display', '');
-		} else {
-			$('#modifyOptionArea').css('display', 'none');
-		}
-
-		$.each($('.modify_box'), function(idx, item) {
-			let ordDtlItemSq = $(item).attr('ordDtlItemSq');
-			let num = $(item).attr('num');
-			let id = '#' + ordDtlItemSq + '_checkAll';
-
-			if (checkedOrdDtlItemSqArr.includes(ordDtlItemSq)) {
-				if (num == 1) {
-					$(item).css('display', '');
-
-					if (oneData.selfGoodsYn == 'Y') {
-						$.each($(item).find('input:radio'), function (index, radio) {
-							if ($(radio).is(':checked')) {
-								$(radio).click();
-							}
-						});
-					} else {
-						$.each($(item).find('li'), function (index, radio) {
-							if ($(radio).hasClass('selected')) {
-								$(radio).click();
-							}
-						});
-					}
-				} else if ($(id).is(':checked')) {
-					$(item).css('display', 'none');
-				} else {
-					$(item).css('display', '');
-				}
-			} else {
-				$(item).css('display', 'none');
-			}
-		});
-
-		fnChangeCss();
-	}
-
 	// 라디오 클릭 이벤트
 	var fnRadioOption = function(param) {
-		let ordDtlItemSq = $(param).attr('ordDtlItemSq');
-		let num = $(param).attr('num');
-		let optCd2 = $(param).val();
-		let checkAllId = '#' + ordDtlItemSq + '_checkAll';
-		let radioId = '.' + ordDtlItemSq + ' input:radio';
-
-		$(param).parent().parent().parent().find('input[name=chgOptCd2]').val(optCd2);
-
-		if (num == 1 && $(checkAllId).is(':checked')) {
-			$.each($(radioId), function(idx, item) {
-				if ($(item).attr('num') != 1 && optCd2 == $(item).val()) {
-					$(item).click();
-				}
-			});
-		}
+		$(param).parent().parent().parent().find('input[name=chgOptCd2]').val($(param).val());
 	}
 
 	// 셀렉트박스 클릭 이벤트
 	var fnSelectOption = function(param) {
-		let ordDtlItemSq = $(param).attr('ordDtlItemSq');
-		let num = $(param).attr('num');
-		let optCd2 = $(param).attr('optCd2');
-		let checkAllId = '#' + ordDtlItemSq + '_checkAll';
-
-		$(param).parent().parent().find('input[name=chgOptCd2]').val(optCd2);
-
-		if (num == 1 && $(checkAllId).is(':checked')) {
-			$.each($('.exchange_option li'), function(idx, item) {
-				if ($(item).attr('num') != 1 && optCd2 == $(item).attr('optCd2')) {
-					$(item).click();
-				}
-			});
-		}
+		$(param).parent().parent().find('input[name=chgOptCd2]').val($(param).attr('optCd2'));
 	}
 	
 	// 옵션 저장 버튼 클릭 이벤트
 	var fnSaveOption = function() {
-		// 옵션 선택 여부 확인
-		if (checkedOrdDtlItemSqArr.length <= 0) {
-			mcxDialog.alert('교환 옵션을 선택해주세요.');
-			return false;
-		}
-
 		// 변경 옵션 처리
 		let dataArr = [];
-		let ordDtlItemSq = 0;
-		let colorNm = '';
-		let itemNm = '';
-		let goodsType = '';
-		let index = 0;
-		let chgOptCd2Arr = [];
-		let selectOptionCheck = true;
 
 		$.each($('input[name=chgOptCd2]'), function(idx, item) {
-			let chgOrdDtlItemSq = $(item).attr('ordDtlItemSq');
-			colorNm = $(item).attr('colorNm');
-			itemNm = $(item).attr('itemNm');
-			goodsType = $(item).attr('goodsType');
-			let changeYn = checkedOrdDtlItemSqArr.includes(chgOrdDtlItemSq)
-			let chgOptCd2 = changeYn ? $(item).val() : $(item).attr('orgOptCd2');
-			let chgOptCd2Obj = {};
-			chgOptCd2Obj.chgOptCd2 = chgOptCd2;
-			chgOptCd2Obj.qty = 1;
-
-			if (ordDtlItemSq != Number(chgOrdDtlItemSq)) {
-				if (index > 0) {
-					let data = {};
-					data.ordDtlNo = oneData.ordDtlNo;
-					data.ordDtlItemSq = ordDtlItemSq;
-					data.chgQty = chgQty;
-					data.colorNm = colorNm;
-					data.itemNm = itemNm;
-					data.goodsType = goodsType;
-					data.chgOptCd2Arr = fnOptionCount(chgOptCd2Arr);
-					dataArr.push(data);
-				}
-
-				ordDtlItemSq = chgOrdDtlItemSq;
-				chgOptCd2Arr = [];
-			}
-
-			chgOptCd2Arr.push(chgOptCd2Obj);
-
-			index++;
-
-			// 옵션 선택 여부 설정
-			if (changeYn && gagajf.isNull($(item).val())) {
-				selectOptionCheck = false;
-			}
+			let ordDtlItemSq = $(item).attr('ordDtlItemSq');
+			let colorNm = $(item).attr('colorNm');
+			let itemNm = $(item).attr('itemNm');
+			let goodsType = $(item).attr('goodsType');
+			let chgOptCd2 = $(item).val();
+
+			let data = {};
+			data.ordDtlNo = oneData.ordDtlNo;
+			data.ordDtlItemSq = ordDtlItemSq;
+			data.chgQty = chgQty;
+			data.colorNm = colorNm;
+			data.itemNm = itemNm;
+			data.goodsType = goodsType;
+			data.chgOptCd2 = chgOptCd2;
+			dataArr.push(data);
 		});
-
-		// 옵션 선택 여부 체크
-		if (!selectOptionCheck) {
-			mcxDialog.alert('교환 옵션을 선택해주세요.');
-			return false;
-		}
-
-		let data = {};
-		data.ordDtlNo = oneData.ordDtlNo;
-		data.ordDtlItemSq = ordDtlItemSq;
-		data.chgQty = chgQty;
-		data.colorNm = colorNm;
-		data.itemNm = itemNm;
-		data.goodsType = goodsType;
-		data.chgOptCd2Arr = fnOptionCount(chgOptCd2Arr);
-		dataArr.push(data);
-
+console.log(dataArr);
 		fnChangeOptionCallback(dataArr)
 
 		$('.close-modal').trigger('click');
 	}
-
-	// 변경 옵션별 수량 처리
-	var fnOptionCount = function(param) {
-		var result = [];
-		param.reduce(function(res, value) {
-			if (!res[value.chgOptCd2]) {
-				res[value.chgOptCd2] = { chgOptCd2: value.chgOptCd2, qty: 0 };
-				result.push(res[value.chgOptCd2])
-			}
-			res[value.chgOptCd2].qty += value.qty;
-			return res;
-		}, {});
-		
-		return result;
-	}
-
-	// 옵션 선택 영역 CSS 수정
-	var fnChangeCss = function() {
-		let index = 0;
-		$.each($('.modify_box'), function(idx, item) {
-			if ($(item).css('display') == 'block') {
-				index++;
-				if (index == 1) {
-					$(item).css('margin-top', '0');
-					$(item).css('padding-top', '0');
-					$(item).css('border-top', 'none');
-				} else {
-					$(item).css('margin-top', '30px');
-					$(item).css('padding-top', '30px');
-					$(item).css('border-top', '1px dashed #ddd');
-				}
-			}
-		});
-	}
 </script>

+ 285 - 0
src/main/webapp/WEB-INF/views/web/mypage/ChangeOptionPopupFormWeb_20210406.html

@@ -0,0 +1,285 @@
+<!-- 배송지변경 팝업 -->
+<div class="modal-header">
+	<h5 class="modal-title" id="exchangeLabel">교환상품 옵션 변경</h5>
+</div>
+<div class="modal-body">
+	<div class="pop_cont">
+		<form class="form_wrap">
+			<div class="select_option_area">
+				<h6>옵션 변경 상품 선택</h6>
+				<div class="form_field">
+					<div th:if="${exchangeOptionInfo}" th:each="oneData, status : ${exchangeOptionInfo}">
+						<input th:id="|chk_exchange_item_${oneData.ordDtlItemSq}|" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}" type="checkbox" onclick="fnSelectOptionChange(this);"><label th:for="|chk_exchange_item_${oneData.ordDtlItemSq}|"><span th:text="|${oneData.itemNm} / ${oneData.colorNm} / ${oneData.optCd2}|"></span></label>
+					</div>
+				</div>
+			</div>
+			<div class="modify_option_area" id="modifyOptionArea" style="display:none">
+				<th:block th:if="${exchangeOptionInfo}" th:each="oneData, status : ${exchangeOptionInfo}">
+					<th:block th:if="${chgQty > 0}" th:each="num, index  : ${#numbers.sequence(1,chgQty)}">
+						<div class="modify_box" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}" style="display:none">
+							<div class="name_blk" th:text="|${oneData.itemNm} / ${oneData.colorNm}|"></div>
+							<div class="select_blk">
+								<!-- 옵션교환 라디오 형태 -->
+								<div class="sel_radio" th:if="${oneData.selfGoodsYn == 'Y'}">
+									<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}, num=${num}">
+									<div th:class="|form_field ${oneData.ordDtlItemSq}|">
+										<div th:if="${oneData.optCd2Arr.length > 0}" th:each="option, idx : ${oneData.optCd2Arr}">
+											<input type="radio" th:name="|${oneData.ordDtlItemSq}_${num}|" th:id="|${oneData.ordDtlItemSq}_${option}_${num}|" th:value="${option}" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}" th:disabled="${#numbers.formatInteger(oneData.currStockQtyArr[idx.index], 0)} <= 0 or ${oneData.soldoutYnArr[idx.index] == 'Y'}" onclick="fnRadioOption(this);">
+											<label th:for="|${oneData.ordDtlItemSq}_${option}_${num}|"><span th:text="${option}"></span></label>
+										</div>
+									</div>
+								</div>
+								<!-- //옵션교환 라디오 형태 -->
+								<!-- 옵션교환 셀렉트박스 형태 -->
+								<div class="sel_select" th:unless="${oneData.selfGoodsYn == 'Y'}">
+									<div class="form_field">
+										<div class="select_custom exchange_option">
+											<div class="combo">
+												<input type="hidden" name="chgOptCd2" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, itemNm=${oneData.itemNm}, colorNm=${oneData.colorNm}, orgOptCd2=${oneData.optCd2}, goodsType=${oneData.goodsType}, num=${num}">
+												<div class="select">옵션 선택</div>
+												<ul class="list">
+													<!-- 선택처리 class="selected" / 선택불가 aria-disabled="true" / 품절표기 data-soldout="true" 추가  -->
+													<li class="selected" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=''" onclick="fnSelectOption(this);">옵션 선택</li>
+													<th:block th:each="option, idx : ${oneData.optCd2Arr}">
+														<li th:if="${oneData.optCd2Arr.length} > 0 and (${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} <= 0 or ${oneData.soldoutYnArr[idx.index]} == 'Y')" th:text="${option}" aria-disabled="true" data-soldout="true" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=''" onclick="fnSelectOption(this);"></li>
+														<li th:if="${oneData.optCd2Arr.length} > 0 and ${#numbers.formatInteger(oneData.currStockQtyArr[idx.index],0)} > 0 and ${oneData.soldoutYnArr[idx.index]} == 'N'" th:text="${option}" th:attr="ordDtlItemSq=${oneData.ordDtlItemSq}, num=${num}, optCd2=${option}" onclick="fnSelectOption(this);"></li>
+													</th:block>
+												</ul>
+											</div>
+										</div>
+									</div>
+								</div>
+								<!-- //옵션교환 셀렉트박스 형태 -->
+							</div>
+							<div class="allcheck_blk" th:if="${num} == 1">
+								<div class="form_field">
+									<div>
+										<input th:id="|${oneData.ordDtlItemSq}_checkAll|" name="chk_exchange_all1" type="checkbox" checked="" onclick="fnSelectOptionChange();"><label th:for="|${oneData.ordDtlItemSq}_checkAll|"><span>선택 옵션으로 전체 교환</span></label>
+									</div>
+								</div>
+							</div>
+						</div>
+					</th:block>
+				</th:block>
+			</div>
+		</form>
+	</div>
+</div>
+<div class="modal-footer">
+	<button type="button" id="" class="btn btn_dark" onclick="fnSaveOption();"><span>옵션 저장</span></button>
+</div>
+<script th:inline="javascript">
+	let exchangeOptionInfo = [[${exchangeOptionInfo}]];
+	let oneData = [[${oneData}]];
+	let chgQty = [[${chgQty}]];
+	let checkedOrdDtlItemSqArr = [];
+
+	$(document).ready( function() {
+		// 셀렉트박스 활성화
+		$('#exchangePop .select_custom.exchange_option').each(function() {
+			new sCombo($(this));
+		});
+	});
+
+	// 구성상품 선택 및 전체 적용 클릭 이벤트
+	var fnSelectOptionChange = function() {
+		checkedOrdDtlItemSqArr = [];
+		let cnt = 0;
+		
+		// 체크 수량 조회
+		$.each($('.select_option_area .form_field input:checkbox'), function(idx, item) {
+			if ($(item).is(':checked')) {
+				checkedOrdDtlItemSqArr.push($(item).attr('ordDtlItemSq'));
+				cnt++;
+			}
+		});
+
+		// 옵션변경영역 처리
+		if (cnt > 0) {
+			$('#modifyOptionArea').css('display', '');
+		} else {
+			$('#modifyOptionArea').css('display', 'none');
+		}
+
+		$.each($('.modify_box'), function(idx, item) {
+			let ordDtlItemSq = $(item).attr('ordDtlItemSq');
+			let num = $(item).attr('num');
+			let id = '#' + ordDtlItemSq + '_checkAll';
+
+			if (checkedOrdDtlItemSqArr.includes(ordDtlItemSq)) {
+				if (num == 1) {
+					$(item).css('display', '');
+
+					if (oneData.selfGoodsYn == 'Y') {
+						$.each($(item).find('input:radio'), function (index, radio) {
+							if ($(radio).is(':checked')) {
+								$(radio).click();
+							}
+						});
+					} else {
+						$.each($(item).find('li'), function (index, radio) {
+							if ($(radio).hasClass('selected')) {
+								$(radio).click();
+							}
+						});
+					}
+				} else if ($(id).is(':checked')) {
+					$(item).css('display', 'none');
+				} else {
+					$(item).css('display', '');
+				}
+			} else {
+				$(item).css('display', 'none');
+			}
+		});
+
+		fnChangeCss();
+	}
+
+	// 라디오 클릭 이벤트
+	var fnRadioOption = function(param) {
+		let ordDtlItemSq = $(param).attr('ordDtlItemSq');
+		let num = $(param).attr('num');
+		let optCd2 = $(param).val();
+		let checkAllId = '#' + ordDtlItemSq + '_checkAll';
+		let radioId = '.' + ordDtlItemSq + ' input:radio';
+
+		$(param).parent().parent().parent().find('input[name=chgOptCd2]').val(optCd2);
+
+		if (num == 1 && $(checkAllId).is(':checked')) {
+			$.each($(radioId), function(idx, item) {
+				if ($(item).attr('num') != 1 && optCd2 == $(item).val()) {
+					$(item).click();
+				}
+			});
+		}
+	}
+
+	// 셀렉트박스 클릭 이벤트
+	var fnSelectOption = function(param) {
+		let ordDtlItemSq = $(param).attr('ordDtlItemSq');
+		let num = $(param).attr('num');
+		let optCd2 = $(param).attr('optCd2');
+		let checkAllId = '#' + ordDtlItemSq + '_checkAll';
+
+		$(param).parent().parent().find('input[name=chgOptCd2]').val(optCd2);
+
+		if (num == 1 && $(checkAllId).is(':checked')) {
+			$.each($('.exchange_option li'), function(idx, item) {
+				if ($(item).attr('num') != 1 && optCd2 == $(item).attr('optCd2')) {
+					$(item).click();
+				}
+			});
+		}
+	}
+	
+	// 옵션 저장 버튼 클릭 이벤트
+	var fnSaveOption = function() {
+		// 옵션 선택 여부 확인
+		if (checkedOrdDtlItemSqArr.length <= 0) {
+			mcxDialog.alert('교환 옵션을 선택해주세요.');
+			return false;
+		}
+
+		// 변경 옵션 처리
+		let dataArr = [];
+		let ordDtlItemSq = 0;
+		let colorNm = '';
+		let itemNm = '';
+		let goodsType = '';
+		let chgOptCd2Arr = [];
+		let selectOptionCheck = true;
+
+		$.each($('input[name=chgOptCd2]'), function(idx, item) {
+			let chgOrdDtlItemSq = $(item).attr('ordDtlItemSq');
+			colorNm = $(item).attr('colorNm');
+			itemNm = $(item).attr('itemNm');
+			goodsType = $(item).attr('goodsType');
+			let changeYn = checkedOrdDtlItemSqArr.includes(chgOrdDtlItemSq)
+			let chgOptCd2 = changeYn ? $(item).val() : $(item).attr('orgOptCd2');
+			let chgOptCd2Obj = {};
+			chgOptCd2Obj.chgOptCd2 = chgOptCd2;
+			chgOptCd2Obj.qty = 1;
+
+			if (ordDtlItemSq != Number(chgOrdDtlItemSq)) {
+				if (idx > 0) {
+					let data = {};
+					data.ordDtlNo = oneData.ordDtlNo;
+					data.ordDtlItemSq = ordDtlItemSq;
+					data.chgQty = chgQty;
+					data.colorNm = colorNm;
+					data.itemNm = itemNm;
+					data.goodsType = goodsType;
+					data.chgOptCd2Arr = fnOptionCount(chgOptCd2Arr);
+					dataArr.push(data);
+				}
+
+				ordDtlItemSq = chgOrdDtlItemSq;
+				chgOptCd2Arr = [];
+			}
+
+			chgOptCd2Arr.push(chgOptCd2Obj);
+
+			
+
+			// 옵션 선택 여부 설정
+			if (changeYn && gagajf.isNull($(item).val())) {
+				selectOptionCheck = false;
+			}
+		});
+
+		// 옵션 선택 여부 체크
+		if (!selectOptionCheck) {
+			mcxDialog.alert('교환 옵션을 선택해주세요.');
+			return false;
+		}
+
+		let data = {};
+		data.ordDtlNo = oneData.ordDtlNo;
+		data.ordDtlItemSq = ordDtlItemSq;
+		data.chgQty = chgQty;
+		data.colorNm = colorNm;
+		data.itemNm = itemNm;
+		data.goodsType = goodsType;
+		data.chgOptCd2Arr = fnOptionCount(chgOptCd2Arr);
+		dataArr.push(data);
+
+		fnChangeOptionCallback(dataArr)
+
+		$('.close-modal').trigger('click');
+	}
+
+	// 변경 옵션별 수량 처리
+	var fnOptionCount = function(param) {
+		var result = [];
+		param.reduce(function(res, value) {
+			if (!res[value.chgOptCd2]) {
+				res[value.chgOptCd2] = { chgOptCd2: value.chgOptCd2, qty: 0 };
+				result.push(res[value.chgOptCd2])
+			}
+			res[value.chgOptCd2].qty += value.qty;
+			return res;
+		}, {});
+		
+		return result;
+	}
+
+	// 옵션 선택 영역 CSS 수정
+	var fnChangeCss = function() {
+		let index = 0;
+		$.each($('.modify_box'), function(idx, item) {
+			if ($(item).css('display') == 'block') {
+				index++;
+				if (index == 1) {
+					$(item).css('margin-top', '0');
+					$(item).css('padding-top', '0');
+					$(item).css('border-top', 'none');
+				} else {
+					$(item).css('margin-top', '30px');
+					$(item).css('padding-top', '30px');
+					$(item).css('border-top', '1px dashed #ddd');
+				}
+			}
+		});
+	}
+</script>

+ 86 - 42
src/main/webapp/WEB-INF/views/web/mypage/MypageExchangeFormWeb.html

@@ -70,7 +70,6 @@
 													<span class="option" th:if="${exchange.goodsType == 'G056_S'}" th:each="option, status : ${exchange.colorNmArr}" th:text="|${exchange.itemNmArr[status.index]} / ${option} / ${exchange.optCd2Arr[status.index]}|"></span>
 													<span class="option" th:unless="${exchange.goodsType == 'G056_S'}" th:text="|${exchange.colorNm} / ${exchange.optCd2}|"></span>
 												</div>
-												<div class="option_wrap exchangeOption" style="display:none" th:attr="ordDtlNo=${exchange.ordDtlNo}"></div>
 											</div>
 											<div class="gd_calc">
 												<p>
@@ -81,6 +80,9 @@
 													<span class="price_sale"><em th:text="${#numbers.formatInteger(exchange.realOrdAmt + exchange.pntDcAmt + exchange.gfcdUseAmt, 1, 'COMMA')}"></em>원</span>
 												</p>
 											</div>
+											<div class="gd_opt exchangeOption" style="display:none" th:attr="ordDtlNo=${exchange.ordDtlNo}">
+												<div class="option_wrap"></div>
+											</div>
 										</div>
 										<div class="button_box">
 											<div class="count_modify">
@@ -146,8 +148,8 @@
 								</tbody>
 							</table>
 						</div>
-						<h4 class="subH3">반품 방식 선택</h4>
-						<div class="tbl type1">
+						<h4 class="subH3 wdGb">반품 방식 선택</h4>
+						<div class="tbl type1 wdGb">
 							<table>
 								<tbody>
 								<tr>
@@ -297,7 +299,7 @@
 <script src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 	var isLogin = [[${isLogin}]];
-	let ordNo = [[${oneData.ordNo}]];
+	//let ordNo = [[${oneData.ordNo}]];
 	let oneData = [[${oneData}]];
 	let isCustomer = true;
 	let addrGb = '';
@@ -315,9 +317,9 @@
 		});
 
 		// 입점업체의 경우 회수방식 직접배송 처리
-		if (oneData.selfGoodsYn == 'Y') {
+		if (oneData.selfGoodsYn != 'Y') {
 			$('#direct').click();
-			$('#wdGb').css('display','none');
+			$('.wdGb').css('display','none');
 		}
 	});
 
@@ -365,57 +367,99 @@
 	// 교환 옵션 변경 팝업 콜백 처리
 	var fnChangeOptionCallback = function(param) {
 		let ordDtlNo;
-		let chgOptionList = [];
-		let chgOptDisp = [];
-		$.each(param, function(idx, item) {
-			chgOptionList.push(item);
-			chgOptDisp.push(item.chgOptCd2Arr);
-		});
 
 		// 교환옵션 HTML 처리
 		let html = '												<span class="title">교환 옵션</span>\n';
-		$.each(chgOptionList, function(idx, item) {
+		$.each(param, function(idx, item) {
+			ordDtlNo = item.ordDtlNo;
 			let colorNm = item.colorNm;
 			let itemNm = item.itemNm;
 			let goodsType = item.goodsType;
+			let optCd2 = item.chgOptCd2;
+			let qty = item.chgQty;
 
-			$.each(item.chgOptCd2Arr, function (index, option) {
-				let optCd2 = option.chgOptCd2;
-				let qty = option.qty;
-				
-				if (goodsType == 'G056_S') {
-					html += '												<span class="option">' + itemNm + ' / ' + colorNm + ' / ' + optCd2 + ' / ' + qty + '개</span>\n';
-				} else {
-					html += '												<span class="option">' + colorNm + ' / ' + optCd2 + ' / ' + qty + '개</span>\n';
-				}
-			});
+			if (goodsType == 'G056_S') {
+				html += '												<span class="option">' + itemNm + ' / ' + colorNm + ' / ' + optCd2 + ' / ' + qty + '개</span>\n';
+			} else {
+				html += '												<span class="option">' + colorNm + ' / ' + optCd2 + ' / ' + qty + '개</span>\n';
+			}
 		});
 
 		$.each($('.exchangeOption'), function(idx, item) {
 			if (ordDtlNo == $(item).attr('ordDtlNo')) {
 				$(item).css('display', '');
-				$(item).html(html);
+				$(item).find('.option_wrap').html(html);
 			}
 		});
 
 		// 교환옵션 값 JSON 형태로 설정
 		$.each($('#exchangeForm input[name=chgOptionList]'), function(idx, item) {
 			if (ordDtlNo == $(item).attr('ordDtlNo')) {
-				$(item).val(JSON.stringify(chgOptionList));
+				$(item).val(JSON.stringify(param));
 			}
 		});
+	}
+
+	// 교환 처리
+	var fnExchange = function() {
+		// TODO
+		// 교환신청 처리
+
+		let url = '/mypage/exchange';
+		let delvFeeCd = oneData.delvFeeCd;
+		let ordDtlNo = oneData.ordDtlNo;
+		let supplyCompCd = oneData.supplyCompCd;
+		let excDelvFee = oneData.excDelvFee;
+		let rtnDelvFee = oneData.rtnDelvFee;
 
 		// 교환옵션 값 파싱 처리 예제
+		let cancelReqList = [];
 		$.each($('#exchangeForm input[name=chgOptionList]'), function(idx, item) {
 			let json = $(item).val();
 			let jsonData = JSON.parse(json);
+			$.each(jsonData, function(index, chgOpt) {
+				let cancelReq = {};
+				cancelReq.ordDtlNo = ordDtlNo;
+				cancelReq.ordDtlItemSq = chgOpt.ordDtlItemSq;
+				cancelReq.delvFeeCd = delvFeeCd;
+				cancelReq.supplyCompCd = supplyCompCd;
+				cancelReq.excDelvFee = excDelvFee;
+				cancelReq.rtnDelvFee = rtnDelvFee;
+				cancelReq.ordChgOpt = chgOpt.chgOptCd2;
+				cancelReq.chgQty = chgOpt.chgQty;
+				cancelReqList.push(cancelReq);
+			});
 		});
-	}
+		
+		let data = {};
+		data.ordNo = oneData.ordNo;
+		data.isCustomer = isCustomer;
+		data.wdGb = $('#exchangeForm input[name=wdGb]:radio:checked').val();
+		data.recipNm = $('#exchangeForm input[name=recipNm]').val();
+		data.recipPhnno = $('#exchangeForm input[name=recipPhnno]').val();
+		data.recipTelno = $('#exchangeForm input[name=recipTelno]').val();
+		data.recipZipcode = $('#exchangeForm input[name=recipZipcode]').val();
+		data.recipBaseAddr = $('#exchangeForm input[name=recipBaseAddr]').val();
+		data.recipDtlAddr = $('#exchangeForm input[name=recipDtlAddr]').val();
+		data.delvMemo = $('#exchangeForm input[name=delvMemo]').val();
+		data.chgReason = $('#exchangeForm input[name=chgReason]').val();
+		data.chgMemo = $('#exchangeForm textarea[name=chgMemo]').val();
+		data.chgerNm = $('#exchangeForm input[name=chgerNm]').val();
+		data.chgerPhnno = $('#exchangeForm input[name=chgerPhnno]').val();
+		data.chgerTelno = $('#exchangeForm input[name=chgerTelno]').val();
+		data.chgerEmail = $('#exchangeForm input[name=chgerEmail]').val();
+		data.chgerZipcode = $('#exchangeForm input[name=chgerZipcode]').val();
+		data.chgerBaseAddr = $('#exchangeForm input[name=chgerBaseAddr]').val();
+		data.chgerDtlAddr = $('#exchangeForm input[name=chgerDtlAddr]').val();
+		data.chgerRtnMemo = $('#exchangeForm input[name=chgerRtnMemo]').val();
+		data.addPayAmt = 0;
+		data.cancelReqList = cancelReqList;
+		
+		let jsonData = JSON.stringify(data);
 
-	// 교환 처리
-	var fnExchange = function() {
-		// TODO
-		// 교환신청 처리
+		gagajf.ajaxJsonSubmit(url, jsonData, function(result) {
+			console.log(result);
+		});
 	}
 
 	// 반품 방식 변경 이벤트
@@ -508,22 +552,22 @@
 			$('#recipAddr').text(recipBaseAddr + ' ' + recipDtlAddr);
 			$('#delvMemo').text(delvMemo);
 
-			$('input[name=recipNm]').val(recipNm);
-			$('input[name=recipPhnno]').val(recipPhnno);
-			$('input[name=recipZipcode]').val(recipZipcode);
-			$('input[name=recipBaseAddr]').val(recipBaseAddr);
-			$('input[name=recipDtlAddr]').val(recipDtlAddr);
-			$('input[name=delvMemo]').val(delvMemo);
+			$('#exchangeForm input[name=recipNm]').val(recipNm);
+			$('#exchangeForm input[name=recipPhnno]').val(recipPhnno);
+			$('#exchangeForm input[name=recipZipcode]').val(recipZipcode);
+			$('#exchangeForm input[name=recipBaseAddr]').val(recipBaseAddr);
+			$('#exchangeForm input[name=recipDtlAddr]').val(recipDtlAddr);
+			$('#exchangeForm input[name=delvMemo]').val(delvMemo);
 		} else {
 			let chgerAddr = recipBaseAddr + ' ' + recipDtlAddr + '\n';
 			chgerAddr += '<button type="button" class="btn btn_default btn_sm" onclick="fnChangeAddr(\'chger\');"><span>회수지 변경</span></button>';
 
-			$('input[name=chgerNm]').val(recipNm);
-			$('input[name=chgerPhnno]').val(recipPhnno);
-			$('input[name=chgerZipcode]').val(recipZipcode);
-			$('input[name=chgerBaseAddr]').val(recipBaseAddr);
-			$('input[name=chgerDtlAddr]').val(recipDtlAddr);
-			$('input[name=chgerRtnMemo]').val(delvMemo);
+			$('#exchangeForm input[name=chgerNm]').val(recipNm);
+			$('#exchangeForm input[name=chgerPhnno]').val(recipPhnno);
+			$('#exchangeForm input[name=chgerZipcode]').val(recipZipcode);
+			$('#exchangeForm input[name=chgerBaseAddr]').val(recipBaseAddr);
+			$('#exchangeForm input[name=chgerDtlAddr]').val(recipDtlAddr);
+			$('#exchangeForm input[name=chgerRtnMemo]').val(delvMemo);
 
 			$('#chgerNm').text(recipNm);
 			$('#chgerPhnno').text(recipPhnno);

+ 4 - 4
src/main/webapp/WEB-INF/views/web/mypage/MypageReturnFormWeb.html

@@ -148,8 +148,8 @@
 								</tbody>
 							</table>
 						</div>
-						<h4 class="subH3">반품 방식 선택</h4>
-						<div class="tbl type1">
+						<h4 class="subH3 wdGb">반품 방식 선택</h4>
+						<div class="tbl type1 wdGb">
 							<table>
 								<tbody>
 									<tr>
@@ -364,9 +364,9 @@
 		var return_reason_selecter = new sCombo('.myOrderView .tbl.type1 td .select_custom.select_reason');
 
 		// 입점업체의 경우 회수방식 직접배송 처리
-		if (oneData.selfGoodsYn == 'Y') {
+		if (oneData.selfGoodsYn != 'Y') {
 			$('#direct').click();
-			$('#wdGb').css('display','none');
+			$('.wdGb').css('display','none');
 		}
 	});
 

+ 1 - 1
src/main/webapp/biz/mypage.js

@@ -291,7 +291,7 @@ var fnChangeDeliveryAddr = function(param) {
 var fnChangeDeliveryMemo = function() {
 	var data = {};
 	data.delvMemo = $('input[name=delvMemo]').val();
-	data.ordNo = ordNo;
+	data.ordNo = oneData.ordNo;
 	
 	$.ajax({
 		type		: "POST",