캐릭터 챗봇 #338
| @@ -5,6 +5,7 @@ import kr.co.vividnext.sodalive.common.SodaException | ||||
| import kr.co.vividnext.sodalive.member.Member | ||||
| import org.springframework.beans.factory.annotation.Value | ||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal | ||||
| import org.springframework.web.bind.annotation.DeleteMapping | ||||
| import org.springframework.web.bind.annotation.GetMapping | ||||
| import org.springframework.web.bind.annotation.PathVariable | ||||
| import org.springframework.web.bind.annotation.PostMapping | ||||
| @@ -79,4 +80,29 @@ class CharacterCommentController( | ||||
|         val data = service.getReplies(imageHost, commentId, cursor, limit) | ||||
|         ApiResponse.ok(data) | ||||
|     } | ||||
|  | ||||
|     @DeleteMapping("/{characterId}/comments/{commentId}") | ||||
|     fun deleteComment( | ||||
|         @PathVariable characterId: Long, | ||||
|         @PathVariable commentId: Long, | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|         if (member.auth == null) throw SodaException("본인인증을 하셔야 합니다.") | ||||
|         service.deleteComment(characterId, commentId, member) | ||||
|         ApiResponse.ok(true, "댓글이 삭제되었습니다.") | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/{characterId}/comments/{commentId}/reports") | ||||
|     fun reportComment( | ||||
|         @PathVariable characterId: Long, | ||||
|         @PathVariable commentId: Long, | ||||
|         @RequestBody request: ReportCharacterCommentRequest, | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|         if (member.auth == null) throw SodaException("본인인증을 하셔야 합니다.") | ||||
|         service.reportComment(characterId, commentId, member, request.content) | ||||
|         ApiResponse.ok(true, "신고가 접수되었습니다.") | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -54,3 +54,8 @@ data class CharacterCommentListResponse( | ||||
|     val comments: List<CharacterCommentResponse>, | ||||
|     val cursor: Long? | ||||
| ) | ||||
|  | ||||
| // 신고 Request | ||||
| data class ReportCharacterCommentRequest( | ||||
|     val content: String | ||||
| ) | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| package kr.co.vividnext.sodalive.chat.character.comment | ||||
|  | ||||
| import kr.co.vividnext.sodalive.common.BaseEntity | ||||
| import kr.co.vividnext.sodalive.member.Member | ||||
| import javax.persistence.Column | ||||
| import javax.persistence.Entity | ||||
| import javax.persistence.FetchType | ||||
| import javax.persistence.JoinColumn | ||||
| import javax.persistence.ManyToOne | ||||
| import javax.persistence.Table | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "character_comment_report") | ||||
| data class CharacterCommentReport( | ||||
|     @Column(columnDefinition = "TEXT", nullable = false) | ||||
|     val content: String | ||||
| ) : BaseEntity() { | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "comment_id", nullable = false) | ||||
|     var comment: CharacterComment? = null | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "member_id", nullable = false) | ||||
|     var member: Member? = null | ||||
| } | ||||
| @@ -0,0 +1,5 @@ | ||||
| package kr.co.vividnext.sodalive.chat.character.comment | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||
|  | ||||
| interface CharacterCommentReportRepository : JpaRepository<CharacterCommentReport, Long> | ||||
| @@ -11,7 +11,8 @@ import java.time.ZoneId | ||||
| @Service | ||||
| class CharacterCommentService( | ||||
|     private val chatCharacterRepository: ChatCharacterRepository, | ||||
|     private val commentRepository: CharacterCommentRepository | ||||
|     private val commentRepository: CharacterCommentRepository, | ||||
|     private val reportRepository: CharacterCommentReportRepository | ||||
| ) { | ||||
|  | ||||
|     private fun profileUrl(imageHost: String, profileImage: String?): String { | ||||
| @@ -157,4 +158,27 @@ class CharacterCommentService( | ||||
|     fun getTotalCommentCount(characterId: Long): Int { | ||||
|         return commentRepository.countByChatCharacter_IdAndIsActiveTrue(characterId) | ||||
|     } | ||||
|  | ||||
|     @Transactional | ||||
|     fun deleteComment(characterId: Long, commentId: Long, member: Member) { | ||||
|         val comment = commentRepository.findById(commentId).orElseThrow { SodaException("댓글을 찾을 수 없습니다.") } | ||||
|         if (comment.chatCharacter?.id != characterId) throw SodaException("잘못된 요청입니다.") | ||||
|         if (!comment.isActive) return | ||||
|         val ownerId = comment.member?.id ?: throw SodaException("유효하지 않은 댓글입니다.") | ||||
|         if (ownerId != member.id) throw SodaException("삭제 권한이 없습니다.") | ||||
|         comment.isActive = false | ||||
|         commentRepository.save(comment) | ||||
|     } | ||||
|  | ||||
|     @Transactional | ||||
|     fun reportComment(characterId: Long, commentId: Long, member: Member, content: String) { | ||||
|         val comment = commentRepository.findById(commentId).orElseThrow { SodaException("댓글을 찾을 수 없습니다.") } | ||||
|         if (comment.chatCharacter?.id != characterId) throw SodaException("잘못된 요청입니다.") | ||||
|         if (content.isBlank()) throw SodaException("신고 내용을 입력해주세요.") | ||||
|  | ||||
|         val report = CharacterCommentReport(content = content) | ||||
|         report.comment = comment | ||||
|         report.member = member | ||||
|         reportRepository.save(report) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user