Activity 审批流简单介绍

本文详细介绍了Activiti审批流的使用,包括组件引入、流程文件创建、流程表初始化、启动审批流程以及审批过程。通过分析ACT_RE_*, ACT_GE_*, ACT_RU_*, ACT_HI_*等表,展示了Activiti在运行时和历史数据存储的结构,帮助理解Activiti的工作原理。" 129295563,8524055,Kafka面试深度解析:DevOps与SRE视角,"['DevOps', 'SRE', '消息队列', 'Kafka', '面试']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

一、概述

     最近做一个项目用到了审批流,在网上找了一下,activity还是比较好用,对其简单整理,主要内容包括组件引入,审批流创建,代码开发等功能

二、引入Activity

     通过gradle和maven都可引入activity,gradle的引入方式如下:

    implementation("org.activiti:activiti-engine:7.1.0.M6")
    implementation("org.activiti:activiti-spring:7.1.0.M6")

    即使用其7.1.0.M6版本,通过maven的方式如下:

<dependency>
	<groupId>org.activiti</groupId>
	<artifactId>activiti-engine</artifactId>
	<version>7.1.0.M6</version>
</dependency>
<dependency>
	<groupId>org.activiti</groupId>
	<artifactId>activiti-engine</artifactId>
	<version>7.1.0.M6</version>
</dependency>

     只要依赖能下载下来,则引入就是成功的

三、创建流程文件

      我们首先要创建一个流程文件,才能在后续的过程中使用这个文件,actiivity7据说是有一个在线的工具,不过不是太会用,这里使用的是eclipse的插件,要注意的是eclipse不能使用最新版本,根据官方的介绍,kepler 版本是可以的,这个不做过多介绍,eclipse的插件虽然已经不再维护了,但老版本也还是可以使用的,其效果如下:

              

    对于每个任务节点来说,可以在Main config里配置审批人变量,在创建流程时对变量设置值。

 

四、创建流程表并初始化流程

      actiivity的数据也是通过表来存储的,所以使用之前还需要建表,当然这个要先进行数据源配置,actiity的配置文件默认为actiity.cfg.xml,示例配置如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

        <property name="jdbcUrl" value="${yourJdbcUrl}" />
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUsername" value="${yourUsername}" />
        <property name="jdbcPassword" value="${yourPassword}" />
        <property name="databaseSchemaUpdate" value="true" />
        <property name="asyncExecutorActivate" value="false" />
    </bean>

</beans>

      系统初始化的时候,要先进行建表,示例代码如下:

public class ActivityConnectionDB {
    public static void main(String args[]){
        //获取流程引擎配置
        ProcessEngineConfiguration pec = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        //设置自动创建表和更新表
        pec.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        //构建流程引擎,即获取流程引擎对象
        ProcessEngine pe=pec.buildProcessEngine();
    }
}

        建好之后,系统里应该会有25张表,都是以ACT开头的,如下:

这个表又可以按前缀分为几类,这里以一个学生提交审批的简单流程为例进行介绍,介绍之前,要先对流程进行初始化,示例代码如下:

private static void deploy(ProcessEngine pe, String processName, String desc){
        //获取流程引擎配置
        DeploymentBuilder builder = pe.getRepositoryService().createDeployment();
        builder.addClasspathResource("bpmn/" + processName + ".bpmn")
                    .name(desc)
                    .category("就业")
                    .addClasspathResource("bpmn/" + processName + ".png");

        builder.deploy();
}

这样流程数据将会在相关表里保存。

1、ACT_RE_*:

’RE’表示repository(存储),RepositoryService接口所操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。

从上面的截图看,一共有三张表,分别如下:

1)act_re_deployment:部署信息表,表示一个流程的静态定义,示例:

每部署一个流程,这个表里就会有流程的定义,它保存了流程名和ID

2)act_re_model  流程设计模型部署表,这个表可以为空,暂不清楚什么样的情况下会有数据

3)act_re_procdef 流程定义数据表,包含了流程的定义信息,如流程定义时的ID等,示例如下:

可以看到这张表中的deployment_id_引用的id正是act_re_deployment中的id

2、ACT_GE_*:

全局通用数据及设置(general),各种情况都使用的数据。从上图可以看到一共有两张表

1)act_ge_bytearray: 二进制数据表,存储流程定义的文件及图片的二进制形式

两条记录,一条存储流程文件,一条存储图片,有需要时,可以读出来

2)act_ge_property:流程引擎的全局属性,这个与具体某个流程无关,属于配置信息,固定4条:

3、ACT_RU_*:

‘RU’表示runtime,运行时表-RuntimeService。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。

相关示例后面给出

4、ACT_HI_*:

