wangyunpeng 8 달 전
부모
커밋
dce792b511
19개의 변경된 파일522개의 추가작업 그리고 26개의 파일을 삭제
  1. 2 2
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/enums/StatusEnum.java
  2. 31 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/enums/recommend/ArticleCategoryStatusEnum.java
  3. 3 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/mapper/longArticle/LongArticleBaseMapper.java
  4. 39 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/dto/kimi/KimiOfficialApiResponse.java
  5. 11 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/dto/kimi/KimiResult.java
  6. 48 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/AccountCategory.java
  7. 53 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/ArticleCategory.java
  8. 34 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/ArticleCrawlerPlan.java
  9. 10 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/vo/ProduceContentCrawlerVO.java
  10. 62 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/CrawlerContentByPlanService.java
  11. 89 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/KimiApiService.java
  12. 9 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/AccountCategoryRepository.java
  13. 16 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/ArticleCategoryRepository.java
  14. 12 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/ArticleCrawlerPlanRepository.java
  15. 6 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/XxlJobService.java
  16. 61 5
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/ArticleService.java
  17. 20 19
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/recall/RecallService.java
  18. 6 0
      long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/XxlJobController.java
  19. 10 0
      long-article-recommend-service/src/main/resources/mapper/longArticle/LongArticleBaseMapper.xml

+ 2 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/enums/StatusEnum.java

@@ -5,8 +5,8 @@ import lombok.Getter;
 @Getter
 public enum StatusEnum {
 
-    FAIL(0, "fail"),
-    SUCCESS(1, "success"),
+    ZERO(0, "0"),
+    ONE(1, "1"),
     ;
 
     private int code;

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

@@ -0,0 +1,31 @@
+package com.tzld.longarticle.recommend.server.common.enums.recommend;
+
+import lombok.Getter;
+
+@Getter
+public enum ArticleCategoryStatusEnum {
+
+    WAITING(0, "待分类"),
+    PROCESS(1, "执行中"),
+    SUCCESS(2, "成功"),
+    FAIL(3, "失败"),
+    ;
+
+    //状态(0-待分类 1-执行中 2-成功 3-失败)
+    private int code;
+    private String msg;
+
+    ArticleCategoryStatusEnum(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public static ArticleCategoryStatusEnum getByCode(int code) {
+        for (ArticleCategoryStatusEnum statusEnum : ArticleCategoryStatusEnum.values()) {
+            if (statusEnum.getCode() == code) {
+                return statusEnum;
+            }
+        }
+        return null;
+    }
+}

+ 3 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/mapper/longArticle/LongArticleBaseMapper.java

@@ -1,5 +1,6 @@
 package com.tzld.longarticle.recommend.server.mapper.longArticle;
 
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticleCategory;
 import com.tzld.longarticle.recommend.server.model.entity.longArticle.DatastatScore;
 import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticlePoolPromotionSource;
 import com.tzld.longarticle.recommend.server.model.entity.longArticle.DatastatSortStrategy;
@@ -21,4 +22,6 @@ public interface LongArticleBaseMapper {
     void updateRootProduceContentLevel(String rootProduceContentId, String level);
 
     void batchInsertDatastatScore(List<DatastatScore> list);
+
+    void batchInsertArticleCategory(List<ArticleCategory> list);
 }

+ 39 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/dto/kimi/KimiOfficialApiResponse.java

@@ -0,0 +1,39 @@
+package com.tzld.longarticle.recommend.server.model.dto.kimi;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class KimiOfficialApiResponse {
+
+    private String id;
+    private String object;
+    private long created;
+    private String model;
+    private List<Choice> choices;
+    private Usage usage;
+
+
+    @Data
+    public static class Choice {
+        private long index;
+        private Message message;
+        private String finishReason;
+    }
+
+
+    @Data
+    public static class Message {
+        private String role;
+        private String content;
+    }
+
+    @Data
+    public static class Usage {
+        private long promptTokens;
+        private long completionTokens;
+        private long totalTokens;
+    }
+
+}

+ 11 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/dto/kimi/KimiResult.java

@@ -0,0 +1,11 @@
+package com.tzld.longarticle.recommend.server.model.dto.kimi;
+
+import lombok.Data;
+
+@Data
+public class KimiResult {
+    private boolean success;
+    private KimiOfficialApiResponse response;
+    private String failReason;
+    private String responseStr;
+}

+ 48 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/AccountCategory.java

@@ -0,0 +1,48 @@
+package com.tzld.longarticle.recommend.server.model.entity.longArticle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "account_category")
+@IdClass(AccountCategory.PK.class)
+public class AccountCategory {
+
+    @Id
+    private String dt;
+    @Id
+    private String ghId;
+
+    @Column(name = "category_map")
+    private String categoryMap;
+
+    @Column(name = "status")
+    private String status;
+
+    @Column(name = "create_timestamp")
+    private Long createTimestamp;
+
+    @Column(name = "update_timestamp")
+    private Long updateTimestamp;
+
+
+    @Data
+    public static class PK implements Serializable {
+
+        @Column(name = "dt")
+        private String dt;
+        @Column(name = "gh_id")
+        private String ghId;
+
+        public PK() {
+        }
+
+    }
+}

+ 53 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/ArticleCategory.java

@@ -0,0 +1,53 @@
+package com.tzld.longarticle.recommend.server.model.entity.longArticle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "article_category")
+public class ArticleCategory {
+
+    @Id
+    @Column(name = "produce_content_id")
+    private String produceContentId;
+
+    @Column(name = "channel_content_id")
+    private String channelContentId;
+
+    @Column(name = "crawler_plan_id")
+    private String crawlerPlanId;
+
+    @Column(name = "title")
+    private String title;
+
+    @Column(name = "title_md5")
+    private String titleMd5;
+
+    @Column(name = "category")
+    private String category;
+
+    @Column(name = "kimi_result")
+    private String kimiResult;
+
+    @Column(name = "status")
+    private Integer status;
+
+    @Column(name = "fail_reason")
+    private String failReason;
+
+    @Column(name = "create_timestamp")
+    private Long createTimestamp;
+
+    @Column(name = "update_timestamp")
+    private Long updateTimestamp;
+
+}

