Migrate accessories to user data
- Add user_accessory as the per-user accessory inventory table. - Migrate old accessory wear records to user-owned accessory ids, including legacy common_accessory_m lookups for old installs. - Allocate default accessories for newly created users and update accessory reads to use user_accessory at runtime. - Validate accessory ownership when wearing accessories and keep existing accessory-based responses working. Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -325,17 +325,7 @@ func getAccessoryInfo(ss *session.Session, targetUserID, unitOwningUserID int) (
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
accessoryData := struct {
|
||||
AccessoryID int `xorm:"accessory_id"`
|
||||
Exp int `xorm:"exp"`
|
||||
}{}
|
||||
has, err = ss.MainEng.Table("common_accessory_m").
|
||||
Where("accessory_owning_user_id = ?", accessoryOwningID).
|
||||
Cols("accessory_id,exp").
|
||||
Get(&accessoryData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
has, accessoryData := ss.GetAccessoryByAccessoryOwningUserID(accessoryOwningID)
|
||||
if !has {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -345,9 +335,9 @@ func getAccessoryInfo(ss *session.Session, targetUserID, unitOwningUserID int) (
|
||||
AccessoryID: accessoryData.AccessoryID,
|
||||
Exp: accessoryData.Exp,
|
||||
NextExp: 0,
|
||||
Level: 8,
|
||||
MaxLevel: 8,
|
||||
RankUpCount: 4,
|
||||
Level: accessoryData.MaxLevel,
|
||||
MaxLevel: accessoryData.MaxLevel,
|
||||
RankUpCount: accessoryData.MaxLevel - accessoryData.DefaultMaxLevel,
|
||||
FavoriteFlag: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func unitAccessoryAll(ctx *gin.Context) (res any, err error) {
|
||||
ss := session.Get(ctx)
|
||||
|
||||
accessoryList := []unitapischema.AccessoryList{}
|
||||
err = ss.MainEng.Table("common_accessory_m").Find(&accessoryList)
|
||||
err = ss.UserEng.Table("user_accessory").Where("user_id = ?", ss.UserID).Find(&accessoryList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -178,23 +178,18 @@ func buildCenterUnitInfo(ss *session.Session, userID, unitOwningUserID, awardID
|
||||
return info, err
|
||||
}
|
||||
if has && accessoryWear.AccessoryOwningUserID > 0 {
|
||||
var accessoryID, exp int
|
||||
_, err = ss.MainEng.Table("common_accessory_m").
|
||||
Where("accessory_owning_user_id = ?", accessoryWear.AccessoryOwningUserID).
|
||||
Cols("accessory_id,exp").
|
||||
Get(&accessoryID, &exp)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
accessoryInfo = friendschema.AccessoryInfo{
|
||||
AccessoryOwningUserID: accessoryWear.AccessoryOwningUserID,
|
||||
AccessoryID: accessoryID,
|
||||
Exp: exp,
|
||||
NextExp: 0,
|
||||
Level: 8,
|
||||
MaxLevel: 8,
|
||||
RankUpCount: 4,
|
||||
FavoriteFlag: true,
|
||||
hasAccessory, accessoryData := ss.GetAccessoryByAccessoryOwningUserID(accessoryWear.AccessoryOwningUserID)
|
||||
if hasAccessory {
|
||||
accessoryInfo = friendschema.AccessoryInfo{
|
||||
AccessoryOwningUserID: accessoryWear.AccessoryOwningUserID,
|
||||
AccessoryID: accessoryData.AccessoryID,
|
||||
Exp: accessoryData.Exp,
|
||||
NextExp: 0,
|
||||
Level: accessoryData.MaxLevel,
|
||||
MaxLevel: accessoryData.MaxLevel,
|
||||
RankUpCount: accessoryData.MaxLevel - accessoryData.DefaultMaxLevel,
|
||||
FavoriteFlag: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -290,6 +290,14 @@ func addUser(dbSession *xorm.Session, phone, password string, isDefault bool) (g
|
||||
}
|
||||
return loginData, loginCode, loginMsg, created, err
|
||||
}
|
||||
|
||||
err = usermodel.EnsureUserAccessories(dbSession, db.MainEng, userID, nil)
|
||||
if err != nil {
|
||||
if localSession {
|
||||
dbSession.Rollback()
|
||||
}
|
||||
return loginData, loginCode, loginMsg, created, err
|
||||
}
|
||||
}
|
||||
|
||||
// 检查用户卡组配置
|
||||
|
||||
@@ -47,6 +47,7 @@ type memberTagMatchKey struct {
|
||||
|
||||
type accessoryBonusRow struct {
|
||||
AccessoryOwningUserID int `xorm:"accessory_owning_user_id"`
|
||||
AccessoryID int `xorm:"accessory_id"`
|
||||
Smile float64 `xorm:"smile_max"`
|
||||
Pure float64 `xorm:"pure_max"`
|
||||
Cool float64 `xorm:"cool_max"`
|
||||
@@ -219,24 +220,51 @@ func loadAccessoryBonusMap(ss *session.Session, userID int, unitOwningUserIDs []
|
||||
}
|
||||
|
||||
rows := []accessoryBonusRow{}
|
||||
err = ss.MainEng.Table("common_accessory_m").
|
||||
Join("LEFT", "accessory_m", "common_accessory_m.accessory_id = accessory_m.accessory_id").
|
||||
In("common_accessory_m.accessory_owning_user_id", accessoryIDs).
|
||||
Cols("common_accessory_m.accessory_owning_user_id,smile_max,pure_max,cool_max").
|
||||
err = ss.UserEng.Table("user_accessory").
|
||||
In("accessory_owning_user_id", accessoryIDs).
|
||||
Cols("accessory_owning_user_id,accessory_id").
|
||||
Find(&rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accessoryMap := make(map[int]accessoryBonus, len(rows))
|
||||
accessoryIDSet := make(map[int]struct{}, len(rows))
|
||||
for _, row := range rows {
|
||||
accessoryMap[row.AccessoryOwningUserID] = accessoryBonus{
|
||||
accessoryIDSet[row.AccessoryID] = struct{}{}
|
||||
}
|
||||
|
||||
accessoryIDList := make([]int, 0, len(accessoryIDSet))
|
||||
for accessoryID := range accessoryIDSet {
|
||||
accessoryIDList = append(accessoryIDList, accessoryID)
|
||||
}
|
||||
|
||||
staticRows := []accessoryBonusRow{}
|
||||
err = ss.MainEng.Table("accessory_m").
|
||||
In("accessory_id", accessoryIDList).
|
||||
Cols("accessory_id,smile_max,pure_max,cool_max").
|
||||
Find(&staticRows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
staticBonusMap := make(map[int]accessoryBonus, len(staticRows))
|
||||
for _, row := range staticRows {
|
||||
staticBonusMap[row.AccessoryID] = accessoryBonus{
|
||||
Smile: row.Smile,
|
||||
Pure: row.Pure,
|
||||
Cool: row.Cool,
|
||||
}
|
||||
}
|
||||
|
||||
accessoryMap := make(map[int]accessoryBonus, len(rows))
|
||||
for _, row := range rows {
|
||||
bonus, ok := staticBonusMap[row.AccessoryID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
accessoryMap[row.AccessoryOwningUserID] = bonus
|
||||
}
|
||||
|
||||
result := make(map[int]accessoryBonus, len(unitToAccessoryID))
|
||||
for unitOwningUserID, accessoryOwningUserID := range unitToAccessoryID {
|
||||
if bonus, ok := accessoryMap[accessoryOwningUserID]; ok {
|
||||
|
||||
@@ -134,17 +134,7 @@ func getGreetingAccessoryInfo(ss *session.Session, userID, unitOwningUserID int)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
accessoryData := struct {
|
||||
AccessoryID int `xorm:"accessory_id"`
|
||||
Exp int `xorm:"exp"`
|
||||
}{}
|
||||
has, err = ss.MainEng.Table("common_accessory_m").
|
||||
Where("accessory_owning_user_id = ?", accessoryWear.AccessoryOwningUserID).
|
||||
Cols("accessory_id,exp").
|
||||
Get(&accessoryData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
has, accessoryData := ss.GetAccessoryByAccessoryOwningUserID(accessoryWear.AccessoryOwningUserID)
|
||||
if !has {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -154,9 +144,9 @@ func getGreetingAccessoryInfo(ss *session.Session, userID, unitOwningUserID int)
|
||||
AccessoryID: accessoryData.AccessoryID,
|
||||
Exp: accessoryData.Exp,
|
||||
NextExp: 0,
|
||||
Level: 8,
|
||||
MaxLevel: 8,
|
||||
RankUpCount: 4,
|
||||
Level: accessoryData.MaxLevel,
|
||||
MaxLevel: accessoryData.MaxLevel,
|
||||
RankUpCount: accessoryData.MaxLevel - accessoryData.DefaultMaxLevel,
|
||||
FavoriteFlag: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -199,17 +199,7 @@ func getRankingAccessoryInfo(ss *session.Session, targetUserID, unitOwningUserID
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
accessoryData := struct {
|
||||
AccessoryID int `xorm:"accessory_id"`
|
||||
Exp int `xorm:"exp"`
|
||||
}{}
|
||||
has, err = ss.MainEng.Table("common_accessory_m").
|
||||
Where("accessory_owning_user_id = ?", accessoryOwningID).
|
||||
Cols("accessory_id,exp").
|
||||
Get(&accessoryData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
has, accessoryData := ss.GetAccessoryByAccessoryOwningUserID(accessoryOwningID)
|
||||
if !has {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -219,9 +209,9 @@ func getRankingAccessoryInfo(ss *session.Session, targetUserID, unitOwningUserID
|
||||
AccessoryID: accessoryData.AccessoryID,
|
||||
Exp: accessoryData.Exp,
|
||||
NextExp: 0,
|
||||
Level: 8,
|
||||
MaxLevel: 8,
|
||||
RankUpCount: 4,
|
||||
Level: accessoryData.MaxLevel,
|
||||
MaxLevel: accessoryData.MaxLevel,
|
||||
RankUpCount: accessoryData.MaxLevel - accessoryData.DefaultMaxLevel,
|
||||
FavoriteFlag: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package unit
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"honoka-chan/internal/middleware"
|
||||
usermodel "honoka-chan/internal/model/user"
|
||||
"honoka-chan/internal/router"
|
||||
unitschema "honoka-chan/internal/schema/unit"
|
||||
"honoka-chan/internal/session"
|
||||
@@ -32,8 +34,20 @@ func wearAccessory(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
// 佩戴饰品
|
||||
var exists bool
|
||||
for _, v := range req.Wear {
|
||||
// fmt.Println("Wear:", v.AccessoryOwningUserID, v.UnitOwningUserID)
|
||||
exists, err = ss.UserEng.Table(new(usermodel.UserAccessory)).
|
||||
Where("user_id = ? AND accessory_owning_user_id = ?", ss.UserID, v.AccessoryOwningUserID).
|
||||
Exist()
|
||||
if ss.CheckErr(err) {
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
ss.CheckErr(errors.New("accessory not found for user"))
|
||||
return
|
||||
}
|
||||
|
||||
data := unitschema.WearAccessoryData{
|
||||
AccessoryOwningUserID: v.AccessoryOwningUserID,
|
||||
UnitOwningUserID: v.UnitOwningUserID,
|
||||
|
||||
Reference in New Issue
Block a user