Springboot+Activiti7
本文最后更新于91 天前,其中的信息可能已经过时,如有错误请发送邮件到1770087309@qq.com

一、项目整合

1.1 引入依赖

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>com.mysql</groupId>
		<artifactId>mysql-connector-j</artifactId>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>com.baomidou</groupId>
		<artifactId>mybatis-plus-boot-starter</artifactId>
		<version>3.5.3.1</version>
	</dependency>
	<dependency>
		<groupId>cn.hutool</groupId>
		<artifactId>hutool-all</artifactId>
		<version>5.8.11</version>
	</dependency>

	<!--web-->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

	<!--引入activiti的springboot启动器 -->
	<dependency>
		<groupId>org.activiti</groupId>
		<artifactId>activiti-spring-boot-starter</artifactId>
		<version>7.1.0.M4</version>
		<exclusions>
			<!--除去mybatis依赖:如果你的项目中无mybatis或者mybatisPlus依赖可不加-->
			<exclusion>
				<artifactId>mybatis</artifactId>
				<groupId>org.mybatis</groupId>
			</exclusion>
		</exclusions>
	</dependency>
</dependencies>

1.2 修改配置文件

server:
  port: 18080

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/activity?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root

  activiti:
    #1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
    #2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
    #3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
    #4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
    database-schema-update: true
    #检测历史表是否存在 activiti7默认没有开启数据库历史记录 启动数据库历史记录
    db-history-used: true
    #记录历史等级 可配置的历史级别有none, activity, audit, full
    #none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
    #activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
    #audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
    #full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
    history-level: full
    #校验流程文件,true表示自动部署resources下的processes文件夹里的流程文件
    check-process-definitions: false
    # id值是否使用uuid,false表示使用数据库自增值
    use-strong-uuids: true

logging:
  level:
    com.itheima: debug
  pattern:
    dateformat: HH:mm:ss
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: com.kch.activitydemo.pojo
  global-config:
    db-config:
      id-type: auto

1.3 修改启动文件

由于activiti-spring-boot-starter自身引入了spring security依赖,所以可以在启动类上移除

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })

1.4 启动项目生成工作流表

运行springboot项目启动类,第一次运行,会检查数据库是否有工作流所需表,如果没有,会自动生成,生成的表都act_开头,一共25张表。

工作流相关表分为4类:

第一类:act_ge开头,存放通用数据、一些流程文件等
第二类:act_hi开头,存放工作流程中的历史数据,如历史任务信息,历史流程参数等
第三类:act_re开头,存放工作流流程定义和发布的信息
第四类:act_ru开头,存放工作流当前正在进行流程的信息,一个流程走完,ru表会删除相关内容,查询历史信息就是act_hi中获取

补充,自动生成数据库表完成后,运行一下两句sql命令
— 修复Activiti7的M4版本缺失字段Bug

alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL;
alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL;

二、BPMN插件

2.1 Activiti BPMN visualizer 安装

2.2 创建BPMN文件

2.3 视图模式打开bpmn.xml

三、Activiti使用流程

Activiti 流程操作步骤

  • 定义流程:按照BPMN的规范,使用流程定义工具,用流程符号把整个流程描述出来
  • 部署流程:把画好的流程定义文件,加载到数据库中,生成表的数据
  • 启动流程:使用 java 代码来操作数据库表中的内容
  • 处理任务:操作流程当中的各个任务

常用API:由Spring管理,可以直接注入使用

RepositoryServiceActiviti的资源管理接口
RuntimeServiceActiviti的流程运行管理接口
TaskServiceActiviti的任务管理接口
HistoryServiceActiviti的历史管理接口

3.2 流程定义

通过工具创建BPMN文件,保存到resource目录下

3.3 部署流程

/**
 * 流程部署
 */
@Test
public void testDeploy() {
	// 进行部署
	Deployment deployment = repositoryService.createDeployment()
			.addClasspathResource("bpmn/apply.bpmn20.xml")
			.addClasspathResource("bpmn/apply.png")
			.name("报销流程")
			.deploy();

	//流程部署时候生成的,每次部署都会生成一个新的部署id,存储在ACT_RE_DEPLOYMENT表中
	System.out.println("流程部署ID:" + deployment.getId());   
        //bpmn设计的名称
	System.out.println("流程部署名称:" + deployment.getName()); 
	System.out.println("流程部署成功");
}

小结:

流程文件部署完成后会生成部署id,存储在ACT_RE_DEPLOYMENT表

流程文件部署完成后会生成流程定义id,存储在ACT_RE_PROCDEF表