+ 34 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/entity/longArticle/ArticleCrawlerPlan.java

@@ -0,0 +1,34 @@
+package com.tzld.longarticle.recommend.server.model.entity.longArticle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "article_crawler_plan")
+public class ArticleCrawlerPlan {
+
+    @Id
+    @Column(name = "crawler_plan_id")
+    private String crawlerPlanId;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "status")
+    private Integer status;
+
+    @Column(name = "create_timestamp")
+    private Long createTimestamp;
+
+    @Column(name = "update_timestamp")
+    private Long updateTimestamp;
+}

+ 10 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/vo/ProduceContentCrawlerVO.java

@@ -0,0 +1,10 @@
+package com.tzld.longarticle.recommend.server.model.vo;
+
+import lombok.Data;
+
+@Data
+public class ProduceContentCrawlerVO {
+    private String produceContentId;
+    private String channelContentId;
+    private String title;
+}

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

@@ -0,0 +1,62 @@
+package com.tzld.longarticle.recommend.server.remote;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.longarticle.recommend.server.common.HttpPoolFactory;
+import com.tzld.longarticle.recommend.server.model.vo.ProduceContentCrawlerVO;
+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.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+@Slf4j
+public class CrawlerContentByPlanService {
+    private final CloseableHttpClient client = HttpPoolFactory.aigcPool();
+    private static final String url = "http://aigc-api.cybertogether.net/aigc/produce/content/getContentByCrawlerPlan";
+
+
+    public List<ProduceContentCrawlerVO> getCrawlerContentByPlan(String crawlerPlanId, List<String> producePlanIds) {
+        long start = System.currentTimeMillis();
+        List<ProduceContentCrawlerVO> result = new ArrayList<>();
+        JSONObject bodyParam = new JSONObject();
+        JSONObject bodyParamParams = new JSONObject();
+        bodyParamParams.put("crawlerPlanId", crawlerPlanId);
+        bodyParamParams.put("producePlanIds", producePlanIds);
+        bodyParam.put("params", bodyParamParams);
+        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) {
+                        JSONArray data = jsonObject.getJSONArray("data");
+                        result.addAll(JSONArray.parseArray(data.toJSONString(), ProduceContentCrawlerVO.class));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("getCrawlerContentByPlan error", e);
+        }
+        log.info("getCrawlerContentByPlan耗时:{}", System.currentTimeMillis() - start);
+        return result;
+    }
+
+}

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

