1 Star 3 Fork 1

白鹭fly / activiti6 工作流

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 13.06 KB
一键复制 编辑 原始数据 按行查看 历史
白鹭fly 提交于 2022-05-02 09:22 . readMe

Activiti工作流

本项目是基于sytsuccess的myActiviti进行的二次开发,本作者主要完成工作为:
1、修正部分流程定义文件,使得测试test模块可以全部运行
2、对每个测试模块进行注释和中文说明
3、命令行执行: mvn test -D=ActivitiQuick#deploy

测试用例写的非常完整和详细,非常适合入门和系统性了解Activiti。第一次启动项目需要设置参数database-schema-update: true,用来自动创建数据库表。

测试用例从test/ActivitiQuick开始用起,批量执行测试用例是走不通的,务必用命令行逐一执行函数,顺序执行部署、启动、查看任务、结束任务。结束任务需要从查看任务中复制任务Id进来。

码云地址 https://gitee.com/baijigan/my-activiti6.git

1.引入依赖


<!本项目用的Mybatis Plus 在启动项目时会报jar包冲突,所以这里去掉Activity的Mybatis配置 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>${activiti.version}</version>
<exclusions>
    <exclusion><!排除activiti的mybatis,避免和外面的mybatis-plus冲突 -->
        <artifactId>mybatis</artifactId>
        <groupId>org.mybatis</groupId>
    </exclusion>
</exclusions>
</dependency>

2.修改配置文件

spring:
  activiti:
    database-schema-update: true
    check-process-definitions: false
    historyLevel: audit
    db-history-used: true
    async-executor-activate: false

    #用到的配置参数说明
    #database-schema-update  置项可以设置流程引擎启动和关闭时数据库执行的策略。
    #flase:       默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。(生产环境常用)
    #true:        activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建。(开发时常用)
    #create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)。(单元测试常用)
    #drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)

    #check-process-definitions  自动部署验证设置:true-开启(默认)、false-关闭

    #db-history-used 表示使用历史表,如果不配置,则工程启动后可以检查数据库,只建立了17张表,历史表没有建立,则流程图及运行节点无法展示

    #historyLevel 保存历史数据级别
    #none: 不记录历史流程,性能高,流程结束后不可读取
    #activiti: 归档流程实例和活动实例,流程变量不同步
    #audit: 默认值,在activiti基础上同步变量值,保存表单属性
    #full: 性能较差,记录所有实例和变量细节变化

# asyncExecutorActivate是指activiti在流程引擎启动就激活AsyncExecutor,异步:true-开启(默认)、false-关闭

3.启动项目

//因为本项目没有用到Spring Security,所以 需要在启动类上加上 exclude = SecurityAutoConfiguration.class 不然启动会保错
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class MyactivitiApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyactivitiApplication.class, args);
    }

}

4.运行

如果第一次运行则会新创建属于Activit的表 28张表

表说明
表前缀

act_ge_ 通用数据表,ge是general的缩写
act_hi_ 历史数据表,hi是history的缩写,对应HistoryService接口
act_id_ 身份数据表,id是identity的缩写,对应IdentityService接口
act_re_ 流程存储表,re是repository的缩写,对应RepositoryService接口,存储流程部署和流程定义等静态数据
act_ru_ 运行时数据表,ru是runtime的缩写,对应RuntimeService接口和TaskService接口,存储流程实例和用户任务等动态数据

表结构操作:

资源库流程规则表
act_re_deployment 部署信息表
act_re_model 流程设计模型部署表
act_re_procdef 流程定义数据表

运行时数据库表

act_ru_execution 运行时流程执行实例表
act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
act_ru_task 运行时任务节点表
act_ru_variable 运行时流程变量数据表
act_ru_timer_job
act_ru_suspended_job
act_ru_job
act_ru_event_subscr
act_ru_deadletter_job

历史数据库表

act_hi_actinst 历史节点表
act_hi_attachment 历史附件表
act_hi_comment 历史意见表
act_hi_identitylink 历史流程人员表
act_hi_detail 历史详情表,提供历史变量的查询
act_hi_procinst 历史流程实例表
act_hi_taskinst 历史任务实例表
act_hi_varinst 历史变量表

组织机构表(这几个表一般都不会使用,都会用自己的用户表)

act_id_group 用户组信息表
act_id_info 用户扩展信息表
act_id_membership 用户与用户组对应信息表
act_id_user 用户信息表

通用数据表

act_ge_bytearray 二进制数据表
act_ge_property 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,
act_evt_log
act_procdef_info

常用表
1 当部署流程文件时 影响4张表

act_re_procdef 系统属性表-存有next.dbid
act_ge_bytearray 资源表,相当于附件表
act_re_deployment 部署对象表
act_re_procdef 流程定义数据表

2 启动流程 影响7张表

act_ru_execution 执行对象表
act_hi_procinst 流程实例历史表
act_ru_task 当前正在执行任务表----待办列表
act_hi_taskinst 历史任务表
act_hi_actinst 历史活动表
act_ru_identitylink 当前任务执行人表
act_hi_identitylink 历史任务执行人表

3 使用流程变量 影响2张表

act_ru_variable 运行时流程变量表
act_hi_varinst 历史流程变量表

5.核心接口

