Spring Boot 如何实现activiti工作流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/P923284735/article/details/87257252

功能简介

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,代码中都写了,大家可以自己看下。
最后还有启动类,需要加如下代码:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/P923284735/article/details/87257252