Просмотр исходного кода

需求内容池 晋级到公共计划中

wangyunpeng 4 часов назад
Родитель
Сommit
426df54328

+ 5 - 4
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/aigc/AIGCProducePlanCreateService.java

@@ -38,16 +38,17 @@ public class AIGCProducePlanCreateService {
     private final CloseableHttpClient client = HttpPoolFactory.aigcPool();
 
     /**
-     * 创建带抓取计划的 demand 利用池生成计划。
+     * 创建带抓取计划的 demand 利用池共用生成计划(所有账号共用一个)
      * 抓取计划 ID 直接注入到 inputSourceGroups[0].inputSources 中,无需后续再调用 articleAddDependPlan 绑定。
      *
-     * @param accountName     账号名
+     * @param accountName     账号名(仅用于日志,计划名固定为共享)
      * @param crawlerPlanId   抓取计划 ID
      * @param crawlerPlanName 抓取计划名称(用于 inputSourceLabel)
      * @return plan ID + name
      */
     public IdNameVO<String> createUtilizeProducePlan(String accountName, String crawlerPlanId, String crawlerPlanName) {
-        String planName = String.format("账号需求池_%s_利用池", accountName);
+        // 所有账号共用一个生成计划
+        String planName = "账号需求池_利用池";
 
         int retryTimes = 2;
         while (retryTimes > 0) {
@@ -87,7 +88,7 @@ public class AIGCProducePlanCreateService {
         JSONArray inputSourceGroups = params.getJSONArray("inputSourceGroups");
         if (inputSourceGroups != null && !inputSourceGroups.isEmpty()) {
             JSONObject group = inputSourceGroups.getJSONObject(0);
-            String inputSourceLabel = String.format("需求池晋级-长文-微信公众号-内容添加计划-%s", crawlerPlanName);
+            String inputSourceLabel = String.format("原始帖子-长文-微信公众号-内容添加计划-%s", crawlerPlanName);
             JSONObject inputSource = new JSONObject();
             inputSource.put("contentType", 1);
             inputSource.put("inputSourceType", 2);   // contentPlan

+ 54 - 47
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/ArticlePromotionService.java

@@ -107,6 +107,11 @@ public class ArticlePromotionService {
     @Value("${readOpenFissionRateThreshold:}")
     private Double readOpenFissionRateThreshold;
 
+    /**
+     * 所有账号共用一个生成计划的哨兵键,替代原来的按账号区分。
+     */
+    public static final String SHARED_ACCOUNT_KEY = "SHARED";
+
     private final List<String> contentPoolType = Arrays.asList("autoArticlePoolLevel1", "autoArticlePoolLevel3", "autoArticlePoolLevel4");
 
     /**
@@ -792,13 +797,14 @@ public class ArticlePromotionService {
     }
 
     /**
-     * 需求池晋级绑定:将已完成溯源的晋级记录绑定到对应账号的 accountDemandPoolLevelUtilize 生成计划。
+     * 需求池晋级绑定:将已完成溯源的晋级记录绑定到 accountDemandPoolLevelUtilize 生成计划。
+     * <p>
+     * 所有账号共用一个生成计划,通过 demand_pool_promotion_bind.account_id 区分归属。
      * <p>
      * 流程:
      * 1. 读取 demand_pool_promotion_source(status=FINISH, 未绑定)
-     * 2. 对每条记录获取 publishContentId → 创建抓取计划
-     * 3. 查找/创建账号的 accountDemandPoolLevelUtilize 生成计划
-     * 4. 将抓取计划绑定到生成计划
+     * 2. 查找/创建共用的 accountDemandPoolLevelUtilize 生成计划
+     * 3. 对每条记录获取 publishContentId → 创建抓取计划 → 绑定到共用生成计划
      */
     public void demandPoolPromotionBind() {
         List<DemandPoolPromotionSource> finishedRecords = demandPoolPromotionSourceRepository
@@ -812,6 +818,22 @@ public class ArticlePromotionService {
         int bindCount = 0;
         int skipCount = 0;
 
+        // 所有账号共用一个生成计划
+        String sharedProducePlanId = null;
+        boolean sharedPlanInitialized = false;
+        AccountDemandUtilizePlan sharedMapping = accountDemandUtilizePlanRepository.getByAccountId(SHARED_ACCOUNT_KEY);
+        if (sharedMapping != null && StringUtils.hasText(sharedMapping.getProducePlanId())) {
+            ProducePlanDetailVO existDetail = getProducePlanDetailRetry(sharedMapping.getProducePlanId());
+            if (existDetail != null) {
+                sharedProducePlanId = sharedMapping.getProducePlanId();
+                sharedPlanInitialized = true;
+                log.info("demandPoolPromotionBind found existing shared plan, planId:{}", sharedProducePlanId);
+            } else {
+                log.warn("demandPoolPromotionBind shared plan not found, will recreate. oldPlanId:{}",
+                        sharedMapping.getProducePlanId());
+            }
+        }
+
         for (DemandPoolPromotionSource record : finishedRecords) {
             try {
                 // 已绑定则跳过
@@ -858,75 +880,60 @@ public class ArticlePromotionService {
                 }
                 long now = System.currentTimeMillis();
 
-                // 3. 查找已有生成计划映射;存在则绑定抓取计划,不存在则创建(抓取计划注入到 inputSources 中)
-                String producePlanId = null;
-                AccountDemandUtilizePlan mapping = accountDemandUtilizePlanRepository.getByAccountId(accountId);
-                boolean hasExistingPlan = mapping != null && StringUtils.hasText(mapping.getProducePlanId());
-
-                if (hasExistingPlan) {
-                    // 校验计划是否仍存在
-                    ProducePlanDetailVO existDetail = getProducePlanDetailRetry(mapping.getProducePlanId());
-                    if (existDetail != null) {
-                        // 计划存在 → 绑定抓取计划
-                        producePlanId = mapping.getProducePlanId();
-                        String inputSourceLabel = String.format("需求池晋级-长文-微信公众号-内容添加计划-%s", crawlerPlanInfo.getName());
-                        articleAddDependPlan(producePlanId, crawlerPlanInfo.getId(), inputSourceLabel,
-                                ProducePlanInputSourceTypeEnum.contentPlan.getVal());
-                        log.info("demandPoolPromotionBind bind to existing plan, accountId:{} planId:{} crawlerPlanId:{}",
-                                accountId, producePlanId, crawlerPlanInfo.getId());
-                    } else {
-                        // 计划已被删除 → 重新创建
-                        log.warn("demandPoolPromotionBind existing plan not found, recreate. accountId:{} oldPlanId:{}",
-                                accountId, mapping.getProducePlanId());
-                        hasExistingPlan = false;
-                    }
-                }
-
-                if (!hasExistingPlan) {
-                    // 创建生成计划(抓取计划 ID 直接注入输入源,无需再调 articleAddDependPlan)
+                // 3. 共用生成计划:首次创建,后续记录绑定到同一个计划
+                if (!sharedPlanInitialized) {
+                    // 创建共用生成计划(抓取计划 ID 直接注入输入源)
                     IdNameVO<String> planInfo = aigcProducePlanCreateService.createUtilizeProducePlan(
                             accountName, crawlerPlanInfo.getId(), crawlerPlanInfo.getName());
                     if (planInfo == null || !StringUtils.hasText(planInfo.getId())) {
-                        log.error("demandPoolPromotionBind create produce plan failed, accountId:{} accountName:{}",
-                                accountId, accountName);
+                        log.error("demandPoolPromotionBind create shared produce plan failed, accountName:{}", accountName);
                         skipCount++;
                         continue;
                     }
-                    producePlanId = planInfo.getId();
+                    sharedProducePlanId = planInfo.getId();
+                    sharedPlanInitialized = true;
 
-                    // 保存映射
-                    if (mapping == null) {
-                        mapping = new AccountDemandUtilizePlan();
+                    if (sharedMapping == null) {
+                        sharedMapping = new AccountDemandUtilizePlan();
                     }
-                    mapping.setAccountId(accountId);
-                    mapping.setProducePlanId(planInfo.getId());
-                    mapping.setPlanName(planInfo.getName());
-                    mapping.setCreatedAt(now);
-                    mapping.setUpdatedAt(now);
-                    accountDemandUtilizePlanRepository.save(mapping);
-
+                    sharedMapping.setAccountId(SHARED_ACCOUNT_KEY);
+                    sharedMapping.setProducePlanId(planInfo.getId());
+                    sharedMapping.setPlanName(planInfo.getName());
+                    sharedMapping.setCreatedAt(now);
+                    sharedMapping.setUpdatedAt(now);
+                    accountDemandUtilizePlanRepository.save(sharedMapping);
+
+                    log.info("demandPoolPromotionBind created shared plan, planId:{} crawlerPlanId:{}",
+                            sharedProducePlanId, crawlerPlanInfo.getId());
+                } else {
+                    // 绑定抓取计划到已有共用生成计划
+                    String inputSourceLabel = String.format("原始帖子-长文-微信公众号-内容添加计划-%s", crawlerPlanInfo.getName());
+                    articleAddDependPlan(sharedProducePlanId, crawlerPlanInfo.getId(), inputSourceLabel,
+                            ProducePlanInputSourceTypeEnum.contentPlan.getVal());
+                    log.info("demandPoolPromotionBind bind to shared plan, accountId:{} planId:{} crawlerPlanId:{}",
+                            accountId, sharedProducePlanId, crawlerPlanInfo.getId());
                 }
 
-                if (producePlanId == null) {
+                if (sharedProducePlanId == null) {
                     FeishuMessageSender.sendWebHookMessage(FeishuRobotIdEnum.JOB.getRobotId(),
                             String.format("【需求池利用池生成计划创建失败】\n账号ID:%s\n账号名:%s\n晋级标题:%s\n<at user_id=\"g6732afb\">王云鹏</at>",
                                     accountId, accountName, record.getTitle()));
                 }
 
-                // 4. 记录绑定关系
+                // 4. 记录绑定关系(accountId 区分归属)
                 DemandPoolPromotionBind bind = new DemandPoolPromotionBind();
                 bind.setPromotionChannelContentId(record.getChannelContentId());
                 bind.setAccountId(accountId);
                 bind.setRootProduceContentId(record.getRootProduceContentId());
                 bind.setCrawlerPlanId(crawlerPlanInfo.getId());
-                bind.setProducePlanId(producePlanId);
+                bind.setProducePlanId(sharedProducePlanId);
                 bind.setCreatedAt(now);
                 bind.setUpdatedAt(now);
                 demandPoolPromotionBindRepository.save(bind);
 
                 bindCount++;
                 log.info("demandPoolPromotionBind success, channelContentId:{} accountId:{} crawlerPlanId:{} producePlanId:{}",
-                        record.getChannelContentId(), accountId, crawlerPlanInfo.getId(), producePlanId);
+                        record.getChannelContentId(), accountId, crawlerPlanInfo.getId(), sharedProducePlanId);
 
             } catch (Exception e) {
                 log.error("demandPoolPromotionBind error, channelContentId:{} title:{}",