@@ -0,0 +1,89 @@
+package com.tzld.longarticle.recommend.server.remote;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.longarticle.recommend.server.model.dto.kimi.KimiOfficialApiResponse;
+import com.tzld.longarticle.recommend.server.model.dto.kimi.KimiResult;
+import com.tzld.longarticle.recommend.server.util.MapBuilder;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.apache.http.util.TextUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@Slf4j
+public class KimiApiService {
+
+    private OkHttpClient client;
+
+    @PostConstruct
+    public void init() {
+        client = new OkHttpClient().newBuilder()
+                .connectTimeout(15, TimeUnit.MINUTES)
+                .readTimeout(15, TimeUnit.MINUTES)
+                .writeTimeout(15, TimeUnit.MINUTES)
+                .build();
+
+    }
+
+
+    public KimiResult requestOfficialApi(String prompt, String model, Double temperature) {
+        KimiResult result = new KimiResult();
+        result.setSuccess(false);
+        if (TextUtils.isBlank(prompt) || TextUtils.isBlank(prompt.trim())) {
+            result.setFailReason("prompt is empty");
+            return result;
+        }
+
+        try {
+            JSONArray jsonArray = new JSONArray();
+            JSONObject message = new JSONObject();
+            message.put("role", "user");
+            message.put("content", prompt);
+            jsonArray.add(message);
+
+            Map<Object, Object> bodyParam = MapBuilder
+                    .builder()
+                    .put("model", Optional.ofNullable(model).orElse("moonshot-v1-auto"))
+                    .put("temperature", Optional.ofNullable(temperature).orElse(0.3))
+                    .put("messages", jsonArray)
+                    .build();
+
+            MediaType mediaType = MediaType.parse("application/json");
+            RequestBody body = RequestBody.create(mediaType, JSONObject.toJSONString(bodyParam));
+            Request request = new Request.Builder()
+                    .url("https://api.moonshot.cn/v1/chat/completions")
+                    .method("POST", body)
+                    .addHeader("Content-Type", "application/json")
+                    .addHeader("Authorization", "Bearer sk-5DqYCa88kche6nwIWjLE1p4oMm8nXrR9kQMKbBolNAWERu7q")
+                    .build();
+            Response response = client.newCall(request).execute();
+
+            String responseContent = response.body().string();
+            result.setResponseStr(responseContent);
+            log.info("kimi api responseContent = {}", responseContent);
+            if (response.isSuccessful()) {
+                KimiOfficialApiResponse obj = JSONObject.parseObject(responseContent, KimiOfficialApiResponse.class);
+                if (CollectionUtil.isNotEmpty(obj.getChoices())) {
+                    result.setSuccess(true);
+                    result.setResponse(obj);
+                } else {
+                    result.setFailReason("response empty");
+                }
+            } else {
+                JSONObject json = JSONObject.parseObject(responseContent);
+                result.setFailReason("request error code:" + response.code() + " message:" + json.getString("error"));
+            }
+        } catch (Exception e) {
+            log.error("kimi official api fail: " + e.getMessage());
+            result.setFailReason(e.getMessage());
+        }
+        return result;
+    }
+}

+ 9 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/AccountCategoryRepository.java

