feat(creator): 채널 홈 응답 모델을 추가한다

This commit is contained in:
2026-06-12 17:06:42 +09:00
parent b85c61bd0b
commit f2c2473a47
3 changed files with 701 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
package kr.co.vividnext.sodalive.v2.creator.channel.domain
import kr.co.vividnext.sodalive.v2.common.domain.CreatorActivityType
import java.time.LocalDateTime
data class CreatorChannelHome(
val creator: CreatorChannelCreator,
val currentLive: CreatorChannelLive?,
val latestAudioContent: CreatorChannelAudioContent?,
val channelDonations: List<CreatorChannelDonation>,
val notices: List<CreatorChannelCommunityPost>,
val schedules: List<CreatorChannelSchedule>,
val audioContents: List<CreatorChannelAudioContent>,
val series: List<CreatorChannelSeries>,
val communities: List<CreatorChannelCommunityPost>,
val fanTalk: CreatorChannelFanTalkSummary,
val introduce: String,
val activity: CreatorChannelActivity,
val sns: CreatorChannelSns
)
data class CreatorChannelCreator(
val creatorId: Long,
val nickname: String,
val profileImageUrl: String,
val followerCount: Int,
val isAiChatAvailable: Boolean,
val isDmAvailable: Boolean,
val isFollow: Boolean,
val isNotify: Boolean
)
data class CreatorChannelLive(
val liveId: Long,
val title: String,
val coverImageUrl: String?,
val beginDateTime: LocalDateTime,
val price: Int,
val isAdult: Boolean
)
data class CreatorChannelAudioContent(
val audioContentId: Long,
val title: String,
val duration: String?,
val imageUrl: String?,
val price: Int,
val isAdult: Boolean,
val isPointAvailable: Boolean,
val isFirstContent: Boolean,
val publishedAt: LocalDateTime,
val seriesName: String?,
val isOriginalSeries: Boolean?
)
data class CreatorChannelDonation(
val donationId: Long,
val memberId: Long,
val nickname: String,
val profileImageUrl: String,
val can: Int,
val isSecret: Boolean,
val message: String,
val createdAt: LocalDateTime
)
data class CreatorChannelSchedule(
val scheduledAt: LocalDateTime,
val title: String,
val type: CreatorActivityType,
val targetId: Long
)
data class CreatorChannelSeries(
val seriesId: Long,
val title: String,
val coverImageUrl: String,
val publishedDaysOfWeek: String,
val isComplete: Boolean,
val numberOfContent: Int,
val isNew: Boolean,
val isPopular: Boolean,
val isOriginal: Boolean
)
data class CreatorChannelCommunityPost(
val postId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileUrl: String,
val imageUrl: String?,
val audioUrl: String?,
val content: String,
val price: Int,
val date: LocalDateTime,
val existOrdered: Boolean,
val likeCount: Int,
val commentCount: Int
)
data class CreatorChannelFanTalkSummary(
val totalCount: Int,
val latestFanTalk: CreatorChannelFanTalk?
)
data class CreatorChannelFanTalk(
val fanTalkId: Long,
val memberId: Long,
val nickname: String,
val profileImageUrl: String,
val content: String,
val languageCode: String?,
val createdAt: LocalDateTime
)
data class CreatorChannelActivity(
val debutDate: LocalDateTime?,
val dDay: String,
val liveCount: Long,
val liveDurationHours: Long,
val liveContributorCount: Long,
val audioContentCount: Long,
val seriesCount: Long
)
data class CreatorChannelSns(
val instagramUrl: String,
val fancimmUrl: String,
val xUrl: String,
val youtubeUrl: String,
val kakaoOpenChatUrl: String
)

View File

