Skip to content

Commit

Permalink
Merge pull request #26 from Domitory-CheckMate/feature/25-post
Browse files Browse the repository at this point in the history
[feat] 게시글 작성 api 구현
  • Loading branch information
RyuKwanKon authored Jan 6, 2024
2 parents a72b8d4 + 757890f commit 8c55b8d
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 9 deletions.
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ dependencies {

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// validate
implementation 'org.springframework.boot:spring-boot-starter-validation'
}

tasks.named('test') {
Expand All @@ -93,4 +96,4 @@ sourceSets {
// gradle clean 시에 QClass 디렉토리 삭제
clean {
delete file(generated)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.persistence.*;
import lombok.*;
import org.gachon.checkmate.domain.checkList.converter.*;
import org.gachon.checkmate.domain.checkList.dto.request.CheckListRequestDto;
import org.gachon.checkmate.domain.post.entity.Post;
import org.gachon.checkmate.global.common.BaseTimeEntity;

Expand Down Expand Up @@ -31,4 +32,18 @@ public class PostCheckList extends BaseTimeEntity {
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;

public static PostCheckList createPostCheckList(CheckListRequestDto checkListRequestDto, Post post) {
PostCheckList checkList = PostCheckList.builder()
.cleanType(checkListRequestDto.cleanType())
.drinkType(checkListRequestDto.drinkType())
.homeType(checkListRequestDto.homeType())
.lifePatterType(checkListRequestDto.lifePatterType())
.noiseType(checkListRequestDto.noiseType())
.sleepType(checkListRequestDto.sleepType())
.post(post)
.build();
post.setPostCheckList(checkList);
return checkList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.gachon.checkmate.domain.checkList.repository;

import org.gachon.checkmate.domain.checkList.entity.PostCheckList;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PostCheckListRepository extends JpaRepository<PostCheckList, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
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.post.converter.RoomTypeConverter;
import org.gachon.checkmate.domain.post.entity.Post;
import org.gachon.checkmate.domain.scrap.entity.Scrap;
import org.gachon.checkmate.global.common.BaseTimeEntity;
Expand Down Expand Up @@ -43,7 +42,7 @@ public class User extends BaseTimeEntity {
@Builder.Default
private List<Scrap> scrapList = new ArrayList<>();

public static User createUser(String email, String storedPassword, String name, String school, String major, MbtiType mbti, GenderType gender, String profile){
public static User createUser(String email, String storedPassword, String name, String school, String major, MbtiType mbti, GenderType gender, String profile) {
return User.builder()
.email(email)
.password(storedPassword)
Expand All @@ -64,7 +63,11 @@ public void setCheckList(CheckList checkList) {
this.checkList = checkList;
}

public void setProfile(String profile){
public void setProfile(String profile) {
this.profile = profile;
}

public void addPost(Post post) {
this.postList.add(post);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.gachon.checkmate.domain.post.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
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.service.PostService;
Expand Down Expand Up @@ -46,4 +48,11 @@ public ResponseEntity<SuccessResponse<?>> searchKeyWordPost(@UserId final Long u
final PostSearchResponseDto responseDto = postService.searchKeyWordPost(userId, key, type, pageable);
return SuccessResponse.ok(responseDto);
}

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

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import lombok.NonNull;
import org.gachon.checkmate.domain.checkList.dto.request.CheckListRequestDto;
import org.gachon.checkmate.domain.post.entity.ImportantKeyType;
import org.gachon.checkmate.domain.post.entity.RoomType;
import org.gachon.checkmate.domain.post.entity.SimilarityKeyType;

import java.time.LocalDate;

public record PostCreateRequestDto(
@NotBlank(message = "제목을 입력해주세요") String title,
@NotBlank(message = "내용을 입력해주세요") String content,
@NotNull(message = "중요 키워드를 입력해주세요") ImportantKeyType importantKey,
@NotNull(message = "유사도를 입력해주세요") SimilarityKeyType similarityKey,
@NotNull(message = "기숙사 유형을 입력해주세요") RoomType roomType,
@NotNull(message = "모집 마감기간을 입력해주세요") LocalDate endDate,
@NotNull(message = "체크리스트를 입력해주세요") CheckListRequestDto checkList
) {
}
21 changes: 20 additions & 1 deletion src/main/java/org/gachon/checkmate/domain/post/entity/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import jakarta.persistence.*;
import lombok.*;
import org.gachon.checkmate.domain.checkList.entity.PostCheckList;
import org.gachon.checkmate.domain.post.converter.RoomTypeConverter;
import org.gachon.checkmate.domain.member.entity.User;
import org.gachon.checkmate.domain.post.converter.ImportantKeyTypeConverter;
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;
import org.gachon.checkmate.domain.scrap.entity.Scrap;
import org.gachon.checkmate.global.common.BaseTimeEntity;

Expand Down Expand Up @@ -41,4 +42,22 @@ public class Post extends BaseTimeEntity {
@OneToMany(mappedBy = "post")
@Builder.Default
private List<Scrap> scrapList = new ArrayList<>();

public static Post createPost(PostCreateRequestDto postCreateRequestDto, User user) {
Post post = Post.builder()
.title(postCreateRequestDto.title())
.content(postCreateRequestDto.content())
.endDate(postCreateRequestDto.endDate())
.roomType(postCreateRequestDto.roomType())
.importantKeyType(postCreateRequestDto.importantKey())
.similarityKeyType(postCreateRequestDto.similarityKey())
.user(user)
.build();
user.addPost(post);
return post;
}

public void setPostCheckList(PostCheckList postCheckList) {
this.postCheckList = postCheckList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Optional<PostDetailDto> findPostDetail(Long postId) {
.leftJoin(post.postCheckList, postCheckList)
.leftJoin(post.user, user)
.where(
containPostId(postId)
eqPostId(postId)
)
.fetchOne());
}
Expand Down Expand Up @@ -123,7 +123,7 @@ public Page<PostSearchDto> searchTextPost(String text, Pageable pageable) {
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount);
}

private BooleanExpression containPostId(Long postId) {
private BooleanExpression eqPostId(Long postId) {
return post.id.eq(postId);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.gachon.checkmate.domain.post.repository;

import org.gachon.checkmate.domain.post.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface PostRepository extends JpaRepository<Post, Long> {
boolean existsByTitle(String title);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package org.gachon.checkmate.domain.post.service;

import lombok.RequiredArgsConstructor;
import org.gachon.checkmate.domain.checkList.dto.request.CheckListRequestDto;
import org.gachon.checkmate.domain.checkList.dto.response.CheckListResponseDto;
import org.gachon.checkmate.domain.checkList.entity.CheckList;
import org.gachon.checkmate.domain.checkList.entity.PostCheckList;
import org.gachon.checkmate.domain.checkList.repository.CheckListRepository;
import org.gachon.checkmate.domain.checkList.repository.PostCheckListRepository;
import org.gachon.checkmate.domain.member.entity.User;
import org.gachon.checkmate.domain.member.repository.UserRepository;
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.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.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;
import org.gachon.checkmate.domain.post.repository.PostRepository;
import org.gachon.checkmate.global.error.exception.EntityNotFoundException;
import org.gachon.checkmate.global.error.exception.InvalidValueException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
Expand All @@ -26,8 +34,7 @@
import java.util.Objects;
import java.util.stream.Collectors;

import static org.gachon.checkmate.global.error.ErrorCode.CHECK_LIST_NOT_FOUND;
import static org.gachon.checkmate.global.error.ErrorCode.POST_NOT_FOUND;
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 @@ -36,8 +43,18 @@
@Transactional
@Service
public class PostService {
private final UserRepository userRepository;
private final CheckListRepository checkListRepository;
private final PostRepository postRepository;
private final PostQuerydslRepository postQuerydslRepository;
private final PostCheckListRepository postCheckListRepository;

public void createPost(Long userId, PostCreateRequestDto requestDto) {
validateDuplicateTitle(requestDto.title());
User user = getUserOrThrow(userId);
Post post = createPostAndSave(requestDto, user);
PostCheckList postCheckList = createPostCheckListAndSave(requestDto.checkList(), post);
}

public PostSearchResponseDto getAllPosts(Long userId, String type, Pageable pageable) {
CheckList checkList = getCheckList(userId);
Expand Down Expand Up @@ -130,6 +147,23 @@ private int getRemainDate(LocalDate endDate) {
return (int) endDate.until(LocalDate.now(), ChronoUnit.DAYS);
}

private void validateDuplicateTitle(String title) {
if (postRepository.existsByTitle(title))
throw new InvalidValueException(INVALID_POST_TITLE);
}

private Post createPostAndSave(PostCreateRequestDto postCreateRequestDto, User user) {
Post post = Post.createPost(postCreateRequestDto, user);
postRepository.save(post);
return post;
}

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

private Page<PostSearchDto> getAllPostsResults(Pageable pageable) {
return postQuerydslRepository.findAllPosts(pageable);
}
Expand All @@ -151,4 +185,9 @@ private PostDetailDto getPostDetailDto(Long postId) {
return postQuerydslRepository.findPostDetail(postId)
.orElseThrow(() -> new EntityNotFoundException(POST_NOT_FOUND));
}

private User getUserOrThrow(Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException(USER_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum ErrorCode {
INVALID_ENUM_CODE(HttpStatus.BAD_REQUEST, "잘못된 Enum class code 입니다."),
INVALID_PAGING_SIZE(HttpStatus.BAD_REQUEST, "잘못된 Paging 크기입니다."),
INVALID_PASSWORD(HttpStatus.BAD_REQUEST, "비밀번호는 8~20자 대소문자 영문, 숫자, 특수문자의 조합이어야 합니다."),
INVALID_POST_TITLE(HttpStatus.BAD_REQUEST, "이미 존재하는 게시물입니다."),

/**
* 401 Unauthorized
Expand Down

0 comments on commit 8c55b8d

Please sign in to comment.