根据网友反馈开源项目

    有自定义业务表单并行审批的bug需要修复,主要是后端自定义业务审批逻辑上的问题

  自定义表的完成任务completeForDataID里的问题

主要是下面代码部分

if (nextFlowNode!=null){
            //**有下一个节点
            UserTask nextUserTask = nextFlowNode.getUserTask();
            //能够处理下个节点的候选人
            List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList();
            List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList());
            //collect_username转换成realname
            List<String> newusername = new ArrayList<String>();
            // 流程发起人
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(taskVo.getInstanceId()).singleResult();
            String startUserId = processInstance.getStartUserId();
            if(taskVo.getValues() !=null && taskVo.getValues().containsKey("approval")) {//前端传回的变量值
            	SysUser sysUser = iFlowThirdService.getUserByUsername(taskVo.getValues().get("approval").toString());
            	newusername.add(sysUser.getRealname());
            }
            else {
            	for (String oldUser : collect_username) {
                  if(StrUtil.equals(oldUser,"${INITIATOR}")) {
                	  SysUser sysUser = iFlowThirdService.getUserByUsername(startUserId);
                      newusername.add(sysUser.getRealname());
                  }
                  else {
                	 SysUser sysUser = iFlowThirdService.getUserByUsername(oldUser);
                     newusername.add(sysUser.getRealname());
                  }
                }
            }
            //下一个实例节点
            List<Task> listtask = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().list();
            Task nexttask = null;
            if(listtask.size()==1) {
            	nexttask = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().singleResult();
            }
            else {
            	nexttask = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().list().get(0);
            }
            
            // 下个节点候选人,目前没有实现这功能,返回null
            List<String> beforeParamsCandidateUsernames = Lists.newArrayList();
            if(nexttask!=null){
                beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(nexttask.getTaskDefinitionKey(),taskVo.getValues());
            }
            business.setActStatus(ActStatus.doing)
                    .setTaskId(nexttask.getId())
                    .setTaskNameId(nextUserTask.getId())
                    .setTaskName(nextUserTask.getName())
                    .setPriority(nextUserTask.getPriority())
                    .setDoneUsers(doneUserList.toJSONString())
                    .setTodoUsers(JSON.toJSONString(newusername))
                ;
            // 删除后重写
            for (String oldUser : collect_username) {
                taskService.deleteCandidateUser(nexttask.getId(),oldUser);
            }
            if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){
                // 业务层有指定候选人,覆盖
                for (String newUser : beforeParamsCandidateUsernames) {
                    taskService.addCandidateUser(nexttask.getId(),newUser);
                }
                business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
            } else {
                for (String oldUser : collect_username) {
                	if(StrUtil.equals(oldUser,"${INITIATOR}")) {
                		taskService.addCandidateUser(nexttask.getId(),startUserId);
                	}
                	else {
                		taskService.addCandidateUser(nexttask.getId(),oldUser);
                	}
                    
                }
            }

1、其中多个并行任务的时候对nexttask的任务进行处理,避免报错

2、增加对发起人设置的支持,原先在自定义业务这块漏了这个