Browse Source

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_scrm_java

caoliqin 1 month ago
parent
commit
14ed84bb22
39 changed files with 506 additions and 66 deletions
  1. 5 0
      fs-company/src/main/java/com/fs/qw/QwGroupChatController.java
  2. 1 1
      fs-company/src/main/resources/application.yml
  3. 99 42
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  4. 1 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseLink.java
  5. 1 0
      fs-service-system/src/main/java/com/fs/course/param/FsCourseLinkCreateParam.java
  6. 1 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  7. 6 0
      fs-service-system/src/main/java/com/fs/qw/domain/QwGroupChat.java
  8. 4 0
      fs-service-system/src/main/java/com/fs/qw/mapper/QwGroupChatMapper.java
  9. 1 0
      fs-service-system/src/main/java/com/fs/qw/mapper/QwGroupChatUserMapper.java
  10. 4 0
      fs-service-system/src/main/java/com/fs/qw/service/IQwGroupChatService.java
  11. 2 0
      fs-service-system/src/main/java/com/fs/qw/service/IQwGroupChatUserService.java
  12. 90 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/AsyncChatSopService.java
  13. 0 1
      fs-service-system/src/main/java/com/fs/qw/service/impl/AsyncSopTestService.java
  14. 11 4
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwGroupChatServiceImpl.java
  15. 6 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwGroupChatUserServiceImpl.java
  16. 93 0
      fs-service-system/src/main/java/com/fs/qw/vo/ChatSopRuleTimeVO.java
  17. 1 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwSopRuleTimeVO.java
  18. 1 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwSopTempSetting.java
  19. 1 0
      fs-service-system/src/main/java/com/fs/qw/vo/WxSopRuleTimeVO.java
  20. 25 14
      fs-service-system/src/main/java/com/fs/sop/domain/QwSop.java
  21. 2 0
      fs-service-system/src/main/java/com/fs/sop/domain/QwSopLogs.java
  22. 2 0
      fs-service-system/src/main/java/com/fs/sop/domain/QwSopTemp.java
  23. 1 0
      fs-service-system/src/main/java/com/fs/sop/domain/SopUserLogs.java
  24. 2 1
      fs-service-system/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java
  25. 5 0
      fs-service-system/src/main/java/com/fs/sop/mapper/QwSopMapper.java
  26. 1 0
      fs-service-system/src/main/java/com/fs/sop/mapper/QwSopTempRulesMapper.java
  27. 4 0
      fs-service-system/src/main/java/com/fs/sop/mapper/SopUserLogsMapper.java
  28. 2 0
      fs-service-system/src/main/java/com/fs/sop/service/IQwSopTempRulesService.java
  29. 3 0
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java
  30. 32 0
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java
  31. 6 0
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java
  32. 22 1
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java
  33. 1 0
      fs-service-system/src/main/java/com/fs/sop/vo/SopUserLogsVo.java
  34. 2 0
      fs-service-system/src/main/resources/mapper/course/FsCourseLinkMapper.xml
  35. 3 0
      fs-service-system/src/main/resources/mapper/qw/QwGroupChatMapper.xml
  36. 3 0
      fs-service-system/src/main/resources/mapper/qw/QwGroupChatUserMapper.xml
  37. 15 1
      fs-service-system/src/main/resources/mapper/sop/QwSopLogsMapper.xml
  38. 26 0
      fs-service-system/src/main/resources/mapper/sop/QwSopMapper.xml
  39. 21 1
      fs-service-system/src/main/resources/mapper/sop/SopUserLogsMapper.xml

+ 5 - 0
fs-company/src/main/java/com/fs/qw/QwGroupChatController.java

@@ -90,4 +90,9 @@ public class QwGroupChatController extends BaseController
         List<QwGroupChatOptionsVO> list = qwGroupChatService.selectGroupChatOptionsVOList(corpId);
         List<QwGroupChatOptionsVO> list = qwGroupChatService.selectGroupChatOptionsVOList(corpId);
         return AjaxResult.success(list);
         return AjaxResult.success(list);
     }
     }
+    @GetMapping("/listAll")
+    public AjaxResult listAll(String qwUserIds){
+        List<QwGroupChatOptionsVO> list = qwGroupChatService.listAllByQwUserList(qwUserIds);
+        return AjaxResult.success(list);
+    }
 }
 }

+ 1 - 1
fs-company/src/main/resources/application.yml

@@ -34,7 +34,7 @@ server:
 # 日志配置
 # 日志配置
 logging:
 logging:
   level:
   level:
-    com.fs: info
+    com.fs: debug
     org.springframework: warn
     org.springframework: warn
 # Spring配置
 # Spring配置
 spring:
 spring:

+ 99 - 42
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -2,24 +2,31 @@ package com.fs.app.taskService.impl;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.app.taskService.SopLogsTaskService;
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.BatchUtils;
 import com.fs.common.utils.BatchUtils;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.date.DateUtil;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.*;
 import com.fs.course.domain.*;
 import com.fs.course.mapper.*;
 import com.fs.course.mapper.*;
+import com.fs.course.param.FsCourseLinkCreateParam;
+import com.fs.course.service.IFsCourseLinkService;
 import com.fs.fastgptApi.util.AudioUtils;
 import com.fs.fastgptApi.util.AudioUtils;
 import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.qw.domain.QwExternalContact;
 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.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwExternalContactService;
+import com.fs.qw.service.IQwGroupChatService;
+import com.fs.qw.service.IQwGroupChatUserService;
 import com.fs.qw.service.impl.QwExternalContactServiceImpl;
 import com.fs.qw.service.impl.QwExternalContactServiceImpl;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.QwSopRuleTimeVO;
@@ -55,6 +62,7 @@ import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
 import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
@@ -92,9 +100,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private QwSopTagMapper qwSopTagMapper ;
     private QwSopTagMapper qwSopTagMapper ;
     @Autowired
     @Autowired
     private QwSopMapper sopMapper;
     private QwSopMapper sopMapper;
+    @Autowired
+    private IFsCourseLinkService courseLinkService;
 
 
     @Autowired
     @Autowired
     private IQwExternalContactService iQwExternalContactService;
     private IQwExternalContactService iQwExternalContactService;
+    @Autowired
+    private IQwGroupChatService qwGroupChatService;
+    @Autowired
+    private IQwGroupChatUserService qwGroupChatUserService;
 
 
     @Autowired
     @Autowired
     private QwExternalContactServiceImpl qwExternalContactService;
     private QwExternalContactServiceImpl qwExternalContactService;
@@ -263,7 +277,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             log.info("没有需要处理的 SOP 用户日志。");
             log.info("没有需要处理的 SOP 用户日志。");
             return;
             return;
         }
         }
