假设定义了流程变量“报销总金额”,请问该变量的值是怎么附上去的?
3 回复
首先,fireflow流程变量可以是简单类型,如String, int ,boolean等;也可以是任何java 对象,比如 用户User,合同Contract等等。可以在任何时候直接使用WorkflowStatement.setVariableValue(Scope scope,String name,Object value)设置流程变量(scope值一般是processInstance),这里的第三个参数"value",就是你的流程变量的值或者流程变量对象。
但是用Java对象直接作为流程变量的值存在一个问题,这个对象一般代表一个业务实体,其属性是不断变化的,比如合同中的金额,审批意见等。如果直接将java对象存储在流程变量表里面,则会造成数据不一致性。Fire workflow 通过BusinessObjectWrapper接口解决这个问题;使用方法是:
1、在你的业务中,自己实现一下这个接口,
2、设置流程变量时,首先将业务对象(比如contract)用这个"wrapper"包装一下,再塞给流程系统。那么流程系统保存的就不是contract本身了,而是一个“wrapper”,使用业务对象的时候,直接用WorkflowStatement.getVariableValue(scope,name)即可得到contract的值,且contract的属性随着业务变化而变化。
3、示例代码如下
public void run() {
//启动流程
org.fireflow.engine.modules.ousystem.User currentUser = WorkflowUtil.getCurrentWorkflowUser();
WorkflowSession fireSession = WorkflowSessionFactory.createWorkflowSession(fireflowRuntimeContext, currentUser);
WorkflowStatement statement = fireSession.createWorkflowStatement();
if (CommonStatus.STATUS_ACCEPT.equals(costOrder.getStatus())){//已经审批通过,进入财务流程的订单,撤销时需要走流程
OrderCancelApply newOca = dao().insert(obj);
result.put("CostCancelApply",newOca);
Map<String,Object> vars = new HashMap<String,Object>();
BusinessObjectWrappImpl wrapper = new BusinessObjectWrappImpl();
wrapper.setBizId(obj.getCode());
wrapper.setBizClzName(OrderCancelApply.class.getName());
vars.put("orderCancelApply", wrapper);
User applicants = dao().fetch(User.class, obj.getApplicantUid());
if (applicants!=null){//将申请人的群组号作为流程变量保存
vars.put(Constants.VAR_NAME_APPLICANT_GROUP_CODE, applicants.getGroupCode());
}
User currentOperator = Utils.getCurrentUser();
Order order = dao().fetch(Order.class,newOca.getCostOkCrmCode());
if(order != null){
if(order.getSalesId().equals(currentOperator.getLoginName())){
vars.put(Constants.VAR_NAME_IS_SALES, "1");
}
}
try {
ProcessInstance processInstance = statement.startProcess(
"Cost_Cancel_Apply", "Cost_Cancel_Apply.main",obj.getCode(), vars);
} catch (InvalidModelException e) {
throw new RuntimeException("流程定义错误",e);
} catch (WorkflowProcessNotFoundException e) {
throw new RuntimeException("特定的流程未找到",e);
} catch (InvalidOperationException e) {
throw new RuntimeException("非法的流程操作",e);
}
4、BusinessObjectWrapper实现类的示例代码如下
package com.okideaad.erp.workflow.ext;
import org.fireflow.engine.context.RuntimeContext;
import org.fireflow.engine.entity.runtime.ProcessInstance;
import org.fireflow.engine.modules.persistence.PersistenceService;
import org.fireflow.engine.modules.persistence.nutz.PersistenceServiceNutzImpl;
import org.fireflow.engine.modules.script.BusinessObjectWrapper;
public class BusinessObjectWrappImpl implements BusinessObjectWrapper {
String bizClzName = null;
String bizId = null;
public String getBizClzName() {
return bizClzName;
}
public void setBizClzName(String bizClzName) {
this.bizClzName = bizClzName;
}
public String getBizId() {
return bizId;
}
public void setBizId(String bizId) {
this.bizId = bizId;
}
@Override
public Object resolveBusinessObject(RuntimeContext arg0,
ProcessInstance arg1, PersistenceService arg2) {
try{
String billCode = bizId;
if (billCode==null || billCode.trim().equals("")){
billCode = arg1.getBizId();
}
Class clz = Class.forName(bizClzName);
PersistenceServiceNutzImpl p = (PersistenceServiceNutzImpl)arg2;
Object obj = p.getDao().fetch(clz, billCode);
return obj;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
至于,什么时候设置流程变量,一般情况下有如下几种时机,
1、流程启动前,如上面的第一段代码
2、一个环节结束时,比如录入了金额,提交审批时,将金额设置到流程变量。
3、但是,如果你用BusinessObjectWrapper包装一个业务对象做位流程变量的话,那么只要在流程启动时设置该流程变量即可,业务过程中如果业务对象变量,那么流程系统自动会获得最新的数据,不需要每次业务对象变化后重新设置一下流程变量。
最后,Fire workflow使用xstream来将流程变量序列化到表中
添加回复
请先登陆