Bladeren bron

Merge branch 'wyp/0827'

wangyunpeng 10 maanden geleden
bovenliggende
commit
5408bef93b
34 gewijzigde bestanden met toevoegingen van 1223 en 56 verwijderingen
  1. 0 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/Application.java
  2. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/ThreadPoolFactory.java
  3. 4 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/enums/RankStrategyEnum.java
  4. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/config/db/AdplatformDBConfig.java
  5. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/config/db/AigcDBConfig.java
  6. 5 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/ArticleSortResponseDataItem.java
  7. 9 10
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/Content.java
  8. 15 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/ContentHisPublishArticle.java
  9. 4 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/AccountAvgInfoRepository.java
  10. 14 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/ArticleDetailInfoRepository.java
  11. 4 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/ArticleRepository.java
  12. 3 3
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/entity/crawler/AccountAvgInfo.java
  13. 63 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/entity/crawler/ArticleDetailInfo.java
  14. 3 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/adplatform/AdplatformBaseMapper.java
  15. 3 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/aigc/AigcBaseMapper.java
  16. 49 15
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/filter/strategy/HistoryTitleStrategy.java
  17. 93 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/filter/strategy/LowScoreStrategy.java
  18. 168 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV10Strategy.java
  19. 0 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV5Strategy.java
  20. 168 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV7Strategy.java
  21. 168 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV8Strategy.java
  22. 168 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV9Strategy.java
  23. 107 8
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recall/RecallService.java
  24. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/Score.java
  25. 9 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/ScoreService.java
  26. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/AccountPreDistributeStrategy.java
  27. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/CategoryStrategy.java
  28. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/FlowCtlDecreaseStrategy.java
  29. 38 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionAvgReadRateRateStrategy.java
  30. 38 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionAvgReadSumRateStrategy.java
  31. 38 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionFansRateRateStrategy.java
  32. 38 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionFansSumRateStrategy.java
  33. 1 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/PublishTimesStrategy.java
  34. 6 5
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/ViewCountRateStrategy.java

+ 0 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/Application.java

@@ -2,7 +2,6 @@ package com.tzld.longarticle.recommend.server;
 
 
 import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
-import org.mybatis.spring.annotation.MapperScan;
 import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -26,7 +25,6 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
         "com.tzld.longarticle.recommend.server.util",
         "com.tzld.longarticle.recommend.server.repository",
 })
