Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,34 @@ public ResponseEntity<ApiResponse<CategoryPostListResponseDTO>> getCategoryPostL
return ApiResponse.success(SuccessStatus.GET_CATEGORY_POST_LIST_SUCCESS, categoryPostListResponseDTO);
}

@Operation(
summary = "공감한 기록 리스트 조회 API (마이페이지)",
description = "사용자가 공감한 기록 리스트를 조회합니다. userId 쿼리 파라미터가 없으면 본인, 있으면 해당 사용자의 공감 기록을 조회합니다. " +
"최신순, 오래된순, 평점 높은순, 평점 낮은순으로 정렬할 수 있습니다." +
"<br><br>[enum] 정렬 옵션 (sortBy):" +
"<br>- LATEST: 최신순 (기본값)" +
"<br>- OLDEST: 오래된순" +
"<br>- RATING_HIGH: 평점 높은순" +
"<br>- RATING_LOW: 평점 낮은순"
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "공감한 기록 리스트 조회 성공"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "해당 사용자의 정보는 공개되지 않습니다."),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "해당 사용자를 찾을 수 없습니다.")
})
@GetMapping("/liked-posts")
public ResponseEntity<ApiResponse<CategoryPostListResponseDTO>> getLikedPostList(
@AuthenticationPrincipal UserDetails userDetails,
@RequestParam(required = false) Long userId,
@RequestParam(defaultValue = "LATEST") String sortBy,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {

CategoryPostListResponseDTO likedPostListResponseDTO =
memberService.getLikedPostList(userDetails.getUsername(), userId, sortBy, page, size);
return ApiResponse.success(SuccessStatus.GET_LIKED_POST_LIST_SUCCESS, likedPostListResponseDTO);
}

@Operation(
summary = "마이페이지 질문 리스트 조회 API",
description = "사용자가 작성한 질문 리스트를 페이징하여 조회합니다. userId 쿼리파라미터가 없으면 본인 질문, 있으면 해당 사용자의 질문을 조회합니다."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,50 @@ public CategoryPostListResponseDTO getCategoryPostList(String email, Long userId
.build();
}

// 공감한 기록 리스트 조회
@Transactional(readOnly = true)
public CategoryPostListResponseDTO getLikedPostList(String email, Long userId, String sortBy, Integer page, Integer size) {

Member currentMember = getMemberByEmail(email);
Member targetMember = (userId == null)
? currentMember
: memberRepository.findById(userId)
.orElseThrow(() -> new NotFoundException(ErrorStatus.USER_NOTFOUND_EXCEPTION.getMessage()));

validatePrivacyAccess(currentMember, targetMember);

Pageable pageable = PageRequest.of(page - 1, size);

Page<Post> postPage = switch (sortBy.toUpperCase()) {
case "LATEST" ->
postRepository.findLikedPostsByMemberIdOrderByCreatedAtDesc(targetMember.getId(), pageable);
case "OLDEST" ->
postRepository.findLikedPostsByMemberIdOrderByCreatedAtAsc(targetMember.getId(), pageable);
case "RATING_HIGH" ->
postRepository.findLikedPostsByMemberIdOrderByRatingDesc(targetMember.getId(), pageable);
case "RATING_LOW" ->
postRepository.findLikedPostsByMemberIdOrderByRatingAsc(targetMember.getId(), pageable);
default ->
postRepository.findLikedPostsByMemberIdOrderByCreatedAtDesc(targetMember.getId(), pageable);
};

List<PostDTO> postList = postPage.getContent().stream()
.map(this::convertToPostDTO)
.collect(Collectors.toList());

log.info("공감한 기록 리스트 조회 완료 - 사용자 ID: {}, 정렬: {}, 페이지: {}, 결과 수: {}",
targetMember.getId(), sortBy, page, postList.size());

return CategoryPostListResponseDTO.builder()
.total(postPage.getTotalElements())
.page(page)
.size(size)
.totalPages(postPage.getTotalPages())
.isLast(postPage.isLast())
.data(postList)
.build();
}

// Post를 PostDTO로 변환
private PostDTO convertToPostDTO(Post post) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,34 @@ List<Post> findWeeklyRecommendationByReadingTasteType(
@Query("SELECT p FROM Post p WHERE p.category.id = :categoryId ORDER BY p.rating ASC, p.createdAt DESC")
Page<Post> findByCategoryIdOrderByRatingAsc(@Param("categoryId") Long categoryId, Pageable pageable);

// 사용자가 공감한 기록 조회 (최신순)
@Query(value = "SELECT DISTINCT l.post FROM Likes l " +
"WHERE l.member.id = :memberId " +
"ORDER BY l.post.createdAt DESC",
countQuery = "SELECT COUNT(DISTINCT l.post.id) FROM Likes l WHERE l.member.id = :memberId")
Page<Post> findLikedPostsByMemberIdOrderByCreatedAtDesc(@Param("memberId") Long memberId, Pageable pageable);

// 사용자가 공감한 기록 조회 (오래된순)
@Query(value = "SELECT DISTINCT l.post FROM Likes l " +
"WHERE l.member.id = :memberId " +
"ORDER BY l.post.createdAt ASC",
countQuery = "SELECT COUNT(DISTINCT l.post.id) FROM Likes l WHERE l.member.id = :memberId")
Page<Post> findLikedPostsByMemberIdOrderByCreatedAtAsc(@Param("memberId") Long memberId, Pageable pageable);

// 사용자가 공감한 기록 조회 (평점 높은순)
@Query(value = "SELECT DISTINCT l.post FROM Likes l " +
"WHERE l.member.id = :memberId " +
"ORDER BY l.post.rating DESC, l.post.createdAt DESC",
countQuery = "SELECT COUNT(DISTINCT l.post.id) FROM Likes l WHERE l.member.id = :memberId")
Page<Post> findLikedPostsByMemberIdOrderByRatingDesc(@Param("memberId") Long memberId, Pageable pageable);

// 사용자가 공감한 기록 조회 (평점 낮은순)
@Query(value = "SELECT DISTINCT l.post FROM Likes l " +
"WHERE l.member.id = :memberId " +
"ORDER BY l.post.rating ASC, l.post.createdAt DESC",
countQuery = "SELECT COUNT(DISTINCT l.post.id) FROM Likes l WHERE l.member.id = :memberId")
Page<Post> findLikedPostsByMemberIdOrderByRatingAsc(@Param("memberId") Long memberId, Pageable pageable);

// 읽은 날짜 기준 월별 게시글 조회 (일자 오름차순, 같은 일자 내 최신 작성순)
@Query("SELECT p FROM Post p JOIN FETCH p.book " +
"WHERE p.member = :member AND p.readDate BETWEEN :startDate AND :endDate " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public enum SuccessStatus {
GET_ALL_POST_SUCCESS(HttpStatus.OK, "기록(게시글) 전체 조회 성공"),
GET_POST_SUCCESS(HttpStatus.OK, "기록(게시글) 상세 조회 성공"),
GET_CATEGORY_POST_LIST_SUCCESS(HttpStatus.OK, "카테고리별 기록 리스트 조회 성공"),
GET_LIKED_POST_LIST_SUCCESS(HttpStatus.OK, "공감한 기록 리스트 조회 성공"),
UPDATE_POST_SUCCESS(HttpStatus.OK, "기록(게시글) 수정 성공"),
DELETE_POST_SUCCESS(HttpStatus.OK, "기록(게시글) 삭제 성공"),
POST_LIKE_SUCCESS(HttpStatus.OK, "기록(게시글) 공감 버튼 등록 성공"),
Expand Down