# activiti6 工作流 **Repository Path**: ly21st/my-activiti6 ## Basic Information - **Project Name**: activiti6 工作流 - **Description**: spring boot 集成activiti6的完整测试用例和说明,作者修正原流程用例、添加注释说明、运行通过 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2025-07-25 - **Last Updated**: 2025-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## 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.引入依赖 ```xml org.activiti activiti-spring-boot-starter-basic ${activiti.version} mybatis org.mybatis ``` #### 2.修改配置文件 ```yml 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.启动项目 ```java //因为本项目没有用到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文件下 ```java 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 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 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 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