Flowable——UserTask和异构的业务权限适配

UserTask

无论在那个流程引擎中,UserTask都是其核心Activity之一,我们的流程或多或少都会有人参与其中,所以这篇博客主要讲解一下如何对usertask进行操作
,而且最重要的是,流程引擎作为一个中间件的角色,我们的业务系统在接入的时候,会涉及到角,权限问题,比如:我们规定这个UserTask谁来操作,那些
指定的人来做,直接接入我们自己单独的业务系统的权限管理进行控制。

走案例

工作流视图
下面看一下这个流程的xml内容:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
  <process id="taskuser" name="taskuserdemo" isExecutable="true">
    <documentation>用来测试taskuser</documentation>
    <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
    <userTask id="sid-E6BEE15E-5E0C-4CB6-8429-EF04E154EB07" name="task1" flowable:assignee="jack" flowable:formFieldValidation="true">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-63BFAE0B-3C2B-40B0-BBD7-9F50E7E640B1" sourceRef="startEvent1" targetRef="sid-E6BEE15E-5E0C-4CB6-8429-EF04E154EB07"></sequenceFlow>
    <userTask id="sid-7F157B39-8EF6-44D5-AF6F-131F7E811CA5" name="task2" flowable:assignee="${taskuser}" flowable:formFieldValidation="true">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-DF243F47-88E5-42F6-BC75-39E0383E6FCB" sourceRef="sid-E6BEE15E-5E0C-4CB6-8429-EF04E154EB07" targetRef="sid-7F157B39-8EF6-44D5-AF6F-131F7E811CA5"></sequenceFlow>
    <userTask id="sid-F7354E79-68EA-4F5F-8059-BE841CC1E1A8" name="task3" flowable:formFieldValidation="true">
      <extensionElements>
        <flowable:taskListener event="create" class="com.example.flowable.listener.TaskAssigneeListener"></flowable:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-204CEF7D-C334-4D4B-8897-96D99AA2E595" sourceRef="sid-7F157B39-8EF6-44D5-AF6F-131F7E811CA5" targetRef="sid-F7354E79-68EA-4F5F-8059-BE841CC1E1A8"></sequenceFlow>
    <endEvent id="sid-7E49054C-097E-4A47-BDC2-2868EAAEC97D"></endEvent>
    <sequenceFlow id="sid-97225C0C-90B7-482E-9A3B-322736BB2E83" sourceRef="sid-F7354E79-68EA-4F5F-8059-BE841CC1E1A8" targetRef="sid-7E49054C-097E-4A47-BDC2-2868EAAEC97D"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_taskuser">
    <bpmndi:BPMNPlane bpmnElement="taskuser" id="BPMNPlane_taskuser">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="90.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-E6BEE15E-5E0C-4CB6-8429-EF04E154EB07" id="BPMNShape_sid-E6BEE15E-5E0C-4CB6-8429-EF04E154EB07">
        <omgdc:Bounds height="80.0" width="100.0" x="165.0" y="125.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7F157B39-8EF6-44D5-AF6F-131F7E811CA5" id="BPMNShape_sid-7F157B39-8EF6-44D5-AF6F-131F7E811CA5">
        <omgdc:Bounds height="80.0" width="100.0" x="495.0" y="125.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-F7354E79-68EA-4F5F-8059-BE841CC1E1A8" id="BPMNShape_sid-F7354E79-68EA-4F5F-8059-BE841CC1E1A8">
        <omgdc:Bounds height="80.0" width="100.0" x="810.0" y="125.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7E49054C-097E-4A47-BDC2-2868EAAEC97D" id="BPMNShape_sid-7E49054C-097E-4A47-BDC2-2868EAAEC97D">
        <omgdc:Bounds height="28.0" width="28.0" x="1075.0" y="151.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-DF243F47-88E5-42F6-BC75-39E0383E6FCB" id="BPMNEdge_sid-DF243F47-88E5-42F6-BC75-39E0383E6FCB">
        <omgdi:waypoint x="264.94999999999334" y="165.0"></omgdi:waypoint>
        <omgdi:waypoint x="494.9999999997877" y="165.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-63BFAE0B-3C2B-40B0-BBD7-9F50E7E640B1" id="BPMNEdge_sid-63BFAE0B-3C2B-40B0-BBD7-9F50E7E640B1">
        <omgdi:waypoint x="119.94999848995758" y="165.0"></omgdi:waypoint>
        <omgdi:waypoint x="165.0" y="165.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-97225C0C-90B7-482E-9A3B-322736BB2E83" id="BPMNEdge_sid-97225C0C-90B7-482E-9A3B-322736BB2E83">
        <omgdi:waypoint x="909.9499999999626" y="165.0"></omgdi:waypoint>
        <omgdi:waypoint x="1075.0" y="165.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-204CEF7D-C334-4D4B-8897-96D99AA2E595" id="BPMNEdge_sid-204CEF7D-C334-4D4B-8897-96D99AA2E595">
        <omgdi:waypoint x="594.9499999999543" y="165.0"></omgdi:waypoint>
        <omgdi:waypoint x="810.0" y="165.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
