Files
tyapi-server/internal/application/product/product_application_service_impl.go
2025-07-20 20:53:26 +08:00

227 lines
7.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package product
import (
"context"
"go.uber.org/zap"
"tyapi-server/internal/application/product/dto/commands"
appQueries "tyapi-server/internal/application/product/dto/queries"
"tyapi-server/internal/application/product/dto/responses"
"tyapi-server/internal/domains/product/entities"
product_service "tyapi-server/internal/domains/product/services"
)
// ProductApplicationServiceImpl 产品应用服务实现
// 负责业务流程编排、事务管理、数据转换,不直接操作仓库
type ProductApplicationServiceImpl struct {
productManagementService *product_service.ProductManagementService
productSubscriptionService *product_service.ProductSubscriptionService
logger *zap.Logger
}
// NewProductApplicationService 创建产品应用服务
func NewProductApplicationService(
productManagementService *product_service.ProductManagementService,
productSubscriptionService *product_service.ProductSubscriptionService,
logger *zap.Logger,
) ProductApplicationService {
return &ProductApplicationServiceImpl{
productManagementService: productManagementService,
productSubscriptionService: productSubscriptionService,
logger: logger,
}
}
// CreateProduct 创建产品
// 业务流程1. 构建产品实体 2. 创建产品
func (s *ProductApplicationServiceImpl) CreateProduct(ctx context.Context, cmd *commands.CreateProductCommand) error {
// 1. 构建产品实体
product := &entities.Product{
Name: cmd.Name,
Code: cmd.Code,
Description: cmd.Description,
Content: cmd.Content,
CategoryID: cmd.CategoryID,
Price: cmd.Price,
IsEnabled: cmd.IsEnabled,
IsVisible: cmd.IsVisible,
IsPackage: cmd.IsPackage,
SEOTitle: cmd.SEOTitle,
SEODescription: cmd.SEODescription,
SEOKeywords: cmd.SEOKeywords,
}
// 2. 创建产品
_, err := s.productManagementService.CreateProduct(ctx, product)
return err
}
// UpdateProduct 更新产品
// 业务流程1. 获取现有产品 2. 更新产品信息 3. 保存产品
func (s *ProductApplicationServiceImpl) UpdateProduct(ctx context.Context, cmd *commands.UpdateProductCommand) error {
// 1. 获取现有产品
existingProduct, err := s.productManagementService.GetProductByID(ctx, cmd.ID)
if err != nil {
return err
}
// 2. 更新产品信息
existingProduct.Name = cmd.Name
existingProduct.Code = cmd.Code
existingProduct.Description = cmd.Description
existingProduct.Content = cmd.Content
existingProduct.CategoryID = cmd.CategoryID
existingProduct.Price = cmd.Price
existingProduct.IsEnabled = cmd.IsEnabled
existingProduct.IsVisible = cmd.IsVisible
existingProduct.IsPackage = cmd.IsPackage
existingProduct.SEOTitle = cmd.SEOTitle
existingProduct.SEODescription = cmd.SEODescription
existingProduct.SEOKeywords = cmd.SEOKeywords
// 3. 保存产品
return s.productManagementService.UpdateProduct(ctx, existingProduct)
}
// DeleteProduct 删除产品
// 业务流程1. 删除产品
func (s *ProductApplicationServiceImpl) DeleteProduct(ctx context.Context, cmd *commands.DeleteProductCommand) error {
return s.productManagementService.DeleteProduct(ctx, cmd.ID)
}
// ListProducts 获取产品列表
// 业务流程1. 获取产品列表 2. 构建响应数据
func (s *ProductApplicationServiceImpl) ListProducts(ctx context.Context, query *appQueries.ListProductsQuery) (*responses.ProductListResponse, error) {
// 根据查询条件获取产品列表
var products []*entities.Product
var err error
if query.CategoryID != "" {
products, err = s.productManagementService.GetProductsByCategory(ctx, query.CategoryID)
} else if query.IsVisible != nil && *query.IsVisible {
products, err = s.productManagementService.GetVisibleProducts(ctx)
} else if query.IsEnabled != nil && *query.IsEnabled {
products, err = s.productManagementService.GetEnabledProducts(ctx)
} else {
// 默认获取可见产品
products, err = s.productManagementService.GetVisibleProducts(ctx)
}
if err != nil {
return nil, err
}
// 转换为响应对象
items := make([]responses.ProductInfoResponse, len(products))
for i := range products {
items[i] = *s.convertToProductInfoResponse(products[i])
}
return &responses.ProductListResponse{
Total: int64(len(items)),
Page: query.Page,
Size: query.PageSize,
Items: items,
}, nil
}
// GetProductsByIDs 根据ID列表获取产品
// 业务流程1. 获取产品列表 2. 构建响应数据
func (s *ProductApplicationServiceImpl) GetProductsByIDs(ctx context.Context, query *appQueries.GetProductsByIDsQuery) ([]*responses.ProductInfoResponse, error) {
// 这里需要扩展领域服务来支持批量获取
// 暂时返回空列表
return []*responses.ProductInfoResponse{}, nil
}
// GetSubscribableProducts 获取可订阅产品列表
// 业务流程1. 获取启用产品 2. 过滤可订阅产品 3. 构建响应数据
func (s *ProductApplicationServiceImpl) GetSubscribableProducts(ctx context.Context, query *appQueries.GetSubscribableProductsQuery) ([]*responses.ProductInfoResponse, error) {
products, err := s.productManagementService.GetEnabledProducts(ctx)
if err != nil {
return nil, err
}
// 过滤可订阅的产品
var subscribableProducts []*entities.Product
for _, product := range products {
if product.CanBeSubscribed() {
subscribableProducts = append(subscribableProducts, product)
}
}
// 转换为响应对象
items := make([]*responses.ProductInfoResponse, len(subscribableProducts))
for i := range subscribableProducts {
items[i] = s.convertToProductInfoResponse(subscribableProducts[i])
}
return items, nil
}
// GetProductByID 根据ID获取产品
// 业务流程1. 获取产品信息 2. 构建响应数据
func (s *ProductApplicationServiceImpl) GetProductByID(ctx context.Context, query *appQueries.GetProductQuery) (*responses.ProductInfoResponse, error) {
product, err := s.productManagementService.GetProductWithCategory(ctx, query.ID)
if err != nil {
return nil, err
}
return s.convertToProductInfoResponse(product), nil
}
// GetProductStats 获取产品统计信息
// 业务流程1. 获取产品统计 2. 构建响应数据
func (s *ProductApplicationServiceImpl) GetProductStats(ctx context.Context) (*responses.ProductStatsResponse, error) {
stats, err := s.productSubscriptionService.GetProductStats(ctx)
if err != nil {
return nil, err
}
return &responses.ProductStatsResponse{
TotalProducts: stats["total"],
EnabledProducts: stats["enabled"],
VisibleProducts: stats["visible"],
PackageProducts: 0, // 需要单独统计
}, nil
}
// convertToProductInfoResponse 转换为产品信息响应
func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *entities.Product) *responses.ProductInfoResponse {
response := &responses.ProductInfoResponse{
ID: product.ID,
Name: product.Name,
Code: product.Code,
Description: product.Description,
Content: product.Content,
CategoryID: product.CategoryID,
Price: product.Price,
IsEnabled: product.IsEnabled,
IsVisible: product.IsVisible,
IsPackage: product.IsPackage,
SEOTitle: product.SEOTitle,
SEODescription: product.SEODescription,
SEOKeywords: product.SEOKeywords,
CreatedAt: product.CreatedAt,
UpdatedAt: product.UpdatedAt,
}
// 添加分类信息
if product.Category != nil {
response.Category = s.convertToCategoryInfoResponse(product.Category)
}
return response
}
// convertToCategoryInfoResponse 转换为分类信息响应
func (s *ProductApplicationServiceImpl) convertToCategoryInfoResponse(category *entities.ProductCategory) *responses.CategoryInfoResponse {
return &responses.CategoryInfoResponse{
ID: category.ID,
Name: category.Name,
Description: category.Description,
IsEnabled: category.IsEnabled,
CreatedAt: category.CreatedAt,
UpdatedAt: category.UpdatedAt,
}
}