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

销售端AI外呼增加企微加个微节点流程

peicj 1 неделя назад
Родитель
Сommit
c4e9d696a3

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

@@ -62,4 +62,6 @@ public class CompanyVoiceRoboticCallees{
 
 
     @TableField(exist = false)
     @TableField(exist = false)
     private String idToString;
     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<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);
     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<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<CompanyWxClient4WorkFlowVO> getAddWxList4Workflow(List<Long> accountIdList);
 
 
     List<CompanyWxClient> getQwAddWxList(List<Long> accountIdList,Integer isWeCom);
     List<CompanyWxClient> getQwAddWxList(List<Long> accountIdList,Integer isWeCom);
+
+    List<CompanyWxClient4WorkFlowVO> getQwAddWxList4Workflow(List<Long> accountIdList);
 }
 }

+ 1 - 0
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.setResult(0);
             callees.setTaskFlow(companyVoiceRobotic.getTaskFlow());
             callees.setTaskFlow(companyVoiceRobotic.getTaskFlow());
             callees.setRunTaskFlow(companyVoiceRobotic.getRunTaskFlow());
             callees.setRunTaskFlow(companyVoiceRobotic.getRunTaskFlow());
+            callees.setIsWeCom(isWeCom);
             return callees;
             return callees;
         }).collect(Collectors.toList());
         }).collect(Collectors.toList());
         companyVoiceRoboticCalleesService.saveBatch(callesList);
         companyVoiceRoboticCalleesService.saveBatch(callesList);

+ 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) {
     public List<CompanyWxClient> getQwAddWxList(List<Long> accountIdList, Integer isWeCom) {
         return baseMapper.getQwAddWxList(accountIdList,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());
+    }
 }
 }

+ 44 - 38
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;
 package com.fs.company.service.impl.call.node;
 
 
+import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.constant.Constants;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCacheT;
 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());
         boolean addSuccess = wxClient != null && Integer.valueOf(1).equals(wxClient.getIsAdd());
         //回调加微成功
         //回调加微成功
         if (addSuccess) {
         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));
                 super.runNextNode(context, cList.get(0));
             }
             }
         }
         }
@@ -78,7 +83,8 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
                     .collect(Collectors.toList());
                     .collect(Collectors.toList());
             // 加微失败,根据条件判断走哪条边
             // 加微失败,根据条件判断走哪条边
             CompanyWorkflowEdge edge = cList.get(0);
             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()) {
                 if (!condition.isAdd()) {
                     log.info("加微失败,执行失败分支 - workflowInstanceId: {}", context.getWorkflowInstanceId());
                     log.info("加微失败,执行失败分支 - workflowInstanceId: {}", context.getWorkflowInstanceId());
@@ -104,8 +110,8 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
             return ExecutionResult.failure().nextNodeKey(null).build();
             return ExecutionResult.failure().nextNodeKey(null).build();
         }
         }
         try {
         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())
                     .outputData(context.getVariables())
                     .nextNodeKey("").build();
                     .nextNodeKey("").build();
         } catch (Exception e) {
         } catch (Exception e) {
@@ -198,35 +204,35 @@ public class AiQwAddWxTaskNode extends AbstractWorkflowNode {
      * 完成加微动作
      * 完成加微动作
      *
      *
      */
      */
-//    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(l) + workflowInstanceId;
+                    ExecutionContext nextContext = context.clone();
+                    nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
+                    super.redisCache.setCacheObject(redisKey, nextContext);
+                }
+            }
+        });
+    }
 }
 }

+ 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="createTime != null">#{createTime},</if>
             <if test="companyId != null">#{companyId},</if>
             <if test="companyId != null">#{companyId},</if>
             <if test="wxAccountId != null">#{wxAccountId},</if>
             <if test="wxAccountId != null">#{wxAccountId},</if>
-            <if test="isWeCom != null">#{is_we_com},</if>
+            <if test="isWeCom != null">#{isWeCom},</if>
          </trim>
          </trim>
     </insert>
     </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 id="selectExcludeList" resultType="com.fs.company.domain.CompanyVoiceRoboticCallees" >
         SELECT * FROM  company_voice_robotic_callees where 1=1
         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">
         <if test="list != null">
             and
             and
             <foreach item="item" collection="list" separator=" or " open="(" close=")">
             <foreach item="item" collection="list" separator=" or " open="(" close=")">

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

@@ -180,7 +180,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
         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_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
                              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}
         and t3.current_node_type = #{execNodeType} And t3.status = #{execStatus}
         <if test="accountIdList != null and !accountIdList.isEmpty()">
         <if test="accountIdList != null and !accountIdList.isEmpty()">
             and t1.account_id in <foreach collection="accountIdList" open="(" separator="," close=")" item="item">#{item}</foreach>
             and t1.account_id in <foreach collection="accountIdList" open="(" separator="," close=")" item="item">#{item}</foreach>

