一、工作流的初步认识
1.工作流就是将开发中由代码控制的业务流程状态抽取出来然后进行统一控制的机制!
2.比如有这样一个小场景:
我们开发了一个小软件,该软件想要上线给所有人用,然后需经纪人审批、老总审批、大boss审批等。该小软件其审核流程状态有:暂存,待审核,通过或拒绝。
当我们在实现这几个状态的改变时,可以通过java编码实现,但如果这时业务需求发生了改变,只需要老总审核,这时我们就得去更改代码了,如果业务再复杂一点,一旦更改流程,代码就需要大改了。
而这时就可以使用工作流,来处理业务复杂且需求经常性变更的流程。
3.该小场景的呈现效果流程:
开发一个小软件,其状态是暂存;
然后提交审核(状态变成待审核),会自动到第一道审批中,则经纪人登录就可看到这条申请,然后给同意;
接着会自动到第二道审批,如果给拒绝,则状态变成拒绝流程结束,否则到第三道,如果大Boss也同意,则最后状态自动变成通过。(哈哈,描述的有点乱,反正大概这个意思)
二、创建流程模型
第一次创建模型:http://localhost:8080/flow/model/create?name=xxname1&key=xxkey1&description=desc
该接口会保存模型数据到ac_re_*三张表,并跳转到http://localhost:8080/flow/model.html?modelId=1模型页面,之后查看或修改该模型,直接加载模型即可(modelId是模型的唯一标识)
设置流程的属性:
1.流程发起人的流程变量
在开始节点的属性中设置流程发起人的变量applicantId,然后可以在某个任务的属性中,设置参与者为${applicantId},
这样可以实现:谁发起谁执行
2.设置流程参与者 (重要)
可以给每道审批动态设置参与者,
根据业务功能指定每道审批哪些人可以看到和执行。
2.1在流程节点中,设置任务分配
这里第一道审批指定职务是agentJob;第二道misterJob;第三道bossJob
2.2 在流程节点中,设置表单属性
根据业务需求,大概有指定用户,指定角色,指定部门和指定职务这几种情况,来指定任务的参与者。
比如这里指定职务,则设置isTargetJob值为true,其余几个设置值为false。(到时代码里会根据哪个是true,然后去调用对应的接口)
3.设置流程跳转的条件
选定流转线,在流条件中填写EL表达式,返回true或false
4.设置服务任务Service task(重要)
ServiceTask任务节点是自动化的,不需要任何的人工干涉,比如大boss审批通过,则流程就会走到了服务任务这个节点,这里就会自动去修改该小软件的状态为审核通过。
${auditService.endAudit(procInstId,xxcode,xxtype)}(调用endAudit()接口)
三、数据库表(超重要)
activiti工作流框架有一套自己的表。
activti有提供接口:RepositoryService、RuntimeService、TaskService 、HistoryService等,里面有对这些表的基本操作,若满足不了有些开发需求,我们可以自写sql玩转这些表。
1. act_re_* 资源库流程规则表(包含了流程定义和流程静态资源)
re:repository
act_re_deployment 部署信息表
act_re_model 流程设计模型表
act_re_procdef 流程定义数据表
注意:当创建模型后,模型信息会保存到这三张表。保存模型时,会部署流程,修改和部署的信息会保留到这几张表中:
act_ge_bytearray,act_re_deployment,act_re_procdef,act_re_model
1.1 act_re_model
ID_: modelId
NAME_:模型名称
KEY_:模型标识
2. act_ge_* 通用数据表
act_ge_bytearray 二进制数据表
act_ge_property 属性数据表,存储整个流程引擎级别的数据;初始化表结构时,会默认插入三条记录
3. act_ru_* 运行时数据库表
ru:runtime
这些运行时的表,包含流程‘实例,任务,变量‘等运行中的数据。
Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。
(1)act_ru_execution 运行时流程执行实例表,即存放实例的
(2)act_ru_identitylink 运行时流程人员表,主要存储任务节点的参与者信息
(3)act_ru_task 运行时任务节点表
(4)act_ru_variable 运行时流程变量数据表,存放在map中的
模型流程、实例、任务的关系区别:(一个模型,一个流程定义ID,可以发起多个流程实例ID,每个流程实例ID,对应3个节点ID)
比如小红发起软件A审批,使用模型A(modleId=1),这时创建了一个实例(procInstId = 11),
这时就走到了该模型流程的第一个任务节点(taskId=111),该任务信息就保存到了ru_和hi_表中,
只有该任务的参与者才能看见这一个任务,审批通过然后进入下一个任务节点( taskId=112 )
然后又发起软件B审批,还是使用模型A (modleId=1),这时也会创建了一个实例( procInstId = 12),
接下去也是走到了第一个任务节点( taskId=121 )
3.1 act_ru_execution 运行时流程执行实例表
ID_ = PROC_INST_ID_
3.2 act_ru_identitylink 运行时流程人员表
3.3 act_ru_task 运行时任务节点表
ID_:任务id
PROC_INST_ID_:实例id
EXECUTION_ID_:实例分支id,软件审批流程就一条线,故这两个值相同
3.4 act_ru_variable 运行时流程变量数据表(重要)
比如:
发起审批时,把业务功能需要的信息放到map中,保存到该表,则流程进入第一个节点,就可获取到该map数据,
如果再给map添加新数据,进入到第二个节点,该表会更新map数据
4. act_hi_* 历史数据库表
hi:history
这些表包含历史数据,比如历史流程实例, 变量,任务等等
(1) act_hi_actinst 历史节点表,存放所有用过的节点(startEvent,userTask,serviceTask,endEvent)
(2) act_hi_attachment 历史附件表
(3) act_hi_comment 历史意见表
(4) act_hi_identitylink 历史流程人员表,存放任务节点的参与者信息
(5) act_hi_detail 历史详情表,提供历史变量的查询
(6) act_hi_procinst 历史流程实例表
(7) act_hi_taskinst 历史任务实例表
(8) act_hi_varinst 历史变量表
注意:
ru 正在处理中的节点信息
hi 已完成和正在处理中的(开发中发现hi其实是都保存的,故主要会查询hi的表)
4.1 act_hi_actinst :历史节点表(startEvent,userTask,serviceTask,endEvent)
与act_hi_taskinst不同的是,taskinst只记录usertask内容
4.2 act_hi_procinst:历史流程实例表
4.3 act_hi_taskinst:历史任务实例表(重要)
END_TIME_:结束时间值为空,则表示该节点是正在处理中的;这个相当于审批时间
DELETE_REASON_:completed(该节点被同意了)、refused(该节点被拒绝了)、空值(该节点正在处理中)
这里有个小技巧:
当经纪人登录后,有个审批列表(全部、待审核、已审核),该列表还需展示软件一些信息,并且还是分页查询。
然后开发时,我发现NAME_和DESCRIPTION_始终是空值,于是就在发起审批时,把该软件信息存在这里。
4.4 act_hi_varinst 历史变量表
5.biz_act_relation(自定义表)
这张表是自己根据业务需求建的,用来存放业务与任务的关系,用于业务功能的开发。
当一个任务节点被完成后,便会把该节点的信息保存到这张表。
(哈哈,其实开发审批功能时,我用了几个小技巧在表中,才满足所给需求,当然我开发的并不是软件的审批,软件只是一个举例)
四、项目中使用activiti工作流
springboot集成activiti:可以把activiti框架单独作为一个子服务,对应单独一个数据库,就只存放上面所有表。
其他服务引入activiti服务,调用开放接口即可。
1.activiti目录结构
2.activiti工作流接口
2.1 关于模型的接口(自带的,用于在线流程设计器)
在线流程设计器不需要登录就可访问,可以这样设置跳过拦截:
|| this.matchers("/modeler.html", request)
|| this.matchers("/editor-app/**", request)
|| this.matchers("/model/**", request)
|| this.matchers("/editor/stencilset", request)
2.2 关于流程实例和任务的接口
3.审批功能效果
来源:oschina
链接:https://my.oschina.net/u/4291623/blog/3370416