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
public interface BOSubsvcMapper {
/** 구독서비스 목록 조회*/
List<DataMap> selectBOSubsvcList(BOSubsvcVO vo);
/** 구독서비스 상세 조회*/
DataMap selectBOSubsvcDetail(BOSubsvcVO vo);
/** 관리자 구독서비스 목록 조회*/
List<DataMap> selectBOMngrSubsvcList(BOSubsvcVO vo);

View File

@@ -30,4 +30,17 @@ public class BOSubsvcService {
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.vo.BOMaComncdVO;
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.vo.BOMbrVO;
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.itrnt.str.service.BOItrntStrService;
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.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.mpage.ordr.vo.MyOrdrDlvyVO;
import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyRefundVO;
import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.response.ApiResponse;
import com.wb.domainserver.response.WnbtResponse;
import com.wb.domainserver.response.WnbtResponseBody;
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.authorization.annotation.AuthPolicy;
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.util.Util;
import jakarta.servlet.http.Cookie;
@@ -45,14 +45,12 @@ import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.math.BigInteger;
@@ -99,6 +97,8 @@ public class MainController {
private BOMaSopmalService boMaSopmalService;
@Autowired
private BOMbrService boMbrService;
@Autowired
private BOSubsvcService boSubsvcService;
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value= {"/","/index", "/sopmal/index","/sopmal/main"})
@@ -796,15 +796,51 @@ public class MainController {
/**
* 구독서비스 폼 이동
*
* @return
* @param model
* @param request
* @return String
*/
@Policy(AuthPolicy.PUBLIC)
@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";
}
/**
* 구독서비스 상세 조회
* @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">
<!-- 구독서비스 목록 조회 -->
<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[
SELECT 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
SELECT GS.SUBSVC_INNB
, SUBSVC_STTUS_CD
, EXPSR_DV_CD
, EXPSR_BGN_DT
, EXPSR_END_DT
, EXPSR_SETUP_FWORDS
, PURCHS_QY_LMTT_DV_CD
, PURCHS_QY_TY_CD
, MUMM_PURCHS_QY
, MXMM_PURCHS_QY
, SUBSVC_DC
, MBL_SUBSVC_DC
, MBL_SUBSVC_DC_PC_SAME_AT
, IMG
, SUBSCRPT_WTHDRAW_POSBL_AT
, DFT_GOODS_OPTN_INNB
, LAST_PROCS_ODR
, USE_AT
, REGUSR
, REGIST_DT
, UPDUSR
, UPDT_DT
FROM GC_SUBSVC
WHERE 1 = 1
AND SOPMAL_CD = #{sopmalCd}
AND EXPSR_DV_CD = 'Y'
AND NOW() BETWEEN EXPSR_BGN_DT AND EXPSR_END_DT
, CONCAT(GS.SUBSVC_NM, ' (', GS.SUBSVC_GNR_NM, ')') AS SUBSVC_CONCAT_NM
FROM GC_SUBSVC GS
WHERE GS.SOPMAL_CD = 'SK'
AND GS.SUBSVC_STTUS_CD != '03'
AND GS.EXPSR_DV_CD IN ('01','03')
AND
CASE
WHEN EXPSR_DV_CD = '03'
THEN NOW() BETWEEN GS.EXPSR_BGN_DT AND GS.EXPSR_END_DT
ELSE 1=1
END
]]>
</select>
<!-- 구독서비스 상세 조회 -->
<select id="selectBOSubsvcDetail"
parameterType="com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO"
resultType="dataMap">
<![CDATA[
SELECT GS.SUBSVC_INNB
, GS.SOPMAL_CD
, GS.SUBSVC_NM
, GS.SUBSVC_GNR
, GS.SUBSVC_GNR_NM
, 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>

View File

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