@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. go输出九九乘法表和金字塔

    用go语言实现输出九九乘法表和金字塔: 1.输出九九乘法表: 代码示例: package main import ( "fmt" "time" ) //实现99 ...

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

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

  3. idea配置javaweb项目(最新版)

    idea(最新版)配置javaweb项目 本篇文章使用Maven构建javaweb环境 最新版maven压缩包 链接:https://pan.baidu.com/s/1El7b3YzPTZX-7QRE ...

  4. Jenkins 入门介绍

    一.概念 近几年,DevOps理念一致处于一个比较热门的状态.我每个月在工作群或者技术交流群都会看到这个名词出现.前年,当我第一次看到这个"DevOps",我压根不知道这是一个什么 ...

  5. GitHub上YOLOv5开源代码的训练数据定义

    GitHub上YOLOv5开源代码的训练数据定义 代码地址:https://github.com/ultralytics/YOLOv5 训练数据定义地址:https://github.com/ultr ...

  6. 多加速器驱动AGX的目标检测与车道分割

    多加速器驱动AGX的目标检测与车道分割 Object Detection and Lane Segmentation Using Multiple Accelerators with DRIVE AG ...

  7. 特斯拉Tesla Model 3整体架构解析(上)

    特斯拉Tesla Model 3整体架构解析(上) 一辆特斯拉 Model 3型车在硬件改造后解体 Sensors for ADAS applications 特斯拉 Model 3型设计的传感器组件 ...

  8. 面试官:说一下JVM常用垃圾回收器的特点、优劣势、使用场景和参数设置

    今天去看牙医,他问我年级轻轻牙齿怎么磨损这么严重?我说,没有人点赞的这些年,我都是咬着牙过来的. Java中的垃圾回收器几乎是面试中的必考点,无论是面试初级,中级还是高级,总免不了要问一问垃圾回收器的 ...

  9. C#-防止用户输入具有风险的敏感字符

    最近有涉及到要防止用户在网页文本框中输入具有风险的敏感字符所以特地编写了一套针对用户输入的字符进行安全过滤的一个方法,在后台接收到用户输入的字符后调用执行该方法即可完成过滤操作,主要使用正则来匹配并替 ...

  10. 03:进程Queue --- 生产者消费者模型

    1 进程Queue介绍 1 进程间数据隔离,两个进程进行通信,借助于Queue​2 进程间通信:IPC -借助于Queue实现进程间通信    -借助于文件        -借助于数据库    -借助 ...