Преглед изворни кода

feat:添加小程序安全视频列表

zhaohaipeng пре 6 дана
родитељ
комит
113faa9996

+ 58 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -103,6 +103,9 @@ public class RecommendService {
     @ApolloJsonValue("${log.upload.field.switch:{}}")
     private Map<String, String> logUploadFieldSwitch;
 
+    @ApolloJsonValue("${special.apptype.set:[]}")
+    private Set<Integer> specialAppTypeSet;
+
     public static final String channelGroupPrefix = "alg_recsys_user_channel_group";
     /**
      * wx_user_info 表信息
@@ -177,6 +180,11 @@ public class RecommendService {
                     && redisTemplate.opsForSet().isMember("special:mid", request.getMid())) {
                 return specialMidRecommend(request);
             }
+
+            if (CollectionUtils.isNotEmpty(specialAppTypeSet) || specialAppTypeSet.contains(request.getAppType())) {
+                return specialAppTypeRecommend(request);
+            }
+
             stopwatch.reset().start();
             RecommendParam param = genRecommendParam(request, recommendType);
             long genRecommendParamTime = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
@@ -363,6 +371,56 @@ public class RecommendService {
                 .build();
     }
 
+    public RecommendResponse specialAppTypeRecommend(RecommendRequest request) {
+        log.info("hit special apptype recommend request={}", JSONUtils.toJson(request));
+        if (request == null) {
+            return RecommendResponse.newBuilder()
+                    .setResult(Result.newBuilder().setCode(1).setMessage("success"))
+                    .build();
+        }
+
+        RecallParam recallParam = new RecallParam();
+        recallParam.setAppType(request.getAppType());
+        recallParam.setMid(request.getMid());
+        recallParam.setAppTypeSpecialRecommend(true);
+        recallParam.setProvince(request.getProvince());
+        recallParam.setCityCode(request.getCityCode());
+        recallParam.setSize(request.getSize());
+
+        RecallResult recallResult = recallService.recall(recallParam);
+
+        RankParam rankParam = new RankParam();
+        rankParam.setRecallResult(recallResult);
+        rankParam.setSize(request.getSize());
+        rankParam.setAppTypeSpecialRecommend(true);
+
+        RankResult rankResult = rankRouter.rank(rankParam);
+
+        if (Objects.isNull(rankResult) || CollectionUtils.isEmpty(rankResult.getVideos())) {
+            return RecommendResponse.newBuilder()
+                    .setResult(Result.newBuilder().setCode(1).setMessage("success"))
+                    .build();
+        }
+
+        // 只返回size条数据
+        List<Video> videos= rankResult.getVideos().subList(0, Math.min(recallParam.getSize(), rankResult.getVideos().size()));
+
+        if (CollectionUtils.isNotEmpty(videos)) {
+            Video lastVideo = videos.get(videos.size() - 1);
+            redisTemplate.opsForValue().set(lastVideo.getLastVideoKey(), String.valueOf(lastVideo.getVideoId()),
+                    1, TimeUnit.DAYS);
+        }
+
+        return RecommendResponse.newBuilder()
+                .setResult(Result.newBuilder().setCode(1).setMessage("success"))
+                .addAllVideo(CommonCollectionUtils.toList(videos, v -> VideoProto.newBuilder()
+                        .setPushFrom(Strings.nullToEmpty(v.getPushFrom()))
+                        .setVideoId(v.getVideoId())
+                        .setRovScore(v.getRovScore())
+                        .build()))
+                .build();
+    }
+
     public RecommendParam genRecommendParam(RecommendRequest request, int recommendType) {
         RecommendParam param = new RecommendParam();
         param.setTopK(3);

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java

@@ -22,6 +22,7 @@ public class RankParam {
     private double flowPoolP;
     private int appType;
     private boolean specialRecommend;
+    private boolean appTypeSpecialRecommend;
     private String mid;
     private String uid;
     private String province;

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java

@@ -26,6 +26,7 @@ public class RecallParam {
     private Long videoId;
     private String uid;
     private boolean specialRecommend;
+    private boolean appTypeSpecialRecommend;
     private Set<String> abExpCodes;
     private Integer categoryId;
 

+ 4 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java

@@ -97,6 +97,10 @@ public class RecallService implements ApplicationContextAware {
             strategies.add(strategyMap.get(SpecialRecallStrategy.class.getSimpleName()));
             return strategies;
         }
+        if (param.isAppTypeSpecialRecommend()){
+            strategies.add(strategyMap.get(AppTypeSpecialRecallStrategy.class.getSimpleName()));
+            return strategies;
+        }
 
         //1:通过“产品”控制“召回子策略”. 票圈美好祝福与内部tab只走祝福召回。APP只走固定列表。特殊配置的app只有固定召回列表。
         if (this.matchSpecialApp(param.getAppType())) {

+ 83 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AppTypeSpecialRecallStrategy.java

@@ -0,0 +1,83 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import com.tzld.piaoquan.recommend.server.util.DateUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ZSetOperations;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+@Slf4j
+@Service
+public class AppTypeSpecialRecallStrategy implements RecallStrategy {
+    @Autowired
+    @Qualifier("redisTemplate")
+    private RedisTemplate<String, String> redisTemplate;
+
+    public static final String LAST_VIDEO_KEY_FORMAT = "recall:apptype:special:%s";
+    public static final String PUSH_FROM = "special_videos";
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        String keyNamePrefix = "apptype:special:videos:item:";
+        String dateStr = DateUtils.getCurrentDateStr("yyyyMMdd");
+        String specialKeyName = keyNamePrefix + dateStr;
+        if (!redisTemplate.hasKey(specialKeyName)) {
+            dateStr = DateUtils.getBeforeDaysDateStr("yyyyMMdd", 1);
+            specialKeyName = keyNamePrefix + dateStr;
+        }
+
+        String recallKey = String.format(LAST_VIDEO_KEY_FORMAT, param.getAppType());
+        String value = redisTemplate.opsForValue().get(recallKey);
+        Long idx = 0L;
+        if (StringUtils.isNotBlank(value)) {
+            idx = redisTemplate.opsForZSet().reverseRank(specialKeyName, value);
+            if (idx == null) {
+                idx = 0L;
+            } else {
+                idx += 1;
+            }
+        }
+
+        int getSize = param.getSize() * 5;
+        int freq = 0;
+        List<Video> results = new ArrayList<>();
+        while (results.size() < param.getSize()) {
+            freq += 1;
+            if (freq > 2) {
+                break;
+            }
+            Set<ZSetOperations.TypedTuple<String>> data = redisTemplate.opsForZSet().reverseRangeWithScores(specialKeyName, idx, idx + getSize - 1);
+            if (CollectionUtils.isEmpty(data)) {
+                break;
+            }
+            idx += getSize;
+            data.forEach(t -> {
+                Video video = new Video();
+                video.setVideoId(NumberUtils.toLong(t.getValue(), 0L));
+                video.setRovScore(t.getScore());
+                video.setPushFrom(PUSH_FROM);
+                video.setLastVideoKey(recallKey);
+                results.add(video);
+            });
+        }
+        return results;
+    }
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+}