/**
* 获取当前任务节点的下一个任务节点
*
* @param task 当前任务节点
* @return 下个任务节点
* @throws Exception
*/
public FlowElement getNextUserFlowElement(Task task) throws Exception {
// 取得已提交的任务
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
.taskId(task.getId()).singleResult();
// 获得流程定义
ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicTaskInstance.getProcessDefinitionId());
//获得当前流程的活动ID
ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
Execution execution = executionQuery.executionId(historicTaskInstance.getExecutionId()).singleResult();
String activityId = execution.getActivityId();
UserTask userTask = null;
while (true) {
//根据活动节点获取当前的组件信息
FlowNode flowNode = getFlowNode(processDefinition.getId(), activityId);
//获取该节点之后的流向
List sequenceFlowListOutGoing = flowNode.getOutgoingFlows();
// 获取的下个节点不一定是userTask的任务节点,所以要判断是否是任务节点
if (sequenceFlowListOutGoing.size() > 1) {
// 如果有1条以上的出线,表示有分支,需要判断分支的条件才能知道走哪个分支
// 遍历节点的出线得到下个activityId
activityId = getNextActivityId(execution.getId(),task.getProcessInstanceId(), sequenceFlowListOutGoing);
} else if (sequenceFlowListOutGoing.size() == 1) {
// 只有1条出线,直接取得下个节点
SequenceFlow sequenceFlow = sequenceFlowListOutGoing.get(0);
// 下个节点
FlowElement flowElement = sequenceFlow.getTargetFlowElement();
if (flowElement instanceof UserTask) {
// 下个节点为UserTask时
userTask = (UserTask) flowElement;
//System.out.println("下个任务为:" + userTask.getName());
return userTask;
} else if (flowElement instanceof ExclusiveGateway) {
// 下个节点为排它网关时
ExclusiveGateway exclusiveGateway = (ExclusiveGateway) flowElement;
List outgoingFlows = exclusiveGateway.getOutgoingFlows();
// 遍历网关的出线得到下个activityId
activityId = getNextActivityId(execution.getId(), task.getProcessInstanceId(), outgoingFlows);
//找到出口的节点
flowNode = getFlowNode(processDefinition.getId(), activityId);
//找不到符合条件的节点,就返回null
if(flowNode==null) {
return null;
}
//如果出口处就是一个UserTask,就返回它
if (flowNode instanceof UserTask) {
userTask = (UserTask) flowNode;
return userTask;
}
//如果出口处是结束节点,则返回空
if(flowNode instanceof EndEvent){
return null;
}
}else{
return null;
}
} else {
// 没有出线,则表明是结束节点
return null;
}
}
}
/**
* 根据el表达式取得满足条件的下一个activityId
* @param executionId
* @param processInstanceId
* @param outgoingFlows
* @return
*/
public String getNextActivityId(String executionId,String processInstanceId,List outgoingFlows) {
String activityId = null;
// 遍历出线
for (SequenceFlow outgoingFlow : outgoingFlows) {
// 取得线上的条件
String conditionExpression = outgoingFlow.getConditionExpression();
// 取得所有变量
Map variables = runtimeService.getVariables(executionId);
String variableName = "";
// 判断网关条件里是否包含变量名
for (String s : variables.keySet()) {
if (conditionExpression.contains(s)) {
// 找到网关条件里的变量名
variableName = s;
}
}
String conditionVal = getVariableValue(variableName, processInstanceId);
// 判断el表达式是否成立
if (isCondition(variableName, conditionExpression, conditionVal)) {
// 取得目标节点
FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
activityId = targetFlowElement.getId();
continue;
}
}
return activityId;
}
/**
* 取得流程变量的值
*
* @param variableName 变量名
* @param processInstanceId 流程实例Id
* @return
*/
public String getVariableValue(String variableName, String processInstanceId) {
Execution execution = runtimeService
.createExecutionQuery().processInstanceId(processInstanceId).list().get(0);
Object object = runtimeService.getVariable(execution.getId(), variableName);
return object == null ? "" : object.toString();
}
/**
* 根据活动节点和流程定义ID获取该活动节点的组件信息
*/
public FlowNode getFlowNode(String processDefinitionId, String flowElementId) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(flowElementId);
return flowNode;
}
/**
* 根据key和value判断el表达式是否通过
*
* @param key el表达式key
* @param el el表达式
* @param value el表达式传入值
* @return
*/
public boolean isCondition(String key, String el, String value) {
ExpressionFactory factory = new ExpressionFactoryImpl();
SimpleContext context = new SimpleContext();
context.setVariable(key, factory.createValueExpression(value, String.class));
ValueExpression e = factory.createValueExpression(context, el, boolean.class);
return (Boolean) e.getValue(context);
}