diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentController.kt index a68faa2..bc0cfba 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentController.kt @@ -74,6 +74,7 @@ class AudioContentCommentController(private val service: AudioContentCommentServ return ApiResponse.ok( service.getCommentReplyList( commentId = commentId, + memberId = member.id!!, timezone = timezone, pageable = pageable ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentRepository.kt index c78cc03..ecf14f0 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentRepository.kt @@ -1,13 +1,14 @@ package kr.co.vividnext.sodalive.content.comment +import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment import kr.co.vividnext.sodalive.member.QMember.member +import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository -import java.time.ZoneId -import java.time.format.DateTimeFormatter +import java.time.LocalDateTime @Repository interface AudioContentCommentRepository : JpaRepository, AudioContentCommentQueryRepository @@ -28,6 +29,7 @@ interface AudioContentCommentQueryRepository { fun getAudioContentCommentReplyList( cloudFrontHost: String, commentId: Long, + memberId: Long, timezone: String, offset: Long, limit: Int @@ -64,35 +66,50 @@ class AudioContentCommentQueryRepositoryImpl( ) } + val formattedDate = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + Expressions.dateTimeTemplate( + LocalDateTime::class.java, + "CONVERT_TZ({0},{1},{2})", + audioContentComment.createdAt, + "UTC", + "Asia/Seoul" + ), + "%Y.%m.%d %W %h:%i %p" + ) + return queryFactory - .selectFrom(audioContentComment) + .select( + QGetAudioContentCommentListItem( + audioContentComment.id, + audioContentComment.member.id, + audioContentComment.member.nickname, + audioContentComment.member.profileImage.prepend("/").prepend(cloudFrontHost), + audioContentComment.comment, + audioContentComment.isSecret, + blockMember.id.isNotNull, + audioContentComment.donationCan.coalesce(0), + formattedDate, + Expressions.constant(0) + ) + ) + .from(audioContentComment) .innerJoin(audioContentComment.audioContent, audioContent) .innerJoin(audioContentComment.member, member) + .leftJoin(blockMember) + .on( + member.id.eq(blockMember.blockedMember.id) + .and(blockMember.isActive.isTrue) + .and(blockMember.member.id.eq(memberId)) + ) .where(where) .offset(offset) .limit(limit.toLong()) .orderBy(audioContentComment.createdAt.desc()) .fetch() .map { - val date = it.createdAt!! - .atZone(ZoneId.of("UTC")) - .withZoneSameInstant(ZoneId.of(timezone)) - - GetAudioContentCommentListItem( - id = it.id!!, - writerId = it.member!!.id!!, - nickname = it.member!!.nickname, - profileUrl = if (it.member!!.profileImage != null) { - "$cloudFrontHost/${it.member!!.profileImage}" - } else { - "$cloudFrontHost/profile/default-profile.png" - }, - comment = it.comment, - isSecret = it.isSecret, - donationCan = it.donationCan ?: 0, - date = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd E hh:mm a")), - replyCount = commentReplyCountByAudioContentCommentId(it.id!!) - ) + it.replyCount = commentReplyCountByAudioContentCommentId(it.id) + it } } @@ -133,11 +150,46 @@ class AudioContentCommentQueryRepositoryImpl( override fun getAudioContentCommentReplyList( cloudFrontHost: String, commentId: Long, + memberId: Long, timezone: String, offset: Long, limit: Int ): List { - return queryFactory.selectFrom(audioContentComment) + val formattedDate = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + Expressions.dateTimeTemplate( + LocalDateTime::class.java, + "CONVERT_TZ({0},{1},{2})", + audioContentComment.createdAt, + "UTC", + "Asia/Seoul" + ), + "%Y.%m.%d %W %h:%i %p" + ) + + return queryFactory + .select( + QGetAudioContentCommentListItem( + audioContentComment.id, + audioContentComment.member.id, + audioContentComment.member.nickname, + audioContentComment.member.profileImage.prepend("/").prepend(cloudFrontHost), + audioContentComment.comment, + audioContentComment.isSecret, + blockMember.id.isNotNull, + audioContentComment.donationCan.coalesce(0), + formattedDate, + Expressions.constant(0) + ) + ) + .from(audioContentComment) + .innerJoin(audioContentComment.member, member) + .leftJoin(blockMember) + .on( + member.id.eq(blockMember.blockedMember.id) + .and(blockMember.isActive.isTrue) + .and(blockMember.member.id.eq(memberId)) + ) .where( audioContentComment.parent.isNotNull .and(audioContentComment.parent.id.eq(commentId)) @@ -147,29 +199,6 @@ class AudioContentCommentQueryRepositoryImpl( .limit(limit.toLong()) .orderBy(audioContentComment.createdAt.desc()) .fetch() - .asSequence() - .map { - val date = it.createdAt!! - .atZone(ZoneId.of("UTC")) - .withZoneSameInstant(ZoneId.of(timezone)) - - GetAudioContentCommentListItem( - id = it.id!!, - writerId = it.member!!.id!!, - nickname = it.member!!.nickname, - profileUrl = if (it.member!!.profileImage != null) { - "$cloudFrontHost/${it.member!!.profileImage}" - } else { - "$cloudFrontHost/profile/default-profile.png" - }, - comment = it.comment, - isSecret = it.isSecret, - donationCan = it.donationCan ?: 0, - date = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd E hh:mm a")), - replyCount = 0 - ) - } - .toList() } override fun findPushTokenByContentIdAndCommentParentIdMyMemberId( diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentService.kt index 632ad9f..f6e8e8c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/AudioContentCommentService.kt @@ -132,10 +132,16 @@ class AudioContentCommentService( return GetAudioContentCommentListResponse(totalCount, commentList) } - fun getCommentReplyList(commentId: Long, timezone: String, pageable: Pageable): GetAudioContentCommentListResponse { + fun getCommentReplyList( + commentId: Long, + memberId: Long, + timezone: String, + pageable: Pageable + ): GetAudioContentCommentListResponse { val commentList = repository.getAudioContentCommentReplyList( cloudFrontHost = cloudFrontHost, commentId = commentId, + memberId = memberId, timezone = timezone, offset = pageable.offset, limit = pageable.pageSize diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/GetAudioContentCommentListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/GetAudioContentCommentListResponse.kt index 2313d35..80d6af9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/GetAudioContentCommentListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/comment/GetAudioContentCommentListResponse.kt @@ -14,7 +14,8 @@ data class GetAudioContentCommentListItem @QueryProjection constructor( val profileUrl: String, val comment: String, val isSecret: Boolean, + val isWriterBlock: Boolean, val donationCan: Int, val date: String, - val replyCount: Int + var replyCount: Int = 0 )