一.简介
学习下UserTask 设置用户的三种方式,至于如何设置用户组,下篇文章再聊。
现在,假设我有如下一个简单的流程图:
那么该如何设置这个用户节点的处理人?
二.第一种:指定具体用户
第一种方式,是我们在绘制流程图的时候,可以选中这个节点,然后直接设置流程的处理人,截图如下:
然后在打开的窗口中选择固定值,设置具体分配的用户是 javaboy,如下图:
现在这个节点就固定的由一个名为 javaboy 的用户去处理了。
对应的 XML 文件如下:
<process id="demo01" name="demo01" isExecutable="true">
<documentation>demo01</documentation>
<startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
<userTask id="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" flowable:assignee="javaboy" 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-71FB3A81-F753-419D-9A0A-2FC6E5361CED" sourceRef="startEvent1" targetRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3"></sequenceFlow>
<endEvent id="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></endEvent>
<sequenceFlow id="sid-DEBE03CD-F247-4EF3-BB67-ABBA94739B0A" sourceRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" targetRef="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></sequenceFlow>
</process>
在上面这段 XML 中,可以看到 UserTask 节点中有一个 flowable:assignee=“javaboy”,这句话就是设置这个 UserTask 的处理人。
接下来,我们部署并启动这个流程(具体的部署启动方式可以参考本系列之前的文章),启动之后,我们可以在数据库的 ACT_RU_TASK 表中看到,这个 UserTask 的处理人是 javaboy,如下图:
根据上面这段代码,执行结果如下:
现在可以通过 Java 代码去查询 javaboy 需要处理的 UserTask 了,代码如下:
@Autowired
TaskService taskService;
@Test
void test11() {
List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
logger.info("id:{},name:{}",task.getId(),task.getName());
}
}
查询到这个任务之后,javaboy 有两种选择:
- 将这个任务指定给另外一个人,例如 zhangsan。
- 自己处理。
1.重新指定任务处理人
假设 javaboy 查询到自己的任务之后,想把这个任务交给 zhangsan 去处理,代码如下:
@Autowired
TaskService taskService;
@Test
void test11() {
List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
taskService.setAssignee(task.getId(),"zhangsan");
}
}
这行代码执行完成后,我们看数据库中的 ACT_RU_TASK 表,还是刚才那条记录,但是处理人变了,变成了 zhangsan,截图如下:
版本号从 1 变为 2 了,说明这条记录被更新过了,处理人则从 javaboy 变为了 zhangsan。
最后再来看下这个操作所执行的 SQL,来验证一下前面的结论:
2.自己处理
如果 javaboy 想自己处理这个任务也是可以的,代码如下:
@Autowired
TaskService taskService;
@Test
void test11() {
List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
taskService.complete(task.getId());
}
}
处理完成后,ACT_RU_TASK 表中的记录也会被自动删除掉(执行过的 UserTask 会被自动删除)。
这种方式是指定了具体的用户,很显然这种硬编码的方式使用起来很不方便,我们需要的是能够动态指定任务处理人的方式。
三.第二种:通过变量设置
如果想动态指定 UserTask 的处理人,则可以通过变量来实现,在绘制流程图的时候,还是指定流程的具体处理人,但是在指定的时候,使用EL变量代替,截图如下:
这里的 #{manager} 表示这个 UserTask 由一个名为 manager 的变量来指定,此时的 XML 文件的代码如下:
<process id="demo01" name="demo01" isExecutable="true">
<documentation>demo01</documentation>
<startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
<userTask id="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" flowable:assignee="#{manager}" 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-71FB3A81-F753-419D-9A0A-2FC6E5361CED" sourceRef="startEvent1" targetRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3"></sequenceFlow>
<endEvent id="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></endEvent>
<sequenceFlow id="sid-DEBE03CD-F247-4EF3-BB67-ABBA94739B0A" sourceRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" targetRef="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></sequenceFlow>
</process>
UserTask 节点中的 flowable:assignee=“#{manager}” 就表示这个 UserTask 的处理人由 manager 变量指定。
对于这样的流程,我们在上一个节点处就需要指定下一个节点的处理人,对于当前案例来说,当然是要在流程启动的时候,指定这个 UserTask 的处理人,代码如下:
@Test
void test01() {
Map<String, Object> variables = new HashMap<>();
variables.put("manager", "javaboy");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo01",variables);
logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}
当流程启动成功之后,去查看 ACT_RU_TASK 表,就可以看到,有一个待处理的 UserTask,处理人是 javaboy,截图如下:
能看到这条记录,就说明这个 UserTask 的处理人我们已经设置成功了。
接下来具体的处理逻辑,则参考第二大点的第一二小点。