fix : 쇼핑몰 구독서비스 관련

This commit is contained in:
이대환
2026-01-23 16:47:37 +09:00
parent 4f920c0919
commit bda09e6e4f
5 changed files with 223 additions and 133 deletions

View File

@@ -12,7 +12,10 @@ import java.util.List;
@Repository @Repository
public interface BOSubsvcMapper { public interface BOSubsvcMapper {
/** 구독서비스 목록 조회*/
List<DataMap> selectBOSubsvcList(BOSubsvcVO vo); List<DataMap> selectBOSubsvcList(BOSubsvcVO vo);
/** 구독서비스 상세 조회*/
DataMap selectBOSubsvcDetail(BOSubsvcVO vo);
/** 관리자 구독서비스 목록 조회*/ /** 관리자 구독서비스 목록 조회*/
List<DataMap> selectBOMngrSubsvcList(BOSubsvcVO vo); List<DataMap> selectBOMngrSubsvcList(BOSubsvcVO vo);

View File

@@ -30,4 +30,17 @@ public class BOSubsvcService {
return dataList; return dataList;
} }
/**
* 구독서비스 상세 조회
* @param vo
* @return
*/
public DataMap selectBOSubsvcDetail(BOSubsvcVO vo) {
DataMap dataMap = new DataMap();
dataMap = mapper.selectBOSubsvcDetail(vo);
return dataMap;
}
} }

View File

