feat(explorer): 크리에이터 상세정보 조회 API를 추가한다
This commit is contained in:
@@ -73,6 +73,15 @@ class ExplorerController(
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/profile/{id}/detail")
|
||||
fun getCreatorDetail(
|
||||
@PathVariable("id") creatorId: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(service.getCreatorDetail(creatorId = creatorId, memberId = member.id!!))
|
||||
}
|
||||
|
||||
@GetMapping("/profile/{id}/donation-rank")
|
||||
fun getCreatorProfileDonationRanking(
|
||||
@PathVariable("id") creatorId: Long,
|
||||
|
||||
@@ -565,6 +565,30 @@ class ExplorerQueryRepository(
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
fun getFirstLiveBeginDateTime(creatorId: Long): LocalDateTime? {
|
||||
return queryFactory
|
||||
.select(liveRoom.beginDateTime.min())
|
||||
.from(liveRoom)
|
||||
.where(
|
||||
liveRoom.member.id.eq(creatorId)
|
||||
.and(liveRoom.channelName.isNotNull)
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
fun getFirstContentReleaseDate(creatorId: Long): LocalDateTime? {
|
||||
return queryFactory
|
||||
.select(audioContent.releaseDate.min())
|
||||
.from(audioContent)
|
||||
.where(
|
||||
audioContent.member.id.eq(creatorId)
|
||||
.and(audioContent.isActive.isTrue)
|
||||
.and(audioContent.releaseDate.isNotNull)
|
||||
.and(audioContent.releaseDate.loe(LocalDateTime.now()))
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
fun getLiveTime(creatorId: Long): Long {
|
||||
val diffs = queryFactory
|
||||
.select(
|
||||
@@ -708,6 +732,8 @@ class ExplorerQueryRepository(
|
||||
.where(
|
||||
audioContent.isActive.isTrue
|
||||
.and(audioContent.member.id.eq(creatorId))
|
||||
.and(audioContent.releaseDate.isNotNull)
|
||||
.and(audioContent.releaseDate.loe(LocalDateTime.now()))
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.time.temporal.TemporalAdjusters
|
||||
import kotlin.random.Random
|
||||
|
||||
@@ -192,6 +193,63 @@ class ExplorerService(
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getCreatorDetail(creatorId: Long, memberId: Long): GetCreatorDetailResponse {
|
||||
val creatorAccount = queryRepository.getMember(creatorId)
|
||||
?: throw SodaException(messageKey = "member.validation.user_not_found")
|
||||
|
||||
if (isBlockedBetweenMembers(memberId = memberId, otherMemberId = creatorId)) {
|
||||
val messageTemplate = messageSource
|
||||
.getMessage("explorer.creator.blocked_access", langContext.lang)
|
||||
.orEmpty()
|
||||
throw SodaException(message = String.format(messageTemplate, creatorAccount.nickname))
|
||||
}
|
||||
|
||||
if (creatorAccount.role != MemberRole.CREATOR) {
|
||||
throw SodaException(messageKey = "member.validation.creator_not_found")
|
||||
}
|
||||
|
||||
val liveCount = queryRepository.getLiveCount(creatorId) ?: 0
|
||||
val liveTime = queryRepository.getLiveTime(creatorId)
|
||||
val liveContributorCount = queryRepository.getLiveContributorCount(creatorId) ?: 0
|
||||
val contentCount = queryRepository.getContentCount(creatorId) ?: 0
|
||||
val activitySummary = GetCreatorActivitySummary(
|
||||
liveCount = liveCount,
|
||||
liveTime = liveTime,
|
||||
liveContributorCount = liveContributorCount,
|
||||
contentCount = contentCount
|
||||
)
|
||||
|
||||
val debutDateTime = listOfNotNull(
|
||||
queryRepository.getFirstLiveBeginDateTime(creatorId),
|
||||
queryRepository.getFirstContentReleaseDate(creatorId)
|
||||
).minOrNull()
|
||||
|
||||
val debutDate = debutDateTime?.toLocalDate()
|
||||
val dDay = if (debutDate != null) {
|
||||
"D+${ChronoUnit.DAYS.between(debutDate, LocalDate.now())}"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
return GetCreatorDetailResponse(
|
||||
nickname = creatorAccount.nickname,
|
||||
profileImageUrl = if (creatorAccount.profileImage != null) {
|
||||
"$cloudFrontHost/${creatorAccount.profileImage}"
|
||||
} else {
|
||||
"$cloudFrontHost/profile/default-profile.png"
|
||||
},
|
||||
debutDate = debutDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "",
|
||||
dDay = dDay,
|
||||
activitySummary = activitySummary,
|
||||
instagramUrl = creatorAccount.instagramUrl,
|
||||
fancimmUrl = creatorAccount.fancimmUrl,
|
||||
xUrl = creatorAccount.xUrl,
|
||||
youtubeUrl = creatorAccount.youtubeUrl,
|
||||
websiteUrl = creatorAccount.websiteUrl,
|
||||
blogUrl = creatorAccount.blogUrl
|
||||
)
|
||||
}
|
||||
|
||||
fun getCreatorProfile(
|
||||
creatorId: Long,
|
||||
timezone: String,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package kr.co.vividnext.sodalive.explorer
|
||||
|
||||
data class GetCreatorDetailResponse(
|
||||
val nickname: String,
|
||||
val profileImageUrl: String,
|
||||
val debutDate: String,
|
||||
val dDay: String,
|
||||
val activitySummary: GetCreatorActivitySummary,
|
||||
val instagramUrl: String,
|
||||
val fancimmUrl: String,
|
||||
val xUrl: String,
|
||||
val youtubeUrl: String,
|
||||
val websiteUrl: String,
|
||||
val blogUrl: String
|
||||
)
|
||||
Reference in New Issue
Block a user