From b51208b9b8a94ee317586932ad8d230ef65592b7 Mon Sep 17 00:00:00 2001 From: CYY1007 Date: Sat, 1 Jun 2024 14:11:28 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Feat=20:=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=20=EC=8B=A0=EA=B3=A0=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/api/post/business/PostMapper.java | 10 +++++ .../server/api/post/business/PostService.java | 29 ++++++++++++ .../server/api/post/presentation/PostApi.java | 13 ++++++ .../post/presentation/dto/PostRequestDTO.java | 14 ++++++ .../implementation/ReportCommandAdapter.java | 19 ++++++++ .../report/persistent/ReportRepository.java | 7 +++ .../server/global/entity/report/Report.java | 44 +++++++++++++++++++ .../global/exception/GlobalErrorCode.java | 4 ++ 8 files changed, 140 insertions(+) create mode 100644 src/main/java/treehouse/server/api/report/implementation/ReportCommandAdapter.java create mode 100644 src/main/java/treehouse/server/api/report/persistent/ReportRepository.java create mode 100644 src/main/java/treehouse/server/global/entity/report/Report.java diff --git a/src/main/java/treehouse/server/api/post/business/PostMapper.java b/src/main/java/treehouse/server/api/post/business/PostMapper.java index 7020cd2..64d5cd5 100644 --- a/src/main/java/treehouse/server/api/post/business/PostMapper.java +++ b/src/main/java/treehouse/server/api/post/business/PostMapper.java @@ -9,6 +9,7 @@ import treehouse.server.global.entity.member.Member; import treehouse.server.global.entity.post.Post; import treehouse.server.global.entity.post.PostImage; +import treehouse.server.global.entity.report.Report; import treehouse.server.global.entity.treeHouse.TreeHouse; import treehouse.server.global.feign.dto.PresignedUrlDTO; @@ -66,4 +67,13 @@ public static PostResponseDTO.updatePostResult toUpdatePostResult(Post post) { .postId(post.getId()) .build(); } + + public static Report toReport(PostRequestDTO.reportPost request, Post post, Member reporter, Member target){ + return Report.builder() + .reason(request.getReason()) + .post(post) + .reporterMember(reporter) + .targetMember(target) + .build(); + } } diff --git a/src/main/java/treehouse/server/api/post/business/PostService.java b/src/main/java/treehouse/server/api/post/business/PostService.java index c34b326..7a4cd52 100644 --- a/src/main/java/treehouse/server/api/post/business/PostService.java +++ b/src/main/java/treehouse/server/api/post/business/PostService.java @@ -15,12 +15,14 @@ import treehouse.server.api.post.implement.PostQueryAdapter; import treehouse.server.api.post.presentation.dto.PostRequestDTO; import treehouse.server.api.post.presentation.dto.PostResponseDTO; +import treehouse.server.api.report.implementation.ReportCommandAdapter; import treehouse.server.api.treehouse.implementation.TreehouseQueryAdapter; import treehouse.server.global.constants.Consts; import treehouse.server.global.entity.User.User; import treehouse.server.global.entity.member.Member; import treehouse.server.global.entity.post.Post; import treehouse.server.global.entity.post.PostImage; +import treehouse.server.global.entity.report.Report; import treehouse.server.global.entity.treeHouse.TreeHouse; import treehouse.server.global.exception.GlobalErrorCode; import treehouse.server.global.exception.ThrowClass.PostException; @@ -45,6 +47,8 @@ public class PostService { private final TreehouseQueryAdapter treehouseQueryAdapter; + private final ReportCommandAdapter reportCommandAdapter; + private final PresignedUrlLambdaClient presignedUrlLambdaClient; /** @@ -153,4 +157,29 @@ public void deletePost(User user, Long treehouseId, Long postId) { postCommandAdapter.deletePost(post); } + + /** + * 게시글 신고하기 + * @param user + * @param treehouseId + * @param postId + * @param request + */ + @Transactional + public void reportPost(User user, Long treehouseId, Long postId,PostRequestDTO.reportPost request) { + + TreeHouse treehouse = treehouseQueryAdapter.getTreehouseById(treehouseId); + Member reporter = memberQueryAdapter.findByUserAndTreehouse(user, treehouse); + + Post post = postQueryAdapter.findById(postId); + + Member target = post.getWriter(); + + if (reporter.equals(target)) + throw new PostException(GlobalErrorCode.POST_SELF_REPORT); + + Report report = PostMapper.toReport(request, post, reporter, target); + + reportCommandAdapter.createReport(report); + } } diff --git a/src/main/java/treehouse/server/api/post/presentation/PostApi.java b/src/main/java/treehouse/server/api/post/presentation/PostApi.java index e3e0945..28b7f01 100644 --- a/src/main/java/treehouse/server/api/post/presentation/PostApi.java +++ b/src/main/java/treehouse/server/api/post/presentation/PostApi.java @@ -88,4 +88,17 @@ public CommonResponse deletePost( postService.deletePost(user, treehouseId, postId); return CommonResponse.onSuccess(null); } + + + @PostMapping("/posts/{postId}/reports") + @Operation(summary = "게시글 신고 ✅ 🔑", description = "게시글을 신고합니다.") + public CommonResponse reportPost( + @PathVariable(name = "treehouseId") Long treehouseId, + @PathVariable(name = "postId") Long postId, + @RequestBody @Validated PostRequestDTO.reportPost request, + @AuthMember @Parameter(hidden = true) User user + ){ + postService.reportPost(user,treehouseId,postId,request); + return CommonResponse.onSuccess(null); + } } diff --git a/src/main/java/treehouse/server/api/post/presentation/dto/PostRequestDTO.java b/src/main/java/treehouse/server/api/post/presentation/dto/PostRequestDTO.java index e4b3913..d174ac8 100644 --- a/src/main/java/treehouse/server/api/post/presentation/dto/PostRequestDTO.java +++ b/src/main/java/treehouse/server/api/post/presentation/dto/PostRequestDTO.java @@ -48,4 +48,18 @@ public static class updatePost{ @NotBlank(message = "게시글 내용이 필요합니다.") private String context; } + + @Getter + public static class reportPost{ + + @JsonProperty("reason") + @Schema(description = "신고 사유", example = "부적절한 게시글") + @NotBlank(message = "게시글 신고 사유가 필요합니다.") + private String reason; + + @JsonProperty("targetMemberId") + @Schema(description = "작성자 멤버 아이디", example = "1") + @NotNull(message = "작성자 멤버 아이디는 필수입니다.") + private Long targetMemberId; + } } diff --git a/src/main/java/treehouse/server/api/report/implementation/ReportCommandAdapter.java b/src/main/java/treehouse/server/api/report/implementation/ReportCommandAdapter.java new file mode 100644 index 0000000..9ea71c6 --- /dev/null +++ b/src/main/java/treehouse/server/api/report/implementation/ReportCommandAdapter.java @@ -0,0 +1,19 @@ +package treehouse.server.api.report.implementation; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import treehouse.server.api.report.persistent.ReportRepository; +import treehouse.server.global.annotations.Adapter; +import treehouse.server.global.entity.report.Report; + +@Adapter +@RequiredArgsConstructor +@Slf4j +public class ReportCommandAdapter { + + private final ReportRepository reportRepository; + + public Report createReport(Report report){ + return reportRepository.save(report); + } +} diff --git a/src/main/java/treehouse/server/api/report/persistent/ReportRepository.java b/src/main/java/treehouse/server/api/report/persistent/ReportRepository.java new file mode 100644 index 0000000..96d1f66 --- /dev/null +++ b/src/main/java/treehouse/server/api/report/persistent/ReportRepository.java @@ -0,0 +1,7 @@ +package treehouse.server.api.report.persistent; + +import org.springframework.data.jpa.repository.JpaRepository; +import treehouse.server.global.entity.report.Report; + +public interface ReportRepository extends JpaRepository { +} diff --git a/src/main/java/treehouse/server/global/entity/report/Report.java b/src/main/java/treehouse/server/global/entity/report/Report.java new file mode 100644 index 0000000..34a4878 --- /dev/null +++ b/src/main/java/treehouse/server/global/entity/report/Report.java @@ -0,0 +1,44 @@ +package treehouse.server.global.entity.report; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import treehouse.server.global.entity.comment.Comment; +import treehouse.server.global.entity.member.Member; +import treehouse.server.global.entity.post.Post; + +@Entity +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Report { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String reason; + + @JoinColumn(name = "reporterId") + @NotNull + @ManyToOne(fetch = FetchType.LAZY) + private Member reporterMember; + + @JoinColumn(name = "targetId") + @NotNull + @ManyToOne(fetch = FetchType.LAZY) + private Member targetMember; + + @JoinColumn(name = "postId") + @ManyToOne(fetch = FetchType.LAZY) + private Post post; + + @JoinColumn(name = "commentId") + @ManyToOne(fetch = FetchType.LAZY) + private Comment comment; + + public void setReporterMember(Member reporterMember) { + this.reporterMember = reporterMember; + } +} \ No newline at end of file diff --git a/src/main/java/treehouse/server/global/exception/GlobalErrorCode.java b/src/main/java/treehouse/server/global/exception/GlobalErrorCode.java index 8036b58..9bc104f 100644 --- a/src/main/java/treehouse/server/global/exception/GlobalErrorCode.java +++ b/src/main/java/treehouse/server/global/exception/GlobalErrorCode.java @@ -58,6 +58,10 @@ public enum GlobalErrorCode implements BaseErrorCode{ // POST + 401 Unauthorized - 권한 없음 POST_UNAUTHORIZED(UNAUTHORIZED, "POST401_1", "게시글 수정 및 삭제 권한이 없습니다."), + + // POST + 403 Forbidden - 금지됨 + POST_SELF_REPORT(FORBIDDEN, "POSt403_1", "자신의 게시글은 신고할 수 없습니다."), + // POST + 404 Not Found - 찾을 수 없음 POST_NOT_FOUND(NOT_FOUND, "POST404_1", "존재하지 않는 게시글입니다."),