Просмотр исходного кода

待发送记录-二级域名的问题

三七 1 неделя назад
Родитель
Сommit
8d09c83101

+ 200 - 87
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -17,12 +17,10 @@ import com.fs.course.domain.*;
 import com.fs.course.mapper.*;
 import com.fs.course.param.FsCourseLinkCreateParam;
 import com.fs.course.service.IFsCourseLinkService;
-import com.fs.qw.domain.QwExternalContact;
-import com.fs.qw.domain.QwGroupChat;
-import com.fs.qw.domain.QwGroupChatUser;
-import com.fs.qw.domain.QwUser;
+import com.fs.qw.domain.*;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwGroupChatService;
 import com.fs.qw.service.IQwGroupChatUserService;
 import com.fs.qw.service.impl.QwExternalContactServiceImpl;
@@ -163,6 +161,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     @Autowired
     private ICompanyUserService companyUserService;
 
+    @Autowired
+    private IQwCompanyService iQwCompanyService;
+
 
     @PostConstruct
     public void init() {
@@ -301,45 +302,48 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             groupChatMap = PubFun.listToMapByGroupObject(qwGroupChatList, QwGroupChat::getChatId);
         }
 
-//        Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
-//                .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
-        // 查询销售二级域名
-        Set<Long> ids = sopUserLogsVos.stream().map(s -> {
-            String[] userKey = s.getUserId().split("\\|");
-            if (userKey.length < 3) {
-                return null;
-            }
-            return Long.parseLong(userKey[1]);
-        }).filter(Objects::nonNull).collect(Collectors.toSet());
-        List<CompanyUser> companyUserList;
-        if (ids.isEmpty()) {
-            companyUserList = new ArrayList<>();
-        } else {
-            companyUserList = companyUserService.selectCompanyUserByIds(ids);
-        }
-
         Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
-                .peek(s -> {
-                    String[] userKey = s.getUserId().split("\\|");
-                    if (userKey.length < 3) {
-                        return;
-                    }
-
-                    // 销售ID
-                    Long companyUserId = Long.parseLong(userKey[1]);
-                    CompanyUser companyUser = companyUserList.stream().filter(cu -> Objects.equals(cu.getUserId(), companyUserId)).findFirst().orElse(null);
-                    if (Objects.nonNull(companyUser)) {
-                        if (StringUtils.isNotBlank(companyUser.getDomain())) {
-                            s.setDomain(companyUser.getDomain().trim());
-                        } else {
-                            s.setDomain(config.getRealLinkDomainName().trim());
-                        }
-                    } else {
-                        s.setDomain(config.getRealLinkDomainName().trim());
-                    }
-                })
                 .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
 
+
+        // 查询销售二级域名
+//        Set<Long> ids = sopUserLogsVos.stream().map(s -> {
+//            String[] userKey = s.getUserId().split("\\|");
+//            if (userKey.length < 3) {
+//                return null;
+//            }
+//            return Long.parseLong(userKey[1]);
+//        }).filter(Objects::nonNull).collect(Collectors.toSet());
+//
+//        List<CompanyUser> companyUserList;
+//        if (ids.isEmpty()) {
+//            companyUserList = new ArrayList<>();
+//        } else {
+//            companyUserList = companyUserService.selectCompanyUserByIds(ids);
+//        }
+//
+//        Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
+//                .peek(s -> {
+//                    String[] userKey = s.getUserId().split("\\|");
+//                    if (userKey.length < 3) {
+//                        return;
+//                    }
+//
+//                    // 销售ID
+//                    Long companyUserId = Long.parseLong(userKey[1]);
+//                    CompanyUser companyUser = companyUserList.stream().filter(cu -> Objects.equals(cu.getUserId(), companyUserId)).findFirst().orElse(null);
+//                    if (Objects.nonNull(companyUser)) {
+//                        if (!StringUtil.strIsNullOrEmpty(companyUser.getDomain())) {
+//                            s.setDomain(companyUser.getDomain().trim());
+//                        } else {
+//                            s.setDomain(config.getRealLinkDomainName().trim());
+//                        }
+//                    } else {
+//                        s.setDomain(config.getRealLinkDomainName().trim());
+//                    }
+//                })
+//                .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
+
         log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
 
         CountDownLatch sopGroupLatch = new CountDownLatch(sopLogsGroupedById.size());
@@ -347,7 +351,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
             String sopId = entry.getKey();
             List<SopUserLogsVo> userLogsVos = entry.getValue();
