From d34ee5ea88179f78c469a6d7e677699febcdeb75 Mon Sep 17 00:00:00 2001 From: Eg <1711788888@qq.com> Date: Tue, 24 Feb 2026 21:05:44 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=8D=A1=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3=EF=BC=88=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E5=88=A0=E9=99=A4=E4=B8=96=E7=95=8C=E4=B9=A6=E5=92=8C?= =?UTF-8?q?=E6=AD=A3=E5=88=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/service/app/character.go | 88 +++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/server/service/app/character.go b/server/service/app/character.go index d1a258b..ec89fef 100644 --- a/server/service/app/character.go +++ b/server/service/app/character.go @@ -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(®exScripts).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 切换收藏状态