diff --git a/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java b/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java index 7cde69b..57f36f4 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java @@ -3,6 +3,8 @@ import com.example.betteriter.fo_domain.review.domain.Review; import com.example.betteriter.fo_domain.user.domain.User; import com.example.betteriter.global.constant.Category; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -16,6 +18,10 @@ public interface ReviewRepository extends JpaRepository { List findFirst7ByWriterInOrderByCreatedAtDesc(List writers); // sum(count (r.reviewLiked),count(r.reviewScraped)) - @Query("select r from REVIEW r") - List findReviewHavingMostScrapedAndLiked(); + @EntityGraph(attributePaths = {"reviewScraped", "reviewLiked"}) + @Query("select r from REVIEW r " + + "left join r.reviewScraped rs " + + "left join r.reviewLiked rl group by r " + + "ORDER BY COALESCE(SUM(rs.id), 0) + COALESCE(SUM(rl.id), 0) DESC") + List findTop7ReviewHavingMostScrapedAndLiked(Pageable pageable); } diff --git a/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java b/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java index dcc9f11..e6378ea 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java @@ -14,6 +14,7 @@ import com.example.betteriter.global.constant.Category; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,8 +45,7 @@ public Long createReview(CreateReviewRequestDto request) { /* 유저가 관심 등록한 카테고리 리뷰 리스트 조회 메소드 */ public Map> getUserCategoryReviews() { - User user = this.getCurrentUser(); - List categories = user.getCategories(); // 유저가 등록한 관심 카테고리 + List categories = this.getCurrentUser().getCategories(); // 유저가 등록한 관심 카테고리 Map> result = new LinkedHashMap<>(); // 카테고리에 해당하는 최신 순 리뷰 for (Category category : categories) { @@ -71,7 +71,8 @@ public List getFollowingReviews() { /* 가장 많은 스크랩 + 좋아요 수를 가지는 리뷰 가져오는 리스트 */ public List getMostScrapedAndLikedReviews() { - return this.reviewRepository.findReviewHavingMostScrapedAndLiked().stream() + return this.reviewRepository.findTop7ReviewHavingMostScrapedAndLiked(PageRequest.of(0, 7)) + .stream() .map(review -> review.of(this.getFirstImageWithReview(review))) .collect(Collectors.toList()); } diff --git a/src/main/java/com/example/betteriter/fo_domain/user/controller/AuthController.java b/src/main/java/com/example/betteriter/fo_domain/user/controller/AuthController.java index 9fd6eb7..e3e61c8 100644 --- a/src/main/java/com/example/betteriter/fo_domain/user/controller/AuthController.java +++ b/src/main/java/com/example/betteriter/fo_domain/user/controller/AuthController.java @@ -143,7 +143,7 @@ public ResponseDto checkNickname( private void checkRequestValidation(BindingResult bindingResult) { if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldErrors().get(0); - log.debug("fieldError occurs : {}", fieldError.getDefaultMessage()); + log.error("fieldError occurs : {}", fieldError.getDefaultMessage()); throw new UserHandler(_METHOD_ARGUMENT_ERROR); } } diff --git a/src/main/java/com/example/betteriter/fo_domain/user/domain/User.java b/src/main/java/com/example/betteriter/fo_domain/user/domain/User.java index 8cb0ec9..84ad076 100644 --- a/src/main/java/com/example/betteriter/fo_domain/user/domain/User.java +++ b/src/main/java/com/example/betteriter/fo_domain/user/domain/User.java @@ -51,10 +51,10 @@ public class User extends BaseEntity implements UserDetails { @Enumerated(EnumType.STRING) private List categories; - @OneToMany(mappedBy = "followee") + @OneToMany(mappedBy = "follower") private List following; // 회원이 팔로잉 하는 유저 리스트 - @OneToMany(mappedBy = "follower") + @OneToMany(mappedBy = "followee") private List follower; // 회원을 팔로잉 하는 유저 리스트 @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) diff --git a/src/main/java/com/example/betteriter/fo_domain/user/service/AuthService.java b/src/main/java/com/example/betteriter/fo_domain/user/service/AuthService.java index d3f502f..c2aba6b 100644 --- a/src/main/java/com/example/betteriter/fo_domain/user/service/AuthService.java +++ b/src/main/java/com/example/betteriter/fo_domain/user/service/AuthService.java @@ -68,6 +68,7 @@ private Long processJoin(JoinDto joinDto, String encryptPassword) { @Transactional public UserServiceTokenResponseDto login(LoginDto loginRequestDto) { User user = this.loadUserByUsername(loginRequestDto.getEmail()); + this.checkUserLoginType(user); this.checkPassword(loginRequestDto, user); return this.saveAuthenticationAndReturnServiceToken(user); } @@ -188,4 +189,12 @@ private UserServiceTokenResponseDto saveAuthenticationAndReturnServiceToken(User serviceToken.getRefreshToken(), jwtProperties.getRefreshExpiration()); // 토큰 발급 후 Redis 에 Refresh token 저장 return serviceToken; } + + // 로그인 시도 회원이 카카오 로그인 회원인지 여부 판단 + private void checkUserLoginType(User user) { + if (user.getOauthId() != null) { + throw new UserHandler(_AUTH_SHOULD_BE_KAKAO); + } + } + } diff --git a/src/main/java/com/example/betteriter/global/error/exception/ErrorCode.java b/src/main/java/com/example/betteriter/global/error/exception/ErrorCode.java index a182eb0..0ca2bb6 100644 --- a/src/main/java/com/example/betteriter/global/error/exception/ErrorCode.java +++ b/src/main/java/com/example/betteriter/global/error/exception/ErrorCode.java @@ -33,25 +33,26 @@ public enum ErrorCode { // Success _OK(HttpStatus.OK, "SUCCESS_200", "OK"), - // Common Error + // Common Error & Global Error _BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON_400", "잘못된 요청입니다."), - _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON_401", "인증 과정에서 오류가 발생했습니다."), + _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "AUTH_401", "인증 과정에서 오류가 발생했습니다."), _FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON_403", "금지된 요청입니다."), _METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "COMMON_405", "지원하지 않는 Http Method 입니다."), _INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON_500", "서버 에러가 발생했습니다."), - _METHOD_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, "COMMON_400", "올바르지 않은 클라이언트 요청값입니다."), // controller 에서 받은 요청 DTO 유효성 검증 + + _METHOD_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, "METHOD_ARGUMENT_ERROR", "올바르지 않은 클라이언트 요청값입니다."), // controller 에서 받은 요청 DTO 유효성 검증 // Example (For Test) - TEST_BAD_REQUEST(HttpStatus.BAD_REQUEST, "TEST_400", "잘못된 요청입니다. (For Test)"), - - // User Error - _USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER_400", "일치하는 회원 정보를 찾을 수 없습니다."), - _PASSWORD_NOT_MATCH(HttpStatus.UNAUTHORIZED, "USER_401", "비밀번호가 일치하지 않습니다."), - _EMAIL_DUPLICATION(HttpStatus.BAD_REQUEST, "USER_400", "이미 존재하는 이메일입니다."), - _AUTH_CODE_ALREADY_EXIT(HttpStatus.BAD_REQUEST, "USER_400", "이미 인증 코드가 존재합니다."), - _AUTH_CODE_NOT_EXIST(HttpStatus.BAD_REQUEST, "USER_400", "인증 코드가 존재하지 않습니다."), - _AUTH_CODE_NOT_MATCH(HttpStatus.BAD_REQUEST, "USER_400", "인증 코드가 일치하지 않습니다."), - _AUTH_SHOULD_BE_KAKAO(HttpStatus.BAD_REQUEST, "USER_400", "해당 회원은 카카오 로그인 회원입니다."), + TEST_BAD_REQUEST(HttpStatus.BAD_REQUEST, "TEST_400", "잘못된 요청 입니다. (For Test)"), + + // User & Auth Error + _USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER_NOT_FOUND_400", "일치하는 회원 정보를 찾을 수 없습니다."), + _PASSWORD_NOT_MATCH(HttpStatus.UNAUTHORIZED, "AUTH_PASSWORD_NOT_MATCH_401", "비밀번호가 일치하지 않습니다."), + _EMAIL_DUPLICATION(HttpStatus.BAD_REQUEST, "AUTH_EMAIL_DUPLICATION_401", "이미 존재하는 이메일입니다."), + _AUTH_CODE_ALREADY_EXIT(HttpStatus.BAD_REQUEST, "AUTH_CODE_ALREADY_EXIST_401", "이미 인증 코드가 존재합니다."), + _AUTH_CODE_NOT_EXIST(HttpStatus.BAD_REQUEST, "AUTH_CODE_NOT_EXIST_401", "인증 코드가 존재하지 않습니다."), + _AUTH_CODE_NOT_MATCH(HttpStatus.BAD_REQUEST, "AUTH_CODE_NOT_MATCH_401", "인증 코드가 일치하지 않습니다."), + _AUTH_SHOULD_BE_KAKAO(HttpStatus.BAD_REQUEST, "AUTH_SHOULD_BE_KAKAO_401", "해당 회원은 카카오 로그인 회원입니다."), // News