JBPM4-回退 功能实现

9 篇文章 0 订阅

1、JBPM4-回退

  回退指的是用户主动回退到当前任务的上一流程节点(上一步骤)。

  • 应用场景示例:
     当前用户接收任务后,发现这个任务不该由他办理或者这个任务存在严重的业务问题,这时就需要回退给上一步的办理者重新办理。
  • 解决方案:
    (1)定义【回退监听器】:
        回退监听器接收一个参数,用于指定回退目的地的活动 ID。之所以这样设计是因为,回退的出发地与目的地可能相隔着多个活动。这个参数也可以设计为流程变量,这样可以在流程运行时动态算出。然后在需要回退时,动态创建一条转移路径,退回到目的地。
    (2)添加【回退监听器】
        在流程定义中识别 “需要具有回退能力” 的任务,为具有回退功能的任务活动设置专门用于处理回退逻辑的监听器。
    (3)定义【回退任务】API:
        如果回退操作造成业务 “损失”,那么就必须在【回退任务】API 中予以补偿;如果需要清除 “历史痕迹”,那么在【回退任务】API 还需要删除相关的历史记录。

2、实例

2.1 流程图及JPDL文件

1
对应的JPDL文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<process name="testProcess" xmlns="http://jbpm.org/4.4/jpdl">
 <swimlane candidate-groups="anhui" name="anhui"/>
   <start g="-6,173,72,48" name="start1">
      <transition g="-22,-25" name="to 申请" to="申请"/>
   </start>
   <end g="1129,60,82,51" name="end1"/>
   <task g="91,166,102,56" name="申请" swimlane="anhui">
      <transition name="to 审批" to="审批" g="-22,-18"/>
   </task>
   <task g="257,168,109,52" name="审批" swimlane="anhui">
   	  <!-- 为【审批】活动添加具有回退到【申请】功能的监听器  - 监听器定义见2.2节-->
   	  <on event="start"> 
   	 	 <event-listener class="com.math.jbpm.util.RollbackListener">
   	 	  	<field name="rollbackTo">
   	 	  		<string value="申请"/>
   	 	  	</field>
   	 	 </event-listener>
   	  </on>
      <transition name="to end" to="end" g="-25,-20"/>
   </task>
   <end g="417,169,48,48" name="end"/>
</process>

2.2 定义【回退监听器】- java 实现

    RollbackListener 是定义的回退监听器,它会根据注入的 rollbackTo 参数值来动态生成一条通向回退目的地的转移路径。定义如下:

import org.apache.log4j.Logger;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.listener.EventListener;
import org.jbpm.api.listener.EventListenerExecution;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.model.TransitionImpl;
/**
 * 工作流任务回退监听器
 * @author rmling
 */
public class RollbackListener implements EventListener{
	public Logger logger = Logger.getLogger(RollbackListener.class);
	/**回退的目的地*/
	private String rollbackTo ;
	@Override
	public void notify(EventListenerExecution execution) throws Exception {
		//获取流程定义对象
		ProcessInstance processInstance = execution.getProcessInstance();
		ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl)JbpmUtil.getProcessEngine().processEngine
				.createProcessDefinitionQuery()
				.processDefinitionId(processInstance.getProcessDefinitionId())
				.uniqueResult();
		//获取退回目的地活动的定义对象
		ActivityImpl toActivityImpl = processDefinition.findActivity(rollbackTo);
		if(toActivityImpl == null){//退回目的地不存在
			String mes = "在此"+processInstance.getProcessDefinitionId()+" 流程中不存在 "+rollbackTo+"活动";
			logger.error(mes);
			throw new Exception(mes);
		}
		//获取当前活动的定义对象
		ActivityImpl fromActivityImpl = (ActivityImpl) execution.getActivity();
		//建立退回路径
		TransitionImpl transition1 = fromActivityImpl.createOutgoingTransition();
		System.out.println("transition:"+fromActivityImpl.getName()+" to "+rollbackTo);
		transition1.setName(fromActivityImpl.getName()+" to "+rollbackTo);
		transition1.setDestination(toActivityImpl);
	}
}

2.3 【回退】任务API

