package com.yunzhupaas.flowable.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.ImmutableList;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.enums.NodeEnum;
import com.yunzhupaas.flowable.enums.OperatorStateEnum;
import com.yunzhupaas.flowable.enums.RecordEnum;
import com.yunzhupaas.flowable.enums.TaskStatusEnum;
import com.yunzhupaas.flowable.job.FlowJobUtil;
import com.yunzhupaas.flowable.model.flowable.*;
import com.yunzhupaas.flowable.model.message.FlowMsgModel;
import com.yunzhupaas.flowable.model.operator.AddSignModel;
import com.yunzhupaas.flowable.model.operator.ReducePagination;
import com.yunzhupaas.flowable.model.operator.ReduceUserModel;
import com.yunzhupaas.flowable.model.record.NodeRecordModel;
import com.yunzhupaas.flowable.model.task.FlowMethod;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.task.SubParameterModel;
import com.yunzhupaas.flowable.model.templatenode.FlowErrorModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.*;
import com.yunzhupaas.flowable.model.trigger.ExecuteAsyncModel;
import com.yunzhupaas.flowable.model.trigger.ExecuteModel;
import com.yunzhupaas.flowable.model.util.*;
import com.yunzhupaas.flowable.service.*;
import com.yunzhupaas.permission.entity.OrganizeEntity;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类的描述
 *
 * @author YUNZHUPAASYUNZHUPAAS开发组
 * @version 5.0.x
 * @since 2024/4/24 20:38
 */
@Slf4j
@Component
public class OperatorUtil {
    @Autowired
    private OperatorService operatorService;
    @Autowired
    private TaskUtil taskUtil;
    @Autowired
    private ConditionService conditionService;
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private TaskService taskService;
    @Autowired
    private FlowAbleUrl flowAbleUrl;
    @Autowired
    private RejectDataService rejectDataService;
    @Autowired
    private RecordUtil recordUtil;
    @Autowired
    private MsgUtil msgUtil;
    @Autowired
    private TemplateNodeService templateNodeService;
    @Autowired
    private CirculateService circulateService;
    @Autowired
    private TemplateService templateService;
    @Autowired
    private TemplateJsonService templateJsonService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private NodeRecordService nodeRecordService;
    @Autowired
    private CirculateUtil circulateUtil;
    @Autowired
    private TaskLineService taskLineService;
    @Autowired
    private RevokeService revokeService;
    @Autowired
    private FlowAsyncUtil flowAsyncUtil;
    @Autowired
    private TriggerUtil triggerUtil;
    @Autowired
    private SubtaskDataService subtaskDataService;

    // 组建FlowMethod
    public FlowMethod getFlowMethod(FlowMethod flowMethod) {
        FlowModel flowModel = flowMethod.getFlowModel();
        String nodeCode = flowMethod.getNodeCode();
        Map<String, NodeModel> nodes = flowMethod.getNodes();
        FlowModel model = JsonUtil.getJsonToBean(flowModel, FlowModel.class);
        model.setHandleOpinion("系统审批");
        model.setSignImg(null);
        model.setFileList(null);
        model.setHandleStatus(FlowNature.AuditCompletion);
        model.setTaskEntity(flowMethod.getTaskEntity());
        model.setFlowableTaskId(flowMethod.getFlowableTaskId());
        FlowMethod method = new FlowMethod();
        method.setFlowModel(model);
        NodeModel nodeModel = nodes.get(nodeCode);
        method.setNodeModel(nodeModel);
        method.setNodeCode(nodeCode);
        return method;
    }

