Преглед на файлове

企微三方群消息发送增加用户/标签来源实验

wangyunpeng преди 2 седмици
родител
ревизия
8397ce50d8

+ 55 - 0
api-module/src/main/java/com/tzld/piaoquan/api/component/VideoApiService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
 import com.tzld.piaoquan.api.common.exception.CommonException;
 import com.tzld.piaoquan.api.model.vo.contentplatform.WxBaseUserInfoVO;
+import com.tzld.piaoquan.api.model.vo.contentplatform.WxVideoV2VO;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -181,4 +182,58 @@ public class VideoApiService {
         }
     }
 
+    public List<WxVideoV2VO> getUserVideoList(Long uid, List<Long> excludeVideoIds, Integer pageNum, Integer pageSize) {
+        String url = videoApiHost + "/longvideoapi/openapi/video/getUserVideoListAuditPass";
+        JSONObject res = null;
+        try {
+            JSONObject param = new JSONObject();
+            param.put("uid", uid);
+            param.put("excludeVideoIds", excludeVideoIds);
+            param.put("pageNum", pageNum);
+            param.put("pageSize", pageSize);
+            String post = httpPoolClient.post(url, param.toJSONString());
+            res = JSONObject.parseObject(post);
+        } catch (Exception e) {
+            log.error("VideoApiService getUserVideoList error, uid={} excludeVideoIds={} pageNum={} pageSize={}",
+                    uid, excludeVideoIds, pageNum, pageSize, e);
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("VideoApiService getUserVideoList error, uid={} excludeVideoIds={} pageNum={} pageSize={} res={}",
+                    uid, excludeVideoIds, pageNum, pageSize, res);
+            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_DELETE_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONArray("data").toJavaList(WxVideoV2VO.class);
+    }
+
+    public List<WxVideoV2VO> getTagVideoList(String tagName, List<Long> excludeVideoIds, Integer pageNum, Integer pageSize) {
+        String url = videoApiHost + "/longvideoapi/openapi/video/getTagVideoListAuditPass";
+        JSONObject res = null;
+        try {
+            JSONObject param = new JSONObject();
+            param.put("tagName", tagName);
+            param.put("excludeVideoIds", excludeVideoIds);
+            param.put("pageNum", pageNum);
+            param.put("pageSize", pageSize);
+            String post = httpPoolClient.post(url, param.toJSONString());
+            res = JSONObject.parseObject(post);
+        } catch (Exception e) {
+            log.error("VideoApiService getTagVideoList error, tagName={} excludeVideoIds={} pageNum={} pageSize={}",
+                    tagName, excludeVideoIds, pageNum, pageSize, e);
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("VideoApiService getTagVideoList error, tagName={} excludeVideoIds={} pageNum={} pageSize={} res={}",
+                    tagName, excludeVideoIds, pageNum, pageSize, res);
+            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_DELETE_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONArray("data").toJavaList(WxVideoV2VO.class);
+    }
+
 }

+ 82 - 6
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java

@@ -3,6 +3,7 @@ package com.tzld.piaoquan.api.job.wecom.thirdpart;
 import com.alibaba.fastjson.JSONObject;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.tzld.piaoquan.api.component.VideoApiService;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComMsgMapper;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CdnUploadImgLinkRequest;
@@ -13,22 +14,27 @@ import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComMsg;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComMsgExample;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
+import com.tzld.piaoquan.api.model.vo.contentplatform.WxVideoV2VO;
 import com.tzld.piaoquan.api.service.WeComThirdPartyService;
 import com.tzld.piaoquan.api.util.CdnUtil;
 import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
 import com.tzld.piaoquan.growth.common.model.po.Staff;
 import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
+import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.tzld.piaoquan.growth.common.utils.MessageUtil;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -44,6 +50,8 @@ public class WeComSendMsgJob {
     @Autowired
     MessageAttachmentService messageAttachmentService;
     @Autowired
+    VideoApiService videoApiService;
+    @Autowired
     ContentPlatformPlanMapperExt planMapperExt;
     @Autowired
     ThirdPartWeComMsgMapper thirdPartWeComMsgMapper;
@@ -56,6 +64,8 @@ public class WeComSendMsgJob {
     private Integer videoNum;
     @ApolloJsonValue("${send.room.msg.test.roomList:[]}")
     private List<String> testRoomList;
+    @ApolloJsonValue("${send.room.msg.video.source.staff.config:{}}")
+    private Map<Long, JSONObject> videoSourceStaffConfig;
 
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(1000),
@@ -129,7 +139,9 @@ public class WeComSendMsgJob {
             return coverUrl;
         }
         String waterMark = "?x-oss-process=image/resize,m_fill,w_600,h_480,limit_0/format,jpg/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9pY29uX3BsYXlfd2hpdGUucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLHdfMTQ0,g_center";
-        coverUrl = coverUrl.substring(0, coverUrl.indexOf("?"));
+        if (coverUrl.contains("?")) {
+            coverUrl = coverUrl.substring(0, coverUrl.indexOf("?"));
+        }
         return coverUrl + waterMark;
     }
 
@@ -142,11 +154,17 @@ public class WeComSendMsgJob {
         String sort = "datastat.fission_rate desc, video.score desc";
         String type = "企微-社群";
         String channel = "sum";
-        List<ContentPlatformVideo> videoList = planMapperExt.getVideoMinDatastatScoreList(dt, datastatDt,
-                type, channel, videoMinScore, sentVideoIds, 0, 100, sort);
-        // 行业数量不足,按平台推荐top选取视频
-        sort = "video.score desc";
-        videoList.addAll(planMapperExt.getVideoMinScoreList(dt, videoMinScore, sentVideoIds, 0, 100, sort));
+        List<ContentPlatformVideo> videoList = getVideoByStrategy(thirdPartWeComStaff.getThirdStaffId(), dt, datastatDt, type, channel, videoMinScore,
+                sentVideoIds, 1, 100, sort);
+        if (CollectionUtils.isEmpty(videoList)) {
+            LarkRobotUtil.sendWeComThirdPartMessage(
+                    "【账号发送群消息,视频数量不足通知】\n" +
+                            "账号名称:" + thirdPartWeComStaff.getName() + "\n" +
+                            "账号VID:" + thirdPartWeComStaff.getThirdStaffId() + "\n" +
+                            "群ID:" + roomId + "\n" +
+                            "账号配置:" + videoSourceStaffConfig.get(thirdPartWeComStaff.getId()));
+            return Collections.emptyList();
+        }
         List<CgiReplyBucketData> result = new ArrayList<>();
         for (int i = 0; i < videoNum; i++) {
             ContentPlatformVideo video = videoList.get(i);
@@ -165,6 +183,64 @@ public class WeComSendMsgJob {
         return result;
     }
 
+    private List<ContentPlatformVideo> getVideoByStrategy(Long staffId,
+                                                          String dt,
+                                                          String datastatDt,
+                                                          String type,
+                                                          String channel,
+                                                          Double videoMinScore,
+                                                          List<Long> sentVideoIds,
+                                                          int pageNum,
+                                                          int pageSize,
+                                                          String sort) {
+        List<ContentPlatformVideo> result = new ArrayList<>();
+        JSONObject staffConfig = videoSourceStaffConfig.get(staffId);
+        if (staffConfig == null) {
+            staffConfig = new JSONObject();
+        }
+        List<ContentPlatformVideo> videoList;
+        String source = (String) staffConfig.getOrDefault("source", "");
+        switch (source) {
+            case "user":
+                Long uid = staffConfig.getLong("uid");
+                List<WxVideoV2VO> list = videoApiService.getUserVideoList(uid, sentVideoIds, pageNum, pageSize);
+                if (CollectionUtils.isEmpty(list)) {
+                    break;
+                }
+                videoList = convertWxVideoV2VOToVideo(list);
+                result.addAll(videoList);
+                break;
+            case "tag":
+                String tagName = staffConfig.getString("tagName");
+                list = videoApiService.getTagVideoList(tagName, sentVideoIds, pageNum, pageSize);
+                if (CollectionUtils.isEmpty(list)) {
+                    break;
+                }
+                videoList = convertWxVideoV2VOToVideo(list);
+                result.addAll(videoList);
+                break;
+            default:
+                result = planMapperExt.getVideoMinDatastatScoreList(dt, datastatDt,
+                        type, channel, videoMinScore, sentVideoIds, 0, 100, sort);
+                // 行业数量不足,按平台推荐top选取视频
+                sort = "video.score desc";
+                result.addAll(planMapperExt.getVideoMinScoreList(dt, videoMinScore, sentVideoIds, 0, 100, sort));
+        }
+        return result;
+    }
+
+    private List<ContentPlatformVideo> convertWxVideoV2VOToVideo(List<WxVideoV2VO> list) {
+        List<ContentPlatformVideo> result = new ArrayList<>();
+        for (WxVideoV2VO vo : list) {
+            ContentPlatformVideo video = new ContentPlatformVideo();
+            video.setVideoId(vo.getId());
+            video.setTitle(vo.getTitle());
+            video.setCover(vo.getVideoCoverSnapshotPath());
+            result.add(video);
+        }
+        return result;
+    }
+
     private List<Long> getSentVideoIds(Long roomId) {
         ThirdPartWeComMsgExample msgExample = new ThirdPartWeComMsgExample();
         msgExample.createCriteria().andSendUseridEqualTo(roomId)

+ 208 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/contentplatform/WxVideoV2VO.java

@@ -0,0 +1,208 @@
+package com.tzld.piaoquan.api.model.vo.contentplatform;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.Map;
+
+@Data
+public class WxVideoV2VO {
+
+	private Long id;
+	@ApiModelProperty(value = "数据状态,1有效,2 已删除,3 已屏蔽,4关注可见,5分享可见 6自己可见")
+	private Integer status;
+	@ApiModelProperty(value = "视频的用户ID")
+	private Long uid;
+	@ApiModelProperty(value = "视频地址")
+	private String videoPath;
+	@ApiModelProperty(value = "OSS原始的地址")
+	private String ossVideoPath;
+	@ApiModelProperty(value = "播放次数")
+	private Integer playCount;
+	@ApiModelProperty(value = "总播放次数")
+	private Integer playCountTotal;
+	@ApiModelProperty(value = "分享到朋友圈次数")
+	private Integer shareCount;
+	@ApiModelProperty(value = "视频时长")
+	private Integer totalTime;
+	@ApiModelProperty(value = "创建时间")
+	private Date gmtCreate;
+	@ApiModelProperty(value = "修改时间")
+	private Date gmtModifie;
+	@ApiModelProperty(value = "创建时间戳")
+	private Long gmtCreateTimestamp;
+	@ApiModelProperty(value = "修改时间戳")
+	private Long gmtModifiedTimestamp;
+	@ApiModelProperty(value = "转码状态:1-不需转码 2-转码中 3-转码完成 4-转码失败")
+	private Integer transcodeStatus;
+	@ApiModelProperty(value = "视频宽")
+	private Integer width;
+	@ApiModelProperty(value = "视频高")
+	private Integer height;
+	@ApiModelProperty(value = "旋转角度")
+	private String rotate;
+	@ApiModelProperty(value = "视频码率")
+	private Long bitRate;
+	@ApiModelProperty(value = "分享图URL")
+	private String shareImgPath;
+	@ApiModelProperty(value = "分享图ID")
+	private Long shareImgId;
+	@ApiModelProperty(value = "缩略图URL")
+	private String thumbnailImagePath;
+	@ApiModelProperty(value = "视频后缀")
+	private String fileExtensions;
+	@ApiModelProperty(value = "视频标题")
+	private String title;
+	@ApiModelProperty(value = "视频标题ID")
+	private Long titleId;
+	@ApiModelProperty(value = "是否收藏")
+	private Boolean favorited = false;
+	@ApiModelProperty(value = "分享到微信好友")
+	private Integer shareCountFriend;
+	@ApiModelProperty(value = "收藏数")
+	private Long favoriteds;
+	@ApiModelProperty(value = "播放时间")
+	private Long playTime;
+	@ApiModelProperty(value = "播放时间距离今天的天数")
+	private int playBeforeDay;
+	@ApiModelProperty(value = "发视频距离今天的天数")
+	private int sendBeforeDay;
+	@ApiModelProperty(value = "时间戳")
+	private Long lastTimestamp;
+	@ApiModelProperty(value = "发视频时间描述")
+	private String gmtCreateDescr;
+	@ApiModelProperty(value = "分享到微信好友的图片的链接的类型")
+	private Integer shareLinkType;
+	@ApiModelProperty(value = "用户视频总播放数,格式化后的值,前端直接显示")
+	private String playCountFormatStr;
+	@ApiModelProperty(value = "分享到微信好友的图片的title")
+	private String shareTitle;
+	@ApiModelProperty(value = "分享标题的ID")
+	private Long shareTitleId;
+	@ApiModelProperty(value = "内容敏感状态(0:未检验,1:不敏感,2:敏感,3:敏感已审)")
+	private Integer sensitiveStatus;
+	@ApiModelProperty(value = "敏感提示信息")
+	private String sensitiveMsg = "";
+	@ApiModelProperty(value = "是否打开弹幕 1打开  -1关闭")
+	private Integer barrageSwitch = 1;
+	@ApiModelProperty(value = "视频所在的视频集ID")
+	private Long videoCollectionId;
+	@ApiModelProperty(value = "转发分享图URL")
+	private String tabShareImgPath;
+	@ApiModelProperty(value = "h5分享图URL")
+	private String h5ShareImgPath;
+	private Map<String, String> h5ShareImgPathMap;
+	@ApiModelProperty(value = "是否需要显示热门推荐")
+	private Boolean showHotRecommend = true;
+	@ApiModelProperty(value = "评论数量")
+	private Integer commentCount = 0;
+	@ApiModelProperty(value = "弹幕数量")
+	private Integer barrageCount = 0;
+	@ApiModelProperty(value = "大小")
+	private Long size;
+	@ApiModelProperty(value = "视频简介")
+	private String descr;
+	@ApiModelProperty(value = "0非流量池 1曝光池2普通推荐测试池3待推荐测试池")
+	private Integer measureType = 0;
+	@ApiModelProperty(value = "是否加密视频:0是1不是")
+	private Integer encryption =1;
+	@ApiModelProperty(value = "视频密码")
+	private String pwd;
+	@ApiModelProperty(value = "封面是否是第一帧,false不是true是")
+	private boolean firstPicture=false;
+	@ApiModelProperty(value = "原始封面图片")
+	private String videoCoverSnapshotPath;
+	@ApiModelProperty(value = "是否有片尾:0没有,1有")
+	private Integer hasTailVideo = 0;
+	@ApiModelProperty(value = "片尾类型:1下载,2分享 3下载+分享")
+	private Integer tailType = 0;
+	@ApiModelProperty(value = "片尾地址")
+	private String videoTailPath;
+	private Long measureId;
+	private Integer measure = 0;
+
+	// 新加试看视频相关字段
+	// 试看视频的转码
+	private String sampleRequestId;
+	private String sampleJobId;
+	private Integer sampleTranscodeStatus;
+	private String sampleTransedVideoPath;
+	private Integer sampleTotalTime;
+
+	@ApiModelProperty(value = "是否有分发推荐的封面和标题 1 有 0 无 传空或者不传默认为0")
+	private Integer isRecommendShare = 0;
+
+	@ApiModelProperty(value = "0 默认 1 第四范式")
+	private Integer recommendSource = 0;
+	@ApiModelProperty(value = "视频上报数据,上报时原样返回")
+	private String videoReportMeta;
+
+	@ApiModelProperty(value = "审核状态  1 审核中,2 不通过 3 待修改,4 自己可见 5 通过")
+	private Integer auditStatus;
+
+	@ApiModelProperty(value = "App 审核状态  1 审核中,2 不通过 3 待修改,4 自己可见 5 通过")
+	private Integer appAuditStatus;
+
+	@JsonIgnore
+	private String auditTranscationId;
+	@ApiModelProperty(value = "审核不通过或者待修改的原因")
+	private String auditReason;
+
+	@JsonIgnore
+	private Integer videoLevelCode;
+	@ApiModelProperty(value = "0 综合模块 1 feed流 ")
+	private Integer sharePageType;
+	@ApiModelProperty(value = "推荐状态")
+	private Integer recommendStatus;
+	@ApiModelProperty(value = "h5剪切板内容")
+	private String cutVoStr;
+    @ApiModelProperty(value = "推荐链路ID")
+    private String recommendId;
+    @ApiModelProperty(value = "推荐日志对象")
+	private String recommendLogVO;
+	@ApiModelProperty(value = "app的推荐状态")
+    private Integer appRecommendStatus;
+	@ApiModelProperty(value = "乐活圈-推荐状态")
+	private Integer lehuoquanRecommendStatus;
+	@ApiModelProperty(value = "流量池信息,格式:#流量池ID#分级ID#级别Level#生命周期ID")
+	private String flowPool;
+	@ApiModelProperty(value = "是否是RUOV热门标签视频 0 否 1 是")
+	private Integer isTopRUOV = 0;
+	@ApiModelProperty(value = "数据原始状态,1有效,2 已删除,3 已屏蔽,4关注可见,5分享可见 6自己可见")
+	private Integer originalStatus;
+	@ApiModelProperty(value = "冻结状态: -1:无须解冻  0:待解冻  1:解冻中  2:解冻完成")
+	private Integer frozenStatus;
+//	@ApiModelProperty(value = "是否有权限播放高清视频:0 否 1 是")
+//	private Integer hasMultiBitRatePermission;
+//	@ApiModelProperty(value = "多码率信息")
+//	private List<VideoMultiBitRateVO> multiBitRate;
+	@ApiModelProperty(value = "是否是流量池视频 1是 2 否")
+	private Integer isInFlowPool;
+
+	@ApiModelProperty(value = "推荐traceId")
+	private String recomTraceId;
+
+	@ApiModelProperty(value = "是否可以被赞赏,0:否,1:是")
+	private Integer canBeReward = 0;
+	@ApiModelProperty(value = "被赞赏次数")
+	private Integer rewardCount = 0;
+	@ApiModelProperty(value = "是否可以在h5被赞赏,0:否,1:是")
+	private Integer h5CanBeReward = 0;
+
+	@ApiModelProperty(value = "流量类型")
+	private Integer trafficType;
+	@ApiModelProperty(value = "封面流量类型")
+	private Integer coverTrafficType;
+
+	@ApiModelProperty(value = "h265转码地址")
+	private String h265VideoPath;
+	@ApiModelProperty(value = "h265码率")
+	private Long h265BitRate;
+	@ApiModelProperty(value = "AI标识")
+	private Integer aiLevel = 0;
+	@ApiModelProperty(value = "AI视频提示文案")
+	private String aiAlertText;
+
+}