package jnpf.personnels.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import io.seata.spring.annotation.GlobalTransactional;
import jnpf.authority.utils.PermissionsEnums;
import jnpf.authority.utils.PermissionsUtils;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.engine.FlowTaskApi;
import jnpf.engine.entity.FlowTaskEntity;
import jnpf.enums.personnel.FtbPersonnelsCheckStatusCodeEnum;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.turnover.FtbPersonnelsTurnoverHandoverDTO;
import jnpf.model.personnels.po.FtbPersonnelsSecondmentManagement;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.model.personnels.po.FtbPersonnelsTransferManage;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.personnels.req.transfer.FtbHandleTransferDTO;
import jnpf.model.personnels.req.transfer.FtbHandleTransferOaDTO;
import jnpf.model.personnels.req.transfer.FtbHandleTransferQueryDTO;
import jnpf.model.personnels.vo.transfer.FtbHandleTransferDetailsVO;
import jnpf.model.personnels.vo.transfer.FtbHandleTransferPageVO;
import jnpf.model.vo.UserSalaryHistoryVo;
import jnpf.permission.V2GradesApi;
import jnpf.permission.V2OrganizeApi;
import jnpf.permission.V2PositionApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.v2.UserBoundInfoDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.vo.v2.grades.GradeVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.position.PositionVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.mapper.FtbPersonnelsStaffRosterMapper;
import jnpf.personnels.mapper.FtbPersonnelsTransferManageMapper;
import jnpf.personnels.msg.PersonnelsConsumerSourceMsg;
import jnpf.personnels.service.FtbPersonnelsAuditRunTaskService;
import jnpf.personnels.service.FtbPersonnelsSecondmentManagementService;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import jnpf.personnels.service.FtbPersonnelsTransferManageService;
import jnpf.personnels.utils.PersonSalaryUtils;
import jnpf.salary.QuerySalaryApi;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FtbPersonnelsTransferManageServiceImpl extends ServiceImpl<FtbPersonnelsTransferManageMapper, FtbPersonnelsTransferManage> implements FtbPersonnelsTransferManageService {
    @Resource
    private PersonnelsConsumerSourceMsg secondmentConsumerSourceMsg;

    @Resource
    private PermissionsUtils permissionsUtils;

    @Resource
    private FtbPersonnelsStaffRosterMapper ftbPersonnelsStaffRosterMapper;

    @Resource
    private FtbPersonnelsStaffRosterService staffRosterService;

    @Resource
    private V2UserApi v2UserApi;

    @Resource
    private V2OrganizeApi v2OrganizeApi;

    @Resource
    private V2PositionApi v2PositionApi;

    @Resource
    private V2GradesApi v2GradesApi;
    @Resource
    private FtbPersonnelsAuditRunTaskService ftbPersonnelsAuditRunTaskService;

    @Resource
    private PersonSalaryUtils personSalaryUtils;

    @Resource
    private QuerySalaryApi querySalaryApi;

    @Resource
    private FlowTaskApi flowTaskApi;

    @Resource
    private FtbPersonnelsSecondmentManagementService ftbPersonnelSecondmentManagementService;

    @Override
    public Page<FtbHandleTransferPageVO> transferManageList(Page<FtbHandleTransferPageVO> page, FtbHandleTransferQueryDTO ftbHandleTransferQueryDTO) {
        Page<FtbHandleTransferPageVO> ftbHandleTransferPageVOPage = this.baseMapper.transferManageList(page, ftbHandleTransferQueryDTO);
        UserInfo userInfo = UserProvider.getUser();
        ftbHandleTransferPageVOPage.getRecords().forEach(a -> {
            // 判断审批Id不能为空
            if (StrUtil.isNotBlank(a.getTaskInfoId())) {
                FlowTaskEntity byTaskId = flowTaskApi.findByTaskId(a.getTaskInfoId());
                a.setCurrentSponsor(0);
                if (userInfo.getUserId().equals(byTaskId.getCreatorUserId())) {
                    a.setCurrentSponsor(1);
                }
            }
        });
        return ftbHandleTransferPageVOPage;
    }

    @Override
    public Page<FtbHandleTransferPageVO> transferListApp(Page<FtbHandleTransferPageVO> page, String userName) {
        // 当前登录人权限
        UserInfo userInfo = UserProvider.getUser();
        List<String> dataPermissions = null;
        if (!userInfo.getIsAdministrator()) {
            dataPermissions = permissionsUtils.obtainPersonnelUserIdDataPermissions(userInfo.getUserId(), PermissionsEnums.PERSONNEL_MANAGEMENT_APP.getValue(), "APP");
        }
        Page<FtbHandleTransferPageVO> result = this.baseMapper.transferListApp(page, dataPermissions, userName);
        result.getRecords().forEach(a -> {
            // 判断审批Id不能为空
            if (StrUtil.isNotBlank(a.getTaskInfoId())) {
                FlowTaskEntity byTaskId = flowTaskApi.findByTaskId(a.getTaskInfoId());
                a.setCurrentSponsor(0);
                if (userInfo.getUserId().equals(byTaskId.getCreatorUserId())) {
                    a.setCurrentSponsor(1);
                }
            }
        });
        return result;
    }

    @Override
    public Page<FtbHandleTransferPageVO> myTransferApp(Page<FtbHandleTransferPageVO> page) {
        String userId = UserProvider.getUser().getUserId();
        Page<FtbHandleTransferPageVO> result = this.baseMapper.transferListApp(page, List.of(userId), null);
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public String handleTransfer(FtbHandleTransferDTO ftbHandleTransferDTO) {
        // 校验该员工（调动的员工）是否处于其他流程中
        String checkIsInTheProcessForOA = ftbPersonnelsAuditRunTaskService.checkWhetherTheCheckIsInTheProcessForOA(ftbHandleTransferDTO.getUserId());
        if (StrUtil.isNotBlank(checkIsInTheProcessForOA)) {
            throw new RuntimeException(checkIsInTheProcessForOA);
        }
        // 薪资作废
        if (ftbHandleTransferDTO.getIsAdjustSalary() == 1 && ftbHandleTransferDTO.getIsDelete() == null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String format = simpleDateFormat.format(ftbHandleTransferDTO.getEffectiveDate());
            ActionResult<List<UserSalaryHistoryVo>> historyByChangeDate = null;
            try {
                historyByChangeDate = querySalaryApi.getHistoryByChangeDate(format, ftbHandleTransferDTO.getUserId());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            if (historyByChangeDate == null) {
                throw new RuntimeException("获取薪酬数据失败!");
            }
            List<UserSalaryHistoryVo> data = historyByChangeDate.getData();
            if (CollUtil.isNotEmpty(data)) return "5";
            // 没有薪酬默认不做废
            ftbHandleTransferDTO.setIsDelete(0);
        }
        // 员工本人不能给自己办理调动
        if (ftbHandleTransferDTO.getUserId().equals(UserProvider.getUser().getUserId())) {
            throw new RuntimeException("员工本人不能给自己办理调动");
        }
        // 数据校验
        transferDataCheck(ftbHandleTransferDTO);
        FtbPersonnelsTransferManage ftbPersonnelsTransferManage = ftbHandleTransferDTO.convert(ftbHandleTransferDTO);
        ftbPersonnelsTransferManage.setProcessingStatus(6);
        // 调动生效执行
        if (ftbPersonnelsTransferManage.getImplementType() == 1) {
            // 同步数据至组织架构
            syncDataToOrganization(ftbHandleTransferDTO.getUserId(), ftbHandleTransferDTO.getAfterOrgId(),
                    ftbHandleTransferDTO.getAfterPostId(), ftbHandleTransferDTO.getAfterRankId(), ftbHandleTransferDTO.getAfterTeamId(),
                    ftbHandleTransferDTO.getAfterDirectSupervisorId(), UserProvider.getUser().getTenantId());
            // 账号下线
            accountOffline(UserProvider.getUser().getTenantId(), ftbHandleTransferDTO.getUserId());
        }
        // 同步数据至薪酬
        if (ftbHandleTransferDTO.getIsAdjustSalary() == 1) {
            String recordId = personSalaryUtils.syncSalaryData(
                    ftbPersonnelsTransferManage.getSalaryStructureList(),
                    ftbHandleTransferDTO.getUserId(),
                    ftbHandleTransferDTO.getAfterOrgId(),
                    ftbHandleTransferDTO.getAfterPostId(),
                    ftbHandleTransferDTO.getAfterRankId(),
                    "1",
                    ftbHandleTransferDTO.getEffectiveDate(),
                    ftbHandleTransferDTO.getRemarks(),
                    "6",
                    ftbHandleTransferDTO.getSalaryType(),
                    ftbHandleTransferDTO.getPayrollSequenceId(),
                    null, null);
            ftbPersonnelsTransferManage.setSalaryRecordId(recordId);
        }
        // 重新办理
        if (StrUtil.isNotBlank(ftbHandleTransferDTO.getId())) {
            ftbPersonnelsTransferManage.setId(ftbHandleTransferDTO.getId());
            this.removeById(ftbHandleTransferDTO.getId());
        }
        ftbPersonnelsTransferManage.setLastModifyUserId(UserProvider.getUser().getUserId());
        ftbPersonnelsTransferManage.setLastModifyTime(new Date());
        this.save(ftbPersonnelsTransferManage);
        // 发送调动通知mq至考勤，用于考勤排班
        sendTransferNoticeMq(ftbHandleTransferDTO.getUserId(),ftbHandleTransferDTO.getAfterOrgId()
                ,ftbHandleTransferDTO.getEffectiveDate(),ftbHandleTransferDTO.getBeforeOrgId());
        return null;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public ActionResult<Void> handleTransferOa(FtbHandleTransferDTO ftbHandleTransferDTO) {
        ActionResult<Void> actionResult = new ActionResult<>();
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        // 数据校验
        try {
            transferDataCheck(ftbHandleTransferDTO);
            // 员工本人发起调动，审批同意时校验
            if (!UserProvider.getUser().getUserId().equals(ftbHandleTransferDTO.getUserId())) {
                checkTransferAndSecondmentConflict(ftbHandleTransferDTO.getUserId(), ftbHandleTransferDTO.getEffectiveDate());
            }
        } catch (RuntimeException runtimeException) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg(runtimeException.getMessage());
            return actionResult;
        }
        // 调动前组织名称
        ActionResult<OrganizeGeneralDetailVO> organizesByTargetCategoryOrganizeIds = v2OrganizeApi.organizeInfoById(null, ftbHandleTransferDTO.getBeforeOrgId());
        ftbHandleTransferDTO.setBeforeOrgName(organizesByTargetCategoryOrganizeIds.getData().getName());
        // 调动前岗位名称
        ActionResult<PositionVO> positionVOActionResult = v2PositionApi.infoPosition(ftbHandleTransferDTO.getBeforePostId());
        ftbHandleTransferDTO.setBeforePostName(positionVOActionResult.getData().getFullName());
        // 调动前职等Id
        if (ftbHandleTransferDTO.getBeforeRankId() != null) {
            ActionResult<GradeVO> gradeVOActionResult = v2GradesApi.infoGrade(ftbHandleTransferDTO.getBeforeRankId());
            ftbHandleTransferDTO.setBeforeRankName(gradeVOActionResult.getData().getName());
        }
        // 调动前班组id
        if (ftbHandleTransferDTO.getBeforeTeamId() != null) {
            ActionResult<OrganizeGeneralDetailVO> organizeGeneralDetailVOActionResult = v2OrganizeApi.organizeInfoById(OrganizeCategoryEnums.TEAM, ftbHandleTransferDTO.getBeforeTeamId());
            ftbHandleTransferDTO.setBeforeTeamName(organizeGeneralDetailVOActionResult.getData().getName());
        }
        // 调动后组织名称
        ActionResult<OrganizeGeneralDetailVO> organizesByTargetCategoryOrganizeIds1 = v2OrganizeApi.organizeInfoById(null, ftbHandleTransferDTO.getAfterOrgId());
        ftbHandleTransferDTO.setAfterOrgName(organizesByTargetCategoryOrganizeIds1.getData().getName());
        // 调动后岗位名称
        ActionResult<PositionVO> positionVOActionResult1 = v2PositionApi.infoPosition(ftbHandleTransferDTO.getAfterPostId());
        ftbHandleTransferDTO.setAfterPostName(positionVOActionResult1.getData().getFullName());
        // 调动后职等Id
        if (ftbHandleTransferDTO.getAfterRankId() != null) {
            ActionResult<GradeVO> gradeVOActionResult = v2GradesApi.infoGrade(ftbHandleTransferDTO.getAfterRankId());
            ftbHandleTransferDTO.setAfterRankName(gradeVOActionResult.getData().getName());
        }
        // 调动后班组id
        if (ftbHandleTransferDTO.getAfterTeamId() != null) {
            ActionResult<OrganizeGeneralDetailVO> organizeGeneralDetailVOActionResult = v2OrganizeApi.organizeInfoById(OrganizeCategoryEnums.TEAM, ftbHandleTransferDTO.getAfterTeamId());
            ftbHandleTransferDTO.setAfterTeamName(organizeGeneralDetailVOActionResult.getData().getName());
        }
        // 调动前直属主管名称
        ftbHandleTransferDTO.setBeforeDirectSupervisorName(getUserName(ftbHandleTransferDTO.getBeforeDirectSupervisorId()));
        // 调动后直属主管名称
        ftbHandleTransferDTO.setAfterDirectSupervisorName(getUserName(ftbHandleTransferDTO.getAfterDirectSupervisorId()));
        FtbPersonnelsTransferManage ftbPersonnelsTransferManage = ftbHandleTransferDTO.convert(ftbHandleTransferDTO);
        ftbPersonnelsTransferManage.setProcessingStatus(1);
        ftbPersonnelsTransferManage.setEffectiveDate(DateUtil.beginOfDay(ftbPersonnelsTransferManage.getEffectiveDate()));
        // 重新办理
        if (StrUtil.isNotBlank(ftbHandleTransferDTO.getSpecialBusinessId())) {
            ftbPersonnelsTransferManage.setId(ftbHandleTransferDTO.getSpecialBusinessId());
            this.removeById(ftbHandleTransferDTO.getSpecialBusinessId());
        }
        this.save(ftbPersonnelsTransferManage);
        return actionResult;
    }

    @Override
    @Transactional
    public void delete(String id) {
        LambdaUpdateWrapper<FtbPersonnelsTransferManage> deleteWrapper = Wrappers.lambdaUpdate();
        deleteWrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, id);
        deleteWrapper.set(FtbPersonnelsTransferManage::getEnableMarkd, 1);
        baseMapper.update(new FtbPersonnelsTransferManage(), deleteWrapper);
    }

    private void accountOffline(String tenantCode, String userId) {
        String loginId = tenantCode + ":" + userId;
        StpUtil.logout(loginId);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void approvalForOA(FtbHandleTransferOaDTO dto) {
        LambdaUpdateWrapper<FtbPersonnelsTransferManage> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FtbPersonnelsTransferManage::getTaskInfoId, dto.getTaskId());
        // 是否通过  0：不通过  1通过 2撤销
        if (dto.getIsPass() == 0) {
            updateWrapper.set(FtbPersonnelsTransferManage::getProcessingStatus, 3);
        } else if (dto.getIsPass() == 1) {
            updateWrapper.set(FtbPersonnelsTransferManage::getProcessingStatus, 2);
        } else if (dto.getIsPass() == 2) {
            updateWrapper.set(FtbPersonnelsTransferManage::getProcessingStatus, 4);
        }
        if (dto.getIsPass() == 1) {
            LambdaQueryWrapper<FtbPersonnelsTransferManage> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(FtbPersonnelsTransferManage::getTaskInfoId, dto.getTaskId());
            FtbPersonnelsTransferManage ftbHandleTransferDTO = this.baseMapper.selectOne(queryWrapper);
            boolean after = new Date().after(ftbHandleTransferDTO.getEffectiveDate());
            // 薪酬延迟填写
            if (ftbHandleTransferDTO.getSalaryStructure() == null && dto.getIsAdjustSalary() != null) {
                // 薪酬
                ftbHandleTransferDTO.setSalaryStructure(dto.getIsAdjustSalary());
                ftbHandleTransferDTO.setSalaryType(dto.getSalaryType());
                ftbHandleTransferDTO.setPayrollSequence(dto.getPayrollSequence());
                ftbHandleTransferDTO.setPayrollSequenceId(dto.getPayrollSequenceId());
                ftbHandleTransferDTO.setSalaryStructureList(JSON.toJSONString(dto.getSalaryList()));
                ftbHandleTransferDTO.setSalaryTotal(dto.getSalaryTotal());
                ftbHandleTransferDTO.setPayrollSequenceName(dto.getPayrollSequenceName());
                updateWrapper.set(FtbPersonnelsTransferManage::getSalaryStructure, dto.getIsAdjustSalary());
                updateWrapper.set(FtbPersonnelsTransferManage::getSalaryType, dto.getSalaryType());
                updateWrapper.set(FtbPersonnelsTransferManage::getPayrollSequence, dto.getPayrollSequence());
                updateWrapper.set(FtbPersonnelsTransferManage::getPayrollSequenceId, dto.getPayrollSequenceId());
                updateWrapper.set(FtbPersonnelsTransferManage::getSalaryStructureList, ftbHandleTransferDTO.getSalaryStructureList());
                updateWrapper.set(FtbPersonnelsTransferManage::getSalaryTotal, dto.getSalaryTotal());
                updateWrapper.set(FtbPersonnelsTransferManage::getPayrollSequenceName, dto.getPayrollSequenceName());
            }
            checkTransferAndSecondmentConflict(ftbHandleTransferDTO.getUserId(), ftbHandleTransferDTO.getEffectiveDate());
            if (after) {
                updateWrapper.set(FtbPersonnelsTransferManage::getImplementType, 1);
                // 同步数据至组织架构
                syncDataToOrganization(ftbHandleTransferDTO.getUserId(), ftbHandleTransferDTO.getAfterOrgId(),
                        ftbHandleTransferDTO.getAfterPostId(), ftbHandleTransferDTO.getAfterRankId(), ftbHandleTransferDTO.getAfterTeamId(),
                        ftbHandleTransferDTO.getAfterDirectSupervisorId(), UserProvider.getUser().getTenantId());
                // 账号下线
                accountOffline(UserProvider.getUser().getTenantId(), ftbHandleTransferDTO.getUserId());
            }
            // 同步数据至薪酬
            if (Objects.nonNull(ftbHandleTransferDTO.getSalaryStructure()) && ftbHandleTransferDTO.getSalaryStructure() == 1) {
                String recordId = personSalaryUtils.syncSalaryData(
                        ftbHandleTransferDTO.getSalaryStructureList(),
                        ftbHandleTransferDTO.getUserId(),
                        ftbHandleTransferDTO.getAfterOrgId(),
                        ftbHandleTransferDTO.getAfterPostId(),
                        ftbHandleTransferDTO.getAfterRankId(),
                        "1",
                        ftbHandleTransferDTO.getEffectiveDate(),
                        ftbHandleTransferDTO.getRemarks(),
                        "6",
                        ftbHandleTransferDTO.getSalaryType(),
                        ftbHandleTransferDTO.getPayrollSequenceId(),
                        null, dto.getTaskId());
                updateWrapper.set(FtbPersonnelsTransferManage::getSalaryRecordId, recordId);
            }
            // 发送调动通知mq至考勤，用于考勤排班
            sendTransferNoticeMq(ftbHandleTransferDTO.getUserId(),ftbHandleTransferDTO.getAfterOrgId()
                    ,ftbHandleTransferDTO.getEffectiveDate(),ftbHandleTransferDTO.getBeforeOrgId());
        }
        this.baseMapper.update(new FtbPersonnelsTransferManage(), updateWrapper);
    }

    @Override
    public FtbHandleTransferDetailsVO transferDetails(String id) {
        FtbPersonnelsTransferManage ftbPersonnelsTransferManage = this.baseMapper.selectById(id);
        FtbHandleTransferDetailsVO ftbHandleTransferDetailsVO = FtbHandleTransferDetailsVO.convert(ftbPersonnelsTransferManage);
        // 物品和工作交接增加员工ID
        if (StrUtil.isNotBlank(ftbPersonnelsTransferManage.getWorkHandover())) {
            List<FtbPersonnelsTurnoverHandoverDTO> turnoverHandovers = JSON.parseArray(ftbPersonnelsTransferManage.getWorkHandover(), FtbPersonnelsTurnoverHandoverDTO.class);
            StaffRosterListReq listReq = new StaffRosterListReq();
            listReq.setIsQueryAuth("0");
            listReq.setPageSize(-1);
            listReq.setUserIds(turnoverHandovers.stream().map(FtbPersonnelsTurnoverHandoverDTO::getArticleRecipientId).collect(Collectors.toList()));
            PageInfo<FtbPersonnelsStaffRosterDto> ftbPersonnelsStaffRosterDtoPageInfo = staffRosterService.postWithSalary(listReq);
            Map<String, FtbPersonnelsStaffRosterDto> userMaps = ftbPersonnelsStaffRosterDtoPageInfo.getList().stream()
                    .collect(Collectors.toMap(FtbPersonnelsStaffRosterDto::getUserId, Function.identity(), (k1, k2) -> k1));
            ftbHandleTransferDetailsVO.setWorkHandover(JSON.toJSONString(turnoverHandovers.stream().peek(item -> {
                if (userMaps.containsKey(item.getArticleRecipientId())) {
                    item.setArticleRecipientName(userMaps.get(item.getArticleRecipientId()).getName());
                    item.setWorkerStatus(userMaps.get(item.getArticleRecipientId()).getWorkerStatus());
                    item.setSystemWokerId(userMaps.get(item.getArticleRecipientId()).getSystemWokerId());
                } else {
                    // 已删除的设置为空串
                    item.setWorkerStatus("");
                    item.setSystemWokerId("");
                }
            }).collect(Collectors.toList())));
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(List.of(ftbPersonnelsTransferManage.getUserId()
                , ftbHandleTransferDetailsVO.getHandlePersonId()), UserProvider.getUser().getTenantId());
        if (userPrimaryBoundBatch.getCode() == 200 || userPrimaryBoundBatch.getData() != null) {
            Map<String, UserBoundVO> map = userPrimaryBoundBatch.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity(), (k1, k2) -> k1));
            UserBoundVO first = map.get(ftbPersonnelsTransferManage.getUserId());
            if (first != null) {
                LambdaQueryWrapper<FtbPersonnelsStaffRoster> queryWrapper = Wrappers.lambdaQuery();
                queryWrapper.select(FtbPersonnelsStaffRoster::getSystemWokerId);
                queryWrapper.eq(FtbPersonnelsStaffRoster::getUserId, ftbPersonnelsTransferManage.getUserId());
                FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(queryWrapper);
                // 员工ID
                ftbHandleTransferDetailsVO.setSystemWorkerId(ftbPersonnelsStaffRoster.getSystemWokerId());
                // 员工姓名
                ftbHandleTransferDetailsVO.setUserName(first.getUserName());
            }
            UserBoundVO second = map.get(ftbHandleTransferDetailsVO.getHandlePersonId());
            if (second != null) {
                ftbHandleTransferDetailsVO.setHandlePersonName(second.getUserName());
            }
        }
        return ftbHandleTransferDetailsVO;
    }

    @Override
    public void transferEffectScheduledTask(String tenantId) {
        LambdaQueryWrapper<FtbPersonnelsTransferManage> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsTransferManage::getEnableMarkd, 0);
        queryWrapper.in(FtbPersonnelsTransferManage::getProcessingStatus, 2, 6);
        queryWrapper.eq(FtbPersonnelsTransferManage::getImplementType, 0);
        queryWrapper.apply("DATE_FORMAT(F_EffectiveDate, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d')");
        List<FtbPersonnelsTransferManage> ftbPersonnelsTransferManages = this.baseMapper.selectList(queryWrapper);
        ftbPersonnelsTransferManages.forEach(a -> {
            // 同步数据至组织架构
            syncDataToOrganization(a.getUserId(), a.getAfterOrgId(),
                    a.getAfterPostId(), a.getAfterRankId(), a.getAfterTeamId(),
                    a.getAfterDirectSupervisorId(), tenantId);
            // 账号下线
            accountOffline(tenantId, a.getUserId());
        });
        this.baseMapper.updateTransferManage();
        log.error("定时任务调动执行成功：{}", DateUtil.formatDate(new Date()));
    }

    @Override
    public List<Map<String, String>> queryFieldValue() {
        List<Map<String, String>> result = new ArrayList<>();
        // 调动类型0调岗1晋升2降职3调店
        Map<String, String> transferType = new HashMap<>();
        transferType.put("id", "0");
        transferType.put("name", "调岗");
        result.add(transferType);
        Map<String, String> promotion = new HashMap<>();
        promotion.put("id", "1");
        promotion.put("name", "晋升");
        result.add(promotion);
        Map<String, String> demotion = new HashMap<>();
        demotion.put("id", "2");
        demotion.put("name", "降职");
        result.add(demotion);
        Map<String, String> transferStore = new HashMap<>();
        transferStore.put("id", "3");
        transferStore.put("name", "调店");
        result.add(transferStore);
        return result;
    }

    @Override
    @Transactional
    public void revokeTheTransferRecord(String id) {
        FtbPersonnelsTransferManage ftbPersonnelsTransferManage = this.baseMapper.selectById(id);
        LambdaUpdateWrapper<FtbPersonnelsTransferManage> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, id);
        updateWrapper.set(FtbPersonnelsTransferManage::getProcessingStatus, 4);
        this.update(new FtbPersonnelsTransferManage(), updateWrapper);
        // 薪资作废
        if (ftbPersonnelsTransferManage.getSalaryStructure() == 1) {
            ActionResult actionResult = null;
            try {
                actionResult = querySalaryApi.voidSalary(ftbPersonnelsTransferManage.getUserId(),
                        DateUtil.format(ftbPersonnelsTransferManage.getEffectiveDate(), "yyyy-MM-dd"),
                        ftbPersonnelsTransferManage.getSalaryRecordId());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            if (actionResult.getCode() != 200) {
                throw new RuntimeException(actionResult.getMsg());
            }
        }
    }

    @Override
    public void clearTransferData(List<String> userId) {
        LambdaUpdateWrapper<FtbPersonnelsTransferManage> queryWrapper = Wrappers.lambdaUpdate();
        queryWrapper.in(FtbPersonnelsTransferManage::getUserId, userId);
        queryWrapper.set(FtbPersonnelsTransferManage::getEnableMarkd, 1);
        this.baseMapper.update(new FtbPersonnelsTransferManage(), queryWrapper);
    }

    @Override
    public List<Date> transferCheckTimeCrossing(String userId, Date startTime, Date endTime) {
        LambdaQueryWrapper<FtbPersonnelsTransferManage> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(FtbPersonnelsTransferManage::getEffectiveDate);
        queryWrapper.eq(FtbPersonnelsTransferManage::getUserId, userId);
        queryWrapper.in(FtbPersonnelsTransferManage::getProcessingStatus,2,6);
        queryWrapper.apply("DATE_FORMAT(F_EffectiveDate, '%Y-%m-%d') >= DATE_FORMAT('" + DateUtil.format(startTime, "yyyy-MM-dd") + "', '%Y-%m-%d')");
        queryWrapper.apply("DATE_FORMAT(F_EffectiveDate, '%Y-%m-%d') <= DATE_FORMAT('" + DateUtil.format(endTime, "yyyy-MM-dd") + "', '%Y-%m-%d')");
        return this.baseMapper.selectList(queryWrapper)
                .stream()
                .map(FtbPersonnelsTransferManage::getEffectiveDate)
                .collect(Collectors.toList());

    }

    /**
     * 调动数据校验
     */
    private void transferDataCheck(FtbHandleTransferDTO ftbHandleTransferDTO) {
        String before = ftbHandleTransferDTO.getBeforeOrgId() + "#" + ftbHandleTransferDTO.getBeforePostId();
        before = before + "#" + (StrUtil.isBlank(ftbHandleTransferDTO.getBeforeRankId()) ? "" : ftbHandleTransferDTO.getBeforeRankId()) + "#"
                + (StrUtil.isBlank(ftbHandleTransferDTO.getBeforeTeamId()) ? "" : ftbHandleTransferDTO.getBeforeTeamId());
        String after = ftbHandleTransferDTO.getAfterOrgId() + "#" + ftbHandleTransferDTO.getAfterPostId();
        after = after + "#" + (StrUtil.isBlank(ftbHandleTransferDTO.getAfterRankId()) ? "" : ftbHandleTransferDTO.getAfterRankId()) + "#"
                + (StrUtil.isBlank(ftbHandleTransferDTO.getAfterTeamId()) ? "" : ftbHandleTransferDTO.getAfterTeamId());
        if (before.equals(after)) {
            throw new RuntimeException("调动前/后的信息无变更，不可提交");
        }
        // 调动生效日期不能早于实际入职日期
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(FtbPersonnelsStaffRoster::getActualStartDate);
        queryWrapper.eq(FtbPersonnelsStaffRoster::getUserId, ftbHandleTransferDTO.getUserId());
        queryWrapper.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
        FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(queryWrapper);
        if (ftbPersonnelsStaffRoster != null && ftbPersonnelsStaffRoster.getActualStartDate().after(ftbHandleTransferDTO.getEffectiveDate())) {
            throw new RuntimeException("调动生效日期不能早于实际入职日期");
        }
        // 薪资总额校验
        if (Objects.nonNull(ftbHandleTransferDTO.getSalaryTotal()) && ftbHandleTransferDTO.getSalaryTotal().compareTo(new BigDecimal("1000000000")) >= 1) {
            throw new RuntimeException("薪资项合计超出上限，请输入合法薪资数据");
        }
        // 调动前组织信息与当前组织信息是否一致
        ActionResult<List<UserBoundVO>> usersBoundAc = v2UserApi.getUserPrimaryBoundBatch(List.of(ftbHandleTransferDTO.getUserId()), null);
        if (Objects.nonNull(usersBoundAc.getData())) {
            UserBoundVO data = usersBoundAc.getData().get(0);
            String curr = data.getOrganizeId() + "#" + data.getPositionId() + "#";
            curr = curr + (StrUtil.isBlank(data.getGradeId()) ? "" : data.getGradeId()) + "#" + (StrUtil.isBlank(data.getStoreTeamId()) ? "" : data.getStoreTeamId());
            if (!before.equals(curr)) {
                throw new RuntimeException("该员工调动前组织信息与当前所在组织信息不一致，不能办理！");
            }
        }
        // 获取调动后的直属主管是否是被办理用户
        if (StrUtil.isNotBlank(ftbHandleTransferDTO.getAfterDirectSupervisorId())) {
            ActionResult<List<UserBoundVO>> usersBoundAfterDirectSupervisor = v2UserApi.getUserPrimaryBoundBatch(List.of(ftbHandleTransferDTO.getAfterDirectSupervisorId()), null);
            if (Objects.nonNull(usersBoundAfterDirectSupervisor.getData())) {
                UserBoundVO data = usersBoundAfterDirectSupervisor.getData().get(0);
                if (ftbHandleTransferDTO.getUserId().equals(data.getLeaderId())) {
                    String errorMsg = "被办理人是" + ftbHandleTransferDTO.getAfterDirectSupervisorName() + "（已选择的主管）的直属主管，不能互为主管！";
                    throw new RuntimeException(errorMsg);
                }
            }
        }
    }

    /**
     * 校验调动与借调时间是否冲突
     *
     * @param userId        用户ID
     * @param effectiveDate 生效日期
     */
    private void checkTransferAndSecondmentConflict(String userId, Date effectiveDate) {
        List<FtbPersonnelsSecondmentManagement> serviceIdList = ftbPersonnelSecondmentManagementService.salarySecondmentCrossover(userId, effectiveDate);
        if (CollUtil.isNotEmpty(serviceIdList)) {
            String collected = serviceIdList.stream().map(v -> {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                return sdf.format(v.getSecondmentStartTime()) + "~" + sdf.format(v.getSecondmentEndTime());
            }).collect(Collectors.joining(","));
            String joined = String.format("当前办理调动选择日期为%s生效，\n" +
                            "检测到您有一项借调业务的起止时间(%s)与当前办理业务的生效日期\n" +
                            "重叠，请重新选择日期(可选择借调开始之前的日期或者借调结束之后的日期)",
                    DateUtil.formatDate(effectiveDate), collected);
            throw new RuntimeException(joined);
        }
    }

    /**
     * 同步数据至组织架构
     */
    private void syncDataToOrganization(String userId, String organizeId, String positionId, String gradesId, String storeTeamId, String leaderId, String tenantId) {
        UserBoundInfoDTO dto = new UserBoundInfoDTO();
        dto.setOrganizeId(organizeId);
        dto.setPositionId(positionId);
        dto.setGradesId(gradesId);
        dto.setStoreTeamId(storeTeamId);
        dto.setLeaderId(leaderId);
        dto.setTenantId(tenantId);
        ActionResult<Boolean> booleanActionResult = v2UserApi.updateUserBoundInfo(userId, dto);
        if (booleanActionResult == null || !booleanActionResult.getData()) {
            throw new RuntimeException("更新用户绑定信息失败");
        }
    }

    /**
     * 获取直属主管姓名
     *
     * @param userId 用户 ID
     * @return {@link String }
     */
    private String getUserName(String userId) {
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(FtbPersonnelsStaffRoster::getName);
        queryWrapper.eq(FtbPersonnelsStaffRoster::getUserId, userId);
        FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(queryWrapper);
        if (Objects.nonNull(ftbPersonnelsStaffRoster)) {
            return ftbPersonnelsStaffRoster.getName();
        }
        return null;
    }

    /**
     * 发送调动通知mq至考勤，用于考勤排班
     *
     * @param userId 用户ID
     * @param organizeId 组织ID
     * @param entryDate 生效日期
     */
    private void sendTransferNoticeMq(String userId, String organizeId, Date entryDate,String beforeOrgId) {
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("userId", userId);
        hashMap.put("entryDate", entryDate);
        hashMap.put("organizeId", organizeId);
        hashMap.put("beforeOrgId", beforeOrgId);
        hashMap.put("tenantId", UserProvider.getUser().getTenantId());
        secondmentConsumerSourceMsg.sendMessageOnboarding(JSONObject.toJSONString(hashMap));
    }

}