@@ -0,0 +1,9 @@
+package com.tzld.longarticle.recommend.server.repository.longArticle;
+
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.AccountCategory;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AccountCategoryRepository extends JpaRepository<AccountCategory, AccountCategory.PK> {
+}

+ 16 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/ArticleCategoryRepository.java

@@ -0,0 +1,16 @@
+package com.tzld.longarticle.recommend.server.repository.longArticle;
+
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticleCategory;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ArticleCategoryRepository extends JpaRepository<ArticleCategory, String> {
+
+    List<ArticleCategory> getByProduceContentIdIn(List<String> produceContentIds);
+
+    List<ArticleCategory> getByStatus(Integer status);
+
+}

+ 12 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/repository/longArticle/ArticleCrawlerPlanRepository.java

@@ -0,0 +1,12 @@
+package com.tzld.longarticle.recommend.server.repository.longArticle;
+
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticleCrawlerPlan;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ArticleCrawlerPlanRepository extends JpaRepository<ArticleCrawlerPlan, String> {
+    List<ArticleCrawlerPlan> getByStatus(Integer status);
+}

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

@@ -391,4 +391,10 @@ public class XxlJobService {
         articleService.articlePromotionTraceability(channelContentId);
         return ReturnT.SUCCESS;
     }
+
+    @XxlJob("articlePromotionTraceability")
+    public ReturnT<String> articleCategoryJob() {
+        articleService.articleCategory();
+        return ReturnT.SUCCESS;
+    }
 }

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

@@ -4,25 +4,35 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.tzld.longarticle.recommend.server.common.CommonThreadPoolExecutor;
 import com.tzld.longarticle.recommend.server.common.enums.StatusEnum;
 import com.tzld.longarticle.recommend.server.common.enums.aigc.PublishContentTypeEnum;
+import com.tzld.longarticle.recommend.server.common.enums.recommend.ArticleCategoryStatusEnum;
 import com.tzld.longarticle.recommend.server.common.enums.recommend.ArticlePoolPromotionSourceStatusEnum;
 import com.tzld.longarticle.recommend.server.mapper.aigc.AigcBaseMapper;
 import com.tzld.longarticle.recommend.server.mapper.crawler.CrawlerBaseMapper;
 import com.tzld.longarticle.recommend.server.mapper.longArticle.LongArticleBaseMapper;
 import com.tzld.longarticle.recommend.server.model.dto.CrawlerContent;
+import com.tzld.longarticle.recommend.server.model.dto.kimi.KimiResult;
 import com.tzld.longarticle.recommend.server.model.entity.aigc.PublishAccount;
 import com.tzld.longarticle.recommend.server.model.entity.aigc.PublishContent;
 import com.tzld.longarticle.recommend.server.model.entity.aigc.PublishContentOutput;
 import com.tzld.longarticle.recommend.server.model.entity.crawler.Article;
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticleCategory;
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticleCrawlerPlan;
 import com.tzld.longarticle.recommend.server.model.entity.longArticle.ArticlePoolPromotionSource;
 import com.tzld.longarticle.recommend.server.model.param.ArticleFindSourceParam;
+import com.tzld.longarticle.recommend.server.model.vo.ProduceContentCrawlerVO;
 import com.tzld.longarticle.recommend.server.model.vo.RootPublishContentVO;
+import com.tzld.longarticle.recommend.server.remote.CrawlerContentByPlanService;
+import com.tzld.longarticle.recommend.server.remote.KimiApiService;
 import com.tzld.longarticle.recommend.server.repository.aigc.PublishAccountRepository;
 import com.tzld.longarticle.recommend.server.repository.aigc.PublishContentOutputRepository;
 import com.tzld.longarticle.recommend.server.repository.crawler.AccountAvgInfoRepository;
 import com.tzld.longarticle.recommend.server.repository.crawler.ArticleRepository;