@@ -9,6 +9,8 @@ import com.wb.domainserver.domain.admin.store.sopmal.vo.BOMaSopmalVO;
import com.wb.domainserver.domain.admin.sys.comncd.service.BOMaComncdService; import com.wb.domainserver.domain.admin.sys.comncd.service.BOMaComncdService;
import com.wb.domainserver.domain.admin.sys.comncd.vo.BOMaComncdVO; import com.wb.domainserver.domain.admin.sys.comncd.vo.BOMaComncdVO;
import com.wb.domainserver.domain.gcone.common.service.BOCommonService; import com.wb.domainserver.domain.gcone.common.service.BOCommonService;
import com.wb.domainserver.domain.gcone.goods.subsvc.service.BOSubsvcService;
import com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO;
import com.wb.domainserver.domain.gcone.mbr.mbr.service.BOMbrService; import com.wb.domainserver.domain.gcone.mbr.mbr.service.BOMbrService;
import com.wb.domainserver.domain.gcone.mbr.mbr.vo.BOMbrVO; import com.wb.domainserver.domain.gcone.mbr.mbr.vo.BOMbrVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrService; import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrService;
@@ -20,15 +22,11 @@ import com.wb.domainserver.domain.gcone.setup.site.vo.BOPrevewVO;
import com.wb.domainserver.domain.gcone.setup.site.vo.BOSiteVO; import com.wb.domainserver.domain.gcone.setup.site.vo.BOSiteVO;
import com.wb.domainserver.domain.itrnt.str.service.BOItrntStrService; import com.wb.domainserver.domain.itrnt.str.service.BOItrntStrService;
import com.wb.domainserver.domain.itrnt.str.vo.BOItrntStrVO; import com.wb.domainserver.domain.itrnt.str.vo.BOItrntStrVO;
import com.wb.domainserver.domain.sample.vo.PrevewVO;
import com.wb.domainserver.domain.sopmal.main.vo.BrandVO; import com.wb.domainserver.domain.sopmal.main.vo.BrandVO;
import com.wb.domainserver.domain.sopmal.main.vo.MaSopmalVO;
import com.wb.domainserver.domain.sopmal.main.vo.MainVO;
import com.wb.domainserver.domain.sopmal.main.vo.StrVO; import com.wb.domainserver.domain.sopmal.main.vo.StrVO;
import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyOrdrDlvyVO; import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyOrdrDlvyVO;
import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyRefundVO; import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyRefundVO;
import com.wb.domainserver.exception.WnbtRestException; import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.response.ApiResponse;
import com.wb.domainserver.response.WnbtResponse; import com.wb.domainserver.response.WnbtResponse;
import com.wb.domainserver.response.WnbtResponseBody; import com.wb.domainserver.response.WnbtResponseBody;
import com.wb.domainserver.response.WnbtWebClientResponseHandler; import com.wb.domainserver.response.WnbtWebClientResponseHandler;
@@ -36,7 +34,9 @@ import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder; import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.security.authorization.annotation.AuthPolicy; import com.wb.domainserver.security.authorization.annotation.AuthPolicy;
import com.wb.domainserver.security.authorization.annotation.Policy; import com.wb.domainserver.security.authorization.annotation.Policy;
import com.wb.domainserver.util.communicate.*; import com.wb.domainserver.util.communicate.KakaoProperties;
import com.wb.domainserver.util.communicate.MultiValueMapConverter;
import com.wb.domainserver.util.communicate.SendToResrc;
import com.wb.domainserver.util.dataaccess.DataMap; import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.util.Util; import com.wb.domainserver.util.util.Util;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
@@ -45,14 +45,12 @@ import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import java.math.BigInteger; import java.math.BigInteger;
@@ -99,6 +97,8 @@ public class MainController {
private BOMaSopmalService boMaSopmalService; private BOMaSopmalService boMaSopmalService;
@Autowired @Autowired
private BOMbrService boMbrService; private BOMbrService boMbrService;
@Autowired
private BOSubsvcService boSubsvcService;
@Policy(AuthPolicy.PUBLIC) @Policy(AuthPolicy.PUBLIC)
@RequestMapping(value= {"/","/index", "/sopmal/index","/sopmal/main"}) @RequestMapping(value= {"/","/index", "/sopmal/index","/sopmal/main"})
@@ -796,15 +796,51 @@ public class MainController {
/** /**
* 구독서비스 폼 이동 * 구독서비스 폼 이동
* * @param model
* @return * @param request
* @return String
*/ */
@Policy(AuthPolicy.PUBLIC) @Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/sopmal/main/selectSubscribeForm") @RequestMapping(value = "/sopmal/main/selectSubscribeForm")
public String selectSubscribeForm(HttpServletRequest request) { public String selectSubscribeForm(ModelMap model, HttpServletRequest request) {
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
DataMap content = new DataMap();
BOSubsvcVO subsvcVo = new BOSubsvcVO();
subsvcVo.setSopmalCd(user.getSopmalCd());
content.put("subsvcList", boSubsvcService.selectBOSubsvcList(subsvcVo));
BOMaSopmalVO sopmalVO = new BOMaSopmalVO();
sopmalVO.setSopmalCd(user.getSopmalCd());
content.put("sopmalInfo", boMaSopmalService.selectBOSopmalUpdtForm(sopmalVO));
model.addAttribute("resultMap", content);
return Util.getDeviceType(request) + "/main/SubscribeR"; return Util.getDeviceType(request) + "/main/SubscribeR";
} }
/**
* 구독서비스 상세 조회
* @param subsvcVO
* @return ResponseEntity<WnbtResponse>
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/sopmal/main/selectSubscribeDetail", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> selectSubscribeDetail(BOSubsvcVO subsvcVO) {
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
Map<String, Object> message = new HashMap<>();
subsvcVO.setSopmalCd(user.getSopmalCd());
message.put("resultMap", boSubsvcService.selectBOSubsvcDetail(subsvcVO));
return ResponseEntity.ok(
WnbtResponse.builder()
.resBody(new WnbtResponseBody(message))
.build()
);
}
/** /**
* 자담유 > 네가지약속 (모바일) * 자담유 > 네가지약속 (모바일)
* *

View File

@@ -3,49 +3,54 @@
<mapper namespace="com.wb.domainserver.domain.gcone.goods.subsvc.mapper.BOSubsvcMapper"> <mapper namespace="com.wb.domainserver.domain.gcone.goods.subsvc.mapper.BOSubsvcMapper">
<!-- 구독서비스 목록 조회 --> <!-- 구독서비스 목록 조회 -->
<select id="selectBOSubsvcList" parameterType="com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO" resultType="dataMap"> <select id="selectBOSubsvcList"
parameterType="com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO"
resultType="dataMap">
<![CDATA[ <![CDATA[
SELECT SUBSVC_INNB SELECT GS.SUBSVC_INNB
, SOPMAL_CD
, SUBSVC_NM
, SUB_PD
, SUBSVC_GNR
, SUBSVC_GNR_NM
, DLVY_CNT
, DLVY_CYCLE
, SUBSVC_CT
, TME_DLVY_AMT
, CNSMRPRIC
, INVNTRY_QY
, USEFUL_INVNTRY_QY
, INVNTRY_POLICY_CD
, AVLINV_LMTT_QY
, SUBSVC_STTUS_CD , SUBSVC_STTUS_CD
, EXPSR_DV_CD , CONCAT(GS.SUBSVC_NM, ' (', GS.SUBSVC_GNR_NM, ')') AS SUBSVC_CONCAT_NM
, EXPSR_BGN_DT FROM GC_SUBSVC GS
, EXPSR_END_DT WHERE GS.SOPMAL_CD = 'SK'
, EXPSR_SETUP_FWORDS AND GS.SUBSVC_STTUS_CD != '03'
, PURCHS_QY_LMTT_DV_CD AND GS.EXPSR_DV_CD IN ('01','03')
, PURCHS_QY_TY_CD AND
, MUMM_PURCHS_QY CASE
, MXMM_PURCHS_QY WHEN EXPSR_DV_CD = '03'
, SUBSVC_DC THEN NOW() BETWEEN GS.EXPSR_BGN_DT AND GS.EXPSR_END_DT
, MBL_SUBSVC_DC ELSE 1=1
, MBL_SUBSVC_DC_PC_SAME_AT END
, IMG ]]>
, SUBSCRPT_WTHDRAW_POSBL_AT </select>
, DFT_GOODS_OPTN_INNB
, LAST_PROCS_ODR <!-- 구독서비스 상세 조회 -->
, USE_AT <select id="selectBOSubsvcDetail"
, REGUSR parameterType="com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO"
, REGIST_DT resultType="dataMap">
, UPDUSR <![CDATA[
, UPDT_DT SELECT GS.SUBSVC_INNB
FROM GC_SUBSVC , GS.SOPMAL_CD
WHERE 1 = 1 , GS.SUBSVC_NM
AND SOPMAL_CD = #{sopmalCd} , GS.SUBSVC_GNR
AND EXPSR_DV_CD = 'Y' , GS.SUBSVC_GNR_NM
AND NOW() BETWEEN EXPSR_BGN_DT AND EXPSR_END_DT , GS.DLVY_CNT
, GS.INVNTRY_QY
, GS.INVNTRY_QY - GS.USEFUL_INVNTRY_QY AS AVAIL_QT /*가용재고*/
, GS.SUBSVC_STTUS_CD
, FN_GET_COMMCODE_NAME('GOODS_STTUS', GS.SUBSVC_STTUS_CD) AS SUBSVC_STTUS
, FN_GET_COMMCODE_NAME('EXPSR_DV', GS.EXPSR_DV_CD) AS EXPSR_DV
, GS.SUBSVC_CT /*구독료*/
, GS.TME_DLVY_AMT /*1회배송비*/
, GS.CNSMRPRIC /*소비자가*/
, GS.SUBSVC_CT + (TME_DLVY_AMT * DLVY_CNT) as SELPRIC /*실판매가=구독료+(1회배송비X배송횟수)*/
, GS.IMG
, GS.SUBSVC_DC
, GS.MBL_SUBSVC_DC
, GS.MBL_SUBSVC_DC_PC_SAME_AT
, GS.SUB_PD
FROM GC_SUBSVC GS
WHERE GS.SOPMAL_CD = #{sopmalCd}
AND GS.SUBSVC_INNB = #{subsvcInnb}
]]> ]]>
</select> </select>