-
+        String[] array = sopUserLogsVos.stream().map(SopUserLogsVo::getChatId).filter(StringUtils::isNotEmpty).toArray(String[]::new);
+        Map<String, QwGroupChat> groupChatMap = new HashMap<>();
+        if(array.length > 0){
+            List<QwGroupChat> qwGroupChatList = qwGroupChatService.selectQwGroupChatByChatIds(array);
+            List<QwGroupChatUser> qwGroupChatUserList = qwGroupChatUserService.selectQwGroupChatUserByChatIds(array);
+            Map<String, List<QwGroupChatUser>> chatUserMap = PubFun.listToMapByGroupList(qwGroupChatUserList, QwGroupChatUser::getChatId);
+            qwGroupChatList.stream().filter(e -> chatUserMap.containsKey(e.getChatId())).forEach(e -> e.setChatUserList(chatUserMap.get(e.getChatId())));
+            groupChatMap = PubFun.listToMapByGroupObject(qwGroupChatList, QwGroupChat::getChatId);
+        }
         // 查询销售二级域名
         // 查询销售二级域名
         Set<Long> ids = sopUserLogsVos.stream().map(s -> {
         Set<Long> ids = sopUserLogsVos.stream().map(s -> {
             String[] userKey = s.getUserId().split("\\|");
             String[] userKey = s.getUserId().split("\\|");
@@ -308,7 +330,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
         for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
             String sopId = entry.getKey();
             String sopId = entry.getKey();
             List<SopUserLogsVo> userLogsVos = entry.getValue();
             List<SopUserLogsVo> userLogsVos = entry.getValue();
-            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime);
+            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap);
         }
         }
 
 
         // 等待所有 SOP 分组处理完成
         // 等待所有 SOP 分组处理完成
@@ -328,9 +350,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             maxAttempts = 3,
             maxAttempts = 3,
             backoff = @Backoff(delay = 2000)
             backoff = @Backoff(delay = 2000)
     )
     )
-    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime) {
+    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch , LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
         try {
         try {
-            processSopGroup(sopId, userLogsVos,currentTime);
+            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
             log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
         } finally {
         } finally {
@@ -339,7 +361,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     }
     }
 
 
 
 
-    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime) throws Exception {
+    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) throws Exception {
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
 
 
         if (ruleTimeVO == null) {
         if (ruleTimeVO == null) {
@@ -373,7 +395,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
         CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
         CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
         for (SopUserLogsVo logVo : userLogsVos) {
         for (SopUserLogsVo logVo : userLogsVos) {
-            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime);
+            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap);
         }
         }
 
 
         // 等待所有用户日志处理完成
         // 等待所有用户日志处理完成
@@ -392,9 +414,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             maxAttempts = 3,
             maxAttempts = 3,
             backoff = @Backoff(delay = 2000)
             backoff = @Backoff(delay = 2000)
     )
     )
-    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, CountDownLatch latch, LocalDateTime currentTime) {
+    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
         try {
         try {
-            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime);
+            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
             log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
         } finally {
         } finally {
@@ -403,7 +425,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     }
     }
 
 
 
 
-    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, LocalDateTime currentTime) {
+    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
         try {
         try {
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
             LocalDate currentDate = currentTime.toLocalDate();
             LocalDate currentDate = currentTime.toLocalDate();
@@ -429,11 +451,11 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 day++;
                 day++;
             }
             }
             List<QwSopTempSetting.Content> contents = getDay(tempSettings, day);
             List<QwSopTempSetting.Content> contents = getDay(tempSettings, day);
+
             if (contents == null || contents.isEmpty()) {
             if (contents == null || contents.isEmpty()) {
                 log.error("SOP ID {} 的 TempSetting 内容为空,跳过处理。", logVo.getSopId());
                 log.error("SOP ID {} 的 TempSetting 内容为空,跳过处理。", logVo.getSopId());
                 return;
                 return;
             }
             }
-
             String[] userKey = logVo.getUserId().split("\\|");
             String[] userKey = logVo.getUserId().split("\\|");
             if (userKey.length < 3) {
             if (userKey.length < 3) {
                 log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
                 log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
@@ -487,7 +509,6 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
             for (QwSopTempSetting.Content content : contents) {
             for (QwSopTempSetting.Content content : contents) {
                 try {
                 try {
-
                     LocalTime elementLocalTime = LocalTime.parse(content.getTime());
                     LocalTime elementLocalTime = LocalTime.parse(content.getTime());
                     LocalDateTime elementDateTime = LocalDateTime.of(currentTime.toLocalDate(), elementLocalTime);
                     LocalDateTime elementDateTime = LocalDateTime.of(currentTime.toLocalDate(), elementLocalTime);
 
 
@@ -508,7 +529,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
                         // 如果时间差在目标范围内,更新记录
                         // 如果时间差在目标范围内,更新记录
                         // 组合年月日和element的时间
                         // 组合年月日和element的时间
-                        LocalDate targetDate = startDate.plusDays(intervalDay * tempGap);
+                        LocalDate targetDate = startDate.plusDays((long) intervalDay * tempGap);
 
 
                         // 将 targetDate 和 elementTime 组合成 LocalDateTime
                         // 将 targetDate 和 elementTime 组合成 LocalDateTime
                         LocalDateTime dateTime = LocalDateTime.of(targetDate, elementLocalTime);
                         LocalDateTime dateTime = LocalDateTime.of(targetDate, elementLocalTime);
@@ -548,7 +569,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 //                        }
 //                        }
 
 
 //                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content);
 //                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content);
-                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId, companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName());
+                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId, companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(), groupChatMap);
 
 
 
 
                     }
                     }
@@ -565,6 +586,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
     private List<QwSopTempSetting.Content> getDay(List<QwSopTempRules> tempSettings, long days){
     private List<QwSopTempSetting.Content> getDay(List<QwSopTempRules> tempSettings, long days){
         List<QwSopTempRules> collect = tempSettings.stream().filter(e -> e.getDayNum() == days).collect(Collectors.toList());
         List<QwSopTempRules> collect = tempSettings.stream().filter(e -> e.getDayNum() == days).collect(Collectors.toList());
+        AtomicInteger i = new AtomicInteger();
         return collect.stream().map(e -> {
         return collect.stream().map(e -> {
             QwSopTempSetting.Content content = new QwSopTempSetting.Content();
             QwSopTempSetting.Content content = new QwSopTempSetting.Content();
             content.setId(e.getId());
             content.setId(e.getId());
@@ -583,13 +605,13 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             content.setCourseType(e.getCourseType());
             content.setCourseType(e.getCourseType());
             content.setAiTouch(e.getAiTouch());
             content.setAiTouch(e.getAiTouch());
             return content;
             return content;
-        }).collect(Collectors.toList());
+        }).sorted(Comparator.comparing(e -> LocalTime.parse(e.getTime() + ":00"))).peek(e -> e.setIndex(i.getAndIncrement())).collect(Collectors.toList());
     }
     }
 
 
     //消息处理
     //消息处理
     private void insertSopUserLogs(List<SopUserLogsInfo> sopUserLogsInfos, SopUserLogsVo logVo, Date sendTime,
     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) {
+                                   QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
+                                   String qwUserId, String companyUserId, String companyId, String welcomeText, String qwUserName, Map<String, QwGroupChat> groupChatMap) {
 
 
         String formattedSendTime = sendTime.toInstant()
         String formattedSendTime = sendTime.toInstant()
                 .atZone(ZoneId.systemDefault())
                 .atZone(ZoneId.systemDefault())
@@ -639,20 +661,37 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             sopAddTag(logVo,content,sendTime);
             sopAddTag(logVo,content,sendTime);
         }
         }
 
 
-
-        // 处理每个 externalContactId
-        sopUserLogsInfos.forEach(contactId -> {
-            try {
-                String externalId = contactId.getExternalId().toString();
-                String externalUserName = contactId.getExternalUserName();
-                Long fsUserId = contactId.getFsUserId();
-                QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId);
+        if(StringUtils.isNotEmpty(logVo.getChatId())){
+            QwGroupChat groupChat = groupChatMap.get(logVo.getChatId());
+            ruleTimeVO.setSendType(6);
+            ruleTimeVO.setType(2);
+            if(content.getIndex() == 0){
+                QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null);
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        type, qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName,fsUserId);
-            } catch (Exception e) {
-                log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
+                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText,qwUserName, null, true);
+            }else{
+                groupChat.getChatUserList().forEach(user -> {
+                    QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null);
+                    handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
+                            type, qwUserId, companyUserId, companyId, user.getUserId(), welcomeText,qwUserName, null, false);
+                });
             }
             }
