diff --git a/src/main/java/com/example/sharemind/post/application/PostService.java b/src/main/java/com/example/sharemind/post/application/PostService.java index 826d8bb7..3bd17536 100644 --- a/src/main/java/com/example/sharemind/post/application/PostService.java +++ b/src/main/java/com/example/sharemind/post/application/PostService.java @@ -2,6 +2,7 @@ import com.example.sharemind.post.domain.Post; import com.example.sharemind.post.dto.request.PostCreateRequest; +import com.example.sharemind.post.dto.request.PostUpdateRequest; import java.util.List; public interface PostService { @@ -11,4 +12,6 @@ public interface PostService { List getUnpaidPrivatePosts(); Post getPostByPostId(Long postId); + + void updatePost(PostUpdateRequest postUpdateRequest, Long customerId); } diff --git a/src/main/java/com/example/sharemind/post/application/PostServiceImpl.java b/src/main/java/com/example/sharemind/post/application/PostServiceImpl.java index 2ea57eb8..3ce60de3 100644 --- a/src/main/java/com/example/sharemind/post/application/PostServiceImpl.java +++ b/src/main/java/com/example/sharemind/post/application/PostServiceImpl.java @@ -2,8 +2,10 @@ import com.example.sharemind.customer.application.CustomerService; import com.example.sharemind.customer.domain.Customer; +import com.example.sharemind.global.content.ConsultCategory; import com.example.sharemind.post.domain.Post; import com.example.sharemind.post.dto.request.PostCreateRequest; +import com.example.sharemind.post.dto.request.PostUpdateRequest; import com.example.sharemind.post.exception.PostErrorCode; import com.example.sharemind.post.exception.PostException; import com.example.sharemind.post.repository.PostRepository; @@ -38,4 +40,16 @@ public Post getPostByPostId(Long postId) { return postRepository.findByPostIdAndIsActivatedIsTrue(postId).orElseThrow( () -> new PostException(PostErrorCode.POST_NOT_FOUND, postId.toString())); } + + @Transactional + @Override + public void updatePost(PostUpdateRequest postUpdateRequest, Long customerId) { + Customer customer = customerService.getCustomerByCustomerId(customerId); + Post post = getPostByPostId(postUpdateRequest.getPostId()); + ConsultCategory consultCategory = ConsultCategory.getConsultCategoryByName( + postUpdateRequest.getConsultCategory()); + + post.updatePost(consultCategory, postUpdateRequest.getTitle(), + postUpdateRequest.getContent(), postUpdateRequest.getIsCompleted(), customer); + } } diff --git a/src/main/java/com/example/sharemind/post/domain/Post.java b/src/main/java/com/example/sharemind/post/domain/Post.java index ea216f4b..28010d85 100644 --- a/src/main/java/com/example/sharemind/post/domain/Post.java +++ b/src/main/java/com/example/sharemind/post/domain/Post.java @@ -4,6 +4,8 @@ import com.example.sharemind.global.common.BaseEntity; import com.example.sharemind.global.content.ConsultCategory; import com.example.sharemind.post.content.PostStatus; +import com.example.sharemind.post.exception.PostErrorCode; +import com.example.sharemind.post.exception.PostException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -62,6 +64,9 @@ public class Post extends BaseEntity { @Column(name = "is_paid", nullable = false) private Boolean isPaid; + @Column(name = "is_completed") + private Boolean isCompleted; + @Builder public Post(Customer customer, Long cost, Boolean isPublic) { this.customer = customer; @@ -77,6 +82,21 @@ public void updateIsPaid() { this.isPaid = true; } + public void updatePost(ConsultCategory consultCategory, String title, String content, + Boolean isCompleted, Customer customer) { + checkUpdatability(); + checkWriteAuthority(customer); + + this.consultCategory = consultCategory; + this.title = title; + this.content = content; + this.isCompleted = isCompleted; + + if (isCompleted) { + this.postStatus = PostStatus.PROCEEDING; + } + } + private void setIsPaid(Boolean isPublic) { if (isPublic) { this.isPaid = true; @@ -84,4 +104,16 @@ private void setIsPaid(Boolean isPublic) { this.isPaid = false; } } + + private void checkWriteAuthority(Customer customer) { + if (!customer.getCustomerId().equals(this.customer.getCustomerId())) { + throw new PostException(PostErrorCode.POST_MODIFY_DENIED); + } + } + + private void checkUpdatability() { + if (this.isCompleted.equals(true)) { + throw new PostException(PostErrorCode.POST_ALREADY_COMPLETED); + } + } } diff --git a/src/main/java/com/example/sharemind/post/dto/request/PostUpdateRequest.java b/src/main/java/com/example/sharemind/post/dto/request/PostUpdateRequest.java new file mode 100644 index 00000000..93022be4 --- /dev/null +++ b/src/main/java/com/example/sharemind/post/dto/request/PostUpdateRequest.java @@ -0,0 +1,32 @@ +package com.example.sharemind.post.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; + +@Getter +public class PostUpdateRequest { + + @Schema(description = "일대다 상담 아이디") + @NotNull(message = "일대다 상담 아이디는 공백일 수 없습니다.") + private Long postId; + + @Schema(description = "선택한 상담 카테고리", example = "BOREDOM") + @NotBlank(message = "상담 카테고리는 공백일 수 없습니다.") + private String consultCategory; + + @Schema(description = "상담 제목", example = "남자친구의 심리가 궁금해요") + @NotBlank(message = "상담 제목은 공백일 수 없습니다.") + private String title; + + @Schema(description = "상담 내용", example = "안녕하세요 어쩌구저쩌구~") + @NotBlank(message = "상담 내용은 공백일 수 없습니다.") + @Size(max = 1000, message = "상담 내용은 최대 1000자입니다.") + private String content; + + @Schema(description = "최종 저장 여부", example = "최종 저장이면 true, 임시 저장이면 false") + @NotNull(message = "최종 저장 여부는 공백일 수 없습니다.") + private Boolean isCompleted; +} diff --git a/src/main/java/com/example/sharemind/post/exception/PostErrorCode.java b/src/main/java/com/example/sharemind/post/exception/PostErrorCode.java index 108f4a1b..fe319c4e 100644 --- a/src/main/java/com/example/sharemind/post/exception/PostErrorCode.java +++ b/src/main/java/com/example/sharemind/post/exception/PostErrorCode.java @@ -9,7 +9,9 @@ public enum PostErrorCode { POST_NOT_FOUND(HttpStatus.NOT_FOUND, "일대다 상담이 존재하지 않습니다."), - POST_ALREADY_PAID(HttpStatus.BAD_REQUEST, "이미 결제 완료된 일대다 상담입니다."); + POST_ALREADY_PAID(HttpStatus.BAD_REQUEST, "이미 결제 완료된 일대다 상담입니다."), + POST_MODIFY_DENIED(HttpStatus.FORBIDDEN, "일대다 상담 질문 작성 권한이 없습니다."), + POST_ALREADY_COMPLETED(HttpStatus.BAD_REQUEST, "이미 일대다 상담 질문이 최종 제출되었습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/com/example/sharemind/post/exception/PostException.java b/src/main/java/com/example/sharemind/post/exception/PostException.java index 63d8c524..1bf41f18 100644 --- a/src/main/java/com/example/sharemind/post/exception/PostException.java +++ b/src/main/java/com/example/sharemind/post/exception/PostException.java @@ -7,6 +7,11 @@ public class PostException extends RuntimeException { private final PostErrorCode errorCode; + public PostException(PostErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + public PostException(PostErrorCode errorCode, String message) { super(errorCode.getMessage() + " : " + message); this.errorCode = errorCode; diff --git a/src/main/java/com/example/sharemind/post/presentation/PostController.java b/src/main/java/com/example/sharemind/post/presentation/PostController.java index 9529aa27..8b353dfc 100644 --- a/src/main/java/com/example/sharemind/post/presentation/PostController.java +++ b/src/main/java/com/example/sharemind/post/presentation/PostController.java @@ -4,6 +4,7 @@ import com.example.sharemind.global.jwt.CustomUserDetails; import com.example.sharemind.post.application.PostService; import com.example.sharemind.post.dto.request.PostCreateRequest; +import com.example.sharemind.post.dto.request.PostUpdateRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -15,6 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -47,4 +49,28 @@ public ResponseEntity createPost(@Valid @RequestBody PostCreateRequest pos postService.createPost(postCreateRequest, customUserDetails.getCustomer().getCustomerId()); return ResponseEntity.status(HttpStatus.CREATED).build(); } + + @Operation(summary = "일대다 상담 질문 내용 작성", description = "일대다 상담 질문 내용 작성") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "작성 성공"), + @ApiResponse(responseCode = "400", + description = "1. 요청 값 중 공백이 존재\n 2. 이미 최종 제출된 상담", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = CustomExceptionResponse.class)) + ), + @ApiResponse(responseCode = "403", description = "작성 권한이 없는 상담", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = CustomExceptionResponse.class)) + ), + @ApiResponse(responseCode = "404", description = "1. 존재하지 않는 일대다 상담\n 2. 존재하지 않는 상담 카테고리", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = CustomExceptionResponse.class)) + ) + }) + @PatchMapping + public ResponseEntity updatePost(@Valid @RequestBody PostUpdateRequest postUpdateRequest, + @AuthenticationPrincipal CustomUserDetails customUserDetails) { + postService.updatePost(postUpdateRequest, customUserDetails.getCustomer().getCustomerId()); + return ResponseEntity.ok().build(); + } }