RepositoryService:提供一系列管理流程部署和流程定义的API。
RuntimeService:在流程运行时对流程实例进行管理与控制。
TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。
IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。
ManagementService:提供对流程引擎进行管理和维护的服务。
HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。
FormService:表单服务。

6.画流程图

这里用的是Eclipse的画图工具,下载插件参考 下载参考:https://www.cnblogs.com/mingforyou/p/5347561.html
因业务简单和时间关系,我这里只是简单的使用activit的功能.具体其他的复杂功能用到在做记录

用到的节点

1:开始 Start Event
2:Task User Task
3:结束 End Event
开始和结束就没什么特殊的地方.这里主要记录下Task的简单设置参数

Task
1:添加UserTask节点 ,找到 Main Config 属性
2:Assignee 中代表当前节点负责人 可以直接在流程图中设置值,也可以动态设置: ${} 例:${userId} 
3:Candidate Users 中可以设置多个人(组任务),多个用 "," 隔开,候选人. 也可以动态设置: ${} 例:${userIds}
连线

连线中可以添加判断条件,如果多个节点,可以根据线的条件来决定走哪条线

1:添加UserTask节点 ,找到 Main Config 属性
2:Condition 中可以填写判断的条件,例:${outcome=='通过'},会去传入的参数中找 outcome 参数

流程图的例子可以参考 src/main/resources/processes 下的流程图.

7.代码

7.1 部署流程

把上边画好的流程图放到processes文件下

package com.sun.myactiviti.b_first;

import com.sun.myactiviti.ApplicationTests;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

public class ActivitiQuick extends ApplicationTests {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    private final String bpmnNameAndKey = "first";

    /*见表,默认启动的时候就会建好表格*/
    @Test
    public void createTable() {

    }

    /*第一步:--永远是画制流程图---部署流程图*/
    @Test
    public void deploy() {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("processes/first.bpmn")
                .addClasspathResource("processes/first.png")
                .key(bpmnNameAndKey)
                .name(bpmnNameAndKey + "name")
                .category("HR")
                .deploy();
        System.out.println("流程部署ID\t" + deploy.getId());
        System.out.println("流程keyID\t" + deploy.getKey());
        System.out.println("流程名称ID\t" + deploy.getName());
        System.out.println("流程分类ID\t" + deploy.getCategory());
    }

    /*第二步:启动一个流程实例,相当于----有人请假一次*/
    @Test
    public void start() {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(bpmnNameAndKey);
        System.out.println("流程实例ID\t" + processInstance.getId());
        System.out.println("流程定义ID\t" + processInstance.getProcessDefinitionId());
        System.out.println("流程定义key\t" + processInstance.getProcessDefinitionKey());
    }

    /*第三步:查找个人待办任务列表*/
    @Test
    public void findMyTask() {
        String assignee = "李四";
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .list();
        if (!CollectionUtils.isEmpty(list)) {
            for (Task task : list) {
                System.out.println("任务ID\t" + task.getId());
                System.out.println("任务名称\t" + task.getName());
                System.out.println("任务执行人\t" + task.getAssignee());
            }
        }

        // 任务ID	c8f8aa07-4b71-11ec-a8f0-acd564a26d7a
        // 任务名称	审批【部门经理】
        // 任务执行人	张三
    }

    /*第四步:执行任务*/
    @Test
    public void complte() {
        String taskId = "652773cc-4c33-11ec-94c8-acd564a26d7a";
        taskService.complete(taskId);
        System.out.println("任务执行完成");
    }

    /*第五步:查看历史流程实例*/
    @Test
    public void findhistProcessInstance() {
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(bpmnNameAndKey)
                .list();
        if (!CollectionUtils.isEmpty(list)) {
            for (HistoricProcessInstance historicProcessInstance : list) {
                System.out.println("业务系统key\t" + historicProcessInstance.getBusinessKey());
                System.out.println("部署对象ID\t" + historicProcessInstance.getDeploymentId());
                System.out.println("执行时长\t" + historicProcessInstance.getDurationInMillis());
                System.out.println("流程定义ID\t" + historicProcessInstance.getProcessDefinitionId());
                System.out.println("流程定义的key\t" + historicProcessInstance.getProcessDefinitionKey());
                System.out.println("流程定义名称\t" + historicProcessInstance.getProcessDefinitionName());
            }
        }
    }

    /*第六步:查看历史任务*/
    @Test
    public void findHisTask() {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .list();
        if (!CollectionUtils.isEmpty(list)) {
            for (HistoricTaskInstance historicTaskInstance : list) {
                System.out.println("任务执行人\t" + historicTaskInstance.getAssignee());
                System.out.println("任务名称\t" + historicTaskInstance.getName());
                System.out.println("任务ID\t" + historicTaskInstance.getId());
                System.out.println("流程实例ID\t" + historicTaskInstance.getProcessInstanceId());
                System.out.println("*****************");
            }
        }
    }

}

8:其余的代码

其余的代码都在test文件中可以查看. 其中:ActivitiController是当前项目中用的的接口整理出来的类,该文档主要参考的是马士兵教育的的Activiti视频.

码云地址 https://gitee.com/baijigan/my-activiti6.git

原项目地址 https://gitee.com/sytsuccess/myactiviti

Java
1
https://gitee.com/baijigan/my-activiti6.git
git@gitee.com:baijigan/my-activiti6.git
baijigan
my-activiti6
activiti6 工作流
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891