-        });
+        }else{
+            // 处理每个 externalContactId
+            sopUserLogsInfos.forEach(contactId -> {
+                try {
+                    String externalId = contactId.getExternalId().toString();
+                    String externalUserName = contactId.getExternalUserName();
+                    Long fsUserId = contactId.getFsUserId();
+                    QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId);
+                    handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
+                            type, qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName,fsUserId, false);
+                } catch (Exception e) {
+                    log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
+                }
+            });
+        }
+
     }
     }
 
 
     private void sopAddTag(SopUserLogsVo logVo, QwSopTempSetting.Content content, Date sendTime) {
     private void sopAddTag(SopUserLogsVo logVo, QwSopTempSetting.Content content, Date sendTime) {
@@ -700,15 +739,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
     private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       Long videoId, int type, String qwUserId,
                                       Long videoId, int type, String qwUserId,
-                                      String companyUserId, String companyId, String externalId,String welcomeText,
-                                      String qwUserName,Long fsUserId) {
+                                      String companyUserId, String companyId, String externalId, String welcomeText,
+                                      String qwUserName, Long fsUserId, boolean isGroupChat) {
         switch (type) {
         switch (type) {
             case 1:
             case 1:
                 handleNormalMessage(sopLogs, content,companyUserId);
                 handleNormalMessage(sopLogs, content,companyUserId);
                 break;
                 break;
             case 2:
             case 2:
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName,fsUserId);
+                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName,fsUserId, isGroupChat);
                 break;
                 break;
             case 3:
             case 3:
                 handleOrderMessage(sopLogs, content);
                 handleOrderMessage(sopLogs, content);
@@ -740,8 +779,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
     private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      Long videoId, String qwUserId, String companyUserId,
                                      Long videoId, String qwUserId, String companyUserId,
-                                     String companyId, String externalId,String welcomeText,
-                                     String qwUserName,Long fsUserId) {
+                                     String companyId, String externalId, String welcomeText,
+                                     String qwUserName, Long fsUserId, boolean isGroupChat) {
         // 深拷贝 Content 对象,避免使用 JSON
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
         if (clonedContent == null) {
@@ -766,22 +805,40 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 case "1":
                 case "1":
                 case "3":
                 case "3":
                     if ("1".equals(setting.getIsBindUrl())) {
                     if ("1".equals(setting.getIsBindUrl())) {
+                        String link;
+                        if(isGroupChat){
+                            FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
+                            createParam.setCourseId(courseId);
+                            createParam.setVideoId(videoId);
+                            createParam.setCorpId(logVo.getCorpId());
+                            createParam.setCompanyUserId(Long.parseLong(companyUserId));
+                            createParam.setCompanyId(Long.parseLong(companyId));
+                            createParam.setChatId(logVo.getChatId());
+                            createParam.setQwUserId(qwUserId);
+                            createParam.setDays(setting.getExpiresDays());
+                            R createLink = courseLinkService.createRoomLinkUrl(createParam);
+                            if (createLink.get("code").equals(500)){
+                                throw new BaseException("链接生成失败!");
+                            }
+                            link = (String) createLink.get("url");
+                        }else{
+                            addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
+                            link = generateShortLink(setting, logVo, sendTime, courseId, videoId,
+                                    qwUserId, companyUserId, companyId, externalId,fsUserId);
+                        }
 
 
-                        addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
-                        String sortLink = generateShortLink(setting, logVo, sendTime, courseId, videoId,
-                                qwUserId, companyUserId, companyId, externalId,fsUserId);
-                        if (StringUtils.isNotEmpty(sortLink)) {
+                        if (StringUtils.isNotEmpty(link)) {
                             if ("3".equals(setting.getContentType())) {
                             if ("3".equals(setting.getContentType())) {
-                                setting.setLinkUrl(sortLink);
+                                setting.setLinkUrl(link);
                             } else {
                             } else {
                                 String currentValue = setting.getValue();
                                 String currentValue = setting.getValue();
                                 if (currentValue == null) {
                                 if (currentValue == null) {
-                                    setting.setValue(sortLink);
+                                    setting.setValue(link);
                                 } else {
                                 } else {
 //                                    setting.setValue(currentValue + "\n" + sortLink);
 //                                    setting.setValue(currentValue + "\n" + sortLink);
                                     setting.setValue(currentValue
                                     setting.setValue(currentValue
                                             .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(welcomeText)?"":welcomeText)
                                             .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(welcomeText)?"":welcomeText)
-                                            + "\n" + sortLink);
+                                            + "\n" + link);
                                 }
                                 }
                             }
                             }
                         } else {
                         } else {

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseLink.java

@@ -57,5 +57,6 @@ public class FsCourseLink extends BaseEntity
 //    private String link_uuid;
 //    private String link_uuid;
 
 
     private Integer isRoom;//是否发群
     private Integer isRoom;//是否发群
+    private String chatId;//是否发群
 
 
 }
 }

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/param/FsCourseLinkCreateParam.java

@@ -27,6 +27,7 @@ public class FsCourseLinkCreateParam {
     private Integer sendType;
     private Integer sendType;
 
 
     private Date sendTime;
     private Date sendTime;
+    private String chatId;
 
 
     @ApiModelProperty(value = "链接有效时长(分钟)")
     @ApiModelProperty(value = "链接有效时长(分钟)")
     private Integer effectiveDuration;
     private Integer effectiveDuration;

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -211,6 +211,7 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
         link.setRealLink(realLink+course);
         link.setRealLink(realLink+course);
         String randomString = generateRandomString();
         String randomString = generateRandomString();
         link.setLink(randomString);
         link.setLink(randomString);
+        link.setChatId(param.getChatId());
         link.setCreateTime(new Date());
         link.setCreateTime(new Date());
         Integer expireDays = 0;
         Integer expireDays = 0;
         if (param.getDays() == null || param.getDays() == 0){
         if (param.getDays() == null || param.getDays() == 0){

+ 6 - 0
fs-service-system/src/main/java/com/fs/qw/domain/QwGroupChat.java

@@ -1,9 +1,12 @@
 package com.fs.qw.domain;
 package com.fs.qw.domain;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fs.common.annotation.Excel;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
 import com.fs.common.core.domain.BaseEntity;
 import lombok.Data;
 import lombok.Data;
 
 
+import java.util.List;
+
 /**
 /**
  * 客户群详情对象 qw_group_chat
  * 客户群详情对象 qw_group_chat
  *
  *
@@ -71,4 +74,7 @@ public class QwGroupChat extends BaseEntity
     @Excel(name = "累计退群人数")
     @Excel(name = "累计退群人数")
     private Long allOutGroup;
     private Long allOutGroup;
 
 
+    @TableField(exist = false)
+    private List<QwGroupChatUser> chatUserList;
+
 }
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/QwGroupChatMapper.java

@@ -110,4 +110,8 @@ public interface QwGroupChatMapper
     @Select("select chat_id,name from qw_group_chat where  corp_id=#{corpId}")
     @Select("select chat_id,name from qw_group_chat where  corp_id=#{corpId}")
     List<QwGroupChatOptionsVO> selectGroupChatOptionsVOList(String corpId);
     List<QwGroupChatOptionsVO> selectGroupChatOptionsVOList(String corpId);
 
 
+    @Select("select chat_id,name from qw_group_chat where  find_in_set(owner,#{qwUserIds})")
+    List<QwGroupChatOptionsVO> listAllByQwUserList(String qwUserIds);
+
+    List<QwGroupChat> selectQwGroupChatByChatIds(@Param("ids") String[] ids);
 }
 }

+ 1 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/QwGroupChatUserMapper.java

@@ -139,4 +139,5 @@ public interface QwGroupChatUserMapper
     @Delete("delete from qw_group_chat_user where chat_id=#{chatId} and corp_id=#{corpId}")
     @Delete("delete from qw_group_chat_user where chat_id=#{chatId} and corp_id=#{corpId}")
     public int deleteQwGroupChatUserByIdAndCompanyId(@Param("chatId") String chatId,@Param("corpId") String corpId);
     public int deleteQwGroupChatUserByIdAndCompanyId(@Param("chatId") String chatId,@Param("corpId") String corpId);
 
 
+    List<QwGroupChatUser> selectQwGroupChatUserByChatIds(@Param("ids") String[] ids);
 }
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/qw/service/IQwGroupChatService.java

@@ -62,4 +62,8 @@ public interface IQwGroupChatService
     public int deleteQwGroupChatByChatIdAndCompanyId(String chatId,String corpId);
     public int deleteQwGroupChatByChatIdAndCompanyId(String chatId,String corpId);
 
 
     List<QwGroupChatOptionsVO> selectGroupChatOptionsVOList(String corpId);
     List<QwGroupChatOptionsVO> selectGroupChatOptionsVOList(String corpId);
+
+    List<QwGroupChatOptionsVO> listAllByQwUserList(String qwUserIds);
+
+    List<QwGroupChat> selectQwGroupChatByChatIds(String[] ids);
 }
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/qw/service/IQwGroupChatUserService.java

@@ -46,4 +46,6 @@ public interface IQwGroupChatUserService
     /** 根据成员id和公司corpId等查询群成员信息 */
     /** 根据成员id和公司corpId等查询群成员信息 */
 
 
     public QwGroupChatUser selectQwGroupChatUserByExternalUserId(QwGroupChatUser qwGroupChatUser);
     public QwGroupChatUser selectQwGroupChatUserByExternalUserId(QwGroupChatUser qwGroupChatUser);
+
+    List<QwGroupChatUser> selectQwGroupChatUserByChatIds(String[] array);
 }
 }

+ 90 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/AsyncChatSopService.java

@@ -0,0 +1,90 @@
+package com.fs.qw.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fs.common.utils.PubFun;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.date.DateUtil;
+import com.fs.qw.domain.QwGroupChat;
+import com.fs.qw.service.IQwGroupChatService;
+import com.fs.qw.service.IQwUserService;
+import com.fs.qw.vo.ChatSopRuleTimeVO;
+import com.fs.qw.vo.QwUserVO;
+import com.fs.sop.domain.QwSop;
+import com.fs.sop.domain.QwSopTemp;
+import com.fs.sop.domain.SopUserLogs;
+import com.fs.sop.mapper.QwSopMapper;
+import com.fs.sop.mapper.QwSopTempMapper;
+import com.fs.sop.mapper.SopUserLogsMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@AllArgsConstructor
+public class AsyncChatSopService {
+
+    private final QwSopMapper qwSopMapper;
+    private final QwSopTempMapper qwSopTempMapper;
+    private final SopUserLogsMapper sopUserLogsMapper;
+    private final IQwUserService qwUserService;
+    private final IQwGroupChatService qwGroupChatService;
+
+    /**
+     * 立即执行SOP任务
+     */
+    @Async("scheduledExecutorService")
+    public void executeChatSopByIds(String[] ids) {
+        try {
+            List<ChatSopRuleTimeVO> ruleTimeVOList = qwSopMapper.executeSopChatByIds(ids);
+            List<QwSopTemp> tempList = qwSopTempMapper.selectListByIds(PubFun.listToNewList(ruleTimeVOList, ChatSopRuleTimeVO::getTempId));
+            Map<String, QwSopTemp> tempMap = PubFun.listToMapByGroupObject(tempList, QwSopTemp::getId);
+            ruleTimeVOList = ruleTimeVOList.stream().filter(e -> tempMap.containsKey(e.getTempId())).collect(Collectors.toList());
+            List<QwUserVO> qwUserVOList = qwUserService.selectQwUserVOByIds(ruleTimeVOList.stream().flatMap(e -> Arrays.stream(e.getQwUserIds().split(",")).map(Long::parseLong)).toArray(Long[]::new));
+            Map<String, QwUserVO> qwUserMap = PubFun.listToMapByGroupObject(qwUserVOList, QwUserVO::getQwUserId);
+            List<QwGroupChat> qwGroupChatList = qwGroupChatService.selectQwGroupChatByChatIds(ruleTimeVOList.stream().flatMap(e -> Arrays.stream(e.getChatId().split(","))).toArray(String[]::new));
+            Map<String, QwGroupChat> groupChatMap = PubFun.listToMapByGroupObject(qwGroupChatList, QwGroupChat::getChatId);
+            ruleTimeVOList.forEach(ruleTimeVO -> {
+                QwSopTemp qwSopTemp = tempMap.get(ruleTimeVO.getTempId());
+                if (!qwSopTemp.getStatus().equals("0")) {
+                    processInternal(ruleTimeVO, qwSopTemp, qwUserMap, groupChatMap);
+                }
+                QwSop qwSop = new QwSop();
+                qwSop.setStatus(3L);
+            });
+            qwSopMapper.updateStatusQwSopById2(PubFun.listToNewList(ruleTimeVOList, ChatSopRuleTimeVO::getId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("立即执行执行失败", e);
+        }
+    }
+
+    private void processInternal(ChatSopRuleTimeVO timeVO, QwSopTemp temp, Map<String, QwUserVO> qwUserMap, Map<String, QwGroupChat> groupChatMap) {
+        if(StringUtils.isNotEmpty(timeVO.getChatId())){
+            List<SopUserLogs> list = Arrays.stream(timeVO.getChatId().split(",")).map(e -> {
+                SopUserLogs sopUserLogs = new SopUserLogs();
+                sopUserLogs.setSopId(timeVO.getId());
+                sopUserLogs.setSopTempId(temp.getId());
+                QwGroupChat groupChat = groupChatMap.get(e);
+                sopUserLogs.setQwUserId(groupChat.getOwner());
+                sopUserLogs.setChatId(e);
+                sopUserLogs.setCorpId(timeVO.getCorpId());
+                sopUserLogs.setStartTime(DateUtil.formatLocalDate(timeVO.getStartTime()));
+                sopUserLogs.setStatus(1);
+                QwUserVO qwUserVO = qwUserMap.get(groupChat.getOwner());
+                if(qwUserVO != null){
+                    sopUserLogs.setUserId(qwUserVO.getId() + "|" + qwUserVO.getCompanyUserId() + "|" + qwUserVO.getCompanyId());
+                }
+                return sopUserLogs;
+            }).collect(Collectors.toList());
+            sopUserLogsMapper.batchInsertSopUserLogs(list);
+        }
+    }
+
+}

+ 0 - 1
fs-service-system/src/main/java/com/fs/qw/service/impl/AsyncSopTestService.java

@@ -512,5 +512,4 @@ public class AsyncSopTestService {
         });
         });
 
 
     }
     }
-
 }
 }

