diff --git a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepository.java b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepository.java index 4391807..870bf1a 100644 --- a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepository.java +++ b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepository.java @@ -17,5 +17,7 @@ public interface BoardQueryDslRepository { // UserProfileRes findByUserId(Long userId); - UserProfileRes findBoardListByUser(User user, Long currentUserId); + UserProfileRes findBoardListByUser(User user, Long currentUserId, int pageSize, int offset); + + boolean isBoardLikedByUser(Long id, Long id1); } diff --git a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepositoryImpl.java b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepositoryImpl.java index ab37968..0af75f4 100644 --- a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepositoryImpl.java +++ b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardQueryDslRepositoryImpl.java @@ -130,7 +130,7 @@ public Tuple findMostLikedBoardCountAndTitleWithUserAndTheme(User user, Theme th // } @Override - public UserProfileRes findBoardListByUser(User user, Long currentUserId) { + public UserProfileRes findBoardListByUser(User user, Long currentUserId, int pageSize, int offset) { List likedBoardIds = new ArrayList<>(); @@ -159,10 +159,12 @@ public UserProfileRes findBoardListByUser(User user, Long currentUserId) { .from(board) .leftJoin(boardLike) .on(board.id.eq(boardLike.board.id)) - .where(board.user.id.eq(user.getId())) + .where(board.user.id.eq(user.getId()), + board.isPublished.eq(true)) .groupBy(board.id, board.title, board.content) .orderBy(board.createdDate.desc()) - .limit(3) + .offset(offset) + .limit(pageSize) .fetch(); return new UserProfileRes( @@ -172,4 +174,22 @@ public UserProfileRes findBoardListByUser(User user, Long currentUserId) { boardListResList ); } + + @Override + public boolean isBoardLikedByUser(Long boardId, Long userId) { + if (userId == null) { + return false; + } + Integer count = queryFactory + .selectOne() + .from(boardLike) + .where( + boardLike.board.id.eq(boardId), + boardLike.user.id.eq(userId), + boardLike.status.eq(Status.ACTIVE) + ) + .fetchFirst(); + + return count != null; + } } diff --git a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardRepository.java b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardRepository.java index 89bfe9f..8401591 100644 --- a/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardRepository.java +++ b/src/main/java/depth/mvp/ns/domain/board/domain/repository/BoardRepository.java @@ -67,6 +67,10 @@ List findListByUserAndIsPublishedAndBoardFieldsContaining( List findByUser(User user); + @Query("SELECT COUNT(bl) > 0 FROM BoardLike bl WHERE bl.board.id = :boardId AND bl.user.id = :userId") + boolean isBoardLikedByUser(@Param("boardId") Long boardId, @Param("userId") Long userId); + @Query("SELECT COUNT(b) FROM Board b WHERE b.user = :user AND b.isPublished = true") + int countByUser(User user); } diff --git a/src/main/java/depth/mvp/ns/domain/report/dto/response/PrevReportRes.java b/src/main/java/depth/mvp/ns/domain/report/dto/response/PrevReportRes.java index 06886f6..22a1cd3 100644 --- a/src/main/java/depth/mvp/ns/domain/report/dto/response/PrevReportRes.java +++ b/src/main/java/depth/mvp/ns/domain/report/dto/response/PrevReportRes.java @@ -30,7 +30,8 @@ public static record BestPost( Long bestSelectionCount, Long boardId, @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime boardCreatedAt + LocalDateTime boardCreatedAt, + boolean isLiked ) { } } diff --git a/src/main/java/depth/mvp/ns/domain/report/service/ReportService.java b/src/main/java/depth/mvp/ns/domain/report/service/ReportService.java index d93d460..83ceab3 100644 --- a/src/main/java/depth/mvp/ns/domain/report/service/ReportService.java +++ b/src/main/java/depth/mvp/ns/domain/report/service/ReportService.java @@ -23,6 +23,7 @@ import depth.mvp.ns.global.payload.ApiResponse; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.openkoreantext.processor.KoreanTokenJava; import org.openkoreantext.processor.OpenKoreanTextProcessorJava; import org.openkoreantext.processor.tokenizer.KoreanTokenizer; @@ -43,6 +44,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +@Slf4j @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -61,6 +63,15 @@ public class ReportService { public ResponseEntity findReport(CustomUserDetails customUserDetails, LocalDate parsedDate) { Optional optionalTheme = themeRepository.findByDate(parsedDate); + LocalDate today = LocalDate.now(); + + if (optionalTheme.isEmpty() && parsedDate.equals(today)) { + ApiResponse apiResponse = ApiResponse.builder() + .check(false) + .information("No theme found for the given date.") + .build(); + return ResponseEntity.ok(apiResponse); + } if (optionalTheme.isEmpty()) { ApiResponse apiResponse = ApiResponse.builder() @@ -71,11 +82,12 @@ public ResponseEntity findReport(CustomUserDetails customUserDetails, LocalDa } Theme theme = optionalTheme.get(); + log.info("Theme found: {}", theme.getContent()); Optional optionalReport = reportRepository.findByTheme(theme); - if (optionalReport.isEmpty()) { + if (optionalReport.isEmpty() && parsedDate.equals(today) ) { // 오늘자 레포트 조회 int writtenTotal = reportRepository.getBoardCount(theme); @@ -106,64 +118,86 @@ public ResponseEntity findReport(CustomUserDetails customUserDetails, LocalDa } else { // 과거 레포트 조회 - System.out.println("Report found for the theme: " + theme.getContent()); + Report report = null; + + if (optionalReport.isPresent()) { + log.info("Existing report found for theme: {}", theme.getContent()); + + report = optionalReport.get(); + // 나머지 로직 계속 진행... - Report report = optionalReport.get(); + } Board longestBoardByTheme = boardRepository.findLongestBoardByTheme(theme); User user = longestBoardByTheme.getUser(); - System.out.println("Longest board user: " + user.getNickname()); List allBestReportTypeByReport = reportDetailRepository.findAllBestReportTypeByReport(report); - System.out.println("Number of best report details found: " + allBestReportTypeByReport.size()); - for (int i = 0; i < allBestReportTypeByReport.size(); i++) { - System.out.println("allBestReportTypeByReport = " + allBestReportTypeByReport.get(i)); - } + log.info("Number of best report details found: {}", allBestReportTypeByReport.size()); + if (allBestReportTypeByReport.isEmpty()) { + log.warn("No best report details found for the given report."); + }else { + allBestReportTypeByReport.forEach(detail -> { + log.info("ReportDetail found: ReportType={}, UserId={}", detail.getReportType(), detail.getUser().getId()); + });} Long bestSelectedCountByUserId = customUserDetails != null ? reportDetailRepository.findBestSelectedCountByUserId(customUserDetails.getId()) - : null; + : 0; - System.out.println("Best selection count for user: " + bestSelectedCountByUserId); int writtenTotal = reportRepository.getBoardCount(theme); - System.out.println("Written total: " + writtenTotal); + log.info("Total written count: {}", writtenTotal); + List bestPosts = allBestReportTypeByReport.stream() .map(reportDetail -> { Tuple mostLikedBoardInfo = boardRepository.findMostLikedBoardCountAndTitleWithUserAndTheme(reportDetail.getUser(), theme); - System.out.println("Most liked board info: " + (mostLikedBoardInfo != null ? mostLikedBoardInfo.toString() : "None")); boolean isCurrentUser = customUserDetails != null && customUserDetails.getId().equals(reportDetail.getUser().getId()); + Long bestSelectedCountByUserId1 = reportDetailRepository.findBestSelectedCountByUserId(reportDetail.getUser().getId()); + + Long boardId = reportDetail.getBoard().getId(); // BEST로 선정된 게시글의 ID + boolean isLiked = customUserDetails != null && boardRepository.isBoardLikedByUser(boardId, customUserDetails.getId()); + + + + int likeCount = boardRepository.countLikesByBoardId(reportDetail.getBoard().getId()); + long likeCount2 = likeCount; + if (mostLikedBoardInfo == null) { + log.warn("No valid title found for user: {}", reportDetail.getUser().getNickname()); + return PrevReportRes.BestPost.builder() .isCurrentUser(isCurrentUser) .userId(reportDetail.getUser().getId()) .nickname(reportDetail.getUser().getNickname()) .imageUrl(reportDetail.getUser().getImageUrl()) .title("유효한 제목 없음.") - .likeCount(0L) + .likeCount(likeCount2) + .bestSelectionCount(bestSelectedCountByUserId1) + .boardCreatedAt(reportDetail.getBoard().getCreatedDate()) + .boardId(reportDetail.getBoard().getId()) + .isLiked(isLiked) .build(); } - Long likeCount = mostLikedBoardInfo.get(6, Long.class); + String title = mostLikedBoardInfo.get(1, String.class); LocalDateTime localDateTime = mostLikedBoardInfo.get(2, LocalDateTime.class); - Long boardId = mostLikedBoardInfo.get(3, Long.class); - System.out.println("Like count: " + likeCount); - System.out.println("Title: " + title); - System.out.println("Board created at: " + localDateTime); - System.out.println("Board ID: " + boardId); + + log.info("Best post found: title={}, likes={}, user={}", title, likeCount, reportDetail.getUser().getNickname()); + + return PrevReportRes.BestPost.builder() @@ -172,14 +206,19 @@ public ResponseEntity findReport(CustomUserDetails customUserDetails, LocalDa .nickname(reportDetail.getUser().getNickname()) .imageUrl(reportDetail.getUser().getImageUrl()) .title(title) - .likeCount(likeCount) - .bestSelectionCount(bestSelectedCountByUserId) + .likeCount(likeCount2) + .bestSelectionCount(bestSelectedCountByUserId1) .boardCreatedAt(reportDetail.getBoard().getCreatedDate()) .boardId(reportDetail.getBoard().getId()) + .isLiked(isLiked) .build(); + }) .collect(Collectors.toList()); + log.info("Total best posts found: {}", bestPosts.size()); + + return ResponseEntity.ok(PrevReportRes.builder() .selectedDate(parsedDate) .themeName(theme.getContent()) diff --git a/src/main/java/depth/mvp/ns/domain/report_detail/domain/repository/ReportDetailQueryDslRepositoryImpl.java b/src/main/java/depth/mvp/ns/domain/report_detail/domain/repository/ReportDetailQueryDslRepositoryImpl.java index ad2d393..d8e6f3d 100644 --- a/src/main/java/depth/mvp/ns/domain/report_detail/domain/repository/ReportDetailQueryDslRepositoryImpl.java +++ b/src/main/java/depth/mvp/ns/domain/report_detail/domain/repository/ReportDetailQueryDslRepositoryImpl.java @@ -1,5 +1,6 @@ package depth.mvp.ns.domain.report_detail.domain.repository; +import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import depth.mvp.ns.domain.report.domain.Report; import depth.mvp.ns.domain.report_detail.domain.ReportDetail; @@ -19,10 +20,18 @@ public class ReportDetailQueryDslRepositoryImpl implements ReportDetailQueryDslR @Override public List findAllBestReportTypeByReport(Report report) { + + BooleanExpression predicate; + if (report != null) { + predicate = reportDetail.report.eq(report); + } else { + predicate = reportDetail.report.isNull(); // Null일 경우를 대비한 처리 + } + return queryFactory .select(reportDetail) .from(reportDetail) - .where(reportDetail.report.eq(report), + .where(predicate, reportDetail.reportType.eq(ReportType.BEST)) .fetch(); } diff --git a/src/main/java/depth/mvp/ns/domain/user/controller/UserController.java b/src/main/java/depth/mvp/ns/domain/user/controller/UserController.java index 4d4c1b4..0385736 100644 --- a/src/main/java/depth/mvp/ns/domain/user/controller/UserController.java +++ b/src/main/java/depth/mvp/ns/domain/user/controller/UserController.java @@ -64,12 +64,13 @@ public ResponseEntity getRanking( @GetMapping("/profile/{userId}") public ResponseEntity getUserProfile( @CurrentUser CustomUserDetails customUserDetails, - @PathVariable(required = true) Long userId + @PathVariable(required = true) Long userId, + @RequestParam(defaultValue = "1") int page ) { if (customUserDetails != null) { - return userService.getProfile(userId, customUserDetails.getId()); + return userService.getProfile(userId, customUserDetails.getId(), page); } - return userService.getProfile(userId, null); + return userService.getProfile(userId, null, page); } @GetMapping("/nickname") diff --git a/src/main/java/depth/mvp/ns/domain/user/dto/UserProfileWithPageInfoRes.java b/src/main/java/depth/mvp/ns/domain/user/dto/UserProfileWithPageInfoRes.java new file mode 100644 index 0000000..da9005d --- /dev/null +++ b/src/main/java/depth/mvp/ns/domain/user/dto/UserProfileWithPageInfoRes.java @@ -0,0 +1,9 @@ +package depth.mvp.ns.domain.user.dto; + +import depth.mvp.ns.domain.user.dto.response.UserProfileRes; +import depth.mvp.ns.global.payload.PageInfo; +import lombok.Builder; + +@Builder +public record UserProfileWithPageInfoRes(UserProfileRes userProfileRes, PageInfo pageInfo) { +} diff --git a/src/main/java/depth/mvp/ns/domain/user/service/UserService.java b/src/main/java/depth/mvp/ns/domain/user/service/UserService.java index 4dd156e..7467b82 100644 --- a/src/main/java/depth/mvp/ns/domain/user/service/UserService.java +++ b/src/main/java/depth/mvp/ns/domain/user/service/UserService.java @@ -5,6 +5,7 @@ import depth.mvp.ns.domain.user.domain.RankingType; import depth.mvp.ns.domain.user.domain.User; import depth.mvp.ns.domain.user.domain.repository.UserRepository; +import depth.mvp.ns.domain.user.dto.UserProfileWithPageInfoRes; import depth.mvp.ns.domain.user.dto.request.CheckPasswordReq; import depth.mvp.ns.domain.user.dto.request.UpdateNicknameReq; import depth.mvp.ns.domain.user.dto.response.MyPageRes; @@ -15,6 +16,7 @@ import depth.mvp.ns.global.config.security.token.CustomUserDetails; import depth.mvp.ns.global.payload.ApiResponse; import depth.mvp.ns.global.payload.DefaultAssert; +import depth.mvp.ns.global.payload.PageInfo; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -127,22 +129,28 @@ public UserRankingRes getRankingData(Long id, RankingType type) { return userRepository.getNRankingDesc(id, type); } - public ResponseEntity getProfile(Long userId, Long currentUserId) { + public ResponseEntity getProfile(Long userId, Long currentUserId, int page) { User user = userRepository.findById(userId) .orElseThrow(EntityNotFoundException::new); + int pageSize = 5; + int offset = (page - 1) * pageSize; - UserProfileRes userProfileRes = boardRepository.findBoardListByUser(user, currentUserId); + UserProfileRes userProfileRes = boardRepository.findBoardListByUser(user, currentUserId, pageSize, offset); + int totalElements = boardRepository.countByUser(user); + int totalPages = (int) Math.ceil((double) totalElements / pageSize); + PageInfo pageInfo = new PageInfo(page, pageSize, totalElements, totalPages); ApiResponse apiResponse = ApiResponse.builder() .check(true) - .information(userProfileRes) + .information(new UserProfileWithPageInfoRes(userProfileRes, pageInfo)) .build(); return ResponseEntity.ok(apiResponse); } + // 추가된 메서드: 닉네임으로 사용자 정보 조회 public ResponseEntity getUInfoByNickname(Long userId, String nickname) {