ssm与activiti整合之全套流程

1.画流程图

2.使用junit完成流程部署

package cn.itcat.leaveBill;

import javax.annotation.Resource;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:conf/applicationContext.xml"})
public class LeaveBill {
	/**
	 * 与流程定义和部署对象相关的service
	 */
	@Resource(name="repositoryService")  
	private RepositoryService repositoryService;
	
	/**
	 * 部署流程定义
	 */
	@Test
	public void deploymentProcssDefiniton() {
		Deployment deploy = repositoryService.createDeployment()					// 创建一个部署对象
			.name("leaveBill请假程序")							// 添加部署名称
			.addClasspathResource("diagrams/leaveBill.bpmn")	// 从classpath资源中加载,一次只能加载一个文件
			.addClasspathResource("diagrams/leaveBill.png")
			.deploy();											// 完成部署
		
		System.out.println("部署id:" + deploy.getId());
		System.out.println("部署名称:" + deploy.getName());
	}
	
	/**
	 * 删除流程定义
	 */
	@Test
	public void deleteProcessDefinition() {
		String deploymentId = "57501";
		
		repositoryService.deleteDeployment(deploymentId, true);
		System.out.println("删除成功!");
	}
}

 3.设计main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	登录成功!欢迎你 ${emp.name}
	<a href="<%=request.getContextPath() %>/myTask">我的任务</a>
	
	<c:if test="${!empty list }">
		<table border="1" align="center">
			<tr>
				<th>ID</th>
				<th>请假天数</th>
				<th>请假事由</th>
				<th>请假原因</th>
				<th>请假时间</th>
				<th>请假人</th>
				<th>请假状态</th>
				<th>操作</th>
			</tr>
			
			<c:forEach items="${list}" var="leaveBill">
				<tr>
					<td>${leaveBill.id }</td>
					<td>${leaveBill.days }</td>
					<td>${leaveBill.content }</td>
					<td>${leaveBill.remark }</td>
					<td>${leaveBill.leaveDate }</td>
					<td>${leaveBill.name }</td>
					<c:if test="${leaveBill.status == 0}">
						<td>初始录入</td>
					</c:if>
					<c:if test="${leaveBill.status == 1}">
						<td>审批中</td>
					</c:if>
					<c:if test="${leaveBill.status == 2}">
						<td>审批完成</td>
					</c:if>
					<td>
						<c:if test="${leaveBill.status == 0}">
							<a href="<%=request.getContextPath() %>/saveStartProcess?id=${leaveBill.id }">发起请假申请</a>
						</c:if>
						<c:if test="${leaveBill.status == 2}">
							<a href="<%=request.getContextPath() %>/queryTaskHistory?id=${leaveBill.id }">查看审核记录</a>
						</c:if>
					</td>
				</tr>
			</c:forEach>
		</table>
	</c:if>
</body>
</html>

4.完成saveStartProcess方法

package com.gewb.activiti.controller;

import java.util.List;
import java.util.Map;

import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.gewb.activiti.entity.LeaveBill;
import com.gewb.activiti.entity.Workflow;
import com.gewb.activiti.service.LeaveBillService;
import com.gewb.activiti.utils.SessionContext;

@Controller
public class LeaveBillController {
	@Autowired
	private LeaveBillService leaveBillService;
	
	/**
	 * 启动流程
	 * @param id
	 * @param map
	 * @return
	 */
	@RequestMapping("/saveStartProcess")
	public String startProcess(Integer id, Map<String, Object> map) {
		leaveBillService.startProcess(id);
		
		List<Map<String, Object>> list = leaveBillService.queryAll();
		
		if(list != null && !list.isEmpty()) {
			map.put("list", list);
		}
		
		return "main";
	}
	
	/**
	 * 查询我的任务
	 * @param map
	 * @return
	 */
	@RequestMapping("/myTask")
	public String myTask(Map<String, Object> map) {
		String name = SessionContext.get().getName();
		List<Task> list = leaveBillService.myTask(name);
		
		if(list != null && !list.isEmpty()) {
			map.put("list", list);
		}
		
		return "task";
	}
	
	/**
	 * 办理任务
	 * @param taskId
	 * @param map
	 * @return
	 */
	@RequestMapping("/applyTask")
	public String applyTask(String taskId, Map<String, Object> map) {
		LeaveBill leaveBill = leaveBillService.queryLeaveBillByTaskId(taskId);
		List<String> outcomes = leaveBillService.findOutcomeListByTaskId(taskId);
		List<Comment> commentList = leaveBillService.findCommentsByTaskId(taskId);
		
		map.put("leaveBill", leaveBill);
		map.put("outcomes", outcomes);
		map.put("commentList", commentList);
		map.put("taskId", taskId);
		return "taskForm";
	}
	
	@RequestMapping("/saveSubmitTask")
	public String saveSubmitTask(Workflow workflow, Map<String, Object> map) {
		leaveBillService.saveSubmitTask(workflow);
		
		
		String name = SessionContext.get().getName();
		List<Task> list = leaveBillService.myTask(name);
		
		if(list != null && !list.isEmpty()) {
			map.put("list", list);
		}
		
		return "task";	
	}
	
	
	@RequestMapping("/queryTaskHistory")
	public String queryTaskHistory(Integer id, Map<String, Object> map) {
		LeaveBill leaveBill = leaveBillService.findById(id);
		List<Comment> commentList = leaveBillService.findCommentsById(id);
			
		map.put("leaveBill", leaveBill);
		map.put("commentList", commentList);
		
		return "taskFormHistory";
	}
	
}

