@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. Lua中的元表(metatable)、元方法(metamethod)详解

    在第一次看见这两样东西的时候,可能会觉得它很深奥,但其实很好理解,虽然实际上它可能真的很深奥.(小若:停!滚粗.) 1.知道为什么1 + 1 = 2吗? 为什么在Lua中,1+1会等于2呢?(小若:难 ...

  2. 行业资讯 | Android WebView 致安卓应用闪退,mPaaS 助你规避这波 Bug

    根据外媒 9to5 Google 报道,3 月 23 日几个小时内,大量安卓用户遇到一些安卓应用连续闪退的情况,有人发现卸载安卓系统 WebView 就可以停止闪退.目前,谷歌已经发布了应用崩溃问题的 ...

  3. 目标形体形状轮廓重建:ICCV2019论文解析

    目标形体形状轮廓重建:ICCV2019论文解析 Shape Reconstruction using Differentiable Projections and Deep Priors 论文链接: ...

  4. GeforceRTX系列参数对比

    GeforceRTX系列参数对比

  5. 在cuDNN中简化Tensor Ops

    在cuDNN中简化Tensor Ops 在Tesla V100 GPU中引入神经网络模型以来,神经网络模型已迅速利用NVIDIA Tensor Cores进行深度学习.例如,基于Tensor Core ...

  6. 理解 this

    this this 取什么值是在函数执行的时候确认的,不是在函数定义的时候确认的 this 的不同应用场景,this 的指向 函数在调用时,js 会默认给 this 绑定一个值,this 的值与绑定方 ...

  7. JUC 并发编程--10, 阻塞队列之--LinkedBlockingDeque 工作窃取, 代码演示

    直接上代码 class LinkedBlockingDequeDemo { // 循环是否结束的开关 private static volatile boolean flag1 = true; pri ...

  8. 用CLion实现本地方法并给java调用

    众所周知,PHP是世界上最好的语言,java排第二,因为PHP无所不能.但是在某些场景下java还要调用本地方法来提高执行的效率,故java只能排第二.java提供了jni(Java Native I ...

  9. Idea快捷键大全(Windows)

    Ctrl 快捷键 介绍 Ctrl + F 在当前文件进行文本查找 (必备) Ctrl + R 在当前文件进行文本替换 (必备) Ctrl + Z 撤销 (必备) Ctrl + Y 删除光标所在行 或 ...

  10. 重新整理 .net core 实践篇—————中间件[十九]

    前言 简单介绍一下.net core的中间件. 正文 官方文档已经给出了中间件的概念图: 和其密切相关的是下面这两个东西: IApplicationBuilder 和 RequestDelegate( ...