前言

这里我们先抛出两个大问题,整篇文章针对这两个大问题再详细解析。

首先我们在设计流程定义时,流程节点可能是或签也可能是会签

会签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,需全部同意之后,审批才可到下一审批节点。
或签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,只要其中任意一人审批即可到下一审批节点。

当前会签也可以是比例签,比如节点上的审批人同意的超过60%就算通过。此时我们需要考虑的问题如下:

问题一:被加签人如何加到节点上

问题二:加签后是否会影响节点的通过【不同通过规则的节点】

如何加签

这里还需要区分设置审批人的方式:

  1. 在发起流程实例时,一次性将所有节点的审批人全部设置完成
  2. 通过监听器来设置审批人

在设计流程定义时,节点上主要设置这几个参数

1是分配到待办任务的人,变量名和3保持一致;2是我们要传入的参数名,3是用来遍历2中集合的变量名,4是节点通过的条件。

关于怎么发布流程定义可以查看我之前的文章,不赘述了。

一次性设置审批人

    @GetMapping("/startProcessInstance")public String startProcessInstance(@RequestParam("processDefineKey")String processDefineKey,@RequestParam("businessKey")String businessKey) {Map<String, Object> map = new HashMap<>();List<String> userOneList = new ArrayList<>();userOneList.add("zhangsan");userOneList.add("lisi");List<String> userTwoList = new ArrayList<>();userTwoList.add("wangwu");userTwoList.add("maliu");map.put("initiator","lonewalker");map.put("userOneList", userOneList);map.put("userTwoList", userTwoList);ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefineKey, businessKey, map);//默认把发起人节点审批通过Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();String taskId = task.getId();taskService.complete(taskId);return processInstance.getProcessInstanceId();}

请求接口

来看一下流程图,生成两个用户任务

我们开始加签,这里流程跑到第二个节点时会创建和userOneList.size 的Task,想在这个节点加签,就得想办法让这个事件再触发一次。

    @GetMapping("/addSign")public void addSign(@RequestParam("processInstanceId")String processInstanceId,@RequestParam("nodeId")String nodeId,@RequestParam("userId")String userId){runtimeService.createProcessInstanceModification(processInstanceId).startBeforeActivity(nodeId).setVariable("userOne",userId).setAnnotation("加签").execute();}

请求接口后查看已经成功加签

按节点设置审批人

此时我们需要通过执行监听器来完成审批人的设置,两种监听器的区别可查看此篇

修改流程定义,在或签节点之前的连线上设置执行监听器。

自定义一个执行监听器

@Component
public class CustomExecutionListener implements ExecutionListener {@Overridepublic void notify(DelegateExecution execution) throws Exception {System.out.println("触发了执行监听器");List<String> userOneList = new ArrayList<>();userOneList.add("zhangsan");userOneList.add("lisi");execution.setVariable("userOneList",userOneList);}
}

发起流程实例的接口中把或签节点审批人去掉

然后部署,发起流程实例

