@Override
@Transactional(rollbackFor = Exception.class)
public int callBack(String processId) {

//通过流程id查找到当前的任务
List<Task> tasks= taskService.createTaskQuery()
.processInstanceId(processId)
.list();
//如果为空或者小于等于0则证明没有可查看到的任务
if (tasks == null||tasks.size()<=0) {
System.out.println("当前没有任务或者任务已执行完了");
return -1;
}
//查看所有走过的历史任务
List<HistoricTaskInstance> htlist = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processId)
.finished()
.list();
if (htlist == null||htlist.size()<=0) {
System.out.println("请先提交任务");
}
String myTaskId = null;
HistoricTaskInstance myTask = null;
//前一个任务节点,也就是提交人 拿到前一个任务
for (HistoricTaskInstance hti : htlist) {
//回退到zhangsan也就是任务A,业务中这里就是当前登录的用户名 TODO:从登录名拿
if (hti.getAssignee().equals("1")) {
myTaskId = hti.getId();

myTask = hti;
break;
}
}

if (myTask == null) {
System.out.println("这个任务不是你的任务");
}
//流程定义id
String processDefinitionId = myTask.getProcessDefinitionId();

//整个流程节点对象
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

//我的节点
String myActivityId = null;
//历史节点完成节点
List<HistoricActivityInstance> haiList =
historyService
.createHistoricActivityInstanceQuery()
.executionId(myTask.getExecutionId())
.finished()
.list();
//拿到我的节点 _3
for (HistoricActivityInstance hai : haiList) {
if (myTaskId.equals(hai.getTaskId())) {
myActivityId = hai.getActivityId();
break;
}
}
//我的流程节点
FlowNode myFlowNode =
(FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
//当前执行对象
Execution execution = runtimeService.createExecutionQuery()
.executionId(tasks.get(0).getExecutionId()).singleResult();
//当任务执行节点_4
String activityId = execution.getActivityId();

System.out.println(activityId);
//当前流程节点对象
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess()
.getFlowElement(activityId);

//记录原活动方向出方向
List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

//清理活动方向
flowNode.getOutgoingFlows().clear();

//建立新方向
List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
SequenceFlow newSequenceFlow = new SequenceFlow();
newSequenceFlow.setId("newSequenceFlowId");
newSequenceFlow.setSourceFlowElement(flowNode);
newSequenceFlow.setTargetFlowElement(myFlowNode);
newSequenceFlowList.add(newSequenceFlow);
flowNode.setOutgoingFlows(newSequenceFlowList);
//设置操作人记录 和备注信息
Authentication.setAuthenticatedUserId("zhangsan");
taskService.addComment(tasks.get(0).getId(), tasks.get(0).getProcessInstanceId(), "撤回");
String taskId= tasks.get(0).getId();
//完成任务
if (tasks.size() > 1) {
//会签撤回
HashMap<String, Object> variables = new HashMap<>();
variables.put("pass",true);
// variables.put("param","y");
taskService.complete(taskId,variables);
//恢复原方向
flowNode.setOutgoingFlows(oriSequenceFlows);
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(tasks.get(0).getProcessInstanceId()).singleResult();
//更新数据库 从新设置state为未提交状态
Apply apply = new Apply();
apply.setCode(processInstance.getBusinessKey());
apply.setState(0);

return applyService.updateByCode(apply);
}
//普通撤回
taskService.complete(taskId);
//恢复原方向
flowNode.setOutgoingFlows(oriSequenceFlows);
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(tasks.get(0).getProcessInstanceId()).singleResult();
//更新数据库 从新设置state为未提交状态
Apply apply = new Apply();
apply.setCode(processInstance.getBusinessKey());
apply.setState(0);

return applyService.updateByCode(apply);
}

