[b]灵活的临时动态性需求,例如:任意回退、会签(包括加、减签,补签)[/b]
关于名词解释参看这里
[url]http://www.infoq.com/cn/articles/jbpm4-process-requirement[/url]
[b]回退:如果你有回退的路线,那么completeTask后直接指定路线就可以。
任意回退:setActivity()[/b]
[b]会签:这里以单步会签为例[/b]
思想:活动中使用custom,调用用户代码,实现一个自定义的活动行为。
使task处于等待状态,生成几个子任务,当所有子任务结束后查看会签结果,最后进行走向。(不同的投票机制可以采取不同的方案,如果一票否决制,那么就不必等所有人都审核了再决定走向,所以具体还是要看投票的机制;投票的审核方式可以放在signal方法里,也可以放在signal方法外,即实际业务中,主要还是要看应用的场景)
以上怎么来触发呢?
// 设置为true时,completeTask 会触发 signal
subtask.setSignalling(false);
如果设置的是false
参考[url]http://www.family168.com/tutorial/jbpm4.0/html/services.html#singallingawaitingexecution[/url]
使用以下代码即可
是不是很简单?
[b]另外关于会签中决策方式,比如一票否决,少数服从多数,N票认可,按比例通过等可以通过定义会签结论接口,不同的实现来进行处理。[/b]
当我们的工作流和实际业务结合的很紧密,例如:我们必须知道一个人在一个项目中的任务,这个时候我们必须把工作流实例和项目进行绑定,这也是最简单有效地方法。
获取一个流程实例中的个人任务
然后我们再回头看下官方用户手册和demo中的实现方法
这个时候,我们所取得的任务只是任务列表中的某个任务,而无法取得我们需要指定的任务,实用性显而易见。
关于名词解释参看这里
[url]http://www.infoq.com/cn/articles/jbpm4-process-requirement[/url]
[b]回退:如果你有回退的路线,那么completeTask后直接指定路线就可以。
任意回退:setActivity()[/b]
[b]会签:这里以单步会签为例[/b]
思想:活动中使用custom,调用用户代码,实现一个自定义的活动行为。
使task处于等待状态,生成几个子任务,当所有子任务结束后查看会签结果,最后进行走向。(不同的投票机制可以采取不同的方案,如果一票否决制,那么就不必等所有人都审核了再决定走向,所以具体还是要看投票的机制;投票的审核方式可以放在signal方法里,也可以放在signal方法外,即实际业务中,主要还是要看应用的场景)
public class CountersignCustom implements ExternalActivityBehaviour {
...
public void execute(ActivityExecution activityExecution) {
ExecutionImpl execution = (ExecutionImpl) activityExecution;
// 创建主任务
DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
TaskImpl task = (TaskImpl) dbSession.createTask();
task.setExecution(execution);
task.setProcessInstance((ExecutionImpl) execution.getProcessInstance());
task.setSignalling(true);
task.setName(taskName);
dbSession.save(task);
HistoryEvent.fire(new TaskActivityStart(task), (ExecutionImpl) execution);
//通过变量传入会签人员
String[] counters = (String[]) execution.getVariable(counterignVarName);
// 创建子任务
for (String countersigner : counters) {
TaskImpl subtask = (TaskImpl) dbSession.createTask();
task.addSubTask(subtask);
subtask.setAssignee(countersigner);
subtask.setName(taskName + "." + countersigner);
subtask.setProcessInstance((ExecutionImpl) execution.getProcessInstance());
subtask.setExecution(execution);
// 设置为true时,completeTask 会触发 signal
// 参见 TaskImpl.complete() 方法
subtask.setSignalling(false);
dbSession.save(subtask);
// 触发事件
HistoryEvent.fire(new TaskActivityStart(subtask), (ExecutionImpl) execution);
}
execution.waitForSignal();
}
public void signal(ActivityExecution activityExecution, String signalName, Map<String, ?> parms) throws Exception {
...
if (会签完成) {
Transition transition = null;
if(会签不批准) {
ExecutionService executionService = processEngine.getExecutionService();
executionService.endProcessInstance(pi.getId(), Execution.STATE_ENDED);
}else {
transition = activity.findOutgoingTransition(countersignSuccess);
signalName = countersignSuccess;
executionImpl.historyActivityEnd(signalName);
executionImpl.take(transition);
}
} else {//会签未完成继续等待
executionImpl.waitForSignal();
}
...
}
以上怎么来触发呢?
// 设置为true时,completeTask 会触发 signal
subtask.setSignalling(false);
如果设置的是false
参考[url]http://www.family168.com/tutorial/jbpm4.0/html/services.html#singallingawaitingexecution[/url]
使用以下代码即可
ExecutionService executionService = processEngine.getExecutionService();
executionService.signalExecutionById(id);
是不是很简单?
[b]另外关于会签中决策方式,比如一票否决,少数服从多数,N票认可,按比例通过等可以通过定义会签结论接口,不同的实现来进行处理。[/b]
当我们的工作流和实际业务结合的很紧密,例如:我们必须知道一个人在一个项目中的任务,这个时候我们必须把工作流实例和项目进行绑定,这也是最简单有效地方法。
获取一个流程实例中的个人任务
ExecutionService executionService = processEngine.getExecutionService();
ProcessInstance processInstance = executionService.startProcessInstanceByKey(key,variables);
TaskService taskService = processEngine.getTaskService();
//根据节点名取一流程实例下的任务
Task task1 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).activityName("经理签收").uniqueResult();
//根据任务分配者userId取一流程实例下的任务
Task task2 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).assignee(userId).uniqueResult();
然后我们再回头看下官方用户手册和demo中的实现方法
List<Task> taskList = taskService.findPersonalTasks("johndoe");
Task task = taskList.get(0);
这个时候,我们所取得的任务只是任务列表中的某个任务,而无法取得我们需要指定的任务,实用性显而易见。