package service import ( "github.com/google/uuid" appErrors "nex/backend/pkg/errors" "nex/backend/internal/domain" "nex/backend/internal/repository" ) type modelService struct { modelRepo repository.ModelRepository providerRepo repository.ProviderRepository cache *RoutingCache } func NewModelService(modelRepo repository.ModelRepository, providerRepo repository.ProviderRepository, cache *RoutingCache) ModelService { return &modelService{modelRepo: modelRepo, providerRepo: providerRepo, cache: cache} } func (s *modelService) Create(model *domain.Model) error { if _, err := s.providerRepo.GetByID(model.ProviderID); err != nil { return appErrors.ErrProviderNotFound } if err := s.checkDuplicateModelName(model.ProviderID, model.ModelName, ""); err != nil { return err } model.ID = uuid.New().String() model.Enabled = true err := s.modelRepo.Create(model) if err != nil { return err } s.cache.SetModel(model) return nil } func (s *modelService) Get(id string) (*domain.Model, error) { return s.modelRepo.GetByID(id) } func (s *modelService) List(providerID string) ([]domain.Model, error) { return s.modelRepo.List(providerID) } func (s *modelService) ListEnabled() ([]domain.Model, error) { return s.modelRepo.ListEnabled() } func (s *modelService) Update(id string, updates map[string]interface{}) error { current, err := s.modelRepo.GetByID(id) if err != nil { return appErrors.ErrModelNotFound } if providerID, ok := updates["provider_id"].(string); ok { if _, err := s.providerRepo.GetByID(providerID); err != nil { return appErrors.ErrProviderNotFound } } newProviderID := current.ProviderID if v, ok := updates["provider_id"].(string); ok { newProviderID = v } newModelName := current.ModelName if v, ok := updates["model_name"].(string); ok { newModelName = v } if newProviderID != current.ProviderID || newModelName != current.ModelName { if err := s.checkDuplicateModelName(newProviderID, newModelName, id); err != nil { return err } } err = s.modelRepo.Update(id, updates) if err != nil { return err } s.cache.InvalidateModel(current.ProviderID, current.ModelName) if newProviderID != current.ProviderID || newModelName != current.ModelName { s.cache.InvalidateModel(newProviderID, newModelName) } return nil } func (s *modelService) Delete(id string) error { model, err := s.modelRepo.GetByID(id) if err != nil { return appErrors.ErrModelNotFound } err = s.modelRepo.Delete(id) if err != nil { return err } s.cache.InvalidateModel(model.ProviderID, model.ModelName) return nil } // checkDuplicateModelName 校验同一供应商下 model_name 是否重复 // excludeID 用于更新时排除自身 func (s *modelService) checkDuplicateModelName(providerID, modelName, excludeID string) error { existing, err := s.modelRepo.FindByProviderAndModelName(providerID, modelName) if err != nil { return nil // 未找到,不重复 } if excludeID != "" && existing.ID == excludeID { return nil // 排除自身 } return appErrors.ErrDuplicateModel }