From 1453088c0b717e47ab5339b992d5b9ccf24f82cf Mon Sep 17 00:00:00 2001 From: fish Date: Sat, 4 Jul 2026 11:11:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(stock):=20=E7=BB=9F=E8=AE=A1=E6=B6=A8?= =?UTF-8?q?=E8=B7=8C=E6=97=B6=E8=BF=87=E6=BB=A4=E7=9C=9F=E5=81=9C=E7=89=8C?= =?UTF-8?q?=E8=82=A1=EF=BC=8C=E5=90=8C=E6=AD=A5=E6=97=A5=E5=BF=97=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=8B=89=E5=8F=96=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/handlers/stock.go | 12 +++++++----- backend/internal/services/stock_sync.go | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/backend/internal/handlers/stock.go b/backend/internal/handlers/stock.go index 2be4e1a..45d2d68 100644 --- a/backend/internal/handlers/stock.go +++ b/backend/internal/handlers/stock.go @@ -65,6 +65,8 @@ func (h *StockHandler) Overview(c *gin.Context) { return } + baseWhere := "trade_date = ? AND symbol NOT IN ? AND NOT (volume = 0 AND change_pct = 0)" + var counts marketCounts if err := h.DB.WithContext(ctx).Model(&models.StockDailyQuote{}). Select(` @@ -73,7 +75,7 @@ func (h *StockHandler) Overview(c *gin.Context) { SUM(CASE WHEN change_pct < 0 THEN 1 ELSE 0 END) AS down, SUM(CASE WHEN change_pct = 0 THEN 1 ELSE 0 END) AS flat `). - Where("trade_date = ? AND symbol NOT IN ?", latestDate, indexSymbolsList()). + Where(baseWhere, latestDate, indexSymbolsList()). Scan(&counts).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "统计涨跌失败"}) return @@ -82,12 +84,12 @@ func (h *StockHandler) Overview(c *gin.Context) { var avgChange float64 h.DB.WithContext(ctx).Model(&models.StockDailyQuote{}). Select("COALESCE(AVG(change_pct), 0)"). - Where("trade_date = ? AND symbol NOT IN ?", latestDate, indexSymbolsList()). + Where(baseWhere, latestDate, indexSymbolsList()). Scan(&avgChange) indices := h.topRows(ctx, latestDate, "symbol IN ?", indexSymbolsList(), 10, false) - gainers := h.topRows(ctx, latestDate, "symbol NOT IN ?", indexSymbolsList(), 10, true) - losers := h.topRows(ctx, latestDate, "symbol NOT IN ?", indexSymbolsList(), 10, false) + gainers := h.topRows(ctx, latestDate, "symbol NOT IN ? AND NOT (volume = 0 AND change_pct = 0)", indexSymbolsList(), 10, true) + losers := h.topRows(ctx, latestDate, "symbol NOT IN ? AND NOT (volume = 0 AND change_pct = 0)", indexSymbolsList(), 10, false) turnover := h.topRowsByAmount(ctx, latestDate) c.JSON(http.StatusOK, overviewResponse{ @@ -121,7 +123,7 @@ func (h *StockHandler) topRowsByAmount(ctx context.Context, tradeDate time.Time) var rows []stockRow h.DB.WithContext(ctx).Model(&models.StockDailyQuote{}). Select("symbol, name, close, change_pct, amount"). - Where("trade_date = ? AND symbol NOT IN ?", tradeDate, indexSymbolsList()). + Where("trade_date = ? AND symbol NOT IN ? AND NOT (volume = 0 AND change_pct = 0)", tradeDate, indexSymbolsList()). Order("amount DESC"). Limit(10). Scan(&rows) diff --git a/backend/internal/services/stock_sync.go b/backend/internal/services/stock_sync.go index e6002c1..6e9809f 100644 --- a/backend/internal/services/stock_sync.go +++ b/backend/internal/services/stock_sync.go @@ -3,6 +3,7 @@ package services import ( "context" "fmt" + "log" "sync" "time" @@ -87,6 +88,9 @@ func (s *StockSyncService) doSync(ctx context.Context) (int, error) { return 0, fmt.Errorf("no quotes returned") } + log.Printf("[stock sync] fetched %d stock quotes from CN_Equity_A, %d index quotes, total %d", + len(stockQuotes), len(indexQuotes), len(quotes)) + // 3. 归一化并写入 DB records := make([]models.StockDailyQuote, 0, len(quotes)) for _, q := range quotes {