package service import ( "context" "fmt" "time" "github.com/google/uuid" "market-data-service/api" "market-data-service/internal/repository" ) // AdminServiceImpl 管理服务实现 type AdminServiceImpl struct { db *repository.DB } // NewAdminService 创建管理服务 func NewAdminService(db *repository.DB) AdminService { return &AdminServiceImpl{ db: db, } } // GetDataSourceStatus 获取数据源状态 func (s *AdminServiceImpl) GetDataSourceStatus(ctx context.Context) (*api.DataSourceStatusData, error) { // 查询数据库中的数据源配置 query := ` SELECT asset_class, active_source, standby_sources, updated_at FROM public.data_source_config ` rows, err := s.db.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() data := &api.DataSourceStatusData{} for rows.Next() { var assetClass, activeSource string var standbySources []string var updatedAt time.Time if err := rows.Scan(&assetClass, &activeSource, &standbySources, &updatedAt); err != nil { return nil, err } info := api.DataSourceInfo{ ActiveSource: activeSource, StandbySources: standbySources, Status: api.DataSourceHealthy, } switch assetClass { case "stock": data.Stock = info case "futures": data.Futures = info } } return data, rows.Err() } // SwitchDataSource 切换数据源 func (s *AdminServiceImpl) SwitchDataSource(ctx context.Context, req *api.SourceSwitchRequest) error { // 更新数据源配置 query := ` UPDATE public.data_source_config SET active_source = $1, updated_at = NOW() WHERE asset_class = $2 ` assetClasses := []string{} if req.AssetClass == api.AssetAll { assetClasses = []string{"stock", "futures"} } else { assetClasses = []string{string(req.AssetClass)} } for _, ac := range assetClasses { _, err := s.db.ExecContext(ctx, query, req.Source, ac) if err != nil { return fmt.Errorf("failed to switch %s data source: %w", ac, err) } } // 如果需要同步补录,启动后台任务 if req.SyncBackfill { // TODO: 启动异步补录任务 go func() { // 异步执行补录 }() } return nil } // BackfillData 历史数据补录 func (s *AdminServiceImpl) BackfillData(ctx context.Context, req *api.BackfillRequest) (string, error) { taskID := uuid.New().String() // TODO: 将补录任务存入数据库,启动后台Worker执行 // 这里简化处理,直接返回任务ID return taskID, nil } // HealthCheck 健康检查 func (s *AdminServiceImpl) HealthCheck(ctx context.Context) (*api.HealthResponse, error) { // 检查数据库连接 if err := s.db.PingContext(ctx); err != nil { return nil, fmt.Errorf("database connection failed: %w", err) } return &api.HealthResponse{ Status: "healthy", Timestamp: time.Now(), }, nil }