feat(live-room): 라이브 룸 채팅 얼림 상태 저장/조회 기능 추가

- `LiveRoomInfo`에 `isChatFrozen` 필드(기본 false) 추가하여 Redis에 상태 저장 가능
- `GetRoomInfoResponse`에 `isChatFrozen` 노출 및 `LiveRoomService.getRoomInfo` 매핑 반영
- 요청 DTO `SetChatFreezeRequest(roomId, isChatFrozen)` 추가
- `PUT /live/room/info/set/chat-freeze` 엔드포인트 추가(크리에이터 권한 검증 포함)
This commit is contained in:
2026-03-19 16:20:47 +09:00
parent ddfb194716
commit f26c97861e
6 changed files with 75 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.live.room.cancel.CancelLiveRequest
import kr.co.vividnext.sodalive.live.room.donation.DeleteLiveRoomDonationMessage
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRequest
import kr.co.vividnext.sodalive.live.room.info.SetChatFreezeRequest
import kr.co.vividnext.sodalive.live.room.like.LiveRoomLikeHeartRequest
import kr.co.vividnext.sodalive.live.room.visit.LiveRoomVisitService
import kr.co.vividnext.sodalive.member.Member
@@ -204,6 +205,16 @@ class LiveRoomController(
ApiResponse.ok(service.setManager(request, member))
}
@PutMapping("/info/set/chat-freeze")
fun setChatFreeze(
@RequestBody request: SetChatFreezeRequest,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.setChatFreeze(request, member))
}
@PostMapping("/donation")
fun donation(
@RequestBody request: LiveRoomDonationRequest,

View File

@@ -44,6 +44,7 @@ import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
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.info.SetChatFreezeRequest
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
@@ -1052,10 +1053,29 @@ class LiveRoomService(
creatorLanguageCode = creatorLanguageCode,
isPrivateRoom = room.type == LiveRoomType.PRIVATE,
password = room.password,
isActiveRoulette = isActiveRoulette
isActiveRoulette = isActiveRoulette,
isChatFrozen = roomInfo.isChatFrozen
)
}
fun setChatFreeze(request: SetChatFreezeRequest, member: Member) {
val lock = getOrCreateLock(memberId = member.id!!)
lock.write {
val room = repository.findByIdOrNull(request.roomId)
?: throw SodaException(messageKey = "live.room.not_found")
if (room.member!!.id!! != member.id!!) {
throw SodaException(messageKey = "common.error.access_denied")
}
val roomInfo = roomInfoRepository.findByIdOrNull(request.roomId)
?: throw SodaException(messageKey = "live.room.info_not_found")
roomInfo.isChatFrozen = request.isChatFrozen
roomInfoRepository.save(roomInfo)
}
}
fun getDonationMessageList(roomId: Long, member: Member): List<LiveRoomDonationMessage> {
val liveRoomCreatorId = repository.getLiveRoomCreatorId(roomId)
?: throw SodaException(messageKey = "live.room.info_not_found")

View File

@@ -24,5 +24,6 @@ data class GetRoomInfoResponse(
val creatorLanguageCode: String?,
val isPrivateRoom: Boolean = false,
val password: String? = null,
val isActiveRoulette: Boolean = false
val isActiveRoulette: Boolean = false,
val isChatFrozen: Boolean = false
)

View File

@@ -83,6 +83,9 @@ data class LiveRoomInfo(
managerCount = managerList.size
}
// 채팅 얼림 상태 (기본값: 해제)
var isChatFrozen: Boolean = false
fun addDonationMessage(memberId: Long, nickname: String, isSecret: Boolean, can: Int, donationMessage: String) {
val donationMessageSet = donationMessageList.toMutableSet()
donationMessageSet.add(

View File

@@ -0,0 +1,6 @@
package kr.co.vividnext.sodalive.live.room.info
data class SetChatFreezeRequest(
val roomId: Long,
val isChatFrozen: Boolean
)