-@MapperScan("com.tzld.longarticle.recommend.server.repository.mapper")
 @EnableAspectJAutoProxy
 @EnableApolloConfig
 public class Application {

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/ThreadPoolFactory.java

@@ -15,7 +15,7 @@ public final class ThreadPoolFactory {
             32,
             128,
             0L, TimeUnit.SECONDS,
-            new LinkedBlockingQueue<>(1000),
+            new LinkedBlockingQueue<>(10000),
             new ThreadFactoryBuilder().setNameFormat("DEFAULT-%d").build(),
             new ThreadPoolExecutor.AbortPolicy());
     public final static ExecutorService RECALL = new CommonThreadPoolExecutor(

+ 4 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/enums/RankStrategyEnum.java

@@ -11,6 +11,10 @@ public enum RankStrategyEnum {
     ArticleRankV4("ArticleRankV4", "ArticleRankV4", "rankV4Strategy"),
     ArticleRankV5("ArticleRankV5", "ArticleRankV5", "rankV5Strategy"),
     ArticleRankV6("ArticleRankV6", "ArticleRankV6", "rankV6Strategy"),
+    ArticleRankV7("ArticleRankV7", "ArticleRankV7", "rankV7Strategy"),
+    ArticleRankV8("ArticleRankV8", "ArticleRankV8", "rankV8Strategy"),
+    ArticleRankV9("ArticleRankV9", "ArticleRankV9", "rankV9Strategy"),
+    ArticleRankV10("ArticleRankV10", "ArticleRankV10", "rankV10Strategy"),
 
     default_strategy("ArticleRankV1", "默认策略", "defaultRankStrategy"),
     ;

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/config/db/AdplatformDBConfig.java

@@ -47,7 +47,7 @@ public class AdplatformDBConfig {
 
     @Bean(name = "adplatformEntityManagerFactory")
     public LocalContainerEntityManagerFactoryBean adplatformEntityManagerFactory(EntityManagerFactoryBuilder builder,
-                                                                                @Qualifier("adplatformDataSource") DataSource dataSource) {
+                                                                                 @Qualifier("adplatformDataSource") DataSource dataSource) {
         return builder
                 .dataSource(dataSource)
                 .packages("com.tzld.longarticle.recommend.server.repository.entity.adplatform") // 实体类包路径

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/config/db/AigcDBConfig.java

@@ -47,7 +47,7 @@ public class AigcDBConfig {
 
     @Bean(name = "aigcEntityManagerFactory")
     public LocalContainerEntityManagerFactoryBean aigcEntityManagerFactory(EntityManagerFactoryBuilder builder,
-                                                                                @Qualifier("aigcDataSource") DataSource dataSource) {
+                                                                           @Qualifier("aigcDataSource") DataSource dataSource) {
         return builder
                 .dataSource(dataSource)
                 .packages("com.tzld.longarticle.recommend.server.repository.entity.aigc") // 实体类包路径

+ 5 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/ArticleSortResponseDataItem.java

@@ -4,6 +4,8 @@ import lombok.Getter;
 import lombok.Setter;
 import lombok.experimental.Accessors;
 
+import java.util.Map;
+
 @Getter
 @Setter
 @Accessors(chain = true)
@@ -12,4 +14,7 @@ public class ArticleSortResponseDataItem {
     private String title;
     private String producePlanName;
     private String filterReason;
+
+    private Map<String, Double> scoreMap;
+    private double score;
 }

+ 9 - 10
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/Content.java

@@ -6,6 +6,7 @@ import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author dyp
@@ -18,16 +19,7 @@ import java.util.List;
 public class Content {
     private String id;
     private String title;
-    // private String content;
-//    private String coverUrl;
-//    private List<String> imageUrls;
     private String producePlanName;
-    /**
-     * "Level4": "autoArticlePoolLevel4",
-     * "Level3": "autoArticlePoolLevel3",
-     * "Level2": "autoArticlePoolLevel2",
-     * "Level1": "autoArticlePoolLevel1"
-     */
     private String contentPoolType; // 内容池类别
     private String crawlerChannelContentId; // 抓取内容channelContentId
     private List<String> category; // 品类
@@ -35,11 +27,18 @@ public class Content {
     private String crawlerTitle;
     private String crawlerCoverUrl;
     private Integer crawlerViewCount;
-    //    private Integer crawlerLikeCount;
+//    private Integer crawlerLikeCount;
 //    private Long crawlerPublishTimestamp;
 //    private String crawlerAccountName;
     private String filterReason;
 
     private List<ContentHisPublishArticle> hisPublishArticleList;
+    private Double t0FissionByFansMean;
+    private Double t0FissionByReadAvgMean;
+    private Double t0FissionByFansSumAvg;
+    private Double t0FissionByReadAvgSumAvg;
+
+    private Map<String, Double> scoreMap;
+    private double score;
 }
 

+ 15 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/ContentHisPublishArticle.java

@@ -1,19 +1,32 @@
 package com.tzld.longarticle.recommend.server.model;
 
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.ArticleDetailInfo;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.List;
+
 @Getter
 @Setter
 public class ContentHisPublishArticle {
 
     private String ghId;
     private String accountName;
+    private String msgId;
     private String title;
     private Integer itemIndex;
-    private Integer showViewCount;
+    private Integer viewCount;
     private Long updateTime;
     private Integer avgViewCount;
     private Double viewCountRate;
-    private boolean isInnerAccount;
+    private Integer firstViewCount;
+    private Double firstViewCountRate;
+    private boolean isInnerAccount = false;
+    private long fans;
+    private List<ArticleDetailInfo> articleDetailInfoList;
+
+    // data
+    private Integer t0FissionSum;
+    private Double t0FissionByFans;
+    private Double t0FissionByReadAvg;
 }

+ 4 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/AccountAvgInfoRepository.java

@@ -4,7 +4,11 @@ import com.tzld.longarticle.recommend.server.repository.entity.crawler.AccountAv
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+import java.util.Set;
+
 @Repository
 public interface AccountAvgInfoRepository extends JpaRepository<AccountAvgInfo, AccountAvgInfo.PK> {
 
+    List<AccountAvgInfo> getAllByGhIdIn(Set<String> ghIds);
 }

+ 14 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/ArticleDetailInfoRepository.java

@@ -0,0 +1,14 @@
+package com.tzld.longarticle.recommend.server.repository.crawler;
+
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.ArticleDetailInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Set;
+
+@Repository
+public interface ArticleDetailInfoRepository extends JpaRepository<ArticleDetailInfo, ArticleDetailInfo.PK> {
+
+    List<ArticleDetailInfo> getAllByWxSnIn(Set<String> wxSnList);
+}

+ 4 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/ArticleRepository.java

@@ -5,12 +5,15 @@ import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
+import java.util.Set;
 
 @Repository
 public interface ArticleRepository extends JpaRepository<Article, String> {
 
     List<Article> getByAccountNameAndItemIndexInAndTypeEquals(String accountName, List<Integer> indexList, String type);
 
-    List<Article> getByTitleIn(List<String> titleList);
+    List<Article> getByTitleIn(Set<String> titleList);
+
+    List<Article> getByGhIdInAndAppMsgIdInAndItemIndex(Set<String> ghIds, Set<String> appMsgIds, Integer itemIndex);
 
 }

+ 3 - 3
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/entity/crawler/AccountAvgInfo.java

@@ -11,7 +11,7 @@ import java.io.Serializable;
 @AllArgsConstructor
 @NoArgsConstructor
 @Entity
-@Table(name = "account_avg_info")
+@Table(name = "account_avg_info_v2")
 @IdClass(AccountAvgInfo.PK.class)
 public class AccountAvgInfo implements Serializable {
 
@@ -26,9 +26,9 @@ public class AccountAvgInfo implements Serializable {
     @Column(name = "fans")
     private long fans;
     @Column(name = "read_avg")
-    private double readAvg;
+    private Double readAvg;
     @Column(name = "like_avg")
-    private double likeAvg;
+    private Double likeAvg;
 
     @Data
     public static class PK implements Serializable {

+ 63 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/entity/crawler/ArticleDetailInfo.java

@@ -0,0 +1,63 @@
+package com.tzld.longarticle.recommend.server.repository.entity.crawler;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "long_articles_detail_info")
+@IdClass(ArticleDetailInfo.PK.class)
+public class ArticleDetailInfo implements Serializable {
+
+    @Id
+    @Column(name = "wx_sn")
+    private String wxSn;
+    @Id
+    @Column(name = "recall_dt")
+    private Date recallDt;
+    @Id
+    @Column(name = "video_id")
+    private Long videoId;
+    @Column(name = "mini_title")
+    private String miniTitle;
+    @Column(name = "mini_name")
+    private String miniName;
+    @Column(name = "cover_url")
+    private String coverUrl;
+    @Column(name = "video_index")
+    private Integer videoIndex;
+    @Column(name = "root_source_id")
+    private String rootSourceId;
+    @Column(name = "publish_dt")
+    private Date publishDt;
+    @Column(name = "first_level")
+    private Integer firstLevel;
+    @Column(name = "fission_0")
+    private Integer fission0;
+    @Column(name = "fission_1")
+    private Integer fission1;
+    @Column(name = "fission_2")
+    private Integer fission2;
+
+    @Data
+    public static class PK implements Serializable {
+
+        @Column(name = "wx_sn")
+        private String wxSn;
+        @Column(name = "recall_dt")
+        private Date recallDt;
+        @Column(name = "video_id")
+        private Long videoId;
+
+        public PK() {
+        }
+
+    }
+}

+ 3 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/adplatform/AdplatformBaseMapper.java

@@ -1,5 +1,8 @@
 package com.tzld.longarticle.recommend.server.repository.mapper.adplatform;
 
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
 public interface AdplatformBaseMapper {
 
 }

+ 3 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/aigc/AigcBaseMapper.java

@@ -1,5 +1,8 @@
 package com.tzld.longarticle.recommend.server.repository.mapper.aigc;
 
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
 public interface AigcBaseMapper {
 
 }

+ 49 - 15
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/filter/strategy/HistoryTitleStrategy.java

@@ -1,8 +1,9 @@
 package com.tzld.longarticle.recommend.server.service.filter.strategy;
 
+import com.tzld.longarticle.recommend.server.common.ThreadPoolFactory;
 import com.tzld.longarticle.recommend.server.model.Content;
-import com.tzld.longarticle.recommend.server.repository.entity.crawler.Article;
 import com.tzld.longarticle.recommend.server.remote.ArticleListRemoteService;
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.Article;
 import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
 import com.tzld.longarticle.recommend.server.service.filter.FilterParam;
 import com.tzld.longarticle.recommend.server.service.filter.FilterResult;
@@ -12,11 +13,16 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -34,6 +40,7 @@ public class HistoryTitleStrategy implements FilterStrategy {
     private static final List<Integer> firstSecondIndex = Arrays.asList(1, 2);
     private static final List<Integer> allIndex = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
 
+    private final ExecutorService pool = ThreadPoolFactory.defaultPool();
 
     @Override
     public FilterResult filter(FilterParam param) {
@@ -41,29 +48,56 @@ public class HistoryTitleStrategy implements FilterStrategy {
         FilterResult filterResult = new FilterResult();
         List<String> result = new ArrayList<>();
         List<Content> filterContents = new ArrayList<>();
-        List<Article> firstSecondArticleList = articleListRemoteService.articleList(param.getAccountName(), firstSecondIndex);
-        List<String> firstSecondTitleList = firstSecondArticleList.stream().map(Article::getTitle).distinct().collect(Collectors.toList());
         List<Article> allArticleList = articleListRemoteService.articleList(param.getAccountName(), allIndex);
         List<String> allTitleList = allArticleList.stream().map(Article::getTitle).distinct().collect(Collectors.toList());
+        List<Article> firstSecondArticleList = allArticleList.stream().filter(article -> firstSecondIndex.contains(article.getItemIndex())).collect(Collectors.toList());
+        List<String> firstSecondTitleList = firstSecondArticleList.stream().map(Article::getTitle).distinct().collect(Collectors.toList());
 
         List<String> firstSecondContentPool = new ArrayList<>();
         String[] contentPoolConfig = accountContentPoolConfigService.getContentPools(param.getAccountName());
         if (Objects.nonNull(contentPoolConfig)) {
             firstSecondContentPool = Arrays.asList(contentPoolConfig[0], contentPoolConfig[1]);
         }
+        List<Future<Content>> futures = new ArrayList<>();
+        CountDownLatch cdl = new CountDownLatch(param.getContents().size());
         for (Content content : param.getContents()) {
-            boolean isDuplicate;
-            if (CollectionUtils.isNotEmpty(firstSecondContentPool) && firstSecondContentPool.contains(content.getContentPoolType())) {
-                // 四个内容池 配置 判断头条,次头条
-                isDuplicate = TitleSimilarCheckUtil.isDuplicateContent(content.getTitle(), firstSecondTitleList);
-            } else {
-                isDuplicate = TitleSimilarCheckUtil.isDuplicateContent(content.getTitle(), allTitleList);
-            }
-            if (!isDuplicate) {
-                result.add(content.getId());
-            } else {
-                content.setFilterReason("历史已发布文章");
-                filterContents.add(content);
+            List<String> finalFirstSecondContentPool = firstSecondContentPool;
+            Future<Content> future = pool.submit(() -> {
+                try {
+                    boolean isDuplicate;
+                    if (CollectionUtils.isNotEmpty(finalFirstSecondContentPool) && finalFirstSecondContentPool.contains(content.getContentPoolType())) {
+                        // 四个内容池 配置 判断头条,次头条
+                        isDuplicate = TitleSimilarCheckUtil.isDuplicateContent(content.getTitle(), firstSecondTitleList);
+                    } else {
+                        isDuplicate = TitleSimilarCheckUtil.isDuplicateContent(content.getTitle(), allTitleList);
+                    }
+                    if (isDuplicate) {
+                        content.setFilterReason("历史已发布文章");
+                    }
+                    return content;
+                } finally {
+                    cdl.countDown();
+                }
+            });
+            futures.add(future);
+        }
+        try {
+            cdl.await(5000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            log.error("filter error", e);
+            return null;
+        }
+
+        for (Future<Content> f : futures) {
+            try {
+                Content content = f.get();
+                if (StringUtils.hasText(content.getFilterReason())) {
+                    filterContents.add(content);
+                } else {
+                    result.add(content.getId());
+                }
+            } catch (Exception e) {
+                log.error("future get error ", e);
             }
         }
         filterResult.setContentIds(result);

+ 93 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/filter/strategy/LowScoreStrategy.java

@@ -0,0 +1,93 @@
+package com.tzld.longarticle.recommend.server.service.filter.strategy;
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.model.ContentHisPublishArticle;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
+import com.tzld.longarticle.recommend.server.service.filter.FilterParam;
+import com.tzld.longarticle.recommend.server.service.filter.FilterResult;
+import com.tzld.longarticle.recommend.server.service.filter.FilterStrategy;
+import com.tzld.longarticle.recommend.server.service.score.Score;
+import com.tzld.longarticle.recommend.server.util.MathUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class LowScoreStrategy implements FilterStrategy {
+
+    @Autowired
+    AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+    @Autowired
+    AccountContentPoolConfigService accountContentPoolConfigService;
+
+    @Override
+    public FilterResult filter(FilterParam param) {
+        long start = System.currentTimeMillis();
+        FilterResult filterResult = new FilterResult();
+        if (param.getContents().size() <= 1000) {
+            filterResult.setContentIds(param.getContents().stream().map(Content::getId).collect(Collectors.toList()));
+            return filterResult;
+        }
+        filterResult.setContentIds(new ArrayList<>());
+        List<Score> scores = new ArrayList<>();
+        Map<String, Content> contentMap = param.getContents().stream().collect(Collectors.toMap(Content::getId, c -> c));
+        for (Content content : param.getContents()) {
+            String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
+            if (!contentPools[2].equals(content.getContentPoolType())) {
+                filterResult.getContentIds().add(content.getId());
+                continue;
+            }
+            if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+                filterResult.getContentIds().add(content.getId());
+                continue;
+            }
+            double avgViewCountPos = accountIndexAvgViewCountService.getAvgReadCount(param.getGhId(), 3);
+            double showViewCountSum = 0D;
+            double avgViewCountSum = 0D;
+            for (ContentHisPublishArticle hisItem : content.getHisPublishArticleList()) {
+                if (hisItem.isInnerAccount() && Objects.nonNull(hisItem.getViewCount())
+                        && hisItem.getViewCount() > 0 && Objects.nonNull(hisItem.getAvgViewCount())
+                        && hisItem.getAvgViewCount() > 0) {
+                    if (!(hisItem.getItemIndex() == 1) && !(hisItem.getItemIndex() == 2)) {
+                        showViewCountSum += hisItem.getViewCount();
+                        avgViewCountSum += hisItem.getAvgViewCount();
+                    }
+                }
+            }
+            double viewCountRate = 0D; // 设置默认值
+            double minRate = 5D;
+            if (avgViewCountSum > 0) {
+                viewCountRate = showViewCountSum / avgViewCountSum;
+            }
+            double viewCountRateW = MathUtils.sigmoid(avgViewCountSum, 0.0005, avgViewCountPos);
+            double viewCountRateScore = 0;
+            if (viewCountRate > 0) {
+                viewCountRateScore = (Math.min(viewCountRate, minRate) - 1D) * viewCountRateW;
+            }
+            Score score = new Score();
+            score.setContentId(content.getId());
+            score.setScore(viewCountRateScore);
+            scores.add(score);
+        }
+        scores.sort((o1, o2) -> -(o1.getScore().compareTo(o2.getScore())));
+        filterResult.getContentIds().addAll(scores.subList(0, Math.min(100, scores.size())).stream()
+                .map(Score::getContentId).collect(Collectors.toList()));
+        if (scores.size() > 100) {
+            List<Content> filterContent = scores.subList(100, scores.size() - 1).stream()
+                    .map(o -> contentMap.get(o.getContentId())).collect(Collectors.toList());
+            filterContent.forEach(o -> o.setFilterReason("低评分内容"));
+            filterResult.setFilterContent(filterContent);
+        }
+        log.info("LowScoreStrategy cost:{}", System.currentTimeMillis() - start);
+        return filterResult;
+    }
+}

+ 168 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV10Strategy.java

@@ -0,0 +1,168 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.common.enums.ContentPoolEnum;
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+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.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class RankV10Strategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+    @Autowired
+    private AccountContentPoolConfigService accountContentPoolConfigService;
+
+    public RankResult rank(RankParam param) {
+
+        //log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+
+        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()));
+            double score;
+            if (contentPools[0].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(HisFissionAvgReadSumRateStrategy.class.getSimpleName());
+            } else if (contentPools[1].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(SimilarityStrategy.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);
+            item.setScore(score);
+            return item;
+        });
+
+        // 1 排序
+        Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore()));
+        // 2 相似去重
+        List<Content> contents = CommonCollectionUtils.toList(items, RankItem::getContent);
+        contents = deduplication(contents);
+
+        // 3 文章按照内容池分组
+        Map<String, List<Content>> contentMap = new HashMap<>();
+        for (Content c : contents) {
+            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        // 4 选文章
+        List<Content> result = new ArrayList<>();
+
+        // 头
+        List<Content> pool1 = contentMap.get(contentPools[0]);
+        if (CollectionUtils.isNotEmpty(pool1)) {
+            result.add(pool1.get(0));
+        } else {
+            // 替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(1);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool1Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool1Replace)) {
+                    result.add(pool1Replace.get(0));
+                }
+            }
+        }
+        // 次
+        List<Content> pool2 = contentMap.get(contentPools[1]);
+        if (CollectionUtils.isNotEmpty(pool2)) {
+            int i = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            int j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            result.add(pool2.get(i));
+            // 替补 头条内容不足使用次条内容
+            if (result.size() == 1 && pool2.size() > 1) {
+                while (i == j && pool2.size() > 1) {
+                    j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+                    if (i != j) {
+                        result.add(pool2.get(1));
+                        break;
+                    }
+                }
+            }
+        } else {
+            // 替补 根据设置替补内容池查找内容尽心替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(2);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool2Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool2Replace)) {
+                    result.add(pool2Replace.get(0));
+                }
+            }
+        }
+
+        // 3-8
+        List<Content> pool = contentMap.get(contentPools[2]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setGhId(param.getGhId());
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        scoreParam.setStrategy(param.getStrategy());
+        scoreParam.setScene(param.getScene());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (String contentPool : ContentPoolEnum.getOrderContentPool()) {
+            for (Content c : contents) {
+                if (!contentPool.equals(c.getContentPoolType())) {
+                    continue;
+                }
+                if (!TitleSimilarCheckUtil.isDuplicateContent(c.getTitle(), titles)) {
+                    result.add(c);
+                    titles.add(c.getTitle());
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

+ 0 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV5Strategy.java

@@ -14,7 +14,6 @@ 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;
@@ -47,7 +46,6 @@ public class RankV5Strategy implements RankStrategy {
 
         List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> {
             RankItem item = new RankItem();
-            c.setHisPublishArticleList(null);
             item.setContent(c);
             item.setScoreMap(scoreMap.get(c.getId()));
             double score;

+ 168 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV7Strategy.java

@@ -0,0 +1,168 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.common.enums.ContentPoolEnum;
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+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.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class RankV7Strategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+    @Autowired
+    private AccountContentPoolConfigService accountContentPoolConfigService;
+
+    public RankResult rank(RankParam param) {
+
+        //log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+
+        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()));
+            double score;
+            if (contentPools[0].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(HisFissionFansRateRateStrategy.class.getSimpleName());
+            } else if (contentPools[1].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(SimilarityStrategy.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);
+            item.setScore(score);
+            return item;
+        });
+
+        // 1 排序
+        Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore()));
+        // 2 相似去重
+        List<Content> contents = CommonCollectionUtils.toList(items, RankItem::getContent);
+        contents = deduplication(contents);
+
+        // 3 文章按照内容池分组
+        Map<String, List<Content>> contentMap = new HashMap<>();
+        for (Content c : contents) {
+            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        // 4 选文章
+        List<Content> result = new ArrayList<>();
+
+        // 头
+        List<Content> pool1 = contentMap.get(contentPools[0]);
+        if (CollectionUtils.isNotEmpty(pool1)) {
+            result.add(pool1.get(0));
+        } else {
+            // 替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(1);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool1Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool1Replace)) {
+                    result.add(pool1Replace.get(0));
+                }
+            }
+        }
+        // 次
+        List<Content> pool2 = contentMap.get(contentPools[1]);
+        if (CollectionUtils.isNotEmpty(pool2)) {
+            int i = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            int j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            result.add(pool2.get(i));
+            // 替补 头条内容不足使用次条内容
+            if (result.size() == 1 && pool2.size() > 1) {
+                while (i == j && pool2.size() > 1) {
+                    j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+                    if (i != j) {
+                        result.add(pool2.get(1));
+                        break;
+                    }
+                }
+            }
+        } else {
+            // 替补 根据设置替补内容池查找内容尽心替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(2);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool2Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool2Replace)) {
+                    result.add(pool2Replace.get(0));
+                }
+            }
+        }
+
+        // 3-8
+        List<Content> pool = contentMap.get(contentPools[2]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setGhId(param.getGhId());
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        scoreParam.setStrategy(param.getStrategy());
+        scoreParam.setScene(param.getScene());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (String contentPool : ContentPoolEnum.getOrderContentPool()) {
+            for (Content c : contents) {
+                if (!contentPool.equals(c.getContentPoolType())) {
+                    continue;
+                }
+                if (!TitleSimilarCheckUtil.isDuplicateContent(c.getTitle(), titles)) {
+                    result.add(c);
+                    titles.add(c.getTitle());
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

+ 168 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV8Strategy.java

@@ -0,0 +1,168 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.common.enums.ContentPoolEnum;
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+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.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class RankV8Strategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+    @Autowired
+    private AccountContentPoolConfigService accountContentPoolConfigService;
+
+    public RankResult rank(RankParam param) {
+
+        //log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+
+        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()));
+            double score;
+            if (contentPools[0].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(HisFissionFansSumRateStrategy.class.getSimpleName());
+            } else if (contentPools[1].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(SimilarityStrategy.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);
+            item.setScore(score);
+            return item;
+        });
+
+        // 1 排序
+        Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore()));
+        // 2 相似去重
+        List<Content> contents = CommonCollectionUtils.toList(items, RankItem::getContent);
+        contents = deduplication(contents);
+
+        // 3 文章按照内容池分组
+        Map<String, List<Content>> contentMap = new HashMap<>();
+        for (Content c : contents) {
+            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        // 4 选文章
+        List<Content> result = new ArrayList<>();
+
+        // 头
+        List<Content> pool1 = contentMap.get(contentPools[0]);
+        if (CollectionUtils.isNotEmpty(pool1)) {
+            result.add(pool1.get(0));
+        } else {
+            // 替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(1);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool1Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool1Replace)) {
+                    result.add(pool1Replace.get(0));
+                }
+            }
+        }
+        // 次
+        List<Content> pool2 = contentMap.get(contentPools[1]);
+        if (CollectionUtils.isNotEmpty(pool2)) {
+            int i = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            int j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            result.add(pool2.get(i));
+            // 替补 头条内容不足使用次条内容
+            if (result.size() == 1 && pool2.size() > 1) {
+                while (i == j && pool2.size() > 1) {
+                    j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+                    if (i != j) {
+                        result.add(pool2.get(1));
+                        break;
+                    }
+                }
+            }
+        } else {
+            // 替补 根据设置替补内容池查找内容尽心替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(2);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool2Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool2Replace)) {
+                    result.add(pool2Replace.get(0));
+                }
+            }
+        }
+
+        // 3-8
+        List<Content> pool = contentMap.get(contentPools[2]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setGhId(param.getGhId());
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        scoreParam.setStrategy(param.getStrategy());
+        scoreParam.setScene(param.getScene());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (String contentPool : ContentPoolEnum.getOrderContentPool()) {
+            for (Content c : contents) {
+                if (!contentPool.equals(c.getContentPoolType())) {
+                    continue;
+                }
+                if (!TitleSimilarCheckUtil.isDuplicateContent(c.getTitle(), titles)) {
+                    result.add(c);
+                    titles.add(c.getTitle());
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

+ 168 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV9Strategy.java

@@ -0,0 +1,168 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.common.enums.ContentPoolEnum;
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+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.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class RankV9Strategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+    @Autowired
+    private AccountContentPoolConfigService accountContentPoolConfigService;
+
+    public RankResult rank(RankParam param) {
+
+        //log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+
+        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()));
+            double score;
+            if (contentPools[0].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(HisFissionAvgReadRateRateStrategy.class.getSimpleName());
+            } else if (contentPools[1].equals(item.getContent().getContentPoolType())) {
+                score = item.getScore(SimilarityStrategy.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);
+            item.setScore(score);
+            return item;
+        });
+
+        // 1 排序
+        Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore()));
+        // 2 相似去重
+        List<Content> contents = CommonCollectionUtils.toList(items, RankItem::getContent);
+        contents = deduplication(contents);
+
+        // 3 文章按照内容池分组
+        Map<String, List<Content>> contentMap = new HashMap<>();
+        for (Content c : contents) {
+            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        // 4 选文章
+        List<Content> result = new ArrayList<>();
+
+        // 头
+        List<Content> pool1 = contentMap.get(contentPools[0]);
+        if (CollectionUtils.isNotEmpty(pool1)) {
+            result.add(pool1.get(0));
+        } else {
+            // 替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(1);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool1Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool1Replace)) {
+                    result.add(pool1Replace.get(0));
+                }
+            }
+        }
+        // 次
+        List<Content> pool2 = contentMap.get(contentPools[1]);
+        if (CollectionUtils.isNotEmpty(pool2)) {
+            int i = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            int j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+            result.add(pool2.get(i));
+            // 替补 头条内容不足使用次条内容
+            if (result.size() == 1 && pool2.size() > 1) {
+                while (i == j && pool2.size() > 1) {
+                    j = RandomUtils.nextInt(0, Math.min(pool2.size(), 5));
+                    if (i != j) {
+                        result.add(pool2.get(1));
+                        break;
+                    }
+                }
+            }
+        } else {
+            // 替补 根据设置替补内容池查找内容尽心替补
+            AccountIndexReplacePoolConfig replacePoolConfig = indexReplacePoolConfigMap.get(2);
+            if (Objects.nonNull(replacePoolConfig)) {
+                List<Content> pool2Replace = contentMap.get(replacePoolConfig.getContentPool());
+                if (CollectionUtils.isNotEmpty(pool2Replace)) {
+                    result.add(pool2Replace.get(0));
+                }
+            }
+        }
+
+        // 3-8
+        List<Content> pool = contentMap.get(contentPools[2]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setGhId(param.getGhId());
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        scoreParam.setStrategy(param.getStrategy());
+        scoreParam.setScene(param.getScene());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (String contentPool : ContentPoolEnum.getOrderContentPool()) {
+            for (Content c : contents) {
+                if (!contentPool.equals(c.getContentPoolType())) {
+                    continue;
+                }
+                if (!TitleSimilarCheckUtil.isDuplicateContent(c.getTitle(), titles)) {
+                    result.add(c);
+                    titles.add(c.getTitle());
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

+ 107 - 8
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recall/RecallService.java

@@ -5,12 +5,16 @@ import com.tzld.longarticle.recommend.server.model.Content;
 import com.tzld.longarticle.recommend.server.model.ContentHisPublishArticle;
 import com.tzld.longarticle.recommend.server.remote.AIGCRemoteService;
 import com.tzld.longarticle.recommend.server.repository.aigc.CrawlerMetaArticleRepository;
+import com.tzld.longarticle.recommend.server.repository.crawler.AccountAvgInfoRepository;
+import com.tzld.longarticle.recommend.server.repository.crawler.ArticleDetailInfoRepository;
 import com.tzld.longarticle.recommend.server.repository.crawler.ArticleRepository;
 import com.tzld.longarticle.recommend.server.repository.entity.aigc.CrawlerMetaArticle;
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.AccountAvgInfo;
 import com.tzld.longarticle.recommend.server.repository.entity.crawler.Article;
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.ArticleDetailInfo;
+import com.tzld.longarticle.recommend.server.repository.mapper.crawler.CrawlerBaseMapper;
 import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
 import com.tzld.longarticle.recommend.server.service.recall.strategy.DefaultRecallStrategy;
-import com.tzld.longarticle.recommend.server.service.score.AvgReadDTO;
 import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
 import com.tzld.longarticle.recommend.server.util.JSONUtils;
 import com.tzld.longarticle.recommend.server.util.Md5Util;
@@ -41,11 +45,17 @@ public class RecallService implements ApplicationContextAware {
     @Autowired
     ArticleRepository articleRepository;
     @Autowired
+    AccountAvgInfoRepository accountAvgInfoRepository;
+    @Autowired
+    ArticleDetailInfoRepository articleDetailInfoRepository;
+    @Autowired
     CrawlerMetaArticleRepository crawlerMetaArticleRepository;
     @Autowired
     AIGCRemoteService aigcRemoteService;
     @Autowired
     AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+    @Autowired
+    CrawlerBaseMapper crawlerBaseMapper;
 
     private final Map<String, RecallStrategy> strategyMap = new HashMap<>();
     private ApplicationContext applicationContext;
@@ -177,12 +187,29 @@ public class RecallService implements ApplicationContextAware {
     public void setTitleAvgViewCount(List<Content> contentList) {
         long start = System.currentTimeMillis();
 
-        List<String> titleList = contentList.stream().map(Content::getTitle).collect(Collectors.toList());
-        List<String> crawlerTitleList = contentList.stream().map(Content::getCrawlerTitle).collect(Collectors.toList());
+        Set<String> titleList = contentList.stream().map(Content::getTitle).collect(Collectors.toSet());
+        Set<String> crawlerTitleList = contentList.stream().map(Content::getCrawlerTitle).collect(Collectors.toSet());
         titleList.addAll(crawlerTitleList);
+        // 获取历史已发布文章
         List<Article> hisArticleList = articleRepository.getByTitleIn(titleList);
         Map<String, Map<Integer, List<Article>>> map = hisArticleList.stream()
                 .collect(Collectors.groupingBy(Article::getTitle, Collectors.groupingBy(Article::getItemIndex)));
+        Set<String> snList = hisArticleList.stream().map(Article::getWxSn).collect(Collectors.toSet());
+        List<ArticleDetailInfo> articleDetailInfoList = articleDetailInfoRepository.getAllByWxSnIn(snList);
+        Map<String, List<ArticleDetailInfo>> articleDetailInfoMap = articleDetailInfoList.stream()
+                .collect(Collectors.groupingBy(ArticleDetailInfo::getWxSn));
+        // 获取历史已发布文章所属头条内容
+        Set<String> ghIds = hisArticleList.stream().map(Article::getGhId).collect(Collectors.toSet());
+        Set<String> appMsgIds = hisArticleList.stream().map(Article::getAppMsgId).collect(Collectors.toSet());
+        List<Article> firstIndexHisArticleList = articleRepository.getByGhIdInAndAppMsgIdInAndItemIndex(ghIds, appMsgIds, 1);
+        Map<String, Map<String, Article>> firstIndexHisArticleMap = firstIndexHisArticleList.stream().collect(
+                Collectors.groupingBy(Article::getGhId, Collectors.toMap(Article::getAppMsgId, o -> o)));
+        // 获取发布账号 位置历史均值
+        List<AccountAvgInfo> accountAvgInfoList = accountAvgInfoRepository.getAllByGhIdIn(ghIds);
+        Map<String, Map<String, AccountAvgInfo>> accountAvgInfoIndexMap = accountAvgInfoList.stream().collect(
+                Collectors.groupingBy(AccountAvgInfo::getGhId, Collectors.toMap(AccountAvgInfo::getPosition, o -> o)));
+        Map<String, AccountAvgInfo> firstIndexAvgInfoMap = accountAvgInfoList.stream().filter(o -> "1".equals(o.getPosition()))
+                .collect(Collectors.toMap(AccountAvgInfo::getGhId, o -> o));
         for (Content content : contentList) {
             List<Article> hisArticles = new ArrayList<>();
             Map<Integer, List<Article>> indexArticleMap = map.get(content.getTitle());
@@ -212,22 +239,94 @@ public class RecallService implements ApplicationContextAware {
             for (Article hisArticle : hisArticles) {
                 ContentHisPublishArticle article = new ContentHisPublishArticle();
                 BeanUtils.copyProperties(hisArticle, article);
-                AvgReadDTO dto = accountIndexAvgViewCountService.getAvgReadDto(hisArticle.getGhId() + "_" + hisArticle.getItemIndex());
+                article.setViewCount(hisArticle.getShowViewCount());
+                article.setArticleDetailInfoList(articleDetailInfoMap.get(hisArticle.getWxSn()));
+                // 设置账号位置阅读均值
                 int avgViewCount = 0;
-                if (Objects.nonNull(dto)) {
+                Map<String, AccountAvgInfo> indexMap = accountAvgInfoIndexMap.get(hisArticle.getGhId());
+                if (Objects.nonNull(indexMap) && indexMap.containsKey(hisArticle.getItemIndex().toString())) {
                     article.setInnerAccount(true);
-                    avgViewCount = (int) dto.getReadAvg();
+                    avgViewCount = Optional.ofNullable(indexMap.get(hisArticle.getItemIndex().toString()).getReadAvg())
+                            .orElse(0.0).intValue();
                 }
                 article.setAvgViewCount(avgViewCount);
-                if (Objects.nonNull(article.getAvgViewCount()) && article.getAvgViewCount() > 0) {
-                    article.setViewCountRate((article.getShowViewCount() * 1.0) / article.getAvgViewCount());
+                if (Objects.nonNull(article.getAvgViewCount()) && article.getAvgViewCount() > 0
+                        && Objects.nonNull(article.getViewCount())) {
+                    article.setViewCountRate((article.getViewCount() * 1.0) / article.getAvgViewCount());
+                }
+                // 设置头条阅读均值
+                AccountAvgInfo firstIndexAvgInfo = firstIndexAvgInfoMap.get(hisArticle.getGhId());
+                if (Objects.nonNull(firstIndexAvgInfo)) {
+                    article.setFans(firstIndexAvgInfo.getFans());
+                }
+                Map<String, Article> firstIndexArticle = firstIndexHisArticleMap.get(hisArticle.getGhId());
+                if (Objects.nonNull(firstIndexArticle) && firstIndexArticle.containsKey(hisArticle.getAppMsgId())) {
+                    Article firstArticle = firstIndexArticle.get(hisArticle.getAppMsgId());
+                    article.setFirstViewCount(firstArticle.getShowViewCount());
+                    if (Objects.nonNull(firstIndexAvgInfo) && Objects.nonNull(firstIndexAvgInfo.getReadAvg())
+                            && firstIndexAvgInfo.getReadAvg() > 0 && Objects.nonNull(firstArticle.getShowViewCount())) {
+                        article.setFirstViewCountRate((firstArticle.getShowViewCount() * 1.0) / firstIndexAvgInfo.getReadAvg());
+                    }
                 }
                 content.getHisPublishArticleList().add(article);
             }
+            // 设置头条阅读均值
+            setT0Data(content);
         }
         log.info("setTitleAvgViewCount cost:{}", System.currentTimeMillis() - start);
     }
 
+    private void setT0Data(Content content) {
+        if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+            return;
+        }
+        int firstLevelSize = 0;
+        int fissionSum = 0;
+        int fansSum = 0;
+        int avgReadCountSum = 0;
+        Double t0FissionByFansSum = 0.0;
+        Double t0FissionByReadAvgSum = 0.0;
+        for (ContentHisPublishArticle article : content.getHisPublishArticleList()) {
+            if (article.getItemIndex() != 1
+                    || CollectionUtils.isEmpty(article.getArticleDetailInfoList())) {
+                continue;
+            }
+            int sumFission = 0;
+            Date minDate = article.getArticleDetailInfoList().stream().map(ArticleDetailInfo::getRecallDt).min(Date::compareTo).orElse(new Date());
+            for (ArticleDetailInfo articleDetailInfo : article.getArticleDetailInfoList()) {
+                if (articleDetailInfo.getRecallDt().equals(minDate) && Objects.nonNull(articleDetailInfo.getFission0())) {
+                    sumFission += articleDetailInfo.getFission0();
+                }
+            }
+            if (sumFission == 0) {
+                continue;
+            }
+            article.setT0FissionSum(sumFission);
+            if (article.getFans() > 0) {
+                article.setT0FissionByFans(sumFission * 1.0 / article.getFans());
+                fansSum += (int) article.getFans();
+                t0FissionByFansSum += article.getT0FissionByFans();
+            }
+            if (Objects.nonNull(article.getAvgViewCount()) && article.getAvgViewCount() > 0) {
+                article.setT0FissionByReadAvg(sumFission * 1.0 / article.getAvgViewCount());
+                avgReadCountSum += article.getAvgViewCount();
+                t0FissionByReadAvgSum += article.getT0FissionByReadAvg();
+            }
+            fissionSum += sumFission;
+            firstLevelSize++;
+        }
+        if (firstLevelSize > 0) {
+            content.setT0FissionByFansMean(t0FissionByFansSum / firstLevelSize);
+            content.setT0FissionByReadAvgMean(t0FissionByReadAvgSum / firstLevelSize);
+            if (fansSum > 0) {
+                content.setT0FissionByFansSumAvg(fissionSum * 1.0 / fansSum);
+            }
+            if (avgReadCountSum > 0) {
+                content.setT0FissionByReadAvgSumAvg(fissionSum * 1.0 / avgReadCountSum);
+            }
+        }
+    }
+
     public static void main(String[] args) {
         String url = "http://mp.weixin.qq.com/s?__biz=Mzg2ODk4MTg3OQ==&mid=2247488306&idx=1&sn=93ebadc5bc7161a0dee48355013d3bc4&chksm=cfb6c1cb2bcdd80dd16d5d604d741a0019ae791125265a042d26100ba21ddb9e5c643ecc2264&scene=126&sessionid=1679649075#rd";
         String md5 = generateArticleUniqueMd5(url);

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/Score.java

@@ -15,7 +15,7 @@ import lombok.Setter;
 public class Score {
     private String strategy;
     private String contentId;
-    private double score;
+    private Double score;
 
     public void setStrategy(ScoreStrategy strategy) {
         this.strategy = strategy.getClass().getSimpleName();

+ 9 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/ScoreService.java

@@ -93,12 +93,20 @@ public class ScoreService implements ApplicationContextAware {
             strategies.add(strategyMap.get(ViewCountRateStrategy.class.getSimpleName()));
         }
         if (StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV4.getStrategy())
-                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV5.getStrategy())) {
+                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV5.getStrategy())
+                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV7.getStrategy())
+                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV8.getStrategy())
+                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV9.getStrategy())
+                || StringUtils.equals(param.getStrategy(), RankStrategyEnum.ArticleRankV10.getStrategy())) {
             strategies.add(strategyMap.get(CategoryStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(AccountPreDistributeStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(FlowCtlDecreaseStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(ViewCountRateStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(PublishTimesStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HisFissionFansRateRateStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HisFissionFansSumRateStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HisFissionAvgReadRateRateStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(HisFissionAvgReadSumRateStrategy.class.getSimpleName()));
         }
 
         return strategies;

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/AccountPreDistributeStrategy.java

@@ -60,7 +60,7 @@ public class AccountPreDistributeStrategy implements ScoreStrategy {
             if (pools[2].equals(content.getContentPoolType())) {
                 if (articles.contains(content.getCrawlerChannelContentId())) {
                     score.setContentId(content.getId());
-                    score.setScore(weight);
+                    score.setScore(Double.valueOf(weight));
                 }
             }
             if (StringUtils.hasText(score.getContentId())) {

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/CategoryStrategy.java

@@ -52,7 +52,7 @@ public class CategoryStrategy implements ScoreStrategy {
                         List<AccountCategoryWeightConfig.CategoryWeight> categoryWeightList = categoryWeightConfig.getCategoryWeightList();
                         for (AccountCategoryWeightConfig.CategoryWeight categoryWeight : categoryWeightList) {
                             if (content.getCategory().contains(categoryWeight.getCategory())) {
-                                score.setScore(categoryWeight.getWeight());
+                                score.setScore(Double.valueOf(categoryWeight.getWeight()));
                             }
                         }
                     }

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/FlowCtlDecreaseStrategy.java

@@ -57,7 +57,7 @@ public class FlowCtlDecreaseStrategy implements ScoreStrategy {
             score.setContentId(content.getId());
             Integer scoreVal = getContentScore(param.getAccountName(), hisPublishedContentMap, content);
             if (scoreVal != 0) {
-                score.setScore(scoreVal);
+                score.setScore(Double.valueOf(scoreVal));
                 scores.add(score);
             }
         }

+ 38 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionAvgReadRateRateStrategy.java

@@ -0,0 +1,38 @@
+package com.tzld.longarticle.recommend.server.service.score.strategy;
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
+import com.tzld.longarticle.recommend.server.service.score.Score;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@Slf4j
+public class HisFissionAvgReadRateRateStrategy implements ScoreStrategy {
+
+    @Autowired
+    AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+
+    @Override
+    public List<Score> score(ScoreParam param) {
+        List<Score> scores = new ArrayList<>();
+        for (Content content : param.getContents()) {
+            if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+                continue;
+            }
+            Score score = new Score();
+            score.setStrategy(this);
+            score.setContentId(content.getId());
+            score.setScore(content.getT0FissionByReadAvgMean());
+            scores.add(score);
+        }
+        return scores;
+    }
+}

+ 38 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionAvgReadSumRateStrategy.java

@@ -0,0 +1,38 @@
+package com.tzld.longarticle.recommend.server.service.score.strategy;
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
+import com.tzld.longarticle.recommend.server.service.score.Score;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@Slf4j
+public class HisFissionAvgReadSumRateStrategy implements ScoreStrategy {
+
+    @Autowired
+    AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+
+    @Override
+    public List<Score> score(ScoreParam param) {
+        List<Score> scores = new ArrayList<>();
+        for (Content content : param.getContents()) {
+            if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+                continue;
+            }
+            Score score = new Score();
+            score.setStrategy(this);
+            score.setContentId(content.getId());
+            score.setScore(content.getT0FissionByReadAvgSumAvg());
+            scores.add(score);
+        }
+        return scores;
+    }
+}

+ 38 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionFansRateRateStrategy.java

@@ -0,0 +1,38 @@
+package com.tzld.longarticle.recommend.server.service.score.strategy;
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
+import com.tzld.longarticle.recommend.server.service.score.Score;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@Slf4j
+public class HisFissionFansRateRateStrategy implements ScoreStrategy {
+
+    @Autowired
+    AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+
+    @Override
+    public List<Score> score(ScoreParam param) {
+        List<Score> scores = new ArrayList<>();
+        for (Content content : param.getContents()) {
+            if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+                continue;
+            }
+            Score score = new Score();
+            score.setStrategy(this);
+            score.setContentId(content.getId());
+            score.setScore(content.getT0FissionByFansMean());
+            scores.add(score);
+        }
+        return scores;
+    }
+}

+ 38 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/HisFissionFansSumRateStrategy.java

@@ -0,0 +1,38 @@
+package com.tzld.longarticle.recommend.server.service.score.strategy;
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountIndexAvgViewCountService;
+import com.tzld.longarticle.recommend.server.service.score.Score;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@Slf4j
+public class HisFissionFansSumRateStrategy implements ScoreStrategy {
+
+    @Autowired
+    AccountIndexAvgViewCountService accountIndexAvgViewCountService;
+
+    @Override
+    public List<Score> score(ScoreParam param) {
+        List<Score> scores = new ArrayList<>();
+        for (Content content : param.getContents()) {
+            if (CollectionUtils.isEmpty(content.getHisPublishArticleList())) {
+                continue;
+            }
+            Score score = new Score();
+            score.setStrategy(this);
+            score.setContentId(content.getId());
+            score.setScore(content.getT0FissionByFansSumAvg());
+            scores.add(score);
+        }
+        return scores;
+    }
+}

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/PublishTimesStrategy.java

@@ -68,6 +68,7 @@ public class PublishTimesStrategy implements ScoreStrategy {
             Score score = new Score();
             score.setStrategy(this);
             score.setContentId(content.getId());
+            score.setScore(0.0);
             for (int i = 0; i < contentPools.length; i++) {
                 int val = i + 1;
                 if (CollectionUtils.isEmpty(hisPublishedContentMap.get(content.getTitle()))

+ 6 - 5
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/ViewCountRateStrategy.java

@@ -34,7 +34,6 @@ public class ViewCountRateStrategy implements ScoreStrategy {
                 }
                 double avgViewCountPos = accountIndexAvgViewCountService.getAvgReadCount(param.getGhId(), i + 1);
                 double avgViewCountFirst = accountIndexAvgViewCountService.getAvgReadCount(param.getGhId(), 1);
-                double avgViewCountSecond = accountIndexAvgViewCountService.getAvgReadCount(param.getGhId(), 2);
                 double showViewCountSum = 0D;
                 double avgViewCountSum = 0D;
                 double showViewCountSumFirst = 0D;
@@ -42,15 +41,17 @@ public class ViewCountRateStrategy implements ScoreStrategy {
                 double showViewCountSumSecond = 0D;
                 double avgViewCountSumSecond = 0D;
                 for (ContentHisPublishArticle hisItem : content.getHisPublishArticleList()) {
-                    if (hisItem.isInnerAccount() && hisItem.getShowViewCount() > 0 && hisItem.getAvgViewCount() > 0) {
+                    if (hisItem.isInnerAccount() && Objects.nonNull(hisItem.getViewCount())
+                            && hisItem.getViewCount() > 0 && Objects.nonNull(hisItem.getAvgViewCount())
+                            && hisItem.getAvgViewCount() > 0) {
                         if (hisItem.getItemIndex() == 1) {
-                            showViewCountSumFirst += hisItem.getShowViewCount();
+                            showViewCountSumFirst += hisItem.getViewCount();
                             avgViewCountSumFirst += hisItem.getAvgViewCount();
                         } else if (hisItem.getItemIndex() == 2) {
-                            showViewCountSumSecond += hisItem.getShowViewCount();
+                            showViewCountSumSecond += hisItem.getViewCount();
                             avgViewCountSumSecond += hisItem.getAvgViewCount();
                         } else {
-                            showViewCountSum += hisItem.getShowViewCount();
+                            showViewCountSum += hisItem.getViewCount();
                             avgViewCountSum += hisItem.getAvgViewCount();
                         }
                     }