Forráskód Böngészése

一键群发,SOP自动APP发课

wjj 1 napja
szülő
commit
97dd44f335

+ 132 - 0
fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java

@@ -47,6 +47,138 @@ public class IpadSendServer {
     private final RedisCache redisCache;
     private final ICompanyMiniappService companyMiniappService;
 
+    //private final LiveWatchLogMapper liveWatchLogMapper;
+
+
+    /**
+     * 直播间判定消息
+     * @param qwSopLogs
+     * @param setting
+     * @param qwUser
+     * @return
+     */
+    public boolean isSendLogsLive(QwSopLogs qwSopLogs, QwSopCourseFinishTempSetting setting, QwUser qwUser){
+        if(qwSopLogs.getSendStatus() != 3){
+            log.info("直播状态异常不发送:{}, LOGID: {}", qwUser.getQwUserName(), qwSopLogs.getId());
+            return false;
+        }
+        if(redisCache.getCacheObject("qw:user:id:" + qwUser.getId()) != null){
+            log.info("直播频率异常不发送:{}", qwUser.getQwUserName());
+            return false;
+        }
+
+        boolean noSop = qwSopLogs.getSendType() != 3 && qwSopLogs.getSendType() != 7;
+
+        if (qwSopLogs.getExpiryTime() == null && noSop) {
+            // 作废消息
+            log.warn("直播SOP_LOG_ID:{}, 直播SOP任务被删除", qwSopLogs.getId());
+            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "直播SOP任务被删除");
+            return false;
+        }
+
+        LocalDateTime sendTime = DateUtil.stringToLocalDateTime(qwSopLogs.getSendTime());
+        LocalDateTime expiryDateTime;
+
+        // 判断是否过期
+        if(qwSopLogs.getSendType() == 3 || qwSopLogs.getSendType() == 7){
+            expiryDateTime = sendTime.plusHours(12);
+        }else{
+            expiryDateTime = sendTime.plusHours(qwSopLogs.getExpiryTime());
+        }
+
+        if (LocalDateTime.now().isAfter(expiryDateTime)) {
+            // 作废消息
+            log.warn("直播SOP_LOG_ID:{}, 已过期,不发送", qwSopLogs.getId());
+            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "已过期,不发送");
+            return false;
+        }
+
+        if (setting.getCourseType() == null && noSop && setting.getType() == 2) {
+            log.warn("直播SOP_LOG_ID:{}, 模板未选消息类型,不发送", qwSopLogs.getId());
+            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "直播模板未选消息类型,不发送");
+            return false;
+        }
+
+        // 查询视频是否下架
+//        if(setting.getVideoId()!= null){
+//            FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId( setting.getVideoId().longValue());
+//            if(video != null){
+//                if(video.getIsOnPut()!=null && video.getIsOnPut() == 1){
+//                    log.warn("SOP_LOG_ID:{}, 视频已下架,不发送", qwSopLogs.getId());
+//                    qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "视频已下架,不发送");
+//                    return false;
+//                }
+//            }
+//        }
+        Long queryLiveId = null;
+        queryLiveId = setting.getLiveId();
+        if(null == queryLiveId){
+            for (QwSopCourseFinishTempSetting.Setting a : setting.getSetting()) {
+                if (StringUtils.isNotBlank(a.getLiveId())) {
+                    queryLiveId = Long.valueOf(a.getLiveId());
+                    break;
+                }
+            }
+        }
+//        LiveWatchLog liveWatchLog = liveWatchLogMapper.selectOneLogByLiveIdAndQwUserIdAndExternalId(
+//                queryLiveId,
+//                String.valueOf(qwUser.getId()),
+//                qwSopLogs.getExternalId()
+//        );
+        Integer courseType = setting.getCourseType();
+        String logId = qwSopLogs.getId();
+//        if(null != liveWatchLog){
+//            if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, liveWatchLog.getLogType())) {
+//                // 作废消息
+//                log.warn("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
+//                qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
+//                return false;
+//            }
+//        }
+//        else{
+//            log.warn("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
+//            qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "无观看记录,不发送");
+//            return false;
+//        }
+        log.warn("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
+        qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "无观看记录,不发送");
+        return false;
+//        if (qwSopLogs.getSendType() != 6 && noSop) {
+//            // 客户的信息
+////            QwExternalContactHParam contactHParam = new QwExternalContactHParam();
+////            contactHParam.setUserId(qwUser.getQwUserId().trim());
+////            contactHParam.setExternalUserId(qwSopLogs.getExternalUserId().trim());
+////            contactHParam.setCorpId(qwUser.getCorpId().trim());
+//            Integer courseType = setting.getCourseType();
+//            if (setting.getType() == 2 && courseType != 0) {// 课程消息,进行复杂的条件判断
+////                log.debug("企微查询:{}", contactHParam);
+////                Long qwExternalContactId = qwExternalContactMapper.getQwExternalContactId(contactHParam);
+//                FsCourseWatchLog watchLog = watchLogService.getWatchCourseLogVideoBySop(
+//                        setting.getVideoId().longValue(),
+//                        String.valueOf(qwUser.getId()),
+//                        qwSopLogs.getExternalId()
+//                );
+//                log.debug("ID:{}-看课记录参数:videoID:{}, qwUserID:{}, extID:{}", qwSopLogs.getId(), setting.getVideoId().longValue(), qwUser.getId(), qwSopLogs.getExternalId());
+//                log.debug("ID:{}-看课记录:{}", qwSopLogs.getId(), watchLog);
+//                String logId = qwSopLogs.getId();
+//                if (watchLog != null) {
+//                    //新逻辑
+//                    if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, watchLog.getLogType())) {
+//                        // 作废消息
+//                        log.warn("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
+//                        qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
+//                        return false;
+//                    }
+//                } else {
+//                    log.warn("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
+//                    qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "无观看记录,不发送");
+//                    return false;
+//                }
+//            }
+//        }
+        //return true;
+    }
+
     private void sendMiniProgram(BaseVo vo, QwSopCourseFinishTempSetting.Setting content, Map<String, FsCoursePlaySourceConfig> miniMap, Long companyId) {
         String appid = content.getMiniprogramAppid();
         if(companyId != null && content.getMiniType() != null){

+ 48 - 17
fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java

@@ -2,6 +2,7 @@ package com.fs.app.task;
 
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.app.service.IpadSendServer;
 import com.fs.common.core.redis.RedisCacheT;
@@ -90,19 +91,21 @@ public class SendMsg {
         if (qwUserList.isEmpty()) {
             List<QwIpadServer> serverList = qwIpadServerMapper.selectList(new QueryWrapper<QwIpadServer>().eq("group_no", groupNo));
             if (serverList.isEmpty()) {
+                log.info("没找到可用的服务器 {} ",serverList);
                 return new ArrayList<>();
             }
             List<Long> serverIds = PubFun.listToNewList(serverList, QwIpadServer::getId);
             List<QwUser> qwUsers = qwUserMapper.selectList(new QueryWrapper<QwUser>().eq("send_msg_type", 1).eq("server_status", 1).eq("ipad_status", 1).in("server_id", serverIds));
             qwUserList.addAll(qwUsers);
         }
+        log.info("getQwUserList {}",JSON.toJSONString(qwUserList));
         return qwUserList;
     }
 
     private Map<String, FsCoursePlaySourceConfig> getMiniMap() {
         List<FsCoursePlaySourceConfig> list = fsCoursePlaySourceConfigService.list(new QueryWrapper<FsCoursePlaySourceConfig>().ne("type", 2).eq("is_del", 0));
-        log.info("获取到的小程序配置:{}", JSON.toJSONString(list));
-        log.info("获取到的小程序配置:{}", JSON.toJSONString(list));
+//        log.info("获取到的小程序配置:{}", JSON.toJSONString(list));
+//        log.info("获取到的小程序配置:{}", JSON.toJSONString(list));
         return PubFun.listToMapByGroupObject(list, FsCoursePlaySourceConfig::getAppid);
     }
 
@@ -169,6 +172,7 @@ public class SendMsg {
         // 获取当前企微待发送记录
         List<QwSopLogs> qwSopLogList = qwSopLogsMapper.selectByQwUserId(qwUser.getId());
         if (qwSopLogList.isEmpty()) {
+            log.info("获取当前企微待发送记录为空");
             return;
         }
         // 获取企微用户
@@ -178,6 +182,7 @@ public class SendMsg {
         long end1 = System.currentTimeMillis();
         // 判断这个企微是否需要发送
         if (!sendServer.isSend(user, parentVo)) {
+            log.info("当前这个企微不需要发送 数据{}",user);
             return;
         }
         log.info("销售:{}, 消息:{}, 耗时: {}, 时间:{}", user.getQwUserName(), qwSopLogList.size(), end1 - start1, qwMap.get(qwUser.getId()));
@@ -186,10 +191,20 @@ public class SendMsg {
         for (QwSopLogs qwSopLogs : qwSopLogList) {
             long start2 = System.currentTimeMillis();
             QwSopCourseFinishTempSetting setting = JSON.parseObject(qwSopLogs.getContentJson(), QwSopCourseFinishTempSetting.class);
-            // 判断消息状态是否满足发送条件
-            if (!sendServer.isSendLogs(qwSopLogs, setting, user)) {
-                log.info("销售:{}, 消息发送条件未满足:{}", user.getQwUserName(), qwSopLogs.getId());
-                continue;
+            //直播的sendType:20单独走判断 其他的走以前的逻辑
+            boolean isSendLive = Integer.valueOf(20).equals(qwSopLogs.getSendType());
+            if(isSendLive){
+                if (!sendServer.isSendLogsLive(qwSopLogs, setting, user)) {
+                    log.info("销售:{}, 直播消息发送条件未满足:{}", user.getQwUserName(), qwSopLogs.getId());
+                    continue;
+                }
+            }
+            else{
+                // 判断消息状态是否满足发送条件
+                if (!sendServer.isSendLogs(qwSopLogs, setting, user)) {
+                    log.info("销售:{}, 消息发送条件未满足:{}", user.getQwUserName(), qwSopLogs.getId());
+                    continue;
+                }
             }
             log.info("进入发送消息状态:{}", qwSopLogs.getId());
             String key = "qw:logs:pad:send:id:" + qwSopLogs.getId();
@@ -246,7 +261,7 @@ public class SendMsg {
                     }
                     long end4 = System.currentTimeMillis();
                     log.info("请求pad发送完成:{}, {}, 时长4:{}", user.getQwUserName(), qwSopLogs.getId(), end4 - start4);
-                    if (content.getSendStatus() == 2 && ("请求失败:消息发送过于频繁,请稍后再试".equals(content.getSendRemarks()) || "请求失败:请求频率异常".equals(content.getSendRemarks()))) {
+                    if(content.getSendStatus() == 2 && ("请求失败:消息发送过于频繁,请稍后再试".equals(content.getSendRemarks()) || "请求失败:请求频率异常".equals(content.getSendRemarks()))){
                         QwUser update = new QwUser();
                         update.setRemark("请求频率异常,暂停发送,三小时后恢复继续发送");
                         update.setUpdateTime(new Date());
@@ -264,16 +279,32 @@ public class SendMsg {
                 }
             }
             // 推送 APP
-//            if (!setting.getSetting().isEmpty()) {
-//                new Thread(() -> {
-//                    try {
-//                        List<QwSopTempSetting.Content.Setting> settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "9".equals(e.getContentType())).collect(Collectors.toList());
-//                        asyncSopTestService.asyncSendMsgBySopAppLinkNormalIM(settings, qwSopLogs.getCorpId(), user.getCompanyUserId(), qwSopLogs.getFsUserId());
-//                    } catch (Exception e) {
-//                        log.error("推送APP失败", e);
-//                    }
-//                }).start();
-//            }
+            if (!setting.getSetting().isEmpty()) {
+                new Thread(() -> {
+                    try {
+                        List<QwSopTempSetting.Content.Setting> settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "9".equals(e.getContentType())).collect(Collectors.toList());
+                        if (!settings.isEmpty()) {
+                            asyncSopTestService.asyncSendMsgBySopAppLinkNormalIM(settings, qwSopLogs.getCorpId(), user.getCompanyUserId(), qwSopLogs.getFsUserId());
+                        }
+
+                        //app文本消息
+                        log.info("开始发送app文本消息消息开始,消息{},用户{}", JSONObject.toJSONString(settings), user.getQwUserName());
+                        settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "15".equals(e.getContentType())).collect(Collectors.toList());
+
+                        if (!settings.isEmpty()) {
+                            asyncSopTestService.asyncSendMsgBySopAppTxtNormalIM(settings, qwSopLogs.getCorpId(), qwUser.getCompanyUserId(), qwSopLogs.getFsUserId());
+                        }
+                        //app语音消息
+                        log.info("开始发送app语音消息消息开始,消息{},用户{}", JSONObject.toJSONString(settings), user.getQwUserName());
+                        settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "16".equals(e.getContentType())).collect(Collectors.toList());
+                        if (!settings.isEmpty()) {
+                            asyncSopTestService.asyncSendMsgBySopAppMP3NormalIM(settings, qwSopLogs.getCorpId(), qwUser.getCompanyUserId(), qwSopLogs.getFsUserId());
+                        }
+                    } catch (Exception e) {
+                        log.error("推送APP失败", e);
+                    }
+                }).start();
+            }
             qwSopLogs.setSend(true);
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             QwSopLogs updateQwSop = new QwSopLogs();

+ 2 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -1079,6 +1079,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
                     setting.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
                     setting.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
+                    setting.setCourseUrl(setting.getLinkImageUrl());
+                    setting.setTitle(setting.getLinkDescribe()); //小节名称
 
                     break;
                 //自定义小程序

+ 2 - 0
fs-service/src/main/java/com/fs/im/dto/OpenImMsgDTO.java

@@ -28,6 +28,8 @@ public class OpenImMsgDTO {
         private String data;
         private String description;
         private String extension;
+        private String sourceUrl;
+        private Integer duration;
     }
     @Data
     public static class ImData{

+ 82 - 18
fs-service/src/main/java/com/fs/qw/service/impl/AsyncSopTestService.java

@@ -1,5 +1,6 @@
 package com.fs.qw.service.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fs.common.utils.PubFun;
@@ -7,6 +8,8 @@ import com.fs.course.domain.FsCourseSopAppLink;
 import com.fs.course.mapper.FsCourseSopAppLinkMapper;
 import com.fs.gtPush.service.uniPush2Service;
 import com.fs.his.mapper.FsUserMapper;
+import com.fs.im.dto.OpenImMsgDTO;
+import com.fs.im.service.OpenIMService;
 import com.fs.qw.domain.QwSopUpdateStatus;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
@@ -28,6 +31,7 @@ import com.fs.wxUser.param.CompanyWxUserSopParam;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
@@ -473,24 +477,24 @@ public class AsyncSopTestService {
                                             Integer courseId,String linkTile,String linkImageUrl,Integer videoId,
                                             String linkDescribe,String appMsgLink,Long externalId){
 
-//        FsCourseSopAppLink sopAppLink=new FsCourseSopAppLink();
-//        sopAppLink.setLink(link);
-//        sopAppLink.setCreateTime(sendTime);
-//        sopAppLink.setUpdateTime(updateTime);
-//        sopAppLink.setCompanyId(Long.parseLong(companyId));
-//        sopAppLink.setCompanyUserId(Long.parseLong(companyUserId));
-//        sopAppLink.setQwUserId(Long.parseLong(qwUserId));
-//        sopAppLink.setQwUserName(qwUserName);
-//        sopAppLink.setCorpId(corpId);
-//        sopAppLink.setCourseId(Long.valueOf(courseId));
-//        sopAppLink.setCourseTitle(linkTile);
-//        sopAppLink.setCourseUrl(linkImageUrl);
-//        sopAppLink.setVideoId(Long.valueOf(videoId));
-//        sopAppLink.setVideoTitle(linkDescribe);
-//        sopAppLink.setAppRealLink(appMsgLink);
-//        sopAppLink.setQwExternalId(externalId);
-//
-//        fsCourseSopAppLinkMapper.insertFsCourseSopAppLink(sopAppLink);
+        FsCourseSopAppLink sopAppLink=new FsCourseSopAppLink();
+        sopAppLink.setLink(link);
+        sopAppLink.setCreateTime(sendTime);
+        sopAppLink.setUpdateTime(updateTime);
+        sopAppLink.setCompanyId(Long.parseLong(companyId));
+        sopAppLink.setCompanyUserId(Long.parseLong(companyUserId));
+        sopAppLink.setQwUserId(Long.parseLong(qwUserId));
+        sopAppLink.setQwUserName(qwUserName);
+        sopAppLink.setCorpId(corpId);
+        sopAppLink.setCourseId(Long.valueOf(courseId));
+        sopAppLink.setCourseTitle(linkTile);
+        sopAppLink.setCourseUrl(linkImageUrl);
+        sopAppLink.setVideoId(Long.valueOf(videoId));
+        sopAppLink.setVideoTitle(linkDescribe);
+        sopAppLink.setAppRealLink(appMsgLink);
+        sopAppLink.setQwExternalId(externalId);
+
+        fsCourseSopAppLinkMapper.insertFsCourseSopAppLink(sopAppLink);
 
     }
 
@@ -518,6 +522,66 @@ public class AsyncSopTestService {
 
     }
 
+    @Autowired
+    private OpenIMService openIMService;
+    @Async("scheduledExecutorService")
+    public void  asyncSendMsgBySopAppTxtNormalIM(List<QwSopTempSetting.Content.Setting> setting,String cropId,Long companyUserId,Long fsUserId){
+
+        setting.forEach(item->{
+            try {
+                log.info("执行发送app文本消息:{}",item);
+                OpenImMsgDTO openImMsgDTO = new OpenImMsgDTO();
+                openImMsgDTO.setSendID("C"+companyUserId);
+                openImMsgDTO.setRecvID("U"+fsUserId);
+                openImMsgDTO.setContentType(101);
+                openImMsgDTO.setSessionType(1);
+                OpenImMsgDTO.Content imContent = new OpenImMsgDTO.Content();
+                imContent.setContent(item.getValue());
+                openImMsgDTO.setContent(imContent);
+                openIMService.openIMSendMsg(openImMsgDTO);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+    }
+
+    @Async("scheduledExecutorService")
+    public void  asyncSendMsgBySopAppMP3NormalIM(List<QwSopTempSetting.Content.Setting> setting,String cropId,Long companyUserId,Long fsUserId){
+
+        setting.forEach(item->{
+            try {
+                if(StrUtil.isEmpty(item.getVoiceUrl())){
+                    log.info("执行发送app文本消息:{}",item);
+                    OpenImMsgDTO openImMsgDTO = new OpenImMsgDTO();
+                    openImMsgDTO.setSendID("C"+companyUserId);
+                    openImMsgDTO.setRecvID("U"+fsUserId);
+                    openImMsgDTO.setContentType(101);
+                    openImMsgDTO.setSessionType(1);
+                    OpenImMsgDTO.Content imContent = new OpenImMsgDTO.Content();
+                    imContent.setContent(item.getValue());
+                    openImMsgDTO.setContent(imContent);
+                    openIMService.openIMSendMsg(openImMsgDTO);
+                }else {
+                    log.info("执行发送app语音消息:{}",item);
+                    OpenImMsgDTO openImMsgDTO = new OpenImMsgDTO();
+                    openImMsgDTO.setSendID("C"+companyUserId);
+                    openImMsgDTO.setRecvID("U"+fsUserId);
+                    openImMsgDTO.setContentType(103);
+                    openImMsgDTO.setSessionType(1);
+                    OpenImMsgDTO.Content imContent = new OpenImMsgDTO.Content();
+                    imContent.setSourceUrl(item.getVoiceUrl());
+                    imContent.setDuration(Integer.parseInt(item.getVoiceDuration()));
+                    openImMsgDTO.setContent(imContent);
+                    openIMService.openIMSendMsg(openImMsgDTO);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+    }
+
     /**
      * 异步录入 发送有app的客户 之 正常sop版
      */

+ 5 - 0
fs-service/src/main/java/com/fs/qw/vo/QwSopCourseFinishTempSetting.java

@@ -23,6 +23,8 @@ public class QwSopCourseFinishTempSetting implements Serializable,Cloneable{
     //课节
     private Integer videoId;
 
+    private Long liveId;
+
     private List<Setting> setting;
 
     @Override
@@ -80,6 +82,9 @@ public class QwSopCourseFinishTempSetting implements Serializable,Cloneable{
         /** 小程序page路径 */
         private String miniprogramPage;
 
+        /** 直播间ID */
+        private String liveId;
+
         //链接标题
         private String linkTitle;
         //链接描述

+ 6 - 0
fs-service/src/main/java/com/fs/qw/vo/QwSopTempSetting.java

@@ -144,6 +144,12 @@ public class QwSopTempSetting implements Serializable{
             //链接过期时间
             private Integer expiresDays;
 
+            //封面图片地址 app用的参数
+            private String courseUrl;
+
+            //app显示标题 app用的参数
+            private String title;
+
             @Override
             public Setting clone() {
                 try {

+ 13 - 3
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -1343,6 +1343,16 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     QwSop qwSop = qwSopMapper.selectQwSopById(param.getSopId());
                     createVoiceUrl(st, companyUserId, qwSop);
                     break;
+                //app
+                case "9":
+                    addWatchLogIfNeeded(item.getSopId(), param.getVideoId(), param.getCourseId(), item.getFsUserId(), String.valueOf(qwUser.getId()),
+                            companyUserId, companyId, item.getExternalId(), item.getStartTime(), dataTime);
+
+                    QwCreateLinkByAppVO linkByApp = createLinkByApp(st, param.getCorpId(), dataTime, param.getCourseId(), param.getVideoId(),
+                            qwUser.getId(), companyUserId, companyId, item.getExternalId(), config, qwUser.getQwUserName(), contact.getFsUserId());
+                    st.setLinkUrl(linkByApp.getSortLink());
+                    st.setAppLinkUrl(linkByApp.getAppMsgLink());
+                    break;
                 //自定义小程序
                 case "10":
 
@@ -1532,9 +1542,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 qwUserName,corpId,courseId,setting.getLinkTitle(),setting.getLinkImageUrl(),videoId,
                 setting.getLinkDescribe(),appMsgLink,externalId);
 
-        //异步给app用户发送消息
-        asyncSopTestService.asyncSendMsgBySopAppLink(externalId,setting.getLinkTitle(),setting.getLinkDescribe(),appMsgLink);
-
+//        //异步给app用户发送消息
+//        asyncSopTestService.asyncSendMsgBySopAppLink(externalId,setting.getLinkTitle(),setting.getLinkDescribe(),appMsgLink);
+//
 
 
         //存短链-