Skip to content

Commit 259a740

Browse files
authored
Merge pull request #76 from GD-YD/feature/Best-Post-API
자유게시글, 질문글에 대한 베스트글 요청 API
2 parents 48d3b72 + 9e98677 commit 259a740

File tree

8 files changed

+73
-7
lines changed

8 files changed

+73
-7
lines changed

gd-yd-api/src/main/java/com/gdyd/gdydapi/controller/board/PostController.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import org.springframework.http.ResponseEntity;
2121
import org.springframework.web.bind.annotation.*;
2222

23+
import java.time.LocalDateTime;
24+
2325
@Tag(name = "Post", description = "Post 관련 API")
2426
@RestController
2527
@RequiredArgsConstructor
@@ -38,21 +40,33 @@ public ResponseEntity<SavePostResponse> createPost(@RequestBody SavePostReqeust
3840
@Operation(summary = "Post 목록 조회 API", description = "Post의 목록을 조회하는 API")
3941
@Parameter(name = "page", description = "페이지 번호")
4042
@Parameter(name = "size", description = "페이지 크기")
41-
@Parameter(name = "criteria", description = "정렬 기준 (createAt | likeCount)")
43+
@Parameter(name = "criteria", description = "정렬 기준 (createdAt | likeCount)")
4244
@GetMapping
4345
public ResponseEntity<PageResponse<GetPostSummaryResponse>> getPostList(
4446
@RequestParam(value = "page", defaultValue = "0") int page,
4547
@RequestParam(value = "size", defaultValue = "20") int size,
4648
@RequestParam(value = "criteria", defaultValue = "createdAt") String criteria
4749
) {
4850
Pageable pageable = switch (criteria) {
49-
case "likeCount" -> PageRequest.of(page, size, Sort.by(criteria).descending());
50-
default -> PageRequest.of(page, size, Sort.by(criteria));
51+
case "likeCount" -> PageRequest.of(page, size, Sort.by("likeCount", "createdAt").descending());
52+
default -> PageRequest.of(page, size, Sort.by("createdAt"));
5153
};
5254
PageResponse<GetPostSummaryResponse> response = postQueryService.getPostList(pageable);
5355
return ResponseEntity.ok(response);
5456
}
5557

58+
@Operation(summary = "인기 Post 조회 API", description = "특정 기간 내 인기 게시글 n개를 불러오는 API")
59+
@GetMapping("/best")
60+
public ResponseEntity<PageResponse<GetPostSummaryResponse>> getBestPostList(
61+
@RequestParam(value = "size", defaultValue = "20") int size,
62+
@RequestParam(value = "period", defaultValue = "1") int period
63+
) {
64+
LocalDateTime weeksAgo = LocalDateTime.now().minusWeeks(period);
65+
Pageable pageable = PageRequest.of(0, size, Sort.by("likeCount", "createdAt").descending());
66+
PageResponse<GetPostSummaryResponse> response = postQueryService.getBestPostList(weeksAgo, pageable);
67+
return ResponseEntity.ok(response);
68+
}
69+
5670
@Operation(summary = "Post 상세 조회 API", description = "Post와 Comments를 PostId로 불러오는 API")
5771
@GetMapping("/{postId}")
5872
public ResponseEntity<GetPostResponse> getPostById(@PathVariable("postId") Long postId) {

gd-yd-api/src/main/java/com/gdyd/gdydapi/controller/mentoring/MentoringController.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.gdyd.gdydapi.request.mentoring.CreateHighSchoolStudentQuestionRequest;
44
import com.gdyd.gdydapi.request.mentoring.CreateUniversityStudentAnswerRequest;
55
import com.gdyd.gdydapi.request.report.ReportRequest;
6+
import com.gdyd.gdydapi.response.board.GetPostSummaryResponse;
67
import com.gdyd.gdydapi.response.common.LikeListResponse;
78
import com.gdyd.gdydapi.response.common.PageResponse;
89
import com.gdyd.gdydapi.response.common.ScrapListResponse;
@@ -24,6 +25,8 @@
2425
import org.springframework.http.ResponseEntity;
2526
import org.springframework.web.bind.annotation.*;
2627

28+
import java.time.LocalDateTime;
29+
2730
@Tag(name = "Mentoring", description = "Mentoring 관련 API")
2831
@RestController
2932
@RequiredArgsConstructor
@@ -55,21 +58,33 @@ public ResponseEntity<CreateUniversityStudentAnswerResponse> createUniversityStu
5558
@Operation(summary = "고등학생 질문 목록 조회 API", description = "고등학생 질문 목록을 페이지네이션으로 조회하는 API")
5659
@Parameter(name = "page", description = "페이지 번호")
5760
@Parameter(name = "size", description = "페이지 크기")
58-
@Parameter(name = "criteria", description = "정렬 기준 (createAt | likeCount)")
61+
@Parameter(name = "criteria", description = "정렬 기준 (createdAt | likeCount)")
5962
@GetMapping("/high-school-student-questions")
6063
public ResponseEntity<PageResponse<HighSchoolStudentQuestionResponse>> getHighSchoolStudentQuestionList(
6164
@RequestParam(value = "page", defaultValue = "0") int page,
6265
@RequestParam(value = "size", defaultValue = "20") int size,
6366
@RequestParam(value = "criteria", defaultValue = "createdAt") String criteria
6467
) {
6568
Pageable pageable = switch (criteria) {
66-
case "likeCount" -> PageRequest.of(page, size, Sort.by(criteria).descending());
67-
default -> PageRequest.of(page, size, Sort.by(criteria));
69+
case "likeCount" -> PageRequest.of(page, size, Sort.by("likeCount", "createdAt").descending());
70+
default -> PageRequest.of(page, size, Sort.by("createdAt"));
6871
};
6972
PageResponse<HighSchoolStudentQuestionResponse> response = mentoringQueryService.getHighSchoolStudentQuestions(pageable);
7073
return ResponseEntity.ok(response);
7174
}
7275

76+
@Operation(summary = "인기 질문글 조회 API", description = "특정 기간 내 인기 질문글 n개를 불러오는 API")
77+
@GetMapping("/high-school-student-questions/best")
78+
public ResponseEntity<PageResponse<HighSchoolStudentQuestionResponse>> getBestHighSchoolStudentQuestionList(
79+
@RequestParam(value = "size", defaultValue = "20") int size,
80+
@RequestParam(value = "period", defaultValue = "1") int period
81+
) {
82+
LocalDateTime weeksAgo = LocalDateTime.now().minusWeeks(period);
83+
Pageable pageable = PageRequest.of(0, size, Sort.by("likeCount", "createdAt").descending());
84+
PageResponse<HighSchoolStudentQuestionResponse> response = mentoringQueryService.getBestHighSchoolStudentQuestions(weeksAgo, pageable);
85+
return ResponseEntity.ok(response);
86+
}
87+
7388
@Operation(summary = "고등학생 질문 상세 조회 API", description = "고등학생 질문 상세 정보(대학생 답변 내용 등)를 조회하는 API")
7489
@Parameter(name = "highSchoolStudentQuestionId", description = "고등학생 질문글 ID", required = true)
7590
@GetMapping("/high-school-student-question/{highSchoolStudentQuestionId}")

gd-yd-api/src/main/java/com/gdyd/gdydapi/service/board/PostQueryService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import org.springframework.stereotype.Service;
1212
import org.springframework.transaction.annotation.Transactional;
1313

14+
import java.time.LocalDateTime;
15+
import java.util.List;
16+
1417
@Service
1518
@RequiredArgsConstructor
1619
@Transactional(readOnly = true)
@@ -26,4 +29,9 @@ public GetPostResponse getPostAndCommentsByPostId(Long postId) {
2629
Post post = postService.getPostById(postId);
2730
return GetPostResponse.from(post);
2831
}
32+
33+
public PageResponse<GetPostSummaryResponse> getBestPostList(LocalDateTime weeksAgo, Pageable pageable) {
34+
List<Post> posts = postService.findAllByCreatedAtIsAfter(weeksAgo, pageable);
35+
return PageResponse.of(posts.stream().map(GetPostSummaryResponse::from).toList());
36+
}
2937
}

gd-yd-api/src/main/java/com/gdyd/gdydapi/service/mentoring/MentoringQueryService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.springframework.stereotype.Service;
1313
import org.springframework.transaction.annotation.Transactional;
1414

15+
import java.time.LocalDateTime;
1516
import java.util.List;
1617

1718
@Service
@@ -29,6 +30,11 @@ public PageResponse<HighSchoolStudentQuestionResponse> getHighSchoolStudentQuest
2930
return PageResponse.of(pages.getContent().stream().map(HighSchoolStudentQuestionResponse::from).toList());
3031
}
3132

