package services import ( "errors" "fmt" "strings" "tyapi-server/internal/domains/product/entities" "tyapi-server/internal/domains/product/repositories" ) // ProductService 产品领域服务 type ProductService struct { productRepo repositories.ProductRepository categoryRepo repositories.ProductCategoryRepository subscriptionRepo repositories.SubscriptionRepository } // NewProductService 创建产品领域服务 func NewProductService( productRepo repositories.ProductRepository, categoryRepo repositories.ProductCategoryRepository, subscriptionRepo repositories.SubscriptionRepository, ) *ProductService { return &ProductService{ productRepo: productRepo, categoryRepo: categoryRepo, subscriptionRepo: subscriptionRepo, } } // ValidateProduct 验证产品 func (s *ProductService) ValidateProduct(product *entities.Product) error { if product == nil { return errors.New("产品不能为空") } if strings.TrimSpace(product.Name) == "" { return errors.New("产品名称不能为空") } if strings.TrimSpace(product.Code) == "" { return errors.New("产品编号不能为空") } if product.Price < 0 { return errors.New("产品价格不能为负数") } // 验证分类是否存在 if product.CategoryID != "" { category, err := s.categoryRepo.GetByID(nil, product.CategoryID) if err != nil { return fmt.Errorf("产品分类不存在: %w", err) } if !category.IsValid() { return errors.New("产品分类已禁用或删除") } } return nil } // ValidateProductCode 验证产品编号唯一性 func (s *ProductService) ValidateProductCode(code string, excludeID string) error { if strings.TrimSpace(code) == "" { return errors.New("产品编号不能为空") } existingProduct, err := s.productRepo.FindByCode(nil, code) if err == nil && existingProduct != nil && existingProduct.ID != excludeID { return errors.New("产品编号已存在") } return nil } // CanUserSubscribeProduct 检查用户是否可以订阅产品 func (s *ProductService) CanUserSubscribeProduct(userID string, productID string) (bool, error) { // 检查产品是否存在且可订阅 product, err := s.productRepo.GetByID(nil, productID) if err != nil { return false, fmt.Errorf("产品不存在: %w", err) } if !product.CanBeSubscribed() { return false, errors.New("产品不可订阅") } // 检查用户是否已有该产品的订阅 existingSubscription, err := s.subscriptionRepo.FindByUserAndProduct(nil, userID, productID) if err == nil && existingSubscription != nil { return false, errors.New("用户已有该产品的订阅") } return true, nil } // GetProductWithCategory 获取产品及其分类信息 func (s *ProductService) GetProductWithCategory(productID string) (*entities.Product, error) { product, err := s.productRepo.GetByID(nil, productID) if err != nil { return nil, fmt.Errorf("产品不存在: %w", err) } // 加载分类信息 if product.CategoryID != "" { category, err := s.categoryRepo.GetByID(nil, product.CategoryID) if err == nil { product.Category = &category } } return &product, nil } // GetVisibleProducts 获取可见产品列表 func (s *ProductService) GetVisibleProducts() ([]*entities.Product, error) { return s.productRepo.FindVisible(nil) } // GetEnabledProducts 获取启用产品列表 func (s *ProductService) GetEnabledProducts() ([]*entities.Product, error) { return s.productRepo.FindEnabled(nil) } // GetProductsByCategory 根据分类获取产品 func (s *ProductService) GetProductsByCategory(categoryID string) ([]*entities.Product, error) { return s.productRepo.FindByCategoryID(nil, categoryID) } // GetProductStats 获取产品统计信息 func (s *ProductService) GetProductStats() (map[string]int64, error) { stats := make(map[string]int64) total, err := s.productRepo.CountByCategory(nil, "") if err == nil { stats["total"] = total } enabled, err := s.productRepo.CountEnabled(nil) if err == nil { stats["enabled"] = enabled } visible, err := s.productRepo.CountVisible(nil) if err == nil { stats["visible"] = visible } return stats, nil }