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