一. 流程的批启动

使用场景:针对某个data中的数据,为每一条记录启动一个流程实例。
接口协议:输入data中多个记录的id,启动多个流程实例;返回这些流程实例的第一个环节的待办任务(注意:要求每个流程实例有且只有一条待办任务,后续才能执行批流转);
实现方式:有两种方式

1. 使用process组件来启动多个流程实例

1.0  设置process组件的属性:
autoClose、autoStart、autoSave、autoFilter的属性值设置为false
1.1    声明一个实例变量,用来存储流程启动后的待办任务

	var Model = function() {
		this.callParent();
		this.tasks = [];// 用于存在流程启动后关系的待办,将会在process的onStartCommit事件中赋值
	};

1.2   获取选中的数据(此案例用的dataTabels组件),分别启动流程

	Model.prototype.batchStartProcess1 = function() {
		var dataTables = this.comp("list");
		// 获取选择行的rowId
		var checkedIDs = dataTables.getCheckeds();
		if (checkedIDs.length == 0) {
			alert("请选择要启动的订单!");
			return;
		}
		// 根据业务数据启动多个流程实例,在启动的process的onStartCommit事件中收集待办任务的id
		biz.Request.beginBatch();// 启动批
		var p = this.comp("process1");
		for (var i = 0; i < checkedIDs.length; i++) {
			p.start(null, null, checkedIDs[i].getID(), null);// 批中启动流程
		}
		biz.Request.endBatch();// 结束批

		if (this.tasks.length == 0) {
			alert("启动流程失败!");
			return;
		}

	};

1.3  在process的onStartCommit事件中收集每个流程实例的待办任务

	Model.prototype.process1StartCommit = function(event) {
		this.tasks.push(event.task);
	};

1.4   到此为止,流程已经启动成功,this.tasks实例变量中存储了所有流程实例的待办任务;

2. 使用自定义的action来启动多个流程实例

2.0  后台自定义一个batchStartProcessAction,接收多个业务数据ID,启动多个流程实例,具体定义如下:

  <action name="batchStartProcessAction" global="false" procedure="batchStartProcessProcedure">
    <public type="String" name="process"/> 
    <public type="List" name="datas"/>
  </action> 

action对应的procedure定义如下:

  <procedure name="batchStartProcessProcedure" code-model="/demo/process/logic/code"
    code="Process.batchStartProcess"> 
    <parameter name="process" type="String"/> 
    <parameter name="datas" type="List"/> 
  </procedure> 

对应的java代码如下:

	public static List<String> batchStartProcess(String process, List<String> datas){
		List<String> result = new ArrayList<String>();
		for (String data : datas){
			List<Map<String, String>> items = ProcessUtils.startProcess(process, null, data, null);
			
			if (items.size() != 1){
				throw new RuntimeException("流程启动后必须有且只能有一个待办!");
			}
			
			String task = items.get(0).get("task");
			result.add(task);
		}
		
		return result;
	}

2.1 界面的js中调用batchStartProcessAction这个action,如下:

	Model.prototype.batchStartProcess2 = function(){
	    var me = this;
		var dataTables = me.comp("list");
		var dList = me.comp("mainData");
		// 获取选择行的rowId
		var checkedIDs = dataTables.getCheckeds();
		if (checkedIDs.length == 0) {
			alert("请选择要启动的订单!");
			return;
		}
                //调用action,并传参
		var param = new biz.Request.ActionParam();
		var dataParam = new biz.Request.ListParam();
		for (var i = 0; i < checkedIDs.length; i++) {
			dataParam.add(checkedIDs[i].getID());
		}
		param.setString("process", this.getContext().getCurrentProcess());
		param.setList("datas", dataParam);
		biz.Request.sendBizRequest({
			"context" : this.getContext(),
			"action" : "batchStartProcessAction",
			"parameters" : param,
			"callback" : function(callbackData) {
				if (callbackData.state) {
					me.tasks = callbackData.response;//收集启动成功后返回的每个流程实例的待办任务
					alert("批量启动成功")
				}
			}
		});
	};

2.2 到此为止,多个流程实例已经启动,所有的待办都存储在实例遍历this.tasks中.

