文章目录
推荐网址
一、认识Flowable
1.1 flowable业务概念
flowable是一个工作流,实现审批流程的功能;
-
变量:注意bpmn中变量使用${xxxx}来指定,在启动流程创建流程实例的时候指定变量的具体值,然后在后边还可以给变量覆盖改值
在申请人设置那里,可以使用变量和审核人中间表来实现已有流程中更改审核人的需求 -
设置审核人、组(使用候选组) flowable:assignee=“ a s s i g n e e 1 " 、 f l o w a b l e : c a n d i d a t e G r o u p s = " {assignee1} " 、 flowable:candidateGroups=" assignee1"、flowable:candidateGroups="{assignee2}”
-
候选人或者候选组 就是添加更多的人可以审核
-
在代码里面也可以使用变量的,表达如上
-
审核的时候使用户还是组都可以用变量代替
-
审核人的值可以不走flowable的用户体系,直接设置值,比如1-1(用户-用户id),2-4(组-部门id),此时都用 flowable:assignee="${assignee1} ",而不用组的审核设置
1.2 类结构 & API说明
总入口点是ProcessEngine;使用ProcessEngine,可以获得各种提供工作流/BPM方法的服务。ProcessEngine与服务对象都是线程安全的,因此可以在服务器中保存并共用同一个引用。
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // spring的项目可以直接导入pom依赖,然后@Autowired导入使用
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
默认的其实就是默认application.yml文件下的数据库配置
也可以不适用默认 的getDefaultProcessEngine,可以用如下的配置放在启动类中
4.1.1 FormService
表单数据的管理;
是可选服务,也就是说Flowable没有它也能很好地运行,而不必牺牲任何功能。这个服务引入了开始表单(start form)与任务表单(task form)的概念。 开始表单是在流程实例启动前显示的表单,而任务表单是用户完成任务时显示的表单。Flowable可以在BPMN 2.0流程定义中定义这些表单。表单服务通过简单的方式暴露这些数据。再次重申,表单不一定要嵌入流程定义,因此这个服务是可选的
formService.getStartFormKey() // 获取表单key
formService.getRenderedStartForm() // 查询表单json(无数据)
4.1.2 RepositiryService
提供了在编辑和发布审批流程的api。主要是模型管理和流程定义的业务api
这个服务提供了管理与控制部署(deployments)与流程定义(process definitions)的操作
- 查询引擎现有的部署与流程定义。
- 暂停或激活部署中的某些流程,或整个部署。暂停意味着不能再对它进行操作,激活刚好相反,重新使它可以操作。
- 获取各种资源,比如部署中保存的文件,或者引擎自动生成的流程图。
- 获取POJO版本的流程定义。它可以用Java而不是XML的方式查看流程。
1.提供了带条件的查询模型流程定义的api
repositoryService.createXXXQuery()
例如:
repositoryService.createModelQuery().list() 模型查询
repositoryService.createProcessDefinitionQuery().list() 流程定义查询
repositoryService.createXXXXQuery().XXXKey(XXX) (查询该key是否存在)
2.提供一大波模型与流程定义的通用方法
模型相关
repositoryService.getModel() (获取模型)
repositoryService.saveModel() (保存模型)
repositoryService.deleteModel() (删除模型)
repositoryService.createDeployment().deploy(); (部署模型)
repositoryService.getModelEditorSource() (获得模型JSON数据的UTF8字符串)
repositoryService.getModelEditorSourceExtra() (获取PNG格式图像)
3.流程定义相关
repositoryService.getProcessDefinition(ProcessDefinitionId); 获取流程定义具体信息
repositoryService.activateProcessDefinitionById() 激活流程定义
repositoryService.suspendProcessDefinitionById() 挂起流程定义
repositoryService.deleteDeployment() 删除流程定义
repositoryService.getProcessDiagram()获取流程定义图片流
repositoryService.getResourceAsStream()获取流程定义xml流
repositoryService.getBpmnModel(pde.getId()) 获取bpmn对象(当前进行到的那个节点的流程图使用)
4.流程定义授权相关
repositoryService.getIdentityLinksForProcessDefinition() 流程定义授权列表
repositoryService.addCandidateStarterGroup()新增组流程授权
repositoryService.addCandidateStarterUser()新增用户流程授权
repositoryService.deleteCandidateStarterGroup() 删除组流程授权
repositoryService.deleteCandidateStarterUser() 删除用户流程授权
4.1.3 RuntimeService
处理正在运行的流程
runtimeService.createProcessInstanceBuilder().start() 发起流程
runtimeService.deleteProcessInstance() 删除正在运行的流程
runtimeService.suspendProcessInstanceById() 挂起流程定义
runtimeService.activateProcessInstanceById() 激活流程实例
runtimeService.getVariables(processInstanceId); 获取表单中填写的值
runtimeService.getActiveActivityIds(processInstanceId)获取以进行的流程图节点 (当前进行到的那个节点的流程图使用)
runtimeService.createChangeActivityStateBuilder().moveExecutionsToSingleActivityId(executionIds, endId).changeState(); 终止流程
4.1.4 HistoryService
在用户发起审批后,会生成流程实例。historyService为处理流程实例的api,但是其中包括了已完成的和未完成的流程实例;
如果是处理正在运行的流程实例,请使用runtimeService;
暴露Flowable引擎收集的所有历史数据。当执行流程时,引擎会保存许多数据(可配置),例如流程实例启动时间、谁在执行哪个任务、完成任务花费的事件、每个流程实例的执行路径,等等。这个服务主要提供查询这些数据的能力
historyService.createHistoricProcessInstanceQuery().list() 查询流程实例列表(历史流程,包括未完成的)
historyService.createHistoricProcessInstanceQuery().list().foreach().getValue() 可以获取历史中表单的信息
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); 根绝id查询流程实例
historyService.deleteHistoricProcessInstance() 删除历史流程
historyService.deleteHistoricTaskInstance(taskid); 删除任务实例
historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list() 流程实例节点列表 (当前进行到的那个节点的流程图使用)
flowable 有api查看act_hi_varinst里面的数据吗
HistoricVariableInstanceQuery query = historyService.createHistoricVariableInstanceQuery().processInstanceId(instance.getId());
HistoricVariableInstance operate = query.variableName("operate").singleResult();
if (operate.getValue().toString().equals("1")) { // 表示流程同意}
4.1.5 TaskService
对流程实例的各个节点的审批处理
流转的节点审批
taskService.createTaskQuery().list() 待办任务列表
taskService.createTaskQuery().taskId(taskId).singleResult(); 待办任务详情
taskService.saveTask(task); 修改任务
taskService.setAssignee() 设置审批人
taskService.addComment() 设置审批备注
taskService.complete() 完成当前审批
taskService.getProcessInstanceComments(processInstanceId); 查看任务详情(也就是都经过哪些人的审批,意见是什么)
taskService.delegateTask(taskId, delegater); 委派任务
taskService.claim(taskId, userId);认领任务
taskService.unclaim(taskId); 取消认领
taskService.complete(taskId, completeVariables); 完成任务
任务授权
taskService.addGroupIdentityLink()新增组任务授权
taskService.addUserIdentityLink() 新增人员任务授权
taskService.deleteGroupIdentityLink() 删除组任务授权
taskService.deleteUserIdentityLink() 删除人员任务授权
4.1.6 ManagementService
主要是执行自定义命令
managementService.executeCommand(new classA()) 执行classA的内部方法
在自定义的方法中可以使用以下方法获取repositoryService
ProcessEngineConfiguration processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
RepositoryService repositoryService = processEngineConfiguration.getRepositoryService();
也可以获得流程定义方法集合
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
ProcessDefinitionEntityManager processDefinitionEntityManager =
processEngineConfiguration.getProcessDefinitionEntityManager();
如findById/findLatestProcessDefinitionByKey/findLatestProcessDefinitionByKeyAndTenantId等。
4.1.7 IdentityService
用于身份信息获取和保存,这里主要是获取身份信息
用于管理(创建,更新,删除,查询……)组与用户。请注意,Flowable实际上在运行时并不做任何用户检查。例如任务可以分派给任何用户,而引擎并不会验证系统中是否存在该用户。这是因为Flowable有时要与LDAP、Active Directory等服务结合使用
identityService.createUserQuery().userId(userId).singleResult(); 获取审批用户的具体信息
identityService.createGroupQuery().groupId(groupId).singleResult(); 获取审批组的具体信息
4.1.8 DynamicBpmnService
可用于修改流程定义中的部分内容,而不需要重新部署它。例如可以修改流程定义中一个用户任务的办理人设置,或者修改一个服务任务中的类名。
1.3 通用业务流程
标准的审批流系统都有一套标准化的业务流程下文,介绍如何操作审批流系统。
一般在系统中的模块名如下, 请个字对应。
这里的任务管理可以查看到一个流程每个审批节点的具体信息。
1.4 表说明
flowable为我们提供了47张表和7个常用api
常常查看的数据表
PROC_INST_ID_ 是流程实例的唯一id
表分类 | 表名 | 表说明 |
---|---|---|
一般数据(2) | ACT_GE_BYTEARRAY | 通用的流程定义和流程资源 |
ACT_GE_PROPERTY | 系统相关属性 | |
流程历史记录(8) | ACT_HI_ACTINST | 历史的流程实例 |
ACT_HI_ATTACHMENT | 历史的流程附件 | |
ACT_HI_COMMENT | 历史的说明性信息 | |
ACT_HI_DETAIL | 历史的流程运行中的细节信息 | |
ACT_HI_IDENTITYLINK | 历史的流程运行过程中用户关系 | |
ACT_HI_PROCINST | 历史的流程实例 | |
ACT_HI_TASKINST | 历史的任务实例 | |
ACT_HI_VARINST | 历史的流程运行中的变量信息 | |
用户用户组表(9) | ACT_ID_BYTEARRAY | 二进制数据表 |
ACT_ID_GROUP | 用户组信息表 | |
ACT_ID_INFO | 用户信息详情表 | |
ACT_ID_MEMBERSHIP | 人与组关系表 | |
ACT_ID_PRIV | 权限表 | |
ACT_ID_PRIV_MAPPING | 用户或组权限关系表 | |
ACT_ID_PROPERTY | 属性表 | |
ACT_ID_TOKEN | 系统登录日志表 | |
ACT_ID_USER | 用户表 | |
流程定义表(3) | ACT_RE_DEPLOYMENT | 部署单元信息 |
ACT_RE_MODEL | 模型信息 | |
ACT_RE_PROCDEF | 已部署的流程定义 | |
运行实例表(10) | ACT_RU_DEADLETTER_JOB | 正在运行的任务表 |
ACT_RU_EVENT_SUBSCR | 运行时事件 | |
ACT_RU_EXECUTION | 运行时流程执行实例 | |
ACT_RU_HISTORY_JOB | 历史作业表 | |
ACT_RU_IDENTITYLINK | 运行时用户关系信息 | |
ACT_RU_JOB | 运行时作业表 | |
ACT_RU_SUSPENDED_JOB | 暂停作业表 | |
ACT_RU_TASK | 运行时任务表 | |
ACT_RU_TIMER_JOB | 定时作业表 | |
ACT_RU_VARIABLE | 运行时变量表 | |
其他表(2) | ACT_EVT_LOG | 事件日志表 |
ACT_PROCDEF_INFO | 流程定义信息 |
二、BPMN的使用
bpmn例子:
2.1 事件(任务节点)图标
我们基本上使用不到这么多,主要是使用 启动、结束事件,用户任务事件,服务事件,有些事件需要设定指定审批人;
2.1.1用户任务
格式
“用户任务(user task)”指需要人工执行的任务。当流程执行到达用户任务时,流程实例会停止等待,直到用户触发完成任务动作。
用户任务在XML中如下定义。其中id是必须属性,name是可选属性。
<userTask id="theTask" name="重要任务" />
每个任务都可以设置到期日期(due date)。
可以指定固定时间或相对时间,比如,当dueDate为“PT30M”时,表示到达任务30分钟后到期。
到期日期必须符合java.util.Date或java.util.String(ISO8601格式)。
实际应用,我们指定为变量值。
<userTask id="theTask" name="Important task" flowable:dueDate="${dateVariable}"/>
任务的到期日期可以使用TaskService,或者在TaskListener中使用传递的DelegateTask修改。
任务指派
指派确定的办理人
<userTask id="theTask" name="重要任务" flowable:assignee="jinyangjie"/>
指派潜在办理人
<userTask id="theTask" name="重要任务" flowable:candidateUsers="jinyangjie, zhangsan" />
指派潜在办理组
<userTask id="theTask" name="重要任务" flowable:candidateGroups="leader, manager" />
更多任务指派的内容,已在“用户和组”的篇章中介绍,这里不再赘述。
会签用户任务属性设置
-
多实例类型
可以选择并行会签(parallel)、顺序会签(sequential),其中并行会签的意思是 多个人同时执行任务。顺序会签是按顺序执行任务。 -
集合多实例
我这里设置assigneeList。这个是会签的人员的ID集合的变量名称。可以随意命名。 -
元素变量(多实例)
就是循环的变量名称,我这里设置assignee。 可以随意命名。 -
分配用户
需要和元素变量(多实例)的名称保持一致,比如元素变量(多实例)设置a,那么分配用户就要设置 a 。由于我元素变量(多实例)设置的是 a s s i g n e e ,所以分配用户我这里值是 {a}。由于我元素变量(多实例)设置的是assignee,所以分配用户我这里值是 a。由于我元素变量(多实例)设置的是assignee,所以分配用户我这里值是{assignee}. -
完成条件
${nrOfCompletedInstances/nrOfInstances == 1}
nrOfCompletedInstances: 完成的实例数
nrOfInstances:会签实例总数
比如设置${nrOfCompletedInstances/nrOfInstances == 1} 是指必须审批人全部同意才会到下一个任务节点。
2.1.2 Java Service任务(服务任务)
格式
Java Service任务(Java service task)用于调用Java类。Java Service不属于BPMN2.0规范,而是Flowable的自定义扩展。
有三种方法声明如何调用Java逻辑
第一种: 调用固定的类
使用flowable:class属性提供全限定类名(fully qualified classname),指定流程执行时调用的类,该类必须实现JavaDelegate或ActivityBehavior接口。
<serviceTask id="javaService" flowable:class="com.example.service.MyJavaDelegate" />
第二种:调用动态类
使用flowable:delegateExpression属性提供委托对象(delegation object)的表达式。该功能和flowable:class类似,同样需要实现JavaDelegate或ActivityBehavior接口,只不过这里不是指定一个具体的实现类,而是查询指定名称的Bean对象。
<serviceTask id="javaService" flowable:delegateExpression="${myDelegateExpressionBean}" />
myDelegateExpressionBean是一个实现了JavaDelegate接口的bean,定义在Spring容器中。
第三种:调用类的指定方法或属性值
使用flowable:expression属性指定类的方法或属性值。同样的,该类需要实现JavaDelegate或ActivityBehavior接口。
<serviceTask id="javaService" flowable:expression="#{printer.printMessage()}" />
将在名为printer的对象上调用printMessage方法(不带参数)。当然也可以为表达式中使用的方法传递变量。
属性值示例:
<serviceTask id="javaService" flowable:expression="#{printer.ready}" />
会调用名为printer的bean的ready参数的getter方法,getReady(不带参数)。该值会被解析为执行的流程变量。
例子
可以查看4.2.5
下面是一个Java类的示例,用于将流程变量String改为大写。这个类通过实现org.flowable.engine.delegate.JavaDelegate接口,可以在流程执行中被调用。
同时,需要重写execute(DelegateExecution)方法实现业务逻辑。这个方法就是引擎将调用的方法。另外,通过该方法中的DelegateExecution参数可以访问流程实例的各种信息。
public class ToUppercase implements JavaDelegate {
public void execute(DelegateExecution execution) {
String var = (String) execution.getVariable("input");
var = var.toUpperCase();
execution.setVariable("input", var);
}
}
如果实现org.flowable.engine.impl.delegate.ActivityBehavior接口,可以访问更强大的引擎功能,例如,可以影响流程的控制流程。但注意这并不是好的实践,需要避免这么使用。
任务的返回值
服务执行的返回值(仅对使用表达式的服务任务),可以通过为服务任务定义的’flowable:resultVariable’属性设置为流程变量。可以是已经存在的,或者新的流程变量。 如果指定为已存在的流程变量,则流程变量的值会被服务执行的返回值覆盖。 如果不指定结果变量名,则服务任务的返回值将被忽略。
<serviceTask id="aMethodExpressionServiceTask"
flowable:expression="#{myService.doSomething()}"
flowable:resultVariable="myVar" />
在上例中,服务执行的结果(调用’doSomething()'方法的返回值),在服务执行完成后,会设置为名为’myVar’的流程变量。
2.1.3 脚本任务
格式
脚本任务(script task)是自动执行的活动。当流程执行到达脚本任务时,会执行相应的脚本。
脚本任务使用script与scriptFormat元素定义。
<scriptTask id="theScriptTask" scriptFormat