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 16 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 @@ -42,10 +42,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,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 @@ -60,4 +60,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
@@ -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,11 +5,11 @@
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;
Expand Down Expand Up @@ -65,6 +65,7 @@ public Page<PostSearchDto> searchPosts(PostSearchCondition condition) {
.where(
eqImportantKey(condition.importantKeyType()),
eqGenderType(condition.genderType()),
validateUserState(),
validatePostDate()
)
.fetch();
Expand All @@ -75,7 +76,7 @@ public Page<PostSearchDto> searchPosts(PostSearchCondition condition) {
}

@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 @@ -92,16 +93,22 @@ public Page<PostSearchDto> searchTextPost(String text, Pageable pageable) {
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
containTextCondition(text),
containTextCondition(condition.text()),
eqUserId(condition.selectedUser()),
validateUserState(),
validatePostDate()
RyuKwanKon marked this conversation as resolved.
Show resolved Hide resolved
)
.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);
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,6 +127,10 @@ private BooleanExpression containTextCondition(String text) {
return hasText(text) ? post.title.contains(text) : null;
}

private BooleanExpression validateUserState() {
return user.userState.eq(UserState.JOIN);
}

private BooleanExpression validatePostDate() {
return post.endDate.after(LocalDate.now());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
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.PostPagingSearchCondition;
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.Post;
Expand Down Expand Up @@ -53,6 +54,14 @@ public void createPost(Long userId, PostCreateRequestDto requestDto) {
createPostCheckListAndSave(requestDto.checkList(), post);
}

public PostSearchResponseDto getMyPosts(Long userId, Pageable pageable) {
CheckList checkList = getCheckList(userId);
PostPagingSearchCondition condition = PostPagingSearchCondition.searchSelectedUser(userId, pageable);
Page<PostSearchDto> postSearchList = getTextSearchResults(condition);
List<PostSearchElementResponseDto> searchResults = createPostSearchResponseDto(postSearchList, checkList);
return PostSearchResponseDto.of(searchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements());
}

public PostSearchResponseDto getAllPosts(Long userId, String key, String type, String gender, Pageable pageable) {
CheckList checkList = getCheckList(userId);
PostSearchCondition condition = PostSearchCondition.of(type, key, gender, pageable);
Expand All @@ -72,7 +81,8 @@ public PostDetailResponseDto getPostDetails(Long postId) {

public PostSearchResponseDto searchTextPost(Long userId, String text, Pageable pageable) {
CheckList checkList = getCheckList(userId);
Page<PostSearchDto> postSearchList = getTextSearchResults(text, pageable);
PostPagingSearchCondition condition = PostPagingSearchCondition.searchText(text, pageable);
Page<PostSearchDto> postSearchList = getTextSearchResults(condition);
List<PostSearchElementResponseDto> searchResults = createPostSearchResponseDto(postSearchList, checkList);
return PostSearchResponseDto.of(searchResults, postSearchList.getTotalPages(), postSearchList.getTotalElements());
}
Expand Down Expand Up @@ -149,18 +159,17 @@ private Post createPostAndSave(PostCreateRequestDto postCreateRequestDto, User u
return post;
}

private PostCheckList createPostCheckListAndSave(CheckListRequestDto checkListRequestDto, Post post) {
private void createPostCheckListAndSave(CheckListRequestDto checkListRequestDto, Post post) {
PostCheckList postCheckList = PostCheckList.createPostCheckList(checkListRequestDto, post);
postCheckListRepository.save(postCheckList);
return postCheckList;
}

private Page<PostSearchDto> getSearchResults(PostSearchCondition condition) {
return postRepository.searchPosts(condition);
}

private Page<PostSearchDto> getTextSearchResults(String text, Pageable pageable) {
return postRepository.searchTextPost(text, pageable);
private Page<PostSearchDto> getTextSearchResults(PostPagingSearchCondition condition) {
return postRepository.searchPostsWithPaging(condition);
}

private CheckList getCheckList(Long userId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.gachon.checkmate.domain.scrap.controller;

import lombok.RequiredArgsConstructor;
import org.gachon.checkmate.domain.post.dto.response.PostSearchResponseDto;
import org.gachon.checkmate.domain.scrap.dto.request.ScrapRequestDto;
import org.gachon.checkmate.domain.scrap.service.ScrapService;
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.web.bind.annotation.*;

@RequiredArgsConstructor
@RequestMapping("/api/scrap")
@RestController
public class ScrapController {
private final ScrapService scrapService;

@GetMapping
public ResponseEntity<SuccessResponse<?>> getScrapPosts(@UserId final Long userId,
final Pageable pageable) {
final PostSearchResponseDto responseDto = scrapService.getScrapPosts(userId, pageable);
return SuccessResponse.ok(responseDto);
}

@PostMapping
public ResponseEntity<SuccessResponse<?>> createScrapPost(@UserId final Long userId,
@RequestBody final ScrapRequestDto requestDto) {
scrapService.creatScrapPost(userId, requestDto);
return SuccessResponse.created(null);
}

@DeleteMapping("/{id}")
public ResponseEntity<SuccessResponse<?>> deleteScrapPost(@UserId final Long userId,
@PathVariable("id") final Long scrapId) {
scrapService.deleteScrapPost(userId, scrapId);
return SuccessResponse.ok(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.gachon.checkmate.domain.scrap.dto.request;

public record ScrapRequestDto(
Long postId
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gachon.checkmate.domain.scrap.dto.support;

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

@Builder
public record ScrapSearchCondition(
Long userId,
Pageable pageable
) {
public static ScrapSearchCondition of(Long userId, Pageable pageable) {
return ScrapSearchCondition.builder()
.userId(userId)
.pageable(pageable)
.build();
}
}
10 changes: 10 additions & 0 deletions src/main/java/org/gachon/checkmate/domain/scrap/entity/Scrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,14 @@ public class Scrap extends BaseTimeEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;

public static Scrap createScrap(User user, Post post) {
Scrap scrap = Scrap.builder()
.user(user)
.post(post)
.build();
user.addScrap(scrap);
post.addScrap(scrap);
return scrap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.gachon.checkmate.domain.scrap.repository;

import org.gachon.checkmate.domain.post.dto.support.PostSearchDto;
import org.gachon.checkmate.domain.scrap.dto.support.ScrapSearchCondition;
import org.springframework.data.domain.Page;

public interface ScrapCustomRepository {
Page<PostSearchDto> searchMyScrapPosts(ScrapSearchCondition condition);
}
Loading