+ 187 - 220
fs-wx-task/src/main/java/com/fs/app/service/WxTaskService.java

@@ -1,14 +1,11 @@
 package com.fs.app.service;
 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.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.common.constant.Constants;
 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.RedisCache;
 import com.fs.common.core.redis.RedisCacheT;
 import com.fs.common.core.redis.RedisCacheT;
 import com.fs.common.utils.PubFun;
 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.*;
 import com.fs.company.service.impl.*;
 import com.fs.company.service.impl.*;
 import com.fs.company.service.impl.call.node.AiAddWxTaskNode;
 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.service.impl.call.node.WorkflowNodeFactory;
 import com.fs.company.vo.CompanyWxClient4WorkFlowVO;
 import com.fs.company.vo.CompanyWxClient4WorkFlowVO;
 import com.fs.course.config.RedisKeyScanner;
 import com.fs.course.config.RedisKeyScanner;
@@ -39,8 +36,6 @@ import com.fs.wxcid.dto.friend.AddContactParam;
 import com.fs.wxcid.service.FriendService;
 import com.fs.wxcid.service.FriendService;
 import com.fs.wxcid.vo.AddContactVo;
 import com.fs.wxcid.vo.AddContactVo;
 import com.fs.wxwork.dto.WxAddSearchDTO;
 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.dto.WxWorkResponseDTO;
 import com.fs.wxwork.service.WxWorkService;
 import com.fs.wxwork.service.WxWorkService;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
