feat(creator-channel): FanTalk 탭 응답 조립을 추가한다

This commit is contained in:
2026-06-22 14:51:44 +09:00
parent 831c26c155
commit 90bf4c770c
4 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
package kr.co.vividnext.sodalive.v2.api.creator.channel.fantalk.application
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.v2.api.creator.channel.fantalk.dto.CreatorChannelFanTalkTabResponse
import kr.co.vividnext.sodalive.v2.creator.channel.fantalk.application.CreatorChannelFanTalkQueryService
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
@Service
@Transactional(readOnly = true)
class CreatorChannelFanTalkFacade(
private val creatorChannelFanTalkQueryService: CreatorChannelFanTalkQueryService
) {
fun getFanTalkTab(
creatorId: Long,
viewer: Member,
page: Int?,
size: Int?,
now: LocalDateTime = LocalDateTime.now()
): CreatorChannelFanTalkTabResponse {
return CreatorChannelFanTalkTabResponse.from(
creatorChannelFanTalkQueryService.getFanTalkTab(
creatorId = creatorId,
viewer = viewer,
page = page,
size = size,
now = now
)
)
}
}

View File

@@ -0,0 +1,74 @@
package kr.co.vividnext.sodalive.v2.api.creator.channel.fantalk.dto
import com.fasterxml.jackson.annotation.JsonProperty
import kr.co.vividnext.sodalive.extensions.toUtcIso
import kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain.CreatorChannelFanTalk
import kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain.CreatorChannelFanTalkReply
import kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain.CreatorChannelFanTalkTab
data class CreatorChannelFanTalkTabResponse(
val fanTalkCount: Int,
val fanTalks: List<CreatorChannelFanTalkResponse>,
val page: Int,
val size: Int,
@JsonProperty("hasNext")
val hasNext: Boolean
) {
companion object {
fun from(tab: CreatorChannelFanTalkTab): CreatorChannelFanTalkTabResponse {
return CreatorChannelFanTalkTabResponse(
fanTalkCount = tab.fanTalkCount,
fanTalks = tab.fanTalks.map(CreatorChannelFanTalkResponse::from),
page = tab.page.page,
size = tab.page.size,
hasNext = tab.hasNext
)
}
}
}
data class CreatorChannelFanTalkResponse(
val fanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImageUrl: String,
val content: String,
val createdAtUtc: String,
val creatorReplies: List<CreatorChannelFanTalkReplyResponse>
) {
companion object {
fun from(fanTalk: CreatorChannelFanTalk): CreatorChannelFanTalkResponse {
return CreatorChannelFanTalkResponse(
fanTalkId = fanTalk.fanTalkId,
writerId = fanTalk.writerId,
writerNickname = fanTalk.writerNickname,
writerProfileImageUrl = fanTalk.writerProfileImageUrl,
content = fanTalk.content,
createdAtUtc = fanTalk.createdAt.toUtcIso(),
creatorReplies = fanTalk.creatorReplies.map(CreatorChannelFanTalkReplyResponse::from)
)
}
}
}
data class CreatorChannelFanTalkReplyResponse(
val fanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImageUrl: String,
val content: String,
val createdAtUtc: String
) {
companion object {
fun from(reply: CreatorChannelFanTalkReply): CreatorChannelFanTalkReplyResponse {
return CreatorChannelFanTalkReplyResponse(
fanTalkId = reply.fanTalkId,
writerId = reply.writerId,
writerNickname = reply.writerNickname,
writerProfileImageUrl = reply.writerProfileImageUrl,
content = reply.content,
createdAtUtc = reply.createdAt.toUtcIso()
)
}
}
}

View File

@@ -0,0 +1,21 @@
package kr.co.vividnext.sodalive.v2.creator.channel.fantalk.application
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain.CreatorChannelFanTalkTab
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
@Service
@Transactional(readOnly = true)
class CreatorChannelFanTalkQueryService {
fun getFanTalkTab(
creatorId: Long,
viewer: Member,
page: Int?,
size: Int?,
now: LocalDateTime = LocalDateTime.now()
): CreatorChannelFanTalkTab {
throw UnsupportedOperationException("CreatorChannelFanTalkQueryService is implemented in Phase 3")
}
}