-            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap);
+            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap,config);
         }
 
         // 等待所有 SOP 分组处理完成
@@ -367,9 +371,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             maxAttempts = 3,
             backoff = @Backoff(delay = 2000)
     )
-    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
+    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime,
+                                     Map<String, QwGroupChat> groupChatMap,CourseConfig config) {
         try {
-            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap);
+            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap, config);
         } catch (Exception e) {
             log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
         } finally {
@@ -378,7 +383,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     }
 
 
-    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) throws Exception {
+    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String,
+            QwGroupChat> groupChatMap,CourseConfig config) throws Exception {
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
 
         if (ruleTimeVO == null) {
@@ -392,6 +398,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             log.error("SOP ID {} 模板不存在,相关日志已清除。", sopId);
             return;
         }
+
         ruleTimeVO.setTempStatus(qwSopTemp.getStatus());
         ruleTimeVO.setTempGap(qwSopTemp.getGap());
 
@@ -410,9 +417,16 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             return;
         }
 
+        QwCompany qwCompany = iQwCompanyService.getQwCompanyByRedis(ruleTimeVO.getCorpId());
+
+        if (qwCompany == null ) {
+            log.error("SOP ID {} 的 公司信息为空 为空,跳过处理。", sopId);
+            return ;
+        }
+
         CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
         for (SopUserLogsVo logVo : userLogsVos) {
-            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap);
+            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap,qwCompany.getMiniAppId(), config);
         }
 
         // 等待所有用户日志处理完成
@@ -431,9 +445,11 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             maxAttempts = 3,
             backoff = @Backoff(delay = 2000)
     )
-    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
+    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
+                                    CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,
+                                    String miniAppId,CourseConfig config) {
         try {
-            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap);
+            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap, miniAppId, config);
         } catch (Exception e) {
             log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
         } finally {
@@ -442,8 +458,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     }
 
 
-    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
+    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
+                                LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,String miniAppId,CourseConfig config) {
         try {
+
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
             LocalDate currentDate = currentTime.toLocalDate();
 
@@ -472,14 +490,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 return;
             }
 
-            String[] userKey = logVo.getUserId().split("\\|");
-            if (userKey.length < 3) {
-                log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
-                return;
-            }
-            String qwUserId = userKey[0].trim();
-            String companyUserId = userKey[1].trim();
-            String companyId = userKey[2].trim();
+//            String[] userKey = logVo.getUserId().split("\\|");
+//            if (userKey.length < 3) {
+//                log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
+//                return;
+//            }
+
+//            String qwUserId = userKey[0].trim();
+//            String companyUserId = userKey[1].trim();
+//            String companyId = userKey[2].trim();
 
 
             //获取企业微信员工的称呼//从redis里或者从库里取
@@ -489,6 +508,26 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 return;
             }
 
+            String qwUserId = String.valueOf(qwUserByRedis.getId()).trim();
+            String companyUserId = String.valueOf(qwUserByRedis.getCompanyUserId()).trim();
+            String companyId = String.valueOf(qwUserByRedis.getCompanyId()).trim();
+
+            if (StringUtil.strIsNullOrEmpty(companyUserId) || StringUtil.strIsNullOrEmpty(companyId) || "null".equals(companyUserId)) {
+                log.error("员工未绑定销售账号或公司,跳过处理:"+qwUserId);
+                return;
+            }
+
+            CompanyUser companyUser = companyUserService.selectCompanyUserByIdForRedis(Long.valueOf(companyUserId));
+            if (Objects.nonNull(companyUser)) {
+                if (!StringUtil.strIsNullOrEmpty(companyUser.getDomain())) {
+                    logVo.setDomain(companyUser.getDomain().trim());
+                } else {
+                    logVo.setDomain(config.getRealLinkDomainName().trim());
+                }
+            } else {
+                logVo.setDomain(config.getRealLinkDomainName().trim());
+            }
+
             //寻找时间
 //            LocalDateTime currentTime = LocalDateTime.of(2024, 12, 25,23 , 40);
 
@@ -582,20 +621,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                             }
                         }
 