@@ -49,9 +44,7 @@ import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
@@ -102,6 +95,7 @@ public class WxTaskService {
     private final QwUserMapper qwUserMapper;
     private final QwUserMapper qwUserMapper;
     private final WxWorkService wxWorkService;
     private final WxWorkService wxWorkService;
     private final QwExternalContactMapper qwExternalContactMapper;
     private final QwExternalContactMapper qwExternalContactMapper;
+    private final CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
 
 
     public void addWx(List<Long> accountIdList) {
     public void addWx(List<Long> accountIdList) {
         log.info("==========执行加微信任务开始==========");
         log.info("==========执行加微信任务开始==========");
@@ -110,7 +104,7 @@ public class WxTaskService {
         // 需要添加微信的列表
         // 需要添加微信的列表
         List<CompanyWxClient> list = companyWxClientService.getAddWxList(accountIdList,1);
         List<CompanyWxClient> list = companyWxClientService.getAddWxList(accountIdList,1);
         //排除掉没到达加微步骤的人
         //排除掉没到达加微步骤的人
-        List<CompanyVoiceRoboticCallees> exList = companyVoiceRoboticCalleesMapper.selectExcludeList(list);
+        List<CompanyVoiceRoboticCallees> exList = companyVoiceRoboticCalleesMapper.selectExcludeList(list, 1);
         List<CompanyVoiceRoboticCallees> collect =
         List<CompanyVoiceRoboticCallees> collect =
                 exList.stream().filter(e -> !Constants.ADD_WX.equals(getNextTaskOptimized(e.getTaskFlow(), e.getRunTaskFlow())))
                 exList.stream().filter(e -> !Constants.ADD_WX.equals(getNextTaskOptimized(e.getTaskFlow(), e.getRunTaskFlow())))
                         .collect(Collectors.toList());
                         .collect(Collectors.toList());
@@ -852,64 +846,99 @@ public class WxTaskService {
         log.info("===========工作流延时任务扫描结束===========");
         log.info("===========工作流延时任务扫描结束===========");
     }
     }
 
 
+
     /**
     /**
      * 企微加微信任务
      * 企微加微信任务
      *
      *
      * @param accountIdList 企微成员id
      * @param accountIdList 企微成员id
      */
      */
     public void qwAddWx(List<Long> accountIdList) {
     public void qwAddWx(List<Long> accountIdList) {
-        log.info("==========执行企微申请加个微任务开始==========");
+        log.info("==========执行申请企微加好友任务开始==========");
         try {
         try {
-            // 获取需要添加微信的企微客户列表
-            List<CompanyWxClient> clientList = getFilteredClientList(accountIdList);
-            if (clientList.isEmpty()) {
-                log.info("没有符合条件的客户需要添加微信");
-                return;
-            }
-            
-            // 获取CompanyWxClient信息
-            Map<Long, CompanyWxClient> clientMap = PubFun.listToMapByGroupObject(clientList, CompanyWxClient::getAccountId);
+            // 需要添加微信的列表
+            List<CompanyWxClient4WorkFlowVO> list = companyWxClientService.getQwAddWxList4Workflow(accountIdList);
+            log.info("申请企微加好友任务需要添加微信的数量:{}", list.size());
+            if (list.isEmpty()) return;
+            List<CompanyWxClient> addList = new ArrayList<>();
+            Map<Long, CompanyWxClient4WorkFlowVO> clientMap = PubFun.listToMapByGroupObject(list, CompanyWxClient4WorkFlowVO::getAccountId);
             // 获取实际企微用户信息
             // 获取实际企微用户信息
-            List<QwUser> qwUserList = qwUserMapper.selectBatchIds(clientMap.keySet()).stream()
+            List<QwUser> addAccountList = qwUserMapper.selectBatchIds(clientMap.keySet()).stream()
                     .filter(this::isValidQwUser)
                     .filter(this::isValidQwUser)
                     .collect(Collectors.toList());
                     .collect(Collectors.toList());
-            
-            log.info("需要企微添加的账号数量:{}", qwUserList.size());
-            if (qwUserList.isEmpty()) return;
-            
-            // 处理加微逻辑
-            List<CompanyWxClient> upClientList = processQwAddWx(qwUserList, clientMap);
-            
-            // 批量更新客户状态
-            if (!upClientList.isEmpty()) {
-                companyWxClientService.updateBatchById(upClientList);
-                log.info("成功更新{}个客户的加微状态", upClientList.size());
+            log.info("企微申请加好友任务需要企微的账号数量:{}", addAccountList.size());
+            addAccountList.forEach(qwUser -> {
+                CompanyWxClient4WorkFlowVO client = clientMap.get(qwUser.getId());
+                if (client != null) {
+                    CrmCustomer crmCustomer = crmCustomerService.selectCrmCustomerById(client.getCustomerId());
+                    // 开始申请加微
+                    WxWorkResponseDTO<String> resp = qwAddWxInvokeIpad(crmCustomer.getMobile(), qwUser.getUid(), qwUser.getServerId());
+                    JSONObject runParam = new JSONObject();
+                    runParam.put("qwId", qwUser.getId());
+                    runParam.put("mobile", crmCustomer.getMobile());
+                    runParam.put("qwUid", qwUser.getUid());
+                    runParam.put("clientId", client.getId());
+                    CompanyVoiceRoboticCallLogAddwx addLog = CompanyVoiceRoboticCallLogAddwx.initCallLog(
+                            runParam.toJSONString(), client.getId(), client.getRoboticId(), qwUser.getId(), qwUser.getCompanyId());
+                    if (resp != null && resp.getErrcode() == 0) {
+                        // 加微消息已发送成功
+                        client.setIsAdd(2);
+                        client.setAddTime(LocalDateTime.now());
+                        CompanyWxClient addItem = new CompanyWxClient();
+                        BeanUtils.copyProperties(client, addItem);
+                        addList.add(addItem);
+                        addLog.setStatus(1);
+                        addLog.setResult(JSON.toJSONString(resp));
+                        addLog.setIsWeCom(2);
+                        log.info("ROBOTIC-ID:{},企微申请加好友任务申请成功", client.getRoboticId());
+                    } else {
+                        log.error("ROBOTIC-ID:{},企微申请加好友任务加微失败:{}", client.getRoboticId(), runParam);
+                        addLog.setStatus(3);
+                        addLog.setResult(JSON.toJSONString(runParam));
+                    }
+                    asyncSaveCompanyVoiceRoboticCallLog(addLog);
+                } else {
+                    log.error("企微申请加好友任务当前账号暂无需要添加微信:{}-{}", qwUser.getId(), qwUser.getQwUserName());
+                }
+            });
+            if (!addList.isEmpty()) {
+                companyWxClientService.updateBatchById(addList);
+                for (CompanyWxClient client : addList) {
+                    CompanyWxClient4WorkFlowVO vo = clientMap.get(client.getAccountId());
+                    IWorkflowNode node = workflowNodeFactory.createNode(vo.getCurrentNodeKey(),
+                            NodeTypeEnum.fromValue(vo.getCurrentNodeType()),
+                            vo.getCurrentNodeName(), null);
+                    if (node instanceof AiQwAddWxTaskNode) {
+                        CompletableFuture.runAsync(() -> {
+                            AiQwAddWxTaskNode qwAddWxNode = (AiQwAddWxTaskNode) node;
+                            qwAddWxNode.doneQwAddWx(vo.getWorkflowInstanceId());
+                        }, cidExcutor);
+                    }
+                }
             }
             }
         } catch (Exception e) {
         } catch (Exception e) {
-            log.error("企微加微信任务执行异常", e);
+            log.error("企微申请加好友任务执行异常", e);
         }
         }
-        log.info("==========执行企微申请加个微任务结束==========");
+        log.info("==========执行企微申请加好友任务结束==========");
     }
     }
 
 
     /**
     /**
      * 企微加微结果处理
      * 企微加微结果处理
      */
      */
     public void qwAddWxResult(List<Long> accountIdList) {
     public void qwAddWxResult(List<Long> accountIdList) {
-        log.info("==========执行企微申请加个微结果查询任务开始==========");
+        log.info("==========执行企微申请加微结果查询任务开始==========");
         try {
         try {
             //is_add = 2,状态为加微中且是企微类型
             //is_add = 2,状态为加微中且是企微类型
             List<CompanyWxClient> clients = companyWxClientService.getQwAddWxList(accountIdList, 2);
             List<CompanyWxClient> clients = companyWxClientService.getQwAddWxList(accountIdList, 2);
-            log.info("需要查询企微加个微结果的数量:{}", clients.size());
+            log.info("企微申请加微结果查询任务需要查询的数量:{}", clients.size());
             
             
             if (clients.isEmpty()) return;
             if (clients.isEmpty()) return;
-            
             // 处理每个客户的加微结果
             // 处理每个客户的加微结果
             List<CompanyWxClient> upClientList = new ArrayList<>();
             List<CompanyWxClient> upClientList = new ArrayList<>();
             clients.parallelStream().forEach(client -> {
             clients.parallelStream().forEach(client -> {
                 try {
                 try {
                     processSingleClientResult(client, upClientList);
                     processSingleClientResult(client, upClientList);
                 } catch (Exception e) {
                 } catch (Exception e) {
-                    log.error("处理客户{}加微结果异常", client.getId(), e);
+                    log.error("企微申请加微结果查询任务处理客户{}加微结果异常", client.getId(), e);
                 }
                 }
             });
             });
             
             
@@ -919,30 +948,43 @@ public class WxTaskService {
             }
             }
             
             
         } catch (Exception e) {
         } catch (Exception e) {
-            log.error("企微加微结果处理异常", e);
+            log.error("企微申请加微结果查询任务处理异常", e);
         }
         }
-        log.info("==========执行企微申请加微结果查询任务结束==========");
+        log.info("==========执行企微申请加微结果查询任务结束==========");
     }
     }
 
 
-    
     /**
     /**
-     * 获取过滤后的企微客户列表
+     * 扫描企微加微工作流延时任务
      */
      */
-    private List<CompanyWxClient> getFilteredClientList(List<Long> accountIdList) {
-        List<CompanyWxClient> list = companyWxClientService.getAddWxList(accountIdList, 2);
-        
-        // 排除掉没到达加微步骤的人
-        List<CompanyVoiceRoboticCallees> excludeList = companyVoiceRoboticCalleesMapper.selectExcludeList(list);
-        Set<String> excludeKeys = excludeList.stream()
-                .filter(e -> !Constants.QW_ADD_WX.equals(getNextTaskOptimized(e.getTaskFlow(), e.getRunTaskFlow())))
-                .map(callee -> callee.getRoboticId() + "_" + callee.getUserId())
-                .collect(Collectors.toSet());
-        
-        return list.stream()
-                .filter(client -> !excludeKeys.contains(client.getRoboticId() + "_" + client.getCustomerId()))
-                .collect(Collectors.toList());
+    public void cidWorkflowQwAddWxRun() {
+        log.info("===========企微加微工作流延时任务开始扫描===========");
+        String delayAddWxKeyPrefix = AiQwAddWxTaskNode.getDelayAddWxKeyPrefix(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("===========工作流延时任务扫描结束===========");
     }
     }
-    
+
+
     /**
     /**
      * 验证企微用户有效性
      * 验证企微用户有效性
      */
      */
@@ -953,55 +995,7 @@ public class WxTaskService {
         }
         }
         return true;
         return true;
     }
     }
