강의를 구매하지 않은 회원만
찜하기/장바구니에 추가기능을 사용할 수 있다.
강의 구매 후 수강할 수 있는 권한을 획득할 수 있다.
강의를 상세 조회할 때 관여하는 컨트롤러
    /** 강의 상세 조회 **/
    /* /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에 담는다
현재 로그인한 유저가 구매한 강의인지 확인
/** 현재 로그인한 유저가 구매한 강의인지 확인 **/
@Override
public boolean myLectureCheck(Long member_id, Long lecture_id) {
	return myLectureRepository.existsByMember_IdAndLecture_Id(member_id, lecture_id);
}
유저가 특정 강의를 수강하고 있는지 확인
   /** 유저가 특정 강의를 수강하고 있는지 확인 **/
    boolean existsByMember_IdAndLecture_Id(Long member_id, Long lecture_id);
강의 상세 페이지
<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}">
<span sec:authorize="isAuthenticated()">
th:if="${lectureCheck}">
위시 리스트/장바구니에 추가 버튼을 눌렀을 때 실행되는 함수
<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 통신'/rest/wish/' + lectureId 컨트롤러로 post 방식으로 aja통신
'/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 메소드를 통해 확인장바구니에 강의가 존재하는지 확인, 장바구니에 저장
    /** member_id, lecture_id에 해당하는 cart가 존재하는지 확인 - 유저가 특정 강의를 장바구니에 넣었는지 확인 **/
    @Override
    public boolean checkCart(Long member_id, Long lecture_id) {
        return cartRepository.existsByMember_IdAndLecture_Id(member_id, lecture_id);
    }
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());
    }
유저가 특정 강의를 장바구니에 추가했는지 확인
    /** member_id, lecture_id에 해당하는 cart 엔티티 존재 여부 반환 - 유저가 특정 강의를 장바구니에 추가했는지 확인 **/
    boolean existsByMember_IdAndLecture_Id(Long member_id, Long lecture_id);
현재 로그인한 유저가 특정 강의를 찜했는지 확인하여 해당 결괏값을 반환하는 컨트롤러
- 찜한 강의라면 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;
        }
    }
해당 강의를 찜했는지 확인
- 찜한 강의라면 찜한 강의 목록에서 삭제
 - 찜한 강의가 아니라면 찜한 강의 목록에 추가
 
    /** 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);
    }
    /** 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);