|
|
@@ -644,8 +644,16 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
* priorScene 池基数小(单 channel 几十~百条),仍保持 >0(在 groupAndTopK 内兜底)。 */
|
|
|
private static final double DEMAND_MIN_ROV = 0.02;
|
|
|
/** channel_name 映射:企微/小程序 type 直推,公众号入口按 ghName 反查 demand 表(见 resolveChannelName)。 */
|
|
|
- private static final String CHANNEL_NAME_QW = "群/企微合作-稳定";
|
|
|
- private static final String CHANNEL_NAME_XCX = "小程序投流-稳定";
|
|
|
+ private static final String CHANNEL_NAME_QW = "群/企微合作-稳定";
|
|
|
+ private static final String CHANNEL_NAME_XCX = "小程序投流-稳定";
|
|
|
+ private static final String CHANNEL_NAME_GZH_JIZHUAN = "公众号合作-即转-稳定";
|
|
|
+ private static final String CHANNEL_NAME_GZH_DAILY = "公众号合作-Daily-自选";
|
|
|
+ /**
|
|
|
+ * 合作类渠道:demand.crowd_segment 语义=合作方代码(yy/szhx/cdjh/...),与登录账号 ContentPlatformAccount.channel 同义,可作为过滤条件。
|
|
|
+ * 其余渠道(投流-稳定/服务号投流):demand.crowd_segment 语义=人群分组标签(R50*xx/回流xx),与登录账号合作方无关,绝不可用 user.channel 过滤。
|
|
|
+ */
|
|
|
+ private static final Set<String> CHANNELS_USE_PARTNER_AS_CROWD = new HashSet<>(Arrays.asList(
|
|
|
+ CHANNEL_NAME_QW, CHANNEL_NAME_GZH_JIZHUAN, CHANNEL_NAME_GZH_DAILY));
|
|
|
private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
|
|
|
/** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
|
|
|
* 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
|
|
|
@@ -681,6 +689,20 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 仅对"合作类"渠道(企微/即转/Daily-自选)用 user.channel 作为 demand.crowd_segment 过滤;
|
|
|
+ * 投流/服务号类渠道一律 null(crowd_segment 是人群分组标签,与合作方无关)。
|
|
|
+ * 解决:0526 之前 user.channel 被无条件喂给所有渠道,投流类零命中后触发跨渠道退化,
|
|
|
+ * 退化把 ghName 一并丢掉,导致公众号入口结果串号到其他公众号。
|
|
|
+ */
|
|
|
+ private String resolveCrowdSegment(String channelName, ContentPlatformAccount user) {
|
|
|
+ if (user == null) return null;
|
|
|
+ if (channelName != null && CHANNELS_USE_PARTNER_AS_CROWD.contains(channelName)) {
|
|
|
+ return user.getChannel();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public Page<VideoContentItemVO> getVideoContentList(VideoContentListParam param) {
|
|
|
ContentPlatformAccount user = LoginUserContext.getUser();
|
|
|
@@ -983,7 +1005,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
if (!StringUtils.hasText(dt)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
- String crowdSegment = user.getChannel();
|
|
|
+ String crowdSegment = resolveCrowdSegment(channelName, user);
|
|
|
String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
|
|
|
|
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
|
@@ -991,10 +1013,11 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
// priorScene 池新识别:demand_strategy='人群需求' AND match_method='场景已看视频'(0519+ 起,旧 demand_strategy='人群需求-场景' 已迁走)
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
|
|
|
- // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧渠道下 0 行(如公众号账号切到企微入口)→ 去 crowd_segment,只按 channel_name 拉通用数据
|
|
|
- if (channelName != null && rows.isEmpty()) {
|
|
|
+ // 跨渠道退化:仅合作类渠道(企微/即转/Daily-自选)主查 crowd_segment 0 行时去掉合作方代码再试一次,
|
|
|
+ // 仍保留 ghName,避免公众号入口结果跨账号串号。投流/服务号类渠道 crowdSegment 已是 null,主查与本路径等价,不会进入。
|
|
|
+ if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_PRIOR, null, null, null, null, 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);
|
|
|
}
|
|
|
// 1. 同 video_id 取 total_rov 最大的代表行(SQL 已排序,putIfAbsent 保留首次)
|
|
|
LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
|
|
|
@@ -1052,7 +1075,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
if (!StringUtils.hasText(dt)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
- String crowdSegment = user.getChannel();
|
|
|
+ String crowdSegment = resolveCrowdSegment(channelName, user);
|
|
|
String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
|
|
|
int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
|
|
|
|
|
|
@@ -1061,9 +1084,10 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
|
|
|
|
|
|
- if (channelName != null && rows.isEmpty()) {
|
|
|
+ // 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
|
+ if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_PRIOR, dimension, null, null, null, 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);
|
|
|
}
|
|
|
|
|
|
rows = rows.stream()
|
|
|
@@ -1127,7 +1151,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
if (!StringUtils.hasText(dt)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
- String crowdSegment = user.getChannel();
|
|
|
+ String crowdSegment = resolveCrowdSegment(channelName, user);
|
|
|
String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
|
|
|
int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
|
|
|
|
|
|
@@ -1138,10 +1162,10 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
|
|
|
|
|
|
- // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
|
|
|
- if (channelName != null && rows.isEmpty()) {
|
|
|
+ // 跨渠道退化:见 fetchPriorSceneCandidates 注释。仅合作类渠道触发,保留 ghName 防串号。
|
|
|
+ if (channelName != null && crowdSegment != null && rows.isEmpty()) {
|
|
|
rows = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, 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);
|
|
|
}
|
|
|
|
|
|
// 近 7 日 rov 下限,与 prior 池一致(cdjh 0514 验证 ≥0.02 保留 ~54%)
|