从上面可以看出来 定义了三个usertask,task1,task2,task3。
然后我分别给task1指定了任务分配人:jack
task2的任务分配人:${taskuser} (这是个EL表达式,还支持bean.attribute)
task3没有指定任务分配人但是task3指定了任务监听器:触发事件是create, 监听器的类是:
com.example.flowable.listener.TaskAssigneeListener

task3的任务监听器

可以看上面的xml,也可以看到每个task的定义里面的assign属性都是指定了对应的人和监听器。

这里要注意一下:
任务分配人
我们可以看到上图,这上面类型有两个,一个是身份存储,一个是固定值,那个身份存储 应该走的是flowable自己的身份管理模块:IDM,所以我选择了固定值,就是比较灵活一点,上面说的三个task的分配人的设定都是通过固定值这个类型设置的。

执行task1

初始化了流程之后,我们看一下:
流程进度走到task1
我们看下task1的初始化信息:
assignee是jack
我们可以看到因为我们在流程定义里指定了 assignee 是jack,所以流程走到task1的时候默认已经被分配给了jack,然后我们尝试在complete之前修改一下assignee 看行不行,通过java taskService.setAssignee(taskId, "olsen");将jack换成olsen
在这里插入图片描述
此时我们再看task的assignee已经被改成了 olsen,下面我们进行complete这个task1:
报错了
他报错了,内容是说找不到${taskuser}这个property,为什么会这样呢?我分析一下:
其实从刚开始我们初始化了流程之后,流程就自动进行到task1,并且根据我们定义时候填入的信息初始化了task1,
也就是说我们complete之后,流程会自动进入到task2,并且根据们定义的信息初始化task2,然后发现找不到 ${taskuser}这个el表达式对应的值,所以就报了上面的错误,也就是说我们要再完成complete的时候或者之前,就已经要有taskuser这个属性了,
虽然报错了,我们先来看一下task1究竟complete成功了没,流程进行到哪里了。
在这里插入图片描述
可以看到流程没有变化,下面看下数据库中task1的进度是否已完成
在这里插入图片描述
从截图我们可以看到根据task的id我们看到 assignee确实已经从定义默认的jack转换成了oslen,end_time是空,说明也没结束,
好了,确保了流程没问题,我就去看complete的api,然后我换了complete的api,在完成的时候设置taskuser,

        Map<String, Object> Tmap = new HashMap<>();
        Tmap.put("taskuser", "allen");
        taskService.complete(taskId, null, Tmap);

结果很完美,成功了。

task2

在这里插入图片描述
流程从task1进入到task2,我们看一下task2的初始化信息:
task2的初始化信息
我们可以看到此时的task2的assignee被初始化为allen了,也就是说我们再 上面complete task1的时候的 Map生效了,那么我们直接complete task2 进入到task3。

task3

下面是任务监听器的内容:触发事件是create,也就是说在我complete task2之后,会自动触发 任务监听器。

package com.example.flowable.listener;

import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;

public class TaskAssigneeListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println(delegateTask.getName());
        delegateTask.setAssignee("孙露通");
    }
}

根据 任务监听器的内容就是做了一个打印然后,把任务assignee 给了"孙露通"这个人,然后我们看下现在流程的进度:
工作流的进度
我们再看一下此时task3的一些基本信息:
task3的基本信息
我们可以看到此时的task3的assignee 是:“孙露通”,
也就是说:我们在complete task2之后,流程会创建task3,此时触发了 create事件,又因为我们在task3上面定义了事件监听器TaskAssigneeListener然后会触发任务监听器的 notify(DelegateTask delegateTask)函数,然后将task3 assignee给了"孙露通"。

总结

从上面的案例我们可以清楚的看到我们在给usertask设置assignee的时候我们用了三种方式:

  • 定义的时候写死在xml定义文件里
  • 用EL表达式占位符
  • 用任务监听器进行监听设置
综上来看:建议使用任务监听器这种方式,因为相对比较灵活,自控能力比较强,同时可以通过这个接入自己业务的用户管理权限组
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值