jbpm学习笔记(四) 模拟借款申请以及各级审批 熟悉各种服务API调用

首先,我们来思考一个这样的逻辑,如下图,
[img]
http://dl.iteye.com/upload/picture/pic/79595/dd99a470-0acd-3bd4-b51c-ba9458c97792.png
[/img]



用文字描述是这样的:公司员工在申请借款时,首先填写借款申请,然后部门经理审批,不通过,则取消,若通过,并且金额《5000时,由财务拨款,完成申请,假如金额》=5000,则由总经理审批,通过,则由财务拨款,完成申请,不通过,取消。

通过这个流程图,我们设计jbpm流程定义文件(jbdl),实际上 上面的图就是GPD工具(图形化流程设计器)生成的,源码如下:

Loan.jpdl.xml:

<?xml version="1.0" encoding="UTF-8"?>

<process name="loan" xmlns="http://jbpm.org/4.4/jpdl">

<start name="start">
<transition name="startLoan" to="inputLoan"/>
</start>

<task assignee="#{proposer}" name="inputLoan">
<transition name="submitApplication" to="managerCheck" />
</task>

<task assignee="manager" name="managerCheck">
<transition name="managerNotPass" to="cancel" />
<transition name="managerPass" to="moneyCheck" />
</task>

<decision name="moneyCheck" expr="#{money>=5000?'x1':'x2'}">
<transition name="x1" to="ceoCheck"/>
<transition name="x2" to="financeGet"/>
</decision>

<end name="end" />
<end-cancel name="cancel" />

<task assignee="ceo" name="ceoCheck">
<transition name="ceoPass" to="financeGet" />
<transition name="ceoNotPass" to="cancel" />
</task>

<task assignee="finance" name="financeGet">
<transition name="finishFinance" to="end"/>
</task>


</process>

[color=red](注:最开始我的name全部写的中文,发觉在运行的时候会报一个错,改成字母就好了)
有的人比较模糊task和state的区别:task有分配,state没有。[/color]

在编码过程中,我们经常会用到jbpm API服务帮我们“走”流程,上一篇中说过,jbpm中JbpmTestCase是作为jbpm4框架的单元测试超类出现的,而且帮我们初始化了如下6个流程引擎服务:

//资源库服务
Protected static RepositoryService repositoryService;

//执行服务
Protected static ExecutionService executionService;

//管理服务
Protected static ManagementService managementService;

//任务服务
Protected static TaskService taskService;

//历史服务
Protected static HistoryService historyService;

//身份认证服务
Protected static IdentiryService identiryService;

这些比较常用


package org.test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jbpm.api.ProcessInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.task.Task;
import org.jbpm.test.JbpmTestCase;

