// Filename: internal/domain/upstream/service.go package upstream import ( "errors" "gemini-balancer/internal/models" "math/rand" "time" "gorm.io/gorm" ) type Service struct { db *gorm.DB } func NewService(db *gorm.DB) *Service { rand.New(rand.NewSource(time.Now().UnixNano())) return &Service{db: db} } func (s *Service) SelectActiveWeighted(upstreams []*models.UpstreamEndpoint) (*models.UpstreamEndpoint, error) { activeUpstreams := make([]*models.UpstreamEndpoint, 0) totalWeight := 0 for _, u := range upstreams { if u.Status == "active" { activeUpstreams = append(activeUpstreams, u) totalWeight += u.Weight } } if len(activeUpstreams) == 0 { return nil, errors.New("no active upstream endpoints available") } if totalWeight <= 0 || len(activeUpstreams) == 1 { return activeUpstreams[0], nil } randomWeight := rand.Intn(totalWeight) for _, u := range activeUpstreams { randomWeight -= u.Weight if randomWeight < 0 { return u, nil } } return activeUpstreams[len(activeUpstreams)-1], nil } // CRUD,供Handler调用 func (s *Service) Create(upstream *models.UpstreamEndpoint) error { if upstream.Weight == 0 { upstream.Weight = 100 // 默认权重 } if upstream.Status == "" { upstream.Status = "active" // 默认状态 } return s.db.Create(upstream).Error } // List Service层只做数据库查询 func (s *Service) List() ([]models.UpstreamEndpoint, error) { var upstreams []models.UpstreamEndpoint err := s.db.Find(&upstreams).Error return upstreams, err } // GetByID Service层只做数据库查询 func (s *Service) GetByID(id int) (*models.UpstreamEndpoint, error) { var upstream models.UpstreamEndpoint if err := s.db.First(&upstream, id).Error; err != nil { return nil, err } return &upstream, nil } // Update Service层只做数据库更新 func (s *Service) Update(upstream *models.UpstreamEndpoint) error { return s.db.Save(upstream).Error } // Delete Service层只做数据库删除 func (s *Service) Delete(id int) (int64, error) { result := s.db.Delete(&models.UpstreamEndpoint{}, id) return result.RowsAffected, result.Error }