package com.yunzhupaas.flowable.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ImmutableList;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.model.systemconfig.SysConfigModel;
import com.yunzhupaas.constant.MsgCode;
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.model.flowable.FlowAbleUrl;
import com.yunzhupaas.flowable.model.flowable.FlowableNodeModel;
import com.yunzhupaas.flowable.model.flowable.NextOrPrevFo;
import com.yunzhupaas.flowable.model.operator.AddSignModel;
import com.yunzhupaas.flowable.model.task.FlowMethod;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.templatenode.ButtonModel;
import com.yunzhupaas.flowable.model.templatenode.TaskNodeModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.FileConfig;
import com.yunzhupaas.flowable.model.templatenode.nodejson.NodeModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.PrintConfig;
import com.yunzhupaas.flowable.model.templatenode.nodejson.ProperCond;
import com.yunzhupaas.flowable.model.util.FlowNature;
import com.yunzhupaas.flowable.service.*;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
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/5/16 17:35
 */
@Component
public class ButtonUtil {
    @Autowired
    private OperatorService operatorService;
    @Autowired
    private FlowAbleUrl flowAbleUrl;
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private OperatorUtil operatorUtil;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RevokeService revokeService;
    @Autowired
    private DelegateService delegateService;
    @Autowired
    private TriggerRecordService triggerRecordService;
    @Autowired
    private RecordService recordService;

    /**
     * 按钮控制
     *
     * @param flowModel 参数
     */
    public ButtonModel handleButton(FlowModel flowModel) throws WorkFlowException {
        String opType = flowModel.getOpType();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        OperatorEntity operatorEntity = flowModel.getOperatorEntity();
        RecordEntity recordEntity = flowModel.getRecordEntity();
        Map<String, Object> formData = flowModel.getFormData();
        List<TaskNodeModel> nodeList = flowModel.getNodeList();
        TemplateEntity template = flowModel.getTemplateEntity();
        UserInfo userInfo = flowModel.getUserInfo() == null ? UserProvider.getUser() : flowModel.getUserInfo();
        String userId = userInfo.getUserId();

        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        Map<String, NodeModel> nodes = new HashMap<>();
        for (TemplateNodeEntity nodeEntity : nodeEntityList) {
            nodes.put(nodeEntity.getNodeCode(), JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class));
        }
        flowModel.setNodes(nodes);
        RevokeEntity revokeEntity = revokeService.getRevokeTask(taskEntity.getId());

        // 全局节点
        NodeModel global = nodes.get(NodeEnum.global.getType());