+ 11 - 4
fs-service-system/src/main/java/com/fs/qw/service/impl/QwGroupChatServiceImpl.java

@@ -30,10 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 
 /**
 /**
  * 客户群详情Service业务层处理
  * 客户群详情Service业务层处理
@@ -290,6 +287,16 @@ public class QwGroupChatServiceImpl implements IQwGroupChatService
         return qwGroupChatMapper.selectGroupChatOptionsVOList(corpId);
         return qwGroupChatMapper.selectGroupChatOptionsVOList(corpId);
     }
     }
 
 
+    @Override
+    public List<QwGroupChatOptionsVO> listAllByQwUserList(String qwUserIds) {
+        return qwGroupChatMapper.listAllByQwUserList(qwUserIds);
+    }
+
+    @Override
+    public List<QwGroupChat> selectQwGroupChatByChatIds(String[] ids) {
+        return qwGroupChatMapper.selectQwGroupChatByChatIds(ids);
+    }
+
     /**
     /**
      *  同步客户群列表
      *  同步客户群列表
      */
      */

+ 6 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/QwGroupChatUserServiceImpl.java

@@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collections;
 import java.util.Date;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
@@ -214,4 +215,9 @@ public class QwGroupChatUserServiceImpl implements IQwGroupChatUserService
         return qwGroupChatUserMapper.selectQwGroupChatUserByExternalUserId(qwGroupChatUser);
         return qwGroupChatUserMapper.selectQwGroupChatUserByExternalUserId(qwGroupChatUser);
     }
     }
 
 
