diff --git a/src/main/java/org/gachon/checkmate/domain/member/entity/GenderType.java b/src/main/java/org/gachon/checkmate/domain/member/entity/GenderType.java index db6ae4c..60a842b 100644 --- a/src/main/java/org/gachon/checkmate/domain/member/entity/GenderType.java +++ b/src/main/java/org/gachon/checkmate/domain/member/entity/GenderType.java @@ -8,8 +8,8 @@ @AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter public enum GenderType implements EnumField { - MAN("1", "man"), - WOMAN("2", "woman"); + MAN("1", "남자"), + WOMAN("2", "여자"); private final String code; private final String desc; diff --git a/src/main/java/org/gachon/checkmate/domain/post/controller/PostController.java b/src/main/java/org/gachon/checkmate/domain/post/controller/PostController.java index c55a770..931fc93 100644 --- a/src/main/java/org/gachon/checkmate/domain/post/controller/PostController.java +++ b/src/main/java/org/gachon/checkmate/domain/post/controller/PostController.java @@ -5,11 +5,14 @@ import org.gachon.checkmate.domain.post.dto.request.PostCreateRequestDto; import org.gachon.checkmate.domain.post.dto.response.PostDetailResponseDto; import org.gachon.checkmate.domain.post.dto.response.PostSearchResponseDto; +import org.gachon.checkmate.domain.post.dto.support.PostSearchCondition; +import org.gachon.checkmate.domain.post.repository.PostQuerydslRepository; import org.gachon.checkmate.domain.post.service.PostService; import org.gachon.checkmate.global.common.SuccessResponse; import org.gachon.checkmate.global.config.auth.UserId; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @@ -21,8 +24,9 @@ public class PostController { @GetMapping public ResponseEntity> getAllPosts(@UserId final Long userId, @RequestParam final String type, + @RequestParam(required = false) final String gender, final Pageable pageable) { - final PostSearchResponseDto responseDto = postService.getAllPosts(userId, type, pageable); + final PostSearchResponseDto responseDto = postService.getAllPosts(userId, type, gender, pageable); return SuccessResponse.ok(responseDto); } @@ -44,14 +48,15 @@ public ResponseEntity> searchTextPost(@UserId final Long user public ResponseEntity> searchKeyWordPost(@UserId final Long userId, @PathVariable final String key, @RequestParam final String type, + @RequestParam(required = false) final String gender, final Pageable pageable) { - final PostSearchResponseDto responseDto = postService.searchKeyWordPost(userId, key, type, pageable); + final PostSearchResponseDto responseDto = postService.searchKeyWordPost(userId, key, type, gender, pageable); return SuccessResponse.ok(responseDto); } @PostMapping public ResponseEntity> createPost(@UserId final Long userId, - @Valid @RequestBody final PostCreateRequestDto requestDto) { + @RequestBody @Valid final PostCreateRequestDto requestDto) { postService.createPost(userId, requestDto); return SuccessResponse.ok(null); } diff --git a/src/main/java/org/gachon/checkmate/domain/post/dto/response/PostSearchElementResponseDto.java b/src/main/java/org/gachon/checkmate/domain/post/dto/response/PostSearchElementResponseDto.java index a5d6a58..20314e6 100644 --- a/src/main/java/org/gachon/checkmate/domain/post/dto/response/PostSearchElementResponseDto.java +++ b/src/main/java/org/gachon/checkmate/domain/post/dto/response/PostSearchElementResponseDto.java @@ -12,7 +12,8 @@ public record PostSearchElementResponseDto( String similarityKey, int scrapCount, int remainDate, - int accuracy + int accuracy, + String gender ) { public static PostSearchElementResponseDto of(PostSearchDto postSearchDto, int remainDate, @@ -26,6 +27,7 @@ public static PostSearchElementResponseDto of(PostSearchDto postSearchDto, .scrapCount(postSearchDto.scrapCount()) .remainDate(remainDate) .accuracy(accuracy) + .gender(postSearchDto.genderType().getDesc()) .build(); } } diff --git a/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchCondition.java b/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchCondition.java new file mode 100644 index 0000000..6735e0e --- /dev/null +++ b/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchCondition.java @@ -0,0 +1,30 @@ +package org.gachon.checkmate.domain.post.dto.support; + +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.Builder; +import org.gachon.checkmate.domain.member.entity.GenderType; +import org.gachon.checkmate.domain.post.entity.ImportantKeyType; +import org.gachon.checkmate.domain.post.entity.SortType; +import org.springframework.data.domain.Pageable; + +import static org.gachon.checkmate.global.utils.EnumValueUtils.toEntityCode; + +@Builder(access = AccessLevel.PRIVATE) +public record PostSearchCondition( + ImportantKeyType importantKeyType, + GenderType genderType, + @NotNull SortType sortType, + Pageable pageable + +) { + public static PostSearchCondition of(@NotNull String sortType, String importantKeyType, String genderType, Pageable pageable) { + return PostSearchCondition.builder() + .importantKeyType(importantKeyType != null ? toEntityCode(ImportantKeyType.class, importantKeyType) : null) + .genderType(genderType != null ? toEntityCode(GenderType.class, genderType) : null) + .sortType(toEntityCode(SortType.class, sortType)) + .pageable(pageable) + .build(); + + } +} diff --git a/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchDto.java b/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchDto.java index e77d8cf..9c003e0 100644 --- a/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchDto.java +++ b/src/main/java/org/gachon/checkmate/domain/post/dto/support/PostSearchDto.java @@ -2,6 +2,7 @@ import com.querydsl.core.annotations.QueryProjection; import org.gachon.checkmate.domain.checkList.entity.PostCheckList; +import org.gachon.checkmate.domain.member.entity.GenderType; import org.gachon.checkmate.domain.post.entity.ImportantKeyType; import org.gachon.checkmate.domain.post.entity.SimilarityKeyType; @@ -15,10 +16,11 @@ public record PostSearchDto( SimilarityKeyType similarityKey, LocalDate endDate, int scrapCount, - PostCheckList postCheckList + PostCheckList postCheckList, + GenderType genderType ) { @QueryProjection - public PostSearchDto(Long postId, String title, String content, ImportantKeyType importantKey, SimilarityKeyType similarityKey, LocalDate endDate, int scrapCount, PostCheckList postCheckList) { + public PostSearchDto(Long postId, String title, String content, ImportantKeyType importantKey, SimilarityKeyType similarityKey, LocalDate endDate, int scrapCount, PostCheckList postCheckList, GenderType genderType) { this.postId = postId; this.title = title; this.content = content; @@ -27,5 +29,6 @@ public PostSearchDto(Long postId, String title, String content, ImportantKeyType this.endDate = endDate; this.scrapCount = scrapCount; this.postCheckList = postCheckList; + this.genderType = genderType; } } diff --git a/src/main/java/org/gachon/checkmate/domain/post/repository/PostQuerydslRepository.java b/src/main/java/org/gachon/checkmate/domain/post/repository/PostQuerydslRepository.java index 197cb9b..28b7ecf 100644 --- a/src/main/java/org/gachon/checkmate/domain/post/repository/PostQuerydslRepository.java +++ b/src/main/java/org/gachon/checkmate/domain/post/repository/PostQuerydslRepository.java @@ -4,10 +4,8 @@ import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import org.gachon.checkmate.domain.post.dto.support.PostDetailDto; -import org.gachon.checkmate.domain.post.dto.support.PostSearchDto; -import org.gachon.checkmate.domain.post.dto.support.QPostDetailDto; -import org.gachon.checkmate.domain.post.dto.support.QPostSearchDto; +import org.gachon.checkmate.domain.member.entity.GenderType; +import org.gachon.checkmate.domain.post.dto.support.*; import org.gachon.checkmate.domain.post.entity.ImportantKeyType; import org.gachon.checkmate.domain.post.entity.Post; import org.springframework.data.domain.Page; @@ -22,6 +20,7 @@ import static org.gachon.checkmate.domain.checkList.entity.QPostCheckList.postCheckList; import static org.gachon.checkmate.domain.member.entity.QUser.user; import static org.gachon.checkmate.domain.post.entity.QPost.post; +import static org.springframework.util.StringUtils.hasText; @RequiredArgsConstructor @Repository @@ -47,7 +46,7 @@ public Optional findPostDetail(Long postId) { .fetchOne()); } - public Page findAllPosts(Pageable pageable) { + public Page searchPosts(PostSearchCondition condition) { List content = queryFactory .select(new QPostSearchDto( post.id, @@ -57,43 +56,22 @@ public Page findAllPosts(Pageable pageable) { post.similarityKeyType, post.endDate, post.scrapList.size(), - postCheckList - )) - .from(post) - .leftJoin(post.postCheckList, postCheckList) - .where( - validatePostDate() - ) - .fetch(); - - JPAQuery countQuery = queryFactory - .selectFrom(post); - return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount); - } - - public Page searchKeyPost(ImportantKeyType importantKeyType, Pageable pageable) { - List content = queryFactory - .select(new QPostSearchDto( - post.id, - post.title, - post.content, - post.importantKeyType, - post.similarityKeyType, - post.endDate, - post.scrapList.size(), - postCheckList + postCheckList, + user.gender )) .from(post) .leftJoin(post.postCheckList, postCheckList) + .leftJoin(post.user, user) .where( - containKeyWordCondition(importantKeyType), + eqImportantKey(condition.importantKeyType()), + eqGenderType(condition.genderType()), validatePostDate() ) .fetch(); JPAQuery countQuery = queryFactory .selectFrom(post); - return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount); + return PageableExecutionUtils.getPage(content, condition.pageable(), countQuery::fetchCount); } public Page searchTextPost(String text, Pageable pageable) { @@ -106,10 +84,12 @@ public Page searchTextPost(String text, Pageable pageable) { post.similarityKeyType, post.endDate, post.scrapList.size(), - postCheckList + postCheckList, + user.gender )) .from(post) .leftJoin(post.postCheckList, postCheckList) + .leftJoin(post.user, user) .where( containTextCondition(text), validatePostDate() @@ -127,12 +107,16 @@ private BooleanExpression eqPostId(Long postId) { return post.id.eq(postId); } - private BooleanExpression containKeyWordCondition(ImportantKeyType importantKeyType) { - return post.importantKeyType.eq(importantKeyType); + private BooleanExpression eqGenderType(GenderType genderType) { + return genderType != null ? user.gender.eq(genderType) : null; + } + + private BooleanExpression eqImportantKey(ImportantKeyType importantKeyType) { + return importantKeyType != null ? post.importantKeyType.eq(importantKeyType) : null; } private BooleanExpression containTextCondition(String text) { - return post.title.contains(text); + return hasText(text) ? post.title.contains(text) : null; } private BooleanExpression validatePostDate() { diff --git a/src/main/java/org/gachon/checkmate/domain/post/service/PostService.java b/src/main/java/org/gachon/checkmate/domain/post/service/PostService.java index 1109ccc..9d69291 100644 --- a/src/main/java/org/gachon/checkmate/domain/post/service/PostService.java +++ b/src/main/java/org/gachon/checkmate/domain/post/service/PostService.java @@ -14,8 +14,8 @@ import org.gachon.checkmate.domain.post.dto.response.PostSearchElementResponseDto; import org.gachon.checkmate.domain.post.dto.response.PostSearchResponseDto; import org.gachon.checkmate.domain.post.dto.support.PostDetailDto; +import org.gachon.checkmate.domain.post.dto.support.PostSearchCondition; import org.gachon.checkmate.domain.post.dto.support.PostSearchDto; -import org.gachon.checkmate.domain.post.entity.ImportantKeyType; import org.gachon.checkmate.domain.post.entity.Post; import org.gachon.checkmate.domain.post.entity.SortType; import org.gachon.checkmate.domain.post.repository.PostQuerydslRepository; @@ -31,11 +31,9 @@ import java.time.temporal.ChronoUnit; import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import static org.gachon.checkmate.global.error.ErrorCode.*; -import static org.gachon.checkmate.global.utils.EnumValueUtils.toEntityCode; import static org.gachon.checkmate.global.utils.PagingUtils.convertPaging; @@ -56,12 +54,12 @@ public void createPost(Long userId, PostCreateRequestDto requestDto) { PostCheckList postCheckList = createPostCheckListAndSave(requestDto.checkList(), post); } - public PostSearchResponseDto getAllPosts(Long userId, String type, Pageable pageable) { + public PostSearchResponseDto getAllPosts(Long userId, String type, String gender, Pageable pageable) { CheckList checkList = getCheckList(userId); - SortType sortType = toEntityCode(SortType.class, type); - Page postSearchList = getAllPostsResults(pageable); + PostSearchCondition condition = PostSearchCondition.of(type, null, gender, pageable); + Page postSearchList = getSearchResults(condition); List searchResults = createPostSearchResponseDto(postSearchList, checkList); - sortByTypeForSearchResults(searchResults, Objects.requireNonNull(sortType)); + sortByTypeForSearchResults(searchResults, condition.sortType()); List pagingSearchResults = convertPaging(searchResults, pageable.getOffset(), pageable.getPageSize()); return PostSearchResponseDto.of(pagingSearchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements()); @@ -73,13 +71,12 @@ public PostDetailResponseDto getPostDetails(Long postId) { return PostDetailResponseDto.of(postDetailDto, checkListResponseDto); } - public PostSearchResponseDto searchKeyWordPost(Long userId, String key, String type, Pageable pageable) { + public PostSearchResponseDto searchKeyWordPost(Long userId, String key, String type, String gender, Pageable pageable) { CheckList checkList = getCheckList(userId); - SortType sortType = toEntityCode(SortType.class, type); - ImportantKeyType importantKeyType = toEntityCode(ImportantKeyType.class, key); - Page postSearchList = getKeySearchResults(importantKeyType, pageable); + PostSearchCondition condition = PostSearchCondition.of(type, key, gender, pageable); + Page postSearchList = getSearchResults(condition); List searchResults = createPostSearchResponseDto(postSearchList, checkList); - sortByTypeForSearchResults(searchResults, Objects.requireNonNull(sortType)); + sortByTypeForSearchResults(searchResults, condition.sortType()); List pagingSearchResults = convertPaging(searchResults, pageable.getOffset(), pageable.getPageSize()); return PostSearchResponseDto.of(pagingSearchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements()); @@ -164,12 +161,8 @@ private PostCheckList createPostCheckListAndSave(CheckListRequestDto checkListRe return postCheckList; } - private Page getAllPostsResults(Pageable pageable) { - return postQuerydslRepository.findAllPosts(pageable); - } - - private Page getKeySearchResults(ImportantKeyType importantKeyType, Pageable pageable) { - return postQuerydslRepository.searchKeyPost(importantKeyType, pageable); + private Page getSearchResults(PostSearchCondition condition) { + return postQuerydslRepository.searchPosts(condition); } private Page getTextSearchResults(String text, Pageable pageable) { diff --git a/src/main/java/org/gachon/checkmate/global/config/auth/SecurityConfig.java b/src/main/java/org/gachon/checkmate/global/config/auth/SecurityConfig.java index acc0f8b..05316b0 100644 --- a/src/main/java/org/gachon/checkmate/global/config/auth/SecurityConfig.java +++ b/src/main/java/org/gachon/checkmate/global/config/auth/SecurityConfig.java @@ -25,7 +25,8 @@ public class SecurityConfig { private final CorsConfig corsConfig; private final JwtProvider jwtProvider; - private static final String[] whiteList = {"/", + private static final String[] whiteList = { + "/", "api/member/email", "api/member/signup", "api/member/signin",