package com.qmth.distributed.print.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.distributed.print.business.bean.result.FlowApproveResult;
import com.qmth.distributed.print.business.bean.result.FlowTaskApprovePeopleAllResult;
import com.qmth.distributed.print.business.bean.result.FlowTaskApprovePeopleResult;
import com.qmth.distributed.print.business.bean.result.FlowTaskResult;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.enums.ExamStatusEnum;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.bean.params.ApproveUserResult;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.*;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.util.RedisUtil;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: activiti service impl
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/7/12
 */
@Service
public class ActivitiServiceImpl implements ActivitiService {
    private final static Logger log = LoggerFactory.getLogger(ActivitiServiceImpl.class);

    @Resource
    RuntimeService runtimeService;

    @Resource
    TaskService taskService;

    @Resource
    RepositoryService repositoryService;

    @Resource
    TFFlowApproveService tfFlowApproveService;

    @Resource
    TFFlowLogService tfFlowLogService;

    @Resource
    HistoryService historyService;

    @Resource
    ExamTaskService examTaskService;

    @Resource
    TFFlowApproveLogService tfFlowApproveLogService;

    @Resource
    RedisUtil redisUtil;

    @Resource
    TFFlowService tfFlowService;

    @Resource
    SysUserService sysUserService;

    /**
     * 注册流程
     *
     * @param processFileName
     */
    @Override
    public void createDeployment(String processFileName) {
        DeploymentBuilder builder = repositoryService.createDeployment();
        builder.addClasspathResource(SystemConstant.PROCESSES + File.separator + processFileName);
        builder.deploy();
    }

    /**
     * 上传流程文件
     *
     * @param file
     */
    @Override
    public void uploadDeployment(MultipartFile file) throws IOException {
        DeploymentBuilder builder = repositoryService.createDeployment();
        builder.addInputStream(file.getOriginalFilename(), file.getInputStream());
        builder.deploy();
    }

    /**
     * 根据流程key开启一个流程
     *
     * @param processKey
     * @param map
     */
    @Override
    @Transactional
    public ProcessInstance startActivity(String processKey, Map<String, Object> map) {
        ProcessInstance processInstance = null;
        if (Objects.nonNull(map) && map.size() > 0) {
            processInstance = runtimeService.startProcessInstanceByKey(processKey, map);
        } else {
            processInstance = runtimeService.startProcessInstanceByKey(processKey);
        }
        log.info("流程id:{},processInstanceId:{},processDefinitionId:{},processDefinitionKey:{}", processInstance.getId(), processInstance.getProcessInstanceId(), processInstance.getProcessDefinitionId(), processInstance.getProcessDefinitionKey());
        ProcessInstance finalProcessInstance = processInstance;
        map.computeIfAbsent(SystemConstant.FLOW_ID, v -> finalProcessInstance.getId());
        map.computeIfAbsent(SystemConstant.FLOW_STATUS, v -> FlowStatusEnum.START);
        this.flowApproveStart(map);
        return processInstance;
    }

