쇼핑몰 웹사이트 만들어보기 - 회원 등급

Shiba·2024년 8월 20일
0

프로젝트 및 일기

목록 보기
19/29

회원등급을 구현해보자.

현재 users에 만들어둔 role이라는 열을 이용해서 레벨을 구현하려고 한다. 하지만, 문제가 있다고 생각했다.

등급에 따라 상품의 가격을 깎아주는 형태가 아닌 등급마다 받을 수 있는 쿠폰이 있으며, 이를 발급받아 사용할 수 있도록 한다.


문제점?
가장 처음 생각한 방법은 이를 컨트롤러 부분에서 등급을 비교하여 응답을 보내는 것이다. 하지만 이 방법을 사용하면 등급이 많으면 많을수록 복붙코드가 많아진다(같은 로직이지만 등급마다 하나의 함수를 매핑시켜주어야함)

즉, 컨트롤러에서 하나하나 비교해주는 것이 아니라 하나의 함수를 두고, 그 함수가 돌아가면 자동적으로 자신의 등급에 맞는 쿠폰을 받을 수 있도록 하고싶다. 그렇게 설계하여야 나중에 수정이 필요할 때 훨씬 편할 것이다.

생각해본 방법

쿠폰에도 등급을 저장해둘 수 있는 열을 추가해서 해당 등급을 통해서 쿠폰리스트를 만들 수 있도록한다면 등급에 맞는 쿠폰들을 가져올 수 있을 것 같다!

쿠폰에 등급을 추가해야되는게 약간 아쉽긴한데 내가 생각한 방법중에는 최선인 것 같다..


쿠폰에 정수형으로 level열을 추가했다. 정수형으로 추가한 이유는 메모리를 최대한 적게쓰기 위해서이며, user의 role을 정수형으로 변형하여 사용할 수 있기 때문이다. 엔티티에도 마찬가지로 정수형으로 level을 추가해주자

그 후에는 level을 enum으로 선언하여 하나의 타입으로 사용할 수 있도록 코드를 작성해주자

Level

package com.shoppingmall.dto;

public enum Level {
    BASIC(1), NORMAL(2), VIP(3), VVIP(4), admin(999); // enum 오브젝트 정의

    private final int value;

    Level(int value) { // 생성자 만들기
        this.value = value;
    }

    public int getValue() { // 값을 가져오는 메소드
        return value;
    }

    // 문자열을 받아 해당하는 enum을 반환하는 메서드
    public static Level fromString(String status) {
        for (Level s : Level.values()) {
            if (s.name().equalsIgnoreCase(status)) {
                return s;
            }
        }
        throw new IllegalArgumentException("Unknown status: " + status);
    }

    // 문자열을 받아 정수값을 반환하는 메서드
    public static int toInt(String level) {
        return fromString(level).getValue();
    }
}

이제 level을 통해 쿠폰을 찾을 수 있도록 하는 함수를 작성하자. 이전에 작성한 코드에서 sql문만 바꾸면 만들 수 있다

CouponRepository

public List<Coupon> findByLevel(int level){
   TypedQuery<Coupon> query = em.createQuery("SELECT u FROM Coupon u WHERE u.level = :level", Coupon.class);
    query.setParameter("level", level);
    return query.getResultList();
}

리포지토리에 추가한 함수를 서비스를 통해 제공할 수 있도록 하자

CouponService

public List<Coupon> findCouponByLevel(int level) { return couponRepository.findByLevel(level); }

마지막으로 컨트롤러를 통해 해당 함수를 이용하여 사용자가 원하는 동작을 할 수 있도록 하자
이전에 만들어둔 event 쿠폰 발급 코드를 수정했다.

@GetMapping("/event")
    public String eventCouponPage(@AuthenticationPrincipal UserDetails userDetails, Model model){
        Users users = userService.findById(userDetails.getUsername());
        int level = Level.toInt(users.getRole());
        List<Coupon> coupons = couponService.findCouponByLevel(level);
        model.addAttribute("coupons", coupons);
        model.addAttribute("level", users.getRole());
        return "/event";
    }

또한 model에 level을 추가해서 level을 html에 표시할 수 있도록 하여 테스트 결과가 확실한지 확인해보기로 했다

테스트 결과

실험용 데이터베이스

BASIC 등급으로 로그인 시,

VIP 등급으로 로그인 시,

성공적으로 작동했음을 확인할 수 있다. 아쉬운 점이라면 리스트를 percent를 기준으로 오름차순 정렬을 해두는 것이 미관상 더 좋아보일 것 같다. (물론 사용자의 쿠폰함이 기준이라면 유효기간을 기준으로 정렬하는 것이 나을 수도 있다)

아무튼 회원등급을 추가해서 해당 등급에 맞는 쿠폰을 발급 받을 수 있도록 했다. 점점 기능들이 쉽고 빠르게 추가되는 것 같다. 스프링에 익숙해지니 스프링이 얼마나 편한 것인지 몸소 체감을 하고있는 것 같다.

다음 시간에는 리뷰기능을 추가해보자! 물건을 구매했다면 리뷰를 남길 수 있도록하고, 이를 다른 사용자가 볼 수 있도록 만들어보자.

profile
모르는 것 정리하기

0개의 댓글