NutzCN Logo
问答 假设定义了流程变量“报销总金额”,请问该变量的值是怎么附上去的?
发布于 137天前 作者 qq_f3f924f5 136 次浏览 复制 上一个帖子 下一个帖子
标签: fireflow

假设定义了流程变量“报销总金额”,请问该变量的值是怎么附上去的?

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来将流程变量序列化到表中

使用BusinessObjectWrapper来封装业务对象时,流程系统如何知道业务系统对象发生了变化?

因为流程变量表保存BusinessObjectWrapper时,根本就没有保存具体的业务对象字段,仅仅是保存了业务对象的主键信息,所以流程每次拿业务对象都是最新的。

你看下上述代码就知道了。

添加回复
请先登陆
回到顶部