报销流程发起页面主要包括两个动作,一个是填写报销单,另一个是提交报销申请。填写报销单,只是把报销信息填写好并持久化到数据库,此时,并没有开启报销流程,相当于报销信息暂存。提交报销申请,开启报销流程,并完成填写报销单任务,与此同时,将报销实体关主键的值赋给流程实例的businessId,并添加报销金额流程变量,变量名称为money,以提供给报销金额决策节点进行决策判断,此外,当报销金额小于等于1000时,需要另一个流程变量assignee,这个变量的值将作为财务二部审批节点的处理人。添加报销单如下图所示:

通过添加按钮可以添加新的报销申请单,添加后,报销申请为暂存状态,通过提交报销申请按钮可以开启报销申请流程,此时的报销单变为正在审批状态。页面上的DataGrid,展现的都是暂存的报销单,判断报销单是否为暂存可以通过判断业务数据的processInstanceId属性是否为null,为null说明是暂存状态,否则不是暂存状态。
1)暂存数据加载
暂存数据加载的后台代码如下:
加载暂存数据代码
@DataProvider
public Collection<Reimbursement> loadReimbursement(String id){
Session session=this.getSessionFactory().openSession();
try{
return Arrays.asList((Reimbursement) session.get(Reimbursement.class, id));
}finally{
session.flush();
session.close();
}
}
2)暂存业务表单
暂存业务表单后台代码
@DataResolver
public void saveReimbursements(Collection<Reimbursement> reimbursements){
Session session = this.getSessionFactory().openSession();
try{
for(Reimbursement reimbursement:reimbursements){
EntityState state=EntityUtils.getState(reimbursement);
if(EntityState.NEW.equals(state)){
reimbursement.setId(UUID.randomUUID().toString());
reimbursement.setCreateDate(new Date());
session.save(reimbursement);
}else if(EntityState.MODIFIED.equals(state)){
session.update(reimbursement);
}
}
}finally{
session.flush();
session.close();
}
}
3)提交报销申请
通过AjaxAction来实现,后台代码如下:
提交报销申请后台代码
@Expose
public void startFlow(String businessId){
Session session = this.getSessionFactory().openSession();
try{
Reimbursement r=(Reimbursement) session.load(Reimbursement.class,businessId);
StartProcessInfo startProcessInfo =new StartProcessInfo();
startProcessInfo.setBusinessId(businessId);
startProcessInfo.setPromoter(ContextHolder.getLoginUserName());
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", r.getMoney());
if(r.getMoney()<=1000){
variables.put("assignee", "user1");
}
startProcessInfo.setVariables(variables);
ProcessInstance pi=processService.startProcessByName("Reimbursement", startProcessInfo);
r.setProcessInstanceId(pi.getId());
r.setState(State.process);
}finally{
session.flush();
session.close();
}
}
提交报销申请成功后,为了页面上的暂存数据同步,需要主动刷新暂存报销单的数据,这里就是刷新暂存报销单对应的DataSet即可。