diff --git a/gg-data/src/main/java/gg/data/party/UserReport.java b/gg-data/src/main/java/gg/data/party/UserReport.java index 5aa76af6d..e33de0e54 100644 --- a/gg-data/src/main/java/gg/data/party/UserReport.java +++ b/gg-data/src/main/java/gg/data/party/UserReport.java @@ -37,4 +37,11 @@ public class UserReport extends BaseTimeEntity { @Column(length = 100) private String message; + + public UserReport(User reporter, User reportee, Room room, String message) { + this.reporter = reporter; + this.reportee = reportee; + this.room = room; + this.message = message; + } } diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java index 217e23acc..ecf25c2fc 100644 --- a/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java @@ -27,27 +27,40 @@ public class ReportController { * 방을 신고한다. * @param reportReqDto 신고 내용 * @param roomId 방 번호 - * @return roomId */ @PostMapping("/rooms/{room_id}") - public ResponseEntity reportRoomAdd(@PathVariable("room_id") Long roomId, + public ResponseEntity reportRoomAdd(@PathVariable("room_id") Long roomId, @RequestBody @Valid ReportReqDto reportReqDto, @Parameter(hidden = true) @Login UserDto user) { - return ResponseEntity.status(HttpStatus.CREATED) - .body(reportService.addReportRoom(roomId, reportReqDto, user)); + reportService.addReportRoom(roomId, reportReqDto, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); } /** * 댓글을 신고한다. * @param reportReqDto 신고 내용 * @param commentId 댓글 번호 - * @return commentId */ @PostMapping("/comments/{comment_id}") - public ResponseEntity reportCommentAdd(@PathVariable("comment_id") Long commentId, + public ResponseEntity reportCommentAdd(@PathVariable("comment_id") Long commentId, @RequestBody @Valid ReportReqDto reportReqDto, @Parameter(hidden = true) @Login UserDto user) { - return ResponseEntity.status(HttpStatus.CREATED) - .body(reportService.addReportComment(commentId, reportReqDto, user)); + reportService.addReportComment(commentId, reportReqDto, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * 유저 노쇼 신고한다. + * @param reportReqDto 신고 내용 + * @param roomId 방 번호 + * @param userIntraId 유저 인트라 아이디 + */ + @PostMapping("/rooms/{room_id}/users/{user_intra_id}") + public ResponseEntity reportUserAdd(@PathVariable("room_id") Long roomId, + @PathVariable("user_intra_id") String userIntraId, + @RequestBody @Valid ReportReqDto reportReqDto, + @Parameter(hidden = true) @Login UserDto user) { + reportService.addReportUser(roomId, reportReqDto, userIntraId, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); } } diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java index 45ca89ca2..66bc2b30b 100644 --- a/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java @@ -15,6 +15,7 @@ import gg.data.party.PartyPenalty; import gg.data.party.Room; import gg.data.party.RoomReport; +import gg.data.party.UserReport; import gg.data.party.UserRoom; import gg.data.party.type.RoomType; import gg.data.user.User; @@ -24,17 +25,23 @@ import gg.repo.party.PartyPenaltyRepository; import gg.repo.party.RoomReportRepository; import gg.repo.party.RoomRepository; +import gg.repo.party.UserReportRepository; import gg.repo.party.UserRoomRepository; import gg.repo.user.UserRepository; import gg.utils.exception.party.AlredayReportedException; import gg.utils.exception.party.CommentNotFoundException; import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomNotParticipantException; import gg.utils.exception.party.SelfReportException; +import gg.utils.exception.user.UserNotFoundException; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class ReportService { + private static final int COMMENT_PENALTY_TIME = 1; // 댓글 패널티 시간 (분) + private static final int NO_SHOW_PENALTY_TIME = 6; // 노쇼 패널티 시간 (시간) + private static final int ROOM_PENALTY_TIME = 24; // 방 패널티 시간 (시간) private final RoomRepository roomRepository; private final CommentRepository commentRepository; private final UserRepository userRepository; @@ -42,6 +49,7 @@ public class ReportService { private final CommentReportRepository commentReportRepository; private final PartyPenaltyRepository partyPenaltyRepository; private final UserRoomRepository userRoomRepository; + private final UserReportRepository userReportRepository; /** * 방을 신고한다. @@ -54,7 +62,7 @@ public class ReportService { * @throws AlredayReportedException 이미 신고한 경우 */ @Transactional - public Long addReportRoom(Long roomId, ReportReqDto reportReqDto, UserDto user) { + public void addReportRoom(Long roomId, ReportReqDto reportReqDto, UserDto user) { Room targetRoom = roomRepository.findById(roomId) .orElseThrow(RoomNotFoundException::new); User userEntity = userRepository.findById(user.getId()).get(); @@ -75,9 +83,8 @@ public Long addReportRoom(Long roomId, ReportReqDto reportReqDto, UserDto user) targetRoom.updateRoomStatus(RoomType.HIDDEN); roomRepository.save(targetRoom); User targetUser = targetRoom.getCreator(); - partyGivePenalty(targetUser.getIntraId(), 24, "방 패널티"); + partyGivePenalty(targetUser.getIntraId(), ROOM_PENALTY_TIME, "방 패널티"); } - return roomId; } /** @@ -91,7 +98,7 @@ public Long addReportRoom(Long roomId, ReportReqDto reportReqDto, UserDto user) * @throws AlredayReportedException 이미 신고한 경우 */ @Transactional - public Long addReportComment(Long commentId, ReportReqDto reportReqDto, UserDto user) { + public void addReportComment(Long commentId, ReportReqDto reportReqDto, UserDto user) { Comment targetComment = commentRepository.findById(commentId) .orElseThrow(CommentNotFoundException::new); User userEntity = userRepository.findById(user.getId()).get(); @@ -114,9 +121,50 @@ public Long addReportComment(Long commentId, ReportReqDto reportReqDto, UserDto targetComment.updateHidden(true); commentRepository.save(targetComment); User targetUser = targetComment.getUser(); - partyGivePenalty(targetUser.getIntraId(), 1, "댓글 패널티"); + partyGivePenalty(targetUser.getIntraId(), COMMENT_PENALTY_TIME, "댓글 패널티"); + } + } + + /** + * 유저 노쇼 신고한다. + * + * @param roomId 방 번호 + * @param reportReqDto 신고 내용 + * @param user 신고자 + * @param userIntraId 피신고자 + * @return 방 번호 + * @throws CommentNotFoundException 방을 찾을 수 없음 + * @throws AlredayReportedException 이미 신고한 경우 + */ + @Transactional + public void addReportUser(Long roomId, ReportReqDto reportReqDto, String userIntraId, UserDto user) { + // 신고자와 피신고자가 같은 경우 + if (Objects.equals(user.getIntraId(), userIntraId)) { + throw new SelfReportException(); + } + // 신고자와 피신고자가 같은 방에 있는지 확인 + User reporteeEntity = userRepository.findByIntraId(userIntraId) + .orElseThrow(UserNotFoundException::new); + UserRoom reporterUserRoom = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(user.getId(), roomId) + .orElseThrow(RoomNotParticipantException::new); + userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(reporteeEntity.getId(), roomId) + .orElseThrow(RoomNotParticipantException::new); + User reporterEntity = reporterUserRoom.getUser(); + Room targetRoom = reporterUserRoom.getRoom(); + if (targetRoom == null) { + throw new RoomNotFoundException(); + } + // 이미 신고한 경우 + userReportRepository.findByReporterAndReportee( + reporterEntity, reporteeEntity).orElseThrow(AlredayReportedException::new); + // 신고 저장 + UserReport userReport = new UserReport(reporterEntity, reporteeEntity, targetRoom, reportReqDto.getContent()); + userReportRepository.save(userReport); + // 노쇼 패널티 판단 + List allReportUser = userReportRepository.findByReporteeAndRoomId(reporteeEntity, roomId); + if (allReportUser.size() == targetRoom.getMaxPeople() / 2) { + partyGivePenalty(reporteeEntity.getIntraId(), NO_SHOW_PENALTY_TIME, "노쇼 패널티"); } - return commentId; } /** diff --git a/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java b/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java index 0dcdab4e7..eee65f8bc 100644 --- a/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java +++ b/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java @@ -1,13 +1,23 @@ package gg.repo.party; +import java.util.List; +import java.util.Optional; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import gg.data.party.UserReport; +import gg.data.user.User; public interface UserReportRepository extends JpaRepository { + public Optional findByReporterAndReportee(User reporter, User reportee); + + @Query("SELECT ur FROM UserReport ur JOIN FETCH ur.reportee " + + "JOIN FETCH ur.room WHERE ur.reportee = :reportee AND ur.room.id = :roomId") + List findByReporteeAndRoomId(@Param("reportee") User reportee, @Param("roomId") Long roomId); @Query(value = "SELECT ur FROM UserReport ur " + "JOIN FETCH ur.reporter " diff --git a/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java b/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java index da78569ff..57496e2fa 100644 --- a/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java +++ b/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java @@ -31,5 +31,7 @@ public interface UserRoomRepository extends JpaRepository { + "AND ur.isExist = true AND ur.room.status = 'OPEN'") List findOpenRoomsByUserId(@Param("userId") Long userId); - Optional findByUserIdAndRoomIdAndIsExistTrue(Long userId, Long roomId); + @Query("SELECT ur FROM UserRoom ur JOIN FETCH ur.user " + + "JOIN FETCH ur.room WHERE ur.user.id = :userId AND ur.room.id = :roomId AND ur.isExist = true") + Optional findByUserIdAndRoomIdAndIsExistTrue(@Param("userId") Long userId, @Param("roomId") Long roomId); } diff --git a/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java b/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java index 68f0b3b58..9a8f514ab 100644 --- a/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java +++ b/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java @@ -1,12 +1,10 @@ package gg.utils.exception.party; import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; -public class UserAlreadyInRoom extends RuntimeException { - private ErrorCode errorCode; - +public class UserAlreadyInRoom extends DuplicationException { public UserAlreadyInRoom(ErrorCode errorCode) { - super(ErrorCode.USER_ALREADY_IN_ROOM.getMessage()); - this.errorCode = errorCode; + super(ErrorCode.USER_ALREADY_IN_ROOM.getMessage(), ErrorCode.USER_ALREADY_IN_ROOM); } }