diff --git a/src/main/java/com/back/domain/post/post/controller/PostController.java b/src/main/java/com/back/domain/post/post/controller/PostController.java index 160b871d..270f5066 100644 --- a/src/main/java/com/back/domain/post/post/controller/PostController.java +++ b/src/main/java/com/back/domain/post/post/controller/PostController.java @@ -1,13 +1,15 @@ package com.back.domain.post.post.controller; -import com.back.domain.post.post.dto.request.PostRequestDto; +import com.back.domain.post.post.dto.request.PostCreateRequestDto; +import com.back.domain.post.post.dto.request.PostUpdateRequestDto; import com.back.domain.post.post.dto.response.PostResponseDto; -import com.back.domain.post.post.entity.Post; import com.back.domain.post.post.service.PostService; import com.back.global.rsData.RsData; +import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -23,14 +25,14 @@ public class PostController { /** * 게시글 작성 API - * @param postRequestDto 게시글 작성 요청 DTO + * @param reqBody 게시글 작성 요청 DTO * @return 작성된 게시글 정보 */ @PostMapping public RsData createPost( - @RequestBody PostRequestDto postRequestDto + @Valid @RequestBody PostCreateRequestDto reqBody ) { - return RsData.successOf(postService.createPost(postRequestDto)); // code=200, message="success" + return RsData.successOf(postService.createPost(reqBody)); // code=200, message="success" } /** @@ -53,4 +55,18 @@ public RsData getPost( ) { return RsData.successOf(postService.getPost(postId)); // code=200, message="success" } + + /** + * 게시글 수정 API + * @param postId 수정할 게시글 ID + * @param reqBody 게시글 수정 요청 DTO + * @return 수정된 게시글 정보 + */ + @PatchMapping("/{postId}") + public RsData updatePost( + @PathVariable Long postId, + @Valid @RequestBody PostUpdateRequestDto reqBody + ) { + return RsData.successOf(postService.updatePost(postId, reqBody)); // code=200, message="success" + } } diff --git a/src/main/java/com/back/domain/post/post/dto/request/PostCreateRequestDto.java b/src/main/java/com/back/domain/post/post/dto/request/PostCreateRequestDto.java new file mode 100644 index 00000000..e1b8a37d --- /dev/null +++ b/src/main/java/com/back/domain/post/post/dto/request/PostCreateRequestDto.java @@ -0,0 +1,17 @@ +package com.back.domain.post.post.dto.request; + +import com.back.domain.post.post.enums.PostStatus; +import jakarta.validation.constraints.NotBlank; +import java.util.List; + +public record PostCreateRequestDto( + Long categoryId, + PostStatus status, + @NotBlank (message = "제목은 필수입니다.") + String title, + @NotBlank (message = "내용은 필수입니다.") + String content, + String imageUrl, + List tags +) { +} diff --git a/src/main/java/com/back/domain/post/post/dto/request/PostRequestDto.java b/src/main/java/com/back/domain/post/post/dto/request/PostUpdateRequestDto.java similarity index 62% rename from src/main/java/com/back/domain/post/post/dto/request/PostRequestDto.java rename to src/main/java/com/back/domain/post/post/dto/request/PostUpdateRequestDto.java index 7ddafc49..a44e5895 100644 --- a/src/main/java/com/back/domain/post/post/dto/request/PostRequestDto.java +++ b/src/main/java/com/back/domain/post/post/dto/request/PostUpdateRequestDto.java @@ -1,12 +1,13 @@ package com.back.domain.post.post.dto.request; +import com.back.domain.post.post.enums.PostStatus; import java.util.List; -public record PostRequestDto( +public record PostUpdateRequestDto( Long categoryId, + PostStatus status, String title, String content, - String userNickName, String imageUrl, List tags ) { diff --git a/src/main/java/com/back/domain/post/post/entity/Post.java b/src/main/java/com/back/domain/post/post/entity/Post.java index 275a8667..858865e3 100644 --- a/src/main/java/com/back/domain/post/post/entity/Post.java +++ b/src/main/java/com/back/domain/post/post/entity/Post.java @@ -31,7 +31,6 @@ @Entity @Getter -@Setter @Table(name = "post") @EntityListeners(AuditingEntityListener.class) @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) @@ -97,8 +96,32 @@ public class Post { @Column(name = "view_count") private Integer viewCount; + public void updateCategory(Category category) { + this.category = category; + } + + public void updateStatus(PostStatus status) { + this.status = status; + } + + public void updateTitle(String title) { + this.title = title; + } + + public void updateContent(String content) { + this.content = content; + } + + public void updateImage(String imageUrl) { + this.imageUrl = imageUrl; + } + public void addTag(Tag tag) { PostTag postTag = PostTag.create(this, tag); this.postTags.add(postTag); } + + public void clearTags() { + this.postTags.clear(); + } } diff --git a/src/main/java/com/back/domain/post/post/service/PostService.java b/src/main/java/com/back/domain/post/post/service/PostService.java index 4261e00f..6eedac05 100644 --- a/src/main/java/com/back/domain/post/post/service/PostService.java +++ b/src/main/java/com/back/domain/post/post/service/PostService.java @@ -2,7 +2,8 @@ import com.back.domain.post.category.entity.Category; import com.back.domain.post.category.repository.CategoryRepository; -import com.back.domain.post.post.dto.request.PostRequestDto; +import com.back.domain.post.post.dto.request.PostCreateRequestDto; +import com.back.domain.post.post.dto.request.PostUpdateRequestDto; import com.back.domain.post.post.dto.response.PostResponseDto; import com.back.domain.post.post.entity.Post; import com.back.domain.post.post.entity.Tag; @@ -28,34 +29,23 @@ public class PostService { // 게시글 작성 로직 @Transactional - public PostResponseDto createPost(PostRequestDto postRequestDto) { + public PostResponseDto createPost(PostCreateRequestDto reqBody) { User user = rq.getActor(); // 현재 로그인한 사용자의 정보 가져오기 - Category category = categoryRepository.findById(postRequestDto.categoryId()) - .orElseThrow(() -> new IllegalArgumentException("해당 카테고리를 찾을 수 없습니다. ID: " + postRequestDto.categoryId())); + Category category = categoryRepository.findById(reqBody.categoryId()) + .orElseThrow(() -> new IllegalArgumentException("해당 카테고리를 찾을 수 없습니다. ID: " + reqBody.categoryId())); Post post = Post.builder() .category(category) .user(user) - .title(postRequestDto.title()) - .content(postRequestDto.content()) - .imageUrl(postRequestDto.imageUrl()) + .title(reqBody.title()) + .content(reqBody.content()) + .imageUrl(reqBody.imageUrl()) .build(); - List tagNames = postRequestDto.tags(); + List tagNames = reqBody.tags(); if (tagNames != null && !tagNames.isEmpty()) { - for (String tagName : tagNames) { - // 태그 이름으로 Tag 엔티티를 조회하거나, 없으면 새로 생성하여 저장 - Tag tag = tagRepository.findByName(tagName) - .orElseGet(() -> tagRepository.save( - Tag.builder() - .name(tagName) - .build() - ) - ); - - post.addTag(tag); - } + addTag(tagNames, post); } return new PostResponseDto(postRepository.save(post)); @@ -79,4 +69,55 @@ public PostResponseDto getPost(Long postId) { .orElseThrow(() -> new NoSuchElementException("해당 게시글을 찾을 수 없습니다. ID: " + postId)) ); } + + // 게시글 수정 로직 + @Transactional + public PostResponseDto updatePost(Long postId, PostUpdateRequestDto reqBody) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new NoSuchElementException("해당 게시글을 찾을 수 없습니다. ID: " + postId)); + + if (reqBody.categoryId() != null) { + Category category = categoryRepository.findById(reqBody.categoryId()) + .orElseThrow(() -> new IllegalArgumentException( + "해당 카테고리를 찾을 수 없습니다. ID: " + reqBody.categoryId() + ) + ); + post.updateCategory(category); + } + if (reqBody.status() != null) { + post.updateStatus(reqBody.status()); + } + if (reqBody.title() != null && !reqBody.title().isBlank()){ + post.updateTitle(reqBody.title()); + } + if (reqBody.content() != null && !reqBody.content().isBlank()) { + post.updateContent(reqBody.content()); + } + if (reqBody.imageUrl() != null && !reqBody.imageUrl().isBlank()) { + post.updateImage(reqBody.imageUrl()); + } + if (reqBody.tags() != null) { + // 기존 태그들 삭제 + post.clearTags(); + + // 새로운 태그들 추가 + addTag(reqBody.tags(), post); + } + + return new PostResponseDto(post); + } + + // 태그 추가 메서드 + private void addTag(List tagNames, Post post) { + for (String tagName : tagNames) { + Tag tag = tagRepository.findByName(tagName) + .orElseGet(() -> tagRepository.save( + Tag.builder() + .name(tagName) + .build() + ) + ); + post.addTag(tag); + } + } }