| 
					
				 | 
			
			
				@@ -8,16 +8,16 @@ import com.tzld.longarticle.recommend.server.service.rank.RankItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.rank.RankParam; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.rank.RankResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.rank.RankStrategy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.longarticle.recommend.server.service.score.AccountIndexReplacePoolConfig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.score.ScoreParam; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.score.ScoreResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.score.ScoreService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.service.score.strategy.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import com.tzld.longarticle.recommend.server.util.JSONUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.longarticle.recommend.server.util.TitleSimilarCheckUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import lombok.extern.slf4j.Slf4j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.apache.commons.collections4.CollectionUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.apache.commons.lang3.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang3.RandomUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.stereotype.Service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -39,30 +39,30 @@ public class RankV3Strategy implements RankStrategy { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //log.info("RankParam {}", JSONUtils.toJson(param)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ScoreResult scoreResult = scoreService.score(convertToScoreParam(param)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //log.info("ScoreResult {}", JSONUtils.toJson(scoreResult)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Map<String, Map<String, Double>> scoreMap = scoreResult.getScoreMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<Integer, AccountIndexReplacePoolConfig> indexReplacePoolConfigMap = accountContentPoolConfigService.getContentReplacePools(param.getAccountName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             RankItem item = new RankItem(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             item.setContent(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             c.setScoreMap(scoreMap.get(c.getId())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             item.setScoreMap(scoreMap.get(c.getId())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             double score; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (contentPools[0].equals(item.getContent().getContentPoolType())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (contentPools[0].equals(item.getContent().getContentPoolType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    || contentPools[1].equals(item.getContent().getContentPoolType())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 score = item.getScore(SimilarityStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        + item.getScore(CategoryStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        + item.getScore(ViewCountRateStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        + item.getScore(FlowCtlDecreaseStrategy.class.getSimpleName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (contentPools[1].equals(item.getContent().getContentPoolType())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                score = item.getScore(ViewCountStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         + item.getScore(CategoryStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         + item.getScore(FlowCtlDecreaseStrategy.class.getSimpleName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (item.getScore(PublishTimesStrategy.class.getSimpleName()) >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    score += item.getScore(ViewCountRateStrategy.class.getSimpleName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 score = item.getScore(SimilarityStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         + item.getScore(CategoryStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         + item.getScore(AccountPreDistributeStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        + item.getScore(PublishTimesStrategy.class.getSimpleName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         + item.getScore(FlowCtlDecreaseStrategy.class.getSimpleName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             c.setScore(score); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -72,11 +72,9 @@ public class RankV3Strategy implements RankStrategy { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 1 排序 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        log.info("SortResult {}", JSONUtils.toJson(items)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 2 相似去重 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<Content> contents = CommonCollectionUtils.toList(items, RankItem::getContent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //        contents = deduplication(contents); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        log.info("Deduplication {}", JSONUtils.toJson(contents)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 3 文章按照内容池分组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Map<String, List<Content>> contentMap = new HashMap<>(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -84,66 +82,37 @@ public class RankV3Strategy implements RankStrategy { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             data.add(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        log.info("ContentMap {}", JSONUtils.toJson(contentMap)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 4 选文章 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<Content> result = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         String[] publishPool = Arrays.copyOf(contentPools, contentPools.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 头、次 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (StringUtils.equals(contentPools[0], contentPools[1])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            List<Content> pool = contentMap.get(contentPools[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Integer level = accountContentPoolConfigService.getLevelByContentPool(contentPools[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (level == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (CollectionUtils.isNotEmpty(pool)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    result.add(pool.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (pool.size() > 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        result.add(pool.get(2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // level2 兜底 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    pool = contentMap.get(accountContentPoolConfigService.getContentPoolByLevel(2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (CollectionUtils.isNotEmpty(pool)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        result.add(pool.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (pool.size() > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            result.add(pool.get(1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (level == 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (CollectionUtils.isNotEmpty(pool)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    result.add(pool.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (pool.size() > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        result.add(pool.get(1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    pool = contentMap.get(ContentPoolEnum.autoArticlePoolLevel1.getContentPool()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (CollectionUtils.isNotEmpty(pool)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        result.add(pool.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Content> pool1 = contentMap.get(contentPools[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (CollectionUtils.isNotEmpty(pool1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result.add(pool1.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 配置错误 兜底 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            List<Content> pool1 = contentMap.get(contentPools[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            List<Content> pool2 = contentMap.get(contentPools[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (CollectionUtils.isNotEmpty(pool1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                result.add(pool1.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (CollectionUtils.isNotEmpty(pool2)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    result.add(pool2.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (CollectionUtils.isNotEmpty(pool2)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                result.add(pool2.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                publishPool[0] = contentPools[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (pool2.size() > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    result.add(pool2.get(1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return new RankResult(result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 次 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Content> pool2 = contentMap.get(contentPools[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (CollectionUtils.isNotEmpty(pool2)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int i = RandomUtils.nextInt(0, Math.min(pool2.size(), 5)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result.add(pool2.get(i)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 替补 根据设置替补内容池查找内容尽心替补 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (Objects.nonNull(replacePoolConfig)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                List<Content> pool2Replace = contentMap.get(replacePoolConfig.getContentPool()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (CollectionUtils.isNotEmpty(pool2Replace)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    publishPool[1] = replacePoolConfig.getContentPool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    result.add(pool2Replace.get(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 3-8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<Content> pool = contentMap.get(contentPools[2]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (CollectionUtils.isNotEmpty(pool)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (CollectionUtils.isNotEmpty(pool) && param.getSize() > result.size()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size()))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -158,6 +127,7 @@ public class RankV3Strategy implements RankStrategy { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         scoreParam.setAccountName(param.getAccountName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         scoreParam.setContents(param.getContents()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         scoreParam.setStrategy(param.getStrategy()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        scoreParam.setScene(param.getScene()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return scoreParam; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |