lmx hace 3 semanas
padre
commit
5c600830a1

+ 2 - 4
fs-service/src/main/java/com/fs/company/mapper/CompanyVoiceRoboticBusinessMapper.java

@@ -4,9 +4,7 @@ import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.company.domain.CompanyVoiceRoboticBusiness;
 import com.fs.company.domain.CompanyVoiceRoboticCallees;
-import io.lettuce.core.dynamic.annotation.Param;
-
-import javax.validation.constraints.NotNull;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * ai外呼业务Mapper接口
@@ -78,7 +76,7 @@ public interface CompanyVoiceRoboticBusinessMapper extends BaseMapper<CompanyVoi
      * @param wxClientId
      * @return
      */
-    int updateActionCount(@Param("actionType")@NotNull Integer actionType,
+    int updateActionCount(@Param("actionType") Integer actionType,
                           @Param("roboticId") Long roboticId,
                           @Param("callerId") Long callerId,
                           @Param("wxClientId") Long wxClientId);

+ 20 - 13
fs-service/src/main/java/com/fs/company/service/impl/CompanyVoiceRoboticServiceImpl.java

@@ -12,6 +12,7 @@ import com.fs.aicall.domain.result.CalltaskcreateaiCustomizeResult;
 import com.fs.aicall.service.AiCallService;
 import com.fs.common.annotation.DataScope;
 import com.fs.common.constant.Constants;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.redis.RedisCacheT;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.service.impl.SmsServiceImpl;
@@ -96,7 +97,7 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
     private final CompanyWorkflowEngine companyWorkflowEngine;
     private final CompanyAiWorkflowExecMapper companyAiWorkflowExecMapper;
     private final CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
-
+    private final RedisCache redisCache2;
     @Autowired
     @Qualifier("cidWorkFlowExecutor")
     private Executor cidWorkFlowExecutor;
@@ -309,11 +310,12 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
 
     }
 
+    private final String WORKFLOW_CALL_ONE_REDIS_KEY = "workflowCallOne:uuid:";
     /**
-     * 流程Ai呼叫 callOne
+     *  流程Ai呼叫 callOne
      * @param roboticId
      * @param callerId
-     * @param workflowInstanceId
+     * @param context
      * @param callConfigVo
      * @return
      */