+    @Override
+    public List<QwGroupChatUser> selectQwGroupChatUserByChatIds(String[] array) {
+        return qwGroupChatUserMapper.selectQwGroupChatUserByChatIds(array);
+    }
+
 }
 }

+ 93 - 0
fs-service-system/src/main/java/com/fs/qw/vo/ChatSopRuleTimeVO.java

@@ -0,0 +1,93 @@
+package com.fs.qw.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+//查出要执行的SOP
+@Data
+public class ChatSopRuleTimeVO extends BaseEntity {
+
+    /** id */
+    private String id;
+
+    private String corpId;
+
+    /** 规则名称 */
+    @Excel(name = "规则名称")
+    private String name;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long status;
+
+    /** 类别 1个人 2企业微信 */
+    @Excel(name = "类别 1个人 2企业微信")
+    private Integer type;
+
+    /** qw_user主表的主键 */
+    @Excel(name = "qw_user主表的主键")
+    private String qwUserIds;
+
+    @Excel(name = "公司编号")
+    private Long companyId;
+
+    /**
+     发送类型 1定时接口发送 2 Ai接口发送  3wanke  4AIduihua
+     **/
+    private Integer sendType;
+
+    /**
+    * 筛选的标签
+    */
+    private String tags;
+
+    /**
+    * 排除的标签
+    */
+    private String excludeTags;
+
+    /**
+    * 开始时间
+    */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate startTime;
+    /**
+     *  是否开启新客户添加自动创建sop 1 否 2 是
+     */
+    private Integer isAutoSop;
+    /**
+     *   自动添加SOP的时间段
+     */
+    private String autoSopTime;
+
+    /**
+    * 模板id
+    */
+    private String tempId;
+
+    /**
+     * 过滤类别 1 包含全部 2 包含任意
+     */
+    private Integer filterType;
+
+    /**
+    * 模板内容
+    */
+//    private String tempSetting;
+
+    /**
+    * 模板状态 正常  停用
+    */
+    private String tempStatus;
+
+    /**
+    * 间隔天数
+    */
+    private Integer tempGap;
+    private String chatId;
+
+}

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

@@ -89,5 +89,6 @@ public class QwSopRuleTimeVO extends BaseEntity {
     */
     */
     private Integer tempGap;
     private Integer tempGap;
     private Integer project;
     private Integer project;
+    private String chatId;
 
 
 }
 }

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

@@ -21,6 +21,7 @@ public class QwSopTempSetting implements Serializable{
         //普通/课程/订单/ai
         //普通/课程/订单/ai
         private Long id;
         private Long id;
         private int type;
         private int type;
+        private int index;
 
 
         private String contentType;
         private String contentType;
 
 

+ 1 - 0
fs-service-system/src/main/java/com/fs/qw/vo/WxSopRuleTimeVO.java

@@ -89,5 +89,6 @@ public class WxSopRuleTimeVO extends BaseEntity {
     * 间隔天数
     * 间隔天数
     */
     */
     private Integer tempGap;
     private Integer tempGap;
+    private String chatId;
 
 
 }
 }

+ 25 - 14
fs-service-system/src/main/java/com/fs/sop/domain/QwSop.java

@@ -15,26 +15,35 @@ import java.io.Serializable;
  * @date 2024-07-31
  * @date 2024-07-31
  */
  */
 @Data
 @Data
-public class QwSop implements Serializable
-{
+public class QwSop implements Serializable {
 
 
-    /** id */
+    /**
+     * id
+     */
     @TableId(type = IdType.UUID)
     @TableId(type = IdType.UUID)
     private String id;
     private String id;
 
 
-    /** 规则名称 */
+    /**
+     * 规则名称
+     */
     @Excel(name = "规则名称")
     @Excel(name = "规则名称")
     private String name;
     private String name;
 
 
-    /** 状态 */
+    /**
+     * 状态
+     */
     @Excel(name = "状态")
     @Excel(name = "状态")
     private Long status;
     private Long status;
 
 
-    /** 类别 1个人 2企业微信 */
+    /**
+     * 类别 1个人 2企业微信
+     */
     @Excel(name = "类别 1个人 2企业微信")
     @Excel(name = "类别 1个人 2企业微信")
     private Integer type;
     private Integer type;
 
 
-    /** qw_user主表的主键 */
+    /**
+     * qw_user主表的主键
+     */
     @Excel(name = "qw_user主表的主键")
     @Excel(name = "qw_user主表的主键")
     private String qwUserIds;
     private String qwUserIds;
 
 
@@ -42,7 +51,7 @@ public class QwSop implements Serializable
     private Long companyId;
     private Long companyId;
 
 
     /**
     /**
-     发送类型 1定时接口发送 2 Ai接口发送 3完课 4ai新客对话
+     * 发送类型 1定时接口发送 2 Ai接口发送 3完课 4ai新客对话
      **/
      **/
     private Integer sendType;
     private Integer sendType;
 
 
@@ -68,12 +77,12 @@ public class QwSop implements Serializable
     private Integer expiryTime;
     private Integer expiryTime;
 
 
     /**
     /**
-    *  是否开启新客户添加自动创建sop 1 否 2 是
-    */
+     * 是否开启新客户添加自动创建sop 1 否 2 是
+     */
     private Integer isAutoSop;
     private Integer isAutoSop;
     /**
     /**
-    *   自动添加SOP的时间段
-    */
+     * 自动添加SOP的时间段
+     */
     private String autoSopTime;
     private String autoSopTime;
 
 
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@@ -88,8 +97,8 @@ public class QwSop implements Serializable
     private Integer voice;
     private Integer voice;
 
 
     /**
     /**
-    * 是否开启评级 1否 2是
-    */
+     * 是否开启评级 1否 2是
+     */
     private Integer isRating;
     private Integer isRating;
 
 
     private Integer courseDay;
     private Integer courseDay;
@@ -110,5 +119,7 @@ public class QwSop implements Serializable
     // 新课对话模板
     // 新课对话模板
     private String newTemplateId;
     private String newTemplateId;
     private Integer project;
     private Integer project;
+    // 群聊ID
+    private String chatId;
 
 
 }
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/sop/domain/QwSopLogs.java

@@ -17,6 +17,8 @@ public class QwSopLogs implements Serializable {
 
 
     private String id;
     private String id;
 
 
+    private Integer type;
+
     private String corpId;
     private String corpId;
 
 
     private Long customerId;
     private Long customerId;

+ 2 - 0
fs-service-system/src/main/java/com/fs/sop/domain/QwSopTemp.java

@@ -65,6 +65,8 @@ public class QwSopTemp implements Serializable
     @TableField(exist = false)
     @TableField(exist = false)
     private List<Map<String, Object>> rules;
     private List<Map<String, Object>> rules;
     @TableField(exist = false)
     @TableField(exist = false)
+    private boolean cuoser;
+    @TableField(exist = false)
     private List<QwSopTempDay> list = new ArrayList<>();
     private List<QwSopTempDay> list = new ArrayList<>();
 
 
 }
 }

