Compare commits

..

No commits in common. "dd07d724a89c6056d82347219e748a96f80f2b41" and "03ce8618e74e5c70519c744a049d4f109a1ff698" have entirely different histories.

3 changed files with 97 additions and 65 deletions

View File

@ -18,6 +18,8 @@ import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers
import kr.co.vividnext.sodalive.explorer.profile.QChannelNotice.channelNotice import kr.co.vividnext.sodalive.explorer.profile.QChannelNotice.channelNotice
import kr.co.vividnext.sodalive.explorer.profile.QCreatorCheers.creatorCheers import kr.co.vividnext.sodalive.explorer.profile.QCreatorCheers.creatorCheers
import kr.co.vividnext.sodalive.explorer.profile.TimeDifferenceResult import kr.co.vividnext.sodalive.explorer.profile.TimeDifferenceResult
import kr.co.vividnext.sodalive.explorer.section.ExplorerSection
import kr.co.vividnext.sodalive.explorer.section.QExplorerSection.explorerSection
import kr.co.vividnext.sodalive.live.room.LiveRoom import kr.co.vividnext.sodalive.live.room.LiveRoom
import kr.co.vividnext.sodalive.live.room.LiveRoomType import kr.co.vividnext.sodalive.live.room.LiveRoomType
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
@ -34,7 +36,6 @@ import kr.co.vividnext.sodalive.member.tag.QMemberCreatorTag.memberCreatorTag
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
import java.time.Duration import java.time.Duration
import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -171,38 +172,36 @@ class ExplorerQueryRepository(
.where( .where(
member.role.eq(MemberRole.CREATOR) member.role.eq(MemberRole.CREATOR)
.and(member.createdAt.goe(LocalDateTime.now().minusDays(30))) .and(member.createdAt.goe(LocalDateTime.now().minusDays(30)))
.and(member.isActive.isTrue)
) )
.orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc()) .orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc())
.limit(20) .limit(20)
.fetch() .fetch()
} }
fun findCreatorByGender(gender: Int): List<Member> { fun getExplorerSectionData(isAdult: Boolean): List<ExplorerSection> {
val today = LocalDate.now() var explorerSectionCondition = explorerSection.isActive.eq(true)
val offset = (today.dayOfMonth - 1) % 26 if (!isAdult) {
val characters = ('A'..'Z').map { it.toString() } explorerSectionCondition = explorerSectionCondition.and(explorerSection.isAdult.isFalse)
val rotatedChars = characters.drop(offset) + characters.take(offset)
val caseWhenClauses = rotatedChars.withIndex().joinToString(" ") {
"WHEN ${member.email} LIKE '${it.value}%' THEN ${it.index + 1}"
} }
val caseExpression = Expressions.stringTemplate("CASE $caseWhenClauses END")
val randomExpression = Expressions.numberTemplate(Double::class.java, "function('rand')").asc()
return queryFactory
.selectFrom(explorerSection)
.where(explorerSectionCondition)
.orderBy(explorerSection.orders.asc())
.fetch()
}
fun findMemberByTag(tags: List<String>): List<Member> {
return queryFactory return queryFactory
.selectFrom(member) .selectFrom(member)
.innerJoin(member.auth, auth) .leftJoin(member.tags, memberCreatorTag)
.join(memberCreatorTag.tag, creatorTag)
.where( .where(
member.role.eq(MemberRole.CREATOR) member.role.eq(MemberRole.CREATOR)
.and(member.isActive.isTrue) .and(creatorTag.tag.`in`(tags))
.and(auth.gender.eq(gender))
) )
.orderBy(caseExpression.asc(), randomExpression)
.offset(0)
.limit(10)
.fetch() .fetch()
.distinct()
} }
fun getSearchChannel(channel: String, memberId: Long): List<Member> { fun getSearchChannel(channel: String, memberId: Long): List<Member> {

View File

@ -29,7 +29,6 @@ import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters import java.time.temporal.TemporalAdjusters
import kotlin.random.Random
@Service @Service
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -53,8 +52,25 @@ class ExplorerService(
// 인기 크리에이터 // 인기 크리에이터
val creatorRankings = queryRepository val creatorRankings = queryRepository
.getCreatorRankings() .getCreatorRankings()
.asSequence()
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
.map { it.toExplorerSectionCreator(cloudFrontHost) } .map {
GetExplorerSectionCreatorResponse(
id = it.id!!,
nickname = it.nickname,
tags = it.tags
.asSequence()
.filter { tag -> tag.tag.isActive }
.map { tag -> tag.tag.tag }
.joinToString(" ") { tag -> "#$tag" },
profileImageUrl = if (it.profileImage != null) {
"$cloudFrontHost/${it.profileImage}"
} else {
"$cloudFrontHost/profile/default-profile.png"
}
)
}
.toList()
val currentDateTime = LocalDateTime.now() val currentDateTime = LocalDateTime.now()
val lastMonday = currentDateTime val lastMonday = currentDateTime
@ -81,8 +97,25 @@ class ExplorerService(
// 새로 시작 (newCreators) // 새로 시작 (newCreators)
val newCreators = queryRepository val newCreators = queryRepository
.getNewCreators() .getNewCreators()
.asSequence()
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
.map { it.toExplorerSectionCreator(cloudFrontHost) } .map {
GetExplorerSectionCreatorResponse(
id = it.id!!,
nickname = it.nickname,
tags = it.tags
.asSequence()
.filter { tag -> tag.tag.isActive }
.map { tag -> tag.tag.tag }
.joinToString(" ") { tag -> "#$tag" },
profileImageUrl = if (it.profileImage != null) {
"$cloudFrontHost/${it.profileImage}"
} else {
"$cloudFrontHost/profile/default-profile.png"
}
)
}
.toList()
val newCreatorsSection = GetExplorerSectionResponse( val newCreatorsSection = GetExplorerSectionResponse(
title = "새로 시작", title = "새로 시작",
@ -92,35 +125,52 @@ class ExplorerService(
) )
sections.add(newCreatorsSection) sections.add(newCreatorsSection)
val maleCreatorSection = GetExplorerSectionResponse( // 관리자에서 설정한 타이틀과 크리에이터
title = "남자 크리에이터", sections.addAll(
coloredTitle = "남자", queryRepository
color = "39abde", .getExplorerSectionData(isAdult = member.auth != null)
creators = queryRepository .asSequence()
.findCreatorByGender(1) .map {
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } val tags = it.tags.asSequence().map { explorerSectionTag -> explorerSectionTag.tag!!.tag }.toList()
.map { it.toExplorerSectionCreator(cloudFrontHost) } val creators = queryRepository.findMemberByTag(tags)
) .asSequence()
.filter { creator ->
!memberService.isBlocked(
blockedMemberId = member.id!!,
memberId = creator.id!!
)
}
.toList()
val femaleCreatorSection = GetExplorerSectionResponse( GetExplorerSectionResponse(
title = "여자 크리에이터", it.title,
coloredTitle = "여자", it.coloredTitle,
color = "ff5c49", it.color,
creators = queryRepository creators = creators
.findCreatorByGender(0) .asSequence()
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } .map { account ->
.map { it.toExplorerSectionCreator(cloudFrontHost) } GetExplorerSectionCreatorResponse(
id = account.id!!,
nickname = account.nickname,
tags = account.tags
.asSequence()
.filter { counselorTag -> counselorTag.tag.isActive }
.toList()
.joinToString(" ") { counselorTag ->
"#${counselorTag.tag.tag}"
},
profileImageUrl = if (account.profileImage != null) {
"$cloudFrontHost/${account.profileImage}"
} else {
"$cloudFrontHost/profile/default-profile.png"
}
)
}.toList()
)
}
.toList()
) )
val randomInt = Random.nextInt(0, 2)
if (randomInt == 0) {
sections.add(femaleCreatorSection)
sections.add(maleCreatorSection)
} else {
sections.add(maleCreatorSection)
sections.add(femaleCreatorSection)
}
return GetExplorerResponse(sections = sections) return GetExplorerResponse(sections = sections)
} }

View File

@ -1,7 +1,6 @@
package kr.co.vividnext.sodalive.member package kr.co.vividnext.sodalive.member
import kr.co.vividnext.sodalive.common.BaseEntity import kr.co.vividnext.sodalive.common.BaseEntity
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse
import kr.co.vividnext.sodalive.member.auth.Auth import kr.co.vividnext.sodalive.member.auth.Auth
import kr.co.vividnext.sodalive.member.following.CreatorFollowing import kr.co.vividnext.sodalive.member.following.CreatorFollowing
import kr.co.vividnext.sodalive.member.notification.MemberNotification import kr.co.vividnext.sodalive.member.notification.MemberNotification
@ -108,22 +107,6 @@ data class Member(
} }
} }
} }
fun toExplorerSectionCreator(imageHost: String): GetExplorerSectionCreatorResponse {
return GetExplorerSectionCreatorResponse(
id = id!!,
nickname = nickname,
tags = tags
.filter { tag -> tag.tag.isActive }
.map { tag -> tag.tag.tag }
.joinToString(" ") { tag -> "#$tag" },
profileImageUrl = if (profileImage != null) {
"$imageHost/$profileImage"
} else {
"$imageHost/profile/default-profile.png"
}
)
}
} }
enum class Gender { enum class Gender {