[스프링부트+JPA+타임리프] 강의 위시 리스트 / 장바구니 추가 / 강의 구매 후 권한 획득

jyleever·2022년 5월 19일
0

강의를 구매하지 않은 회원만 찜하기/장바구니에 추가 기능을 사용할 수 있다.
강의 구매 후 수강할 수 있는 권한을 획득할 수 있다.

Iamport API 이용 강의 구매 포스팅

LectureController

강의를 상세 조회할 때 관여하는 컨트롤러

    /** 강의 상세 조회 **/
    /* /lecture/{category_name}/{lecture_id} */
    @GetMapping("/{category_name}/{lecture_id}")
    public String readByLectureId(@PathVariable("category_name") String category_name,
                                  @PathVariable("lecture_id") Long lecture_id,
                                  @AuthenticationPrincipal UserAdapter user,
                                  Model model){

        /** 구매한 강의인지 확인 lectureCheck, 구매한 강의라면 true, 구매하지 않은 강의라면 false **/
        /** 리뷰한 강의인지 확인 reviewCheck **/

        boolean lectureCheck;
        boolean reviewCheck;

        if(user != null){
            // 로그인한 사용자라면
            Long member_id = user.getMemberDto().getId();
            model.addAttribute("member_id", member_id);

            lectureCheck = lectureService.myLectureCheck(member_id, lecture_id);
            reviewCheck = reviewService.reviewCheck(member_id, lecture_id);

        } else {
            // 로그인하지 않은 사용자도 false
            lectureCheck = false;
            reviewCheck = false;
        }

        model.addAttribute("lectureCheck", lectureCheck);
        model.addAttribute("reviewCheck", reviewCheck);

        /* 강의, 리뷰 목록 반환 */
        LectureDto.ResponseDto lecture = lectureService.getById(lecture_id);
        List<ReviewDto.ResponseDto> reviewList = reviewService.findAllByLecture(lecture_id);
        List<CourseDto.ResponseDto> courseList = courseService.getAllById(lecture_id);

        model.addAttribute("lecture", lecture);
        model.addAttribute("reviewList", reviewList);
        model.addAttribute("courseList", courseList);

        /* 강의 카테고리 리스트, 현재 카테고리 반환 */
        List<LectureCategoryDto.ResponseDto> categoryList = categoryService.findLectureList();
        model.addAttribute("categoryList", categoryList);
        model.addAttribute("category_name", category_name);

        return "lecture/lecture-read";
    }

LectureService에 로그인 유저 id와 조회하려는 강의 id를 파라미터로 넘겨서 로그인 유저가 구매한 강의인지 확인한 boolean 결괏값을 lectureCheck에 담는다

  • 구매한 강의라면 true, 구매하지 않은 강의라면 false
  • 비로그인 유저라면 무조건 false 반환

LectureService

현재 로그인한 유저가 구매한 강의인지 확인

/** 현재 로그인한 유저가 구매한 강의인지 확인 **/
@Override
public boolean myLectureCheck(Long member_id, Long lecture_id) {
	return myLectureRepository.existsByMember_IdAndLecture_Id(member_id, lecture_id);
}

MyLectureRepository

유저가 특정 강의를 수강하고 있는지 확인

   /** 유저가 특정 강의를 수강하고 있는지 확인 **/
    boolean existsByMember_IdAndLecture_Id(Long member_id, Long lecture_id);

lecture-read.html

강의 상세 페이지

<div class="card card-body blur shadow-blur mx-1 mx-md-1 mt-n3" th:unless="${lectureCheck}">
	<span class="text-dark">한 번 결제하면 평생 수강!</span>
		<span class="h3 text-dark" th:text="${lecture.price} + '원'"></span>
			<span sec:authorize="isAuthenticated()">
              <!-- 수강신청 -->
              <button type="button" class="btn btn-danger btn-lg w-auto me-2" id="buy-button">장바구니 추가</button>
              <!--찜하기-->

              <button class="btn bg-gradient-primary btn-icon w-auto me-2" type="button"
                   th:onclick="saveWish([[${lecture.id}]])">

              <div class="d-flex align-items-center">
                    <i class="material-icons me-2" aria-hidden="true">favorite</i>
                        찜 하기
                </div>
              </button>
   			</span>
