package service import ( "cid/dao" "cid/model/dto" "cid/model/entity" "context" "encoding/json" "strconv" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" ) var ( Strategy = strategyService{} ) type strategyService struct{} // CreateStrategy 创建策略 func (s *strategyService) CreateStrategy(ctx context.Context, req *dto.CreateStrategyReq) (id int64, err error) { // 检查策略名称是否已存在 existingStrategy, err := dao.Strategy.GetByName(ctx, req.Name) if err != nil { return 0, err } if existingStrategy != nil { return 0, gerror.New("策略名称已存在") } // 验证转化率范围 if req.MaxConversion <= req.MinConversion { return 0, gerror.New("最高转化率必须大于最低转化率") } // 序列化权重配置 weightsJson, err := json.Marshal(req.SourceWeights) if err != nil { return 0, gerror.Wrap(err, "权重配置序列化失败") } strategy := &entity.Strategy{ Name: req.Name, Description: req.Description, MinConversion: req.MinConversion, MaxConversion: req.MaxConversion, SourceWeights: string(weightsJson), MaxAdsPerReq: req.MaxAdsPerReq, Priority: req.Priority, } // 设置状态 strategy.Status = req.Status _, err = dao.Strategy.Create(ctx, strategy) if err != nil { return 0, err } // MongoDB使用ObjectId,创建成功后返回成功状态 return 1, nil } // UpdateStrategy 更新策略 func (s *strategyService) UpdateStrategy(ctx context.Context, req *dto.UpdateStrategyReq) (affected int64, err error) { // 检查策略是否存在 existingStrategy, err := dao.Strategy.GetByID(ctx, strconv.FormatInt(req.Id, 10)) if err != nil { return 0, err } if existingStrategy == nil { return 0, gerror.New("策略不存在") } // 如果更新名称,检查是否与其他策略冲突 if req.Name != "" && req.Name != existingStrategy.Name { conflictStrategy, err := dao.Strategy.GetByName(ctx, req.Name) if err != nil { return 0, err } if conflictStrategy != nil { return 0, gerror.New("策略名称已存在") } } // 验证转化率范围 if req.MaxConversion <= req.MinConversion { return 0, gerror.New("最高转化率必须大于最低转化率") } // 序列化权重配置 weightsJson, err := json.Marshal(req.SourceWeights) if err != nil { return 0, gerror.Wrap(err, "权重配置序列化失败") } strategy := &entity.Strategy{ Name: req.Name, Description: req.Description, MinConversion: req.MinConversion, MaxConversion: req.MaxConversion, SourceWeights: string(weightsJson), MaxAdsPerReq: req.MaxAdsPerReq, Priority: req.Priority, } // 设置状态 strategy.Status = req.Status return dao.Strategy.Update(ctx, strategy) } // DeleteStrategy 删除策略 func (s *strategyService) DeleteStrategy(ctx context.Context, id int64) (affected int64, err error) { // 检查策略是否存在 existingStrategy, err := dao.Strategy.GetByID(ctx, strconv.FormatInt(id, 10)) if err != nil { return 0, err } if existingStrategy == nil { return 0, gerror.New("策略不存在") } return dao.Strategy.Delete(ctx, strconv.FormatInt(id, 10)) } // GetStrategyByID 根据ID获取策略 func (s *strategyService) GetStrategyByID(ctx context.Context, id int64) (strategy *dto.StrategyRes, err error) { entity, err := dao.Strategy.GetByID(ctx, strconv.FormatInt(id, 10)) if err != nil { return nil, err } if entity == nil { return nil, gerror.New("策略不存在") } // 反序列化权重配置 var weights map[string]int if entity.SourceWeights != "" { err = json.Unmarshal([]byte(entity.SourceWeights), &weights) if err != nil { return nil, gerror.Wrap(err, "权重配置反序列化失败") } } // 将ObjectId的十六进制字符串转换为int64,如果失败则使用0 var idInt64 int64 if id, err := strconv.ParseInt(entity.Id.Hex(), 16, 64); err == nil { idInt64 = id } return &dto.StrategyRes{ Id: idInt64, Name: entity.Name, Description: entity.Description, TenantLevel: "", // Strategy实体中没有TenantLevel字段,暂时设为空字符串 MinConversion: entity.MinConversion, MaxConversion: entity.MaxConversion, SourceWeights: weights, MaxAdsPerReq: entity.MaxAdsPerReq, Priority: entity.Priority, Status: entity.Status, CreatedAt: entity.CreatedAt.String(), UpdatedAt: entity.UpdatedAt.String(), CreatedBy: 0, // 这些字段在MongoBaseDO中不存在,暂时设为0 UpdatedBy: 0, }, nil } // GetStrategyList 获取策略列表 func (s *strategyService) GetStrategyList(ctx context.Context, req *dto.GetStrategyListReq) (res *dto.GetStrategyListRes, err error) { list, total, err := dao.Strategy.GetList(ctx, req.Page, req.Size, req.TenantLevel, req.Status) if err != nil { return nil, err } var strategyList []*dto.StrategyRes for _, entity := range list { // 反序列化权重配置 var weights map[string]int if entity.SourceWeights != "" { err = json.Unmarshal([]byte(entity.SourceWeights), &weights) if err != nil { g.Log().Warningf(ctx, "策略 %d 权重配置反序列化失败: %v", entity.Id, err) weights = make(map[string]int) } } // 将ObjectId的十六进制字符串转换为int64,如果失败则使用0 var idInt64 int64 if id, err := strconv.ParseInt(entity.Id.Hex(), 16, 64); err == nil { idInt64 = id } strategyList = append(strategyList, &dto.StrategyRes{ Id: idInt64, Name: entity.Name, Description: entity.Description, TenantLevel: "", // Strategy实体中没有TenantLevel字段,暂时设为空字符串 MinConversion: entity.MinConversion, MaxConversion: entity.MaxConversion, SourceWeights: weights, MaxAdsPerReq: entity.MaxAdsPerReq, Priority: entity.Priority, Status: entity.Status, CreatedAt: entity.CreatedAt.String(), UpdatedAt: entity.UpdatedAt.String(), CreatedBy: 0, // 这些字段在MongoBaseDO中不存在,暂时设为0 UpdatedBy: 0, }) } return &dto.GetStrategyListRes{ List: strategyList, Total: total, Page: req.Page, Size: req.Size, }, nil } // GetStrategyByTenantLevel 根据租户级别获取策略 func (s *strategyService) GetStrategyByTenantLevel(ctx context.Context, tenantLevel string) (strategy *entity.Strategy, err error) { return dao.Strategy.GetByTenantLevel(ctx, tenantLevel) }