Activiti6相比5有比较大的改进,增加了一个表单编辑器,对于流程引擎也有优化。在学习之前,我们可以先下载Activiti6 Demo,先对Activiti有一个整体的了解。
1. 运行
- 解压zip,拷贝activiti-app.war到tomcat webapp目录
- 访问http://localhost:8080/activiti-app/#/login进行登陆(admin test)
- 默认是内存数据库,可以在这个配置文件中(webapps\activiti-app\WEB-INF\classes\META-INF\activiti-app\activiti-app.properties)修改为本地数据库
2.绘制流程
这里我们以请假流程为例,看看要完成一个完整流程需要哪些步骤
-
创建用户
首先创建几个模拟用户,dev发起申请,leader审核,hr归档
点击 Identity management-->Users --> Create user,创建四个用户 dev leader hr1 hr2
-
创建表单
表单是干什么的呢?以我们常用的OA为例,dev请假的时候,需要填写请假时间,请假原因,请假类型等信息,这就是一个申请表单;而leader审核的时候,需要填写是否同意,以及不同意的原因等信息,这就是一个审核表单。一句话,表单就是用户在操作该节点时,看到的页面
点击Kickstart App-->Forms -->Create Forms,创建一个申请表单,一个审核表单
-
设计流程
Activiti自带一个流程编辑器,我们自己绘制请假流程。点击Kickstart App-->Processes -->Create Processes,绘制流程需要注意:
①.Model name,就是流程的名字,比如"请假",Model key,就是流程的唯一标志,比如"dayOff"
②.在绘制流程图时,需要在节点上挂对应的表单,点击节点"申请",选择下面的属性 Referenced form,选择刚才画的申请表单
③.需要在节点上设置处理人,选择下面的属性Assignments,其中Assigned to single user ,就是指定一个人来处理,比如审批节点,我们指定给之前创建的用户"领导";Candidate users ,就是指定给一些人处理,比如归档节点,我们指定给之前创建的两个用户"hr1","hr2"
④.在分支线上,需要设置流转条件,格式为EL表达式,设置的值取决于表单的字段的name。以领导同意申请为例,选择Flow condition,填入${result=="同意"},其中result就是来自于审核页面
关于流程编辑器的使用,也可以参看这个视频,提取码vyg2
完整的流程文件,dayOff.bpmn20.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="dayOff" name="请假" isExecutable="true">
<documentation>请假流程</documentation>
<startEvent id="startEvent1"></startEvent>
<userTask id="sid-505FDB35-A171-4321-9470-53A963A432EC" name="申请" activiti:assignee="$INITIATOR" activiti:formKey="apply">
<extensionElements>
<modeler:activiti-idm-initiator xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-initiator>
</extensionElements>
</userTask>
<sequenceFlow id="sid-70705D8A-9EF3-4C7C-A901-59DFDA346549" sourceRef="startEvent1" targetRef="sid-505FDB35-A171-4321-9470-53A963A432EC"></sequenceFlow>
<userTask id="sid-3AEB1C63-7B64-42A1-BBCD-B27DA6216AD0" name="领导审核" activiti:assignee="leader" activiti:formKey="check">
<extensionElements>
<modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
<modeler:assignee-info-email xmlns:modeler="http://activiti.com/modeler"><![CDATA[leader@qq.com]]></modeler:assignee-info-email>
<modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[领导]]></modeler:assignee-info-firstname>
<modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<sequenceFlow id="sid-D3E5E3B2-8E9D-4077-8D9D-0D4CFF99C7F3" sourceRef="sid-505FDB35-A171-4321-9470-53A963A432EC" targetRef="sid-3AEB1C63-7B64-42A1-BBCD-B27DA6216AD0"></sequenceFlow>
<exclusiveGateway id="sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F"></exclusiveGateway>
<sequenceFlow id="sid-A96ED7A4-B674-4FB9-AD45-DCEC35D7D309" sourceRef="sid-3AEB1C63-7B64-42A1-BBCD-B27DA6216AD0" targetRef="sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F"></sequenceFlow>
<userTask id="sid-EE16917A-632F-4322-9766-6A732612F015" name="归档" activiti:candidateUsers="hr1,hr2">
<extensionElements>
<modeler:user-info-email-hr1 xmlns:modeler="http://activiti.com/modeler"><![CDATA[hr1@qq.com]]></modeler:user-info-email-hr1>
<modeler:user-info-firstname-hr1 xmlns:modeler="http://activiti.com/modeler"><![CDATA[人力资源1]]></modeler:user-info-firstname-hr1>
<modeler:user-info-email-hr2 xmlns:modeler="http://activiti.com/modeler"><![CDATA[hr2@qq.com]]></modeler:user-info-email-hr2>
<modeler:user-info-firstname-hr2 xmlns:modeler="http://activiti.com/modeler"><![CDATA[人力资源2]]></modeler:user-info-firstname-hr2>
<modeler:activiti-idm-candidate-user xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-user>
<modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<endEvent id="sid-8865AAD9-F3E3-4D44-B374-96743FD64FF0"></endEvent>
<sequenceFlow id="sid-E78A322F-B253-462A-B914-BFD0F25520C4" sourceRef="sid-EE16917A-632F-4322-9766-6A732612F015" targetRef="sid-8865AAD9-F3E3-4D44-B374-96743FD64FF0"></sequenceFlow>
<sequenceFlow id="sid-9C98C7B8-0910-4A17-B6E8-293B0D60719C" name="同意" sourceRef="sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F" targetRef="sid-EE16917A-632F-4322-9766-6A732612F015">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${result=="同意"}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-E62D9BBF-CF67-40F2-B8A7-DFF6D040CC38" name="不同意" sourceRef="sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F" targetRef="sid-505FDB35-A171-4321-9470-53A963A432EC">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${result=="不同意"}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_dayOff">
<bpmndi:BPMNPlane bpmnElement="dayOff" id="BPMNPlane_dayOff">
<bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
<omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-505FDB35-A171-4321-9470-53A963A432EC" id="BPMNShape_sid-505FDB35-A171-4321-9470-53A963A432EC">
<omgdc:Bounds height="80.0" width="100.0" x="175.0" y="138.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-3AEB1C63-7B64-42A1-BBCD-B27DA6216AD0" id="BPMNShape_sid-3AEB1C63-7B64-42A1-BBCD-B27DA6216AD0">
<omgdc:Bounds height="80.0" width="100.0" x="320.0" y="138.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F" id="BPMNShape_sid-FC3B8646-FB3B-402B-B463-A5F4E87F919F">
<omgdc:Bounds height="40.0" width="40.0" x="465.0" y="158.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-EE16917A-632F-4322-9766-6A732612F015" id="BPMNShape_sid-EE16917A-632F-4322-9766-6A732612F015">
<omgdc:Bounds height="80.0" width="100.0" x="550.0" y="138.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-8865AAD9-F3E3-4D44-B374-96743FD64FF0" id="BPMNShape_sid-8865AAD9-F3E3-4D44-B374-96743FD64FF0">
<omgdc:Bounds height="28.0" width="28.0" x="695.0" y="164.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-E62D9BBF-CF67-40F2-B8A7-DFF6D040CC38" id="BPMNEdge_sid-E62D9BBF-CF67-40F2-B8A7-DFF6D040CC38">
<omgdi:waypoint x="485.5" y="197.5"></omgdi:waypoint>
<omgdi:waypoint x="485.5" y="270.0"></omgdi:waypoint>
<omgdi:waypoint x="225.0" y="270.0"></omgdi:waypoint>
<omgdi:waypoint x="225.0" y="218.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-9C98C7B8-0910-4A17-B6E8-293B0D60719C" id="BPMNEdge_sid-9C98C7B8-0910-4A17-B6E8-293B0D60719C">
<omgdi:waypoint x="504.5833333333333" y="178.41666666666666"></omgdi:waypoint>
<omgdi:waypoint x="550.0" y="178.2183406113537"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-E78A322F-B253-462A-B914-BFD0F25520C4" id="BPMNEdge_sid-E78A322F-B253-462A-B914-BFD0F25520C4">
<omgdi:waypoint x="650.0" y="178.0"></omgdi:waypoint>
<omgdi:waypoint x="695.0" y="178.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-D3E5E3B2-8E9D-4077-8D9D-0D4CFF99C7F3" id="BPMNEdge_sid-D3E5E3B2-8E9D-4077-8D9D-0D4CFF99C7F3">
<omgdi:waypoint x="275.0" y="178.0"></omgdi:waypoint>
<omgdi:waypoint x="320.0" y="178.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-A96ED7A4-B674-4FB9-AD45-DCEC35D7D309" id="BPMNEdge_sid-A96ED7A4-B674-4FB9-AD45-DCEC35D7D309">
<omgdi:waypoint x="420.0" y="178.2164502164502"></omgdi:waypoint>
<omgdi:waypoint x="465.4130434782609" y="178.41304347826087"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-70705D8A-9EF3-4C7C-A901-59DFDA346549" id="BPMNEdge_sid-70705D8A-9EF3-4C7C-A901-59DFDA346549">
<omgdi:waypoint x="130.0" y="178.0"></omgdi:waypoint>
<omgdi:waypoint x="175.0" y="178.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
发布流程
流程画好之后,需要发布,别人才能申请。点击Apps-->Create App-->Edit included models,选中刚刚画好的流程,点击save,记得勾选publish复选框执行申请,审批
使用dev用户登陆,点击刚刚创建的的app,点击Processes,可以看到刚刚发布的请假流程,点击Start a process,启动流程,点击Active tasks,就会弹出申请页面,发起申请后,再用leader登陆,点击同意后,再用hr1登陆,完成归档,整个流程就结束了。也可以试试leader点击不同意,流程会重新打回给dev,同时dev还可以看到leader不同意的理由,就像OA的请假一样。
至此,我们就通过activiti自带的app对activiti的整个流程有了较为完整的认识,下一步,我们就从代码的角度,看看如何使用activiti的Api