    /**
     * 根据流程id直接结束流程
     *
     * @param flowId
     */
    @Override
    @Transactional
    public void flowEnd(String flowId) {
        try {
            if (redisUtil.lock(SystemConstant.REDIS_LOCK_FLOW_PREFIX + flowId, SystemConstant.REDIS_LOCK_FLOW_TIME_OUT)) {
                Task task = taskService.createTaskQuery().processInstanceId(flowId).singleResult();
                SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
                runtimeService.deleteProcessInstance(flowId, FlowGdykdxApproveSetupEnum.END.getTitle());
                //流程审批
                QueryWrapper<TFFlowApprove> tfFlowApproveQueryWrapper = new QueryWrapper<>();
                tfFlowApproveQueryWrapper.lambda().eq(TFFlowApprove::getFlowId, Long.parseLong(flowId));
                TFFlowApprove tfFlowApprove = tfFlowApproveService.getOne(tfFlowApproveQueryWrapper);
                if (Objects.isNull(tfFlowApprove)) {
                    tfFlowApprove = new TFFlowApprove(sysUser.getSchoolId(), sysUser.getOrgId(), Long.parseLong(flowId), sysUser.getId(), FlowStatusEnum.END, sysUser.getId());
                } else {
                    tfFlowApprove.setStatus(FlowStatusEnum.END);
                    tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.END.getSetup());
                    tfFlowApprove.updateInfo(sysUser.getId());
                }
                tfFlowApproveService.saveOrUpdate(tfFlowApprove);

                //流程流水日志
                QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
                examTaskQueryWrapper.lambda().eq(ExamTask::getFlowId, Long.parseLong(flowId));
                ExamTask examTask = examTaskService.getOne(examTaskQueryWrapper);
                TFFlowLog tfFlowLog = new TFFlowLog(sysUser.getSchoolId(), sysUser.getOrgId(), Long.parseLong(flowId), examTask.getId(), sysUser.getId(), sysUser.getId(), FlowGdykdxApproveSetupEnum.END.getTitle());
                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.END);
                tfFlowLog.setApproveSetup(FlowGdykdxApproveSetupEnum.END.getSetup());
                tfFlowLogService.save(tfFlowLog);

                if (Objects.nonNull(task)) {
                    String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(flowId).singleResult().getProcessDefinitionId();
                    ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
                    //获取当前流程节点
                    String currActivityId = task.getTaskDefinitionKey();
                    BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
                    FlowNode currFlow = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currActivityId);
                    if (currFlow instanceof UserTask) {
                        UserTask userTask = (UserTask) currFlow;
                        //广东医科大学流程
                        if (Objects.nonNull(processDefinitionEntity) && processDefinitionEntity.getKey().contains(SystemConstant.GDYKDX_FLOW_KEY)) {
                            //流程审批记录
                            QueryWrapper<TFFlowApproveLog> tfFlowApproveLogQueryWrapper = new QueryWrapper<>();
                            tfFlowApproveLogQueryWrapper.lambda().eq(TFFlowApproveLog::getFlowId, Long.parseLong(flowId))
                                    .eq(TFFlowApproveLog::getTaskId, examTask.getId());
                            TFFlowApproveLog tfFlowApproveLog = tfFlowApproveLogService.getOne(tfFlowApproveLogQueryWrapper);
                            if (Objects.isNull(tfFlowApproveLog)) {
                                tfFlowApproveLog = new TFFlowApproveLog(sysUser.getSchoolId(), sysUser.getOrgId(), Long.parseLong(flowId), examTask.getId(), sysUser.getId(), sysUser.getId());
                            }

                            FlowGdykdxApproveSetupEnum setupEnum = FlowGdykdxApproveSetupEnum.convertToInstance(userTask.getId());
                            if (setupEnum == FlowGdykdxApproveSetupEnum.SUBMIT) {//命题
                                tfFlowApproveLog.setStartId(sysUser.getId());
                                tfFlowApproveLog.setRemark(FlowGdykdxApproveSetupEnum.SUBMIT.getTitle() + FlowApproveOperationEnum.END.getTitle());
                            } else if (setupEnum == FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE) {//主任
                                tfFlowApproveLog.setPrimaryApproveId(sysUser.getId());
                                tfFlowApproveLog.setPrimaryApproveOperation(FlowApproveOperationEnum.END);
                                tfFlowApproveLog.setPrimaryApproveRemark(FlowApproveOperationEnum.END.getTitle());
                            } else if (setupEnum == FlowGdykdxApproveSetupEnum.SECOND_APPROVE) {//院长
                                tfFlowApproveLog.setSecondApproveId(sysUser.getId());
                                tfFlowApproveLog.setSecondApproveOperation(FlowApproveOperationEnum.END);
                                tfFlowApproveLog.setSecondApproveRemark(FlowApproveOperationEnum.END.getTitle());
                            }
                            tfFlowApproveLog.updateInfo(sysUser.getId());
                            tfFlowApproveLogService.saveOrUpdate(tfFlowApproveLog);
                        }
                    }
                }

