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>
效果如图:展示当前流程图,并提示正在进行中的任务。