基于jeecgboot-vue3的Flowable流程-集成仿钉钉流程(二)增加基本的发起人审批与多用户多实例

 因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。

1、AssigneeNode 增加approvalText

public abstract class AssigneeNode extends Node {
    // 审批对象
    private AssigneeTypeEnum assigneeType;
    // 表单内人员
    private String formUser;
    // 表单内角色
    private String formRole;
    // 审批人
    private List<String> users;
    // 审批人角色
    private List<String> roles;
    // 审批人名称
    private String approvalText;
    // 主管
    private Integer leader;
    // 组织主管
    private Integer orgLeader;
    // 发起人自选:true-单选,false-多选
    private Boolean choice;
    // 发起人自己
    private Boolean self;
    public abstract List<FlowElement> convert();
}

2、对于public List<FlowElement> convert() {流程转换,做如下调整

// 审批人
        if(this.getMulti() !=  ApprovalMultiEnum.NONE) {
        	MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = new MultiInstanceLoopCharacteristics();
            if (this.getMulti() == ApprovalMultiEnum.SEQUENTIAL) {
                multiInstanceLoopCharacteristics.setSequential(true);
            } else if (this.getMulti() == ApprovalMultiEnum.JOINT) {
                multiInstanceLoopCharacteristics.setSequential(false);
                if (Objects.nonNull(this.getMultiPercent()) && this.getMultiPercent().compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal percent = this.getMultiPercent().divide(new BigDecimal(100), 2, RoundingMode.DOWN);
                    multiInstanceLoopCharacteristics.setCompletionCondition(String.format("${nrOfCompletedInstances/nrOfInstances >= %s}", percent));
                }
            } else if (this.getMulti() == ApprovalMultiEnum.SINGLE) {
                multiInstanceLoopCharacteristics.setSequential(false);
                multiInstanceLoopCharacteristics.setCompletionCondition("${nrOfCompletedInstances > 0}");
            }
            multiInstanceLoopCharacteristics.setElementVariable("assignee");
            multiInstanceLoopCharacteristics.setInputDataItem(String.format("${multiInstanceHandler.getUserName(execution)}"));
            userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);
            userTask.setAssignee("${assignee}");
            userTask.setCandidateUsers(this.getUsers());
            ExtensionAttribute extDataTypeAttribute =  new ExtensionAttribute();
            extDataTypeAttribute.setNamespace(ProcessConstants.NAMASPASE);
    		extDataTypeAttribute.setName("dataType");
    		extDataTypeAttribute.setValue("USERS");
    		userTask.addAttribute(extDataTypeAttribute);
    		ExtensionAttribute extTextAttribute =  new ExtensionAttribute();
    		extTextAttribute.setNamespace(ProcessConstants.NAMASPASE);
    		extTextAttribute.setName("text");
    		extTextAttribute.setValue(this.getApprovalText());
    		userTask.addAttribute(extTextAttribute);
        }
    	if(this.getAssigneeType() == AssigneeTypeEnum.SELF) {
    		userTask.setName("发起人");
    		ExtensionAttribute extAttribute =  new ExtensionAttribute();
    		extAttribute.setNamespace(ProcessConstants.NAMASPASE);
    		extAttribute.setName("dataType");
    		extAttribute.setValue("INITIATOR");
    		userTask.addAttribute(extAttribute);
    		userTask.setAssignee("${initiator}");
    	}
    	else {
    		userTask.setAssignee(String.join(",", this.getUsers()));
    	}  

3、对应多人审批增加none方式

export interface ApprovalNode extends AssigneeNode {
  // 多人审批方式
  multi: 'none' | 'sequential' | 'joint' | 'single'

4、对应人员审批采用jeecg的j-select-user-by-dept

<div style="width:100%">
            <j-select-user-by-dept 
              v-if="activeData.nobody === 'assign'"
              v-model:value="activeData.nobodyUsers" 
              :multi="true" 
              placeholder="指定人员"
              @getSelectResult="handleSelectUsers">
            </j-select-user-by-dept>
          </div>

同时上面的方法如下

const  handleSelectUsers = (options, userList) => {
    props.activeData.approvalText = options.map((user) => user.label).join(',')
}    

5、仿钉钉流程设置如下

6、生成的xml如下:

<?xml version="1.0" encoding="UTF-8"?>

-<definitions targetNamespace="https://flowable.org/bpmn20" expressionLanguage="http://www.w3.org/1999/XPath" typeLanguage="http://www.w3.org/2001/XMLSchema" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">


-<process isExecutable="true" name="测试" id="test">

<startEvent name="发起人" id="root"/>

<sequenceFlow id="root-node_nfntd" targetRef="node_nfntd" sourceRef="root"/>

<userTask name="发起人" id="node_nfntd" flowable:dataType="INITIATOR" flowable:assignee="${initiator}"/>

<sequenceFlow id="node_nfntd-node_wusut" targetRef="node_wusut" sourceRef="node_nfntd"/>


-<userTask name="审批人" id="node_wusut" flowable:dataType="USERS" flowable:assignee="zhangsan,admin" flowable:text="张三,管理员" flowable:candidateUsers="zhangsan,admin">


-<multiInstanceLoopCharacteristics flowable:elementVariable="assignee" flowable:collection="${multiInstanceHandler.getUserName(execution)}" isSequential="false">

<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 1.00}</completionCondition>

