下载插件
首先下载Activity插件,在19版之后的idea不再维护之前的插件,下载新插件
下载依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</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>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Apache Commons DBCP -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version> <!-- 替换为实际版本号 -->
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
spring和activity版本和我一致,避免出现不兼容问题(不同版本的activity使用方式也有差异)
创建配置类
在resources文件下创建 activiti.cfg.xml (命名一定要一致,因为acitity默认读取这个文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--dbcp链接池-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:"/>
<property name="username" value=""/>
<property name="password" value=""/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!--在默认方式下 bean的id 固定为 processEngineConfiguration-->
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--配置数据库相关的信息-->
<!--数据库驱动
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>-->
<!--数据库链接
<property name="jdbcUrl" value="jdbc:mysql:///activiti"/>-->
<!--数据库用户名
<property name="jdbcUsername" value="root"/>-->
<!--数据库密码
<property name="jdbcPassword" value="123456"/>-->
<!--直接引用上面配置的链接池-->
<property name="dataSource" ref="dataSource"/>
<!--actviti数据库表在生成时的策略
true - 如果数据库中已经存在相应的表,那么直接使用,
如果不存在,那么会创建-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
配置数据库信息
绘画流程图
绘画完后会自动保存到文件
直接提供文件:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
<process id="test" name="test" isExecutable="true">
<startEvent id="sid-6f072ea9-86ec-41d6-8407-d78e22c2aed5" name="请假提交申请"/>
<userTask id="sid-e47fd7c2-91d1-42d3-9cca-88c85d5a1f3c" name="部门领导审批"/>
<exclusiveGateway id="sid-cea6ac0e-f479-4297-841c-64b8b6426ef6"/>
<sequenceFlow id="sid-3326aae1-d115-4f5a-bbb4-3664a44d738d" sourceRef="sid-e47fd7c2-91d1-42d3-9cca-88c85d5a1f3c" targetRef="sid-cea6ac0e-f479-4297-841c-64b8b6426ef6"/>
<userTask id="sid-c2feff16-787c-4c36-853f-ca6e0100e88b" name="人工审批"/>
<sequenceFlow id="sid-504e03c6-15c0-440b-bec9-89367e6ad97b" sourceRef="sid-cea6ac0e-f479-4297-841c-64b8b6426ef6" targetRef="sid-c2feff16-787c-4c36-853f-ca6e0100e88b" name="同意">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
<exclusiveGateway id="sid-b524f8c0-19ab-4c1a-bc92-80ed8fe514e1"/>
<userTask id="sid-1e23d2bf-2eea-48f5-9e80-d84eff68ca47" name="销毁"/>
<sequenceFlow id="sid-035b89cf-cd8a-40e4-89f9-ae8f03a9318f" sourceRef="sid-c2feff16-787c-4c36-853f-ca6e0100e88b" targetRef="sid-b524f8c0-19ab-4c1a-bc92-80ed8fe514e1"/>
<sequenceFlow id="sid-668ddb21-5f23-49cf-a734-6053016d6243" sourceRef="sid-b524f8c0-19ab-4c1a-bc92-80ed8fe514e1" targetRef="sid-1e23d2bf-2eea-48f5-9e80-d84eff68ca47" name="同意">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
<endEvent id="sid-b1a8bec3-c527-4de3-9967-cd16eea9f2db" name="结束"/>
<sequenceFlow id="sid-bd602564-662a-4b97-8d7c-e208d26f91ad" sourceRef="sid-1e23d2bf-2eea-48f5-9e80-d84eff68ca47" targetRef="sid-b1a8bec3-c527-4de3-9967-cd16eea9f2db"/>
<userTask id="sid-62f364cb-6ab3-45f7-a53d-1ec7665cb8fa" name="调整申请"/>
<sequenceFlow id="sid-9d9e0262-9a03-40c4-bc6c-b86b248aac31" sourceRef="sid-b524f8c0-19ab-4c1a-bc92-80ed8fe514e1" targetRef="sid-62f364cb-6ab3-45f7-a53d-1ec7665cb8fa" name="不同意">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
<sequenceFlow id="sid-81017c92-cf68-4822-a17b-4df96aaaa235" sourceRef="sid-cea6ac0e-f479-4297-841c-64b8b6426ef6" targetRef="sid-62f364cb-6ab3-45f7-a53d-1ec7665cb8fa" name="不同意">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
<sequenceFlow id="sid-b9aef3bb-1a4f-444f-b740-c6f6a80172d3" sourceRef="sid-6f072ea9-86ec-41d6-8407-d78e22c2aed5" targetRef="sid-e47fd7c2-91d1-42d3-9cca-88c85d5a1f3c"/>
<exclusiveGateway id="sid-af5fa5a2-2f25-4fd0-9e51-32faf1b15825"/>
<sequenceFlow id="sid-9969d938-a86a-4b17-87cc-da4ed29edd92" sourceRef="sid-62f364cb-6ab3-45f7-a53d-1ec7665cb8fa" targetRef="sid-af5fa5a2-2f25-4fd0-9e51-32faf1b15825"/>
<sequenceFlow id="sid-51846001-076b-4249-8db1-0cf5ba808c56" sourceRef="sid-af5fa5a2-2f25-4fd0-9e51-32faf1b15825" targetRef="sid-e47fd7c2-91d1-42d3-9cca-88c85d5a1f3c" name="重新申请">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
<sequenceFlow id="sid-01ba1fa5-2272-4db2-a9af-ad7a0791786e" sourceRef="sid-af5fa5a2-2f25-4fd0-9e51-32faf1b15825" targetRef="sid-b1a8bec3-c527-4de3-9967-cd16eea9f2db" name="结束流程">
<conditionExpression xsi:type="tFormalExpression"/>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_test">
<bpmndi:BPMNPlane bpmnElement="test" id="BPMNPlane_test">
<bpmndi:BPMNShape id="shape-4a56222c-a949-45e8-9bdd-fefe568a98c3" bpmnElement="sid-6f072ea9-86ec-41d6-8407-d78e22c2aed5">
<omgdc:Bounds x="-400.0" y="-335.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-8650ca00-6fba-4f7e-a42a-3cde9c3732d9" bpmnElement="sid-e47fd7c2-91d1-42d3-9cca-88c85d5a1f3c">
<omgdc:Bounds x="-270.0" y="-340.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-339a685e-5018-4bb9-86e1-df81b0e0d381" bpmnElement="sid-cea6ac0e-f479-4297-841c-64b8b6426ef6">
<omgdc:Bounds x="-125.0" y="-310.0" width="40.0" height="40.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-8a49c120-3cec-49c8-8d3d-2f2dce37253f" bpmnElement="sid-3326aae1-d115-4f5a-bbb4-3664a44d738d">
<omgdi:waypoint x="-170.0" y="-300.0"/>
<omgdi:waypoint x="-125.0" y="-290.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-2d80c228-52db-4315-b658-f6754e1bc7c9" bpmnElement="sid-c2feff16-787c-4c36-853f-ca6e0100e88b">
<omgdc:Bounds x="-20.0" y="-330.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-654db559-6404-4aee-b76d-fce5cfa57ac6" bpmnElement="sid-504e03c6-15c0-440b-bec9-89367e6ad97b">
<omgdi:waypoint x="-85.0" y="-290.0"/>
<omgdi:waypoint x="-20.0" y="-290.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-7e1a9625-d407-4675-97a3-ec8fe219707b" bpmnElement="sid-b524f8c0-19ab-4c1a-bc92-80ed8fe514e1">
<omgdc:Bounds x="130.0" y="-300.0" width="40.0" height="40.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-c109564f-b8f0-49d4-a8c5-4827b1360d46" bpmnElement="sid-1e23d2bf-2eea-48f5-9e80-d84eff68ca47">
<omgdc:Bounds x="240.0" y="-330.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-78f2c4db-36be-41a3-a643-b50180d30eb3" bpmnElement="sid-035b89cf-cd8a-40e4-89f9-ae8f03a9318f">
<omgdi:waypoint x="80.0" y="-290.0"/>
<omgdi:waypoint x="130.0" y="-280.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-44828bb6-de84-46bf-8468-c3879d2e5dd3" bpmnElement="sid-668ddb21-5f23-49cf-a734-6053016d6243">
<omgdi:waypoint x="170.0" y="-280.0"/>
<omgdi:waypoint x="240.0" y="-290.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-5e46f818-0b3f-42df-aa2c-ab127f230cda" bpmnElement="sid-b1a8bec3-c527-4de3-9967-cd16eea9f2db">
<omgdc:Bounds x="295.0" y="-55.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-9172d5e6-3d33-4ad9-b68c-eb25b02bca58" bpmnElement="sid-bd602564-662a-4b97-8d7c-e208d26f91ad">
<omgdi:waypoint x="315.0" y="-250.0"/>
<omgdi:waypoint x="310.0" y="-55.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-3ece8ff1-a62b-4b61-94eb-ede93f190a28" bpmnElement="sid-62f364cb-6ab3-45f7-a53d-1ec7665cb8fa">
<omgdc:Bounds x="-150.0" y="-180.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-549b3284-a137-4345-9dac-45650f03aaf2" bpmnElement="sid-9d9e0262-9a03-40c4-bc6c-b86b248aac31">
<omgdi:waypoint x="150.0" y="-260.0"/>
<omgdi:waypoint x="150.0" y="-145.0"/>
<omgdi:waypoint x="-50.0" y="-160.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-038d562b-a568-4330-97e5-6b39f06b38e1" bpmnElement="sid-81017c92-cf68-4822-a17b-4df96aaaa235">
<omgdi:waypoint x="-105.0" y="-270.0"/>
<omgdi:waypoint x="-100.0" y="-180.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-84f72973-dd37-42bc-8eff-04e820fd7079" bpmnElement="sid-b9aef3bb-1a4f-444f-b740-c6f6a80172d3">
<omgdi:waypoint x="-370.0" y="-320.0"/>
<omgdi:waypoint x="-270.0" y="-320.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-99c69135-7a1a-4bd8-bb50-7b49f87bca15" bpmnElement="sid-af5fa5a2-2f25-4fd0-9e51-32faf1b15825">
<omgdc:Bounds x="-120.0" y="-15.0" width="40.0" height="40.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-06282dce-1153-4090-9fb2-68f4943a8bad" bpmnElement="sid-9969d938-a86a-4b17-87cc-da4ed29edd92">
<omgdi:waypoint x="-100.0" y="-100.0"/>
<omgdi:waypoint x="-100.0" y="-15.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-332e9428-9d5e-4e17-80c4-9ae47e953889" bpmnElement="sid-51846001-076b-4249-8db1-0cf5ba808c56">
<omgdi:waypoint x="-120.0" y="5.0"/>
<omgdi:waypoint x="-212.5" y="5.0"/>
<omgdi:waypoint x="-195.0" y="-260.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-6a2b3b76-4992-4584-9a6f-3a69e4326396" bpmnElement="sid-01ba1fa5-2272-4db2-a9af-ad7a0791786e">
<omgdi:waypoint x="-80.0" y="5.0"/>
<omgdi:waypoint x="295.0" y="-32.5"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
此文件要放在resources文件下的bpmn文件夹下(其他文件夹下也可以,初始化流程记得更改路径)
业务代码
/**
* 部署流程
*/
@Test
public void a() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment().addClasspathResource("bpmn/test.bpmn20.xml").deploy();
System.out.println(deploy.getId());
}
/**
* 申请启动流程
*/
@Test
public void startProcessInstance() {
//启动流程时传递的参数列表 这里根据实际情况 也可以选择不传
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("姓名", "张三");
variables.put("请假天数", 4);
variables.put("请假原因", "我很累!");
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId("test:4:20003")//改成自己的流程key
.singleResult();
// 获取流程定义的Key
String processDefinitionKey = processDefinition.getKey();
//定义businessKey businessKey一般为流程实例key与实际业务数据的结合
//假设一个请假的业务 在数据库中的id是1001
String businessKey = processDefinitionKey + ":" + "1001";
//设置启动流程的人
Authentication.setAuthenticatedUserId("xxyin");
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
System.out.println("流程启动成功:" + processInstance);
}
/**
* 查询流程
*/
@Test
public void findTodoTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
TaskQuery taskQuery = ((TaskQuery) taskService.createTaskQuery().orderByTaskCreateTime()).asc();
// <userTask id="deptLeaderVerify" name="部门领导审批" activiti:assignee="zhangsan" ></userTask>
//添加查询条件 查询指派给 zhangsan 的任务 假设这个任务指派给了zhangsan
taskQuery.taskAssignee("zhangsan");
//添加查询条件 查询流程定义key为 leave 的任务
taskQuery.processDefinitionKey("test");
List<Task> tasks = taskQuery.list();
// 处理查询结果
for (Task task : tasks) {
System.out.println("Task ID: " + task.getId());
System.out.println("Task Name: " + task.getName());
// 其他任务属性的获取和处理
}
}
/**
* 审批流程
*/
@Test
public void complete() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
//这里模拟传进来的参数
String taskId = "22509";
String assignee = "zhangsan";
Map<String, Object> variables = new HashMap<>();
variables.put("pass", true);
variables.put("comment", "同意请假");
//根据任务id获取到当前的任务
TaskQuery query = taskService.createTaskQuery();
Task task = (Task) ((TaskQuery) query.taskId(taskId)).singleResult();
//将参数列表的评论赋值给comment
String taskComment = variables.remove("comment").toString();
//向特定的任务添加评论
if (!taskComment.equals("")) {
taskService.addComment(taskId, task.getProcessInstanceId(), taskComment);
}
//如果当前任务没有指派人,需要先使用 claim() 方法领取任务
taskService.claim(taskId, assignee);
//如果有指派人,直接完成任务
taskService.complete(taskId, variables);
}
@Test
//挂起流程
public void suspendProcessDefinition() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
repositoryService.suspendProcessDefinitionByKey("test");
try {
runtimeService.startProcessInstanceByKey("test");
} catch (ActivitiException e) {
e.printStackTrace();
}
}
//激活挂起的流程
@Test
public void ji() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.activateProcessDefinitionByKey("test");
}