/**
* 模拟借款
*
* @author 阿飞哥
*
*/
public class LoanTest extends JbpmTestCase {
String deploymentId;

@Override
protected void setUp() throws Exception {
super.setUp();
deploymentId = repositoryService.createDeployment()
.addResourceFromClasspath("org/test/loan.jpdl.xml").deploy();
}

@Override
protected void tearDown() throws Exception {
repositoryService.deleteDeploymentCascade(deploymentId);
super.tearDown();
}

/************ 测试例子 ***********/

/**
* 张山 申请4000元,部门经理驳回
*/
/*public void test1(){
String curUser = "张山";
//创建流程实例
ProcessInstance pi = startLoanProcess(curUser);
String piId = pi.getId();
fillOutApplication(piId,curUser,4000);
curUser = "manager";
//部门经理不同意
managerCheck(piId,curUser,false,"最近资金紧张);
pi = executionService.findProcessInstanceById(piId);
assertNull(pi);// 结束
HistoryProcessInstance hpi = getHistoryProcessInstanceById(piId);
// 流程结束状态是cancel , 取消
assertEquals(hpi.getState(), "cancel");

}*/

/**
* 李四 申请4000元,部门经理同意
*/
public void test2(){
String curUser="李四";
//创建流程实例
ProcessInstance pi= startLoanProcess(curUser);
String piId=pi.getId();
fillOutApplication(piId,curUser,4000);

curUser="manager";
managerCheck(piId,curUser,true,"同意");//部门经理同意
pi=executionService.findProcessInstanceById(piId);
assertNotNull(pi);//流程未结束

/**
* pi.findActiveExecutionIn("financeGet")的意思是
在给出的活动名中查询处于活动的可执行活动,假如没有则返回
null
*/
assertNotNull(pi.findActiveExecutionIn("financeGet"));//财务拨款处于活动状态


/*
* Set<String> activityNames=pi.findActiveActivityNames();
* for(Iterator it=activityNames.iterator();it.hasNext();){
System.out.println(it.next());
}
*可以看看执行活动名
*/

curUser="finance";
earmark(piId,curUser,"我拨款了 哈哈");
pi=executionService.findProcessInstanceById(piId);
assertNull(pi);//流程结束
HistoryProcessInstance
hpi=getHistoryProcessInstanceById(piId);

//流程结束状态是end,正常结束
assertEquals(hpi.getState(),"ended");
}


/**
* wang wu申请6000元,部门经理同意,总经理驳回
*/
public void test3(){
String curUser="wang wu";
//创建流程实例
ProcessInstance pi= startLoanProcess(curUser);
String piId=pi.getId();
fillOutApplication(piId,curUser,6000);

curUser="manager";
managerCheck(piId,curUser,true,"同意");//部门经理同意
pi=executionService.findProcessInstanceById(piId);
assertNotNull(pi);

//既然部门经理同意,而且money>5000,那么必须得有总经理审批
assertNotNull(pi.findActiveExecutionIn("ceoCheck"));
curUser="ceo";
ceoCheck(piId,curUser,false,"不同意");//总经理驳回
pi=executionService.findProcessInstanceById(piId);
assertNull(pi);//流程结束

HistoryProcessInstance
hpi=getHistoryProcessInstanceById(piId);
//流程结束状态是cancel,取消
assertEquals(hpi.getState(),"cancel");



}

/**
* afei 申请6000,部门经理同意,总经理同意
*/
public void test4(){
String curUser="afei";
//创建流程实例
ProcessInstance pi= startLoanProcess(curUser);
String piId=pi.getId();
fillOutApplication(piId,curUser,6000);

curUser="manager";
//部门经理同意
managerCheck(piId, curUser, true,"manager ok");
pi=executionService.findProcessInstanceById(piId);
assertNotNull(pi);
assertNotNull(pi.findActiveExecutionIn("ceoCheck"));//总经理审批处于活动状态

curUser="ceo";
ceoCheck(piId, curUser, true, "ceo ok");//总经理同意
pi=executionService.findProcessInstanceById(piId);
assertNotNull(pi);
assertNotNull(pi.findActiveExecutionIn("financeGet"));//财务拨款处于活动状态

curUser="finance";
earmark(piId, curUser, "拨款");
pi=executionService.findProcessInstanceById(piId);
assertNull(pi);//流程结束
HistoryProcessInstance hpi=getHistoryProcessInstanceById(piId);
//流程结束状态是ended,正常结束
assertEquals(hpi.getState(),"ended");


}
/*** 其他方法 ***/

/**
* 用户发起借款申请
*/
public ProcessInstance startLoanProcess(String user) {
Map<String, Object> valMap = new HashMap<String, Object>();
valMap.put("proposer", user);

//创建流程实例
return executionService.startProcessInstanceByKey("loan", valMap);
}

/**
* 填写借款说明
*
* @param piId
* @param user
* @param money
* @throws Exception
*/
public void fillOutApplication(String piId, String user, double money){
List<Task> tasks = taskService.findPersonalTasks(user);//获取任务列表
Task filloutTask = null;
for (Task task : tasks) {
if (task.getExecutionId().equals(piId)) {
filloutTask = task;//匹配任务
break;
}
}
System.out.println("piId: "+piId);
assertNotNull(filloutTask);//任务不为空
Map<String, Object> valMap = new HashMap<String, Object>();
valMap.put("money", money);//申请金额

//设置变量参数
executionService.setVariables(piId, valMap);

/*
* 删除这个任务,标记相关任务为完成,
* 假如任务在流程执行的上下文中被创建,
* 这个操作可能导致一个流程实例被触发
* (这是我自己翻译的)
* */
taskService.completeTask(filloutTask.getId());

}

/**
* 部门经理审批
*
* @param piId
* @param user
* @param isPass
* @param comment
* @throws Exception
*/
public void managerCheck(String piId, String user, boolean isPass,
String comment) {
List<Task> tasks = taskService.findPersonalTasks(user);
Task checkTask = null;
for (Task task : tasks) {
if (task.getExecutionId().equals(piId)) {
checkTask = task;
break;
}
}
assertNotNull(checkTask);
taskService.addTaskComment(checkTask.getId(), comment);
taskService.completeTask(checkTask.getId(), isPass ? "managerPass"
: "managerNotPass");

}

/**
* 总经理审批
*
* @param piId
* @param user
* @param isPass
* @param comment
* @throws Exception
*/
public void ceoCheck(String piId, String user, boolean isPass,
String comment){
List<Task> tasks = taskService.findPersonalTasks(user);
Task checkTask = null;
for (Task task : tasks) {
if (task.getExecutionId().equals(piId)) {
checkTask = task;
break;
}
}
assertNotNull(checkTask);
taskService.addTaskComment(checkTask.getId(), comment);
taskService.completeTask(checkTask.getId(), isPass ? "ceoPass"
: "ceoNotPass");
}

/**
* 财务拨款
*
* @param piId
* @param user
* @param comment
*/
public void earmark(String piId, String user, String comment) {
List<Task> tasks = taskService.findPersonalTasks(user);
Task earTask = null;
for (Task task : tasks) {
if (task.getExecutionId().equals(piId)) {
earTask = task;
break;
}
}
assertNotNull(earTask);
taskService.addTaskComment(earTask.getId(), comment);
String proposer = (String) executionService.getVariable(piId,
"proposer");

// 通知借款申请人
System.out.println("hello:" + proposer + ",财务已经给你拨款了,请查收");
taskService.completeTask(earTask.getId());


}
/**
* 得到流程实例历史
* @param piId
* @return
*/
public HistoryProcessInstance getHistoryProcessInstanceById(String piId) {
return historyService.createHistoryProcessInstanceQuery()
.processInstanceId(piId).uniqueResult();
}
}

再次说明,此测试类继承JbpmTestCase,很多service服务都已经初始化好了,直接run junit就ok了,它会把所有test开头的类当做测试用例执行下去,假如测试出有误,那么会给你报出来。这个例子主要是稍微熟悉一下service api,主要是对各种情况的判断或流转有一个清晰地认识。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值