SpringBoot集成activiti工作流(模拟请假流程)
链接:https://pan.baidu.com/s/10BT_Zertm1WBBrlrdE-QWQ
提取码:zsq6
其他代码都是最原始的测试activiti 的api代码,整合springboot的所有代码见下图.
1.pom文件
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.22.0</version>
</dependency>
2.配置文件
#===server 端口号配置===
server.port=8090
#数据源配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
# 使用druid数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#驱动com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#连接池初始化数量
spring.datasource.druid.initial-size=5
#最小空闲连接数
spring.datasource.druid.min-idle=10
#最大连接数
spring.datasource.druid.max-active=2000
#获取连接等待超时时间
spring.datasource.druid.max-wait=60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
spring.datasource.druid.time-between-eviction-runs-millis=60000
# Activiti配置
## 自动构建Activiti数据库表,设置value="true",启动时检测,无表创建,有表跳过;设置value="drop-create"
## 每次启动时建新表(Springboot1.x中生效,Springboot2.x中已经不生效,因此关闭)
#spring.activiti.database-schema-update=true
## Activiti自动部署验证设置,:true-开启(默认)、false-关闭
spring.activiti.check-process-definitions=false
## 设置true后将代替那些老的Job executor
spring.activiti.async-executor-enabled=false
## Activiti定时扫描任务,默认:true(开启),不使用的话建议关掉,需要和spring.activiti.async-executor-enabled=false配合使用,否则不起作用
spring.activiti.job-executor-activate=false
#spring.activiti.process-definition-location-prefix=classpath:/processes/
#spring.activiti.process-definition-location-suffixes=**.bpmn
#===mybatis 配置===
# 注意:一定要对应mapper映射xml文件的所在路径
mybatis.mapper-locations=classpath*:mapper/*.xml
# Mybatis SQL语句控制台打印
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#开启驼峰命名 譬如数据库create_time 自动映射pojo属性createTime
mybatis.configuration.map-underscore-to-camel-case=true
3.启动类排除掉权限SecurityAutoConfiguration类,不然启动失败.报找不着这个类的问题
@SpringBootApplication(exclude = org.activiti.spring.boot.SecurityAutoConfiguration.class)
public class ActivitiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ActivitiDemoApplication.class, args);
}
}
4.启动成功便已经创建好了activiti的表
5.画流程图
其他连线依次设置即可
设置办理人,使用监听器监听设置办理人,新建TaskListenerImpl 类实现 TaskListener
public class TaskListenerImpl implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
//====流程模拟====
//1.得到当前用户
String name="小王";
//2.取出领导id
String id="5";
//3.查询领导信息
String leader="小李";
//4.设置办理人
delegateTask.setAssignee(leader);
}
}
画好流程图压缩成zip包待使用,Controller 接口
@RestController("/workFlow")
@Api(tags = "测试activiti",description = "LeaveBillConttroller")
public class LeaveBillConttroller {
@Autowired
private LeaveBillService leaveBillService;
@ApiOperation("查询流程部署")
@GetMapping(value = "/queryProcessDeploy")
public List<ActDeployment> queryProcessDeploy(WorkFlowVo workFlowVo){
return leaveBillService.queryProcessDeploy(workFlowVo);
}
@ApiOperation("查询流程定义")
@GetMapping(value = "/queryAllProcessDefinition")
public List<ActProcessDefinition> queryAllProcessDefinition(WorkFlowVo workFlowVo){
return leaveBillService.queryAllProcessDefinition(workFlowVo);
}
@ApiOperation("添加流程部署")
@PostMapping(value = "/addWorkFlow")
public Map<String ,Object> addWorkFlow(MultipartFile file ,WorkFlowVo workFlowVo) throws IOException {
leaveBillService.addWorkFlow(file.getInputStream(),workFlowVo.getDeploymentName());
return null;
}
@ApiOperation("删除流程部署")
@PostMapping(value = "/deleteWorkFlow")
public Map<String ,Object> deleteWorkFlow(WorkFlowVo workFlowVo) throws IOException {
leaveBillService.deleteWorkFlow(workFlowVo.getDeploymentId());
return null;
}
@ApiOperation("流程部署id查看流程图")
@PostMapping(value = "/viewProcessImage")
public void viewProcessImage(WorkFlowVo workFlowVo, HttpServletResponse response) throws IOException {
leaveBillService.viewProcessImage(workFlowVo.getDeploymentId(),response);
}
@ApiOperation("提交申请,启动流程")
@PostMapping(value = "/startProcess")
public void startProcess(WorkFlowVo workFlowVo) throws IOException {
leaveBillService.startProcess(workFlowVo);
}
@ApiOperation("查询当前登录人的待办任务")
@GetMapping(value = "/loadCurrentUserTask")
public List<ActTask> loadCurrentUserTask(WorkFlowVo workFlowVo) throws IOException {
return leaveBillService.loadCurrentUserTask(workFlowVo);
}
@ApiOperation("根据任务id查询业务id和连线")
@GetMapping(value = "/toDoTask")
public Map<String ,Object> toDoTask(WorkFlowVo workFlowVo) throws IOException {
Leavebill leavebill=leaveBillService.toDoTask(workFlowVo.getTaskId());
List<String> outComeName=leaveBillService.queryOutComes(workFlowVo.getTaskId());
Map map=new HashMap();
map.put("leavebill",leavebill);
map.put("outComeName",outComeName);
return null;
}
@ApiOperation("根据任务id查询批注信息")
@GetMapping(value = "/loadAllCommentByTaskId")
public List<ActComment> loadAllCommentByTaskId(WorkFlowVo workFlowVo) throws IOException {
return leaveBillService.loadAllCommentByTaskId(workFlowVo.getTaskId());
}
@ApiOperation("完成任务")
@GetMapping(value = "/doTask")
public Map<String ,Object> doTask(WorkFlowVo workFlowVo, HttpServletRequest request) throws IOException {
return leaveBillService.completeTask(workFlowVo);
}
}
实现类的方法
@Service
public class LeaveBillService {
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private RepositoryService repositoryService;
//查询流程部署
public List<ActDeployment>queryProcessDeploy(WorkFlowVo workFlowVo){
if(workFlowVo.getDeploymentName()==null){
workFlowVo.setDeploymentName("");
}
String name=workFlowVo.getDeploymentName();
long count = repositoryService.
createDeploymentQuery().deploymentNameLike("%"+name+"%").count();
List<Deployment> deployments = repositoryService.createDeploymentQuery().deploymentNameLike("%"+name+"%")
.listPage(0, 10);
List<ActDeployment> actDeployments=new ArrayList<>();
for (Deployment deployment :deployments){
ActDeployment actDeployment=new ActDeployment();
BeanUtils.copyProperties(deployment,actDeployment);
actDeployments.add(actDeployment);
}
return actDeployments;
}
//查询流程定义
public List<ActProcessDefinition> queryAllProcessDefinition(WorkFlowVo workFlowVo){
if(workFlowVo.getDeploymentName()==null){
workFlowVo.setDeploymentName("");
}
String name=workFlowVo.getDeploymentName();
List<Deployment> deployments =
repositoryService.createDeploymentQuery().deploymentNameLike("%"+name+"%").list();
Set<String> deploymentIds=new HashSet<>();
for (Deployment deployment :deployments){
deploymentIds.add(deployment.getId());
}
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.deploymentIds(deploymentIds).list();
List<ActProcessDefinition> actProcessDefinitions=new ArrayList<>();
for (ProcessDefinition definition :list){
ActProcessDefinition actProcessDefinition=new ActProcessDefinition();
BeanUtils.copyProperties(definition,actProcessDefinition);
actProcessDefinitions.add(actProcessDefinition);
}
return actProcessDefinitions;
}
//添加流程部署
@Transactional
public void addWorkFlow(InputStream inputStream, String deployMentName) throws IOException {
//流程部署 ,获取流程部署对象
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
Deployment deploy = repositoryService.createDeployment().name(deployMentName)
.addZipInputStream(zipInputStream)
.deploy();
inputStream.close();
zipInputStream.close();
System.err.println("流程部署完成");
}
//删除流程部署
@Transactional
public void deleteWorkFlow(String deploymentId) {
//根据流程部署id删除,如果当前id的流程正在执行,那么会报错
repositoryService.deleteDeployment(deploymentId);
//根据流程部署id删除,删除流程定义,如果当前id流程正在执行,那么会把正在执行的流程数据删除 act_ru_*和act_hi_*表里的数据
//repositoryService.deleteDeployment(deploymentId,true);
System.err.println("删除流程部署完成");
}
//流程部署id查看流程图
public void viewProcessImage(String deploymentId, HttpServletResponse response) throws IOException {
//根据部署id查询流程定义对象
ProcessDefinition definition = repositoryService
.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
//从流程定义里面得到图片的名称
String resourceName = definition.getDiagramResourceName();
//使用部署id和图片名称去查询图片流
InputStream inputStream = repositoryService.
getResourceAsStream(deploymentId, resourceName);
//写出图片
File file = new File("C://abc.jpeg");
FileOutputStream fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int length;
while ((length = inputStream.read(b)) != -1) {
fos.write(b, 0, length);
}
inputStream.close();
}
/**
* 提交申请,启动流程
*
*/
@Transactional
public void startProcess(WorkFlowVo workFlowVo) {
//模拟入库提交请假申请,返回请假id
Integer leavebillId = workFlowVo.getId();
//找到流程的key
String processDefinitionKey = Leavebill.class.getSimpleName();
String businessKey=processDefinitionKey+":"+leavebillId;
Map<String,Object> variables=new HashMap<>();
//请假人
variables.put("username",workFlowVo.getUsername());
runtimeService.startProcessInstanceByKey
(processDefinitionKey,businessKey,variables);
System.err.println("提交申请,启动流程成功");
//todo 修改请假状态
}
/**
* 查询当前登录人的待办任务
*/
public List<ActTask> loadCurrentUserTask(WorkFlowVo workFlowVo) {
String username = workFlowVo.getUsername(); //当前登录用户
long count=taskService.createTaskQuery().taskAssignee(username).count();
List<Task> taskList =
taskService.createTaskQuery().taskAssignee(username).listPage(0, 10);
List<ActTask> actTaskList=new ArrayList<>();
for (Task task :taskList){
ActTask actTask=new ActTask();
BeanUtils.copyProperties(task,actTask);
actTaskList.add(actTask);
}
return actTaskList;
}
//根据任务id查询业务信息
public Leavebill toDoTask(String taskId) {
//根据任务id查询任务实例
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//任务实例中取出流程实例id
String processInstanceId = task.getProcessInstanceId();
//根据流程实例id查询流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
//取出business_key ,拆分获取业务id,并查询业务信息
String businessKey = processInstance.getBusinessKey();
String id = businessKey.split(":")[1];
Leavebill leavebill=new Leavebill();
leavebill.setId(Integer.valueOf(id));
return leavebill;
}
//根据任务id查询连线信息
public List<String> queryOutComes(String taskId) {
List<String> names=new ArrayList<>();
//1.根据任务id查询任务实例
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//2.取出流程定义id
String processDefinitionId = task.getProcessDefinitionId();
//3.取出流程实例id
String processInstanceId = task.getProcessInstanceId();
//4.根据流程实例id查询流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
//5.根据流程定义id查询流程定义的xml信息
ProcessDefinitionEntity processDefinition =
(ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
//6.从流程实例对象取出当前活动节点id
String activityId = processInstance.getActivityId();
//7.根据活动节点id取出xml和当前活动节点相关数据
ActivityImpl activityImpl = processDefinition.findActivity(activityId);
//8.从activityImpl中取出连线对象
List<PvmTransition> incomingTransitions = activityImpl.getIncomingTransitions(); //进入的线
List<PvmTransition> transitions = activityImpl.getOutgoingTransitions(); //出去的线
if(!CollectionUtils.isEmpty(transitions)){
for (PvmTransition trans : transitions) {
String name = trans.getProperty("name").toString();
names.add(name);
}
}
return names;
}
/**
* 根据任务id查询批注信息
*/
public List<ActComment> loadAllCommentByTaskId(String taskId) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
String processInstanceId = task.getProcessInstanceId();
List<Comment> commentList =
taskService.getProcessInstanceComments(processInstanceId);
List<ActComment> actCommentList=new ArrayList<>();
for (Comment comment :commentList){
ActComment actComment=new ActComment();
BeanUtils.copyProperties(comment,actComment);
actCommentList.add(actComment);
}
return actCommentList;
}
/**
* 完成任务
*/
@Transactional
public Map<String, Object> completeTask(WorkFlowVo workFlowVo) {
String taskId = workFlowVo.getTaskId(); //任务id
String outCome = workFlowVo.getOutCome(); //连接名称
Integer id = workFlowVo.getId(); //请假单id
String comment = workFlowVo.getComment(); //批注信息
String username = workFlowVo.getUsername(); //用户名
//根据任务id查询任务实例
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//从任务中取出流程实例id
String processInstanceId = task.getProcessInstanceId();
//设置批注人名 因为批注人使用线程局部变量设置,故批注人必须这样设置
Authentication.setAuthenticatedUserId(username);
//添加批注信息
taskService.addComment(taskId,processInstanceId,comment);
//完成任务
Map<String,Object> variables=new HashMap<>();
variables.put("coutcome",outCome);
taskService.complete(taskId,variables);
//判断任务是否结束
ProcessInstance processInstance = runtimeService.
createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(processInstance==null){
Leavebill leavebill=new Leavebill();
leavebill.setId(id);
if(outCome.equals("放弃")){
leavebill.setState(3); //放弃
}else {
leavebill.setState(2); //审批完成
}
//todo 模拟修改数据库请假单状态
}
return null;
}
}