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

[feat] 스크랩, 내가 작성한 게시글 조회 api 구현 #36

Merged
merged 20 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
561544f
[feat] #34 내가 작성한 게시물 조회 api controller 구현
RyuKwanKon Jan 11, 2024
17d622a
[feat] #34 내가 작성한 게시물 조회 api service 구현
RyuKwanKon Jan 11, 2024
004effa
[fix] #34 게시물 조회 쿼리를 custom paging과 spring paging 사용여부로 구분
RyuKwanKon Jan 11, 2024
2fb0319
[feat] #34 spring paging 사용 조회 condition 구현
RyuKwanKon Jan 11, 2024
68a260d
Merge remote-tracking branch 'origin/develop' into feature/34-post
RyuKwanKon Jan 11, 2024
0503746
[feat] #34 scrap mapping 관계 정의
RyuKwanKon Jan 11, 2024
5313b7a
[feat] #34 scrap crd api controller 구현
RyuKwanKon Jan 11, 2024
9489190
[feat] #34 scrap crd api service 구현
RyuKwanKon Jan 11, 2024
4f26b0f
[feat] #34 user 상태 관리 enum 추가
RyuKwanKon Jan 11, 2024
29d99ec
[feat] #34 scrap 검색 조건 객체 구현
RyuKwanKon Jan 11, 2024
7373838
[feat] #34 scrap 생성 request dto 구현
RyuKwanKon Jan 11, 2024
78a6fa3
[feat] #34 scrap query dsl 추상화 및 구현
RyuKwanKon Jan 11, 2024
6fbe42e
[feat] #34 scrap jpa repository 및 custom repository 추상화
RyuKwanKon Jan 11, 2024
b025c82
[feat] #34 유저 상태 관리에 따른 조회 조건 추가
RyuKwanKon Jan 11, 2024
b426f79
[fix] #34 게시글 생성 response header 변경
RyuKwanKon Jan 11, 2024
6dbb27d
[fix] #34 scrap 삭제 api userId 조건 추가
RyuKwanKon Jan 11, 2024
da34e9c
[fix] #34 개인 게시물 작성 조회에서 지난 게시글 조회 가능
RyuKwanKon Jan 11, 2024
ad56643
[fix] #34 지난 게시글 조회 가능
RyuKwanKon Jan 11, 2024
a146fa1
[fix] #34 post 모집중, 모집 완료 상태 관리 및 조회 dto 추가
RyuKwanKon Jan 11, 2024
7a4d11e
[fix] #34 post 상세 조회시 scrap 여부 데이터 추가
RyuKwanKon Jan 11, 2024
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
@@ -0,0 +1,10 @@
package org.gachon.checkmate.domain.member.converter;

import org.gachon.checkmate.domain.member.entity.UserState;
import org.gachon.checkmate.global.utils.AbstractEnumCodeAttributeConverter;