+import com.tzld.longarticle.recommend.server.repository.longArticle.ArticleCategoryRepository;
+import com.tzld.longarticle.recommend.server.repository.longArticle.ArticleCrawlerPlanRepository;
 import com.tzld.longarticle.recommend.server.repository.longArticle.ArticlePoolPromotionSourceRepository;
 import com.tzld.longarticle.recommend.server.service.recommend.config.AccountIndexAvgViewCountService;
 import com.tzld.longarticle.recommend.server.util.DateUtils;
+import com.tzld.longarticle.recommend.server.util.Md5Util;
 import com.tzld.longarticle.recommend.server.util.TitleSimilarCheckUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
@@ -31,10 +41,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.*;
 import java.util.stream.Collectors;
 
@@ -63,6 +70,14 @@ public class ArticleService {
     LongArticleBaseMapper longArticleBaseMapper;
     @Autowired
     ArticlePoolPromotionSourceRepository articlePoolPromotionSourceRepository;
+    @Autowired
+    ArticleCrawlerPlanRepository articleCrawlerPlanRepository;
+    @Autowired
+    ArticleCategoryRepository articleCategoryRepository;
+    @Autowired
+    CrawlerContentByPlanService crawlerContentByPlanService;
+    @Autowired
+    KimiApiService kimiApiService;
 
     private final static ExecutorService pool = new CommonThreadPoolExecutor(
             32,
@@ -302,9 +317,50 @@ public class ArticleService {
                 }
                 longArticleBaseMapper.updateRootProduceContentLevel(task.getRootProduceContentId(), task.getLevel());
             } else {
-                task.setDeleted(StatusEnum.SUCCESS.getCode());
+                task.setDeleted(StatusEnum.ONE.getCode());
                 articlePoolPromotionSourceRepository.save(task);
             }
         }
     }
+
+    public void articleCategory() {
+        List<ArticleCrawlerPlan> articleCrawlerPlanList = articleCrawlerPlanRepository.getByStatus(StatusEnum.ZERO.getCode());
+        List<String> producePlanIds = Arrays.asList("20240802021606053813696", "20240802080355355308981",
+                "20240805154433785506170", "20240805154359027876170", "20241024100016206421084", "20241030070010871546586");
+        for (ArticleCrawlerPlan crawlerPlan : articleCrawlerPlanList) {
+            List<ProduceContentCrawlerVO> list = crawlerContentByPlanService.getCrawlerContentByPlan(crawlerPlan.getCrawlerPlanId(), producePlanIds);
+            List<String> produceContentIds = list.stream().map(ProduceContentCrawlerVO::getProduceContentId).collect(Collectors.toList());
+            List<ArticleCategory> exists = articleCategoryRepository.getByProduceContentIdIn(produceContentIds);
+            List<String> existsIds = exists.stream().map(ArticleCategory::getProduceContentId).collect(Collectors.toList());
+            list = list.stream().filter(o -> !existsIds.contains(o.getProduceContentId())).collect(Collectors.toList());
+            long now = System.currentTimeMillis();
+            List<ArticleCategory> saveList = new ArrayList<>();
+            for (ProduceContentCrawlerVO vo : list) {
+                ArticleCategory item = new ArticleCategory();
+                item.setCrawlerPlanId(crawlerPlan.getCrawlerPlanId());
+                item.setChannelContentId(vo.getChannelContentId());
+                item.setProduceContentId(vo.getProduceContentId());
+                item.setTitle(vo.getTitle());
+                item.setTitleMd5(Md5Util.encoderByMd5(vo.getTitle()));
+                item.setCreateTimestamp(now);
+                saveList.add(item);
+            }
+            longArticleBaseMapper.batchInsertArticleCategory(saveList);
+        }
+        List<ArticleCategory> dealList = articleCategoryRepository.getByStatus(ArticleCategoryStatusEnum.WAITING.getCode());
+        for (ArticleCategory articleCategory : dealList) {
+            KimiResult kimiResult = kimiApiService.requestOfficialApi(articleCategory.getTitle(), null, null);
+            articleCategory.setKimiResult(kimiResult.getResponseStr());
+            articleCategory.setUpdateTimestamp(System.currentTimeMillis());
+            if (kimiResult.isSuccess()) {
+                articleCategory.setCategory(kimiResult.getResponse().getChoices().get(0).getMessage().getContent());
+                articleCategory.setStatus(ArticleCategoryStatusEnum.SUCCESS.getCode());
+            } else {
+                articleCategory.setStatus(ArticleCategoryStatusEnum.FAIL.getCode());
+                articleCategory.setFailReason(kimiResult.getFailReason());
+            }
+            articleCategoryRepository.save(articleCategory);
+        }
+
+    }
 }

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