+ 1 - 0
fs-service-system/src/main/java/com/fs/sop/domain/SopUserLogs.java

@@ -13,6 +13,7 @@ public class SopUserLogs implements Serializable {
     private String sopTempId;
     private String sopTempId;
 
 
     private String qwUserId;
     private String qwUserId;
+    private String chatId;
     private String corpId;
     private String corpId;
     @JsonFormat(pattern = "yyyy-MM-dd")
     @JsonFormat(pattern = "yyyy-MM-dd")
     private String startTime;
     private String startTime;

+ 2 - 1
fs-service-system/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java

@@ -274,5 +274,6 @@ public interface QwSopLogsMapper extends BaseMapper<QwSopLogs> {
 
 
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
     List<QwSopLogs> selectSopLogsByCreateCorpMassSendResult();
     List<QwSopLogs> selectSopLogsByCreateCorpMassSendResult();
-
+    @DataSource(DataSourceType.SOP)
+    List<QwSopLogsListCVO> selectQwSopLogsListByChatSopId(@Param("map") QwSopLogsParam param);
 }
 }

+ 5 - 0
fs-service-system/src/main/java/com/fs/sop/mapper/QwSopMapper.java

@@ -8,6 +8,7 @@ import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
 import com.fs.common.enums.DataSourceType;
 import com.fs.qw.domain.QwSopUpdateStatus;
 import com.fs.qw.domain.QwSopUpdateStatus;
 import com.fs.qw.result.QwFilterSopCustomersResult;
 import com.fs.qw.result.QwFilterSopCustomersResult;
+import com.fs.qw.vo.ChatSopRuleTimeVO;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.WxSopRuleTimeVO;
 import com.fs.qw.vo.WxSopRuleTimeVO;
 import com.fs.sop.domain.QwSop;
 import com.fs.sop.domain.QwSop;
@@ -246,6 +247,8 @@ public interface QwSopMapper extends BaseMapper<QwSop> {
     public List<QwSopRuleTimeVO> executeSopByIds(@Param("ids") String[] ids);
     public List<QwSopRuleTimeVO> executeSopByIds(@Param("ids") String[] ids);
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
     public List<WxSopRuleTimeVO> executeSopWxByIds(@Param("ids") String[] ids);
     public List<WxSopRuleTimeVO> executeSopWxByIds(@Param("ids") String[] ids);
+    @DataSource(DataSourceType.SOP)
+    public List<ChatSopRuleTimeVO> executeSopChatByIds(@Param("ids") String[] ids);
 
 
 //    @Select("<script> " +
 //    @Select("<script> " +
 //            "SELECT\n" +
 //            "SELECT\n" +
@@ -271,6 +274,8 @@ public interface QwSopMapper extends BaseMapper<QwSop> {
 
 
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
     public int updateStatusQwSopById(@Param("ids") String[] ids);
     public int updateStatusQwSopById(@Param("ids") String[] ids);
+    @DataSource(DataSourceType.SOP)
+    public int updateStatusQwSopById2(@Param("ids") List<String> ids);
 
 
 
 
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)

+ 1 - 0
fs-service-system/src/main/java/com/fs/sop/mapper/QwSopTempRulesMapper.java

@@ -78,4 +78,5 @@ public interface QwSopTempRulesMapper extends BaseMapper<QwSopTempRules>{
     List<QwSopTempRules> listByTempIdAndNameAndDayNum(@Param("id") String id, @Param("dayNum") Integer dayNum);
     List<QwSopTempRules> listByTempIdAndNameAndDayNum(@Param("id") String id, @Param("dayNum") Integer dayNum);
 
 
     void deleteByIdList(@Param("ids") List<String> ids);
     void deleteByIdList(@Param("ids") List<String> ids);
+
 }
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/sop/mapper/SopUserLogsMapper.java

@@ -17,6 +17,7 @@ import java.util.List;
 
 
 
 
 @Repository
 @Repository
+@DataSource(DataSourceType.SOP)
 public interface SopUserLogsMapper {
 public interface SopUserLogsMapper {
 
 
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
@@ -162,4 +163,7 @@ public interface SopUserLogsMapper {
             "order by start_time desc" +
             "order by start_time desc" +
             "</script>"})
             "</script>"})
     List<SopUserLogsVO> selectSopUserLogsListByParam(@Param("maps") SopUserLogsParam param);
     List<SopUserLogsVO> selectSopUserLogsListByParam(@Param("maps") SopUserLogsParam param);
+
+    @DataSource(DataSourceType.SOP)
+    void batchInsertSopUserLogs(@Param("list") List<SopUserLogs> list);
 }
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/sop/service/IQwSopTempRulesService.java

@@ -88,4 +88,6 @@ public interface IQwSopTempRulesService extends IService<QwSopTempRules>{
     List<QwSopTempRules> listById(List<Long> rulesIds);
     List<QwSopTempRules> listById(List<Long> rulesIds);
 
 
     void updateSiFenTemp();
     void updateSiFenTemp();
+
+    List<QwSopTempRules> selectByTemplateIds(List<String> ids);
 }
 }

+ 3 - 0
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java

@@ -134,6 +134,9 @@ public class QwSopLogsServiceImpl implements IQwSopLogsService
             //企微
             //企微
             case 2:
             case 2:
                 return qwSopLogsMapper.selectQwSopLogsListByQwSopId(param);
                 return qwSopLogsMapper.selectQwSopLogsListByQwSopId(param);
+            //企微
+            case 3:
+                return qwSopLogsMapper.selectQwSopLogsListByChatSopId(param);
         }
         }
        return null;
        return null;
     }
     }

+ 32 - 0
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java

