|
|
@@ -116,16 +116,17 @@ public class GzhReplyVideoRefreshJob {
|
|
|
if (ghDetail == null) {
|
|
|
return;
|
|
|
}
|
|
|
- Map<String, Long> creativeIdTextMap = analysisImageText(costDataList);
|
|
|
- log.info("GzhReplyVideoRefreshJob creativeIdTextMap:{}", JSONObject.toJSONString(creativeIdTextMap));
|
|
|
+ Map<String, JSONObject> creativeIdTextMap = analysisImageText(costDataList);
|
|
|
+ log.info("GzhReplyVideoRefreshJob accountName:{} creativeIdTextMap:{}", accountName, JSONObject.toJSONString(creativeIdTextMap));
|
|
|
// 按cost排序 获取top2内容
|
|
|
- List<String> sortedList = creativeIdTextMap.entrySet().stream()
|
|
|
- .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
|
|
|
+ List<JSONObject> sortedList = creativeIdTextMap.entrySet().stream()
|
|
|
+ .sorted((o1, o2) -> o2.getValue().getLong("cost").compareTo(o1.getValue().getLong("cost")))
|
|
|
.limit(topNum)
|
|
|
- .map(Map.Entry::getKey)
|
|
|
+ .map(Map.Entry::getValue)
|
|
|
.collect(Collectors.toList());
|
|
|
List<VideoDetail> searchVideos = new ArrayList<>();
|
|
|
- for (String text : sortedList) {
|
|
|
+ for (JSONObject obj : sortedList) {
|
|
|
+ String text = obj.getString("title");
|
|
|
// 提取关键词
|
|
|
String keywordPrompt =
|
|
|
"你是一位精通算法推荐逻辑的世界级短视频SEO专家。你擅长从标题中提炼出搜索量最大、用户意图最明确的“核心流量词”。\n" +
|
|
|
@@ -157,9 +158,11 @@ public class GzhReplyVideoRefreshJob {
|
|
|
AIResult aiResult = deepSeekApiService.requestOfficialApi(keywordPrompt, null, null, false);
|
|
|
if (aiResult.isSuccess()) {
|
|
|
List<String> keywords = JSONObject.parseArray(aiResult.getResponse().getChoices().get(0).getMessage().getContent(), String.class);
|
|
|
- log.info("GzhReplyVideoRefreshJob text:{} keywords:{}", text, keywords);
|
|
|
+ log.info("GzhReplyVideoRefreshJob accountName:{} text:{} keywords:{}", accountName, text, keywords);
|
|
|
VideoDetail videoDetail = searchVideoByKeyword(keywords, searchVideos);
|
|
|
if (videoDetail != null) {
|
|
|
+ videoDetail.setTitle(text);
|
|
|
+ videoDetail.setCover(obj.getString("coverImgUrl"));
|
|
|
searchVideos.add(videoDetail);
|
|
|
}
|
|
|
}
|
|
|
@@ -170,28 +173,41 @@ public class GzhReplyVideoRefreshJob {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private Map<String, Long> analysisImageText(List<AdPutCreativeComponentCostData> costDataList) {
|
|
|
- Map<String, Long> creativeIdTextMap = new HashMap<>();
|
|
|
+ private Map<String, JSONObject> analysisImageText(List<AdPutCreativeComponentCostData> costDataList) {
|
|
|
+ Map<String, JSONObject> creativeIdTextMap = new HashMap<>();
|
|
|
for (AdPutCreativeComponentCostData costData : costDataList) {
|
|
|
for (AdPutCreativeComponentCostData.AdPutTencentComponent component : costData.getComponentList()) {
|
|
|
String imageUrl = component.getImageUrl();
|
|
|
- // download & upload to oss
|
|
|
- String fileName = String.format("growth/image/%s_%d.jpg", costData.getCreativeId(), System.currentTimeMillis());
|
|
|
- String ossImageUrl = AliOssFileTool.downloadAndSaveInOSS(fileName, imageUrl, "image/jpeg");
|
|
|
- // 调用gemini-3-pro模型提取图片中的文字
|
|
|
- String prompt = "识别图片里的文字,直接输出图片里的文字标题,但是不要输出图片里右下角的字,比如“点开看看”“看这里”等,仅输出标题,不要有多余的文字输出";
|
|
|
- GoogleLLMResult result = aigcApiService.gemini("gemini-2.0-flash", prompt, Arrays.asList(ossImageUrl));
|
|
|
- String text = result.getResult();
|
|
|
- for (String existText : creativeIdTextMap.keySet()) {
|
|
|
- if (TitleSimilarCheckUtil.isSimilar(text, existText, TitleSimilarCheckUtil.SIMILARITY_THRESHOLD)) {
|
|
|
- text = existText;
|
|
|
- break;
|
|
|
+ try {
|
|
|
+ // download & upload to oss
|
|
|
+ String fileName = String.format("growth/image/%s_%d.jpg", costData.getCreativeId(), System.currentTimeMillis());
|
|
|
+ String ossImageUrl = AliOssFileTool.downloadAndSaveInOSS(fileName, imageUrl, "image/jpeg");
|
|
|
+ // 调用gemini-3-pro模型提取图片中的文字
|
|
|
+ String prompt = "识别图片里的文字,直接输出图片里的文字标题,但是不要输出图片里右下角的字,比如“点开看看”“看这里”等,仅输出标题,不要有多余的文字输出";
|
|
|
+ GoogleLLMResult result = aigcApiService.gemini("gemini-2.0-flash", prompt, Arrays.asList(ossImageUrl));
|
|
|
+ String text = result.getResult();
|
|
|
+ for (String existText : creativeIdTextMap.keySet()) {
|
|
|
+ if (TitleSimilarCheckUtil.isSimilar(text, existText, TitleSimilarCheckUtil.SIMILARITY_THRESHOLD)) {
|
|
|
+ text = existText;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ JSONObject obj = creativeIdTextMap.getOrDefault(text, new JSONObject());
|
|
|
+ Long cost = obj.getLong("cost");
|
|
|
+ if (Objects.isNull(cost)) {
|
|
|
+ cost = costData.getCost();
|
|
|
+ obj.put("cost", cost);
|
|
|
+ obj.put("title", text);
|
|
|
+ obj.put("coverImgUrl", ossImageUrl);
|
|
|
+ } else {
|
|
|
+ cost += costData.getCost();
|
|
|
+ obj.put("cost", cost);
|
|
|
}
|
|
|
+ creativeIdTextMap.put(text, obj);
|
|
|
+ break;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("GzhReplyVideoRefreshJob analysisImageText error, imageUrl:{}", imageUrl, e);
|
|
|
}
|
|
|
- Long cost = creativeIdTextMap.getOrDefault(text, 0L);
|
|
|
- cost += costData.getCost();
|
|
|
- creativeIdTextMap.put(text, cost);
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
return creativeIdTextMap;
|
|
|
@@ -233,6 +249,8 @@ public class GzhReplyVideoRefreshJob {
|
|
|
}
|
|
|
|
|
|
private void updateVideoReply(GhDetail ghDetail, List<VideoDetail> searchVideos) {
|
|
|
+ log.info("GzhReplyVideoRefreshJob accountName:{} updateVideoReply, oldVideoIds: {}, replaceVideos: {}",
|
|
|
+ ghDetail.getGhName(), ghDetail.getVideoIds(), JSONObject.toJSONString(searchVideos));
|
|
|
GhDetailVo ghDetailVo = new GhDetailVo();
|
|
|
ghDetailVo.setId(ghDetail.getId());
|
|
|
ghDetailVo.setAccountId(ghDetail.getGhId());
|
|
|
@@ -248,11 +266,21 @@ public class GzhReplyVideoRefreshJob {
|
|
|
GhDetailVo.VideoDetail videoDetailVo = new GhDetailVo.VideoDetail();
|
|
|
videoDetailVo.setVideoId(videoDetail.getId());
|
|
|
videoDetailVo.setSort(i + 1);
|
|
|
- videoDetailVo.setTitle(videoDetail.getTitle());
|
|
|
+ videoDetailVo.setTitle(dealTitleLength(videoDetail.getTitle()));
|
|
|
videoDetailVo.setCover(videoDetail.getCover());
|
|
|
videoDetailList.add(videoDetailVo);
|
|
|
}
|
|
|
ghDetailVo.setVideoList(videoDetailList);
|
|
|
ghDetailService.updateDetail(ghDetailVo);
|
|
|
}
|
|
|
+
|
|
|
+ private String dealTitleLength(String title) {
|
|
|
+ if (StringUtils.isBlank(title)) {
|
|
|
+ return title;
|
|
|
+ }
|
|
|
+ if (title.length() > 20) {
|
|
|
+ title = title.substring(0, 19) + "…";
|
|
|
+ }
|
|
|
+ return title;
|
|
|
+ }
|
|
|
}
|