文章目录
- 代码实现
- 部署流程
- 启动流程
- 填写放假通知任务
- 投票审批
- xml文件
- 会签场景:
开始 - 填写放假通知单(代理人)- 投票审批(指定多个参与人)- 根据设置的完成条件后,全部参与人必须完成后,自动结束流程- 或签场景:
开始 - 填写放假通知单(代理人)- 投票审批(指定多个参与人)- 根据设置的完成条件后,比例数完成,自动结束流程
代码实现
部署流程
@Testpublic void deployProcess() throws IOException {ClassPathResource classPathResource = new ClassPathResource("/processes/holiday.bpmn20.xml");Deployment deploy = repositoryService.createDeployment().addInputStream(classPathResource.getPath(), classPathResource.getInputStream()).deploy();System.out.println("deploy = " + deploy);}
启动流程
@Testpublic void startProcess() {// 设置流程变量Map<String, Object> variables = new HashMap<>();variables.put("applyUserId", APPLY_USER_ID);variables.put("managerList", CollectionUtil.newArrayList("张三", "李四", "王五"));// 获取流程定义的KeyString processDefinitionKey = "holiday";// 定义businessKeyString businessKey = processDefinitionKey + ":" + BUSINESS_ID;// 启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);System.out.println("processInstance = " + processInstance);// 获取流程变量System.out.println("===================流程变量===================");runtimeService.getVariables(processInstance.getId()).forEach((key, value) -> System.out.println("key:" + key + ",value:" + value));// 输出当前任务列表this.printTaskList(processInstance.getId());}
填写放假通知任务
将启动流程后的流程实例ID更换到下面
@Testpublic void fillOutHolidayNotice() {// 查询任务Task task = taskService.createTaskQuery().processInstanceId(PROCESS_INSTANCE_ID).taskAssignee(APPLY_USER_ID).singleResult();// 增加意见taskService.addComment(task.getId(), task.getProcessInstanceId(), "我支持放假的");// 完成任务Map<String, Object> hashMap = new HashMap<>();hashMap.put("days", 10);taskService.complete(task.getId(), hashMap);// 输出当前任务列表this.printTaskList(task.getProcessInstanceId());}
投票审批
将启动流程后的流程实例ID更换到下面
@Testpublic void voteAudit() {// 查询任务(代理人分别查询完成)Task task = taskService.createTaskQuery().processInstanceId(PROCESS_INSTANCE_ID).taskAssignee("张三").singleResult();// 增加意见taskService.addComment(task.getId(), task.getProcessInstanceId(), "同意放假");// 完成任务taskService.complete(task.getId());// 输出当前任务列表this.printTaskList(task.getProcessInstanceId());}
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: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="http://www.activiti.org/processdef"><process id="holiday" name="放假审批流程" isExecutable="true"><documentation>模拟放假审批流程</documentation><startEvent id="sid-f8852670-b815-4f97-84b0-eb11d34d9334" name="开始"/><userTask id="sid-f4101616-870b-45f6-b710-22978eb27828" name="填写放假通知单" activiti:assignee="${applyUserId}"/><userTask id="sid-a6f78e45-6624-4996-869d-ae616b2b78e4" name="投票审批" activiti:assignee="${manager}"><!-- 多实例会签 --><multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${managerList}" activiti:elementVariable="manager"><!--isSequential:false表示并行,true串行activiti:collection:多实例人员集合变量activiti:elementVariable:人员集合中的元素变量,这里要UserTask中activiti:assignee的值对应nrOfInstances:总实例数nrOfCompletedInstances:完成数completionCondition:完成条件-->
<!-- <completionCondition><![CDATA[${nrOfCompletedInstances == nrOfInstances}]]></completionCondition>--><completionCondition><![CDATA[${nrOfCompletedInstances/nrOfInstances >= 0.6}]]></completionCondition></multiInstanceLoopCharacteristics></userTask><sequenceFlow id="sid-92f3fd0d-a6ed-45cc-ae12-71adb0d0060b" sourceRef="sid-f8852670-b815-4f97-84b0-eb11d34d9334" targetRef="sid-f4101616-870b-45f6-b710-22978eb27828"/><sequenceFlow id="sid-14fabbf8-263a-4b6b-a8b2-60c494ec52ae" sourceRef="sid-f4101616-870b-45f6-b710-22978eb27828" targetRef="sid-a6f78e45-6624-4996-869d-ae616b2b78e4"/><endEvent id="sid-b9011d2c-1871-49d2-82bb-b521dbd9dfeb" name="结束"/><sequenceFlow id="sid-6aa8c217-001a-43a3-a28b-509edc0100a2" sourceRef="sid-a6f78e45-6624-4996-869d-ae616b2b78e4" targetRef="sid-b9011d2c-1871-49d2-82bb-b521dbd9dfeb"/></process><bpmndi:BPMNDiagram id="BPMNDiagram_holiday"><bpmndi:BPMNPlane bpmnElement="holiday" id="BPMNPlane_holiday"><bpmndi:BPMNShape id="shape-d078e42c-b1e3-4fa1-86fe-6c8f21f5e62e" bpmnElement="sid-f8852670-b815-4f97-84b0-eb11d34d9334"><omgdc:Bounds x="-161.5" y="-32.265995" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-8f198408-3f86-45b6-ab85-4bcf104a9786" bpmnElement="sid-a6f78e45-6624-4996-869d-ae616b2b78e4"><omgdc:Bounds x="64.696" y="-57.265995" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-6006d1ea-5233-4f69-a21d-c42fb50492aa" bpmnElement="sid-f4101616-870b-45f6-b710-22978eb27828"><omgdc:Bounds x="-93.65202" y="-57.266" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-a4f60f49-040d-4cae-82db-3502dd77a1ab" bpmnElement="sid-92f3fd0d-a6ed-45cc-ae12-71adb0d0060b"><omgdi:waypoint x="-131.5" y="-17.265995"/><omgdi:waypoint x="-93.65202" y="-17.265999"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-4b34fd90-434d-491d-b1cc-e10431bad198" bpmnElement="sid-14fabbf8-263a-4b6b-a8b2-60c494ec52ae"><omgdi:waypoint x="6.3479767" y="-17.265999"/><omgdi:waypoint x="64.696" y="-17.265995"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-bdb837a7-defc-466a-bfd5-c89d3fac4951" bpmnElement="sid-b9011d2c-1871-49d2-82bb-b521dbd9dfeb"><omgdc:Bounds x="218.34798" y="-32.265995" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-af623160-12e5-40f9-aed5-ee1d597367f3" bpmnElement="sid-6aa8c217-001a-43a3-a28b-509edc0100a2"><omgdi:waypoint x="164.696" y="-17.265995"/><omgdi:waypoint x="218.34798" y="-17.265995"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>