</multiInstanceLoopCharacteristics>

</userTask>

<sequenceFlow id="node_wusut-end" targetRef="end" sourceRef="node_wusut"/>

<endEvent name="流程结束" id="end"/>

</process>


-<bpmndi:BPMNDiagram id="BPMNDiagram_test">


-<bpmndi:BPMNPlane id="BPMNPlane_test" bpmnElement="test">


-<bpmndi:BPMNShape id="BPMNShape_node_wusut" bpmnElement="node_wusut">

<omgdc:Bounds y="0.0" x="230.0" width="100.0" height="60.0"/>

</bpmndi:BPMNShape>


-<bpmndi:BPMNShape id="BPMNShape_root" bpmnElement="root">

<omgdc:Bounds y="15.0" x="0.0" width="30.0" height="30.0"/>

</bpmndi:BPMNShape>


-<bpmndi:BPMNShape id="BPMNShape_node_nfntd" bpmnElement="node_nfntd">

<omgdc:Bounds y="0.0" x="80.0" width="100.0" height="60.0"/>

</bpmndi:BPMNShape>


-<bpmndi:BPMNShape id="BPMNShape_end" bpmnElement="end">

<omgdc:Bounds y="15.0" x="380.0" width="30.0" height="30.0"/>

</bpmndi:BPMNShape>


-<bpmndi:BPMNEdge id="BPMNEdge_node_wusut-end" bpmnElement="node_wusut-end">

<omgdi:waypoint y="30.0" x="330.0"/>

<omgdi:waypoint y="30.0" x="342.0"/>

<omgdi:waypoint y="30.000000000000004" x="342.0"/>

<omgdi:waypoint y="30.000000000000004" x="380.0"/>

</bpmndi:BPMNEdge>


-<bpmndi:BPMNEdge id="BPMNEdge_node_nfntd-node_wusut" bpmnElement="node_nfntd-node_wusut">

<omgdi:waypoint y="30.0" x="180.0"/>

<omgdi:waypoint y="30.0" x="192.0"/>

<omgdi:waypoint y="30.000000000000007" x="192.0"/>

<omgdi:waypoint y="30.000000000000007" x="230.0"/>

</bpmndi:BPMNEdge>


-<bpmndi:BPMNEdge id="BPMNEdge_root-node_nfntd" bpmnElement="root-node_nfntd">

<omgdi:waypoint y="30.0" x="30.0"/>

<omgdi:waypoint y="30.0" x="42.0"/>

<omgdi:waypoint y="30.000000000000007" x="42.0"/>

<omgdi:waypoint y="30.000000000000007" x="80.0"/>

</bpmndi:BPMNEdge>

</bpmndi:BPMNPlane>

</bpmndi:BPMNDiagram>

</definitions>

7、导入流程设计器图如下,满足实际的需求:

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 21:42:06       49 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 21:42:06       53 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 21:42:06       42 阅读
  4. Python语言-面向对象

    2024-07-09 21:42:06       53 阅读

热门阅读

  1. MySQL8之mysql-community-common的作用

    2024-07-09 21:42:06       21 阅读
  2. 机器学习综述

    2024-07-09 21:42:06       20 阅读
  3. Qt | Qt常用类列举和说明

    2024-07-09 21:42:06       19 阅读
  4. chatgpt工作原理

    2024-07-09 21:42:06       21 阅读
  5. 在make类构建系统配置文件中定义函数宏

    2024-07-09 21:42:06       19 阅读
  6. lvs集群

    lvs集群

    2024-07-09 21:42:06      19 阅读
  7. 记录Linux安装go环境的一个坑

    2024-07-09 21:42:06       19 阅读
  8. Python开发——Python 字典的使用

    2024-07-09 21:42:06       19 阅读
  9. 流媒体技术

    2024-07-09 21:42:06       22 阅读