美文网首页
Activiti 会签

Activiti 会签

作者: 指下光年 | 来源:发表于2023-03-09 18:21 被阅读0次

    Activiti 会签

    在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务。这种业务需求很常见,如一个请款单领导审批环节中就需要多个部门领导签字。在流程业务中,我们可以把每个领导签字的环节都定义为任务,并且这个会签的人员是不固定的,若固定的我们可以通过Activiti的并行任务或串行任务来处理。会签的引入说明,无非就是为了流程流转至某一环节点,其审批的人员是动态的,并且需要根据会签审批的结果实现流程的不同流转。

    利用activiti实现会签功能

    实现步骤:首先在画流程图时,userTask 节点中有 多实例类型(multiinstance_type) 属性(此属性有两个选项(默认空):parallel(会签,没顺序)、sequential(串签,顺序执行)),选择parallel以后设置集合(多实例)

    image.png

    生成的xml文件代码:

    <userTask id="s3" name="会签">
       <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}"/>
    </userTask>
    

    然后userList设置流程变量,或者监听器设置value

    userTask节点配置核心属性说明

    1. isSequential指定多实例是按照并行或者串行的方式进行,当isSequential=true时,表示的串行执行,即虽然该节点有多条任务,但只有上一条执行完,才可以执行下一条。当isSequential=false时,表示的并行执行,即该节点下的多条任务可以同时执行,如三个人参与会签,是三个人同时收到待办,任务实例是同时产生的。

    2. activiti:collection:用于执行该会签环节的参与参与的人,可以用形如实例中的${leaderList}获取,也可以用户可以通过定义自身的服务类来获取

    3. activiti:elementVariable:此处表示的是每一个分支都有一个名叫leader的流程变量和userTask节点属性中的activiti:assignee="${leader}"一致

    4. completionCondition:指定会签环节的结束条件,表示是任务往下跳转的完成条件,返回true是,表示条件成立,流程会跳至下一审批环节

    会签的种类:

    • 按数量通过: 达到一定数量的通过表决后,会签通过。

    • 按比例通过: 达到一定比例的通过表决后,会签通过。

    • 一票否决: 只要有一个表决时否定的,会签通过。

    • 一票通过: 只要有一个表决通过的,会签通过。

    每个实例有以下变量:

    • nrOfInstances: 实例总数

    • nrOfActiveInstances: 当前激活的(未完成的)实例总数。 如果串行执行,则改值永远是1

    • nrOfCompletedInstances: 已完成的实例总数 条件nrOfInstances == nrOfCompletedInstances表示所有人员审批完成后会签结束。 条件${ nrOfCompletedInstances == 1 }表示一个人完成审批,该会签就结束。

    其他条件依次类推,同时这里也可以写自己添加的流程变量。

    会签(多实例节点)环节中涉及的几个默认的流程变量

    1. nrOfInstances 该会签环节中总共有多少个实例

    2. nrOfActiveInstances 当前活动的实例的数量,即还没有 完成的实例数量。

    3. nrOfCompletedInstances 已经完成的实例的数量

    会签人员部分示例代码

    1. 分配会签人员
    Map<String, Object> vars = new HashMap<>();
     List<String> leaderList = new ArrayList<>();
     leaderList.add("zhangsan");
     leaderList.add("lisi");
     leaderList.add("wangwu");
    
     vars.put("leaderList", leaderList);
    
     ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), vars);
    
    1. 会签人员审批
    Map<String, Object> leaderOneAudit = new HashMap<>();
     Scanner scanner = new Scanner(System.in);
     System.out.println("请输入领导审批意见。。。。");
     String auditOne = scanner.nextLine();
     leaderOneAudit.put("audit", auditOne);
     System.out.println("张三的审批意见为:" + (auditOne.equals("yes") ? "同意" : "不同意"));
     task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee("zhangsan").singleResult();
     taskService.complete(task.getId(), leaderOneAudit);
    
    1. 示例代码控制台结果输出
    填写申请|assignee:worker
    请输入领导审批意见。。。。
    yes
    张三的审批意见为:同意
    流程实例总数:3
    当前活动的流程实例总数:3
    已经完成实例的数目:0
    leader:zhangsan
    ---------------------------------------分隔线----------------------------------------------------
    taskName2:领导审批|assignee:zhangsan
    --------------------------------------------
    请输入领导审批意见。。。。
    yes
    李四的审批意见为:同意
    流程实例总数:3
    当前活动的流程实例总数:2
    已经完成实例的数目:1
    leader:lisi
    ---------------------------------------分隔线----------------------------------------------------
    taskName3:领导审批|assignee:lisi
    --------------------------------------------
    请输入领导审批意见。。。。
    yes
    李四的审批意见为:同意
    流程实例总数:3
    当前活动的流程实例总数:1
    已经完成实例的数目:2
    leader:wangwu
    ---------------------------------------分隔线----------------------------------------------------
    taskName4:领导审批|assignee:wangwu
    taskName5:人事归档|assignee:hr
    ----------------------------------流程实例流转-----------------------
    任务ID:75014
    流程实例ID:75005
    任务名称:填写申请
    办理人:worker
    开始时间:Tue Jul 31 10:12:39 CST 2018
    结束时间:Tue Jul 31 10:12:39 CST 2018
    =================================
    任务ID:75028
    流程实例ID:75005
    任务名称:领导审批
    办理人:zhangsan
    开始时间:Tue Jul 31 10:12:39 CST 2018
    结束时间:Tue Jul 31 10:12:43 CST 2018
    =================================
    任务ID:75031
    流程实例ID:75005
    任务名称:领导审批
    办理人:lisi
    开始时间:Tue Jul 31 10:12:39 CST 2018
    结束时间:Tue Jul 31 10:12:49 CST 2018
    =================================
    任务ID:75034
    流程实例ID:75005
    任务名称:领导审批
    办理人:wangwu
    开始时间:Tue Jul 31 10:12:39 CST 2018
    结束时间:Tue Jul 31 10:12:56 CST 2018
    =================================
    任务ID:75038
    流程实例ID:75005
    任务名称:人事归档
    办理人:hr
    开始时间:Tue Jul 31 10:12:56 CST 2018
    结束时间:Tue Jul 31 10:12:56 CST 2018
    =================================
    

    如何通过代码设置多实例属性

    本例中的流程图都是通过ide的插件画出来,而在web开发中,如何通过代码把会签的多实例的属性给实现出来,可能不同人有不同的实现方式。我这边提供一种实现,废话有点多,直接上代码

    1. 设置会签节点属性
    public static void setMultiInstance(String modelId, String nodelId) throws Exception {
     // 获取模型
     byte[] mes = repositoryService.getModelEditorSource(modelId);
     // 转换成JsonNode
     JsonNode jsonNode = objectMapper.readTree(mes);
     // 转换成BpmnModel
     BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();
     BpmnModel bpmnModel = bpmnJsonConverter.convertToBpmnModel(jsonNode);
     // 获取物理形态的流程
     Process process = bpmnModel.getProcesses().get(0);
     // 获取节点信息
     FlowElement flowElement = process.getFlowElement(nodelId);
     // 只有人工任务才可以设置会签节点
     UserTask userTask = (UserTask) flowElement;
     // 设置受理人,这里应该和ElementVariable的值是相同的
     userTask.setAssignee("${" + Constant.ACT_MUIT_VAR_NAME + "}");
     // userTask.setOwner("${user}");
    
     // 获取多实例配置
     MultiInstanceLoopCharacteristics characteristics = new MultiInstanceLoopCharacteristics();
     // 设置集合变量,统一设置成users
     characteristics.setInputDataItem(Constant.ACT_MUIT_LIST_NAME);
     // 设置变量
     characteristics.setElementVariable(Constant.ACT_MUIT_VAR_NAME);
     // 设置为同时接收(false 表示不按顺序执行)
     characteristics.setSequential(false);
     // 设置条件(暂时处理成,全部会签完转下步)
     characteristics.setCompletionCondition("${nrOfCompletedInstances==nrOfInstances}");
    
     userTask.setLoopCharacteristics(characteristics);
     // 保存
     ObjectNode objectNode = new BpmnJsonConverter().convertToJson(bpmnModel);
     repositoryService.addModelEditorSource(modelId, objectNode.toString().getBytes("utf-8"));
     }
    
    1. 清空会签属性
    public static void clearMultiInstance(String modelId, String nodelId) throws Exception {
     // 获取模型
     byte[] mes = repositoryService.getModelEditorSource(modelId);
     // 转换成JsonNode
     JsonNode jsonNode = new ObjectMapper().readTree(mes);
     // 转换成BpmnModel
     BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();
     BpmnModel bpmnModel = bpmnJsonConverter.convertToBpmnModel(jsonNode);
     // 获取物理形态的流程
     Process process = bpmnModel.getProcesses().get(0);
     // 获取节点信息
     FlowElement flowElement = process.getFlowElement(nodelId);
     // 只有人工任务才可以设置会签节点
     UserTask userTask = (UserTask) flowElement;
     // 清空受理人
     userTask.setAssignee("");
     // 获取多实例配置
     MultiInstanceLoopCharacteristics characteristics = userTask.getLoopCharacteristics();
     if (characteristics != null) {
     // 清空集合
     characteristics.setInputDataItem("");
     // 清空变量
     characteristics.setElementVariable("");
     // 设置为顺序接收(true 表示不按顺序执行)
     characteristics.setSequential(true);
     // 清空条件
     characteristics.setCompletionCondition("");
     }
    
     // 保存
     ObjectNode objectNode = new BpmnJsonConverter().convertToJson(bpmnModel);
     repositoryService.addModelEditorSource(modelId, objectNode.toString().getBytes("utf-8"));
     }
    

    https://www.jianshu.com/p/bcfd2a31abb4

    相关文章

      网友评论

          本文标题:Activiti 会签

          本文链接:https://www.haomeiwen.com/subject/cwxzldtx.html