                //命题任务修改
                examTask.setFlowId(null);
                examTask.setStatus(ExamStatusEnum.DRAFT);
                examTask.updateInfo(sysUser.getId());
                examTaskService.updateById(examTask);
            } else {
                throw ExceptionResultEnum.ERROR.exception("正在终止中，请稍候再试！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FLOW_PREFIX + flowId);
        }
    }

    /**
     * 流程审批启动
     *
     * @param map
     */
    public void flowApproveStart(Map<String, Object> map) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

        if (Objects.isNull(map.get(SystemConstant.FLOW_ID))) {
            throw ExceptionResultEnum.ERROR.exception("流程id不能为空");
        }
        Long flowId = Long.parseLong(map.get(SystemConstant.FLOW_ID).toString());

        if (Objects.isNull(map.get(SystemConstant.FLOW_STATUS))) {
            throw ExceptionResultEnum.ERROR.exception("流程状态不能为空");
        }
        FlowStatusEnum flowStatusEnum = (FlowStatusEnum) map.get(SystemConstant.FLOW_STATUS);

        Long approveId = Objects.nonNull(map.get(SystemConstant.APPROVE_ID)) ? Long.parseLong(String.valueOf(map.get(SystemConstant.APPROVE_ID))) : null;
        tfFlowApproveService.save(new TFFlowApprove(sysUser.getSchoolId(), sysUser.getOrgId(), flowId, approveId, flowStatusEnum, sysUser.getId()));
    }

    /**
     * 审批任务
     *
     * @param map
     */
    @Override
    @Transactional
    public Map<String, Object> taskApprove(Map<String, Object> map) {
        String flowTaskId = null;
        try {
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            if (Objects.isNull(map.get(SystemConstant.FLOW_TASK_ID))) {
                throw ExceptionResultEnum.ERROR.exception("流程任务id不能为空");
            }
            flowTaskId = (String) map.get(SystemConstant.FLOW_TASK_ID);
            if (redisUtil.lock(SystemConstant.REDIS_LOCK_FLOW_TASK_PREFIX + flowTaskId, SystemConstant.REDIS_LOCK_FLOW_TASK_TIME_OUT)) {
                Task task = taskService.createTaskQuery().taskId(flowTaskId).singleResult();
                if (Objects.isNull(task)) {
                    throw ExceptionResultEnum.ERROR.exception("流程任务为空");
                }
                String processInstanceId = task.getProcessInstanceId();
                QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
                examTaskQueryWrapper.lambda().eq(ExamTask::getFlowId, Long.parseLong(processInstanceId));
                ExamTask examTask = examTaskService.getOne(examTaskQueryWrapper);

                String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
                ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
                //获取当前流程节点
                String currActivityId = task.getTaskDefinitionKey();
                BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
                FlowNode currFlow = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currActivityId);

                //流程审批
                QueryWrapper<TFFlowApprove> tfFlowApproveQueryWrapper = new QueryWrapper<>();
                tfFlowApproveQueryWrapper.lambda().eq(TFFlowApprove::getFlowId, Long.parseLong(processInstanceId));
                TFFlowApprove tfFlowApprove = tfFlowApproveService.getOne(tfFlowApproveQueryWrapper);

                //流程审批记录
                QueryWrapper<TFFlowApproveLog> tfFlowApproveLogQueryWrapper = new QueryWrapper<>();
                tfFlowApproveLogQueryWrapper.lambda().eq(TFFlowApproveLog::getFlowId, Long.parseLong(processInstanceId))
                        .eq(TFFlowApproveLog::getTaskId, examTask.getId());
                TFFlowApproveLog tfFlowApproveLog = tfFlowApproveLogService.getOne(tfFlowApproveLogQueryWrapper);

                TFFlowLog tfFlowLog = null;
                if (currFlow instanceof UserTask) {
                    UserTask userTask = (UserTask) currFlow;
                    //广东医科大学流程
                    if (Objects.nonNull(processDefinitionEntity) && processDefinitionEntity.getKey().contains(SystemConstant.GDYKDX_FLOW_KEY)) {
                        String remark = Objects.nonNull(map.get(SystemConstant.APPROVE_REMARK)) ? map.get(SystemConstant.APPROVE_REMARK).toString() : null;
                        //流程流水日志
                        tfFlowLog = new TFFlowLog(sysUser.getSchoolId(), sysUser.getOrgId(), Long.parseLong(processInstanceId), examTask.getId(), sysUser.getId(), sysUser.getId(), remark);
                        FlowGdykdxApproveSetupEnum setupEnum = FlowGdykdxApproveSetupEnum.convertToInstance(userTask.getId());
                        if (setupEnum == FlowGdykdxApproveSetupEnum.SUBMIT) {//命题提交
                            flowSubmitVaild(task, sysUser.getId());
                            if (Objects.isNull(tfFlowApproveLog)) {
                                tfFlowApproveLog = new TFFlowApproveLog(sysUser.getSchoolId(), sysUser.getOrgId(), Long.parseLong(processInstanceId), examTask.getId(), sysUser.getId(), sysUser.getId());
                            }
                            tfFlowLog.setApproveSetup(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup());
                            tfFlowLog.setApproveOperation(FlowApproveOperationEnum.SUBMIT);
                            tfFlowApprove.setStatus(FlowStatusEnum.AUDITING);
                            tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup());
                        } else if (setupEnum == FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE) {//主任提交
                            flowApproveVaild(task, sysUser.getId(), map);
                            FlowApprovePassEnum approvePass = (FlowApprovePassEnum) map.get(SystemConstant.APPROVE_OPERATION);
                            FlowApproveVariableEnum approve = approvePass == FlowApprovePassEnum.PASS ? FlowApproveVariableEnum.PRIMARY_APPROVE : FlowApproveVariableEnum.PRIMARY_REJECT;
                            tfFlowLog.setApproveSetup(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup());
                            tfFlowApproveLog.setPrimaryApproveId(sysUser.getId());
                            tfFlowApproveLog.setPrimaryApproveRemark(remark);
                            if (approve == FlowApproveVariableEnum.PRIMARY_REJECT) {//驳回命题
                                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApproveLog.setPrimaryApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApprove.setStatus(FlowStatusEnum.REJECT);
                                tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup());
                            } else if (approve == FlowApproveVariableEnum.PRIMARY_APPROVE) {//提交
                                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.APPROVE);
                                tfFlowApproveLog.setPrimaryApproveOperation(FlowApproveOperationEnum.APPROVE);
                                tfFlowApprove.setStatus(FlowStatusEnum.AUDITING);
                                tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup());
                            } else {
                                throw ExceptionResultEnum.ERROR.exception("流程变量值错误");
                            }
                            map.computeIfAbsent(SystemConstant.APPROVE, v -> approve.getId());
                        } else if (setupEnum == FlowGdykdxApproveSetupEnum.SECOND_APPROVE) {//院长提交
                            flowApproveVaild(task, sysUser.getId(), map);
                            FlowApprovePassEnum approvePass = (FlowApprovePassEnum) map.get(SystemConstant.APPROVE_OPERATION);
                            FlowApproveVariableEnum approve = null;
                            tfFlowApproveLog.setSecondApproveId(sysUser.getId());
                            tfFlowApproveLog.setSecondApproveRemark(remark);
                            if (approvePass == FlowApprovePassEnum.PASS) {
                                approve = FlowApproveVariableEnum.SECOND_APPROVE;
                            } else {
                                if (Objects.isNull(map.get(SystemConstant.APPROVE_SETUP))) {
                                    throw ExceptionResultEnum.ERROR.exception("流程驳回节点不能为空");
                                }
                                Integer setup = Integer.parseInt(map.get(SystemConstant.APPROVE_SETUP).toString());
                                if (setup.intValue() < FlowGdykdxApproveSetupEnum.SUBMIT.getSetup() || setup.intValue() >= FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup()) {
                                    throw ExceptionResultEnum.ERROR.exception("流程驳回节点有误");
                                }
                                approve = setup.intValue() == 1 ? FlowApproveVariableEnum.SECOND_REJECT_ONE : FlowApproveVariableEnum.SECOND_REJECT_TWO;
                            }
                            tfFlowLog.setApproveSetup(FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup());
                            if (approve == FlowApproveVariableEnum.SECOND_REJECT_ONE) {//驳回命题
                                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApproveLog.setSecondApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApprove.setStatus(FlowStatusEnum.REJECT);
                                tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup());
                            } else if (approve == FlowApproveVariableEnum.SECOND_REJECT_TWO) {//驳回主任
                                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApproveLog.setSecondApproveOperation(FlowApproveOperationEnum.REJECT);
                                tfFlowApprove.setStatus(FlowStatusEnum.REJECT);
                                tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup());
                            } else if (approve == FlowApproveVariableEnum.SECOND_APPROVE) {//提交
                                tfFlowLog.setApproveOperation(FlowApproveOperationEnum.APPROVE);
                                tfFlowApproveLog.setSecondApproveOperation(FlowApproveOperationEnum.APPROVE);
                                tfFlowApprove.setStatus(FlowStatusEnum.FINISH);
                                tfFlowApprove.setSetup(FlowGdykdxApproveSetupEnum.FINISH.getSetup());
                            } else {
                                throw ExceptionResultEnum.ERROR.exception("流程变量值错误");
                            }
                            FlowApproveVariableEnum finalApprove = approve;
                            map.computeIfAbsent(SystemConstant.APPROVE, v -> finalApprove.getId());
                        }
                        tfFlowApprove.updateInfo(sysUser.getId());
                        tfFlowApproveLog.updateInfo(sysUser.getId());
                    }
                }
                tfFlowApprove.setApproveId(sysUser.getId());
                //当前实例的执行到哪个节点
                taskService.complete(String.valueOf(flowTaskId), map);
                tfFlowApproveService.saveOrUpdate(tfFlowApprove);
                if (Objects.nonNull(tfFlowLog)) {
                    tfFlowLogService.save(tfFlowLog);
                }
                if (Objects.nonNull(tfFlowApproveLog)) {
                    tfFlowApproveLogService.saveOrUpdate(tfFlowApproveLog);
                }
                examTask.updateInfo(sysUser.getId());
                examTaskService.updateById(examTask);
                Map<String, Object> objectMap = new HashMap<>();
                objectMap.putIfAbsent("tfFlowApprove", tfFlowApprove);
                objectMap.putIfAbsent("examTask", examTask);
                objectMap.putIfAbsent("sysUser", sysUser);
                return objectMap;
            } else {
                throw ExceptionResultEnum.ERROR.exception("正在审批中，请稍候再试！");
            }
        } catch (Exception e) {
            log.error("请求出错", e);
            e.printStackTrace();
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FLOW_TASK_PREFIX + flowTaskId);
        }
        return null;
    }

    /**
     * 获取所有流程节点
     *
     * @param flowId
     * @return
     */
    @Override
    public List<FlowTaskResult> getTaskAll(String flowId) {
        String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(flowId).singleResult().getProcessDefinitionId();
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcessById(processDefinitionEntity.getKey());
        Collection<FlowElement> flowElements = process.getFlowElements();
        List<FlowTaskResult> flowTaskResultList = new ArrayList<>();
        for (FlowElement flowElement : flowElements) {
            //假设是任务节点
            if (flowElement instanceof UserTask) {
                UserTask userTask = (UserTask) flowElement;
                if (Objects.nonNull(userTask)) {
                    //广东药科大学流程
                    if (Objects.nonNull(processDefinitionEntity) && processDefinitionEntity.getKey().contains(SystemConstant.GDYKDX_FLOW_KEY)) {
                        FlowGdykdxApproveSetupEnum flowGdykdxApproveSetupEnum = FlowGdykdxApproveSetupEnum.convertToInstance(userTask.getId());
                        flowTaskResultList.add(new FlowTaskResult(Long.parseLong(flowId), userTask.getName(), flowGdykdxApproveSetupEnum.getId(), flowGdykdxApproveSetupEnum.getSetup()));
                    }
                }
            }
        }
        return flowTaskResultList;
    }

    /**
     * 流程删除
     *
     * @param id
     * @return
     */
    @Override
    public Boolean flowDelete(Long id) {
        TFFlow tfFlow = tfFlowService.getById(id);
        List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processDefinitionId(tfFlow.getActFlowId()).processDefinitionKey(SystemConstant.GDYKDX_FLOW_KEY).list();
        if (Objects.nonNull(processInstanceList) && processInstanceList.size() > 0) {
            throw ExceptionResultEnum.ERROR.exception("有在途的流程，无法删除！");
        } else {
            UpdateWrapper<TFFlow> tfFlowUpdateWrapper = new UpdateWrapper<>();
            tfFlowUpdateWrapper.lambda().eq(TFFlow::getFlowKey, SystemConstant.GDYKDX_FLOW_KEY)
                    .eq(TFFlow::getActFlowId, tfFlow.getActFlowId())
                    .set(TFFlow::getEnable, false);
            tfFlowService.update(tfFlowUpdateWrapper);
        }
        return true;
    }

    /**
     * 获取所有流程节点待审批人
     *
     * @param courseCode
     * @param taskId
     * @return
     */
    @Override
    public FlowTaskApprovePeopleAllResult taskApproverPeopleAll(String courseCode, String taskId) {
        FlowTaskApprovePeopleAllResult flowTaskApprovePeopleAllResult = null;
        List<FlowTaskApprovePeopleResult> flowTaskApprovePeopleResultList = null;
        if (Objects.nonNull(taskId) && !Objects.equals(taskId, "")) {//说明从已审核的节点开始捞人
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (Objects.isNull(task)) {
                throw ExceptionResultEnum.ERROR.exception("流程任务为空");
            }
            flowTaskApprovePeopleAllResult = new FlowTaskApprovePeopleAllResult(Long.parseLong(task.getProcessInstanceId()));
            flowTaskApprovePeopleResultList = new LinkedList();
            //获取当前流程节点
            TFFlowApprove tfFlowApprove = tfFlowApproveService.findByFlowId(flowTaskApprovePeopleAllResult.getFlowId());
            if (Objects.isNull(tfFlowApprove)) {
                throw ExceptionResultEnum.ERROR.exception("未找到流程状态记录");
            }
            if (tfFlowApprove.getSetup() <= 0) {
                throw ExceptionResultEnum.ERROR.exception("流程已结束或已终止");
            }

            QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
            examTaskQueryWrapper.lambda().eq(ExamTask::getFlowId, flowTaskApprovePeopleAllResult.getFlowId());
            ExamTask examTask = examTaskService.getOne(examTaskQueryWrapper);

            IPage<FlowApproveResult> flowApproveResultIPage = tfFlowService.flowApproveList(new Page<>(SystemConstant.PAGE_NUMBER, SystemConstant.PAGE_SIZE), null, SystemConstant.getHeadOrUserSchoolId(), null, flowTaskApprovePeopleAllResult.getFlowId());
            FlowApproveResult flowApproveResult = null;
            if (Objects.nonNull(flowApproveResultIPage) && flowApproveResultIPage.getRecords().size() > 0) {
                flowApproveResult = flowApproveResultIPage.getRecords().get(0);
            }
            switch (tfFlowApprove.getSetup()) {
                case -1:
                    if (Objects.isNull(flowApproveResult)) {
                        throw ExceptionResultEnum.ERROR.exception("未找到流程审批记录");
                    }
                    if (Objects.nonNull(flowApproveResult.getStartId())) {
                        //获取命题已审
                        List<ApproveUserResult> approveUserMtResult = sysUserService.findById(flowApproveResult.getStartId());
                        flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup(), true, approveUserMtResult));
                    }
                    if (Objects.nonNull(flowApproveResult.getPrimaryApproveId())) {
                        //获取主任已审
                        List<ApproveUserResult> approveUserDirectorList = sysUserService.findById(flowApproveResult.getPrimaryApproveId());
                        flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup(), true, approveUserDirectorList));
                    }
                    break;
                case 0:
                    if (Objects.isNull(flowApproveResult)) {
                        throw ExceptionResultEnum.ERROR.exception("未找到流程审批记录");
                    }
                    //获取命题已审
                    List<ApproveUserResult> approveUserMtResult = sysUserService.findById(flowApproveResult.getStartId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup(), true, approveUserMtResult));
                    //获取主任已审
                    List<ApproveUserResult> approveUserDirectorList = sysUserService.findById(flowApproveResult.getPrimaryApproveId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup(), true, approveUserDirectorList));
                    //获取院长已审
                    List<ApproveUserResult> approveUserPresidentList = sysUserService.findById(flowApproveResult.getSecondApproveId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup(), true, approveUserPresidentList));
                    break;
                case 1:
                    flowTaskApprovePeopleResultList = getApproveUserAll(examTask.getCourseCode(), flowTaskApprovePeopleResultList);
                    break;
                case 2:
                    if (Objects.isNull(flowApproveResult)) {
                        throw ExceptionResultEnum.ERROR.exception("未找到流程审批记录");
                    }
                    //获取命题已审
                    approveUserMtResult = sysUserService.findById(flowApproveResult.getStartId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup(), true, approveUserMtResult));

                    SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
                    if (Objects.nonNull(sysUser.getOrgId())) {
                        //获取院长审批人
                        List<ApproveUserResult> sysUserPresidentList = sysUserService.findByPresidentApprove(Arrays.asList(sysUser.getOrgId()), null);
                        flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup(), false, sysUserPresidentList));
                    }
                    break;
                case 3:
                    if (Objects.isNull(flowApproveResult)) {
                        throw ExceptionResultEnum.ERROR.exception("未找到流程审批记录");
                    }
                    //获取命题已审
                    approveUserMtResult = sysUserService.findById(flowApproveResult.getStartId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SUBMIT.getSetup(), true, approveUserMtResult));
                    //获取主任已审
                    List<ApproveUserResult> sysUserDirectorList = sysUserService.findById(flowApproveResult.getPrimaryApproveId());
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup(), true, sysUserDirectorList));
                    break;
                default:
                    break;
            }
        } else {//获取整个节点审批人
            if (Objects.isNull(courseCode) || Objects.equals(courseCode, "")) {
                throw ExceptionResultEnum.ERROR.exception("课程编码为空");
            }
            flowTaskApprovePeopleResultList = getApproveUserAll(courseCode, flowTaskApprovePeopleResultList);
            flowTaskApprovePeopleAllResult = new FlowTaskApprovePeopleAllResult();
        }
        flowTaskApprovePeopleAllResult.setApproveUserList(flowTaskApprovePeopleResultList);
        return flowTaskApprovePeopleAllResult;
    }

    /**
     * 流程节点转他人审批
     *
     * @param userId
     * @param taskId
     * @return
     */
    @Override
    @Transactional
    public boolean taskApproverExchange(String userId, String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (Objects.isNull(task)) {
            throw ExceptionResultEnum.ERROR.exception("流程任务为空");
        }
        TFFlowApprove tfFlowApprove = tfFlowApproveService.findByFlowId(Long.parseLong(task.getProcessInstanceId()));
        if (Objects.isNull(tfFlowApprove)) {
            throw ExceptionResultEnum.ERROR.exception("未找到流程状态记录");
        }
        if (tfFlowApprove.getSetup() <= 0) {
            throw ExceptionResultEnum.ERROR.exception("流程已结束或已终止");
        }
        switch (tfFlowApprove.getSetup()) {
            case 1:
                if (Objects.nonNull(task) && Objects.nonNull(task.getAssignee()) && Objects.equals(task.getAssignee(), userId)) {
                    throw ExceptionResultEnum.ERROR.exception("不能转给自己");
                }
                break;
            case 2:
            case 3:
                if (Objects.nonNull(task) && Objects.nonNull(task.getAssignee()) && Objects.equals(task.getAssignee(), userId)) {
                    throw ExceptionResultEnum.ERROR.exception("不能转给自己");
                } else {
                    Task taskUser = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(userId).singleResult();
                    if (Objects.nonNull(taskUser)) {
                        throw ExceptionResultEnum.ERROR.exception("该审批人已有审批权限，无需流转");
                    }
                }
                break;
            default:
                break;
        }
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        taskService.deleteCandidateUser(taskId, String.valueOf(sysUser.getId()));
        taskService.addCandidateUser(taskId, userId);
        return true;
    }

    /**
     * 获取转他人审批人
     *
     * @param taskId
     * @param realName
     * @return
     */
    @Override
    public FlowTaskApprovePeopleAllResult taskApproverExchangePeople(String taskId, String realName) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (Objects.isNull(task)) {
            throw ExceptionResultEnum.ERROR.exception("流程任务为空");
        }
        FlowTaskApprovePeopleAllResult flowTaskApprovePeopleAllResult = new FlowTaskApprovePeopleAllResult(Long.parseLong(task.getProcessInstanceId()));
        //获取当前流程节点
        TFFlowApprove tfFlowApprove = tfFlowApproveService.findByFlowId(flowTaskApprovePeopleAllResult.getFlowId());
        if (Objects.isNull(tfFlowApprove)) {
            throw ExceptionResultEnum.ERROR.exception("未找到流程状态记录");
        }
        if (tfFlowApprove.getSetup() <= 0) {
            throw ExceptionResultEnum.ERROR.exception("流程已结束或已终止");
        }
        QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
        examTaskQueryWrapper.lambda().eq(ExamTask::getFlowId, flowTaskApprovePeopleAllResult.getFlowId());
        ExamTask examTask = null;

        List<FlowTaskApprovePeopleResult> flowTaskApprovePeopleResultList = new ArrayList<>();
        switch (tfFlowApprove.getSetup()) {
            case 1:
                //获取命题审批人
                examTask = examTaskService.getOne(examTaskQueryWrapper);
                List<ApproveUserResult> approveUserResultList = sysUserService.findByAssignApprove(examTask.getCourseCode(), realName);
                flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(approveUserResultList));
                break;
            case 2:
                //获取教研室主任审批人
                examTask = examTaskService.getOne(examTaskQueryWrapper);
                List<ApproveUserResult> sysUserDirectorList = sysUserService.findByDirectorApprove(examTask.getCourseCode(), realName);
                flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(sysUserDirectorList));
                break;
            case 3:
                //获取院长审批人
                if (Objects.nonNull(sysUser.getOrgId())) {
                    List<ApproveUserResult> sysUserPresidentList = sysUserService.findByPresidentApprove(Arrays.asList(sysUser.getOrgId()), realName);
                    flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(sysUserPresidentList));
                }
                break;
            default:
                break;
        }
        flowTaskApprovePeopleAllResult.setApproveUserList(flowTaskApprovePeopleResultList);
        return flowTaskApprovePeopleAllResult;
    }

    /**
     * 流程提交校验
     *
     * @param task
     * @param userId
     */
    private void flowSubmitVaild(Task task, Long userId) {
        if (Objects.isNull(task.getAssignee())) {
            Task taskUser = taskService.createTaskQuery().taskId(task.getId()).taskAssignee(String.valueOf(userId)).singleResult();
            if (Objects.isNull(taskUser)) {
                throw ExceptionResultEnum.ERROR.exception("不能提交他人的任务或者该任务已被审核，请刷新再试");
            }
        } else {
            if (!Objects.equals(task.getAssignee(), String.valueOf(userId))) {
                throw ExceptionResultEnum.ERROR.exception("不能提交他人的任务或者该任务已被审核，请刷新再试");
            }
        }
    }

    /**
     * 流程审批校验
     *
     * @param task
     * @param userId
     * @param map
     */
    private void flowApproveVaild(Task task, Long userId, Map<String, Object> map) {
        if (Objects.isNull(task.getAssignee())) {
            Task taskUser = taskService.createTaskQuery().taskId(task.getId()).taskCandidateUser(String.valueOf(userId)).singleResult();
            if (Objects.isNull(taskUser)) {
                throw ExceptionResultEnum.ERROR.exception("不能提交他人的任务或者该任务已被审核，请刷新再试");
            }
        } else {
            if (!Objects.equals(task.getAssignee(), String.valueOf(userId))) {
                throw ExceptionResultEnum.ERROR.exception("不能提交他人的任务或者该任务已被审核，请刷新再试");
            }
        }
        if (Objects.isNull(map.get(SystemConstant.APPROVE_OPERATION))) {
            throw ExceptionResultEnum.ERROR.exception("流程审核操作不能为空");
        }
    }

    /**
     * 获取所有审批人
     *
     * @param courseCode
     * @param flowTaskApprovePeopleResultList
     */
    private List<FlowTaskApprovePeopleResult> getApproveUserAll(String courseCode, List<FlowTaskApprovePeopleResult> flowTaskApprovePeopleResultList) {
        flowTaskApprovePeopleResultList = Objects.isNull(flowTaskApprovePeopleResultList) ? new LinkedList() : flowTaskApprovePeopleResultList;
        //获取教研室主任审批人
        List<ApproveUserResult> sysUserDirectorList = sysUserService.findByDirectorApprove(courseCode, null);
        flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.PRIMARY_APPROVE.getSetup(), false, sysUserDirectorList));
        Set<Long> orgIds = sysUserDirectorList.stream().map(s -> s.getOrgId()).collect(Collectors.toSet());
        //获取院长审批人
        List<ApproveUserResult> sysUserPresidentList = sysUserService.findByPresidentApprove(new ArrayList<>(orgIds), null);
        flowTaskApprovePeopleResultList.add(new FlowTaskApprovePeopleResult(FlowGdykdxApproveSetupEnum.SECOND_APPROVE.getSetup(), false, sysUserPresidentList));
        return flowTaskApprovePeopleResultList;
    }
}
