Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] 성별 검색 필터 기능 추가 #28

Merged
merged 8 commits into from
Jan 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,8 +24,9 @@ public class PostController {
@GetMapping
public ResponseEntity<SuccessResponse<?>> 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);
}

Expand All @@ -44,14 +48,15 @@ public ResponseEntity<SuccessResponse<?>> searchTextPost(@UserId final Long user
public ResponseEntity<SuccessResponse<?>> 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<SuccessResponse<?>> createPost(@UserId final Long userId,
@Valid @RequestBody final PostCreateRequestDto requestDto) {
@RequestBody @Valid final PostCreateRequestDto requestDto) {
postService.createPost(userId, requestDto);
return SuccessResponse.ok(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -26,6 +27,7 @@ public static PostSearchElementResponseDto of(PostSearchDto postSearchDto,
.scrapCount(postSearchDto.scrapCount())
.remainDate(remainDate)
.accuracy(accuracy)
.gender(postSearchDto.genderType().getDesc())
.build();
}
}
RyuKwanKon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -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();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -47,7 +46,7 @@ public Optional<PostDetailDto> findPostDetail(Long postId) {
.fetchOne());
}

public Page<PostSearchDto> findAllPosts(Pageable pageable) {
public Page<PostSearchDto> searchPosts(PostSearchCondition condition) {
List<PostSearchDto> content = queryFactory
.select(new QPostSearchDto(
post.id,
Expand All @@ -57,43 +56,22 @@ public Page<PostSearchDto> findAllPosts(Pageable pageable) {
post.similarityKeyType,
post.endDate,
post.scrapList.size(),
postCheckList
))
.from(post)
.leftJoin(post.postCheckList, postCheckList)
.where(
validatePostDate()
)
.fetch();

JPAQuery<Post> countQuery = queryFactory
.selectFrom(post);
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount);
}

public Page<PostSearchDto> searchKeyPost(ImportantKeyType importantKeyType, Pageable pageable) {
List<PostSearchDto> 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<Post> countQuery = queryFactory
.selectFrom(post);
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount);
return PageableExecutionUtils.getPage(content, condition.pageable(), countQuery::fetchCount);
}

public Page<PostSearchDto> searchTextPost(String text, Pageable pageable) {
Expand All @@ -106,10 +84,12 @@ public Page<PostSearchDto> 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()
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;


Expand All @@ -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<PostSearchDto> postSearchList = getAllPostsResults(pageable);
PostSearchCondition condition = PostSearchCondition.of(type, null, gender, pageable);
Page<PostSearchDto> postSearchList = getSearchResults(condition);
List<PostSearchElementResponseDto> searchResults = createPostSearchResponseDto(postSearchList, checkList);
sortByTypeForSearchResults(searchResults, Objects.requireNonNull(sortType));
sortByTypeForSearchResults(searchResults, condition.sortType());
List<PostSearchElementResponseDto> pagingSearchResults
= convertPaging(searchResults, pageable.getOffset(), pageable.getPageSize());
return PostSearchResponseDto.of(pagingSearchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements());
Expand All @@ -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<PostSearchDto> postSearchList = getKeySearchResults(importantKeyType, pageable);
PostSearchCondition condition = PostSearchCondition.of(type, key, gender, pageable);
Page<PostSearchDto> postSearchList = getSearchResults(condition);
List<PostSearchElementResponseDto> searchResults = createPostSearchResponseDto(postSearchList, checkList);
sortByTypeForSearchResults(searchResults, Objects.requireNonNull(sortType));
sortByTypeForSearchResults(searchResults, condition.sortType());
List<PostSearchElementResponseDto> pagingSearchResults
= convertPaging(searchResults, pageable.getOffset(), pageable.getPageSize());
return PostSearchResponseDto.of(pagingSearchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements());
Expand Down Expand Up @@ -164,12 +161,8 @@ private PostCheckList createPostCheckListAndSave(CheckListRequestDto checkListRe
return postCheckList;
}

private Page<PostSearchDto> getAllPostsResults(Pageable pageable) {
return postQuerydslRepository.findAllPosts(pageable);
}

private Page<PostSearchDto> getKeySearchResults(ImportantKeyType importantKeyType, Pageable pageable) {
return postQuerydslRepository.searchKeyPost(importantKeyType, pageable);
private Page<PostSearchDto> getSearchResults(PostSearchCondition condition) {
return postQuerydslRepository.searchPosts(condition);
}

private Page<PostSearchDto> getTextSearchResults(String text, Pageable pageable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down