5.完成WorkflowServiceImpl

package com.gewb.activiti.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.identity.Authentication;
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.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gewb.activiti.dao.LeaveBillDao;
import com.gewb.activiti.entity.Workflow;
import com.gewb.activiti.service.WorkflowService;
import com.gewb.activiti.utils.SessionContext;

@Service
public class WorkflowServiceImpl implements WorkflowService {
	@Autowired
	private LeaveBillDao leaveBillDao;
	
	/**
	 * 与流程定义和部署对象相关的service
	 */
	@Resource(name="repositoryService")  
	private RepositoryService repositoryService;
	
	/**
	 * 与正在执行的流程实例和执行对象相关的service
	 */
	@Resource(name = "runtimeService")
	private RuntimeService runTimeService;
	
	/**
	 * 与正在执行的任务管理相关的service
	 */
	@Resource(name = "taskService")
	private TaskService taskService;
	
	/**
	 * 与动态表单管理相关的service
	 */
	@Resource(name = "formService")
	private FormService formService;
	
	
	/**
	 * 与历史任务管理相关的service
	 */
	@Resource(name = "historyService")
	private HistoryService historyService;


	@Override
	@Transactional
	public void saveStartProcess(Integer id) {
		// 更新业务状态
		leaveBillDao.updateStatus(id);
		
		// 放入审批人
		Map<String, Object> variables = new HashMap<>();
		variables.put("inputUser", SessionContext.get().getName());
		
		String businessKey = "leaveBill." + id;
		variables.put("businessKey", businessKey);
		
		runTimeService.startProcessInstanceByKey("leaveBill", businessKey, variables);
	}


	@Override
	public List<Task> myTask(String userName) {
		return taskService.createTaskQuery().taskAssignee(userName).list();
	}


	@Override
	public Integer queryLeaveBillByTaskId(String taskId) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		
		String processInstanceId = task.getProcessInstanceId();
		
		ProcessInstance processInstance = runTimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		
		String businessKey = processInstance.getBusinessKey();
		
		int leaveBillId = 0;
		if(StringUtils.isNotBlank(businessKey)) {
			leaveBillId = Integer.valueOf(businessKey.split("\\.")[1]);
		}
		
		return leaveBillId;
	}


	@Override
	public List<String> findOutcomeListByTaskId(String taskId) {
		// 得到任务
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		// 得到流程定义id,用来获取流程定义对象,从而拿到流程定义entity(bpmn文件)
		String processDefinitionId = task.getProcessDefinitionId();
		// 强转才能拿到当前活动
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
		
		String processInstanceId = task.getProcessInstanceId();
		ProcessInstance processInstance = runTimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		
		String activityId = processInstance.getActivityId();
		// 获取当前活动
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
		// 获取当前活动完成后的连线名称
		List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();
		// 存放返回连线的名称
		List<String> list = new ArrayList<>();
		
		if(pvmTransitions != null && !pvmTransitions.isEmpty()) {
			for (PvmTransition pvmTransition : pvmTransitions) {
				String name = (String) pvmTransition.getProperty("name");
				if(StringUtils.isNotBlank(name)) {
					list.add(name);
				} else {
					list.add("默认提交");
				}
			}
		}
		
		return list;
	}
	
	@Override
	@Transactional
	public void saveSubmitTask(Workflow workflow) {
		String taskId = workflow.getTaskId();
		String outcome = workflow.getOutcome();
		String message = workflow.getComment();
		Integer leaveBillId = workflow.getLeaveBillId();
		
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		String processInstanceId = task.getProcessInstanceId();
		
		// 在添加批注时会获取当前用户
		Authentication.setAuthenticatedUserId(SessionContext.get().getName());
		// 添加批注
		taskService.addComment(taskId, processInstanceId, message);
		
		Map<String, Object> variables = new HashMap<>();
		if(!outcome.equals("默认提交")) {
			variables.put("outcome", outcome);	
		}
		
		taskService.complete(taskId, variables);
		
		// 判断流程是否结束
		ProcessInstance processInstance = runTimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		
		if(processInstance == null) {
			if(outcome.equals("批准")) {
				leaveBillDao.updatePass(leaveBillId);
			}
		}
	}
	
	@Override
	public List<Comment> findCommentsByTaskId(String taskId) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		String processInstanceId = task.getProcessInstanceId();
		
//		List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
//				.processInstanceId(processInstanceId).list();
//		
//		List<Comment> list = new ArrayList<>();
//		if(historicTaskInstances != null && !historicTaskInstances.isEmpty()) {
//			for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
//				String hTaskId = historicTaskInstance.getId();
//				List<Comment> taskComments = taskService.getTaskComments(hTaskId);
//				list.addAll(taskComments);
//			}
//		}
		
		List<Comment> list2 = taskService.getProcessInstanceComments(processInstanceId);
		
		return list2;
	}


	@Override
	public List<Comment> findCommentsById(Integer id) {
		// 根据businessKey得到流程实例
		HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey("leaveBill." + id).singleResult();
		// 得到流程实例id
		String hisProcessInstanceId = historicProcessInstance.getId();
		
//		List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
//				.processInstanceId(hisProcessInstanceId).list();
//
//		List<Comment> list = new ArrayList<>();
//		if (historicTaskInstances != null && !historicTaskInstances.isEmpty()) {
//			for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
//				String hTaskId = historicTaskInstance.getId();
//				List<Comment> taskComments = taskService.getTaskComments(hTaskId);
//				list.addAll(taskComments);
//			}
//		}
		
		List<Comment> list2 = taskService.getProcessInstanceComments(hisProcessInstanceId);
		
		return list2;
	}
	
	
	
	
	
}

