본문 바로가기

JAVA/JAVA-Project

[스프링] 독서실 관리 프로그램- 이용 기간 연장하기 21. 06. 02. 수정

개요

좌석을 이용 중인 회원이 만료일 전에 이용 기간을 연장할 수 있도록 한다.
좌석 배치도에서 (추후에 MyPage같은 회원 정보 페이지로 이 기능을 이동할 것이다.) 내 만료일을 확인할 수 있고 '연장하기'버튼을 누르면 이용 기간 연장 페이지(exPament.jsp)로 이동한다.
이용 기간 연장 페이지(exPament.jsp)에서 이용중인 좌석 번호와 만료일을 확인할 수 있고 연장할 기간을 선택 후 '결제하기'버튼을 누른다.

+) 다른 조원 파트인 결제 부분이랑 합치다가 이 글을 쓰다 말았다는 것을 깜빡했다.😂 뒤늦게 올림.

 


🍏 mapper

 

public interface RegInfoMapper {
    // 이용 기간 연장 (이용 등록 정보 수정)
    int updatePeriod(RegInfoVO infoVO);
}

 

regInfoMapper.xml

<!-- 이용 기간 연장 (이용 등록 정보 수정) -->
<update id="updatePeriod">
    UPDATE TBL_REGINFO SET
    ENDDATE = ENDDATE + #{period}
    WHERE USERNO = #{userNo}
</update>

 

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/security-context.xml"})
@Log4j
public class RegInfoMapperTests {
    @Autowired
    private RegInfoMapper mapper;

    @Test
    public void updatePeriodTest() {
        RegInfoVO infoVO = new RegInfoVO();
        infoVO.setPeriod(1);
        infoVO.setUserNo(156L);
        mapper.updatePeriod(infoVO);
    }

}

 

🔶 회원 번호 156번이 하루 연장한다고 가정하고 테스트..

 


 

🍄 service

public interface RegInfoService {
    // 이용 기간 연장
    int extendUsingPeriod(RegInfoVO infoVO);
}

 

PaymentServiceImpl.java

@Service
@Log4j
public class PaymentServiceImpl implements PaymentService{
    @Autowired
    private PaymentMapper paymentMapper;
    @Autowired
    private RegInfoMapper reginfoMapper;
    @Autowired
    private SeatMapper seatMapper;
    @Autowired
    private LockerMapper lockerMapper;

        @Transactional
    @Override
    public void extendPayment(PaymentVO paymentVO, RegInfoVO regInfoVO) {
        regInfoVO.setUserNo(regInfoVO.getUserNo()); // 등록정보에서 유저넘 가져오기
        reginfoMapper.updatePeriod(regInfoVO); // userNo, period
        paymentVO.setUserNo(regInfoVO.getUserNo());
        paymentMapper.insert(paymentVO);
    }
}

 

🔶 이용 중이던 좌석과 사물함은 그대로 쓰는 것이기 때문에 따로 좌석/사물함과는 트랜잭션 처리할 것은 없고, 결제 서비스에서 트랜잭션 처리를 했다.

 


🍍 controller

 

@Controller
@Log4j
@RequestMapping("/payment/*")
@AllArgsConstructor
public class PaymentController {
    @Autowired
    private PaymentService paymentservice;
    @Autowired
    private RegInfoService reginfoservice;

