v0.1
This commit is contained in:
@@ -2,7 +2,9 @@ package product
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"tyapi-server/internal/application/product/dto/commands"
|
||||
@@ -10,25 +12,29 @@ import (
|
||||
"tyapi-server/internal/application/product/dto/responses"
|
||||
"tyapi-server/internal/domains/product/entities"
|
||||
product_service "tyapi-server/internal/domains/product/services"
|
||||
"tyapi-server/internal/shared/interfaces"
|
||||
)
|
||||
|
||||
// ProductApplicationServiceImpl 产品应用服务实现
|
||||
// 负责业务流程编排、事务管理、数据转换,不直接操作仓库
|
||||
type ProductApplicationServiceImpl struct {
|
||||
productManagementService *product_service.ProductManagementService
|
||||
productSubscriptionService *product_service.ProductSubscriptionService
|
||||
logger *zap.Logger
|
||||
productManagementService *product_service.ProductManagementService
|
||||
productSubscriptionService *product_service.ProductSubscriptionService
|
||||
productApiConfigAppService ProductApiConfigApplicationService
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewProductApplicationService 创建产品应用服务
|
||||
func NewProductApplicationService(
|
||||
productManagementService *product_service.ProductManagementService,
|
||||
productSubscriptionService *product_service.ProductSubscriptionService,
|
||||
productApiConfigAppService ProductApiConfigApplicationService,
|
||||
logger *zap.Logger,
|
||||
) ProductApplicationService {
|
||||
return &ProductApplicationServiceImpl{
|
||||
productManagementService: productManagementService,
|
||||
productSubscriptionService: productSubscriptionService,
|
||||
productApiConfigAppService: productApiConfigAppService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
@@ -43,7 +49,7 @@ func (s *ProductApplicationServiceImpl) CreateProduct(ctx context.Context, cmd *
|
||||
Description: cmd.Description,
|
||||
Content: cmd.Content,
|
||||
CategoryID: cmd.CategoryID,
|
||||
Price: cmd.Price,
|
||||
Price: decimal.NewFromFloat(cmd.Price),
|
||||
IsEnabled: cmd.IsEnabled,
|
||||
IsVisible: cmd.IsVisible,
|
||||
IsPackage: cmd.IsPackage,
|
||||
@@ -72,7 +78,7 @@ func (s *ProductApplicationServiceImpl) UpdateProduct(ctx context.Context, cmd *
|
||||
existingProduct.Description = cmd.Description
|
||||
existingProduct.Content = cmd.Content
|
||||
existingProduct.CategoryID = cmd.CategoryID
|
||||
existingProduct.Price = cmd.Price
|
||||
existingProduct.Price = decimal.NewFromFloat(cmd.Price)
|
||||
existingProduct.IsEnabled = cmd.IsEnabled
|
||||
existingProduct.IsVisible = cmd.IsVisible
|
||||
existingProduct.IsPackage = cmd.IsPackage
|
||||
@@ -92,22 +98,9 @@ func (s *ProductApplicationServiceImpl) DeleteProduct(ctx context.Context, cmd *
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (s *ProductApplicationServiceImpl) ListProducts(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*responses.ProductListResponse, error) {
|
||||
// 调用领域服务获取产品列表
|
||||
products, total, err := s.productManagementService.ListProducts(ctx, filters, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -119,9 +112,9 @@ func (s *ProductApplicationServiceImpl) ListProducts(ctx context.Context, query
|
||||
}
|
||||
|
||||
return &responses.ProductListResponse{
|
||||
Total: int64(len(items)),
|
||||
Page: query.Page,
|
||||
Size: query.PageSize,
|
||||
Total: total,
|
||||
Page: options.Page,
|
||||
Size: options.PageSize,
|
||||
Items: items,
|
||||
}, nil
|
||||
}
|
||||
@@ -186,6 +179,177 @@ func (s *ProductApplicationServiceImpl) GetProductStats(ctx context.Context) (*r
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AddPackageItem 添加组合包子产品
|
||||
func (s *ProductApplicationServiceImpl) AddPackageItem(ctx context.Context, packageID string, cmd *commands.AddPackageItemCommand) error {
|
||||
// 验证组合包是否存在
|
||||
packageProduct, err := s.productManagementService.GetProductByID(ctx, packageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !packageProduct.IsPackage {
|
||||
return fmt.Errorf("产品不是组合包")
|
||||
}
|
||||
|
||||
// 验证子产品是否存在且不是组合包
|
||||
subProduct, err := s.productManagementService.GetProductByID(ctx, cmd.ProductID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subProduct.IsPackage {
|
||||
return fmt.Errorf("不能将组合包作为子产品")
|
||||
}
|
||||
|
||||
// 检查是否已经存在
|
||||
existingItems, err := s.productManagementService.GetPackageItems(ctx, packageID)
|
||||
if err == nil {
|
||||
for _, item := range existingItems {
|
||||
if item.ProductID == cmd.ProductID {
|
||||
return fmt.Errorf("该产品已在组合包中")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前最大排序号
|
||||
maxSortOrder := 0
|
||||
if existingItems != nil {
|
||||
for _, item := range existingItems {
|
||||
if item.SortOrder > maxSortOrder {
|
||||
maxSortOrder = item.SortOrder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建组合包项目
|
||||
packageItem := &entities.ProductPackageItem{
|
||||
PackageID: packageID,
|
||||
ProductID: cmd.ProductID,
|
||||
SortOrder: maxSortOrder + 1,
|
||||
}
|
||||
|
||||
return s.productManagementService.CreatePackageItem(ctx, packageItem)
|
||||
}
|
||||
|
||||
// UpdatePackageItem 更新组合包子产品
|
||||
func (s *ProductApplicationServiceImpl) UpdatePackageItem(ctx context.Context, packageID, itemID string, cmd *commands.UpdatePackageItemCommand) error {
|
||||
// 验证组合包项目是否存在
|
||||
packageItem, err := s.productManagementService.GetPackageItemByID(ctx, itemID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if packageItem.PackageID != packageID {
|
||||
return fmt.Errorf("组合包项目不属于指定组合包")
|
||||
}
|
||||
|
||||
// 更新项目
|
||||
packageItem.SortOrder = cmd.SortOrder
|
||||
|
||||
return s.productManagementService.UpdatePackageItem(ctx, packageItem)
|
||||
}
|
||||
|
||||
// RemovePackageItem 移除组合包子产品
|
||||
func (s *ProductApplicationServiceImpl) RemovePackageItem(ctx context.Context, packageID, itemID string) error {
|
||||
// 验证组合包项目是否存在
|
||||
packageItem, err := s.productManagementService.GetPackageItemByID(ctx, itemID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if packageItem.PackageID != packageID {
|
||||
return fmt.Errorf("组合包项目不属于指定组合包")
|
||||
}
|
||||
|
||||
return s.productManagementService.DeletePackageItem(ctx, itemID)
|
||||
}
|
||||
|
||||
// ReorderPackageItems 重新排序组合包子产品
|
||||
func (s *ProductApplicationServiceImpl) ReorderPackageItems(ctx context.Context, packageID string, cmd *commands.ReorderPackageItemsCommand) error {
|
||||
// 验证所有项目是否属于该组合包
|
||||
for i, itemID := range cmd.ItemIDs {
|
||||
packageItem, err := s.productManagementService.GetPackageItemByID(ctx, itemID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if packageItem.PackageID != packageID {
|
||||
return fmt.Errorf("组合包项目不属于指定组合包")
|
||||
}
|
||||
|
||||
// 更新排序
|
||||
packageItem.SortOrder = i + 1
|
||||
if err := s.productManagementService.UpdatePackageItem(ctx, packageItem); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePackageItems 批量更新组合包子产品
|
||||
func (s *ProductApplicationServiceImpl) UpdatePackageItems(ctx context.Context, packageID string, cmd *commands.UpdatePackageItemsCommand) error {
|
||||
// 验证组合包是否存在
|
||||
packageProduct, err := s.productManagementService.GetProductByID(ctx, packageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !packageProduct.IsPackage {
|
||||
return fmt.Errorf("产品不是组合包")
|
||||
}
|
||||
|
||||
// 验证所有子产品是否存在且不是组合包
|
||||
for _, item := range cmd.Items {
|
||||
subProduct, err := s.productManagementService.GetProductByID(ctx, item.ProductID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subProduct.IsPackage {
|
||||
return fmt.Errorf("不能将组合包作为子产品")
|
||||
}
|
||||
}
|
||||
|
||||
// 使用事务进行批量更新
|
||||
return s.productManagementService.UpdatePackageItemsBatch(ctx, packageID, cmd.Items)
|
||||
}
|
||||
|
||||
// GetAvailableProducts 获取可选子产品列表
|
||||
func (s *ProductApplicationServiceImpl) GetAvailableProducts(ctx context.Context, query *appQueries.GetAvailableProductsQuery) (*responses.ProductListResponse, error) {
|
||||
// 构建筛选条件
|
||||
filters := make(map[string]interface{})
|
||||
filters["is_package"] = false // 只获取非组合包产品
|
||||
filters["is_enabled"] = true // 只获取启用产品
|
||||
|
||||
if query.Keyword != "" {
|
||||
filters["keyword"] = query.Keyword
|
||||
}
|
||||
if query.CategoryID != "" {
|
||||
filters["category_id"] = query.CategoryID
|
||||
}
|
||||
|
||||
// 设置分页选项
|
||||
options := interfaces.ListOptions{
|
||||
Page: query.Page,
|
||||
PageSize: query.PageSize,
|
||||
Sort: "created_at",
|
||||
Order: "desc",
|
||||
}
|
||||
|
||||
// 获取产品列表
|
||||
products, total, err := s.productManagementService.ListProducts(ctx, filters, options)
|
||||
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: total,
|
||||
Page: options.Page,
|
||||
Size: options.PageSize,
|
||||
Items: items,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// convertToProductInfoResponse 转换为产品信息响应
|
||||
func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *entities.Product) *responses.ProductInfoResponse {
|
||||
response := &responses.ProductInfoResponse{
|
||||
@@ -195,7 +359,7 @@ func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *en
|
||||
Description: product.Description,
|
||||
Content: product.Content,
|
||||
CategoryID: product.CategoryID,
|
||||
Price: product.Price,
|
||||
Price: product.Price.InexactFloat64(),
|
||||
IsEnabled: product.IsEnabled,
|
||||
IsVisible: product.IsVisible,
|
||||
IsPackage: product.IsPackage,
|
||||
@@ -211,6 +375,21 @@ func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *en
|
||||
response.Category = s.convertToCategoryInfoResponse(product.Category)
|
||||
}
|
||||
|
||||
// 转换组合包项目信息
|
||||
if product.IsPackage && len(product.PackageItems) > 0 {
|
||||
response.PackageItems = make([]*responses.PackageItemResponse, len(product.PackageItems))
|
||||
for i, item := range product.PackageItems {
|
||||
response.PackageItems[i] = &responses.PackageItemResponse{
|
||||
ID: item.ID,
|
||||
ProductID: item.ProductID,
|
||||
ProductCode: item.Product.Code,
|
||||
ProductName: item.Product.Name,
|
||||
SortOrder: item.SortOrder,
|
||||
Price: item.Product.Price.InexactFloat64(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
@@ -224,4 +403,24 @@ func (s *ProductApplicationServiceImpl) convertToCategoryInfoResponse(category *
|
||||
CreatedAt: category.CreatedAt,
|
||||
UpdatedAt: category.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// GetProductApiConfig 获取产品API配置
|
||||
func (s *ProductApplicationServiceImpl) GetProductApiConfig(ctx context.Context, productID string) (*responses.ProductApiConfigResponse, error) {
|
||||
return s.productApiConfigAppService.GetProductApiConfig(ctx, productID)
|
||||
}
|
||||
|
||||
// CreateProductApiConfig 创建产品API配置
|
||||
func (s *ProductApplicationServiceImpl) CreateProductApiConfig(ctx context.Context, productID string, config *responses.ProductApiConfigResponse) error {
|
||||
return s.productApiConfigAppService.CreateProductApiConfig(ctx, productID, config)
|
||||
}
|
||||
|
||||
// UpdateProductApiConfig 更新产品API配置
|
||||
func (s *ProductApplicationServiceImpl) UpdateProductApiConfig(ctx context.Context, configID string, config *responses.ProductApiConfigResponse) error {
|
||||
return s.productApiConfigAppService.UpdateProductApiConfig(ctx, configID, config)
|
||||
}
|
||||
|
||||
// DeleteProductApiConfig 删除产品API配置
|
||||
func (s *ProductApplicationServiceImpl) DeleteProductApiConfig(ctx context.Context, configID string) error {
|
||||
return s.productApiConfigAppService.DeleteProductApiConfig(ctx, configID)
|
||||
}
|
||||
Reference in New Issue
Block a user