6.task.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<c:if test="${!empty list }">
		<table border="1" align="center">
			<tr>
				<th>任务ID</th>
				<th>任务名称</th>
				<th>创建时间</th>
				<th>办理人</th>
				<th>操作</th>
			</tr>
			
			<c:forEach items="${list}" var="task">
				<tr>
					<td>${task.id }</td>
					<td>${task.name }</td>
					<td>${task.createTime }</td>
					<td>${task.assignee }</td>
					<td><a href="<%=request.getContextPath() %>/applyTask?taskId=${task.id}">办理任务</a></td>
				</tr>
			
			</c:forEach>
		
		</table>
	
	</c:if>
	<input type="button" value="返回" onclick="history.go(-1);">
</body>
</html>

7.taskForm.jsp

扫描二维码关注公众号,回复: 4054720 查看本文章
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<c:if test="${!empty list }">
		<table border="1" align="center">
			<tr>
				<th>任务ID</th>
				<th>任务名称</th>
				<th>创建时间</th>
				<th>办理人</th>
				<th>操作</th>
			</tr>
			
			<c:forEach items="${list}" var="task">
				<tr>
					<td>${task.id }</td>
					<td>${task.name }</td>
					<td>${task.createTime }</td>
					<td>${task.assignee }</td>
					<td><a href="<%=request.getContextPath() %>/applyTask?taskId=${task.id}">办理任务</a></td>
				</tr>
			
			</c:forEach>
		
		</table>
	
	</c:if>
	<input type="button" value="返回" onclick="history.go(-1);">
</body>
</html>

8.taskFormHistory.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
		请假天数:<input type="text" value="${leaveBill.days }" readonly="readonly"><br>
		请假原因:<input type="text" value="${leaveBill.content }" readonly="readonly"><br>
		请假备注:<input type="text" value="${leaveBill.remark }" readonly="readonly"><br>
		
		<input type="button" value="返回" onclick="history.go(-1);">
	
	<br>
	<table border="1" align="center">
		<tr>
			<th>审批时间</th>
			<th>审批人</th>
			<th>批注</th>
		</tr>
		
		<c:forEach items="${commentList}" var="comment">
			<tr>
				<td>${comment.time }</td>
				<td>${comment.userId }</td>
				<td>${comment.fullMessage }</td>
			</tr>
		</c:forEach>
	</table>
	
	
	
	
	
	
</body>
</html>

附:WorkflowEntity

package com.gewb.activiti.entity;

import java.io.Serializable;

public class Workflow implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 4343439094129672355L;

	private String taskId;
	private String outcome;
	private String comment;
	private Integer leaveBillId;
	

	public Integer getLeaveBillId() {
		return leaveBillId;
	}

	public void setLeaveBillId(Integer leaveBillId) {
		this.leaveBillId = leaveBillId;
	}

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getOutcome() {
		return outcome;
	}

	public void setOutcome(String outcome) {
		this.outcome = outcome;
	}

}

ManagerTaskHandler

package com.gewb.activiti.utils;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.gewb.activiti.entity.Employee;
import com.gewb.activiti.service.EmployeeService;

public class ManagerTaskHandler implements TaskListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3772524270306357666L;
	
	@Override
	public void notify(DelegateTask delegateTask) {
		
		Employee employee = SessionContext.get();
		WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ContextLoader.getCurrentWebApplicationContext().getServletContext());
		EmployeeService employeeService = (EmployeeService) applicationContext.getBean("employeeServiceImpl");
		String managerName = employeeService.queryManagerName(employee);
		
		delegateTask.setAssignee(managerName);

	}


}

SessionContext

package com.gewb.activiti.utils;

import javax.servlet.http.HttpSession;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.gewb.activiti.entity.Employee;

public class SessionContext {
	
	public static Employee get() {
		HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
		Employee emp = (Employee)session.getAttribute("emp");
		
		return emp;
	}
	
