package cn.iocoder.yudao.module.bpm.service.oa.turnover;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.turnover.vo.OaTurnoverPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.turnover.vo.OaTurnoverRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.turnover.vo.OaTurnoverSaveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.turnover.OaTurnoverDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.turnover.OaTurnOverMapper;
import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_TURNOVER_NOT_EXISTS;

/**
 * 离职流程信息 Service 实现类
 *
 * @author dp
 */
@Service
@Validated
public class OaTurnoverServiceImpl implements OaTurnoverService {


    /**
     * 对应的流程定义 KEY
     */
    public static final String PROCESS_KEY = "oa_turnover";


    @Resource
    private OaTurnOverMapper oaTurnoverMapper;

    @Resource
    private BpmProcessInstanceApi processInstanceApi;

    @Resource
    private BpmTaskService bpmTaskService;

    @Resource
    private TaskService taskService;

    @Resource
    private FileApi fileApi;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private DeptApi deptApi;

    @Override
    @Transactional
    public Long stagingOaTurnover(OaTurnoverSaveReqVO stagingReqVO) {
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
        Objects.requireNonNull(loginUser, "登录用户不能为空");
        // 人信息
        AdminUserRespDTO employee = adminUserApi.getUser(stagingReqVO.getEmployeeId());

        OaTurnoverDO oaTurnover = BeanUtils.toBean(stagingReqVO, OaTurnoverDO.class);
        if (StringUtils.isBlank(oaTurnover.getTurnoverId())) {
            // 创建单据uuid
            String uuid = IdUtil.fastSimpleUUID();
            oaTurnover.setTurnoverId(uuid);
        }
        if (employee != null) {
            oaTurnover.setEmployeeId(loginUser.getId());
            oaTurnover.setEmployeeName(loginUser.getNickname());
            oaTurnover.setEmployeePhone(loginUser.getMobile());
            oaTurnover.setDeptId(loginUser.getDeptId());
            oaTurnover.setPosition("员工职位");
            oaTurnover.setEntryDate("2023-01-01");
            oaTurnover.setUserId(loginUser.getId());
        }
        oaTurnover.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_STAGING);
        oaTurnover.setInfoSource("0");
        oaTurnover.setApplyEmployeeId(loginUser.getId());
        oaTurnover.setApplyEmployeeName(loginUser.getNickname());
        // 暂存不保存审批人信息
        oaTurnover.setStartUserSelectAssignees(null);
        // 保存或更新表单信息
        if (oaTurnover.getId() == null) {
            oaTurnoverMapper.insert(oaTurnover);
        } else {
            validateOaTurnoverExists(oaTurnover.getId());
            oaTurnoverMapper.updateById(oaTurnover);
        }
        // 保存业务uuid到附件中
        saveFileList(stagingReqVO.getFileIdList(), oaTurnover.getTurnoverId());

