From 6d6e1dd9eac4e2342b12ab27aead612e902ec662 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 3 May 2024 00:22:35 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=ED=83=90=EC=83=89=20-=20=EB=82=A8/?= =?UTF-8?q?=EC=97=AC=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=ED=81=AC=EB=A6=AC,=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=99=B8=20=EB=82=98=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explorer/ExplorerQueryRepository.kt | 42 ++++--- .../sodalive/explorer/ExplorerService.kt | 110 +++++------------- .../kr/co/vividnext/sodalive/member/Member.kt | 17 +++ 3 files changed, 71 insertions(+), 98 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index 674d5c4..77d2d3e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -18,8 +18,6 @@ import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers 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.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.LiveRoomType import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom @@ -36,6 +34,7 @@ import kr.co.vividnext.sodalive.member.tag.QMemberCreatorTag.memberCreatorTag import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Repository import java.time.Duration +import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter @@ -172,36 +171,43 @@ class ExplorerQueryRepository( .where( member.role.eq(MemberRole.CREATOR) .and(member.createdAt.goe(LocalDateTime.now().minusDays(30))) + .and(member.isActive.isTrue) ) .orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc()) .limit(20) .fetch() } - fun getExplorerSectionData(isAdult: Boolean): List { - var explorerSectionCondition = explorerSection.isActive.eq(true) - if (!isAdult) { - explorerSectionCondition = explorerSectionCondition.and(explorerSection.isAdult.isFalse) - } + fun findCreatorByGender(gender: Int): List { + val today = LocalDate.now() + val offset = (today.dayOfMonth - 1) % 26 + val characters = ('A'..'Z').map { it.toString() } + val rotatedChars = characters.drop(offset) + characters.take(offset) - return queryFactory - .selectFrom(explorerSection) - .where(explorerSectionCondition) - .orderBy(explorerSection.orders.asc()) - .fetch() - } + val caseBuilder = Expressions.stringTemplate( + "CASE {0}", + rotatedChars + .withIndex() + .joinToString(" ") { + "WHEN {0} THEN {1}".format(member.email.startsWith(it.value), it.index + 1) + } + ) - fun findMemberByTag(tags: List): List { + val randomExpression = Expressions.numberTemplate(Double::class.java, "function('random')") + + // gender : 0 - female, 1 - male return queryFactory .selectFrom(member) - .leftJoin(member.tags, memberCreatorTag) - .join(memberCreatorTag.tag, creatorTag) + .innerJoin(member.auth, auth) .where( member.role.eq(MemberRole.CREATOR) - .and(creatorTag.tag.`in`(tags)) + .and(member.isActive.isTrue) + .and(auth.gender.eq(gender)) ) + .orderBy(caseBuilder.asc(), randomExpression.desc()) + .offset(0) + .limit(10) .fetch() - .distinct() } fun getSearchChannel(channel: String, memberId: Long): List { diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt index 2a1515d..b46fa76 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt @@ -29,6 +29,7 @@ import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.temporal.TemporalAdjusters +import kotlin.random.Random @Service @Transactional(readOnly = true) @@ -52,25 +53,8 @@ class ExplorerService( // 인기 크리에이터 val creatorRankings = queryRepository .getCreatorRankings() - .asSequence() .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } - .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() + .map { it.toExplorerSectionCreator(cloudFrontHost) } val currentDateTime = LocalDateTime.now() val lastMonday = currentDateTime @@ -97,25 +81,8 @@ class ExplorerService( // 새로 시작 (newCreators) val newCreators = queryRepository .getNewCreators() - .asSequence() .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } - .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() + .map { it.toExplorerSectionCreator(cloudFrontHost) } val newCreatorsSection = GetExplorerSectionResponse( title = "새로 시작", @@ -125,52 +92,35 @@ class ExplorerService( ) sections.add(newCreatorsSection) - // 관리자에서 설정한 타이틀과 크리에이터 - sections.addAll( - queryRepository - .getExplorerSectionData(isAdult = member.auth != null) - .asSequence() - .map { - val tags = it.tags.asSequence().map { explorerSectionTag -> explorerSectionTag.tag!!.tag }.toList() - val creators = queryRepository.findMemberByTag(tags) - .asSequence() - .filter { creator -> - !memberService.isBlocked( - blockedMemberId = member.id!!, - memberId = creator.id!! - ) - } - .toList() - - GetExplorerSectionResponse( - it.title, - it.coloredTitle, - it.color, - creators = creators - .asSequence() - .map { account -> - 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 maleCreatorSection = GetExplorerSectionResponse( + title = "남자 크리에이터", + coloredTitle = "남자", + color = "39abde", + creators = queryRepository + .findCreatorByGender(1) + .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } + .map { it.toExplorerSectionCreator(cloudFrontHost) } ) + val femaleCreatorSection = GetExplorerSectionResponse( + title = "여자 크리에이터", + coloredTitle = "여자", + color = "ff5c49", + creators = queryRepository + .findCreatorByGender(0) + .filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) } + .map { it.toExplorerSectionCreator(cloudFrontHost) } + ) + + 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) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/Member.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/Member.kt index f48575b..fa268fc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/Member.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/Member.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.member 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.following.CreatorFollowing import kr.co.vividnext.sodalive.member.notification.MemberNotification @@ -107,6 +108,22 @@ 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 { -- 2.40.1 From 047446ba3aaf1c5fc5a312800c12bc639f568f06 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 3 May 2024 00:34:56 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=ED=83=90=EC=83=89=20-=20=EB=82=A8/?= =?UTF-8?q?=EC=97=AC=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=ED=81=AC=EB=A6=AC,=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=99=B8=20=EB=82=98=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vividnext/sodalive/explorer/ExplorerQueryRepository.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index 77d2d3e..c68a0bf 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -193,9 +193,8 @@ class ExplorerQueryRepository( } ) - val randomExpression = Expressions.numberTemplate(Double::class.java, "function('random')") + val randomExpression = Expressions.numberTemplate(Double::class.java, "function('rand')").asc() - // gender : 0 - female, 1 - male return queryFactory .selectFrom(member) .innerJoin(member.auth, auth) @@ -204,7 +203,7 @@ class ExplorerQueryRepository( .and(member.isActive.isTrue) .and(auth.gender.eq(gender)) ) - .orderBy(caseBuilder.asc(), randomExpression.desc()) + .orderBy(caseBuilder.asc(), randomExpression) .offset(0) .limit(10) .fetch() -- 2.40.1 From 54072412f3987252f6708ae9b121435c79bfc11b Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 3 May 2024 01:06:57 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=ED=83=90=EC=83=89=20-=20=EB=82=A8/?= =?UTF-8?q?=EC=97=AC=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=ED=81=AC=EB=A6=AC,=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=99=B8=20=EB=82=98=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/explorer/ExplorerQueryRepository.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index c68a0bf..339c3ec 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -185,12 +185,14 @@ class ExplorerQueryRepository( val rotatedChars = characters.drop(offset) + characters.take(offset) val caseBuilder = Expressions.stringTemplate( - "CASE {0}", - rotatedChars - .withIndex() - .joinToString(" ") { - "WHEN {0} THEN {1}".format(member.email.startsWith(it.value), it.index + 1) - } + "CASE", + rotatedChars.withIndex().joinToString(" ") { + "WHEN {0} LIKE {1} THEN {2}".format( + member.email, + "'" + it.value + "%'", + it.index + 1 + ) + } ) val randomExpression = Expressions.numberTemplate(Double::class.java, "function('rand')").asc() -- 2.40.1 From 82f49667a98649392dd3b3632ac5bc924ee3e482 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 3 May 2024 01:24:33 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=ED=83=90=EC=83=89=20-=20=EB=82=A8/?= =?UTF-8?q?=EC=97=AC=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=ED=81=AC=EB=A6=AC,=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=99=B8=20=EB=82=98=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/explorer/ExplorerQueryRepository.kt | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index 339c3ec..f427501 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -184,16 +184,10 @@ class ExplorerQueryRepository( val characters = ('A'..'Z').map { it.toString() } val rotatedChars = characters.drop(offset) + characters.take(offset) - val caseBuilder = Expressions.stringTemplate( - "CASE", - rotatedChars.withIndex().joinToString(" ") { - "WHEN {0} LIKE {1} THEN {2}".format( - member.email, - "'" + it.value + "%'", - it.index + 1 - ) - } - ) + val caseWhenClauses = rotatedChars.withIndex().joinToString(" ") { + "WHEN {0}.email LIKE '{1}%' THEN {2}".format(member, it.value, it.index + 1) + } + val caseExpression = Expressions.stringTemplate("CASE $caseWhenClauses END") val randomExpression = Expressions.numberTemplate(Double::class.java, "function('rand')").asc() @@ -205,7 +199,7 @@ class ExplorerQueryRepository( .and(member.isActive.isTrue) .and(auth.gender.eq(gender)) ) - .orderBy(caseBuilder.asc(), randomExpression) + .orderBy(caseExpression.asc(), randomExpression) .offset(0) .limit(10) .fetch() -- 2.40.1 From 6b138246a907b41c130e69dba8f0c4be82241d0e Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 3 May 2024 01:34:30 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=ED=83=90=EC=83=89=20-=20=EB=82=A8/?= =?UTF-8?q?=EC=97=AC=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=ED=81=AC=EB=A6=AC,=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=99=B8=20=EB=82=98=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index f427501..e119fc9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -185,7 +185,7 @@ class ExplorerQueryRepository( val rotatedChars = characters.drop(offset) + characters.take(offset) val caseWhenClauses = rotatedChars.withIndex().joinToString(" ") { - "WHEN {0}.email LIKE '{1}%' THEN {2}".format(member, it.value, it.index + 1) + "WHEN ${member.email} LIKE '${it.value}%' THEN ${it.index + 1}" } val caseExpression = Expressions.stringTemplate("CASE $caseWhenClauses END") -- 2.40.1