家政公司响应式网站建设案例,网站开发需求模板,wordpress 标题图片,十大app软件禁止下载我们在开发自动化办公软件时经常会遇到各种审批流程功能#xff0c;这个使用就需要使用到工作流引擎。目前主流的工作流引擎有Activiti、Flowable、camunda#xff0c;其中Flowable是在Activiti的基础上开发出来的#xff0c;基于BPMN2.0协议#xff0c;它包括 BPMN#x…我们在开发自动化办公软件时经常会遇到各种审批流程功能这个使用就需要使用到工作流引擎。目前主流的工作流引擎有Activiti、Flowable、camunda其中Flowable是在Activiti的基础上开发出来的基于BPMN2.0协议它包括 BPMNBusiness Process Model and Notation引擎、CMMNCase Management Model and Notation引擎、DMNDecision Model and Notation引擎、表单引擎Form Engine等模块。
这里我们基于springboot和PostgreSQL数据库介绍一下如何搭建一个基础的Flowable工作流框架。
创建项目添加依赖
下图是我在线创建的springboot项目只添加了Spring Web和Postgre SQL Driver两个依赖。 添加Flowable依赖
dependencygroupIdorg.flowable/groupIdartifactIdflowable-spring-boot-starter/artifactIdversion6.7.2/version
/dependency配置数据库链接 这里要解释一下网上有的博文说添加完数据库启动服务就会在数据库里自动创建一堆表本人测试需要创建bpmn20.xml文件后数据库才会自动生成对应的表。
spring:datasource:username: postgrespassword: postgresurl: jdbc:postgresql://192.168.2.172/test到这里已经完成了项目的基础配置。
bpmn20.xml文件制作
在整个工作流框架中比较核心的是bpmn20.xml文件的制作如果之前没有一定的基础制作整个文件还是有点难度的。idea的插件市场里有一个Flowable BPMN visualizer插件可以在idea中直接用来制作bpmn20.xml文件。 安装插件后在resources文件夹下创建processes文件夹流程文件默认放在此文件夹下。idea中右键创建文件选择BPMN 2.0 file。 注意文件名要以**.bpmn20.xml**结尾。在创建的文件上右键选择View BPMN。 在弹出的编辑器中即可进行相关的绘制操作。新手注意在编辑器上右键可以创建节点。 网上也有一些其他工具可以用来绘制的都可以尝试。我的xml文件源码如下
?xml version1.0 encodingUTF-8?
definitions xmlnshttp://www.omg.org/spec/BPMN/20100524/MODEL xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:xsdhttp://www.w3.org/2001/XMLSchema xmlns:flowablehttp://flowable.org/bpmn xmlns:bpmndihttp://www.omg.org/spec/BPMN/20100524/DI xmlns:omgdchttp://www.omg.org/spec/DD/20100524/DC xmlns:omgdihttp://www.omg.org/spec/DD/20100524/DI typeLanguagehttp://www.w3.org/2001/XMLSchema expressionLanguagehttp://www.w3.org/1999/XPath targetNamespacehttp://www.flowable.org/processdefprocess idask_for_leave nameask_for_leave isExecutabletruestartEvent idsid-8f75290b-6d4f-4304-98e3-592be1f19a4e/endEvent idsid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9d/userTask idsid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a name请假/userTask idsid-7b7c9585-5913-49fe-910f-fea79e53518c name组长审批 flowable:assignee${taskUser}/userTask idsid-627ef23c-3f54-4536-bda9-bbf0d3243230 name经理审批 flowable:assignee${taskUser}/exclusiveGateway idsid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f /sequenceFlow idsid-b1bdf216-3433-4052-ae80-ad753e16aed7 sourceRefsid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f targetRefsid-627ef23c-3f54-4536-bda9-bbf0d3243230 name通过conditionExpression xsi:typetFormalExpression${finishFlag\YES\}/conditionExpression/sequenceFlowsequenceFlow idsid-0b327947-1e7f-48c3-8047-e8afc3d15005 sourceRefsid-8f75290b-6d4f-4304-98e3-592be1f19a4e targetRefsid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a/sequenceFlow idsid-e5703760-35e2-497f-9501-7b616d5c1d02 sourceRefsid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a targetRefsid-7b7c9585-5913-49fe-910f-fea79e53518c/sequenceFlow idsid-17b98be9-ef29-48a8-8cf6-cfde4be9d7c9 sourceRefsid-7b7c9585-5913-49fe-910f-fea79e53518c targetRefsid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f/serviceTask idsid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a flowable:exclusivetrue name发送失败消息 flowable:classcom.work.flow.listener.TestServiceListener/sequenceFlow idsid-7f8d7cc2-ddd0-4cb4-9ce6-81e8b42f4717 sourceRefsid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f targetRefsid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a name不通过conditionExpression xsi:typetFormalExpression${finishFlag\NO\}/conditionExpression/sequenceFlowsequenceFlow idsid-95ed6745-c15f-4489-a9a5-93f4aeea1f43 sourceRefsid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a targetRefsid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9d/exclusiveGateway idsid-03e9886b-d80c-4a5a-8916-76f2b6683727 /sequenceFlow idsid-e8f7bf08-9b5b-4f0b-b0aa-c1a74d42e870 sourceRefsid-03e9886b-d80c-4a5a-8916-76f2b6683727 targetRefsid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a name不通过conditionExpression xsi:typetFormalExpression${finishFlag\NO\}/conditionExpression/sequenceFlowsequenceFlow idsid-fc8f3bf6-d817-4d6b-9dbd-f15d11032fae sourceRefsid-627ef23c-3f54-4536-bda9-bbf0d3243230 targetRefsid-03e9886b-d80c-4a5a-8916-76f2b6683727/endEvent idsid-f7bc1956-c2b1-4036-99fa-0318f6da4221/sequenceFlow idsid-2a97e964-4e84-4936-9356-14b7b7b6ecb4 sourceRefsid-03e9886b-d80c-4a5a-8916-76f2b6683727 targetRefsid-f7bc1956-c2b1-4036-99fa-0318f6da4221 name通过conditionExpression xsi:typetFormalExpression${finishFlag\YES\}/conditionExpression/sequenceFlow/processbpmndi:BPMNDiagram idBPMNDiagram_ask_for_leavebpmndi:BPMNPlane bpmnElementask_for_leave idBPMNPlane_ask_for_leavebpmndi:BPMNShape idshape-44c54737-7c91-4844-8210-7db7f6853bb6 bpmnElementsid-8f75290b-6d4f-4304-98e3-592be1f19a4eomgdc:Bounds x-245.0 y-65.0 width30.0 height30.0//bpmndi:BPMNShapebpmndi:BPMNShape idshape-12f82f19-3220-442d-893b-b139db4834e4 bpmnElementsid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9domgdc:Bounds x-155.0 y15.0 width30.0 height30.0//bpmndi:BPMNShapebpmndi:BPMNShape idshape-146cee26-7a5b-4da7-9bbb-6c392e645b94 bpmnElementsid-ca4fe38f-af1d-47ad-8646-d045a82fcb6aomgdc:Bounds x-180.0 y-75.0 width55.0 height50.0//bpmndi:BPMNShapebpmndi:BPMNShape idshape-bd5bc59b-ab57-4e3c-8dfa-cb2827d9a331 bpmnElementsid-7b7c9585-5913-49fe-910f-fea79e53518comgdc:Bounds x-75.0 y-80.0 width80.0 height60.0//bpmndi:BPMNShapebpmndi:BPMNShape idshape-cc2b2bce-04fd-4641-ae8b-419d9f79c2b0 bpmnElementsid-627ef23c-3f54-4536-bda9-bbf0d3243230omgdc:Bounds x185.0 y-97.5 width100.0 height55.0//bpmndi:BPMNShapebpmndi:BPMNShape idshape-43f90d29-b7d6-4a74-8acb-1fc7f3f29289 bpmnElementsid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5fomgdc:Bounds x55.0 y-80.0 width40.0 height40.0//bpmndi:BPMNShapebpmndi:BPMNEdge idedge-9eca388f-9baf-4a0b-8201-892c738b6ad0 bpmnElementsid-b1bdf216-3433-4052-ae80-ad753e16aed7omgdi:waypoint x95.0 y-60.0/omgdi:waypoint x185.0 y-70.0//bpmndi:BPMNEdgebpmndi:BPMNEdge idedge-a5e04944-60fb-4696-ad16-c8092d6c0bb5 bpmnElementsid-0b327947-1e7f-48c3-8047-e8afc3d15005omgdi:waypoint x-215.0 y-50.0/omgdi:waypoint x-180.0 y-50.0//bpmndi:BPMNEdgebpmndi:BPMNEdge idedge-6fb6a4c1-3b9a-4238-a66b-10f3d8571af1 bpmnElementsid-e5703760-35e2-497f-9501-7b616d5c1d02omgdi:waypoint x-125.0 y-50.0/omgdi:waypoint x-75.0 y-50.0//bpmndi:BPMNEdgebpmndi:BPMNEdge idedge-e23fcf4e-1309-4639-a40e-9f0fe3fb42b7 bpmnElementsid-17b98be9-ef29-48a8-8cf6-cfde4be9d7c9omgdi:waypoint x5.0 y-50.0/omgdi:waypoint x55.0 y-60.0//bpmndi:BPMNEdgebpmndi:BPMNShape idshape-d6c43ede-95db-49fe-a468-0c8678deff6f bpmnElementsid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49aomgdc:Bounds x-20.0 y7.5 width110.0 height75.0//bpmndi:BPMNShapebpmndi:BPMNEdge idedge-80b91b72-184a-4add-878d-a0553d8fdd04 bpmnElementsid-7f8d7cc2-ddd0-4cb4-9ce6-81e8b42f4717omgdi:waypoint x75.0 y-40.0/omgdi:waypoint x62.5 y7.5//bpmndi:BPMNEdgebpmndi:BPMNEdge idedge-92accc38-c426-45f8-bf82-4ab1d8b6625b bpmnElementsid-95ed6745-c15f-4489-a9a5-93f4aeea1f43omgdi:waypoint x-20.0 y45.0/omgdi:waypoint x-125.0 y30.0//bpmndi:BPMNEdgebpmndi:BPMNShape idshape-aed10d1f-11b7-4c70-91ca-63514182f93f bpmnElementsid-03e9886b-d80c-4a5a-8916-76f2b6683727omgdc:Bounds x225.0 y15.0 width40.0 height40.0//bpmndi:BPMNShapebpmndi:BPMNEdge idedge-1a9651dc-930e-4642-b2f3-4ba0b47fe97d bpmnElementsid-e8f7bf08-9b5b-4f0b-b0aa-c1a74d42e870omgdi:waypoint x225.0 y35.0/omgdi:waypoint x90.0 y45.0//bpmndi:BPMNEdgebpmndi:BPMNEdge idedge-5e55bb58-f07a-45d5-bb8a-8c13a6c0b9dd bpmnElementsid-fc8f3bf6-d817-4d6b-9dbd-f15d11032faeomgdi:waypoint x260.0 y-42.5/omgdi:waypoint x245.0 y15.0//bpmndi:BPMNEdgebpmndi:BPMNShape idshape-12be209b-f581-4e87-b480-41c60acb8d8e bpmnElementsid-f7bc1956-c2b1-4036-99fa-0318f6da4221omgdc:Bounds x255.0 y100.0 width30.0 height30.0//bpmndi:BPMNShapebpmndi:BPMNEdge idedge-7aba8c58-63e5-4c57-b3d7-679ad58b6388 bpmnElementsid-2a97e964-4e84-4936-9356-14b7b7b6ecb4omgdi:waypoint x245.0 y55.0/omgdi:waypoint x270.0 y100.0//bpmndi:BPMNEdge/bpmndi:BPMNPlane/bpmndi:BPMNDiagram
/definitions接口开发 防止流程图乱码配置 package com.work.flow.config;import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;Configuration
public class FlowableConfig implements EngineConfigurationConfigurerSpringProcessEngineConfiguration {Overridepublic void configure(SpringProcessEngineConfiguration engineConfiguration) {engineConfiguration.setActivityFontName(宋体);engineConfiguration.setLabelFontName(宋体);engineConfiguration.setAnnotationFontName(宋体);}
} 发起流程接口 package com.work.flow.controller;import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;RestController
public class TestController {AutowiredRuntimeService runtimeService;AutowiredTaskService taskService;AutowiredRepositoryService repositoryService;AutowiredProcessEngine processEngine;GetMapping( /add)public String addExpense(RequestParam String userId) {//启动流程HashMapString, Object map new HashMap(4);//name客服代表 flowable:candidateGroups${customerServiceId}map.put(userId, userId);//process idadviceApply name投诉建议 isExecutabletrueProcessInstance processInstance runtimeService.startProcessInstanceByKey(ask_for_leave, map);return 提交成功.流程Id为 processInstance.getId();}
} 获取流程图接口
GetMapping(/pic)public void showPic(HttpServletResponse resp, RequestParam String processId) throws Exception {System.out.println(收到请求processId);ListProcessInstance instances runtimeService.createProcessInstanceQuery().list();for (ProcessInstance instance : instances) {System.out.println(instance.getId());}ProcessInstance pi runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();if (pi null) {return;}ListExecution executions runtimeService.createExecutionQuery().processInstanceId(processId).list();ListString activityIds new ArrayList();ListString flows new ArrayList();for (Execution exe : executions) {ListString ids runtimeService.getActiveActivityIds(exe.getId());activityIds.addAll(ids);}/*** 生成流程图*/BpmnModel bpmnModel repositoryService.getBpmnModel(pi.getProcessDefinitionId());ProcessEngineConfiguration engconf processEngine.getProcessEngineConfiguration();ProcessDiagramGenerator diagramGenerator engconf.getProcessDiagramGenerator();InputStream in diagramGenerator.generateDiagram(bpmnModel, png, activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, false);OutputStream out null;byte[] buf new byte[1024];int legth 0;try {out resp.getOutputStream();while ((legth in.read(buf)) ! -1) {out.write(buf, 0, legth);}out.flush();} catch (Exception e) {e.printStackTrace();} finally {if (in ! null) {in.close();}if (out ! null) {out.close();}System.out.println(运行结束);}}流程推进接口
/*** 流转** param processId 流程id*/GetMapping(/apply)public String apply(RequestParam String processId,RequestParam String userId,RequestParam boolean isPass) {//查询当前办理人的任务IDTask task taskService.createTaskQuery()//使用流程实例ID.processInstanceId(processId)//任务办理人.singleResult();if (task null) {throw new RuntimeException(流程不存在);}//通过审核HashMapString, Object map new HashMap();map.put(taskUser, userId);String pass NO;if(isPass){pass YES;}map.put(finishFlag, pass);taskService.complete(task.getId(), map);return processed ok!;}走流程后再次查看流程图
总结
总体bpmn20.xml的配置比较麻烦需要一定的专业知识上手还是有一定的难度的