Skip to content

Commit

Permalink
Merge pull request EveryUniv#39 from kjungw1025/dev_deploy
Browse files Browse the repository at this point in the history
feat: With-dankook 게시판들에 대한 리뷰 기능 작업
  • Loading branch information
gutanbug authored Jan 2, 2024
2 parents 83d97b9 + 71e3971 commit 7d45367
Show file tree
Hide file tree
Showing 28 changed files with 771 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.dku.council.domain.review.controller;

import com.dku.council.domain.post.model.dto.response.ResponsePage;
import com.dku.council.domain.review.exception.AlreadyWrittenReviewException;
import com.dku.council.domain.review.exception.InvalidCreateReviewToMyselfException;
import com.dku.council.domain.review.model.dto.request.RequestCreateReviewDto;
import com.dku.council.domain.review.model.dto.response.ResponseReviewPositiveCountDto;
import com.dku.council.domain.review.service.ReviewService;
import com.dku.council.domain.with_dankook.exception.InvalidStatusException;
import com.dku.council.domain.with_dankook.exception.WithDankookUserNotFoundException;
import com.dku.council.domain.with_dankook.model.entity.WithDankook;
import com.dku.council.domain.with_dankook.service.WithDankookService;
import com.dku.council.domain.with_dankook.service.WithDankookUserService;
import com.dku.council.global.auth.jwt.AppAuthentication;
import com.dku.council.global.auth.role.UserAuth;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Map;

