Skip to content

Commit 9041021

Browse files
Merge pull request #154 from prgrms-web-devcourse-final-project/develop
chore: develop → main 브랜치 머지
2 parents 999c525 + 8d008c1 commit 9041021

32 files changed

+519
-237
lines changed

src/main/java/grep/neogul_coder/domain/admin/controller/dto/response/AdminStudyResponse.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import lombok.Builder;
77
import lombok.Data;
88

9+
import java.time.LocalDate;
10+
911
@Data
1012
@Schema(description = "관리자용 스터디 응답 DTO")
1113
public class AdminStudyResponse {
@@ -40,7 +42,7 @@ public static AdminStudyResponse from(Study study) {
4042
.id(study.getId())
4143
.name(study.getName())
4244
.category(study.getCategory())
43-
.isFinished(study.isFinished())
45+
.isFinished(study.getEndDate().toLocalDate().isBefore(LocalDate.now()))
4446
.activated(study.getActivated())
4547
.build();
4648
}

src/main/java/grep/neogul_coder/domain/main/controller/MainController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package grep.neogul_coder.domain.main.controller;
22

33
import grep.neogul_coder.domain.main.controller.dto.response.MainResponse;
4+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
45
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostPagingInfo;
56
import grep.neogul_coder.domain.recruitment.post.service.RecruitmentPostService;
67
import grep.neogul_coder.domain.study.controller.dto.response.StudyItemResponse;
78
import grep.neogul_coder.domain.study.service.StudyService;
89
import grep.neogul_coder.global.auth.Principal;
910
import grep.neogul_coder.global.response.ApiResponse;
1011
import lombok.RequiredArgsConstructor;
11-
import org.springframework.data.domain.Pageable;
12-
import org.springframework.data.web.PageableDefault;
1312
import org.springframework.security.core.annotation.AuthenticationPrincipal;
1413
import org.springframework.web.bind.annotation.GetMapping;
14+
import org.springframework.web.bind.annotation.RequestBody;
1515
import org.springframework.web.bind.annotation.RequestMapping;
1616
import org.springframework.web.bind.annotation.RestController;
1717

@@ -26,12 +26,12 @@ public class MainController implements MainSpecification {
2626
private final RecruitmentPostService recruitmentPostService;
2727

2828
@GetMapping
29-
public ApiResponse<MainResponse> getMain(@PageableDefault(size = 10) Pageable pageable,
29+
public ApiResponse<MainResponse> getMain(@RequestBody PagingCondition condition,
3030
@AuthenticationPrincipal Principal userDetails) {
3131
Long userId = userDetails.getUserId();
3232

3333
List<StudyItemResponse> myStudies = studyService.getMyStudies(userId);
34-
RecruitmentPostPagingInfo recruitingStudies = recruitmentPostService.getPagingInfo(pageable, null);
34+
RecruitmentPostPagingInfo recruitingStudies = recruitmentPostService.getPagingInfo(condition, null);
3535
MainResponse response = MainResponse.from(myStudies, recruitingStudies);
3636

3737
return ApiResponse.success(response);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package grep.neogul_coder.domain.main.controller;
22

33
import grep.neogul_coder.domain.main.controller.dto.response.MainResponse;
4+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
45
import grep.neogul_coder.global.auth.Principal;
56
import grep.neogul_coder.global.response.ApiResponse;
67
import io.swagger.v3.oas.annotations.Operation;
78
import io.swagger.v3.oas.annotations.tags.Tag;
8-
import org.springframework.data.domain.Pageable;
99

1010
@Tag(name = "Main", description = "메인화면 API")
1111
public interface MainSpecification {
1212

1313
@Operation(summary = "메인 화면 조회", description = "메인 화면을 조회합니다.")
14-
ApiResponse<MainResponse> getMain(Pageable pageable, Principal userDetails);
14+
ApiResponse<MainResponse> getMain(PagingCondition condition, Principal userDetails);
1515
}

src/main/java/grep/neogul_coder/domain/recruitment/post/controller/RecruitmentPostController.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package grep.neogul_coder.domain.recruitment.post.controller;
22

3+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
34
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.RecruitmentPostStatusUpdateRequest;
45
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.RecruitmentPostUpdateRequest;
56
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentApplicationPagingInfo;
@@ -23,15 +24,15 @@ public class RecruitmentPostController implements RecruitmentPostSpecification {
2324
private final RecruitmentPostService recruitmentPostService;
2425

2526
@GetMapping
26-
public ApiResponse<RecruitmentPostPagingInfo> getPagingInfo(@PageableDefault(size = 10) Pageable pageable) {
27-
RecruitmentPostPagingInfo response = recruitmentPostService.getPagingInfo(pageable, null);
27+
public ApiResponse<RecruitmentPostPagingInfo> getPagingInfo(@RequestBody PagingCondition condition) {
28+
RecruitmentPostPagingInfo response = recruitmentPostService.getPagingInfo(condition, null);
2829
return ApiResponse.success(response);
2930
}
3031

3132
@GetMapping("/me")
32-
public ApiResponse<RecruitmentPostPagingInfo> getMyPostPagingInfo(@PageableDefault(size = 10) Pageable pageable,
33+
public ApiResponse<RecruitmentPostPagingInfo> getMyPostPagingInfo(@RequestBody PagingCondition condition,
3334
@AuthenticationPrincipal Principal userDetails) {
34-
RecruitmentPostPagingInfo response = recruitmentPostService.getPagingInfo(pageable, userDetails.getUserId());
35+
RecruitmentPostPagingInfo response = recruitmentPostService.getPagingInfo(condition, userDetails.getUserId());
3536
return ApiResponse.success(response);
3637
}
3738

src/main/java/grep/neogul_coder/domain/recruitment/post/controller/RecruitmentPostSpecification.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package grep.neogul_coder.domain.recruitment.post.controller;
22

3+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
34
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.RecruitmentPostStatusUpdateRequest;
45
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.RecruitmentPostUpdateRequest;
56
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentApplicationPagingInfo;
@@ -10,6 +11,7 @@
1011
import io.swagger.v3.oas.annotations.Operation;
1112
import io.swagger.v3.oas.annotations.tags.Tag;
1213
import org.springframework.data.domain.Pageable;
14+
import org.springframework.web.bind.annotation.RequestBody;
1315

1416
@Tag(name = "Recruitment-Post", description = "모집 글 API")
1517
public interface RecruitmentPostSpecification {
@@ -63,7 +65,7 @@ public interface RecruitmentPostSpecification {
6365
```
6466
"""
6567
)
66-
ApiResponse<RecruitmentPostPagingInfo> getMyPostPagingInfo(Pageable pageable, Principal userDetails);
68+
ApiResponse<RecruitmentPostPagingInfo> getMyPostPagingInfo(@RequestBody PagingCondition condition, Principal userDetails);
6769

6870
@Operation(
6971
summary = "모집글 페이징 조회",
@@ -102,7 +104,7 @@ public interface RecruitmentPostSpecification {
102104
```
103105
"""
104106
)
105-
ApiResponse<RecruitmentPostPagingInfo> getPagingInfo(Pageable pageable);
107+
ApiResponse<RecruitmentPostPagingInfo> getPagingInfo(PagingCondition condition);
106108

107109
@Operation(
108110
summary = "스터디 신청한 회원 목록 페이징 조회",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package grep.neogul_coder.domain.recruitment.post.controller.dto.request;
2+
3+
import grep.neogul_coder.domain.study.enums.Category;
4+
import grep.neogul_coder.domain.study.enums.StudyType;
5+
import lombok.Getter;
6+
import org.springframework.data.domain.PageRequest;
7+
import org.springframework.data.domain.Pageable;
8+
9+
@Getter
10+
public class PagingCondition {
11+
12+
private int page;
13+
private int pageSize;
14+
15+
private Category category;
16+
private StudyType studyType;
17+
private String content;
18+
19+
private PagingCondition() {
20+
}
21+
22+
public PagingCondition(int page, int pageSize, Category category, StudyType studyType, String content) {
23+
this.page = page;
24+
this.pageSize = pageSize;
25+
this.category = category;
26+
this.studyType = studyType;
27+
this.content = content;
28+
}
29+
30+
public Pageable toPageable() {
31+
return PageRequest.of(page, pageSize);
32+
}
33+
}

src/main/java/grep/neogul_coder/domain/recruitment/post/controller/dto/response/RecruitmentPostPagingInfo.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@
1717
public class RecruitmentPostPagingInfo {
1818

1919
private List<RecruitmentPostInfo> postInfos;
20+
private int totalPage;
21+
private long totalElementCount;
22+
private boolean hasNext;
2023

21-
public RecruitmentPostPagingInfo(List<RecruitmentPostInfo> postInfos) {
24+
public RecruitmentPostPagingInfo(List<RecruitmentPostInfo> postInfos, int totalPage, long totalElementCount, boolean hasNext) {
2225
this.postInfos = postInfos;
26+
this.totalPage = totalPage;
27+
this.totalElementCount = totalElementCount;
28+
this.hasNext = hasNext;
2329
}
2430

2531
public static RecruitmentPostPagingInfo of(List<RecruitmentPost> recruitmentPosts,
26-
Map<Long, Study> studyIdMap,
27-
Map<Long, List<RecruitmentPostComment>> postIdMap) {
32+
Map<Long, Study> studyIdMap, Map<Long, List<RecruitmentPostComment>> postIdMap,
33+
int totalPages, long totalElements, boolean hasNext) {
2834

2935
List<RecruitmentPostInfo> postInfos = recruitmentPosts.stream()
3036
.map(post -> new RecruitmentPostInfo(
@@ -33,7 +39,7 @@ public static RecruitmentPostPagingInfo of(List<RecruitmentPost> recruitmentPost
3339
postIdMap.getOrDefault(post.getId(), Collections.emptyList())))
3440
.toList();
3541

36-
return new RecruitmentPostPagingInfo(postInfos);
42+
return new RecruitmentPostPagingInfo(postInfos, totalPages, totalElements, hasNext);
3743
}
3844

3945
@ToString

src/main/java/grep/neogul_coder/domain/recruitment/post/repository/RecruitmentPostQueryRepository.java

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package grep.neogul_coder.domain.recruitment.post.repository;
22

3+
import com.querydsl.core.BooleanBuilder;
4+
import com.querydsl.core.types.dsl.BooleanExpression;
35
import com.querydsl.jpa.impl.JPAQueryFactory;
46
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
7+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
58
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.QRecruitmentPostWithStudyInfo;
69
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostWithStudyInfo;
10+
import grep.neogul_coder.domain.study.enums.Category;
11+
import grep.neogul_coder.domain.study.enums.StudyType;
712
import jakarta.persistence.EntityManager;
8-
import org.springframework.data.domain.Pageable;
13+
import org.springframework.data.domain.Page;
14+
import org.springframework.data.domain.PageImpl;
915
import org.springframework.stereotype.Repository;
1016

1117
import java.util.List;
18+
import java.util.function.Supplier;
1219

1320
import static grep.neogul_coder.domain.recruitment.post.QRecruitmentPost.recruitmentPost;
1421
import static grep.neogul_coder.domain.study.QStudy.study;
@@ -51,24 +58,88 @@ public RecruitmentPostWithStudyInfo findPostWithStudyInfo(Long recruitmentPostId
5158
).fetchOne();
5259
}
5360

54-
public List<RecruitmentPost> findAllByFilter(Pageable pageable) {
55-
return queryFactory.selectFrom(recruitmentPost)
56-
.where(recruitmentPost.activated.isTrue())
57-
.offset(pageable.getOffset())
58-
.limit(pageable.getPageSize())
61+
public Page<RecruitmentPost> findAllByFilter(PagingCondition condition) {
62+
List<RecruitmentPost> content = queryFactory.select(recruitmentPost)
63+
.from(recruitmentPost)
64+
.join(study).on(recruitmentPost.studyId.eq(study.id))
65+
.where(
66+
recruitmentPost.activated.isTrue(),
67+
68+
equalsStudyCategory(condition.getCategory()),
69+
equalsStudyType(condition.getStudyType()),
70+
likeContent(condition.getContent())
71+
)
72+
.offset(condition.getPage())
73+
.limit(condition.getPageSize())
5974
.orderBy(recruitmentPost.createdDate.desc())
6075
.fetch();
76+
77+
Long count = queryFactory.select(recruitmentPost.count())
78+
.from(recruitmentPost)
79+
.join(study).on(recruitmentPost.studyId.eq(study.id))
80+
.where(
81+
recruitmentPost.activated.isTrue(),
82+
83+
equalsStudyCategory(condition.getCategory()),
84+
equalsStudyType(condition.getStudyType()),
85+
likeContent(condition.getContent())
86+
)
87+
.fetchOne();
88+
89+
return new PageImpl<>(content, condition.toPageable(), count == null ? 0 : count);
6190
}
6291

63-
public List<RecruitmentPost> findAllByFilter(Pageable pageable, Long userId) {
64-
return queryFactory.selectFrom(recruitmentPost)
92+
public Page<RecruitmentPost> findAllByFilter(PagingCondition condition, Long userId) {
93+
List<RecruitmentPost> content = queryFactory.select(recruitmentPost)
94+
.from(recruitmentPost)
95+
.join(study).on(recruitmentPost.studyId.eq(study.id))
6596
.where(
6697
recruitmentPost.userId.eq(userId),
67-
recruitmentPost.activated.isTrue()
98+
recruitmentPost.activated.isTrue(),
99+
100+
equalsStudyCategory(condition.getCategory()),
101+
equalsStudyType(condition.getStudyType()),
102+
likeContent(condition.getContent())
68103
)
69-
.offset(pageable.getOffset())
70-
.limit(pageable.getPageSize())
104+
.offset(condition.getPage())
105+
.limit(condition.getPageSize())
71106
.orderBy(recruitmentPost.createdDate.desc())
72107
.fetch();
108+
109+
110+
Long count = queryFactory.select(recruitmentPost.count())
111+
.from(recruitmentPost)
112+
.join(study).on(recruitmentPost.studyId.eq(study.id))
113+
.where(
114+
recruitmentPost.userId.eq(userId),
115+
recruitmentPost.activated.isTrue(),
116+
117+
equalsStudyCategory(condition.getCategory()),
118+
equalsStudyType(condition.getStudyType()),
119+
likeContent(condition.getContent())
120+
)
121+
.fetchOne();
122+
123+
return new PageImpl<>(content, condition.toPageable(), count == null ? 0 : count);
124+
}
125+
126+
private BooleanBuilder equalsStudyType(StudyType studyType) {
127+
return nullSafeBuilder(() -> study.studyType.eq(studyType));
128+
}
129+
130+
private BooleanBuilder equalsStudyCategory(Category category) {
131+
return nullSafeBuilder(() -> study.category.eq(category));
132+
}
133+
134+
private BooleanBuilder likeContent(String content) {
135+
return nullSafeBuilder(() -> recruitmentPost.content.contains(content));
136+
}
137+
138+
private BooleanBuilder nullSafeBuilder(Supplier<BooleanExpression> supplier) {
139+
try {
140+
return new BooleanBuilder(supplier.get());
141+
} catch (Exception e) {
142+
return new BooleanBuilder();
143+
}
73144
}
74145
}

src/main/java/grep/neogul_coder/domain/recruitment/post/service/RecruitmentPostService.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import grep.neogul_coder.domain.recruitment.comment.controller.dto.response.CommentsWithWriterInfo;
55
import grep.neogul_coder.domain.recruitment.comment.repository.RecruitmentPostCommentQueryRepository;
66
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
7+
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
78
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostInfo;
89
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostPagingInfo;
910
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostWithStudyInfo;
@@ -18,7 +19,7 @@
1819
import grep.neogul_coder.global.exception.business.BusinessException;
1920
import grep.neogul_coder.global.exception.business.NotFoundException;
2021
import lombok.RequiredArgsConstructor;
21-
import org.springframework.data.domain.Pageable;
22+
import org.springframework.data.domain.Page;
2223
import org.springframework.stereotype.Service;
2324
import org.springframework.transaction.annotation.Transactional;
2425

@@ -53,17 +54,21 @@ public RecruitmentPostInfo get(long recruitmentPostId) {
5354
return new RecruitmentPostInfo(postInfo, comments, applications.size());
5455
}
5556

56-
public RecruitmentPostPagingInfo getPagingInfo(Pageable pageable, Long userId) {
57-
List<RecruitmentPost> recruitmentPosts = findPostsFilteredByUser(pageable, userId);
58-
List<Long> recruitmentPostIds = extractId(recruitmentPosts);
57+
public RecruitmentPostPagingInfo getPagingInfo(PagingCondition condition, Long userId) {
58+
Page<RecruitmentPost> pages = findPostsFilteredByUser(condition, userId);
59+
List<RecruitmentPost> content = pages.getContent();
60+
List<Long> recruitmentPostIds = extractId(content);
5961

60-
List<Study> studies = findConnectedStudiesFrom(recruitmentPosts);
62+
List<Study> studies = findConnectedStudiesFrom(content);
6163
Map<Long, Study> studyIdMap = groupedStudyIdMapFrom(studies);
6264

6365
List<RecruitmentPostComment> comments = commentQueryRepository.findByPostIdIn(recruitmentPostIds);
6466
Map<Long, List<RecruitmentPostComment>> postIdMap = groupedPostIdBy(comments);
6567

66-
return RecruitmentPostPagingInfo.of(recruitmentPosts, studyIdMap, postIdMap);
68+
return RecruitmentPostPagingInfo.of(
69+
content, studyIdMap, postIdMap,
70+
pages.getTotalPages(), pages.getTotalElements(), pages.hasNext()
71+
);
6772
}
6873

6974
@Transactional
@@ -97,11 +102,11 @@ private List<CommentsWithWriterInfo> findCommentsWithWriterInfo(RecruitmentPost
97102
return applyWithdrawnUserNameChanges(comments, withdrawnUserComments);
98103
}
99104

100-
private List<RecruitmentPost> findPostsFilteredByUser(Pageable pageable, Long userId) {
105+
private Page<RecruitmentPost> findPostsFilteredByUser(PagingCondition condition, Long userId) {
101106
if (userId == null) {
102-
return postQueryRepository.findAllByFilter(pageable);
107+
return postQueryRepository.findAllByFilter(condition);
103108
}
104-
return postQueryRepository.findAllByFilter(pageable, userId);
109+
return postQueryRepository.findAllByFilter(condition, userId);
105110
}
106111

107112
private List<CommentsWithWriterInfo> withdrawnUserChangeNameFrom(List<CommentsWithWriterInfo> comments) {

0 commit comments

Comments
 (0)