[F] Fix incomplete export

This commit is contained in:
Azalea 2026-08-02 04:49:01 +00:00
parent 4781396860
commit 63e3ac4ecb
3 changed files with 135 additions and 5 deletions

View File

@ -3,6 +3,7 @@ package icu.samnyan.aqua.net.games.chu3
import ext.API
import ext.returns
import ext.vars
import icu.samnyan.aqua.net.games.ExportOptions
import icu.samnyan.aqua.net.games.IExportClass
import icu.samnyan.aqua.net.games.ImportClass
import icu.samnyan.aqua.net.games.ImportController
@ -12,6 +13,7 @@ import icu.samnyan.aqua.sega.chusan.model.userdata.*
import org.springframework.web.bind.annotation.RestController
import kotlin.reflect.full.declaredMembers
@Suppress("UNCHECKED_CAST")
@RestController
@API("api/v2/game/chu3")
class Chu3Import(
@ -22,7 +24,7 @@ class Chu3Import(
it.name.replace("List", "").lowercase()
},
exportRepos = Chu3DataExport::class.vars()
.filter { f -> f.name !in setOf("gameId", "userData") }
.filter { f -> f.name !in setOf("gameId", "userData", "userLoginBonusList") }
.associateWith { Chu3Repos::class.declaredMembers
.filter { f -> f returns Chu3UserLinked::class }
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
@ -44,7 +46,22 @@ class Chu3Import(
// "chuni_profile_emoney" to ImportClass(UserEmoney::class),
// "chuni_profile_overpower" to ImportClass(UserOverpower::class),
// "chuni_profile_recent_rating" to ImportClass(UserRecentRating::class),
)
),
customExporters = mapOf(
Chu3DataExport::userLoginBonusList to { user: Chu3UserData, _: ExportOptions ->
repos.userLoginBonus.findByUser(user.card!!.extId.toInt())
},
) as Map<kotlin.reflect.KMutableProperty1<Chu3DataExport, Any>, (Chu3UserData, ExportOptions) -> Any?>,
customImporters = mapOf(
Chu3DataExport::userLoginBonusList to { export: Chu3DataExport, user: Chu3UserData ->
val userId = user.card!!.extId.toInt()
repos.userLoginBonus.deleteAll(repos.userLoginBonus.findByUser(userId))
repos.userLoginBonus.saveAll(export.userLoginBonusList.map { it.apply {
id = 0
this.user = userId
} })
},
) as Map<kotlin.reflect.KMutableProperty1<Chu3DataExport, Any>, (Chu3DataExport, Chu3UserData) -> Unit>,
) {
override fun createEmpty() = Chu3DataExport()
override val userDataRepo = repos.userData
@ -67,6 +84,16 @@ data class Chu3DataExport(
var userMateList: List<UserMate> = emptyList(),
var userGeneralDataList: List<UserGeneralData> = emptyList(),
var userMiscList: Chu3UserMisc = Chu3UserMisc(),
var userCardPrintStateList: List<UserCardPrintState> = emptyList(),
var userGachaList: List<UserGacha> = emptyList(),
var userRegionsList: List<UserRegions> = emptyList(),
var userCMissionList: List<UserCMission> = emptyList(),
var userCMissionProgressList: List<UserCMissionProgress> = emptyList(),
var netBattleLogList: List<Chu3NetBattleLog> = emptyList(),
var userChallengeList: List<Chu3UserChallenge> = emptyList(),
var userLinkedVerseList: List<Chu3UserLinkedVerse> = emptyList(),
var userVoteList: List<UserVote> = emptyList(),
var userLoginBonusList: List<UserLoginBonus> = emptyList(),
): IExportClass<Chu3UserData> {
constructor() : this("SDHD",
Chu3UserData(), UserGameOption(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), Chu3UserMisc())

View File

@ -25,7 +25,9 @@ class Mai2Import(
it.name.replace("List", "").lowercase()
},
exportRepos = Maimai2DataExport::class.vars()
.filter { f -> f.name !in setOf("gameId", "userData", "userPlaylogList", "userFavoriteMusicList") }
.filter { f -> f.name !in setOf(
"gameId", "userData", "userPlaylogList", "userFavoriteMusicList", "userPrintDetailList"
) }
.associateWith { field ->
val repoName = when (field.name) {
"userKaleidxScopeList" -> "userKaleidx"
@ -68,7 +70,10 @@ class Mai2Import(
?.split(",")
?.mapIndexed { index, id -> Mai2UserFavoriteItem().apply { orderId = index; this.id = id.toInt() } }
?: emptyList()
}
},
Maimai2DataExport::userPrintDetailList to { user: Mai2UserDetail, _: ExportOptions ->
repos.userPrintDetail.findByUser(user).map(::Mai2UserPrintDetailExport)
},
) as Map<kotlin.reflect.KMutableProperty1<Maimai2DataExport, Any>, (Mai2UserDetail, ExportOptions) -> Any?>,
customImporters = mapOf(
Maimai2DataExport::userPlaylogList to { export: Maimai2DataExport, user: Mai2UserDetail ->
@ -85,7 +90,18 @@ class Mai2Import(
propertyValue = favoriteMusicList.sortedBy { it.orderId }.map { it.id }.joinToString(",")
})
}
}
},
Maimai2DataExport::userPrintDetailList to { export: Maimai2DataExport, user: Mai2UserDetail ->
val userCards = repos.userCard.findByUser(user).associateBy { it.cardId }
repos.userPrintDetail.saveAll(export.userPrintDetailList.map { detail ->
detail.toEntity(
user,
detail.userCardId?.let { cardId ->
userCards[cardId] ?: error("Missing Mai2 user card $cardId for print detail")
},
)
})
},
) as Map<kotlin.reflect.KMutableProperty1<Maimai2DataExport, Any>, (Maimai2DataExport, Mai2UserDetail) -> Unit>
) {
override fun createEmpty() = Maimai2DataExport()
@ -113,6 +129,9 @@ data class Maimai2DataExport(
var userFavoriteMusicList: List<Mai2UserFavoriteItem> = mutableListOf(),
var userKaleidxScopeList: List<Mai2UserKaleidx> = mutableListOf(),
var userPlaylogList: List<Mai2UserPlaylog> = mutableListOf(),
var userCardList: List<Mai2UserCard> = mutableListOf(),
var userPrintDetailList: List<Mai2UserPrintDetailExport> = mutableListOf(),
var userRegionsList: List<UserRegions> = mutableListOf(),
// Not supported yet:
// var userWeeklyData
// var userMissionDataList
@ -120,3 +139,76 @@ data class Maimai2DataExport(
// var userTradeItemList
override var gameId: String = "SDEZ",
): IExportClass<Mai2UserDetail>
data class Mai2UserPrintDetailExport(
var orderId: Long = 0,
var printNumber: Int = 0,
var printDate: String = "",
var serialId: String = "",
var placeId: Int = 0,
var clientId: String = "",
var printerSerialId: String = "",
var userCardId: Int? = null,
var cardRomVersion: Int = 0,
var isHolograph: Boolean = false,
var printOption1: Boolean = false,
var printOption2: Boolean = false,
var printOption3: Boolean = false,
var printOption4: Boolean = false,
var printOption5: Boolean = false,
var printOption6: Boolean = false,
var printOption7: Boolean = false,
var printOption8: Boolean = false,
var printOption9: Boolean = false,
var printOption10: Boolean = false,
var created: String = "",
) {
constructor(detail: Mai2UserPrintDetail) : this(
orderId = detail.orderId,
printNumber = detail.printNumber,
printDate = detail.printDate,
serialId = detail.serialId,
placeId = detail.placeId,
clientId = detail.clientId,
printerSerialId = detail.printerSerialId,
userCardId = detail.userCard?.cardId,
cardRomVersion = detail.cardRomVersion,
isHolograph = detail.isHolograph,
printOption1 = detail.printOption1,
printOption2 = detail.printOption2,
printOption3 = detail.printOption3,
printOption4 = detail.printOption4,
printOption5 = detail.printOption5,
printOption6 = detail.printOption6,
printOption7 = detail.printOption7,
printOption8 = detail.printOption8,
printOption9 = detail.printOption9,
printOption10 = detail.printOption10,
created = detail.created,
)
fun toEntity(user: Mai2UserDetail, userCard: Mai2UserCard?) = Mai2UserPrintDetail().also { detail ->
detail.user = user
detail.userCard = userCard
detail.orderId = orderId
detail.printNumber = printNumber
detail.printDate = printDate
detail.serialId = serialId
detail.placeId = placeId
detail.clientId = clientId
detail.printerSerialId = printerSerialId
detail.cardRomVersion = cardRomVersion
detail.isHolograph = isHolograph
detail.printOption1 = printOption1
detail.printOption2 = printOption2
detail.printOption3 = printOption3
detail.printOption4 = printOption4
detail.printOption5 = printOption5
detail.printOption6 = printOption6
detail.printOption7 = printOption7
detail.printOption8 = printOption8
detail.printOption9 = printOption9
detail.printOption10 = printOption10
detail.created = created
}
}

View File

@ -0,0 +1,11 @@
-- V1000.7 accidentally replaced the user foreign key with a second user-card
-- foreign key. Restore the direct ownership link so every print detail is
-- removed with its Mai2 user, including legacy rows without a user card.
DELETE detail FROM maimai2_user_print_detail detail
LEFT JOIN maimai2_user_detail user_data ON detail.user_id = user_data.id
WHERE user_data.id IS NULL;
ALTER TABLE maimai2_user_print_detail
ADD CONSTRAINT fku_maimai2_user_print_detail_user
FOREIGN KEY (user_id) REFERENCES maimai2_user_detail (id)
ON DELETE CASCADE ON UPDATE CASCADE;