21 커밋 2e6a040804 ... e60428baa8

작성자 SHA1 메시지 날짜
  Joe e60428baa8 Merge branch 'master' into feature_20230906_qjl_cgiReply 10 달 전
  Joe 65bad24502 init 自动回复 10 달 전
  wangyunpeng 2414cfe0f8 batch save partition 10 달 전
  wangyunpeng 025cbe8da4 数据统计更新数据库 10 달 전
  yangxiaohui d08f9fa7e4 修复缺省 10 달 전
  yangxiaohui 8874da3a78 修复次条 10 달 전
  yangxiaohui 59ceec8457 Merge branch 'yxh/0907' of Server/long-article-recommend into master 10 달 전
  yangxiaohui c6f3e85270 rate缺省头条均值设置为2w 10 달 전
  yangxiaohui 0065040e6f Merge branch 'yxh/0907' of Server/long-article-recommend into master 10 달 전
  yangxiaohui ebfbd4d519 v8策略增加相似度 10 달 전
  wangyunpeng 7aadbb2c2b Merge remote-tracking branch 'origin/master' 10 달 전
  wangyunpeng b90e247850 更改表头 10 달 전
  丁云鹏 4fbf59b624 disableHtmlEscaping 10 달 전
  丁云鹏 90fa15c51c disableHtmlEscaping 10 달 전
  丁云鹏 f7dfce360e fuwuhao content link 10 달 전
  dingyunpeng 0110e40689 Merge branch 'feature_fuwuhao' of Server/long-article-recommend into master 10 달 전
  丁云鹏 2132537273 fuwuhao content link 10 달 전
  丁云鹏 05564c43bf fuwuhao content link 10 달 전
  dingyunpeng 5c7a9a86f6 Merge branch 'feature_fuwuhao' of Server/long-article-recommend into master 10 달 전
  丁云鹏 3e423d1cdc fuwuhao content link 10 달 전
  丁云鹏 2686a04401 fuwuhao content link 10 달 전
30개의 변경된 파일3656개의 추가작업 그리고 111개의 파일을 삭제
  1. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/MBG.java
  2. 1 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/ThreadPoolFactory.java
  3. 2 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/NewSortStrategyExport.java
  4. 61 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/WxFetchRemoteService.java
  5. 10 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/crawler/DatastatSortStrategyRepository.java
  6. 100 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/entity/crawler/DatastatSortStrategy.java
  7. 35 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/ArticleContentLinkMapper.java
  8. 30 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/CgiReplyBucketDataMapper.java
  9. 8 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/CrawlerBaseMapper.java
  10. 83 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/ArticleContentLink.java
  11. 709 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/ArticleContentLinkExample.java
  12. 175 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/CgiReplyBucketData.java
  13. 1310 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/CgiReplyBucketDataExample.java
  14. 33 9
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/DataDashboardService.java
  15. 61 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/JobService.java
  16. 81 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/MessageSendCallbackService.java
  17. 8 16
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/UserManagementService.java
  18. 31 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/WXListenService.java
  19. 4 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV8Strategy.java
  20. 51 10
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/score/strategy/ViewCountRateStrategy.java
  21. 22 1
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/strategy/reply/impl/BuckStrategyV1.java
  22. 2 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/util/JSONUtils.java
  23. 33 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/JobController.java
  24. 6 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/UserManagementController.java
  25. 41 0
      long-article-recommend-service/src/main/resources/generatorCgiConfig.xml
  26. 1 1
      long-article-recommend-service/src/main/resources/generatorConfig.xml
  27. 267 0
      long-article-recommend-service/src/main/resources/mapper/crawler/ArticleContentLinkMapper.xml
  28. 401 0
      long-article-recommend-service/src/main/resources/mapper/crawler/CgiReplyBucketDataMapper.xml
  29. 22 0
      long-article-recommend-service/src/main/resources/mapper/crawler/CrawlerBaseMapper.xml
  30. 67 67
      long-article-recommend-service/src/test/java/com/tzld/longarticle/recommend/server/RecommendTest.java

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