一个流程文件部署可以多次部署,每次部署都会生成新的部署id,流程定义id,但是拥有相同的key(BPMN文件中process标签的id)

3.4 启动流程

方式一:使用流程定义的key启动流程

/**
 * 启动流程实例
 */
@Test
public void testStartProcess() {

	ProcessInstance instance = runtimeService.startProcessInstanceByKey("apply");

	// 获取流程实例的相关信息
	System.out.println("流程定义的id = " + instance.getProcessDefinitionId()); // 流程定义部署是生成的,流程定义id存储在ACT_RE_PROCDEF表中
	System.out.println("流程实例的id = " + instance.getId()); // 贯穿本次启动的流程实例的id, 存储在 ACT_RU_EXECUTION 表和 ACT_HI_PROCINST 表中

	//两个id关联关系存储在 ACT_RU_EXECUTION 表和 ACT_HI_PROCINST 表中

	System.out.println("启动流程成功 ");
}

方式二:使用流程定义id部署

/**
 * 启动流程实例
 */
@Test
public void testStartProcess() {
	// 根据流程定义id启动流程实例
	//流程定义id是部署流程后生成,存在ACT_RE_DEPLOYMENT表中
	ProcessInstance instance = runtimeService.startProcessInstanceById("apply:1:eb0d87ce-f7d2-11ef-af3d-005056c00001");

	// 获取流程实例的相关信息
	System.out.println("流程定义的id = " + instance.getProcessDefinitionId()); // 流程定义部署是生成的,流程定义id存储在ACT_RE_PROCDEF表中
	System.out.println("流程实例的id = " + instance.getId()); // 贯穿本次启动的流程实例的id, 存储在 ACT_RU_EXECUTION 表和 ACT_HI_PROCINST 表中

	//两个id关联关系存储在 ACT_RU_EXECUTION 表和 ACT_HI_PROCINST 表中

	System.out.println("启动流程成功 ");
}

方式三:BusinessKey 绑定流程实例启动

/**
 * 启动流程,需要进行 BusinessKey 绑定流程实例
 */
@Test
public void testStartBindBusinessKey() {
	String businessKey = "kch";
	// 根据流程定义的key启动流程实例,这个key是在定义bpmn的时候设置的
	// 在启动流程的时候将业务key加进去,也可使用startProcessInstanceById传流程定义id
	ProcessInstance instance = runtimeService.startProcessInstanceByKey("apply", businessKey);
	// 获取流程实例的相关信息
	System.out.println("流程定义id = " + instance.getProcessDefinitionId());
	System.out.println("流程实例id = " + instance.getId());
	System.out.println("业务标识 = " + instance.getBusinessKey());
}

小结:

流程启动后会生成流程实例id,存储在 ACT_RU_EXECUTION 表和 ACT_HI_PROCINST 表中

流程定义id和流程实例id的关系在ACT_RU_EXECUTION表中

每次根据key启动,如果有多个版本的流程定义,会启动最新的一个

3.5 查询任务

查询流程定义相关信息

/**
 * 查询流程相关信息
 */
@Test
public void testDefinitionQuery() {
	// 获取流程定义集合
	List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
			.processDefinitionKey("apply")
			// 最新的一个版本
//                .latestVersion()
			.list();
	// 遍历集合
	for (ProcessDefinition definition : processDefinitionList) {
		System.out.println("流程定义id = " + definition.getId()); //存储在ACT_RE_PROCDEF中
		System.out.println("流程定义名称 = " + definition.getName()); //bpmn时定义,存储在ACT_RE_PROCDEF中
		System.out.println("流程定义key = " + definition.getKey()); //存储在ACT_RE_PROCDEF中
		System.out.println("流程定义版本 = " + definition.getVersion()); //存储在ACT_RE_PROCDEF中
		System.out.println("流程部署id = " + definition.getDeploymentId()); // 流程定义部署是生成的,存在ACT_RE_DEPLOYMENT表中
		System.out.println("===============");
	}
}

根据流程实例id查询到流程实例

/**
 * 根据流程实例id查询当前流程实例
 */
@Test
public void testQueryProcessStatus() {
	String processInstanceId = "0d88094a-f7f2-11ef-9e68-005056c00001"; // 流程实例ID
	List<Task> tasks = taskService.createTaskQuery()
			.processInstanceId(processInstanceId) // 查询指定流程实例的任务
			.list();

	for (Task task : tasks) {
		System.out.println("任务ID: " + task.getId());
		System.out.println("任务名称: " + task.getName());
		System.out.println("当前分配人: " + task.getAssignee());
		System.out.println("任务的流程定义ID: " + task.getProcessDefinitionId());
		System.out.println("任务的流程实例ID: " + task.getProcessInstanceId());
	}
}

