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
<%@ 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&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;
}
}