        /**
     * 기간 연장 페이지로 이동하는 메서드.
     * @author 김보경
     * 
     * @param model
     * 
     * @param auth
     *             시큐리티를 이용한 로그인 된 이용자의 정보를 담고 있음.
     */
    @GetMapping("exPayment")
    public void getExPayment(Model model, Authentication auth) {
        log.info("기간 연장 결제 페이지..");
        /* 만료일의 날짜 포맷을 변경하는 작업*/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        /* 이용자의 만료일을 처리하는 작업 */
        CustomUser user = (CustomUser) auth.getPrincipal(); // 로그인 된 이용자의 정보를 가져 온다.

        RegInfoVO regInfoVO = reginfoservice.read(user.getVo().getUserNo()); // 해당 이용자의 이용정보를 불러온다.
        String endDate = sdf.format(regInfoVO.getEndDate());
        FeeVO feeVO = paymentservice.findBy(regInfoVO.getFno());

        model.addAttribute("regInfoVO", regInfoVO);
        model.addAttribute("endDate",endDate);
        model.addAttribute("feeVO", feeVO);
    }
    /*
     * 연장결제 완료 페이지 이동 컨트롤러
     */
    @PreAuthorize("principal.vo.userNo == #regInfoVO.userNo")
    @PostMapping("exPayComplete")
    public void postExPayComplete(RegInfoVO regInfoVO, PaymentVO paymentVO, Model model) {
        log.info("exPayment......");
        log.info("regInfoVO" + regInfoVO);
        log.info("paymentVO" + paymentVO);
        model.addAttribute("PaymentVO", paymentVO);
        model.addAttribute("RegInfoVO", regInfoVO);
        /*연장실행 - 결제 및 기간연장*/
        paymentservice.extendPayment(paymentVO, regInfoVO);
    }

}

 

🔶 시큐리티의 csrf를 disable 해놓고 지금까지 작업했었는데 오늘부턴 csrf를 적용해서 테스트 하고 있다. 그래서 포스트 처리한 부분들에 @PreAuthorize를 붙여주었다.
🔶 이전에는 아이디만 비교 했어서 principal.username만 썼었는데 좌석 기능에서는 userNo이 필요했고 어떻게 하면 접근할 수 있나 했더니 principal.vo.userNo 이렇게 하니깐 됐다!

 


