cuikaidong
2025-05-27 504333e56f249d16e71e8ac2a435cf2212040c23
lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/service/impl/FlowTaskServiceImpl.java
@@ -1,5 +1,6 @@
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;
@@ -68,6 +69,7 @@
import java.util.stream.Collectors;
/**
 *
 **/
@Service
@Slf4j
@@ -78,6 +80,7 @@
    private IFlowThirdService iFlowThirdService;
    @Autowired
    FlowMyBusinessServiceImpl flowMyBusinessService;
    /**
     * 完成任务
     *
@@ -87,23 +90,23 @@
    @Override
    public Result complete(FlowTaskVo taskVo) {
        Task task = taskService.createTaskQuery().taskId(taskVo.getTaskId()).singleResult();
        if (Objects.isNull(task)){
        if (Objects.isNull(task)) {
            return Result.error("任务不存在");
        }
        if(StringUtils.isNotEmpty(taskVo.getComment())){
        if (StringUtils.isNotEmpty(taskVo.getComment())) {
            task.setDescription(taskVo.getComment());
            taskService.saveTask(task);
        }
        SysUser loginUser = iFlowThirdService.getLoginUser();
        //判断用户是否有权限
        if (!task.getAssignee().equals(loginUser.getUsername())){
        if (!task.getAssignee().equals(loginUser.getUsername())) {
            return Result.error("当前用户无权限");
        }
        if (DelegationState.PENDING.equals(task.getDelegationState())) {
            taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
            //taskService.resolveTask(taskVo.getTaskId(), taskVo.getValues());
        } else {
            System.out.println("taskVo.getTaskId()--->taskVo.getInstanceId()--->FlowComment.NORMAL.getType()--->taskVo.getComment()"+taskVo.getTaskId() + "---" + taskVo.getInstanceId() + "---" + FlowComment.NORMAL.getType() + "---"+taskVo.getComment() );
            System.out.println("taskVo.getTaskId()--->taskVo.getInstanceId()--->FlowComment.NORMAL.getType()--->taskVo.getComment()" + taskVo.getTaskId() + "---" + taskVo.getInstanceId() + "---" + FlowComment.NORMAL.getType() + "---" + taskVo.getComment());
            taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
            taskService.setAssignee(taskVo.getTaskId(), loginUser.getUsername());
        }
@@ -111,20 +114,22 @@
        //业务数据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);
        // 流程变量
        Map<String, Object> flowBeforeParamsValues = flowCallBackService.flowValuesOfTask(business.getTaskNameId(),taskVo.getValues());
        Map<String, Object> flowBeforeParamsValues = flowCallBackService.flowValuesOfTask(business.getTaskNameId(), taskVo.getValues());
        //设置数据
        Map<String, Object> values = taskVo.getValues();
        if (MapUtil.isNotEmpty(flowBeforeParamsValues)){
        //    业务层有设置变量,使用业务层的变量
        if (MapUtil.isNotEmpty(flowBeforeParamsValues)) {
            //    业务层有设置变量,使用业务层的变量
            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);
@@ -132,140 +137,218 @@
            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();
        if (StrUtil.isNotBlank(doneUsers)){
        if (StrUtil.isNotBlank(doneUsers)) {
            doneUserList = JSON.parseArray(doneUsers);
        }
        if (!doneUserList.contains(loginUser.getUsername())){
        if (!doneUserList.contains(loginUser.getUsername())) {
            doneUserList.add(loginUser.getUsername());
        }
        if (task2!=null && task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())){
        //    * 当前节点是会签节点,没有走完
            business.setTaskId(task2.getId())
//                    .setActStatus(ActStatus.doing)
        if (CollectionUtils.isEmpty(nextFlowNodeList)) {
            //    **没有下一个节点,流程已经结束了
            business
                    .setDoneUsers(doneUserList.toJSONString())
                    .setTodoUsers("")
                    .setTaskId("")
                    .setTaskNameId("")
                    .setTaskName("")
            ;
            String todoUsersStr = business.getTodoUsers();
            JSONArray todosArr = JSON.parseArray(todoUsersStr);
            // 删除后重写
            for (Task task2One : task2List) {
                for (Object oldUser : todosArr) {
                    taskService.deleteCandidateUser(task2One.getId(),oldUser.toString());
            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 (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){
                beforeParamsCandidateUsernames.remove(loginUser.getUsername());
                // 业务层有指定候选人,覆盖
                for (Task task2One : task2List) {
                    for (String newUser : beforeParamsCandidateUsernames) {
                        taskService.addCandidateUser(task2One.getId(),newUser);
                    }
                }
                business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
            } else {
                todosArr.remove(loginUser.getUsername());
                for (Task task2One : task2List) {
                if (task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())) {
                    //多实例 会签 TODO
                    //    * 当前节点是会签节点,没有走完
                    business.setTaskId(task2.getId())
//                    .setActStatus(ActStatus.doing)
                            .setDoneUsers(doneUserList.toJSONString())
                    ;
                    String todoUsersStr = business.getTodoUsers();
                    JSONArray todosArr = JSON.parseArray(todoUsersStr);
                    // 删除后重写
                    for (Object oldUser : todosArr) {
                        taskService.addCandidateUser(task2One.getId(),oldUser.toString());
                        taskService.deleteCandidateUser(task2.getId(), oldUser.toString());
                    }
                    // 重写
                    if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) {
                        beforeParamsCandidateUsernames.remove(loginUser.getUsername());
                        // 业务层有指定候选人,覆盖
                        for (String newUser : beforeParamsCandidateUsernames) {
                            taskService.addCandidateUser(task2.getId(), newUser);
                        }
                        business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
                    } else {
                        todosArr.remove(loginUser.getUsername());
                        for (Object oldUser : todosArr) {
                            taskService.addCandidateUser(task2.getId(), oldUser.toString());
                        }
                        business.setTodoUsers(todosArr.toJSONString());
                    }
                } else {
                    //能够处理下个节点的候选人
                    List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList();
                    List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(candidateUsers)) {
                        //    前端传入候选人
                        collect_username = candidateUsers;
                    }
                    business
                            .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);
                        }
                        business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
                    } else {
                        for (String oldUser : collect_username) {
                            taskService.addCandidateUser(task2.getId(), oldUser);
                        }
                        business.setTodoUsers(JSON.toJSONString(collect_username));
                    }
                }
                business.setTodoUsers(todosArr.toJSONString());
            }
        } else {
        //    * 下一节点是会签节点 或 普通用户节点,逻辑一致
            if (nextFlowNode!=null){
            flowMyBusinessService.updateById(business);
        }
        else {
            for(FlowNextDto nextFlowNode : nextFlowNodeList) {
                //**有下一个节点
                UserTask nextTask = nextFlowNode.getUserTask();
                //能够处理下个节点的候选人
                List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList();
                List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(candidateUsers)){
                    //    前端传入候选人
                    collect_username = candidateUsers;
                Task task2 = null;
                Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst();
                if (first.isPresent()) {
                    task2 = first.get();
                }
                business
                        .setTaskId(task2.getId())
//                        .setActStatus(ActStatus.doing)
                        .setTaskNameId(nextTask.getId())
                        .setTaskName(nextTask.getName())
                        .setPriority(nextTask.getPriority())
                        .setDoneUsers(doneUserList.toJSONString())
                        .setTodoUsers(JSON.toJSONString(collect_username))
                ;
                // 删除后重写
                for (Task task2One : task2List) {
                    for (String oldUser : collect_username) {
                        taskService.deleteCandidateUser(task2One.getId(),oldUser);
                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 (CollUtil.isEmpty(candidateUsers)&&CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){
                    // 前端没有传入候选人 && 业务层有指定候选人,覆盖
                    for (Task task2One : task2List) {
                        for (String newUser : beforeParamsCandidateUsernames) {
                            taskService.addCandidateUser(task2One.getId(),newUser);
                    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());
                        }
                    }
                    business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
                } else {
                    for (Task task2One : task2List) {
                        for (String oldUser : collect_username) {
                            taskService.addCandidateUser(task2One.getId(),oldUser);
                        // 重写
                        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("")
                ;
                    } else {
                        //能够处理下个节点的候选人
                        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();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result completeByDateId(FlowTaskVo flowTaskVo){
    public Result completeByDateId(FlowTaskVo flowTaskVo) {
        return this.complete(flowTaskVo);
    }
    @Override
    public void taskRejectByDataId(FlowTaskVo flowTaskVo){
    public void taskRejectByDataId(FlowTaskVo flowTaskVo) {
        FlowMyBusiness business = flowMyBusinessService.getByDataId(flowTaskVo.getDataId());
        flowTaskVo.setTaskId(business.getTaskId());
        this.taskReject(flowTaskVo);
    }
    /**
     * 驳回任务
     *
@@ -387,7 +470,7 @@
            /*======================驳回  回调以及关键数据保存======================*/
            //业务数据id
            String dataId = flowTaskVo.getDataId();
            if (dataId==null) return;
            if (dataId == null) return;
            //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题
            FlowMyBusiness business = flowMyBusinessService.getByDataId(dataId);
            // 驳回到了上一个节点等待处理
