|
@@ -639,15 +639,21 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
private static final String MATCH_METHOD_PRIOR_SCENE = "场景已看视频";
|
|
private static final String MATCH_METHOD_PRIOR_SCENE = "场景已看视频";
|
|
|
/** match_method 取值,prior / posterior 池识别用 */
|
|
/** match_method 取值,prior / posterior 池识别用 */
|
|
|
private static final String MATCH_METHOD_PRIOR = "视频库_解构特征_向量相似匹配";
|
|
private static final String MATCH_METHOD_PRIOR = "视频库_解构特征_向量相似匹配";
|
|
|
- /** prior/posterior 池视频近 7 日 rov 下限(质量过滤):0.02 在 prior 池 0513 全量保留 ~41%,
|
|
|
|
|
- * cdjh 优质相似 0514 验证保留 ~54%,量大有意义;
|
|
|
|
|
- * priorScene 池基数小(单 channel 几十~百条),仍保持 >0(在 groupAndTopK 内兜底)。 */
|
|
|
|
|
- private static final double DEMAND_MIN_ROV = 0.02;
|
|
|
|
|
|
|
+ /** prior/posterior 池视频近 7 日 rov 下限(质量过滤):统一与 priorScene sceneSumRov 一致,0.03。 */
|
|
|
|
|
+ private static final double DEMAND_MIN_ROV = 0.03;
|
|
|
|
|
+ /** priorScene 池(场景已看视频)的 sceneSumRov 下限(质量过滤):与 rov 下限同口径 0.03。 */
|
|
|
|
|
+ private static final double PRIOR_SCENE_MIN_SUM_ROV = 0.03;
|
|
|
/** channel_name 映射:企微/小程序 type 直推,公众号入口按 ghName 反查 demand 表(见 resolveChannelName)。 */
|
|
/** channel_name 映射:企微/小程序 type 直推,公众号入口按 ghName 反查 demand 表(见 resolveChannelName)。 */
|
|
|
private static final String CHANNEL_NAME_QW = "群/企微合作-稳定";
|
|
private static final String CHANNEL_NAME_QW = "群/企微合作-稳定";
|
|
|
private static final String CHANNEL_NAME_XCX = "小程序投流-稳定";
|
|
private static final String CHANNEL_NAME_XCX = "小程序投流-稳定";
|
|
|
|
|
+ private static final String CHANNEL_NAME_GZH_TOULIU = "公众号投流-稳定";
|
|
|
private static final String CHANNEL_NAME_GZH_JIZHUAN = "公众号合作-即转-稳定";
|
|
private static final String CHANNEL_NAME_GZH_JIZHUAN = "公众号合作-即转-稳定";
|
|
|
private static final String CHANNEL_NAME_GZH_DAILY = "公众号合作-Daily-自选";
|
|
private static final String CHANNEL_NAME_GZH_DAILY = "公众号合作-Daily-自选";
|
|
|
|
|
+ /** 搜索入口仅对这两个渠道放开:小程序投流(按人群包)+ 公众号投流-稳定(按公众号)。 */
|
|
|
|
|
+ private static final Set<String> CHANNELS_ALLOW_SEARCH = new HashSet<>(Arrays.asList(
|
|
|
|
|
+ CHANNEL_NAME_XCX, CHANNEL_NAME_GZH_TOULIU));
|
|
|
|
|
+ /** 搜索入口仅对 INTERNAL(2 自营)/ AGENT(3 代理) 类型账号放开。 */
|
|
|
|
|
+ private static final Set<Integer> USER_TYPES_ALLOW_SEARCH = new HashSet<>(Arrays.asList(2, 3));
|
|
|
/**
|
|
/**
|
|
|
* 合作类渠道:demand.crowd_segment 语义=合作方代码(yy/szhx/cdjh/...),与登录账号 ContentPlatformAccount.channel 同义,可作为过滤条件。
|
|
* 合作类渠道:demand.crowd_segment 语义=合作方代码(yy/szhx/cdjh/...),与登录账号 ContentPlatformAccount.channel 同义,可作为过滤条件。
|
|
|
* 其余渠道(投流-稳定/服务号投流):demand.crowd_segment 语义=人群分组标签(R50*xx/回流xx),与登录账号合作方无关,绝不可用 user.channel 过滤。
|
|
* 其余渠道(投流-稳定/服务号投流):demand.crowd_segment 语义=人群分组标签(R50*xx/回流xx),与登录账号合作方无关,绝不可用 user.channel 过滤。
|
|
@@ -703,12 +709,28 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 推荐池剔除的 category 列表(身份相关)。
|
|
|
|
|
+ * - 渠道「公众号合作-Daily-自选」:所有身份返回空(白名单语义保留,等价于不做 NOT IN)
|
|
|
|
|
+ * - 其他渠道:内部(2)/代理(3) 仅过滤「节日祝福」;合作方(1)/其他 过滤「早中晚好」+「节日祝福」
|
|
|
|
|
+ * 仅作用于推荐池(selectForRecommend);搜索路径维持现状不做 category 过滤。
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<String> resolveExcludeCategories(String channelName, ContentPlatformAccount user) {
|
|
|
|
|
+ if (CHANNEL_NAME_GZH_DAILY.equals(channelName)) return Collections.emptyList();
|
|
|
|
|
+ Integer type = user == null ? null : user.getType();
|
|
|
|
|
+ boolean privileged = Objects.equals(type, ContentPlatformAccountTypeEnum.INTERNAL.getVal())
|
|
|
|
|
+ || Objects.equals(type, ContentPlatformAccountTypeEnum.AGENT.getVal());
|
|
|
|
|
+ return privileged
|
|
|
|
|
+ ? Collections.singletonList("节日祝福")
|
|
|
|
|
+ : Arrays.asList("早中晚好", "节日祝福");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public Page<VideoContentItemVO> getVideoContentList(VideoContentListParam param) {
|
|
public Page<VideoContentItemVO> getVideoContentList(VideoContentListParam param) {
|
|
|
ContentPlatformAccount user = LoginUserContext.getUser();
|
|
ContentPlatformAccount user = LoginUserContext.getUser();
|
|
|
- // 如果 title 有内容,调用 manager 平台接口搜索
|
|
|
|
|
|
|
+ // title 非空 → 走 demand 池白名单 + 向量召回交集搜索(切掉管理平台关键词 fallback,只对 type∈{2,3} + 投流类渠道放开)
|
|
|
if (StringUtils.hasText(param.getTitle())) {
|
|
if (StringUtils.hasText(param.getTitle())) {
|
|
|
- return getVideoContentListByTitleV2(param);
|
|
|
|
|
|
|
+ return searchByTitleInDemandPool(param, user);
|
|
|
}
|
|
}
|
|
|
String source = param.getSource();
|
|
String source = param.getSource();
|
|
|
if (SOURCE_PRIOR.equalsIgnoreCase(source)) {
|
|
if (SOURCE_PRIOR.equalsIgnoreCase(source)) {
|
|
@@ -1010,14 +1032,15 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
|
|
|
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
|
|
|
+ List<String> excludeCategories = resolveExcludeCategories(channelName, user);
|
|
|
// priorScene 池新识别:demand_strategy='人群需求' AND match_method='场景已看视频'(0519+ 起,旧 demand_strategy='人群需求-场景' 已迁走)
|
|
// priorScene 池新识别:demand_strategy='人群需求' AND match_method='场景已看视频'(0519+ 起,旧 demand_strategy='人群需求-场景' 已迁走)
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
|
|
|
|
|
|
|
+ dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false, excludeCategories);
|
|
|
// 跨渠道退化:仅合作类渠道(企微/即转/Daily-自选)主查 crowd_segment 0 行时去掉合作方代码再试一次,
|
|
// 跨渠道退化:仅合作类渠道(企微/即转/Daily-自选)主查 crowd_segment 0 行时去掉合作方代码再试一次,
|
|
|
// 仍保留 ghName,避免公众号入口结果跨账号串号。投流/服务号类渠道 crowdSegment 已是 null,主查与本路径等价,不会进入。
|
|
// 仍保留 ghName,避免公众号入口结果跨账号串号。投流/服务号类渠道 crowdSegment 已是 null,主查与本路径等价,不会进入。
|
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
|
|
|
|
|
|
|
+ dt, channelName, null, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false, excludeCategories);
|
|
|
}
|
|
}
|
|
|
// 1. 同 video_id 取 total_rov 最大的代表行(SQL 已排序,putIfAbsent 保留首次)
|
|
// 1. 同 video_id 取 total_rov 最大的代表行(SQL 已排序,putIfAbsent 保留首次)
|
|
|
LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
|
|
LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
|
|
@@ -1025,10 +1048,11 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
if (r.getVideoId() == null) continue;
|
|
if (r.getVideoId() == null) continue;
|
|
|
bestPerVideo.putIfAbsent(r.getVideoId(), r);
|
|
bestPerVideo.putIfAbsent(r.getVideoId(), r);
|
|
|
}
|
|
}
|
|
|
- // 2. 过滤 rov<=0/null
|
|
|
|
|
|
|
+ // 2. 过滤 rov<=0/null,以及 sceneSumRov < PRIOR_SCENE_MIN_SUM_ROV(场景关联弱视频砍掉)
|
|
|
List<ContentPlatformDemandVideo> filtered = new ArrayList<>(bestPerVideo.size());
|
|
List<ContentPlatformDemandVideo> filtered = new ArrayList<>(bestPerVideo.size());
|
|
|
for (ContentPlatformDemandVideo r : bestPerVideo.values()) {
|
|
for (ContentPlatformDemandVideo r : bestPerVideo.values()) {
|
|
|
if (r.getRov() == null || r.getRov() <= 0) continue;
|
|
if (r.getRov() == null || r.getRov() <= 0) continue;
|
|
|
|
|
+ if (r.getSceneSumRov() == null || r.getSceneSumRov() < PRIOR_SCENE_MIN_SUM_ROV) continue;
|
|
|
filtered.add(r);
|
|
filtered.add(r);
|
|
|
}
|
|
}
|
|
|
// 3. 按 sceneSumRov DESC 排序,次级 total_rov DESC
|
|
// 3. 按 sceneSumRov DESC 排序,次级 total_rov DESC
|
|
@@ -1081,13 +1105,14 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
|
|
|
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
|
|
|
+ List<String> excludeCategories = resolveExcludeCategories(channelName, user);
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
|
|
|
|
|
|
|
+ dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false, excludeCategories);
|
|
|
|
|
|
|
|
// 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
// 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
|
|
|
|
|
|
|
+ dt, channelName, null, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false, excludeCategories);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
rows = rows.stream()
|
|
rows = rows.stream()
|
|
@@ -1157,18 +1182,19 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
|
|
|
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
|
|
|
+ List<String> excludeCategories = resolveExcludeCategories(channelName, user);
|
|
|
// posterior 池加 match_method='视频库_解构特征_向量相似匹配' 兜底,防止未来上游对优质相似分量出别的 match_method 值后污染本池
|
|
// posterior 池加 match_method='视频库_解构特征_向量相似匹配' 兜底,防止未来上游对优质相似分量出别的 match_method 值后污染本池
|
|
|
// 优质相似池:drive_dimension_time 一律不限制(含主查与退化路径),避免仅「昨日」窗口召回过少。
|
|
// 优质相似池:drive_dimension_time 一律不限制(含主查与退化路径),避免仅「昨日」窗口召回过少。
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
|
|
|
|
|
|
|
+ dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true, excludeCategories);
|
|
|
|
|
|
|
|
// 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
// 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
|
|
|
|
|
|
|
+ dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true, excludeCategories);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 近 7 日 rov 下限,与 prior 池一致(cdjh 0514 验证 ≥0.02 保留 ~54%)
|
|
|
|
|
|
|
+ // 近 7 日 rov 下限,与 prior 池一致(DEMAND_MIN_ROV,统一到 0.03)
|
|
|
rows = rows.stream()
|
|
rows = rows.stream()
|
|
|
.filter(r -> r.getRov() != null && r.getRov() >= DEMAND_MIN_ROV)
|
|
.filter(r -> r.getRov() != null && r.getRov() >= DEMAND_MIN_ROV)
|
|
|
.collect(Collectors.toList());
|
|
.collect(Collectors.toList());
|
|
@@ -2016,6 +2042,89 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 搜索:在当前入口的 demand 白名单(rov >= 0.03)内做 title LIKE 关键字命中,按 rov DESC 排序。
|
|
|
|
|
+ * 门控:
|
|
|
|
|
+ * - 用户身份 type ∈ {2 自营, 3 代理},否则返回空
|
|
|
|
|
+ * - 渠道 ∈ {小程序投流-稳定, 公众号投流-稳定},否则返回空
|
|
|
|
|
+ * - 小程序投流必填 crowdPackage,公众号投流必填 ghName,否则返回空
|
|
|
|
|
+ * 流程:
|
|
|
|
|
+ * 1. demand 白名单(channel + crowdSegment/channelLevel3 + demand_strategy IN (人群需求,优质相似) + rov>=0.03)
|
|
|
|
|
+ * SQL 已 ORDER BY rov DESC, id ASC
|
|
|
|
|
+ * 2. 同 video_id 去重:putIfAbsent 取 max rov 代表行 —— 与搜索 rov DESC 排序对齐,
|
|
|
|
|
+ * 与 priorScene 池(取 max sceneSumRov 代表行)有意区别;同 dt 内稳定,跨 dt 重灌可能换代表行。
|
|
|
|
|
+ * 3. title.trim().toLowerCase().contains(query) 关键字命中
|
|
|
|
|
+ * 4. 排序:rov DESC,次级 total_rov DESC,score 字段清空避免前端歧义
|
|
|
|
|
+ * 5. 按 pageNum/pageSize 内存切片返回
|
|
|
|
|
+ */
|
|
|
|
|
+ private Page<VideoContentItemVO> searchByTitleInDemandPool(VideoContentListParam param, ContentPlatformAccount user) {
|
|
|
|
|
+ Page<VideoContentItemVO> empty = new Page<>(param.getPageNum(), param.getPageSize());
|
|
|
|
|
+ empty.setTotalSize(0);
|
|
|
|
|
+ empty.setObjs(new ArrayList<>());
|
|
|
|
|
+
|
|
|
|
|
+ if (user == null || !USER_TYPES_ALLOW_SEARCH.contains(user.getType())) {
|
|
|
|
|
+ return empty;
|
|
|
|
|
+ }
|
|
|
|
|
+ String channelName = resolveChannelName(param);
|
|
|
|
|
+ if (channelName == null || !CHANNELS_ALLOW_SEARCH.contains(channelName)) {
|
|
|
|
|
+ return empty;
|
|
|
|
|
+ }
|
|
|
|
|
+ boolean isXcx = CHANNEL_NAME_XCX.equals(channelName);
|
|
|
|
|
+ String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
|
|
|
|
|
+ String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
|
|
|
|
|
+ if (isXcx && crowdPackage == null) return empty;
|
|
|
|
|
+ if (!isXcx && ghName == null) return empty;
|
|
|
|
|
+
|
|
|
|
|
+ String kw = param.getTitle() == null ? "" : param.getTitle().trim().toLowerCase();
|
|
|
|
|
+ if (kw.isEmpty()) return empty;
|
|
|
|
|
+
|
|
|
|
|
+ String dt = demandVideoMapperExt.getMaxDt(channelName);
|
|
|
|
|
+ if (!StringUtils.hasText(dt)) return empty;
|
|
|
|
|
+
|
|
|
|
|
+ List<ContentPlatformDemandVideo> whitelist = demandVideoMapperExt.selectSearchWhitelist(
|
|
|
|
|
+ dt, channelName, isXcx ? crowdPackage : null, isXcx ? null : ghName);
|
|
|
|
|
+ if (CollectionUtils.isEmpty(whitelist)) return empty;
|
|
|
|
|
+
|
|
|
|
|
+ // SQL 已 ORDER BY rov DESC,putIfAbsent 即拿到 max rov 代表行(设计意图:与排序键一致)
|
|
|
|
|
+ LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
|
|
|
|
|
+ for (ContentPlatformDemandVideo r : whitelist) {
|
|
|
|
|
+ if (r.getVideoId() == null) continue;
|
|
|
|
|
+ bestPerVideo.putIfAbsent(r.getVideoId(), r);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<VideoContentItemVO> hits = new ArrayList<>();
|
|
|
|
|
+ for (ContentPlatformDemandVideo demand : bestPerVideo.values()) {
|
|
|
|
|
+ if (demand.getTitle() == null) continue;
|
|
|
|
|
+ if (!demand.getTitle().toLowerCase().contains(kw)) continue;
|
|
|
|
|
+ VideoContentItemVO vo = buildDemandVideoContentItemVOList(Collections.singletonList(demand)).get(0);
|
|
|
|
|
+ vo.setSearchSource("keyword");
|
|
|
|
|
+ vo.setScore(null);
|
|
|
|
|
+ hits.add(vo);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (hits.isEmpty()) return empty;
|
|
|
|
|
+
|
|
|
|
|
+ // rov DESC,次级 total_rov DESC 作稳定兜底
|
|
|
|
|
+ hits.sort((a, b) -> {
|
|
|
|
|
+ double ra = a.getRov() == null ? 0d : a.getRov();
|
|
|
|
|
+ double rb = b.getRov() == null ? 0d : b.getRov();
|
|
|
|
|
+ int c = Double.compare(rb, ra);
|
|
|
|
|
+ if (c != 0) return c;
|
|
|
|
|
+ double ta = a.getTotalRov() == null ? 0d : a.getTotalRov();
|
|
|
|
|
+ double tb = b.getTotalRov() == null ? 0d : b.getTotalRov();
|
|
|
|
|
+ return Double.compare(tb, ta);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ int pageNum = Math.max(1, param.getPageNum());
|
|
|
|
|
+ int pageSize = param.getPageSize() > 0 ? param.getPageSize() : 10;
|
|
|
|
|
+ Page<VideoContentItemVO> page = new Page<>(pageNum, pageSize);
|
|
|
|
|
+ page.setTotalSize(hits.size());
|
|
|
|
|
+ int from = Math.min((pageNum - 1) * pageSize, hits.size());
|
|
|
|
|
+ int to = Math.min(pageNum * pageSize, hits.size());
|
|
|
|
|
+ page.setObjs(new ArrayList<>(hits.subList(from, to)));
|
|
|
|
|
+ return page;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private List<VideoContentItemVO> buildDemandVideoContentItemVOList(List<ContentPlatformDemandVideo> videoList) {
|
|
private List<VideoContentItemVO> buildDemandVideoContentItemVOList(List<ContentPlatformDemandVideo> videoList) {
|
|
|
if (CollectionUtils.isEmpty(videoList)) {
|
|
if (CollectionUtils.isEmpty(videoList)) {
|
|
|
return new ArrayList<>();
|
|
return new ArrayList<>();
|