actviti7撤回操作的更多相关文章

  1. winfrom保存图片,将文件夹中图片放入listview,与撤回操作

    之前那些操作完成对图片的修改之后,就是要保存图片了. 这里保存用到一个SaveFileDialog控件,可以获取用户选择的保存文件的路径. ) { SaveFileDialog saveImageDi ...

  2. git commit撤回操作

    git commit 之后没有push,怎么回撤commit操作呢? $ git reset HEAD~

  3. Python3.5+PyQt5多线程+itchat实现微信防撤回桌面版代码

    weChatThread线程类 之前一直不会python多线程,写这个程序的时候,发现不用多线程会陷入无限未响应状态.于是学了半天python多线程,但是在主函数里写的时候,发现一个问题,Ui主线程和 ...

  4. vim操作(待补充)

    :wq 存盘 + 退出 (:w 存盘, :q 退出) :e 打开新文件 :q 退出 h.j.k.l,分别控制光标左.下.上.右移一格. 按Ctrl+B:屏幕往后移动一页.[常用] 按Ctrl+F:屏幕 ...

  5. unity编辑器扩展_05(删除游戏对象并具有撤回功能)

    代码: [MenuItem("Tools/Delete",false,1)]    static void Delete()    {        GameObject[] go ...

  6. Windows常用快捷操作

    Windows操作系统作为目前最广泛使用的PC端OS,掌握一些快捷键,方便快速在Windows系统下进行操作. 下面收集整理了一些常用的快捷操作: Ctrl + A   全选 Ctrl + C   复 ...

  7. HANA SQL

    约束 注释 你可以给你的 SQL 语句添加注释来增加可读性和可维护性. SQL 语句中注释的分隔如下: l  双连字符“--”.所有在双连字符之后直到行尾的内容都被 SQL 解析器认为是注释. l  ...

  8. 小杨同学git使用记(适合使用过git但是不熟练的童鞋)

    首先声明:这不是一篇git使用手册或者指南,如果要详细的git使用指南,下面是廖雪峰的git教程,可以系统学习廖雪峰的git教程,当然,如果你想马上以一种正确的方式使用git,那么接下来你很快就会学会 ...

  9. CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)

    JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...

随机推荐

  1. Docker存储(4)

    一.docker存储资源类型 用户在使用 Docker 的过程中,势必需要查看容器内应用产生的数据,或者需要将容器内数据进行备份,甚至多个容器之间进行数据共享,这必然会涉及到容器的数据管理 (1)Da ...

  2. IDEA 自定义文件头注释

    什么是 IDEA 自定义文件头注释 IDEA 自定义文件头注释指的是创建 Java 类文件时,IDEA 可以自动设置文件头的注释信息,如下: 如何设置 IDEA 自定义文件头注释 打开 File-&g ...

  3. 03丨认识文档数据库MongoDB

  4. java_[类加载器]

    Class 与 类加载 Class对象由JVM自动产生,每当一个类被加载时,JVM就自动为其生成一个Class对象,通过Class对象可以获得类的相关信息. 将类信息读到内存中过程,称为类加载 Jav ...

  5. 3D网页小实验-基于Babylon.js与recast.js实现RTS式单位控制

    一.运行效果 1.建立一幅具有地形起伏和不同地貌纹理的地图: 地图中间为凹陷的河道,两角为突出的高地,高地和低地之间以斜坡通道相连. 水下为沙土材质,沙土材质网格贴合地形,河流材质网格则保持水平. 2 ...

  6. Elasticsearch常用DSL关键字

    Elasticsearch常用DSL关键字 query: 用于包含查询使用到的语法 match_all: 最简单的查询,获取索引所有数据,类似搜索 *.如:"query":{&qu ...

  7. es 查询更新操作

    # es 查询更新操作# _*_ coding: utf-8 _*_ import time import datetime import pymysql from elasticsearch imp ...

  8. python操作kafka

    python操作kafka 一.什么是kafka kafka特性: (1) 通过磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能. (2) 高吞吐量 :即使是 ...

  9. pytest - 失败重运行机制:rerun

    失败重运行机制 用例失败的情况下,可以重新运行用例 一旦用例失败,马上重新运行 安装插件:pip install pytest-rerunfailures 使用命令:--reruns 重试次数 如 - ...

  10. 第一个 Angular 应用程序

    node download https://nodejs.org/zh-cn/ 全局安装 npm install @angular/cli -g 指定版本 npm install @angular/c ...