’HI’表示history,历史数据表,HistoryService。就是这些表包含着流程执行的历史相关数据,如结束的流程实例,变量,任务,等等

相关示例后面给出。除此之外还有两个表,介绍如下:

5、ACT_EVT_LOG:流程引擎事件表,目前无记录

6、ACT_PROCDEF_INFO:流程动态信息表,目前无记录

 

五、启动流程并审批

这里我们把启动和审批放在一起,以便于对表的分析,代码如下:

ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();

ProcessInstance processInstance =
                pe.getRuntimeService().startProcessInstanceByKey(applying.getProcess(), paramMap);

//完成第一个节点
Task task = pe.getTaskService()
    .createTaskQuery().taskAssignee(firstAssignee).singleResult();

if(task != null) {
     pe.getTaskService().complete(task.getId(), paramMap); //完成
}

这样就创建了一个流程实例,并完成了第一个节点的审核,根据前面的介绍,这个数据在act_ru相关表中存在,先看来看这些表:

1、ACT_RU_*:

这个系列下表示实时任务,有10张表,介绍如下:

1)ACT_RU_DEADLETTER_JOB : 作业死信表-作业失败超过重试次数,正常情况下,不会有数据

2)ACT_RU_EVENT_SUBSCR:运行时事件监听,如果没有事件,这个也为空

3)ACT_RU_EXECUTION:运行时流程执行实例表,在启动一个流程并完成一个节点之后,可以看到本表数据如下:

从表的定义来看,这里第一条记录为流程实例,第二条记录表示当前待执行的节点,可以看到是departmentApprove,表示学院审核,但为什么没有第一个节点的信息呢,因为节点1已经完成,被删除了。

4)ACT_RU_IDENTITYLINK: 运行时人员流程表,数据如下:

U002表示当前待审批人员

5)ACT_RU_INTEGRATION:这个表应该是activity7新增的,没有数据,暂时不清楚其用途

6)ACT_RU_JOB:运行时定时任务数据表,没有定时任务这个也是空的

7)ACT_RU_SUSPENDED_JOB:运行时作业暂停表,通常也为空

8)ACT_RU_TASK:运行时任务,存储当前待处理的任务,这个比较重要,同样完成之后就会删除,数据如下:

execution_id表示要执行哪个流程,assignee表示应该由谁来执行

9)ACT_RU_TIMER_JOB : 运行时定时器作业表,这个也没用到

10)ACT_RU_VARIABLE:运行时变量表,存储实际运行时,可以使用哪些变量

从上表可以看出来任务112501时,可以使用两个变量,值都为U002,用来定义审批人。流程112504没有对应的变量

 

2、ACT_HI_*:

本系列下一共有8张表,介绍如下:

1)ACT_HI_ACTINST:历史的活动节点表,这个表记录了流程的审批节点历史,介绍如下:

从这个表里可以看到审批人,节点名,开始与结束时间,持续时间等

2)ACT_HI_ATTACHMENT:历史的流程附件,本例无记录

3)ACT_HI_COMMENT:历史的说明性信息,本例也没有记录

4)ACT_HI_DETAIL:历史的流程运行中的细节信息,本例也无记录

5)ACT_HI_IDENTITYLINK:历史的流程运行过程中用户关系,这个和ACT_RU_IDENTITYLINK 相对应

6)ACT_HI_PROCINST:历史的流程实例,记录之前发生的流程

因为流程在结束后会删除掉,所以要查历史流程只能在这里查

7)ACT_HI_TASKINST:历史的任务实例

前面是历史节点信息,本表为历史任务信息,同样记录了任务的开始,结束,持续时间,如果是查流程,这个更为合理。

8)ACT_HI_VARINST:历史的流程运行中的变量信息

从上表可以看到流程节点112501有两个变量。

六、审批与打回

activity 只有审批的动作,没有打回的动作,想要打回,要么自己通过复杂的代码实现,要么就是通过流程图中加判断条件来控制,不同分支上加不同变量,比如本例就是如此,相关设计如下:

如上图,在处理本任务节点时,如果想实现打回的效果,传入变量flag的值为0,其它值为通过。

审批方法如下:

public boolean approve(String actProcessId, ApproveAction approveAction, 
        String reason, String userId,Map<String, Object> paramMap) {

        ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
        Task task = pe.getTaskService()
                .createTaskQuery()
                .taskAssignee(userId)
                .processInstanceId(actProcessId)
                .singleResult();

        if(task == null) {
            logger.warn("没有找到{}的审批任务", userId);
            return false;
        }

        int flag = approveAction == ApproveAction.PASS ? 1 : 0;
        paramMap.put("reason", reason);
        paramMap.put("flag", flag);

        pe.getTaskService().complete(task.getId(), paramMap);
        return true;
}

 我们先试一下打回之后,再看下数据的变化,通过对前面的分析,我们主要关注ru和hi的几个表:
