(八)、SpringBoot2.x 整合 Activiti7 功能实践
(八)、SpringBoot2.x 整合 Activiti7 功能实践
1、简介
前面的文章我们简单了解了Activiti 的功能(1、简介、2、核心表结构和Api、3、idea-BPMN插件、插件2、4、SpringBoot2的简单整合、5、流程定义的操作、6、用户任务、7、流程变量、8、用户组任务),下面我们进行全面实践。
2、创建SpringBoot2.x项目
2.1、maven依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dw.study</groupId>
<artifactId>springboot-activiti7</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-activiti7</name>
<description>springboot-activiti7</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- activity 7 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.0.0.Beta2</version>
</dependency>
<!-- pageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
<!-- druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2、yml配置
server:
port: 8082
# mybatis
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
spring:
application:
name: spring-boot-activiti
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://localhost:3306/activiti_study?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf8
&autoReconnect=true&failOverReadOnly=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
initial-size: 1
min-idle: 2
max-active: 20
max-wait: 60000
pool-prepared-statements: true
max-open-prepared-statements: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
max-evictable-idle-time-millis: 900000
validation-query: SELECT 1
test-on-borrow: true
test-on-return: false
test-while-idle: true
filter:
stat:
log-slow-sql: true
slow-sql-millis: 2000
# activity
activiti:
#1.false,默认值,acticiti启动时对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true,acticiti会对数据中所有的表进行更新操作,如果表不存在,则自动创建
#3.create_drop,在acticiti启动时创建表,关闭时删除表(必须手动关闭引擎才能删除表)
#4.drop_create,在acticiti启动时删除原来的表,然后创建新表(不需要手动关闭引擎)
database-schema-update: true
#默认true,效验流程文件,默认效验resources下的processes文件夹里的流程,为true自动部署流程,为false则不部署
check-process-definitions: true
# 流程文件存放目录
process-definition-location-prefix: classpath:/processes/
async-executor-activate: false
# 启用历史记录
db-history-used: true
#历史记录等级
#1.none:不保存任何历史记录,因此在流程执行过程中,这是最高效的
#2.acticiti:级别高于none,保存流程实例与流程行为,其他数据不保存
#3.audit:除activiti级别会保存的数据外,还会保存全部的流程任务及其属性,audit为默认值
#4.full:保存历史数据的最高级别,除了保存audit级别的数据外,还会保存其他流程相关的细节数据,包括一些流程参数等
history-level: full
profiles:
active: dev
autoconfigure:
exclude: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
3、创建一个请假的BPMN20流程文件(画图插件)
3.2、 分配流程节点的处理人
holidayProcess.bpmn20.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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: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" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" targetNamespace="http://www.activiti.org/processdef" exporter="Camunda Modeler" exporterVersion="4.11.1"> <process id="holidayProcess" name="holidayProcess" isExecutable="true"> <startEvent id="sid-6b3151c0-c07a-4106-b56e-31549176b84b" /> <userTask id="sid-0a26713e-7254-4b26-9af8-e72350b8d008" name="填写请假申请" activiti:assignee="zhangsan" /> <sequenceFlow id="sid-4c8c2ba6-74ab-46b6-b20d-e55e25ff06c8" sourceRef="sid-6b3151c0-c07a-4106-b56e-31549176b84b" targetRef="sid-0a26713e-7254-4b26-9af8-e72350b8d008" /> <sequenceFlow id="sid-96180d0e-27e7-4222-ba69-cc9cc0276037" sourceRef="sid-0a26713e-7254-4b26-9af8-e72350b8d008" targetRef="sid-f3ef852e-26b8-4922-9ee9-f514cfcecd15" /> <userTask id="sid-f3ef852e-26b8-4922-9ee9-f514cfcecd15" name="组长审批" activiti:assignee="lisi" /> <userTask id="sid-ab723b22-4b15-4868-95da-9449844f304a" name="人事归档" activiti:assignee="wangwu" /> <sequenceFlow id="sid-13a2993b-e107-4937-8fbb-7a55d7a8af3b" sourceRef="sid-f3ef852e-26b8-4922-9ee9-f514cfcecd15" targetRef="sid-ab723b22-4b15-4868-95da-9449844f304a" /> <endEvent id="sid-4961da55-0df3-4329-9a41-3058d33bd836" /> <sequenceFlow id="sid-02e52b8f-3e72-4656-8b8a-93b98a828e9e" sourceRef="sid-ab723b22-4b15-4868-95da-9449844f304a" targetRef="sid-4961da55-0df3-4329-9a41-3058d33bd836" /> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_holidayProcess"> <bpmndi:BPMNPlane id="BPMNPlane_holidayProcess" bpmnElement="holidayProcess"> <bpmndi:BPMNEdge id="edge-889da73a-4520-4440-832d-1a50c3c21623" bpmnElement="sid-02e52b8f-3e72-4656-8b8a-93b98a828e9e"> <omgdi:waypoint x="725" y="119.99998" /> <omgdi:waypoint x="845" y="119.99998" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="edge-5c5793cc-fc43-471b-ad7f-b8727a840dc6" bpmnElement="sid-13a2993b-e107-4937-8fbb-7a55d7a8af3b"> <omgdi:waypoint x="530" y="120" /> <omgdi:waypoint x="625" y="120" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="edge-3c84b116-610b-42f6-9112-feebe5c6f203" bpmnElement="sid-96180d0e-27e7-4222-ba69-cc9cc0276037"> <omgdi:waypoint x="335" y="120" /> <omgdi:waypoint x="430" y="120" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="edge-02d04728-12aa-42e9-85c1-88c1826a91af" bpmnElement="sid-4c8c2ba6-74ab-46b6-b20d-e55e25ff06c8"> <omgdi:waypoint x="189.99994000000004" y="120" /> <omgdi:waypoint x="234.99994" y="119.99998" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="shape-faf46466-ed0e-4a0f-9275-2be818b4207d" bpmnElement="sid-6b3151c0-c07a-4106-b56e-31549176b84b"> <omgdc:Bounds x="160" y="105" width="30" height="30" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="shape-1ba5dd41-2304-4ae9-b90b-b98ef1d6abb8" bpmnElement="sid-0a26713e-7254-4b26-9af8-e72350b8d008"> <omgdc:Bounds x="235" y="80" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="shape-2e87bf2b-408f-45cb-a393-5fff51be92dc" bpmnElement="sid-ab723b22-4b15-4868-95da-9449844f304a"> <omgdc:Bounds x="625" y="80" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="shape-ceba04e3-3913-4f80-8a9b-40f41acdf148" bpmnElement="sid-4961da55-0df3-4329-9a41-3058d33bd836"> <omgdc:Bounds x="845" y="105" width="30" height="30" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="shape-3220528e-c4d8-4d42-b057-f89a815d064b" bpmnElement="sid-f3ef852e-26b8-4922-9ee9-f514cfcecd15"> <omgdc:Bounds x="430" y="80" width="100" height="80" /> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
4、启动应用程序
4.1 启动之后数据库会自动创建25张表
4.2、启动项目会自动部署processes包下面的holidayProcess.bpmn20.xml文件,流程部署修改的表:
1、act_re_deployment 流程部署(部署名称、部署时间)
2、act_ge_bytearray (存储流程部署的id、bmpn-xml文件、资源名称)
3、act_re_procdef 流程定义表(存储:类别、流程名称、流程key、部署的id、资源名称)
id 属性设置为 {processDefinitionKey}:{processDefinitionVersion}:{generated-id},其中generated-id
是添加的唯一编号,以保证集群环境中进程定义缓存的进程 ID 的唯一性。
4.3、如果流程文件有修改, 重新启动项目会再次部署。
3、启动流程实例
(一)启动流程实例: 流程实例的key 为xml 中定义的Key:
/**
* 2、启动流程实例
*/
@Test
public void runProcess() {
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayProcess");
log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
}
(二)启动流程修改的表
1、act_ru_execution(运行时流程执行实例数据表,一条是开始事件的执行实例,这个一直存在,只到流程结束后才会自动删除,is_active字段表示是否正在执行实例),开始-->填写请假申请。所以有两条记录。
2、act_ru_task(运行时任务信息数据信息表)
3、act_ru_identitylink
4、act_hi_taskinst(历史任务实例数据表)
5、act_hi_procinst(历史流程实例数据表,正在执行的任务也在其中)
6、 act_hi_actinst(历史节点数据,图片上的节点信息)
7、act_hi_identitylink(历史流程参与用户信息数据表)
4、查询个人代办任务
(一)代码实现
/**
* 查询个人代办任务
*/
@Test
public void queryPersonJob() {
//1、获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2、获取taskService
TaskService taskService = processEngine.getTaskService();
//3、根据流程key 和 任务的负责人 查询任务
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess") //流程Key
.taskAssignee("zhangsan") //要查询的负责人
.list();
//4、输出
for (Task task : taskList) {
System.out.println("流程实例id= " + task.getProcessInstanceId());
System.out.println("任务Id= " + task.getId());
System.out.println("任务负责人= " + task.getAssignee());
System.out.println("任务名称= " + task.getName());
}
}
(二)查询过程
查询以下sql语句(ACT_RU_TASK 与 ACT_RE_PROCDEF关联查询)
select
distinct RES.*
from ACT_RU_TASK RES
inner join ACT_RE_PROCDEF D on RES.PROC_DEF_ID_ = D.ID_
WHERE RES.ASSIGNEE_ = 'zhangsan' and D.KEY_ = 'holidayProcess'
order by RES.ID_ asc
LIMIT 2147483647 OFFSET 0
5、完成个人任务
(一)代码实现(依次完成张三、李四、王五的任务)
/**
* 完成 zhangsan 的任务
*/
@Test
public void finishPersonJob(){
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess") //流程Key
.taskAssignee("zhangsan") //要查询的负责人
.singleResult();
// 完成任务,参数:任务id
taskService.complete(task.getId());
}
/**
* 完成 lisi 的任务
*/
@Test
public void finishPersonJob2(){
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess") //流程Key
.taskAssignee("lisi") //要查询的负责人
.singleResult();
// 完成任务,参数:任务id
taskService.complete(task.getId());
}
/**
* 完成 wangwu 的任务
*/
@Test
public void finishPersonJob3(){
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess") //流程Key
.taskAssignee("wangwu") //要查询的负责人
.singleResult();
// 完成任务,参数:任务id
taskService.complete(task.getId());
}
( 二 )、完成个人任务修改的表
1、ACT_HI_TASKINST(历史的任务实例表)
操作:1、修改上一个节点的结束时间; 2、插入下一个待执行的任务以及开始时间。
1.1、zhangsan完成任务(插入下一个lisi的任务实例组长审批,修改 zhangsan 任务实例 end_time加入处理完结时间)
1.2、lisi 完成任务(插入下一个wangwu的任务实例,lisi 的任务实例 end_time 加入处理完结时间)
1.3、wangwu完成任务(修改人事归档的结束时间)
2、ACT_HI_ACTINST(历史节点数据) 2.1、修改上一个节点的结束时间,2.2、插入下一个待执行的节点,以及节点的开始时间。
2.1、zhangsan完成任务(插入下一个组长审批节点,节点中taskid为运行时任务信息表中的id, 修改请假申请节点的 end_time 字段 加入处理完结时间)
2.2、lisi 完成任务(插入下一个人事归档节点,节点中 taskid为运行时任务信息表中的id, 组长审批节点的 end_time 字段加入处理完结时间)
2.3、wangwu完成任务(修改人事归档的结束时间, 插入endEvent)
3、ACT_HI_IDENTITYLINK(历史流程参与用户信息数据表)
3.1、zhangsan完成任务(插入lisi负责人)
3.2、lisi 完成任务(插入wangwu负责人)
4、ACT_RU_TASK(运行时任务信息数据信息表)操作:1、删除了上一个任务, 2、插入了下一个节点的任务。
4.1、zhangsan完成任务(删除了zhangsan的请假申请的任务,添加了组长审批任务记录)
4.2、lisi 完成任务(删除了lisi的组长审批的任务,添加了人事归档的任务记录)
4.3、wangwu完成任务, 删除正在运行的任务数据。
5、ACT_RU_IDENTITYLINK(运行时用户信息数据)当流程执行完时会删除该流程的所有参与人,在历史记录表中可以查看所有的参与者。
5.1、zhangsan完成任务(插入lisi负责人)
5.2、lisi完成任务(插入wangwu负责人)
5.3、wangwu完成任务(删除正在运行的实例的参与者)
6、ACT_RU_EXECUTION(运行时流程执行实例数据表)修改ACT_id为下一个执行的节点id, 任务执行完毕会删除记录。
6.1、zhangsan完成任务(第二条记录ACT_ID_改为下一个的节点的id(组长审批))
6.2、lisi 完成任务(第二条记录ACT_ID_改为下一个的节点的id(人事归档))
6.3、wangwu完成任务删除流程执行实例
6、查看历史信息
(一)代码实现
/**
* 查询流程执行历史
*/
@Test
public void queryHistory() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 获取历史流程实例
HistoricProcessInstanceQuery holidayProcess = historyService.createHistoricProcessInstanceQuery()
.processDefinitionKey("holidayProcess");
HistoricProcessInstance historicProcessInstance = holidayProcess.singleResult();
String superProcessInstanceId = historicProcessInstance.getSuperProcessInstanceId();
// 创建历史运行查询
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(superProcessInstanceId);
// 增加排序操作,根据开始时间排序 asc 升序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//查询所有内容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 输出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println("节点id:" + hi.getActivityId());
System.out.println("节点名字:" + hi.getActivityName());
System.out.println("流程定义key: " + hi.getProcessDefinitionId());
System.out.println("流程实例id: " + hi.getProcessInstanceId());
System.out.println("<==========================>");
}
}
输出:
节点id:sid-6b3151c0-c07a-4106-b56e-31549176b84b
节点名字:null
流程定义key: holidayProcess:1:db04ed98-bd71-11ec-8e0d-00ff0f6cf7db
流程实例id: f67a5872-bd71-11ec-9f77-00ff0f6cf7db
<==========================>
节点id:sid-0a26713e-7254-4b26-9af8-e72350b8d008
节点名字:填写请假申请
流程定义key: holidayProcess:1:db04ed98-bd71-11ec-8e0d-00ff0f6cf7db
流程实例id: f67a5872-bd71-11ec-9f77-00ff0f6cf7db
<==========================>
节点id:sid-f3ef852e-26b8-4922-9ee9-f514cfcecd15
节点名字:组长审批
流程定义key: holidayProcess:1:db04ed98-bd71-11ec-8e0d-00ff0f6cf7db
流程实例id: f67a5872-bd71-11ec-9f77-00ff0f6cf7db
<==========================>
节点id:sid-ab723b22-4b15-4868-95da-9449844f304a
节点名字:人事归档
流程定义key: holidayProcess:1:db04ed98-bd71-11ec-8e0d-00ff0f6cf7db
流程实例id: f67a5872-bd71-11ec-9f77-00ff0f6cf7db
<==========================>
节点id:sid-4961da55-0df3-4329-9a41-3058d33bd836
节点名字:null
流程定义key: holidayProcess:1:db04ed98-bd71-11ec-8e0d-00ff0f6cf7db
流程实例id: f67a5872-bd71-11ec-9f77-00ff0f6cf7db
<==========================>
7、与业务表关联
(一)代码实现(使用关联id启动流程)
@Test
public void runProcessByBusinessKey() {
// 1、获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3、启动流程的过程中,添加businesskey
// 第二个参数:businessKey,业务表的id,就是 10010
ProcessInstance instance = runtimeService.
startProcessInstanceByKey("holidayProcess", "10010");
// 4、输出
System.out.println("businessKey=="+instance.getBusinessKey());
}
(二)与普通方式启动实例比较
1. ACT_HI_PROCINST(历史流程实例数据表比较,普通启动business_key为空,说明业务表的id存在这个字段中)
2. ACT_RU_EXECUTION(运行时流程执行实例数据表比较,普通启动business_key为空,说明业务表的id存在这个字段中)
八、使用变量分配执行人
(一)、设置流程变量
(二)、流程启动时设置流程变量(也可以运行时设置)代码实现:
@Test
public void runProcessAndSetVariables() {
// 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 设定assignee的值,用来替换uel表达式
Map<String, Object> assigneeMap = new HashMap<>();
assigneeMap.put("assignee1", "zhangsan");
assigneeMap.put("assignee2", "lisi");
assigneeMap.put("assignee3", "wangwu");
// 启动流程实例
runtimeService.startProcessInstanceByKey("holidayProcess", assigneeMap);
}
额外修改的表
九、候选人实例介绍
(一)设置候选人
(二)、启动流程。。。
(三)、 查询候选人任务
/**
* 查询候选人任务
*/
@Test
public void queryCandidateUserJob() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取TaskService
TaskService taskService = processEngine.getTaskService();
// 查询组任务
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess")
.taskCandidateUser("zhangsan") //根据候选人查询任务
.list();
for (Task task : taskList) {
System.out.println("========================");
System.out.println("流程实例ID=" + task.getProcessInstanceId());
System.out.println("任务id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
}
}
提示错误:
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.springframework.security.core.userdetails.UsernameNotFoundException: zhangsan
### Cause: org.springframework.security.core.userdetails.UsernameNotFoundException: zhangsan
解决方案:
1、实现UserDetailsService接口
@Component
public class CustomUserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userService.findOneUserByName(username);
}
}
2、userService
@Service
public class UserService {
private final Logger logger = LoggerFactory.getLogger(UserService.class);
public MyUser findOneUserByName(String username) {
logger.info("username:"+ username);
// 查询数据库获取权限(我这里伪造)
List<GrantedAuthority> authorities= AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
MyUser myUser = new MyUser();
myUser.setUserName(username);
myUser.setAuthorities(authorities);
return myUser;
}
}
4、MyUser
@Data
public class MyUser implements UserDetails {
private String userName;
private List<GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getUsername() {
return userName;
}
@Override
public String getPassword() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
查询结果:
========================
流程实例ID=3fd660ed-bd9a-11ec-aa6b-00ff0f6cf7db
任务id=3fda5897-bd9a-11ec-aa6b-00ff0f6cf7db
任务负责人=null
========================
流程实例ID=a667bb6c-bd97-11ec-a8d7-00ff0f6cf7db
任务id=a66bb314-bd97-11ec-a8d7-00ff0f6cf7db
任务负责人=null
(四)、wanger拾取任务代码实现:
/**
* 拾取任务
*/
@Test
public void claimJob() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取TaskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess")
.taskCandidateUser("wanger").singleResult();//根据候选人查询任务
// 任务候选人
String candidateUser = "wanger";
// 查询任务
if (task != null) {
// 拾取任务
taskService.claim(task.getId(), candidateUser);
System.out.println("taskid-" + task.getId() + "-用户-" + candidateUser + "-拾取任务完成");
}
}
拾取任务前后对比
(五)wanger归还任务、交接任务代码实现:
总的来说就是改assignee_字段: 归还任务设置成null; 交接任务设置成lisi
@Test
public void changeAssignUser() {
//获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//根据key 和负责人来查询任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("holidayProcess")
.taskCandidateUser("wanger").singleResult();//根据候选人查询任务
if (task != null) {
//归还任务 ,就是把负责人 设置为空
taskService.setAssignee(task.getId(), null);
taskService.setAssignee(task.getId(), "lisi");
System.out.println("taskid-" + task.getId() + "-归还任务完成");
}
}
十、监听器
(二)、代码实现
@Slf4j
public class MyTaskListener implements TaskListener {
//delegateTasK是当前任务的对象
@Override
public void notify(DelegateTask delegateTask) {
log.info("执行 MyTaskListener....");
//默认是create事件
if("填写请假申请".equals(delegateTask.getName()) &&
"create".equals(delegateTask.getEventName())){
delegateTask.setAssignee("张三");
}
}
}
控制台日志:
数据库: