# 请假申请-动态审批
在实际的业务实战中,用户发起请假流程,常常需要部门直属领导进行第一次审批,再流转到其他审批节点。 本文主要模拟一下这个业务场景如何实现。
# 需求描述
以Jeecg本身的组织结构来举例说明, 假设现在有一个组织如下
组织名称:北京国炬信息技术有限公司
部门: 市场部
在市场部门分别绑定了张飞,黄忠, 关羽, 诸葛亮等多个用户。这些用户分属不同的角色。
其中我们将军师角色的诸葛亮的身份设置为上级。
此时关羽发起的一个请假申请,要动态查询到自己的部门直属上级诸葛亮该如何实现?
# BPMN建模
设置申请用户任务节点的指定人员,以及内置表单的参数
设置申请用户任务节点在完成后的监听事件,该事件将查询发起人的部门直属领导
设置直属领导的用户任务节点参数配置,其中${leader}就是接收上一个节点任务监听器的设置。
# XML内容
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="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:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_choose_leader" name="动态审批" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_09w75kg</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_09w75kg" sourceRef="StartEvent_1" targetRef="Activity_1xn21s1" />
<bpmn:userTask id="Activity_1xn21s1" name="申请" camunda:assignee="${general}">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="days" label="请假天数" type="long" defaultValue="1" />
<camunda:formField id="reason" label="请假理由" type="string" />
<camunda:formField id="type" label="请假类型" type="string" />
</camunda:formData>
<camunda:taskListener delegateExpression="${chooseLeaderListener}" event="complete" />
</bpmn:extensionElements>
<bpmn:incoming>Flow_09w75kg</bpmn:incoming>
<bpmn:outgoing>Flow_1n7z9g2</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_1n7z9g2" sourceRef="Activity_1xn21s1" targetRef="Activity_0474tsq" />
<bpmn:userTask id="Activity_0474tsq" name="直属领导" camunda:assignee="${leader}">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="comment" label="评论" type="string" />
<camunda:formField id="imageUrl" label="图片" type="string" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1n7z9g2</bpmn:incoming>
<bpmn:outgoing>Flow_1lyuw6k</bpmn:outgoing>
</bpmn:userTask>
<bpmn:endEvent id="Event_10twye6">
<bpmn:incoming>Flow_1lyuw6k</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1lyuw6k" sourceRef="Activity_0474tsq" targetRef="Event_10twye6" />
</bpmn:process>
</bpmn:definitions>
# 监听器核心代码
@Component("chooseLeaderListener")
@Slf4j
public class ChooseLeaderListener implements TaskListener {
@Autowired
private ISysBaseAPI sysBaseAPI;
@Override
public void notify(DelegateTask delegateTask) {
log.info("动态选择下一个用户任务节点审批人员监听器");
//查询发起用户所属的部门Id集合
String startUser = String.valueOf(delegateTask.getVariable("general"));
List<String> myDeptIds = sysBaseAPI.getDepartIdsByUsername(startUser);
//根据部门id查询负责人
List<String> leaderList = new ArrayList<>();
for (String myDeptId : myDeptIds) {
leaderList.addAll(sysBaseAPI.getDeptHeadByDepId(myDeptId));
}
log.info("直属部门领导人员:{}", leaderList);
//设置下一个审批节点的用户名称,注意如何是有多个领导需要同时审批,要把审批节点设置为多实例。
if(CollectionUtil.isNotEmpty(leaderList)){
delegateTask.setVariable("leader", leaderList.get(0));
}
}
}
上述代码逻辑就是如何查询部门直属领导,并且将查询到的领导名,设置到leader流程变量。在线测试JeecgFlow-Camunda演示战 (opens new window)的动态审批菜单