导入Flowable依赖
<!-- flowable-->
<!--
添加flowable工作流依赖
-->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.2</version>
</dependency>
<!--
添加flowable工作流前端页面依赖,如果项目没有集成页面,无需添加此依赖
-->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-rest</artifactId>
<version>6.7.2</version>
</dependency>
<!--
添加flowable-ui-modeler配置依赖项
/-->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-conf</artifactId>
<version>6.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
yml配置文件:
server:
port: 8080
spring:
datasource:
#driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/exportdb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: root
flowable:
#异步执行
async-executor-activate: true
#自动更新数据库
database-schema-update: true
#校验流程文件,默认校验resources下的processes文件夹里的流程文件
process-definition-location-prefix: classpath*:/processes/
process-definition-location-suffixes: "**.bpmn20.xml, **.bpmn"
#该配置只是防止页面报错,没有实际意义
common:
app:
idm-admin:
password: test
user: test
#没有实际意义
idm-url: http://localhost:8080/flowable-demo
Flowable案例:
package com.flowable;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
@Slf4j
@RestController
@RequestMapping("askForLeave")
public class AskForLeaveFlowableController {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ProcessEngine processEngine;
/**
* 员工提交请假申请
*
* @param employeeNo 员工工号
* @param name 姓名
* @param reason 原因
* @param days 天数
* @return
*/
@GetMapping("employeeSubmit")
public String employeeSubmitAskForLeave(
@RequestParam(value = "employeeNo") String employeeNo,
@RequestParam(value = "name") String name,
@RequestParam(value = "reason") String reason,
@RequestParam(value = "days") Integer days) {
HashMap<String, Object> map = new HashMap<>();
/**
* 员工编号字段来自于配置文件
*/
map.put("employeeNo", employeeNo);
map.put("name", name);
map.put("reason", reason);
map.put("days", days);
/**
* key:配置文件中的下个处理流程id
* value:默认领导工号为002
*/
map.put("leaderNo", "002");
/**
* askForLeave:为开启流程的id 与配置文件中的一致
*/
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("askForLeave", map);
log.info("{},提交请假申请,流程id:{}", name, processInstance.getId());
return "提交成功,流程id:"+processInstance.getId();
}
/**
* 领导审核通过
* @param employeeNo 员工工号
* @return
*/
@GetMapping("leaderExaminePass")
public String leaderExamine(@RequestParam(value = "employeeNo") String employeeNo) {
List<Task> taskList = taskService.createTaskQuery().taskAssignee(employeeNo).orderByTaskId().desc().list();
if (null == taskList) {
throw new RuntimeException("当前员工没有任何申请");
}
for (Task task : taskList) {
if (task == null) {
log.info("任务不存在 ID:{};", task.getId());
continue;
}
log.info("任务 ID:{};任务处理人:{};任务是否挂起:{}", task.getId(), task.getAssignee(), task.isSuspended());
Map<String, Object> map = new HashMap<>();
/**
* key:配置文件中的下个处理流程id
* value:默认老板工号为001
*
*/
map.put("bossNo", "001");
/**
* key:指定配置文件中的条件判断id
* value:指定配置文件中的审核条件
*/
map.put("outcome", "通过");
taskService.complete(task.getId(), map);
}
return "领导审核通过";
}
/**
* 老板审核通过
* @param leaderNo 领导工号
* @return
*/
@GetMapping("bossExaminePass")
public String bossExamine(@RequestParam(value = "leaderNo") String leaderNo) {
List<Task> taskList = taskService.createTaskQuery().taskAssignee(leaderNo).orderByTaskId().desc().list();
if (null == taskList) {
throw new RuntimeException("当前员工没有任何申请");
}
for (Task task : taskList) {
if (task == null) {
log.info("任务不存在 ID:{};", task.getId());
continue;
}
log.info("任务 ID:{};任务处理人:{};任务是否挂起:{}", task.getId(), task.getAssignee(), task.isSuspended());
Map<String, Object> map = new HashMap<>();
/**
* 老板是最后的审批人 无需指定下个流程
*/
// map.put("boss", "001");
/**
* key:指定配置文件中的条件判断id
* value:指定配置文件中的审核条件
*/
map.put("outcome", "通过");
taskService.complete(task.getId(), map);
}
return "领导审核通过";
}
/**
* 驳回
*
* @param employeeNo 员工工号
* @return
*/
@GetMapping("reject")
public String reject(@RequestParam(value = "employeeNo") String employeeNo) {
List<Task> taskList = taskService.createTaskQuery().taskAssignee(employeeNo).orderByTaskId().desc().list();
if (null == taskList) {
throw new RuntimeException("当前员工没有任何申请");
}
for (Task task : taskList) {
if (task == null) {
log.info("任务不存在;");
continue;
}
log.info("任务 ID:{};任务处理人:{};任务是否挂起:{}", task.getId(), task.getAssignee(), task.isSuspended());
Map<String, Object> map = new HashMap<>();
/**
* key:指定配置文件中的领导id
* value:指定配置文件中的审核条件
*/
map.put("outcome", "驳回");
taskService.complete(task.getId(), map);
}
return "申请被驳回";
}
/**
* 生成流程图
*
* @param processId 任务ID
*/
@GetMapping(value = "processDiagram")
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
//流程走完的不显示图
if (pi == null) {
return;
}
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
//使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
String InstanceId = task.getProcessInstanceId();
List<Execution> executions = runtimeService
.createExecutionQuery()
.processInstanceId(InstanceId)
.list();
//得到正在执行的Activity的Id
List<String> activityIds = new ArrayList<>();
List<String> flows = new ArrayList<>();
for (Execution exe : executions) {
List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
activityIds.addAll(ids);
}
//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows,
engconf.getActivityFontName(), engconf.getLabelFontName(),
engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
OutputStream out = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
out = httpServletResponse.getOutputStream();
while ((legth = in.read(buf)) != -1) {
out.write(buf, 0, legth);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}