BPMN2.0,flowable工作流,【用户任务】使用【任务监听器】动态设置下一步处理人

1、环境

前端:BPMN2.0.js

后端:flowable:6.8.0

2、流程信息

流程图:

各节点信息:

节点名称 节点id
开始 ks
登记 dj
员工 yg
领导审批 ldsp
结束 js

3、需求

【领导审批】节点的审批人需要根据【员工】节点的提交人所属部门来确定。比如(人事部)的需要(人事主管)来审批;(开发部)的需要(技术经理)来审批。

4、思路

【任务监听器】:

在【任务监听器】中做逻辑的判断,动态设置【领导审批】节点的【实际处理人】、【候选人】、【候选组】。在【领导审批】节点中配置【任务监听器】,【任务监听器】配置class="com.cn.workflow.flowable.listener.SetAssigneeListener" event="create",详细查看文章最后的流程文件。

5、代码实现

java 复制代码
package com.cn.workflow.flowable.listener;

import cn.hutool.extra.spring.SpringUtil;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;

import java.util.Map;

public class SetAssigneeListener implements TaskListener {
    private static final long serialVersionUID = 1L;
    private TaskService taskService = SpringUtil.getBean(TaskService.class);
    //获取需要执行的sql的Mapper
    private WfBusinessInfoMapper wfBusinessInfoMapper=     SpringUtil.getBean(WfBusinessInfoMapper.class);
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("用户任务监听器-设置下一节点信息...start");
        //获取任务ID
        String taskId = delegateTask.getId();
        //获取当前处理人
        String assignee = delegateTask.getAssignee();
        //根据当前处理人所属部门做判断,判断下一步具体的实际处理人、候选处理人活候选组
        String deptName = wfBusinessInfoMapper.getDeptByUserName(assignee);
        //具体判断代码省略
        
        //设置处理人,如果原来设置了实际办理人,要先删除办理人,再新增候选组
        taskService.deleteUserIdentityLink(taskId,"yuangong001", IdentityLinkType.ASSIGNEE);//删除当前节点的处理人,可以删除多个,执行多条
        taskService.setAssignee(taskId,"zhuguan001");//设置实际办理人,实际办理人只能有一个
        taskService.addGroupIdentityLink(taskId,TaskConstants."ROLE123456", IdentityLinkType.CANDIDATE);//新增候选组,可以新增多个,执行多条
        taskService.deleteGroupIdentityLink(taskId, TaskConstants."ROLE123456", IdentityLinkType.CANDIDATE);//删除候选组,可以删除多个,执行多条
        taskService.addUserIdentityLink(taskId, "yuangong001", IdentityLinkType.CANDIDATE);//新增下一步候选人,可以新增多个,执行多条
        System.out.println("用户任务监听器-设置下一节点信息...end");
    }

}

6、流程文件

flowable.xml:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" id="diagram_Process_1761616908502" targetNamespace="http://flowable.org/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  <bpmn2:process id="Process_1761616908502" name="审批流程" isExecutable="true">
    <bpmn2:startEvent id="ks" name="开始">
      <bpmn2:outgoing>Flow_0zttbj2</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:userTask id="yg" name="员工" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
      <bpmn2:incoming>fq</bpmn2:incoming>
      <bpmn2:incoming>th</bpmn2:incoming>
      <bpmn2:outgoing>sq</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:userTask id="ldsp" name="领导审批" flowable:dataType="ROLES" flowable:candidateGroups="ROLE123456" flowable:text="领导">
      <bpmn2:extensionElements>
        <flowable:taskListener class="com.cn.workflow.flowable.listener.SetAssigneeListener" event="create" />
      </bpmn2:extensionElements>
      <bpmn2:incoming>sq</bpmn2:incoming>
      <bpmn2:outgoing>Flow_13elc6g</bpmn2:outgoing>
      <bpmn2:outgoing>th</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:endEvent id="js" name="结束">
      <bpmn2:incoming>Flow_13elc6g</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="Flow_13elc6g" name="提交" sourceRef="ldsp" targetRef="js">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${nextNodeId=="js"}</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="fq" name="发起" sourceRef="dj" targetRef="yg" />
    <bpmn2:sequenceFlow id="sq" name="申请" sourceRef="yg" targetRef="ldsp" />
    <bpmn2:sequenceFlow id="th" name="退回" sourceRef="ldsp" targetRef="yg">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${nextNodeId=="yg"}</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:userTask id="dj" name="登记" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
      <bpmn2:incoming>Flow_0zttbj2</bpmn2:incoming>
      <bpmn2:outgoing>fq</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:sequenceFlow id="Flow_0zttbj2" sourceRef="ks" targetRef="dj" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1761616908502">
      <bpmndi:BPMNEdge id="Flow_0zttbj2_di" bpmnElement="Flow_0zttbj2">
        <di:waypoint x="38" y="239" />
        <di:waypoint x="110" y="239" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="th_di" bpmnElement="th">
        <di:waypoint x="550" y="199" />
        <di:waypoint x="550" y="170" />
        <di:waypoint x="336" y="170" />
        <di:waypoint x="336" y="199" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="432" y="152" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="sq_di" bpmnElement="sq">
        <di:waypoint x="386" y="239" />
        <di:waypoint x="500" y="239" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="432" y="221" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fq_di" bpmnElement="fq">
        <di:waypoint x="210" y="239" />
        <di:waypoint x="286" y="239" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="235" y="221" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_13elc6g_di" bpmnElement="Flow_13elc6g">
        <di:waypoint x="600" y="239" />
        <di:waypoint x="682" y="239" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="635" y="217" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="ks_di" bpmnElement="ks">
        <dc:Bounds x="2" y="221" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="10" y="264" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="yg_di" bpmnElement="yg">
        <dc:Bounds x="286" y="199" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ldsp_di" bpmnElement="ldsp">
        <dc:Bounds x="500" y="199" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="js_di" bpmnElement="js">
        <dc:Bounds x="682" y="221" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="691" y="264" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="dj_di" bpmnElement="dj">
        <dc:Bounds x="110" y="199" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>
相关推荐
缓慢更新4 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
LMT流氓兔5 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
wangbing11256 小时前
平台介绍-modbus设备调试
java
西索斯coding7 小时前
gpt-image-2.5-sunburst 和 gemini-3.1-flash-image 差多少?60 组项目素材的成功成本评测框架
java·linux·gpt·ai
wuminyu7 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++
Flynn Liang8 小时前
大模型怎么自己调函数?Spring AI 2.0 Tool Calling 自动循环原理 + 完整时序图
java·人工智能·spring·agent·函数调用·springai·toolcalling
乌暮9 小时前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring
学长毕设9 小时前
基于SpringBoot的烘焙商品商品系统-附源码
java·spring boot·后端
金銀銅鐵9 小时前
[Java] 用纯 Swing 做一个《論語·學而》阅读器
java·ai编程·交互设计
艾伦_耶格宇10 小时前
【kubernetes - 1.28版本】-11 K8S核心组件
java·容器·kubernetes