Browse Source

广告点击计费重构

xueyiming 1 day ago
parent
commit
7cb6cbbeff

+ 1 - 1
ad-engine-commons/pom.xml

@@ -26,7 +26,7 @@
         <dependency>
             <groupId>com.tzld.piaoquan</groupId>
             <artifactId>recommend-feature-client</artifactId>
-            <version>1.1.22</version>
+            <version>1.1.23</version>
         </dependency>
         <dependency>
             <groupId>com.tzld.piaoquan</groupId>

+ 2 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/dto/AdPlatformCreativeDTO.java

@@ -50,4 +50,6 @@ public class AdPlatformCreativeDTO {
     private Long skuId;
 
     private String customer;
+
+    private Long customerId;
 }

+ 7 - 0
ad-engine-server/src/main/java/com/tzld/piaoquan/ad/engine/server/controller/AdRecommendController.java

@@ -47,6 +47,13 @@ public class AdRecommendController {
                 Double ctcvrScore = rankResult.getScoreMap().get("ctcvrScore");
                 if (ctcvrScore != null) {
                     contentMap.put("ecpm", ctcvrScore * rankResult.getCpa() * 1000);
+                    if (rankResult.getExt().get("correctionFactor") != null) {
+                        contentMap.put("revisedBid", ctcvrScore * rankResult.getCpa() * (double) rankResult.getExt().get("correctionFactor"));
+                    } else {
+                        contentMap.put("revisedBid", ctcvrScore * rankResult.getCpa());
+                    }
+                } else {
+                    contentMap.put("revisedBid", rankResult.getCpm() / 1000);
                 }
                 if (rankResult.getExt().get("isGuaranteed") != null && rankResult.getExt().get("isGuaranteed").equals(true)) {
                     contentMap.put("type", GuaranteedTypeEnum.IS_GUARANTEED.getType());

+ 13 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/entity/CorrectCpaParam.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.ad.engine.service.entity;
+
+import lombok.Data;
+
+@Data
+public class CorrectCpaParam {
+    private Integer view;
+    private Double correctionFactor;
+    private Double realCtcvrHour;
+    private Double pCtcvrHour;
+    private Double realCtcvrDay;
+    private Double pCtcvrDay;
+}

+ 147 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBasic.java

@@ -11,7 +11,9 @@ import com.tzld.piaoquan.ad.engine.commons.redis.AdRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
+import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
 import com.tzld.piaoquan.ad.engine.commons.util.ObjUtil;
+import com.tzld.piaoquan.ad.engine.service.entity.CorrectCpaParam;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
@@ -37,8 +39,31 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
     @Value("${guarantee.exp:742}")
     protected String guaranteeExp;
+
     @ApolloJsonValue("${alpha:1.0}")
     protected Double alpha;
+
+    @Value("${correct.cpa.exp.1:}")
+    protected String correctCpaExp1;
+
+    @Value("${correct.cpa.exp.2:}")
+    protected String correctCpaExp2;
+
+    @Value("${correct.cpa.alpha.1:1.0}")
+    protected Double correctCpaAlpha1;
+
+    @Value("${correct.cpa.beta.1:1.0}")
+    protected Double correctCpaBeta1;
+
+    @Value("${correct.cpa.alpha.2:0.7}")
+    protected Double correctCpaAlpha2;
+
+    @Value("${correct.cpa.beta.2:0.2}")
+    protected Double correctCpaBeta2;
+
+    @Value("${correct.cpa.view:1000}")
+    protected Integer correctCpaView;
+
     @Autowired
     private FeatureService featureService;
     @Autowired
@@ -48,6 +73,15 @@ public abstract class RankStrategyBasic implements RankStrategy {
 
     String adPlatformGuaranteeKey = "ad:platform:guarantee:data:{date}:{adverId}";
 
+    String adCustomerLayerHourKey = "ad:platform:customer:hour:{layer}:{clazz}:{customerId}";
+
+    String adVerLayerHourKey = "ad:platform:adver:hour:{layer}:{clazz}:{adverId}";
+
+    String adCustomerLayerDayKey = "ad:platform:customer:day:{layer}:{clazz}:{customerId}";
+
+    String adVerLayerDayKey = "ad:platform:adver:day:{layer}:{clazz}:{adverId}";
+
+
     protected static final List<String> hasChannelScenes = new ArrayList<String>() {{
         add("DaiTou");
         add("GzhTouLiu");
@@ -271,6 +305,119 @@ public abstract class RankStrategyBasic implements RankStrategy {
         }
     }
 
+    protected Map<Long, CorrectCpaParam> getCorrectCpaParamMap(RankRecommendRequestParam request, ScoreParam scoreParam) {
+        Map<String, String> userLayer = this.getUserLayer(request.getMid());
+
+        String layer = userLayer.getOrDefault("layer", "无曝光");
+        String clazz = userLayer.getOrDefault("class", "近期未出现");
+
+        if (request.getIsFilterUser()) {
+            layer = layer + "-炸";
+        }
+
+        String redisAdCustomerLayerHourKey = adCustomerLayerHourKey.replace("{layer}", layer).replace("{clazz}", clazz);
+        String redisAdVerLayerHourKey = adVerLayerHourKey.replace("{layer}", layer).replace("{clazz}", clazz);
+        String redisAadCustomerLayerDayKey = adCustomerLayerDayKey.replace("{layer}", layer).replace("{clazz}", clazz);
+        String redisAdVerLayerDayKey = adVerLayerDayKey.replace("{layer}", layer).replace("{clazz}", clazz);
+
+
+        Map<Long, CorrectCpaParam> resultMap = new HashMap<>();
+        try {
+            List<Long> customerIds = request.getAdIdList().stream().map(AdPlatformCreativeDTO::getCustomerId).distinct().collect(Collectors.toList());
+            List<String> customerLayerHourKeys = customerIds.stream().map(e -> redisAdCustomerLayerHourKey.replace("{customerId}", String.valueOf(e))).collect(Collectors.toList());
+            List<String> customerLayerHourValues = adRedisHelper.mget(customerLayerHourKeys);
+            List<String> customerLayerDayKeys = customerIds.stream().map(e -> redisAadCustomerLayerDayKey.replace("{customerId}", String.valueOf(e))).collect(Collectors.toList());
+            List<String> customerLayerDayValues = adRedisHelper.mget(customerLayerDayKeys);
+
+            Map<Long, JSONObject> customerLayerMap = new HashMap<>();
+            for (int i = 0; i < customerIds.size(); i++) {
+                JSONObject jsonObject = new JSONObject();
+                if (StringUtils.isNotEmpty(customerLayerHourValues.get(i))) {
+                    JSONObject jsonObject1 = JSONObject.parseObject(customerLayerHourValues.get(i));
+                    jsonObject.put("realCtcvrHour", jsonObject1.get("ctcvr"));
+                    jsonObject.put("pCtcvrHour", jsonObject1.get("pCtcvr"));
+                    jsonObject.put("viewsHour", jsonObject1.get("views"));
+                }
+                if (StringUtils.isNotEmpty(customerLayerDayValues.get(i))) {
+                    JSONObject jsonObject1 = JSONObject.parseObject(customerLayerDayValues.get(i));
+                    jsonObject.put("realCtcvrDay", jsonObject1.get("ctcvr"));
+                    jsonObject.put("pCtcvrDay", jsonObject1.get("pCtcvr"));
+                    jsonObject.put("viewsDay", jsonObject1.get("views"));
+                }
+                customerLayerMap.put(customerIds.get(i), jsonObject);
+            }
+            List<String> adVerIds = request.getAdIdList().stream().map(AdPlatformCreativeDTO::getAdVerId).distinct().collect(Collectors.toList());
+            List<String> adVerLayerHourKeys = adVerIds.stream().map(e -> redisAdVerLayerHourKey.replace("{adverId}", e)).collect(Collectors.toList());
+            List<String> adVerLayerHourValues = adRedisHelper.mget(adVerLayerHourKeys);
+            List<String> adVerLayerDayKeys = adVerIds.stream().map(e -> redisAdVerLayerDayKey.replace("{adverId}", e)).collect(Collectors.toList());
+            List<String> adVerLayerDayValues = adRedisHelper.mget(adVerLayerDayKeys);
+            Map<String, JSONObject> adVerLayerMap = new HashMap<>();
+            for (int i = 0; i < adVerIds.size(); i++) {
+                JSONObject jsonObject = new JSONObject();
+                if (StringUtils.isNotEmpty(adVerLayerHourValues.get(i))) {
+                    JSONObject jsonObject1 = JSONObject.parseObject(adVerLayerHourValues.get(i));
+                    jsonObject.put("realCtcvrHour", jsonObject1.get("ctcvr"));
+                    jsonObject.put("pCtcvrHour", jsonObject1.get("pCtcvr"));
+                    jsonObject.put("viewsHour", jsonObject1.get("views"));
+                }
+                if (StringUtils.isNotEmpty(adVerLayerDayValues.get(i))) {
+                    JSONObject jsonObject1 = JSONObject.parseObject(adVerLayerDayValues.get(i));
+                    jsonObject.put("realCtcvrDay", jsonObject1.get("ctcvr"));
+                    jsonObject.put("pCtcvrDay", jsonObject1.get("pCtcvr"));
+                    jsonObject.put("viewsDay", jsonObject1.get("views"));
+                }
+                adVerLayerMap.put(adVerIds.get(i), jsonObject);
+            }
+            for (AdPlatformCreativeDTO adPlatformCreativeDTO : request.getAdIdList()) {
+                Long creativeId = adPlatformCreativeDTO.getCreativeId();
+                Long customerId = adPlatformCreativeDTO.getCustomerId();
+                JSONObject jsonObject;
+                if (customerId != null && customerId != 0 && customerLayerMap.containsKey(customerId)) {
+                    jsonObject = customerLayerMap.get(customerId);
+                } else {
+                    jsonObject = adVerLayerMap.get(adPlatformCreativeDTO.getAdVerId());
+                }
+                CorrectCpaParam correctCpaParam = new CorrectCpaParam();
+                Integer view = jsonObject.getInteger("view");
+                Double realCtcvrHour = jsonObject.getDouble("realCtcvrHour");
+                Double pCtcvrHour = jsonObject.getDouble("pCtcvrHour");
+                Double realCtcvrDay = jsonObject.getDouble("realCtcvrDay");
+                Double pCtcvrDay = jsonObject.getDouble("pCtcvrDay");
+                correctCpaParam.setRealCtcvrHour(realCtcvrHour);
+                correctCpaParam.setPCtcvrHour(pCtcvrHour);
+                correctCpaParam.setRealCtcvrDay(realCtcvrDay);
+                correctCpaParam.setPCtcvrDay(pCtcvrDay);
+                correctCpaParam.setView(view);
+                double correctionFactor = 1;
+                //曝光数小于目标曝光数,不进行修正
+                if (view < correctCpaView) {
+                    correctCpaParam.setCorrectionFactor(correctionFactor);
+                    resultMap.put(creativeId, correctCpaParam);
+                    continue;
+                }
+                if (realCtcvrHour != null && pCtcvrHour != null && realCtcvrDay != null && pCtcvrDay != null) {
+                    if (scoreParam.getExpCodeSet().contains(correctCpaExp2)) {
+                        correctionFactor = (1 - correctCpaAlpha2 - correctCpaBeta2) +
+                                NumUtil.div(realCtcvrHour, pCtcvrHour) * correctCpaAlpha2 +
+                                NumUtil.div(realCtcvrDay, pCtcvrDay) * correctCpaBeta2;
+                    } else {
+                        correctionFactor = Math.pow(NumUtil.div(realCtcvrHour, pCtcvrHour), correctCpaAlpha1) *
+                                Math.pow(NumUtil.div(realCtcvrDay, pCtcvrDay), correctCpaBeta1);
+                    }
+                    if (correctionFactor <= 0) {
+                        correctionFactor = 1;
+                    }
+                }
+                correctCpaParam.setCorrectionFactor(correctionFactor);
+                resultMap.put(creativeId, correctCpaParam);
+            }
+        } catch (Exception e) {
+            log.error("getCorrectCpaParamMap error", e);
+        }
+        return resultMap;
+    }
+
+
     protected AdRankItem creativeCovertRankItem(AdPlatformCreativeDTO dto, RankRecommendRequestParam request, Set<String> noApiAdVerIds) {
         AdRankItem adRankItem = new AdRankItem();
         adRankItem.setAdId(dto.getCreativeId());

+ 19 - 4
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy679.java

@@ -1,5 +1,6 @@
 package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
+import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
@@ -7,10 +8,12 @@ import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
+import com.tzld.piaoquan.ad.engine.service.entity.CorrectCpaParam;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
@@ -93,6 +96,7 @@ public class RankStrategyBy679 extends RankStrategyBasic {
         Map<String, String> sceneFeatureMap = this.handleSceneFeature(ts);
         long time1 = System.currentTimeMillis();
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
+        Map<Long, CorrectCpaParam> correctCpaMap = getCorrectCpaParamMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
         Random random = new Random();
         List<Future<AdRankItem>> futures = new ArrayList<>();
@@ -110,6 +114,7 @@ public class RankStrategyBy679 extends RankStrategyBasic {
                     adRankItem.setCampaignId(dto.getCampaignId());
                     adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
                     adRankItem.setSkuId(dto.getSkuId());
+                    adRankItem.setCustomerId(dto.getCustomerId());
                     adRankItem.setRandom(random.nextInt(1000));
                     if (noApiAdVerIds.contains(dto.getAdVerId())) {
                         adRankItem.getExt().put("isApi", "0");
@@ -117,6 +122,8 @@ public class RankStrategyBy679 extends RankStrategyBasic {
                         adRankItem.getExt().put("isApi", "1");
                     }
                     adRankItem.getExt().put("recallsources", dto.getRecallSources());
+                    adRankItem.getExt().put("correctCpaMap", JSONObject.toJSONString(correctCpaMap.get(dto.getCreativeId())));
+                    adRankItem.getExt().put("correctionFactor", correctCpaMap.get(dto.getCreativeId()).getCorrectionFactor());
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
@@ -217,7 +224,7 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
             double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getAdId(), 1d);
             double guaranteeScoreCoefficient = getGuaranteeScoreCoefficient(scoreParam, item.getExt());
-            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient);
+            double score = item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient;
             item.getScoreMap().put("guaranteeScoreCoefficient", guaranteeScoreCoefficient);
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
@@ -228,10 +235,14 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
-                item.setScore(item.getCpm() * cpmCoefficient / 1000);
+                score = item.getCpm() * cpmCoefficient / 1000;
             }
-
-            putMetaFeature(item, feature, reqFeature, sceneFeatureMap, request);
+            if (scoreParam.getExpCodeSet().contains(correctCpaExp1) || scoreParam.getExpCodeSet().contains(correctCpaExp2)) {
+                Double correctionFactor = (Double) item.getExt().get("correctionFactor");
+                item.getScoreMap().put("correctionFactor", correctionFactor);
+                score = score * correctionFactor;
+            }
+            item.setScore(score);
         }
 
         log.info("cost={}, feature1={}, feature2={}, feature31={}, feature32={}, feature4={}, getScorerPipeline={}, " +
@@ -241,6 +252,10 @@ public class RankStrategyBy679 extends RankStrategyBasic {
 
         result.sort(ComparatorUtil.equalsRandomComparator());
 
+        if (CollectionUtils.isNotEmpty(result)) {
+            AdRankItem top1Item = result.get(0);
+            putMetaFeature(top1Item, feature, reqFeature, sceneFeatureMap, request);
+        }
         return result;
     }
 

+ 13 - 3
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy680.java

@@ -6,6 +6,7 @@ import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
+import com.tzld.piaoquan.ad.engine.service.entity.CorrectCpaParam;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -131,6 +132,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
+        Map<Long, CorrectCpaParam> correctCpaMap = getCorrectCpaParamMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
         Random random = new Random();
         List<Future<AdRankItem>> futures = new ArrayList<>();
@@ -148,6 +150,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
                     adRankItem.setCampaignId(dto.getCampaignId());
                     adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
                     adRankItem.setSkuId(dto.getSkuId());
+                    adRankItem.setCustomerId(dto.getCustomerId());
                     adRankItem.setRandom(random.nextInt(1000));
                     if (noApiAdVerIds.contains(dto.getAdVerId())) {
                         adRankItem.getExt().put("isApi", "0");
@@ -156,6 +159,8 @@ public class RankStrategyBy680 extends RankStrategyBasic {
                     }
 
                     adRankItem.getExt().put("recallsources", dto.getRecallSources());
+                    adRankItem.getExt().put("correctCpaMap", JSONObject.toJSONString(correctCpaMap.get(dto.getCreativeId())));
+                    adRankItem.getExt().put("correctionFactor", correctCpaMap.get(dto.getCreativeId()).getCorrectionFactor());
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
@@ -264,7 +269,7 @@ public class RankStrategyBy680 extends RankStrategyBasic {
 
             double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getAdId(), 1d);
             double guaranteeScoreCoefficient = getGuaranteeScoreCoefficient(scoreParam, item.getExt());
-            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient);
+            double score = item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient;
             item.getScoreMap().put("guaranteeScoreCoefficient", guaranteeScoreCoefficient);
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
@@ -275,11 +280,16 @@ public class RankStrategyBy680 extends RankStrategyBasic {
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
-                item.setScore(item.getCpm() * cpmCoefficient / 1000);
+                score = item.getCpm() * cpmCoefficient / 1000;
             }
+            if (scoreParam.getExpCodeSet().contains(correctCpaExp1) || scoreParam.getExpCodeSet().contains(correctCpaExp2)) {
+                Double correctionFactor = (Double) item.getExt().get("correctionFactor");
+                item.getScoreMap().put("correctionFactor", correctionFactor);
+                score = score * correctionFactor;
+            }
+            item.setScore(score);
         }
 
-
         result.sort(ComparatorUtil.equalsRandomComparator());
 
         if (CollectionUtils.isNotEmpty(result)) {

+ 14 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy683.java

@@ -1,10 +1,12 @@
 package com.tzld.piaoquan.ad.engine.service.score.strategy;
 
+import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
+import com.tzld.piaoquan.ad.engine.service.entity.CorrectCpaParam;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
@@ -103,6 +105,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
+        Map<Long, CorrectCpaParam> correctCpaMap = getCorrectCpaParamMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
         Random random = new Random();
         List<Future<AdRankItem>> futures = new ArrayList<>();
@@ -120,6 +123,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
                     adRankItem.setCampaignId(dto.getCampaignId());
                     adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
                     adRankItem.setSkuId(dto.getSkuId());
+                    adRankItem.setCustomerId(dto.getCustomerId());
                     adRankItem.setRandom(random.nextInt(1000));
                     if (noApiAdVerIds.contains(dto.getAdVerId())) {
                         adRankItem.getExt().put("isApi", "0");
@@ -128,6 +132,8 @@ public class RankStrategyBy683 extends RankStrategyBasic {
                     }
 
                     adRankItem.getExt().put("recallsources", dto.getRecallSources());
+                    adRankItem.getExt().put("correctCpaMap", JSONObject.toJSONString(correctCpaMap.get(dto.getCreativeId())));
+                    adRankItem.getExt().put("correctionFactor", correctCpaMap.get(dto.getCreativeId()).getCorrectionFactor());
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
@@ -236,7 +242,7 @@ public class RankStrategyBy683 extends RankStrategyBasic {
 
             double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getAdId(), 1d);
             double guaranteeScoreCoefficient = getGuaranteeScoreCoefficient(scoreParam, item.getExt());
-            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient);
+            double score = item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient;
             item.getScoreMap().put("guaranteeScoreCoefficient", guaranteeScoreCoefficient);
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
@@ -247,8 +253,14 @@ public class RankStrategyBy683 extends RankStrategyBasic {
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
-                item.setScore(item.getCpm() * cpmCoefficient / 1000);
+                score = item.getCpm() * cpmCoefficient / 1000;
             }
+            if (scoreParam.getExpCodeSet().contains(correctCpaExp1) || scoreParam.getExpCodeSet().contains(correctCpaExp2)) {
+                Double correctionFactor = (Double) item.getExt().get("correctionFactor");
+                item.getScoreMap().put("correctionFactor", correctionFactor);
+                score = score * correctionFactor;
+            }
+            item.setScore(score);
         }
 
 

+ 13 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy688.java

@@ -9,6 +9,7 @@ import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
 import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
 import com.tzld.piaoquan.ad.engine.commons.thread.ThreadPoolFactory;
 import com.tzld.piaoquan.ad.engine.commons.util.*;
+import com.tzld.piaoquan.ad.engine.service.entity.CorrectCpaParam;
 import com.tzld.piaoquan.ad.engine.service.entity.GuaranteeView;
 import com.tzld.piaoquan.ad.engine.service.feature.Feature;
 import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
@@ -168,6 +169,7 @@ public class RankStrategyBy688 extends RankStrategyBasic {
         long time1 = System.currentTimeMillis();
 
         Map<String, GuaranteeView> map = getGuaranteeViewMap(request, scoreParam);
+        Map<Long, CorrectCpaParam> correctCpaMap = getCorrectCpaParamMap(request, scoreParam);
         List<AdRankItem> adRankItems = new ArrayList<>();
         Random random = new Random();
         List<Future<AdRankItem>> futures = new ArrayList<>();
@@ -185,6 +187,7 @@ public class RankStrategyBy688 extends RankStrategyBasic {
                     adRankItem.setCampaignId(dto.getCampaignId());
                     adRankItem.setCpm(ObjUtil.nullOrDefault(dto.getCpm(), 90).doubleValue());
                     adRankItem.setSkuId(dto.getSkuId());
+                    adRankItem.setCustomerId(dto.getCustomerId());
                     adRankItem.setRandom(random.nextInt(1000));
                     if (noApiAdVerIds.contains(dto.getAdVerId())) {
                         adRankItem.getExt().put("isApi", "0");
@@ -192,6 +195,8 @@ public class RankStrategyBy688 extends RankStrategyBasic {
                         adRankItem.getExt().put("isApi", "1");
                     }
                     adRankItem.getExt().put("recallsources", dto.getRecallSources());
+                    adRankItem.getExt().put("correctCpaMap", JSONObject.toJSONString(correctCpaMap.get(dto.getCreativeId())));
+                    adRankItem.getExt().put("correctionFactor", correctCpaMap.get(dto.getCreativeId()).getCorrectionFactor());
                     setGuaranteeWeight(map, dto.getAdVerId(), adRankItem.getExt());
                     String cidStr = dto.getCreativeId().toString();
                     Map<String, String> cidFeatureMap = adRankItem.getFeatureMap();
@@ -320,7 +325,7 @@ public class RankStrategyBy688 extends RankStrategyBasic {
 
             double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getAdId(), 1d);
             double guaranteeScoreCoefficient = getGuaranteeScoreCoefficient(scoreParam, item.getExt());
-            item.setScore(item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient);
+            double score = item.getLrScore() * scoreCoefficient * item.getCpa() * guaranteeScoreCoefficient;
             item.getScoreMap().put("guaranteeScoreCoefficient", guaranteeScoreCoefficient);
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());
@@ -331,8 +336,14 @@ public class RankStrategyBy688 extends RankStrategyBasic {
 
             // 没有转化回传的广告主,使用后台配置的CPM
             if (noApiAdVerIds.contains(item.getAdVerId())) {
-                item.setScore(item.getCpm() * cpmCoefficient / 1000);
+                score = item.getCpm() * cpmCoefficient / 1000;
             }
+            if (scoreParam.getExpCodeSet().contains(correctCpaExp1) || scoreParam.getExpCodeSet().contains(correctCpaExp2)) {
+                Double correctionFactor = (Double) item.getExt().get("correctionFactor");
+                item.getScoreMap().put("correctionFactor", correctionFactor);
+                score = score * correctionFactor;
+            }
+            item.setScore(score);
         }