33+
public PageResponse<HighSchoolStudentQuestionResponse> getBestHighSchoolStudentQuestions(LocalDateTime weeksAgo, Pageable pageable) {
34+
List<HighSchoolStudentQuestion> questions = highSchoolStudentQuestionService.findAllByCreatedAtIsAfter(weeksAgo, pageable);
35+
return PageResponse.of(questions.stream().map(HighSchoolStudentQuestionResponse::from).toList());
36+
}
37+
3238
/**
3339
* 고등학생 질문 상세 조회
3440
* @param highSchoolStudentQuestionId 고등학생 질문 ID
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.gdyd.gdydcore.repository.board;
22

33
import com.gdyd.gdydcore.domain.board.Post;
4+
import org.springframework.data.domain.Pageable;
45
import org.springframework.data.jpa.repository.JpaRepository;
56

7+
import java.time.LocalDateTime;
8+
import java.util.List;
69
import java.util.Optional;
710

811
public interface PostRepository extends JpaRepository<Post, Long> {
912
Optional<Post> findByIdAndMemberId(Long postId, Long memberId);
13+
14+
List<Post> findAllByCreatedAtIsAfter(LocalDateTime weeksAgo, Pageable pageable);
1015
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.gdyd.gdydcore.repository.mentoring;
22

33
import com.gdyd.gdydcore.domain.mentoring.HighSchoolStudentQuestion;
4+
import org.springframework.data.domain.Pageable;
45
import org.springframework.data.jpa.repository.JpaRepository;
56

6-
public interface HighSchoolStudentQuestionRepository extends JpaRepository<HighSchoolStudentQuestion, Long> {
7+
import java.time.LocalDateTime;
8+
import java.util.List;
79

10+
public interface HighSchoolStudentQuestionRepository extends JpaRepository<HighSchoolStudentQuestion, Long> {
11+
List<HighSchoolStudentQuestion> findAllByCreatedAtIsAfter(LocalDateTime weeksAgo, Pageable pageable);
812
}

gd-yd-core/src/main/java/com/gdyd/gdydcore/service/board/PostService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import org.springframework.stereotype.Service;
1111
import org.springframework.transaction.annotation.Transactional;
1212

13+
import java.time.LocalDateTime;
14+
import java.util.List;
15+
1316
@Service
1417
@RequiredArgsConstructor
1518
@Transactional(readOnly = true)
@@ -35,6 +38,10 @@ public Post getPostByIdAndMemberId(Long postId, Long memberId) {
3538
.orElseThrow(() -> new BusinessException(ErrorCode.UNAUTHORIZED_MEMBER));
3639
}
3740

41+
public List<Post> findAllByCreatedAtIsAfter(LocalDateTime weeksAgo, Pageable pageable) {
42+
return postRepository.findAllByCreatedAtIsAfter(weeksAgo, pageable);
43+
}
44+
3845
@Transactional
3946
public void deletePost(Long postId) {
4047
postRepository.deleteById(postId);

gd-yd-core/src/main/java/com/gdyd/gdydcore/service/mentoring/HighSchoolStudentQuestionService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import org.springframework.stereotype.Service;
1111
import org.springframework.transaction.annotation.Transactional;
1212

13+
import java.time.LocalDateTime;
14+
import java.util.List;
15+
1316
@Service
1417
@RequiredArgsConstructor
1518
@Transactional(readOnly = true)
@@ -25,6 +28,10 @@ public Page<HighSchoolStudentQuestion> findHighSchoolStudentQuestionByPagination
2528
return highSchoolStudentQuestionRepository.findAll(pageable);
2629
}
2730

31+
public List<HighSchoolStudentQuestion> findAllByCreatedAtIsAfter(LocalDateTime weeksAgo, Pageable pageable) {
32+
return highSchoolStudentQuestionRepository.findAllByCreatedAtIsAfter(weeksAgo, pageable);
33+
}
34+
2835
@Transactional
2936
public void save(HighSchoolStudentQuestion highSchoolStudentQuestion) {
3037
highSchoolStudentQuestionRepository.save(highSchoolStudentQuestion);

0 commit comments

Comments
 (0)