@Tag(name = "리뷰", description = "with-dankook 게시판들에 대한 리뷰 작성/조회 API")
@RestController
@RequestMapping("with-dankook/review")
@RequiredArgsConstructor
public class ReviewController {
private final ReviewService reviewService;
private final WithDankookUserService withDankookUserService;
private final WithDankookService<WithDankook> withDankookService;

/**
* 모집이 완료된 with-dankook 게시판들에 대한 리뷰 작성
*
* @param dto 작성한 리뷰 내용 dto
*
* <p>
* Request Body에 포함되는 reviewList는 아래 링크를 참고해주세요.</br>
* https://www.notion.so/With-dankook-Review-a8c6b5bb322b417098fcfff50406473f
* </p>
*/
@PostMapping
@UserAuth
public void create(AppAuthentication auth,
@Valid @RequestBody RequestCreateReviewDto dto) {
reviewService.create(auth.getUserId(), dto);
}

/**
* with-dankook 타입에 해당하는 리뷰 Top3 조회
*
* @param withDankookType 조회하고자 하는 with-dankook 타입을 영어로 입력
* <p>
* <b>withDankookType Parameter 입력시 참고해주세요.</b></br>
* 단혼밥 : EatingAlong</br>
* 단터디 : Study</br>
* 단국 거래 : Trade</br>
* 베어이츠 : BearEats</br>
* 구해줘 룸메 : Dormitory</br>
* </p>
*
* @return 페이징된 with-dankook 타입에 해당하는 리뷰 Top3 조회
*/
@GetMapping("/rank")
@UserAuth
public ResponsePage<ResponseReviewPositiveCountDto> listTop3Review(AppAuthentication auth,
@Valid @RequestParam String withDankookType) {
Page<ResponseReviewPositiveCountDto> list = reviewService.rank(withDankookType, Pageable.ofSize(3));
return new ResponsePage<>(list);
}

/**
* With-Dankook 타입 별, 특정 사용자가 받은 모든 '추천해요!' 리뷰 내역 상세 조회
*
* @param withDankookType 조회하고자 하는 with-dankook 타입을 영어로 입력
* <p>
* <b>withDankookType Parameter 입력시 참고해주세요.</b></br>
* 단혼밥 : EatingAlong</br>
* 단터디 : Study</br>
* 단국 거래 : Trade</br>
* 베어이츠 : BearEats</br>
* 구해줘 룸메 : Dormitory</br>
* </p>
*
* @return '추천해요!'를 받은 개수, 리뷰 내역
*/
@GetMapping("/received/positive")
@UserAuth
public Map<String, Integer> AllReceivedPositiveReview(AppAuthentication auth,
@Valid @RequestParam String withDankookType) {
return reviewService.findAllUserPositiveReviewDetail(withDankookType, auth.getUserId());
}

/**
* With-Dankook 타입 별, 특정 사용자가 받은 모든 '아쉬워요!' 리뷰 내역 상세 조회
*
* @param withDankookType 조회하고자 하는 with-dankook 타입을 영어로 입력
* <p>
* <b>withDankookType Parameter 입력시 참고해주세요.</b></br>
* 단혼밥 : EatingAlong</br>
* 단터디 : Study</br>
* 단국 거래 : Trade</br>
* 베어이츠 : BearEats</br>
* 구해줘 룸메 : Dormitory</br>
* </p>
*
* @return '아쉬워요!'를 받은 개수, 리뷰 내역
*/
@GetMapping("/received/negative")
@UserAuth
public Map<String, Integer> AllReceivedNegativeReview(AppAuthentication auth,
@Valid @RequestParam String withDankookType) {
return reviewService.findAllUserNegativeReviewDetail(withDankookType, auth.getUserId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.review.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class AlreadyWrittenReviewException extends LocalizedMessageException {
public AlreadyWrittenReviewException() {
super(HttpStatus.BAD_REQUEST, "already.written-review");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.dku.council.domain.review.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidCreateReviewToMyselfException extends LocalizedMessageException {
public InvalidCreateReviewToMyselfException() { super(HttpStatus.BAD_REQUEST, "invalid.create-review-to-myself"); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.dku.council.domain.review.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class ReviewNotFoundException extends LocalizedMessageException {
public ReviewNotFoundException() { super(HttpStatus.NOT_FOUND, "notfound.review"); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.dku.council.domain.review.model.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

@Getter
public class RequestCreateReviewDto {
@NotNull
@Schema(description = "게시글 id", example = "5")
private final Long withDankookId;

@NotNull
@Schema(description = "리뷰를 받는 유저 id", example = "35")
private final Long targetUserId;

@Schema(description = "추천해요! = true / 아쉬워요! = false", example = "true")
private final Boolean isPositive;

@Schema(description = "리뷰내용 번호 리스트", example = "[1, 3, 4]")
private final List<Integer> reviewList;

public RequestCreateReviewDto(@NotNull Long withDankookId,
@NotNull Long targetUserId,
Boolean isPositive,
@NotBlank List<Integer> reviewList) {
this.withDankookId = withDankookId;
this.targetUserId = targetUserId;
this.isPositive = isPositive;
this.reviewList = reviewList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.dku.council.domain.review.model.dto.response;

import com.dku.council.domain.review.model.entity.Review;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Getter
public class ResponseReviewPositiveCountDto {
@Schema(description = "유저 닉네임", example="Leonardo DiCaprio")
private final String userName;

@Schema(description = "추천해요 개수", example="100")
private final int positiveCount;

public ResponseReviewPositiveCountDto(Review review) {
this.userName = review.getUser().getNickname();
this.positiveCount = review.getPositiveCount();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.dku.council.domain.review.model.entity;

import com.dku.council.domain.user.model.entity.User;
import com.dku.council.domain.with_dankook.model.entity.WithDankook;
import com.dku.council.domain.with_dankook.model.entity.WithDankookUser;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Review {
@Id
@GeneratedValue
@Column(name = "review_id")
private Long id;

@NotBlank
private String withDankookType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@NotNull
private int positiveCount;

@NotNull
private int negativeCount;

@Builder
private Review(String withDankookType,
User user) {
this.withDankookType = withDankookType;
this.user = user;
this.positiveCount = 0;
this.negativeCount = 0;
}

public void addPositiveCount(int value) {
this.positiveCount += value;
}

public void addNegativeCount(int value) {
this.negativeCount += value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.dku.council.domain.review.model.entity;

import com.dku.council.domain.with_dankook.model.entity.WithDankook;
import com.dku.council.domain.with_dankook.model.entity.WithDankookUser;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ReviewComment {
@Id
@GeneratedValue
@Column(name = "review_comment_id")
private Long id;

@NotBlank
private String withDankookType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "with_dankook_user_id")
private WithDankookUser withDankookUser;

@NotNull
private Long writerUserId;

@NotNull
private int reviewNumber;

private boolean isPositive;

@Builder
private ReviewComment(String withDankookType,
WithDankookUser withDankookUser,
Long writerUserId,
int reviewNumber,
boolean isPositive) {
this.withDankookType = withDankookType;
this.withDankookUser = withDankookUser;
this.writerUserId = writerUserId;
this.reviewNumber = reviewNumber;
this.isPositive = isPositive;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.dku.council.domain.review.repository;

import com.dku.council.domain.review.model.entity.ReviewComment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

public interface ReviewCommentRepository extends JpaRepository<ReviewComment, Long> {

@Query(value = "select group_concat(r.review_number) from review_comment r " +
"join with_dankook_user w " +
"on w.with_dankook_user_id = r.with_dankook_user_id " +
"where r.with_dankook_type = :withDankookType and " +
"r.is_positive = true and " +
"w.participant_id = :userId ", nativeQuery = true)
Optional<String> findAllPositiveReviewNumber(String withDankookType, Long userId);

@Query(value = "select group_concat(r.review_number) from review_comment r " +
"join with_dankook_user w " +
"on w.with_dankook_user_id = r.with_dankook_user_id " +
"where r.with_dankook_type = :withDankookType and " +
"r.is_positive = false and " +
"w.participant_id = :userId ", nativeQuery = true)
Optional<String> findAllNegativeReviewNumber(String withDankookType, Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.dku.council.domain.review.repository;

import com.dku.council.domain.review.model.entity.Review;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface ReviewRepository extends JpaRepository<Review, Long> {

@Query("select r from Review r " +
"where r.user.id = :userId and r.withDankookType = :withDankookType ")
List<Review> findByUserId(String withDankookType, Long userId);

@Query("select r.positiveCount from Review r " +
"where r.user.id = :userId and r.withDankookType = :withDankookType ")
int findPositiveCount(String withDankookType, Long userId);

@Query("select r.negativeCount from Review r " +
"where r.user.id = :userId and r.withDankookType = :withDankookType ")
int findNegativeCount(String withDankookType, Long userId);

@Query("select r from Review r " +
"where r.withDankookType = :withDankookType " +
"order by r.positiveCount desc")
Page<Review> findPositiveUserRank(@Param("withDankookType") String withDankookType, Pageable pageable);

}
Loading

0 comments on commit 7d45367

Please sign in to comment.