ssm與activiti整合之全套流程
阿新 • • 發佈:2018-11-13
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;
}
}