首页 > 代码库 > activiti工作流退回问题研究
activiti工作流退回问题研究
近期由于业务需求,需要一个开源的工作流。研究了一下activiti工作流版本5.13 .在研究过程中发现,activiti工作流现有的功能中不能满足中国式的驳回。如果工作流不能驳回,那对于咱们来说基本上是用不了。后来在网上找了一个退回到上一节点的例子。现在改了一下,可以从当前节点退回的以前走过的人工节点。废话少说直接上例子。
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="helloworld" name="helloworldProcess" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="提交申请" activiti:assignee="张三"></userTask>
<userTask id="usertask2" name="审批【部门经理】" activiti:assignee="李四"></userTask>
<userTask id="usertask3" name="审批【总经理】" activiti:assignee="王五"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
</process>
以上是最简单的审批流程
退回到上一级提交人的代码如下:
public class ModelRollBack {
private Logger log = LogManager.getLogger(ModelRollBack.class);//日志文件
private RuntimeService runtimeService;//
private TaskService taskService;
private RepositoryService repositoryService;
private HistoryService historyService;
private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//退回上一个节点
public String rollBackWorkFlow(String taskId) {
this.taskService=processEngine.getTaskService();
this.historyService = processEngine.getHistoryService();
this.repositoryService = processEngine.getRepositoryService();
this.runtimeService = processEngine.getRuntimeService();
try {
Map<String, Object> variables;
// 取得当前任务.当前任务节点
HistoricTaskInstance currTask = historyService
.createHistoricTaskInstanceQuery().taskId(taskId)
.singleResult();
// 取得流程实例,流程实例
ProcessInstance instance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(currTask.getProcessInstanceId())
.singleResult();
if (instance == null) {
log.info("流程结束");
log.error("出错啦!流程已经结束");
return "ERROR";
}
variables = instance.getProcessVariables();
// 取得流程定义
ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(currTask
.getProcessDefinitionId());
if (definition == null) {
log.info("流程定义未找到");
log.error("出错啦!流程定义未找到");
return "ERROR";
}
// 取得上一步活动
ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
.findActivity(currTask.getTaskDefinitionKey());
//也就是节点间的连线
List<PvmTransition> nextTransitionList = currActivity
.getIncomingTransitions();
// 清除当前活动的出口
List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
//新建一个节点连线关系集合
List<PvmTransition> pvmTransitionList = currActivity
.getOutgoingTransitions();
//
for (PvmTransition pvmTransition : pvmTransitionList) {
oriPvmTransitionList.add(pvmTransition);
}
pvmTransitionList.clear();
// 建立新出口
List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
for (PvmTransition nextTransition : nextTransitionList) {
PvmActivity nextActivity = nextTransition.getSource();
ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) definition)
.findActivity(nextActivity.getId());
TransitionImpl newTransition = currActivity
.createOutgoingTransition();
newTransition.setDestination(nextActivityImpl);
newTransitions.add(newTransition);
}
// 完成任务
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(instance.getId())
.taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
for (Task task : tasks) {
taskService.complete(task.getId(), variables);
historyService.deleteHistoricTaskInstance(task.getId());
}
// 恢复方向
for (TransitionImpl transitionImpl : newTransitions) {
currActivity.getOutgoingTransitions().remove(transitionImpl);
}
for (PvmTransition pvmTransition : oriPvmTransitionList) {
pvmTransitionList.add(pvmTransition);
}
log.info("OK");
log.info("流程结束");
return "SUCCESS";
} catch (Exception e) {
log.error("失败");
log.error(e.getMessage());
return "ERROR";
}
}
//回退到指定节点
public String rollBackToAssignWorkFlow(String taskId,String destTaskkey) {
this.taskService=processEngine.getTaskService();
this.historyService = processEngine.getHistoryService();
this.repositoryService = processEngine.getRepositoryService();
this.runtimeService = processEngine.getRuntimeService();
try {
Map<String, Object> variables;
// 取得当前任务.当前任务节点
HistoricTaskInstance currTask = historyService
.createHistoricTaskInstanceQuery().taskId(taskId)
.singleResult();
// 取得流程实例,流程实例
ProcessInstance instance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(currTask.getProcessInstanceId())
.singleResult();
if (instance == null) {
log.info("流程结束");
log.error("出错啦!流程已经结束");
return "ERROR";
}
variables = instance.getProcessVariables();
// 取得流程定义
ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(currTask
.getProcessDefinitionId());
if (definition == null) {
log.info("流程定义未找到");
log.error("出错啦!流程定义未找到");
return "ERROR";
}
//取得当前活动节点
ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
.findActivity(currTask.getTaskDefinitionKey());
log.info("currActivity"+currActivity);
// 取得上一步活动
//也就是节点间的连线
//获取来源节点的关系
List<PvmTransition> nextTransitionList = currActivity.getIncomingTransitions();
// 清除当前活动的出口
List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
//新建一个节点连线关系集合
//获取出口节点的关系
List<PvmTransition> pvmTransitionList = currActivity
.getOutgoingTransitions();
//
for (PvmTransition pvmTransition : pvmTransitionList) {
oriPvmTransitionList.add(pvmTransition);
}
pvmTransitionList.clear();
// 建立新出口
List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
for (PvmTransition nextTransition : nextTransitionList) {
PvmActivity nextActivity = nextTransition.getSource();
log.info("nextActivity"+nextActivity);
log.info("nextActivity.getId()"+nextActivity.getId());
//destTaskkey
ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) definition)
// .findActivity(nextActivity.getId());
.findActivity(destTaskkey);
TransitionImpl newTransition = currActivity
.createOutgoingTransition();
newTransition.setDestination(nextActivityImpl);
newTransitions.add(newTransition);
}
// 完成任务
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(instance.getId())
.taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
for (Task task : tasks) {
taskService.complete(task.getId(), variables);
historyService.deleteHistoricTaskInstance(task.getId());
}
// 恢复方向
for (TransitionImpl transitionImpl : newTransitions) {
currActivity.getOutgoingTransitions().remove(transitionImpl);
}
for (PvmTransition pvmTransition : oriPvmTransitionList) {
pvmTransitionList.add(pvmTransition);
}
log.info("OK");
log.info("流程结束");
return "SUCCESS";
} catch (Exception e) {
log.error("失败");
log.error(e.getMessage());
return "ERROR";
}
}
public static void main(String []args){
ModelRollBack back = new ModelRollBack();
//back.rollBackWorkFlow("1102");
back.rollBackToAssignWorkFlow("2402", "usertask1");
}
}
以上代码是退回到上一节点,和退回到提交人节点的代码
代码解析 : 例如 流程开始 走到张三 ,张三提交 ,走到李四 ,李四提交走到王五 。现在王五发现有问题,需要直接退回到 张三,让张三修改之后再次提交 。
这个过程中当前节点在王五 也就是usertask3 在此过程中我们要理清 节点之间的关系
usertask1----->usertask2
usertask2------>usertask3
usertask3------->endevent
目前对于uesrtask3来说来源 是usertask2------>usertask3
出口usertask3------>enendevent
所以我们只需要根据流程引擎中的定义将出口替换成usertask1就可以。
在此过程中 PvmTransition 只工作流引擎中 的节点关系维护
ActivityImpl是具体的节点。
ProcessDefinitionEntity是当前流程的定义
目前只研究到这个阶段如果需要交流,可以给我留言哦 或者加我Q 1107582053
activiti工作流退回问题研究