diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt index ebbd3a9..6874e68 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt @@ -283,4 +283,14 @@ class LiveRoomController( ApiResponse.ok(service.getTotalHeartCount(roomId)) } + + @GetMapping("/{id}/heart-list") + fun heartList( + @PathVariable("id") roomId: Long, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.getHeartList(roomId)) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt index d1fe8f2..e06153b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt @@ -12,6 +12,8 @@ import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom import kr.co.vividnext.sodalive.live.room.QQuarterLiveRankings.quarterLiveRankings import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationItem import kr.co.vividnext.sodalive.live.room.donation.QGetLiveRoomDonationItem +import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListItem +import kr.co.vividnext.sodalive.live.room.like.QGetLiveRoomHeartListItem import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.beans.factory.annotation.Value import org.springframework.data.jpa.repository.JpaRepository @@ -56,6 +58,8 @@ interface LiveRoomQueryRepository { fun getRoomActiveAndChannelNameIsNotNull(memberId: Long): List fun getActiveRoomIdList(memberId: Long): Int fun getTotalHeartCount(roomId: Long): Int? + fun getLiveRoomCreatorId(roomId: Long): Long? + fun getHeartList(roomId: Long): List } class LiveRoomQueryRepositoryImpl( @@ -334,4 +338,40 @@ class LiveRoomQueryRepositoryImpl( .where(where) .fetchOne() } + + override fun getLiveRoomCreatorId(roomId: Long): Long? { + return queryFactory + .select(liveRoom.member.id) + .from(liveRoom) + .where( + liveRoom.isActive.isTrue + .and(liveRoom.id.eq(roomId)) + ) + .fetchFirst() + } + + override fun getHeartList(roomId: Long): List { + val where = liveRoom.id.eq(roomId) + .and(useCan.canUsage.eq(CanUsage.HEART)) + .and(useCan.isRefund.isFalse) + + return queryFactory + .select( + QGetLiveRoomHeartListItem( + member.profileImage + .coalesce("profile/default-profile.png") + .prepend("/") + .prepend(cloudFrontHost), + member.nickname, + useCan.can.add(useCan.rewardCan).sum() + ) + ) + .from(useCan) + .innerJoin(useCan.room, liveRoom) + .innerJoin(useCan.member, member) + .groupBy(useCan.member.id) + .where(where) + .orderBy(useCan.can.add(useCan.rewardCan).sum().desc()) + .fetch() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt index 18addd3..37ecf7b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt @@ -39,6 +39,7 @@ import kr.co.vividnext.sodalive.live.room.info.LiveRoomInfo import kr.co.vividnext.sodalive.live.room.info.LiveRoomInfoRedisRepository import kr.co.vividnext.sodalive.live.room.info.LiveRoomMember import kr.co.vividnext.sodalive.live.room.kickout.LiveRoomKickOutService +import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListResponse import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartTotalResponse import kr.co.vividnext.sodalive.live.room.like.LiveRoomLikeHeartRequest import kr.co.vividnext.sodalive.live.room.menu.CreateLiveMenuRequest @@ -885,10 +886,18 @@ class LiveRoomService( } fun getDonationMessageList(roomId: Long, member: Member): List { + val liveRoomCreatorId = repository.getLiveRoomCreatorId(roomId) + ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") + val roomInfo = roomInfoRepository.findByIdOrNull(roomId) ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") - return roomInfo.donationMessageList + return if (liveRoomCreatorId != member.id!!) { + roomInfo.donationMessageList + .filter { !it.isSecret || it.memberId == member.id!! } + } else { + roomInfo.donationMessageList + } } fun deleteDonationMessage(request: DeleteLiveRoomDonationMessage, member: Member) { @@ -1068,14 +1077,16 @@ class LiveRoomService( container = request.container ) - if (!request.isSecret && request.message.isNotBlank()) { + if (request.message.isNotBlank()) { val lock = getOrCreateLock(memberId = member.id!!) lock.write { val roomInfo = roomInfoRepository.findByIdOrNull(room.id!!) ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") roomInfo.addDonationMessage( + memberId = member.id!!, nickname = member.nickname, + isSecret = request.isSecret, can = request.can, donationMessage = request.message ) @@ -1112,14 +1123,16 @@ class LiveRoomService( container = request.container ) - if (!request.isSecret && request.message.isNotBlank()) { + if (request.message.isNotBlank()) { val lock = getOrCreateLock(memberId = member.id!!) lock.write { val roomInfo = roomInfoRepository.findByIdOrNull(room.id!!) ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") roomInfo.addDonationMessage( + memberId = member.id!!, nickname = member.nickname, + isSecret = request.isSecret, can = request.can, donationMessage = request.message ) @@ -1257,4 +1270,14 @@ class LiveRoomService( fun getTotalHeartCount(roomId: Long): GetLiveRoomHeartTotalResponse { return GetLiveRoomHeartTotalResponse(totalHeartCount = repository.getTotalHeartCount(roomId = roomId) ?: 0) } + + fun getHeartList(roomId: Long): GetLiveRoomHeartListResponse { + val heartList = repository.getHeartList(roomId = roomId) + + return GetLiveRoomHeartListResponse( + heartList = heartList, + totalCount = heartList.size, + totalHeart = heartList.sumOf { it.heart } + ) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationMessage.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationMessage.kt index 52bb4a1..9088b3a 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationMessage.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationMessage.kt @@ -4,7 +4,9 @@ import java.util.UUID data class LiveRoomDonationMessage( val uuid: String = UUID.randomUUID().toString(), + val memberId: Long, val nickname: String, + val isSecret: Boolean, val canMessage: String, val donationMessage: String ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/info/LiveRoomInfo.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/info/LiveRoomInfo.kt index 8d19de1..6c366d8 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/info/LiveRoomInfo.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/info/LiveRoomInfo.kt @@ -83,23 +83,31 @@ data class LiveRoomInfo( managerCount = managerList.size } - fun addDonationMessage(nickname: String, can: Int, donationMessage: String) { + fun addDonationMessage(memberId: Long, nickname: String, isSecret: Boolean, can: Int, donationMessage: String) { val donationMessageSet = donationMessageList.toMutableSet() donationMessageSet.add( LiveRoomDonationMessage( + memberId = memberId, nickname = nickname, - canMessage = "${can}캔을 후원하셨습니다.", + isSecret = isSecret, + canMessage = if (isSecret) { + "${can}캔으로 비밀미션을 보냈습니다." + } else { + "${can}캔을 후원하셨습니다." + }, donationMessage = donationMessage ) ) donationMessageList = donationMessageSet.toList() } - fun addRouletteMessage(nickname: String, donationMessage: String) { + fun addRouletteMessage(memberId: Long, nickname: String, donationMessage: String) { val donationMessageSet = donationMessageList.toMutableSet() donationMessageSet.add( LiveRoomDonationMessage( + memberId = memberId, nickname = nickname, + isSecret = false, canMessage = "", donationMessage = donationMessage ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt new file mode 100644 index 0000000..882df29 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt @@ -0,0 +1,15 @@ +package kr.co.vividnext.sodalive.live.room.like + +import com.querydsl.core.annotations.QueryProjection + +data class GetLiveRoomHeartListResponse( + val heartList: List, + val totalCount: Int, + val totalHeart: Int +) + +data class GetLiveRoomHeartListItem @QueryProjection constructor( + val profileImage: String, + val nickname: String, + val heart: Int +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/roulette/v2/RouletteService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/roulette/v2/RouletteService.kt index 7b273f4..bcd5802 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/roulette/v2/RouletteService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/roulette/v2/RouletteService.kt @@ -162,6 +162,7 @@ class RouletteService( ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") roomInfo.addRouletteMessage( + memberId = member.id!!, nickname = member.nickname, donationMessage = "[$result] 당첨!" )