🎨 优化角色卡删除接口(同步删除世界书和正则)

This commit is contained in:
2026-02-24 21:05:44 +08:00
parent e5e33996d3
commit d34ee5ea88

View File

@@ -388,11 +388,91 @@ func (cs *CharacterService) DeleteCharacter(characterID uint, userID uint) error
return errors.New("无权删除")
}
// 删除相关的收藏记录
global.GVA_DB.Where("character_id = ?", characterID).Delete(&app.AppUserFavoriteCharacter{})
characterIDStr := fmt.Sprintf("%d", characterID)
// 删除角色卡
return global.GVA_DB.Delete(&character).Error
// 使用事务确保数据一致性
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
// 1. 删除相关的收藏记录
if err := tx.Where("character_id = ?", characterID).Delete(&app.AppUserFavoriteCharacter{}).Error; err != nil {
global.GVA_LOG.Warn("删除角色收藏记录失败", zap.Error(err))
}
// 2. 删除关联的世界书(只删除专属于该角色的世界书)
// 查找只关联了该角色的世界书
var worldBooks []app.AIWorldInfo
if err := tx.Where("? = ANY(linked_chars)", characterIDStr).Find(&worldBooks).Error; err == nil {
for _, book := range worldBooks {
// 如果世界书只关联了这一个角色,则删除
if len(book.LinkedChars) == 1 && book.LinkedChars[0] == characterIDStr {
if err := tx.Delete(&book).Error; err != nil {
global.GVA_LOG.Warn("删除角色专属世界书失败",
zap.Uint("worldBookID", book.ID),
zap.Error(err))
} else {
global.GVA_LOG.Info("删除角色专属世界书",
zap.Uint("worldBookID", book.ID),
zap.String("bookName", book.BookName))
}
} else {
// 如果世界书关联了多个角色,只移除该角色的关联
newLinkedChars := make([]string, 0)
for _, charID := range book.LinkedChars {
if charID != characterIDStr {
newLinkedChars = append(newLinkedChars, charID)
}
}
if err := tx.Model(&book).Update("linked_chars", pq.StringArray(newLinkedChars)).Error; err != nil {
global.GVA_LOG.Warn("更新世界书关联失败",
zap.Uint("worldBookID", book.ID),
zap.Error(err))
}
}
}
}
// 3. 删除关联的正则脚本(只删除专属于该角色的脚本)
var regexScripts []app.AIRegexScript
if err := tx.Where("? = ANY(linked_chars)", characterIDStr).Find(&regexScripts).Error; err == nil {
for _, script := range regexScripts {
// 如果脚本只关联了这一个角色,则删除
if len(script.LinkedChars) == 1 && script.LinkedChars[0] == characterIDStr {
if err := tx.Delete(&script).Error; err != nil {
global.GVA_LOG.Warn("删除角色专属正则脚本失败",
zap.Uint("scriptID", script.ID),
zap.Error(err))
} else {
global.GVA_LOG.Info("删除角色专属正则脚本",
zap.Uint("scriptID", script.ID),
zap.String("scriptName", script.ScriptName))
}
} else {
// 如果脚本关联了多个角色,只移除该角色的关联
newLinkedChars := make([]string, 0)
for _, charID := range script.LinkedChars {
if charID != characterIDStr {
newLinkedChars = append(newLinkedChars, charID)
}
}
if err := tx.Model(&script).Update("linked_chars", pq.StringArray(newLinkedChars)).Error; err != nil {
global.GVA_LOG.Warn("更新正则脚本关联失败",
zap.Uint("scriptID", script.ID),
zap.Error(err))
}
}
}
}
// 4. 删除角色卡本身
if err := tx.Delete(&character).Error; err != nil {
return err
}
global.GVA_LOG.Info("成功删除角色卡及其关联数据",
zap.Uint("characterID", characterID),
zap.String("characterName", character.Name))
return nil
})
}
// ToggleFavorite 切换收藏状态