目录
Flowable 简介Flowable 是一个用 Java 编写的轻量级业务流程引擎。Flowable 流程引擎允许您部署 BPMN 2.0 流程定义(用于定义流程的行业 XML 标准)、创建这些流程定义的流程实例、运行查询、访问活动或历史流程实例和相关数据
Flowable 在将其添加到应用程序、服务、体系结构时非常灵活。您可以将引擎嵌入到您的应用程序或服务中,方法是包含 Flowable 库,该库作为 JAR 提供。因为它是一个 JAR,所以可以很容易地将它添加到任何 Java 环境中:javase;servlet 容器,如 Tomcat或 Jetty、Spring;javaee 服务器,如 JBoss 或 WebSphere 等。或者,您可以使用可流动的 restapi 通过 HTTP 进行通信。还有一些可流动的应用程序(Flowable Modeler、Flowable Admin、Flowable IDM 和 Flowable Task),它们提供了用于处理流程和任务的现成示例 UI
Flowable 的 GitHub 官网:https://github.com/flowable/flowable-engine
Flowable 中文用户书册:https://tkjohn.github.io/flowable-userguide/#_advanced
现在市面上主流的流程引擎就一共有三个:
ActivitiFlowableCamunda这三个各有特点:
Activiti 目前是侧重云,他目前的设计会向 Spring Cloud、Docker 这些去靠拢Flowable 核心思想还是在做一个功能丰富的流程引擎工具,除了最最基础的工作流,他还提供了很多其他的扩展点,我们可以基于 Flowable 实现出许多我们想要的功能(当然这也是小伙伴们觉得 Flowable 使用复杂的原因之一)Camunda 相对于前两个而言比较轻量级,Camunda 有一个比较有特色的功能就是他提供了一个小巧的编辑器,基于 bpmn.io 来实现的。如果你的项目需求是做一个轻巧的、灵活的、定制性强的编辑器,工作流是嵌入式的,那么可以选择 Camunda工作流程图这块其实有一个统一的标准,那就是 BPMN。BPMN 全称是 Business Process Model and Notation,中文译作业务流程模型和标记法,这个中文太绕口了,还是简称 BPMN 吧
这是一套图形化表示法,用图形来表示业务流程模型。BPMN 最初由业务流程管理倡议组织(BPMI, Business Process Management Initiative)开发,BPMI 于 2005 年与对象管理组织(OMG, Object Management Group)合并,并于 2011 年 1 月 OMG 发布 2.0 版本,同时改为现在的名称
一句话,就是流程图这块有一个特别古老的规范,那就是 BPMN,而我们前面所说的无论是 Activiti、Flowable 还是 Camunda,都是支持这个规范的,所以呢,无论你使用哪一个流程引擎,都可以使用同一套流程图
Flowable UI 的安装部署首先下载文件 Flowable 相关的资源,进入 https://github.com/flowable/flowable-engine/releases,选择版本下载,下载下来是一个 ZIP 压缩包,解压压缩会看到如下目录结构

进入 wars 目录,会看到 flowable-rest.war 和 flowable-ui.war 两个 war 文件,然后 cmd 执行如下命令
java -jar flowable-ui.war
如果一闪而过则检查 jdk 的环境变量配置。启动成功后,在浏览器中访问 http://localhost:8080/flowable-ui/#/,默认的账号密码是:admin/test

我们先在 身份管理应用程序 中创建用户并授权

创建用户

填写详细信息

授权管理

最后完成的工作流程图如下

点击创建流程,填写相关的信息

进入流程图绘制界面





ID:可以结合业务需求,业务可以根据不同步骤执行不同的业务操作ID 从而实现不同角色审批不同流程的效果
EL 表达式,因此可以使用 ${}${executeType=='YES'} 的意思是主管审批的时候传递一个 executeType 变量,并且 executeType 变量的值为 YES 的时候,则走到下一步(经理审批)
${executeType=='YES'} 的意思是主管审批的时候传递一个 executeType 变量,并且 executeType 变量的值为 NO 的时候,则结束流程

