From 5be7b7b51aee13811a171684eef6a4e5df192202 Mon Sep 17 00:00:00 2001 From: moonyaeyoon Date: Sat, 27 Jul 2024 12:51:37 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=EC=9E=84=EC=8B=9C=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/domain/entity/post/Post.java | 5 ++ .../domain/repository/PostRepository.java | 3 + .../post/controller/PostController.java | 19 +++- .../server/post/dto/PostDetailResponse.java | 15 ++++ .../post/dto/TempPostDetailResponse.java | 4 + .../server/post/service/PostService.java | 86 ++++++++++++++----- .../meltingpot/server/util/ResponseCode.java | 1 + 7 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 src/main/java/meltingpot/server/post/dto/TempPostDetailResponse.java diff --git a/src/main/java/meltingpot/server/domain/entity/post/Post.java b/src/main/java/meltingpot/server/domain/entity/post/Post.java index f6de4a3..0af91f4 100644 --- a/src/main/java/meltingpot/server/domain/entity/post/Post.java +++ b/src/main/java/meltingpot/server/domain/entity/post/Post.java @@ -35,6 +35,8 @@ public class Post extends BaseEntity { @Enumerated(EnumType.STRING) private PostType postType; + private Boolean isDraft; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private Account account; @@ -61,4 +63,7 @@ public void setPostImages(List postImages) { .collect(Collectors.toList()); } + public void setIsDraft(boolean isDraft) { + this.isDraft = isDraft; } +} diff --git a/src/main/java/meltingpot/server/domain/repository/PostRepository.java b/src/main/java/meltingpot/server/domain/repository/PostRepository.java index 919f43a..aa22264 100644 --- a/src/main/java/meltingpot/server/domain/repository/PostRepository.java +++ b/src/main/java/meltingpot/server/domain/repository/PostRepository.java @@ -14,6 +14,7 @@ import org.springframework.data.domain.Pageable; import java.util.List; +import java.util.Optional; public interface PostRepository extends JpaRepository { @@ -23,4 +24,6 @@ public interface PostRepository extends JpaRepository { Slice findAllByAccountAndDeletedAtIsNullOrderByIdDesc(Account account, Pageable page); Slice findByIdAndDeletedAtIsNull(Long id); + + Optional findByAccountAndIsDraftTrue(Account account); } diff --git a/src/main/java/meltingpot/server/post/controller/PostController.java b/src/main/java/meltingpot/server/post/controller/PostController.java index 5d917f0..ea1469f 100644 --- a/src/main/java/meltingpot/server/post/controller/PostController.java +++ b/src/main/java/meltingpot/server/post/controller/PostController.java @@ -27,11 +27,14 @@ public class PostController { private final PostService postService; - @Operation(summary = "게시물 작성, 이미지가 없을 때는 빈 값으로 주시면 됩니다. ") + @Operation(summary = "게시물 작성", description="requestParam으로 임시저장 여부를 알려주세요." + + "이미지가 없을 때는 빈 값으로 주시면 됩니다.") @PostMapping("") - public ResponseEntity createPost( @CurrentUser Account account,@RequestBody PostCreateRequest createPostDTO) { + public ResponseEntity createPost( @CurrentUser Account account, + @RequestBody PostCreateRequest postCreateRequest, + @RequestParam boolean isDraft) { try{ - return ResponseData.toResponseEntity(postService.createPost(createPostDTO,account)); + return ResponseData.toResponseEntity(postService.createPost(postCreateRequest,account,isDraft)); }catch (NoSuchElementException e) { return ResponseData.toResponseEntity(ResponseCode.POST_CREATE_FAIL); } @@ -83,4 +86,14 @@ public ResponseEntity deletePost(@CurrentUser Account account,@Pat } } + @GetMapping("/temp-saved") + @Operation(summary = "임시저장된 글 불러오기", description = "임시저장된 글 불러오기") + public ResponseEntity> getTempPost(@CurrentUser Account account) { + try { + return ResponseData.toResponseEntity(ResponseCode.POST_DETAIL_FETCH_SUCCEESS,postService.getTempPost(account)); + } catch (NoSuchElementException e) { + return ResponseData.toResponseEntity(ResponseCode.POST_NOT_FOUND,null); + } + } + } diff --git a/src/main/java/meltingpot/server/post/dto/PostDetailResponse.java b/src/main/java/meltingpot/server/post/dto/PostDetailResponse.java index 6ae5bdf..d127568 100644 --- a/src/main/java/meltingpot/server/post/dto/PostDetailResponse.java +++ b/src/main/java/meltingpot/server/post/dto/PostDetailResponse.java @@ -52,4 +52,19 @@ public static PostDetailResponse of(Post post, CommentsListResponse commentsList .updatedAt(post.getUpdatedAt()) .build(); } + + public static PostDetailResponse from(Post post) { + List imgData = post.getPostImages().stream() + .map(postImage -> new ImageData(postImage.getId(), postImage.getImageUrl())) + .collect(Collectors.toList()); + + return PostDetailResponse.builder() + .postId(post.getId()) + .name(post.getAccount().getName()) + .title(post.getTitle()) + .content(post.getContent()) + .imgData(imgData) + .updatedAt(post.getUpdatedAt()) + .build(); + } } diff --git a/src/main/java/meltingpot/server/post/dto/TempPostDetailResponse.java b/src/main/java/meltingpot/server/post/dto/TempPostDetailResponse.java new file mode 100644 index 0000000..53cb32f --- /dev/null +++ b/src/main/java/meltingpot/server/post/dto/TempPostDetailResponse.java @@ -0,0 +1,4 @@ +package meltingpot.server.post.dto; + +public class TempPostDetailResponse { +} diff --git a/src/main/java/meltingpot/server/post/service/PostService.java b/src/main/java/meltingpot/server/post/service/PostService.java index 4391b32..cea9374 100644 --- a/src/main/java/meltingpot/server/post/service/PostService.java +++ b/src/main/java/meltingpot/server/post/service/PostService.java @@ -4,8 +4,9 @@ import lombok.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; import java.util.stream.Collectors; import meltingpot.server.comment.dto.CommentsListResponse; @@ -25,10 +26,13 @@ import meltingpot.server.util.r2.FileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.data.domain.Pageable; +import org.springframework.web.server.ResponseStatusException; +import static meltingpot.server.util.ResponseCode.POST_NOT_FOUND; @Service @@ -44,30 +48,34 @@ public class PostService { /*post 작성하기*/ - public ResponseCode createPost(PostCreateRequest createPostDTO,Account account){ - Post post = createPostDTO.toEntity(account); - List postImgUrls = Collections.emptyList(); - List postImages = createPostImages(createPostDTO.getImageKeys(), post, account); - post.setPostImages(postImages); + public ResponseCode createPost(PostCreateRequest postCreateRequest, Account account, boolean isDraft) { + Optional optionalDraft = getDraftPost(account); + Post post = optionalDraft.orElseGet(() -> postCreateRequest.toEntity(account)); + System.out.println("Post " + post.getId() + post.getTitle() + post.getIsDraft()); + + if (optionalDraft.isPresent()) { + updatePostContent(post, account, postCreateRequest); + } + setPostImages(post, account, postCreateRequest); + // isDraft 값을 설정하기 전에 현재 상태 출력 + System.out.println("Setting isDraft for post with ID " + post.getId() + " to " + isDraft); + post.setIsDraft(isDraft); + + // isDraft 값 설정 후 출력 + System.out.println("Post isDraft status: " + post.getIsDraft()); + postRepository.save(post); - return ResponseCode.CREATE_POST_SUCCESS; + + return isDraft ? ResponseCode.DRAFT_SAVE_SUCCESS : ResponseCode.CREATE_POST_SUCCESS; } + /*post 수정하기*/ public ResponseCode updatePost(PostCreateRequest updateRequest,Long postId, Account account){ Post post = findPostById(postId); - - post.setTitle(updateRequest.getTitle()); - post.setContent(updateRequest.getContent()); - - // 기존의 모든 PostImage 삭제 - if (post.getPostImages() != null) { - postImageRepository.deleteAll(post.getPostImages()); - - } - // 새로운 PostImage 설정 - List postImages = createPostImages(updateRequest.getImageKeys(), post, account); - post.setPostImages(postImages); + isAuthenticated ( post, account); + updatePostContent(post, account, updateRequest); + setPostImages(post,account,updateRequest); postRepository.save(post); @@ -95,7 +103,7 @@ public PostsListResponse getPostsList(Account account, PostType postType, Long /*post 삭제하기*/ public ResponseCode deletePost(Long postId, Account account){ Post post = findPostById(postId); - Account postAccount = findAccountById(post.getAccount().getId()); + isAuthenticated ( post, account); // 게시물에 연관된 이미지 삭제 if (!post.getPostImages().isEmpty()) { @@ -114,6 +122,18 @@ public ResponseCode deletePost(Long postId, Account account){ } + /* 임시저장된 글 불러오기 */ + public PostDetailResponse getTempPost (Account account ){ + Optional optionalDraft = getDraftPost(account); + if(optionalDraft.isPresent()){ + Post draftPost = optionalDraft.get(); + return PostDetailResponse.from(draftPost); + }else{ + throw new NoSuchElementException(ResponseCode.POST_NOT_FOUND.getDetail()); + } + } + + private Account findAccountById(Long accountId) { return accountRepository.findById(accountId) @@ -125,6 +145,12 @@ private Post findPostById(Long postId) { .orElseThrow(() -> new RuntimeException("게시글을 찾을 수 없습니다.")); } + private void isAuthenticated (Post post, Account account) { + if (!post.getAccount().getId().equals(account.getId())) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "권한이 없습니다."); + } + } + private List getCdnUrls(List imageKeys) { return imageKeys.stream() .map(imageKey -> { @@ -134,6 +160,19 @@ private List getCdnUrls(List imageKeys) { .collect(Collectors.toList()); } + private void updatePostContent(Post post, Account account, PostCreateRequest updateRequest) { + post.setTitle(updateRequest.getTitle()); + post.setContent(updateRequest.getContent()); + + // 기존의 모든 PostImage 삭제 + if (post.getPostImages() != null && !post.getPostImages().isEmpty()) { + postImageRepository.deleteAll(post.getPostImages()); + post.getPostImages().clear(); + } + } + + + private List createPostImages(List imageKeys, Post post, Account account) { List postImgUrls = getCdnUrls(imageKeys); return postImgUrls.stream() @@ -204,6 +243,13 @@ private CommentsListResponse fetchCommentsList(Long postId, Long cursor, int pag return CommentsListResponse.from(commentDetailDTOs, nextCursor, isLast); } + private Optional getDraftPost(Account account) { + return postRepository.findByAccountAndIsDraftTrue(account); + } + private void setPostImages(Post post, Account account,PostCreateRequest postRequest) { + List postImages = createPostImages(postRequest.getImageKeys(), post, account); + post.setPostImages(postImages); + } } diff --git a/src/main/java/meltingpot/server/util/ResponseCode.java b/src/main/java/meltingpot/server/util/ResponseCode.java index 9aa2556..13b750f 100644 --- a/src/main/java/meltingpot/server/util/ResponseCode.java +++ b/src/main/java/meltingpot/server/util/ResponseCode.java @@ -61,6 +61,7 @@ public enum ResponseCode { SIGNUP_SUCCESS(CREATED, "회원가입 성공"), CREATE_CHAT_ROOM_SUCCESS(CREATED, "채팅방 생성 성공"), CREATE_POST_SUCCESS(CREATED, "게시물 작성 성공"), + DRAFT_SAVE_SUCCESS(CREATED,"게시물 임시 저장 성공"), CREATE_COMMENT_SUCCESS(CREATED, "댓글 작성 성공"), CREATE_CHILD_COMMENT_SUCCESS(CREATED, "대댓글 작성 성공"), REPORT_CREATE_SUCCESS(CREATED, "신고 작성 성공"),