Quellcode durchsuchen

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

caoliqin vor 6 Tagen
Ursprung
Commit
974a4af2f3
25 geänderte Dateien mit 202 neuen und 100 gelöschten Zeilen
  1. 8 2
      fs-ai-call-task/src/main/java/com/fs/app/service/CallTaskService.java
  2. 1 0
      fs-ai-call-task/src/main/resources/application.yml
  3. 6 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyVoiceRoboticController.java
  4. 3 0
      fs-company/src/main/java/com/fs/company/controller/crm/CrmCustomerController.java
  5. 2 0
      fs-service/src/main/java/com/fs/company/domain/CompanyVoiceRoboticCallees.java
  6. 1 1
      fs-service/src/main/java/com/fs/company/mapper/CompanyVoiceRoboticCalleesMapper.java
  7. 1 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyWxClientMapper.java
  8. 2 0
      fs-service/src/main/java/com/fs/company/service/ICompanyWxClientService.java
  9. 3 1
      fs-service/src/main/java/com/fs/company/service/impl/CompanyVoiceRoboticServiceImpl.java
  10. 10 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyWxClientServiceImpl.java
  11. 12 7
      fs-service/src/main/java/com/fs/company/service/impl/CompanyWxServiceImpl.java
  12. 15 15
      fs-service/src/main/java/com/fs/company/service/impl/call/node/AiAddWxTaskNode.java
  13. 5 5
      fs-service/src/main/java/com/fs/company/service/impl/call/node/AiCallTaskNode.java
  14. 46 40
      fs-service/src/main/java/com/fs/company/service/impl/call/node/AiQwAddWxTaskNode.java
  15. 1 1
      fs-service/src/main/java/com/fs/company/service/impl/call/node/WorkflowNodeFactory.java
  16. 1 1
      fs-service/src/main/java/com/fs/wxcid/service/ICidIpadServerService.java
  17. 2 2
      fs-service/src/main/java/com/fs/wxcid/service/impl/CidIpadServerServiceImpl.java
  18. 1 0
      fs-service/src/main/resources/application-dev.yml
  19. 1 1
      fs-service/src/main/resources/mapper/company/CompanyVoiceRoboticCallLogAddwxMapper.xml
  20. 3 0
      fs-service/src/main/resources/mapper/company/CompanyVoiceRoboticCalleesMapper.xml
  21. 2 0
      fs-service/src/main/resources/mapper/company/CompanyWxAccountMapper.xml
  22. 14 1
      fs-service/src/main/resources/mapper/company/CompanyWxClientMapper.xml
  23. 45 13
      fs-wx-task/src/main/java/com/fs/app/service/WxTaskService.java
  24. 16 10
      fs-wx-task/src/main/java/com/fs/app/task/WxTask.java
  25. 1 0
      fs-wx-task/src/main/resources/application.yml

+ 8 - 2
fs-ai-call-task/src/main/java/com/fs/app/service/CallTaskService.java

@@ -8,8 +8,10 @@ import com.fs.company.service.*;
 import com.fs.company.service.impl.call.node.AiCallTaskNode;
 import com.fs.course.config.RedisKeyScanner;
 import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
