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 1/3] =?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_"}) { From 9337084ebf4f2f259605a8f59327222d179fb07a 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, 23 Jun 2025 16:37:20 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/data/stock_data_api.go | 32 +++++++------------------------ frontend/src/components/stock.vue | 5 ++++- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index f6daa0d..b022cdb 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -469,17 +469,9 @@ func (receiver StockDataApi) SetStockSort(newSort int64, stockCode string) { stockCode = strings.Replace(stockCode, "gb_", "us", 1) } - 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() + if err := db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", strings.ToLower(stockCode)).First(¤tStock).Error; err != nil { logger.SugaredLogger.Error("找不到当前股票: ", err.Error()) return } @@ -488,56 +480,46 @@ func (receiver StockDataApi) SetStockSort(newSort int64, stockCode string) { // 如果排序值没有变化,直接返回 if oldSort == newSort { - tx.Rollback() return } - // 检查新排序位置是否被占用 var count int64 - if err := tx.Model(&FollowedStock{}).Where("sort = ?", newSort).Count(&count).Error; err != nil { - tx.Rollback() + if err := db.Dao.Model(&FollowedStock{}).Where("sort = ?", newSort).Count(&count).Error; err != nil { logger.SugaredLogger.Error("检查新排序位置被占用失败: ", err.Error()) return } if count == 0 { // 新位置未被占用,直接更新当前记录 - if err := tx.Model(&FollowedStock{}). + if err := db.Dao.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{}). + if err := db.Dao.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{}). + if err := db.Dao.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{}). + if err := db.Dao.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()) + logger.SugaredLogger.Error("更新股票排序失败: ", 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) { diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue index 1b958cd..8f4e4cb 100644 --- a/frontend/src/components/stock.vue +++ b/frontend/src/components/stock.vue @@ -226,7 +226,8 @@ onMounted(() => { GetFollowList(currentGroupId.value).then(result => { - followList.value = result + followList.value = result + console.log("onMounted",result) for (const followedStock of result) { if(followedStock.StockCode.startsWith("us")){ followedStock.StockCode="gb_"+ followedStock.StockCode.replace("us", "").toLowerCase() @@ -1273,8 +1274,10 @@ function showK(code,name){ function updateCostPriceAndVolumeNew(code,price,volume,alarm,formModel){ if(formModel.sort){ + console.log("sort:",formModel.sort) SetStockSort(formModel.sort,code).then(result => { //message.success(result) + console.log("sort result:",result) }) } if(formModel.cron){ From 9f2719cdbc13797ce912ef586adb0d567236ba59 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, 23 Jun 2025 18:09:43 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/stock.vue | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue index 5120caa..e231977 100644 --- a/frontend/src/components/stock.vue +++ b/frontend/src/components/stock.vue @@ -151,7 +151,6 @@ const danmakuColor = computed(()=> { const icon = ref('https://raw.githubusercontent.com/ArvinLovegood/go-stock/master/build/appicon.png'); const sortedResults = computed(() => { - ////console.log("computed",sortedResults.value) const sortedKeys =keys(results.value).sort(); ////console.log("sortedKeys",sortedKeys) const sortedObject = {}; @@ -227,7 +226,6 @@ onMounted(() => { GetFollowList(currentGroupId.value).then(result => { followList.value = result - console.log("onMounted",result) for (const followedStock of result) { if(followedStock.StockCode.startsWith("us")){ followedStock.StockCode="gb_"+ followedStock.StockCode.replace("us", "").toLowerCase() @@ -587,14 +585,16 @@ async function updateData(result) { } } - //result.key=result.sort + // result.key=result.sort + results.value = Object.fromEntries( + Object.entries(results.value).filter( + ([key]) => !key.includes(result["股票代码"]) + )); result.key=GetSortKey(result.sort,result["股票代码"]) results.value[GetSortKey(result.sort,result["股票代码"])]=result if(!stocks.value.includes(result["股票代码"])) { delete results.value[result.key] } - - ////console.log("updateData",result) } @@ -1274,10 +1274,8 @@ function showK(code,name){ function updateCostPriceAndVolumeNew(code,price,volume,alarm,formModel){ if(formModel.sort){ - console.log("sort:",formModel.sort) SetStockSort(formModel.sort,code).then(result => { //message.success(result) - console.log("sort result:",result) }) } if(formModel.cron){ @@ -1296,6 +1294,7 @@ function updateCostPriceAndVolumeNew(code,price,volume,alarm,formModel){ message.success(result) GetFollowList(currentGroupId.value).then(result => { followList.value = result + stocks.value=[] for (const followedStock of result) { if (!stocks.value.includes(followedStock.StockCode)) { stocks.value.push(followedStock.StockCode)