@@ -157,25 +157,26 @@ public class RecallService implements ApplicationContextAware {
     }
 
     public void setContentCategory(List<Content> contentList) {
-        long start = System.currentTimeMillis();
-        Map<String, String> articleMd5Map = new HashMap<>();
-        List<String> md5List = new ArrayList<>();
-        for (Content content : contentList) {
-            String md5 = generateArticleUniqueMd5(content.getCrawlerLink());
-            md5List.add(md5);
-            articleMd5Map.put(content.getId(), md5);
-        }
-        List<CrawlerMetaArticle> categoryList = getByUniqueIndexIn(md5List);
-        if (CollectionUtils.isEmpty(categoryList)) {
-            return;
-        }
-        Map<String, List<String>> categoryMap = categoryList.stream().collect(Collectors.groupingBy(CrawlerMetaArticle::getUniqueIndex,
-                Collectors.mapping(CrawlerMetaArticle::getCategory, Collectors.toList())));
-        for (Content content : contentList) {
-            String md5 = articleMd5Map.get(content.getId());
-            content.setCategory(categoryMap.get(md5));
-        }
-        log.info("setContentCategory cost:{}", System.currentTimeMillis() - start);
+//        Map<String, String> articleMd5Map = new HashMap<>();
+//        List<String> md5List = new ArrayList<>();
+//        for (Content content : contentList) {
+//            String md5 = generateArticleUniqueMd5(content.getCrawlerLink());
+//            md5List.add(md5);
+//            articleMd5Map.put(content.getId(), md5);
+//        }
+//        List<CrawlerMetaArticle> categoryList = getByUniqueIndexIn(md5List);
+//        if (CollectionUtils.isEmpty(categoryList)) {
+//            return;
+//        }
+//        Map<String, List<String>> categoryMap = categoryList.stream().collect(Collectors.groupingBy(CrawlerMetaArticle::getUniqueIndex,
+//                Collectors.mapping(CrawlerMetaArticle::getCategory, Collectors.toList())));
+//        for (Content content : contentList) {
+//            String md5 = articleMd5Map.get(content.getId());
+//            content.setCategory(categoryMap.get(md5));
+//        }
+        // 查询晋升rootProduceContentId
+        // 根据produceContentId查询category
+
     }
 
     private List<CrawlerMetaArticle> getByUniqueIndexIn(List<String> md5List) {

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

@@ -48,4 +48,10 @@ public class XxlJobController {
     public void articlePromotionTraceability(String channelContentId) {
         service.articlePromotionTraceability(channelContentId);
     }
+
+    @GetMapping("/articleCategoryJob")
+    public void articleCategoryJob() {
+        service.articleCategoryJob();
+    }
+
 }

+ 10 - 0
long-article-recommend-service/src/main/resources/mapper/longArticle/LongArticleBaseMapper.xml

@@ -71,4 +71,14 @@
         </foreach>
     </insert>
 
+    <insert id="batchInsertArticleCategory">
+        INSERT INTO article_category
+        (produce_content_id, channel_content_id, crawler_plan_id, title, title_md5, create_timestamp)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.produceContentId}, #{item.channelContentId}, #{item.crawlerPlanId}, #{item.title}, #{item.titleMd5},
+             #{item.createTimestamp})
+        </foreach>
+    </insert>
+
 </mapper>