二. 流程的批流转

使用场景:已知多个待办任务,对这些待办任务进行批量流转,要求这些待办的后续环节和执行者信息一致;
接口协议:输入多个流程实例的待办,执行流转操作。
基本思路:使用其中一条待办任务进行流转查询,弹出对话框供用户修改流转信息(主要是执行者信息);之后根据用户选择的执行者,批量流转所有的待办任务。
实现步骤:
1.  使用第个待办任务执行流转查询

	Model.prototype.batchAdvanceProcess = function(){
	    var p = this.comp("process1");
		// 使用其中的一条待办执行流转查询,并弹出流转对话框给用户修改,以得到control信息
		p.advanceQueryExt(this.tasks[0]);
	}

2.  用户可以看到流转对话框,修改其中的执行者信息
3.  在process组件的onBeforeAdvance事件中,获取编辑后的流转信息,取消后续操作,调用后台的自定义的批流转动作(batchAdvanceProcessAction)

	Model.prototype.process1BeforeAdvance = function(event) {
		event.cancel = true; // 取消后续操作

		// 所有的待办按得到的control中的执行人进行流转
		var params = new biz.Request.ActionParam();
		var tasksParam = new biz.Request.ListParam();

		// 批量启动后直接批量流转
		for (var i = 0; i < this.tasks.length; i++) {
			tasksParam.add(this.tasks[i]);
		}
		params.setList("tasks", tasksParam);
		var controlData = event.processControl.getData();
		var controlParam = new biz.Request.ObjectParam(controlData, "com.justep.system.process.ProcessControl");
		params.setObject("control", controlParam);
		biz.Request.sendBizRequest({
			"context" : this.getContext(),
			"action" : "batchAdvanceProcessAction",
			"directExecute" : true,
			"parameters" : params			
		});
		// 流程成功后关闭页面
		setTimeout(function() {
			me.close()
		}, 1);

	};

4. batchAdvanceProcessAction的定义如下:

  <action name="batchAdvanceProcessAction" global="false" procedure="batchAdvanceProcessProcedure">
    <public type="List" name="tasks"/>  
    <public type="Object" name="control"/> 
  </action> 

action对应的procedure定义如下:

  <procedure name="batchStartProcessProcedure" code-model="/demo/process/logic/code"
    code="Process.batchStartProcess"> 
    <parameter name="process" type="String"/> 
    <parameter name="datas" type="List"/> 
  </procedure> 

对应的java代码如下:

	/**
	 * 当前主要使用control中后续环节和通知的执行人信息 
	 */
	public static void batchAdvanceProcess(List<String> tasks, ProcessControl control){
		for (String task : tasks){
			ProcessControl cur = ProcessUtils.advanceProcessQuery(task);
			modifyFlowToExecutor(cur, control);
			modifyNoticeExecutor(cur, control);
			ProcessUtils.advanceProcess(task, cur);
		}
	}
	
	private static void modifyNoticeExecutor(ProcessControl cur, ProcessControl control){
		Iterator<ProcessControlItem> it = cur.getNotices().iterator();
		while (it.hasNext()){
			ProcessControlItem item = it.next();
			ProcessControlItem template = control.getNotice(item.getUnit());
			if (template == null){
				it.remove();
			}else{
				item.clearExecutors();
				item.addExecutors(template.getExecutors());
			}
		}
	}
	
	
	private static void modifyFlowToExecutor(ProcessControl cur, ProcessControl control){
		Iterator<ProcessControlItem> it = cur.getFlowTos().iterator();
		while (it.hasNext()){
			ProcessControlItem item = it.next();
			ProcessControlItem template = control.getFlowTo(item.getUnit());
			if (template == null){
				it.remove();
			}else{
				item.clearExecutors();
				item.addExecutors(template.getExecutors());
			}
		}
	}

在BeX5中默认的/BIZ/demo/process下就有批启动和批流转的BIZ相关的资源包括上面发的action以及java的定义
下面的附件是对应的UI2下的资源,可以直接把目录放到/UI2/demo/process/process下,然后添加菜单配置分配功能权限即可运行batch