    // 处理撤销的经办
    public void handleRevokeOperator(FlowMethod flowMethod) throws Exception {
        FlowModel flowModel = flowMethod.getFlowModel();
        String taskId = flowMethod.getTaskId();
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        String instanceId = taskEntity.getInstanceId();
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        NodeModel global = nodes.get(NodeEnum.global.getType());
        List<OperatorEntity> operatorEntities = new ArrayList<>();
        // 生成经办，获取之前同意的经办，再次生成经办
        List<OperatorEntity> operatorList = this.getList(taskId)
                .stream().filter(e -> ObjectUtil.equals(e.getHandleStatus(), FlowNature.AuditCompletion)
                        && !ObjectUtil.equals(e.getStatus(), OperatorStateEnum.Futility.getCode()))
                .collect(Collectors.toList());
        List<FlowableTaskModel> taskModelList = flowAbleUrl.getCurrentTask(instanceId);

        // 原来的当前节点
        List<String> srcCurrentList = StringUtil.isNotEmpty(taskEntity.getCurrentNodeCode())
                ? Arrays.stream(taskEntity.getCurrentNodeCode().split(",")).collect(Collectors.toList())
                : new ArrayList<>();

        taskUtil.updateCurrentNode(taskModelList, nodes, taskEntity);

        List<NodeRecordEntity> nodeRecordList = nodeRecordService.getList(taskId);
        nodeRecordList = nodeRecordList.stream()
                .sorted(Comparator.comparing(NodeRecordEntity::getCreatorTime).reversed()).collect(Collectors.toList());

        for (FlowableTaskModel flowableTaskModel : taskModelList) {
            // 当前节点已存在，跳过
            if (CollectionUtil.isNotEmpty(srcCurrentList) && srcCurrentList.contains(flowableTaskModel.getTaskKey())) {
                continue;
            }
            TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeCode(), flowableTaskModel.getTaskKey())).findFirst()
                    .orElse(null);
            if (null == nodeEntity) {
                continue;
            }
            // 处理子流程、办理节点
            if (ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.subFlow.getType())
                    || ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.processing.getType())) {
                // FlowModel model = JsonUtil.getJsonToBean(flowModel, FlowModel.class);
                // model.setTaskEntity(taskEntity);
                // model.setFlowableTaskId(flowableTaskModel.getTaskId());
                // this.handleSubFlow(nodeEntity, model);

                CompleteFo completeFo = new CompleteFo();
                completeFo.setTaskId(flowableTaskModel.getTaskId());
                flowAbleUrl.complete(completeFo);
                this.handleRevokeOperator(flowMethod);
                continue;
            }

            String nodeCode = flowableTaskModel.getTaskKey();
            String nodeId = flowableTaskModel.getTaskId();
            flowMethod.setFlowableTaskId(flowableTaskModel.getTaskId());
            flowMethod.setNodes(nodes);
            flowMethod.setNodeCode(nodeCode);
            // 判断拒绝
            NodeRecordEntity nodeRecord = nodeRecordList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeCode(), flowableTaskModel.getTaskKey())).findFirst()
                    .orElse(new NodeRecordEntity());
            if (ObjectUtil.equals(nodeRecord.getNodeStatus(), 3)) {
                // 系统通过
                FlowMethod method = this.getFlowMethod(flowMethod);
                this.autoAudit(method);
                continue;
            }
            List<OperatorEntity> list = operatorList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeCode(), nodeCode)).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(list)) {
                if ((list.size() == 1 && ObjectUtil.equals(list.get(0).getHandleId(), FlowNature.SYSTEM_CODE))) {
                    // 系统通过
                    FlowMethod method = this.getFlowMethod(flowMethod);
                    this.autoAudit(method);
                    continue;
                }
                for (OperatorEntity operator : list) {
                    OperatorEntity operatorEntity = this.createOperator(operator, OperatorStateEnum.Revoke.getCode(),
                            operator.getHandleId(), global);
                    operatorEntity.setTaskId(taskEntity.getId());
                    operatorEntity.setNodeId(nodeId);
                    operatorEntity.setParentId("0");
                    operatorEntities.add(operatorEntity);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(operatorEntities)) {
            operatorService.saveBatch(operatorEntities);
            flowModel.setList(operatorEntities);
            // 消息
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setNodeList(nodeEntityList);
            flowMsgModel.setTaskEntity(taskEntity);
            flowMsgModel.setFlowModel(flowModel);
            flowMsgModel.setOperatorList(operatorEntities);
            flowMsgModel.setFormData(FlowContextHolder.getAllData());
            msgUtil.message(flowMsgModel);
        }
    }

    public List<OperatorEntity> getList(String taskId) {
        return operatorService.getList(taskId);
    }

    // 归档 最后节点审批人：表示最后节点的审批人才有权限查看该文档（取最后节点实际参与审批的人，不包含加签和转审人员）；
    public List<String> getListOfLast(String taskId) {
        List<String> resList = new ArrayList<>();

        List<Integer> status = ImmutableList.of(OperatorStateEnum.AddSign.getCode(),
                OperatorStateEnum.Transfer.getCode(),
                OperatorStateEnum.Assist.getCode(), OperatorStateEnum.Futility.getCode());

        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskId)
                .ne(OperatorEntity::getHandleId, FlowNature.SYSTEM_CODE)
                .notIn(OperatorEntity::getStatus, status)
                .isNotNull(OperatorEntity::getHandleStatus).orderByDesc(OperatorEntity::getHandleTime);

        List<OperatorEntity> list = operatorService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            // 获取符合条件的最后一个审批人，通过该审批人获取节点
            OperatorEntity operator = list.get(0);
            List<OperatorEntity> operatorList = list.stream()
                    .filter(e -> ObjectUtil.equals(operator.getNodeId(), e.getNodeId()))
                    .sorted(Comparator.comparing(OperatorEntity::getHandleTime).reversed())
                    .collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(operatorList)) {
                List<String> handleIds = operatorList.stream().map(OperatorEntity::getHandleId).distinct()
                        .collect(Collectors.toList());
                resList.addAll(handleIds);
            }
            List<CirculateEntity> circulateList = circulateService.getList(taskId);
            if (CollectionUtil.isNotEmpty(circulateList)) {
                List<String> userIds = circulateList.stream()
                        .filter(e -> ObjectUtil.equals(operator.getNodeId(), e.getNodeId()))
                        .map(CirculateEntity::getUserId).collect(Collectors.toList());
                resList.addAll(userIds);
            }
        }
        return resList.stream().distinct().collect(Collectors.toList());
    }

    // 归档 当前流程所有人：包含流程的发起人、所有节点的审批人及抄送人员，不包含加签和转审人员；（审批人读取参与审批的人）
    public List<String> getListOfFile(String taskId) {
        List<String> resList = new ArrayList<>();
        List<OperatorEntity> operatorList = operatorService.getList(taskId);
        if (CollectionUtil.isNotEmpty(operatorList)) {
            List<Integer> status = ImmutableList.of(OperatorStateEnum.AddSign.getCode(),
                    OperatorStateEnum.Transfer.getCode(),
                    OperatorStateEnum.Assist.getCode(), OperatorStateEnum.Futility.getCode());
            List<OperatorEntity> list = operatorList.stream()
                    .filter(e -> !status.contains(e.getStatus()) && e.getHandleStatus() != null)
                    .collect(Collectors.toList());

            resList.addAll(list.stream().map(OperatorEntity::getHandleId).collect(Collectors.toList()));
        }
        List<CirculateEntity> circulateList = circulateService.getList(taskId);
        if (CollectionUtil.isNotEmpty(circulateList)) {
            resList.addAll(circulateList.stream().map(CirculateEntity::getUserId).collect(Collectors.toList()));
        }
        return resList.stream().distinct().collect(Collectors.toList());
    }

    // 校验经办
    public OperatorEntity checkOperator(String id) throws WorkFlowException {
        OperatorEntity operator = operatorService.getInfo(id);
        if (null == operator) {
            throw new WorkFlowException(MsgCode.FA001.get());
        }
        if (null == operator.getSignTime()) {
            throw new WorkFlowException(MsgCode.WF087.get());
        }
        if (null == operator.getStartHandleTime()) {
            throw new WorkFlowException(MsgCode.WF088.get());
        }
        if (null != operator.getHandleStatus()) {
            throw new WorkFlowException(MsgCode.WF031.get());
        }
        return operator;
    }

    // 创建经办
    public List<OperatorEntity> createOperator(FlowMethod flowMethod) {
        List<String> userIds = flowMethod.getUserIds();
        NodeModel nodeModel = flowMethod.getNodeModel();
        FlowModel flowModel = flowMethod.getFlowModel();
        List<OperatorEntity> entityList = new ArrayList<>();
        if (userIds.isEmpty()) {
            return entityList;
        }
        TaskEntity taskEntity = flowModel.getTaskEntity();
        String flowableTaskId = flowModel.getFlowableTaskId();
        NodeModel global = flowModel.getNodes().get(NodeEnum.global.getType());

        // 是否签收
        Boolean signFor = global.getHasSignFor();
        flowMethod.setTaskEntity(taskEntity);
        flowMethod.setSignFor(signFor);
        flowMethod.setFlowableTaskId(flowableTaskId);

        if (nodeModel.getCounterSign().equals(FlowNature.ImproperApprover)) {
            List<String> list = taskUtil.improperSort(userIds, nodeModel);
            if (CollectionUtil.isNotEmpty(list)) {
                OperatorEntity entity = this.createOperatorEntity(flowMethod);
                entity.setHandleId(list.get(0));
                entity.setHandleAll(String.join(",", list));
                entity.setParentId("0");
                entityList.add(entity);
            }
        } else {
            // 或签、会签
            for (String userId : userIds) {
                OperatorEntity entity = this.createOperatorEntity(flowMethod);
                entity.setHandleId(userId);
                entity.setParentId("0");
                entityList.add(entity);
            }
        }

        if (CollectionUtil.isNotEmpty(entityList)) {
            operatorService.saveBatch(entityList);
        }
        return entityList;
    }

    public OperatorEntity createOperatorEntity(FlowMethod flowMethod) {
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        TemplateNodeEntity nodeEntity = flowMethod.getNodeEntity();
        NodeModel nodeModel = flowMethod.getNodeModel();
        Boolean signFor = flowMethod.getSignFor();
        String flowableTaskId = flowMethod.getFlowableTaskId();
        OperatorEntity entity = new OperatorEntity();
        entity.setId(RandomUtil.uuId());
        entity.setIsProcessing(ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.processing.getType()) ? 1 : 0);
        entity.setNodeId(flowableTaskId);
        entity.setNodeName(nodeModel.getNodeName());
        entity.setNodeCode(nodeEntity.getNodeCode());
        entity.setStatus(OperatorStateEnum.Runing.getCode());
        Boolean flowTodo = serviceUtil.getFlowTodo();
        if (flowTodo) {
            entity.setSignTime(new Date());
            entity.setStartHandleTime(new Date());
        } else {
            Boolean flowSign = serviceUtil.getFlowSign();
            if (flowSign) {
                entity.setSignTime(new Date());
            } else {
                if (!signFor) {
                    entity.setSignTime(new Date());
                }
            }
        }
        entity.setCompletion(0);
        entity.setTaskId(taskEntity.getId());
        entity.setEngineType(taskEntity.getEngineType());
        return entity;
    }

    // 判断节点的审批结果
    public boolean checkAudit(FlowMethod flowMethod) throws WorkFlowException {
        OperatorEntity operator = flowMethod.getOperatorEntity();
        NodeModel nodeModel = flowMethod.getNodeModel();
        NodeModel global = flowMethod.getNodes().get(NodeEnum.global.getType());
        Integer handleStatus = flowMethod.getHandleStatus();
        boolean result = false;

        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, operator.getTaskId())
                .eq(OperatorEntity::getNodeCode, operator.getNodeCode())
                .eq(OperatorEntity::getParentId, "0")
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                .select(OperatorEntity::getId, OperatorEntity::getHandleStatus, OperatorEntity::getHandleTime);
        List<OperatorEntity> list = operatorService.list(queryWrapper);

        Boolean auditFlag = flowMethod.getAuditFlag();
        if (auditFlag) {
            for (OperatorEntity entity : list) {
                if (ObjectUtil.equals(entity.getId(), operator.getId())) {
                    entity.setHandleStatus(operator.getHandleStatus());
                    break;
                }
            }
        }

        Integer counterSign = nodeModel.getCounterSign();
        if (FlowNature.FixedApprover.equals(counterSign)) {
            // 或签，一人同意或拒绝
            result = operator.getHandleStatus().equals(handleStatus);
        } else if (FlowNature.FixedJointlyApprover.equals(counterSign)) {
            // 会签
            long numAudit;
            long numReject;
            if (auditFlag) {
                numAudit = list.stream().filter(e -> FlowNature.AuditCompletion.equals(e.getHandleStatus())).count();
                numReject = list.stream().filter(e -> FlowNature.RejectCompletion.equals(e.getHandleStatus())).count();
            } else {
                numAudit = list.stream()
                        .filter(e -> FlowNature.AuditCompletion.equals(e.getHandleStatus())
                                && null != e.getHandleTime())
                        .count();
                numReject = list.stream()
                        .filter(e -> FlowNature.RejectCompletion.equals(e.getHandleStatus())
                                && null != e.getHandleTime())
                        .count();
            }
            CounterSignConfig config = nodeModel.getCounterSignConfig();

            // 判断计算方式，延后计算（在所有审批人审批完成后进行规则判断）
            int type = config.getCalculateType();
            if (ObjectUtil.equals(type, FlowNature.CALCULATE_TYPE_DELAY)) {
                int auditCount = (int) list.stream().filter(e -> null != e.getHandleStatus()).count();
                if (list.size() != auditCount) {
                    return false;
                }
            }

            int auditNum = config.getAuditNum();
            int auditRatio = config.getAuditRatio();
            int rejectNum = config.getRejectNum();
            int rejectRatio = config.getRejectRatio();

            if (config.getAuditType().equals(FlowNature.Percent)) {
                // 百分比
                int res = (int) (numAudit * 100 / list.size());
                result = res >= auditRatio;
            } else if (config.getAuditType().equals(FlowNature.Number)) {
                // 人数
                result = numAudit >= auditNum;
            }
            // 同意比例没通过，再计算拒绝的比例
            if (!result) {
                if (config.getRejectType().equals(FlowNature.Percent)) {
                    // 百分比
                    int res = (int) (numReject * 100 / list.size());
                    result = res >= rejectRatio;
                } else if (config.getRejectType().equals(FlowNature.Number)) {
                    // 人数
                    result = numReject >= rejectNum;
                } else {
                    // 同意取反
                    if (numReject > 0) {
                        if (config.getAuditType().equals(FlowNature.Percent)) {
                            int res = (int) (numReject * 100 / list.size());
                            result = res >= (100 - auditRatio);
                        } else if (config.getAuditType().equals(FlowNature.Number)) {
                            result = numReject >= (list.size() - auditNum);
                        }
                    }
                }
                if (result && ObjectUtil.equals(type, FlowNature.CALCULATE_TYPE_DELAY)) {
                    flowMethod.setHandleStatus(FlowNature.RejectCompletion);
                }
            } else {
                if (ObjectUtil.equals(type, FlowNature.CALCULATE_TYPE_DELAY)) {
                    flowMethod.setHandleStatus(FlowNature.AuditCompletion);
                }
            }
        } else if (FlowNature.ImproperApprover.equals(counterSign)) {
            // 依次审批
            if (ObjectUtil.equals(handleStatus, FlowNature.RejectCompletion)) {
                // 拒绝直接返回true，根据拒绝是否继续流转，直接结束 或 流转一下节点
                return true;
            }
            List<String> allList = StringUtil.isNotEmpty(operator.getHandleAll())
                    ? Arrays.stream(operator.getHandleAll().split(",")).collect(Collectors.toList())
                    : new ArrayList<>();

            String userId = operator.getHandleId();
            // 转审的经办，通过记录获取原来的审批人
            if (ObjectUtil.equals(operator.getStatus(), OperatorStateEnum.Transfer.getCode())) {
                RecordEntity record = recordUtil.getTransferRecord(operator.getId());
                String handleId = record.getHandleId();
                if (StringUtil.isNotBlank(handleId)) {
                    userId = handleId;
                }
            }
            int index = allList.indexOf(userId);
            // 最后一人直接返回
            if (index == allList.size() - 1) {
                return true;
            }
            if (flowMethod.getAuditFlag()) {
                return false;
            }
            String handleId = "";
            if (index != -1) {
                handleId = allList.get(index + 1);
            }
            OperatorEntity entity = this.createOperator(operator, OperatorStateEnum.Runing.getCode(), handleId, global);
            operatorService.save(entity);

            this.improperApproverMessage(flowMethod, entity);
        }
        if (result && !flowMethod.getAuditFlag()) {
            // 结束该节点的其他经办
            flowMethod.setTaskId(operator.getTaskId());
            flowMethod.setNodeCode(operator.getNodeCode());
            endOperator(flowMethod);
        }
        return result;
    }

    // 依次审批消息
    public void improperApproverMessage(FlowMethod flowMethod, OperatorEntity entity) throws WorkFlowException {
        FlowModel flowModel = flowMethod.getFlowModel();
        List<CirculateEntity> circulateList = flowMethod.getCirculateList();
        TemplateNodeEntity nodeEntity = flowMethod.getNodeEntity();
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        List<TemplateNodeEntity> nodeEntityList = flowMethod.getNodeEntityList();

        List<OperatorEntity> entityList = new ArrayList<>();
        entityList.add(entity);
        // 消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setNodeList(nodeEntityList);
        flowMsgModel.setCirculateList(circulateList);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setTaskEntity(taskEntity);
        flowMsgModel.setNodeCode(nodeEntity.getNodeCode());
        flowMsgModel.setOperatorList(entityList);
        flowMsgModel.setCopy(true);
        flowMsgModel.setApprove(true);
        flowMsgModel.setFormData(FlowContextHolder.getAllData());
        msgUtil.message(flowMsgModel);
    }

    // 结束经办
    public void endOperator(FlowMethod flowMethod) {
        String taskId = flowMethod.getTaskId();
        String nodeCode = flowMethod.getNodeCode();
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskId)
                .isNull(OperatorEntity::getHandleStatus);
        if (StringUtil.isNotEmpty(nodeCode)) {
            queryWrapper.lambda().eq(OperatorEntity::getNodeCode, nodeCode);
        }
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            for (OperatorEntity entity : list) {
                entity.setCompletion(1);
            }
            operatorService.updateBatchById(list);
        }
    }

    // 结束加签经办
    public void endAddSign(String taskId, String parentId) {
        List<OperatorEntity> list = new ArrayList<>();
        this.getAddSignChildren(parentId, list);
        if (CollectionUtil.isNotEmpty(list)) {
            operatorService.updateBatchById(list);
        }
    }

    // 撤回复原
    public void recallRestore(OperatorEntity operator, String nodeId, List<String> userIds) {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, operator.getTaskId())
                .eq(OperatorEntity::getNodeCode, operator.getNodeCode()).eq(OperatorEntity::getNodeId, nodeId)
                .eq(OperatorEntity::getCompletion, 1).isNull(OperatorEntity::getHandleTime);
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return;
        }

        List<OperatorEntity> updateList = new ArrayList<>();
        for (OperatorEntity operatorEntity : list) {
            if (ObjectUtil.equals(operatorEntity.getParentId(), operator.getParentId())) {
                updateList.add(operatorEntity);
                if (null != userIds) {
                    userIds.add(operatorEntity.getHandleId());
                }
            }
        }

        if (CollectionUtil.isNotEmpty(updateList)) {
            Date date = new Date();
            UpdateWrapper<OperatorEntity> wrapper = new UpdateWrapper<>();
            List<String> ids = updateList.stream().map(OperatorEntity::getId).collect(Collectors.toList());
            wrapper.lambda().in(OperatorEntity::getId, ids)
                    .set(OperatorEntity::getCreatorTime, date)
                    .set(OperatorEntity::getStatus, OperatorStateEnum.Runing.getCode())
                    .set(OperatorEntity::getCompletion, 0)
                    .set(OperatorEntity::getHandleStatus, null);
            operatorService.update(wrapper);
            // 作废记录
            recordUtil.invalid(updateList);
        }

        List<OperatorEntity> deleteList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(updateList)) {
            for (OperatorEntity op : updateList) {
                this.getAddSignChildren(op.getId(), deleteList);
            }
            if (CollectionUtil.isNotEmpty(deleteList)) {
                deleteList.forEach(e -> e.setStatus(OperatorStateEnum.Futility.getCode()));
                operatorService.updateBatchById(deleteList);
                // 作废记录
                recordUtil.invalid(deleteList);
            }
        }
    }

    public List<OperatorEntity> getAddSignChildren(String operatorId, List<OperatorEntity> list) {
        list = null == list ? new ArrayList<>() : list;
        List<OperatorEntity> childList = this.getChildList(operatorId);
        if (CollectionUtil.isNotEmpty(childList)) {
            for (OperatorEntity operator : childList) {
                operator.setCompletion(1);
                list.add(operator);
                this.getAddSignChildren(operator.getId(), list);
            }
        }
        return list;
    }

    // 判断自动审批
    public int checkAuto(FlowMethod flowMethod) {
        NodeModel nodeModel = flowMethod.getNodeModel();
        if (nodeModel.getHasAutoApprover()) {
            AutoAuditRule autoAuditRule = nodeModel.getAutoAuditRule();
            if (null != autoAuditRule) {
                List<ProperCond> conditions = autoAuditRule.getConditions();
                flowMethod.setConditions(conditions);
                flowMethod.setMatchLogic(autoAuditRule.getMatchLogic());
                if (conditionService.hasCondition(flowMethod)) {
                    return 1;
                }
            }
            AutoAuditRule autoRejectRule = nodeModel.getAutoRejectRule();
            if (null != autoRejectRule) {
                List<ProperCond> conditions = autoRejectRule.getConditions();
                flowMethod.setConditions(conditions);
                flowMethod.setMatchLogic(autoRejectRule.getMatchLogic());
                if (conditionService.hasCondition(flowMethod)) {
                    return 2;
                }
            }
        }
        return 3;
    }

    // 节点的自动审批
    public void autoAudit(FlowMethod flowMethod) throws Exception {
        FlowModel flowModel = flowMethod.getFlowModel();

        OperatorEntity entity = this.saveSystemOperator(flowMethod);
        if (null == entity) {
            return;
        }
        operatorService.audit(entity, flowModel);
    }

    public void autoAudit(OperatorEntity entity, FlowModel flowModel) throws Exception {
        if (null == entity || null == flowModel) {
            return;
        }
        operatorService.audit(entity, flowModel);
    }

    // 系统审批
    public void systemAudit() {
        List<SystemAuditModel> systemList = SystemAuditHolder.getAll();
        if (CollectionUtil.isNotEmpty(systemList)) {
            List<SystemAuditModel> jsonToList = JsonUtil.getJsonToList(systemList, SystemAuditModel.class);
            Map<String, NodeModel> nodes = null;
            TaskEntity taskEntity = null;

            SystemAuditHolder.clear();
            for (SystemAuditModel model : jsonToList) {
                OperatorEntity operator = model.getOperator();
                FlowModel flowModel = model.getFlowModel();
                if (null == nodes) {
                    nodes = flowModel.getNodes();
                }
                if (null == taskEntity) {
                    taskEntity = flowModel.getTaskEntity();
                }
                try {
                    this.autoAudit(operator, flowModel);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (null != taskEntity) {
                List<FlowableTaskModel> newTaskModelList = null;
                try {
                    newTaskModelList = flowAbleUrl.getCurrentTask(taskEntity.getInstanceId());
                } catch (WorkFlowException e) {
                    e.printStackTrace();
                }
                if (CollectionUtil.isNotEmpty(newTaskModelList)) {
                    taskUtil.updateCurrentNode(newTaskModelList, nodes, taskEntity);
                }
            }
        }
    }

    public OperatorEntity saveSystemOperator(FlowMethod flowMethod) {
        NodeModel nodeModel = flowMethod.getNodeModel();
        FlowModel flowModel = flowMethod.getFlowModel();

        TaskEntity taskEntity = flowModel.getTaskEntity();
        String flowableTaskId = flowModel.getFlowableTaskId();

        OperatorEntity entity = new OperatorEntity();
        entity.setStatus(OperatorStateEnum.Runing.getCode());
        entity.setCompletion(1);
        entity.setParentId("0");

        entity.setTaskId(taskEntity.getId());
        entity.setNodeCode(nodeModel.getNodeId());
        entity.setNodeId(flowableTaskId);
        entity.setNodeName(nodeModel.getNodeName());
        entity.setEngineType(taskEntity.getEngineType());

        entity.setSignTime(new Date());
        entity.setStartHandleTime(new Date());
        entity.setHandleId(FlowNature.SYSTEM_CODE);
        entity.setHandleTime(new Date());

        operatorService.save(entity);

        return entity;
    }

    // 全局属性的自动审批
    public boolean handleGlobalAuto(FlowMethod flowMethod) throws WorkFlowException {
        OperatorEntity entity = flowMethod.getOperatorEntity();
        NodeModel global = flowMethod.getNodeModel();
        FlowModel flowModel = flowMethod.getFlowModel();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        String deploymentId = flowModel.getDeploymentId();
        if (null == entity.getSignTime()) {
            entity.setSignTime(new Date());
        }

        // 自动提交规则
        AutoSubmitConfig autoSubmitConfig = global.getAutoSubmitConfig();
        // 相邻节点审批人重复
        if (autoSubmitConfig.getAdjacentNodeApproverRepeated()) {
            // 获取上一级节点编码
            List<String> nodeCodeList = new ArrayList<>();
            taskUtil.prevNodeList(deploymentId, entity.getNodeCode(), nodeEntityList, nodeCodeList);
            if (CollectionUtil.isNotEmpty(nodeCodeList)) {
                QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId())
                        .eq(OperatorEntity::getHandleId, entity.getHandleId())
                        .isNotNull(OperatorEntity::getHandleStatus)
                        .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                        .in(OperatorEntity::getNodeCode, nodeCodeList);
                long count = operatorService.count(queryWrapper);
                if (count > 0) {
                    entity.setStartHandleTime(new Date());
                    return true;
                }
            }
        }
        // 审批人审批过该流程
        if (autoSubmitConfig.getApproverHasApproval()) {
            QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId())
                    .eq(OperatorEntity::getHandleId, entity.getHandleId())
                    .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                    .isNotNull(OperatorEntity::getHandleStatus);
            long count = operatorService.count(queryWrapper);
            if (count > 0) {
                entity.setStartHandleTime(new Date());
                return true;
            }
        }
        // 发起人与审批人重复
        if (autoSubmitConfig.getInitiatorApproverRepeated()) {
            if (StringUtil.equals(taskEntity.getCreatorUserId(), entity.getHandleId())) {
                entity.setStartHandleTime(new Date());
                return true;
            }
        }
        return false;
    }

    public List<OperatorEntity> getChildList(String id) {
        QueryWrapper<OperatorEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OperatorEntity::getParentId, id)
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Assist.getCode());
        return operatorService.list(wrapper);
    }

    // 处理加签审批比例
    public void handleAddCounterSign(OperatorEntity operator, FlowModel flowModel) throws Exception {
        if (null == operator.getParentId()) {
            return;
        }
        OperatorEntity parentEntity = operatorService.getInfo(operator.getParentId());
        if (null == parentEntity) {
            return;
        }
        String handleParameter = parentEntity.getHandleParameter();
        AddSignModel addSignModel = JsonUtil.getJsonToBean(handleParameter, AddSignModel.class);
        if (null == addSignModel) {
            return;
        }
        TaskEntity taskEntity = flowModel.getTaskEntity();
        List<OperatorEntity> list = this.getChildList(operator.getParentId());

        int total = list.size();
        long countAudit = list.stream()
                .filter(e -> FlowNature.AuditCompletion.equals(e.getHandleStatus()) && null != e.getHandleTime())
                .count();
        long countReject = list.stream()
                .filter(e -> FlowNature.RejectCompletion.equals(e.getHandleStatus()) && null != e.getHandleTime())
                .count();

        FlowMethod flowMethod = new FlowMethod();
        flowMethod.setAddSignModel(addSignModel);
        flowMethod.setOperatorEntity(parentEntity);
        flowMethod.setFlowModel(flowModel);
        if (ObjectUtil.equals(addSignModel.getCounterSign(), FlowNature.ImproperApprover)) {
            if (ObjectUtil.equals(flowModel.getHandleStatus(), FlowNature.RejectCompletion)) {
                Map<String, NodeModel> nodes = flowModel.getNodes();
                NodeModel global = nodes.get(NodeEnum.global.getType());
                // 101003前加签给10001、10002、10003，不管是否开启拒绝继续流转，10001通过，10002拒绝，应该回到101003那里
                // 后加签逻辑：流程设置继续流转，依次审批中只要有人拒绝，其他审批人不用审批流程就流转下一节点；流程未设置继续流转，依次审批中只要有人拒绝，就拒绝回发起节点
                if (ObjectUtil.equals(addSignModel.getAddSignType(), FlowNature.Later)
                        && !global.getHasContinueAfterReject()) {
                    flowMethod.setTaskEntity(taskEntity);
                    taskUtil.handleEndTask(flowMethod);
                } else {
                    this.handleAddSign(flowMethod);
                }
                return;
            }
            String userId = operator.getHandleId();
            // 转审的经办，通过记录获取原来的审批人
            if (ObjectUtil.equals(operator.getStatus(), OperatorStateEnum.Transfer.getCode())) {
                RecordEntity record = recordUtil.getTransferRecord(operator.getId());
                String handleId = record.getHandleId();
                if (StringUtil.isNotBlank(handleId)) {
                    userId = handleId;
                }
            }
            List<String> idList = addSignModel.getAddSignUserIdList();
            int index = idList.indexOf(userId);
            if (index == idList.size() - 1) {
                // 依次审批最后一个人
                this.handleAddSign(flowMethod);
            } else {
                NodeModel global = flowModel.getNodes().get(NodeEnum.global.getType());
                String handleId = idList.get(index + 1);
                OperatorEntity entity = this.createOperator(operator, OperatorStateEnum.AddSign.getCode(), handleId,
                        global);
                operatorService.save(entity);
                flowMethod.setNodeEntity(flowModel.getNodeEntity());
                flowMethod.setTaskEntity(taskEntity);
                flowMethod.setNodeEntityList(flowModel.getNodeEntityList());
                this.improperApproverMessage(flowMethod, entity);
                return;
            }
        } else if (ObjectUtil.equals(addSignModel.getCounterSign(), FlowNature.FixedJointlyApprover)) {
            // 会签
            Integer ratio = addSignModel.getAuditRatio();

            int rejectRatio = 100 - ratio;
            int rejectRes = (int) (countReject * 100 / total);
            if (rejectRes != 0 && rejectRes >= rejectRatio) {
                // 直接拒绝
                flowMethod.setHandleStatus(FlowNature.RejectCompletion);
                this.handleAddSign(flowMethod);
                this.endAddSign(taskEntity.getId(), parentEntity.getId());
                return;
            }

            int res = (int) (countAudit * 100 / total);
            if (res >= ratio) {
                flowMethod.setHandleStatus(FlowNature.AuditCompletion);
                this.handleAddSign(flowMethod);
                this.endAddSign(taskEntity.getId(), parentEntity.getId());
            }
        } else {
            int auditFlag = FlowNature.AuditCompletion;
            // 或签
            if (countReject >= 1) {
                auditFlag = FlowNature.RejectCompletion;
            }
            flowMethod.setHandleStatus(auditFlag);
            this.handleAddSign(flowMethod);
            this.endAddSign(taskEntity.getId(), parentEntity.getId());
        }
        if (CollectionUtil.isNotEmpty(flowModel.getList())) {
            UserEntity userEntity = serviceUtil.getUserInfo(taskEntity.getCreatorUserId());
            if (null != userEntity) {
                FlowModel model = JsonUtil.getJsonToBean(flowModel, FlowModel.class);
                UserInfo userInfo = model.getUserInfo();
                userInfo.setUserName(userEntity.getRealName());
                userInfo.setUserAccount(userEntity.getAccount());
                userInfo.setUserId(userEntity.getId());
                model.setUserInfo(userInfo);
                for (OperatorEntity operatorEntity : flowModel.getList()) {
                    FlowJobUtil.deleteByOperatorId(operatorEntity.getId(), redisUtil);
                }
                TimeUtil.timeModel(flowModel.getList(), model, redisUtil);
                flowModel.setList(null);
            }
        }
    }

    public void handleAddSign(FlowMethod flowMethod) throws Exception {
        AddSignModel addSignModel = flowMethod.getAddSignModel();
        OperatorEntity parentEntity = flowMethod.getOperatorEntity();
        FlowModel flowModel = flowMethod.getFlowModel();
        if (addSignModel.getAddSignType().equals(FlowNature.Later)) {
            // 后加签需要默认同意
            flowModel.setHandleStatus(FlowNature.AuditCompletion);
            UserEntity userEntity = serviceUtil.getUserInfo(parentEntity.getHandleId());
            UserInfo userInfo = JsonUtil.getJsonToBean(UserProvider.getUser(), UserInfo.class);
            userInfo.setUserId(userEntity.getId());
            userInfo.setUserName(userEntity.getRealName());
            flowModel.setUserInfo(userInfo);
            flowModel.setCopyMsgFlag(false);
            parentEntity.setHandleStatus(null);
            operatorService.audit(parentEntity, flowModel);
            flowModel.setCopyMsgFlag(true);
        } else {
            UpdateWrapper<OperatorEntity> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(OperatorEntity::getId, parentEntity.getId())
                    .set(OperatorEntity::getCreatorTime, new Date())
                    .set(OperatorEntity::getCompletion, 0);
            NodeModel global = flowModel.getNodes().get(NodeEnum.global.getType());
            Boolean flowTodo = serviceUtil.getFlowTodo();
            if (!flowTodo) {
                updateWrapper.lambda().set(OperatorEntity::getStartHandleTime, null);
                Boolean flowSign = serviceUtil.getFlowSign();
                if (!flowSign) {
                    if (global != null && global.getHasSignFor()) {
                        updateWrapper.lambda().set(OperatorEntity::getSignTime, null);
                    }
                }
            }
            operatorService.update(updateWrapper);
            parentEntity = operatorService.getById(parentEntity.getId());
            // recordUtil.invalidAddSignRecord(parentEntity);
            // 超时经办
            List<OperatorEntity> list = new ArrayList<>();
            list.add(parentEntity);
            flowModel.setList(list);
        }
    }

    // 设置可减签的人员名称
    public List<ReduceUserModel> getReduceUsers(List<OperatorEntity> todoList, ReducePagination pagination) {
        List<String> ids = todoList.stream().map(OperatorEntity::getHandleId).collect(Collectors.toList());
        List<String> userIds = serviceUtil.getUserListAll(ids);

        List<UserEntity> userList = serviceUtil.getUserName(userIds, pagination);
        pagination.setTotal(pagination.getTotal());
        List<String> userIdList = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
        Map<String, List<UserRelationEntity>> userMap = serviceUtil.getListByUserIdAll(userIdList).stream()
                .filter(t -> PermissionConst.ORGANIZE.equals(t.getObjectType()))
                .collect(Collectors.groupingBy(UserRelationEntity::getUserId));

        List<ReduceUserModel> list = new ArrayList<>();
        for (UserEntity user : userList) {
            ReduceUserModel model = JsonUtil.getJsonToBean(user, ReduceUserModel.class);
            model.setFullName(user.getRealName() + "/" + user.getAccount());
            model.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
            List<UserRelationEntity> listByUserId = userMap.get(user.getId()) != null ? userMap.get(user.getId())
                    : new ArrayList<>();
            StringJoiner joiner = new StringJoiner(",");
            for (UserRelationEntity relation : listByUserId) {
                List<OrganizeEntity> organizeId = serviceUtil.getOrganizeId(relation.getObjectId());
                if (!organizeId.isEmpty()) {
                    String organizeName = organizeId.stream().map(OrganizeEntity::getFullName)
                            .collect(Collectors.joining("/"));
                    joiner.add(organizeName);
                }
            }
            model.setOrganize(joiner.toString());
            list.add(model);
        }
        return list;
    }

    // 处理退回数据，当前的经办通过计算比例后进入该方法，无需变更状态
    public void handleRejectData(FlowModel flowModel) throws WorkFlowException {
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        OperatorEntity operatorEntity = flowModel.getOperatorEntity();

        TaskEntity taskEntity = flowModel.getTaskEntity();
        String currentNodeCode = taskEntity.getCurrentNodeCode();
        // 待提交（即未发起）重新发起，需要获取当前节点
        String instanceId = taskEntity.getInstanceId();
        if (instanceId != null) {
            List<FlowableTaskModel> taskModelList = flowAbleUrl.getCurrentTask(instanceId);
            List<String> currentCodes = taskModelList.stream().map(FlowableTaskModel::getTaskKey)
                    .collect(Collectors.toList());
            currentNodeCode = String.join(",", currentCodes);
        }

        String rejectDataId = taskEntity.getRejectDataId();

        RejectDataEntity rejectData = rejectDataService.getInfo(taskEntity.getRejectDataId());
        if (!ObjectUtil.equals(rejectData.getNodeCode(), operatorEntity.getNodeCode())) {
            throw new WorkFlowException("当前节点无法操作");
        }
        String taskJson = rejectData.getTaskJson();
        String operatorJson = rejectData.getOperatorJson();

        List<OperatorEntity> srcOperatorList = JsonUtil.getJsonToList(operatorJson, OperatorEntity.class);
        // 获取被退回的节点编码，用于表单值传递
        List<String> nodeCodes = srcOperatorList.stream().sorted(Comparator.comparing(OperatorEntity::getCreatorTime))
                .map(OperatorEntity::getNodeCode).distinct().collect(Collectors.toList());

        TaskEntity srcTask = JsonUtil.getJsonToBean(taskJson, TaskEntity.class);
        String srcCurrentNodeCode = srcTask.getCurrentNodeCode();
        // 跳转
        JumpFo fo = new JumpFo();
        fo.setInstanceId(instanceId);
        List<String> sourceList = StringUtil.isNotEmpty(currentNodeCode)
                ? Arrays.stream(currentNodeCode.split(",")).collect(Collectors.toList())
                : new ArrayList<>();
        List<String> targetList = StringUtil.isNotEmpty(srcCurrentNodeCode)
                ? Arrays.stream(srcCurrentNodeCode.split(",")).collect(Collectors.toList())
                : new ArrayList<>();

        List<String> source = sourceList.stream().filter(e -> !targetList.contains(e)).collect(Collectors.toList());
        List<String> target = targetList.stream().filter(e -> !sourceList.contains(e)).collect(Collectors.toList());
        fo.setSource(source);
        fo.setTarget(target);
        flowAbleUrl.jump(fo);

        // 跳转后，获取当前的节点信息，更新经办
        List<FlowableTaskModel> taskModelList = flowAbleUrl.getCurrentTask(instanceId);
        if (CollectionUtil.isNotEmpty(taskModelList)) {
            for (OperatorEntity operator : srcOperatorList) {
                FlowableTaskModel model = taskModelList.stream()
                        .filter(e -> ObjectUtil.equals(e.getTaskKey(), operator.getNodeCode())).findFirst()
                        .orElse(null);
                if (null != model) {
                    operator.setNodeId(model.getTaskId());
                }
                operator.setCreatorTime(new Date());
            }
        }
        // 还原经办
        operatorService.updateBatchById(srcOperatorList);

        // 还原任务
        UpdateWrapper<TaskEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(TaskEntity::getId, srcTask.getId())
                .set(TaskEntity::getInstanceId, instanceId)
                .set(TaskEntity::getCurrentNodeCode, srcTask.getCurrentNodeCode())
                .set(TaskEntity::getCurrentNodeName, srcTask.getCurrentNodeName())
                .set(TaskEntity::getStatus, srcTask.getStatus())
                .set(TaskEntity::getStartTime, srcTask.getStartTime())
                .set(TaskEntity::getRejectDataId, null);
        taskService.update(updateWrapper);

        // 赋值更新后的任务
        flowModel.setTaskEntity(srcTask);

        rejectDataService.removeById(rejectDataId);

        // 处理表单值传递
        for (TemplateNodeEntity nodeEntity : nodeEntityList) {
            if (nodeCodes.contains(nodeEntity.getNodeCode())) {
                FlowMethod flowMethod = new FlowMethod();
                flowMethod.setTaskEntity(taskEntity);
                flowMethod.setNodeEntity(nodeEntity);
                flowMethod.setNodeEntityList(nodeEntityList);
                flowMethod.setFlowModel(flowModel);
                flowMethod.setIsAssign(true);
                flowMethod.setIsData(true);
                taskUtil.dataTransfer(flowMethod);
            }
        }
    }

    // 获取任务 节点下的经办
    public List<OperatorEntity> getByNodeCode(String taskId, String nodeCode) {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskId)
                .eq(OperatorEntity::getNodeCode, nodeCode)
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode());
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            return list;
        }
        return new ArrayList<>();
    }

    // 处理指派
    public OperatorEntity handleAssign(FlowModel flowModel) throws WorkFlowException {
        TaskEntity taskEntity = flowModel.getTaskEntity();
        NodeModel global = flowModel.getNodes().get(NodeEnum.global.getType());
        String nodeCode = flowModel.getNodeCode();
        String assignUserId = flowModel.getHandleIds();
        NodeModel nodeModel = flowModel.getNodes().get(nodeCode);
        Integer transferState = ObjectUtil.equals(nodeModel.getType(), NodeEnum.processing.getType())
                ? OperatorStateEnum.TransferProcessing.getCode()
                : OperatorStateEnum.Transfer.getCode();

        Integer state = flowModel.getAutoTransferFlag() ? transferState : OperatorStateEnum.Assigned.getCode();

        List<OperatorEntity> operatorList = this.getByNodeCode(taskEntity.getId(), nodeCode);
        if (CollectionUtil.isNotEmpty(operatorList)) {
            // 作废记录
            recordUtil.invalid(operatorList);
            // 删除原来的经办
            operatorService.removeByIds(operatorList);

            OperatorEntity operator = operatorList.get(0);
            operator.setParentId("0");
            // 生成指派经办
            OperatorEntity entity = this.createOperator(operator, state, assignUserId, global);

            operatorService.save(entity);
            return entity;
        } else {
            OperatorEntity entity = new OperatorEntity();
            entity.setId(RandomUtil.uuId());
            NodeModel node = flowModel.getNodes().get(nodeCode);
            entity.setNodeName(node.getNodeName());
            List<FlowableTaskModel> currentTask = flowAbleUrl.getCurrentTask(taskEntity.getInstanceId());
            FlowableTaskModel model = currentTask.stream().filter(e -> e.getTaskKey().equals(nodeCode)).findFirst()
                    .orElse(null);
            if (null == model) {
                throw new WorkFlowException(MsgCode.FA001.get());
            }
            entity.setNodeId(model.getTaskId());
            entity.setNodeCode(nodeCode);
            entity.setStatus(state);
            entity.setTaskId(taskEntity.getId());
            entity.setEngineType(taskEntity.getEngineType());
            Boolean flowTodo = serviceUtil.getFlowTodo();
            if (flowTodo) {
                entity.setSignTime(new Date());
                entity.setStartHandleTime(new Date());
            } else {
                Boolean flowSign = serviceUtil.getFlowSign();
                if (flowSign) {
                    entity.setSignTime(new Date());
                } else {
                    if (global != null && !global.getHasSignFor()) {
                        entity.setSignTime(new Date());
                    }
                }
            }
            if (node.getCounterSign().equals(FlowNature.ImproperApprover)) {
                entity.setHandleAll(assignUserId);
            }
            entity.setHandleId(assignUserId);
            entity.setParentId("0");
            entity.setCompletion(0);
            operatorService.save(entity);
            return entity;
        }
    }

    public void handleRevoke(FlowModel flowModel, OperatorEntity operator, RevokeEntity revokeEntity) throws Exception {
        TaskEntity taskEntity = flowModel.getTaskEntity();
        Integer handleStatus = flowModel.getHandleStatus();
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> StringUtil.equals(e.getNodeCode(), operator.getNodeCode())).findFirst().orElse(null);

        FlowMethod flowMethod = new FlowMethod();
        flowMethod.setNodeEntity(nodeEntity);

        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setFormData(FlowContextHolder.getAllData());
        flowMsgModel.setNodeList(nodeEntityList);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setTaskEntity(taskEntity);
        flowMsgModel.setNodeCode(operator.getNodeCode());
        flowMsgModel.setWait(false);
        List<OperatorEntity> operatorList = new ArrayList<>();
        OperatorEntity entity = new OperatorEntity();
        entity.setNodeCode(operator.getNodeCode());
        entity.setHandleId(taskEntity.getCreatorUserId());
        operatorList.add(entity);
        flowMsgModel.setOperatorList(operatorList);

        TaskEntity task = taskService.getById(revokeEntity.getTaskId());
        boolean endFlag = false;
        if (ObjectUtil.equals(handleStatus, FlowNature.AuditCompletion)) {
            flowMsgModel.setApprove(true);
            // 消息
            msgUtil.message(flowMsgModel);
            operator.setHandleStatus(FlowNature.AuditCompletion);
            flowMethod.setType(RecordEnum.audit.getCode());
        } else {
            operator.setHandleStatus(FlowNature.RejectCompletion);
            flowMethod.setType(RecordEnum.reject.getCode());
            // 结束
            endFlag = true;
        }

        // 经办记录
        flowMethod.setFlowModel(flowModel);
        flowMethod.setOperatorEntity(operator);
        recordUtil.createRecord(flowMethod);

        operator.setHandleTime(new Date());
        operator.setCompletion(1);
        operatorService.updateById(operator);

        flowMethod.setTaskEntity(taskEntity);
        List<CirculateEntity> circulateList = circulateUtil.circulateList(flowMethod);
        flowMethod.setCirculateList(circulateList);

        if (endFlag) {
            flowMethod.setIsRevoke(true);
            taskUtil.handleEndTask(flowMethod);
            revokeService.deleteRevoke(taskEntity.getId());
            return;
        }
        // 判断撤销经办的比例
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, operator.getTaskId())
                .eq(OperatorEntity::getNodeCode, operator.getNodeCode())
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode());
        List<OperatorEntity> list = operatorService.list(queryWrapper);

        long count = list.stream().filter(e -> ObjectUtil.equals(e.getHandleStatus(), FlowNature.AuditCompletion))
                .count();
        if (count == list.size()) {
            // 节点记录
            NodeRecordModel nodeRecordModel = new NodeRecordModel();
            nodeRecordModel.setTaskId(operator.getTaskId());
            nodeRecordModel.setNodeId(operator.getNodeId());
            nodeRecordModel.setNodeCode(operator.getNodeCode());
            nodeRecordModel.setNodeName(operator.getNodeName());
            nodeRecordModel.setNodeStatus(2);
            nodeRecordService.create(nodeRecordModel);

            // 节点通过
            CompleteFo fo = new CompleteFo();
            fo.setTaskId(operator.getNodeId());
            flowAbleUrl.complete(fo);

            flowMethod.setTaskId(revokeEntity.getTaskId());
            flowMethod.setTaskEntity(taskEntity);
            this.handleRevokeOperator(flowMethod);

            // 判断结束，更新源任务的状态
            if (taskUtil.isFinished(flowModel)) {
                if (null != task) {
                    taskUtil.endRevoke(task);
                }
            }

        }
    }

    public OperatorEntity createOperator(OperatorEntity operator, Integer state, String handleId, NodeModel global) {
        OperatorEntity entity = new OperatorEntity();
        entity.setId(RandomUtil.uuId());
        entity.setNodeName(operator.getNodeName());
        entity.setNodeId(operator.getNodeId());
        entity.setNodeCode(operator.getNodeCode());
        entity.setStatus(state);
        entity.setTaskId(operator.getTaskId());
        entity.setIsProcessing(operator.getIsProcessing());
        entity.setEngineType(operator.getEngineType());
        Boolean flowTodo = serviceUtil.getFlowTodo();
        if (flowTodo) {
            entity.setSignTime(new Date());
            entity.setStartHandleTime(new Date());
        } else {
            Boolean flowSign = serviceUtil.getFlowSign();
            if (flowSign) {
                entity.setSignTime(new Date());
            } else {
                if (global != null && !global.getHasSignFor()) {
                    entity.setSignTime(new Date());
                }
            }
        }
        entity.setHandleId(handleId);
        entity.setHandleAll(operator.getHandleAll());
        entity.setParentId(operator.getParentId());
        entity.setCompletion(0);
        return entity;
    }

    // 处理子流程
    public void handleSubFlow(TemplateNodeEntity nodeEntity, FlowModel flowModel) throws Exception {
        if (!nodeEntity.getNodeType().equals(NodeEnum.subFlow.getType())) {
            return;
        }
        NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        Map<String, List<String>> errorRuleUserList = flowModel.getErrorRuleUserList();

        String templateId = nodeModel.getFlowId();
        TemplateEntity template = templateService.getById(templateId);
        if (null == template) {
            return;
        }
        if (!ObjectUtil.equals(template.getStatus(), 1)) {
            throw new WorkFlowException(MsgCode.WF140.get());
        }
        String flowId = template.getFlowId();

        TemplateJsonEntity jsonEntity = templateJsonService.getById(flowId);
        if (null == jsonEntity) {
            return;
        }
        List<TemplateNodeEntity> subNodeEntityList = templateNodeService.getList(jsonEntity.getId());
        Map<String, NodeModel> subNodes = new HashMap<>();
        for (TemplateNodeEntity node : subNodeEntityList) {
            subNodes.put(node.getNodeCode(), JsonUtil.getJsonToBean(node.getNodeJson(), NodeModel.class));
        }
        FlowMethod method = new FlowMethod();
        method.setDeploymentId(jsonEntity.getFlowableId());
        TemplateNodeEntity subStart = subNodeEntityList.stream()
                .filter(e -> StringUtil.equals(NodeEnum.start.getType(), e.getNodeType())).findFirst()
                .orElse(new TemplateNodeEntity());
        method.setNodeCode(subStart.getNodeCode());
        method.setNodes(subNodes);
        method.setNodeEntityList(subNodeEntityList);

        List<NodeModel> nextApprover = taskUtil.getNextApprover(method);
        boolean autoSubmit = ObjectUtil.equals(nodeModel.getAutoSubmit(), 1);
        if (autoSubmit) {
            if (taskUtil.checkBranch(subStart)) {
                throw new WorkFlowException(MsgCode.WF121.get());
            }
            if (!taskUtil.checkNextCandidates(nextApprover)) {
                throw new WorkFlowException(MsgCode.WF121.get());
            }
        }

        String nodeCode = nodeModel.getNodeId();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        String deploymentId = flowModel.getDeploymentId();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        String flowableTaskId = flowModel.getFlowableTaskId();

        FlowMethod flowMethod = new FlowMethod();
        flowMethod.setFlowModel(flowModel);
        flowMethod.setTaskEntity(taskEntity);
        flowMethod.setNodeEntity(nodeEntity);
        flowMethod.setNodeEntityList(nodeEntityList);
        flowMethod.setErrorRule(true);
        flowMethod.setExtraRule(true);
        // 获取上一级节点
        List<String> nodeCodeList = new ArrayList<>();
        taskUtil.prevNodeList(deploymentId, nodeCode, nodeEntityList, nodeCodeList);
        nodeCodeList = nodeCodeList.stream().distinct().collect(Collectors.toList());
        String parentCode;
        if (nodeCodeList.size() == 1) {
            parentCode = nodeCodeList.get(0);
        } else if (nodeCodeList.size() > 1) {
            // 如果子流程是合流节点 就存最后一个审批的分流节点
            QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId())
                    .in(OperatorEntity::getNodeCode, nodeCodeList).isNotNull(OperatorEntity::getHandleStatus)
                    .orderByDesc(OperatorEntity::getHandleTime);
            List<OperatorEntity> list = operatorService.list(queryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                parentCode = list.get(0).getNodeCode();
            } else {
                parentCode = null;
            }
        } else {
            TemplateNodeEntity startNode = nodeEntityList.stream()
                    .filter(e -> StringUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst()
                    .orElse(new TemplateNodeEntity());
            parentCode = startNode.getNodeCode();
        }
        TemplateNodeEntity parentNode = nodeEntityList.stream()
                .filter(e -> StringUtil.equals(e.getNodeCode(), parentCode)).findFirst()
                .orElse(new TemplateNodeEntity());
        String formId = parentNode.getFormId();
        Map<String, Boolean> resMap = new HashMap<>();
        Map<String, Map<String, Object>> allData = FlowContextHolder.getAllData();
        Map<String, Object> formData = allData.get(taskEntity.getId() + "_yunzhupaas_" + formId);
        if (nodeModel.getIsAsync().equals(FlowNature.ChildAsync)) {
            flowMethod.setDeploymentId(deploymentId);
            flowMethod.setNodeCode(nodeCode);
            flowMethod.setFormData(formData);
            flowMethod.setNodes(nodes);
            flowMethod.setTaskEntity(taskEntity);
            resMap = conditionService.handleCondition(flowMethod);
            conditionService.checkCondition(resMap, nodes);
        }
        // 表单数据传递
        flowMethod.setIsAssign(true);
        flowMethod.setIsData(true);
        formData = taskUtil.createOrUpdate(flowMethod);
        flowMethod.setSubFormData(formData);

        List<String> userIds = taskUtil.userListAll(flowMethod);
        List<UserEntity> userList = serviceUtil.getUserName(userIds, true);
        if (userList.isEmpty()) {
            userIds.add(serviceUtil.getAdmin());
        }

        Integer createRule = nodeModel.getCreateRule();
        boolean inTurn = ObjectUtil.equals(createRule, 1);
        int flag = 0;
        List<FlowModel> subTaskData = new ArrayList<>();

        UserInfo userInfo = flowModel.getUserInfo();

        for (UserEntity user : userList) {
            flag++;
            FlowModel model = new FlowModel();
            model.setSubCode(nodeCode);
            model.setParentId(taskEntity.getId());
            model.setDeploymentId(jsonEntity.getFlowableId());

            Map<String, Object> map = new HashMap<>();
            if (CollectionUtil.isNotEmpty(formData)) {
                map = new HashMap<>(formData);
            }
            map.put(FlowFormConstant.FLOWID, flowId);
            model.setFormData(map);
            model.setFlowId(flowId);
            model.setErrorRuleUserList(errorRuleUserList);

            // 自动提交 0.否
            if (autoSubmit) {
                model.setStatus(1);
            } else {
                model.setSubFlow(true);
            }

            SubParameterModel subParameter = new SubParameterModel();
            subParameter.setParentCode(parentCode);
            subParameter.setNodeId(flowableTaskId);
            model.setSubParameter(subParameter);

            UserInfo info = JsonUtil.getJsonToBean(userInfo, UserInfo.class);
            info.setUserName(user.getRealName());
            info.setUserAccount(user.getAccount());
            info.setUserId(user.getId());
            model.setUserInfo(info);

            model.setIsAsync(nodeModel.getIsAsync());
            model.setIsFlow(1);

            TaskEntity subTask = new TaskEntity();
            subTask.setCreatorUserId(user.getId());
            model.setTaskEntity(subTask);

            // 依次创建，只创建第一个人的，存储后续的人员参数
            if (inTurn && flag > 1) {
                subTaskData.add(model);
                continue;
            }

            if (nodeModel.getAutoSubmit().equals(1)) {
                model.setNodeEntityList(subNodeEntityList);
                if (taskUtil.checkNextError(model, nextApprover, false, false) != 0) {
                    throw new WorkFlowException(MsgCode.WF121.get());
                }
            }

            UserProvider.setLocalLoginUser(info);
            // 生成任务，根据是否自动发起进行提交
            taskService.saveOrSubmit(model);

            // 组装消息发送的人
            OperatorEntity operator = new OperatorEntity();
            operator.setHandleId(user.getId());
            operator.setNodeCode(nodeEntity.getNodeCode());
            // 子流程任务
            TaskEntity task = model.getTaskEntity();
            operator.setTaskId(task.getId());

            List<OperatorEntity> operatorList = new ArrayList<>();
            operatorList.add(operator);

            // 消息
            if (ObjectUtil.equals(nodeModel.getAutoSubmit(), 0)) {
                FlowMsgModel flowMsgModel = new FlowMsgModel();
                flowMsgModel.setOperatorList(operatorList);
                flowMsgModel.setNodeList(nodeEntityList);
                flowMsgModel.setFlowModel(flowModel);
                flowMsgModel.setTaskEntity(task);
                flowMsgModel.setNodeCode(nodeCode);
                flowMsgModel.setWait(false);
                flowMsgModel.setLaunch(true);
                flowMsgModel.setFormData(FlowContextHolder.getAllData());
                msgUtil.message(flowMsgModel);
            }
            this.autoAudit(model);
        }
        UserProvider.setLocalLoginUser(userInfo);
        // 保存依次创建的子流程数据
        subtaskDataService.save(subTaskData);

        // 异步，直接通过节点，后续继续递归下一级节点生成经办
        if (nodeModel.getIsAsync().equals(FlowNature.ChildAsync)) {
            flowMethod.setFlowableTaskId(flowableTaskId);
            flowMethod.setResMap(resMap);
            completeNode(flowMethod);
        }
    }

    // 完成节点
    public void completeNode(FlowMethod flowMethod) throws Exception {
        FlowModel flowModel = flowMethod.getFlowModel();
        String flowableTaskId = flowMethod.getFlowableTaskId();
        Map<String, Boolean> resMap = flowMethod.getResMap();
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        taskLineService.create(taskEntity.getId(), resMap);
        CompleteFo completeFo = new CompleteFo();
        completeFo.setTaskId(flowableTaskId);
        completeFo.setVariables(new HashMap<>(resMap));
        flowAbleUrl.complete(completeFo);

        if (taskUtil.isFinished(flowModel)) {
            return;
        }

        // 生成经办
        List<OperatorEntity> operatorEntities = operatorService.handleOperator(flowModel);

        List<TemplateNodeEntity> nodeEntityList = flowMethod.getNodeEntityList();
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setNodeList(nodeEntityList);
        flowMsgModel.setTaskEntity(taskEntity);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setOperatorList(operatorEntities);
        flowMsgModel.setFormData(FlowContextHolder.getAllData());
        msgUtil.message(flowMsgModel);

        if (taskEntity.getRejectDataId() == null) {
            this.autoAudit(flowModel);
        }
    }

    public void autoAudit(FlowModel flowModel) throws Exception {
        this.autoAudit(flowModel, true);
    }

    public void autoAudit(FlowModel flowModel, Boolean flag) throws Exception {
        TaskEntity taskEntity = flowModel.getTaskEntity();
        if (null == taskEntity) {
            return;
        }
        flowModel.setBranchList(new ArrayList<>());
        String taskId = taskEntity.getId();
        List<OperatorEntity> operatorList = operatorService.getList(taskId);
        operatorList = operatorList.stream()
                .filter(e -> !ObjectUtil.equals(e.getStatus(), OperatorStateEnum.Back.getCode())
                        && !ObjectUtil.equals(e.getCompletion(), 1))
                .collect(Collectors.toList());
        this.autoAudit(flowModel, operatorList, flag);
    }

    @DSTransactional
    public void autoAudit(FlowModel flowModel, List<OperatorEntity> operatorList, Boolean flag) throws Exception {
        // flag标识为true时 需要排除未激活的经办
        if (flag) {
            operatorList = operatorList.stream()
                    .filter(e -> !ObjectUtil.equals(e.getStatus(), OperatorStateEnum.Waiting.getCode()))
                    .collect(Collectors.toList());
        }
        if (CollectionUtil.isEmpty(operatorList)) {
            return;
        }
        String deploymentId = flowModel.getDeploymentId();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        NodeModel global = nodes.get(NodeEnum.global.getType());
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        TemplateNodeEntity globalEntity = nodeEntityList.stream()
                .filter(e -> StringUtil.equals(NodeEnum.global.getType(), e.getNodeType())).findFirst()
                .orElse(new TemplateNodeEntity());

        AutoSubmitConfig autoConfig = global.getAutoSubmitConfig();
        if (!autoConfig.getApproverHasApproval() && !autoConfig.getInitiatorApproverRepeated()
                && !autoConfig.getAdjacentNodeApproverRepeated()) {
            // 先判断自动审批，未开启直接返回
            return;
        }
        flowModel.setSignImg(null);
        flowModel.setFileList(null);
        Map<String, List<OperatorEntity>> map = operatorList.stream()
                .collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
        List<String> handleIds = operatorList.stream().map(OperatorEntity::getHandleId).distinct()
                .collect(Collectors.toList());
        List<UserEntity> users = serviceUtil.getUserName(handleIds);
        for (String key : map.keySet()) {
            NodeModel model = nodes.get(key);
            Map<String, Map<String, Object>> allData = FlowContextHolder.getAllData();
            String modelFormId = model.getFormId();
            modelFormId = StringUtil.isNotBlank(modelFormId) ? modelFormId : globalEntity.getFormId();
            Map<String, Object> formData = allData.get(taskEntity.getId() + "_yunzhupaas_" + modelFormId);
            // 获取流程参数
            taskUtil.getGlobalParam(taskEntity, model, global, formData);
            flowModel.setTaskEntity(taskEntity);
            FlowMethod flowMethod = new FlowMethod();
            flowMethod.setTaskEntity(taskEntity);
            flowMethod.setFormData(formData == null ? new HashMap<>() : formData);
            flowMethod.setDeploymentId(deploymentId);
            flowMethod.setNodeCode(key);
            flowMethod.setNodes(nodes);
            // 判断节点的线的条件
            Map<String, Boolean> resMap = conditionService.handleCondition(flowMethod);
            try {
                conditionService.checkCondition(resMap, nodes);
            } catch (WorkFlowException e) {
                continue;
            }
            List<NodeModel> nextApprover;
            boolean mark = true;
            try {
                nextApprover = taskUtil.getNextApprover(flowMethod);
            } catch (WorkFlowException e) {
                nextApprover = null;
                mark = false;
            }
            if (!mark) {
                continue;
            }
            List<OperatorEntity> list = map.get(key);
            if (CollectionUtil.isNotEmpty(list)) {
                flowModel.setOperatorEntity(list.get(0));
            }
            boolean isBranch = taskUtil.checkBranch(model);
            boolean nextCandidates = taskUtil.checkNextCandidates(nextApprover);
            int nextError = taskUtil.checkNextError(flowModel, nextApprover, false, false);
            if (!isBranch && nextCandidates && nextError == 0) {
                for (OperatorEntity operator : list) {
                    operator = operatorService.getById(operator.getId());
                    if (null == operator || ObjectUtil.equals(operator.getCompletion(), 1)) {
                        continue;
                    }
                    String handleId = operator.getHandleId();
                    String username = "";
                    String userId = "";
                    String userName = "";
                    String userAccount = "";
                    UserEntity user = users.stream().filter(e -> ObjectUtil.equals(e.getId(), handleId)).findFirst()
                            .orElse(null);
                    if (user != null) {
                        username = user.getAccount() + "(" + user.getRealName() + ")";
                        userId = user.getId();
                        userName = user.getRealName();
                        userAccount = user.getAccount();
                    }
                    String str = ObjectUtil.equals(operator.getIsProcessing(), 0) ? "自动审批通过" : "自动办理通过";
                    flowModel.setHandleOpinion(username + str);
                    FlowMethod method = new FlowMethod();
                    method.setOperatorEntity(operator);
                    method.setNodeModel(global);
                    method.setFlowModel(flowModel);
                    if (this.handleGlobalAuto(method)) {
                        if (taskEntity.getEndTime() != null) {
                            return;
                        }
                        UserInfo userInfo = flowModel.getUserInfo();
                        userInfo.setUserId(userId);
                        userInfo.setUserAccount(userAccount);
                        userInfo.setUserName(userName);
                        flowModel.setUserInfo(userInfo);
                        flowModel.setHandleStatus(FlowNature.AuditCompletion);
                        operatorService.audit(operator, flowModel);
                        if (taskEntity.getRejectDataId() == null) {
                            this.autoAudit(flowModel);
                        }
                    }
                }
            }
        }
    }

    // 异常补偿
    public void compensate(TaskEntity taskEntity) throws WorkFlowException {
        String instanceId = taskEntity.getInstanceId();
        CompensateFo fo = new CompensateFo();
        fo.setInstanceId(instanceId);
        List<String> sourceList = Arrays.stream(taskEntity.getCurrentNodeCode().split(","))
                .collect(Collectors.toList());
        fo.setSource(sourceList);
        List<FlowableTaskModel> models = flowAbleUrl.compensate(fo);

        if (CollectionUtil.isNotEmpty(models)) {
            FlowableTaskModel flowableTaskModel = models.get(0);
            // 实例ID不一样，更新
            String newInstanceId = flowableTaskModel.getInstanceId();
            if (StringUtil.isNotBlank(newInstanceId) && !instanceId.equals(newInstanceId)) {
                taskEntity.setInstanceId(newInstanceId);
                taskService.updateById(taskEntity);
            }
            List<NodeRecordEntity> nodeRecords = recordUtil.getNodeRecord(taskEntity.getId());
            List<String> nodeIds = nodeRecords.stream().map(NodeRecordEntity::getNodeId).filter(StringUtil::isNotBlank)
                    .collect(Collectors.toList());
            // 更新经办关联的flowable的任务id
            List<OperatorEntity> operatorList = this.getList(taskEntity.getId());
            List<OperatorEntity> updateList = new ArrayList<>();
            // 更新记录关联的flowable的任务id
            List<RecordEntity> recordList = recordUtil.getList(taskEntity.getId());
            List<RecordEntity> updateRecordList = new ArrayList<>();

            if (CollectionUtil.isNotEmpty(nodeIds)) {
                // 在节点记录中的存在的nodeId，不需要更新
                operatorList = operatorList.stream().filter(e -> !nodeIds.contains(e.getNodeId()))
                        .collect(Collectors.toList());
                recordList = recordList.stream().filter(e -> !nodeIds.contains(e.getNodeId()))
                        .collect(Collectors.toList());
            }

            for (FlowableTaskModel model : models) {
                List<OperatorEntity> list = operatorList.stream()
                        .filter(e -> e.getNodeCode().equals(model.getTaskKey())).collect(Collectors.toList());
                list.forEach(e -> e.setNodeId(model.getTaskId()));
                updateList.addAll(list);
                // 记录修改
                List<RecordEntity> collect = recordList.stream()
                        .filter(e -> e.getNodeCode().equals(model.getTaskKey())).collect(Collectors.toList());
                collect.forEach(e -> e.setNodeId(model.getTaskId()));
                updateRecordList.addAll(collect);
            }
            operatorService.updateBatchById(updateList);
            recordUtil.updateRecords(updateRecordList);
        }
        if (!ObjectUtil.equals(taskEntity.getParentId(), "0")) {
            TaskEntity parent = taskService.getById(taskEntity.getParentId());
            if (null == parent) {
                return;
            }
            this.compensate(parent);
            List<FlowableTaskModel> currentModel = flowAbleUrl.getCurrentTask(parent.getInstanceId());
            FlowableTaskModel model = currentModel.stream()
                    .filter(e -> ObjectUtil.equals(taskEntity.getSubCode(), e.getTaskKey())).findFirst().orElse(null);
            if (null != model) {
                SubParameterModel subParameter = JsonUtil.getJsonToBean(taskEntity.getSubParameter(),
                        SubParameterModel.class);
                subParameter.setNodeId(model.getTaskId());
                taskEntity.setSubParameter(JsonUtil.getObjectToString(subParameter));
                taskService.updateById(taskEntity);
            }
        }
    }

    // 设置异常处理
    public void handleErrorRule(NodeModel nodeModel, List<FlowErrorModel> errorList) {
        if (null == nodeModel) {
            return;
        }
        FlowErrorModel errorModel = new FlowErrorModel();
        errorModel.setNodeCode(nodeModel.getNodeId());
        errorModel.setNodeName(nodeModel.getNodeName());
        errorList.add(errorModel);
    }

    /**
     * 校验经办的任务是否暂停
     *
     * @param ids     经办主键集合
     * @param resList 结果经办主键集合
     * @param flag    true则判断退签
     */
    public void checkBatch(List<String> ids, List<String> resList, Boolean flag) throws WorkFlowException {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(OperatorEntity::getId, ids);
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        List<String> taskIds = list.stream().map(OperatorEntity::getTaskId).collect(Collectors.toList());
        List<TaskEntity> taskEntityList = taskIds.isEmpty() ? new ArrayList<>() : taskService.listByIds(taskIds);

        for (OperatorEntity operator : list) {
            TaskEntity taskEntity = taskEntityList.stream()
                    .filter(e -> !Objects.equals(e.getStatus(), TaskStatusEnum.PAUSED.getCode())
                            && e.getId().equals(operator.getTaskId()))
                    .findFirst().orElse(null);
            if (null != taskEntity) {
                resList.add(operator.getId());
            }
        }
        if (CollectionUtil.isEmpty(resList)) {
            throw new WorkFlowException(MsgCode.WF112.get());
        }

        if (flag) {
            resList.clear();
            List<String> flowIds = taskEntityList.stream().map(TaskEntity::getFlowId).collect(Collectors.toList());
            List<TemplateNodeEntity> globalList = templateNodeService.getList(flowIds, NodeEnum.global.getType());
            for (OperatorEntity operator : list) {
                TaskEntity taskEntity = taskEntityList.stream()
                        .filter(e -> e.getId().equals(operator.getTaskId())).findFirst().orElse(null);
                if (null != taskEntity) {
                    TemplateNodeEntity globalEntity = globalList.stream()
                            .filter(e -> e.getFlowId().equals(taskEntity.getFlowId())).findFirst().orElse(null);
                    if (null != globalEntity) {
                        NodeModel global = JsonUtil.getJsonToBean(globalEntity.getNodeJson(), NodeModel.class);
                        // 开启签收，允许退签
                        if (global.getHasSignFor()) {
                            resList.add(operator.getId());
                        }
                    }
                }
            }
            if (CollectionUtil.isEmpty(resList)) {
                throw new WorkFlowException(MsgCode.WF080.get());
            }
        }
    }

    public void checkBatchRevoke(List<String> ids, List<String> resList, Integer batchType) throws WorkFlowException {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(OperatorEntity::getId, ids);
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        List<Integer> status = ImmutableList.of(2, 3);
        for (OperatorEntity operator : list) {
            if (status.contains(batchType)
                    && ObjectUtil.equals(operator.getStatus(), OperatorStateEnum.Revoke.getCode())) {
                continue;
            }
            resList.add(operator.getId());
        }
        if (CollectionUtil.isEmpty(resList)) {
            if (ObjectUtil.equals(batchType, 2)) {
                throw new WorkFlowException(MsgCode.WF126.get());
            } else if (ObjectUtil.equals(batchType, 3)) {
                throw new WorkFlowException(MsgCode.WF127.get());
            }
        }
    }

    // 判断终止
    public void checkCancel(List<String> ids, List<String> resList) throws WorkFlowException {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(OperatorEntity::getId, ids);
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        List<String> taskIds = list.stream().map(OperatorEntity::getTaskId).collect(Collectors.toList());
        List<TaskEntity> taskEntityList = taskIds.isEmpty() ? new ArrayList<>() : taskService.listByIds(taskIds);

        for (OperatorEntity operator : list) {
            TaskEntity taskEntity = taskEntityList.stream()
                    .filter(e -> !Objects.equals(e.getStatus(), TaskStatusEnum.CANCEL.getCode())
                            && e.getId().equals(operator.getTaskId()))
                    .findFirst().orElse(null);
            if (null != taskEntity) {
                resList.add(operator.getId());
            }
        }
        if (CollectionUtil.isEmpty(resList)) {
            throw new WorkFlowException(MsgCode.WF123.get());
        }
    }

    // 更新经办的接收时间
    public void updateCreateTime(FlowModel flowModel) {
        TaskEntity taskEntity = flowModel.getTaskEntity();
        String taskId = taskEntity.getId();
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskId)
                .isNull(OperatorEntity::getHandleStatus);
        List<OperatorEntity> list = operatorService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            list.forEach(e -> e.setCreatorTime(new Date()));
            operatorService.updateBatchById(list);
            TimeUtil.timeModel(list, flowModel, redisUtil);
        }
    }

    // 添加事件到线程变量
    public void addEvent(FlowModel flowModel) {
        Integer status = flowModel.getEventStatus();
        FlowModel model = new FlowModel();
        model.setTaskEntity(flowModel.getTaskEntity());
        model.setNodeEntity(flowModel.getNodeEntity());
        model.setNodes(flowModel.getNodes());
        model.setFormData(flowModel.getFormData());
        if (ObjectUtil.equals(2, status)) {
            List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
            TemplateNodeEntity start = nodeEntityList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst().orElse(null);
            if (null != start) {
                model.setNodeEntity(start);
            }
        }
        FlowEventHolder.addEvent(status, model, FlowContextHolder.getAllData());
    }

    // 处理线程变量中的事件
    public void handleEvent() throws WorkFlowException {
        List<EventModel> allEvent = FlowEventHolder.getAllEvent();
        for (EventModel eventModel : allEvent) {
            this.event(eventModel.getFlowModel(), eventModel.getStatus(), eventModel.getAllData());
        }
        FlowEventHolder.clear();
    }

    // 事件
    public void event(FlowModel flowModel, Integer status, Map<String, Map<String, Object>> allData)
            throws WorkFlowException {
        FlowModel model = JsonUtil.getJsonToBean(flowModel, FlowModel.class);
        TemplateNodeEntity nodeEntity = model.getNodeEntity();
        NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
        RecordEntity record = new RecordEntity();
        record.setNodeCode(nodeModel.getNodeId());
        // 结束事件
        if (ObjectUtil.equals(status, 2)) {
            List<TemplateNodeEntity> nodeEntityList = model.getNodeEntityList();
            TemplateNodeEntity start = nodeEntityList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst().orElse(null);
            if (null != start) {
                nodeModel = JsonUtil.getJsonToBean(start.getNodeJson(), NodeModel.class);
            }
        }
        TaskEntity taskEntity = model.getTaskEntity();
        String formId = nodeEntity.getFormId();
        String taskId = taskEntity.getId();
        Map<String, Object> map = allData.get(taskId + "_yunzhupaas_" + formId) != null
                ? allData.get(taskId + "_yunzhupaas_" + formId)
                : serviceUtil.infoData(formId, taskId);
        model.setFormData(map);
        msgUtil.event(status, nodeModel, record, model);
    }

    // 事件
    public void event(FlowModel flowModel, Integer status) throws WorkFlowException {
        event(flowModel, status, new HashMap<>());
    }

    public List<OperatorEntity> getList(String taskId, List<String> nodeCodes) {
        if (StringUtil.isEmpty(taskId)) {
            return new ArrayList<>();
        }
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskId).ne(OperatorEntity::getStatus,
                OperatorStateEnum.Futility.getCode());
        if (CollectionUtil.isNotEmpty(nodeCodes)) {
            queryWrapper.lambda().in(OperatorEntity::getNodeCode, nodeCodes);
        }
        queryWrapper.lambda().orderByDesc(OperatorEntity::getCreatorTime);
        return operatorService.list(queryWrapper);
    }

    public void deleteInTurnOperator(OperatorEntity operator, String handleId) {
        List<String> handleAll = new ArrayList<>();
        if (operator.getHandleAll() != null) {
            handleAll = Arrays.stream(operator.getHandleAll().split(",")).collect(Collectors.toList());
        } else {
            String handleParameter = operator.getHandleParameter();
            AddSignModel addSignModel = JsonUtil.getJsonToBean(handleParameter, AddSignModel.class);
            if (ObjectUtil.equals(addSignModel.getCounterSign(), 2)) {
                handleAll = addSignModel.getAddSignUserIdList();
            }
        }
        int index = handleAll.indexOf(handleId);
        if (index != -1 && index < handleAll.size() - 1) {
            String nextHandleId = handleAll.get(index + 1);
            QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OperatorEntity::getNodeId, operator.getNodeId())
                    .eq(OperatorEntity::getHandleId, nextHandleId);
            List<OperatorEntity> deleteList = operatorService.list(queryWrapper);
            if (CollectionUtil.isNotEmpty(deleteList)) {
                operatorService.removeByIds(deleteList);
            }
        }
    }

    // 处理嵌入的任务流程
    public void handleTrigger(OperatorEntity operatorEntity, FlowModel flowModel) throws WorkFlowException {
        String nodeCode = operatorEntity.getNodeCode();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        List<String> nextList = new ArrayList<>();
        nextList = taskUtil.getNextList(flowModel.getDeploymentId(), nodeCode, nodes, nextList);
        if (CollectionUtil.isEmpty(nextList)) {
            return;
        }

        Integer action = flowModel.getAction();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        String flowId = taskEntity.getFlowId();
        Map<String, Object> formData = flowModel.getFormData();
        List<SystemAuditModel> systemList = SystemAuditHolder.getAll();

        // 存在同步
        boolean isAsync = false;

        List<String> approveNode = new ArrayList<>();
        Map<String, NodeModel> triggers = new HashMap<>();
        for (String next : nextList) {
            NodeModel nodeModel = nodes.get(next);
            if (null != nodeModel) {
                if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.trigger.getType())) {
                    if (ObjectUtil.equals(nodeModel.getIsAsync(), 0)) {
                        isAsync = true;
                    }
                    triggers.put(next, nodeModel);
                } else if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.approver.getType())) {
                    approveNode.add(nodeModel.getNodeId());
                }
            }
        }

        if (CollectionUtil.isEmpty(triggers)) {
            return;
        }

        Boolean rejectTrigger = flowModel.getRejectTrigger();
        if (ObjectUtil.equals(action, 3) || rejectTrigger) {
            Map<String, Object> variables = triggerUtil.getVariables(flowModel.getDeploymentId(), nodeCode);
            if (ObjectUtil.equals(action, 3)) {
                List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
                TemplateNodeEntity end = nodeEntityList.stream()
                        .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.end.getType())).findFirst()
                        .orElse(null);
                if (null != end) {
                    // 将目标是结束节点的线 的值变更为false
                    FlowableNodeModel info = flowAbleUrl.getElementInfo(flowModel.getDeploymentId(), end.getNodeCode());
                    List<String> incomingList = info.getIncomingList();
                    if (CollectionUtil.isNotEmpty(incomingList)) {
                        for (String key : variables.keySet()) {
                            if (incomingList.contains(key)) {
                                variables.put(key, false);
                            }
                        }
                    }
                }
            }
            triggerUtil.complete(operatorEntity.getNodeId(), variables);
        } else {
            // 异步处理
            if (!isAsync) {
                // 获取线程存储的需要系统通过的经办
                if (CollectionUtil.isNotEmpty(systemList)) {
                    for (SystemAuditModel model : systemList) {
                        try {
                            this.autoAudit(model.getOperator(), model.getFlowModel());
                        } catch (Exception e) {
                            log.error("系统审批异常", e);
                        }
                    }
                    systemList = new ArrayList<>();
                }
            }
        }

        UserInfo userInfo = UserProvider.getUser();
        List<ExecuteAsyncModel> list = new ArrayList<>();
        for (String key : triggers.keySet()) {
            NodeModel nodeModel = nodes.get(key);
            if (null == nodeModel) {
                continue;
            }
            if (ObjectUtil.equals(nodeModel.getTriggerEvent(), 2)) {
                if (!nodeModel.getActionList().contains(action)) {
                    continue;
                }
            }
            List<OperatorEntity> operatorList = new ArrayList<>();
            List<TaskEntity> subTaskList = new ArrayList<>();
            Boolean sync = ObjectUtil.equals(nodeModel.getIsAsync(), 0);
            if (sync) {
                if (CollectionUtil.isNotEmpty(approveNode)) {
                    operatorList = this.getList(taskEntity.getId(), approveNode);
                    if (CollectionUtil.isNotEmpty(operatorList)) {
                        for (OperatorEntity operator : operatorList) {
                            operator.setStatus(OperatorStateEnum.Waiting.getCode());
                        }
                        operatorService.updateBatchById(operatorList);
                    }
                    // 子流程的处理
                    subTaskList = taskUtil.getSubTask(taskEntity.getId(), approveNode);
                    if (CollectionUtil.isNotEmpty(subTaskList)) {
                        for (TaskEntity subTask : subTaskList) {
                            Integer status = subTask.getStatus();
                            subTask.setHisStatus(status);
                            subTask.setStatus(-2);
                        }
                        taskService.updateBatchById(subTaskList);
                    }
                }
            }
            List<Map<String, Object>> dataList = new ArrayList<>();
            dataList.add(formData);
            ExecuteModel model = new ExecuteModel();
            model.setFlowId(flowId);
            model.setDataList(dataList);
            model.setUserInfo(userInfo);
            model.setParentId("0");
            model.setTaskId(taskEntity.getId());
            model.setInstanceId(taskEntity.getInstanceId());
            model.setGroupId(nodeModel.getGroupId());
            model.setNodeCode(nodeCode);
            model.setNodeId(operatorEntity.getNodeId());
            model.setTriggerKey(key);
            model.setIsAsync(nodeModel.getIsAsync());
            if (ObjectUtil.equals(action, 3) || rejectTrigger) {
                try {
                    triggerUtil.execute(model);
                } catch (Exception e) {
                    e.printStackTrace();
                    // TriggerRecordHolder.clear();
                    if (sync) {
                        taskService.cancel(taskEntity.getId(), flowModel, true);
                    }
                }
                flowModel.setBackId(model.getCurrentNodeId());
            } else {
                // flowAsyncUtil.execute(model, sync, operatorList, subTaskList, systemList,
                // flowModel);
                ExecuteAsyncModel asyncModel = new ExecuteAsyncModel();
                asyncModel.setModel(model);
                asyncModel.setSync(sync);
                asyncModel.setOperatorList(operatorList);
                asyncModel.setSubTaskList(subTaskList);
                asyncModel.setSystemList(systemList);
                asyncModel.setFlowModel(flowModel);
                list.add(asyncModel);
            }
        }
        try {
            flowAsyncUtil.execute(list);
        } catch (Exception e) {
            e.printStackTrace();
            // TriggerRecordHolder.clear();
        }
        SystemAuditHolder.clear();
    }
}