/**
   * 任务回退
   * @param taskID
   * @param rollbackToActivityName
   */
  public void completedTaskRollback(String taskID, String rollbackToActivityName) {
	  Task task = JbpmUtil.taskService.getTask(taskID);
	  	if(task != null){
	  		if(rollbackToActivityName != null){
	  			JbpmUtil.taskService.completeTask(task.getId(),task.getName()+" to "+rollbackToActivityName);
	  		}else{
	  			JbpmUtil.taskService.completeTask(task.getId());
	  		}
			logger.info("-- 工作流"+processID+" 任务 '"+task.getName()+"' 已完成 --");
		}
  }

2.4 主测试函数

public static void main(String[] args) {
		User user = createTestUser();
		//初始化工作流
		ProcessForJbpm process = new ProcessForJbpm("com/math/jbpm/test/rollback/","testProcess",ProcessType.Unknown);
		process.startProcessInstance(111111l,null);
		//工作流启动
		process.startTask(user);
//		start->申请->审批->end
		try {
			//申请
			Task task = process.findActiveTask();
			System.out.println(" -- 当前任务:"+task.getName());
			System.out.println(" -- 结束任务:"+task.getName());
			process.completedTask(null, user.getId(), user.getName());
			
			task = process.findActiveTask();
			//审批
			System.out.println(" -- 当前任务:"+task.getName());
			System.out.println(" -- 假设【审批】未通过,任务回退");
			System.out.println("outcomes:"+process.getTaskOutcomes(task.getId()).toString());
			//假设【审批】未通过,回退到【申请】
			process.completedTaskRollback(task.getId(),"申请",user.getId(),user.getName());
			task = process.findActiveTask();
			System.out.println("outcomes:"+process.getTaskOutcomes(task.getId()).toString());
			//【审批】通过,结束任务
			process.completedTask(null, user.getId(), user.getName());
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		//关闭工作流
		process.closedProcess();
	}

测试函数输出结果如下(工作流自身日志没截取,只截取了部分流程日志):
1、当前任务:【申请】
1
2、结束任务【申请】,进入【审批】任务
2
3、【审批】任务添加了【回退】监听器,此时,假设【审批】未通过,回退到【申请】任务
3
4、结束【回退】任务后,进入【审批】任务
4
5、结束【审批】任务, 工作流结束
5

2.5 其他相关函数定义

 /**完成任务函数*/
  public void completedTask(String outboundTransName, String userID, String userName) {
	  Task task = findTask(userID, false);
	  	if(task != null){
	  		if(outboundTransName != null){
	  			JbpmUtil.taskService.completeTask(task.getId(),outboundTransName);
	  		}else{
	  			JbpmUtil.taskService.completeTask(task.getId());
	  		}
		}
	}
/** 获取一个任务的所有外向转移名称
   * @param taskId*/
  public Set<String> getTaskOutcomes(String taskId){
	  return JbpmUtil.taskService.getOutcomes(taskId);
  }
/**获取当前激活的所有活动名称*/
 public Set<String> findActiveActivityNames() {
	  return JbpmUtil.executionService.createProcessInstanceQuery().processInstanceId(processID).uniqueResult().findActiveActivityNames();
  }
/**获取工作流中当前正在进行的任务  */
  public Task findActiveTask(){
	  return JbpmUtil.taskService.createTaskQuery().processInstanceId(processID).uniqueResult();
  }
import org.hibernate.Session;
import org.jbpm.api.Configuration;
import org.jbpm.api.Deployment;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
/**
 * 工作流工具类
 * @author mling
 */
public class JbpmUtil {
	/**流程引擎*/
	public static ProcessEngine processEngine;
	/**流程管理:流程模板的部署、查询、删除*/
	public static RepositoryService repositoryService;
	/**流程执行:设置流程实例的发起、执行*/
	public static ExecutionService executionService;
	/**任务服务*/
	public static TaskService taskService;
	/**历史服务*/
	public static HistoryService historyService;
	public static Session session;
	static{
		//流程定义引擎的初始化
		processEngine = Configuration.getProcessEngine();
		//管理流程定义
		repositoryService = processEngine.getRepositoryService();
		//executionService  用于执行流程定义实例
		executionService = processEngine.getExecutionService();
		//任务服务
		taskService = processEngine.getTaskService();
		//历史服务
		historyService = processEngine.getHistoryService();
		//由于JBPM4没有清除历史数据的服务API直接提供,所以这里要获取的是Hibernate Session对象
		session = processEngine.get(Session.class);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值