        return oaTurnover.getId();
    }

    @Override
    @Transactional
    public Long commitOaTurnover(OaTurnoverSaveReqVO commitReqVO) {
        if (CollectionUtil.isEmpty(commitReqVO.getStartUserSelectAssignees())) {
            throw exception(ErrorCodeConstants.TASK_CREATE_FAIL_NO_START_SELECT_ASSIGNEE);
        }
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
        if (loginUser == null) {
            throw exception(ErrorCodeConstants.OA_LOGIN_USER_NOT_EXISTS);
        }
        // 人信息
        AdminUserRespDTO employee = adminUserApi.getUser(commitReqVO.getEmployeeId());
        if (employee == null) {
            throw exception(ErrorCodeConstants.OA_EMPLOYEE_NOT_EXISTS);
        }


        OaTurnoverDO oaTurnover = BeanUtils.toBean(commitReqVO, OaTurnoverDO.class);
        if (StringUtils.isBlank(oaTurnover.getTurnoverId())) {
            // 创建单据uuid
            String uuid = IdUtil.fastSimpleUUID();
            oaTurnover.setTurnoverId(uuid);
        }
        oaTurnover.setEmployeeId(employee.getId());
        oaTurnover.setEmployeeName(employee.getNickname());
        oaTurnover.setEmployeePhone(employee.getMobile());
        oaTurnover.setDeptId(employee.getDeptId());
        oaTurnover.setPosition("员工职位");
        oaTurnover.setEntryDate("2023-01-01");
        oaTurnover.setUserId(loginUser.getId());
        oaTurnover.setInfoSource("0");
        oaTurnover.setApplyEmployeeId(loginUser.getId());
        oaTurnover.setApplyEmployeeName(loginUser.getNickname());
        // 保存或更新表单信息
        if (oaTurnover.getId() == null) {
            oaTurnoverMapper.insert(oaTurnover);
        } else {
            OaTurnoverDO oaTurnoverDO = validateOaTurnoverExists(oaTurnover.getId());
            if (StrUtil.isNotBlank(oaTurnoverDO.getProcInstId())) {
                throw exception(ErrorCodeConstants.PROCESS_INSTANCE_CREATE_FAIL_HAS_PROCESS);
            }
            oaTurnoverMapper.updateById(oaTurnover);
        }
        // 发起流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        processInstanceVariables.put("auditPass", "true");
        // 添加审批人信息
        Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
        List<Long> selectAssignees = commitReqVO.getStartUserSelectAssignees();
        startUserSelectAssignees.put("approver", selectAssignees);
        String processInstanceId = processInstanceApi
                .createProcessInstance(loginUser.getId(),
                        new BpmProcessInstanceCreateReqDTO()
                                .setProcessDefinitionKey(PROCESS_KEY)
                                .setVariables(processInstanceVariables)
                                .setBusinessKey(String.valueOf(oaTurnover.getId()))
                                .setStartUserSelectAssignees(startUserSelectAssignees));

        //获取下一个审批人
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();

        // 审批同意
        BpmTaskApproveReqVO agreeReqVO = new BpmTaskApproveReqVO();
        agreeReqVO.setId(task.getId());
        agreeReqVO.setReason("[首次提交]");
        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
        taskService.setVariable(task.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
        taskService.setVariable(task.getId(), "auditPass", "true");
        bpmTaskService.approveTask(loginUserId, agreeReqVO);

        Task nextTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        if (nextTask == null) {
            throw exception(ErrorCodeConstants.TASK_CREATE_FAIL_NO_START_SELECT_ASSIGNEE);
        }
        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);


        // 将工作流的流程实例ID、单据状态、最后一次审批时间、当前审批人更新到单据信息中
        oaTurnoverMapper.updateById(new OaTurnoverDO()
                .setId(oaTurnover.getId())
                .setProcInstId(processInstanceId)
                .setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_COMMITTED)
                .setFinalAuditDate(LocalDateTime.now())
                .setCurrentAuditEmployeeId(currentAuditEmployeeId)
                .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
                .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
        // 保存业务uuid到附件中
        saveFileList(commitReqVO.getFileIdList(), oaTurnover.getTurnoverId());
        // TODO DP 发送提交成功站内信
        return oaTurnover.getId();
    }

    @Override
    @Transactional
    public Long agreeOaTurnover(BpmTaskApproveReqVO agreeReqVO) {
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // TODO DP 根据登录人查询出对应的员工信息

        Task currentTask = bpmTaskService.getTask(agreeReqVO.getId());
        if (currentTask == null) {
            throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
        }
        // 先更新为审批中
        taskService.setVariable(currentTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
        LambdaQueryWrapper<OaTurnoverDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
        OaTurnoverDO oaTurnover = oaTurnoverMapper.selectOne(lambdaQueryWrapper);
        // 如果是最后一个人审批同意，设置流程审批状态为已审核
        String[] auditPersons = oaTurnover.getStartUserSelectAssignees().split(",");
        String lastAuditPerson = Arrays.stream(auditPersons)
                .reduce((first, second) -> second)
                .orElse(null);
        if (currentTask.getAssignee().equals(lastAuditPerson)) {
            // 更新为已审核(暂时未生效，未找到原因，先不处理)
            taskService.setVariable(agreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITED);
        }
        // 审批同意
        String reason = "[同意]";
        if (StrUtil.isNotBlank(agreeReqVO.getReason())) {
            reason = reason + agreeReqVO.getReason();
        }
        agreeReqVO.setReason(reason);
        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_AUDITING));
        taskService.setVariable(agreeReqVO.getId(), "auditPass", "true");
        bpmTaskService.approveTask(loginUserId, agreeReqVO);

        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
        OaTurnoverDO oaTurnoverDO = new OaTurnoverDO();
        if (nextTask != null) {
            Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
            AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);

            // 如果审批人重复，实际未结束，再次更新为审核中
            taskService.setVariable(nextTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
            oaTurnoverDO.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_AUDITING)
                    .setCurrentAuditEmployeeId(currentAuditEmployeeId)
                    .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
                    .setFinalAuditDate(LocalDateTime.now())
                    .setId(oaTurnover.getId());

        } else {
            oaTurnoverDO.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_AUDITED)
                    .setCurrentAuditEmployeeId(null)
                    .setCurrentAuditEmployeeName(null)
                    .setFinalAuditDate(LocalDateTime.now())
                    .setId(oaTurnover.getId());

            // TODO 复制业务单据信息到业务模块单据表

        }
        oaTurnoverMapper.updateById(oaTurnoverDO);
        // 发送通知

        // 返回
        return 1L;
    }

    @Override
    @Transactional
    public Long disagreeOaTurnover(BpmTaskReturnReqVO disagreeReqVO) {
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // TODO DP 根据登录人查询出对应的员工信息

        Task currentTask = bpmTaskService.getTask(disagreeReqVO.getId());

        disagreeReqVO.setTargetTaskDefinitionKey("modifyApply");
        disagreeReqVO.setReason("[驳回]" + disagreeReqVO.getReason());
        disagreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RETURNED));
        taskService.setVariable(disagreeReqVO.getId(), "auditPass", "false");
        taskService.setVariable(disagreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RETURNED);
        bpmTaskService.returnTask(loginUserId, disagreeReqVO);

        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);

        // 更新单据状态，当前处理人，最后处理时间
        LambdaUpdateWrapper<OaTurnoverDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(OaTurnoverDO::getCurrentAuditEmployeeId, currentAuditEmployeeId)
                .set(OaTurnoverDO::getCurrentAuditEmployeeName, currentAuditEmployee.getNickname())
                .set(OaTurnoverDO::getFinalAuditDate, LocalDateTime.now())
                .set(OaTurnoverDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_RETURNED)
                .eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
        oaTurnoverMapper.update(updateWrapper);

        // 发送通知

        return 1L;
    }

    @Override
    @Transactional
    public Long revocationOaTurnover(BpmTaskApproveReqVO revocationReqVO) {
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // TODO DP 根据登录人查询出对应的员工信息

        Task currentTask = bpmTaskService.getTask(revocationReqVO.getId());
        if (currentTask == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_NOT_EXISTS);
        }
        LambdaQueryWrapper<OaTurnoverDO> lambdaQueryWrapper = new LambdaQueryWrapper<OaTurnoverDO>()
                .eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
        OaTurnoverDO oaTurnoverDO = oaTurnoverMapper.selectOne(lambdaQueryWrapper);
        if (!DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaTurnoverDO.getAuditStatus())
                || !Objects.equals(String.valueOf(loginUserId), oaTurnoverDO.getCreator())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NOT_ALLOWED);
        }

        BpmTaskReturnReqVO returnReqVO = BeanUtils.toBean(revocationReqVO, BpmTaskReturnReqVO.class);
        returnReqVO.setTargetTaskDefinitionKey("modifyApply");
        String reason = "[撤回]";
        if (StrUtil.isNotBlank(returnReqVO.getReason())) {
            reason = reason + returnReqVO.getReason();
        }
        returnReqVO.setReason(reason);
        returnReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RECALLED));
        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RECALLED);
        bpmTaskService.revocationTask(loginUserId, returnReqVO);

        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);

        // 更新单据状态，当前处理人，最后处理时间
        LambdaUpdateWrapper<OaTurnoverDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(OaTurnoverDO::getCurrentAuditEmployeeId, currentAuditEmployeeId)
                .set(OaTurnoverDO::getCurrentAuditEmployeeName, currentAuditEmployee.getNickname())
                .set(OaTurnoverDO::getFinalAuditDate, LocalDateTime.now())
                .set(OaTurnoverDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_RECALLED)
                .eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
        oaTurnoverMapper.update(updateWrapper);

        // 发送通知

        return 1L;
    }

    @Override
    @Transactional
    public Long reCommitOaTurnover(OaTurnoverSaveReqVO reCommitReqVO) {
        if (reCommitReqVO.getId() == null) {
            throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
        }
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
        if (loginUser == null) {
            throw exception(ErrorCodeConstants.OA_LOGIN_USER_NOT_EXISTS);
        }
        // 人信息
        AdminUserRespDTO employee = adminUserApi.getUser(reCommitReqVO.getEmployeeId());
        if (employee == null) {
            throw exception(ErrorCodeConstants.OA_EMPLOYEE_NOT_EXISTS);
        }

        OaTurnoverDO oaTurnoverNew = BeanUtils.toBean(reCommitReqVO, OaTurnoverDO.class);
        OaTurnoverDO oaTurnoverOld = validateOaTurnoverExists(oaTurnoverNew.getId());
        oaTurnoverNew.setTurnoverId(oaTurnoverOld.getTurnoverId())
                .setProcInstId(oaTurnoverOld.getProcInstId());

        oaTurnoverNew.setEmployeeId(employee.getId());
        oaTurnoverNew.setEmployeeName(employee.getNickname());
        oaTurnoverNew.setEmployeePhone(employee.getMobile());
        oaTurnoverNew.setDeptId(employee.getDeptId());
        oaTurnoverNew.setPosition("员工职位");
        oaTurnoverNew.setEntryDate("2023-01-01");
        oaTurnoverNew.setUserId(loginUser.getId());
        oaTurnoverNew.setApplyEmployeeId(loginUser.getId());
        oaTurnoverNew.setApplyEmployeeName(loginUser.getNickname());

        Task currentTask = taskService.createTaskQuery().processInstanceId(oaTurnoverNew.getProcInstId()).singleResult();
        BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
        approveReqVO.setId(currentTask.getId())
                .setReason("[再次提交]");
        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
        if (CollectionUtil.isNotEmpty(reCommitReqVO.getStartUserSelectAssignees())) {
            // 添加审批人信息到流程参数中
            Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
            List<Long> selectAssignees = reCommitReqVO.getStartUserSelectAssignees();
            startUserSelectAssignees.put("approver", selectAssignees);
            taskService.setVariable(currentTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees);
            // 保存审批人信息
            oaTurnoverNew.setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(",")));
        }
        taskService.setVariable(currentTask.getId(), "auditPass", "true");
        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
        // 再次提交，和审批通过逻辑相同
        bpmTaskService.approveTask(loginUserId, approveReqVO);

        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
        oaTurnoverNew.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_COMMITTED)
                .setCurrentAuditEmployeeId(currentAuditEmployeeId)
                .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
                .setFinalAuditDate(LocalDateTime.now());
        oaTurnoverMapper.updateById(oaTurnoverNew);

        // 保存业务uuid到附件中
        saveFileList(reCommitReqVO.getFileIdList(), oaTurnoverNew.getTurnoverId());

        return 1L;
    }

    @Override
    @Transactional
    public Long closeOaTurnover(Long id) {
        if (id == null) {
            throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
        }
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // TODO DP 根据登录人查询出对应的员工信息

        OaTurnoverDO oaTurnoverDO = validateOaTurnoverExists(id);
        if (!DictDataConstants.OA_AUDIT_STATUS_RETURNED.equals(oaTurnoverDO.getAuditStatus())
                && !DictDataConstants.OA_AUDIT_STATUS_RECALLED.equals(oaTurnoverDO.getAuditStatus())) {
            throw exception(ErrorCodeConstants.TASK_CLOSE_NOT_ALLOWED);
        }

        Task currentTask = taskService.createTaskQuery().processInstanceId(oaTurnoverDO.getProcInstId()).singleResult();
        BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
        approveReqVO.setId(currentTask.getId())
                .setReason("[关闭]");
        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_CLOSED));
        taskService.setVariable(currentTask.getId(), "auditPass", "false");
        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_CLOSED);
        // 关闭，使用审批通过的方法实现
        bpmTaskService.approveTask(loginUserId, approveReqVO);

        LambdaUpdateWrapper<OaTurnoverDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(OaTurnoverDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_CLOSED)
                .set(OaTurnoverDO::getCurrentAuditEmployeeId, null)
                .set(OaTurnoverDO::getCurrentAuditEmployeeName, null)
                .set(OaTurnoverDO::getFinalAuditDate, LocalDateTime.now())
                .eq(OaTurnoverDO::getId, id);
        oaTurnoverMapper.update(lambdaUpdateWrapper);
        return 1L;
    }

    @Override
    public void deleteOaTurnover(Long id) {
        // 校验存在
        validateOaTurnoverDelete(id);
        // 删除
        oaTurnoverMapper.deleteById(id);
    }

    @Override
    public OaTurnoverRespVO getOaTurnover(Long id) {
        // 登录人信息
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // TODO DP 根据登录人查询出对应的员工信息

        OaTurnoverDO oaTurnoverDO = oaTurnoverMapper.selectById(id);
        OaTurnoverRespVO oaTurnoverRespVO = BeanUtils.toBean(oaTurnoverDO, OaTurnoverRespVO.class);
        if (oaTurnoverDO.getDeptId() != null) {
            DeptRespDTO dept = deptApi.getDept(oaTurnoverDO.getDeptId());
            if (dept != null) {
                oaTurnoverRespVO.setDeptName(dept.getName());
            }
        }

        String procInstId = oaTurnoverDO.getProcInstId();
        if (StrUtil.isNotBlank(procInstId)) {
            Task task = taskService.createTaskQuery()
                    .processInstanceId(procInstId)
                    .taskAssignee(String.valueOf(loginUserId))
                    .singleResult();
            if (DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaTurnoverDO.getAuditStatus())) {
                // 如果是已提交，不限制任务处理人是当前登录人，用于直接撤回
                task = taskService.createTaskQuery()
                        .processInstanceId(procInstId)
                        .singleResult();
            }
            if (task != null) {
                oaTurnoverRespVO.setTaskId(task.getId());
            }
        }

        // 附件列表
        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaTurnoverDO.getTurnoverId());
        oaTurnoverRespVO.setFileList(fileList);

        // 审批记录
        if (StrUtil.isNotBlank(oaTurnoverDO.getProcInstId())) {
            List<BpmTaskRespVO> auditRecordList = bpmTaskService.getAuditRecordListByProcessInstanceId(oaTurnoverDO.getProcInstId());
            oaTurnoverRespVO.setAuditRecordList(auditRecordList);
        }

        // 审批人
        String startUserSelectAssignees = oaTurnoverDO.getStartUserSelectAssignees();
        if (StrUtil.isNotEmpty(startUserSelectAssignees)) {
            List<Long> userIdList = Arrays.stream(startUserSelectAssignees.split(","))
                    .map(Long::valueOf).collect(Collectors.toList());
            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIdList);
            List<AdminUserRespDTO> auditUserList = new ArrayList<>();
            for (Long userId : userIdList) {
                for (AdminUserRespDTO adminUserRespDTO : userList) {
                    if (Objects.equals(userId, adminUserRespDTO.getId())) {
                        auditUserList.add(adminUserRespDTO);
                        break;
                    }
                }
            }
            oaTurnoverRespVO.setAuditUserList(auditUserList);
        }

        return oaTurnoverRespVO;
    }

    @Override
    public OaTurnoverRespVO getOaTurnoverByProcInstId(String procInstId) {
        OaTurnoverDO oaTurnoverDO = oaTurnoverMapper.selectOne(OaTurnoverDO::getProcInstId, procInstId);
        OaTurnoverRespVO oaTurnoverRespVO = BeanUtils.toBean(oaTurnoverDO, OaTurnoverRespVO.class);
        if (oaTurnoverDO.getDeptId() != null) {
            DeptRespDTO dept = deptApi.getDept(oaTurnoverDO.getDeptId());
            if (dept != null) {
                oaTurnoverRespVO.setDeptName(dept.getName());
            }
        }

        // 附件列表
        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaTurnoverDO.getTurnoverId());
        oaTurnoverRespVO.setFileList(fileList);

        // 审批记录
        if (StrUtil.isNotBlank(oaTurnoverDO.getProcInstId())) {
            List<BpmTaskRespVO> auditRecordList = bpmTaskService.getAuditRecordListByProcessInstanceId(oaTurnoverDO.getProcInstId());
            oaTurnoverRespVO.setAuditRecordList(auditRecordList);
        }

        // 审批人
        String startUserSelectAssignees = oaTurnoverDO.getStartUserSelectAssignees();
        if (StrUtil.isNotEmpty(startUserSelectAssignees)) {
            List<Long> userIdList = Arrays.stream(startUserSelectAssignees.split(","))
                    .map(Long::valueOf).collect(Collectors.toList());
            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIdList);
            List<AdminUserRespDTO> auditUserList = new ArrayList<>();
            for (Long userId : userIdList) {
                for (AdminUserRespDTO adminUserRespDTO : userList) {
                    if (Objects.equals(userId, adminUserRespDTO.getId())) {
                        auditUserList.add(adminUserRespDTO);
                        break;
                    }
                }
            }
            oaTurnoverRespVO.setAuditUserList(auditUserList);
        }

        return oaTurnoverRespVO;
    }

    @Override
    public PageResult<OaTurnoverRespVO> getOaTurnoverPage(OaTurnoverPageReqVO pageReqVO) {
        PageResult<OaTurnoverDO> oaTurnoverDOPageResult = oaTurnoverMapper.selectPage(pageReqVO);
        PageResult<OaTurnoverRespVO> oaTurnoverRespVOPageResult = BeanUtils.toBean(oaTurnoverDOPageResult, OaTurnoverRespVO.class);

        List<OaTurnoverRespVO> oaTurnoverRespVOList = oaTurnoverRespVOPageResult.getList();
        if (CollectionUtil.isNotEmpty(oaTurnoverRespVOList)) {
            List<Long> employeeIdList = oaTurnoverRespVOList.stream().map(OaTurnoverRespVO::getCurrentAuditEmployeeId).collect(Collectors.toList());
            List<AdminUserRespDTO> employeeList = adminUserApi.getUserList(employeeIdList);
            for (OaTurnoverRespVO respVO : oaTurnoverRespVOList) {
                for (AdminUserRespDTO employee : employeeList) {
                    if (employee.getId() != null && employee.getId().equals(respVO.getCurrentAuditEmployeeId())) {
                        respVO.setCurrentAuditEmployeeName(employee.getNickname());
                        break;
                    }
                }
            }

            List<Long> deptIdList = oaTurnoverRespVOList.stream().map(OaTurnoverRespVO::getDeptId).collect(Collectors.toList());
            List<DeptRespDTO> deptList = deptApi.getDeptList(deptIdList);
            for (OaTurnoverRespVO respVO : oaTurnoverRespVOList) {
                for (DeptRespDTO dept : deptList) {
                    if (dept.getId() != null && dept.getId().equals(respVO.getDeptId())) {
                        respVO.setDeptName(dept.getName());
                        break;
                    }
                }
            }
        }

        return oaTurnoverRespVOPageResult;
    }

    @Override
    public PageResult<OaTurnoverRespVO> exportOaTurnoverExcel(OaTurnoverPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        return getOaTurnoverPage(pageReqVO);
    }

    private void validateOaTurnoverDelete(Long id) {
        OaTurnoverDO oaTurnoverDO = validateOaTurnoverExists(id);
        if (!DictDataConstants.OA_AUDIT_STATUS_STAGING.equals(oaTurnoverDO.getAuditStatus())) {
            throw exception(ErrorCodeConstants.DELETE_FAIL_NOT_STAGING);
        }
    }

    private OaTurnoverDO validateOaTurnoverExists(Long id) {
        OaTurnoverDO oaTurnoverDO = oaTurnoverMapper.selectById(id);
        if (oaTurnoverDO == null) {
            throw exception(OA_TURNOVER_NOT_EXISTS);
        }
        return oaTurnoverDO;
    }

    /**
     * 保存业务uuid到附件中
     */
    private void saveFileList(List<Long> fileIdList, String serviceId) {
        if (CollectionUtil.isNotEmpty(fileIdList) && StrUtil.isNotEmpty(serviceId)) {
            fileApi.updateFileBiz(fileIdList, serviceId);
        }
    }

}