flowable

1. 概念

  • 模型 Model

  • 流程定义
    类似一个java类,可以创建多个流程实例。

  • 流程部署

  • 流程实例
    类似Java new 出来的对象,一个流程定义可以发起n个不同的流程实例。

  • 执行id
    可以理解为流程实例更小的流程单元,2个并行网关,就对应者一个流程实例id,2个执行id(每条子线的id)

  • 活动 Activity
    实例的发起,任务,网关,都是活动。

  • 任务 Task
    一个待办,就是一个任务。

2. 对比总结

wps搜:流程引擎flowable表解读

3. 表、字段相关含义

4. yml配置项解读

4.1. flowable.history-level

有4个值,记录范围从小到大:none > activity > audit > full

4.1.1. none

  • 含义:不记录任何历史数据。这是性能最优的选项,因为它避免了历史数据的存储和处理开销。但是,这种模式下,无法获取工作流实例的历史信息,如流程的启动时间、结束时间、任务的完成时间等。
  • 适用场景:适用于对历史数据没有需求,并且希望最大程度提高性能的场景,例如一些简单的、临时的工作流,或者对性能要求极高且历史数据无关紧要的流程。

4.1.2. activity

  • 含义:记录活动(Activity)级别的历史数据。它会记录流程实例中每个活动(如任务、网关等) 的开始和结束时间等基本信息。这样可以追踪流程中每个步骤的执行时间,但不会记录详细的变量变化等信息。
  • 适用场景:适用于需要大致了解流程执行步骤的时间信息,用于简单的流程监控和性能分析。例如,在一个简单的请假流程中,可以知道每个审批任务的开始和结束时间,从而统计每个环节的耗时。

4.1.3. audit

  • 含义:除了活动级别的历史数据外,还会记录流程变量的更新情况。这提供了更详细的历史信息,包括流程在执行过程中变量是如何变化的。这样可以更好地进行流程审计,了解流程的详细执行情况。
  • 适用场景:适用于需要对流程进行详细审计的场景,例如财务审批流程,需要追踪金额等变量的变化情况,以及流程步骤的执行时间,以确保流程的合规性和准确性。

4.1.4. full

  • 含义:记录最完整的历史数据,包括所有的活动信息、变量变化、表单属性等。这提供了关于流程执行的最全面的历史记录,但会产生最多的存储开销和一定的性能影响。
  • 适用场景:适用于对流程执行历史有严格的追溯和分析需求的场景,例如在复杂的业务流程中,需要详细分析每个流程实例的所有细节,包括用户操作、变量变化等所有信息,用于故障排查、业务优化等复杂场景。

5. 问题

5.1. 查模型当前激活的流程版本(定义)

  • 可通过部署id查询。
    发布部署时,得保证模型的部署id是最新流程定义的部署id,且该部署id对应的流程定义状态=1。
    act_re_deployment 流程部署表
    act_re_model表DEPLOYMENT_ID_可以存激活的部署id,act_re_procdef 表也会存部署id。

  • 通过模型key + 状态 + 版本号
    流程定义的key就是模型的key,act_re_procdef表SUSPENSION_STATE_ = 1代表激活,vesion最大的,就是某个模型当前最新的激活版本。

5.2. 模型部署时是否自动生成流程定义?

是的。
flowable在模型部署时,核心是部署bpm.xml,act_ge_bytearray表也有部署id。

5.3. 如何生成一个流程定义?

  • 前置条件:1:得有bpm.xml流程图;2:得通过部署产生;
  • repositoryService负责
  • 通过创建部署,自动生成的定义。
  • 定义的category 2家都是分2步设置,难道不能创建时就设置?
// 芋道 的用法
// 基于模型,部署
Deployment deploy = repositoryService.createDeployment()
                .key(model.getKey()).name(model.getName()).category(model.getCategory())
                .addBytes(model.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, bpmnBytes)
                .tenantId(FlowableUtils.getTenantId())
                .disableSchemaValidation() // 禁用 XML Schema 验证,因为有自定义的属性
                .deploy();
// 设置 ProcessDefinition 的 category 分类
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId()).singleResult();
        repositoryService.setProcessDefinitionCategory(definition.getId(), model.getCategory());

// ruoyi-flowable 的用法
// 没有用模型,直接用xml部署
Deployment deploy = repositoryService.createDeployment().addInputStream(name + BPMN_FILE_SUFFIX, in).name(name).category(category).deploy();
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
        repositoryService.setProcessDefinitionCategory(definition.getId(), category);

5.4. 如何生成一个流程实例?

  • 流程实例依赖流程定义,流程定义又依赖于bpm.xml文件的部署。所以act_ge_bytearray文件表得有数据,act_re_deployment 流程部署表得有部署id, act_re_procdef 定义表得有数据。
  • 最好在检查状态是否已激活。同一个key,是否有多个激活,最好保证只有一个激活。
  • 确定好发起人
  • runtimeService 负责
