在实际业务使用过程中,存在需要当前审批人指定或可修改下一审批节点的审批人(单个或多个),这时候就先要获取到下一审批节点,然后在提交时给引擎传递相应的变量,达到用户指定下一节点审批人的目标。
模型定义文件:
Flow_1lqot0o
Flow_18thiqs
Flow_1lqot0o
Flow_0yuchf0
Flow_11k93to
Flow_0qdzfen
${nrOfCompletedInstances==1}
Flow_0qdzfen
Flow_1xbjwul
Flow_0yuchf0
Flow_11k93to
Flow_0njpgjv
${amount >= 1000}
Flow_0uawe9o
Flow_1xbjwul
Flow_18thiqs
Flow_0njpgjv
Flow_0uawe9o
发起流程:
@Test
public void startProcess() {
try {
ProcessRequest processRequest = new ProcessRequest();
processRequest.setProcessDefKey("Process_1fh6max");
processRequest.setStarter("bx1");
AuthenticationService authenticationService = new AuthenticationService();
String engineName = processEngine.getName();
UserAuthentication authentication = (UserAuthentication) authenticationService
.createAuthenticate(engineName, "bx1", null, null);
logger.info("authentication--------->" + authentication.getName());
// Authentications.clearCurrent();
identityService.setAuthenticatedUserId(authentication.getName());
String processInstanceId = null;
List resultList = new ArrayList();
Map variables = new HashMap();
List assigneeList = new ArrayList<>();
assigneeList.add("bx2");
assigneeList.add("bx3");
variables.put("assigneeList", assigneeList);
//variables.put("starter", processRequest.getStarter());
variables.put("amount", 1100);
ProcessInstance processInstance = null;
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(processRequest.getProcessDefKey()).latestVersion().singleResult();
if (pd == null) {
throw new Exception("流程模型:" + processRequest.getProcessDefKey() + "不存在!");
}
if (pd != null && pd.isSuspended()) {
throw new Exception("流程模型:" + processRequest.getProcessDefKey() + "已挂起,暂无法发起流程!");
}
// 流程初始化
if (StringUtils.isNotBlank(processRequest.getProcessDefKey())) {
processInstance = runtimeService.startProcessInstanceByKey(processRequest.getProcessDefKey(),
variables);
} else {
processInstance = runtimeService.startProcessInstanceById(processRequest.getProcessDefId(), variables);
}
// 创建成功
if (processInstance != null && StringUtils.isNotBlank(processInstance.getId())) {
processInstanceId = processInstance.getId();
List taskList = simpleGetTasks(processInstanceId);
logger.info(JSON.toJSONString(taskList));
// if (taskList != null && taskList.size() == 1) {
// taskService.complete(taskList.get(0).getId(), variables);
// taskService.createComment(taskList.get(0).getId(), processInstanceId, "提交流程");
// resultList = simpleGetTasks(processInstanceId);
// } else {
// throw new Exception("获取提交任务失败:" + taskList.size());
// }
} else {
throw new Exception("创建流程实例失败:");
}
System.out.println(JSON.toJSONString(resultList));
} catch (Exception e) {
e.printStackTrace();
}
}
执行预取:
@Test
public void simulationNextPath() {
String userId = "bx1";
String processInstanceId = "5e46947a-8cd1-11ec-b7ab-8c1645647a47";
AuthenticationService authenticationService = new AuthenticationService();
String engineName = processEngine.getName();
UserAuthentication authentication = (UserAuthentication) authenticationService.createAuthenticate(engineName,
userId, null, null);
logger.info("authentication--------->" + authentication.getName());
identityService.setAuthenticatedUserId(authentication.getName());
Map condition = runtimeService.getVariables(processInstanceId);
condition.put("amount", 500);
System.out.println("condition---->" + JSON.toJSONString(condition));
List tasks = null;
try {
tasks = getNextTaskInfos(processInstanceId, condition);
} catch (Exception e) {
e.printStackTrace();
}
logger.info("----------->" + JSON.toJSONString(tasks, SerializerFeature.DisableCircularReferenceDetect));
JSONArray ja = new JSONArray();
if (!CollectionUtils.isEmpty(tasks)) {
for (TaskDefinition task : tasks) {
JSONObject jo = new JSONObject();
jo.put("key", task.getKey());
jo.put("name", task.getNameExpression().getExpressionText());
jo.put("assignment",
task.getAssigneeExpression() == null ? "" : task.getAssigneeExpression().getExpressionText());
ja.add(jo);
}
}
System.out.println("----->" + ja.toString());
}
预取核心代码:
/**
* 获取下一个节点任务信息
*
* @param processInstanceId
* 流程实例ID
* @return 下一个节点信息
* @throws Exception
*/
public List getNextTaskInfos(String processInstanceId, Map condition)
throws Exception {
try {
ProcessDefinitionEntity processDefinitionEntity = null;
String id = null;
// List tasks =
// null;//会出现java.util.ConcurrentModificationException异常,改成CopyOnWriteArrayList
List tasks = new CopyOnWriteArrayList();
// 获取流程发布Id信息
String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult().getProcessDefinitionId();
processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(definitionId);
ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery()
.executionId(processInstanceId).singleResult();
// 当前流程节点Id信息
String activitiId = execution.getActivityId();
System.out.println("execution----->" + activitiId);
// 获取流程所有节点信息
List activitiList = processDefinitionEntity.getActivities();
JSONArray ja = new JSONArray();
// 遍历所有节点信息
for (ActivityImpl activityImpl : activitiList) {
id = activityImpl.getId();
System.out.println("id----------->" + id + "----->" + activityImpl.getProperty("type"));
if (activitiId.equals(id)) {
// 获取下一个节点信息
tasks = nextTaskDefinitions(activityImpl, activityImpl.getId(), processInstanceId, condition);
break;
}
}
return tasks;
} catch (Exception e) {
logger.error("operation error", e);
throw e;
}
}
private List nextTaskDefinitions(ActivityImpl activityImpl, String activityId,
String processInstanceId, Map condition) {
try {
PvmActivity ac = null;
Object s = null;
System.out.println("activityImpl.getActivityId()---->"+activityImpl.getActivityId()+"---activityId---------->"+activityId+"--->"+activityImpl.getProperty("type"));
// List taskDefinitions = new
// ArrayList();
// //会出现java.util.ConcurrentModificationException异常,改成CopyOnWriteArrayList
List taskDefinitions = new CopyOnWriteArrayList();
// 如果遍历节点为用户任务并且节点不是当前节点信息
if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
// 获取该节点下一个节点信息
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
.getTaskDefinition();
taskDefinitions.add(taskDefinition);
}else if (activityImpl.getProperty("type").toString().contains("EndEvent") && !activityId.equals(activityImpl.getId())) {
// 设置结束节点
TaskDefinition taskDefinition = new TaskDefinition(null);
ExpressionManager expressionManager = new ExpressionManager();
taskDefinition.setKey(activityImpl.getId() == null ? "end" : activityImpl.getId());
String name = activityImpl.getProperty("name") == null ? "结束" : activityImpl.getProperty("name").toString();
taskDefinition.setNameExpression(expressionManager.createExpression(name));
taskDefinitions.add(taskDefinition);
} else if ("multiInstanceBody".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
// 获取该节点下一个节点信息
List list = ((ActivityImpl) activityImpl).getActivities();
for(ActivityImpl act : list){
//System.out.println("act-------------->"+act.getActivityBehavior().getClass().getTypeName());
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) act.getActivityBehavior())
.getTaskDefinition();
taskDefinitions.add(taskDefinition);
}
} else if ("exclusiveGateway".equals(activityImpl.getProperty("type"))
|| "inclusiveGateway".equals(activityImpl.getProperty("type"))) {// 当前节点为exclusiveGateway或inclusiveGateway
List outTransitions = activityImpl.getOutgoingTransitions();
String defaultTransition = (String) activityImpl.getProperty("default");
if (outTransitions.size() == 1) {
taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) outTransitions.get(0).getDestination(),
activityId, processInstanceId, condition));
} else if (outTransitions.size() > 1) { // 如果排他网关有多条线路信息
for (PvmTransition tr1 : outTransitions) {
ActivityImpl actImpl = (ActivityImpl) tr1.getDestination();
if (actImpl.getProperty("type").toString().contains("EndEvent")) {
TaskDefinition taskDefinition = new TaskDefinition(null);
ExpressionManager expressionManager = new ExpressionManager();
taskDefinition.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
String name = actImpl.getProperty("name") == null ? "结束"
: actImpl.getProperty("name").toString();
taskDefinition.setNameExpression(expressionManager.createExpression(name));
taskDefinitions.add(taskDefinition);
break;
}
s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
if (null == s) {
continue;
}
// 判断el表达式是否成立
if (isCondition(condition, StringUtils.trim(s.toString()))) {
taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
processInstanceId, condition));
}
}
if(taskDefinitions.size()==0 && StringUtils.isNotBlank(defaultTransition)){
for (PvmTransition tr3 : outTransitions) {
if(defaultTransition.equals(tr3.getId())){
ActivityImpl actImpl = (ActivityImpl) tr3.getDestination();
if (actImpl.getProperty("type").toString().contains("EndEvent")) {
TaskDefinition taskDefinition2 = new TaskDefinition(null);
ExpressionManager expressionManager2 = new ExpressionManager();
taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
String name2 = actImpl.getProperty("name") == null ? "结束"
: actImpl.getProperty("name").toString();
taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
taskDefinitions.add(taskDefinition2);
break;
}
taskDefinitions.addAll(nextTaskDefinitions( actImpl,
activityId, processInstanceId, condition));
System.out.println("taskDefinitions---333333333--->"+taskDefinitions.size());
}
}
}
}
} else if ("parrallelGateway".equals(activityImpl.getProperty("type"))) {
List outTransitions = activityImpl.getOutgoingTransitions();
for (PvmTransition tr1 : outTransitions) {
taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
processInstanceId, condition));
}
} else {
// 获取节点所有流向线路信息
List outTransitions = activityImpl.getOutgoingTransitions();
List outTransitionsTemp = null;
for (PvmTransition tr : outTransitions) {
ac = tr.getDestination(); // 获取线路的终点节点
System.out.println("ac----------->" + ac.getId() + "------>" + ac.getProperty("type"));
// 如果流向线路为排他网关或包容网关
if ("exclusiveGateway".equals(ac.getProperty("type"))
|| "inclusiveGateway".equals(ac.getProperty("type"))) {
outTransitionsTemp = ac.getOutgoingTransitions();
String defaultTransition = (String) ac.getProperty("default");
// 如果排他网关只有一条线路信息
if (outTransitionsTemp.size() == 1) {
taskDefinitions.addAll(
nextTaskDefinitions((ActivityImpl) outTransitionsTemp.get(0).getDestination(),
activityId, processInstanceId, condition));
} else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息
for (PvmTransition tr1 : outTransitionsTemp) {
ActivityImpl actImpl = (ActivityImpl) tr1.getDestination();
if (actImpl.getProperty("type").toString().contains("EndEvent")) {
TaskDefinition taskDefinition2 = new TaskDefinition(null);
ExpressionManager expressionManager2 = new ExpressionManager();
taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
String name2 = actImpl.getProperty("name") == null ? "结束"
: actImpl.getProperty("name").toString();
taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
taskDefinitions.add(taskDefinition2);
break;
}
System.out.println("taskDefinitions--1111---->"+taskDefinitions.size());
s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
if (null == s) {
continue;
}
// 判断el表达式是否成立
if (isCondition(condition, StringUtils.trim(s.toString()))) {
taskDefinitions.addAll(nextTaskDefinitions(actImpl,activityId, processInstanceId, condition));
}
System.out.println("taskDefinitions---22222--->"+taskDefinitions.size());
}
if(taskDefinitions.size()==0 && StringUtils.isNotBlank(defaultTransition)){
for (PvmTransition tr3 : outTransitionsTemp) {
if(defaultTransition.equals(tr3.getId())){
ActivityImpl actImpl = (ActivityImpl) tr3.getDestination();
if (actImpl.getProperty("type").toString().contains("EndEvent")) {
TaskDefinition taskDefinition2 = new TaskDefinition(null);
ExpressionManager expressionManager2 = new ExpressionManager();
taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
String name2 = actImpl.getProperty("name") == null ? "结束"
: actImpl.getProperty("name").toString();
taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
taskDefinitions.add(taskDefinition2);
break;
}
taskDefinitions.addAll(nextTaskDefinitions( actImpl,
activityId, processInstanceId, condition));
System.out.println("taskDefinitions---333333333--->"+taskDefinitions.size());
}
}
}
}
} else if ("userTask".equals(ac.getProperty("type"))) {
taskDefinitions.add(((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior())
.getTaskDefinition());
} else if ("multiInstanceBody".equals(ac.getProperty("type"))) {
List list = ((ActivityImpl) ac).getActivities();
for(ActivityImpl act : list){
//System.out.println("act-------------->"+act.getActivityBehavior().getClass().getTypeName());
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) act.getActivityBehavior())
.getTaskDefinition();
taskDefinitions.add(taskDefinition);
}
} else if (ac.getProperty("type").toString().contains("EndEvent")) {
// 设置结束节点
TaskDefinition taskDefinition = new TaskDefinition(null);
ExpressionManager expressionManager = new ExpressionManager();
taskDefinition.setKey(ac.getId() == null ? "end" : ac.getId());
String name = ac.getProperty("name") == null ? "结束" : ac.getProperty("name").toString();
taskDefinition.setNameExpression(expressionManager.createExpression(name));
taskDefinitions.add(taskDefinition);
} else if ("parrallelGateway".equals(ac.getProperty("type"))) {
List poutTransitions = ac.getOutgoingTransitions();
for (PvmTransition tr1 : poutTransitions) {
taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
processInstanceId, condition));
}
}
}
}
return taskDefinitions;
} catch (Exception e) {
logger.error("operation error", e);
throw e;
}
}
private boolean isCondition(Map condition, String el) {
try {
ExpressionFactory factory = new ExpressionFactoryImpl();
SimpleContext context = new SimpleContext();
if (condition != null) {
Iterator> iterator = condition.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry value = iterator.next();
context.setVariable(value.getKey(), factory.createValueExpression(value.getValue(), String.class));
}
}
ValueExpression e = factory.createValueExpression(context, el, boolean.class);
return (Boolean) e.getValue(context);
} catch (Exception e) {
logger.error("operation error", e);
throw e;
}
}
关于分支条件问题,预取时可以传入变量,模拟修改或设置变量,以便根据isCondition来判断分支条件是否成立,如下,该流程实例启动时设置的amount变量为1100,预取时设置为500,获取到的节点为”审批2“,经测试达到预期效果。
PS:预取代码没有进行严格测试,可能存在缺陷或性能问题,欢迎加QQ群:650886724 进行反馈与讨论,谢谢!