@@ -16,6 +16,7 @@ import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.param.QwAutoSopTimeParam;
 import com.fs.qw.param.QwAutoSopTimeParam;
 import com.fs.qw.result.QwFilterSopCustomersResult;
 import com.fs.qw.result.QwFilterSopCustomersResult;
+import com.fs.qw.service.impl.AsyncChatSopService;
 import com.fs.qw.service.impl.AsyncSopService;
 import com.fs.qw.service.impl.AsyncSopService;
 import com.fs.qw.service.impl.AsyncSopTestService;
 import com.fs.qw.service.impl.AsyncSopTestService;
 import com.fs.qw.service.impl.AsyncWxSopService;
 import com.fs.qw.service.impl.AsyncWxSopService;
@@ -49,6 +50,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.*;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 /**
 /**
@@ -92,6 +94,8 @@ public class QwSopServiceImpl implements IQwSopService
     private AsyncSopTestService asyncSopTestService;
     private AsyncSopTestService asyncSopTestService;
     @Autowired
     @Autowired
     private AsyncWxSopService asyncWxSopService;
     private AsyncWxSopService asyncWxSopService;
+    @Autowired
+    private AsyncChatSopService asyncChatSopService;
 
 
 
 
     @Autowired
     @Autowired
@@ -751,6 +755,7 @@ public class QwSopServiceImpl implements IQwSopService
         List<QwSop> qwSops = qwSopMapper.selectStatusQwSopById(ids);
         List<QwSop> qwSops = qwSopMapper.selectStatusQwSopById(ids);
         List<QwSop> qwSopList = qwSops.stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
         List<QwSop> qwSopList = qwSops.stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
         List<QwSop> wxSopList = qwSops.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
         List<QwSop> wxSopList = qwSops.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
+        List<QwSop> chatSopList = qwSops.stream().filter(e -> e.getType() == 3).collect(Collectors.toList());
 
 
         if(!wxSopList.isEmpty()){
         if(!wxSopList.isEmpty()){
             // 筛选出 status == 1 的 IDs
             // 筛选出 status == 1 的 IDs
@@ -806,6 +811,33 @@ public class QwSopServiceImpl implements IQwSopService
                 return R.error().put("err",areadyList);
                 return R.error().put("err",areadyList);
             }
             }
         }
         }
+        if(!chatSopList.isEmpty()){
+            // 筛选出 status == 1 的 IDs
+            String[] toBeSent = chatSopList.stream()
+                    .filter(qwSop -> qwSop.getStatus() == 1)
+                    .map(QwSop::getId)
+                    .toArray(String[]::new);
+
+            // 筛选出 status != 1 的 IDs
+            List<String> areadyList = chatSopList.stream()
+                    .filter(qwSop -> qwSop.getStatus() != 1)
+                    .map(QwSop::getId)
+                    .collect(Collectors.toList());
+
+            //异步执行
+            asyncChatSopService.executeChatSopByIds(toBeSent);
+
+            if (toBeSent.length > 0) {
+                int i = qwSopMapper.updateStatusQwSopById(toBeSent);
+                if (i > 0) {
+                    return R.ok().put("suc",toBeSent).put("err",areadyList);
+                }else {
+                    return R.error();
+                }
+            }else {
+                return R.error().put("err",areadyList);
+            }
+        }
         return R.error();
         return R.error();
     }
     }
 
 

+ 6 - 0
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java

@@ -245,4 +245,10 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
             contentMapper.updateQwSopTempContent(content1);
             contentMapper.updateQwSopTempContent(content1);
         }
         }
     }
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopTempRules> selectByTemplateIds(List<String> ids) {
+        return list(new QueryWrapper<QwSopTempRules>().in("temp_id", ids));
+    }
 }
 }

+ 22 - 1
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -23,6 +23,7 @@ import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
+import java.time.LocalTime;
 import java.util.*;
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
@@ -262,7 +263,27 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
 
     @Override
     @Override
     public List<QwSopTemp> selectQwSopTempListNew(QwSopTemp qwSopTemp) {
     public List<QwSopTemp> selectQwSopTempListNew(QwSopTemp qwSopTemp) {
-        return qwSopTempMapper.selectQwSopTempListNew(qwSopTemp);
+        List<QwSopTemp> list = qwSopTempMapper.selectQwSopTempListNew(qwSopTemp);
+        if(qwSopTemp.isCuoser()){
+            List<QwSopTempRules> rulesList = qwSopTempRulesService.selectByTemplateIds(PubFun.listToNewList(list, QwSopTemp::getId));
+            rulesList.sort(Comparator.comparing(
+                    e -> {
+                        String timeStr = e.getTime();
+                        if (timeStr == null || timeStr.isEmpty()) {
+                            return null; // 返回 null 表示该条目需排在最后
+                        }
+                        return LocalTime.parse(timeStr + ":00"); // 正常解析有效时间
+                    },
+                    Comparator.nullsLast(Comparator.naturalOrder()) // 处理 null 并排序
+            ));
+            Map<String, List<QwSopTempRules>> ruleMap = PubFun.listToMapByGroupList(rulesList, QwSopTempRules::getTempId);
+            list.stream().filter(e -> ruleMap.containsKey(e.getId())).forEach(e -> {
+                List<QwSopTempRules> rulesListSub = ruleMap.get(e.getId());
+                Map<Long, QwSopTempRules> dayMap = PubFun.listToMapByGroupObject(rulesListSub, QwSopTempRules::getDayId);
+                e.setCuoser(dayMap.entrySet().stream().allMatch(d -> d.getValue().getContentType() == 2));
+            });
+        }
+        return list;
     }
     }
 
 
     @Override
     @Override

+ 1 - 0
fs-service-system/src/main/java/com/fs/sop/vo/SopUserLogsVo.java

@@ -38,5 +38,6 @@ public class SopUserLogsVo  {
     private Integer isFixed;
     private Integer isFixed;
     // 是否只发送注册用户
     // 是否只发送注册用户
     private Integer isRegister;
     private Integer isRegister;
+    private String chatId;
 
 
 }
 }

+ 2 - 0
fs-service-system/src/main/resources/mapper/course/FsCourseLinkMapper.xml

@@ -62,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="qwExternalId != null">qw_external_id,</if>
             <if test="qwExternalId != null">qw_external_id,</if>
             <if test="linkType != null">link_type,</if>
             <if test="linkType != null">link_type,</if>
             <if test="isRoom != null">is_room,</if>
             <if test="isRoom != null">is_room,</if>
+            <if test="chatId != null">chat_id,</if>
          </trim>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="link != null">#{link},</if>
             <if test="link != null">#{link},</if>
@@ -77,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="qwExternalId != null">#{qwExternalId},</if>
             <if test="qwExternalId != null">#{qwExternalId},</if>
             <if test="linkType != null">#{linkType},</if>
             <if test="linkType != null">#{linkType},</if>
             <if test="isRoom != null">#{isRoom},</if>
             <if test="isRoom != null">#{isRoom},</if>
+            <if test="chatId != null">#{chatId},</if>
          </trim>
          </trim>
     </insert>
     </insert>
 
 

+ 3 - 0
fs-service-system/src/main/resources/mapper/qw/QwGroupChatMapper.xml

@@ -49,6 +49,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectQwGroupChatVo"/>
         <include refid="selectQwGroupChatVo"/>
         where chat_id = #{chatId}
         where chat_id = #{chatId}
     </select>
     </select>
+    <select id="selectQwGroupChatByChatIds" resultType="com.fs.qw.domain.QwGroupChat">
+        select * from qw_group_chat where chat_id in <foreach collection="ids" open="(" separator="," close=")" item="item">#{item}</foreach>
+    </select>
     <insert id="insertOrUpdateQwGroupChat" parameterType="QwGroupChat">
     <insert id="insertOrUpdateQwGroupChat" parameterType="QwGroupChat">
         insert into qw_group_chat
         insert into qw_group_chat
         <trim prefix="(" suffix=")" suffixOverrides=",">
         <trim prefix="(" suffix=")" suffixOverrides=",">

+ 3 - 0
fs-service-system/src/main/resources/mapper/qw/QwGroupChatUserMapper.xml

@@ -56,6 +56,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectQwGroupChatUserVo"/>
         <include refid="selectQwGroupChatUserVo"/>
         where chat_id = #{chatId} AND user_id=#{userId}  AND corp_id=#{corpId}
         where chat_id = #{chatId} AND user_id=#{userId}  AND corp_id=#{corpId}
     </select>
     </select>
+    <select id="selectQwGroupChatUserByChatIds" resultType="com.fs.qw.domain.QwGroupChatUser">
+        select * from qw_group_chat_user where is_out = 1 and type = 2 and chat_id in <foreach collection="ids" open="(" separator="," close=")" item="item">#{item}</foreach>
+    </select>
 
 
     <insert id="insertOrUpdateQwGroupChatUser" parameterType="QwGroupChatUser" useGeneratedKeys="true" keyProperty="id">
     <insert id="insertOrUpdateQwGroupChatUser" parameterType="QwGroupChatUser" useGeneratedKeys="true" keyProperty="id">
         insert into qw_group_chat_user
         insert into qw_group_chat_user

+ 15 - 1
fs-service-system/src/main/resources/mapper/sop/QwSopLogsMapper.xml

@@ -510,7 +510,21 @@
         AND real_send_time < now()
         AND real_send_time < now()
         ]]>
         ]]>
     </select>
     </select>
-
+    <select id="selectQwSopLogsListByChatSopId" resultType="com.fs.sop.vo.QwSopLogsListCVO">
+        SELECT * FROM qw_sop_logs
+        <where>
+            <if test="map.sopId != null">sop_id = #{map.sopId}</if>
+            <if test="map.corpId != null">AND corp_id = #{map.corpId}</if>
+            <if test="map.sendType != null">AND send_type = #{map.sendType}</if>
+            <if test="map.sendStatus != null">AND send_status = #{map.sendStatus}</if>
+            <if test="map.receivingStatus != null">AND receiving_status = #{map.receivingStatus}</if>
+            <if test="map.qwUserid != null and map.qwUserid !='' ">AND qw_userid = #{map.qwUserid}</if>
+            <if test="map.externalUserName != null and map.externalUserName!= '' ">AND external_user_name = #{map.externalUserName}</if>
+            <if test="map.scheduleStartTime != null">AND send_time &gt;= #{map.scheduleStartTime}</if>
+            <if test="map.scheduleEndTime != null">AND send_time &lt;=  #{map.scheduleEndTime}</if>
+        </where>
+        ORDER BY send_time desc
+    </select>
 
 
 
 
     <!-- 批量更新 QwSopLogs -->
     <!-- 批量更新 QwSopLogs -->

+ 26 - 0
fs-service-system/src/main/resources/mapper/sop/QwSopMapper.xml

@@ -395,6 +395,24 @@
         select a.* from qw_sop a
         select a.* from qw_sop a
         where a.send_type != 4 and a.status in (2,3) and a.type = 1
         where a.send_type != 4 and a.status in (2,3) and a.type = 1
     </select>
     </select>
+    <select id="executeSopChatByIds" resultType="com.fs.qw.vo.ChatSopRuleTimeVO">
+
+        SELECT qs.*,
+        qst.name AS temp_name,
+        qst.setting AS temp_setting,
+        qst.status AS temp_status,
+        qst.gap AS temp_gap,
+        qst.sort AS temp_sort,
+        qst.create_time AS temp_create_time,
+        qst.create_by AS temp_create_by,
+        qst.corp_id AS temp_company_id
+        FROM qw_sop qs
+        LEFT JOIN qw_sop_temp qst ON qs.temp_id = qst.id
+        WHERE qs.id IN
+        <foreach item="id" collection="ids"  open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
     <update id="updateQwSop" parameterType="QwSop" useGeneratedKeys="false" keyProperty="id" >
     <update id="updateQwSop" parameterType="QwSop" useGeneratedKeys="false" keyProperty="id" >
         UPDATE  qw_sop
         UPDATE  qw_sop
         <trim prefix="SET" suffixOverrides=",">
         <trim prefix="SET" suffixOverrides=",">
@@ -456,6 +474,14 @@
             #{id}
             #{id}
         </foreach>
         </foreach>
     </update>
     </update>
+    <update id="updateStatusQwSopById2" useGeneratedKeys="false" keyProperty="id" >
+        UPDATE qw_sop
+        SET status = 3
+        WHERE id IN
+        <foreach item="id" collection="ids" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
 
 
     <update id="updateMinSendStatus">
     <update id="updateMinSendStatus">
         UPDATE qw_sop
         UPDATE qw_sop

+ 21 - 1
fs-service-system/src/main/resources/mapper/sop/SopUserLogsMapper.xml

@@ -107,6 +107,26 @@
             <if test="data.userId != null  ">#{data.userId},</if>
             <if test="data.userId != null  ">#{data.userId},</if>
         </trim>
         </trim>
     </insert>
     </insert>
+    <insert id="batchInsertSopUserLogs">
+        INSERT INTO sop_user_logs
+        (
+        sop_id, sop_temp_id, qw_user_id,chat_id,corp_id, start_time,
+        status, user_id
+        )
+        VALUES
+        <foreach collection="list" item="log" separator=",">
+            (
+            #{log.sopId},
+            #{log.sopTempId},
+            #{log.qwUserId},
+            #{log.chatId},
+            #{log.corpId},
+            #{log.startTime},
+            #{log.status},
+            #{log.userId}
+            )
+        </foreach>
+    </insert>
 
 
     <update id="updateSopUserLogsByTempId" parameterType="String">
     <update id="updateSopUserLogsByTempId" parameterType="String">
         update  sop_user_logs
         update  sop_user_logs
@@ -158,7 +178,7 @@
 
 
 
 
     <select id="selectSopUserLogsListByTime" resultType="com.fs.sop.vo.SopUserLogsVo">
     <select id="selectSopUserLogsListByTime" resultType="com.fs.sop.vo.SopUserLogsVo">
-        select a.*,b.min_conversion_day,b.max_conversion_day,b.min_send,b.max_send,b.is_fixed,b.is_register from sop_user_logs a
+        select a.*,b.min_conversion_day,b.max_conversion_day,b.min_send,b.max_send,b.is_fixed,b.is_register,b.chat_id from sop_user_logs a
         inner join qw_sop b on a.sop_id = b.id
         inner join qw_sop b on a.sop_id = b.id
         where a.start_time &lt;= Now() and a.status = 1 and b.send_type != 4 and b.status in (2,3)
         where a.start_time &lt;= Now() and a.status = 1 and b.send_type != 4 and b.status in (2,3)
     </select>
     </select>