@@ -17,7 +17,7 @@ public class MBG {
         List<String> warnings = new ArrayList<String>();
         boolean overwrite = true;
         ConfigurationParser cp = new ConfigurationParser(warnings);
-        Configuration config = cp.parseConfiguration(new File("/Users/dingyunpeng/Desktop/code/changwen/long-article-recommend/long-article-recommend-service/src/main/resources/generatorConfig.xml"));
+        Configuration config = cp.parseConfiguration(new File("D:\\taizi\\code\\long-article-recommend\\long-article-recommend-service\\src\\main\\resources\\generatorCgiConfig.xml"));
         DefaultShellCallback callback = new DefaultShellCallback(overwrite);
         MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
         myBatisGenerator.generate(null);

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

@@ -26,8 +26,8 @@ public final class ThreadPoolFactory {
             new ThreadFactoryBuilder().setNameFormat("RecallService-%d").build(),
             new ThreadPoolExecutor.AbortPolicy());
     private final static ExecutorService FILTER = new CommonThreadPoolExecutor(
-            32,
             128,
+            256,
             0L, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(1000),
             new ThreadFactoryBuilder().setNameFormat("FilterService-%d").build(),

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

@@ -16,6 +16,8 @@ public class NewSortStrategyExport {
     private long fans;
     private Integer viewCount;
     private Double avgViewCount;
+    private Integer firstViewCount;
+    private Double firstAvgViewCount;
     private Integer firstLevel;
     private Integer fission0;
     private Integer fission1;

+ 61 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/WxFetchRemoteService.java

@@ -0,0 +1,61 @@
+package com.tzld.longarticle.recommend.server.remote;
+
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.longarticle.recommend.server.common.HttpPoolFactory;
+import com.tzld.longarticle.recommend.server.model.Content;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class WxFetchRemoteService {
+    private final CloseableHttpClient client = HttpPoolFactory.aigcPool();
+    private static final String url = "http://8.217.190.241:8888/crawler/wei_xin/detail";
+
+
+    public Map<String, String> getContent(String contentUrl) {
+        Map<String, String> result = new HashMap<>();
+        JSONObject bodyParam = new JSONObject();
+        bodyParam.put("content_link", contentUrl);
+        bodyParam.put("is_count", true);
+        bodyParam.put("is_cache", false);
+        try {
+            HttpPost httpPost = new HttpPost(url);
+            StringEntity stringEntity = new StringEntity(bodyParam.toJSONString(), StandardCharsets.UTF_8);
+            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
+            httpPost.setEntity(stringEntity);
+            CloseableHttpResponse response = client.execute(httpPost);
+            StatusLine statusLine = response.getStatusLine();
+            if (statusLine.getStatusCode() == 200) {
+                HttpEntity responseEntity = response.getEntity();
+                if (Objects.nonNull(responseEntity)) {
+                    String responseBody = EntityUtils.toString(responseEntity, "UTF-8");
+                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                    if (jsonObject.getInteger("code") == 0) {
+                        JSONObject data = jsonObject.getJSONObject("data");
+                        data = data.getJSONObject("data");
+                        result.put("view_count", data.getString("view_count"));
+                        result.put("title", data.getString("title"));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("getViewCount error", e);
+        }
+        return result;
+    }
+
+}

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

@@ -0,0 +1,10 @@
+package com.tzld.longarticle.recommend.server.repository.crawler;
+
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.DatastatSortStrategy;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface DatastatSortStrategyRepository extends JpaRepository<DatastatSortStrategy, DatastatSortStrategy.PK> {
+
+}

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

@@ -0,0 +1,100 @@
+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;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "datastat_sort_strategy")
+@IdClass(DatastatSortStrategy.PK.class)
+public class DatastatSortStrategy  implements Serializable {
+
+    @Id
+    private String dateStr;
+    @Id
+    private String publishTime;
+    @Id
+    private String accountName;
+    @Id
+    private Integer position;
+
+    @Column(name = "account_mode")
+    private String accountMode;
+    @Column(name = "account_source")
+    private String accountSource;
+    @Column(name = "account_type")
+    private String accountType;
+    @Column(name = "account_status")
+    private String accountStatus;
+    @Column(name = "strategy")
+    private String strategy;
+    @Column(name = "fans")
+    private long fans;
+    @Column(name = "view_count")
+    private Integer viewCount;
+    @Column(name = "avg_view_count")
+    private Double avgViewCount;
+    @Column(name = "first_view_count")
+    private Integer firstViewCount;
+    @Column(name = "first_avg_view_count")
+    private Double firstAvgViewCount;
+    @Column(name = "first_level")
+    private Integer firstLevel;
+    @Column(name = "fission0")
+    private Integer fission0;
+    @Column(name = "fission1")
+    private Integer fission1;
+    @Column(name = "fission2")
+    private Integer fission2;
+    @Column(name = "read_rate")
+    private Double readRate;
+    @Column(name = "read_fans_rate")
+    private Double readFansRate;
+    @Column(name = "first_read_rate")
+    private Double firstReadRate;
+    @Column(name = "fission0_first_rate")
+    private Double fission0FirstRate;
+    @Column(name = "fission1_fission0_rate")
+    private Double fission1Fission0Rate;
+    @Column(name = "fission0_read_avg_rate")
+    private Double fission0ReadAvgRate;
+    @Column(name = "gh_id")
+    private String ghId;
+    @Column(name = "title")
+    private String title;
+    @Column(name = "link")
+    private String link;
+    @Column(name = "wx_sn")
+    private String wxSn;
+    @Column(name = "fission0_read_avg_100_rate")
+    private Double fission0ReadAvg100Rate;
+    @Column(name = "fission0_read_avg_500_rate")
+    private Double fission0ReadAvg500Rate;
+    @Column(name = "fission0_read_avg_1000_rate")
+    private Double fission0ReadAvg1000Rate;
+
+
+    @Data
+    public static class PK implements Serializable {
+
+        @Column(name = "date_str")
+        private String dateStr;
+        @Column(name = "publish_time")
+        private String publishTime;
+        @Column(name = "account_name")
+        private String accountName;
+        @Column(name = "position")
+        private Integer position;
+
+        public PK() {
+        }
+
+
+    }
+}

+ 35 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/ArticleContentLinkMapper.java

@@ -0,0 +1,35 @@
+package com.tzld.longarticle.recommend.server.repository.mapper.crawler;
+
+import com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink;
+import com.tzld.longarticle.recommend.server.repository.model.ArticleContentLinkExample;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface ArticleContentLinkMapper {
+    long countByExample(ArticleContentLinkExample example);
+
+    int deleteByExample(ArticleContentLinkExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(ArticleContentLink row);
+
+    int insertSelective(ArticleContentLink row);
+
+    List<ArticleContentLink> selectByExample(ArticleContentLinkExample example);
+
+    ArticleContentLink selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("row") ArticleContentLink row, @Param("example") ArticleContentLinkExample example);
+
+    int updateByExample(@Param("row") ArticleContentLink row, @Param("example") ArticleContentLinkExample example);
+
+    int updateByPrimaryKeySelective(ArticleContentLink row);
+
+    int updateByPrimaryKey(ArticleContentLink row);
+
+    int insertBatch(List<ArticleContentLink> list);
+}

+ 30 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/CgiReplyBucketDataMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.longarticle.recommend.server.repository.mapper.crawler;
+
+import com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData;
+import com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketDataExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface CgiReplyBucketDataMapper {
+    long countByExample(CgiReplyBucketDataExample example);
+
+    int deleteByExample(CgiReplyBucketDataExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(CgiReplyBucketData row);
+
+    int insertSelective(CgiReplyBucketData row);
+
+    List<CgiReplyBucketData> selectByExample(CgiReplyBucketDataExample example);
+
+    CgiReplyBucketData selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("row") CgiReplyBucketData row, @Param("example") CgiReplyBucketDataExample example);
+
+    int updateByExample(@Param("row") CgiReplyBucketData row, @Param("example") CgiReplyBucketDataExample example);
+
+    int updateByPrimaryKeySelective(CgiReplyBucketData row);
+
+    int updateByPrimaryKey(CgiReplyBucketData row);
+}

+ 8 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/mapper/crawler/CrawlerBaseMapper.java

@@ -1,5 +1,13 @@
 package com.tzld.longarticle.recommend.server.repository.mapper.crawler;
 
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.DatastatSortStrategy;
+
+import java.util.List;
+
 public interface CrawlerBaseMapper {
 
+    void deleteByDateStrGreaterThanEqual(String dateStr);
+
+    void batchInsertDatastatSortStrategy(List<DatastatSortStrategy> list);
+
 }

+ 83 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/ArticleContentLink.java

@@ -0,0 +1,83 @@
+package com.tzld.longarticle.recommend.server.repository.model;
+
+public class ArticleContentLink {
+    private Long id;
+
+    private String gzhId;
+
+    private Integer idx;
+
+    private String contentLink;
+
+    private Long createTime;
+
+    private String title;
+
+    private Long viewCount;
+
+    private Long updateTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getGzhId() {
+        return gzhId;
+    }
+
+    public void setGzhId(String gzhId) {
+        this.gzhId = gzhId == null ? null : gzhId.trim();
+    }
+
+    public Integer getIdx() {
+        return idx;
+    }
+
+    public void setIdx(Integer idx) {
+        this.idx = idx;
+    }
+
+    public String getContentLink() {
+        return contentLink;
+    }
+
+    public void setContentLink(String contentLink) {
+        this.contentLink = contentLink == null ? null : contentLink.trim();
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title == null ? null : title.trim();
+    }
+
+    public Long getViewCount() {
+        return viewCount;
+    }
+
+    public void setViewCount(Long viewCount) {
+        this.viewCount = viewCount;
+    }
+
+    public Long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 709 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/ArticleContentLinkExample.java

@@ -0,0 +1,709 @@
+package com.tzld.longarticle.recommend.server.repository.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ArticleContentLinkExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    public ArticleContentLinkExample() {
+        oredCriteria = new ArrayList<>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(Long value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(Long value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(Long value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(Long value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(Long value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<Long> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<Long> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(Long value1, Long value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(Long value1, Long value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdIsNull() {
+            addCriterion("gzh_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdIsNotNull() {
+            addCriterion("gzh_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdEqualTo(String value) {
+            addCriterion("gzh_id =", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdNotEqualTo(String value) {
+            addCriterion("gzh_id <>", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdGreaterThan(String value) {
+            addCriterion("gzh_id >", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdGreaterThanOrEqualTo(String value) {
+            addCriterion("gzh_id >=", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdLessThan(String value) {
+            addCriterion("gzh_id <", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdLessThanOrEqualTo(String value) {
+            addCriterion("gzh_id <=", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdLike(String value) {
+            addCriterion("gzh_id like", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdNotLike(String value) {
+            addCriterion("gzh_id not like", value, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdIn(List<String> values) {
+            addCriterion("gzh_id in", values, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdNotIn(List<String> values) {
+            addCriterion("gzh_id not in", values, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdBetween(String value1, String value2) {
+            addCriterion("gzh_id between", value1, value2, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGzhIdNotBetween(String value1, String value2) {
+            addCriterion("gzh_id not between", value1, value2, "gzhId");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxIsNull() {
+            addCriterion("idx is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxIsNotNull() {
+            addCriterion("idx is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxEqualTo(Integer value) {
+            addCriterion("idx =", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxNotEqualTo(Integer value) {
+            addCriterion("idx <>", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxGreaterThan(Integer value) {
+            addCriterion("idx >", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxGreaterThanOrEqualTo(Integer value) {
+            addCriterion("idx >=", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxLessThan(Integer value) {
+            addCriterion("idx <", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxLessThanOrEqualTo(Integer value) {
+            addCriterion("idx <=", value, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxIn(List<Integer> values) {
+            addCriterion("idx in", values, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxNotIn(List<Integer> values) {
+            addCriterion("idx not in", values, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxBetween(Integer value1, Integer value2) {
+            addCriterion("idx between", value1, value2, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdxNotBetween(Integer value1, Integer value2) {
+            addCriterion("idx not between", value1, value2, "idx");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkIsNull() {
+            addCriterion("content_link is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkIsNotNull() {
+            addCriterion("content_link is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkEqualTo(String value) {
+            addCriterion("content_link =", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkNotEqualTo(String value) {
+            addCriterion("content_link <>", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkGreaterThan(String value) {
+            addCriterion("content_link >", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkGreaterThanOrEqualTo(String value) {
+            addCriterion("content_link >=", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkLessThan(String value) {
+            addCriterion("content_link <", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkLessThanOrEqualTo(String value) {
+            addCriterion("content_link <=", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkLike(String value) {
+            addCriterion("content_link like", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkNotLike(String value) {
+            addCriterion("content_link not like", value, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkIn(List<String> values) {
+            addCriterion("content_link in", values, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkNotIn(List<String> values) {
+            addCriterion("content_link not in", values, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkBetween(String value1, String value2) {
+            addCriterion("content_link between", value1, value2, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andContentLinkNotBetween(String value1, String value2) {
+            addCriterion("content_link not between", value1, value2, "contentLink");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNull() {
+            addCriterion("create_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNotNull() {
+            addCriterion("create_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeEqualTo(Long value) {
+            addCriterion("create_time =", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotEqualTo(Long value) {
+            addCriterion("create_time <>", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThan(Long value) {
+            addCriterion("create_time >", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
+            addCriterion("create_time >=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThan(Long value) {
+            addCriterion("create_time <", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
+            addCriterion("create_time <=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIn(List<Long> values) {
+            addCriterion("create_time in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotIn(List<Long> values) {
+            addCriterion("create_time not in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeBetween(Long value1, Long value2) {
+            addCriterion("create_time between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
+            addCriterion("create_time not between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIsNull() {
+            addCriterion("title is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIsNotNull() {
+            addCriterion("title is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleEqualTo(String value) {
+            addCriterion("title =", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotEqualTo(String value) {
+            addCriterion("title <>", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleGreaterThan(String value) {
+            addCriterion("title >", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleGreaterThanOrEqualTo(String value) {
+            addCriterion("title >=", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLessThan(String value) {
+            addCriterion("title <", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLessThanOrEqualTo(String value) {
+            addCriterion("title <=", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLike(String value) {
+            addCriterion("title like", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotLike(String value) {
+            addCriterion("title not like", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIn(List<String> values) {
+            addCriterion("title in", values, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotIn(List<String> values) {
+            addCriterion("title not in", values, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleBetween(String value1, String value2) {
+            addCriterion("title between", value1, value2, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotBetween(String value1, String value2) {
+            addCriterion("title not between", value1, value2, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountIsNull() {
+            addCriterion("view_count is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountIsNotNull() {
+            addCriterion("view_count is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountEqualTo(Long value) {
+            addCriterion("view_count =", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountNotEqualTo(Long value) {
+            addCriterion("view_count <>", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountGreaterThan(Long value) {
+            addCriterion("view_count >", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountGreaterThanOrEqualTo(Long value) {
+            addCriterion("view_count >=", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountLessThan(Long value) {
+            addCriterion("view_count <", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountLessThanOrEqualTo(Long value) {
+            addCriterion("view_count <=", value, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountIn(List<Long> values) {
+            addCriterion("view_count in", values, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountNotIn(List<Long> values) {
+            addCriterion("view_count not in", values, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountBetween(Long value1, Long value2) {
+            addCriterion("view_count between", value1, value2, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andViewCountNotBetween(Long value1, Long value2) {
+            addCriterion("view_count not between", value1, value2, "viewCount");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNull() {
+            addCriterion("update_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNotNull() {
+            addCriterion("update_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeEqualTo(Long value) {
+            addCriterion("update_time =", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotEqualTo(Long value) {
+            addCriterion("update_time <>", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThan(Long value) {
+            addCriterion("update_time >", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) {
+            addCriterion("update_time >=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThan(Long value) {
+            addCriterion("update_time <", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThanOrEqualTo(Long value) {
+            addCriterion("update_time <=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIn(List<Long> values) {
+            addCriterion("update_time in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotIn(List<Long> values) {
+            addCriterion("update_time not in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeBetween(Long value1, Long value2) {
+            addCriterion("update_time between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotBetween(Long value1, Long value2) {
+            addCriterion("update_time not between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+    }
+
+    public static class Criteria extends GeneratedCriteria {
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 175 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/CgiReplyBucketData.java

@@ -0,0 +1,175 @@
+package com.tzld.longarticle.recommend.server.repository.model;
+
+import java.util.Date;
+
+public class CgiReplyBucketData {
+    private Long id;
+
+    private String strategy;
+
+    private Integer sort;
+
+    private String strategyDt;
+
+    private String ghId;
+
+    private Integer msgType;
+
+    private String title;
+
+    private String coverUrl;
+
+    private String miniAppId;
+
+    private String miniPagePath;
+
+    private Long miniVideoId;
+
+    private Long pagePathUrlId;
+
+    private String newsPublishContentId;
+
+    private String planId;
+
+    private Integer isDelete;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getStrategy() {
+        return strategy;
+    }
+
+    public void setStrategy(String strategy) {
+        this.strategy = strategy == null ? null : strategy.trim();
+    }
+
+    public Integer getSort() {
+        return sort;
+    }
+
+    public void setSort(Integer sort) {
+        this.sort = sort;
+    }
+
+    public String getStrategyDt() {
+        return strategyDt;
+    }
+
+    public void setStrategyDt(String strategyDt) {
+        this.strategyDt = strategyDt == null ? null : strategyDt.trim();
+    }
+
+    public String getGhId() {
+        return ghId;
+    }
+
+    public void setGhId(String ghId) {
+        this.ghId = ghId == null ? null : ghId.trim();
+    }
+
+    public Integer getMsgType() {
+        return msgType;
+    }
+
+    public void setMsgType(Integer msgType) {
+        this.msgType = msgType;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title == null ? null : title.trim();
+    }
+
+    public String getCoverUrl() {
+        return coverUrl;
+    }
+
+    public void setCoverUrl(String coverUrl) {
+        this.coverUrl = coverUrl == null ? null : coverUrl.trim();
+    }
+
+    public String getMiniAppId() {
+        return miniAppId;
+    }
+
+    public void setMiniAppId(String miniAppId) {
+        this.miniAppId = miniAppId == null ? null : miniAppId.trim();
+    }
+
+    public String getMiniPagePath() {
+        return miniPagePath;
+    }
+
+    public void setMiniPagePath(String miniPagePath) {
+        this.miniPagePath = miniPagePath == null ? null : miniPagePath.trim();
+    }
+
+    public Long getMiniVideoId() {
+        return miniVideoId;
+    }
+
+    public void setMiniVideoId(Long miniVideoId) {
+        this.miniVideoId = miniVideoId;
+    }
+
+    public Long getPagePathUrlId() {
+        return pagePathUrlId;
+    }
+
+    public void setPagePathUrlId(Long pagePathUrlId) {
+        this.pagePathUrlId = pagePathUrlId;
+    }
+
+    public String getNewsPublishContentId() {
+        return newsPublishContentId;
+    }
+
+    public void setNewsPublishContentId(String newsPublishContentId) {
+        this.newsPublishContentId = newsPublishContentId == null ? null : newsPublishContentId.trim();
+    }
+
+    public String getPlanId() {
+        return planId;
+    }
+
+    public void setPlanId(String planId) {
+        this.planId = planId == null ? null : planId.trim();
+    }
+
+    public Integer getIsDelete() {
+        return isDelete;
+    }
+
+    public void setIsDelete(Integer isDelete) {
+        this.isDelete = isDelete;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 1310 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/model/CgiReplyBucketDataExample.java

@@ -0,0 +1,1310 @@
+package com.tzld.longarticle.recommend.server.repository.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class CgiReplyBucketDataExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    public CgiReplyBucketDataExample() {
+        oredCriteria = new ArrayList<>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(Long value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(Long value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(Long value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(Long value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(Long value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<Long> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<Long> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(Long value1, Long value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(Long value1, Long value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyIsNull() {
+            addCriterion("strategy is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyIsNotNull() {
+            addCriterion("strategy is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyEqualTo(String value) {
+            addCriterion("strategy =", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyNotEqualTo(String value) {
+            addCriterion("strategy <>", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyGreaterThan(String value) {
+            addCriterion("strategy >", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyGreaterThanOrEqualTo(String value) {
+            addCriterion("strategy >=", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyLessThan(String value) {
+            addCriterion("strategy <", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyLessThanOrEqualTo(String value) {
+            addCriterion("strategy <=", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyLike(String value) {
+            addCriterion("strategy like", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyNotLike(String value) {
+            addCriterion("strategy not like", value, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyIn(List<String> values) {
+            addCriterion("strategy in", values, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyNotIn(List<String> values) {
+            addCriterion("strategy not in", values, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyBetween(String value1, String value2) {
+            addCriterion("strategy between", value1, value2, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyNotBetween(String value1, String value2) {
+            addCriterion("strategy not between", value1, value2, "strategy");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortIsNull() {
+            addCriterion("sort is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortIsNotNull() {
+            addCriterion("sort is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortEqualTo(Integer value) {
+            addCriterion("sort =", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortNotEqualTo(Integer value) {
+            addCriterion("sort <>", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortGreaterThan(Integer value) {
+            addCriterion("sort >", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortGreaterThanOrEqualTo(Integer value) {
+            addCriterion("sort >=", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortLessThan(Integer value) {
+            addCriterion("sort <", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortLessThanOrEqualTo(Integer value) {
+            addCriterion("sort <=", value, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortIn(List<Integer> values) {
+            addCriterion("sort in", values, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortNotIn(List<Integer> values) {
+            addCriterion("sort not in", values, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortBetween(Integer value1, Integer value2) {
+            addCriterion("sort between", value1, value2, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andSortNotBetween(Integer value1, Integer value2) {
+            addCriterion("sort not between", value1, value2, "sort");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtIsNull() {
+            addCriterion("strategy_dt is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtIsNotNull() {
+            addCriterion("strategy_dt is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtEqualTo(String value) {
+            addCriterion("strategy_dt =", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtNotEqualTo(String value) {
+            addCriterion("strategy_dt <>", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtGreaterThan(String value) {
+            addCriterion("strategy_dt >", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtGreaterThanOrEqualTo(String value) {
+            addCriterion("strategy_dt >=", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtLessThan(String value) {
+            addCriterion("strategy_dt <", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtLessThanOrEqualTo(String value) {
+            addCriterion("strategy_dt <=", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtLike(String value) {
+            addCriterion("strategy_dt like", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtNotLike(String value) {
+            addCriterion("strategy_dt not like", value, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtIn(List<String> values) {
+            addCriterion("strategy_dt in", values, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtNotIn(List<String> values) {
+            addCriterion("strategy_dt not in", values, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtBetween(String value1, String value2) {
+            addCriterion("strategy_dt between", value1, value2, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andStrategyDtNotBetween(String value1, String value2) {
+            addCriterion("strategy_dt not between", value1, value2, "strategyDt");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIsNull() {
+            addCriterion("gh_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIsNotNull() {
+            addCriterion("gh_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdEqualTo(String value) {
+            addCriterion("gh_id =", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotEqualTo(String value) {
+            addCriterion("gh_id <>", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdGreaterThan(String value) {
+            addCriterion("gh_id >", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdGreaterThanOrEqualTo(String value) {
+            addCriterion("gh_id >=", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLessThan(String value) {
+            addCriterion("gh_id <", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLessThanOrEqualTo(String value) {
+            addCriterion("gh_id <=", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLike(String value) {
+            addCriterion("gh_id like", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotLike(String value) {
+            addCriterion("gh_id not like", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIn(List<String> values) {
+            addCriterion("gh_id in", values, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotIn(List<String> values) {
+            addCriterion("gh_id not in", values, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdBetween(String value1, String value2) {
+            addCriterion("gh_id between", value1, value2, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotBetween(String value1, String value2) {
+            addCriterion("gh_id not between", value1, value2, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeIsNull() {
+            addCriterion("msg_type is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeIsNotNull() {
+            addCriterion("msg_type is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeEqualTo(Integer value) {
+            addCriterion("msg_type =", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeNotEqualTo(Integer value) {
+            addCriterion("msg_type <>", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeGreaterThan(Integer value) {
+            addCriterion("msg_type >", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeGreaterThanOrEqualTo(Integer value) {
+            addCriterion("msg_type >=", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeLessThan(Integer value) {
+            addCriterion("msg_type <", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeLessThanOrEqualTo(Integer value) {
+            addCriterion("msg_type <=", value, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeIn(List<Integer> values) {
+            addCriterion("msg_type in", values, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeNotIn(List<Integer> values) {
+            addCriterion("msg_type not in", values, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeBetween(Integer value1, Integer value2) {
+            addCriterion("msg_type between", value1, value2, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andMsgTypeNotBetween(Integer value1, Integer value2) {
+            addCriterion("msg_type not between", value1, value2, "msgType");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIsNull() {
+            addCriterion("title is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIsNotNull() {
+            addCriterion("title is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleEqualTo(String value) {
+            addCriterion("title =", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotEqualTo(String value) {
+            addCriterion("title <>", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleGreaterThan(String value) {
+            addCriterion("title >", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleGreaterThanOrEqualTo(String value) {
+            addCriterion("title >=", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLessThan(String value) {
+            addCriterion("title <", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLessThanOrEqualTo(String value) {
+            addCriterion("title <=", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleLike(String value) {
+            addCriterion("title like", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotLike(String value) {
+            addCriterion("title not like", value, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIn(List<String> values) {
+            addCriterion("title in", values, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotIn(List<String> values) {
+            addCriterion("title not in", values, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleBetween(String value1, String value2) {
+            addCriterion("title between", value1, value2, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleNotBetween(String value1, String value2) {
+            addCriterion("title not between", value1, value2, "title");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIsNull() {
+            addCriterion("cover_url is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIsNotNull() {
+            addCriterion("cover_url is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlEqualTo(String value) {
+            addCriterion("cover_url =", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotEqualTo(String value) {
+            addCriterion("cover_url <>", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlGreaterThan(String value) {
+            addCriterion("cover_url >", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlGreaterThanOrEqualTo(String value) {
+            addCriterion("cover_url >=", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLessThan(String value) {
+            addCriterion("cover_url <", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLessThanOrEqualTo(String value) {
+            addCriterion("cover_url <=", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLike(String value) {
+            addCriterion("cover_url like", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotLike(String value) {
+            addCriterion("cover_url not like", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIn(List<String> values) {
+            addCriterion("cover_url in", values, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotIn(List<String> values) {
+            addCriterion("cover_url not in", values, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlBetween(String value1, String value2) {
+            addCriterion("cover_url between", value1, value2, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotBetween(String value1, String value2) {
+            addCriterion("cover_url not between", value1, value2, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdIsNull() {
+            addCriterion("mini_app_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdIsNotNull() {
+            addCriterion("mini_app_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdEqualTo(String value) {
+            addCriterion("mini_app_id =", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdNotEqualTo(String value) {
+            addCriterion("mini_app_id <>", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdGreaterThan(String value) {
+            addCriterion("mini_app_id >", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdGreaterThanOrEqualTo(String value) {
+            addCriterion("mini_app_id >=", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdLessThan(String value) {
+            addCriterion("mini_app_id <", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdLessThanOrEqualTo(String value) {
+            addCriterion("mini_app_id <=", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdLike(String value) {
+            addCriterion("mini_app_id like", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdNotLike(String value) {
+            addCriterion("mini_app_id not like", value, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdIn(List<String> values) {
+            addCriterion("mini_app_id in", values, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdNotIn(List<String> values) {
+            addCriterion("mini_app_id not in", values, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdBetween(String value1, String value2) {
+            addCriterion("mini_app_id between", value1, value2, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniAppIdNotBetween(String value1, String value2) {
+            addCriterion("mini_app_id not between", value1, value2, "miniAppId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathIsNull() {
+            addCriterion("mini_page_path is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathIsNotNull() {
+            addCriterion("mini_page_path is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathEqualTo(String value) {
+            addCriterion("mini_page_path =", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathNotEqualTo(String value) {
+            addCriterion("mini_page_path <>", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathGreaterThan(String value) {
+            addCriterion("mini_page_path >", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathGreaterThanOrEqualTo(String value) {
+            addCriterion("mini_page_path >=", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathLessThan(String value) {
+            addCriterion("mini_page_path <", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathLessThanOrEqualTo(String value) {
+            addCriterion("mini_page_path <=", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathLike(String value) {
+            addCriterion("mini_page_path like", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathNotLike(String value) {
+            addCriterion("mini_page_path not like", value, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathIn(List<String> values) {
+            addCriterion("mini_page_path in", values, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathNotIn(List<String> values) {
+            addCriterion("mini_page_path not in", values, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathBetween(String value1, String value2) {
+            addCriterion("mini_page_path between", value1, value2, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniPagePathNotBetween(String value1, String value2) {
+            addCriterion("mini_page_path not between", value1, value2, "miniPagePath");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdIsNull() {
+            addCriterion("mini_video_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdIsNotNull() {
+            addCriterion("mini_video_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdEqualTo(Long value) {
+            addCriterion("mini_video_id =", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdNotEqualTo(Long value) {
+            addCriterion("mini_video_id <>", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdGreaterThan(Long value) {
+            addCriterion("mini_video_id >", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("mini_video_id >=", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdLessThan(Long value) {
+            addCriterion("mini_video_id <", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdLessThanOrEqualTo(Long value) {
+            addCriterion("mini_video_id <=", value, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdIn(List<Long> values) {
+            addCriterion("mini_video_id in", values, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdNotIn(List<Long> values) {
+            addCriterion("mini_video_id not in", values, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdBetween(Long value1, Long value2) {
+            addCriterion("mini_video_id between", value1, value2, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMiniVideoIdNotBetween(Long value1, Long value2) {
+            addCriterion("mini_video_id not between", value1, value2, "miniVideoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdIsNull() {
+            addCriterion("page_path_url_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdIsNotNull() {
+            addCriterion("page_path_url_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdEqualTo(Long value) {
+            addCriterion("page_path_url_id =", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdNotEqualTo(Long value) {
+            addCriterion("page_path_url_id <>", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdGreaterThan(Long value) {
+            addCriterion("page_path_url_id >", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("page_path_url_id >=", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdLessThan(Long value) {
+            addCriterion("page_path_url_id <", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdLessThanOrEqualTo(Long value) {
+            addCriterion("page_path_url_id <=", value, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdIn(List<Long> values) {
+            addCriterion("page_path_url_id in", values, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdNotIn(List<Long> values) {
+            addCriterion("page_path_url_id not in", values, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdBetween(Long value1, Long value2) {
+            addCriterion("page_path_url_id between", value1, value2, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPagePathUrlIdNotBetween(Long value1, Long value2) {
+            addCriterion("page_path_url_id not between", value1, value2, "pagePathUrlId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdIsNull() {
+            addCriterion("news_publish_content_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdIsNotNull() {
+            addCriterion("news_publish_content_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdEqualTo(String value) {
+            addCriterion("news_publish_content_id =", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdNotEqualTo(String value) {
+            addCriterion("news_publish_content_id <>", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdGreaterThan(String value) {
+            addCriterion("news_publish_content_id >", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdGreaterThanOrEqualTo(String value) {
+            addCriterion("news_publish_content_id >=", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdLessThan(String value) {
+            addCriterion("news_publish_content_id <", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdLessThanOrEqualTo(String value) {
+            addCriterion("news_publish_content_id <=", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdLike(String value) {
+            addCriterion("news_publish_content_id like", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdNotLike(String value) {
+            addCriterion("news_publish_content_id not like", value, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdIn(List<String> values) {
+            addCriterion("news_publish_content_id in", values, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdNotIn(List<String> values) {
+            addCriterion("news_publish_content_id not in", values, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdBetween(String value1, String value2) {
+            addCriterion("news_publish_content_id between", value1, value2, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNewsPublishContentIdNotBetween(String value1, String value2) {
+            addCriterion("news_publish_content_id not between", value1, value2, "newsPublishContentId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdIsNull() {
+            addCriterion("plan_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdIsNotNull() {
+            addCriterion("plan_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdEqualTo(String value) {
+            addCriterion("plan_id =", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdNotEqualTo(String value) {
+            addCriterion("plan_id <>", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdGreaterThan(String value) {
+            addCriterion("plan_id >", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdGreaterThanOrEqualTo(String value) {
+            addCriterion("plan_id >=", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdLessThan(String value) {
+            addCriterion("plan_id <", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdLessThanOrEqualTo(String value) {
+            addCriterion("plan_id <=", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdLike(String value) {
+            addCriterion("plan_id like", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdNotLike(String value) {
+            addCriterion("plan_id not like", value, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdIn(List<String> values) {
+            addCriterion("plan_id in", values, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdNotIn(List<String> values) {
+            addCriterion("plan_id not in", values, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdBetween(String value1, String value2) {
+            addCriterion("plan_id between", value1, value2, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPlanIdNotBetween(String value1, String value2) {
+            addCriterion("plan_id not between", value1, value2, "planId");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteIsNull() {
+            addCriterion("is_delete is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteIsNotNull() {
+            addCriterion("is_delete is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteEqualTo(Integer value) {
+            addCriterion("is_delete =", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotEqualTo(Integer value) {
+            addCriterion("is_delete <>", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteGreaterThan(Integer value) {
+            addCriterion("is_delete >", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteGreaterThanOrEqualTo(Integer value) {
+            addCriterion("is_delete >=", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteLessThan(Integer value) {
+            addCriterion("is_delete <", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteLessThanOrEqualTo(Integer value) {
+            addCriterion("is_delete <=", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteIn(List<Integer> values) {
+            addCriterion("is_delete in", values, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotIn(List<Integer> values) {
+            addCriterion("is_delete not in", values, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteBetween(Integer value1, Integer value2) {
+            addCriterion("is_delete between", value1, value2, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotBetween(Integer value1, Integer value2) {
+            addCriterion("is_delete not between", value1, value2, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNull() {
+            addCriterion("create_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNotNull() {
+            addCriterion("create_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeEqualTo(Date value) {
+            addCriterion("create_time =", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotEqualTo(Date value) {
+            addCriterion("create_time <>", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThan(Date value) {
+            addCriterion("create_time >", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThanOrEqualTo(Date value) {
+            addCriterion("create_time >=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThan(Date value) {
+            addCriterion("create_time <", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThanOrEqualTo(Date value) {
+            addCriterion("create_time <=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIn(List<Date> values) {
+            addCriterion("create_time in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotIn(List<Date> values) {
+            addCriterion("create_time not in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeBetween(Date value1, Date value2) {
+            addCriterion("create_time between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotBetween(Date value1, Date value2) {
+            addCriterion("create_time not between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNull() {
+            addCriterion("update_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNotNull() {
+            addCriterion("update_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeEqualTo(Date value) {
+            addCriterion("update_time =", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotEqualTo(Date value) {
+            addCriterion("update_time <>", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThan(Date value) {
+            addCriterion("update_time >", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThanOrEqualTo(Date value) {
+            addCriterion("update_time >=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThan(Date value) {
+            addCriterion("update_time <", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThanOrEqualTo(Date value) {
+            addCriterion("update_time <=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIn(List<Date> values) {
+            addCriterion("update_time in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotIn(List<Date> values) {
+            addCriterion("update_time not in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeBetween(Date value1, Date value2) {
+            addCriterion("update_time between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotBetween(Date value1, Date value2) {
+            addCriterion("update_time not between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+    }
+
+    public static class Criteria extends GeneratedCriteria {
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 33 - 9
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/DataDashboardService.java

@@ -10,15 +10,14 @@ import com.tzld.longarticle.recommend.server.repository.crawler.AccountAvgInfoRe
 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.crawler.PublishSortLogRepository;
-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.entity.crawler.PublishSortLog;
+import com.tzld.longarticle.recommend.server.repository.entity.crawler.*;
+import com.tzld.longarticle.recommend.server.repository.mapper.crawler.CrawlerBaseMapper;
 import com.tzld.longarticle.recommend.server.util.DateUtils;
 import com.tzld.longarticle.recommend.server.util.MapBuilder;
 import com.tzld.longarticle.recommend.server.util.feishu.FeiShu;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.util.Pair;
 import org.springframework.http.*;
@@ -45,6 +44,8 @@ public class DataDashboardService {
     private AccountAvgInfoRepository accountAvgInfoRepository;
     @Autowired
     private PublishSortLogRepository publishSortLogRepository;
+    @Autowired
+    private CrawlerBaseMapper crawlerBaseMapper;
 
     @ApolloJsonValue("${export.account.ghId:[]}")
     private static List<String> ghIdList;
@@ -113,15 +114,15 @@ public class DataDashboardService {
 
         List<Pair<String, String>> styles = Arrays
                 .asList(
-                        Pair.of("P", "0.00%"),
-                        Pair.of("Q", "0.00%"),
                         Pair.of("R", "0.00%"),
                         Pair.of("S", "0.00%"),
                         Pair.of("T", "0.00%"),
                         Pair.of("U", "0.00%"),
-                        Pair.of("AA", "0.00%"),
-                        Pair.of("AB", "0.00%"),
-                        Pair.of("AC", "0.00%")
+                        Pair.of("V", "0.00%"),
+                        Pair.of("W", "0.00%"),
+                        Pair.of("AC", "0.00%"),
+                        Pair.of("AD", "0.00%"),
+                        Pair.of("AE", "0.00%")
                 );
 
         doSendFeishuSheet(dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles);
@@ -132,6 +133,8 @@ public class DataDashboardService {
         List<AccountAvgInfo> accountAvgInfoList = accountAvgInfoRepository.getAllByStatusEquals(1);
         Set<String> ghIds = accountAvgInfoList.stream().map(AccountAvgInfo::getGhId).collect(Collectors.toSet());
         List<Article> articleList = articleRepository.getByGhIdInAndUpdateTimeGreaterThan(ghIds, timestamp);
+        Map<String, Map<String, Map<Integer, Article>>> articleMap = articleList.stream().collect(Collectors.groupingBy(Article::getGhId,
+                Collectors.groupingBy(Article::getAppMsgId, Collectors.toMap(Article::getItemIndex, o -> o))));
 
         Set<String> snList = articleList.stream().map(Article::getWxSn).collect(Collectors.toSet());
         List<ArticleDetailInfo> articleDetailInfoList = articleDetailInfoRepository.getAllByWxSnIn(new ArrayList<>(snList));
@@ -150,6 +153,7 @@ public class DataDashboardService {
             if (CollectionUtils.isEmpty(articleDetailInfos)) {
                 continue;
             }
+            Article firstArticle = articleMap.get(article.getGhId()).get(article.getAppMsgId()).get(1);
             Map<String, String> dateStrategy = sortStrategyMap.get(article.getGhId());
             Date minDate = articleDetailInfos.stream().map(ArticleDetailInfo::getRecallDt).min(Date::compareTo).orElse(new Date());
             int sumfirstLevel = 0;
@@ -166,8 +170,10 @@ public class DataDashboardService {
             }
             Map<String, AccountAvgInfo> accountAvgInfoMap = accountAvgInfoIndexMap.get(article.getGhId());
             AccountAvgInfo avgInfo = null;
+            AccountAvgInfo firstAvgInfo = null;
             if (Objects.nonNull(accountAvgInfoMap)) {
                 avgInfo = accountAvgInfoMap.get(article.getItemIndex().toString());
+                firstAvgInfo = accountAvgInfoMap.get("1");
             }
             String date = DateUtils.timestampToYMDStr(article.getUpdateTime(), "yyyyMMdd");
             NewSortStrategyExport obj = new NewSortStrategyExport();
@@ -184,6 +190,12 @@ public class DataDashboardService {
             obj.setFission1(sumFission1);
             obj.setFission2(sumFission2);
             obj.setWxSn(article.getWxSn());
+            if (Objects.nonNull(firstArticle)) {
+                obj.setFirstViewCount(firstArticle.getShowViewCount());
+            }
+            if (Objects.nonNull(firstAvgInfo)) {
+                obj.setFirstAvgViewCount(firstAvgInfo.getReadAvg());
+            }
             if (Objects.nonNull(dateStrategy)) {
                 obj.setStrategy(dateStrategy.get(date));
             }
@@ -218,6 +230,18 @@ public class DataDashboardService {
         }
         result.sort(Comparator.comparing(NewSortStrategyExport::getDateStr).reversed()
                 .thenComparing(NewSortStrategyExport::getGhId).thenComparing(NewSortStrategyExport::getPosition));
+        if (CollectionUtils.isNotEmpty(result)) {
+            crawlerBaseMapper.deleteByDateStrGreaterThanEqual(dateStr);
+            List<DatastatSortStrategy> saveList = new ArrayList<>();
+            for (NewSortStrategyExport newSortStrategyExport : result) {
+                DatastatSortStrategy item = new DatastatSortStrategy();
+                BeanUtils.copyProperties(newSortStrategyExport, item);
+                saveList.add(item);
+            }
+            for (List<DatastatSortStrategy> saveListPartition : Lists.partition(saveList, 1000)) {
+                crawlerBaseMapper.batchInsertDatastatSortStrategy(saveListPartition);
+            }
+        }
         return result;
     }
 

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

@@ -0,0 +1,61 @@
+package com.tzld.longarticle.recommend.server.service;
+
+import com.tzld.longarticle.recommend.server.common.ThreadPoolFactory;
+import com.tzld.longarticle.recommend.server.remote.WxFetchRemoteService;
+import com.tzld.longarticle.recommend.server.repository.mapper.crawler.ArticleContentLinkMapper;
+import com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink;
+import com.tzld.longarticle.recommend.server.repository.model.ArticleContentLinkExample;
+import com.tzld.longarticle.recommend.server.util.DateUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.math.NumberUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class JobService {
+
+    @Autowired
+    private ArticleContentLinkMapper articleContentLinkMapper;
+    @Autowired
+    private WxFetchRemoteService wxFetchRemoteService;
+
+    private long seconds1d = 60 * 60 * 24 * 1000;
+    private long seconds7d = 7 * seconds1d;
+
+    public void syncViewCount() {
+        ArticleContentLinkExample example = new ArticleContentLinkExample();
+
+
+        LocalDate today = LocalDate.now();
+        // 计算7天前的日期
+        LocalDate dateSevenDaysAgo = today.minusDays(7);
+        // 将日期转换为当天开始的时间(00:00:00)并指定时区
+        ZonedDateTime zonedDateTime = dateSevenDaysAgo.atStartOfDay(ZoneId.systemDefault());
+        // 将ZonedDateTime转换为时间戳(毫秒)
+        long time = zonedDateTime.toInstant().toEpochMilli();
+
+
+        example.createCriteria().andCreateTimeGreaterThanOrEqualTo(time);
+        List<ArticleContentLink> links = articleContentLinkMapper.selectByExample(example);
+        for (ArticleContentLink link : links) {
+            Map<String, String> content = wxFetchRemoteService.getContent(link.getContentLink());
+            link.setTitle(content.getOrDefault("title", ""));
+            link.setViewCount(NumberUtils.toLong(content.getOrDefault("view_count", "0"), 0L));
+            link.setUpdateTime(System.currentTimeMillis());
+
+            articleContentLinkMapper.updateByPrimaryKey(link);
+        }
+
+
+    }
+}

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

@@ -0,0 +1,81 @@
+package com.tzld.longarticle.recommend.server.service;
+
+import com.tzld.longarticle.recommend.server.repository.mapper.crawler.ArticleContentLinkMapper;
+import com.tzld.longarticle.recommend.server.repository.mapper.crawler.ArticleGzhDeveloperMapper;
+import com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink;
+import com.tzld.longarticle.recommend.server.repository.model.ArticleGzhDeveloper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author dyp
+ */
+@Slf4j
+@Service
+public class MessageSendCallbackService {
+
+    @Autowired
+    private ArticleContentLinkMapper articleContentLinkMapper;
+
+    @Autowired
+    private ArticleGzhDeveloperMapper articleGzhDeveloperMapper;
+
+    /**
+     * https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html#_8%E3%80%81%E4%BA%8B%E4%BB%B6%E6%8E%A8%E9%80%81%E7%BE%A4%E5%8F%91%E7%BB%93%E6%9E%9C
+     */
+    public void listenWx(String xmlData) {
+        try {
+            SAXReader saxReader = new SAXReader();
+            Document document = saxReader.read(new StringReader(xmlData));
+            Element root = document.getRootElement();
+
+            String msgType = root.elementText("MsgType");
+            String event = root.elementText("Event");
+            if (!StringUtils.equals("event", msgType)
+                    || !StringUtils.equals("MASSSENDJOBFINISH", event)) {
+                return;
+            }
+
+
+            String gzhId = root.elementText("ToUserName");
+            ArticleGzhDeveloper agd = articleGzhDeveloperMapper.selectByPrimaryKey(gzhId);
+            if (agd == null) {
+                // 不再体系内的账号,不记录链接
+                return;
+            }
+
+
+            long createTime = NumberUtils.toLong(root.elementText("CreateTime"), 0) * 1000;
+
+            Element articleUrlResultEle = root.element("ArticleUrlResult");
+            Element resultListEle = articleUrlResultEle.element("ResultList");
+            List<Element> itemEle = resultListEle.elements("item");
+            List<ArticleContentLink> links = new ArrayList<>();
+            for (Element item : itemEle) {
+                ArticleContentLink link = new ArticleContentLink();
+                link.setGzhId(gzhId);
+                link.setIdx(NumberUtils.toInt(item.elementText("ArticleIdx"), 0));
+                link.setContentLink(item.elementText("ArticleUrl"));
+                link.setCreateTime(createTime);
+                link.setTitle("");
+                link.setUpdateTime(createTime);
+                link.setViewCount(-1L);
+                links.add(link);
+            }
+            articleContentLinkMapper.insertBatch(links);
+        } catch (Exception e) {
+            log.error("listenWx handle error {} ", xmlData, e);
+        }
+    }
+
+}

+ 8 - 16
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/UserManagementService.java

@@ -100,7 +100,6 @@ public class UserManagementService {
         obj.setAppId(appId);
         obj.setGzhId(gzhId);
         articleGzhDeveloperMapper.insert(obj);
-//        log.info("start group gzhId={}", gzhId);
 
 
     }
@@ -153,29 +152,22 @@ public class UserManagementService {
                 param.put(e.getName(), e.getTextTrim());
             }
 
-            String appId = "";
-            String gzhId = "";
-            String openId = "";
+            String gzhId = param.get("ToUserName");
+            String openId = param.get("FromUserName");
+
+            ArticleGzhDeveloper agd = articleGzhDeveloperMapper.selectByPrimaryKey(gzhId);
+            if (agd == null) {
+                // 不再体系内的账号,不记录链接
+                return;
+            }
 
             if (StringUtils.equals("event", param.get("MsgType"))) {
                 String event = param.get("Event");
                 switch (event) {
                     case "subscribe":
-                        appId = param.get("ToUserName");
-                        gzhId = articleGzhDeveloperMapper.selectGzhIdByAppId(appId);
-                        if (StringUtils.isBlank(gzhId)) {
-                            break;
-                        }
-                        openId = param.get("FromUserName");
                         handleSubscribe(gzhId, openId);
                         break;
                     case "unsubscribe":
-                        appId = param.get("ToUserName");
-                        gzhId = articleGzhDeveloperMapper.selectGzhIdByAppId(appId);
-                        if (StringUtils.isBlank(gzhId)) {
-                            break;
-                        }
-                        openId = param.get("FromUserName");
                         handleUnsubscribe(gzhId, openId);
                         break;
                     default:

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

@@ -0,0 +1,31 @@
+package com.tzld.longarticle.recommend.server.service;
+
+import com.tzld.longarticle.recommend.server.common.ThreadPoolFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class WXListenService {
+    @Autowired
+    private UserManagementService userManagementService;
+
+    @Autowired
+    private MessageSendCallbackService messageSendCallbackService;
+
+    public void listenWx(String xmlData) {
+
+        ThreadPoolFactory.defaultPool().submit(() -> {
+            userManagementService.listenWx(xmlData);
+        });
+
+        ThreadPoolFactory.defaultPool().submit(() -> {
+            messageSendCallbackService.listenWx(xmlData);
+        });
+
+    }
+}

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

@@ -51,7 +51,10 @@ public class RankV8Strategy implements RankStrategy {
             item.setScoreMap(scoreMap.get(c.getId()));
             double score;
             if (contentPools[0].equals(item.getContent().getContentPoolType())) {
-                score = item.getScore(HisFissionFansSumRateStrategy.class.getSimpleName());
+                score = item.getScore(SimilarityStrategy.class.getSimpleName())
+                        + item.getScore(CategoryStrategy.class.getSimpleName())
+                        + item.getScore(FlowCtlDecreaseStrategy.class.getSimpleName());
+                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())

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

@@ -36,31 +36,69 @@ public class ViewCountRateStrategy implements ScoreStrategy {
         String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
         List<AccountAvgInfo> avgInfoList = accountAvgInfoRepository.getAllByGhIdEqualsAndStatusEquals(param.getGhId(), 1);
         double avgViewCountFirst = accountIndexAvgViewCountService.getAvgReadCountByDB(avgInfoList, param.getGhId(), 1);
+        double avgViewCountSecond = accountIndexAvgViewCountService.getAvgReadCountByDB(avgInfoList, param.getGhId(), 2);
+        double avgViewCountThird = accountIndexAvgViewCountService.getAvgReadCountByDB(avgInfoList, param.getGhId(), 3);
+        // 缺省头条均值设置为2w,次条为1w
+        if (avgViewCountFirst < 10) {
+            avgViewCountFirst = 20000D;
+            avgViewCountSecond = 10000D;
+            avgViewCountThird = 400D;
+        }
         for (Content content : param.getContents()) {
             for (int i = 0; i < contentPools.length; i++) {
                 if (!contentPools[i].equals(content.getContentPoolType())) {
                     continue;
                 }
                 double avgViewCountPos = accountIndexAvgViewCountService.getAvgReadCountByDB(avgInfoList, param.getGhId(), i + 1);
+                // 缺省头条均值设置为2w,次条为1w
+                if (avgViewCountPos < 10) {
+                    if (i == 0) {
+                        avgViewCountPos = 20000D;
+                    } else if (i == 1) {
+                        avgViewCountPos = 10000D;
+                    } else {
+                        avgViewCountPos = 400D;
+                    }
+                }
                 double showViewCountSum = 0D;
                 double avgViewCountSum = 0D;
                 double showViewCountSumFirst = 0D;
                 double avgViewCountSumFirst = 0D;
                 double showViewCountSumSecond = 0D;
                 double avgViewCountSumSecond = 0D;
+                double maxAvgViewCount = 0D;
                 for (ContentHisPublishArticle hisItem : content.getHisPublishArticleList()) {
                     if (hisItem.isInnerAccount() && Objects.nonNull(hisItem.getViewCount())
                             && hisItem.getViewCount() > 0 && Objects.nonNull(hisItem.getAvgViewCount())
                             && hisItem.getAvgViewCount() > 0) {
+                        maxAvgViewCount = Math.max(maxAvgViewCount, hisItem.getAvgViewCount());
                         if (hisItem.getItemIndex() == 1) {
                             showViewCountSumFirst += hisItem.getViewCount();
                             avgViewCountSumFirst += hisItem.getAvgViewCount();
                         } else if (hisItem.getItemIndex() == 2) {
-                            showViewCountSumSecond += hisItem.getViewCount();
-                            avgViewCountSumSecond += hisItem.getAvgViewCount();
+                            if (Objects.nonNull(hisItem.getFirstViewCount()) &&  hisItem.getFirstViewCount() > 0 &&
+                                    Objects.nonNull(hisItem.getFirstViewCountRate()) && hisItem.getFirstViewCountRate() > 0) {
+                                showViewCountSumSecond += hisItem.getViewCount();
+                                if (hisItem.getFirstViewCountRate() > 1) {
+                                    // 对于头条均值倍数大于1的情况,次条均值线性增加,用于debias;
+                                    // TODO: 对于小于1的情况,是否要减去?
+                                    avgViewCountSumSecond += hisItem.getAvgViewCount() * hisItem.getFirstViewCountRate();
+                                } else {
+                                    avgViewCountSumSecond += hisItem.getAvgViewCount();
+                                }
+                            }
                         } else {
-                            showViewCountSum += hisItem.getViewCount();
-                            avgViewCountSum += hisItem.getAvgViewCount();
+                            if (Objects.nonNull(hisItem.getFirstViewCount()) && hisItem.getFirstViewCount() > 0
+                                    && Objects.nonNull(hisItem.getFirstViewCountRate()) && hisItem.getFirstViewCountRate() > 0) {
+                                showViewCountSum += hisItem.getViewCount();
+                                if (hisItem.getFirstViewCountRate() > 1) {
+                                    // 对于头条均值倍数大于1的情况,次条均值线性增加,用于debias;
+                                    // TODO: 对于小于1的情况,是否要减去?
+                                    avgViewCountSum += hisItem.getAvgViewCount() * hisItem.getFirstViewCountRate();
+                                } else {
+                                    avgViewCountSum += hisItem.getAvgViewCount();
+                                }
+                            }
                         }
                     }
                 }
@@ -70,23 +108,26 @@ public class ViewCountRateStrategy implements ScoreStrategy {
                 if (showViewCountSumFirst > 0) {
                     showViewCountSum = showViewCountSumFirst;
                     avgViewCountSum = avgViewCountSumFirst;
-                    avgViewCountPos = avgViewCountFirst;
                 } else if (showViewCountSumSecond > 0) {
                     showViewCountSum = showViewCountSumSecond;
                     avgViewCountSum = avgViewCountSumSecond;
-                    avgViewCountPos = avgViewCountFirst;
                     // 如果是大号头条,则降权
-                    if (avgViewCountFirst >= 2000 && i == 0) {
-                        minRate = 1.001D;
-                    }
+//                    if (avgViewCountFirst >= 2000 && i == 0) {
+//                        minRate = 1.001D;
+//                    }
                 }
+                // 均值倍数
                 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;
+                    // 最终分数 = 置信度 * 均值倍数
+                    viewCountRateScore = viewCountRateW * viewCountRate;
+//                    viewCountRateScore = (Math.min(viewCountRate, minRate) - 1D) * viewCountRateW;
                 }
                 Score score = new Score();
                 score.setStrategy(this);

+ 22 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/strategy/reply/impl/BuckStrategyV1.java

@@ -14,10 +14,31 @@ public class BuckStrategyV1 implements ReplyStrategyService {
      */
     private static final Integer bucketNum = 10;
 
+    /**
+     * 分桶实验策略,key为策略,arr为对应桶
+     * {"base":[0,1,2,3,4,5],"bucketV1":[6,7,8,9]}
+     */
+    private static final String bucketStrategyConfig = "{\n" +
+            "    \"base\": [\n" +
+            "        0,\n" +
+            "        1,\n" +
+            "        2,\n" +
+            "        3,\n" +
+            "        4,\n" +
+            "        5\n" +
+            "    ],\n" +
+            "    \"bucketV1\": [\n" +
+            "        6,\n" +
+            "        7,\n" +
+            "        8,\n" +
+            "        9\n" +
+            "    ]\n" +
+            "}";
+
     /**
      * 自动回复使用小程序Id
      */
-    private static final String CGI_Id = "gh_1ee2e1b39ccf";
+    private static final String SMALL_APP_Id = "gh_1ee2e1b39ccf";
 
     @Override
     public ReplyBucketData getResult(BucketDataParam bucketDataParam) {

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

@@ -2,7 +2,7 @@ package com.tzld.longarticle.recommend.server.util;
 
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.reflect.TypeToken;
-import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 
@@ -27,7 +27,7 @@ public class JSONUtils {
             return "";
         }
         try {
-            return new Gson().toJson(obj);
+            return new GsonBuilder().disableHtmlEscaping().create().toJson(obj);
         } catch (Exception e) {
             log.error("toJson exception", e);
             return "";

+ 33 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/JobController.java

@@ -0,0 +1,33 @@
+package com.tzld.longarticle.recommend.server.web;
+
+import com.tzld.longarticle.recommend.server.model.Result;
+import com.tzld.longarticle.recommend.server.service.JobService;
+import com.tzld.longarticle.recommend.server.service.UserManagementService;
+import com.tzld.longarticle.recommend.server.service.WXListenService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author dyp
+ */
+@RestController
+@Slf4j
+@RequestMapping("/job")
+public class JobController {
+    @Autowired
+    private JobService jobService;
+
+
+    @RequestMapping("/syncViewCount")
+    public String syncViewCount() {
+        jobService.syncViewCount();
+        return "success";
+    }
+
+}

+ 6 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/UserManagementController.java

@@ -2,6 +2,7 @@ package com.tzld.longarticle.recommend.server.web;
 
 import com.tzld.longarticle.recommend.server.model.Result;
 import com.tzld.longarticle.recommend.server.service.UserManagementService;
+import com.tzld.longarticle.recommend.server.service.WXListenService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -21,12 +22,15 @@ public class UserManagementController {
     @Autowired
     private UserManagementService userManagementService;
 
+    @Autowired
+    private WXListenService wxListenService;
+
 
     @RequestMapping("/addGZH")
     public String addGZH(@RequestParam(name = "gzhId") String gzhId,
                          @RequestParam(name = "appId") String appId,
                          @RequestParam(name = "groupNum") int groupNum) {
-        userManagementService.addGZH(gzhId,appId, groupNum);
+        userManagementService.addGZH(gzhId, appId, groupNum);
         return "success";
     }
 
@@ -43,7 +47,7 @@ public class UserManagementController {
      */
     @RequestMapping("/listenWx")
     public String listenWx(@RequestBody String xmlData) {
-        userManagementService.listenWx(xmlData);
+        wxListenService.listenWx(xmlData);
         return "success";
     }
 

+ 41 - 0
long-article-recommend-service/src/main/resources/generatorCgiConfig.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE generatorConfiguration
+        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
+        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
+
+<generatorConfiguration>
+    <context id="simple" targetRuntime="MyBatis3">
+        <commentGenerator>
+            <property name="suppressAllComments" value="true"/>
+        </commentGenerator>
+        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
+                        connectionURL="jdbc:mysql://rm-bp1159bu17li9hi94.mysql.rds.aliyuncs.com:3306/piaoquan-crawler?useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false"
+                        userId="crawler"
+                        password="crawler123456@">
+        </jdbcConnection>
+
+        <javaTypeResolver >
+            <property name="forceBigDecimals" value="false" />
+        </javaTypeResolver>
+
+        <javaModelGenerator targetPackage="com.tzld.longarticle.recommend.server.repository.model" targetProject="D:\taizi\code\long-article-recommend\long-article-recommend-service\src\main\java">
+            <property name="enableSubPackages" value="true" />
+            <property name="trimStrings" value="true" />
+        </javaModelGenerator>
+
+        <sqlMapGenerator targetPackage="crawler"  targetProject="D:\taizi\code\long-article-recommend\long-article-recommend-service\src\main\resources\mapper">
+            <property name="enableSubPackages" value="true" />
+        </sqlMapGenerator>
+
+        <javaClientGenerator type="XMLMAPPER"
+                             targetPackage="com.tzld.longarticle.recommend.server.repository.mapper.crawler"
+                             targetProject="D:\taizi\code\long-article-recommend\long-article-recommend-service\src\main\java">
+            <property name="enableSubPackages" value="true" />
+        </javaClientGenerator>
+
+        <table schema="mybatis" tableName="cgi_reply_bucket_data" >
+            <generatedKey column="id" sqlStatement="mysql" identity="true" />
+        </table>
+
+    </context>
+</generatorConfiguration>

+ 1 - 1
long-article-recommend-service/src/main/resources/generatorConfig.xml

@@ -33,7 +33,7 @@
             <property name="enableSubPackages" value="true" />
         </javaClientGenerator>
 
-        <table schema="mybatis" tableName="article_gzh_developer" >
+        <table schema="mybatis" tableName="article_content_link" >
             <generatedKey column="id" sqlStatement="mysql" identity="true" />
         </table>
 

+ 267 - 0
long-article-recommend-service/src/main/resources/mapper/crawler/ArticleContentLinkMapper.xml

@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tzld.longarticle.recommend.server.repository.mapper.crawler.ArticleContentLinkMapper">
+  <resultMap id="BaseResultMap" type="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink">
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="gzh_id" jdbcType="VARCHAR" property="gzhId" />
+    <result column="idx" jdbcType="INTEGER" property="idx" />
+    <result column="content_link" jdbcType="VARCHAR" property="contentLink" />
+    <result column="create_time" jdbcType="BIGINT" property="createTime" />
+    <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="view_count" jdbcType="BIGINT" property="viewCount" />
+    <result column="update_time" jdbcType="BIGINT" property="updateTime" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, gzh_id, idx, content_link, create_time, title, view_count, update_time
+  </sql>
+  <select id="selectByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLinkExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from article_content_link
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from article_content_link
+    where id = #{id,jdbcType=BIGINT}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+    delete from article_content_link
+    where id = #{id,jdbcType=BIGINT}
+  </delete>
+  <delete id="deleteByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLinkExample">
+    delete from article_content_link
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink">
+    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
+      SELECT LAST_INSERT_ID()
+    </selectKey>
+    insert into article_content_link (gzh_id, idx, content_link, 
+      create_time, title, view_count, 
+      update_time)
+    values (#{gzhId,jdbcType=VARCHAR}, #{idx,jdbcType=INTEGER}, #{contentLink,jdbcType=VARCHAR}, 
+      #{createTime,jdbcType=BIGINT}, #{title,jdbcType=VARCHAR}, #{viewCount,jdbcType=BIGINT}, 
+      #{updateTime,jdbcType=BIGINT})
+  </insert>
+  <insert id="insertSelective" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink">
+    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
+      SELECT LAST_INSERT_ID()
+    </selectKey>
+    insert into article_content_link
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="gzhId != null">
+        gzh_id,
+      </if>
+      <if test="idx != null">
+        idx,
+      </if>
+      <if test="contentLink != null">
+        content_link,
+      </if>
+      <if test="createTime != null">
+        create_time,
+      </if>
+      <if test="title != null">
+        title,
+      </if>
+      <if test="viewCount != null">
+        view_count,
+      </if>
+      <if test="updateTime != null">
+        update_time,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="gzhId != null">
+        #{gzhId,jdbcType=VARCHAR},
+      </if>
+      <if test="idx != null">
+        #{idx,jdbcType=INTEGER},
+      </if>
+      <if test="contentLink != null">
+        #{contentLink,jdbcType=VARCHAR},
+      </if>
+      <if test="createTime != null">
+        #{createTime,jdbcType=BIGINT},
+      </if>
+      <if test="title != null">
+        #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="viewCount != null">
+        #{viewCount,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        #{updateTime,jdbcType=BIGINT},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLinkExample" resultType="java.lang.Long">
+    select count(*) from article_content_link
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update article_content_link
+    <set>
+      <if test="row.id != null">
+        id = #{row.id,jdbcType=BIGINT},
+      </if>
+      <if test="row.gzhId != null">
+        gzh_id = #{row.gzhId,jdbcType=VARCHAR},
+      </if>
+      <if test="row.idx != null">
+        idx = #{row.idx,jdbcType=INTEGER},
+      </if>
+      <if test="row.contentLink != null">
+        content_link = #{row.contentLink,jdbcType=VARCHAR},
+      </if>
+      <if test="row.createTime != null">
+        create_time = #{row.createTime,jdbcType=BIGINT},
+      </if>
+      <if test="row.title != null">
+        title = #{row.title,jdbcType=VARCHAR},
+      </if>
+      <if test="row.viewCount != null">
+        view_count = #{row.viewCount,jdbcType=BIGINT},
+      </if>
+      <if test="row.updateTime != null">
+        update_time = #{row.updateTime,jdbcType=BIGINT},
+      </if>
+    </set>
+    <if test="example != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update article_content_link
+    set id = #{row.id,jdbcType=BIGINT},
+      gzh_id = #{row.gzhId,jdbcType=VARCHAR},
+      idx = #{row.idx,jdbcType=INTEGER},
+      content_link = #{row.contentLink,jdbcType=VARCHAR},
+      create_time = #{row.createTime,jdbcType=BIGINT},
+      title = #{row.title,jdbcType=VARCHAR},
+      view_count = #{row.viewCount,jdbcType=BIGINT},
+      update_time = #{row.updateTime,jdbcType=BIGINT}
+    <if test="example != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink">
+    update article_content_link
+    <set>
+      <if test="gzhId != null">
+        gzh_id = #{gzhId,jdbcType=VARCHAR},
+      </if>
+      <if test="idx != null">
+        idx = #{idx,jdbcType=INTEGER},
+      </if>
+      <if test="contentLink != null">
+        content_link = #{contentLink,jdbcType=VARCHAR},
+      </if>
+      <if test="createTime != null">
+        create_time = #{createTime,jdbcType=BIGINT},
+      </if>
+      <if test="title != null">
+        title = #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="viewCount != null">
+        view_count = #{viewCount,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        update_time = #{updateTime,jdbcType=BIGINT},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.tzld.longarticle.recommend.server.repository.model.ArticleContentLink">
+    update article_content_link
+    set gzh_id = #{gzhId,jdbcType=VARCHAR},
+      idx = #{idx,jdbcType=INTEGER},
+      content_link = #{contentLink,jdbcType=VARCHAR},
+      create_time = #{createTime,jdbcType=BIGINT},
+      title = #{title,jdbcType=VARCHAR},
+      view_count = #{viewCount,jdbcType=BIGINT},
+      update_time = #{updateTime,jdbcType=BIGINT}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+
+  <insert id="insertBatch" parameterType="list">
+    INSERT INTO article_content_link (gzh_id, idx, content_link, create_time, title, view_count, update_time)
+    VALUES
+    <foreach collection="list" item="item" separator=",">
+      (#{item.gzhId}, #{item.idx}, #{item.contentLink}, #{item.createTime}, #{item.title}, #{item.viewCount},
+      #{item.updateTime})
+    </foreach>
+  </insert>
+</mapper>

+ 401 - 0
long-article-recommend-service/src/main/resources/mapper/crawler/CgiReplyBucketDataMapper.xml

@@ -0,0 +1,401 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tzld.longarticle.recommend.server.repository.mapper.crawler.CgiReplyBucketDataMapper">
+  <resultMap id="BaseResultMap" type="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData">
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="strategy" jdbcType="VARCHAR" property="strategy" />
+    <result column="sort" jdbcType="INTEGER" property="sort" />
+    <result column="strategy_dt" jdbcType="VARCHAR" property="strategyDt" />
+    <result column="gh_id" jdbcType="VARCHAR" property="ghId" />
+    <result column="msg_type" jdbcType="INTEGER" property="msgType" />
+    <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="cover_url" jdbcType="VARCHAR" property="coverUrl" />
+    <result column="mini_app_id" jdbcType="VARCHAR" property="miniAppId" />
+    <result column="mini_page_path" jdbcType="VARCHAR" property="miniPagePath" />
+    <result column="mini_video_id" jdbcType="BIGINT" property="miniVideoId" />
+    <result column="page_path_url_id" jdbcType="BIGINT" property="pagePathUrlId" />
+    <result column="news_publish_content_id" jdbcType="VARCHAR" property="newsPublishContentId" />
+    <result column="plan_id" jdbcType="VARCHAR" property="planId" />
+    <result column="is_delete" jdbcType="INTEGER" property="isDelete" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, strategy, sort, strategy_dt, gh_id, msg_type, title, cover_url, mini_app_id, 
+    mini_page_path, mini_video_id, page_path_url_id, news_publish_content_id, plan_id, 
+    is_delete, create_time, update_time
+  </sql>
+  <select id="selectByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketDataExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from cgi_reply_bucket_data
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from cgi_reply_bucket_data
+    where id = #{id,jdbcType=BIGINT}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+    delete from cgi_reply_bucket_data
+    where id = #{id,jdbcType=BIGINT}
+  </delete>
+  <delete id="deleteByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketDataExample">
+    delete from cgi_reply_bucket_data
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData">
+    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
+      SELECT LAST_INSERT_ID()
+    </selectKey>
+    insert into cgi_reply_bucket_data (strategy, sort, strategy_dt, 
+      gh_id, msg_type, title, 
+      cover_url, mini_app_id, mini_page_path, 
+      mini_video_id, page_path_url_id, news_publish_content_id, 
+      plan_id, is_delete, create_time, 
+      update_time)
+    values (#{strategy,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}, #{strategyDt,jdbcType=VARCHAR}, 
+      #{ghId,jdbcType=VARCHAR}, #{msgType,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, 
+      #{coverUrl,jdbcType=VARCHAR}, #{miniAppId,jdbcType=VARCHAR}, #{miniPagePath,jdbcType=VARCHAR}, 
+      #{miniVideoId,jdbcType=BIGINT}, #{pagePathUrlId,jdbcType=BIGINT}, #{newsPublishContentId,jdbcType=VARCHAR}, 
+      #{planId,jdbcType=VARCHAR}, #{isDelete,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, 
+      #{updateTime,jdbcType=TIMESTAMP})
+  </insert>
+  <insert id="insertSelective" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData">
+    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
+      SELECT LAST_INSERT_ID()
+    </selectKey>
+    insert into cgi_reply_bucket_data
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="strategy != null">
+        strategy,
+      </if>
+      <if test="sort != null">
+        sort,
+      </if>
+      <if test="strategyDt != null">
+        strategy_dt,
+      </if>
+      <if test="ghId != null">
+        gh_id,
+      </if>
+      <if test="msgType != null">
+        msg_type,
+      </if>
+      <if test="title != null">
+        title,
+      </if>
+      <if test="coverUrl != null">
+        cover_url,
+      </if>
+      <if test="miniAppId != null">
+        mini_app_id,
+      </if>
+      <if test="miniPagePath != null">
+        mini_page_path,
+      </if>
+      <if test="miniVideoId != null">
+        mini_video_id,
+      </if>
+      <if test="pagePathUrlId != null">
+        page_path_url_id,
+      </if>
+      <if test="newsPublishContentId != null">
+        news_publish_content_id,
+      </if>
+      <if test="planId != null">
+        plan_id,
+      </if>
+      <if test="isDelete != null">
+        is_delete,
+      </if>
+      <if test="createTime != null">
+        create_time,
+      </if>
+      <if test="updateTime != null">
+        update_time,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="strategy != null">
+        #{strategy,jdbcType=VARCHAR},
+      </if>
+      <if test="sort != null">
+        #{sort,jdbcType=INTEGER},
+      </if>
+      <if test="strategyDt != null">
+        #{strategyDt,jdbcType=VARCHAR},
+      </if>
+      <if test="ghId != null">
+        #{ghId,jdbcType=VARCHAR},
+      </if>
+      <if test="msgType != null">
+        #{msgType,jdbcType=INTEGER},
+      </if>
+      <if test="title != null">
+        #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="coverUrl != null">
+        #{coverUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="miniAppId != null">
+        #{miniAppId,jdbcType=VARCHAR},
+      </if>
+      <if test="miniPagePath != null">
+        #{miniPagePath,jdbcType=VARCHAR},
+      </if>
+      <if test="miniVideoId != null">
+        #{miniVideoId,jdbcType=BIGINT},
+      </if>
+      <if test="pagePathUrlId != null">
+        #{pagePathUrlId,jdbcType=BIGINT},
+      </if>
+      <if test="newsPublishContentId != null">
+        #{newsPublishContentId,jdbcType=VARCHAR},
+      </if>
+      <if test="planId != null">
+        #{planId,jdbcType=VARCHAR},
+      </if>
+      <if test="isDelete != null">
+        #{isDelete,jdbcType=INTEGER},
+      </if>
+      <if test="createTime != null">
+        #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updateTime != null">
+        #{updateTime,jdbcType=TIMESTAMP},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketDataExample" resultType="java.lang.Long">
+    select count(*) from cgi_reply_bucket_data
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update cgi_reply_bucket_data
+    <set>
+      <if test="row.id != null">
+        id = #{row.id,jdbcType=BIGINT},
+      </if>
+      <if test="row.strategy != null">
+        strategy = #{row.strategy,jdbcType=VARCHAR},
+      </if>
+      <if test="row.sort != null">
+        sort = #{row.sort,jdbcType=INTEGER},
+      </if>
+      <if test="row.strategyDt != null">
+        strategy_dt = #{row.strategyDt,jdbcType=VARCHAR},
+      </if>
+      <if test="row.ghId != null">
+        gh_id = #{row.ghId,jdbcType=VARCHAR},
+      </if>
+      <if test="row.msgType != null">
+        msg_type = #{row.msgType,jdbcType=INTEGER},
+      </if>
+      <if test="row.title != null">
+        title = #{row.title,jdbcType=VARCHAR},
+      </if>
+      <if test="row.coverUrl != null">
+        cover_url = #{row.coverUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="row.miniAppId != null">
+        mini_app_id = #{row.miniAppId,jdbcType=VARCHAR},
+      </if>
+      <if test="row.miniPagePath != null">
+        mini_page_path = #{row.miniPagePath,jdbcType=VARCHAR},
+      </if>
+      <if test="row.miniVideoId != null">
+        mini_video_id = #{row.miniVideoId,jdbcType=BIGINT},
+      </if>
+      <if test="row.pagePathUrlId != null">
+        page_path_url_id = #{row.pagePathUrlId,jdbcType=BIGINT},
+      </if>
+      <if test="row.newsPublishContentId != null">
+        news_publish_content_id = #{row.newsPublishContentId,jdbcType=VARCHAR},
+      </if>
+      <if test="row.planId != null">
+        plan_id = #{row.planId,jdbcType=VARCHAR},
+      </if>
+      <if test="row.isDelete != null">
+        is_delete = #{row.isDelete,jdbcType=INTEGER},
+      </if>
+      <if test="row.createTime != null">
+        create_time = #{row.createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="row.updateTime != null">
+        update_time = #{row.updateTime,jdbcType=TIMESTAMP},
+      </if>
+    </set>
+    <if test="example != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update cgi_reply_bucket_data
+    set id = #{row.id,jdbcType=BIGINT},
+      strategy = #{row.strategy,jdbcType=VARCHAR},
+      sort = #{row.sort,jdbcType=INTEGER},
+      strategy_dt = #{row.strategyDt,jdbcType=VARCHAR},
+      gh_id = #{row.ghId,jdbcType=VARCHAR},
+      msg_type = #{row.msgType,jdbcType=INTEGER},
+      title = #{row.title,jdbcType=VARCHAR},
+      cover_url = #{row.coverUrl,jdbcType=VARCHAR},
+      mini_app_id = #{row.miniAppId,jdbcType=VARCHAR},
+      mini_page_path = #{row.miniPagePath,jdbcType=VARCHAR},
+      mini_video_id = #{row.miniVideoId,jdbcType=BIGINT},
+      page_path_url_id = #{row.pagePathUrlId,jdbcType=BIGINT},
+      news_publish_content_id = #{row.newsPublishContentId,jdbcType=VARCHAR},
+      plan_id = #{row.planId,jdbcType=VARCHAR},
+      is_delete = #{row.isDelete,jdbcType=INTEGER},
+      create_time = #{row.createTime,jdbcType=TIMESTAMP},
+      update_time = #{row.updateTime,jdbcType=TIMESTAMP}
+    <if test="example != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData">
+    update cgi_reply_bucket_data
+    <set>
+      <if test="strategy != null">
+        strategy = #{strategy,jdbcType=VARCHAR},
+      </if>
+      <if test="sort != null">
+        sort = #{sort,jdbcType=INTEGER},
+      </if>
+      <if test="strategyDt != null">
+        strategy_dt = #{strategyDt,jdbcType=VARCHAR},
+      </if>
+      <if test="ghId != null">
+        gh_id = #{ghId,jdbcType=VARCHAR},
+      </if>
+      <if test="msgType != null">
+        msg_type = #{msgType,jdbcType=INTEGER},
+      </if>
+      <if test="title != null">
+        title = #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="coverUrl != null">
+        cover_url = #{coverUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="miniAppId != null">
+        mini_app_id = #{miniAppId,jdbcType=VARCHAR},
+      </if>
+      <if test="miniPagePath != null">
+        mini_page_path = #{miniPagePath,jdbcType=VARCHAR},
+      </if>
+      <if test="miniVideoId != null">
+        mini_video_id = #{miniVideoId,jdbcType=BIGINT},
+      </if>
+      <if test="pagePathUrlId != null">
+        page_path_url_id = #{pagePathUrlId,jdbcType=BIGINT},
+      </if>
+      <if test="newsPublishContentId != null">
+        news_publish_content_id = #{newsPublishContentId,jdbcType=VARCHAR},
+      </if>
+      <if test="planId != null">
+        plan_id = #{planId,jdbcType=VARCHAR},
+      </if>
+      <if test="isDelete != null">
+        is_delete = #{isDelete,jdbcType=INTEGER},
+      </if>
+      <if test="createTime != null">
+        create_time = #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updateTime != null">
+        update_time = #{updateTime,jdbcType=TIMESTAMP},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.tzld.longarticle.recommend.server.repository.model.CgiReplyBucketData">
+    update cgi_reply_bucket_data
+    set strategy = #{strategy,jdbcType=VARCHAR},
+      sort = #{sort,jdbcType=INTEGER},
+      strategy_dt = #{strategyDt,jdbcType=VARCHAR},
+      gh_id = #{ghId,jdbcType=VARCHAR},
+      msg_type = #{msgType,jdbcType=INTEGER},
+      title = #{title,jdbcType=VARCHAR},
+      cover_url = #{coverUrl,jdbcType=VARCHAR},
+      mini_app_id = #{miniAppId,jdbcType=VARCHAR},
+      mini_page_path = #{miniPagePath,jdbcType=VARCHAR},
+      mini_video_id = #{miniVideoId,jdbcType=BIGINT},
+      page_path_url_id = #{pagePathUrlId,jdbcType=BIGINT},
+      news_publish_content_id = #{newsPublishContentId,jdbcType=VARCHAR},
+      plan_id = #{planId,jdbcType=VARCHAR},
+      is_delete = #{isDelete,jdbcType=INTEGER},
+      create_time = #{createTime,jdbcType=TIMESTAMP},
+      update_time = #{updateTime,jdbcType=TIMESTAMP}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+</mapper>

+ 22 - 0
long-article-recommend-service/src/main/resources/mapper/crawler/CrawlerBaseMapper.xml

@@ -2,5 +2,27 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.tzld.longarticle.recommend.server.repository.mapper.crawler.CrawlerBaseMapper">
 
+    <delete id="deleteByDateStrGreaterThanEqual">
+        delete from datastat_sort_strategy where date_str >= #{dateStr}
+    </delete>
 
+    <insert id="batchInsertDatastatSortStrategy">
+        INSERT INTO datastat_sort_strategy
+        (date_str, publish_time, account_mode, account_source, account_type, account_status, account_name, strategy,
+         fans, view_count, avg_view_count, first_view_count, first_avg_view_count, first_level, fission0, fission1,
+         fission2, read_rate, read_fans_rate, first_read_rate, fission0_first_rate, fission1_fission0_rate,
+         fission0_read_avg_rate, position, gh_id, title, link, wx_sn, fission0_read_avg_100_rate,
+         fission0_read_avg_500_rate, fission0_read_avg_1000_rate)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.dateStr}, #{item.publishTime}, #{item.accountMode}, #{item.accountSource}, #{item.accountType},
+             #{item.accountStatus}, #{item.accountName}, #{item.strategy}, #{item.fans}, #{item.viewCount},
+             #{item.avgViewCount}, #{item.firstViewCount}, #{item.firstAvgViewCount}, #{item.firstLevel},
+             #{item.fission0}, #{item.fission1}, #{item.fission2}, #{item.readRate}, #{item.readFansRate},
+             #{item.firstReadRate}, #{item.fission0FirstRate}, #{item.fission1Fission0Rate},
+             #{item.fission0ReadAvgRate}, #{item.position}, #{item.ghId}, #{item.title}, #{item.link},
+             #{item.wxSn}, #{item.fission0ReadAvg100Rate}, #{item.fission0ReadAvg500Rate},
+             #{item.fission0ReadAvg1000Rate})
+        </foreach>
+    </insert>
 </mapper>

+ 67 - 67
long-article-recommend-service/src/test/java/com/tzld/longarticle/recommend/server/RecommendTest.java

@@ -35,72 +35,72 @@ public class RecommendTest {
     @Resource
     private AccountAvgInfoRepository accountAvgInfoRepository;
 
-    @Test
-    void recall() {
-        RecallParam param = new RecallParam();
-        param.setAccountId("20231213123536190184852");
-        param.setPlanId("20240718181730864154902");
-        RecallResult recallResult = recallService.recall(param);
-        System.out.println(JSONObject.toJSONString(recallResult));
-    }
-
-    @Test
-    void exportData() {
-        Set<String> ghIds = new HashSet<>(Arrays.asList("gh_adca24a8f429", "gh_e0eb490115f5", "gh_51e4ad40466d", "gh_95ed5ecf9363"));
-        List<Article> articleList = articleRepository.getByGhIdInAndUpdateTimeGreaterThan(ghIds, 1722441600L);
-
-        Map<String, Map<Integer, List<Article>>> map = articleList.stream()
-                .collect(Collectors.groupingBy(Article::getTitle, Collectors.groupingBy(Article::getItemIndex)));
-        Set<String> snList = articleList.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));
-
-        List<AccountAvgInfo> accountAvgInfoList = accountAvgInfoRepository.getAllByGhIdInAndStatusEquals(ghIds, 1);
-        Map<String, Map<String, AccountAvgInfo>> accountAvgInfoIndexMap = accountAvgInfoList.stream().collect(
-                Collectors.groupingBy(AccountAvgInfo::getGhId, Collectors.toMap(AccountAvgInfo::getPosition, o -> o)));
-        JSONArray jsonArray = new JSONArray();
-        for (Article article : articleList) {
-            List<ArticleDetailInfo> articleDetailInfos = articleDetailInfoMap.get(article.getWxSn());
-            if (CollectionUtils.isEmpty(articleDetailInfos)) {
-                continue;
-            }
-            Date minDate = articleDetailInfos.stream().map(ArticleDetailInfo::getRecallDt).min(Date::compareTo).orElse(new Date());
-            int sumfirstLevel = 0;
-            int sumFission0 = 0;
-            int sumFission1 = 0;
-            int sumFission2 = 0;
-            for (ArticleDetailInfo articleDetailInfo : articleDetailInfos) {
-                if (articleDetailInfo.getRecallDt().equals(minDate)) {
-                    sumfirstLevel += Optional.ofNullable(articleDetailInfo.getFirstLevel()).orElse(0);
-                    sumFission0 += Optional.ofNullable(articleDetailInfo.getFission0()).orElse(0);
-                    sumFission1 += Optional.ofNullable(articleDetailInfo.getFission1()).orElse(0);
-                    sumFission2 += Optional.ofNullable(articleDetailInfo.getFission2()).orElse(0);
-                }
-            }
-            Map<String, AccountAvgInfo> accountAvgInfoMap = accountAvgInfoIndexMap.get(article.getGhId());
-            AccountAvgInfo avgInfo = accountAvgInfoMap.get(article.getItemIndex().toString());
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
-            String date = sdf.format(new Date(article.getUpdateTime() * 1000));
-            JSONObject obj = new JSONObject();
-            obj.put("ghId", article.getGhId());
-            obj.put("accountName", article.getAccountName());
-            obj.put("title", article.getTitle());
-            obj.put("index", article.getItemIndex());
-            obj.put("viewCount", article.getShowViewCount());
-            obj.put("time", date);
-            if (Objects.nonNull(avgInfo)) {
-                obj.put("fans", avgInfo.getFans());
-                obj.put("avgViewCount", avgInfo.getReadAvg());
-                obj.put("viewCountRate", (article.getShowViewCount() * 1.0) / avgInfo.getReadAvg());
-            }
-            obj.put("firstLevel", sumfirstLevel);
-            obj.put("fission0", sumFission0);
-            obj.put("fission1", sumFission1);
-            obj.put("fission2", sumFission2);
-            jsonArray.add(obj);
-        }
-        System.out.println(jsonArray.toJSONString());
-    }
+//    @Test
+//    void recall() {
+//        RecallParam param = new RecallParam();
+//        param.setAccountId("20231213123536190184852");
+//        param.setPlanId("20240718181730864154902");
+//        RecallResult recallResult = recallService.recall(param);
+//        System.out.println(JSONObject.toJSONString(recallResult));
+//    }
+//
+//    @Test
+//    void exportData() {
+//        Set<String> ghIds = new HashSet<>(Arrays.asList("gh_adca24a8f429", "gh_e0eb490115f5", "gh_51e4ad40466d", "gh_95ed5ecf9363"));
+//        List<Article> articleList = articleRepository.getByGhIdInAndUpdateTimeGreaterThan(ghIds, 1722441600L);
+//
+//        Map<String, Map<Integer, List<Article>>> map = articleList.stream()
+//                .collect(Collectors.groupingBy(Article::getTitle, Collectors.groupingBy(Article::getItemIndex)));
+//        Set<String> snList = articleList.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));
+//
+//        List<AccountAvgInfo> accountAvgInfoList = accountAvgInfoRepository.getAllByGhIdInAndStatusEquals(ghIds, 1);
+//        Map<String, Map<String, AccountAvgInfo>> accountAvgInfoIndexMap = accountAvgInfoList.stream().collect(
+//                Collectors.groupingBy(AccountAvgInfo::getGhId, Collectors.toMap(AccountAvgInfo::getPosition, o -> o)));
+//        JSONArray jsonArray = new JSONArray();
+//        for (Article article : articleList) {
+//            List<ArticleDetailInfo> articleDetailInfos = articleDetailInfoMap.get(article.getWxSn());
+//            if (CollectionUtils.isEmpty(articleDetailInfos)) {
+//                continue;
+//            }
+//            Date minDate = articleDetailInfos.stream().map(ArticleDetailInfo::getRecallDt).min(Date::compareTo).orElse(new Date());
+//            int sumfirstLevel = 0;
+//            int sumFission0 = 0;
+//            int sumFission1 = 0;
+//            int sumFission2 = 0;
+//            for (ArticleDetailInfo articleDetailInfo : articleDetailInfos) {
+//                if (articleDetailInfo.getRecallDt().equals(minDate)) {
+//                    sumfirstLevel += Optional.ofNullable(articleDetailInfo.getFirstLevel()).orElse(0);
+//                    sumFission0 += Optional.ofNullable(articleDetailInfo.getFission0()).orElse(0);
+//                    sumFission1 += Optional.ofNullable(articleDetailInfo.getFission1()).orElse(0);
+//                    sumFission2 += Optional.ofNullable(articleDetailInfo.getFission2()).orElse(0);
+//                }
+//            }
+//            Map<String, AccountAvgInfo> accountAvgInfoMap = accountAvgInfoIndexMap.get(article.getGhId());
+//            AccountAvgInfo avgInfo = accountAvgInfoMap.get(article.getItemIndex().toString());
+//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+//            String date = sdf.format(new Date(article.getUpdateTime() * 1000));
+//            JSONObject obj = new JSONObject();
+//            obj.put("ghId", article.getGhId());
+//            obj.put("accountName", article.getAccountName());
+//            obj.put("title", article.getTitle());
+//            obj.put("index", article.getItemIndex());
+//            obj.put("viewCount", article.getShowViewCount());
+//            obj.put("time", date);
+//            if (Objects.nonNull(avgInfo)) {
+//                obj.put("fans", avgInfo.getFans());
+//                obj.put("avgViewCount", avgInfo.getReadAvg());
+//                obj.put("viewCountRate", (article.getShowViewCount() * 1.0) / avgInfo.getReadAvg());
+//            }
+//            obj.put("firstLevel", sumfirstLevel);
+//            obj.put("fission0", sumFission0);
+//            obj.put("fission1", sumFission1);
+//            obj.put("fission2", sumFission2);
+//            jsonArray.add(obj);
+//        }
+//        System.out.println(jsonArray.toJSONString());
+//    }
 
 }