@@ -397,21 +480,21 @@
            String serviceImplName = business.getServiceImplName();
            FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName);
            Map<String, Object> values = flowTaskVo.getValues();
            if (values ==null){
            if (values == null) {
                values = MapUtil.newHashMap();
                values.put("dataId",dataId);
                values.put("dataId", dataId);
            } else {
                values.put("dataId",dataId);
                values.put("dataId", dataId);
            }
            List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), values);
            //设置数据
            String doneUsers = business.getDoneUsers();
            // 处理过流程的人
            JSONArray doneUserList = new JSONArray();
            if (StrUtil.isNotBlank(doneUsers)){
            if (StrUtil.isNotBlank(doneUsers)) {
                doneUserList = JSON.parseArray(doneUsers);
            }
            if (!doneUserList.contains(loginUser.getUsername())){
            if (!doneUserList.contains(loginUser.getUsername())) {
                doneUserList.add(loginUser.getUsername());
            }
            business
@@ -432,31 +515,31 @@
                }
            }
            if (targetElement!=null){
            if (targetElement != null) {
                UserTask targetTask = (UserTask) targetElement;
                business.setPriority(targetTask.getPriority());
                if (StrUtil.equals(business.getTaskNameId(),ProcessConstants.START_NODE)){
                if (StrUtil.equals(business.getTaskNameId(), ProcessConstants.START_NODE)) {
                    //    开始节点。设置处理人为申请人
                    business.setTodoUsers(JSON.toJSONString(Lists.newArrayList(business.getProposer())));
                    taskService.setAssignee(business.getTaskId(),business.getProposer());
                    taskService.setAssignee(business.getTaskId(), business.getProposer());
                } else {
                    List<SysUser> sysUserFromTask = getSysUserFromTask(targetTask);
                    List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList());
                    // 前端存入的候选人
                    List<String> candidateUsers = flowTaskVo.getCandidateUsers();
                    if (CollUtil.isNotEmpty(candidateUsers)){
                    if (CollUtil.isNotEmpty(candidateUsers)) {
                        collect_username = candidateUsers;
                    }
                    business.setTodoUsers(JSON.toJSONString(collect_username));
                    // 删除后重写
                    for (Task task2One : task2List) {
                        for (String oldUser : collect_username) {
                            taskService.deleteCandidateUser(task2One.getId(),oldUser);
                            taskService.deleteCandidateUser(task2One.getId(), oldUser);
                        }
                    }
                    if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){
                        if (CollUtil.isNotEmpty(candidateUsers)){
                    if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) {
                        if (CollUtil.isNotEmpty(candidateUsers)) {
                            beforeParamsCandidateUsernames = candidateUsers;
                        }
                        // 业务层有指定候选人,覆盖
@@ -477,9 +560,9 @@
            }
            flowMyBusinessService.updateById(business);
           // 流程处理完后,进行回调业务层
            // 流程处理完后,进行回调业务层
            business.setValues(values);
            if (flowCallBackService!=null) flowCallBackService.afterFlowHandle(business);
            if (flowCallBackService != null) flowCallBackService.afterFlowHandle(business);
        } catch (FlowableObjectNotFoundException e) {
            throw new CustomException("未找到流程实例,流程可能已发生变化");
        } catch (FlowableException e) {
@@ -487,13 +570,15 @@
        }
    }
    @Override
    public void taskReturnByDataId(FlowTaskVo flowTaskVo){
    public void taskReturnByDataId(FlowTaskVo flowTaskVo) {
        //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题
        FlowMyBusiness business = flowMyBusinessService.getByDataId(flowTaskVo.getDataId());
        flowTaskVo.setTaskId(business.getTaskId());
        taskReturn(flowTaskVo);
    }
    /**
     * 退回任务
     *
@@ -574,7 +659,7 @@
            /*======================退回  回调以及关键数据保存======================*/
            //业务数据id
            String dataId = flowTaskVo.getDataId();
            if (dataId==null) return;
            if (dataId == null) return;
            //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题
            FlowMyBusiness business = flowMyBusinessService.getByDataId(dataId);
            //spring容器类名
@@ -584,61 +669,61 @@
            String doneUsers = business.getDoneUsers();
            // 处理过流程的人
            JSONArray doneUserList = new JSONArray();
            if (StrUtil.isNotBlank(doneUsers)){
            if (StrUtil.isNotBlank(doneUsers)) {
                doneUserList = JSON.parseArray(doneUsers);
            }
            if (!doneUserList.contains(loginUser.getUsername())){
            if (!doneUserList.contains(loginUser.getUsername())) {
                doneUserList.add(loginUser.getUsername());
            }
                //**跳转到目标节点
            //**跳转到目标节点
            List<Task> task2List = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().list();
            Task targetTask = task2List.get(0);
                business
                        .setTaskId(targetTask.getId())
            business
                    .setTaskId(targetTask.getId())
//                        .setActStatus(ActStatus.reject)
                        .setTaskNameId(targetTask.getTaskDefinitionKey())
                        .setTaskName(targetTask.getName())
                        .setPriority(targetTask.getPriority()+"")
                        .setDoneUsers(doneUserList.toJSONString())
                ;
            if (target!=null){
                    .setTaskNameId(targetTask.getTaskDefinitionKey())
                    .setTaskName(targetTask.getName())
                    .setPriority(targetTask.getPriority() + "")
                    .setDoneUsers(doneUserList.toJSONString())
            ;
            if (target != null) {
                UserTask target2 = (UserTask) target;
                business.setPriority(target2.getPriority());
                if (StrUtil.equals(business.getTaskNameId(),ProcessConstants.START_NODE)){
                //    开始节点。设置处理人为申请人
                if (StrUtil.equals(business.getTaskNameId(), ProcessConstants.START_NODE)) {
                    //    开始节点。设置处理人为申请人
                    business.setTodoUsers(JSON.toJSONString(Lists.newArrayList(business.getProposer())));
                    taskService.setAssignee(business.getTaskId(),business.getProposer());
                    taskService.setAssignee(business.getTaskId(), business.getProposer());
                } else {
                    List<SysUser> sysUserFromTask = getSysUserFromTask(target2);
                    List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList());
                    List<String> candidateUsers = flowTaskVo.getCandidateUsers();
                    if (CollUtil.isNotEmpty(candidateUsers)){
                    if (CollUtil.isNotEmpty(candidateUsers)) {
                        collect_username = candidateUsers;
                    }
                    business.setTodoUsers(JSON.toJSONString(collect_username));
                    // 删除后重写
                    for (Task task2One : task2List) {
                        for (String oldUser : collect_username) {
                            taskService.deleteCandidateUser(task2One.getId(),oldUser);
                            taskService.deleteCandidateUser(task2One.getId(), oldUser);
                        }
                    }
                    Map<String, Object> values = flowTaskVo.getValues();
                    if (values==null){
                    if (values == null) {
                        values = MapUtil.newHashMap();
                        values.put("dataId",dataId);
                        values.put("dataId", dataId);
                    } else {
                        values.put("dataId",dataId);
                        values.put("dataId", dataId);
                    }
                    List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(targetTask.getTaskDefinitionKey(), values);
                    if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){
                        if (CollUtil.isNotEmpty(candidateUsers)){
                    if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) {
                        if (CollUtil.isNotEmpty(candidateUsers)) {
                            beforeParamsCandidateUsernames = candidateUsers;
                        }
                        // 业务层有指定候选人,覆盖
                        for (Task task2One : task2List) {
                            for (String newUser : beforeParamsCandidateUsernames) {
                                taskService.addCandidateUser(task2One.getId(),newUser);
                                taskService.addCandidateUser(task2One.getId(), newUser);
                            }
                        }
                        business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames));
@@ -654,7 +739,7 @@
            flowMyBusinessService.updateById(business);
            // 流程处理完后,进行回调业务层
            business.setValues(flowTaskVo.getValues());
            if (flowCallBackService!=null) flowCallBackService.afterFlowHandle(business);
            if (flowCallBackService != null) flowCallBackService.afterFlowHandle(business);
        } catch (FlowableObjectNotFoundException e) {
            throw new CustomException("未找到流程实例,流程可能已发生变化");
        } catch (FlowableException e) {
@@ -668,6 +753,30 @@
        flowTaskVo.setTaskId(business.getTaskId());
        return findReturnTaskList(flowTaskVo);
    }
    /**
     * 结束流程
     *
     * @param processInstanceId 流程实例 ID
     * @param deleteReason      定义删除原因
     */
    public Result<?> end(String processInstanceId, String deleteReason) {
        try {
            // 强制结束流程实例
            runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
            // 删除关联流程的业务
            FlowMyBusiness flowMyBusiness = flowMyBusinessService.getFlowMyBusiness(processInstanceId);
            flowMyBusinessService.removeById(flowMyBusiness.getId());
            System.out.println("Process instance with ID " + processInstanceId + " has been forcefully ended.");
        } catch (Exception e) {
            System.err.println("Failed to force end process instance: " + e.getMessage());
        }
        // 关闭流程引擎
        processEngine.close();
        return Result.OK("流程已结束");
    }
    /**
     * 获取所有可回退的节点
     *
@@ -717,7 +826,7 @@
    @Override
    public void deleteTask(FlowTaskVo flowTaskVo) {
        // todo 待确认删除任务是物理删除任务 还是逻辑删除,让这个任务直接通过?
        taskService.deleteTask(flowTaskVo.getTaskId(),flowTaskVo.getComment());
        taskService.deleteTask(flowTaskVo.getTaskId(), flowTaskVo.getComment());
    }
    /**
@@ -762,7 +871,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignTask(FlowTaskVo flowTaskVo) {
        taskService.setAssignee(flowTaskVo.getTaskId(),flowTaskVo.getAssignee());
        taskService.setAssignee(flowTaskVo.getTaskId(), flowTaskVo.getAssignee());
    }
    /**
@@ -780,7 +889,7 @@
                .startedBy(username)
                .orderByProcessInstanceStartTime()
                .desc();
        List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage((pageNum - 1)*pageSize, pageSize);
        List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage((pageNum - 1) * pageSize, pageSize);
        page.setTotal(historicProcessInstanceQuery.count());
        List<FlowTaskDto> flowList = new ArrayList<>();
        for (HistoricProcessInstance hisIns : historicProcessInstances) {
@@ -919,6 +1028,7 @@
    /**
     * 判断多个任务是否处于同一流程节点
     *
     * @param taskIds 逗号分隔的任务ID字符串
     * @return 统一结果封装
     */
@@ -990,7 +1100,7 @@
                .taskAssignee(username)
                .orderByTaskCreateTime().desc();
        page.setTotal(taskQuery.count());
        List<Task> taskList = taskQuery.listPage((pageNum - 1)*pageSize, pageSize);
        List<Task> taskList = taskQuery.listPage((pageNum - 1) * pageSize, pageSize);
        List<FlowTaskDto> flowList = new ArrayList<>();
        for (Task task : taskList) {
            FlowTaskDto flowTask = new FlowTaskDto();
@@ -1017,7 +1127,7 @@
            List<String> departNamesByUsername = iFlowThirdService.getDepartNamesByUsername(historicProcessInstance.getStartUserId());
            flowTask.setStartUserId(startUser.getUsername());
            flowTask.setStartUserName(startUser.getRealname());
            flowTask.setStartDeptName(CollUtil.join(departNamesByUsername,","));
            flowTask.setStartDeptName(CollUtil.join(departNamesByUsername, ","));
            flowList.add(flowTask);
        }
@@ -1039,18 +1149,30 @@
        Page page = new Page(pageNum, pageSize);
        String username = iFlowThirdService.getLoginUser().getUsername();
        flowMyBusinessDto.setCurrentUser(username);
        IPage<FlowTaskDto> flowTaskDtoIPage = flowMyBusinessService.getPageListMyBusiness(page,flowMyBusinessDto);
        flowTaskDtoIPage.getRecords().forEach(flowTaskDto -> {
        List<FlowTaskDto> list = flowMyBusinessService.ListMyBusiness(flowMyBusinessDto);
        list.forEach(flowTaskDto -> {
            // 流程发起人信息
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(flowTaskDto.getProcInsId())
                    .singleResult();
            SysUser startUser = iFlowThirdService.getUserByUsername(historicProcessInstance.getStartUserId());
            flowTaskDto.setStartUserId(startUser.getUsername());
            flowTaskDto.setStartUserName(startUser.getRealname());
            if (startUser != null) {
                flowTaskDto.setStartUserId(startUser.getUsername());
                flowTaskDto.setStartUserName(startUser.getRealname());
            }
            List<String> departNamesByUsername = iFlowThirdService.getDepartNamesByUsername(historicProcessInstance.getStartUserId());
            flowTaskDto.setStartDeptName(CollUtil.join(departNamesByUsername,","));
            flowTaskDto.setStartDeptName(CollUtil.join(departNamesByUsername, ","));
            if (flowTaskDto.getTodoUsers() == null) {
                flowTaskDto.setTodoUsers("");
            } else {
                //去除[]
                flowTaskDto.setTodoUsers(flowTaskDto.getTodoUsers().replaceAll("\\[", "").replaceAll("\\]", ""));
                flowTaskDto.setTodoUsers(flowTaskDto.getTodoUsers().replaceAll("\"", ""));
            }
        });
        IPage<FlowTaskDto> flowTaskDtoIPage = new Page<>();
        flowTaskDtoIPage.setRecords(list);
        flowTaskDtoIPage.setTotal(page.getTotal());
        return Result.OK(flowTaskDtoIPage);
    }
@@ -1090,9 +1212,9 @@
                        flowTask.setAssigneeId(sysUser.getUsername());
                        flowTask.setAssigneeName(sysUser.getRealname());
                        List<String> departNamesByUsername = iFlowThirdService.getDepartNamesByUsername(histIns.getAssignee());
                        flowTask.setDeptName(CollUtil.join(departNamesByUsername,","));
                        if (StrUtil.equals(histIns.getActivityId(),ProcessConstants.START_NODE)){
                        //    开始节点,把候选人设置为发起人,这个值已被其他地方设置过,与实际办理人一致即可
                        flowTask.setDeptName(CollUtil.join(departNamesByUsername, ","));
                        if (StrUtil.equals(histIns.getActivityId(), ProcessConstants.START_NODE)) {
                            //    开始节点,把候选人设置为发起人,这个值已被其他地方设置过,与实际办理人一致即可
                            flowTask.setCandidate(sysUser.getRealname());
                        }
                    }
@@ -1134,9 +1256,9 @@
        String serviceImplName = business.getServiceImplName();
        FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName);
        // 流程处理完后,进行回调业务层
        if (flowCallBackService!=null){
        if (flowCallBackService != null) {
            Object businessDataById = flowCallBackService.getBusinessDataById(dataId);
            map.put("formData",businessDataById);
            map.put("formData", businessDataById);
        }
        return Result.OK(map);
    }
@@ -1225,8 +1347,8 @@
                for (FlowViewerDto viewerDto : flowViewerList) {
                    String key = viewerDto.getKey();
                    if (key.equals(flowViewerDto.getKey())){
                    //    重复删除后面更新
                    if (key.equals(flowViewerDto.getKey())) {
                        //    重复删除后面更新
                        flowViewerList.remove(viewerDto);
                        break;
                    }
@@ -1241,7 +1363,7 @@
    @Override
    public List<FlowViewerDto> getFlowViewerByDataId(String dataId) {
        LambdaQueryWrapper<FlowMyBusiness> flowMyBusinessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        flowMyBusinessLambdaQueryWrapper.eq(FlowMyBusiness::getDataId,dataId)
        flowMyBusinessLambdaQueryWrapper.eq(FlowMyBusiness::getDataId, dataId)
        ;
        //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题
        FlowMyBusiness business = flowMyBusinessService.getOne(flowMyBusinessLambdaQueryWrapper);
@@ -1263,7 +1385,7 @@
                    String firstKey = stev.getId();
                    orderKeys.add(firstKey);
                    //顺序获取节点
                    this.appendKeys(orderKeys, firstKey,flowElements);
                    this.appendKeys(orderKeys, firstKey, flowElements);
                } catch (Exception e) {
                    break;
                }
@@ -1272,11 +1394,11 @@
            for (String key : orderKeys) {
                Optional<FlowViewerDto> any = flowViewers.stream().filter(o -> StrUtil.equals(o.getKey(), key)).findAny();
                if(any.isPresent()){
                if (any.isPresent()) {
                    FlowViewerDto viewerDto = any.get();
                    reflowViewers.add(viewerDto);
                    if (!viewerDto.isCompleted()){
                    //    已到正在等待执行的节点,后面的不要了
                    if (!viewerDto.isCompleted()) {
                        //    已到正在等待执行的节点,后面的不要了
                        break;
                    }
                }
@@ -1292,8 +1414,9 @@
    /**
     * 顺序抽取节点
     * @param orderKeys 容器
     * @param sourceKey 源
     *
     * @param orderKeys    容器
     * @param sourceKey    源
     * @param flowElements 所有的节点对象
     */
    private void appendKeys(List<String> orderKeys, String sourceKey, List<FlowElement> flowElements) {
@@ -1302,9 +1425,9 @@
                SequenceFlow sf = (SequenceFlow) flowElement;
                String sourceRef = sf.getSourceRef();
                String targetRef = sf.getTargetRef();
                if (sourceKey.equals(sourceRef)&&targetRef!=null){
                if (sourceKey.equals(sourceRef) && targetRef != null) {
                    orderKeys.add(targetRef);
                    this.appendKeys(orderKeys,targetRef,flowElements);
                    this.appendKeys(orderKeys, targetRef, flowElements);
                }
            } catch (Exception e) {
                continue;
@@ -1338,89 +1461,116 @@
     * @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)){
                            // 待办人员从变量中获取  否则就是节点中配置的用户 sysUserFromTask
                            List<SysUser> userList = Lists.newArrayList();
                            for (String username : userNameList) {
                                SysUser userByUsername = iFlowThirdService.getUserByUsername(username);
                                if (userByUsername==null){
                                    throw new CustomException(username + " 用户名未找到");
                                } else {
                                    userList.add(userByUsername);
                                }
                    //多任务并行
                    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) {
                            SysUser userByUsername = iFlowThirdService.getUserByUsername(username);
                            if (userByUsername == null) {
                                throw new CustomException(username + " 用户名未找到");
                            } else {
                                userList.add(userByUsername);
                            }
                            flowNextDto.setUserList(userList);
                        } else {
                            // 变量中没有传入,写入节点中配置的用户
                            List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList());
                            values.put(collectionString,collect_username);
                        }
                        flowNextDto.setUserList(userList);
                    } else {
                        // todo 读取自定义节点属性做些啥?
                        //String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
                        String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE);
                        // 变量中没有传入,写入节点中配置的用户
                        List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList());
                        values.put(userTask.getId(), collect_username);
                    }
                    nextDtoList.add(flowNextDto);
                }
                return flowNextDto;
                return nextDtoList;
            }
        }
        return null;
    }
    public List<SysUser> getSysUserFromTask(UserTask userTask) {
        String assignee = userTask.getAssignee();
        if (StrUtil.isNotBlank(assignee)){
        if (StrUtil.isNotBlank(assignee)) {
            // 指定单人
            SysUser userByUsername = iFlowThirdService.getUserByUsername(assignee);
            return Lists.newArrayList(userByUsername);
        }
        List<String> candidateUsers = userTask.getCandidateUsers();
        if (CollUtil.isNotEmpty(candidateUsers)){
        if (CollUtil.isNotEmpty(candidateUsers)) {
            // 指定多人
            List<SysUser> list = iFlowThirdService.getAllUser();
            return list.stream().filter(o->candidateUsers.contains(o.getUsername())).collect(Collectors.toList());
            return list.stream().filter(o -> candidateUsers.contains(o.getUsername())).collect(Collectors.toList());
        }
        List<String> candidateGroups = userTask.getCandidateGroups();
        if (CollUtil.isNotEmpty(candidateGroups)){
        //    指定多组
        if (CollUtil.isNotEmpty(candidateGroups)) {
            //    指定多组
            List<SysUser> userList = Lists.newArrayList();
            for (String candidateGroup : candidateGroups) {
                List<SysUser> usersByRoleId = iFlowThirdService.getUsersByRoleId(candidateGroup);
@@ -1430,6 +1580,7 @@
        }
        return Lists.newArrayList();
    }
    /**
     * 流程完成时间处理
     *