// 芋道 的用法
ProcessInstance instance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionId(definition.getId())
                .businessKey(businessKey)
                .name(definition.getName().trim())
                .variables(variables)
                .start();

//  ruoyi-flowable 的用法(流程定义和变量map)
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
// 流程定义id 、businessKey 、变量map
runtimeService.startProcessInstanceById("流程定义id","businessKey", variables);

5.5. yudao生成流程实例前校验了些什么?

  • 详情见 BpmProcessInstanceServiceImpl.createProcessInstance0()方法

5.6. 执行监听器和任务监听器有什么区别

  • 事件类型不同
    start,end,take
    create,assignment,complete,delete

  • 执行监听器
    针对流程实例,对流程实例启动和结束做增强。
    流程结束,可以执行一些业务处理,如将业务数据同步给三方系统。

  • 任务监听器
    针对任务创建、指派、完成和删除等做增强。

5.7. 流程实例创建、结束,如何执行回调函数?

  • 可以用执行监听器

  • 可以继承AbstractFlowableEngineEventListener,重新相应方法,处理自己的业务。

5.8. 如何打印flowable的sql

  • 以MyBatis为例
    yml文件
logging:
  level:
    org.flowable: DEBUG

5.9. task完成后,是如何指定审批人的?

5.10. 如何确定节点审批人

5.10.1. 流程表达式

5.10.1.1. 利用反射

  • ui设计器:
${bpmTaskAssignLeaderExpression.calculateUsers(execution, 1)}
  • java端
    通过DelegateExecution获取流程实例,
@Component
public class BpmTaskAssignLeaderExpression {

       public Set<Long> calculateUsers(DelegateExecution execution, int level) {
        Assert.isTrue(level > 0, "level 必须大于 0");
        // 获得发起人
        ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
        Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
        // 获得对应 leve 的部门
        DeptRespDTO dept = null;
        for (int i = 0; i < level; i++) {
            // 获得 level 对应的部门
            if (dept == null) {
                dept = getStartUserDept(startUserId);
                if (dept == null) { // 找不到发起人的部门,所以无法使用该规则
                    return emptySet();
                }
            } else {
                DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());
                if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少
                    break;
                }
                dept = parentDept;
            }
        }
        return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();
    } 
}

5.11. 如何实现会签

5.11.1. 用户任务-多实例

  • 3根线的 含义
    竖线:并行(parallel),用户任务ru_task表会为所有用户同时生成待办数据。
    横线:串行(sequential),ru_task表只会有一条,a,b,c依次complete后,下个用户才会生成待办信息。

  • 第一个待办节点使用示例(流程发起时,为下一个用户任务确定待办人)
    1:ui配置
    img
    img
    2:代码map传参
    img

5.12. 如何实现多人或签

  • 基于上面【如何实现会签】,再加一个条件

5.12.1. 条件表达式

涉及3个变量

nrOfInstances: 实例总数。
nrOfActiveInstances: 当前活动的(未完成)实例,对于一个连续的多实例,这将永远是1。
nrOfCompletedInstances: 已经完成的实例数。
  • 基于上面3个变量,可以灵活实现:1人或签,半数通过,n/m通过。
    img

5.12.2. 基于java代码

  • 实际是把uel表达式,改为java代码

  • 1:编写java代码
    img

  • 2:ui填写uel表达式
    img

6. 流程梳理

6.1. 部署(发布)表之间发生了什么

  • 前置条件
    得有xml流程图文件及bpm.xml

  • 有模型表参与
    image

  • 无模型表参与
    image

6.2. 发起流程(生成流程实例)发生了什么

6.3. 流程实例结束发生了什么

  • 包含ru_的表,将清除该流程实例相关数据!!

7. Flowable-ui

7.1. docker运行

  • 运行命令
docker run -p 8080:8080 镜像id
user: admin
password: test

8. 监听器

8.1. 执行监听器

  • 作用域
    开始、结束事件,顺序箭头,任务。
  • 作用效果
    不管是圆圈,箭头,方形任务,此活动activity,开始和结束,就会执行其中的执行监听器。
    img

8.2. xml内容

img

8.2.1. 事件类型

  • start开始事件

  • take执行事件

  • end结束事件

8.2.2. 监听器类型


  • 需要实现ExecutionListener
    不用注入到Spring的bean容器
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.execution;

import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;

/**
 * OA流程结束-执行监听器
 * @author JiangFeng
 * @since 2025/2/10
 */
public class OALeaveFlowEndExecutionListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) {
        System.out.println("执行监听器,触发了。。。");
    }
}

img

  • 表达式
    必须注入到Spring的bean容器
    参数固定带上 DelegateExecution execution

  • 事件类型

8.3. 任务监听器

8.4. 全局事件监听器

posted @ 2024-03-13 15:12  jf666new  阅读(109)  评论(0)    收藏  举报