此时我们加签的逻辑和之前一样,但是实现不一样了:

    @GetMapping("/addSign")public void addSign(@RequestParam("processInstanceId")String processInstanceId,@RequestParam("nodeId")String nodeId){//获取实例的流程定义 这里主要是为了拿到节点前的那条线的IdProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();BpmnModelInstance bpmnModel = repositoryService.getBpmnModelInstance(processInstance.getProcessDefinitionId());ModelElementInstance modelElement = bpmnModel.getModelElementById(nodeId);UserTask userTask = (UserTask) modelElement;Collection<SequenceFlow> incoming = userTask.getIncoming();String transitionId = "";if (incoming.stream().findFirst().isPresent()) {transitionId = incoming.stream().findFirst().get().getId();} else {throw new ProcessException(ErrorCodeEnum.PROC_TASK_REJECT_FAILURE);}runtimeService.createProcessInstanceModification(processInstanceId).setAnnotation("加签").startTransition(transitionId).execute();}

重新触发或签节点前连线上的执行监听器,然后加了一个sunjiu

调用加签接口后:

问题:

此时我模拟sunjiu审批,因为是或签节点按正常情况,流程会到会签节点,或签节点结束。

刚刚加签的那个人确实审批通过了,也到会签节点了,但是原先的两个人还停留在或签,看一下原因

因为重新解析了userOneList,导致加签的任务和原来的任务它们的父环节实例不一致

这是不是意味着,这两个人的其中一人审批都会再次触发会签节点前连线上的执行监听器。这明显不是我们想要的。改一下审批接口

    @GetMapping("/agreeTask")public  void agreeTask(@RequestParam("taskId")String taskId){Task task = taskService.createTaskQuery().taskId(taskId).singleResult();String processInstanceId = task.getProcessInstanceId();//完成任务taskService.complete(taskId);List<Task> activeTaskList = taskService.createTaskQuery().processInstanceId(processInstanceId).active().list();if (CollUtil.isNotEmpty(activeTaskList)){//如果nodeIdSet大于1 就说明下一节点开启待办任务了,而当前节点还有待办任务  说明刚刚处理的这个任务是或签操作Set<String> nodeIdSet = activeTaskList.stream().map(Task::getTaskDefinitionKey).collect(Collectors.toSet());if (nodeIdSet.size() > 1){//查询当前节点未完成的实例List<HistoricActivityInstance> unfinishedInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).activityId(task.getTaskDefinitionKey()).unfinished().list();if (CollUtil.isNotEmpty(unfinishedInstanceList)){//说明或签节点有加签for (HistoricActivityInstance instance : unfinishedInstanceList) {runtimeService.createProcessInstanceModification(processInstanceId).cancelActivityInstance(instance.getId()).execute();}}}}}

重新发起一条流程实例,将上述操作再走一遍:

注意:这种情况下可以一次性加多个人,但是会签就不行了,因为这种方式加签会产生多个multiInstanceBody 。 比如会签节点现在有两个审批人a、b,那它们俩的multiInstanceBody 是同一个,但是如果我用上述加签方式加签 c 后会又产生一个multiInstanceBody,当c审批通过时会触发下一节点连线上的执行监听器,a、b审批通过后又会触发一次

此时就要利用好这个Assignee变量

    @GetMapping("/addSign")public void addSign(@RequestParam("processInstanceId")String processInstanceId,@RequestParam("nodeId")String nodeId,@RequestParam("userId")String userId){runtimeService.createProcessInstanceModification(processInstanceId).startBeforeActivity(nodeId).setVariable("userTwo",userId).execute();}

 个人觉得最好的方式还是这种,而上述的也是为了提供给大家更好的思路,毕竟需求都是不一样的

扩展

有朋友会疑问为什么不用这个参数,这个相当于事先知道这个节点上有几个审批人,比如我设置5,那到这个节点就会创建5个待办任务,那如果是角色呢?所以才用上述的监听器去查询角色对应的人数,从而实现动态设置审批人

深入探究Camunda加签问题相关推荐

  1. Camunda 工作流并行子流程、工作流会签、或签、加签、比例签、跳转节点

    如下图为一个流程图,其需求过程如下: 1.某业务员发起一个登记单 2.领导审批 3.领导选择多个部门进行阅办,每个部门并行进行 4.部门内有两个审批环节(环节一:部门经理或经理助理或签,环节二:部门内 ...

  2. Camunda 多实例会签加签

    流程图: 启动流程,并初始设置为有三个实例: ProcessInstanceContact Customer - Multi-Instance BodyContact CustomerContact ...

  3. RSA体系 c++/java相互进行加签验签--转

    在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java ...

  4. java RSA 加签验签【转】

    引用自: http://blog.csdn.net/wangqiuyun/article/details/42143957/ java RSA 加签验签 package com.testdemo.co ...

  5. 工作流实战_21_flowable 加签 任务向前加签 向后加签

    项目地址 https://gitee.com/lwj/flowable.git 代码分支 flowable-base 视频讲解地址 https://www.bilibili.com/video/av7 ...

  6. signature=c9e077ef93038bf703dbc146dd834bb7,基于RSASignUtil非对称私钥进行字符串加签及公钥解密验证的完整代码示例...

    一.前言 通过之前定义RSAUtil工具类可以生成获取rsa非对称公私钥,基于私钥我们通过将字符串进行加签加密,再通过公钥进行解密验证,详情参见RSASignUtil代码工具类示例. 二.代码示例im ...

  7. activity动态加签任意节点

    前言 设想这么一种场景,一个流程有3级审批,其中第一级审批完毕后本应该到达二级审批的,但是可能觉得这个流程模板设置的不尽合理,需要再在上面增加一级审批人,即变成4级审批,这个需求该怎么做呢? 按照我们 ...

  8. java与php链条遇到的坑,记一次Java加密加签算法到php的坑

    写代码的经历中,总少不了与外部的程序对接,一旦有这样的事,往往周期会很长,很麻烦,因为你要考虑的事会多了很多,其中安全性的加密解密就是重要的一项.写代码,可以出Bug,但逼格不能弱.什么是逼格?和别人 ...

  9. python rsa库_Python中rsa模块【sign 加签验签】的使用

    安装 pip install rsa 使用一 说明:简单入门使用  使用公钥加密  ----------->> 使用私钥进行解密 1 #-*- coding:utf-8 -*- 2 imp ...

最新文章

  1. 十天学Linux内核之第二天---进程
  2. WPF使用RoutedCommand自定义命令
  3. input type=submit 和button的区别及表单提交
  4. Gulp简介、gulp基本使用步骤、gulp-cli工具、gulpfile.js文件、gulp插件
  5. 无意间发现BAT大佬总结的一份目标检测、卷积神经网络和OpenCV学习资料(教程/PPT/代码)...
  6. Windows WSL Ubuntu下配置JDK环境变量
  7. 拍照比剪刀手泄露指纹信息;国内绿 iPhone11 抢断货;PostgreSQL 12 Beta 4 发布​ | 极客头条...
  8. CSS3秘笈复习:第一章第二章第三章
  9. IT 人士工作中的十不要!
  10. MessagePack 二进制序列化格式 开发入门详解
  11. 今日尾号限行数据接口代码实现
  12. 常用电脑软件你选对了吗?(知道的不知道的,这些软件每个都值得你安装)
  13. PS教程:如何设置水彩效果?
  14. php word 生成图片,PHP导出word文档的简单实现方法(可导出图片)-Go语言中文社区
  15. Qt 设置弹出控制台终端
  16. Linux使用nvida-smi查看GPU类型
  17. (一)基于知识图谱的医疗问答系统(实例+代码理解)保姆级教程
  18. 《歪笑小说》—— 读后总结
  19. 伪类元素--before和after
  20. JAVA 输入身份证号码进行验证正误,15位转18位,并解析出生日、当前年龄、地区代码、性别

热门文章

  1. 键鼠大师脚本图片识别键鼠自动
  2. k8s NFS挂载出现 mount.nfs: access denied by server while mounting 192.168.153.128:/nfs/data
  3. 分布式系统设计之高性能、高可用与高并发
  4. InsecureRequestWarning: Unverified HTTPS request is being made to host (https请求警告)
  5. 详解SSL证书中的SSL握手协议
  6. 天天最少应念一遍《三十五佛悔悟文》——来自索达吉堪布的开示
  7. Linux 下非 root 用户 Conda 安装生物信息 R 软件包 MetaboAnalystR 演示
  8. 在Hadoop上使用R进行图度分布
  9. Google真的会被拆分吗?
  10. OSI七层网络模型与TCP/IP四层网络模型的关系