|
|
@@ -1,17 +1,19 @@
|
|
|
package com.fs.company.service.impl.call.node;
|
|
|
|
|
|
-import com.fs.company.domain.CompanyAiWorkflowExec;
|
|
|
-import com.fs.company.domain.CompanyWorkflowEdge;
|
|
|
-import com.fs.company.domain.CompanyWorkflowNode;
|
|
|
-import com.fs.company.mapper.CompanyAiWorkflowExecLogMapper;
|
|
|
-import com.fs.company.mapper.CompanyAiWorkflowExecMapper;
|
|
|
-import com.fs.company.mapper.CompanyWorkflowEdgeMapper;
|
|
|
-import com.fs.company.mapper.CompanyWorkflowNodeMapper;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.fs.company.domain.*;
|
|
|
+import com.fs.company.mapper.*;
|
|
|
import com.fs.company.param.ExecutionContext;
|
|
|
import com.fs.company.service.*;
|
|
|
+import com.fs.company.service.nodeInterface.*;
|
|
|
import com.fs.company.vo.ExecutionResult;
|
|
|
+import com.fs.enums.ExecutionStatusEnum;
|
|
|
+import com.fs.enums.NodeTypeEnum;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import net.bytebuddy.description.modifier.EnumerationState;
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
|
|
@@ -20,12 +22,17 @@ import java.util.*;
|
|
|
* @description 工作节点基类
|
|
|
*/
|
|
|
@Slf4j
|
|
|
-public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapper, IWorkflowNode, HasCompanyAiWorkflowExecMapper, HasCompanyWorkflowEdgeMapper, HasCompanyAiWorkflowExecLogMapper {
|
|
|
+//@SuppressWarnings("all")
|
|
|
+public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapper, IWorkflowNode,
|
|
|
+ HasCompanyAiWorkflowExecMapper, HasCompanyWorkflowEdgeMapper, HasCompanyAiWorkflowExecLogMapper, HasCompanyVoiceRoboticBusinessMapper,
|
|
|
+ HasObjectMapper {
|
|
|
|
|
|
CompanyAiWorkflowExecMapper workflowExecMapper;
|
|
|
CompanyWorkflowEdgeMapper companyWorkflowEdgeMapper;
|
|
|
CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper;
|
|
|
CompanyWorkflowNodeMapper companyWorkflowNodeMapper;
|
|
|
+ CompanyVoiceRoboticBusinessMapper companyVoiceRoboticBusinessMapper;
|
|
|
+ ObjectMapper objectMapper;
|
|
|
|
|
|
@Override
|
|
|
public void setCompanyWorkflowNodeMapper(CompanyWorkflowNodeMapper mapper) {
|
|
|
@@ -44,6 +51,14 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
public void setCompanyAiWorkflowExecLogMapper(CompanyAiWorkflowExecLogMapper companyAiWorkflowExecLogMapper) {
|
|
|
this.companyAiWorkflowExecLogMapper = companyAiWorkflowExecLogMapper;
|
|
|
}
|
|
|
+ @Override
|
|
|
+ public void setCompanyVoiceRoboticBusinessMapper(CompanyVoiceRoboticBusinessMapper companyVoiceRoboticBusinessMapper){
|
|
|
+ this.companyVoiceRoboticBusinessMapper = companyVoiceRoboticBusinessMapper;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void setObjectMapper(ObjectMapper objectMapper){
|
|
|
+ this.objectMapper = objectMapper;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
protected String nodeKey;
|
|
|
@@ -60,13 +75,13 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
public ExecutionResult execute(ExecutionContext context) {
|
|
|
// 记录执行开始时间
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
-
|
|
|
+ ExecutionResult result = null;
|
|
|
try {
|
|
|
// 执行前的通用处理
|
|
|
preExecute(context);
|
|
|
|
|
|
// 执行具体的业务逻辑
|
|
|
- ExecutionResult result = doExecute(context);
|
|
|
+ result = doExecute(context);
|
|
|
|
|
|
// 记录执行时间
|
|
|
long executionTime = System.currentTimeMillis() - startTime;
|
|
|
@@ -76,13 +91,24 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
} catch (Exception e) {
|
|
|
return handleExecutionError(e, context);
|
|
|
} finally {
|
|
|
- postExecute(context);
|
|
|
+ postExecute(context,result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public ExecutionResult continueExecute(ExecutionContext context){
|
|
|
+ try{
|
|
|
+ CompanyAiWorkflowExec companyAiWorkflowExec = workflowExecMapper.selectByWorkflowInstanceId(context.getWorkflowInstanceId());
|
|
|
+ if(!Integer.valueOf(ExecutionStatusEnum.WAITING.getValue()).equals(companyAiWorkflowExec.getStatus())){
|
|
|
+ return handleExecutionError( new Exception("状态不符合"), context);
|
|
|
+ }
|
|
|
+ return doContinue(context);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return handleExecutionError(e, context);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 子类必须实现的具体执行逻辑
|
|
|
- */
|
|
|
+ protected abstract ExecutionResult doContinue(ExecutionContext context);
|
|
|
+
|
|
|
protected abstract ExecutionResult doExecute(ExecutionContext context);
|
|
|
|
|
|
/**
|
|
|
@@ -96,11 +122,16 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
/**
|
|
|
* 执行后的后处理
|
|
|
*/
|
|
|
- protected void postExecute(ExecutionContext context) {
|
|
|
+ protected void postExecute(ExecutionContext context,ExecutionResult result) {
|
|
|
long endTime = System.currentTimeMillis();
|
|
|
context.setVariable("node_end_time_" + nodeKey, endTime);
|
|
|
log.info("Completed execution of node: {} ({})", nodeKey, nodeName);
|
|
|
- //todo 写入执行日志
|
|
|
+ //todo 写入执行日志等后置操作
|
|
|
+ if (result.isSuccess()) {
|
|
|
+
|
|
|
+ } else {
|
|
|
+ updateWorkflowStatus(context.getWorkflowInstanceId(), ExecutionStatusEnum.FAILURE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -134,8 +165,14 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
|
|
|
List<CompanyWorkflowEdge> companyWorkflowEdges =
|
|
|
companyWorkflowEdgeMapper.selectListByWorkflowIdAndNodeKey(companyAiWorkflowExec.getWorkflowId(), nodeKey);
|
|
|
-
|
|
|
//todo 判定条件满足
|
|
|
+ if(null != companyWorkflowEdges && !companyWorkflowEdges.isEmpty()){
|
|
|
+ if(companyWorkflowEdges.size() > 1){
|
|
|
+
|
|
|
+ } else {
|
|
|
+ return companyWorkflowEdges.get(0).getTargetNodeKey();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return companyWorkflowEdges.get(new Random().nextInt(companyWorkflowEdges.size())).getTargetNodeKey();
|
|
|
}
|
|
|
@@ -152,4 +189,95 @@ public abstract class AbstractWorkflowNode implements HasCompanyWorkflowNodeMapp
|
|
|
return companyWorkflowNode;
|
|
|
}
|
|
|
|
|
|
+ public CompanyVoiceRoboticBusiness getRoboticBusiness(String workflowInstanceId){
|
|
|
+ CompanyVoiceRoboticBusiness companyVoiceRoboticBusiness = companyVoiceRoboticBusinessMapper.selectCompanyVoiceRoboticBusinessByWorkflowInstanceId(workflowInstanceId);
|
|
|
+ return companyVoiceRoboticBusiness;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录日志
|
|
|
+ * @param logEntry
|
|
|
+ */
|
|
|
+ public void logExecution(CompanyAiWorkflowExecLog logEntry) {
|
|
|
+ try {
|
|
|
+ CompanyAiWorkflowExecLog logRecord = new CompanyAiWorkflowExecLog();
|
|
|
+ logRecord.setWorkflowInstanceId(logEntry.getWorkflowInstanceId());
|
|
|
+ logRecord.setNodeId(logEntry.getNodeId());
|
|
|
+ logRecord.setNodeType(logEntry.getNodeType());
|
|
|
+ logRecord.setStatus(logEntry.getStatus());
|
|
|
+ logRecord.setInputData(objectMapper.writeValueAsString(logEntry.getInputData()));
|
|
|
+ logRecord.setOutputData(objectMapper.writeValueAsString(logEntry.getOutputData()));
|
|
|
+ logRecord.setStartTime(logEntry.getStartTime());
|
|
|
+ logRecord.setEndTime(logEntry.getEndTime());
|
|
|
+ logRecord.setErrorMessage(logEntry.getErrorMessage());
|
|
|
+ logRecord.setDuration(logEntry.getDuration());
|
|
|
+ companyAiWorkflowExecLogMapper.insert(logRecord);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("记录执行日志失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建执行日志
|
|
|
+ * @param workflowInstanceId
|
|
|
+ * @param nodeKey
|
|
|
+ * @param nodeType
|
|
|
+ * @param result
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public CompanyAiWorkflowExecLog createLogEntry(String workflowInstanceId, String nodeKey,
|
|
|
+ NodeTypeEnum nodeType, ExecutionResult result) {
|
|
|
+ try {
|
|
|
+ CompanyAiWorkflowExecLog logEntry = new CompanyAiWorkflowExecLog();
|
|
|
+ logEntry.setWorkflowInstanceId(workflowInstanceId);
|
|
|
+ logEntry.setNodeKey(nodeKey);
|
|
|
+ logEntry.setNodeType(nodeType.getValue());
|
|
|
+ logEntry.setStatus(result.getStatus().getValue());
|
|
|
+
|
|
|
+ logEntry.setOutputData(objectMapper.writeValueAsString(result.getOutputData()));
|
|
|
+ logEntry.setErrorMessage(result.getErrorMessage());
|
|
|
+ logEntry.setStartTime(new Date());
|
|
|
+ logEntry.setEndTime(new Date());
|
|
|
+ logEntry.setDuration(0L); // 可以根据实际情况计算持续时间
|
|
|
+
|
|
|
+ return logEntry;
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 阻塞工作流
|
|
|
+ * @param workflowInstanceId
|
|
|
+ * @param nodeKey
|
|
|
+ * @param context
|
|
|
+ */
|
|
|
+ public void pauseWorkflowForBlockingNode(String workflowInstanceId, String nodeKey, ExecutionContext context) {
|
|
|
+ try {
|
|
|
+ CompanyAiWorkflowExec update = new CompanyAiWorkflowExec();
|
|
|
+ update.setWorkflowInstanceId(workflowInstanceId);
|
|
|
+ update.setStatus(ExecutionStatusEnum.WAITING.getValue());
|
|
|
+ update.setLastUpdateTime(LocalDateTime.now());
|
|
|
+ update.setVariables(objectMapper.writeValueAsString(context.getVariables()));
|
|
|
+ workflowExecMapper.updateByWorkflowInstanceId(update);
|
|
|
+ log.info("工作流已阻塞在节点: {} -> {}", workflowInstanceId, nodeKey);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新工作流阻塞状态失败: {}", workflowInstanceId, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新工作流状态
|
|
|
+ * @param workflowInstanceId
|
|
|
+ * @param status
|
|
|
+ */
|
|
|
+ public void updateWorkflowStatus(String workflowInstanceId, ExecutionStatusEnum status) {
|
|
|
+ CompanyAiWorkflowExec update = new CompanyAiWorkflowExec();
|
|
|
+ update.setWorkflowInstanceId(workflowInstanceId);
|
|
|
+ update.setStatus(status.getValue());
|
|
|
+ update.setLastUpdateTime(LocalDateTime.now());
|
|
|
+ workflowExecMapper.updateByWorkflowInstanceId(update);
|
|
|
+ }
|
|
|
+
|
|
|
}
|