-                        // 获取fsUserId
-                        Set<Long> externalIds = sopUserLogsInfos.stream().map(SopUserLogsInfo::getExternalId).collect(Collectors.toSet());
-                        if (!externalIds.isEmpty()) {
-                            List<QwExternalContact> externalContactList = qwExternalContactService.list(Wrappers.<QwExternalContact>lambdaQuery().in(QwExternalContact::getId, externalIds));
-                            sopUserLogsInfos.forEach(s -> {
-                                QwExternalContact qwExternalContact = externalContactList.stream().filter(e -> Objects.equals(s.getExternalId(), e.getId())).findFirst().orElse(null);
-                                if (Objects.nonNull(qwExternalContact)) {
-                                    s.setFsUserId(qwExternalContact.getFsUserId());
-                                }
-                            });
-                        }
+                        // 获取fsUserId TODO
+//                        Set<Long> externalIds = sopUserLogsInfos.stream().map(SopUserLogsInfo::getExternalId).collect(Collectors.toSet());
+//                        if (!externalIds.isEmpty()) {
+//                            List<QwExternalContact> externalContactList = qwExternalContactService.list(Wrappers.<QwExternalContact>lambdaQuery().in(QwExternalContact::getId, externalIds));
+//                            sopUserLogsInfos.forEach(s -> {
+//                                QwExternalContact qwExternalContact = externalContactList.stream().filter(e -> Objects.equals(s.getExternalId(), e.getId())).findFirst().orElse(null);
+//                                if (Objects.nonNull(qwExternalContact)) {
+//                                    s.setFsUserId(qwExternalContact.getFsUserId());
+//                                }
+//                            });
+//                        }
 
 
-                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId, companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(), groupChatMap);
+                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId,
+                                companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(),
+                                groupChatMap, miniAppId);
 
                     }
                 } catch (Exception e) {
@@ -637,7 +678,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     //消息处理
     private void insertSopUserLogs(List<SopUserLogsInfo> sopUserLogsInfos, SopUserLogsVo logVo, Date sendTime,
                                    QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
-                                   String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName, Map<String, QwGroupChat> groupChatMap) {
+                                   String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName,
+                                   Map<String, QwGroupChat> groupChatMap,String miniAppId) {
         String formattedSendTime = sendTime.toInstant()
                 .atZone(ZoneId.systemDefault())
                 .format(DATE_TIME_FORMATTER);
@@ -674,7 +716,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     log.error("群聊创建看课记录失败!", e);
                 }
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName, null, true);
+                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName, null, true, miniAppId);
             } else {
                 if(groupChat.getChatUserList() != null && !groupChat.getChatUserList().isEmpty()){
                     groupChat.getChatUserList().forEach(user -> {
@@ -682,7 +724,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         ruleTimeVO.setRemark("客户群催课");
                         QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null, isOfficial, null);
                         handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName, null, false);
+                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName, null, false, miniAppId);
                     });
                 }
             }
@@ -695,7 +737,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     Long fsUserId = contactId.getFsUserId();
                     QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
                     handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false);
+                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId);
                 } catch (Exception e) {
                     log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
                 }
@@ -745,7 +787,23 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         sopLogs.setCorpId(logVo.getCorpId());
         sopLogs.setLogType(ruleTimeVO.getType());
 
-        sopLogs.setSendType(isOfficial == 1 ? 1 : ruleTimeVO.getSendType());
+        if (isOfficial == 1) {
+
+            if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
+                sopLogs.setSendType(2);
+                sopLogs.setRemark("未绑定小程序用户,单链补发");
+                //时间设置成固定7点
+                LocalDateTime dateTime = LocalDateTime.parse(formattedSendTime, DATE_TIME_FORMATTER);
+                sopLogs.setSendTime(OUTPUT_FORMATTER.format(dateTime));
+            }else {
+                sopLogs.setSendType(1);
+            }
+
+        }else if (isOfficial==0){
+            sopLogs.setSendType(ruleTimeVO.getSendType() == 1 ? 2 : ruleTimeVO.getSendType());
+        }else{
+            sopLogs.setSendType(ruleTimeVO.getSendType());
+        }
 
 
         sopLogs.setSendStatus(3L);
@@ -754,11 +812,12 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         String[] userKey = logVo.getUserId().split("\\|");
         sopLogs.setCompanyId(Long.valueOf(userKey[2].trim()));
         sopLogs.setSopId(logVo.getSopId());
-
+        sopLogs.setSort(Integer.valueOf(logVo.getStartTime().replaceAll("-","")));
         sopLogs.setExternalUserId(externalContactId);
         sopLogs.setExternalId(externalId);
         sopLogs.setExternalUserName(externalUserName);
         sopLogs.setFsUserId(fsUserId);