ru表的变化如下:

ACT_RU_EXECUTION

可以看到执行流程已经变为提交人了,原学院审批人节点完成后,已经删除了
ACT_RU_IDENTITYLINK

这个和原来没变化,因为审批人都是同一个

ACT_RU_TASK

待执行任务表,已变成第一个任务了

ACT_RU_VARIABLE

这个表里增加了两个变量,看来变量是流程级别的?

再来看来历史表的变化
ACT_HI_ACTINST

可以看到各个节点都记录了,exclusivegateway1 表示选择节点,虽然没有审核,但也记录了

ACT_HI_IDENTITYLINK

这个没变化,另外 ACT_HI_PROCINST 表示历史流程,因为没结束,所以也没变化
ACT_HI_TASKINST

这个保存了所有任务
ACT_HI_VARINST

这个保存了所有变量


七、流程结束


结束并没有特别的动作,只要流程走完end节点之后就结束了。本例中,再次提交审核,这次选择通过,就可以实现结束。这里我们看下结束后,表的变化,由于ACT_RU的都已经结束,所以这里只分析ACT_HI,即历史表,各表情况如下:

再来看来历史表的变化
ACT_HI_ACTINST

可以看到所有节点都记录了

ACT_HI_IDENTITYLINK:无变化
ACT_HI_PROCINST :可以看到已经有结束时间了


ACT_HI_TASKINST

可以看到所有的审批节点
ACT_HI_VARINST

这个保存了所有变量信息。但这些变量看起来和任务并不关联


八、展示审批节点

 

通过分析,我们可以看到如果要展示审批节点,可以根据实例ID查 ACT_HI_TASKINST表,但该表中未记录审批动作是通过还是驳回,且也无法通过关联变量来实现。所以,只能考虑把这些信息在审批时就加到这个表里,看了下结构,description_是可以来记录这个信息的,字段类型为4000个varchar, 应该说足够了,剩下就是怎么放的问题。这个可以直接save。相当于是自定义一个json字符串放到description_里,取出来时再解析。
不过在网上查资料时,发现了一个更好的方式,就是加批注,这个对应ACT_HI_COMMENT,不仅如此,如果我们希望审批节点时存一些文件,也可以使用ACT_HI_ATTACHMENT。这就完美解决了问题。

示例代码如下:

            if(task != null) {
                pe.getTaskService().addComment(task.getId(),
                        processInstance.getProcessInstanceId(),
                        ApproveAction.COMMIT.toString(),
                        assignee.getName() + "|" );
                pe.getTaskService().complete(task.getId(), paramMap);
            }

这里没有单独放审批人名字的字段,所以将其放在理由里,显示时,再解析。该表中的数据如下:

那么结合ACT_HI_TASKINST,显示审批记录将是一件非常容易做到的事。


九、结语

本文对activity中的简单用法做了分析,重点介绍了其关键表结构,并结合实例进行了演示和数据分析,相信读完本文,会对activity的功能有较好的理解

你好!关于Activity工作的面试,我可以为您提供一些一般性的问题和答案,帮助您做好准备。请注意,以下问题和答案仅供参考,您可以根据自己的经验和知识进行回答。 1. 什么是Activity工作Activity工作是一种用于定义和执行业务程的技术。它通过将任务和活动组织成一个有序的程,使得业务过程的管理和执行更加简单和可控。 2. 请简要介绍Activity工作的主要组件。 Activity工作的主要组件包括:活动(Activity)、程(Workflow)、工作项(Work Item)、规则(Rule)和状态(State)等。 3. Activity工作有什么优势? Activity工作具有以下优势: - 提供了一种可视化的方式来描述和执行业务程。 - 支持业务逻辑的可重用性和模块化开发。 - 可以提高业务过程的可维护性和可扩展性。 - 支持监控和追踪业务程的执行情况。 4. 请举例说明如何使用Activity工作来建模一个简单的业务程。 例如,假设我们要建模一个请假申请程,其中包括以下几个步骤:填写申请表、主管审批、人力资源审批和通知申请人。我们可以使用Activity工作来定义并执行这个程,通过连接各个活动和规则,实现程的自动化。 5. 在使用Activity工作时,如何处理异常情况和错误? Activity工作提供了异常处理机制,通常可以通过捕获异常并采取相应的处理措施来处理异常情况和错误。例如,可以定义异常处理活动来记录错误信息、发送通知或执行其他必要的操作。 这些问题可以帮助您了解Activity工作的基本概念和应用。当然,在面试中还可能会有更加具体和深入的问题,建议您根据自己的经验和实际情况进行准备和回答。祝您面试顺利!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值