From c7655d2adffcd6b8586e760a530d6a691817e8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=93=E7=9D=A1=E4=B8=8D=E6=B6=88=E6=AE=8B=E9=85=92?= <49932926+CodeNoobLH@users.noreply.github.com> Date: Mon, 16 Jun 2025 10:17:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor(backend):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构了 SetStockSort 函数,增加了事务处理和错误处理 - 添加了对新排序位置是否被占用的检查 - 实现了向前和向后移动排序时对其他记录的影响 - 优化了数据库查询和更新操作,提高了代码的健壮性和性能 --- backend/data/stock_data_api.go | 75 ++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index 4399358..f6daa0d 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -463,15 +463,82 @@ func (receiver StockDataApi) SetAlarmChangePercent(val, alarmPrice float64, stoc return "设置成功" } -func (receiver StockDataApi) SetStockSort(sort int64, stockCode string) { +func (receiver StockDataApi) SetStockSort(newSort int64, stockCode string) { if strutil.HasPrefixAny(stockCode, []string{"gb_"}) { stockCode = strings.ToLower(stockCode) stockCode = strings.Replace(stockCode, "gb_", "us", 1) } - err := db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", strings.ToLower(stockCode)).Update("sort", sort).Error - if err != nil { - logger.SugaredLogger.Error(err.Error()) + + tx := db.Dao.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + // 获取当前排序值 + var currentStock FollowedStock + if err := tx.Model(&FollowedStock{}).Where("stock_code = ?", strings.ToLower(stockCode)).First(¤tStock).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("找不到当前股票: ", err.Error()) + return } + + oldSort := currentStock.Sort + + // 如果排序值没有变化,直接返回 + if oldSort == newSort { + tx.Rollback() + return + } + + // 检查新排序位置是否被占用 + var count int64 + if err := tx.Model(&FollowedStock{}).Where("sort = ?", newSort).Count(&count).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("检查新排序位置被占用失败: ", err.Error()) + return + } + if count == 0 { + // 新位置未被占用,直接更新当前记录 + if err := tx.Model(&FollowedStock{}). + Where("stock_code = ?", strings.ToLower(stockCode)). + Update("sort", newSort).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("更新排序位置失败: ", err.Error()) + } + } else { + // 新位置已被占用,需要移动其他记录 + if newSort < oldSort { + // 向前移动:将中间记录向后移动 + if err := tx.Model(&FollowedStock{}). + Where("sort >= ? AND sort < ?", newSort, oldSort). + Update("sort", gorm.Expr("sort + 1")).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("向前排序更新失败: ", err.Error()) + } + } else { + // 向后移动:将中间记录向前移动 + if err := tx.Model(&FollowedStock{}). + Where("sort > ? AND sort <= ?", oldSort, newSort). + Update("sort", gorm.Expr("sort - 1")).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("向后排序更新失败: ", err.Error()) + } + } + + // 更新目标记录的排序 + if err := tx.Model(&FollowedStock{}). + Where("stock_code = ?", strings.ToLower(stockCode)). + Update("sort", newSort).Error; err != nil { + tx.Rollback() + logger.SugaredLogger.Error("Failed to update target stock sort: ", err.Error()) + } + } + if err := tx.Commit().Error; err != nil { + logger.SugaredLogger.Error("Failed to commit transaction: ", err.Error()) + } + } func (receiver StockDataApi) SetStockAICron(cron string, stockCode string) { if strutil.HasPrefixAny(stockCode, []string{"gb_"}) {