+        sopLogs.setUserLogsId(logVo.getId());
 
         return sopLogs;
     }
@@ -766,14 +825,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       Long videoId, int type, String qwUserId,
-                                      String companyUserId, String companyId, String externalId,String welcomeText,String qwUserName, Long fsUserId, boolean isGroupChat) {
+                                      String companyUserId, String companyId, String externalId,String welcomeText,
+                                      String qwUserName, Long fsUserId, boolean isGroupChat,String miniAppId) {
         switch (type) {
             case 1:
                 handleNormalMessage(sopLogs, content,companyUserId);
                 break;
             case 2:
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId, isGroupChat);
+                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId, isGroupChat, miniAppId);
                 break;
             case 3:
                 handleOrderMessage(sopLogs, content);
@@ -805,7 +865,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      Long videoId, String qwUserId, String companyUserId,
-                                     String companyId, String externalId,String welcomeText,String qwUserName, Long fsUserId, boolean isGroupChat) {
+                                     String companyId, String externalId,String welcomeText,String qwUserName,
+                                     Long fsUserId, boolean isGroupChat,String miniAppId) {
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
@@ -816,6 +877,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 //
 //        Integer courseType = clonedContent.getCourseType();
 
+        String isOfficial = clonedContent.getIsOfficial();
+
         List<QwSopTempSetting.Content.Setting> settings = clonedContent.getSetting();
         if (settings == null || settings.isEmpty()) {
             log.error("Cloned content settings are empty, skipping.");
@@ -848,7 +911,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         } else {
                             addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId, logVo);
                             link = generateShortLink(setting, logVo, sendTime, courseId, videoId,
-                                    qwUserId, companyUserId, companyId, externalId, fsUserId);
+                                    qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId());
                         }
 
                         if (StringUtils.isNotEmpty(link)) {
@@ -859,7 +922,6 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                 if (currentValue == null) {
                                     setting.setValue(link);
                                 } else {
-//                                    setting.setValue(currentValue + "\n" + sortLink);
                                     setting.setValue(currentValue
                                             .replaceAll("#销售称呼#", StringUtil.strIsNullOrEmpty(welcomeText) ? "" : welcomeText)
                                             + "\n" + link);
@@ -882,12 +944,18 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
 
                     String sortLink = createLinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
-                            qwUserId, companyUserId, companyId, externalId);
+                            qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId());
+
+                    if (!StringUtil.strIsNullOrEmpty(miniAppId)) {
+                        setting.setMiniprogramAppid(miniAppId);
+                    }else {
+                        log.error("公司的小程序id为空:采用了前端传的固定值"+sopLogs.getSopId());
+                    }
 
                     setting.setMiniprogramPage(sortLink.replaceAll("^[\\s\\u2005]+", ""));
 
                     try {
-                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl()) ? "https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png" : setting.getMiniprogramPicUrl());
+                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl())?"https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png":setting.getMiniprogramPicUrl());
                     } catch (Exception e) {
                         log.error("赋值-小程序封面地址失败-" + e);
                     }
@@ -933,7 +1001,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
     private String generateShortLink(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
                                      Long courseId, Long videoId, String qwUserId,
-                                     String companyUserId, String companyId, String externalId, Long fsUserId) {
+                                     String companyUserId, String companyId, String externalId,String isOfficial, Long fsUserId) {
         // 获取缓存的配置
         CourseConfig config;
         synchronized(configLock) {
@@ -954,7 +1022,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         link.setCorpId(logVo.getCorpId());
         link.setCourseId(courseId.longValue());
         link.setQwExternalId(Long.parseLong(externalId));
-        link.setLinkType(0); //正常链接
+
+        if (StringUtil.strIsNullOrEmpty(isOfficial)){
+            link.setLinkType(0);
+        }else {
+            if (isOfficial.equals("1")) {
+                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
+                    link.setLinkType(0);
+                }else {
+                    link.setLinkType(5);
+                }
+            }else if (isOfficial.equals("0")){
+                link.setLinkType(0);
+            }else{
+                link.setLinkType(0);
+            }
+        }
 
         FsCourseRealLink courseMap = new FsCourseRealLink();
         courseMap.setCompanyId(link.getCompanyId());
@@ -964,9 +1047,25 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         courseMap.setCorpId(link.getCorpId());
         courseMap.setCourseId(link.getCourseId());
         courseMap.setQwExternalId(link.getQwExternalId());
-        courseMap.setLinkType(0);
         courseMap.setFsUserId(fsUserId);
 
+        if (StringUtil.strIsNullOrEmpty(isOfficial)){
+            courseMap.setLinkType(0);
+        }else {
+            if (isOfficial.equals("1")) {
+                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
+                    courseMap.setLinkType(0);
+                }else {
+                    courseMap.setLinkType(5);
+                }
+            }else if (isOfficial.equals("0")){
+                courseMap.setLinkType(0);
+            }else{
+                courseMap.setLinkType(0);
+            }
+        }
+
+
         String courseJson = JSON.toJSONString(courseMap);
         String realLinkFull = REAL_LINK_PREFIX + courseJson;
         link.setRealLink(realLinkFull);
