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 {