|
@@ -231,7 +231,7 @@ public class DataDashboardService {
|
|
|
Pair.of("S", "0.00%"),
|
|
Pair.of("S", "0.00%"),
|
|
|
Pair.of("T", "0.00%")
|
|
Pair.of("T", "0.00%")
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, delDateStrList, null);
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, delDateStrList, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public List<NewSortStrategyExport> newSortStrategyData(String beginDate, String endDate,
|
|
public List<NewSortStrategyExport> newSortStrategyData(String beginDate, String endDate,
|
|
@@ -855,12 +855,11 @@ public class DataDashboardService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- private static void doSendFeishuSheet(List<String> dateStrList, String sheetToken, String sheetId,
|
|
|
|
|
|
|
+ private static void doSendFeishuSheet(Pair<String, Integer> token, List<String> dateStrList, String sheetToken, String sheetId,
|
|
|
int rowNum, List<List<Object>> rows, Integer startRowIndex,
|
|
int rowNum, List<List<Object>> rows, Integer startRowIndex,
|
|
|
List<Pair<String, String>> styles,
|
|
List<Pair<String, String>> styles,
|
|
|
List<String> delDateStrList,
|
|
List<String> delDateStrList,
|
|
|
List<Pair<String, List<Pair<String, String>>>> thanks) {
|
|
List<Pair<String, List<Pair<String, String>>>> thanks) {
|
|
|
- Pair<String, Integer> token = FeiShu.requestAccessToken();
|
|
|
|
|
RestTemplate restTemplate = new RestTemplate();
|
|
RestTemplate restTemplate = new RestTemplate();
|
|
|
HttpHeaders httpHeaders = new HttpHeaders();
|
|
HttpHeaders httpHeaders = new HttpHeaders();
|
|
|
httpHeaders.add("Authorization", "Bearer " + token.getFirst());
|
|
httpHeaders.add("Authorization", "Bearer " + token.getFirst());
|
|
@@ -1132,7 +1131,7 @@ public class DataDashboardService {
|
|
|
Pair.of("S", "0.00%"),
|
|
Pair.of("S", "0.00%"),
|
|
|
Pair.of("T", "0.00%")
|
|
Pair.of("T", "0.00%")
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, delDateStrList, null);
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, delDateStrList, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public List<NewSortStrategyExport> newSortStrategyFWHData(String beginDate, String endDate,
|
|
public List<NewSortStrategyExport> newSortStrategyFWHData(String beginDate, String endDate,
|
|
@@ -1498,7 +1497,7 @@ public class DataDashboardService {
|
|
|
Pair.of("BP", "0.00%")
|
|
Pair.of("BP", "0.00%")
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- doSendFeishuSheet(dateStrList, sheetToken, sheetId, rowNum, rows, 3, styles, null, null);
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, sheetToken, sheetId, rowNum, rows, 3, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void checkViewCountFeishuAlarm(List<IntermediateIndicatorsExport> newContentsYesData) {
|
|
private void checkViewCountFeishuAlarm(List<IntermediateIndicatorsExport> newContentsYesData) {
|
|
@@ -2129,7 +2128,7 @@ public class DataDashboardService {
|
|
|
Pair.of("AD", "#,##0.00")
|
|
Pair.of("AD", "#,##0.00")
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- doSendFeishuSheet(dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, null, null);
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, sheetToken, sheetId, rowNum, rows, 2, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private List<FirstContentScoreExport> firstContentScoreData(List<String> dateStrList) {
|
|
private List<FirstContentScoreExport> firstContentScoreData(List<String> dateStrList) {
|
|
@@ -2337,7 +2336,7 @@ public class DataDashboardService {
|
|
|
Pair.of("I", "0%")
|
|
Pair.of("I", "0%")
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "28RgAZ", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "28RgAZ", rowNum, rows,
|
|
|
2, styles, null, null);
|
|
2, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2495,7 +2494,7 @@ public class DataDashboardService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- doSendFeishuSheet(dateStrList, dailySafeSheetToken, "9fc2e8", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailySafeSheetToken, "9fc2e8", rowNum, rows,
|
|
|
2, null, null, null);
|
|
2, null, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2570,7 +2569,7 @@ public class DataDashboardService {
|
|
|
Pair.of("K", "0.00%")
|
|
Pair.of("K", "0.00%")
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "vddANt", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "vddANt", rowNum, rows,
|
|
|
2, styles, null, null);
|
|
2, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2712,7 +2711,7 @@ public class DataDashboardService {
|
|
|
Pair.of("U", "0.00%"),
|
|
Pair.of("U", "0.00%"),
|
|
|
Pair.of("V", "0.00%")
|
|
Pair.of("V", "0.00%")
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "qEipyL", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "qEipyL", rowNum, rows,
|
|
|
4, styles, null, null);
|
|
4, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2872,7 +2871,7 @@ public class DataDashboardService {
|
|
|
Pair.of("搜狐视频", "#D9F5D6"),
|
|
Pair.of("搜狐视频", "#D9F5D6"),
|
|
|
Pair.of("票圈视频", "#F8DEF8")))
|
|
Pair.of("票圈视频", "#F8DEF8")))
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "6aW60b", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "6aW60b", rowNum, rows,
|
|
|
3, styles, null, thank);
|
|
3, styles, null, thank);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3147,7 +3146,7 @@ public class DataDashboardService {
|
|
|
Pair.of("次条", "#B1E8FC"),
|
|
Pair.of("次条", "#B1E8FC"),
|
|
|
Pair.of("3-8", "#F8E6AB")))
|
|
Pair.of("3-8", "#F8E6AB")))
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "qvxJsD", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "qvxJsD", rowNum, rows,
|
|
|
2, styles, null, thank);
|
|
2, styles, null, thank);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3514,7 +3513,7 @@ public class DataDashboardService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "jwayC4", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "jwayC4", rowNum, rows,
|
|
|
2, null, null, null);
|
|
2, null, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3542,7 +3541,7 @@ public class DataDashboardService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "QiEZiz", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "QiEZiz", rowNum, rows,
|
|
|
2, null, null, null);
|
|
2, null, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4095,7 +4094,7 @@ public class DataDashboardService {
|
|
|
Pair.of("长文审核", "#BACEFD"),
|
|
Pair.of("长文审核", "#BACEFD"),
|
|
|
Pair.of("文章内容池", "#FED4A4")))
|
|
Pair.of("文章内容池", "#FED4A4")))
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "Lushkl", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "Lushkl", rowNum, rows,
|
|
|
3, styles, null, thank);
|
|
3, styles, null, thank);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4174,7 +4173,7 @@ public class DataDashboardService {
|
|
|
Pair.of("L", "0.00%"),
|
|
Pair.of("L", "0.00%"),
|
|
|
Pair.of("M", "0.00%")
|
|
Pair.of("M", "0.00%")
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "bl1eL2", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "bl1eL2", rowNum, rows,
|
|
|
2, styles, null, null);
|
|
2, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4347,7 +4346,7 @@ public class DataDashboardService {
|
|
|
Pair.of("Q", "0.00%"),
|
|
Pair.of("Q", "0.00%"),
|
|
|
Pair.of("R", "0%")
|
|
Pair.of("R", "0%")
|
|
|
);
|
|
);
|
|
|
- doSendFeishuSheet(dateStrList, dailyDetailSheetToken, "0Lwz8A", rowNum, rows,
|
|
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestAccessToken(), dateStrList, dailyDetailSheetToken, "0Lwz8A", rowNum, rows,
|
|
|
2, styles, null, null);
|
|
2, styles, null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4455,4 +4454,319 @@ public class DataDashboardService {
|
|
|
bd = bd.setScale(places, RoundingMode.HALF_UP);
|
|
bd = bd.setScale(places, RoundingMode.HALF_UP);
|
|
|
return bd.doubleValue();
|
|
return bd.doubleValue();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ @XxlJob("contentSupplyAndDemandDashBoardJob")
|
|
|
|
|
+ public ReturnT<String> contentSupplyAndDemandDashBoardJob(String param) {
|
|
|
|
|
+ List<String> dateStrList = DateUtils.getBeforeDays(null, null, 1);
|
|
|
|
|
+ contentSupplyAndDemandDashBoard(dateStrList);
|
|
|
|
|
+ return ReturnT.SUCCESS;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void contentSupplyAndDemandDashBoard(String dateStr) {
|
|
|
|
|
+ if (!StringUtils.hasText(dateStr)) {
|
|
|
|
|
+ dateStr = DateUtils.getBeforeDaysDateStr("yyyyMMdd", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ contentSupplyAndDemandDashBoard(Collections.singletonList(dateStr));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void contentSupplyAndDemandDashBoard(List<String> dateStrList) {
|
|
|
|
|
+ List<LongArticlesSupplyAndDemandExport> exportList = new ArrayList<>();
|
|
|
|
|
+ dateStrList = Lists.reverse(dateStrList);
|
|
|
|
|
+ for (String dateStr : dateStrList) {
|
|
|
|
|
+ exportList.addAll(buildContentSupplyAndDemandExport(dateStr));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (CollectionUtil.isEmpty(exportList)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ int rowNum = exportList.size();
|
|
|
|
|
+ List<List<Object>> rows = new ArrayList<>();
|
|
|
|
|
+ Field[] fields = LongArticlesSupplyAndDemandExport.class.getDeclaredFields();
|
|
|
|
|
+ for (LongArticlesSupplyAndDemandExport datum : exportList) {
|
|
|
|
|
+ List<Object> rowDatas = new ArrayList<>();
|
|
|
|
|
+ rows.add(rowDatas);
|
|
|
|
|
+
|
|
|
|
|
+ for (Field field : fields) {
|
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ rowDatas.add(field.get(datum));
|
|
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
|
|
+ log.error("获取值出错:{}", field.getName());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new RuntimeException(e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<Pair<String, String>> styles = Arrays
|
|
|
|
|
+ .asList(
|
|
|
|
|
+ Pair.of("E", "0.00%"),
|
|
|
|
|
+ Pair.of("G", "0.00%"),
|
|
|
|
|
+ Pair.of("K", "0.00%"),
|
|
|
|
|
+ Pair.of("M", "0.00%"),
|
|
|
|
|
+ Pair.of("N", "0.00%"),
|
|
|
|
|
+ Pair.of("O", "0.00%")
|
|
|
|
|
+ );
|
|
|
|
|
+ doSendFeishuSheet(FeiShu.requestPQAccessToken(), dateStrList, "FD47w23TaiITHSkKCmqcM85FnBd", "fd59c2", rowNum, rows,
|
|
|
|
|
+ 2, styles, null, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<LongArticlesSupplyAndDemandExport> buildContentSupplyAndDemandExport(String dateStr) {
|
|
|
|
|
+ List<LongArticlesSupplyAndDemandExport> result = new ArrayList<>();
|
|
|
|
|
+ Long start = DateUtils.getStartOfDay(dateStr, "yyyyMMdd") * 1000;
|
|
|
|
|
+ Long end = start + 86400000;
|
|
|
|
|
+
|
|
|
|
|
+ // 定义固定的15个品类
|
|
|
|
|
+ List<String> categoryList = Arrays.asList(
|
|
|
|
|
+ "知识科普", "军事历史", "家长里短", "社会法治", "奇闻趣事",
|
|
|
|
|
+ "名人八卦", "健康养生", "情感故事", "国家大事", "现代人物",
|
|
|
|
|
+ "怀旧时光", "政治新闻", "历史人物", "社会现象", "财经科技"
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 查询头条生成计划 plan_tag='autoArticlePoolLevel1'
|
|
|
|
|
+ List<ProducePlan> firstLevelPlans = producePlanRepository.findByPlanTagLike("autoArticlePoolLevel1");
|
|
|
|
|
+ List<String> firstLevelPlanIds = firstLevelPlans.stream().map(ProducePlan::getId).collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 根据生成计划查询所有内容 produce_plan_exe_record
|
|
|
|
|
+ List<ProducePlanExeRecord> exeRecordList = aigcBaseMapper.getAllPassContentByProducePlanId(firstLevelPlanIds);
|
|
|
|
|
+ List<String> planExeIds = exeRecordList.stream()
|
|
|
|
|
+ .map(ProducePlanExeRecord::getPlanExeId).collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 视频审核过滤 - 分批查询审核通过的内容
|
|
|
|
|
+ Set<String> auditPassContentIds = new HashSet<>();
|
|
|
|
|
+ if (CollectionUtils.isNotEmpty(planExeIds)) {
|
|
|
|
|
+ for (List<String> partition : Lists.partition(planExeIds, 1000)) {
|
|
|
|
|
+ List<LongArticleTitleAudit> auditList = longArticleTitleAuditRepository
|
|
|
|
|
+ .getByContentIdInAndStatus(partition, ArticleVideoAuditStatusEnum.PASS.getCode());
|
|
|
|
|
+ auditPassContentIds.addAll(auditList.stream()
|
|
|
|
|
+ .map(LongArticleTitleAudit::getContentId)
|
|
|
|
|
+ .collect(Collectors.toSet()));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 根据审核通过的内容ID查询内容标题(用于后续去重)
|
|
|
|
|
+ Map<String, String> contentIdTitleMap = new HashMap<>();
|
|
|
|
|
+ if (CollectionUtils.isNotEmpty(auditPassContentIds)) {
|
|
|
|
|
+ List<String> auditPassContentIdList = new ArrayList<>(auditPassContentIds);
|
|
|
|
|
+ for (List<String> partition : Lists.partition(auditPassContentIdList, 1000)) {
|
|
|
|
|
+ List<ProduceContentDTO> contentList = aigcBaseMapper.getProduceContentByPlanExeIds(partition);
|
|
|
|
|
+ contentIdTitleMap.putAll(contentList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(ProduceContentDTO::getPlanExeId, ProduceContentDTO::getTitle, (a, b) -> a)));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 查询所有内容品类 - 使用内容ID分批查询
|
|
|
|
|
+ List<ArticleCategory> articleCategoryList = new ArrayList<>();
|
|
|
|
|
+ if (CollectionUtils.isNotEmpty(auditPassContentIds)) {
|
|
|
|
|
+ List<String> auditPassContentIdList = new ArrayList<>(auditPassContentIds);
|
|
|
|
|
+ for (List<String> partition : Lists.partition(auditPassContentIdList, 1000)) {
|
|
|
|
|
+ articleCategoryList.addAll(articleCategoryRepository.getByProduceContentIdInAndVersionAndStatus(
|
|
|
|
|
+ partition, activeVersion, ArticleCategoryStatusEnum.SUCCESS.getCode()));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, ArticleCategory> categoryMap = articleCategoryList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(ArticleCategory::getProduceContentId, Function.identity(), (a, b) -> a));
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 计算头条内容池量(历史所有审核通过的内容,按品类分组)
|
|
|
|
|
+ Map<String, Long> categoryPoolCountMap = new HashMap<>();
|
|
|
|
|
+ Map<String, Set<String>> categoryPoolTitleSetMap = new HashMap<>();
|
|
|
|
|
+ for (String category : categoryList) {
|
|
|
|
|
+ categoryPoolCountMap.put(category, 0L);
|
|
|
|
|
+ categoryPoolTitleSetMap.put(category, new HashSet<>());
|
|
|
|
|
+ }
|
|
|
|
|
+ long totalFirstLevelContentPoolCount = 0L;
|
|
|
|
|
+ Set<String> totalPoolTitleSet = new HashSet<>();
|
|
|
|
|
+
|
|
|
|
|
+ for (String contentId : auditPassContentIds) {
|
|
|
|
|
+ ArticleCategory articleCategory = categoryMap.get(contentId);
|
|
|
|
|
+ if (Objects.isNull(articleCategory)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String category = articleCategory.getCategory();
|
|
|
|
|
+ if (!categoryPoolCountMap.containsKey(category)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 不去重计数
|
|
|
|
|
+ categoryPoolCountMap.put(category, categoryPoolCountMap.get(category) + 1);
|
|
|
|
|
+ totalFirstLevelContentPoolCount++;
|
|
|
|
|
+ // 去重计数(按标题)
|
|
|
|
|
+ String contentTitle = contentIdTitleMap.get(contentId);
|
|
|
|
|
+ if (StringUtils.hasText(contentTitle)) {
|
|
|
|
|
+ categoryPoolTitleSetMap.get(category).add(contentTitle);
|
|
|
|
|
+ totalPoolTitleSet.add(contentTitle);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 查询当日发送条数、品类 datastat_sort_strategy
|
|
|
|
|
+ List<DatastatSortStrategy> sortStrategyList = datastatSortStrategyRepository.getByDateStrAndPositionEquals(dateStr, 1);
|
|
|
|
|
+ List<DatastatSortStrategy> firstLevelSortList = sortStrategyList.stream()
|
|
|
|
|
+ .filter(o -> Objects.equals(o.getPosition(), 1))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 8. 按品类分组统计当日发送数据
|
|
|
|
|
+ Map<String, LongArticlesSupplyAndDemandExport> categoryExportMap = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 初始化所有品类
|
|
|
|
|
+ for (String category : categoryList) {
|
|
|
|
|
+ LongArticlesSupplyAndDemandExport export = new LongArticlesSupplyAndDemandExport();
|
|
|
|
|
+ export.setDateStr(dateStr);
|
|
|
|
|
+ export.setCategory(category);
|
|
|
|
|
+ // 头条内容池量 - 来自历史所有审核通过的内容
|
|
|
|
|
+ export.setFirstLevelContentPoolCount(categoryPoolCountMap.get(category));
|
|
|
|
|
+ export.setFirstLevelContentPoolDedupCount((long) categoryPoolTitleSetMap.get(category).size());
|
|
|
|
|
+ export.setReadCount(0L);
|
|
|
|
|
+ export.setPushFansCount(0L);
|
|
|
|
|
+ export.setPushReadCount(0L);
|
|
|
|
|
+ export.setPublishCount(0L);
|
|
|
|
|
+ categoryExportMap.put(category, export);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 总量统计
|
|
|
|
|
+ long totalReadCount = 0L;
|
|
|
|
|
+ long totalPublishCount = 0L;
|
|
|
|
|
+ long totalFansCount = 0L;
|
|
|
|
|
+
|
|
|
|
|
+ for (DatastatSortStrategy item : firstLevelSortList) {
|
|
|
|
|
+ // 获取品类
|
|
|
|
|
+ String category = item.getCategory();
|
|
|
|
|
+ if (!categoryExportMap.containsKey(category)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LongArticlesSupplyAndDemandExport export = categoryExportMap.get(category);
|
|
|
|
|
+
|
|
|
|
|
+ // 累计发布条数
|
|
|
|
|
+ export.setPublishCount(export.getPublishCount() + 1);
|
|
|
|
|
+ totalPublishCount++;
|
|
|
|
|
+
|
|
|
|
|
+ // 阅读量
|
|
|
|
|
+ if (Objects.nonNull(item.getViewCount())) {
|
|
|
|
|
+ export.setReadCount(export.getReadCount() + item.getViewCount());
|
|
|
|
|
+ totalReadCount += item.getViewCount();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 粉丝量
|
|
|
|
|
+ if (Objects.nonNull(item.getFans())) {
|
|
|
|
|
+ export.setPushFansCount(export.getPushFansCount() + item.getFans());
|
|
|
|
|
+ totalFansCount += item.getFans();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // push阅读量 = 首层阅读
|
|
|
|
|
+ if (Objects.nonNull(item.getFirstLevel())) {
|
|
|
|
|
+ export.setPushReadCount(export.getPushReadCount() + item.getFirstLevel());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 9. 计算各项比率并设置分析字段
|
|
|
|
|
+ List<LongArticlesSupplyAndDemandExport> categoryResultList = new ArrayList<>();
|
|
|
|
|
+ for (String category : categoryList) {
|
|
|
|
|
+ LongArticlesSupplyAndDemandExport export = categoryExportMap.get(category);
|
|
|
|
|
+
|
|
|
|
|
+ // 头条内容池占比
|
|
|
|
|
+ if (totalFirstLevelContentPoolCount > 0) {
|
|
|
|
|
+ export.setFirstLevelContentPoolRate(export.getFirstLevelContentPoolCount() * 1.0 / totalFirstLevelContentPoolCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 消费占比
|
|
|
|
|
+ if (totalReadCount > 0) {
|
|
|
|
|
+ export.setConsumptionRate(export.getReadCount() * 1.0 / totalReadCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 发布条数占比
|
|
|
|
|
+ if (totalPublishCount > 0) {
|
|
|
|
|
+ export.setPublishCountRate(export.getPublishCount() * 1.0 / totalPublishCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // push粉丝量占比
|
|
|
|
|
+ if (totalFansCount > 0) {
|
|
|
|
|
+ export.setPushFansCountRate(export.getPushFansCount() * 1.0 / totalFansCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // push阅读率
|
|
|
|
|
+ if (Objects.nonNull(export.getPushFansCount()) && export.getPushFansCount() > 0) {
|
|
|
|
|
+ export.setPushReadRate(export.getPushReadCount() * 1.0 / export.getPushFansCount());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 供需比 = 头条内容池占比/(消费占比+0.001)
|
|
|
|
|
+ if (Objects.nonNull(export.getFirstLevelContentPoolRate()) && Objects.nonNull(export.getConsumptionRate())) {
|
|
|
|
|
+ export.setSupplyDemandRate(export.getFirstLevelContentPoolRate() / (export.getConsumptionRate() + 0.001));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 需曝比 = 消费占比/push粉丝量占比
|
|
|
|
|
+ if (Objects.nonNull(export.getConsumptionRate()) && Objects.nonNull(export.getPushFansCountRate()) && export.getPushFansCountRate() > 0) {
|
|
|
|
|
+ export.setDemandExposureRate(export.getConsumptionRate() / export.getPushFansCountRate());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 供需分析
|
|
|
|
|
+ if (Objects.nonNull(export.getSupplyDemandRate())) {
|
|
|
|
|
+ if (export.getSupplyDemandRate() >= 1.1) {
|
|
|
|
|
+ export.setSupplyDemandAnalysis("供给足");
|
|
|
|
|
+ } else if (export.getSupplyDemandRate() <= 0.9) {
|
|
|
|
|
+ export.setSupplyDemandAnalysis("供给缺");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ export.setSupplyDemandAnalysis("供需平衡");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // push质量分析
|
|
|
|
|
+ if (Objects.nonNull(export.getPushReadRate())) {
|
|
|
|
|
+ double ratePercent = export.getPushReadRate() * 100;
|
|
|
|
|
+ if (ratePercent >= 0.75) {
|
|
|
|
|
+ export.setPushQualityAnalysis("高质量");
|
|
|
|
|
+ } else if (ratePercent >= 0.5) {
|
|
|
|
|
+ export.setPushQualityAnalysis("中质量");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ export.setPushQualityAnalysis("低质量");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 供需举措
|
|
|
|
|
+ StringBuilder action = new StringBuilder();
|
|
|
|
|
+ if ("低质量".equals(export.getPushQualityAnalysis())) {
|
|
|
|
|
+ action.append("提质");
|
|
|
|
|
+ } else if ("高质量".equals(export.getPushQualityAnalysis())) {
|
|
|
|
|
+ action.append("保质");
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("供给足".equals(export.getSupplyDemandAnalysis())) {
|
|
|
|
|
+ action.append("保持供给");
|
|
|
|
|
+ } else if ("供给缺".equals(export.getSupplyDemandAnalysis())) {
|
|
|
|
|
+ action.append("提供给");
|
|
|
|
|
+ }
|
|
|
|
|
+ export.setSupplyDemandAction(action.toString());
|
|
|
|
|
+
|
|
|
|
|
+ categoryResultList.add(export);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 10. 构建SUM记录
|
|
|
|
|
+ LongArticlesSupplyAndDemandExport sumExport = buildSumExport(dateStr, categoryResultList);
|
|
|
|
|
+ sumExport.setFirstLevelContentPoolCount(totalFirstLevelContentPoolCount);
|
|
|
|
|
+ sumExport.setFirstLevelContentPoolDedupCount((long) totalPoolTitleSet.size());
|
|
|
|
|
+ sumExport.setReadCount(totalReadCount);
|
|
|
|
|
+ sumExport.setPushFansCount(totalFansCount);
|
|
|
|
|
+ sumExport.setPublishCount(totalPublishCount);
|
|
|
|
|
+ if (totalFansCount > 0) {
|
|
|
|
|
+ sumExport.setPushReadRate(sumExport.getPushReadCount() * 1.0 / totalFansCount);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 需曝比 = 消费占比/push粉丝量占比,SUM记录都为1.0
|
|
|
|
|
+ sumExport.setDemandExposureRate(1.0);
|
|
|
|
|
+
|
|
|
|
|
+ result.addAll(categoryResultList);
|
|
|
|
|
+ result.add(sumExport);
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private LongArticlesSupplyAndDemandExport buildSumExport(String dateStr, List<LongArticlesSupplyAndDemandExport> categoryResultList) {
|
|
|
|
|
+ LongArticlesSupplyAndDemandExport sumExport = new LongArticlesSupplyAndDemandExport();
|
|
|
|
|
+ sumExport.setDateStr(dateStr);
|
|
|
|
|
+ sumExport.setCategory("SUM");
|
|
|
|
|
+ sumExport.setFirstLevelContentPoolRate(1.0);
|
|
|
|
|
+ sumExport.setConsumptionRate(1.0);
|
|
|
|
|
+ sumExport.setSupplyDemandRate(1.0);
|
|
|
|
|
+ sumExport.setPublishCountRate(1.0);
|
|
|
|
|
+ sumExport.setPushFansCountRate(1.0);
|
|
|
|
|
+ sumExport.setPushReadCount(categoryResultList.stream()
|
|
|
|
|
+ .mapToLong(e -> Objects.nonNull(e.getPushReadCount()) ? e.getPushReadCount() : 0L).sum());
|
|
|
|
|
+
|
|
|
|
|
+ return sumExport;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|