功能简介
Spring Boot 使用Activiti 工作流,其实只需要配置下bpmn文件的路径即可,让Spring Boot扫描到后将流程节点信息入库,这次为大家介绍的是Spring Boot 2.0 + Activiti 5.2.1,因为Activiti低版本的需要手动部署BPMN资源文件,5.2.X之后的版本不需要手动部署。
现有Springboot项目搭建
maven的引用
在配置文件中加入Activiti的配置,并且新建processes文件夹。
接下来我们就要用Eclipse工具安装Activiti的插件,进行流程图的绘制。
可以参考这位博主的博客:
https://blog.csdn.net/ka_ka314/article/details/79431197
安装完成后我们就可以进行绘制流程图了,这个是我画的一个Demo,如下:
流程图绘制好了,接下来就是流程的属性配置了,我们先看第一个环节,
项目经理审批:
我们都知道流程图只是展示当前流程的环节,以及当前流程的进度情况。我们看到Main Config这个是主要配置,
员工填写完了请假信息后,然后提交到项目经理审批时,是不是得知道提交给谁,所以就要根据员工的部门ID查找当前部门的项目经理,所以就需要调用我们自己写的方法,然后将项目经理信息返回。
我们看下网关的属性配置,属性audit是我们代码中定义的属性,代码中将audit赋予不同的值,当然值必须是图中的,它才会根据值的不同,进行流程的推进。
通过:
拒绝:
人事经理审批:
通过:
这里我没有写拒绝,通过后就结束了。
图中的用到的方法都在下面的代码中:
工作处理类
package com.jeesite.modules.activiti.common;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.jeesite.modules.activiti.dao.ActivitiMapper;
import com.jeesite.modules.utils.StrUtils;
/**
* @Desc 工作流程公共类
* @author pgqing
* @Version 5.2.1
*/
@Service
public class activitiCommonService {
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;
@Resource
private RepositoryService repositoryService;
@Resource
private ManagementService managementService;
@Autowired
private ProcessEngineFactoryBean processEngine;
@Resource
private ProcessEngineConfiguration processEngineConfiguration;
@Resource
private ActivitiMapper mapper;
/**
* 启动流程
*
* @param processDefinitionKey
*/
public void startProcess(String processDefinitionKey, String bizKey) {
runtimeService.startProcessInstanceByKey(processDefinitionKey, bizKey);
}
/**
* 审批
*
* @param taskId 流程ID
* @param userId 审批人
* @param audit 审批意见(通过:pass,拒绝:refund)
*/
public String completeTaskByUser(String taskId, String userId, String audit, String comment) {
// 根据taskId查询流程ID
String processInstanceId = mapper.queryProcessIdByTaskId(taskId);
if (null != processInstanceId && !"".equals(processInstanceId)) {
// 1.认领任务
taskService.claim(taskId, userId);
// 2.添加备注(保存建议)
taskService.addComment(taskId, processInstanceId, comment);
// 3.完成任务
Map<String, Object> map = new HashMap<String, Object>();
map.put("audit", audit);
taskService.complete(taskId, map);
}
return "审批完成";
}
/**
* @DESC 根据用户ID查询待办事项
* @param userId
* @return
*/
public List<Task> findTaskByUserId(String userId) {
return taskService.createTaskQuery().taskCandidateOrAssigned(userId).list();
}
/**
* @Desc 根据用户和流程名称获取任务列表(待办、已办)
* @param userId
* @param processName
* @return
*/
public List<Task> getAllTaskByUserId(String userId,String processName){
return taskService.createTaskQuery().taskAssignee(userId).orderByTaskId().desc().list();
}
/**
* (暂时不用)
* 如果项目功能存在下一步需要选人,通过该方法即可完成。
* 设置该task的审批用户
* @param taskId
* @param userId
*/
public void setApproveUser(String taskId,String userId) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
task.setAssignee(userId);
taskService.saveTask(task);
}
/**
* 查询待办人员(项目经理)
*
* @param execution
* @return
*/
public List<String> findProjectManager(DelegateExecution execution) throws Exception {
// TODO
return Arrays.asList("user1");
}
/**
* 查询待办人员(人事)
*
* @param execution
* @return
*/
public List<String> findHRManager(DelegateExecution execution) throws Exception {
// TODO
return Arrays.asList("user2");
}
/**
* 修改数据状态
*
* @param execution
* @param status
* @return
public int updateProcessStatus(DelegateExecution execution, String status) throws Exception {
String bizKey = execution.getProcessBusinessKey();
TicketInfo ticketInfo = new TicketInfo();
ticketInfo = mapper.queryTicketInfoById(bizKey);
ticketInfo.setStatus(status);
return mapper.updateProcessStatus(ticketInfo);
}*/
/**
* 根据业务主键查询历史
*
* @param bizKey
* @return
*/
public List<JSONObject> queryHistoryById(String bizKey) throws Exception {
Lock lock = new ReentrantLock();
lock.lock();
List<JSONObject> list = new ArrayList<JSONObject>();
try {
String processId = mapper.queryProcessIdByBizKey(bizKey);
if (null != processId && !"".equals(processId)) {
List<HistoricTaskInstance> hislist = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processId).finished().list();
for (HistoricTaskInstance h : hislist) {
JSONObject obj = new JSONObject();
obj.put("taskId", h.getId());
obj.put("id", h.getProcessInstanceId());
obj.put("taskName", h.getName());
obj.put("checkor", h.getAssignee());
obj.put("start", StrUtils.dateFormatStr(h.getStartTime(),"yyyy-MM-dd HH:mm:ss"));
obj.put("checkTime", StrUtils.dateFormatStr(h.getClaimTime(),"yyyy-MM-dd HH:mm:ss"));
// obj.put("end", h.getEndTime());
// 查询关联的审批意见
String message = mapper.queryMessageByTaskId(h.getId());
obj.put("msg", message);
list.add(obj);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return list;
}
/**
* 查询用户的已办列表数据
* @param userId
* @return
*/
public List<JSONObject> queryAllHistoryByUserId(String userId){
List<JSONObject> list = new ArrayList<JSONObject>();
List<HistoricTaskInstance> hislist = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).orderByTaskId().desc().list();
for (HistoricTaskInstance h : hislist) {
JSONObject obj = new JSONObject();
obj.put("taskId", h.getId());
obj.put("id", h.getProcessInstanceId());
obj.put("taskName", h.getName());
obj.put("checkor", h.getAssignee());
obj.put("start", StrUtils.dateFormatStr(h.getStartTime(),"yyyy-MM-dd HH:mm:ss"));
obj.put("checkTime", StrUtils.dateFormatStr(h.getClaimTime(),"yyyy-MM-dd HH:mm:ss"));
// obj.put("end", h.getEndTime());
// 查询关联的审批意见
String message = mapper.queryMessageByTaskId(h.getId());
obj.put("msg", message);
list.add(obj);
}
return list;
}
/**
* 根据业务ID查询流程ID
*
* @param bizKey
* @return
*/
public String queryProcessIdByBizKey(String bizKey) {
return mapper.queryProcessIdByBizKey(bizKey);
}
/**
* 根据流程ID获取动态流程图
*
* @param processInstanceId
* @throws IOException
*/
public void getPNGByProcessId(String processInstanceId, HttpServletResponse response) throws Exception {
// 获取历史流程实例
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
// 获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
processEngineConfiguration = processEngine.getProcessEngineConfiguration();
Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);
ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(processInstance.getProcessDefinitionId());
List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId).list();
// 高亮环节id集合
List<String> highLightedActivitis = new ArrayList<String>();
// 高亮线路id集合(路线集合)
List<String> highLightedFlows = getHighLightedFlows(definitionEntity, highLightedActivitList);
for (HistoricActivityInstance tempActivity : highLightedActivitList) {
String activityId = tempActivity.getActivityId();
highLightedActivitis.add(activityId);
}
//只做当前步骤的标红,如果想要路线标红,将此代码注释即可。
for(int i=0;i<highLightedActivitis.size();i++) {
System.out.println(highLightedActivitis.get(i));
if(i!=highLightedActivitis.size()) {
highLightedActivitis.remove(i);
}
}
// 中文显示的是口口口,设置字体就好了
// InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png",
// highLightedActivitis,highLightedFlows,null,null,1.0);
InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis,
Collections.<String>emptyList(), "宋体",
"宋体", null, null, 1.0);
// 单独返回流程图,不高亮显示
// InputStream imageStream = diagramGenerator.generatePngDiagram(bpmnModel);
// 输出资源内容到相应对象
byte[] b = new byte[1024];
int len;
while ((len = imageStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
}
/**
* @Desc 获取需要高亮的线
* @param processDefinitionEntity
* @param historicActivityInstances
* @return
*/
private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity,
List<HistoricActivityInstance> historicActivityInstances) {
List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历
ActivityImpl activityImpl = processDefinitionEntity
.findActivity(historicActivityInstances.get(i).getActivityId());// 得到节点定义的详细信息
List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
ActivityImpl sameActivityImpl1 = processDefinitionEntity
.findActivity(historicActivityInstances.get(i + 1).getActivityId());
// 将后面第一个节点放在时间相同节点的集合里
sameStartTimeNodes.add(sameActivityImpl1);
for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 后续第一个节点
HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 后续第二个节点
if (activityImpl1.getStartTime().equals(activityImpl2.getStartTime())) {
// 如果第一个节点和第二个节点开始时间相同保存
ActivityImpl sameActivityImpl2 = processDefinitionEntity
.findActivity(activityImpl2.getActivityId());
sameStartTimeNodes.add(sameActivityImpl2);
} else {
// 有不相同跳出循环
break;
}
}
List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();// 取出节点的所有出去的线
for (PvmTransition pvmTransition : pvmTransitions) {
// 对所有的线进行遍历
ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();
// 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
if (sameStartTimeNodes.contains(pvmActivityImpl)) {
highFlows.add(pvmTransition.getId());
}
}
}
return highFlows;
}
/**
* @Desc 根据流程ID获取流程图
* @param processInstanceId
* @param response
*/
public void getProcessPngInfo(String processInstanceId,HttpServletResponse response) throws Exception {
// 实例在活动中,获取实例
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult();
// 活动已完结,获取实例
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
if (pi != null || hpi != null) {
// 根据获取到的流程实例获取流程是定义实体
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(pi == null ? hpi.getProcessDefinitionId() : pi.getProcessDefinitionId());
// 准备参数,分为以下部分
// 1.业务流程模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
// 2.需高亮节点
List<String> activeActivityIds = new LinkedList<String>();
// 判断流程实例仍未完结,采用运行组件的查询结果,若流程结束采用历史组件查询结果
if (pi != null) {
activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
} else {
/*
* 此处深入数据时发现,使用自由流命令模式的问题已经体现: 1.使用自由流跳转时,不会更新本次完成活动历史表相应记录的完成时间
* 2.原生任务完成方法会更新,但更新的是时间正序排,开始时间最早那条符合环节定义的记录时间 结论:
* 1.自由流与非自由流混合使用,活动历史表结束时间有问题却暂时不可避免,应尽量避免使用活动历史表数据
* 2.若需取时间差等信息要从任务历史表中取
* 3.由于现行模式流程均为用户任务,故此法可靠,若引入与其他类型任务,整个封装思路需要重新考虑
*
* 上述问题于20170227,自由流改用executionEntity.destroyScope()方式解决
*/
// 最终环节名称
String endLinkName = "";
// 对于以“流程作废”结束的流程,将结束节点固定至结束节点,正常结束流程固定至结束事件
if (!"completed by break".equals(hpi.getDeleteReason())) {
endLinkName = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId)
.activityType("endEvent").singleResult().getActivityId();
} else {
endLinkName = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId)
.finished().orderByHistoricTaskInstanceEndTime().desc().list().get(0).getTaskDefinitionKey();
}
// 20160923 考虑流程终止的情况,改变结束节点的出具策略,要求结束事件命名必须为“endevent1”
// 20170222 根据流程结束方式变更处理策略,分为正常结束与中止两种情况,不再要求结束事件命名
activeActivityIds.add(endLinkName);
}
// 获取流程引擎的配置
ProcessEngineConfigurationImpl processEngineConfiguration = processEngine.getProcessEngineConfiguration();
// Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl)
// processEngineConfiguration);
// 引擎配置中获取流程图绘制器
ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
// 调用绘制器绘图方法绘制当前等待任务高亮的流程图
// InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds,
// Collections.<String>emptyList(), processEngineConfiguration.getActivityFontName(),
// processEngineConfiguration.getLabelFontName(), null, null, 1.0);
InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds,
Collections.<String>emptyList(), "宋体",
"宋体", null, null, 1.0);
// 输出资源内容到相应对象
byte[] b = new byte[1024];
int len;
while ((len = imageStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
}
}
public RuntimeService getRuntimeService() {
return runtimeService;
}
public void setRuntimeService(RuntimeService runtimeService) {
this.runtimeService = runtimeService;
}
public TaskService getTaskService() {
return taskService;
}
public void setTaskService(TaskService taskService) {
this.taskService = taskService;
}
public HistoryService getHistoryService() {
return historyService;
}
public void setHistoryService(HistoryService historyService) {
this.historyService = historyService;
}
public RepositoryService getRepositoryService() {
return repositoryService;
}
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
public ManagementService getManagementService() {
return managementService;
}
public void setManagementService(ManagementService managementService) {
this.managementService = managementService;
}
public ProcessEngineFactoryBean getProcessEngine() {
return processEngine;
}
public void setProcessEngine(ProcessEngineFactoryBean processEngine) {
this.processEngine = processEngine;
}
public ProcessEngineConfiguration getProcessEngineConfiguration() {
return processEngineConfiguration;
}
public void setProcessEngineConfiguration(ProcessEngineConfiguration processEngineConfiguration) {
this.processEngineConfiguration = processEngineConfiguration;
}
}
控制层代码如下:
package com.jeesite.modules.activiti.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.modules.activiti.common.activitiCommonService;
import com.jeesite.modules.activiti.entity.TicketInfo;
import com.jeesite.modules.activiti.service.IActivitiService;
@Controller
@RequestMapping("/ticket")
public class ActivitiController {
@Autowired
private IActivitiService service;
@Autowired
private activitiCommonService activitiSrv;
/**
* 新增请假单
*
* @param info
*/
@ResponseBody
@RequestMapping("/addTicketInfo")
public String addTicketInfo(String msg) {
return service.addTicketInfo(msg);
}
/**
* 查询用户待办任务
*
* @param userId
* @return
*/
@ResponseBody
@RequestMapping("/queryTicketInfo")
public List<TicketInfo> queryTicketInfo(String userId){
return service.queryTicketInfo(userId);
}
/**
* 完成任务
*
* @param taskId
* @param userId
* @param audit
*/
@ResponseBody
@RequestMapping("/complete")
public String complete(String taskId, String userId, String audit, String comment) {
return service.complete(taskId, userId, audit, comment);
}
/**
* 查询任务历史
* @return
*/
@ResponseBody
@RequestMapping("/queryHistory")
public String queryHistoryById(String businesskey) {
try {
return activitiSrv.queryHistoryById(businesskey).toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询用户已办任务
* @param userId
* @return
*/
@ResponseBody
@RequestMapping("/queryAllHistoryByUserId")
public String queryAllHistoryByUserId(String userId) {
return activitiSrv.queryAllHistoryByUserId(userId).toString();
}
@RequestMapping("/getPng")
public String getPng() {
return "modules/activiti/ticketInfo";
}
/**
* 根据流程ID获取流程图
* @param processId
*/
@ResponseBody
@RequestMapping("/processPng")
public void getPngByProcessId(HttpServletRequest request,HttpServletResponse response) {
try {
String processInstanceId = request.getParameter("processId");
if(null!=processInstanceId&&!"".equals(processInstanceId)) {
// activitiSrv.getPNGByProcessId(processInstanceId, response);
activitiSrv.getProcessPngInfo(processInstanceId, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取某个用户的某个流程的所有任务
* @param userId
* @param processName
* @return
*/
@ResponseBody
@RequestMapping("/getAllTaskByUserId")
public String getAllTaskByUserId(String userId,String processName) {
return activitiSrv.getAllTaskByUserId(userId, processName).toString();
}
}
业务逻辑处理接口
package com.jeesite.modules.activiti.service;
import java.util.List;
import com.jeesite.modules.activiti.entity.TicketInfo;
/**
* @author pgqing
* @Desc 更新数据的流程状态
*/
public interface ITicketInfoService {
/**
* 新增请假单
*
* @param info
*/
public String addTicketInfo(String msg);
/**
* 查询用户待办任务
*
* @param userId
* @return
*/
public List<TicketInfo> queryTicketInfo(String userId);
/**
* 完成任务
* @param taskId
* @param userId
* @param audit
* @param comment
* @return
*/
public String complete(String taskId, String userId, String audit, String comment);
}
业务逻辑处理类
package com.jeesite.modules.activiti.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jeesite.modules.activiti.entity.TicketInfo;
import com.jeesite.modules.activiti.service.ITicketInfoService;
import com.jeesite.modules.activiti.common.commonService;
import com.jeesite.modules.activiti.dao.TicketInfoMapper;;
@Service
public class ticketInfoServiceImpl implements ITicketInfoService {
@Autowired
private commonService activitiSrv;
@Resource
private RuntimeService runtimeSrv;
@Autowired
private TicketInfoMapper mapper;
@Override
public String addTicketInfo(String msg) {
try {
TicketInfo ticketInfo = new TicketInfo();
String id = UUID.randomUUID().toString();
ticketInfo.setId(id);
ticketInfo.setName("张三");
ticketInfo.setMsg(msg);
// 保存数据
mapper.addTicketInfo(ticketInfo);
// 启动流程
activitiSrv.startProcess("demoProcess", id);
} catch (Exception e) {
e.printStackTrace();
}
return "保存成功";
}
@Override
public List<TicketInfo> queryTicketInfo(String userId) {
List<TicketInfo> result = new ArrayList<TicketInfo>();
try {
List<Task> tasks = activitiSrv.findTaskByUserId(userId);
for (Task task : tasks) {
ProcessInstance processInstance = runtimeSrv.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId()).singleResult();
String bizKey = processInstance.getBusinessKey();
TicketInfo info = mapper.queryTicketInfoById(bizKey);
info.setTaskId(task.getId());
result.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public String complete(String taskId, String userId, String audit,String comment) {
try {
return activitiSrv.completeTaskByUser(taskId, userId, audit, comment);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
数据库处理层
package com.jeesite.modules.activiti.dao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.activiti.entity.TicketInfo;
@MyBatisDao
public interface TicketInfoMapper {
/**
* 更新流程状态
*
* @param execution
* @param status
* @return
*/
public int updateProcessStatus(TicketInfo info);
/**
* 新增请假信息
* @param info
*/
public void addTicketInfo(TicketInfo info);
/**
* 根据ID查询业务数据
* @param id
*/
public TicketInfo queryTicketInfoById(String id);
/**
* 根据业务ID查询流程Id
* @param bizKey
* @return
*/
public String queryProcessIdByBizKey(String bizKey);
/**
* 根据环节ID查询流程Id
* @param taskId
* @return
*/
public String queryProcessIdByTaskId(String taskId);
/**
* 根据taskId查询审批意见
* @param taskId
* @return
*/
public String queryMessageByTaskId(String taskId);
}
实体类
package com.jeesite.modules.activiti.entity;
import java.io.Serializable;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* 请假单实体信息
*
* @author pgqing
*
*/
@Data
@Getter
@Setter
public class TicketInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String msg;
private String status;
private String taskId;
}
Mapper配置文件内容:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jeesite.modules.activiti.dao.TicketInfoMapper">
<!-- 新增请假信息 -->
<insert id="addTicketInfo" parameterType="com.jeesite.modules.activiti.entity.TicketInfo">
insert into ACT_TICKETINFO(id,name,msg,status)
values(#{id},#{name},#{msg},'')
</insert>
<!-- 根据ID查询请假信息 -->
<select id="queryTicketInfoById" parameterType="java.lang.String" resultType="com.jeesite.modules.activiti.entity.TicketInfo">
select * from ACT_TICKETINFO where id = #{id}
</select>
<!-- 修改请假流程状态 -->
<update id="updateProcessStatus" parameterType="com.jeesite.modules.activiti.entity.TicketInfo">
update ACT_TICKETINFO set status = #{status} where id = #{id}
</update>
<!-- 根据业务ID查询流程ID -->
<select id="queryProcessIdByBizKey" resultType="java.lang.String" parameterType="java.lang.String">
select ID_ from ACT_HI_PROCINST where BUSINESS_KEY_ = #{bizKey}
</select>
<!-- 根据taskId查询流程ID -->
<select id="queryProcessIdByTaskId" resultType="java.lang.String" parameterType="java.lang.String">
select PROC_INST_ID_ from ACT_HI_TASKINST where ID_ = #{taskId}
</select>
<!-- 根据taskId查询审批意见 -->
<select id="queryMessageByTaskId" resultType="java.lang.String" parameterType="java.lang.String">
select MESSAGE_ from ACT_HI_COMMENT where TASK_ID_ = #{taskId}
</select>
</mapper>
启动流程、查询项目经理、人事经理,这些大家可以在控制层自己用接口调试工具进行调试,最后查看流程图,这个比较关键,页面代码如下:
processId是流程ID,代码中都写了,大家可以自己看下。
最后还有启动类,需要加如下代码: