This commit is contained in:
2025-07-20 20:53:26 +08:00
parent 83bf9aea7d
commit 8ad1d7288e
158 changed files with 18156 additions and 13188 deletions

View File

@@ -0,0 +1,144 @@
package services
import (
"context"
"errors"
"fmt"
"go.uber.org/zap"
"tyapi-server/internal/domains/product/entities"
"tyapi-server/internal/domains/product/repositories"
)
// ProductSubscriptionService 产品订阅领域服务
// 负责产品订阅相关的业务逻辑,包括订阅验证、订阅管理等
type ProductSubscriptionService struct {
productRepo repositories.ProductRepository
subscriptionRepo repositories.SubscriptionRepository
logger *zap.Logger
}
// NewProductSubscriptionService 创建产品订阅领域服务
func NewProductSubscriptionService(
productRepo repositories.ProductRepository,
subscriptionRepo repositories.SubscriptionRepository,
logger *zap.Logger,
) *ProductSubscriptionService {
return &ProductSubscriptionService{
productRepo: productRepo,
subscriptionRepo: subscriptionRepo,
logger: logger,
}
}
// CanUserSubscribeProduct 检查用户是否可以订阅产品
func (s *ProductSubscriptionService) CanUserSubscribeProduct(ctx context.Context, userID string, productID string) (bool, error) {
// 检查产品是否存在且可订阅
product, err := s.productRepo.GetByID(ctx, productID)
if err != nil {
return false, fmt.Errorf("产品不存在: %w", err)
}
if !product.CanBeSubscribed() {
return false, errors.New("产品不可订阅")
}
// 检查用户是否已有该产品的订阅
existingSubscription, err := s.subscriptionRepo.FindByUserAndProduct(ctx, userID, productID)
if err == nil && existingSubscription != nil {
return false, errors.New("用户已有该产品的订阅")
}
return true, nil
}
// CreateSubscription 创建订阅
func (s *ProductSubscriptionService) CreateSubscription(ctx context.Context, userID, productID string) (*entities.Subscription, error) {
// 检查是否可以订阅
canSubscribe, err := s.CanUserSubscribeProduct(ctx, userID, productID)
if err != nil {
return nil, err
}
if !canSubscribe {
return nil, errors.New("无法订阅该产品")
}
// 获取产品信息以获取价格
product, err := s.productRepo.GetByID(ctx, productID)
if err != nil {
return nil, fmt.Errorf("产品不存在: %w", err)
}
// 创建订阅
subscription := &entities.Subscription{
UserID: userID,
ProductID: productID,
Price: product.Price,
}
createdSubscription, err := s.subscriptionRepo.Create(ctx, *subscription)
if err != nil {
s.logger.Error("创建订阅失败", zap.Error(err))
return nil, fmt.Errorf("创建订阅失败: %w", err)
}
s.logger.Info("订阅创建成功",
zap.String("subscription_id", createdSubscription.ID),
zap.String("user_id", userID),
zap.String("product_id", productID),
)
return &createdSubscription, nil
}
// GetUserSubscriptions 获取用户订阅列表
func (s *ProductSubscriptionService) GetUserSubscriptions(ctx context.Context, userID string) ([]*entities.Subscription, error) {
return s.subscriptionRepo.FindByUserID(ctx, userID)
}
// GetSubscriptionByID 根据ID获取订阅
func (s *ProductSubscriptionService) GetSubscriptionByID(ctx context.Context, subscriptionID string) (*entities.Subscription, error) {
subscription, err := s.subscriptionRepo.GetByID(ctx, subscriptionID)
if err != nil {
return nil, fmt.Errorf("订阅不存在: %w", err)
}
return &subscription, nil
}
// CancelSubscription 取消订阅
func (s *ProductSubscriptionService) CancelSubscription(ctx context.Context, subscriptionID string) error {
// 由于订阅实体没有状态字段,这里直接删除订阅
if err := s.subscriptionRepo.Delete(ctx, subscriptionID); err != nil {
s.logger.Error("取消订阅失败", zap.Error(err))
return fmt.Errorf("取消订阅失败: %w", err)
}
s.logger.Info("订阅取消成功",
zap.String("subscription_id", subscriptionID),
)
return nil
}
// GetProductStats 获取产品统计信息
func (s *ProductSubscriptionService) GetProductStats(ctx context.Context) (map[string]int64, error) {
stats := make(map[string]int64)
total, err := s.productRepo.CountByCategory(ctx, "")
if err == nil {
stats["total"] = total
}
enabled, err := s.productRepo.CountEnabled(ctx)
if err == nil {
stats["enabled"] = enabled
}
visible, err := s.productRepo.CountVisible(ctx)
if err == nil {
stats["visible"] = visible
}
return stats, nil
}