| | |
| | | package org.jeecg.modules.flowable.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * |
| | | **/ |
| | | @Service |
| | | @Slf4j |
| | |
| | | private IFlowThirdService iFlowThirdService; |
| | | @Autowired |
| | | FlowMyBusinessServiceImpl flowMyBusinessService; |
| | | |
| | | /** |
| | | * 完成任务 |
| | | * |
| | |
| | | //业务数据id |
| | | String dataId = taskVo.getDataId(); |
| | | //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 |
| | | FlowMyBusiness business = flowMyBusinessService.getByDataId(dataId); |
| | | FlowMyBusiness business = flowMyBusinessService.getFlowMyBusiness(taskVo.getInstanceId(), taskVo.getTaskId()); |
| | | //spring容器类名 |
| | | String serviceImplName = business.getServiceImplName(); |
| | | FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName); |
| | |
| | | // 业务层有设置变量,使用业务层的变量 |
| | | values = flowBeforeParamsValues; |
| | | } |
| | | FlowNextDto nextFlowNode = this.getNextFlowNode(task.getId(), values); |
| | | |
| | | //并行网关 多任务 |
| | | List<FlowNextDto> nextFlowNodeList = this.getNextFlowNode(task.getId(), values); |
| | | //下一个实例节点 |
| | | if (DelegationState.PENDING.equals(task.getDelegationState())) { |
| | | taskService.resolveTask(taskVo.getTaskId(), values); |
| | |
| | | taskService.complete(taskVo.getTaskId(), values); |
| | | } |
| | | List<Task> task2List = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().list(); |
| | | Task task2 = null; |
| | | if (CollUtil.isNotEmpty(task2List)){ |
| | | task2 = task2List.get(0); |
| | | } |
| | | |
| | | // 下个节点候选人 |
| | | List<String> beforeParamsCandidateUsernames = Lists.newArrayList(); |
| | | if(task2!=null){ |
| | | beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(),taskVo.getValues()); |
| | | } |
| | | List<String> candidateUsers = taskVo.getCandidateUsers(); |
| | | if (CollUtil.isNotEmpty(candidateUsers)){ |
| | | // 前端传入候选人 覆盖 |
| | | beforeParamsCandidateUsernames = candidateUsers; |
| | | } |
| | | String doneUsers = business.getDoneUsers(); |
| | | // 处理过流程的人 |
| | | JSONArray doneUserList = new JSONArray(); |
| | |
| | | doneUserList.add(loginUser.getUsername()); |
| | | } |
| | | |
| | | if (task2!=null && task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())){ |
| | | if (CollectionUtils.isEmpty(nextFlowNodeList)) { |
| | | // **没有下一个节点,流程已经结束了 |
| | | business |
| | | .setDoneUsers(doneUserList.toJSONString()) |
| | | .setTodoUsers("") |
| | | .setTaskId("") |
| | | .setTaskNameId("") |
| | | .setTaskName("") |
| | | ; |
| | | flowMyBusinessService.updateById(business); |
| | | } |
| | | else if (nextFlowNodeList.size() == 1) { |
| | | FlowNextDto nextFlowNode = nextFlowNodeList.get(0); |
| | | UserTask nextTask = nextFlowNode.getUserTask(); |
| | | Task task2 = null; |
| | | Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); |
| | | task2 = first.orElseGet(() -> task2List.get(0)); |
| | | if (task2 != null) { |
| | | // 下个节点候选人 |
| | | List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), taskVo.getValues()); |
| | | List<String> candidateUsers = taskVo.getCandidateUsers(); |
| | | if (CollUtil.isNotEmpty(candidateUsers)) { |
| | | // 前端传入候选人 覆盖 |
| | | beforeParamsCandidateUsernames = candidateUsers; |
| | | } |
| | | if (task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())) { |
| | | //多实例 会签 TODO |
| | | // * 当前节点是会签节点,没有走完 |
| | | business.setTaskId(task2.getId()) |
| | | // .setActStatus(ActStatus.doing) |
| | |
| | | String todoUsersStr = business.getTodoUsers(); |
| | | JSONArray todosArr = JSON.parseArray(todoUsersStr); |
| | | // 删除后重写 |
| | | for (Task task2One : task2List) { |
| | | for (Object oldUser : todosArr) { |
| | | taskService.deleteCandidateUser(task2One.getId(),oldUser.toString()); |
| | | } |
| | | taskService.deleteCandidateUser(task2.getId(), oldUser.toString()); |
| | | } |
| | | // 重写 |
| | | if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){ |
| | | beforeParamsCandidateUsernames.remove(loginUser.getUsername()); |
| | | // 业务层有指定候选人,覆盖 |
| | | for (Task task2One : task2List) { |
| | | for (String newUser : beforeParamsCandidateUsernames) { |
| | | taskService.addCandidateUser(task2One.getId(),newUser); |
| | | } |
| | | taskService.addCandidateUser(task2.getId(), newUser); |
| | | } |
| | | business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); |
| | | } else { |
| | | todosArr.remove(loginUser.getUsername()); |
| | | for (Task task2One : task2List) { |
| | | for (Object oldUser : todosArr) { |
| | | taskService.addCandidateUser(task2One.getId(),oldUser.toString()); |
| | | } |
| | | taskService.addCandidateUser(task2.getId(), oldUser.toString()); |
| | | } |
| | | business.setTodoUsers(todosArr.toJSONString()); |
| | | } |
| | | |
| | | |
| | | } else { |
| | | // * 下一节点是会签节点 或 普通用户节点,逻辑一致 |
| | | if (nextFlowNode!=null){ |
| | | //**有下一个节点 |
| | | UserTask nextTask = nextFlowNode.getUserTask(); |
| | | //能够处理下个节点的候选人 |
| | | List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); |
| | | List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList()); |
| | |
| | | .setTodoUsers(JSON.toJSONString(collect_username)) |
| | | ; |
| | | // 删除后重写 |
| | | for (Task task2One : task2List) { |
| | | for (String oldUser : collect_username) { |
| | | taskService.deleteCandidateUser(task2One.getId(),oldUser); |
| | | taskService.deleteCandidateUser(task2.getId(), oldUser); |
| | | } |
| | | } |
| | | if (CollUtil.isEmpty(candidateUsers)&&CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){ |
| | | if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { |
| | | // 前端没有传入候选人 && 业务层有指定候选人,覆盖 |
| | | for (Task task2One : task2List) { |
| | | for (String newUser : beforeParamsCandidateUsernames) { |
| | | taskService.addCandidateUser(task2One.getId(),newUser); |
| | | } |
| | | taskService.addCandidateUser(task2.getId(), newUser); |
| | | } |
| | | business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); |
| | | } else { |
| | | for (Task task2One : task2List) { |
| | | for (String oldUser : collect_username) { |
| | | taskService.addCandidateUser(task2One.getId(),oldUser); |
| | | taskService.addCandidateUser(task2.getId(), oldUser); |
| | | } |
| | | business.setTodoUsers(JSON.toJSONString(collect_username)); |
| | | } |
| | | } |
| | | } |
| | | flowMyBusinessService.updateById(business); |
| | | } |
| | | else { |
| | | for(FlowNextDto nextFlowNode : nextFlowNodeList) { |
| | | //**有下一个节点 |
| | | UserTask nextTask = nextFlowNode.getUserTask(); |
| | | Task task2 = null; |
| | | Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); |
| | | if (first.isPresent()) { |
| | | task2 = first.get(); |
| | | } |
| | | if (task2 != null) { |
| | | //新的业务流程节点 |
| | | FlowMyBusiness newBusiness = BeanUtil.copyProperties(business, FlowMyBusiness.class, "id"); |
| | | // 下个节点候选人 |
| | | List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), taskVo.getValues()); |
| | | List<String> candidateUsers = taskVo.getCandidateUsers(); |
| | | if (CollUtil.isNotEmpty(candidateUsers)) { |
| | | // 前端传入候选人 覆盖 |
| | | beforeParamsCandidateUsernames = candidateUsers; |
| | | } |
| | | if (task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())) { |
| | | //多实例 会签 TODO |
| | | // * 当前节点是会签节点,没有走完 |
| | | newBusiness.setTaskId(task2.getId()) |
| | | // .setActStatus(ActStatus.doing) |
| | | .setDoneUsers(doneUserList.toJSONString()) |
| | | ; |
| | | String todoUsersStr = business.getTodoUsers(); |
| | | JSONArray todosArr = JSON.parseArray(todoUsersStr); |
| | | // 删除后重写 |
| | | for (Object oldUser : todosArr) { |
| | | taskService.deleteCandidateUser(task2.getId(), oldUser.toString()); |
| | | } |
| | | // 重写 |
| | | if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { |
| | | beforeParamsCandidateUsernames.remove(loginUser.getUsername()); |
| | | // 业务层有指定候选人,覆盖 |
| | | for (String newUser : beforeParamsCandidateUsernames) { |
| | | taskService.addCandidateUser(task2.getId(), newUser); |
| | | } |
| | | newBusiness.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); |
| | | } else { |
| | | todosArr.remove(loginUser.getUsername()); |
| | | for (Object oldUser : todosArr) { |
| | | taskService.addCandidateUser(task2.getId(), oldUser.toString()); |
| | | } |
| | | newBusiness.setTodoUsers(todosArr.toJSONString()); |
| | | } |
| | | |
| | | } else { |
| | | // **没有下一个节点,流程已经结束了 |
| | | business |
| | | .setDoneUsers(doneUserList.toJSONString()) |
| | | .setTodoUsers("") |
| | | .setTaskId("") |
| | | .setTaskNameId("") |
| | | .setTaskName("") |
| | | ; |
| | | //能够处理下个节点的候选人 |
| | | List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); |
| | | List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList()); |
| | | if (CollUtil.isNotEmpty(candidateUsers)) { |
| | | // 前端传入候选人 |
| | | collect_username = candidateUsers; |
| | | } |
| | | newBusiness |
| | | .setTaskId(task2.getId()) |
| | | // .setActStatus(ActStatus.doing) |
| | | .setTaskNameId(nextTask.getId()) |
| | | .setTaskName(nextTask.getName()) |
| | | .setPriority(nextTask.getPriority()) |
| | | .setDoneUsers(doneUserList.toJSONString()) |
| | | .setTodoUsers(JSON.toJSONString(collect_username)) |
| | | ; |
| | | // 删除后重写 |
| | | for (String oldUser : collect_username) { |
| | | taskService.deleteCandidateUser(task2.getId(), oldUser); |
| | | } |
| | | if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { |
| | | // 前端没有传入候选人 && 业务层有指定候选人,覆盖 |
| | | for (String newUser : beforeParamsCandidateUsernames) { |
| | | taskService.addCandidateUser(task2.getId(), newUser); |
| | | } |
| | | newBusiness.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); |
| | | } else { |
| | | for (String oldUser : collect_username) { |
| | | taskService.addCandidateUser(task2.getId(), oldUser); |
| | | } |
| | | newBusiness.setTodoUsers(JSON.toJSONString(collect_username)); |
| | | } |
| | | } |
| | | flowMyBusinessService.save(newBusiness); |
| | | } |
| | | flowMyBusinessService.updateById(business); |
| | | } |
| | | //删除原有的业务数据 |
| | | flowMyBusinessService.removeById(business.getId()); |
| | | } |
| | | |
| | | flowMyBusinessService.updateById(business); |
| | | // 流程处理完后,进行回调业务层 |
| | | business.setValues(values); |
| | | if (flowCallBackService!=null)flowCallBackService.afterFlowHandle(business); |
| | | if (flowCallBackService != null) { |
| | | flowCallBackService.afterFlowHandle(business); |
| | | } |
| | | return Result.OK(); |
| | | } |
| | | |
| | |
| | | flowTaskVo.setTaskId(business.getTaskId()); |
| | | this.taskReject(flowTaskVo); |
| | | } |
| | | |
| | | /** |
| | | * 驳回任务 |
| | | * |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void taskReturnByDataId(FlowTaskVo flowTaskVo){ |
| | | //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 |
| | |
| | | flowTaskVo.setTaskId(business.getTaskId()); |
| | | taskReturn(flowTaskVo); |
| | | } |
| | | |
| | | /** |
| | | * 退回任务 |
| | | * |
| | |
| | | |
| | | /** |
| | | * 结束流程 |
| | | * |
| | | * @param processInstanceId 流程实例 ID |
| | | * @param deleteReason 定义删除原因 |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 判断多个任务是否处于同一流程节点 |
| | | * |
| | | * @param taskIds 逗号分隔的任务ID字符串 |
| | | * @return 统一结果封装 |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 顺序抽取节点 |
| | | * |
| | | * @param orderKeys 容器 |
| | | * @param sourceKey 源 |
| | | * @param flowElements 所有的节点对象 |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Result getNextFlowNode(FlowTaskVo flowTaskVo) { |
| | | public Result<List<FlowNextDto>> getNextFlowNode(FlowTaskVo flowTaskVo) { |
| | | // todo 似乎逻辑未写完,待检查 |
| | | FlowNextDto flowNextDto = this.getNextFlowNode(flowTaskVo.getTaskId(), flowTaskVo.getValues()); |
| | | if (flowNextDto==null) { |
| | | List<FlowNextDto> nextDtoList = this.getNextFlowNode(flowTaskVo.getTaskId(), flowTaskVo.getValues()); |
| | | if (CollectionUtils.isEmpty(nextDtoList)) { |
| | | return Result.OK("流程已完结", null); |
| | | } |
| | | return Result.OK(flowNextDto); |
| | | return Result.OK(nextDtoList); |
| | | } |
| | | |
| | | @Override |
| | | public boolean checkParallelCompletion(String currentTaskId) { |
| | | //获取当前任务 |
| | | Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult(); |
| | | if (currentTask == null) { |
| | | return false; |
| | | } |
| | | //获取当前执行 |
| | | Execution execution = runtimeService.createExecutionQuery().executionId(currentTask.getExecutionId()).singleResult(); |
| | | if (execution == null) { |
| | | return false; |
| | | } |
| | | String parentId = execution.getParentId(); |
| | | if (StringUtils.isBlank(parentId)) { |
| | | //没有父节点 代表没有并行任务 |
| | | return true; |
| | | } |
| | | // 获取所有兄弟执行 |
| | | List<Execution> siblingExecutions = runtimeService.createExecutionQuery() |
| | | .parentId(parentId) |
| | | .list(); |
| | | |
| | | for (Execution siblingExecution : siblingExecutions) { |
| | | if (!siblingExecution.getId().equals(execution.getId())) { |
| | | //非自身的兄弟节点 |
| | | long count = runtimeService.createActivityInstanceQuery().executionId(siblingExecution.getId()).unfinished().count(); |
| | | if (count > 0) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 获取下一个节点信息,流程定义上的节点信息 |
| | | * |
| | | * @param taskId 当前节点id |
| | | * @param values 流程变量 |
| | | * @return 如果返回null,表示没有下一个节点,流程结束 |
| | | */ |
| | | public FlowNextDto getNextFlowNode(String taskId, Map<String, Object> values) { |
| | | public List<FlowNextDto> getNextFlowNode(String taskId, Map<String, Object> values) { |
| | | //当前节点 |
| | | Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); |
| | | if (Objects.nonNull(task)) { |
| | | // 下个任务节点 |
| | | List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values); |
| | | if (CollectionUtils.isNotEmpty(nextUserTask)) { |
| | | FlowNextDto flowNextDto = new FlowNextDto(); |
| | | List<FlowNextDto> nextDtoList = Lists.newArrayList(); |
| | | FlowNextDto flowNextDto; |
| | | for (UserTask userTask : nextUserTask) { |
| | | flowNextDto = new FlowNextDto(); |
| | | flowNextDto.setUserTask(userTask); |
| | | //待办人员 |
| | | List<SysUser> sysUserFromTask = this.getSysUserFromTask(userTask); |
| | | flowNextDto.setUserList(sysUserFromTask); |
| | | |
| | | MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics(); |
| | | if (Objects.nonNull(multiInstance)) { |
| | | // 会签 多实例 |
| | | String collectionString = multiInstance.getInputDataItem(); |
| | | Object colObj = values.get(collectionString); |
| | | List<String> userNameList = null; |
| | | if(colObj!=null){ |
| | | userNameList = (List) colObj; |
| | | } |
| | | if (CollUtil.isNotEmpty(userNameList)){ |
| | | //多任务并行 |
| | | Object colObj = values.get(userTask.getId()); |
| | | if (Objects.nonNull(colObj)) { |
| | | List<String> userNameList = (List) colObj; |
| | | // 待办人员从变量中获取 否则就是节点中配置的用户 sysUserFromTask |
| | | List<SysUser> userList = Lists.newArrayList(); |
| | | for (String username : userNameList) { |
| | |
| | | } else { |
| | | // 变量中没有传入,写入节点中配置的用户 |
| | | List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList()); |
| | | values.put(collectionString,collect_username); |
| | | values.put(userTask.getId(), collect_username); |
| | | } |
| | | } else { |
| | | // todo 读取自定义节点属性做些啥? |
| | | //String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); |
| | | String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE); |
| | | nextDtoList.add(flowNextDto); |
| | | } |
| | | } |
| | | return flowNextDto; |
| | | return nextDtoList; |
| | | } |
| | | } |
| | | return null; |
| | | |
| | | } |
| | | |
| | | public List<SysUser> getSysUserFromTask(UserTask userTask) { |
| | | String assignee = userTask.getAssignee(); |
| | | if (StrUtil.isNotBlank(assignee)){ |
| | |
| | | } |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | /** |
| | | * 流程完成时间处理 |
| | | * |