public class UserStateConverter extends AbstractEnumCodeAttributeConverter<UserState> {
public UserStateConverter() {
super(UserState.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.gachon.checkmate.domain.checkList.entity.CheckList;
import org.gachon.checkmate.domain.member.converter.GenderTypeConverter;
import org.gachon.checkmate.domain.member.converter.MbtiTypeConverter;
import org.gachon.checkmate.domain.member.converter.UserStateConverter;
import org.gachon.checkmate.domain.post.entity.Post;
import org.gachon.checkmate.domain.scrap.entity.Scrap;
import org.gachon.checkmate.global.common.BaseTimeEntity;
Expand All @@ -29,6 +30,8 @@ public class User extends BaseTimeEntity {
private String profile;
private String school;
private String major;
@Convert(converter = UserStateConverter.class)
private UserState userState;
@Convert(converter = MbtiTypeConverter.class)
private MbtiType mbtiType;
@Convert(converter = GenderTypeConverter.class)
Expand Down Expand Up @@ -70,4 +73,8 @@ public void setProfile(String profile) {
public void addPost(Post post) {
this.postList.add(post);
}

public void addScrap(Scrap scrap) {
this.scrapList.add(scrap);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.gachon.checkmate.domain.member.entity;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.gachon.checkmate.global.utils.EnumField;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum UserState implements EnumField {
JOIN("1", "가입"),
WITHDRAW("2", "탈퇴");

private final String code;
private final String desc;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ public ResponseEntity<SuccessResponse<?>> getAllPosts(@UserId final Long userId,
}

@GetMapping("/{id}")
public ResponseEntity<SuccessResponse<?>> getPostDetails(@PathVariable("id") final Long postId) {
final PostDetailResponseDto responseDto = postService.getPostDetails(postId);
public ResponseEntity<SuccessResponse<?>> getPostDetails(@UserId final Long userId,
@PathVariable("id") final Long postId) {
final PostDetailResponseDto responseDto = postService.getPostDetails(userId, postId);
return SuccessResponse.ok(responseDto);
}

Expand All @@ -42,10 +43,17 @@ public ResponseEntity<SuccessResponse<?>> searchTextPost(@UserId final Long user
return SuccessResponse.ok(responseDto);
}

@GetMapping("/my")
public ResponseEntity<SuccessResponse<?>> getMyPosts(@UserId final Long userId,
final Pageable pageable) {
final PostSearchResponseDto responseDto = postService.getMyPosts(userId, pageable);
return SuccessResponse.ok(responseDto);
}

@PostMapping
public ResponseEntity<SuccessResponse<?>> createPost(@UserId final Long userId,
@RequestBody @Valid final PostCreateRequestDto requestDto) {
postService.createPost(userId, requestDto);
return SuccessResponse.ok(null);
return SuccessResponse.created(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.gachon.checkmate.domain.post.converter;

import org.gachon.checkmate.domain.post.entity.PostState;
import org.gachon.checkmate.global.utils.AbstractEnumCodeAttributeConverter;

public class PostStateConverter extends AbstractEnumCodeAttributeConverter<PostState> {
public PostStateConverter() {
super(PostState.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ public record PostDetailResponseDto(
String profile,
String gender,
String mbti,
boolean isScrap,
CheckListResponseDto checkList
) {
public static PostDetailResponseDto of(PostDetailDto postDetailDto, CheckListResponseDto checkList) {
public static PostDetailResponseDto of(PostDetailDto postDetailDto, CheckListResponseDto checkList, boolean isScrap) {
return PostDetailResponseDto.builder()
.name(postDetailDto.name())
.major(postDetailDto.major())
.profile(postDetailDto.profile())
.gender(postDetailDto.gender().getDesc())
.mbti(postDetailDto.mbti().getDesc())
.isScrap(isScrap)
.checkList(checkList)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public record PostSearchElementResponseDto(
int scrapCount,
int remainDate,
int accuracy,
String gender
String gender,
String postState
) {
public static PostSearchElementResponseDto of(PostSearchDto postSearchDto,
int remainDate,
Expand All @@ -28,6 +29,7 @@ public static PostSearchElementResponseDto of(PostSearchDto postSearchDto,
.remainDate(remainDate)
.accuracy(accuracy)
.gender(postSearchDto.genderType().getDesc())
.postState(postSearchDto.postState().getDesc())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.gachon.checkmate.domain.post.dto.support;

import lombok.Builder;
import org.springframework.data.domain.Pageable;

@Builder
public record PostPagingSearchCondition(
String text,
Long selectedUser,
Pageable pageable
) {
public static PostPagingSearchCondition searchText(String text, Pageable pageable) {
return PostPagingSearchCondition.builder()
.text(text)
.selectedUser(null)
.pageable(pageable)
.build();
}

public static PostPagingSearchCondition searchSelectedUser(Long userId, Pageable pageable) {
return PostPagingSearchCondition.builder()
.text(null)
.selectedUser(userId)
.pageable(pageable)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
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.PostState;
import org.gachon.checkmate.domain.post.entity.SimilarityKeyType;

import java.time.LocalDate;
Expand All @@ -17,10 +18,11 @@ public record PostSearchDto(
LocalDate endDate,
int scrapCount,
PostCheckList postCheckList,
GenderType genderType
GenderType genderType,
PostState postState
) {
@QueryProjection
public PostSearchDto(Long postId, String title, String content, ImportantKeyType importantKey, SimilarityKeyType similarityKey, LocalDate endDate, int scrapCount, PostCheckList postCheckList, GenderType genderType) {
public PostSearchDto(Long postId, String title, String content, ImportantKeyType importantKey, SimilarityKeyType similarityKey, LocalDate endDate, int scrapCount, PostCheckList postCheckList, GenderType genderType, PostState postState) {
this.postId = postId;
this.title = title;
this.content = content;
Expand All @@ -30,5 +32,6 @@ public PostSearchDto(Long postId, String title, String content, ImportantKeyType
this.scrapCount = scrapCount;
this.postCheckList = postCheckList;
this.genderType = genderType;
this.postState = postState;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.gachon.checkmate.domain.checkList.entity.PostCheckList;
import org.gachon.checkmate.domain.member.entity.User;
import org.gachon.checkmate.domain.post.converter.ImportantKeyTypeConverter;
import org.gachon.checkmate.domain.post.converter.PostStateConverter;
import org.gachon.checkmate.domain.post.converter.RoomTypeConverter;
import org.gachon.checkmate.domain.post.converter.SimilarityKeyTypeConverter;
import org.gachon.checkmate.domain.post.dto.request.PostCreateRequestDto;
Expand All @@ -28,6 +29,8 @@ public class Post extends BaseTimeEntity {
private String title;
private String content;
private LocalDate endDate;
@Convert(converter = PostStateConverter.class)
private PostState postState;
@Convert(converter = RoomTypeConverter.class)
private RoomType roomType;
@Convert(converter = ImportantKeyTypeConverter.class)
Expand Down Expand Up @@ -60,4 +63,8 @@ public static Post createPost(PostCreateRequestDto postCreateRequestDto, User us
public void setPostCheckList(PostCheckList postCheckList) {
this.postCheckList = postCheckList;
}

public void addScrap(Scrap scrap) {
this.scrapList.add(scrap);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.gachon.checkmate.domain.post.entity;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.gachon.checkmate.global.utils.EnumField;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum PostState implements EnumField {
RECRUITING("1", "모집중"),
COMPLETE("2", "모집완료");

private String code;
private String desc;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.gachon.checkmate.domain.post.repository;

import org.gachon.checkmate.domain.post.dto.support.PostDetailDto;
import org.gachon.checkmate.domain.post.dto.support.PostPagingSearchCondition;
import org.gachon.checkmate.domain.post.dto.support.PostSearchCondition;
import org.gachon.checkmate.domain.post.dto.support.PostSearchDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Optional;

public interface PostCustomRepository {
Optional<PostDetailDto> findPostDetail(Long postId);
Page<PostSearchDto> searchPosts(PostSearchCondition condition);
Page<PostSearchDto> searchTextPost(String text, Pageable pageable);
Page<PostSearchDto> searchPostsWithPaging(PostPagingSearchCondition condition);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.gachon.checkmate.domain.member.entity.GenderType;
import org.gachon.checkmate.domain.member.entity.UserState;
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;
import org.springframework.data.domain.Pageable;
import org.springframework.data.support.PageableExecutionUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -57,25 +56,33 @@ public Page<PostSearchDto> searchPosts(PostSearchCondition condition) {
post.endDate,
post.scrapList.size(),
postCheckList,
user.gender
user.gender,
post.postState
))
.from(post)
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
eqImportantKey(condition.importantKeyType()),
eqGenderType(condition.genderType()),
validatePostDate()
validateUserState()
)
.fetch();

JPAQuery<Post> countQuery = queryFactory
.selectFrom(post);
.selectFrom(post)
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
eqImportantKey(condition.importantKeyType()),
eqGenderType(condition.genderType()),
validateUserState()
);
return PageableExecutionUtils.getPage(content, condition.pageable(), countQuery::fetchCount);
}

@Override
public Page<PostSearchDto> searchTextPost(String text, Pageable pageable) {
public Page<PostSearchDto> searchPostsWithPaging(PostPagingSearchCondition condition) {
List<PostSearchDto> content = queryFactory
.select(new QPostSearchDto(
post.id,
Expand All @@ -86,22 +93,36 @@ public Page<PostSearchDto> searchTextPost(String text, Pageable pageable) {
post.endDate,
post.scrapList.size(),
postCheckList,
user.gender
user.gender,
post.postState
))
.from(post)
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
containTextCondition(text),
validatePostDate()
containTextCondition(condition.text()),
eqUserId(condition.selectedUser()),
validateUserState()
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.offset(condition.pageable().getOffset())
.limit(condition.pageable().getPageSize())
.fetch();

JPAQuery<Post> countQuery = queryFactory
.selectFrom(post);
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount);
.selectFrom(post)
.from(post)
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
containTextCondition(condition.text()),
eqUserId(condition.selectedUser()),
validateUserState()
);
return PageableExecutionUtils.getPage(content, condition.pageable(), countQuery::fetchCount);
}

private BooleanExpression eqUserId(Long userId) {
return userId != null ? user.id.eq(userId) : null;
}

private BooleanExpression eqPostId(Long postId) {
Expand All @@ -120,7 +141,7 @@ private BooleanExpression containTextCondition(String text) {
return hasText(text) ? post.title.contains(text) : null;
}

private BooleanExpression validatePostDate() {
return post.endDate.after(LocalDate.now());
private BooleanExpression validateUserState() {
return user.userState.eq(UserState.JOIN);
}
}
Loading