@@ -17,9 +19,13 @@ import java.util.concurrent.*;
 
 @Slf4j
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class CallTaskService {
 
+
+    @Value("${cid-group-no}")
+    private Integer cidGroupNo;
+
     private final RedisCacheT<String> redisCache;
 
     private final RedisCache redisCache2;
@@ -40,7 +46,7 @@ public class CallTaskService {
      */
     public void cidWorkflowCallRun() {
         log.info("===========工作流延时任务开始扫描===========");
-        String delayCallKeyPrefix = AiCallTaskNode.getDelayCallKeyPrefix(null) + "*";
+        String delayCallKeyPrefix = AiCallTaskNode.getDelayCallKeyPrefix(cidGroupNo,null) + "*";
         Set<String> keys = redisKeyScanner.scanMatchKey(delayCallKeyPrefix);
         log.info("共扫描到 {} 个待处理键", keys.size());
         keys.parallelStream().forEach(key -> {

+ 1 - 0
fs-ai-call-task/src/main/resources/application.yml

@@ -14,3 +14,4 @@ spring:
 #    active: druid-sxjz
 #    active: druid-hdt
 #    active: druid-myhk-test
+cid-group-no: 1

+ 6 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyVoiceRoboticController.java

@@ -267,4 +267,10 @@ public class CompanyVoiceRoboticController extends BaseController
         List<WorkflowExecRecordVo> records = companyVoiceRoboticService.getExecRecords(roboticId);
         return R.ok().put("data", records);
     }
+
+    @GetMapping("/getCurrentCompanyId")
+    public R getCurrentCompanyId(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        return R.ok().put("companyId", loginUser.getCompany().getCompanyId());
+    }
 }

+ 3 - 0
fs-company/src/main/java/com/fs/company/controller/crm/CrmCustomerController.java

@@ -98,6 +98,9 @@ public class CrmCustomerController extends BaseController
     @PreAuthorize("@ss.hasPermi('crm:customer:list')")
     @GetMapping("/listAll")
     public R listAll(CrmCustomerListQueryParam crmCustomer){
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        crmCustomer.setCompanyId(loginUser.getCompany().getCompanyId());
         PageHelper.startPage(1, 1000);
         if(!StringUtils.isEmpty(crmCustomer.getReceiveTimeRange())){
             crmCustomer.setReceiveTimeList(crmCustomer.getReceiveTimeRange().split("--"));

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

@@ -62,4 +62,6 @@ public class CompanyVoiceRoboticCallees{
 
     @TableField(exist = false)
     private String idToString;
+
+    private Integer isWeCom;
 }

+ 1 - 1
fs-service/src/main/java/com/fs/company/mapper/CompanyVoiceRoboticCalleesMapper.java

@@ -84,6 +84,6 @@ public interface CompanyVoiceRoboticCalleesMapper extends BaseMapper<CompanyVoic
 
     List<SendMsgByTaskVO> getSendMsgTaskListByRoboticId(@Param("roboticId") Long roboticId);
 
-    List<CompanyVoiceRoboticCallees> selectExcludeList(@Param("list")List<CompanyWxClient> list);
+    List<CompanyVoiceRoboticCallees> selectExcludeList(@Param("list")List<CompanyWxClient> list,@Param("isWeCom") Integer isWeCom);
     List<Long> getNotFinishAddWxRobotic(@Param("roboticIds") Set<Long> roboticIds);
 }

+ 1 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyWxClientMapper.java

@@ -84,4 +84,5 @@ public interface CompanyWxClientMapper extends BaseMapper<CompanyWxClient> {
 
     List<CompanyWxClient> getQwAddWxList(@Param("accountIdList") List<Long> accountIdList, @Param("isWeCom") Integer isWeCom);
 
+    List<CompanyWxClient4WorkFlowVO> getQwAddWxList4Workflow(@Param("accountIdList") List<Long> accountIdList, @Param("execStatus") Integer execStatus, @Param("execNodeType") Integer execNodeType);
 }

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

@@ -74,4 +74,6 @@ public interface ICompanyWxClientService extends IService<CompanyWxClient> {
     List<CompanyWxClient4WorkFlowVO> getAddWxList4Workflow(List<Long> accountIdList);
 
     List<CompanyWxClient> getQwAddWxList(List<Long> accountIdList,Integer isWeCom);
+
+    List<CompanyWxClient4WorkFlowVO> getQwAddWxList4Workflow(List<Long> accountIdList);
 }

+ 3 - 1
fs-service/src/main/java/com/fs/company/service/impl/CompanyVoiceRoboticServiceImpl.java

@@ -185,6 +185,7 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
             callees.setResult(0);
             callees.setTaskFlow(companyVoiceRobotic.getTaskFlow());
             callees.setRunTaskFlow(companyVoiceRobotic.getRunTaskFlow());
+            callees.setIsWeCom(isWeCom);
             return callees;
         }).collect(Collectors.toList());
         companyVoiceRoboticCalleesService.saveBatch(callesList);
@@ -1093,7 +1094,8 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
 
     // 绑定销售
     private void bindCompany(CompanyWxClient client, List<CompanyVoiceRoboticWx> wxList) {
-        List<CompanyVoiceRoboticWx> wx = wxList.stream().filter(f -> f.getAccount() != null && f.getAccount().getAllocateNum() < f.getAccount().getAddNum()).collect(Collectors.toList());
+//         取消再分配时 最大加微限制判定 && f.getAccount().getAllocateNum() < f.getAccount().getAddNum()
+        List<CompanyVoiceRoboticWx> wx = wxList.stream().filter(f -> f.getAccount() != null).collect(Collectors.toList());
         // 绑定销售,添加值达到阈值后设置为空,等待下次绑定
         if (!wx.isEmpty()) {
             CompanyVoiceRoboticWx companyVoiceRoboticWx = wx.get(0);

+ 10 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyWxClientServiceImpl.java

@@ -246,4 +246,14 @@ public class CompanyWxClientServiceImpl extends ServiceImpl<CompanyWxClientMappe
     public List<CompanyWxClient> getQwAddWxList(List<Long> accountIdList, Integer isWeCom) {
         return baseMapper.getQwAddWxList(accountIdList,isWeCom);
     }
+
+    /**
+     * 获取添加微信列表 工作流用
+     * @param accountIdList
+     * @return
+     */
+    @Override
+    public  List<CompanyWxClient4WorkFlowVO> getQwAddWxList4Workflow(List<Long> accountIdList){
+        return baseMapper.getQwAddWxList4Workflow(accountIdList, ExecutionStatusEnum.WAITING.getValue(), NodeTypeEnum.AI_QW_ADD_WX_TASK.getValue());
+    }
 }

+ 12 - 7
fs-service/src/main/java/com/fs/company/service/impl/CompanyWxServiceImpl.java

@@ -8,10 +8,7 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCacheT;
 import com.fs.common.utils.DateUtils;
 import com.fs.company.domain.*;
-import com.fs.company.mapper.CompanyAiWorkflowExecLogMapper;
-import com.fs.company.mapper.CompanyAiWorkflowExecMapper;
-import com.fs.company.mapper.CompanyWxAccountMapper;
-import com.fs.company.mapper.CompanyWxClientMapper;
+import com.fs.company.mapper.*;
 import com.fs.company.service.*;
 import com.fs.company.service.impl.call.node.AiAddWxTaskNode;
 import com.fs.enums.ExecutionStatusEnum;
@@ -101,6 +98,8 @@ public class CompanyWxServiceImpl extends ServiceImpl<CompanyWxAccountMapper, Co
     @Autowired
     private CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
 
+    @Autowired
+    CompanyAiWorkflowServerMapper companyAiWorkflowServerMapper;
 
 
     /**
@@ -256,7 +255,13 @@ public class CompanyWxServiceImpl extends ServiceImpl<CompanyWxAccountMapper, Co
         if (addressId==null || addressId.isEmpty()){
             return R.error("请先绑定地址");
         }
-        Long serverId = cidIpadServerService.selectQwIpadServerByAddressId(addressId);
+        Long cidServerId = companyUser.getCidServerId();
+        if ( cidServerId==null ){
+            return R.error("请先绑定cid服务");
+        }
+        CompanyAiWorkflowServer cidServer = companyAiWorkflowServerMapper.selectCompanyAiWorkflowServerById(companyUser.getCidServerId());
+
+        Long serverId = cidIpadServerService.selectQwIpadServerByAddressId(addressId,cidServer.getGroupNo());
         if (serverId==null){
             return  R.error(501,"该地区服务器剩余数量不足");
         }
@@ -264,7 +269,7 @@ public class CompanyWxServiceImpl extends ServiceImpl<CompanyWxAccountMapper, Co
         account.setServerStatus(1);
         updateById(account);
 
-        cidIpadServerService.subtractServer(serverId);
+//        cidIpadServerService.subtractServer(serverId);
         CidIpadServerUser qwIpadServerUser = new CidIpadServerUser();
         qwIpadServerUser.setCompanyUserId(companyUser.getUserId());
         qwIpadServerUser.setCompanyId(companyUser.getCompanyId());
@@ -608,7 +613,7 @@ public class CompanyWxServiceImpl extends ServiceImpl<CompanyWxAccountMapper, Co
             }
 
             // 清除超时检测Key(回调成功了,不需要超时检测了)
-            AiAddWxTaskNode.clearTimeoutKey(workflowInstanceId, wxClientId);
+//            AiAddWxTaskNode.clearTimeoutKey(workflowInstanceId, wxClientId);
 
             // 触发工作流继续执行
             Map<String, Object> inputData = new HashMap<>();

+ 15 - 15
fs-service/src/main/java/com/fs/company/service/impl/call/node/AiAddWxTaskNode.java

@@ -35,7 +35,7 @@ public class AiAddWxTaskNode extends AbstractWorkflowNode {
     private static final CompanyWorkflowNodeMapper companyWorkflowNodeMapper = SpringUtils.getBean(CompanyWorkflowNodeMapper.class);
     @SuppressWarnings("unchecked")
     private static final RedisCacheT<String> redisCache = SpringUtils.getBean(RedisCacheT.class);
-    public static final String DELAY_ADD_WX_KEY = "addWxTask:delay:%s:%s:";
+    public static final String DELAY_ADD_WX_KEY = "addWxTask:delay:%s:%s:%s:";
     /**
      * 默认加微超时时间(分钟)
      */
@@ -225,17 +225,17 @@ public class AiAddWxTaskNode extends AbstractWorkflowNode {
         return true;
     }
 
-    /**
-     * 清除超时检测 Key
-     *
-     * @param workflowInstanceId 工作流实例ID
-     * @param wxClientId         加微客户ID
-     */
-    public static void clearTimeoutKey(String workflowInstanceId, Long wxClientId) {
-        String timeoutKey = Constants.WORKFLOW_ADD_WX_TIMEOUT + workflowInstanceId + ":" + wxClientId;
-        redisCache.deleteObject(timeoutKey);
-        log.info("清除加微超时检测 Key: {}", timeoutKey);
-    }
+//    /**
+//     * 清除超时检测 Key
+//     *
+//     * @param workflowInstanceId 工作流实例ID
+//     * @param wxClientId         加微客户ID
+//     */
+//    public static void clearTimeoutKey(String workflowInstanceId, Long wxClientId) {
+//        String timeoutKey = Constants.WORKFLOW_ADD_WX_TIMEOUT + workflowInstanceId + ":" + wxClientId;
+//        redisCache.deleteObject(timeoutKey);
+//        log.info("清除加微超时检测 Key: {}", timeoutKey);
+//    }
 
     /**
      * getRedisCacheKey
@@ -243,12 +243,12 @@ public class AiAddWxTaskNode extends AbstractWorkflowNode {
      * @param time
      * @return
      */
-    public static String getDelayAddWxKeyPrefix(Long time) {
+    public static String getDelayAddWxKeyPrefix(Integer cidGroupNo,Long time) {
         Date nowDay = new Date();
         if (null != time) {
             nowDay = new Date(time);
         }
-        return String.format(DELAY_ADD_WX_KEY, nowDay.getHours(), nowDay.getMinutes());
+        return String.format(DELAY_ADD_WX_KEY,cidGroupNo, nowDay.getHours(), nowDay.getMinutes());
     }
 
     /**
@@ -287,7 +287,7 @@ public class AiAddWxTaskNode extends AbstractWorkflowNode {
                 //节点包含延时条件
                 if (null != condition.getAddTime() && !condition.isAdd()) {
                     long l = System.currentTimeMillis() + condition.getAddTime() * 60 * 1000;
-                    String redisKey = getDelayAddWxKeyPrefix(l) + workflowInstanceId;
+                    String redisKey = getDelayAddWxKeyPrefix(exec.getCidGroupNo(),l) + workflowInstanceId;
                     ExecutionContext nextContext = context.clone();
                     nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
                     super.redisCache.setCacheObject(redisKey, nextContext);

+ 5 - 5
fs-service/src/main/java/com/fs/company/service/impl/call/node/AiCallTaskNode.java

@@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
 public class AiCallTaskNode extends AbstractWorkflowNode {
     private static final CompanyWorkflowNodeMapper companyWorkflowNodeMapper = SpringUtils.getBean(CompanyWorkflowNodeMapper.class);
     private static final ICompanyVoiceRoboticService companyVoiceRoboticService = SpringUtils.getBean(ICompanyVoiceRoboticService.class);
-    public static final String DELAY_CALL_KEY = "aiCallTask:delay:%s:%s:";
+    public static final String DELAY_CALL_KEY = "aiCallTask:delay:%s:%s:%s:";
     private final String CALL_FROM_CALLBACK = "callBack";
     private final String CALL_FROM_TIMER = "timer";
 
@@ -110,7 +110,7 @@ public class AiCallTaskNode extends AbstractWorkflowNode {
                         ExecutionContext nextContext = context.clone();
                         nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
                         //添加到延时扫描redis
-                        super.redisCache.setCacheObject(this.getDelayCallKeyPrefix(l) + exec.getWorkflowInstanceId(), nextContext, 1, TimeUnit.DAYS);
+                        super.redisCache.setCacheObject(this.getDelayCallKeyPrefix(exec.getCidGroupNo(),l) + exec.getWorkflowInstanceId(), nextContext, 1, TimeUnit.DAYS);
                         super.asyncWorkflowForBlockingNode(context.getWorkflowInstanceId(), context.getCurrentNodeKey(), context, ExecutionStatusEnum.WAITING);
                         updateLogStatusIfExist(context, ExecutionStatusEnum.PAUSED, ExecutionStatusEnum.WAITING);
                         runnableCount++;
@@ -187,16 +187,16 @@ public class AiCallTaskNode extends AbstractWorkflowNode {
 
     /**
      * getRedisCacheKey
-     *
+     * @param cidGroupNo
      * @param time
      * @return
      */
-    public static String getDelayCallKeyPrefix(Long time) {
+    public static String getDelayCallKeyPrefix(Integer cidGroupNo,Long time) {
         Date nowDay = new Date();
         if (null != time) {
             nowDay = new Date(time);
         }
-        return String.format(DELAY_CALL_KEY, nowDay.getHours(), nowDay.getMinutes());
+        return String.format(DELAY_CALL_KEY, cidGroupNo,nowDay.getHours(), nowDay.getMinutes());
     }
 
 //    @Override

+ 46 - 40
fs-service/src/main/java/com/fs/company/service/impl/call/node/AiQwAddWxTaskNode.java

@@ -1,5 +1,6 @@
 package com.fs.company.service.impl.call.node;
 
+import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCacheT;
@@ -65,10 +66,14 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
         boolean addSuccess = wxClient != null && Integer.valueOf(1).equals(wxClient.getIsAdd());
         //回调加微成功
         if (addSuccess) {
-            List<CompanyWorkflowEdge> cList = edges.stream().filter(a ->
-                            StringUtils.isNotBlank(a.getConditionExpr()) && JSONObject.parseArray(a.getConditionExpr(), AiCallWorkflowConditionVo.class).get(0).isAdd())
-                    .collect(Collectors.toList());
-            if(!cList.isEmpty() && nodeKey.equals(exec.getCurrentNodeKey())){
+            List<CompanyWorkflowEdge> cList = edges.stream().filter(a -> {
+                if (StringUtils.isBlank(a.getConditionExpr())) {
+                    return false;
+                }
+                List<AiCallWorkflowConditionVo> list = JSONObject.parseArray(a.getConditionExpr(), AiCallWorkflowConditionVo.class);
+                return list != null && !list.isEmpty() && list.get(0).isAdd();
+            }).collect(Collectors.toList());
+            if (!cList.isEmpty() && nodeKey.equals(exec.getCurrentNodeKey())) {
                 super.runNextNode(context, cList.get(0));
             }
         }
@@ -78,7 +83,8 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
                     .collect(Collectors.toList());
             // 加微失败,根据条件判断走哪条边
             CompanyWorkflowEdge edge = cList.get(0);
-                AiCallWorkflowConditionVo condition = JSONObject.parseObject(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
+            List<AiCallWorkflowConditionVo> conditions = JSONObject.parseArray(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
+             AiCallWorkflowConditionVo condition = conditions.get(0);
                 // 匹配失败条件
                 if (!condition.isAdd()) {
                     log.info("加微失败,执行失败分支 - workflowInstanceId: {}", context.getWorkflowInstanceId());
@@ -104,8 +110,8 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
             return ExecutionResult.failure().nextNodeKey(null).build();
         }
         try {
-            super.asyncWorkflowForBlockingNode(context.getWorkflowInstanceId(), context.getCurrentNodeKey(), context, ExecutionStatusEnum.PAUSED);
-            return ExecutionResult.paused()
+            super.asyncWorkflowForBlockingNode(context.getWorkflowInstanceId(), context.getCurrentNodeKey(), context, ExecutionStatusEnum.WAITING);
+            return ExecutionResult.waiting()
                     .outputData(context.getVariables())
                     .nextNodeKey("").build();
         } catch (Exception e) {
@@ -184,49 +190,49 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
      * getRedisCacheKey
      *
      */
-    public static String getDelayAddWxKeyPrefix(Long time) {
+    public static String getDelayAddWxKeyPrefix(Integer cidGroupNo,Long time) {
         Date nowDay;
         if (null != time) {
             nowDay = new Date(time);
         }else{
             nowDay = new Date();
         }
-        return String.format(DELAY_QW_ADD_WX_KEY, nowDay.getHours(), nowDay.getMinutes());
+        return String.format(DELAY_QW_ADD_WX_KEY,cidGroupNo, nowDay.getHours(), nowDay.getMinutes());
     }
 
     /**
      * 完成加微动作
      *
      */
-//    public void doneQwAddWx(String workflowInstanceId) {
-//        ExecutionContext context = createExecutionContext(workflowInstanceId, nodeKey);
-//        context.setVariable("lastNodeKey", nodeKey);
-//        //启动定时节点倒计时
-//        CompanyAiWorkflowExec exec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(context.getWorkflowInstanceId());
-//        if (!exec.getCurrentNodeKey().equals(nodeKey)) {
-//            //当前节点已流转
-//            log.error("当前节点已流转 ,目标:{},实际:{}", nodeKey, exec.getCurrentNodeKey());
-//            return;
-//        }
-//        //更新加微日志执行状态
-//        super.updateLogStatusIfExist(context, ExecutionStatusEnum.PAUSED, ExecutionStatusEnum.WAITING);
-//        super.asyncWorkflowForBlockingNode(context.getWorkflowInstanceId(), nodeKey, context, ExecutionStatusEnum.WAITING);
-//        List<CompanyWorkflowEdge> edges = companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(exec.getWorkflowId(), nodeKey);
-//        edges.forEach(edge -> {
-//            List<AiCallWorkflowConditionVo> conditions = JSONObject.parseArray(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
-//            if (null == conditions || conditions.isEmpty()) {
-//                super.runNextNode(context, edge);
-//            } else {
-//                AiCallWorkflowConditionVo condition = conditions.get(0);
-//                //节点包含延时条件
-//                if (null != condition.getAddTime() && !condition.isAdd()) {
-//                    long l = System.currentTimeMillis() + condition.getAddTime() * 60 * 1000;
-//                    String redisKey = getDelayAddWxKeyPrefix(l) + workflowInstanceId;
-//                    ExecutionContext nextContext = context.clone();
-//                    nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
-//                    super.redisCache.setCacheObject(redisKey, nextContext);
-//                }
-//            }
-//        });
-//    }
+    public void doneQwAddWx(String workflowInstanceId) {
+        ExecutionContext context = createExecutionContext(workflowInstanceId, nodeKey);
+        context.setVariable("lastNodeKey", nodeKey);
+        //启动定时节点倒计时
+        CompanyAiWorkflowExec exec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(context.getWorkflowInstanceId());
+        if (!exec.getCurrentNodeKey().equals(nodeKey)) {
+            //当前节点已流转
+            log.error("当前节点已流转 ,目标:{},实际:{}", nodeKey, exec.getCurrentNodeKey());
+            return;
+        }
+        //更新加微日志执行状态
+        super.updateLogStatusIfExist(context, ExecutionStatusEnum.WAITING, ExecutionStatusEnum.WAITING);
+        super.asyncWorkflowForBlockingNode(context.getWorkflowInstanceId(), nodeKey, context, ExecutionStatusEnum.WAITING);
+        List<CompanyWorkflowEdge> edges = companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(exec.getWorkflowId(), nodeKey);
+        edges.forEach(edge -> {
+            List<AiCallWorkflowConditionVo> conditions = JSONObject.parseArray(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
+            if (CollectionUtil.isEmpty(conditions)) {
+                super.runNextNode(context, edge);
+            } else {
+                AiCallWorkflowConditionVo condition = conditions.get(0);
+                //节点包含延时条件
+                if (null != condition.getAddTime() && !condition.isAdd()) {
+                    long l = System.currentTimeMillis() + condition.getAddTime() * 60 * 1000;
+                    String redisKey = getDelayAddWxKeyPrefix(exec.getCidGroupNo(),l) + workflowInstanceId;
+                    ExecutionContext nextContext = context.clone();
+                    nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
+                    super.redisCache.setCacheObject(redisKey, nextContext);
+                }
+            }
+        });
+    }
 }

+ 1 - 1
fs-service/src/main/java/com/fs/company/service/impl/call/node/WorkflowNodeFactory.java

@@ -3,6 +3,7 @@ package com.fs.company.service.impl.call.node;
 import com.fs.company.service.IWorkflowNode;
 import com.fs.company.service.IWorkflowNodeFactory;
 import com.fs.enums.NodeTypeEnum;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.util.Map;
@@ -15,7 +16,6 @@ import java.util.Map;
 @Component
 public class WorkflowNodeFactory implements IWorkflowNodeFactory {
 
-
     @Override
     public IWorkflowNode createNode(String nodeKey, NodeTypeEnum type, String nodeName,
                                     Map<String, Object> properties) {

+ 1 - 1
fs-service/src/main/java/com/fs/wxcid/service/ICidIpadServerService.java

@@ -60,7 +60,7 @@ public interface ICidIpadServerService extends IService<CidIpadServer>{
      */
     int deleteCidIpadServerById(Long id);
 
-    Long selectQwIpadServerByAddressId(String addressId);
+    Long selectQwIpadServerByAddressId(String addressId,Integer cidGroupNo);
 
     void subtractServer(Long serverId);
 }

+ 2 - 2
fs-service/src/main/java/com/fs/wxcid/service/impl/CidIpadServerServiceImpl.java

@@ -96,8 +96,8 @@ public class CidIpadServerServiceImpl extends ServiceImpl<CidIpadServerMapper, C
     }
 
     @Override
-    public Long selectQwIpadServerByAddressId(String addressId) {
-        CidIpadServer ipadServer = getOne(new QueryWrapper<CidIpadServer>().eq("address_id", addressId).last("limit 1"));
+    public Long selectQwIpadServerByAddressId(String addressId,Integer cidGroupNo) {
+        CidIpadServer ipadServer = getOne(new QueryWrapper<CidIpadServer>().eq("address_id", addressId).eq("group_no", cidGroupNo).last("limit 1"));
         if(ipadServer == null){
             throw new CustomException("地区PAD不足");
         }

+ 1 - 0
fs-service/src/main/resources/application-dev.yml

@@ -44,6 +44,7 @@ spring:
                 # 主库数据源
                 master:
                     url: jdbc:mysql://139.186.77.83:3306/ylrz_his_scrm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+#                    url: jdbc:mysql://139.186.77.83:3306/ylrz_his_scrm_hetai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
                     username: Rtroot
                     password: Rtroot
                 # 主库数据源

+ 1 - 1
fs-service/src/main/resources/mapper/company/CompanyVoiceRoboticCallLogAddwxMapper.xml

@@ -66,7 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">#{createTime},</if>
             <if test="companyId != null">#{companyId},</if>
             <if test="wxAccountId != null">#{wxAccountId},</if>
-            <if test="isWeCom != null">#{is_we_com},</if>
+            <if test="isWeCom != null">#{isWeCom},</if>
          </trim>
     </insert>
 

+ 3 - 0
fs-service/src/main/resources/mapper/company/CompanyVoiceRoboticCalleesMapper.xml

@@ -175,6 +175,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectExcludeList" resultType="com.fs.company.domain.CompanyVoiceRoboticCallees" >
         SELECT * FROM  company_voice_robotic_callees where 1=1
+        <if test="isWeCom != null and isWeCom != ''">
+            and is_we_com = #{isWeCom}
+        </if>
         <if test="list != null">
             and
             <foreach item="item" collection="list" separator=" or " open="(" close=")">

+ 2 - 0
fs-service/src/main/resources/mapper/company/CompanyWxAccountMapper.xml

@@ -56,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="phone != null">phone,</if>
             <if test="wxNo != null">wx_no,</if>
             <if test="companyUserId != null">company_user_id,</if>
+            <if test="companyId != null">company_id,</if>
             <if test="createTime != null">create_time,</if>
             <if test="createUser != null">create_user,</if>
          </trim>
@@ -64,6 +65,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="phone != null">#{phone},</if>
             <if test="wxNo != null">#{wxNo},</if>
             <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="companyId != null">#{companyId},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="createUser != null">#{createUser},</if>
          </trim>

+ 14 - 1
fs-service/src/main/resources/mapper/company/CompanyWxClientMapper.xml

@@ -56,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         inner join company_voice_robotic robotic on a.robotic_id = robotic.id
         <where>
             <if test="companyId != null"> and b.company_id = #{companyId}</if>
+            <if test="isWeCom != null"> and a.is_we_com = #{isWeCom}</if>
             <if test="roboticId != null "> and a.robotic_id = #{roboticId}</if>
             <if test="roboticWxId != null "> and b.id = #{roboticWxId}</if>
             <if test="customerId != null "> and a.customer_id = #{customerId}</if>
@@ -180,7 +181,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT t1.*,t3.workflow_instance_id,t3.current_node_key,t3.current_node_name,t3.current_node_type FROM company_wx_client t1
                              inner join company_voice_robotic_business t2 on t1.id = t2.wx_client_id and t1.robotic_id = t2.robotic_id
                              inner join company_ai_workflow_exec t3 on t3.business_key = t2.id
-        where t1.is_add = 0 and t1.account_id is not null
+        where t1.is_add = 0 and t1.account_id is not null and t1.is_we_com = 1
+        and t3.current_node_type = #{execNodeType} And t3.status = #{execStatus}
+        <if test="accountIdList != null and !accountIdList.isEmpty()">
+            and t1.account_id in <foreach collection="accountIdList" open="(" separator="," close=")" item="item">#{item}</foreach>
+        </if>
+        group by t1.account_id
+    </select>
+    <select id="getQwAddWxList4Workflow" resultType="com.fs.company.vo.CompanyWxClient4WorkFlowVO">
+
+        SELECT t1.*,t3.workflow_instance_id,t3.current_node_key,t3.current_node_name,t3.current_node_type FROM company_wx_client t1
+        inner join company_voice_robotic_business t2 on t1.id = t2.wx_client_id and t1.robotic_id = t2.robotic_id
+        inner join company_ai_workflow_exec t3 on t3.business_key = t2.id
+        where t1.is_add = 0 and t1.account_id is not null and t1.is_we_com = 2
         and t3.current_node_type = #{execNodeType} And t3.status = #{execStatus}
         <if test="accountIdList != null and !accountIdList.isEmpty()">
             and t1.account_id in <foreach collection="accountIdList" open="(" separator="," close=")" item="item">#{item}</foreach>

+ 45 - 13
fs-wx-task/src/main/java/com/fs/app/service/WxTaskService.java

@@ -1,14 +1,11 @@
 package com.fs.app.service;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.common.constant.Constants;
-import com.fs.common.constant.FsConstants;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.redis.RedisCacheT;
 import com.fs.common.utils.PubFun;
@@ -19,7 +16,7 @@ import com.fs.company.param.ExecutionContext;
 import com.fs.company.service.*;
 import com.fs.company.service.impl.*;
 import com.fs.company.service.impl.call.node.AiAddWxTaskNode;
-import com.fs.company.service.impl.call.node.AiCallTaskNode;
+import com.fs.company.service.impl.call.node.AiQwAddWxTaskNode;
 import com.fs.company.service.impl.call.node.WorkflowNodeFactory;
 import com.fs.company.vo.CompanyWxClient4WorkFlowVO;
 import com.fs.course.config.RedisKeyScanner;
@@ -39,19 +36,18 @@ import com.fs.wxcid.dto.friend.AddContactParam;
 import com.fs.wxcid.service.FriendService;
 import com.fs.wxcid.vo.AddContactVo;
 import com.fs.wxwork.dto.WxAddSearchDTO;
-import com.fs.wxwork.dto.WxSearchContactDTO;
-import com.fs.wxwork.dto.WxSearchContactResp;
 import com.fs.wxwork.dto.WxWorkResponseDTO;
 import com.fs.wxwork.service.WxWorkService;
 import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
@@ -62,9 +58,13 @@ import java.util.stream.Collectors;
 
 @Slf4j
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class WxTaskService {
 
+
+    @Value("${cid-group-no:0}")
+    private Integer cidGroupNo;
+
     private final ICompanyWxAccountService companyWxAccountService;
     private final ISysConfigService sysConfigService;
     private final ICompanyWxClientService companyWxClientService;
@@ -102,6 +102,7 @@ public class WxTaskService {
     private final QwUserMapper qwUserMapper;
     private final WxWorkService wxWorkService;
     private final QwExternalContactMapper qwExternalContactMapper;
+    private final CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
 
     public void addWx(List<Long> accountIdList) {
         log.info("==========执行加微信任务开始==========");
@@ -110,7 +111,7 @@ public class WxTaskService {
         // 需要添加微信的列表
         List<CompanyWxClient> list = companyWxClientService.getAddWxList(accountIdList,1);
         //排除掉没到达加微步骤的人
-        List<CompanyVoiceRoboticCallees> exList = companyVoiceRoboticCalleesMapper.selectExcludeList(list);
+        List<CompanyVoiceRoboticCallees> exList = companyVoiceRoboticCalleesMapper.selectExcludeList(list, 1);
         List<CompanyVoiceRoboticCallees> collect =
                 exList.stream().filter(e -> !Constants.ADD_WX.equals(getNextTaskOptimized(e.getTaskFlow(), e.getRunTaskFlow())))
                         .collect(Collectors.toList());
@@ -295,7 +296,7 @@ public class WxTaskService {
                     if (vo.isSuccess()) {
                         e.setLastAddWxTime(LocalDateTime.now());
 //                        todo 删除还原 以下为测试所用
-//                        e.setLastAddWxTime(LocalDateTime.now().plus(-1, ChronoUnit.DAYS));
+                        e.setLastAddWxTime(LocalDateTime.now().plus(-1, ChronoUnit.DAYS));
                         e.setIsAddNum(e.getIsAddNum() + 1);
                         client.setIsAdd(2);
                         client.setAddTime(LocalDateTime.now());
@@ -826,7 +827,7 @@ public class WxTaskService {
      */
     public void cidWorkflowAddWxRun() {
         log.info("===========工作流延时任务开始扫描===========");
-        String delayAddWxKeyPrefix = AiAddWxTaskNode.getDelayAddWxKeyPrefix(null) + "*";
+        String delayAddWxKeyPrefix = AiAddWxTaskNode.getDelayAddWxKeyPrefix(cidGroupNo,null) + "*";
         Set<String> keys = redisKeyScanner.scanMatchKey(delayAddWxKeyPrefix);
         log.info("共扫描到 {} 个待处理键", keys.size());
         keys.parallelStream().forEach(key -> {
@@ -924,7 +925,38 @@ public class WxTaskService {
         log.info("==========执行企微申请加个微结果查询任务结束==========");
     }
 
-    
+
+    /**
+     * 扫描企微加微工作流延时任务
+     */
+    public void cidWorkflowQwAddWxRun() {
+        log.info("===========企微加微工作流延时任务开始扫描===========");
+        String delayAddWxKeyPrefix = AiQwAddWxTaskNode.getDelayAddWxKeyPrefix(cidGroupNo,null) + "*";
+        Set<String> keys = redisKeyScanner.scanMatchKey(delayAddWxKeyPrefix);
+        log.info("企微加微共扫描到 {} 个待处理键", keys.size());
+        keys.parallelStream().forEach(key -> {
+            try {
+                //doExec
+                CompletableFuture.runAsync(()->{
+                    try {
+                        ExecutionContext context = redisCache2.getCacheObject(key);
+                        context.setVariable("callRedisKey",key);
+                        context.setVariable("callSource","qwAddWxTimer");
+                        companyWorkflowEngine.timeDoExecute(context.getWorkflowInstanceId(),context.getCurrentNodeKey(),context.getVariables());
+                    } catch (Exception e) {
+                        log.error("处理工作流延时任务异常 - key: {}", key, e);
+                    }
+                }, cidExcutor).thenRun(()->{
+                    redisCache2.deleteObject(key);
+                });
+
+            } catch (Exception ex) {
+                log.error("处理工作流延时任务异常 - key: {}", key, ex);
+            }
+        });
+        log.info("===========工作流延时任务扫描结束===========");
+    }
+
     /**
      * 获取过滤后的企微客户列表
      */
@@ -932,7 +964,7 @@ public class WxTaskService {
         List<CompanyWxClient> list = companyWxClientService.getAddWxList(accountIdList, 2);
         
         // 排除掉没到达加微步骤的人
-        List<CompanyVoiceRoboticCallees> excludeList = companyVoiceRoboticCalleesMapper.selectExcludeList(list);
+        List<CompanyVoiceRoboticCallees> excludeList = companyVoiceRoboticCalleesMapper.selectExcludeList(list,2);
         Set<String> excludeKeys = excludeList.stream()
                 .filter(e -> !Constants.QW_ADD_WX.equals(getNextTaskOptimized(e.getTaskFlow(), e.getRunTaskFlow())))
                 .map(callee -> callee.getRoboticId() + "_" + callee.getUserId())

+ 16 - 10
fs-wx-task/src/main/java/com/fs/app/task/WxTask.java

@@ -6,8 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
-import java.util.Collections;
-
 /**
  * 企业微信SOP定时任务管理类
  * 负责处理各种定时任务,包括SOP规则检查、消息发送、数据清理等
@@ -22,10 +20,10 @@ public class WxTask {
     @Autowired
     private WxTaskService taskService;
 
-    @Scheduled(cron = "0 0/30 * * * ?")
-    public void addWx() {
-        taskService.addWx(null);
-    }
+//    @Scheduled(cron = "0 0/30 * * * ?")
+//    public void addWx() {
+//        taskService.addWx(null);
+//    }
     @Scheduled(cron = "0 0/1 * * * ?")
     public void addWx4Workflow() {
         taskService.addWx4Workflow(null);
@@ -53,10 +51,10 @@ public class WxTask {
      * 工作流加微超时检测
      * 每分钟执行一次,检查是否有加微超时的工作流需要继续执行
      */
-    @Scheduled(cron = "0 0/1 * * * ?")
-    public void checkWorkflowAddWxTimeout(){
-        taskService.checkWorkflowAddWxTimeout();
-    }
+//    @Scheduled(cron = "0 0/1 * * * ?")
+//    public void checkWorkflowAddWxTimeout(){
+//        taskService.checkWorkflowAddWxTimeout();
+//    }
 
     @Scheduled(cron = "0 0/1 * * * ?")
     public void cidWorkflowAddWxRun(){
@@ -78,4 +76,12 @@ public class WxTask {
     public void qwAddWxResult() {
         taskService.qwAddWxResult(null);
     }
+    /**
+     * 企微加微工作流超时检测
+     * 每分钟执行一次,检查是否有加微超时的工作流需要继续执行
+     */
+    @Scheduled(cron = "0 0/1 * * * ?")
+    public void cidWorkflowQwAddWxRun(){
+        taskService.cidWorkflowQwAddWxRun();
+    }
 }

+ 1 - 0
fs-wx-task/src/main/resources/application.yml

@@ -14,3 +14,4 @@ spring:
 #    active: druid-sxjz
 #    active: druid-hdt
 #    active: druid-myhk-test
+cid-group-no: 1