</div>

<div class="card card-body blur shadow-blur mx-1 mx-md-1 mt-n3" th:if="${lectureCheck}">
	<span class="text-dark">오늘도 공부한 당신!</span>
		<span class="h4 text-dark">멋진 개발자에 한 걸음 더 :) </span>
</div>
  • th:unless="${lectureCheck}">

    • lectureCheck 값이 false인 경우, 즉 강의를 구매하지 않은 경우
  • <span sec:authorize="isAuthenticated()">

    • 인증 관련 타임리프 문법. 로그인한 유저인 경우에 해당
  • th:if="${lectureCheck}">

    • 강의를 구매한 경우에만 보여줌

lecture-read.html - javascript

위시 리스트/장바구니에 추가 버튼을 눌렀을 때 실행되는 함수

<script>

    const header = $("meta[name='_csrf_header']").attr('content');
    const token = $("meta[name='_csrf']").attr('content');

    /** 강의 구매 버튼 -> 장바구니에 추가 -> 장바구니로 이동 **/
    $("#buy-button").click(function () {
        const lectureId = $("#lectureId").val();

        $.ajax({
            type: 'post',
            url: '/rest/cart/' + lectureId,
            contentType: 'application/json; charset=utf-8'
        }).done(function(result){
            if(result){
                alert("장바구니에 존재하는 강의입니다.");
            } else{
                alert("장바구니에 저장되었습니다.");
                window.location.href = '/cart/';
            }
        }).fail(function(error){
            alert(JSON.stringify(error));
        });
    });

    /** 위시리스트에 추가 **/
    function saveWish(lectureId) {
        $.ajax({
            url: '/rest/wish/' + lectureId,
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
        }).done(function(result){

            // 이미 찜한 강의라면 찜 삭제 및 true 반환
            if(result){
                alert("위시리스트에서 삭제하였습니다.");
                location.reload();
            } else {
                alert("위시리스트에 저장하였습니다.");
                location.reload();
            }
        }).fail(function(error){
            alert(JSON.stringify(error));
        });
    };
  • 장바구니 버튼을 눌렀을 때 '/rest/cart/' + lectureId 컨트롤러로 post 방식으로 ajax 통신
  • lectureId에 대한 컨트롤러 통신 결과 결괏값이 true라면 장바구니에 이미 저장됐다는 의미이므로 "장바구니에 존재하는 강의입니다" 알림이 뜨도록 함
  • 결괏값이 false라면 장바구니에 저장했다는 의미이므로 장바구니에 저장했다는 알림창이 뜨도록 함.
  • 위시리스트도 마찬가지로 '/rest/wish/' + lectureId 컨트롤러로 post 방식으로 aja통신
  • 이미 위시리스트에 저장된 강의라면 삭제하도록 함.

CartRestController

'/rest/cart/' + lectureId 컨트롤러를 통해 현재 로그인한 유저의 장바구니에 해당 강의가 존재하는지 확인 및 저장

   /** 강의 상세 페이지에서 장바구니에 강의 저장 **/
    @PostMapping("/{lecture_id}")
    public boolean save(@PathVariable Long lecture_id,
                        @AuthenticationPrincipal UserAdapter user){

        Long member_id = user.getMemberDto().getId();
        if(cartService.checkCart(member_id, lecture_id)){
            /* cart가 존재한다면 */
            return true;
        } else {
            /* cart가 존재하지 않는다면 장바구니에 저장 */
            cartService.save(member_id, lecture_id);
            return false;
        }
    }
  • lectureId에 대한 장바구니가 존재하는지 CartService의 checkCart 메소드를 통해 확인
  • 장바구니가 존재하지 않는다면 CartService의 save 메소드를 호출하여 장바구니 저장

CartService

