diff --git a/src/main/java/mvp/deplog/domain/member/domain/repository/MemberRepository.java b/src/main/java/mvp/deplog/domain/member/domain/repository/MemberRepository.java index 963dff3..d21d501 100644 --- a/src/main/java/mvp/deplog/domain/member/domain/repository/MemberRepository.java +++ b/src/main/java/mvp/deplog/domain/member/domain/repository/MemberRepository.java @@ -10,4 +10,6 @@ public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); boolean existsByEmail(String email); + + Optional findById(Long id); } diff --git a/src/main/java/mvp/deplog/domain/post/application/PostService.java b/src/main/java/mvp/deplog/domain/post/application/PostService.java index ef293d2..e18ab56 100644 --- a/src/main/java/mvp/deplog/domain/post/application/PostService.java +++ b/src/main/java/mvp/deplog/domain/post/application/PostService.java @@ -354,4 +354,71 @@ public SuccessResponse> getAllTempPosts(Long memberId) { return SuccessResponse.of(TempListRes); } + + @Transactional + public SuccessResponse modifyPost(Long memberId, Long postId, CreatePostReq createPostReq) { + validateTagName(createPostReq.getTagNameList()); + + Post post = postRepository.findById(postId) + .orElseThrow(() -> new ResourceNotFoundException("해당 id의 게시글을 찾을 수 없습니다: " + postId)); + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("해당 id의 멤버를 찾을 수 없습니다: " + memberId)); + + if (!post.getMember().equals(member)) { + throw new UnauthorizedException("본인이 작성한 게시글이 아니므로 수정할 수 없습니다."); + } + + String title = post.getTitle(); + String content = post.getContent(); + String previewContent = post.getPreviewContent(); + String previewImage = post.getPreviewImage(); + + // 수정 전 게시글 내 이미지 url 추출 + List oldImageUrls = MarkdownUtil.extractImageLinks(content); + + if(createPostReq.getTitle() != null) { + title = createPostReq.getTitle(); + } + if(createPostReq.getContent() != null) { + content = createPostReq.getContent(); + previewContent = MarkdownUtil.extractPreviewContent(content); + previewImage = MarkdownUtil.extractPreviewImage(content); + } + + post.updatePost(title, content, previewContent, previewImage, post.getStage()); + + // 수정 후 게시글 내 이미지 url 추출 + List newImageUrls = MarkdownUtil.extractImageLinks(post.getContent()); + + // 기존 이미지 url이 수정된 게시글에 있는지 확인 + for(String oldImageUrl : oldImageUrls) { + if(!newImageUrls.contains(oldImageUrl)) { + fileService.deleteFile(oldImageUrl, DIRNAME); + } + } + + if(createPostReq.getTagNameList() != null && !createPostReq.getTagNameList().isEmpty()) { + taggingRepository.deleteByPost(post); + + for (String tagName : createPostReq.getTagNameList()) { + if(tagName != null) { + Tag tag = tagRepository.findByName(tagName) + .orElseGet(() -> tagRepository.save(Tag.builder().name(tagName).build())); + + Tagging tagging = Tagging.builder() + .post(post) + .tag(tag) + .build(); + + taggingRepository.save(tagging); + } + } + } + + CreatePostRes createPostRes = CreatePostRes.builder() + .postId(postId) + .build(); + + return SuccessResponse.of(createPostRes); + } } diff --git a/src/main/java/mvp/deplog/domain/post/domain/repository/PostRepository.java b/src/main/java/mvp/deplog/domain/post/domain/repository/PostRepository.java index 624d38d..6923cf2 100644 --- a/src/main/java/mvp/deplog/domain/post/domain/repository/PostRepository.java +++ b/src/main/java/mvp/deplog/domain/post/domain/repository/PostRepository.java @@ -11,9 +11,12 @@ import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.Optional; public interface PostRepository extends JpaRepository { + Optional findById(Long id); + @Query("SELECT p FROM Post p WHERE p.member.part IN :parts") Page findByMemberPart(@Param("parts") List partGroup, Pageable pageable); diff --git a/src/main/java/mvp/deplog/domain/post/presentation/PostApi.java b/src/main/java/mvp/deplog/domain/post/presentation/PostApi.java index 34075fb..9c53f06 100644 --- a/src/main/java/mvp/deplog/domain/post/presentation/PostApi.java +++ b/src/main/java/mvp/deplog/domain/post/presentation/PostApi.java @@ -217,10 +217,10 @@ ResponseEntity> createTempPost( content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))} ) }) - @PutMapping("/publishing") + @PutMapping("/publishing/{postId}") ResponseEntity> publishTempPost( @Parameter(description = "Access Token을 입력하세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails, - @Parameter(description = "발행할 임시 저장 게시글의 아이디를 입력하세요.", required = true) @RequestParam(value = "postId") Long postId, + @Parameter(description = "발행할 임시 저장 게시글의 아이디를 입력하세요.", required = true) @PathVariable(value = "postId") Long postId, @Parameter(description = "Schemas의 CreatePostReq를 참고해주세요.", required = true) @RequestBody CreatePostReq createPostReq ); @@ -228,7 +228,7 @@ ResponseEntity> publishTempPost( @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "임시 저장 게시글 목록 조회 성공", - content = {@Content(mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = TempListRes.class)))} + content = {@Content(mediaType = "application/json",array = @ArraySchema(schema = @Schema(implementation = TempListRes.class)))} ), @ApiResponse( responseCode = "400", description = "임시 저장 게시글 목록 조회 실패", @@ -239,4 +239,22 @@ ResponseEntity> publishTempPost( ResponseEntity>> getAllTempPosts( @Parameter(description = "Access Token을 입력하세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails ); + + @Operation(summary = "게시글 수정 API", description = "해당 아이디의 게시글을 수정합니다.") + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", description = "게시글 수정 성공", + content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CreatePostRes.class))} + ), + @ApiResponse( + responseCode = "400", description = "게시글 수정 실패", + content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))} + ) + }) + @PutMapping("/edits/{postId}") + ResponseEntity> modifyPosts( + @Parameter(description = "Access Token을 입력하세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails, + @Parameter(description = "수정할 게시글의 아이디를 입력하세요.", required = true) @PathVariable(value = "postId") Long postId, + @Parameter(description = "Schemas의 CreatePostReq를 참고해주세요.", required = true) @RequestBody CreatePostReq createPostReq + ); } \ No newline at end of file diff --git a/src/main/java/mvp/deplog/domain/post/presentation/PostController.java b/src/main/java/mvp/deplog/domain/post/presentation/PostController.java index 8485f6f..52dbc95 100644 --- a/src/main/java/mvp/deplog/domain/post/presentation/PostController.java +++ b/src/main/java/mvp/deplog/domain/post/presentation/PostController.java @@ -99,9 +99,9 @@ public ResponseEntity> createTempPost(@Authentica } @Override - @PutMapping("/publishing") + @PutMapping("/publishing/{postId}") public ResponseEntity> publishTempPost(@AuthenticationPrincipal UserDetailsImpl userDetails, - @RequestParam(value = "postId") Long postId, + @PathVariable(value = "postId") Long postId, @RequestBody CreatePostReq createPostReq) { return ResponseEntity.ok(postService.publishTempPost(userDetails.getMember().getId(), postId, createPostReq)); } @@ -111,4 +111,12 @@ public ResponseEntity> publishTempPost(@Authentic public ResponseEntity>> getAllTempPosts(@AuthenticationPrincipal UserDetailsImpl userDetails){ return ResponseEntity.ok(postService.getAllTempPosts(userDetails.getMember().getId())); } + + @Override + @PutMapping("/edits/{postId}") + public ResponseEntity> modifyPosts(@AuthenticationPrincipal UserDetailsImpl userDetails, + @PathVariable(value = "postId") Long postId, + @RequestBody CreatePostReq createPostReq) { + return ResponseEntity.ok(postService.modifyPost(userDetails.getMember().getId(), postId, createPostReq)); + } }