View File

@@ -15,63 +15,92 @@
<html lang="ko"> <html lang="ko">
<head> <head>
<jsp:include page="/WEB-INF/views/comm/Include.jsp"/> <jsp:include page="/WEB-INF/views/comm/Include.jsp"/>
</head> </head>
<script> <script>
$(document).ready(function() {
var subsvcInnb = $('#subsvcInnb').val();
fn_select_subsvcDetail(subsvcInnb);
});
/******************************************************
* 구독서비스 상세 조회
* ****************************************************/
const fn_select_subsvcDetail = function(subsvcInnb) {
$.ajax({
type: "post",
url : '<c:url value="/sopmal/main/selectSubscribeDetail"/>',
data : {
subsvcInnb : subsvcInnb
},
success: function (data) {
data = JSON.parse(data.resBody.result);
data = data.resultMap;
$('#subPd').val(data.subPd);
$('#dlvyCnt').val(data.dlvyCnt);
$('#dlvyCycle').val(data.dlvyCycle);
$('#cnsmrpric').val(data.cnsmrpric);
$('#selpric').val(data.selpric);
$('#saleRatio').val(data.saleRatio);
}
});
}
</script> </script>
<style> <style>
.container { .container {
display: flex; display: flex;
width: 100%; width: 100%;
height: 200px; height: 200px;
border: 1px solid #e9ecef; border: 1px solid #e9ecef;
} margin-top: 100px;
}
.box { .box {
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
border-right: 1px solid #e9ecef; border-right: 1px solid #e9ecef;
display: flex; display: flex;
padding: 32px; padding: 32px;
box-sizing: border-box; box-sizing: border-box;
} }
.box:last-child { .box:last-child {
display: flex; display: flex;
border-right: none; border-right: none;
justify-content: center; justify-content: center;
} }
.box > span { .box > span {
width: 100%; width: 100%;
margin-bottom: 16px; margin-bottom: 16px;
} }
.box ul { .box ul {
padding-left: 20px; padding-left: 20px;
margin: 0; margin: 0;
} }
.box ul li { .box ul li {
list-style-type: disc; list-style-type: disc;
margin-bottom: 8px; margin-bottom: 8px;
} }
.box button { .box button {
background-color: #000; background-color: #000;
color: #fff; color: #fff;
border: none; border: none;
padding: 12px 24px; padding: 12px 24px;
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
} }
.box button:hover { .box button:hover {
opacity: 0.85; opacity: 0.85;
} }
</style> </style>
<body> <body>
<%-- 공통 Header --%> <%-- 공통 Header --%>
@@ -79,43 +108,47 @@
<spring:eval expression="@environment.getProperty('currency-unit.default')" var="curUnit"/> <spring:eval expression="@environment.getProperty('currency-unit.default')" var="curUnit"/>
<!-- 메인 컨텐츠 영역 --> <!-- 메인 컨텐츠 영역 -->
<main> <main>
<div class="sub-wrapper"> <div class="sub-wrapper">
<div class="sub-content"> <div class="sub-content">
<form> <form>
<h2 class="subList__title">구독 서비스</h2> <h2 class="subList__title">구독 서비스</h2>
<div class="container"> <div class="ck-content" style="border: 1px solid #e9ecef">
<div class="box"> <c:out value="${ resultMap.sopmalInfo[0].subsvcGuidanceWords }" escapeXml="false"/>
<span>구독서비스</span> </div>
<div class="select-box"> <c:choose>
<select class="" title=""> <c:when test="${not empty resultMap.subsvcList}">
<option value="" selected>구독서비스 안내</option> <div class="container">
<option value="">구독서비스 준비중</option> <div class="box">
<option value="">프리미엄 구독 (잔여 : 100)</option> <span>구독서비스</span>
<option value="">Top10 선정 (잔여 : 10)</option> <div class="select-box">
<option value="">Top100 선정 (잔여 : 100)</option> <select title="구독 서비스 선택" id="subsvcInnb" name="subsvcInnb" onchange="fn_select_subsvcDetail(this.value);">
</select> <c:forEach var="subsvcList" items="${resultMap.subsvcList}" varStatus="status">
</div> <option value="${subsvcList.subsvcInnb}" <c:if test="${status.first}">selected</c:if>>${subsvcList.subsvcConcatNm}</option>
</div> </c:forEach>
<div class="box"> </select>
<span>구독서비스 내역</span> </div>
<ul> </div>
<li>구독기간 : 12개월</li> <div class="box">
<li>배송횟수 : 12회</li> <span>구독서비스 내역</span>
<li>배송주기 : 매달 1회</li> <ul>
<li>상품금액 : 99,000${curUnit} <span style="color: red">58%</span></li> <li>구독기간 : <span id="subPd"></span>개월</li>
</ul> <li>배송횟수 : <span id="dlvyCnt"></span>회</li>
</div> <li>배송주기 : <span id="dlvyCycle"></span></li>
<div class="box"> <li>상품금액 : <span id="cnsmrpric" style="font-size: 12px; color: grey; text-decoration: line-through;"></span><span id="selpric"></span>${curUnit} <span id="saleRatio" style="color: red">%</span></li>
<button>구독하기</button> </ul>
</div> </div>
</div> <div class="box">
<button>구독하기</button>
<div class="ck-content"> </div>
</div> </div>
</c:when>
</form> <c:otherwise>
</div> <span style="display: block; width: 100%; text-align: center; font-size: 32px;">구독 서비스 상품 준비중</span>
</div> </c:otherwise>
</c:choose>
</form>
</div>
</div>
</main> </main>
<jsp:include page="/WEB-INF/views/comm/Footer.jsp"/> <jsp:include page="/WEB-INF/views/comm/Footer.jsp"/>