@@ -1112,7 +1211,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
     private String createLinkByMiniApp(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
                                      Long courseId, Long videoId, String qwUserId,
-                                     String companyUserId, String companyId, String externalId) {
+                                     String companyUserId, String companyId, String externalId,String isOfficial,Long fsUserId) {
         // 获取缓存的配置
         CourseConfig config;
         synchronized(configLock) {
@@ -1137,7 +1236,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         link.setCorpId(logVo.getCorpId());
         link.setCourseId(courseId.longValue());
         link.setQwExternalId(Long.parseLong(externalId));
-        link.setLinkType(3); //正常链接
+
+        if (StringUtil.strIsNullOrEmpty(isOfficial)){
+            link.setLinkType(3);
+        }else {
+            if (isOfficial.equals("1")) {
+                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
+                    link.setLinkType(3);
+                }else {
+                    link.setLinkType(5);
+                }
+            }else if (isOfficial.equals("0")){
+                link.setLinkType(3);
+            }else{
+                link.setLinkType(3);
+            }
+        }
 
         String randomString = generateRandomStringWithLock();
         if (StringUtil.strIsNullOrEmpty(randomString)){
@@ -1153,7 +1267,6 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
         String courseJson = JSON.toJSONString(courseMap);
         String realLinkFull = miniappRealLink + courseJson;
-//        String realLinkFull = config.getMiniprogramPage() + courseJson;
         link.setRealLink(realLinkFull);
 
 

+ 2 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -32,6 +32,8 @@ public interface ICompanyUserService {
      */
     public CompanyUser selectCompanyUserById(Long userId);
 
+    public CompanyUser selectCompanyUserByIdForRedis(Long userId);
+
     /**
      * 查询物业公司管理员信息列表
      *

+ 22 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -1,7 +1,9 @@
 package com.fs.company.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.DataScope;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.*;
@@ -18,6 +20,7 @@ import com.fs.his.vo.CitysAreaVO;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
+import com.fs.voice.utils.StringUtil;
 import com.fs.wxUser.domain.CompanyWxUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -26,6 +29,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -57,6 +61,10 @@ public class CompanyUserServiceImpl implements ICompanyUserService
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
     @Autowired
     public IFsCityService iFsCityService;
+
+    @Autowired
+    private RedisCache redisCache;
+
     /**
      * 查询物业公司管理员信息
      *
@@ -69,6 +77,20 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.selectCompanyUserById(userId);
     }
 
+    @Override
+    public CompanyUser selectCompanyUserByIdForRedis(Long userId) {
+
+        String key =(String)redisCache.getCacheObject("companyUserInfo:"+userId);
+        if (!StringUtil.strIsNullOrEmpty(key)){
+            return JSON.parseObject(key, CompanyUser.class);
+        }
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+
+        redisCache.setCacheObject("companyUserInfo:"+userId ,JSON.toJSONString(companyUser),45, TimeUnit.MINUTES);
+
+        return companyUser;
+    }
+
     /**
      * 查询物业公司管理员信息列表
      *

+ 1 - 1
fs-service/src/main/java/com/fs/qw/vo/QwSopRuleTimeVO.java

@@ -36,7 +36,7 @@ public class QwSopRuleTimeVO extends BaseEntity {
     private Long companyId;
 
     /**
-     发送类型 1定时接口发送 2 Ai接口发送  3完课  4AI对话 5一键群发 6一键群发app
+      发送类型  1企微发送 2 Ai接口发送  3:完课发送  4:AI对话 5一键群发 6客户群群发 7欢迎语补发 8AI 9清除草稿 10发送草稿 11 课程模板类型 12 一键群发APP
      **/
     private Integer sendType;
 

+ 27 - 6
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -27,6 +27,7 @@ import com.fs.qw.param.QwExternalContactVOTime;
 import com.fs.qw.param.QwTagSearchParam;
 import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.impl.AsyncSopTestService;
+import com.fs.qw.service.impl.QwExternalContactServiceImpl;
 import com.fs.qw.vo.GroupUserExternalVo;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopRuleTimeVO;
@@ -134,6 +135,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     @Autowired
     private QwExternalContactMapper qwExternalContactMapper;
 
+    @Autowired
+    private QwExternalContactServiceImpl qwExternalContactService;
+
     @Autowired
     private IQwCompanyService iQwCompanyService;
 
@@ -416,6 +420,11 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         if (config == null) {
             return R.error().put("msg","课程默认配置为空,请联系管理员");
         }
+
+        if (StringUtil.strIsNullOrEmpty(param.getCorpId())){
+            return R.error().put("msg","企业编号为空,不能创建一键群发");
+        }
+
         List<QwSopLogs> sopLogsList;
         if(param.getFilterMode() != null && param.getFilterMode() == 2 && param.getChatIds() != null && param.getChatIds().length > 0){
             List<QwGroupChat> groupList = qwGroupChatMapper.selectQwGroupChatByChatIds(param.getChatIds());
@@ -432,10 +441,16 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 }
                 sopLogsList = groupUserList.stream().map(groupUser -> {
                     QwGroupChat qwGroupChat = groupMap.get(groupUser.getChatId());
-                    QwUser qwUser = qwUserMapper.selectQwUserByIdByWeComeText2(qwGroupChat.getOwner(), qwGroupChat.getCorpId());
-                    if (qwUser == null) {
+
+                    QwUser qwUser = qwExternalContactService.getQwUserByRedis(qwGroupChat.getCorpId(),qwGroupChat.getOwner());
+                    if (qwUser==null){
                         throw new BaseException("企业微信用户不存在:" + qwGroupChat.getOwner());
                     }
+
+//                    QwUser qwUser = qwUserMapper.selectQwUserByIdByWeComeText2(qwGroupChat.getOwner(), qwGroupChat.getCorpId());
+//                    if (qwUser == null) {
+//                        throw new BaseException("企业微信用户不存在:" + qwGroupChat.getOwner());
+//                    }
                     Map<String, GroupUserExternalVo> userMap = PubFun.listToMapByGroupObject(groupUser.getUserList(), GroupUserExternalVo::getUserId);
                     GroupUserExternalVo vo = userMap.get(qwGroupChat.getOwner());
                     QwSopLogs sopLogs = new QwSopLogs();
@@ -450,7 +465,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     sopLogs.setReceivingStatus(0L);
                     sopLogs.setSopId(param.getSopId());
                     sopLogs.setCorpId(qwGroupChat.getCorpId());
-                    sopLogs.setSort(2);
+                    sopLogs.setSort(30000001);
                     sopLogs.setSendType(6);
                     sopLogs.setExternalUserName(groupUser.getName());
                     //域名
@@ -630,14 +645,20 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
             sopLogsList = new ArrayList<>();
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             List<SopUserLogsInfo> sopUserLogsInfos = sopUserLogsInfoMapper.selectSopUserLogsInfoByIds(param.getIds());
+
             String[] userKey = param.getUserIdParam().split("\\|");
+
             String qwUserId = userKey[0].trim();
-            String companyUserId = userKey[1].trim();
-            String companyId = userKey[2].trim();
+
             QwUser qwUser = qwUserMapper.selectQwUserByIdByWeComeText(Long.valueOf(qwUserId));
+
             if (qwUser == null) {
                 return R.error().put("msg","企业微信用户不存在:"+qwUserId);
             }
+
+            String companyUserId = String.valueOf(qwUser.getCompanyUserId()).trim();
+            String companyId = String.valueOf(qwUser.getCompanyId()).trim();
+
             //域名
             String domainName = companyUserMapper.selectDomainByUserId(Long.parseLong(companyUserId));
             if (StringUtils.isEmpty(domainName)){
@@ -660,7 +681,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 sopLogs.setSopId(param.getSopId());
                 sopLogs.setCorpId(item.getCorpId());
                 sopLogs.setFsUserId(item.getFsUserId());
-                sopLogs.setSort(2);
+                sopLogs.setSort(30000000);
                 sopLogs.setSendType(5);
                 sopLogs.setExternalUserName(item.getExternalUserName());