技术分享 工作流 查看内容

Activiti中如何跳过(自动处理)第一步的提交任务?

老高 | 发布于 2015-06-11 15:46| 浏览()| 评论() | 收藏() | 点赞() | 打印

摘要: 在Activiti流程设计中,为了使流程展示的更加完善,经常会将流程图的第一步任务设计成“提交任务”

在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);


第二种方式:使用监听器处理(推荐)

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>

ProxyUserTaskBpmnParseHandler类

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;
	}
}

ProxyTaskListener类

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;
    }
}

AutoCompleteFirstTaskListener类

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());
			}
		}
	}
}

CompleteTaskWithCommentCmd类

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;
	}
}

发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)

表情