一个简单的申请流程如下:
<?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:activiti="http://activiti.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="usertask">
<process id="usertask" name="usertask" isExecutable="true">
<startEvent id="startevent1" name="Start" activiti:initiator="${applyuserid}"></startEvent>
<userTask id="usertask1" name="领导审批" activiti:assignee="${taskUserId}">
<extensionElements>
<activiti:taskListener event="all" class="listener.MyExecutionListener"></activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
<sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve=='true'}]]></conditionExpression>
</sequenceFlow>
<userTask id="modifyapply" name="调整申请" activiti:assignee="${applyuserid}"></userTask>
<sequenceFlow id="flow4" name="不同意" sourceRef="exclusivegateway1" targetRef="modifyapply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve=='false'}]]></conditionExpression>
</sequenceFlow>
<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow5" sourceRef="modifyapply" targetRef="exclusivegateway2"></sequenceFlow>
<sequenceFlow id="flow6" name="放弃申请" sourceRef="exclusivegateway2" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow7" name="重新申请" sourceRef="exclusivegateway2" targetRef="usertask1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='true'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_usertask">
<bpmndi:BPMNPlane bpmnElement="usertask" id="BPMNPlane_usertask">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="121.0" y="100.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="300.0" y="90.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="530.0" y="97.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="760.0" y="100.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="modifyapply" id="BPMNShape_modifyapply">
<omgdc:Bounds height="55.0" width="105.0" x="498.0" y="290.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
<omgdc:Bounds height="40.0" width="40.0" x="530.0" y="410.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="156.0" y="117.0"></omgdi:waypoint>
<omgdi:waypoint x="300.0" y="117.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="405.0" y="117.0"></omgdi:waypoint>
<omgdi:waypoint x="530.0" y="117.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="570.0" y="117.0"></omgdi:waypoint>
<omgdi:waypoint x="760.0" y="117.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="100.0" x="570.0" y="117.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="550.0" y="137.0"></omgdi:waypoint>
<omgdi:waypoint x="550.0" y="290.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="100.0" x="550.0" y="137.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="550.0" y="345.0"></omgdi:waypoint>
<omgdi:waypoint x="550.0" y="410.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="570.0" y="430.0"></omgdi:waypoint>
<omgdi:waypoint x="777.0" y="429.0"></omgdi:waypoint>
<omgdi:waypoint x="777.0" y="135.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="100.0" x="601.0" y="430.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="530.0" y="430.0"></omgdi:waypoint>
<omgdi:waypoint x="352.0" y="429.0"></omgdi:waypoint>
<omgdi:waypoint x="352.0" y="145.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="100.0" x="411.0" y="430.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
动态指定审批人,bpmn文件不能写死,需要指定成变量方式,流程启动时候以流程变量方式传入。
start节点:
领导审批节点:
调整申请节点:
发起流程时候,获取bpmn文件的全部usertask节点变量并动态设置值(一般用户UI选择的值),然后以流程变量方式发起流程:
获取bpmn文件的usertask节点的Assignee变量:
//流程定义KEY
String definitionKey = "usertask";
//发起者
String applyuserid = "123456789";
String taskUserId = "987654321";
//businesskey
String businesskey = "businesskey";
//模拟租户ID
String tenantId = "1311197133446770699";
//解析bpmn文件,获取usertask节点信息
List<ProcessDefinition> processDefinitionList = rep
.createProcessDefinitionQuery()
.processDefinitionKey(definitionKey)
.orderByProcessDefinitionVersion()
.desc()
.list();
BpmnModel bpmnModel = rep.getBpmnModel(processDefinitionList.get(0).getId());
//简单流程获取Process
//复杂的多个执行exceute分支,使用:bpmnModel.getProcesses()
org.activiti.bpmn.model.Process process = bpmnModel.getMainProcess();
List<UserTask> userTaskList = process.findFlowElementsOfType(UserTask.class);
Iterator<UserTask> it = userTaskList.iterator();
while (it.hasNext()) {
UserTask ut = (UserTask) it.next();
String assignee = ut.getAssignee();
String id = ut.getId();
String name = ut.getName();
System.out.println(String.format("assignee=%s,id=%s,name=%s", assignee,id,name));
}
解析获取assignee变量:taskUserId、applyuserid作为key并赋值value(一般用户UI选择的值),最后启动流程实例:
Map<String,Object> variables=new HashMap<String, Object>();
//流程启动人的信息
variables.put("applyuserid", "123456789");
variables.put("taskUserId", "987654321");
//设置发起人
identityservice.setAuthenticatedUserId(applyuserid);
ProcessInstance instance = runservice
.startProcessInstanceByKeyAndTenantId(definitionKey,
businesskey,
variables,
tenantId);
ProcessDefinition processDefinition = rep
.createProcessDefinitionQuery()
.processDefinitionId(instance.getProcessDefinitionId()).singleResult();
runservice.setProcessInstanceName(instance.getProcessInstanceId(),processDefinition.getName());
System.out.println("processInstanceId:" + instance.getProcessInstanceId());
用户获取自己可以审批的任务,放弃API,自己写SQL实现(涉及流程实例历史表ACT_HI_PROCINST 、流程任务运行时表ACT_RU_TASK 、流程定义表ACT_RE_PROCDEF ,3张):
select
distinct RES.*,
arp.NAME_ AS DEF_NAME_,
arp.KEY_ AS DEF_KEY_,
arp.CATEGORY_ AS DEF_CATEGORY_,
arp.VERSION_,
arp.SUSPENSION_STATE_ ,
ahp.START_TIME_,
ahp.END_TIME_,
ahp.START_USER_ID_,
ahp.PROC_INST_ID_
from
ACT_RU_TASK RES
left join ACT_RE_PROCDEF arp
on RES.PROC_DEF_ID_ = arp.ID_
left join ACT_HI_PROCINST ahp on
RES.PROC_INST_ID_ = ahp.PROC_INST_ID_
where
RES.ID_ > 0
and
(
(
exists(
select
distinct LINK.USER_ID_
from
ACT_RU_IDENTITYLINK LINK
where
USER_ID_ = '987654321'
and LINK.TASK_ID_ = RES.ID_)
or RES.ASSIGNEE_ = '987654321'
or RES.OWNER_ = '987654321'
)
)
下面是一些完成任务的操作:
//领导审批(完成任务)
String taskId = "122505";
String processInstanceId= "117522";
Map<String,Object> variablesComplete=new HashMap<String,Object>();
//完成任务
variablesComplete.put("approve", "true");
//添加审批评论
taskservice.addComment(taskId, processInstanceId, "同意了,继续加油");
//多个人处理的时候,拾取任务
//taskId查询Task对象
Task task=taskservice.createTaskQuery().taskId(taskId).singleResult();
//拾取任务
try{
//已经指定就不要拾取任务
if(StringUtils.isBlank(task.getAssignee())){
taskservice.claim(taskId,taskUserId);
}
//完成任务
taskservice.complete(taskId, variablesComplete);
}catch(Exception e){
e.printStackTrace();
}
如果被领导驳回,重新发起申请:
//驳回,重新审批
String taskId = "120005";
String processInstanceId= "117522";
Map<String,Object> variablesComplete=new HashMap<String,Object>();
variablesComplete.put("reapply", "true");
taskservice.addComment(taskId, processInstanceId, "发起人重新申请");
//多个人处理的时候,拾取任务
//taskId查询Task对象
Task task=taskservice.createTaskQuery().taskId(taskId).singleResult();
//拾取任务
try{
if(StringUtils.isBlank(task.getAssignee())){
taskservice.claim(taskId,taskUserId);
}
//完成任务
taskservice.complete(taskId, variablesComplete);
}catch(Exception e){
e.printStackTrace();
}