lmx 2 dias atrás
pai
commit
7b13850d7d

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

@@ -21,6 +21,8 @@ import com.fs.his.domain.FsUser;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.ipad.IpadSendUtils;
 import com.fs.ipad.vo.*;
+import com.fs.live.domain.LiveWatchLog;
+import com.fs.live.mapper.LiveWatchLogMapper;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwUserVideo;
@@ -63,6 +65,8 @@ public class IpadSendServer {
 
 
     private static final List<String> PROJECT_NAMES = Arrays.asList("济南联志健康", "北京存在文化","宽益堂");
+    private final LiveWatchLogMapper liveWatchLogMapper;
+
     private void sendMiniProgram(BaseVo vo, QwSopCourseFinishTempSetting.Setting content, Map<String, FsCoursePlaySourceConfig> miniMap, Long companyId) {
         // 发送参数原本的appid
         String appid = content.getMiniprogramAppid();
@@ -432,6 +436,132 @@ public class IpadSendServer {
         return true;
     }
 
+    /**
+     * 直播间判定消息
+     * @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;
+        }
+//        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;
+    }
+
     public void send(QwSopCourseFinishTempSetting.Setting content, QwUser qwUser, QwSopLogs qwSopLogs, Map<String, FsCoursePlaySourceConfig> miniMap, BaseVo parentVo) {
         BaseVo vo = new BaseVo();
         vo.setId(Long.parseLong(qwSopLogs.getId()));

+ 14 - 4
fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java

@@ -191,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();

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

@@ -950,6 +950,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             switch (setting.getContentType()) {
                 //直播小程序单独
                 case "12":
+                    //直播发送类型
+                    sopLogs.setSendType(20);
+                    clonedContent.setLiveId(setting.getLiveId());
                     String sortLiveLink;
                     sortLiveLink = "/pages_course/living.html?companyId=" + companyId + "&companyUserId=" + companyUserId + "&liveId=" + setting.getLiveId() + "&corpId=" + logVo.getCorpId()+"&qwUserId=" + qwUserId;
                     String json = configService.selectConfigByKey("his.config");
@@ -1198,6 +1201,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     break;
                 //直播小程序单独
                 case "12":
+                    sopLogs.setSendType(20);
+                    clonedContent.setLiveId(setting.getLiveId());
                     String sortLiveLink;
                     sortLiveLink = "/pages_course/living.html?companyId=" + companyId + "&companyUserId=" + companyUserId + "&liveId=" + setting.getLiveId()+"&corpId=" +logVo.getCorpId()+"&qwUserId=" + qwUserId;
                     String json = configService.selectConfigByKey("his.config");
@@ -1984,7 +1989,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     public void batchInsertLiveWatchLog(List<LiveWatchLog> liveWatchLogToInsert) {
         try {
             List<LiveWatchLog> lastInsertList = new ArrayList<>();
-            //判断是否存在数据 liveId + his_qw_external_contact_id 唯一
+            //判断是否存在数据 liveId + his_qw_external_contact_id + qwUserId 唯一
             for (LiveWatchLog liveWatchLog : liveWatchLogToInsert) {
                 //判断是否存在数据 存在的数据直接更新发送时间
                 if(liveWatchLogMapper.updateLiveWatchLogCondition(liveWatchLog) > 0){
@@ -1997,7 +2002,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             }
 //            log.info("批量插入 LiveWatchLog 完成,共插入 {} 条记录。", liveWatchLogToInsert.size());
         } catch (Exception e) {
-            log.error("批量插入 LiveWatchLog 失败: {}", e.getMessage(), e);
+            log.error("批量插入 LiveWatchLog 失败: {}", liveWatchLogToInsert, e);
             // 可选:将失败的数据记录到失败队列或持久化存储以便后续重试
         }
     }

+ 7 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -921,6 +921,13 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo()).put("batchId", transferBatchesResult.getBatchId()).put("mchId", config.getMchId());
         } catch (Exception e) {
             logger.error("商家转账支付失败:参数: {} :原因: {}",JSON.toJSONString(param), e.getMessage(),e);
+            if (e instanceof WxPayException && "济南联志健康".equals(signProjectName)) {
+                WxPayException wxPayException = (WxPayException) e;
+                String customErrorMsg = wxPayException.getCustomErrorMsg();
+                if (null != customErrorMsg && customErrorMsg.startsWith("商户运营账户资金不足")) {
+                    return R.error("[红包领取] 账户余额不足,请联系管理员!");
+                }
+            }
             throw new RuntimeException(e);
         }
     }

+ 2 - 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

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

@@ -47,6 +47,8 @@ public class QwSopTempSetting implements Serializable{
         
         private Integer isAtAll;
 
+        private Long liveId;
+
         @Override
         public Content clone() {
             try {

+ 3 - 1
fs-service/src/main/java/com/fs/sop/domain/QwSopLogs.java

@@ -61,7 +61,9 @@ public class QwSopLogs implements Serializable {
     private String msgId;
 
     /**
-    * 发送类型 1企微发送 2 Ai接口发送  3:完课发送  4:AI对话 5一键群发 6一键群发app
+    * 发送类型  1企微发送 2 Ai接口发送  3:完课发送  4:AI对话 5一键群发 6客户群群发
+     * 7欢迎语补发 8AI 9清除草稿 10发送草稿 11 课程模板类型 12 一键群发APP
+     * 13 注册链接 14 福袋  20直播间发送
     */
     private Integer sendType;
 

+ 7 - 0
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -690,6 +690,8 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                 break;
                             //直播小程序单独
                             case "12":
+                                sopLogs.setSendType(20);
+                                setting.setLiveId(Long.valueOf(st.getLiveId()));
                                 String sortLiveLink = "/pages_course/living.html?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + companyUserId + "&liveId=" + st.getLiveId() + "&corpId=" + param.getCorpId()+"&qwUserId=" + qwUser.getId() +"&externalId=" + vo.getId().toString();
                                 st.setContentType("4");
                                 String js = configService.selectConfigByKey("his.config");
@@ -881,6 +883,8 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                 break;
                             //直播小程序单独
                             case "12":
+                                sopLogs.setSendType(20);
+                                setting.setLiveId(setting.getLiveId());
                                 String sortLiveLink = "/pages_course/living.html?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + qwUser.getCompanyUserId() + "&liveId=" + st.getLiveId() + "&corpId=" +param.getCorpId()+"&qwUserId=" + qwUser.getId() + "&chatId=" + groupChat.getChatId();
                                 st.setContentType("4");
                                 String js = configService.selectConfigByKey("his.config");
@@ -1154,6 +1158,8 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             break;
                         //直播小程序单独
                         case "12":
+                            sopLogs.setSendType(20);
+                            setting.setLiveId(Long.valueOf(st.getLiveId()));
                             String sortLiveLink = "/pages_course/living.html?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + qwUser.getCompanyUserId() + "&liveId=" + st.getLiveId() + "&corpId=" + param.getCorpId()+"&qwUserId=" + qwUserId +"&externalId=" + item.getExternalId().toString();
                             st.setContentType("4");
                             String js = configService.selectConfigByKey("his.config");
@@ -1746,6 +1752,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 //直播小程序单独
                 case "12":
                     String sortLiveLink;
+                    sopLogs.setSendType(20);
                     sortLiveLink = "/pages_course/living.html?companyId=" + companyId + "&companyUserId=" + companyUserId + "&liveId=" + st.getLiveId() + "&corpId=" + param.getCorpId()+"&qwUserId=" + qwUser.getId() +"&externalId=" + item.getExternalId().toString();