activiti流程当前节点5 流程里面怎么回退到上一个节点

&&& 在处理流程回退时,需要获取某个节点当前可以回退到的节点,简单分析下:
1. 只支持回退到userTask。
2. 如果流程流转过某节点时生成了多个任务,从其中某一个任务回退到该节点后,不处理另外的任务。
3. 只能回退到当前节点前已经处理过的节点。
&&& 基于这个考虑,获取哪些节点可以回退按如下处理:
1. 从历史任务表查当前节点所在流程实例已经完成过的所有任务,有可能包括当前节点以后的任务(比如当前节点本来就是由后面节点回退的)
2. 判断任务是不是当前节点以前的userTask节点任务,如果是,加入返回列表。
3. 同一个节点只返回一次。
&&& 在这种处理前提下,需要获取流程中所有userTask节点的前后关系。我用深度优先的方式对流程的所有节点进行了一个遍历,把所有节点的前后关系保存在一个map里,map的内容为:
&&& key: 前面的节点编号#后面的节点编号
&&& value:从前面节点到后面节点中间要经过几个节点。
&&& 如果一个节点前有多个节点,比如 流程是 A--&B--&C--&D,那么 map的数据类似:
&& {A#B:1,A#C:2,A#D:3,B#C:1,B#D:2,C#D:1}
&& 在这种情况下,所有的可能性都存储了一份,但是在后面判断节点的前后关系时相对比较容易,只要把要判断的节点和当前节点编号拼接在一起,判断 要判断的节点#当前节点 是不是在map里存在就好了。
&& 一般来说,流程的节点数不会太多,这样已经够用了。
& 由于回退不是在流程上通过划线处理的,所以一般不会出现环状的流程图,因此用深度优先方式遍历也适用,感觉上应该用广度优先的方式遍历更合适一点。
&&附部分代码:
private static Map&String,Map&String,Object&& PROCESS_NODE_MAP = null;
private Map getFlowNodeRel(String processDefKey){
if (null == PROCESS_NODE_MAP){
PROCESS_NODE_MAP = new HashMap&String, Map&String, Object&&();
if(null == PROCESS_NODE_MAP.get(processDefKey)){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
List&Process& processList = engine.getRepositoryService().getBpmnModel(processDefKey).getProcesses();
Process process = null;
if(processList.size()&0){
process = processList.get(0);
Map relationMap = new HashMap&String,Integer&();
setFlowNodeRel(process,relationMap);
PROCESS_NODE_MAP.put(processDefKey, relationMap);
return PROCESS_NODE_MAP.get(processDefKey);
//根据process往relationMap里写入UserTask之间的前后关系,从start开始遍历节点,不循环
private void setFlowNodeRel(Process process,Map relationMap){
Iterator&FlowElement& iterator = process.getFlowElements().iterator();
HashMap nodeMap = new HashMap&String,FlowElement&();
setFlowNodeMap(process,nodeMap);
//获取start节点
StartEvent startEvent = (StartEvent) nodeMap.get("startEvent");
//处理节点关系
setFlowNodeRel("","startEvent",nodeMap,relationMap,1);
//根据节点ID设置关系
private void setFlowNodeRel(String parentKey,String nodeId,Map&String,FlowElement& nodeMap,Map relationMap,int level){
FlowElement element = nodeMap.get(nodeId);
if(element instanceof UserTask){
relationMap.put(nodeId, element);
if(!(element
instanceof FlowNode)){
List&SequenceFlow& outFlows = ((FlowNode)element).getOutgoingFlows();
if(outFlows.size() == 0){
//采用深度遍历
for(int index=0;index & outFlows.size();index++){
SequenceFlow tmpSequence = outFlows.get(index);
String target = tmpSequence.getTargetRef();
String key = nodeId + "#" +
String loopKey = target + "#" + nodeId;
FlowElement tmpElement = nodeMap.get(target);
//只是源和目标都是 用户任务 才写入
if(relationMap.containsKey(loopKey) || relationMap.containsKey(key)){
if(tmpElement instanceof UserTask && element instanceof UserTask){
setRelMapValue(relationMap,parentKey,target, level);
//递归找下一个任务的关系
setFlowNodeRel(parentKey+"#"+target,target,nodeMap,relationMap,level+1);
private void setRelMapValue(Map relationMap,String parentKey,String nodeKey,int level){
if(parentKey.length() & 0){
String[] parentArr = parentKey.split("#");
for(String parent:parentArr){
if(StringUtils.isNotEmpty(parent)){
String key = parent + "#" + nodeK
String loopKey = nodeKey + "#" +
if(relationMap.containsKey(loopKey) || relationMap.containsKey(key)){
relationMap.put(key, level);
//把流程节点设置到map属性里
private void setFlowNodeMap(Process process,Map&String,FlowElement& nodeMap){
Iterator&FlowElement& iterator = process.getFlowElements().iterator();
while(iterator.hasNext()){
FlowElement element = iterator.next();
if(element instanceof StartEvent){
nodeMap.put("startEvent", element);
nodeMap.put(element.getId(),element);
阅读(...) 评论()activiti中fork多任务时,如果回退到上个节点
如上面这个流程,如果任务进入fork分支,产生子任务task2.2和task2.1。这时,如果需要task2.1回退到task1上,且不需要等待task2.2,直接回退到父任务task1,应该怎么处理?
我现在的想法是当task2.1退回时,直接自动把同时fork出来的相关子任务task2.2,task2.3....等直接结束,然后在并行流程结束的时候通过一个判断回到task1。还有其他更好的办法吗?或者更合理的办法当前位置: >
Activiti 指定节点跳转(适合退回、撤回)流程
来源:CSDN & 发布时间:
& 作者:qq_ &
浏览次数:
//方法一,画退回的路线,设置退回的条件值 //方法二,退回到指定环节 @RequestMapping("/rollBackToAssgin.do") publ...
& & & & //方法一,画退回的路线,设置退回的条件值 //方法二,退回到指定环节 @RequestMapping("/rollBackToAssgin.do") public void rollBackToAssignWoekFlow(@RequestParam("processInstanceId") String processInstanceId,String destTaskkey){ // 取得当前任务.当前任务节点 destTaskkey ="usertask1"; & & & &// HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); Map&String, Object& ExecutionEntity entity = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(processInstanceId).singleResult(); ProcessDefinitionEntity definition = (ProcessDefinitionEntity)((RepositoryServiceImpl)repositoryService) & & & & & .getDeployedProcessDefinition(entity.getProcessDefinitionId()); variables = entity.getProcessVariables(); //当前活动环节 ActivityImpl currActivityImpl = definition.findActivity(entity.getActivityId()); //目标活动节点 ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) definition).findActivity(destTaskkey); if(currActivityImpl !=null){ //所有的出口集合 List&PvmTransition& pvmTransitions = currActivityImpl.getOutgoingTransitions(); List&PvmTransition& oriPvmTransitions = new ArrayList&PvmTransition&(); for(PvmTransition transition : pvmTransitions){ oriPvmTransitions.add(transition); } //清除所有出口 pvmTransitions.clear(); //建立新的出口 List&TransitionImpl& transitionImpls = new ArrayList&TransitionImpl&(); TransitionImpl tImpl = currActivityImpl.createOutgoingTransition(); tImpl.setDestination(nextActivityImpl); transitionImpls.add(tImpl);
List&Task& list = taskService.createTaskQuery().processInstanceId(entity.getProcessInstanceId()) .taskDefinitionKey(entity.getActivityId()).list(); for(Task task:list){ </plete(task.getId(), variables); historyService.deleteHistoricTaskInstance(task.getId()); }
for(TransitionImpl transitionImpl:transitionImpls){ currActivityImpl.getOutgoingTransitions().remove(transitionImpl); }
for(PvmTransition pvmTransition:oriPvmTransitions){ pvmTransitions.add(pvmTransition); } }
& & &//方法三
&&private static Logger logger = Logger.getLogger(HandlerPeocessAction.class); //强制改变当前运行中的流程环节 @RequestMapping("/rejectTaskTo.do") public void rejectTaskTo(@RequestParam("taskId") String taskId,@RequestParam("activityId") String activityId) throws Exception{ & & & &("开始驳回任务,任务原点:::"+taskId+",驳回至:::"+activityId); & & & & HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() & & & & & & & & & & & & .taskId(taskId).finished().singleResult(); & & & & if(historicTaskInstance !=null){ & & & & throw new Exception("任务已结束,不能进行回退操作!"); & & & & } & & & & if(activityId == null || "".equals(activityId)){ & & & & throw new Exception("回退目标节点不能为空!"); & & & & } & & & & long count = taskService.createTaskQuery().taskId(taskId).count(); & & & & if(count == 0){ & & & & throw new Exception("要驳回的任务已不存在!"); & & & & } & & & && & & & & Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult(); & & & & ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getProcessDefinition(currentTask.getProcessDefinitionId()); & & & & String instanceId = currentTask.getProcessInstanceId(); & & & & ActivityImpl activityImpl = definitionEntity.findActivity(activityId); & & & & if(activityImpl == null){ & & & & throw new Exception("要驳回的节点不存在!"); & & & & } & & & & managerService.executeCommand(new JumpActivityCmd(activityId, instanceId)) ; //managerService activiti 七大服务之一 & & & & ("完成驳回操作============"); }
package com.
import org.activiti.engine. import org.activiti.engine.mandC import org.activiti.engine.impl.persistence.entity.ExecutionE import org.activiti.engine.impl.pvm.process.ActivityI import org.activiti.engine.impl.pvm.process.ProcessDefinitionI
public class JumpActivityCmd implements Command&Object& { & && private String activityId; private String processInstanceId; private String jumpO & &&
public JumpActivityCmd(String activityId, String processInstanceId,String jumpOrigin) { this.activityId = activityId; this.processInstanceId = processInstanceId; this.jumpOrigin = jumpO }
public JumpActivityCmd(String activityId, String processInstanceId) { this(activityId,processInstanceId,"jump"); }
public Object execute(CommandContext commandContext) { ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId); executionEntity.destroyScope(jumpOrigin); ProcessDefinitionImpl processDefinition = executionEntity.getProcessDefinition(); ActivityImpl activity = processDefinition.findActivity(activityId); executionEntity.executeActivity(activity); return executionE }
上一篇:没有了
activiti入门
activiti 多实例任务
Activiti自定义设计器
Activiti 多实例实现会签功能
Activiti 自定义用户管理和组管理
我来说两句
友情链接:

我要回帖

更多关于 activiti 流程节点 的文章

 

随机推荐