<?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:flowable="http://flowable.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.flowable.org/processdef" exporter="Flowable Open Source Modeler"
exporterVersion="6.7.2">
<process id="MyLeave" name="MyLeave" isExecutable="true">
<documentation>员工请假流程</documentation>
<startEvent id="sid-159DD77D-9878-4288-AC29-B898E08DC216" flowable:formFieldValidation="true"></startEvent>
<userTask id="zgID" name="主管审批" flowable:assignee="张主管" 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-1E8F84D7-6C11-4D88-84C9-B818474F880E" sourceRef="sid-159DD77D-9878-4288-AC29-B898E08DC216"
targetRef="zgID"></sequenceFlow>
<exclusiveGateway id="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"></exclusiveGateway>
<sequenceFlow id="sid-08020782-2DDE-4C56-BFC0-224DC99FB50E" sourceRef="zgID"
targetRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"></sequenceFlow>
<endEvent id="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"></endEvent>
<userTask id="jlID" name="经理审批" flowable:assignee="李经理" flowable:formFieldValidation="true">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler">
<![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<exclusiveGateway id="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"></exclusiveGateway>
<sequenceFlow id="sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14" sourceRef="jlID"
targetRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"></sequenceFlow>
<endEvent id="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"></endEvent>
<endEvent id="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"></endEvent>
<sequenceFlow id="sid-A74937CE-02B1-493B-8033-08CA2D652771" name="同意"
sourceRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0" targetRef="jlID">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='YES'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A" name="同意"
sourceRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"
targetRef="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='YES'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7" name="拒绝"
sourceRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"
targetRef="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='NO'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-4CC613DD-7789-408B-AFA0-1241261A4E79" name="拒绝"
sourceRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"
targetRef="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='NO'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_MyLeave">
<bpmndi:BPMNPlane bpmnElement="MyLeave" id="BPMNPlane_MyLeave">
<bpmndi:BPMNShape bpmnElement="sid-159DD77D-9878-4288-AC29-B898E08DC216"
id="BPMNShape_sid-159DD77D-9878-4288-AC29-B898E08DC216">
<omgdc:Bounds height="30.0" width="30.0" x="45.0" y="105.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="zgID" id="BPMNShape_zgID">
<omgdc:Bounds height="80.0" width="100.0" x="165.0" y="80.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"
id="BPMNShape_sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0">
<omgdc:Bounds height="40.0" width="40.0" x="360.0" y="100.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"
id="BPMNShape_sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB">
<omgdc:Bounds height="28.0" width="28.0" x="366.0" y="225.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="jlID" id="BPMNShape_jlID">
<omgdc:Bounds height="80.0" width="100.0" x="495.0" y="80.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"
id="BPMNShape_sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF">
<omgdc:Bounds height="40.0" width="40.0" x="690.0" y="100.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"
id="BPMNShape_sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F">
<omgdc:Bounds height="28.0" width="28.0" x="696.0" y="225.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"
id="BPMNShape_sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1">
<omgdc:Bounds height="28.0" width="28.0" x="825.0" y="106.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-1E8F84D7-6C11-4D88-84C9-B818474F880E"
id="BPMNEdge_sid-1E8F84D7-6C11-4D88-84C9-B818474F880E" flowable:sourceDockerX="15.0"
flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
<omgdi:waypoint x="74.94999923927439" y="120.0"></omgdi:waypoint>
<omgdi:waypoint x="164.99999999991007" y="120.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-08020782-2DDE-4C56-BFC0-224DC99FB50E"
id="BPMNEdge_sid-08020782-2DDE-4C56-BFC0-224DC99FB50E" flowable:sourceDockerX="50.0"
flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5">
<omgdi:waypoint x="264.9499999999992" y="120.1509063444109"></omgdi:waypoint>
<omgdi:waypoint x="360.43939393938865" y="120.43939393939392"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-4CC613DD-7789-408B-AFA0-1241261A4E79"
id="BPMNEdge_sid-4CC613DD-7789-408B-AFA0-1241261A4E79" flowable:sourceDockerX="20.5"
flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
<omgdi:waypoint x="710.4194915254237" y="139.52220575783235"></omgdi:waypoint>
<omgdi:waypoint x="710.0588602435497" y="225.00012270930887"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14"
id="BPMNEdge_sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14" flowable:sourceDockerX="50.0"
flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5">
<omgdi:waypoint x="594.9499999999981" y="120.15090634441087"></omgdi:waypoint>
<omgdi:waypoint x="690.4393939393933" y="120.43939393939394"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A"
id="BPMNEdge_sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A" flowable:sourceDockerX="20.5"
flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
<omgdi:waypoint x="729.516569086651" y="120.42578125"></omgdi:waypoint>
<omgdi:waypoint x="825.0001009915921" y="120.054279921789"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7"
id="BPMNEdge_sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7" flowable:sourceDockerX="20.5"
flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
<omgdi:waypoint x="380.4194915254237" y="139.52220575783235"></omgdi:waypoint>
<omgdi:waypoint x="380.05886024354976" y="225.00012270930887"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-A74937CE-02B1-493B-8033-08CA2D652771"
id="BPMNEdge_sid-A74937CE-02B1-493B-8033-08CA2D652771" flowable:sourceDockerX="20.5"
flowable:sourceDockerY="20.5" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
<omgdi:waypoint x="399.50196526507943" y="120.44207317073172"></omgdi:waypoint>
<omgdi:waypoint x="494.9999999999935" y="120.15182370820669"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
使用Ruby1.9.2运行IDE提示说需要gemruby-debug-base19x并提供安装它。但是,在尝试安装它时会显示消息Failedtoinstallgems.Followinggemswerenotinstalled:C:/ProgramFiles(x86)/JetBrains/RubyMine3.2.4/rb/gems/ruby-debug-base19x-0.11.30.pre2.gem:Errorinstallingruby-debug-base19x-0.11.30.pre2.gem:The'linecache19'nativegemrequiresinstall
我知道全局变量$!包含最新的异常对象,但我对下面的语法感到困惑。谁能帮助我理解以下语法?rescue$! 最佳答案 此构造可防止异常停止您的程序并使堆栈跟踪冒泡。它还会将该异常作为值返回,这很有用。a=get_me_datarescue$!在此行之后,a将保存请求的数据或异常。然后您可以分析该异常并采取相应措施。defget_me_dataraise'Nodataforyou'enda=get_me_datarescue$!puts"Executioncarrieson"pa#>>Executioncarrieson#>>#更现实的
我在我正在处理的一些代码中发现了这一点。它旨在解决从磁盘读取key文件的要求。在生产环境中,key文件的内容位于环境变量中。旧代码:key=File.read('path/to/key.pem')新代码:key=File.read('|echo$KEY_VARIABLE')这是如何工作的? 最佳答案 来自IOdocs:Astringstartingwith“|”indicatesasubprocess.Theremainderofthestringfollowingthe“|”isinvokedasaprocesswithappro
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem
我刚刚有一个关于RubyonRails和模型(Rails3)中的attr_accessible属性的一般性问题。有人可以解释应该在那里定义哪些模型属性吗?我记得一些关于批量分配风险的事情,虽然我在这方面不太了解......谢谢:) 最佳答案 想象一个带有一些字段的订单类:Order.new({:type=>'Corn',:quantity=>6})现在假设订单也有折扣代码,比如:price_off。您不想将:price_off标记为attr_accessible。这会阻止恶意代码制作最终会执行如下操作的帖子:Order.new({: