내가 처음에 생각했던 별점기능은 진짜 별거없이 금방 끝낼것 같았는데
검색해보니 좀 복잡해보인다.
깊게 생각 안해서 일어난 일인듯...
내가 생각했던 방식은
- float으로 게시물에 대한(정확히 말하자면 판매자의 별점) 별점 등록하기 (애초에 이거부터가 글렀음)
- 값을 평균내서 판매자 별점에 반영하기
이거 였는데 지금 생각해보면 되겠나 싶다.
front에서 생각해보면 평점을 등록할 때 별 몇개를 준다거나 그런식으로 점수를 부여할텐데
단순히 소수점 한자리까지만 표현하자는 생각으로 float을 사용하게 됨
- 별점은 1에서 5까지 소수점이 없는 정수로 선택
- 그 값을 평균낼땐 float 형태가 되어야함
- member와 별점을 어떻게 연관지을지 생각도 해야하고..
@Schema(description = "리뷰를 작성할 때 입력한 정보를 전달하는 객체")
data class CreateReviewRequest(
@field:Size(min = 1, max = 300, message = "내용은 1자 이상 300자 이하로 작성해주세요.")
@field:NotBlank(message = "내용을 입력해주세요.")
val content: String,
@field:Min(value = 1, message = "별점은 1에서 5까지만 입력할 수 있습니다.")
@field:Max(value = 5, message = "message = 별점은 1에서 5까지만 입력할 수 있습니다.")
val rating: Int,
val sellerRating: Int = rating
)
일단 @field를 사용해 별점에 대한 범위를 정했다.
평균을 내는 방법은 SQL함수 AVG를 사용해 리뷰가 업데이트 될 때마다 평균값을 업데이트 하는 방식으로 작성했다.
@Query ("SELECT AVG(r.rating) FROM Review r WHERE r.member.id = :memberId")
fun getAverageRatingByMember(memberId: Int): Double
이제 그 이후에 가장 중요한 문제인 서비스쪽인데..
override fun createReview(
postId: Int,
request: CreateReviewRequest,
principal: UserPrincipal
): MessageResponse {
val post = postRepository.findByIdOrNull(postId)
?: throw ModelNotFoundException("Post", postId)
val member = memberRepository.findByIdOrNull(principal.id)
?: throw ModelNotFoundException("Member", principal.id)
val seller = post.member
if (!post.isSoldOut) {
throw IllegalStateException("판매되지 않은 물품에 리뷰를 작성할 수 없습니다.")
}
// order.memberId == review.memberId 일 경우에 작성가능한 메서드 추가
post.myPostCheckPermission(principal)
val sellerReview = Review.makeEntity(
request = request.copy(sellerRating = request.rating),
post = post,
member = seller
)
reviewRepository.save(sellerReview)
val averageRating = reviewRepository.getAverageRatingByMember(seller.id!!)
seller.sellerRating = averageRating
memberRepository.save(seller)
return MessageResponse("리뷰가 작성되었습니다.")
}
팩터링은 나중에 하고, 평균값을 조회할 수 있게 구현 먼저 해보려고 코드를 작성했는데.....
이 코드에서 발생하는 문제, 아직 더 추가해야하는 문제
- 일단 평점은 정상적으로 계산되어 업데이트 된다.... 다만
1. review에 memberId가 seller의 id로 생성이 되어 userprincipal에 의해 리뷰 작성자가 수정 및 삭제를 할 수 없게된다.
2. 한 판매글에 리뷰를 중복으로 작성할 수 없게 예외처리 추가해야한다.
3. order.memberId와 review.memberId가 같아야 작성할 수 있다.
리뷰가 seller의 id로 작성되지 않고, 평점도 정상적으로 계산되게 할 방법이 없을까......
'내일배움캠프 프로젝트' 카테고리의 다른 글
BuySell - 선착순 쿠폰발급 (0) | 2024.03.20 |
---|---|
Buysell - 별점기능 구현(2) (0) | 2024.03.20 |
최종프로젝트 (BuySell) 중고거래 플랫폼 서비스 (0) | 2024.03.07 |
백오피스 프로젝트 (1) | 2024.02.13 |
뉴스피드 프로젝트 마무리 (1) | 2024.01.30 |