        ButtonModel model = new ButtonModel();
        FlowMethod flowMethod = new FlowMethod();
        flowMethod.setNodes(nodes);
        flowMethod.setTaskEntity(taskEntity);
        flowMethod.setFormData(formData);
        flowMethod.setPrintNodeList(nodeList);
        switch (opType) {
            case "-1": // 我发起的新建/编辑
                // List<Integer> templateStatus = ImmutableList.of(1, 2);
                // if (!templateStatus.contains(template.getStatus())) {
                // break;
                // }
                // 是否是退回撤回的任务
                List<Integer> taskStatus = ImmutableList.of(TaskStatusEnum.BACKED.getCode(),
                        TaskStatusEnum.RECALL.getCode());
                boolean isBack = null != taskEntity && taskStatus.contains(taskEntity.getStatus());
                if (isBack) {
                    // 是否是委托的任务
                    boolean isDelegate = StringUtil.isNotBlank(taskEntity.getDelegateUserId());
                    if (isDelegate) {
                        if (ObjectUtil.equals(taskEntity.getParentId(), "0")) {
                            model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                        }
                    } else {
                        model.setHasSubmitBtn(true);
                    }
                    model.setHasSaveBtn(true);
                } else {
                    boolean commonUser = serviceUtil.isCommonUser(userId);
                    if (commonUser && ObjectUtil.equals(template.getVisibleType(), 2)) {
                        List<String> permission = serviceUtil.getLaunchPermission(userId);
                        if (permission.contains(template.getId())) {
                            model.setHasSubmitBtn(true);
                            model.setHasSaveBtn(true);
                        }
                    } else {
                        model.setHasSubmitBtn(true);
                        model.setHasSaveBtn(true);
                    }
                    // 委托发起
                    if (null == taskEntity.getId()) {
                        model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                    } else {
                        if (ObjectUtil.equals(taskEntity.getParentId(), "0")) {
                            model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                        }
                    }
                }
                break;
            case "0": // 我发起的详情
                // 打印
                TemplateNodeEntity start = nodeEntityList.stream()
                        .filter(e -> e.getNodeType().equals(NodeEnum.start.getType())).findFirst().orElse(null);
                if (null != start) {
                    NodeModel startNode = JsonUtil.getJsonToBean(start.getNodeJson(), NodeModel.class);
                    flowMethod.setNodeModel(startNode);
                    model.setHasPrintBtn(this.checkPrint(flowMethod));
                }
                // 催办
                List<Integer> statusList = ImmutableList.of(TaskStatusEnum.RUNNING.getCode(),
                        TaskStatusEnum.REVOKING.getCode());
                if (global.getHasInitiatorPressOverdueNode() && statusList.contains(taskEntity.getStatus())) {
                    QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId())
                            .eq(OperatorEntity::getCompletion, 0)
                            .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                            .isNull(OperatorEntity::getHandleStatus).isNotNull(OperatorEntity::getDuedate);
                    List<OperatorEntity> operatorList = operatorService.list(queryWrapper);
                    if (!operatorList.isEmpty()) {
                        model.setHasPressBtn(true);
                    }
                }
                // 撤回
                if (null == revokeEntity) {
                    flowModel.setFlag(1);
                    if (this.checkRecall(flowModel)) {
                        model.setHasRecallLaunchBtn(true);
                    }
                }
                // 撤销，全局属性开启 且 同意状态的任务才能撤销 且不是子流程
                if (global.getHasRevoke() && Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PASSED.getCode())
                        && Objects.equals(taskEntity.getParentId(), "0")) {
                    Boolean isExist = revokeService.checkExist(taskEntity.getId());
                    if (null == revokeEntity && isExist) {
                        model.setHasRevokeBtn(true);
                    }
                }
                break;
            case "1": // 待签事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                model.setHasSignBtn(true);
                if (null != operatorEntity) {
                    model.setProxyMark(!ObjectUtil.equals(operatorEntity.getHandleId(), userId));
                    NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, nodeModel)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case "2": // 待办事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                if (global.getHasSignFor()) {
                    model.setHasReduceSignBtn(true);
                }
                model.setHasTransactBtn(true);
                if (null != operatorEntity) {
                    NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, nodeModel)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case "3": // 在办事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                if (null == operatorEntity) {
                    break;
                }
                // 待办的opType传的也是3，所以待办的代理标识需要再在办判断
                model.setProxyMark(!ObjectUtil.equals(operatorEntity.getHandleId(), userId));
                if (null != revokeEntity) {
                    model.setHasAuditBtn(true);
                    model.setHasRejectBtn(true);
                    break;
                }
                NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                if (null == nodeModel) {
                    break;
                }
                if (this.checkViewStartForm(global, nodeModel)) {
                    model.setHasViewStartFormBtn(true);
                }
                // 协办状态的经办 只有协办保存按钮
                if (OperatorStateEnum.Assist.getCode().equals(operatorEntity.getStatus())) {
                    model.setHasAssistSaveBtn(true);
                    break;
                }
                // 打印
                flowMethod.setNodeModel(nodeModel);
                model.setHasPrintBtn(this.checkPrint(flowMethod));
                if (nodeModel.getHasAuditBtn()) {
                    model.setHasAuditBtn(true);
                }
                if (nodeModel.getHasRejectBtn() && ObjectUtil.equals(operatorEntity.getIsProcessing(), 0)) {
                    model.setHasRejectBtn(true);
                }
                if (nodeModel.getHasBackBtn() && taskEntity.getRejectDataId() == null) {
                    model.setHasBackBtn(true);
                }
                if (nodeModel.getHasSaveAuditBtn()) {
                    model.setHasSaveAuditBtn(true);
                }
                List<Integer> operatorState = ImmutableList.of(OperatorStateEnum.AddSign.getCode(),
                        OperatorStateEnum.Transfer.getCode());
                if (nodeModel.getHasFreeApproverBtn()) {
                    if (!ObjectUtil.equals(operatorEntity.getStatus(), OperatorStateEnum.Transfer.getCode())) {
                        model.setHasFreeApproverBtn(this.checkAddSign(operatorEntity, null, false));
                    }
                }
                if (nodeModel.getHasTransferBtn()) {
                    if (!operatorState.contains(operatorEntity.getStatus())
                            && ObjectUtil.equals(operatorEntity.getParentId(), "0")) {
                        model.setHasTransferBtn(true);
                    }
                }
                if (nodeModel.getHasAssistBtn()) {
                    model.setHasAssistBtn(true);
                }
                break;
            case "4": // 已办事宜
                if (null == operatorEntity || operatorEntity.getId() == null) {
                    break;
                }
                // 减签
                NodeModel node = nodes.get(operatorEntity.getNodeCode());
                // 节点属性开启、经办存在加签信息、记录是加签操作
                if (node != null) {
                    if (null != recordEntity) {
                        if (node.getHasReduceApproverBtn() && null != operatorEntity.getHandleParameter()
                                && recordEntity.getHandleType().equals(RecordEnum.addSign.getCode())) {
                            QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                            queryWrapper.lambda().eq(OperatorEntity::getTaskId, operatorEntity.getTaskId())
                                    .eq(OperatorEntity::getParentId, operatorEntity.getId())
                                    .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                                    .ne(OperatorEntity::getStatus, OperatorStateEnum.Assist.getCode())
                                    .eq(OperatorEntity::getCompletion, 0).isNull(OperatorEntity::getHandleStatus);
                            List<OperatorEntity> list = operatorService.list(queryWrapper);
                            if (CollectionUtil.isNotEmpty(list)) {
                                model.setHasReduceApproverBtn(true);
                            }
                        }
                        // 审批撤回
                        List<Integer> handleTypes = ImmutableList.of(RecordEnum.audit.getCode(),
                                RecordEnum.reject.getCode());
                        if (handleTypes.contains(recordEntity.getHandleType())) {
                            flowModel.setFlag(2);
                            if (this.checkRecall(flowModel)) {
                                model.setHasRecallAuditBtn(true);
                            }
                        }
                    }
                    flowMethod.setNodeModel(node);
                    // 打印
                    model.setHasPrintBtn(this.checkPrint(flowMethod));
                    if (this.checkViewStartForm(global, node)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case "5": // 抄送事宜
                if (null != operatorEntity) {
                    NodeModel node1 = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, node1)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case "6": // 流程监控
                if (!userInfo.getIsAdministrator()) {
                    List<String> organizeUserList = serviceUtil.getOrganizeUserList("edit");
                    if (!organizeUserList.contains(taskEntity.getCreatorUserId())) {
                        break;
                    }
                }
                // 终止状态下只有复活
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.CANCEL.getCode())
                        && ObjectUtil.equals(taskEntity.getParentId(), "0")
                        && ObjectUtil.equals(template.getStatus(), 1)) {
                    List<TriggerRecordEntity> triggerRecordList = triggerRecordService
                            .getListByTaskId(taskEntity.getId());
                    long count = triggerRecordList.stream().filter(e -> ObjectUtil.equals(e.getStatus(), 1)).count();
                    if (count == 0) {
                        model.setHasActivateBtn(true);
                    }
                }
                // 挂起状态下只有恢复
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    if (!ObjectUtil.equals(taskEntity.getIsRestore(), 1)) {
                        model.setHasRebootBtn(true);
                    }
                }
                // 运行状态下，终止、挂起
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.RUNNING.getCode())) {
                    // 子流程不允许终止
                    if (ObjectUtil.equals(taskEntity.getParentId(), "0")) {
                        model.setHasCancelBtn(true);
                    }
                    model.setHasPauseBtn(true);
                    if (this.checkAssign(taskEntity, nodes)) {
                        model.setHasAssignBtn(true);
                    }
                }
                // 归档按钮
                FileConfig config = global.getFileConfig();
                if (config.getOn() && StringUtil.isNotBlank(config.getTemplateId())) {
                    if (ObjectUtil.isNotEmpty(taskEntity.getEndTime())
                            || ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.CANCEL.getCode())) {
                        if (serviceUtil.checkFlowFile(taskEntity.getId())) {
                            model.setHasFileBtn(true);
                        }
                    }
                }
                break;
        }
        return model;
    }

    // 判断指派，当前节点全是子流程，就隐藏
    public boolean checkAssign(TaskEntity taskEntity, Map<String, NodeModel> nodes) {
        String currentNodeCode = taskEntity.getCurrentNodeCode();
        if (StringUtil.isNotBlank(currentNodeCode)) {
            List<String> currentNodeList = Arrays.stream(currentNodeCode.split(",")).collect(Collectors.toList());
            for (String nodeCode : currentNodeList) {
                NodeModel nodeModel = nodes.get(nodeCode);
                if (null != nodeModel && !Objects.equals(nodeModel.getType(), NodeEnum.subFlow.getType())) {
                    return true;
                }
            }
        }
        return false;
    }

    // 委托发起按钮
    public boolean checkDelegateSubmit(String userId, TemplateEntity template) {
        List<DelegateEntity> delegateList = delegateService.getByToUserId(userId, 0);
        if (CollectionUtil.isNotEmpty(delegateList) && ObjectUtil.equals(template.getStatus(), 1)) {
            for (DelegateEntity delegateEntity : delegateList) {
                String flowId = delegateEntity.getFlowId();
                if (StringUtil.isNotBlank(flowId)) {
                    if (flowId.contains(template.getId())) {
                        if (ObjectUtil.equals(template.getVisibleType(), 1)) {
                            return true;
                        }
                        List<String> launchPermission = serviceUtil.getLaunchPermission(delegateEntity.getUserId());
                        if (launchPermission.contains(template.getId())) {
                            return true;
                        }
                    }
                } else {
                    // 全部流程
                    if (ObjectUtil.equals(template.getVisibleType(), 1)) {
                        return true;
                    }
                    List<String> launchPermission = serviceUtil.getLaunchPermission(delegateEntity.getUserId());
                    if (launchPermission.contains(template.getId())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 查看发起表单
     */
    public boolean checkViewStartForm(NodeModel global, NodeModel nodeModel) {
        if (null != nodeModel) {
            if (global.getHasAloneConfigureForms() && StringUtil.isNotBlank(nodeModel.getFormId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断撤回
     *
     * @param flowModel 参数
     */
    public boolean checkRecall(FlowModel flowModel) throws WorkFlowException {
        String deploymentId = flowModel.getDeploymentId();
        String currentNodeCode = flowModel.getNodeEntity().getNodeCode();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        RecordEntity recordEntity = flowModel.getRecordEntity();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        // 判断撤回的标识 1.发起撤回 2.审批撤回
        int flag = flowModel.getFlag();
        boolean isException = flowModel.getIsException();

        NodeModel global = nodes.get(NodeEnum.global.getType());
        Integer recallRule = global.getRecallRule();

        // 全局撤回配置为1 直接不允许撤回 (流程撤回规则 1: 不允许撤回 2: 发起节点允许撤回 3:所有节点允许撤回)
        if (recallRule == null || recallRule == 1) {
            return false;
        }

        // 不是进行中的任务、存在退回冻结数据
        if (!Objects.equals(TaskStatusEnum.RUNNING.getCode(), taskEntity.getStatus())
                || null != taskEntity.getRejectDataId()) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF036.get());
            }
            return false;
        }
        // 经办未审批 说明是已撤回的，不允许撤回
        OperatorEntity operator = operatorService.getInfo(recordEntity.getOperatorId());
        if (null != operator) {
            if (!ObjectUtil.equals(operator.getParentId(), "0")) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF077.get());
                }
                return false;
            }
            // 判断依次审批
            boolean inTurn = this.checkInTurn(operator, isException);
            if (!inTurn && !isException) {
                return false;
            }
            if (operator.getHandleStatus() == null) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF006.get());
                }
                return false;
            } else if (null == operator.getHandleTime()) {
                // 后加签的同意未真正审批，不允许撤回
                List<OperatorEntity> childList = operatorUtil.getChildList(operator.getId());
                if (CollectionUtil.isNotEmpty(childList)) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
        } else {
            // 发起撤回的校验
            QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
            recordWrapper.lambda().eq(RecordEntity::getTaskId, taskEntity.getId())
                    .and(t -> t.ne(RecordEntity::getStatus, -1).or().eq(RecordEntity::getHandleType,
                            RecordEnum.back.getCode()));
            List<RecordEntity> recordList = recordService.list(recordWrapper);
            if (CollectionUtil.isNotEmpty(recordList)) {
                RecordEntity submit = recordList.stream()
                        .filter(e -> ObjectUtil.equals(e.getHandleType(), RecordEnum.submit.getCode())).findFirst()
                        .orElse(null);
                if (null != submit) {
                    recordList = recordList.stream()
                            .filter(e -> !ObjectUtil.equals(e.getNodeCode(), submit.getNodeCode()))
                            .collect(Collectors.toList());
                }
                if (!recordList.isEmpty()) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
        }
        // 获取节点的下一级节点,判断撤回
        NextOrPrevFo fo = new NextOrPrevFo();
        fo.setDeploymentId(deploymentId);
        fo.setTaskKey(currentNodeCode);
        List<FlowableNodeModel> nextModels = flowAbleUrl.getNext(fo);
        List<String> nextCodes = nextModels.stream().map(FlowableNodeModel::getId).collect(Collectors.toList());
        // 审批撤回需要用到下一级节点
        flowModel.setNextCodes(nextCodes);

        if (CollectionUtil.isNotEmpty(nextCodes)) {
            QueryWrapper<TaskEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TaskEntity::getParentId, taskEntity.getId())
                    .in(TaskEntity::getSubCode, nextCodes);
            List<TaskEntity> list = taskService.list(queryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                // 异步子流程，不允许撤回
                long asyncCount = list.stream().filter(e -> Objects.equals(e.getIsAsync(), FlowNature.ChildAsync))
                        .count();
                if (asyncCount > 0) {
                    return false;
                }
                long count = list.stream()
                        .filter(e -> !Objects.equals(e.getStatus(), TaskStatusEnum.TO_BE_SUBMIT.getCode())).count();
                if (count > 0) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF036.get());
                    }
                    return false;
                }
            }
        }

        if (flag == 2 && recallRule == 2) {
            return false;
        }
        if (CollectionUtil.isEmpty(nextCodes)) {
            return true;
        }
        // 存在已办理的经办，撤回后可以重新提交（下个审批节点只进行了签收 此时还可以撤回）
        QueryWrapper<OperatorEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId());
        if (CollectionUtil.isNotEmpty(nextCodes)) {
            wrapper.lambda().in(OperatorEntity::getNodeCode, nextCodes);
        }
        wrapper.lambda().orderByDesc(OperatorEntity::getCreatorTime);
        List<OperatorEntity> list = operatorService.list(wrapper);
        boolean mark = this.checkDraftAndRecord(list);
        if (mark) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF077.get());
            }
            return false;
        }
        return true;
    }

    // 依次审批的撤回判断
    public boolean checkInTurn(OperatorEntity operator, boolean isException) throws WorkFlowException {
        if (StringUtil.isNotBlank(operator.getHandleAll())) {
            List<String> handleIds = Arrays.stream(operator.getHandleAll().split(",")).collect(Collectors.toList());
            int index = handleIds.indexOf(operator.getHandleId());
            if (index != -1 && index < handleIds.size() - 1) {
                String nextHandleId = handleIds.get(index + 1);
                QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(OperatorEntity::getHandleId, nextHandleId)
                        .eq(OperatorEntity::getParentId, operator.getParentId())
                        .eq(OperatorEntity::getNodeId, operator.getNodeId())
                        .orderByDesc(OperatorEntity::getCreatorTime);
                List<OperatorEntity> list = operatorService.list(queryWrapper);
                if (CollectionUtil.isNotEmpty(list)) {
                    OperatorEntity nextOperator = list.get(0);
                    if (StringUtil.isNotEmpty(nextOperator.getDraftData())) {
                        if (isException) {
                            throw new WorkFlowException(MsgCode.WF036.get());
                        }
                        return false;
                    }
                    QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
                    recordWrapper.lambda().eq(RecordEntity::getOperatorId, nextOperator.getId())
                            .ne(RecordEntity::getStatus, -1);
                    List<RecordEntity> recordList = recordService.list(recordWrapper);
                    if (CollectionUtil.isNotEmpty(recordList)) {
                        if (isException) {
                            throw new WorkFlowException(MsgCode.WF036.get());
                        }
                        return false;
                    }
                }
            }
        }
        return true;
    }

    public boolean checkDraftAndRecord(List<OperatorEntity> list) {
        return this.checkDraftAndRecord(list, false);
    }

    // 判断草稿、操作记录
    public boolean checkDraftAndRecord(List<OperatorEntity> list, boolean filterAddSign) {
        list = list.stream().filter(e -> !ObjectUtil.equals(e.getStatus(), -1)).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(list)) {
            return false;
        }
        // if (CollectionUtil.isNotEmpty(list)) {
        // // 回流的处理
        // OperatorEntity first = list.get(0);
        // list = list.stream().filter(e -> ObjectUtil.equals(first.getNodeId(),
        // e.getNodeId())).collect(Collectors.toList());
        // }
        // 只要有操作就不让撤回，草稿数据（暂存）
        long draftCount = list.stream().filter(e -> StringUtil.isNotEmpty(e.getDraftData())).count();
        boolean mark = false;
        // 不存在草稿数据，继续根据记录判断
        if (draftCount == 0) {
            List<String> collect = list.stream().map(OperatorEntity::getId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)) {
                QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
                recordWrapper.lambda().in(RecordEntity::getOperatorId, collect).ne(RecordEntity::getStatus, -1);
                List<RecordEntity> recordList = recordService.list(recordWrapper);
                if (filterAddSign) {
                    List<Integer> status = ImmutableList.of(RecordEnum.addSign.getCode(),
                            RecordEnum.subtractSign.getCode());
                    recordList = recordList.stream().filter(e -> !status.contains(e.getHandleType()))
                            .collect(Collectors.toList());
                }
                mark = !recordList.isEmpty();
            }
        } else {
            mark = true;
        }
        return mark;
    }

    /**
     * 判断打印
     */
    public boolean checkPrint(FlowMethod flowMethod) {
        NodeModel nodeModel = flowMethod.getNodeModel();
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        Map<String, Object> formData = flowMethod.getFormData();
        List<TaskNodeModel> nodeList = flowMethod.getPrintNodeList();

        // 发起除了草稿状态都显示
        if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.TO_BE_SUBMIT.getCode())) {
            return false;
        }
        PrintConfig printConfig = nodeModel.getPrintConfig();
        if (printConfig.getOn()) {
            // 打印没有选择模版，按钮不显示
            if (CollectionUtil.isEmpty(printConfig.getPrintIds())) {
                return false;
            }
            switch (printConfig.getConditionType()) {
                case 1:
                    // 不限制
                    return true;
                case 2:
                    // 节点结束
                    // 开始节点直接返回true，除草稿状态
                    if (nodeModel.getType().equals(NodeEnum.start.getType())
                            && !taskEntity.getStatus().equals(TaskStatusEnum.TO_BE_SUBMIT.getCode())) {
                        return true;
                    }
                    TaskNodeModel taskNode = nodeList.stream()
                            .filter(e -> e.getNodeCode().equals(nodeModel.getNodeId())).findFirst().orElse(null);
                    if (null != taskNode && taskNode.getType().equals("0")) {
                        return true;
                    }
                    break;
                case 3:
                    // 流程结束
                    ImmutableList<Integer> status = ImmutableList.of(TaskStatusEnum.PASSED.getCode(),
                            TaskStatusEnum.REJECTED.getCode());
                    if (status.contains(taskEntity.getStatus())) {
                        return true;
                    }
                    break;
                case 4:
                    // 条件设置
                    List<ProperCond> conditions = printConfig.getConditions();
                    String matchLogic = printConfig.getMatchLogic();
                    UserInfo userInfo = UserProvider.getUser();
                    flowMethod.setUserInfo(userInfo);
                    flowMethod.setUserEntity(serviceUtil.getUserInfo(userInfo.getUserId()));
                    flowMethod.setConditions(conditions);
                    flowMethod.setMatchLogic(matchLogic);
                    if (FlowJsonUtil.nodeConditionDecide(flowMethod)) {
                        return true;
                    }
                    break;
            }
        }
        return false;
    }

    /**
     * 判断加签
     */
    public void checkAddSign(OperatorEntity operator, AddSignModel parameter) throws WorkFlowException {
        this.checkAddSign(operator, parameter, true);
    }

    public boolean checkAddSign(OperatorEntity operator, AddSignModel parameter, Boolean isException)
            throws WorkFlowException {
        int level = 1;
        if (!ObjectUtil.equals(operator.getParentId(), "0")) {
            OperatorEntity parent = operatorService.getById(operator.getParentId());
            if (null != parent) {
                String handleParameter = parent.getHandleParameter() == null ? operator.getHandleParameter()
                        : parent.getHandleParameter();
                AddSignModel jsonToBean = JsonUtil.getJsonToBean(handleParameter, AddSignModel.class);
                level = jsonToBean.getLevel() + 1;
            }
        }
        SysConfigModel sysConfig = serviceUtil.getSysConfig();
        Integer addSignLevel = sysConfig.getAddSignLevel();
        if (level > addSignLevel) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF143.get());
            }
            return false;
        }
        if (null != parameter) {
            parameter.setLevel(level);
        }
        return true;
    }
}
