10 BOS项目第10天
今天继续学习工作流activity,流程变量
10.1 请假流程存在的问题
- 缺少请假原因和请假天数,后期可能还会有其它数据要补充
-
activiti把这些数据称为流程变量,内部提供了一张act_ru_variable 表来存这些数据
10.2 设置流程变量的方式
-
重新创建一个Java项目和数据库,这次用报销流程讲解
10.2.1 第一种:启动流程实例时设置流程变量
@Test
public void test1(){
//2.获取部署构建器对象
DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
//3.添加流程资源
deploymentBuilder.addClasspathResource("bxlc.bpmn");
deploymentBuilder.addClasspathResource("bxlc.jpg");
//4.部署
Deployment deployment = deploymentBuilder.deploy();
System.out.println(deployment.getId());
}
/**
* 启动流程实例时设置流程变量
*/
@Test
public void test2(){
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("bxyy", "成都出差机票");
varibles.put("bxje", "980");
processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
}
10.2.2 第二种:办理任务时设置流程变量
/**
* 审核任务时设置流程变量
*/
@Test
public void test3(){
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("bxyy", "成都出差动车票");
varibles.put("bxje", "260.00");
processEngine.getTaskService().complete("1106", varibles);
}
10.2.3 使用RuntimeService的set方法设置流程变量
/**
* 使用RuntimeService的set方法设置流程变量
*/
@Test
public void test4(){
String processInstanceId = "1101";
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("审核状态", "同意");
processEngine.getRuntimeService().setVariables(processInstanceId, varibles);
}
10.2.4 用TaskService的set方法设置
/**
* 用TaskService的set方法设置
*/
@Test
public void test5(){
String taskId = "1202";//任务id
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("审核状态", "不同意");
processEngine.getTaskService().setVariables(taskId, varibles);
}
10.2.5 如果设置的是自定义的类型,需要实现序列化接口
@Test
public void test5(){
String taskId = "1202";//任务id
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("审核状态", "不同意");
varibles.put("user", new User("kdj", "123456"));
processEngine.getTaskService().setVariables(taskId, varibles);
}
10.3 读取流程变量的方式
10.3.1 方式一:使用RuntimeService的get方法获取
@Test
public void test6() {
//用getRuntimeService的get方法获取流程变量
String processInstanceId = "1101";
User user = (User) processEngine.getRuntimeService().getVariable(processInstanceId, "user");
System.out.println(user);
String state = (String) processEngine.getRuntimeService().getVariable(processInstanceId, "审核状态");
System.out.println(state);
}
10.3.2 使用TaskService的get方法获取
@Test
public void test7() {
//用TaskService的get方法获取流程变量
String taskId = "1202";
User user = (User) processEngine.getTaskService().getVariable(taskId, "user");
System.out.println(user);
String state = (String) processEngine.getTaskService().getVariable(taskId, "审核状态");
System.out.println(state);
}
10.4 动态设置任务的候选人
- 第一步:在启动流程实现时,需要添加一个表达式里的变量值
@Test
public void test2() {
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("bxyy", "成都出差机票");
varibles.put("bxje", "2800");
varibles.put("employeeName", "lisi");
processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
}
-
在任务的Assignee写表达式
10.5 组任务操作
10.5.1 候选人组任务(了解)
-
第一步:给任务添加多个用户
第二步:重新部署流程和启动流程实现
@Test
public void test1() {
//2.获取部署构建器对象
DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
//3.添加流程资源
deploymentBuilder.addClasspathResource("bxlc.bpmn");
deploymentBuilder.addClasspathResource("bxlc.jpg");
//4.部署
Deployment deployment = deploymentBuilder.deploy();
System.out.println(deployment.getId());
}
/**
* 启动流程实例时设置流程变量
*/
@Test
public void test2() {
HashMap<String, Object> varibles = new HashMap<>();
varibles.put("bxyy", "成都出差机票");
varibles.put("bxje", "2800");
varibles.put("employeeName", "lisi");
processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
}
- 第三步:办理第一个流程任务
@Test
public void test3() {
//李四提交申请
processEngine.getTaskService().complete("107");
}
- 第四步:根据用户id查询任务
@Test
public void test4() {
//查找财务人员要审核任务
TaskQuery tq = processEngine.getTaskService().createTaskQuery();
//设置候选人名称
tq.taskCandidateUser("kdj01");
//打印任务id,打印名称
for (Task task : tq.list()) {
System.out.println(task.getId() + ":" + task.getName());
}
}
- 第五步:拾取任务
@Test
public void test4() {
//查找财务人员要审核任务
TaskQuery tq = processEngine.getTaskService().createTaskQuery();
//设置候选人名称
String user = "kdj01";
tq.taskCandidateUser(user);
//打印任务id,打印名称
for (Task task : tq.list()) {
System.out.println(task.getId() + ":" + task.getName());
//拾取任务
processEngine.getTaskService().claim(task.getId(), user);
}
}
10.5.2 候选组组任务(重点)
-
第一步:设置一个财务分组id
第二步:重新部署流程并启动流程实例然后complete提交申请
-
第三步:添加组
-
第四步:添加用户
-
第五步:建立用户和组的关系
-
第六步:根据用户id或者组查询任务
- 注意:查询任务时,要先启动流程实现并输第一个任务
@Test
public void testProcessInstance(){
//启动流程实例:
Map<String,Object> variables = new HashMap<String,Object>();
variables.put("bxyy", "南京出差机机票");
variables.put("bxje", "890");
variables.put("employeeName", "小李");
pe.getRuntimeService().startProcessInstanceByKey("bxlc", variables);
}
@Test
public void testComplete(){
//处理第一个任务
pe.getTaskService().complete("2307");
}
@Test
public void test5(){
//查询组任务
TaskQuery tq = pe.getTaskService().createTaskQuery();
String userId = "1";
//tq.taskCandidateUser(userId);
tq.taskCandidateGroup("财务组");
List<Task> tasks = tq.list();
for(Task t:tasks){
System.out.println(t.getId());
}
}
- 第七步:拾起任务
pe.getTaskService().claim("2402", "1");
10.6 排他网关
10.6.1 排他网关流程图
10.6.2 测试网关
- 在开启流程实例时,必需设置流量变量qjts
public class GateWayTest {
//1.获取流程引擎
ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
@Test
public void test1(){
//2.获取部署构建器对象
DeploymentBuilder db = pe.getRepositoryService().createDeployment();
//3.添加流程资源
db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.bpmn");
db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.png");
//4.部署
Deployment deployment = db.deploy();
System.out.println(deployment.getId());
}
@Test
public void test2(){
Map<String,Object> variables = new HashMap<String,Object>();
variables.put("qjyy", "感冒..");
variables.put("qjts",5);
pe.getRuntimeService().startProcessInstanceByKey("qjlc", variables);
}
@Test
public void test3(){
String taskId = "606";
pe.getTaskService().complete(taskId);
}
}
10.7 activiti与spring整合
10.7.1 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:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///activiti_day1"/>
<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"/>
</bean>
<!-- 使用工厂创建流程引擎对象 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
</beans>
10.7.2 单元测试
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class Main5 {
@Test
public void test1() {
//1.创建spring工厂
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取bean
ProcessEngine pe = (ProcessEngine) ac.getBean("processEngine");
List<ProcessDefinition> list = pe.getRepositoryService().createProcessDefinitionQuery().list();
//有流程定义打印,代表配置成功
for(ProcessDefinition pd : list){
System.out.println(pd.getKey());
}
}
}
10.8 Bos项目集成activiti
10.8.1 第一步:在Bos数据库添加activiti所需要的表
- 之前三个sql文件,已经导入了
10.8.2 第二步:将activiti与spring的整合转移到Bos项目中
导入jar包到项目:使用spring3.2以上版本,不需要添加spring-asm.jar
spring中配置processengin
<!-- 流程引擎配置对象 -->
<bean id="processEngineConfiguration"
class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!-- 使用工厂创建流程引擎对象 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
- 再配置activiti的各种service
<!-- 注册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="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
- 测试下是否能获取到流程定义
@Autowired
private RepositoryService rs;
public String login(){
logger.info(getModel());
System.out.println(rs); //如果有值,证明activiti的配置木有问题
10.9 流程定义管理模型
10.9.1 修改系统管理的菜单数据
- 在admin.json 添加两行数据
- 注意:系统管理的数据是从json中获取,不是从数据库
{ "id":"1004", "pId":"100", "name":"流程定义管理", "page":"processDefinitionAction_list.action"},
{ "id":"1005", "pId":"100", "name":"查看正在运行的流程实例", "page":"processInstanceAction_list.action"}
10.9.2 查看流程定义
- 创建ProcessDefinitionAction,完成流程定义列表展现
10.9.3 部署流程定义
//发布一个流程
public String deploy() throws FileNotFoundException {
//1.获取部署的对象
DeploymentBuilder builder = rs.createDeployment();
//2.builder 添加压缩包的输入流
builder.addZipInputStream(new ZipInputStream(new FileInputStream(zipFile)));
builder.deploy();
//部署完后回到list页面
return "list";
}
10.9.4 查看流程定义图
- 第一步:修改jsp页面
<td>
<a onclick="showPng('${id}')" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查看流程图</a>
</td>
<script>
function showPng(id) {
//alert(id);
//显示流程图
window.open("${pageContext.request.contextPath}/processDefinitionAction_viewpng.action?id=" + id);
}
</script>
- 第二步:Action
public String viewpng(){
//返回一张图片给客户端
//1.根据流程id获取图片
InputStream imgIS = rs.getProcessDiagram(id);
//2.把imgIS放在值栈
ActionContext.getContext().getValueStack().set("imgIS", imgIS);
return "viewpng";
}
- 第三步:Struts
<action name="processDefinitionAction_*" class="com.kdj.bos.web.action.ProcessDefinitionAction" method="{1}">
<result name="list">/WEB-INF/pages/workflow/processdefinition_list.jsp</result>
<!--告诉客户端返回流文件-->
<result name="viewpng" type="stream">
<param name="contentType">image/png</param>
<param name="inputName">imgIS</param>
</result>
</action>
10.9.5 删除流程定义
-
效果
第一步:添加删除的js代码
function del(id) {
$.messager.confirm("提示","是否要删除?", function (r) {
if (r){
var url = "${pageContext.request.contextPath}/processDefinitionAction_del.action";
$.post(url, {id:id}, function (data) {
if (data == "success") {
$.messager.alert("提示", "删除成功", "info", function () {
location.href = "${pageContext.request.contextPath}/processDefinitionAction_list.action"
});
} else{
$.messager.alert("提示", "删除失败", "error");
}
});
}
});
}
- 第二步:Action代码
public void del() throws IOException {
//1.先根据流程定义的id查找部署id
ProcessDefinitionQuery query = rs.createProcessDefinitionQuery();
query.processDefinitionId(id);
ProcessDefinition pd = query.singleResult();
String deploymentId = pd.getDeploymentId();
rs.deleteDeployment(deploymentId);
ServletActionContext.getResponse().getWriter().write("success");
}