Flowable6.4 – 会签实现方案



Flowable6.4 – 会签实现方案

之前介绍过多实例，但只是理论上如何实现，本文将介绍一种能够实际应用的会签方案。

前面几篇文章描述过如何为一个UserTask节点增加扩展属性，多实例UserTask节点也可以按照之前的方法增加扩展属性。

但是分配办理人时，与普通的UserTask节点稍有不同，不能直接从UserTask节点的扩展属性内获取办理人信息。

如何获得办理人？

首先， 声明一个辅助处理器，用来帮助获得UserTask节点的办理人和检查是否结束多实例节点的办理。主要代码如下：

/**

 * 获得当前节点的处理者列表

 * @param execution 当前执行实例

 * @return 处理者列表

 */

public List<DealerInfo> getList(DelegateExecution execution) {

 FlowElement flowElement = execution.getCurrentFlowElement();

 UserTask userTask = (UserTask) flowElement;

 UserTaskExtension userTaskExtension = FlowUtil.getUserTaskExtension(userTask);

 //DealerInfo是一个实体，用来表示办理人的具体信息

 //从扩展属性内读取UserTask的办理人信息

 //返回一个集合，该集合的数量影响了UserTask多实例的数量

 return userTaskExtension.getDealers();

}

/**

 * 获取会签是否结束

 * @param execution 当前执行实例

 * @return 是否结束

 */

public boolean getComplete(DelegateExecution execution) {

 Integer nrOfCompletedInstances = (Integer) execution.getVariable("nrOfCompletedInstances");

 Integer nrOfInstances = (Integer) execution.getVariable("nrOfInstances");

 int agreeCount = 0, rejectCount = 0, abstainCount = 0;

 Map<String, Object> vars = execution.getVariables();

 for (String key : vars.keySet()) {

 //会签投票以SIGN_VOTE+TaskId标识

 //获得会签投票的统计结果

 if (key.contains(FlowConst.SIGN_VOTE) && !key.equals(FlowConst.SIGN_VOTE_RESULT)) {

 Integer value = (Integer) vars.get(key);

 //统计同意、驳回、弃权票数

 //省略代码若干......

 }

 }

 //以下为一段简单的规则，可以按情况实现自己的会签规则

 if (!nrOfCompletedInstances.equals(nrOfInstances)) {

 //必须等所有的办理人都投票

 return false;

 } else {

 //会签全部完成时,使用默认规则结束

 if (rejectCount > 0) {

 //有反对票，则最终的会签结果为不通过

 //移除SIGN_VOTE+TaskId为标识的参数

 removeSignVars(execution);

 //增加会签结果参数，以便之后流转使用

 execution.setVariable(FlowConst.SIGN_VOTE_RESULT, false);

 //会签结束

 return true;

 } else {

 //没有反对票时，则最终的会签结果为通过

 removeSignVars(execution);

 execution.setVariable(FlowConst.SIGN_VOTE_RESULT, true);

 return true;

 }

 }

}

然后， 对流程图内的UserTask节点进行设置：

上图中的Collection设置为：${mutiInstanceHandler.getList(execution)}。

上图中的Completion设置为：${mutiInstanceHandler.getComplete(execution)}。

一定要注意的是：Element Var，这个参数将决定多实例中每一个UserTask的办理人。

接下来，设置办理人，之前的教程可以参考《Flowable6.4 - 分派办理人》，主要的代码如下：

/**

 * 分配办理人员

 */

@Override

protected void handleAssignments(TaskService taskService, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {

 if (null != this.userTaskExtension) {

 //由扩展属性读取办理人规则

 List<DealerInfo> dealerInfos = getDealerInfo();

 if (null == dealerInfos || dealerInfos.size() == 0) {

 throw new RuntimeException("处理者信息不存在");

 }

 if (hasMultiInstanceCharacteristics())

 //多实例节点分配处理者

 //获得传参，流程图中的Element Var

 Object objDealer = execution.getVariable("dealerInfo");

 if (objDealer instanceof DealUserInfo) {

 DealUserInfo userInfo = (DealUserInfo) objDealer;

 assignee = userInfo.getId();

 } else if (objDealer instanceof DealRoleInfo) {

 DealRoleInfo roleInfo = (DealRoleInfo) objDealer;

 task.addGroupIdentityLink(roleInfo.getId(), "role");

 }

 }

 }

 super.handleAssignments(taskService, assignee, owner, candidateUsers, candidateGroups, task, expressionManager, execution);

}

最后， 在Complete流程的时候，按照调用方传回的信息，设置投票的值即可：

//设置会签投票结果

variables.put(FlowConst.SIGN_VOTE + "_" + taskId, signVoteType.getCode());

如何使用会签结果？

在需要判断会签结果的Sequence Flow Condition中直接设置：