@@ -322,7 +324,14 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
         try {
             CompanyVoiceRobotic robotic = companyVoiceRoboticMapper.selectById(roboticId);
             CompanyVoiceRoboticCallees callees = companyVoiceRoboticCalleesMapper.selectById(callerId);
-            CalleeDomain build = CalleeDomain.builder().number(callees.getPhone()).userData(callees.getId().toString()).build();
+            String callBackUuid = UUID.randomUUID().toString();
+            JSONObject userDataJson=new JSONObject();
+            userDataJson.put("callBackUuid",callBackUuid);
+            userDataJson.put("nodeKey",context.getCurrentNodeKey());
+            userDataJson.put("workflowInstanceId",context.getWorkflowInstanceId());
+            userDataJson.put("callerId",callerId);
+            redisCache2.setCacheObject(WORKFLOW_CALL_ONE_REDIS_KEY + callBackUuid, userDataJson.toJSONString());
+            CalleeDomain build = CalleeDomain.builder().number(callees.getPhone()).userData(callBackUuid).build();
             List<CalleeDomain> mobileList = new ArrayList<>();
             mobileList.add(build);
             // 构建三方接口请求数据
@@ -335,6 +344,7 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
             param.setMultiplier(callConfigVo.getMultiplier());
             param.setAutoRecall(callConfigVo.getAutoRecall());
             param.setRecallTimes(callConfigVo.getRecallTimes());
+            param.setCIDGroupID(callConfigVo.getCidGroupId());
             if (StringUtils.isNotEmpty(robotic.getWeekDay1())) {
                 param.setWeekday1(Arrays.asList(robotic.getWeekDay1().split(",")));
             }
@@ -344,12 +354,6 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
             if (StringUtils.isNotEmpty(robotic.getEndTime1())) {
                 param.setEndTime1(robotic.getEndTime1() + ":00");
             }
-            String callBackUuid = UUID.randomUUID().toString();
-            JSONObject userDataJson=new JSONObject();
-            userDataJson.put("callBackUuid",callBackUuid);
-            userDataJson.put("nodeKey",context.getCurrentNodeKey());
-            userDataJson.put("workflowInstanceId",context.getWorkflowInstanceId());
-            param.setUserData(userDataJson.toJSONString());
             JSONObject runParam = (JSONObject) JSON.toJSON(param);
             runParam.put("companyId", robotic.getCompanyId());
             CompanyVoiceRoboticCallLogCallphone addLog = CompanyVoiceRoboticCallLogCallphone.initCallLog(
@@ -636,14 +640,15 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
         //更新调用日志
         companyVoiceRoboticCallLogCallphoneService.asyncHandleCalleeCallBackResult(result,callee);
         if(StringUtils.isNotBlank(notify.getUserData())){
-            JSONObject userData = JSONObject.parseObject(notify.getUserData());
-            if(userData.containsKey("callBackUuid") && userData.containsKey("workflowInstanceId") && userData.containsKey("nodeKey")){
+            JSONObject userData = JSONObject.parseObject(redisCache2.getCacheObject(WORKFLOW_CALL_ONE_REDIS_KEY + notify.getUserData()),JSONObject.class) ;
+            if(null!= userData && userData.containsKey("callBackUuid") && userData.containsKey("workflowInstanceId") && userData.containsKey("nodeKey")){
                 Map<String, Object> param = new HashMap<>();
                 param.put("callBackUuid",userData.getString("callBackUuid"));
                 CompletableFuture.runAsync(()->{
                     companyWorkflowEngine.resumeFromBlockingNode(userData.getString("workflowInstanceId"),userData.getString("nodeKey"),param);
                 },cidWorkFlowExecutor);
             }
+            redisCache2.deleteObject(notify.getUserData());
         }
         long count = companyVoiceRoboticCalleesMapper.countByRoboticIdNotUuid(callee.getRoboticId());
         if(count == 0){
@@ -705,7 +710,9 @@ public class CompanyVoiceRoboticServiceImpl extends ServiceImpl<CompanyVoiceRobo
         companyVoiceRoboticCalleesMapper.updateById(callee);
     }
     public CompanyVoiceRoboticCallees getResultCalleeInfo(Notify notify){
-        CompanyVoiceRoboticCallees callee = companyVoiceRoboticCalleesMapper.selectCompanyVoiceRoboticCalleesById(Long.parseLong(notify.getUserData()));
+        String cacheString = (String) redisCache2.getCacheObject(WORKFLOW_CALL_ONE_REDIS_KEY + notify.getUserData());
+        JSONObject parse = JSONObject.parseObject(cacheString,JSONObject.class);
+        CompanyVoiceRoboticCallees callee = companyVoiceRoboticCalleesMapper.selectCompanyVoiceRoboticCalleesById(parse.getLong("callerId"));
         if(callee == null){
             log.error("回调错误,未找到拨打手机号记录:{}", notify);
             throw new BaseException("回调错误");

+ 16 - 16
fs-service/src/main/java/com/fs/company/service/impl/CompanyWorkflowEngineImpl.java

@@ -123,22 +123,22 @@ public class CompanyWorkflowEngineImpl implements CompanyWorkflowEngine {
             ExecutionResult result = node.execute(context);
 
             // 处理执行结果
-            if (result.isSuccess()) {
-                // 检查是否是结束节点或无下一节点
-                if (StringUtils.isBlank(result.getNextNodeKey())) {
-                    // 结束工作流
-                    completeWorkflow(workflowInstanceId);
-                    log.info("工作流执行完成 - workflowInstanceId: {}", workflowInstanceId);
-                } else {
-                    // 继续执行下一个节点
-                    executeNode(workflowInstanceId, result.getNextNodeKey());
-                }
-            } else {
-                // 执行失败时更新状态
-                updateWorkflowStatus(workflowInstanceId, ExecutionStatusEnum.FAILURE);
-                log.error("节点执行失败 - workflowInstanceId: {}, nodeKey: {}, error: {}",
-                        workflowInstanceId, nodeKey, result.getErrorMessage());
-            }
+//            if (ExecutionStatusEnum.SUCCESS.equals(result.getStatus())) {
+//                // 检查是否是结束节点或无下一节点
+//                if (StringUtils.isBlank(result.getNextNodeKey())) {
+//                    // 结束工作流
+//                    completeWorkflow(workflowInstanceId);
+//                    log.info("工作流执行完成 - workflowInstanceId: {}", workflowInstanceId);
+//                } else {
+//                    // 继续执行下一个节点
+//                    executeNode(workflowInstanceId, result.getNextNodeKey());
+//                }
+//            } else if(ExecutionStatusEnum.FAILURE.equals(result.getStatus())) {
+//                // 执行失败时更新状态
+//                updateWorkflowStatus(workflowInstanceId, ExecutionStatusEnum.FAILURE);
+//                log.error("节点执行失败 - workflowInstanceId: {}, nodeKey: {}, error: {}",
+//                        workflowInstanceId, nodeKey, result.getErrorMessage());
+//            }
         } catch (Exception e) {
             log.error("节点执行异常: {} -> {}", workflowInstanceId, nodeKey, e);
             updateWorkflowStatus(workflowInstanceId, ExecutionStatusEnum.FAILURE);

+ 9 - 19
fs-service/src/main/java/com/fs/company/service/impl/call/node/AbstractWorkflowNode.java

@@ -33,7 +33,7 @@ public abstract class AbstractWorkflowNode implements IWorkflowNode {
     public static final CompanyVoiceRoboticBusinessMapper companyVoiceRoboticBusinessMapper = SpringUtils.getBean(CompanyVoiceRoboticBusinessMapper.class);
     public static final CompanyVoiceRoboticCallLogCallphoneMapper companyVoiceRoboticCallLogCallphoneMapper = SpringUtils.getBean(CompanyVoiceRoboticCallLogCallphoneMapper.class);
     public static final RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
-
+    public static final WorkflowNodeFactory workflowNodeFactory = SpringUtils.getBean(WorkflowNodeFactory.class);
     public static final ObjectMapper objectMapper = new ObjectMapper();
 
     protected String nodeKey;
@@ -74,7 +74,7 @@ public abstract class AbstractWorkflowNode implements IWorkflowNode {
     public ExecutionResult continueExecute(ExecutionContext context) {
         try {
             CompanyAiWorkflowExec companyAiWorkflowExec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(context.getWorkflowInstanceId());
-            if (!Integer.valueOf(ExecutionStatusEnum.WAITING.getValue()).equals(companyAiWorkflowExec.getStatus())) {
+            if (!Integer.valueOf(ExecutionStatusEnum.PAUSED.getValue()).equals(companyAiWorkflowExec.getStatus())) {
                 return handleExecutionError(new CustomException("状态不符合"), context);
             }
             return doContinue(context);
@@ -119,12 +119,14 @@ public abstract class AbstractWorkflowNode implements IWorkflowNode {
         log.info("Completed execution of node: {} ({})", nodeKey, nodeName);
         //todo 写入执行日志等后置操作
         Integer logStatus = 0;
-        if (result.isSuccess()) {
+        if (ExecutionStatusEnum.SUCCESS.equals(result.getStatus()) ) {
             logStatus = ExecutionStatusEnum.SUCCESS.getValue();
             updateWorkflowStatus(context.getWorkflowInstanceId(), ExecutionStatusEnum.SUCCESS);
-        } else {
+        } else if(ExecutionStatusEnum.FAILURE.equals(result.getStatus())) {
             logStatus = ExecutionStatusEnum.FAILURE.getValue();
             updateWorkflowStatus(context.getWorkflowInstanceId(), ExecutionStatusEnum.FAILURE);
+        } else {
+            logStatus = result.getStatus().getValue();
         }
         CompanyAiWorkflowExecLog logEntry = createLogEntry(context.getWorkflowInstanceId(), nodeKey, getType(), result, context);
         logEntry.setStatus(logStatus);
@@ -158,21 +160,9 @@ public abstract class AbstractWorkflowNode implements IWorkflowNode {
      * @return
      */
     public String getNextNodeKey(String workflowInstanceId, String nodeKey) {
-
-        CompanyAiWorkflowExec companyAiWorkflowExec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(workflowInstanceId);
-
-        List<CompanyWorkflowEdge> companyWorkflowEdges =
-                companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(companyAiWorkflowExec.getWorkflowId(), nodeKey);
-        //todo 判定条件满足
-        if (null != companyWorkflowEdges && !companyWorkflowEdges.isEmpty()) {
-            if (companyWorkflowEdges.size() > 1) {
-                //存在多条件节点需重写此方法
-                return null;
-            } else {
-                return companyWorkflowEdges.get(0).getTargetNodeKey();
-            }
-        }
-        return companyWorkflowEdges.get(new Random().nextInt(companyWorkflowEdges.size())).getTargetNodeKey();
+        CompanyAiWorkflowExec exec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(workflowInstanceId);
+        List<CompanyWorkflowEdge> edges = companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(exec.getWorkflowId(), nodeKey);
+        return edges.get(0).getTargetNodeKey();
     }
 
     public Boolean edgeConditionValidate(String condition) {

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

@@ -8,6 +8,7 @@ import com.fs.company.domain.*;
 import com.fs.company.mapper.CompanyWorkflowNodeMapper;
 import com.fs.company.param.ExecutionContext;
 import com.fs.company.service.ICompanyVoiceRoboticService;
+import com.fs.company.service.IWorkflowNode;
 import com.fs.company.service.impl.CompanyVoiceRoboticServiceImpl;
 import com.fs.company.vo.AiCallConfigVO;
 import com.fs.company.vo.AiCallWorkflowConditionVo;
@@ -18,6 +19,7 @@ import com.fs.enums.NodeTypeEnum;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * @author MixLiu
@@ -44,22 +46,25 @@ public class AiCallTaskNode extends AbstractWorkflowNode {
         CompanyAiWorkflowExec exec = companyAiWorkflowExecMapper.selectByWorkflowInstanceId(context.getWorkflowInstanceId());
         List<CompanyWorkflowEdge> edges = companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(exec.getWorkflowId(), nodeKey);
         //获取外呼回调结果日志
-        CompanyVoiceRoboticCallLogCallphone callRes = super.companyVoiceRoboticCallLogCallphoneMapper.selectCallLogByCallbackUuid(context.getVariable("callbackUuid", String.class));
+        CompanyVoiceRoboticCallLogCallphone callRes = super.companyVoiceRoboticCallLogCallphoneMapper.selectCallLogByCallbackUuid(context.getVariable("callBackUuid", String.class));
         edges.forEach(edge -> {
-            AiCallWorkflowConditionVo condition = JSONObject.parseObject(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
+            List<AiCallWorkflowConditionVo> conditions = JSONObject.parseArray(edge.getConditionExpr(), AiCallWorkflowConditionVo.class);
+//            Boolean isValid = true;
+            //暂时考虑单条件
+            AiCallWorkflowConditionVo condition = conditions.get(0);
             //拨通
-            if (condition.isCallConnected() && callRes.getCallTime() > 0) {
+            if (condition.isCallConnected() && callRes.getCallTime()!=null && callRes.getCallTime() > 0) {
                 //如果含有意向度过滤
                 if(null != condition.getIntention()){
-                   if( condition.getIntention().equals(callRes.getIntention())){
-                       this.runNextNode(context,edge);
-                   }
+                    if( condition.getIntention().equals(callRes.getIntention())){
+                        this.runNextNode(context,edge);
+                    }
                 } else {
                     this.runNextNode(context,edge);
                 }
             }
             //未拨通
-            else if (!condition.isCallConnected() && (Long.valueOf(0).equals(callRes.getCallTime()) || callRes.getCallAnswerTime() == null)) {
+            else if (!condition.isCallConnected() && (callRes.getCallTime() == null || Long.valueOf(0).equals(callRes.getCallTime()) || callRes.getCallAnswerTime() == null)) {
                 //延时操作
                 if (null != condition.getCallTime()) {
                     //计算延时分片分钟
@@ -73,6 +78,7 @@ public class AiCallTaskNode extends AbstractWorkflowNode {
                     this.runNextNode(context,edge);
                 }
             }
+
         });
         return null;
     }
@@ -140,6 +146,8 @@ public class AiCallTaskNode extends AbstractWorkflowNode {
         ExecutionContext nextContext = context.clone();
         nextContext.setCurrentNodeKey(edge.getTargetNodeKey());
         super.execPointNextNode(nextContext);
-        super.execute(nextContext);
+        CompanyWorkflowNode nextNode = companyWorkflowNodeMapper.selectNodeByNodeKey(edge.getTargetNodeKey());
+        IWorkflowNode node = super.workflowNodeFactory.createNode(nextNode.getNodeKey(), NodeTypeEnum.fromCode(nextNode.getNodeType()), nextNode.getNodeName(), null);
+        node.execute(nextContext);
     }
 }

+ 27 - 0
fs-service/src/main/java/com/fs/company/service/impl/call/node/StartNode.java

@@ -1,11 +1,15 @@
 package com.fs.company.service.impl.call.node;
 
 import com.fs.company.domain.CompanyAiWorkflowExec;
+import com.fs.company.domain.CompanyAiWorkflowExecLog;
 import com.fs.company.domain.CompanyWorkflowEdge;
 import com.fs.common.utils.spring.SpringUtils;
+import com.fs.company.domain.CompanyWorkflowNode;
 import com.fs.company.mapper.CompanyWorkflowNodeMapper;
 import com.fs.company.param.ExecutionContext;
+import com.fs.company.service.IWorkflowNode;
 import com.fs.company.vo.ExecutionResult;
+import com.fs.enums.ExecutionStatusEnum;
 import com.fs.enums.NodeTypeEnum;
 
 import java.util.List;
@@ -45,4 +49,27 @@ public class StartNode extends AbstractWorkflowNode {
     public Boolean isAsync() {
         return false;
     }
+
+    /**
+     * 执行后的后处理
+     */
+    @Override
+    protected void postExecute(ExecutionContext context, ExecutionResult result) {
+        super.postExecute(context, result);
+        runNextNode(context,result);
+    }
+
+    /**
+     * 运行下一个节点
+     * @param context
+     * @param res
+     */
+    private void runNextNode(ExecutionContext context, ExecutionResult res){
+        ExecutionContext nextContext = context.clone();
+        nextContext.setCurrentNodeKey(res.getNextNodeKey());
+        CompanyWorkflowNode nextNode = companyWorkflowNodeMapper.selectNodeByNodeKey(res.getNextNodeKey());
+        IWorkflowNode node = super.workflowNodeFactory.createNode(nextNode.getNodeKey(), NodeTypeEnum.fromCode(nextNode.getNodeType()), nextNode.getNodeName(), null);
+        super.execPointNextNode(nextContext);
+        node.execute(nextContext);
+    }
 }

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

@@ -119,7 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where
             robotic_id = #{roboticId}
         <if test="callerId != null">
-            and caller_id = #{callerId}
+            and callee_id = #{callerId}
         </if>
 
         <if test="wxClientId != null">