	public static void set(Employee emp) {
		if (emp != null) {
			((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().setAttribute("emp", emp);
		} else {
			((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().removeAttribute("emp");
		}
	}
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

	<context:component-scan base-package="com.gewb.activiti">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
		<context:exclude-filter type="annotation"
			expression="org.springframework.web.bind.annotation.ControllerAdvice" />
	</context:component-scan>

	<!-- 配置数据源, 整合其他框架, 事务等. -->
	<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/activiti?serverTimezone=GMT%2B8&amp;useSSL=false"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
	</bean>

	<!-- 加载Mybatis配置文件,扫描所有mapping文件文件 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:conf/mybatis-config.xml" />
		<property name="mapperLocations" value="classpath:mappers/*Mapper.xml" />
	</bean>

	<!-- DAO接口所在包名,spring会自动查找其下的类 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.gewb.activiti.dao"></property>
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>

	<!-- TransactionMnager -->
	<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 使用Spring的注解事务 -->
	<tx:annotation-driven transaction-manager="txManager" />


	<!-- activiti -->
	<!-- 配置流程引擎文件 -->
	<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
		<property name="dataSource" ref="dataSource" />
		<property name="transactionManager" ref="txManager" />
		<!-- 是否自动创建23张表 -->
		<property name="databaseSchemaUpdate" value="true" />
	</bean>

	<!-- 配置创建流程引擎对象 -->
	<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
		<property name="processEngineConfiguration" ref="processEngineConfiguration" />
	</bean>

	<!-- 提供静态方法service -->
	<bean id="repositoryService" factory-bean="processEngine"
		factory-method="getRepositoryService" />
	<bean id="runtimeService" factory-bean="processEngine"
		factory-method="getRuntimeService" />
	<bean id="taskService" factory-bean="processEngine"
		factory-method="getTaskService" />
	<bean id="historyService" factory-bean="processEngine"
		factory-method="getHistoryService" />
	<bean id="formService" factory-bean="processEngine"
		factory-method="getFormService" />

</beans>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

	<!--  
		需要进行 Spring 整合 SpringMVC 吗 ?
		还是否需要再加入 Spring 的 IOC 容器 ?
		是否需要再 web.xml 文件中配置启动 Spring IOC 容器的 ContextLoaderListener ?
		
		1. 需要: 通常情况下, 类似于数据源, 事务, 整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中).
		实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao. 
		2. 不需要: 都放在 SpringMVC 的配置文件中. 也可以分多个 Spring 的配置文件, 然后使用 import 节点导入其他的配置文件
	-->
	
	<!--  
		问题: 若 Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描的包有重合的部分, 就会导致有的 bean 会被创建 2 次.
		解决:
		1. 使 Spring 的 IOC 容器扫描的包和 SpringMVC 的 IOC 容器扫描的包没有重合的部分. 
		2. 使用 exclude-filter 和 include-filter 子节点来规定只能扫描的注解
	-->
	
	<!--  
		SpringMVC 的 IOC 容器中的 bean 可以来引用 Spring IOC 容器中的 bean. 
		返回来呢 ? 反之则不行. Spring IOC 容器中的 bean 却不能来引用 SpringMVC IOC 容器中的 bean!
	-->
	
	<context:component-scan base-package="com.gewb.activiti" use-default-filters="false">
		<context:include-filter type="annotation" 
			expression="org.springframework.stereotype.Controller"/>
		<context:include-filter type="annotation" 
			expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
	</context:component-scan>

	<!-- 配置视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<mvc:default-servlet-handler/>
	<mvc:annotation-driven></mvc:annotation-driven>
	
	<!-- 配置MultipartResolver -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="defaultEncoding" value="UTF-8"></property>
		<property name="maxUploadSize" value="1024000"></property>
	</bean>
	
	
	
</beans>

================================================================================================

另附上查看流程图代码,基于ssh

task.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="/js/commons.jspf" %>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>任务管理</title>
</head>
<body>
	<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
		  <tr>
		    <td height="30"><table width="100%" border="0" cellspacing="0" cellpadding="0">
		      <tr>
		        <td height="24" bgcolor="#353c44"><table width="100%" border="0" cellspacing="0" cellpadding="0">
		          <tr>
		            <td><table width="100%" border="0" cellspacing="0" cellpadding="0">
		              <tr>
		                <td width="6%" height="19" valign="bottom"><div align="center"><img src="${pageContext.request.contextPath }/images/tb.gif" width="14" height="14" /></div></td>
		                <td width="94%" valign="bottom"><span class="STYLE1">个人任务管理列表</span></td>
		              </tr>
		            </table></td>
		            <td><div align="right"><span class="STYLE1">
		              </span></div></td>
		          </tr>
		        </table></td>
		      </tr>
		    </table></td>
		  </tr>
		  <tr>
		    <td><table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#a8c7ce" onmouseover="changeto()"  onmouseout="changeback()">
		      <tr>
		        <td width="15%" height="20" bgcolor="d3eaef" class="STYLE6"><div align="center"><span class="STYLE10">任务ID</span></div></td>
		        <td width="25%" height="20" bgcolor="d3eaef" class="STYLE6"><div align="center"><span class="STYLE10">任务名称</span></div></td>
		        <td width="20%" height="20" bgcolor="d3eaef" class="STYLE6"><div align="center"><span class="STYLE10">创建时间</span></div></td>
		        <td width="20%" height="20" bgcolor="d3eaef" class="STYLE6"><div align="center"><span class="STYLE10">办理人</span></div></td>
		        <td width="20%" height="20" bgcolor="d3eaef" class="STYLE6"><div align="center"><span class="STYLE10">操作</span></div></td>
		      </tr>
		      <s:if test="#list!=null && #list.size()>0">
		      	<s:iterator value="#list">
		      		<tr>
				        <td height="20" bgcolor="#FFFFFF" class="STYLE6"><div align="center"><s:property value="id"/></div></td>
				        <td height="20" bgcolor="#FFFFFF" class="STYLE19"><div align="center"><s:property value="name"/></div></td>
				        <td height="20" bgcolor="#FFFFFF" class="STYLE19"><div align="center"><s:date name="createTime" format="yyyy-MM-dd HH:mm:ss"/></div></td>
				        <td height="20" bgcolor="#FFFFFF" class="STYLE19"><div align="center"><s:property value="assignee"/></div></td>
				        <td height="20" bgcolor="#FFFFFF"><div align="center" class="STYLE21">
				        	<a href="${pageContext.request.contextPath }/workflowAction_viewTaskForm.action?taskId=<s:property value="id"/>">办理任务</a>
							<a target="_blank" href="workflowAction_viewCurrentImage.action?taskId=<s:property value="id"/>">查看当前流程图</a>
				        </div></td>
				    </tr> 
		      	</s:iterator>
		      </s:if>
		        
		      
		    </table></td>
		  </tr>
	</table>
</body>
</html>

image.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查看当前流程图</title>
</head>
<body>
<!-- 1.获取到规则流程图 -->
<img style="position: absolute;top: 0px;left: 0px;" src="workflowAction_viewImage?deploymentId=<s:property value='#deploymentId'/>&imageName=<s:property value='#imageName'/>">

<!-- 2.根据当前活动的坐标,动态绘制DIV -->
<div style="position: absolute;border:1px solid red;top:<s:property value="#acs.y"/>px;left: <s:property value="#acs.x"/>px;width: <s:property value="#acs.width"/>px;height:<s:property value="#acs.height"/>px;   "></div></body>
</html>

WorkflowAction.java

package cn.itcast.ssh.web.action;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.struts2.ServletActionContext;

import cn.itcast.ssh.domain.LeaveBill;
import cn.itcast.ssh.service.ILeaveBillService;
import cn.itcast.ssh.service.IWorkflowService;
import cn.itcast.ssh.utils.SessionContext;
import cn.itcast.ssh.utils.ValueContext;
import cn.itcast.ssh.web.form.WorkflowBean;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
public class WorkflowAction extends ActionSupport implements ModelDriven<WorkflowBean> {

	private WorkflowBean workflowBean = new WorkflowBean();
	
	@Override
	public WorkflowBean getModel() {
		return workflowBean;
	}
	
	private IWorkflowService workflowService;
	
	private ILeaveBillService leaveBillService;

	public void setLeaveBillService(ILeaveBillService leaveBillService) {
		this.leaveBillService = leaveBillService;
	}

	public void setWorkflowService(IWorkflowService workflowService) {
		this.workflowService = workflowService;
	}

	/**
	 * 部署管理首页显示
	 * @return
	 */
	public String deployHome(){
		//1:查询部署对象信息,对应表(act_re_deployment)
		List<Deployment> depList = workflowService.findDeploymentList();
		//2:查询流程定义的信息,对应表(act_re_procdef)
		List<ProcessDefinition> pdList = workflowService.findProcessDefinitionList();
		//放置到上下文对象中
		ValueContext.putValueContext("depList", depList);
		ValueContext.putValueContext("pdList", pdList);
		return "deployHome";
	}
	
	/**
	 * 发布流程
	 * @return
	 */
	public String newdeploy(){
		//获取页面传递的值
		//1:获取页面上传递的zip格式的文件,格式是File类型
		File file = workflowBean.getFile();
		//文件名称
		String filename = workflowBean.getFilename();
		//完成部署
		workflowService.saveNewDeploye(file,filename);
		return "list";
	}
	
	/**
	 * 删除部署信息
	 */
	public String delDeployment(){
		//1:获取部署对象ID
		String deploymentId = workflowBean.getDeploymentId();
		//2:使用部署对象ID,删除流程定义
		workflowService.deleteProcessDefinitionByDeploymentId(deploymentId);
		return "list";
	}
	
	/**
	 * 查看流程图
	 * @throws Exception 
	 */
	public String viewImage() throws Exception{
		//1:获取页面传递的部署对象ID和资源图片名称
		//部署对象ID
		String deploymentId = workflowBean.getDeploymentId();
		//资源图片名称
		String imageName = workflowBean.getImageName();
		//2:获取资源文件表(act_ge_bytearray)中资源图片输入流InputStream
		InputStream in = workflowService.findImageInputStream(deploymentId,imageName);
		//3:从response对象获取输出流
		OutputStream out = ServletActionContext.getResponse().getOutputStream();
		//4:将输入流中的数据读取出来,写到输出流中
		for(int b=-1;(b=in.read())!=-1;){
			out.write(b);
		}
		out.close();
		in.close();
		//将图写到页面上,用输出流写
		return null;
	}
	
	// 启动流程
	public String startProcess(){
		//更新请假状态,启动流程实例,让启动的流程实例关联业务
		workflowService.saveStartProcess(workflowBean);
		return "listTask";
	}
	
	
	
	/**
	 * 任务管理首页显示
	 * @return
	 */
	public String listTask(){
		//1:从Session中获取当前用户名
		String name = SessionContext.get().getName();
		//2:使用当前用户名查询正在执行的任务表,获取当前任务的集合List<Task>
		List<Task> list = workflowService.findTaskListByName(name); 
		ValueContext.putValueContext("list", list);
		return "task";
	}
	
	/**
	 * 打开任务表单
	 */
	public String viewTaskForm(){
		//任务ID
		String taskId = workflowBean.getTaskId();
		//获取任务表单中任务节点的url连接
		String url = workflowService.findTaskFormKeyByTaskId(taskId);
		url += "?taskId="+taskId;
		ValueContext.putValueContext("url", url);
		return "viewTaskForm";
	}
	
	// 准备表单数据
	public String audit(){
		//获取任务ID
		String taskId = workflowBean.getTaskId();
		/**一:使用任务ID,查找请假单ID,从而获取请假单信息*/
		LeaveBill leaveBill = workflowService.findLeaveBillByTaskId(taskId);
		ValueContext.putValueStack(leaveBill);
		/**二:已知任务ID,查询ProcessDefinitionEntiy对象,从而获取当前任务完成之后的连线名称,并放置到List<String>集合中*/
		List<String> outcomeList = workflowService.findOutComeListByTaskId(taskId);
		ValueContext.putValueContext("outcomeList", outcomeList);
		/**三:查询所有历史审核人的审核信息,帮助当前人完成审核,返回List<Comment>*/
		List<Comment> commentList = workflowService.findCommentByTaskId(taskId);
		ValueContext.putValueContext("commentList", commentList);
		return "taskForm";
	}
	
	/**
	 * 提交任务
	 */
	public String submitTask(){
		workflowService.saveSubmitTask(workflowBean);
		return "listTask";
	}
	
	/**
	 * 查看当前流程图(查看当前活动节点,并使用红色的框标注)
	 */
	public String viewCurrentImage(){
		//任务ID
		String taskId = workflowBean.getTaskId();
		/**一:查看流程图*/
		//1:获取任务ID,获取任务对象,使用任务对象获取流程定义ID,查询流程定义对象
		ProcessDefinition pd = workflowService.findProcessDefinitionByTaskId(taskId);
		//workflowAction_viewImage?deploymentId=<s:property value='#deploymentId'/>&imageName=<s:property value='#imageName'/>
		ValueContext.putValueContext("deploymentId", pd.getDeploymentId());
		ValueContext.putValueContext("imageName", pd.getDiagramResourceName());
		/**二:查看当前活动,获取当期活动对应的坐标x,y,width,height,将4个值存放到Map<String,Object>中*/
		Map<String, Object> map = workflowService.findCoordingByTask(taskId);
		ValueContext.putValueContext("acs", map);
		return "image";
	}
	
	// 查看历史的批注信息
	public String viewHisComment(){
		//获取清单ID
		Long id = workflowBean.getId();
		//1:使用请假单ID,查询请假单对象,将对象放置到栈顶,支持表单回显
		LeaveBill leaveBill = leaveBillService.findLeaveBillById(id);
		ValueContext.putValueStack(leaveBill);
		//2:使用请假单ID,查询历史的批注信息
		List<Comment> commentList = workflowService.findCommentByLeaveBillId(id);
		ValueContext.putValueContext("commentList", commentList);
		return "viewHisComment";
	}
}

WorkflowServiceImpl.java

package cn.itcast.ssh.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;
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.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;

import cn.itcast.ssh.dao.ILeaveBillDao;
import cn.itcast.ssh.domain.LeaveBill;
import cn.itcast.ssh.service.IWorkflowService;
import cn.itcast.ssh.utils.SessionContext;
import cn.itcast.ssh.web.form.WorkflowBean;

public class WorkflowServiceImpl implements IWorkflowService {
	/**请假申请Dao*/
	private ILeaveBillDao leaveBillDao;
	
	private RepositoryService repositoryService;
	
	private RuntimeService runtimeService;
	
	private TaskService taskService;
	
	private FormService formService;
	
	private HistoryService historyService;

	public void setLeaveBillDao(ILeaveBillDao leaveBillDao) {
		this.leaveBillDao = leaveBillDao;
	}

	public void setHistoryService(HistoryService historyService) {
		this.historyService = historyService;
	}
	
	public void setFormService(FormService formService) {
		this.formService = formService;
	}
	
	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public void setRepositoryService(RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}

	/**部署流程定义*/
	@Override
	public void saveNewDeploye(File file, String filename) {
		try {
			//2:将File类型的文件转化成ZipInputStream流
			ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
			repositoryService.createDeployment()//创建部署对象
							.name(filename)//添加部署名称
							.addZipInputStream(zipInputStream)//
							.deploy();//完成部署
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**查询部署对象信息,对应表(act_re_deployment)*/
	@Override
	public List<Deployment> findDeploymentList() {
		List<Deployment> list = repositoryService.createDeploymentQuery()//创建部署对象查询
							.orderByDeploymenTime().asc()//
							.list();
		return list;
	}
	
	/**查询流程定义的信息,对应表(act_re_procdef)*/
	@Override
	public List<ProcessDefinition> findProcessDefinitionList() {
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()//创建流程定义查询
							.orderByProcessDefinitionVersion().asc()//
							.list();
		return list;
	}
	
	/**使用部署对象ID和资源图片名称,获取图片的输入流*/
	@Override
	public InputStream findImageInputStream(String deploymentId,
			String imageName) {
		return repositoryService.getResourceAsStream(deploymentId, imageName);
	}
	
	/**使用部署对象ID,删除流程定义*/
	@Override
	public void deleteProcessDefinitionByDeploymentId(String deploymentId) {
		repositoryService.deleteDeployment(deploymentId, true);
	}
	
	/**更新请假状态,启动流程实例,让启动的流程实例关联业务*/
	@Override
	public void saveStartProcess(WorkflowBean workflowBean) {
		//1:获取请假单ID,使用请假单ID,查询请假单的对象LeaveBill
		Long id = workflowBean.getId();
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(id);
		//2:更新请假单的请假状态从0变成1(初始录入-->审核中)
		leaveBill.setState(1);
		//3:使用当前对象获取到流程定义的key(对象的名称就是流程定义的key)
		String key = leaveBill.getClass().getSimpleName();
		/**
		 * 4:从Session中获取当前任务的办理人,使用流程变量设置下一个任务的办理人
			    * inputUser是流程变量的名称,
			    * 获取的办理人是流程变量的值
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		variables.put("inputUser", SessionContext.get().getName());//表示惟一用户
		/**
		 * 5:	(1)使用流程变量设置字符串(格式:LeaveBill.id的形式),通过设置,让启动的流程(流程实例)关联业务
   				(2)使用正在执行对象表中的一个字段BUSINESS_KEY(Activiti提供的一个字段),让启动的流程(流程实例)关联业务
		 */
		//格式:LeaveBill.id的形式(使用流程变量)
		String objId = key+"."+id;
		variables.put("objId", objId);
		//6:使用流程定义的key,启动流程实例,同时设置流程变量,同时向正在执行的执行对象表中的字段BUSINESS_KEY添加业务数据,同时让流程关联业务
		runtimeService.startProcessInstanceByKey(key,objId,variables);
		
	}
	
	/**2:使用当前用户名查询正在执行的任务表,获取当前任务的集合List<Task>*/
	@Override
	public List<Task> findTaskListByName(String name) {
		List<Task> list = taskService.createTaskQuery()//
					.taskAssignee(name)//指定个人任务查询
					.orderByTaskCreateTime().asc()//
					.list();
		return list;
	}
	
	/**使用任务ID,获取当前任务节点中对应的Form key中的连接的值*/
	@Override
	public String findTaskFormKeyByTaskId(String taskId) {
		TaskFormData formData = formService.getTaskFormData(taskId);
		//获取Form key的值
		String url = formData.getFormKey();
		return url;
	}
	
	/**一:使用任务ID,查找请假单ID,从而获取请假单信息*/
	@Override
	public LeaveBill findLeaveBillByTaskId(String taskId) {
		//1:使用任务ID,查询任务对象Task
		Task task = taskService.createTaskQuery()//
						.taskId(taskId)//使用任务ID查询
						.singleResult();
		//2:使用任务对象Task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//3:使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
						.processInstanceId(processInstanceId)//使用流程实例ID查询
						.singleResult();
		//4:使用流程实例对象获取BUSINESS_KEY
		String buniness_key = pi.getBusinessKey();
		//5:获取BUSINESS_KEY对应的主键ID,使用主键ID,查询请假单对象(LeaveBill.1)
		String id = "";
		if(StringUtils.isNotBlank(buniness_key)){
			//截取字符串,取buniness_key小数点的第2个值
			id = buniness_key.split("\\.")[1];
		}
		//查询请假单对象
		//使用hql语句:from LeaveBill o where o.id=1
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(Long.parseLong(id));
		return leaveBill;
	}
	
	/**二:已知任务ID,查询ProcessDefinitionEntiy对象,从而获取当前任务完成之后的连线名称,并放置到List<String>集合中*/
	@Override
	public List<String> findOutComeListByTaskId(String taskId) {
		//返回存放连线的名称集合
		List<String> list = new ArrayList<String>();
		//1:使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery()//
					.taskId(taskId)//使用任务ID查询
					.singleResult();
		//2:获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		//3:查询ProcessDefinitionEntiy对象
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);
		//使用任务对象Task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
		//获取当前活动的id
		String activityId = pi.getActivityId();
		//4:获取当前的活动
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
		//5:获取当前活动完成之后连线的名称
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
		if(pvmList!=null && pvmList.size()>0){
			for(PvmTransition pvm:pvmList){
				String name = (String) pvm.getProperty("name");
				if(StringUtils.isNotBlank(name)){
					list.add(name);
				}
				else{
					list.add("默认提交");
				}
			}
		}
		return list;
	}
	
	/**指定连线的名称完成任务*/
	@Override
	public void saveSubmitTask(WorkflowBean workflowBean) {
		//获取任务ID
		String taskId = workflowBean.getTaskId();
		//获取连线的名称
		String outcome = workflowBean.getOutcome();
		//批注信息
		String message = workflowBean.getComment();
		//获取请假单ID
		Long id = workflowBean.getId();
		
		/**
		 * 1:在完成之前,添加一个批注信息,向act_hi_comment表中添加数据,用于记录对当前申请人的一些审核信息
		 */
		//使用任务ID,查询任务对象,获取流程流程实例ID
		Task task = taskService.createTaskQuery()//
						.taskId(taskId)//使用任务ID查询
						.singleResult();
		//获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		/**
		 * 注意:添加批注的时候,由于Activiti底层代码是使用:
		 * 		String userId = Authentication.getAuthenticatedUserId();
			    CommentEntity comment = new CommentEntity();
			    comment.setUserId(userId);
			  所有需要从Session中获取当前登录人,作为该任务的办理人(审核人),对应act_hi_comment表中的User_ID的字段,不过不添加审核人,该字段为null
			 所以要求,添加配置执行使用Authentication.setAuthenticatedUserId();添加当前任务的审核人
		 * */
		Authentication.setAuthenticatedUserId(SessionContext.get().getName());
		taskService.addComment(taskId, processInstanceId, message);
		/**
		 * 2:如果连线的名称是“默认提交”,那么就不需要设置,如果不是,就需要设置流程变量
		 * 在完成任务之前,设置流程变量,按照连线的名称,去完成任务
				 流程变量的名称:outcome
				 流程变量的值:连线的名称
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		if(outcome!=null && !outcome.equals("默认提交")){
			variables.put("outcome", outcome);
		}

		//3:使用任务ID,完成当前人的个人任务,同时流程变量
		taskService.complete(taskId, variables);
		//4:当任务完成之后,需要指定下一个任务的办理人(使用类)-----已经开发完成
		
		/**
		 * 5:在完成任务之后,判断流程是否结束
   			如果流程结束了,更新请假单表的状态从1变成2(审核中-->审核完成)
		 */
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
						.processInstanceId(processInstanceId)//使用流程实例ID查询
						.singleResult();
		//流程结束了
		if(pi==null){
			//更新请假单表的状态从1变成2(审核中-->审核完成)
			LeaveBill bill = leaveBillDao.findLeaveBillById(id);
			bill.setState(2);
		}
	}
	
	/**获取批注信息,传递的是当前任务ID,获取历史任务ID对应的批注*/
	@Override
	public List<Comment> findCommentByTaskId(String taskId) {
		List<Comment> list = new ArrayList<Comment>();
		//使用当前的任务ID,查询当前流程对应的历史任务ID
		//使用当前任务ID,获取当前任务对象
		Task task = taskService.createTaskQuery()//
				.taskId(taskId)//使用任务ID查询
				.singleResult();
		//获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
//		//使用流程实例ID,查询历史任务,获取历史任务对应的每个任务ID
//		List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()//历史任务表查询
//						.processInstanceId(processInstanceId)//使用流程实例ID查询
//						.list();
//		//遍历集合,获取每个任务ID
//		if(htiList!=null && htiList.size()>0){
//			for(HistoricTaskInstance hti:htiList){
//				//任务ID
//				String htaskId = hti.getId();
//				//获取批注信息
//				List<Comment> taskList = taskService.getTaskComments(htaskId);//对用历史完成后的任务ID
//				list.addAll(taskList);
//			}
//		}
		list = taskService.getProcessInstanceComments(processInstanceId);
		return list;
	}
	
	/**使用请假单ID,查询历史批注信息*/
	@Override
	public List<Comment> findCommentByLeaveBillId(Long id) {
		//使用请假单ID,查询请假单对象
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(id);
		//获取对象的名称
		String objectName = leaveBill.getClass().getSimpleName();
		//组织流程表中的字段中的值
		String objId = objectName+"."+id;
		
		/**1:使用历史的流程实例查询,返回历史的流程实例对象,获取流程实例ID*/
//		HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()//对应历史的流程实例表
//						.processInstanceBusinessKey(objId)//使用BusinessKey字段查询
//						.singleResult();
//		//流程实例ID
//		String processInstanceId = hpi.getId();
		/**2:使用历史的流程变量查询,返回历史的流程变量的对象,获取流程实例ID*/
		HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery()//对应历史的流程变量表
						.variableValueEquals("objId", objId)//使用流程变量的名称和流程变量的值查询
						.singleResult();
		//流程实例ID
		String processInstanceId = hvi.getProcessInstanceId();
		List<Comment> list = taskService.getProcessInstanceComments(processInstanceId);
		return list;
	}
	
	/**1:获取任务ID,获取任务对象,使用任务对象获取流程定义ID,查询流程定义对象*/
	@Override
	public ProcessDefinition findProcessDefinitionByTaskId(String taskId) {
		//使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery()//
					.taskId(taskId)//使用任务ID查询
					.singleResult();
		//获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		//查询流程定义的对象
		ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()//创建流程定义查询对象,对应表act_re_procdef 
					.processDefinitionId(processDefinitionId)//使用流程定义ID查询
					.singleResult();
		return pd;
	}
	
	/**
	 * 二:查看当前活动,获取当期活动对应的坐标x,y,width,height,将4个值存放到Map<String,Object>中
		 map集合的key:表示坐标x,y,width,height
		 map集合的value:表示坐标对应的值
	 */
	@Override
	public Map<String, Object> findCoordingByTask(String taskId) {
		//存放坐标
		Map<String, Object> map = new HashMap<String,Object>();
		//使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery()//
					.taskId(taskId)//使用任务ID查询
					.singleResult();
		//获取流程定义的ID
		String processDefinitionId = task.getProcessDefinitionId();
		//获取流程定义的实体对象(对应.bpmn文件中的数据)
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
		//流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID,查询正在执行的执行对象表,获取当前活动对应的流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//创建流程实例查询
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
		//获取当前活动的ID
		String activityId = pi.getActivityId();
		//获取当前活动对象
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//活动ID
		//获取坐标
		map.put("x", activityImpl.getX());
		map.put("y", activityImpl.getY());
		map.put("width", activityImpl.getWidth());
		map.put("height", activityImpl.getHeight());
		return map;
	}
}

猜你喜欢

转载自blog.csdn.net/jamesge2010/article/details/81158329