package handlers import ( "net/http" "strings" "stock-user-system/internal/config" "stock-user-system/internal/datasource" "stock-user-system/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // DataSyncHandler 处理数据同步相关接口。 type DataSyncHandler struct { DB *gorm.DB CFG *config.Config client *datasource.Client } // NewDataSyncHandler 创建数据同步处理器。 func NewDataSyncHandler(db *gorm.DB, cfg *config.Config) *DataSyncHandler { return &DataSyncHandler{ DB: db, CFG: cfg, client: datasource.NewClient(cfg), } } type initStocksResponse struct { Count int `json:"count"` Message string `json:"message"` } // InitStocks 从 Tushare 拉取全部上市股票列表并写入数据库。 func (h *DataSyncHandler) InitStocks(c *gin.Context) { if h.CFG.TushareToken == "" { c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "未配置 TUSHARE_TOKEN"}) return } stocks, err := h.client.ListStocks() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()}) return } records := make([]models.Stock, 0, len(stocks)) for _, s := range stocks { records = append(records, models.Stock{ TsCode: s.TsCode, Symbol: s.Symbol, Name: s.Name, Area: s.Area, Industry: s.Industry, Market: s.Market, Exchange: s.Exchange, ListStatus: s.ListStatus, }) } if err := h.DB.Exec("TRUNCATE TABLE stocks RESTART IDENTITY").Error; err != nil { if !strings.Contains(err.Error(), "does not exist") { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "清空旧数据失败: " + err.Error()}) return } } if err := h.DB.CreateInBatches(records, 500).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "写入股票列表失败: " + err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "data": initStocksResponse{ Count: len(records), Message: "股票列表初始化完成", }, }) }