장바구니에 강의가 존재하는지 확인, 장바구니에 저장

    /** member_id, lecture_id에 해당하는 cart가 존재하는지 확인 - 유저가 특정 강의를 장바구니에 넣었는지 확인 **/
    @Override
    public boolean checkCart(Long member_id, Long lecture_id) {

        return cartRepository.existsByMember_IdAndLecture_Id(member_id, lecture_id);
    }
  • cartRepository의 existsByMember_IdAndLecture_Id 쿼리 메소드를 호출하여 존재 여부 확인
    /** 장바구니 저장 **/
    @Override
    public void save(Long member_id, Long lecture_id) {
        Member member = memberRepository.findById(member_id).orElseThrow(() ->
                new IllegalArgumentException("해당 회원이 존재하지 않습니다."));
        Lecture lecture = lectureRepository.findById(lecture_id).orElseThrow(() ->
                new IllegalArgumentException("해당 강의가 존재하지 않습니다."));

        /* DB에 cart 엔티티 저장  */
        cartRepository.save(Cart.builder().member(member).lecture(lecture).build());
    }

CartRepository

유저가 특정 강의를 장바구니에 추가했는지 확인

    /** member_id, lecture_id에 해당하는 cart 엔티티 존재 여부 반환 - 유저가 특정 강의를 장바구니에 추가했는지 확인 **/
    boolean existsByMember_IdAndLecture_Id(Long member_id, Long lecture_id);

MemberWishLectureController

현재 로그인한 유저가 특정 강의를 찜했는지 확인하여 해당 결괏값을 반환하는 컨트롤러

  • 찜한 강의라면 true 반환
  • 찜한 강의가 아니라면 false 반환
    @PostMapping("/{lecture_id}")
    public boolean save(@PathVariable Long lecture_id,
                        @AuthenticationPrincipal UserAdapter user){

        Long member_id = user.getMemberDto().getId();

        if(memberWishLectureService.checkWish(member_id, lecture_id)){
            /* 해당 강의를 찜했다면 찜 목록에서 삭제 */
            memberWishLectureService.deleteById(member_id, lecture_id);
            return true;
        } else {
            /* 해당 강의를 찜하지 않았다면 찜 목록에 강의 추가 */
            memberWishLectureService.save(member_id, lecture_id);
            return false;
        }
    }

MemberWishLectureService

해당 강의를 찜했는지 확인

  • 찜한 강의라면 찜한 강의 목록에서 삭제
  • 찜한 강의가 아니라면 찜한 강의 목록에 추가
  • 찜 확인
    /** member_id가 lecture_id를 찜 리스트에 추가했는지 확인 - 유저가 특정 강의를 찜했는지 확인 **/
    @Override
    public boolean checkWish(Long member_id, Long lecture_id) {

        return memberWishLectureRepository.existsByMember_IdAndLecture_Id(member_id, lecture_id);
    }
  • 찜 목록에 강의 추가
    /** 찜 목록에 강의 추가 **/
    @Override
    public void save(Long member_id, Long lecture_id) {

        Member member = memberRepository.findById(member_id).orElseThrow(() ->
                new IllegalArgumentException("해당 사용자가 존재하지 않습니다."));
        Lecture lecture = lectureRepository.findById(lecture_id).orElseThrow(() ->
                new IllegalArgumentException("해당 강의가 존재하지 않습니다."));

        memberWishLectureRepository.save(MemberWishLecture.builder().member(member).lecture(lecture).build());
    }
  • 특정 유저의 찜 목록에서 특정 강의 삭제
    /** 강의 상세 페이지에서 member_id, lecture_id에 해당하는 찜 삭제 - 유저가 특정 강의 찜 취소 **/
    @Override
    public void deleteById(Long member_id, Long lecture_id) {
        memberWishLectureRepository.deleteByMember_IdAndLecture_Id(member_id, lecture_id);
    }

MemberWishLectureRepository

    /** member_id, lecture_id에 해당하는 wish 엔티티 존재 여부 반환 - 유저가 특정 강의를 찜 목록에 추가했는지 확인 **/
    boolean existsByMember_IdAndLecture_Id(Long member_id, Long lecture_id);

    /** member_id, lecture_id에 해당하는 찜 엔티티 삭제 - 유저가 특정 강의 삭제 **/
    void deleteByMember_IdAndLecture_Id(Long member_id, Long lecture_id);

0개의 댓글