-    
-    /**
-     * 处理企微加微逻辑
-     */
-    private List<CompanyWxClient> processQwAddWx(List<QwUser> qwUserList, Map<Long, CompanyWxClient> clientMap) {
-        List<CompanyWxClient> upClientList = Collections.synchronizedList(new ArrayList<>());
-        
-        qwUserList.parallelStream().forEach(qwUser -> {
-            try {
-                processSingleQwUser(qwUser, clientMap, upClientList);
-            } catch (Exception e) {
-                log.error("处理企微用户{}异常", qwUser.getId(), e);
-            }
-        });
-        
-        return upClientList;
-    }
-    
-    /**
-     * 处理单个企微用户
-     */
-    private void processSingleQwUser(QwUser qwUser, Map<Long, CompanyWxClient> clientMap, 
-                                   List<CompanyWxClient> upClientList) {
-        CompanyWxClient client = clientMap.get(qwUser.getId());
-        if (client == null) {
-            log.error("当前账号暂无需要添加微信:{}-{}", qwUser.getId(), qwUser.getQwUserName());
-            return;
-        }
-        
-        CrmCustomer crmCustomer = crmCustomerService.selectCrmCustomerById(client.getCustomerId());
-        if (crmCustomer == null || StringUtils.isBlank(crmCustomer.getMobile())) {
-            log.info("查询客户{}手机号为空,跳过执行", crmCustomer == null ? "" : crmCustomer.getCustomerName());
-            return;
-        }
-        
-        String task = redisCache.getCacheObject(Constants.TASK_ID + client.getRoboticId());
-        log.info("ROBOTIC-ID:{},CLIENT-ID:{},当前任务执行状态:{}", 
-                client.getRoboticId(), client.getId(), task);
-        
-        if (!StringUtils.isNotEmpty(task) || !Constants.QW_ADD_WX.equals(task)) {
-            log.error("ROBOTIC-ID:{},当前任务没有执行加微任务", client.getRoboticId());
-            return;
-        }
-        
-        // 开始申请加微
-        WxWorkResponseDTO<String> resp = qwAddWxInvokeIpad(crmCustomer.getMobile(), qwUser.getUid(), qwUser.getServerId());
-        //处理申请加微结果
-        handleAddWxResult(resp, client, qwUser, crmCustomer, upClientList);
-    }
+
 
 
     /**
     /**
      * 企微加个微调用ipad端
      * 企微加个微调用ipad端
@@ -1012,7 +1006,7 @@ public class WxTaskService {
      */
      */
     private WxWorkResponseDTO<String> qwAddWxInvokeIpad(String mobile, String qwUid, Long serverId) {
     private WxWorkResponseDTO<String> qwAddWxInvokeIpad(String mobile, String qwUid, Long serverId) {
         if (StringUtils.isBlank(mobile) || StringUtils.isBlank(qwUid) || serverId == null) {
         if (StringUtils.isBlank(mobile) || StringUtils.isBlank(qwUid) || serverId == null) {
-            log.warn("参数校验失败: mobile={}, qwUid={}, serverId={}", mobile, qwUid, serverId);
+            log.warn("企微申请加好友任务参数校验失败: mobile={}, qwUid={}, serverId={}", mobile, qwUid, serverId);
             return null;
             return null;
         }
         }
         try {
         try {
@@ -1025,67 +1019,44 @@ public class WxTaskService {
             wxAddSearchDTO.setTicket(null);
             wxAddSearchDTO.setTicket(null);
 
 
             WxWorkResponseDTO<String> response = wxWorkService.addSearch(wxAddSearchDTO, serverId);
             WxWorkResponseDTO<String> response = wxWorkService.addSearch(wxAddSearchDTO, serverId);
-            log.debug("企微加微接口调用结果: errcode={}, errmsg={}",
+            log.debug("企微申请加好友任务调用结果: errcode={}, errmsg={}",
                     response != null ? response.getErrcode() : "null",
                     response != null ? response.getErrcode() : "null",
                     response != null ? response.getErrmsg() : "null");
                     response != null ? response.getErrmsg() : "null");
 
 
             return response;
             return response;
+
+            // 测试代码
+//            WxWorkResponseDTO<String> response = new WxWorkResponseDTO<>();
+//            response.setErrcode(0);
+//            return response;
         } catch (Exception e) {
         } catch (Exception e) {
-            log.error("企微加个微请求接口异常: mobile={}, qwUid={}, serverId={}", mobile, qwUid, serverId, e);
+            log.error("企微申请加好友任务请求接口异常: mobile={}, qwUid={}, serverId={}", mobile, qwUid, serverId, e);
             return null;
             return null;
         }
         }
     }
     }
-
-    /**
-     * 处理加微结果
-     */
-    private void handleAddWxResult(WxWorkResponseDTO<String> resp, CompanyWxClient client, 
-                                 QwUser qwUser, CrmCustomer crmCustomer, 
-                                 List<CompanyWxClient> upClientList) {
-        JSONObject runParam = new JSONObject();
-        runParam.put("qwId", qwUser.getId());
-        runParam.put("mobile", crmCustomer.getMobile());
-        runParam.put("qwUid", qwUser.getUid());
-        runParam.put("clientId", client.getId());
-        
-        CompanyVoiceRoboticCallLogAddwx addLog = CompanyVoiceRoboticCallLogAddwx.initCallLog(
-                runParam.toJSONString(), client.getId(), client.getRoboticId(), qwUser.getId(), qwUser.getCompanyId());
-        
-        if (resp != null && resp.getErrcode() == 0) {
-            // 加微消息已发送成功
-            client.setIsAdd(2);
-            client.setAddTime(LocalDateTime.now());
-            upClientList.add(client);
-            addLog.setStatus(1);
-            addLog.setResult(JSON.toJSONString(resp));
-            addLog.setIsWeCom(2);
-            log.info("ROBOTIC-ID:{},加微成功", client.getRoboticId());
-        } else {
-            // 加微消息发送失败,补偿重试
-            handleFailedAddWxWithRetry(client, upClientList);
-        }
-        
-        asyncSaveCompanyVoiceRoboticCallLog(addLog);
-    }
     
     
     /**
     /**
      * 处理单个客户加微结果
      * 处理单个客户加微结果
      */
      */
     private void processSingleClientResult(CompanyWxClient client, List<CompanyWxClient> upClientList) {
     private void processSingleClientResult(CompanyWxClient client, List<CompanyWxClient> upClientList) {
         if (StringUtils.isBlank(client.getPhone())) {
         if (StringUtils.isBlank(client.getPhone())) {
-            handleFailedAddWx(client, upClientList, "无电话号码");
+            handleFailedAddWx(client, upClientList, "无电话号码",0);
             return;
             return;
         }
         }
         
         
         // 查询外部联系人表是否有数据
         // 查询外部联系人表是否有数据
         QwExternalContact qwExternalContact = qwExternalContactMapper.queryQwUserIdIsAddContact(
         QwExternalContact qwExternalContact = qwExternalContactMapper.queryQwUserIdIsAddContact(
                 client.getAccountId(), client.getPhone(), 2);
                 client.getAccountId(), client.getPhone(), 2);
-        
+
         if (qwExternalContact != null && qwExternalContact.getId() > 0) {
         if (qwExternalContact != null && qwExternalContact.getId() > 0) {
             handleSuccessfulAddWx(client, upClientList);
             handleSuccessfulAddWx(client, upClientList);
         } else {
         } else {
-            handleFailedAddWxWithRetry(client, upClientList);
+            handleFailedAddWxWithRetry(client, upClientList,0);
         }
         }
+
+        //测试代码
+//        handleSuccessfulAddWx(client, upClientList);
+//        handleFailedAddWx(client, upClientList, "无电话号码",0);
     }
     }
     
     
     /**
     /**
@@ -1105,19 +1076,19 @@ public class WxTaskService {
         client.setAddTime(LocalDateTime.now());
         client.setAddTime(LocalDateTime.now());
         upClientList.add(client);
         upClientList.add(client);
         redisCache.deleteObject("qwAddWx_" + client.getId());
         redisCache.deleteObject("qwAddWx_" + client.getId());
-        log.info("ROBOTIC-ID:{},加微成功:{}", client.getRoboticId(), client.getId());
+        log.info("ROBOTIC-ID:{},企微申请加微结果查询任务加微成功:{}", client.getRoboticId(), client.getId());
     }
     }
-    
+
     /**
     /**
      * 处理加微失败的情况
      * 处理加微失败的情况
      */
      */
-    private void handleFailedAddWx(CompanyWxClient client, List<CompanyWxClient> upClientList, String reason) {
-        log.error("ROBOTIC-ID:{},{}加微失败:{}", client.getRoboticId(), reason, client.getId());
+    private void handleFailedAddWx(CompanyWxClient client, List<CompanyWxClient> upClientList, String reason,Integer isAdd) {
+        String taskName = isAdd == 1 ? "企微申请加好友任务" : "加微结果查询任务";
+        log.error("ROBOTIC-ID:{},{}:{},clientId={}", client.getRoboticId(),taskName, reason, client.getId());
         client.setIsAdd(3);
         client.setIsAdd(3);
         client.setUpdateTime(new Date());
         client.setUpdateTime(new Date());
         upClientList.add(client);
         upClientList.add(client);
-        
-        // 更新记录
+        // 更新日志记录
         companyVoiceRoboticCallLogAddwxService.lambdaUpdate()
         companyVoiceRoboticCallLogAddwxService.lambdaUpdate()
                 .eq(CompanyVoiceRoboticCallLogAddwx::getRoboticId, client.getRoboticId())
                 .eq(CompanyVoiceRoboticCallLogAddwx::getRoboticId, client.getRoboticId())
                 .eq(CompanyVoiceRoboticCallLogAddwx::getWxClientId, client.getId())
                 .eq(CompanyVoiceRoboticCallLogAddwx::getWxClientId, client.getId())
@@ -1131,17 +1102,19 @@ public class WxTaskService {
     /**
     /**
      * 处理加微失败并重试计数
      * 处理加微失败并重试计数
      */
      */
-    private void handleFailedAddWxWithRetry(CompanyWxClient client, List<CompanyWxClient> upClientList) {
-        log.error("ROBOTIC-ID:{},加微失败:{}", client.getRoboticId(), client.getId());
+    private void handleFailedAddWxWithRetry(CompanyWxClient client, List<CompanyWxClient> upClientList,Integer isAdd) {
+        String taskName = isAdd == 1 ? "企微申请加好友任务" : "加微结果查询任务";
+        log.error("ROBOTIC-ID:{},{}失败:{}", client.getRoboticId(),taskName, client.getId());
         String failCountStr = redisCache.getCacheObject("qwAddWx_" + client.getId());
         String failCountStr = redisCache.getCacheObject("qwAddWx_" + client.getId());
         int failCount = 1;
         int failCount = 1;
         
         
         if (StringUtils.isNotBlank(failCountStr)) {
         if (StringUtils.isNotBlank(failCountStr)) {
-            failCount += Integer.parseInt(failCountStr);
-            if (failCount >= 60 * 24) { // 超过一天
-                handleFailedAddWx(client, upClientList, "超过最大重试次数");
+            if (Integer.parseInt(failCountStr) >= 60 * 24) { // 超过一天
+                handleFailedAddWx(client, upClientList, "超过最大重试次数",isAdd);
+                redisCache.deleteObject("qwAddWx_" + client.getId());
             } else {
             } else {
-                redisCache.setCacheObject("qwAddWx_" + client.getId(), String.valueOf(failCount));
+                failCount += Integer.parseInt(failCountStr);
+                redisCache.setCacheObject("qwAddWx_" + client.getId(), String.valueOf(failCount-1));
             }
             }
         } else {
         } else {
             redisCache.setCacheObject("qwAddWx_" + client.getId(), String.valueOf(failCount), 25, TimeUnit.HOURS);
             redisCache.setCacheObject("qwAddWx_" + client.getId(), String.valueOf(failCount), 25, TimeUnit.HOURS);
@@ -1153,80 +1126,74 @@ public class WxTaskService {
      */
      */
     private void batchUpdateClients(List<CompanyWxClient> upClientList) {
     private void batchUpdateClients(List<CompanyWxClient> upClientList) {
         companyWxClientService.updateBatchById(upClientList);
         companyWxClientService.updateBatchById(upClientList);
-
-        // 从 upClientList 中筛选出 isAdd=1即加微成功的数据
+        // 从 upClientList 中筛选出 isAdd=1和3加微失败的数据
         List<CompanyWxClient> successClients = upClientList.stream()
         List<CompanyWxClient> successClients = upClientList.stream()
-                .filter(client -> client.getIsAdd() != null && client.getIsAdd() == 1)
+                .filter(client -> client.getIsAdd() != null && (client.getIsAdd() == 1 || client.getIsAdd() == 3))
                 .collect(Collectors.toList());
                 .collect(Collectors.toList());
-
-        // 根据加微成功的用户,判定是否加入延时执行下一步任务
-        Set<Long> roboticIdSet = successClients.stream()
-                .map(CompanyWxClient::getRoboticId)
-                .collect(Collectors.toSet());
-        Set<Long> userIdSet = successClients.stream()
-                .map(CompanyWxClient::getCustomerId)
-                .collect(Collectors.toSet());
-        
-        // 获取任务和callees数据
-        List<CompanyVoiceRobotic> robotList = companyVoiceRoboticMapper.selectBatchIds(roboticIdSet);
-        Map<Long, CompanyVoiceRobotic> roboticsMap = robotList.stream()
-                .collect(Collectors.toMap(CompanyVoiceRobotic::getId, Function.identity(), (a, b) -> a));
-        
-        List<CompanyVoiceRoboticCallees> calleesList = companyVoiceRoboticCalleesMapper
-                .selectCalleesListByRoboticIdsAndUserIds(userIdSet, roboticIdSet);
-        Map<String, CompanyVoiceRoboticCallees> calleesMap = calleesList.stream()
-                .collect(Collectors.toMap(e -> e.getUserId() + "-" + e.getRoboticId(), Function.identity(), (a, b) -> a));
-        
-        // 设置延时任务
-        setupDelayTasks(successClients, roboticsMap, calleesMap);
-        
-        // 更新任务流程状态
-        updateTaskFlows(calleesList, roboticIdSet);
+        if(!successClients.isEmpty()){
+            successClients.forEach(client -> {
+                triggerWorkflowOnAddWxSuccess(client.getId());
+            });
+        }
     }
     }
-    
+
+
     /**
     /**
-     * 设置延时任务
+     * 加微结果触发工作流继续执行
+     * @param wxClientId 加微客户ID
      */
      */
-    private void setupDelayTasks(List<CompanyWxClient> upClientList, 
-                               Map<Long, CompanyVoiceRobotic> roboticsMap,
-                               Map<String, CompanyVoiceRoboticCallees> calleesMap) {
-        upClientList.forEach(client -> {
-            CompanyVoiceRobotic robotic = roboticsMap.get(client.getRoboticId());
-            if (robotic == null) {
-                log.error("ROBOTIC-ID:{},CLIENT-ID:{},没有找到任务", client.getRoboticId(), client.getId());
+    private void triggerWorkflowOnAddWxSuccess(Long wxClientId) {
+        try {
+            // 查找等待中的加微工作流实例
+            CompanyAiWorkflowExec waitingExec = companyAiWorkflowExecMapper.selectWaitingAddWxWorkflowByWxClientId(
+                    wxClientId,
+                    ExecutionStatusEnum.WAITING.getValue(),
+                    NodeTypeEnum.AI_QW_ADD_WX_TASK.getValue());
+            if (waitingExec == null) {
+                log.info("未找到等待中的加微工作流实例 - wxClientId: {}", wxClientId);
                 return;
                 return;
             }
             }
-            
-            CompanyVoiceRoboticCallees callee = calleesMap.get(client.getCustomerId() + "-" + client.getRoboticId());
-            if (callee == null) {
-                log.error("ROBOTIC-ID:{},CLIENT-ID:{},没有找到任务", client.getRoboticId(), client.getId());
+            //查询工作流加微执行日志是否未更新状态
+            CompanyAiWorkflowExecLog queryP = new CompanyAiWorkflowExecLog();
+            queryP.setWorkflowInstanceId(waitingExec.getWorkflowInstanceId());
+            queryP.setNodeType(NodeTypeEnum.AI_QW_ADD_WX_TASK.getValue());
+            queryP.setStatus(ExecutionStatusEnum.WAITING.getValue());
+            List<CompanyAiWorkflowExecLog> companyAiWorkflowExecLogs = companyAiWorkflowExecLogMapper.selectCompanyAiWorkflowExecLogList(queryP);
+            companyAiWorkflowExecLogs.forEach(log -> {
+                        log.setStatus(ExecutionStatusEnum.SUCCESS.getValue());
+                        companyAiWorkflowExecLogMapper.updateById(log);
+                    }
+            );
+
+            String workflowInstanceId = waitingExec.getWorkflowInstanceId();
+            String currentNodeKey = waitingExec.getCurrentNodeKey();
+
+            log.info("加微成功回调,尝试触发工作流继续执行 - workflowInstanceId: {}, nodeKey: {}, wxClientId: {}",
+                    workflowInstanceId, currentNodeKey, wxClientId);
+
+            // 互斥检查:如果已经被执行过(超时路径或其他回调),则不再执行
+            if (!AiQwAddWxTaskNode.tryMarkAsExecuted(workflowInstanceId, wxClientId)) {
+                log.info("企微申请加微结果查询任务工作流已被其他路径执行,跳过 - workflowInstanceId: {}, wxClientId: {}",
+                        workflowInstanceId, wxClientId);
                 return;
                 return;
             }
             }
-            
-            Integer addWxTime = robotic.getAddWxTime();
-            if (addWxTime != null) {
-                long endTime = System.currentTimeMillis() + addWxTime * 60 * 1000;
-                String key = Constants.CID_NEXT_TASK_ID + callee.getRoboticId() + ":" + callee.getId();
-                redisCache.setCacheObject(key, String.valueOf(endTime));
-            } else {
-                log.error("ROBOTIC-ID:{},CLIENT-ID:{},没有设置加微后置等待时间", client.getRoboticId(), client.getId());
-            }
-        });
-    }
-    
-    /**
-     * 更新任务流程状态
-     */
-    private void updateTaskFlows(List<CompanyVoiceRoboticCallees> calleesList, Set<Long> roboticIdSet) {
-        calleesList.forEach(callee -> 
-            callee.setRunTaskFlow(
-                StringUtils.isBlank(callee.getRunTaskFlow()) ?
-                    Constants.QW_ADD_WX : callee.getRunTaskFlow() + "," + Constants.QW_ADD_WX
-            )
-        );
-        
-        companyVoiceRoboticCalleesServiceImpl.updateBatchById(calleesList);
-        companyVoiceRoboticServiceImpl.finishAddWxByCallees(roboticIdSet);
-    }
 
 
+            // 清除超时检测Key(回调成功了,不需要超时检测了)
+            AiQwAddWxTaskNode.clearTimeoutKey(workflowInstanceId, wxClientId);
+
+            // 触发工作流继续执行
+            Map<String, Object> inputData = new HashMap<>();
+            inputData.put("addWxSuccess", true);
+            inputData.put("wxClientId", wxClientId);
+            inputData.put("triggerType", "callback"); // 回调触发
+
+            companyWorkflowEngine.resumeFromBlockingNode(workflowInstanceId, currentNodeKey, inputData);
+
+            log.info("企微申请加微结果查询任务加微成功回调触发工作流继续执行完成 - workflowInstanceId: {}, wxClientId: {}",
+                    workflowInstanceId, wxClientId);
+
+        } catch (Exception ex) {
+            log.error("企微申请加微结果查询任务加微成功回调触发工作流异常 - wxClientId: {}", wxClientId, ex);
+        }
+    }
 }
 }

+ 8 - 2
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.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
-import java.util.Collections;
-
 /**
 /**
  * 企业微信SOP定时任务管理类
  * 企业微信SOP定时任务管理类
  * 负责处理各种定时任务,包括SOP规则检查、消息发送、数据清理等
  * 负责处理各种定时任务,包括SOP规则检查、消息发送、数据清理等
@@ -78,4 +76,12 @@ public class WxTask {
     public void qwAddWxResult() {
     public void qwAddWxResult() {
         taskService.qwAddWxResult(null);
         taskService.qwAddWxResult(null);
     }
     }
+    /**
+     * 企微加微工作流超时检测
+     * 每分钟执行一次,检查是否有加微超时的工作流需要继续执行
+     */
+    @Scheduled(cron = "0 0/1 * * * ?")
+    public void cidWorkflowQwAddWxRun(){
+        taskService.cidWorkflowQwAddWxRun();
+    }
 }
 }