Activiti工作流樣例教程(請假-審批流程並向用戶展示工作流實時過程圖)
阿新 • • 發佈:2019-02-17
1 配置工作流。
啟動activiti-explorer並登入。(使用者名稱:kermit;密碼:kermit)
選擇 流程->流程設計工作區->新建模型 輸入流程名稱進入流程設計介面,繪製流程圖:
給事件和活動新增ID,並給活動分配(Assignments)代理人(assignee):
儲存退出編輯介面,處理模型選擇匯出模型,導出工作流文件process.bpmn20.xml。並將檔案新增進專案中:
<process id="approvalprocess" isExecutable="true"> <startEvent id="beginId"></startEvent> <userTask id="leaveId" name="請假申請" activiti:assignee="員工"></userTask> <sequenceFlow id="sid-3E778B12-F461-4ED0-B332-6711B1BF8006" sourceRef="beginId" targetRef="leaveId"></sequenceFlow> <userTask id="approvalId" name="總經理審批" activiti:assignee="總經理"></userTask> <sequenceFlow id="sid-4D19FF7E-CADE-4BA7-BC8E-FE02384B5318" sourceRef="leaveId" targetRef="approvalId"></sequenceFlow> <endEvent id="endId"></endEvent> <sequenceFlow id="sid-1D5CAC61-71D7-4A33-BD98-5FD661BE8494" sourceRef="approvalId" targetRef="endId"></sequenceFlow> </process>
在maven中配置activiti的依賴
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>${activiti.version}</version> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring</artifactId> <version>${activiti.version}</version> </dependency>
在Spring中配置資料來源、事務管理、流程引擎及幾個必要的xxxService
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/activiti" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="mailServerHost" value="localhost" /> <property name="mailServerPort" value="5025" /> <property name="jpaHandleTransaction" value="true" /> <property name="jpaCloseEntityManager" value="true" /> <property name="jobExecutorActivate" value="false" /> <property name="xmlEncoding" value="utf-8" /> <property name="labelFontName" value="宋體"></property> <property name="activityFontName" value="宋體"></property> </bean> <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"> <property name="processEngineConfiguration" ref="processEngineConfiguration" /> </bean> <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="managementService" factory-bean="processEngine" factory-method="getManagementService" /> <bean id="formService" factory-bean="processEngine" factory-method="getFormService" /> <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" /> </beans>
2 開發工作流。
首先部署工作流檔案:
@RequestMapping("/deployment")
public void deployment(@RequestParam("resourceName")String resourceName) {
Deployment deployment = repositoryService
.createDeployment()
.addClasspathResource("workflow/"+resourceName)
.deploy();
}
2.1 啟動工作流
根據process.bpmn20.xml中配置的工作流Id啟動該工作流例項,並得到該流程例項的id,儲存到資料庫中:
ProcessInstance pi = runtimeService.startProcessInstanceByKey(id);
String processid = pi.getId();
2.2 推進工作流
根據流程例項id找到任務代理人(assignee)的流程任務,呼叫complete方法完成該任務,使任務向下推進:
String processid = (String) map.get("processid");
String assignee = "員工";
Task task = taskService.createTaskQuery().processInstanceId(processid).taskAssignee(assignee).singleResult();
taskService.complete(task.getId());
繼續完成下一步任務:
String processid = (String) map.get("processid");
String assignee = "總經理";
Task task = taskService.createTaskQuery().processInstanceId(processid).taskAssignee(assignee).singleResult();
taskService.complete(task.getId());
3 檢視工作流
根據流程例項id找到當前流程定義實體,根據該流程定義獲取流程部署的id和圖形資源名稱,根據其得到圖形輸入流,將其輸出到瀏覽器可得到當前流程的流程圖:
String processid = (String) map.get("processid");
ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().processInstanceId(processid).singleResult();
ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(execution.getProcessDefinitionId());
String diagramResourceName = def.getDiagramResourceName();
InputStream is = repositoryService.getResourceAsStream(
def.getDeploymentId(), diagramResourceName);
try {
OutputStream os = httpServletResponse.getOutputStream();
byte [] bs = new byte[1024];
int i = 0;
while((i=is.read(bs))!=-1){
os.write(bs,0,i);
}
} catch (IOException e) {
}
根據流程例項id找到當前正在執行的任務節點,得到該節點的座標,在頁面上通過座標標示相應的提示紅框:
String processid = (String) map.get("processid");
ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().processInstanceId(processid).singleResult();
String activitiId = execution.getCurrentActivityId();// 當前例項的執行到哪個節點
ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(execution.getProcessDefinitionId());
List<ActivityImpl> activitiList = def.getActivities();// 獲得當前任務的所有節點
ActivityImpl actImpl = null;
for (ActivityImpl activityImpl : activitiList) {
String id = activityImpl.getId();
if (id.equals(activitiId)) {// 獲得執行到那個節點
actImpl = activityImpl;
break;
}
}
if(actImpl==null) return null;
Map currentActivityMap=new HashMap();
currentActivityMap.put("x",actImpl.getX());
currentActivityMap.put("y",actImpl.getY());
currentActivityMap.put("width",actImpl.getWidth());
currentActivityMap.put("height",actImpl.getHeight());
String msg=JSON.toJSONString(currentActivityMap);
頁面展示當前工作流流程圖:
<head>
<script type="text/javascript">
var id="<%=id%>";
$(function(){
var data = U.action("/leaveApprove/nextActivityId", {pk:id});
var json = JSON.parse(data.msg);
$("#next").css({"position":"absolute","top":json.y,"left":json.x,"width":json.width,"height":json.height});
});
</script>
</head>
<body>
<img src="<%=basePath%>/leaveApprove/watch?pk=<%=id%>" />
<div id="next" style="border: 1px red solid"></div>
</body>
</html>
效果如圖:展示當前流程圖,並提示正在進行中的任務。