🍎 jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec"%>
<jsp:include page="../includes/header_.jsp" />
    <!-- Home -->

    <div class="home">
        <div class="home_background_container prlx_parent">
            <div class="home_background prlx" style="background-image:url(${pageContext.request.contextPath}/resources/images/news_background.jpg)"></div>
        </div>
        <div class="home_content">
            <h1>이용 기간 연장</h1>
        </div>
    </div>

    <!-- News -->

    <div class="news">
        <div class="container">
            <div class="row">
            <div class="col-lg-6 d-none d-lg-block">
                <img class="img-fluid" src="${pageContext.request.contextPath}/resources/images/logo_transparent.png" alt="logo" width="600px">
            </div>
            <div class="col-lg-6 mt-5">
                <div class="p-5 mt-5">
                    <div class="">
                        <sec:authorize access="isAuthenticated()">
                        <sec:authentication property="principal" var="member"/>
                            <div class="mb-3">
                                <h3 class="text-muted">이용 중인 좌석 번호: ${regInfoVO.seatNo}</h3>
                                <h3 class="text-muted">이용 중인 사물함 번호: ${regInfoVO.lockerNo}</h3>
                                <h3 class="text-muted">나의 만료일: ${endDate}</h3>
                            </div>
                        </sec:authorize>
                    </div>
                    <form method="post" class="ex-form mt-3" action="exPayComplete">
                        <span class="text-danger">이용중인 사물함이 있을 시 사물함도 같이 연장됩니다.</span>
                        <select name="fno" class="period form-control mt-3">
                            <option value=""> 기간을 선택하세요 </option>
                            <option value="1">1일 (8,000)</option>
                            <option value="2">7일 (50,000)</option>
                            <option value="3">14일 (90,000)</option>
                            <option value="4">30일 (200,000)</option>
                        </select>
                                <input type="hidden" name="seatNo" value="${regInfoVO.seatNo}">
                                <input type="hidden" name="lockerNo" value="${regInfoVO.lockerNo}">
                                <c:if test="${regInfoVO.lockerNo !=''}"> <!-- 기존에 사물함도 이용하는 유저일 때 -->
                                    <input class="chkLoc" type="checkbox" value="usingLoc" checked onclick="return false;"> <!-- script에서 fno2 처리 -->
                                </c:if>
                        <input type="hidden" name="userNo" value="${member.vo.userNo}">
                        <input type="hidden" name="userName" value="${member.vo.userName}">
                        <button type="button" class="btn btn-outline-warning btn-block mt-4 extBtn">결제하기</button>
                        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">
                    </form>
                    <hr>
                </div>
            </div>           
            </div>
        </div>
    </div>
    <script src="${pageContext.request.contextPath}/resources/js/payment.js"></script>
    <script>
    var cp = '${pageContext.request.contextPath}';

    $(function(){

        var buyerName = '${member.vo.userName}'; //구매자

        console.log(buyerName);
        $(".extBtn").hide(); // 결제버튼 숨김
        $(".chkLoc").hide();
        $(".period").on("change", function(){ //셀렉트태그 변경시
            $(".period option[value='']").remove(); // 기본값제거
            $(".extBtn").show(); // 결제버튼 보여줌
            var fno = $(".period option:selected").val(); // fno에 셀렉트 값부여
            fname = $(".period option:selected").text(); // fname에 셀렉트 이름부여
            console.log(fno); 
            console.log(fname);
            paymentService.feeFindBy({fno:fno, cp:cp}, function(result){ //fno로 해당하는 feeVO 찾는 함수
                console.log(result);
                amount = result.price; // amount에 feeVO의가격부여
                period = result.period; // period에 feeVO의가격부여
                console.log(amount);
                console.log(period);
            });
            //console.log($(".chkLoc").prop('checked'));

            if($(".chkLoc").prop('checked') && fno != 1) { //check박스가 true이고 fno가 1일아닐때
                // 기간이 같은 사물함요금제에 해당하는 fno2를 부여
                if (fno == 2) {
                    fno2 = 5;
                } else if(fno == 3) {
                    fno2 = 6;
                } else if(fno == 4) {
                    fno2 = 7;
                }

                paymentService.feeFindBy({fno:fno2 , cp:cp}, function(result){ //fno2로 해당하는 feeVO 찾는 함수
                    console.log(result);
                    amount += result.price; // amount에 feeVO의가격추가
                    fname += result.name; // period에 feeVO의가격추가
                    console.log("after..." + amount);
                    console.log("atter..." + period);
                });
            }

        })

            /* 이니시스 결제 코드 */
        $(".extBtn").click(function(){
            var IMP = window.IMP; // 생략가능
            IMP.init('imp66686777'); // 'iamport' 대신 부여받은 "가맹점 식별코드"를 사용

            IMP.request_pay({
                pg : 'inicis', // version 1.1.0부터 지원.
                pay_method : 'card',
                merchant_uid : 'merchant_' + new Date().getTime(),
                name :  fname ,
                amount : amount ,
                //buyer_email : 'iamport@siot.do',
                buyer_name : buyerName ,
                //buyer_tel : '010-1234-5678',
                //buyer_addr : '서울특별시 강남구 삼성동',
                //buyer_postcode : '123-456',
                m_redirect_url : 'https://www.yourdomain.com/payments/complete'
            }, function(rsp) {
                if ( rsp.success ) {
                    var msg = '결제가 완료되었습니다.';
                    msg += '고유ID : ' + rsp.imp_uid;
                    msg += '상점 거래ID : ' + rsp.merchant_uid;
                    msg += '결제 금액 : ' + rsp.paid_amount;
                    msg += '카드 승인번호 : ' + rsp.apply_num;



                } else {
                    var msg = '결제에 실패하였습니다.';
                    msg += '에러내용 : ' + rsp.error_msg;

                    var str = '<input type="hidden" name="period" value="'+ period +'">';
                    str += '<input type="hidden" name="payment" value="'+ amount +'">';
                    str += '<input type="hidden" name="itemName" value="'+ fname +'">';
                    console.log(str);
                    $(".ex-form").append(str).submit();

                }
                alert(msg);
            });
        });
    }) 


</script>
<jsp:include page="../includes/footer.jsp" />

 

🔶 form 안에 csrf 토큰을 꼭 보내야 한다.