Activiti中如何跳过(自动处理)第一步的提交任务?(转载)
在Activiti流程设计中,为了使流程展示的更加完善,经常会将流程图的第一步任务设计成“提交任务”,例如:
申请人启动流程后,流程就会到达“提交任务”,而“提交任务”的办理人还是该申请人,这个时候就需要通过代码跳过(自动处理)该任务节点,让流程流转到下一任务节点。有两种方法可以处理这个问题。
第一种方式:在启动流程后,获取当前流程实例申请人的待办任务,并执行当前流程实例的下一步任务
1 Task task = null; 2 TaskQuery query = taskService.createTaskQuery().taskCandidateOrAssigned(empId).active(); 3 List<Task> todoList = query.list();//获取申请人的待办任务列表 4 for (Task tmp : todoList) { 5 if(tmp.getProcessInstanceId().equals(processInstance.getId())){ 6 task = tmp;//获取当前流程实例,当前申请人的待办任务 7 break; 8 } 9 } 10 variables.put(ProcessConstants.KEY_DEPT_LEADER_ID, employeeId);//设置下一步办理人的流程变量 11 taskService.complete(task.getId(),variables);
第二种方式:使用监听器处理(推荐)
spring配置文件
1 <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> 2 ... 3 <!-- 添加的自定义监听器 --> 4 <property name="postBpmnParseHandlers"> 5 <list> 6 <bean class="com.eazytec.common.activiti.listener.ProxyUserTaskBpmnParseHandler"> 7 <property name="taskListenerId" value="postTaskListener"/> 8 </bean> 9 </list> 10 </property> 11 ... 12 </bean> 13 <!-- 在记录history之后执行的TaskListener --> 14 <bean id="postTaskListener" class="com.eazytec.common.activiti.listener.ProxyTaskListener"> 15 <property name="taskListeners"> 16 <list> 17 <bean class="com.eazytec.common.activiti.listener.AutoCompleteFirstTaskListener"/> 18 </list> 19 </property> 20 </bean>
ProxyUserTaskBpmnParseHandler类
1 public class ProxyUserTaskBpmnParseHandler implements BpmnParseHandler { 2 private static Logger logger = LoggerFactory.getLogger(ProxyUserTaskBpmnParseHandler.class); 3 private String taskListenerId; 4 private boolean useDefaultUserTaskParser; 5 6 public void parse(BpmnParse bpmnParse, BaseElement baseElement) { 7 if (!(baseElement instanceof UserTask)) { 8 return; 9 } 10 11 if (useDefaultUserTaskParser) { 12 new UserTaskParseHandler().parse(bpmnParse, baseElement); 13 } 14 15 UserTask userTask = (UserTask) baseElement; 16 logger.info("bpmnParse : {}, userTask : {}", bpmnParse, userTask); 17 18 TaskDefinition taskDefinition = (TaskDefinition) bpmnParse.getCurrentActivity().getProperty(UserTaskParseHandler.PROPERTY_TASK_DEFINITION); 19 20 this.configEvent(taskDefinition, bpmnParse, TaskListener.EVENTNAME_CREATE); 21 this.configEvent(taskDefinition, bpmnParse, TaskListener.EVENTNAME_ASSIGNMENT); 22 this.configEvent(taskDefinition, bpmnParse, TaskListener.EVENTNAME_COMPLETE); 23 this.configEvent(taskDefinition, bpmnParse, TaskListener.EVENTNAME_DELETE); 24 } 25 26 public void configEvent(TaskDefinition taskDefinition, BpmnParse bpmnParse, String eventName) { 27 ActivitiListener activitiListener = new ActivitiListener(); 28 activitiListener.setEvent(eventName); 29 activitiListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); 30 activitiListener.setImplementation("#{" + taskListenerId + "}"); 31 taskDefinition.addTaskListener(eventName, bpmnParse.getListenerFactory().createDelegateExpressionTaskListener(activitiListener)); 32 } 33 34 public Collection<Class<? extends BaseElement>> getHandledTypes() { 35 List types = Collections.singletonList(UserTask.class); 36 return types; 37 } 38 39 public void setTaskListenerId(String taskListenerId) { 40 this.taskListenerId = taskListenerId; 41 } 42 43 public void setUseDefaultUserTaskParser(boolean useDefaultUserTaskParser) { 44 this.useDefaultUserTaskParser = useDefaultUserTaskParser; 45 } 46 }
ProxyTaskListener类
1 public class ProxyTaskListener implements TaskListener { 2 private List<TaskListener> taskListeners = Collections.EMPTY_LIST; 3 public void notify(DelegateTask delegateTask) { 4 for (TaskListener taskListener : taskListeners) { 5 taskListener.notify(delegateTask); 6 } 7 } 8 public void setTaskListeners(List<TaskListener> taskListeners) { 9 this.taskListeners = taskListeners; 10 } 11 }
AutoCompleteFirstTaskListener类
1 public class AutoCompleteFirstTaskListener extends DefaultTaskListener { 2 private static Logger logger = LoggerFactory.getLogger(AutoCompleteFirstTaskListener.class); 3 4 @Override 5 public void onCreate(DelegateTask delegateTask) throws Exception { 6 String userId = Authentication.getAuthenticatedUserId(); 7 String assignee = delegateTask.getAssignee(); 8 9 ProcessDefinitionEntity processDefinitionEntity = Context.getProcessEngineConfiguration().getProcessDefinitionCache().get(delegateTask.getProcessDefinitionId()); 10 11 ActivityImpl startActivity = processDefinitionEntity.getInitial(); 12 13 if (startActivity.getOutgoingTransitions().size() != 1) { 14 throw new IllegalStateException("start activity outgoing transitions cannot more than 1, now is : " + startActivity.getOutgoingTransitions().size()); 15 } 16 17 PvmTransition pvmTransition = startActivity.getOutgoingTransitions().get(0); 18 PvmActivity targetActivity = pvmTransition.getDestination(); 19 20 if (!"userTask".equals(targetActivity.getProperty("type"))) { 21 logger.debug("first activity is not userTask, just skip"); 22 return; 23 } 24 25 if (targetActivity.getId().equals(delegateTask.getExecution().getCurrentActivityId())) { 26 if ((userId != null) && userId.equals(assignee)) { 27 logger.debug("auto complete first task : {}", delegateTask); 28 new CompleteTaskWithCommentCmd(delegateTask.getId(), null, "发起流程").execute(Context.getCommandContext()); 29 } 30 } 31 } 32 }
CompleteTaskWithCommentCmd类
1 public class CompleteTaskWithCommentCmd implements Command<Object> { 2 private String taskId; 3 private String comment; 4 private Map<String, Object> variables; 5 6 public CompleteTaskWithCommentCmd(String taskId, Map<String, Object> variables, String comment) { 7 this.taskId = taskId; 8 this.variables = variables; 9 this.comment = comment; 10 } 11 12 public Object execute(CommandContext commandContext) { 13 TaskEntity taskEntity = commandContext.getTaskEntityManager().findTaskById(taskId); 14 15 if (variables != null) { 16 taskEntity.setExecutionVariables(variables); 17 } 18 19 taskEntity.fireEvent(TaskListener.EVENTNAME_COMPLETE); 20 21 if ((Authentication.getAuthenticatedUserId() != null) && (taskEntity.getProcessInstanceId() != null)) { 22 taskEntity.getProcessInstance().involveUser(Authentication.getAuthenticatedUserId(), IdentityLinkType.PARTICIPANT); 23 } 24 25 Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, comment, false); 26 27 if (taskEntity.getExecutionId() != null) { 28 ExecutionEntity execution = taskEntity.getExecution(); 29 execution.removeTask(taskEntity); 30 execution.signal(null, null); 31 } 32 33 return null; 34 } 35 }