167 lines
4.6 KiB
Go
167 lines
4.6 KiB
Go
package comb
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"sort"
|
||
"sync"
|
||
|
||
"tyapi-server/internal/domains/api/services/processors"
|
||
"tyapi-server/internal/domains/product/entities"
|
||
"tyapi-server/internal/domains/product/services"
|
||
)
|
||
|
||
// CombService 组合包服务
|
||
type CombService struct {
|
||
productManagementService *services.ProductManagementService
|
||
processorRegistry map[string]processors.ProcessorFunc
|
||
}
|
||
|
||
// NewCombService 创建组合包服务
|
||
func NewCombService(productManagementService *services.ProductManagementService) *CombService {
|
||
return &CombService{
|
||
productManagementService: productManagementService,
|
||
processorRegistry: make(map[string]processors.ProcessorFunc),
|
||
}
|
||
}
|
||
|
||
// RegisterProcessor 注册处理器
|
||
func (cs *CombService) RegisterProcessor(apiCode string, processor processors.ProcessorFunc) {
|
||
cs.processorRegistry[apiCode] = processor
|
||
}
|
||
|
||
// ProcessCombRequest 处理组合包请求 - 实现 CombServiceInterface
|
||
func (cs *CombService) ProcessCombRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies, packageCode string) ([]byte, error) {
|
||
// 1. 根据组合包code获取产品信息
|
||
packageProduct, err := cs.productManagementService.GetProductByCode(ctx, packageCode)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("获取组合包信息失败: %s", err.Error())
|
||
}
|
||
|
||
if !packageProduct.IsPackage {
|
||
return nil, fmt.Errorf("产品 %s 不是组合包", packageCode)
|
||
}
|
||
|
||
// 2. 获取组合包的所有子产品
|
||
packageItems, err := cs.productManagementService.GetPackageItems(ctx, packageProduct.ID)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("获取组合包子产品失败: %s", err.Error())
|
||
}
|
||
|
||
if len(packageItems) == 0 {
|
||
return nil, fmt.Errorf("组合包 %s 没有配置子产品", packageCode)
|
||
}
|
||
|
||
// 3. 并发调用所有子产品的处理器
|
||
results := cs.processSubProducts(ctx, params, deps, packageItems)
|
||
|
||
// 4. 组合结果
|
||
return cs.combineResults(results)
|
||
}
|
||
|
||
// processSubProducts 并发处理子产品
|
||
func (cs *CombService) processSubProducts(
|
||
ctx context.Context,
|
||
params []byte,
|
||
deps *processors.ProcessorDependencies,
|
||
packageItems []*entities.ProductPackageItem,
|
||
) []*SubProductResult {
|
||
results := make([]*SubProductResult, 0, len(packageItems))
|
||
var wg sync.WaitGroup
|
||
var mu sync.Mutex
|
||
|
||
// 并发处理每个子产品
|
||
for _, item := range packageItems {
|
||
wg.Add(1)
|
||
go func(item *entities.ProductPackageItem) {
|
||
defer wg.Done()
|
||
|
||
result := cs.processSingleSubProduct(ctx, params, deps, item)
|
||
|
||
mu.Lock()
|
||
results = append(results, result)
|
||
mu.Unlock()
|
||
}(item)
|
||
}
|
||
|
||
wg.Wait()
|
||
|
||
// 按SortOrder排序
|
||
sort.Slice(results, func(i, j int) bool {
|
||
return results[i].SortOrder < results[j].SortOrder
|
||
})
|
||
|
||
return results
|
||
}
|
||
|
||
// processSingleSubProduct 处理单个子产品
|
||
func (cs *CombService) processSingleSubProduct(
|
||
ctx context.Context,
|
||
params []byte,
|
||
deps *processors.ProcessorDependencies,
|
||
item *entities.ProductPackageItem,
|
||
) *SubProductResult {
|
||
result := &SubProductResult{
|
||
ApiCode: item.Product.Code,
|
||
SortOrder: item.SortOrder,
|
||
Success: false,
|
||
}
|
||
|
||
// 查找对应的处理器
|
||
processor, exists := cs.processorRegistry[item.Product.Code]
|
||
if !exists {
|
||
result.Error = fmt.Sprintf("未找到处理器: %s", item.Product.Code)
|
||
return result
|
||
}
|
||
|
||
// 调用处理器
|
||
respBytes, err := processor(ctx, params, deps)
|
||
if err != nil {
|
||
result.Error = err.Error()
|
||
return result
|
||
}
|
||
|
||
// 解析响应
|
||
var responseData interface{}
|
||
if err := json.Unmarshal(respBytes, &responseData); err != nil {
|
||
result.Error = fmt.Sprintf("解析响应失败: %s", err.Error())
|
||
return result
|
||
}
|
||
|
||
result.Success = true
|
||
result.Data = responseData
|
||
|
||
return result
|
||
}
|
||
|
||
// combineResults 组合所有子产品的结果
|
||
func (cs *CombService) combineResults(results []*SubProductResult) ([]byte, error) {
|
||
// 构建组合结果
|
||
combinedResult := &CombinedResult{
|
||
Responses: results,
|
||
}
|
||
|
||
// 序列化结果
|
||
respBytes, err := json.Marshal(combinedResult)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("序列化组合结果失败: %s", err.Error())
|
||
}
|
||
|
||
return respBytes, nil
|
||
}
|
||
|
||
// SubProductResult 子产品处理结果
|
||
type SubProductResult struct {
|
||
ApiCode string `json:"api_code"` // 子接口标识
|
||
Data interface{} `json:"data"` // 子接口返回数据
|
||
Success bool `json:"success"` // 是否成功
|
||
Error string `json:"error,omitempty"` // 错误信息(仅在失败时)
|
||
SortOrder int `json:"-"` // 排序字段,不输出到JSON
|
||
}
|
||
|
||
// CombinedResult 组合结果
|
||
type CombinedResult struct {
|
||
Responses []*SubProductResult `json:"responses"` // 子接口响应列表
|
||
}
|