Files
cid/service/strategy_service.go
2025-12-18 17:51:33 +08:00

222 lines
6.3 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 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,
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,
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)
}