(八)、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

<?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("张三"); } } }
控制台日志:
数据库: