[+] Mai2 music ranking

This commit is contained in:
Menci
2025-01-12 03:53:57 +08:00
parent 65cc3095e2
commit 3d66b7e022
5 changed files with 106 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ class Maimai2ServletController(
val getUserFavoriteItem: GetUserFavoriteItemHandler,
val getUserRivalMusic: GetUserRivalMusicHandler,
val getUserCharacter: GetUserCharacterHandler,
val getGameRanking: GetGameRankingHandler,
val repos: Mai2Repos
) {
companion object {
@@ -222,7 +223,6 @@ class Maimai2ServletController(
val getUserIntimate = UserReqHandler { _, uid -> mapOf("userId" to uid, "length" to 0, "userIntimateList" to empty) }
val getTransferFriend = UserReqHandler { _, uid -> mapOf("userId" to uid, "transferFriendList" to empty) }
val getGameNgMusicId = BaseHandler { mapOf("length" to 0, "musicIdList" to empty) }
val getGameRanking = BaseHandler { mapOf("type" to it["type"].toString(), "gameRankingList" to empty) }
val getGameTournamentInfo = BaseHandler { mapOf("length" to 0, "gameTournamentInfoList" to empty) }
val getGameKaleidxScope = BaseHandler { mapOf("gameKaleidxScopeList" to empty) }
val getUserKaleidxScope = UserReqHandler { _, uid -> mapOf("userId" to uid, "userKaleidxScopeList" to empty) }

View File

@@ -0,0 +1,71 @@
package icu.samnyan.aqua.sega.maimai2.handler
import com.querydsl.jpa.impl.JPAQueryFactory
import icu.samnyan.aqua.sega.general.BaseHandler
import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos
import icu.samnyan.aqua.sega.maimai2.model.userdata.QMai2UserPlaylog
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("Maimai2GetGameRankingHandler")
class GetGameRankingHandler(
private val repos: Mai2Repos,
private val queryFactory: JPAQueryFactory
) : BaseHandler {
private data class MusicRankingItem(val musicId: Int, val weight: Long)
private var musicRankingCache: Array<MusicRankingItem> = emptyArray()
init {
// To make sure the cache is initialized before the first request,
// not using `initialDelay = 0` in `@Scheduled`.
refreshMusicRankingCache()
}
@Scheduled(fixedDelay = 3600_000)
private fun refreshMusicRankingCache() {
val LOOK_BACK_DAYS: Long = 7
val QUREY_LIMIT: Long = 50
val qMai2Playlog = QMai2UserPlaylog.mai2UserPlaylog
val qPlaylog = QMai2UserPlaylog.mai2UserPlaylog
// Get the play count of each music in the last N days
val queryAfter = LocalDateTime.now().minusDays(LOOK_BACK_DAYS)
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val queryAfterStr = queryAfter.format(formatter)
val cMusicId = qPlaylog.musicId
val cUserCount = qPlaylog.user.id.countDistinct()
musicRankingCache = queryFactory
.select(cMusicId, cUserCount)
.from(qPlaylog)
.where(qPlaylog.userPlayDate.stringValue().goe(queryAfterStr))
.groupBy(cMusicId)
.orderBy(cUserCount.desc())
.limit(QUREY_LIMIT)
.fetch()
.map { MusicRankingItem(it.get(cMusicId)!!, it.get(cUserCount)!!) }
.toTypedArray()
logger.info("Refreshed music ranking cache: ${musicRankingCache.size} items")
}
override fun handle(request: Map<String, Any>): Any = mapOf(
"type" to request["type"],
"gameRankingList" to when(request["type"]) {
1 -> musicRankingCache.map { mapOf("id" to it.musicId, "point" to it.weight, "userName" to "") }
else -> emptyList()
}
)
companion object {
val logger: Logger = LoggerFactory.getLogger(GetGameRankingHandler::class.java)
}
}

View File

@@ -0,0 +1,18 @@
package icu.samnyan.aqua.spring
import com.querydsl.jpa.impl.JPAQueryFactory
import jakarta.persistence.EntityManager
import jakarta.persistence.PersistenceContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class QuerydslConfig {
@PersistenceContext
private lateinit var entityManager: EntityManager
@Bean
fun jpaQueryFactory(): JPAQueryFactory {
return JPAQueryFactory(entityManager)
}
}

View File

@@ -0,0 +1,2 @@
CREATE INDEX idx_play_date_music_user
ON maimai2_user_playlog (user_play_date, music_id, user_id);