根据流程定义key查询流程实例

/**
 * 根据流程实例id查询当前流程实例
 */
@Test
public void testQueryProcessStatus() {
	String processInstanceId = "0d88094a-f7f2-11ef-9e68-005056c00001"; // 流程实例ID
	List<Task> tasks = taskService.createTaskQuery()
			.processDefinitionKey("apply")  // 根据流程定义的key查询
			.list();

	for (Task task : tasks) {
		System.out.println("任务ID: " + task.getId());
		System.out.println("任务名称: " + task.getName());
		System.out.println("当前分配人: " + task.getAssignee());
		System.out.println("任务的流程定义ID: " + task.getProcessDefinitionId());
		System.out.println("任务的流程实例ID: " + task.getProcessInstanceId());
	}
}

查询某个人的待办任务

/**
 * 查询某个人的待办任务
 */
@Test
public void testSelectTodoTaskList() {
	String assignee = "张三";
	// 使用面对对象方式查询数据库
	List<Task> tasks = taskService.createTaskQuery() //ACT_RU_TASK表
			.processDefinitionKey("apply")  // 根据流程定义的key查询
//                .processInstanceId("ce8c33be-f7e9-11ef-a2f4-005056c00001")  // 根据流程实例id查询
			.taskAssignee(assignee)
			// 返回多个结果
			.list();
	// 只返回一个结果
	// .singleResult();

	// 获取流程实例的相关信息
	for (Task task : tasks) {
		System.out.println("流程定义的id = " + task.getProcessDefinitionId());
		System.out.println("流程实例的id = " + task.getProcessInstanceId());
		System.out.println("任务id = " + task.getId());
		System.out.println("任务名称 = " + task.getName());
	}
}

查询审批历史

/**
 * 查询审批历史
 */
@Test
public void testSelectHistoryTask() {
	String processInstanceId = "f0dccbba-f7f3-11ef-9bdb-005056c00001";
	String assignee = "张三";
	// 获取历史审核信息
	List<HistoricActivityInstance> userTask = historyService.createHistoricActivityInstanceQuery()
			.activityType("userTask")
			// 指定实例的id
			.processInstanceId(processInstanceId)
			.taskAssignee(assignee)
			.finished()
			.list();

	for (HistoricActivityInstance instance : userTask) {
		System.out.println("任务名称 = " + instance.getActivityName());
		System.out.println("任务开始时间 = " + instance.getStartTime());
		System.out.println("任务结束时间 = " + instance.getEndTime());
		System.out.println("任务耗时 = " + instance.getDurationInMillis());
		// 获取审批批注信息
		List<Comment> taskComments = taskService.getTaskComments(instance.getTaskId());
		if (!taskComments.isEmpty()) {
			System.out.println("审批批注 = " + taskComments.get(0).getFullMessage());
		}
	}
}

小结:

当前执行任务存储在ACT_RU_TASK表中

3.6 执行任务

指定用户去完成任务待办

/**
 * 指定用户去完成任务待办:多人审批在这操作,改变审核人名称就行了
 */
@Test
public void testCompleteTask() {
	String assignee = "李四";
	List<Task> tasks = taskService.createTaskQuery()
			.processDefinitionKey("apply")
//                .processInstanceId("a570bd84-f7f2-11ef-a28f-005056c00001")
			.taskAssignee(assignee)
			.list();
	if (tasks != null && !tasks.isEmpty()) {
		// 当前流程图所限制,只能做审核同意的动作
		for (Task task : tasks) {
			taskService.complete(task.getId());
			System.out.println(assignee + "完成了任务:" + task.getName());
		}
	}
}

审批添加备注

/**
 * 审批添加备注
 */
@Test
public void testAddComment() {
	String assignee = "张三";
	List<Task> tasks = taskService.createTaskQuery()
			.processDefinitionKey("apply")
			.taskAssignee(assignee)
			.list();
	if (tasks != null && !tasks.isEmpty()) {
		// 当前流程图所限制,只能做审核同意的动作
		for (Task task : tasks) {
			// 添加备注
			taskService.addComment(task.getId(), task.getProcessInstanceId(), assignee + "表示同意");
			taskService.complete(task.getId());
		}
	}
}

觉得有帮助可以投喂下博主哦~感谢!
作者:KCH
版权声明: 转载请注明文章地址及作者哦~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