工作流已经广泛使用,如下介绍入门
pom中先引入
<!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring-boot-starter -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
引入这个后,启动项目,数据库就会有想应的表
代码如下:
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private HistoryService historyService;
/**
* 部署流程
*/
@GetMapping("/prepare")
public void prepare() {
// 创建一个部署对象
Deployment deployment = repositoryService.createDeployment ()
.name ("请假流程")
.addClasspathResource ("bpmn/test_bpm20.bpmn")
.addClasspathResource ("bpmn/test_bpm20.png")
.deploy ();
System.out.println ("部署ID:" + deployment.getId ());
System.out.println ("部署名称:" + deployment.getName ());
}
/**
* 查询流程实例
*/
@GetMapping("/queryProcessDefinition")
public void queryProcessDefinition(){
System.out.println("queryProcessDefinition:start");
String processDefinitionKey="testid";
//查询流程定义
ProcessDefinitionQuery processDefinitionQuery=repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> list=processDefinitionQuery.processDefinitionKey(processDefinitionKey)
.list();
for(ProcessDefinition processDefinition:list){
System.out.println("流程部署id:"+processDefinition.getDeploymentId());
System.out.println("流程定义id:"+processDefinition.getId());
System.out.println("流程定义名称:"+processDefinition.getName());
System.out.println("流程定义key:"+processDefinition.getKey());
System.out.println("流程定义版本:"+processDefinition.getVersion());
}
}
/**
* 删除已经部署成功的流程定义
* 背后影响的表
* act_ge_bytearray
*act_re_deployment
* act_re_prodef
*/
@GetMapping("/deleteDeployment")
public void deleteDeployment(){
String deploymentId="b683db33-ca3a-11ea-a392-00ff2b031dcd";
//设置true级联删除,即使该流程有流程实例启动也可以删除,false有实例删除会出错
repositoryService.deleteDeployment(deploymentId,true);
}
/**
* 启动流程实例,执行流程,部署在activity,执行流程表示一次执行
* 启动流程设置流程变量,变量的作用域是整个流程实例
*/
@GetMapping("/startProcess")
public void startProcess() {
String processDefinitionKey = "testid";
Map<String, Object> map = new HashMap<>();
//使用UEL 表达式设置,使用流程分配任务
// 学生填写申请单 Assignee:${student}
map.put ("student", "lucy");
// 班主任审批 Assignee:${teacher}
map.put ("teacher", "jack");
ProcessInstance instance = runtimeService.startProcessInstanceByKey (processDefinitionKey, "1001",map);
String businessKey=instance.getBusinessKey();
System.out.println ("流程实例businessKey:" + businessKey);
System.out.println ("流程实例ID:" + instance.getId ());
System.out.println ("流程定义ID:" + instance.getProcessDefinitionId ());
}
/**
* 任务查询,开启一个流程,就会进入流程图第一个节点,一个节点就相当于一个任务
*/
@GetMapping("/searchTask")
public List<String> searchTask() {
//流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
List<Task> list = taskService.createTaskQuery ()
//流程实例key
.processDefinitionKey ("testid")//使用流程定义的id查询
//查询某个的任务
.taskAssignee("lucy")
.orderByTaskCreateTime().desc()//使用创建时间升序
.list ();
List<String> idList = new ArrayList<String>();
for (Task task : list) {
idList.add (task.getId ());
System.out.println ("任务ID:" + task.getId ());
System.out.println ("任务名称:" + task.getName ());
System.out.println ("任务的创建时间:" + task.getCreateTime ());
System.out.println ("任务的办理人:" + task.getAssignee ());
System.out.println ("流程实例ID:" + task.getProcessInstanceId ());
System.out.println ("执行对象ID:" + task.getExecutionId ());
System.out.println ("流程定义ID:" + task.getProcessDefinitionId ());
}
return idList;
}
或者你用activity里面提供的ProcessEngine类
在resources下面新增activiti.cfg.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--这里的类太多别导错了 -->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 配置流程引擎配置对象 -->
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://10.217.56.131:3306/activiti_test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&allowMultiQueries=true&useSSL=false"></property>
<property name="jdbcUsername" value="brt"></property>
<property name="jdbcPassword" value="brt123456"></property>
<!-- 注入数据源信息 -->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<!-- 注入自动建表设置 -->
<property name="processEngineConfiguration" ref="processEngineConfiguration"></property>
</bean>
</beans>
代码:
/**
* 部署流程
*/
@GetMapping("/prepare")
public void prepare() {
// 创建一个部署对象
Deployment deployment = repositoryService.createDeployment ()
.name ("请假流程")
.addClasspathResource ("bpmn/users.bpmn")
.addClasspathResource ("bpmn/users.png")
.deploy ();
System.out.println ("部署ID:" + deployment.getId ());
System.out.println ("部署名称:" + deployment.getName ());
}
/**
* 启动流程实例,执行流程,部署在activity,执行流程表示一次执行
* 启动流程设置流程变量,变量的作用域是整个流程实例
*/
@GetMapping("/startProcess")
public void startProcess() {
String processDefinitionKey = "myProcess";
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
ProcessInstance instance = processEngine.getRuntimeService().startProcessInstanceByKey (processDefinitionKey, "1002");
/*
* Map<String,Object> map=new HashMap<String,Object>(); map.put("ids",
* "小李,小陈,小文"); ProcessInstance instance =
* runtimeService.startProcessInstanceByKey (processDefinitionKey,map, "1002");
*/
//还可以加监听
String businessKey=instance.getBusinessKey();
System.out.println ("流程实例businessKey:" + businessKey);
System.out.println ("流程实例ID:" + instance.getId ());
System.out.println ("流程定义ID:" + instance.getProcessDefinitionId ());
}
/**
* 没有用户拾取
*/
@GetMapping("/findMyGroupTask")
@Test
public void findMyGroupTask() {
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
String user="B";
List<Task> list = processEngine.getTaskService().createTaskQuery ()
//流程实例key
.processDefinitionKey ("myProcess")//使用流程定义的id查询
//查询某个的任务
.taskCandidateUser(user)
.list ();
List<String> idList = new ArrayList<String>();
for (Task task : list) {
idList.add (task.getId ());
System.out.println ("任务ID:" + task.getId ());
System.out.println ("任务名称:" + task.getName ());
System.out.println ("任务的创建时间:" + task.getCreateTime ());
System.out.println ("任务的办理人:" + task.getAssignee ());
System.out.println ("流程实例ID:" + task.getProcessInstanceId ());
System.out.println ("执行对象ID:" + task.getExecutionId ());
System.out.println ("流程定义ID:" + task.getProcessDefinitionId ());
}
processEngine.close();
}
/**
* 拾取任务,此个任务的assignee会出现值
*/
@GetMapping("/claimTask")
public void claimTask() {
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
//可以是组任务,也可以是非组人员
String candiate ="B";
Task task=processEngine.getTaskService().createTaskQuery()
.processDefinitionKey("myProcess").
taskCandidateUser(candiate)
.singleResult();
if(task!=null) {
taskService.claim(task.getId(), candiate);
System.out.println("任务被:"+candiate+"拾取");
}
processEngine.close();
}
/**
* 查看任务
*/
@GetMapping("/getCompleteTask")
public void getCompleteTask() {
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
//查询自己的任务然后通过id进行提交
Task task=processEngine.getTaskService().createTaskQuery().processDefinitionKey("myProcess")
.taskAssignee("B").singleResult();
if(task!=null) {
taskService.complete(task.getId());
System.out.println("任务处理完毕");
}
}
/**
*任务退回/交接
*/
@GetMapping("/taskReturn")
public void taskReturn() {
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
Task task=processEngine.getTaskService().createTaskQuery().processDefinitionKey("myProcess")
.taskAssignee("B").singleResult();
if(task!=null) {
//任务退回,任务id,null代表没有处理人执行,需要后续再次拾取任务
//第二个参数部位空代表将该任务交给处理人,个人任务回退到组任务,前提一定是组任务null
taskService.setAssignee(task.getAssignee(), "B");
System.out.println("任务退回");
}
}
/**
*任务退回/交接
*/
@GetMapping("/taskBack")
public void taskBack() {
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
Task task=processEngine.getTaskService().createTaskQuery().processDefinitionKey("myProcess")
.taskAssignee("B").singleResult();
if(task!=null) {
//任务退回,任务id,null代表没有处理人执行,需要后续再次拾取任务
//第二个参数部位空代表将该任务交给处理人,个人任务回退到组任务,前提一定是组任务null
taskService.setAssignee(task.getAssignee(), null);
System.out.println("任务退回");
/*
* //或者直接根据taskid进行操作 String taskId=""; taskService.setAssignee(taskId, null);
*/
}
}
/**
* 向组任务添加新成员
*/
@GetMapping("/addGroupUser")
public void addGroupUser(){
String taskId="9fb7669d-d888-11ea-815b-00ff2b031dcd";
String userId="H";
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
processEngine.getTaskService().addCandidateUser(taskId, userId);
}
/**
* 从组任务中删除成员
*/
@GetMapping("/deleteGroupUser")
public void deleteGroupUser() {
String taskId="9fb7669d-d888-11ea-815b-00ff2b031dcd";
String userId="H";
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
processEngine.getTaskService().deleteCandidateUser(taskId, userId);
}
/**
* 正在执行的组任务办理人
* 查询正在执行的任务暴力人表 act_ru_identitylink
*/
@GetMapping("/findRunPersonTask")
public void findRunPersonTask() {
String taskId="9fb7669d-d888-11ea-815b-00ff2b031dcd";
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
List<IdentityLink> list=processEngine.getTaskService().getIdentityLinksForTask(taskId);
if (list!=null&&list.size()>0) {
for(IdentityLink identityLink:list) {
System.out.println(identityLink.getTaskId()+" "+identityLink.getType()
+identityLink.getProcessInstanceId()+" "+identityLink.getUserId());
}
}
}
/**
* 获取历史组任务办理人
* 查询历史任务办理人表 act_hi_identitylink
*/
@GetMapping("/findHistoryPersonTask")
public void findHistoryPersonTask() {
//流程实例id
String processInstanceId="9fadc9a9-d888-11ea-815b-00ff2b031dcd";
//载入资源
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建引擎
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
//通过实例id查询,查询都是参与者
List<HistoricIdentityLink> list=processEngine.getHistoryService().getHistoricIdentityLinksForProcessInstance(processInstanceId);
//通过任务,查询的都是候选者(candidate)
//getHistoricIdentityLinksForTask(taskId)
if(list!=null&&list.size()>0) {
for(HistoricIdentityLink historicIdentityLink:list) {
System.out.println(historicIdentityLink.getTaskId()+" "
+historicIdentityLink.getType()+" "
+historicIdentityLink.getProcessInstanceId()+" "
+historicIdentityLink.getUserId());
}
}
}
表说明:
ACT_RE_DEPLOYMENT:在createDeployment后数据库将会出现一条数据
ACT_RE_PROCDEF:在startProcessInstanceByKey后,这个表将会新增数据
ACT_RU_TASK:节点任务,当运行一个工作流,这个会新增一条数据,就是工作流中第一个节点
ACT_RU_:等都是运行时候的数据
组任务:
ACT_RU_TASK里面没有 ASSIGNEE_这个信息
相关数据会保存在ACT_RU_IDENTITYLINK这个表里面
Execution流程实例执行表,一个流程实例运行完成,此表与流程实例相关记录删除
Task:执行到第一个任务借店,此表会插入一条记录,表示当前任务执行情况
Procinst:流程实例历史表
Taskinst:历史任务插入一条记录
Actinst历史表
然后根据上面代码逐个赋值。
参考:
详解
https://blog.csdn.net/oWanShiKaiTouNan/article/details/106837317
流程图具体画法
https://blog.csdn.net/taojin12/article/details/105064582
踩坑记录
https://www.cnblogs.com/momoweiduan/p/9454140.html
继续学习
https://blog.csdn.net/MrWangf/article/details/89473748
http://www.manongjc.com/detail/15-ivjjcptktjauwvb.html
https://www.cnblogs.com/szhhhh/p/12653240.html
https://blog.csdn.net/MrWangf/article/details/89473748
https://blog.csdn.net/weixin_44096448/article/details/103615512
http://www.mossle.com/docs/jbpm4devguide/html/bpmn2.html
https://activiti.gitbook.io/activiti-7-developers-guide
https://segmentfault.com/a/1190000021129168#item-4
https://segmentfault.com/a/1190000021279081?utm_source=tag-newest
https://www.jianshu.com/p/fc442e84ea37
https://www.cnblogs.com/firebata/p/5033527.html