Skip to content

Commit

Permalink
Merge pull request #44 from goalSetter09/10th-Kampus-BE-41
Browse files Browse the repository at this point in the history
[FEATURE] 게시글 수정 기능 구현
  • Loading branch information
u-genuine authored Jan 26, 2025
2 parents 9a921de + c6b59c6 commit 49619df
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package com.cotato.kampus.domain.post.api;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.cotato.kampus.domain.post.application.PostService;
import com.cotato.kampus.domain.post.dto.request.PostCreateRequest;
import com.cotato.kampus.domain.post.dto.request.PostUpdateRequest;
import com.cotato.kampus.domain.post.dto.response.MyPostResponse;
import com.cotato.kampus.domain.post.dto.response.PostCreateResponse;
import com.cotato.kampus.domain.post.dto.response.PostDeleteResponse;
Expand Down Expand Up @@ -95,6 +99,17 @@ public ResponseEntity<DataResponse<PostDeleteResponse>> deletePost(
));
}

@PutMapping(value = "/{postId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "게시글 수정", description = "게시글의 내용 수정")
public ResponseEntity<DataResponse<Void>> updatePost(
@PathVariable Long postId,
@ModelAttribute PostUpdateRequest request
) throws ImageException {
postService.updatePost(postId, request.title(), request.content(), request.postCategory(), request.anonymity(),
request.images() == null ? List.of() : request.images()); // 이미지 없는 경우 빈 리스트로 요청
return ResponseEntity.ok(DataResponse.ok());
}

@GetMapping("/my")
@Operation(summary = "[마이페이지] 내가 쓴 게시글 조회", description = "현재 사용자가 작성한 게시글을 최신순으로 조회합니다.")
public ResponseEntity<DataResponse<MyPostResponse>> findMyPosts(
Expand All @@ -107,4 +122,5 @@ public ResponseEntity<DataResponse<MyPostResponse>> findMyPosts(
)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import com.cotato.kampus.domain.common.application.ApiUserResolver;
import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.PostStatus;
import com.cotato.kampus.domain.post.enums.PostCategory;
import com.cotato.kampus.domain.post.enums.PostStatus;
import com.cotato.kampus.domain.post.dao.PostRepository;
import com.cotato.kampus.domain.post.domain.Post;

Expand All @@ -25,7 +26,7 @@ public Long append(
Long boardId,
String title,
String content,
String postCategory,
PostCategory postCategory,
Anonymity anonymity
){

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import com.cotato.kampus.domain.common.application.ApiUserResolver;
import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.dao.PostRepository;
import com.cotato.kampus.domain.post.domain.Post;
import com.cotato.kampus.domain.post.dto.AnonymousOrPostAuthor;
import com.cotato.kampus.domain.post.dto.PostDto;
import com.cotato.kampus.domain.user.dao.UserRepository;
Expand All @@ -21,6 +23,7 @@
public class PostAuthorResolver {

private final UserRepository userRepository;
private final PostRepository postRepository;
private final ApiUserResolver apiUserResolver;

public AnonymousOrPostAuthor getAuthor(PostDto postDto) {
Expand All @@ -41,4 +44,11 @@ public AnonymousOrPostAuthor getAuthor(PostDto postDto) {
author.getProfileImage());
}
}

public Boolean validatePostAuthor(Long postId, Long userId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new AppException(ErrorCode.POST_NOT_FOUND));

return post.getUserId().equals(userId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.cotato.kampus.domain.post.application;

import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.cotato.kampus.domain.post.dao.PostPhotoRepository;
import com.cotato.kampus.domain.post.domain.PostPhoto;
import com.cotato.kampus.global.error.exception.ImageException;
import com.cotato.kampus.global.util.s3.S3Uploader;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;

@Component
@Transactional(readOnly = true)
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class PostImageUpdater {

private final PostPhotoRepository postPhotoRepository;
private final S3Uploader s3Uploader;
private static final String POST_IMAGE_FOLDER = "post";

public void updatePostImages(Long postId, List<MultipartFile> images) throws ImageException {
postPhotoRepository.deleteAllByPostId(postId);

// 이미지가 있는 경우에만 업데이트
if (!images.isEmpty()) {
List<String> postImages = s3Uploader.uploadFiles(images, POST_IMAGE_FOLDER);

List<PostPhoto> postPhotos = postImages.stream()
.map((postImage) -> PostPhoto.builder()
.postId(postId)
.photoUrl(postImage)
.build()
).toList();

postPhotoRepository.saveAll(postPhotos);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
import com.cotato.kampus.domain.post.dto.PostDetails;
import com.cotato.kampus.domain.post.dto.PostDto;
import com.cotato.kampus.domain.post.dto.PostWithPhotos;
import com.cotato.kampus.domain.post.enums.PostCategory;
import com.cotato.kampus.domain.product.application.PostDeleter;
import com.cotato.kampus.global.error.ErrorCode;
import com.cotato.kampus.global.error.exception.AppException;
import com.cotato.kampus.domain.user.application.UserValidator;
import com.cotato.kampus.global.error.exception.ImageException;
import com.cotato.kampus.global.util.s3.S3Uploader;
Expand All @@ -24,14 +28,22 @@
@RequiredArgsConstructor(access = lombok.AccessLevel.PROTECTED)
public class PostService {

private final S3Uploader s3Uploader;
private final PostAppender postAppender;
private final PostDeleter postDeleter;
private final PostImageAppender postImageAppender;
private static final String POST_IMAGE_FOLDER = "post";
private final PostFinder postFinder;
private final PostUpdater postUpdater;

private static final String POST_IMAGE_FOLDER = "post";

private final PostImageAppender postImageAppender;
private final PostImageFinder postImageFinder;
private final PostImageUpdater postImageUpdater;

private final PostAuthorResolver postAuthorResolver;
private final ApiUserResolver apiUserResolver;
private final S3Uploader s3Uploader;

private final UserValidator userValidator;
private final ImageValidator imageValidator;

Expand All @@ -40,7 +52,7 @@ public Long createPost(
Long boardId,
String title,
String content,
String postCategory,
PostCategory postCategory,
Anonymity anonymity,
List<MultipartFile> images
) throws ImageException {
Expand Down Expand Up @@ -93,7 +105,22 @@ public PostDetails findPostDetail(Long postId) {
return PostDetails.of(author, postDto, postPhotos);
}

@Transactional
public void updatePost(Long postId, String title, String content, PostCategory postCategory, Anonymity anonymity,
List<MultipartFile> images) throws ImageException {
// 1. Post Author 검증
Long userId = apiUserResolver.getUserId();
postAuthorResolver.validatePostAuthor(postId, userId);

// 2. Post 업데이트
postUpdater.updatePost(postId, title, content, postCategory, anonymity);

// 3. Post Images 업데이트
postImageUpdater.updatePostImages(postId, images);
}

public Slice<MyPostWithPhoto> findUserPosts(int page){
return postFinder.findUserPosts(page);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.dao.PostRepository;
import com.cotato.kampus.domain.post.domain.Post;
import com.cotato.kampus.domain.post.enums.PostCategory;
import com.cotato.kampus.global.error.ErrorCode;
import com.cotato.kampus.global.error.exception.AppException;
import com.cotato.kampus.domain.post.dao.PostRepository;
import com.cotato.kampus.domain.post.domain.Post;

Expand All @@ -17,6 +23,14 @@ public class PostUpdater {
private final PostRepository postRepository;
private final PostFinder postFinder;

@Transactional
public void updatePost(Long postId, String title, String content, PostCategory postCategory, Anonymity anonymity) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new AppException(ErrorCode.POST_NOT_FOUND));

post.update(title, content, postCategory, anonymity);
}

public Long increaseNextAnonymousNumber(Long postId){

Post post = postFinder.getPost(postId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public interface PostPhotoRepository extends JpaRepository<PostPhoto, Long> {
Optional<PostPhoto> findFirstByPostIdOrderByCreatedTimeAsc(Long postId);

List<PostPhoto> findALlByPostId(Long postId);

void deleteAllByPostId(Long postId);
}
17 changes: 13 additions & 4 deletions src/main/java/com/cotato/kampus/domain/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import com.cotato.kampus.domain.common.domain.BaseTimeEntity;
import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.PostStatus;
import com.cotato.kampus.domain.post.enums.PostCategory;
import com.cotato.kampus.domain.post.enums.PostStatus;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -58,15 +59,15 @@ public class Post extends BaseTimeEntity {
private PostStatus postStatus;

@Column(name = "post_category", nullable = false)
private String postCategory;
private PostCategory postCategory;

@Column(name = "next_ananymous_number", nullable = false)
private Long nextAnonymousNumber = 1L;

@Builder
public Post(Long userId, Long boardId, String title, String content,
Long likes, Long scraps, Anonymity anonymity,
PostStatus postStatus, String postCategory, Long nextAnonymousNumber) {
PostStatus postStatus, PostCategory postCategory, Long nextAnonymousNumber) {
this.userId = userId;
this.boardId = boardId;
this.title = title;
Expand All @@ -79,7 +80,15 @@ public Post(Long userId, Long boardId, String title, String content,
this.nextAnonymousNumber = nextAnonymousNumber;
}

public void increaseNextAnonymousNumber(){
public void update(String title, String content, PostCategory postCategory, Anonymity anonymity) {
this.title = title;
this.content = content;
this.postCategory = postCategory;
this.anonymity = anonymity;
}

public void increaseNextAnonymousNumber(){
this.nextAnonymousNumber++;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import org.springframework.web.multipart.MultipartFile;

import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.enums.PostCategory;

public record PostCreateRequest(
Long boardId,
String title,
String content,
String postCategory,
PostCategory postCategory,
Anonymity anonymity,
List<MultipartFile> images
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.cotato.kampus.domain.post.dto.request;

import java.util.List;

import org.springframework.web.multipart.MultipartFile;

import com.cotato.kampus.domain.common.enums.Anonymity;
import com.cotato.kampus.domain.post.enums.PostCategory;

import jakarta.annotation.Nullable;

public record PostUpdateRequest(
String title,
String content,
PostCategory postCategory,
Anonymity anonymity,
@Nullable
List<MultipartFile> images
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.cotato.kampus.domain.post.enums;

public enum PostCategory {
HOSPITAL, UNIVERSITY, RESTAURANT, ETC
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.cotato.kampus.domain.post;
package com.cotato.kampus.domain.post.enums;

public enum PostStatus {
DRAFT, PUBLISHED, DELETED
Expand Down

0 comments on commit 49619df

Please sign in to comment.