@@ -0,0 +1,338 @@
package kr.co.vividnext.sodalive.v2.creator.channel.dto
import com.fasterxml.jackson.annotation.JsonProperty
import kr.co.vividnext.sodalive.v2.common.domain.CreatorActivityType
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelActivity
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelAudioContent
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelCommunityPost
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelCreator
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelDonation
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelFanTalk
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelFanTalkSummary
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelHome
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelLive
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelSchedule
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelSeries
import kr.co.vividnext.sodalive.v2.creator.channel.domain.CreatorChannelSns
import java.time.LocalDateTime
import java.time.ZoneOffset
data class CreatorChannelHomeResponse(
val creator: CreatorChannelCreatorResponse,
val currentLive: CreatorChannelLiveResponse?,
val latestAudioContent: CreatorChannelAudioContentResponse?,
val channelDonations: List<CreatorChannelDonationResponse>,
val notices: List<CreatorChannelCommunityPostResponse>,
val schedules: List<CreatorChannelScheduleResponse>,
val audioContents: List<CreatorChannelAudioContentResponse>,
val series: List<CreatorChannelSeriesResponse>,
val communities: List<CreatorChannelCommunityPostResponse>,
val fanTalk: CreatorChannelFanTalkSummaryResponse,
val introduce: String,
val activity: CreatorChannelActivityResponse,
val sns: CreatorChannelSnsResponse
) {
companion object {
fun from(home: CreatorChannelHome): CreatorChannelHomeResponse {
return CreatorChannelHomeResponse(
creator = CreatorChannelCreatorResponse.from(home.creator),
currentLive = home.currentLive?.let(CreatorChannelLiveResponse::from),
latestAudioContent = home.latestAudioContent?.let(CreatorChannelAudioContentResponse::from),
channelDonations = home.channelDonations.map(CreatorChannelDonationResponse::from),
notices = home.notices.map(CreatorChannelCommunityPostResponse::from),
schedules = home.schedules.map(CreatorChannelScheduleResponse::from),
audioContents = home.audioContents.map(CreatorChannelAudioContentResponse::from),
series = home.series.map(CreatorChannelSeriesResponse::from),
communities = home.communities.map(CreatorChannelCommunityPostResponse::from),
fanTalk = CreatorChannelFanTalkSummaryResponse.from(home.fanTalk),
introduce = home.introduce,
activity = CreatorChannelActivityResponse.from(home.activity),
sns = CreatorChannelSnsResponse.from(home.sns)
)
}
}
}
data class CreatorChannelCreatorResponse(
val creatorId: Long,
val nickname: String,
val profileImageUrl: String,
val followerCount: Int,
@JsonProperty("isAiChatAvailable")
val isAiChatAvailable: Boolean,
@JsonProperty("isDmAvailable")
val isDmAvailable: Boolean,
@JsonProperty("isFollow")
val isFollow: Boolean,
@JsonProperty("isNotify")
val isNotify: Boolean
) {
companion object {
fun from(creator: CreatorChannelCreator): CreatorChannelCreatorResponse {
return CreatorChannelCreatorResponse(
creatorId = creator.creatorId,
nickname = creator.nickname,
profileImageUrl = creator.profileImageUrl,
followerCount = creator.followerCount,
isAiChatAvailable = creator.isAiChatAvailable,
isDmAvailable = creator.isDmAvailable,
isFollow = creator.isFollow,
isNotify = creator.isNotify
)
}
}
}
data class CreatorChannelLiveResponse(
val liveId: Long,
val title: String,
val coverImageUrl: String?,
val beginDateTimeUtc: String,
val price: Int,
@JsonProperty("isAdult")
val isAdult: Boolean
) {
companion object {
fun from(live: CreatorChannelLive): CreatorChannelLiveResponse {
return CreatorChannelLiveResponse(
liveId = live.liveId,
title = live.title,
coverImageUrl = live.coverImageUrl,
beginDateTimeUtc = live.beginDateTime.toUtcIso(),
price = live.price,
isAdult = live.isAdult
)
}
}
}
data class CreatorChannelAudioContentResponse(
val audioContentId: Long,
val title: String,
val duration: String?,
val imageUrl: String?,
val price: Int,
@JsonProperty("isAdult")
val isAdult: Boolean,
@JsonProperty("isPointAvailable")
val isPointAvailable: Boolean,
@JsonProperty("isFirstContent")
val isFirstContent: Boolean,
val seriesName: String?,
@JsonProperty("isOriginalSeries")
val isOriginalSeries: Boolean?
) {
companion object {
fun from(audioContent: CreatorChannelAudioContent): CreatorChannelAudioContentResponse {
return CreatorChannelAudioContentResponse(
audioContentId = audioContent.audioContentId,
title = audioContent.title,
duration = audioContent.duration,
imageUrl = audioContent.imageUrl,
price = audioContent.price,
isAdult = audioContent.isAdult,
isPointAvailable = audioContent.isPointAvailable,
isFirstContent = audioContent.isFirstContent,
seriesName = audioContent.seriesName,
isOriginalSeries = audioContent.isOriginalSeries
)
}
}
}
data class CreatorChannelDonationResponse(
val donationId: Long,
val memberId: Long,
val nickname: String,
val profileImageUrl: String,
val can: Int,
@JsonProperty("isSecret")
val isSecret: Boolean,
val message: String,
val createdAtUtc: String
) {
companion object {
fun from(donation: CreatorChannelDonation): CreatorChannelDonationResponse {
return CreatorChannelDonationResponse(
donationId = donation.donationId,
memberId = donation.memberId,
nickname = donation.nickname,
profileImageUrl = donation.profileImageUrl,
can = donation.can,
isSecret = donation.isSecret,
message = donation.message,
createdAtUtc = donation.createdAt.toUtcIso()
)
}
}
}
data class CreatorChannelScheduleResponse(
val scheduledAtUtc: String,
val title: String,
val type: CreatorActivityType,
val targetId: Long
) {
companion object {
fun from(schedule: CreatorChannelSchedule): CreatorChannelScheduleResponse {
return CreatorChannelScheduleResponse(
scheduledAtUtc = schedule.scheduledAt.toUtcIso(),
title = schedule.title,
type = schedule.type,
targetId = schedule.targetId
)
}
}
}
data class CreatorChannelSeriesResponse(
val seriesId: Long,
val title: String,
val coverImageUrl: String,
val publishedDaysOfWeek: String,
@JsonProperty("isComplete")
val isComplete: Boolean,
val numberOfContent: Int,
@JsonProperty("isNew")
val isNew: Boolean,
@JsonProperty("isPopular")
val isPopular: Boolean,
@JsonProperty("isOriginal")
val isOriginal: Boolean
) {
companion object {
fun from(series: CreatorChannelSeries): CreatorChannelSeriesResponse {
return CreatorChannelSeriesResponse(
seriesId = series.seriesId,
title = series.title,
coverImageUrl = series.coverImageUrl,
publishedDaysOfWeek = series.publishedDaysOfWeek,
isComplete = series.isComplete,
numberOfContent = series.numberOfContent,
isNew = series.isNew,
isPopular = series.isPopular,
isOriginal = series.isOriginal
)
}
}
}
data class CreatorChannelCommunityPostResponse(
val postId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileUrl: String,
val imageUrl: String?,
val audioUrl: String?,
val content: String,
val price: Int,
val dateUtc: String,
val existOrdered: Boolean,
val likeCount: Int,
val commentCount: Int
) {
companion object {
fun from(post: CreatorChannelCommunityPost): CreatorChannelCommunityPostResponse {
return CreatorChannelCommunityPostResponse(
postId = post.postId,
creatorId = post.creatorId,
creatorNickname = post.creatorNickname,
creatorProfileUrl = post.creatorProfileUrl,
imageUrl = post.imageUrl,
audioUrl = post.audioUrl,
content = post.content,
price = post.price,
dateUtc = post.date.toUtcIso(),
existOrdered = post.existOrdered,
likeCount = post.likeCount,
commentCount = post.commentCount
)
}
}
}
data class CreatorChannelFanTalkSummaryResponse(
val totalCount: Int,
val latestFanTalk: CreatorChannelFanTalkResponse?
) {
companion object {
fun from(summary: CreatorChannelFanTalkSummary): CreatorChannelFanTalkSummaryResponse {
return CreatorChannelFanTalkSummaryResponse(
totalCount = summary.totalCount,
latestFanTalk = summary.latestFanTalk?.let(CreatorChannelFanTalkResponse::from)
)
}
}
}
data class CreatorChannelFanTalkResponse(
val fanTalkId: Long,
val memberId: Long,
val nickname: String,
val profileImageUrl: String,
val content: String,
val languageCode: String?,
val createdAtUtc: String
) {
companion object {
fun from(fanTalk: CreatorChannelFanTalk): CreatorChannelFanTalkResponse {
return CreatorChannelFanTalkResponse(
fanTalkId = fanTalk.fanTalkId,
memberId = fanTalk.memberId,
nickname = fanTalk.nickname,
profileImageUrl = fanTalk.profileImageUrl,
content = fanTalk.content,
languageCode = fanTalk.languageCode,
createdAtUtc = fanTalk.createdAt.toUtcIso()
)
}
}
}
data class CreatorChannelActivityResponse(
val debutDateUtc: String?,
val dDay: String,
val liveCount: Long,
val liveDurationHours: Long,
val liveContributorCount: Long,
val audioContentCount: Long,
val seriesCount: Long
) {
companion object {
fun from(activity: CreatorChannelActivity): CreatorChannelActivityResponse {
return CreatorChannelActivityResponse(
debutDateUtc = activity.debutDate?.toUtcIso(),
dDay = activity.dDay,
liveCount = activity.liveCount,
liveDurationHours = activity.liveDurationHours,
liveContributorCount = activity.liveContributorCount,
audioContentCount = activity.audioContentCount,
seriesCount = activity.seriesCount
)
}
}
}
data class CreatorChannelSnsResponse(
val instagramUrl: String,
val fancimmUrl: String,
val xUrl: String,
val youtubeUrl: String,
val kakaoOpenChatUrl: String
) {
companion object {
fun from(sns: CreatorChannelSns): CreatorChannelSnsResponse {
return CreatorChannelSnsResponse(
instagramUrl = sns.instagramUrl,
fancimmUrl = sns.fancimmUrl,
xUrl = sns.xUrl,
youtubeUrl = sns.youtubeUrl,
kakaoOpenChatUrl = sns.kakaoOpenChatUrl
)
}
}
}
private fun LocalDateTime.toUtcIso(): String {
return atOffset(ZoneOffset.UTC).toInstant().toString()
}