package jnpf.personnels.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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 com.google.common.collect.Maps;
import io.seata.spring.annotation.GlobalTransactional;
import jnpf.ContractSignPersonnelNoticeApi;
import jnpf.EvaluateManageApi;
import jnpf.account.PTenantAccountApi;
import jnpf.attendance.dto.GroupUpdateByUserDTO;
import jnpf.authority.service.FtbPermissionRoleAuthorizePersonService;
import jnpf.authority.utils.PermissionsApplicableEnums;
import jnpf.authority.utils.PermissionsApplicableObject;
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.base.vo.PageListVO;
import jnpf.cultivate.service.impl.FtbCultivateFileService;
import jnpf.cultivate.utils.CultivatePerUtils;
import jnpf.engine.FlowTaskApi;
import jnpf.engine.entity.FlowTaskEntity;
import jnpf.engine.model.flowstatistics.vo.ReloadTaskVO;
import jnpf.entity.StoreEntity;
import jnpf.enums.personnel.FtbPersonnelsCheckStatusCodeEnum;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.dto.offline.FtbCultivateOfflineFileDTO;
import jnpf.model.cultivate.event.JnpfApplicationEvent;
import jnpf.model.cultivate.event.dto.file.FileEventDTO;
import jnpf.model.cultivate.po.FtbCultivateFile;
import jnpf.model.cultivate.vo.offline.FtbCultivateOfflineFileVO;
import jnpf.model.enums.FtbPersonnelsAuditTaskEnum;
import jnpf.model.enums.FtbPersonnelsCofigEnum;
import jnpf.model.personnels.bo.ExportRosterOneVo;
import jnpf.model.personnels.bo.FtbRosterImportTemplateBO;
import jnpf.model.personnels.dto.base.PersonnelsQueryDTO;
import jnpf.model.personnels.dto.black.FtbPersonnelsBlacklistAddDTO;
import jnpf.model.personnels.dto.regular.FtbPersonnelsForAppQueryDTO;
import jnpf.model.personnels.dto.staff.field.ExportFormTypeDto;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.staff.roster.StaffDepartDto;
import jnpf.model.personnels.dto.staff.roster.StaffHomeDto;
import jnpf.model.personnels.dto.staff.roster.WorkerGroupDataDto;
import jnpf.model.personnels.dto.turnover.*;
import jnpf.model.personnels.po.*;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.personnels.vo.app.FtbPersonnelsBubbleCountVO;
import jnpf.model.personnels.vo.task.FtbPersonnelsResult;
import jnpf.model.personnels.vo.turnover.FtbPersonnelsTurOrgInfo;
import jnpf.model.personnels.vo.turnover.FtbPersonnelsTurnoverInfoVO;
import jnpf.model.personnels.vo.turnover.FtbPersonnelsTurnoverManagementVO;
import jnpf.permission.OrganizeApi;
import jnpf.permission.RoleApi;
import jnpf.permission.UserApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.v2.user.UpdateUserDTO;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.model.organize.OrganizeListVO;
import jnpf.permission.model.role.RoleCountUserRelationVO;
import jnpf.permission.model.role.RoleUserBoundVO;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.permission.model.user.PositionMoreBoundVO;
import jnpf.permission.model.user.SubordinateUserInfoVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.mapper.*;
import jnpf.personnels.service.*;
import jnpf.personnels.utils.*;
import jnpf.store.service.StoreService;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.util.context.SpringContext;
import jnpf.util.excel.EasyExcelUtils;
import jnpf.vo.ContractSignPersonnelFlagVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FtbPersonnelsTurnoverManagementServiceImpl extends ServiceImpl<FtbPersonnelsTurnoverManagementMapper, FtbPersonnelsTurnoverManagement> implements FtbPersonnelsTurnoverManagementService {

    @Resource
    private FtbPersonnelsTurnoverHandoverService handoverService;

    @Resource
    private FtbCultivateFileService ftbCultivateFileService;

    @Resource
    private FtbPersonnelsAuditRunTaskService runTaskService;

    @Resource
    private FtbPersonnelsAuditSubConfigService subConfigService;

    @Resource
    private FtbPersonnelsTurnoverAccountRegistrationMapper registrationMapper;

    @Resource
    private  StoreService storeService;

    @Autowired
    private OrganizeApi organizeApi;

    @Resource
    private FtbPersonnelsStaffRosterService staffRosterService;

    @Autowired
    private PersonnelOrgUtils personnelOrgUtils;

    @Autowired
    private RoleApi roleApi;

    @Resource
    public PersonnelPerUtils personnelPerUtils;

    @Autowired
    private UserApi userApi;

    @Resource
    private CultivatePerUtils cultivatePerUtils;

    @Resource
    private FtbPersonnelsBlacklistService blacklistService;

    @Resource
    private  FtbPersonnelsBlacklistTypeMapper ftbPersonnelsBlacklistTypeMapper;

    @Resource
    FtbPersonnelsRegularManagementService regularManagementService;

    @Resource
    FtbPersonnelsPostApplyService personnelsPostApplyService;

    @Resource
    FtbPersonnelsStaffTransferPositionService transferPositionService;

    @Resource
    FtbPersonnelsPermissionsService personnelsPermissionsService;

    @Resource
    FlowTaskApi flowTaskApi;
    @Resource
    ContractSignPersonnelNoticeApi contractSignPersonnelNoticeApi;

    @Resource
    EvaluateManageApi evaluateManageApi;

    @Resource
    PermissionsUtils permissionsUtils;

    @Autowired
    private V2UserApi v2UserApi;

    @Resource
    FtbPermissionRoleAuthorizePersonService ftbPermissionRoleAuthorizePersonService;


    @Autowired
    FtbPersonnelsStaffEmploymentApplyService staffEmploymentApplyService;


    @Autowired
    FtbPersonnelsTransferManageService transferManageService;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    private FtbPersonnelsStaffRegistrationFormDataMapper dataMapper;

    @Autowired
    FtbPersonnelsSecondmentManagementService secondmentManagementService;


    @Autowired
    private FtbPersonnelsStaffRegistrationFormDataService registrationFormDataService;


    @Autowired
    private RosterExportUtils rosterExportUtils;

    @Autowired
    private FtbPersonnelsRegistrationFormFieldOptionService fieldOptionService;

    @Autowired
    private PTenantAccountApi pTenantAccountApi;


    @Override
    @Transactional
    public String applyForResignation(FtbPersonnelsTurnoverCreateDTO createDto) {
        List<WorkerGroupDataDto> userOrgBoundInfo = personnelOrgUtils.getUserOrgBoundInfo(createDto.getUserId());
        if (CollUtil.isNotEmpty(userOrgBoundInfo)) createDto.setOrganizationInfo(userOrgBoundInfo);
        FtbPersonnelsTurnoverManagement management = FtbPersonnelsTurnoverCreateDTO.coverFtbPersonnelsTurnoverManagement(createDto);
        UserInfo userInfo = UserProvider.getUser();
        if (management.getUserId().equals(userInfo.getUserId())){
            throw new RuntimeException("无法给自己进行手动离职!");
        }
        if (CollUtil.isNotEmpty(createDto.getOrganizationInfo())) {
            management.setOrganizationInfo( JSONObject.toJSONString(createDto.getOrganizationInfo()));
        }
        if (CollUtil.isNotEmpty(createDto.getOrganizationInfoForApp())) {
            management.setOrganizationInfo( JSONObject.toJSONString(createDto.getOrganizationInfoForApp()));
        }
        String userId = management.getUserId();
        // 离职交接物品
        List<FtbPersonnelsTurnoverHandoverDTO> createDtoHandover = createDto.getHandover();
        if (CollUtil.isNotEmpty(createDtoHandover)){
            //校验物品人是不是选择了本人
            List<String> usrIds = createDtoHandover.stream().map(FtbPersonnelsTurnoverHandoverDTO::getArticleRecipientId).collect(Collectors.toList());
            if (usrIds.contains(userId)){
                throw new RuntimeException("离职交接物品不能选择本人!");
            }
        }
        // 校验是否处于流程中
        checkWhetherTheCheckIsInTheProcess(userId);
        // 校验
        String flag = calibrationNumber(userId);
        int record = secondmentManagementService.checkWhetherThereIsASecondmentRecord(userId, createDto.getResignationDate());
        if (record > 0){
            log.error("该员工离职日期处于借调时间段中，到达离职日期将自动结束借调！");
            flag = "3";
        }
        // 标识强制申请
        if (createDto.getForceDelete() == null && flag != null) return flag;
        // 设计多态审核
        // 编辑
        String newFlag = "";
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getWorkingCondition,"304");
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getUserId,userId);
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark,0);
        Long l = baseMapper.selectCount(queryWrapper);
        if (l>0) throw new RuntimeException("该员工处于待离职，请勿重复操作!");
        FtbPersonnelsTurnoverManagement turnoverManagement = baseMapper.selectById(management.getId());
        if (ObjectUtil.isNotEmpty(turnoverManagement)){
            // 离职编辑 删除之前的信息
            LambdaUpdateWrapper<FtbPersonnelsTurnoverHandover> wrapper = Wrappers.lambdaUpdate();
            wrapper.eq(FtbPersonnelsTurnoverHandover::getManagementId, management.getId());
            handoverService.remove(wrapper);
            // 删除上传的文件重新上传
            LambdaUpdateWrapper<FtbCultivateFile> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(FtbCultivateFile::getBusinessId, management.getId());
            ftbCultivateFileService.remove(updateWrapper);
        }
        FtbPersonnelsResult result = FtbPersonnelsResult.getResult(createDto.getSource(),createDto.getFlag());
        management.setTurnoverStatus(result.state);
        management.setApplicationSource(result.source);
        if (result.source == 0){
            management.setEmpResignationDate(createDto.getResignationDate());
        }else {
            management.setResignationDate(createDto.getResignationDate());
        }
        management.setTaskInfoId(null);
        management.setCreatorTime(new Date());
        management.setEnableMark(0L);
        management.setWorkingCondition("304");
        // 改为待离职状态
        staffRosterService.innerChangeWaitDepart(userId,null,0);

        UpdateUserDTO userDTO = new UpdateUserDTO();
        userDTO.setWorkerStatus("304");
        v2UserApi.updateUserInfo(userId,userDTO);

        saveOrUpdate(management);
        String managementId = management.getId();
        //  查询人员是否签署电子合同进行弹窗
        ActionResult<ContractSignPersonnelFlagVo> actionResult = contractSignPersonnelNoticeApi.signPersonnel(userId, UserProvider.getUser().getTenantId());
        if (actionResult != null && actionResult.getCode() == 200){
            ContractSignPersonnelFlagVo data = actionResult.getData();
            if (data != null && CollUtil.isNotEmpty(data.getSignType()) ){
                if ( data.getSignType().contains(0)) {
                    newFlag = "6";
                }else if ( ! data.getSignType().contains(0) && data.getSignType().contains(1)){
                    newFlag = "7" ;
                }
            }
        }
        //加入黑名单
        if (management.getIsBeBlackList() == 1){
            // 加入黑名单
            FtbPersonnelsBlacklistAddDTO ftbPersonnelsBlacklistAddDTO = FtbPersonnelsTurnoverCreateDTO.covertBlacklist(management);
            blacklistService.addBlacklist(ftbPersonnelsBlacklistAddDTO);
        }

        if (CollUtil.isNotEmpty(createDtoHandover)){
            Map<String, List<FtbPersonnelsTurnoverHandoverDTO>> listMap =
                    createDtoHandover.stream().collect(Collectors.groupingBy(FtbPersonnelsTurnoverHandoverDTO::getTurnoverType, Collectors.toList()));
            listMap.keySet().forEach(item->{
                List<FtbPersonnelsTurnoverHandoverDTO> handoverDTOS = listMap.get(item);
                List<FtbPersonnelsTurnoverHandover> turnoverHandovers = handoverDTOS.stream().map(vo -> {
                    FtbPersonnelsTurnoverHandover handover = FtbPersonnelsTurnoverHandoverDTO.coverFtbPersonnelsTurnoverHandover(vo);
                    handover.setManagementId(managementId);
                    if (StringUtils.isEmpty(handover.getArticleRecipientId()) &&
                            handover.getArticleRecipientId().equals(management.getUserId())) throw new RuntimeException("离职交接不能选择本人!");
                    return handover;
                }).collect(Collectors.toList());
                handoverService.saveBatch(turnoverHandovers);
            });
        }
        //通过文件事件监听信息
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                .files(createDto.getFiles())
                .businessTypeID(managementId)
                .type(FileEventDTO.FileType.RESIGNATION_MANAGEMENT)
                .build()));
        // 同步数据
        removeAccountAndAddDataSynchronizationStatus(managementId, management.getResignationDate(),userId,management.getUserName());
        return newFlag;
    }



    @Override
    @GlobalTransactional
    public ActionResult<Void> applyForResignatioForOA(FtbPersonnelsTurnoverCreateDTO createDto) {
        ActionResult<Void> actionResult = new ActionResult<>();
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg( FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg() );
        if (StringUtils.isNotEmpty(createDto.getReasonForResignation())){
            List<String> stringList = JSONObject.parseArray(createDto.getReasonForResignation(), String.class);
            // 数据转换
            createDto.setReasonForResignation(stringList.stream().collect(Collectors.joining(",")));
        }
        Integer isBeBlackListForOA = createDto.getIsBeBlackListForOA();
        if (ObjectUtil.isNotEmpty(isBeBlackListForOA)){
            if (isBeBlackListForOA == 2) {
                createDto.setIsBeBlackList(1);
            } else {
                createDto.setIsBeBlackList(0);
            }
        }
        Integer blackListPeriodForOA = createDto.getBlackListPeriodForOA();
        if (ObjectUtil.isNotEmpty(blackListPeriodForOA)){
            createDto.setBlackListPeriod(blackListPeriodForOA -1 );
        }
        FtbPersonnelsTurnoverManagement management = FtbPersonnelsTurnoverCreateDTO.coverFtbPersonnelsTurnoverManagement(createDto);
        FtbPersonnelsResult result = FtbPersonnelsResult.getResult(createDto.getSource(),createDto.getFlag());
        management.setTurnoverStatus(result.state);
        management.setApplicationSource(result.source);
        if (result.source == 0){
            management.setEmpResignationDate(createDto.getResignationDate());
        }else {
            management.setResignationDate(createDto.getResignationDate());
        }
        List<FtbCultivateOfflineFileDTO> fileDTOS = new ArrayList<>();
        if (StringUtils.isNotEmpty(createDto.getFilesWithOa())){
            String filesWithOa = createDto.getFilesWithOa();
            fileDTOS = JSONObject.parseArray(filesWithOa, FtbCultivateOfflineFileDTO.class);
        }
        // 个人办理不需要验证权限
        if (ObjectUtil.isNotEmpty(createDto.getSource()) &&  createDto.getSource() != 0 && !UserProvider.getUser().getIsAdministrator()) {
            // 权限用户
            List<String> userIds = permissionsUtils.obtainPersonnelUserIdDataPermissions(UserProvider.getUser().getUserId(), PermissionsEnums.PERSONNEL_MANAGEMENT_WEB.getValue(), "Web");
            // 当前人不是本人申请,且权限中有当前可以办理人
            if ((management.getApplicationSource() != 0) && (CollUtil.isNotEmpty(userIds) && !userIds.contains(management.getUserId()))) {
                actionResult.setMsg("当前人办理人不具有该员工办理权限!");
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                return actionResult;
            }
        }
        // 构建数据
        buildYourData(management);
        String userId = management.getUserId();
        List<WorkerGroupDataDto> userOrgBoundInfo = personnelOrgUtils.getUserOrgBoundInfo(userId);
        if (CollUtil.isNotEmpty(userOrgBoundInfo)) management.setOrganizationInfo(JSONObject.toJSONString(userOrgBoundInfo));
        // 离职交接物品
        // oa单独处理只能选一个人
        if (CollUtil.isNotEmpty(createDto.getRecipientOfTheWorkUserId()) ){
            //校验物品人是不是选择了本人
            List<String> recipientOfTheWorkUserIds = createDto.getRecipientOfTheWorkUserId();
            if (userId.equals(recipientOfTheWorkUserIds.get(0))  ){
                actionResult.setMsg("离职交接物品不能选择本人!");
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                return actionResult;
            }
        }
        if (management.getResignationDate() !=null && management.getDateOfEntry().after(management.getResignationDate())){
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg("离职日期不能小于入职日期!");
            return actionResult;
        }
        if (CollUtil.isNotEmpty(createDto.getRecipientOfTheItemUserId()) ){
            //校验物品人是不是选择了本人
            List<String> recipientOfTheItemUserIds = createDto.getRecipientOfTheItemUserId();
            if (userId.equals(recipientOfTheItemUserIds.get(0))){
                actionResult.setMsg("离职交接物品不能选择本人!");
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                return actionResult;
            }
        }
        // 校验是否处于流程中
        checkWhetherTheCheckIsInTheProcess(userId);
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getWorkingCondition,"304");
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getUserId,userId);
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark,0);
        Long l = baseMapper.selectCount(queryWrapper);
        if (l>0) {
            actionResult.setMsg("该员工处于待离职，请勿重复操作!");
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            return actionResult;
        }
        // 编辑
        FtbPersonnelsTurnoverManagement turnoverManagement = baseMapper.selectById(management.getId());
        if (ObjectUtil.isNotEmpty(turnoverManagement)){
            // 离职编辑 删除之前的信息
            LambdaUpdateWrapper<FtbPersonnelsTurnoverHandover> wrapper = Wrappers.lambdaUpdate();
            wrapper.eq(FtbPersonnelsTurnoverHandover::getManagementId, management.getId());
            handoverService.remove(wrapper);
            // 删除上传的文件重新上传
            LambdaUpdateWrapper<FtbCultivateFile> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(FtbCultivateFile::getBusinessId, management.getId());
            ftbCultivateFileService.remove(updateWrapper);
        }
        management.setCreatorTime(new Date());
        management.setEnableMark(0L);
        // 标识为新审批
        management.setVersionNum(1);
        String taskId = createDto.getTaskId();
        management.setTaskInfoId(taskId);
        management.setWorkingCondition("304");
        management.setTurnoverStatus(FtbPersonnelsAuditTaskEnum.UNDER_REVIEW.getCode());
        saveOrUpdate(management);
        String managementId = management.getId();
        // 改为待离职状态
        staffRosterService.innerChangeWaitDepart(userId,taskId,1);
        // 修改状态
        UpdateUserDTO userDTO = new UpdateUserDTO();
        userDTO.setWorkerStatus("304");
        v2UserApi.updateUserInfo(userId,userDTO);
        // 物品接收人
        if (CollUtil.isNotEmpty(createDto.getRecipientOfTheWorkUserId()) || CollUtil.isNotEmpty(createDto.getRecipientOfTheItemUserId())){
            List<FtbPersonnelsTurnoverHandover> turnoverHandoverList = new ArrayList<>();
            // 离职工作接收人
            if(CollUtil.isNotEmpty(createDto.getRecipientOfTheWorkUserId())){
                String recipientOfTheWorkInfo = createDto.getRecipientOfTheWorkInfo();
                String recipientOfTheWorkUserId = createDto.getRecipientOfTheWorkUserId().get(0);
                if (StringUtils.isNotEmpty(recipientOfTheWorkInfo) && StringUtil.length(recipientOfTheWorkInfo) > 50){
                    actionResult.setMsg("离职交接详情不能超过50字!");
                    actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                    return actionResult;
                }
                FtbPersonnelsTurnoverHandover turnoverHandovers = getFtbPersonnelsTurnoverHandover("2", managementId,
                        recipientOfTheWorkInfo, recipientOfTheWorkUserId);
                turnoverHandoverList.add(turnoverHandovers);
            }
            // 离职物品接收人
            if(CollUtil.isNotEmpty(createDto.getRecipientOfTheItemUserId()) ){
                String recipientOfTheItemInfo = createDto.getRecipientOfTheItemInfo();
                if (StringUtils.isNotEmpty(recipientOfTheItemInfo) && StringUtil.length(recipientOfTheItemInfo) > 50){
                    actionResult.setMsg("离职交接详情不能超过50字!");
                    actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                    return actionResult;
                }
                String recipientOfTheItemUserId = createDto.getRecipientOfTheItemUserId().get(0);
                FtbPersonnelsTurnoverHandover turnoverHandovers = getFtbPersonnelsTurnoverHandover("1", managementId,
                        recipientOfTheItemInfo, recipientOfTheItemUserId);
                turnoverHandoverList.add(turnoverHandovers);
            }
            handoverService.saveBatch(turnoverHandoverList);
        }
        //通过文件事件监听信息
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                .files(fileDTOS)
                .businessTypeID(managementId)
                .type(FileEventDTO.FileType.RESIGNATION_MANAGEMENT)
                .build()));
        return actionResult;
    }

    @NotNull
    private FtbPersonnelsTurnoverHandover getFtbPersonnelsTurnoverHandover(String number, String managementId, String info,
                                                                           String userId) {
        FtbPersonnelsTurnoverHandover turnoverHandovers = new FtbPersonnelsTurnoverHandover();
        turnoverHandovers.setTurnoverType(number);
        turnoverHandovers.setManagementId(managementId);
        turnoverHandovers.setHandoverItems(info);
        turnoverHandovers.setArticleRecipientId(userId);
        UserEntity infoById = userApi.getInfoById(userId);
        if (ObjectUtil.isNotEmpty(infoById)) turnoverHandovers.setArticleRecipientName(infoById.getRealName());
        return turnoverHandovers;
    }

    private void buildYourData(FtbPersonnelsTurnoverManagement management) {
        StaffHomeDto staffHomeDto = staffRosterService.queryWorkerHomeDetail(management.getUserId());
        management.setPhoneNumber(staffHomeDto.getPhone());
        management.setUserName(staffHomeDto.getName());
        management.setJobNumber(staffHomeDto.getWorkerNo());
        management.setDateOfEntry(staffHomeDto.getActualStartDate());
        management.setActualConverDate(staffHomeDto.getActualProbationaryDate());
        management.setOrgId(staffHomeDto.getCurrOrg());
        management.setOrgName(staffHomeDto.getCurrOrgName());
        management.setEntryPostId(staffHomeDto.getCurrPosition());
        management.setEntryPostName(staffHomeDto.getCurrPositionName());
        management.setEntryGradeId(staffHomeDto.getCurrRank());
        management.setEntryGradeName(staffHomeDto.getCurrRankName());
        management.setSystemWokerId(staffHomeDto.getSystemWokerId());
        management.setProbation(staffHomeDto.getProbationPeriod());
        management.setProbationPeriodDay(staffHomeDto.getProbationPeriodDay());


    }


    private void checkWhetherTheCheckIsInTheProcess(String userId) {
        // null 不处于 ,1 转正 2,调岗, 3离职
        String s = runTaskService.checkWhetherTheCurrentPersonnelIsInTheReviewProcess(userId);
        if (StringUtil.isNotEmpty(s)){
            // 1 转正 2 调岗, 3 离职
            String str="";
            // 1 转正 2 调岗, 3 离职
            switch (s) {
                case "1":
                    str = "转正";
                    break;
                case "2":
                    str = "调岗";
                    break;
                case "3":
                    str = "离职";
                    break;
                case "4":
                    str = "晋升";
                    break;
                case "5":
                    str = "调店";
                    break;
                case "6":
                    str = "降职";
                    break;
                case "7":
                    str = "借调";
                    break;
            }
            throw new RuntimeException("当前人员处于"+str+"审批中,请勿重复进行审批!");
        }
        // 添加
        LambdaQueryWrapper<FtbPersonnelsSecondmentManagement> queryWrapper4 = Wrappers.lambdaQuery();
        queryWrapper4.eq(FtbPersonnelsSecondmentManagement::getUserId, userId);
        queryWrapper4.in(FtbPersonnelsSecondmentManagement::getTransferStatus, 1);
        queryWrapper4.eq(FtbPersonnelsSecondmentManagement::getEnableMark,0);
        long count1 = secondmentManagementService.count(queryWrapper4);
        if (count1 > 0){
            throw new RuntimeException("该员工处于借调审批中，请先完成审批，否则无法办理离职!");
        }
    }
    @Override
    public void jobTrialRejected(FtbPersonnelsJobTrialRejectedCreateDTO createDTO) {
        String tenantId = UserProvider.getUser().getTenantId();
        FtbPersonnelsTurnoverCreateDTO turnoverCreateDTO = FtbPersonnelsTurnoverCreateDTO.covertJobRejected(createDTO);
        FtbPersonnelsTurnoverManagement management = FtbPersonnelsTurnoverCreateDTO.coverFtbPersonnelsTurnoverManagement(turnoverCreateDTO);
        management.setWorkingCondition("305");
        // 组织岗位信息
        if (CollUtil.isNotEmpty(turnoverCreateDTO.getOrganizationInfo())) {
            management.setOrganizationInfo(JSONObject.toJSONString(turnoverCreateDTO.getOrganizationInfo()));
        }
        // 试岗驳回
        management.setApplicationSource(3);
        // 离职时间为当前时间
        management.setResignationDate(new Date());
        baseMapper.insert(management);
        String userId = management.getUserId();
        UserEntity userEntity = new UserEntity();
        userEntity.setId(userId);
        // 关闭用户
        userApi.deleteNoToken(userEntity,tenantId);
        // 清楚缓存
        staffRosterService.logout(tenantId,userId);
        //清楚考勤组
        GroupUpdateByUserDTO groupUpdateByUserDTO = new GroupUpdateByUserDTO();
        groupUpdateByUserDTO.setTenantId(tenantId);
        groupUpdateByUserDTO.setType(2);//1入职 2离职 3调岗
        groupUpdateByUserDTO.setUserIds(List.of(userId));
        personnelOrgUtils.syncAttendanceGroup(groupUpdateByUserDTO);
    }

    @Override
    public void deleteResignationApplication(List<String> userIds) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaQuery();
        wrapper.in(FtbPersonnelsTurnoverManagement::getUserId,userIds);
        wrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark,0);
        List<FtbPersonnelsTurnoverManagement> managementList = baseMapper.selectList(wrapper);
        if (CollUtil.isEmpty(managementList)){
            return;
        }
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> lambdaed = Wrappers.lambdaUpdate();
        lambdaed.set(FtbPersonnelsTurnoverManagement::getEnableMark,1);
        lambdaed.in(FtbPersonnelsTurnoverManagement::getId,managementList.stream()
                .map(SuperBaseEntity.SuperIBaseEntity::getId)
                .collect(Collectors.toList()));
        baseMapper.update(null,lambdaed);
        if (CollUtil.isNotEmpty(managementList) ){
            // 删除审核配置
            managementList.stream().filter(vo->StringUtils.isNotEmpty(vo.getTaskInfoId()) && vo.getVersionNum() == 0)
                    .forEach(item->runTaskService.deleteReviewProcessAndRecords(item.getTaskInfoId(),item.getId()));
        }

    }

    @Override
    public void deleteResignationApplicationWithId(List<String> id) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaQuery();
        wrapper.in(FtbPersonnelsTurnoverManagement::getId,id);
        wrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark,0);
        List<FtbPersonnelsTurnoverManagement> managementList = baseMapper.selectList(wrapper);
        if (CollUtil.isEmpty(managementList)){
            return;
        }
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> lambdaed = Wrappers.lambdaUpdate();
        lambdaed.set(FtbPersonnelsTurnoverManagement::getEnableMark,1);
        lambdaed.in(FtbPersonnelsTurnoverManagement::getId,id);
        baseMapper.update(null,lambdaed);
        if (CollUtil.isNotEmpty(managementList)){
            // 删除审核配置
            managementList.stream().filter(vo->
                            StringUtils.isNotEmpty(vo.getTaskInfoId()) && ObjectUtil.isNotEmpty(vo.getVersionNum())
                                    &&  vo.getVersionNum() == 0)
                    .forEach(item->runTaskService.deleteReviewProcessAndRecords(item.getTaskInfoId(),item.getId()));
        }
    }

    @Override
    public Boolean userHasSignedASeparationAgreement(String userId,Integer flag) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverAccountRegistration> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getUserId,userId);
        wrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getEnableMark,0);
        Long aLong = registrationMapper.selectCount(wrapper);
        if( aLong ==  0 ){
            return true;
        }
        LambdaUpdateWrapper<FtbPersonnelsTurnoverAccountRegistration> update = Wrappers.lambdaUpdate();
        // 0-未签署 1-已签署
        //update.set(FtbPersonnelsTurnoverAccountRegistration::getSignAgreement,flag);
        update.eq(FtbPersonnelsTurnoverAccountRegistration::getUserId,userId);
        return registrationMapper.update(null, update) > 0;
    }

    @Override
    public ActionResult<Void> resignationPreCheck(String userId,String taskFlag,String... whetherItPassesOrNot) {
        ActionResult<Void> maps = new ActionResult<>();
        // 校验是否处于流程中
        if ("1".equals(taskFlag)) {
            // 添加
            LambdaQueryWrapper<FtbPersonnelsSecondmentManagement> queryWrapper4 = Wrappers.lambdaQuery();
            queryWrapper4.eq(FtbPersonnelsSecondmentManagement::getUserId, userId);
            queryWrapper4.in(FtbPersonnelsSecondmentManagement::getTransferStatus, 1);
            queryWrapper4.eq(FtbPersonnelsSecondmentManagement::getEnableMark,0);
            long count1 = secondmentManagementService.count(queryWrapper4);
            if (count1 > 0){
                throw new RuntimeException("该员工处于借调审批中，请先完成审批，否则无法办理离职!");
            }
            checkWhetherTheCheckIsInTheProcess(userId);
        }
        String s = calibrationNumber(userId);

        LambdaQueryWrapper<FtbPersonnelsStaffRoster> queryWrapper1 = Wrappers.lambdaQuery();
        queryWrapper1.eq(FtbPersonnelsStaffRoster::getUserId, userId);
        queryWrapper1.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
        long count = staffRosterService.count(queryWrapper1);
        LambdaQueryWrapper<FtbPersonnelsStaffEmploymentApply> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getUserId, userId);
        queryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getEnabledMark, 0);
        queryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getIsNeedCheck, 0);
        queryWrapper.notIn(FtbPersonnelsStaffEmploymentApply::getCheckStatus, 2);
        queryWrapper.last("limit 1");
        FtbPersonnelsStaffEmploymentApply one = staffEmploymentApplyService.getOne(queryWrapper);
        if (Objects.nonNull(one) && count == 0) {
            throw new RuntimeException("当前选择人员还未办理入职,无法提交!");
        }

        //  "1" 为是否为审批人 2 是否为门店负责人 3是否存在角色组 4 自属主管
        int checkStatusCodeEnum = 200;
        String msg = "";
        if ("4".equals(s)){
            checkStatusCodeEnum = FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode();
        }else if ("1".equals(s)   || "3".equals(s) || "2".equals(s)){
            checkStatusCodeEnum = FtbPersonnelsCheckStatusCodeEnum.CHECK_WARNING.getCode();
        }
        if (StringUtils.isNotEmpty(s)) {
            switch (s) {
                case "1":
                    msg = "该员工当前有待处理的审批单,可在'OA-审批交接'主菜单中办理交接!";
                    break;
                case "2":
                    List<Map<String, Object>> userBoundApproval = getUserBoundApproval("2", userId);
                    String  string1= userBoundApproval.stream().map(item -> item.get("storeName").toString()).collect(Collectors.toList()).stream().collect(Collectors.joining(","));
                    msg = "该人员为"+string1+"的负责人，离职后该门店将暂无负责人。";
                    break;
                case "3":
                    List<Map<String, Object>> mapList = getUserBoundApproval("3", userId);
                    String  string= mapList.stream().map(item -> item.get("roleName").toString()).collect(Collectors.toList()).stream().collect(Collectors.joining(","));
                    msg = "该人员存在于"+string+"角色组中，建议对仅1人存在的角色组成员管理调整，可以避免业务断链的情况。";
                    break;
                case "4":
                    msg = "该人员有直系下属，请为相关下属重新绑定直属主管，否则无法办理离职。";
                    break;
            }
        }
        if (StringUtils.isNotEmpty(msg)) maps.setMsg(msg);
        maps.setCode(checkStatusCodeEnum);
        //  合同提示
        //  查询人员是否签署电子合同进行弹窗
        // 是否通过 0否,1是
        String flag = whetherItPassesOrNot != null && whetherItPassesOrNot.length > 0 ? whetherItPassesOrNot[0] : null;
        if (StringUtils.isEmpty(flag) || "1".equals(flag)){
            ActionResult<ContractSignPersonnelFlagVo> personnel = contractSignPersonnelNoticeApi.signPersonnel(userId, UserProvider.getUser().getTenantId());
            if (personnel != null && personnel.getCode() == 200){
                ContractSignPersonnelFlagVo data = personnel.getData();
                if (data != null && CollUtil.isNotEmpty(data.getSignType()) ){
                    if ( data.getSignType().contains(0)) {
                        maps.setMsg("该员工已办理电子版劳动合同，办理后需在电脑端电子合同模块作废劳动合同并发起离职证明。");
                        maps.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_WARNING.getCode());
                    }else if ( ! data.getSignType().contains(0) && data.getSignType().contains(1)){
                        maps.setMsg(" 该员工已办理纸质版合同，办理离职后可在电脑端电子合同模块直接发起离职证明。");
                        maps.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_WARNING.getCode());
                    }
                }
            }
        }
        return maps;
    }




    /**
     * 组装离职数据
     *
     * @param management
     * @return
     */
    @NotNull
    private StaffDepartDto getStaffDepartDtos(FtbPersonnelsTurnoverManagement management, int type) {
        StaffDepartDto dto = new StaffDepartDto();
        dto.setReasonForLeaving(management.getReasonForResignation());
        // 类型 1办理离职 2 试岗驳回
        dto.setType(type);
        dto.setActualStartDate(management.getDateOfEntry());
        dto.setEmployeeID(management.getSystemWokerId());
        List<WorkerGroupDataDto> workerGroupDataDtoList = personnelOrgUtils.getUserOrgBoundInfo(management.getUserId());
        if(CollectionUtil.isEmpty(workerGroupDataDtoList)) return dto;
        dto.setWorkerGroupDataDto(workerGroupDataDtoList);
        return dto;
    }

    @Override
    public List<Map<String, Object>> getUserBoundApproval(String flag, String userId) {
        // "1" 为是否为审批人 2 是否为门店负责人 3是否存在角色组
        List<Map<String, Object>> list = new ArrayList<>();
        switch (flag){
            case "1":
                ActionResult reloadTask = flowTaskApi.getReloadTask(userId);
                if (reloadTask !=null && reloadTask.getCode() == 200 && ObjectUtil.isNotEmpty(reloadTask.getData())) {
                    List<ReloadTaskVO> reloadTaskVOS = JSONObject.parseArray(reloadTask.getData().toString(), ReloadTaskVO.class);
                    // 处理数据
                    return reloadTaskVOS.stream().map(vo -> {
                        Map<String, Object> hashMap = new HashMap<>();
                        // 审批单编号
                        String taskCoding = vo.getTaskCoding();
                        // 审批单名称
                        String taskName = vo.getTaskName();
                        hashMap.put("taskCoding", taskCoding);
                        hashMap.put("taskName", taskName);
                        return hashMap;
                    }).collect(Collectors.toList());
                }
                break;
            case "2":
                List<StoreEntity> storeEntities = storeService.lambdaQuery().eq(StoreEntity::getStoreheaduserid, userId).list();
                List<String> collect1 = storeEntities.stream().map(StoreEntity::getOrganizeid).collect(Collectors.toList());
                Map<String, String> orgMap = cultivatePerUtils.convertOrganizationalId(collect1);
                list = storeEntities.stream().map(item -> {
                    Map<String, Object> hashMap = Maps.newHashMap();
                    OrganizeEntity organize = organizeApi.getInfoById(item.getOrganizeid());
                    hashMap.put("orgId",orgMap.get(item.getOrganizeid()));
                    hashMap.put("orgName",organize.getFullName());
                    hashMap.put("storeName",item.getStorename());
                    return hashMap;
                }).collect(Collectors.toList());
                break;
            case "3":
                // 获取用户绑定信息
                List<RoleUserBoundVO> userBoundRolesList = roleApi.getUserBoundRolesList(userId);
                if (CollUtil.isEmpty(userBoundRolesList)){
                    break;
                }
                list = getMaps(userBoundRolesList);
                break;
            case "4":
                List<SubordinateUserInfoVO> subordinateUserInfoVOS = userApi.userInfoByLeaderId(userId);
                if (CollUtil.isEmpty(subordinateUserInfoVOS)) {
                    break;
                }
                List<String> orgIds = subordinateUserInfoVOS.stream().map(PartUserInfoVo::getOrganizeId).collect(Collectors.toList());
                Map<String, String> map = cultivatePerUtils.convertOrganizationalId(orgIds);
                list = subordinateUserInfoVOS.stream().map(item -> {
                    List<String> collect = item.getPositionMoreBoundVOList().stream().map(PositionMoreBoundVO::getOrganizeName).collect(Collectors.toList());
                    Map<String, Object> hashMap = Maps.newHashMap();
                    hashMap.put("orgName", String.join(",", collect));
                    hashMap.put("orgId",map.get(item.getOrganizeId()));
                    hashMap.put("userName",item.getRealName());
                    return hashMap;
                }).collect(Collectors.toList());
                break;
        }
        return list;
    }

    @NotNull
    private List<Map<String, Object>> getMaps(List<RoleUserBoundVO> userBoundRolesList) {
        List<Map<String, Object>> list;
        list = userBoundRolesList.stream().map(item -> {
            List<RoleCountUserRelationVO> relationCount = roleApi.getRolesUserRelationCount(Collections.singletonList(item.getId()));
            if (CollUtil.isNotEmpty(relationCount)) {
                Map<String, Object> hashMap = Maps.newHashMap();
                hashMap.put("orgName", "");
                hashMap.put("roleName", "");
                hashMap.put("roleNubmer", "");
                hashMap.put("orgId", "");
                List<OrganizeListVO> organizeList = item.getOrganizeList();
                if (CollUtil.isNotEmpty(organizeList)){
                    List<String> stringList = organizeList.stream().map(OrganizeListVO::getId).collect(Collectors.toList());
                    Map<String, String> orgMap = cultivatePerUtils.convertOrganizationalId(stringList);
                    String orgName = organizeList.stream().map(vo -> {
                        String orgId = vo.getId();
                        OrganizeEntity infoById = organizeApi.getInfoById(orgId);
                        return infoById.getFullName();
                    }).collect(Collectors.joining(","));
                    String sysOrgId = organizeList.stream().map(vo -> orgMap.get(vo.getId())).collect(Collectors.joining(","));
                    hashMap.put("orgName", orgName);
                    hashMap.put("orgId", sysOrgId);
                }
                RoleCountUserRelationVO roleCountUserRelationVO = relationCount.stream().findFirst().orElse(new RoleCountUserRelationVO());
                hashMap.put("roleName", roleCountUserRelationVO.getFullName());
                hashMap.put("roleNubmer", roleCountUserRelationVO.getUserBoundCount());
                return hashMap;
            }
            return null;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public FtbPersonnelsBubbleCountVO getListCont(String flag) {
        //  flag "1" 我的审批 "2" 抄送
        FtbPersonnelsBubbleCountVO countVO=new FtbPersonnelsBubbleCountVO();
        FtbPersonnelsForAppQueryDTO appQueryDTO =new FtbPersonnelsForAppQueryDTO();
        appQueryDTO.setUserId(UserProvider.getUser().getUserId());
        if ("1".equals(flag)){
            appQueryDTO.setFlagByApp("2");
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.PENDING.getCode());
            Integer total = getTurnoverForList(appQueryDTO, new CultivatePage()).getPagination().getTotal();
            countVO.setPendingCount(Long.valueOf(total));
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.UNDER_REVIEW.getCode());
            appQueryDTO.setConfigType(FtbPersonnelsCofigEnum.RESIGNATION_APPROVAL_CONFIGURATION.getConfigType());
            // 审批中
            countVO.setQuantityUnderCount(baseMapper.getApprovedData(new Page<>(), appQueryDTO).getTotal());
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED.getCode());
            countVO.setApprovedCount(baseMapper.getApprovedData(new Page<>(), appQueryDTO).getTotal());
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.AUDIT_NOT_PASSED.getCode());
            countVO.setApprovalFailedCount(baseMapper.getApprovedData(new Page<>(), appQueryDTO).getTotal());
        }else if ("2".equals(flag)){
            appQueryDTO.setFlagByApp("3");
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.UNDER_REVIEW.getCode());
            appQueryDTO.init("3",FtbPersonnelsCofigEnum.RESIGNATION_APPROVAL_CONFIGURATION);
            countVO.setQuantityUnderCount(baseMapper.getListForCC(new Page<>(), appQueryDTO).getTotal());
            appQueryDTO.setStatusList(null);
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED.getCode());
            countVO.setApprovedCount(baseMapper.getListForCC(new Page<>(), appQueryDTO).getTotal());
            appQueryDTO.setApprovalStatus(FtbPersonnelsAuditTaskEnum.AUDIT_NOT_PASSED.getCode());
            countVO.setApprovalFailedCount(baseMapper.getListForCC(new Page<>(), appQueryDTO).getTotal());
        }
        return countVO;

    }



    @Override
    public PageListVO<FtbPersonnelsTurnoverManagementVO> getTurnoverList(PersonnelsQueryDTO dto, CultivatePage cultivatePage) {
        Page<FtbPersonnelsTurnoverManagementVO> page = cultivatePage.coverCultivatePage();
        // 校验离职用户是否都已经过期
        // extracted();
        Page<FtbPersonnelsTurnoverManagementVO> managementVOPage = null ;
        if (dto.getApprovalStatus() !=null &&  8 == dto.getApprovalStatus()){
            dto.setApprovalStatus(7);
        }
        // 如果有组织筛选且数据权限为管理员
        // 已筛序为准
        String postId = dto.getPostId();
        String gradeId = dto.getGradeId();
        List<String>  orgIds = null;
        List<String> filteOrgIds =  CollUtil.isNotEmpty(dto.getOrgIds()) ? dto.getOrgIds() : null;
        if (!UserProvider.getUser().getIsAdministrator() ) {
            // 数据权限userIds
            String userId = UserProvider.getUser().getUserId();
            orgIds =  permissionsUtils.obtainPersonnelOrganizationIdDataPermissions(userId);
            List<String> ids;
            PermissionsApplicableObject permissionsApplicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(UserProvider.getUser().getUserId());
            // 数据权限 仅下属单独处理
            if (permissionsApplicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE){
                // 查询当前登录人的下属
                ids = inquireAboutSubordinates(userId);
            } else {
                ids = doEmployeesOfYourOrganization(orgIds, postId, gradeId);
            }
            // 只要不是全部且数据为空
            if (!(orgIds  == null) && CollUtil.isEmpty(ids)) {
                return CultivatePage.coverPageList(page);
            }
            dto.setIds(ids);
        }
        if ( filteOrgIds != null){
            if (CollUtil.isNotEmpty(filteOrgIds) && CollUtil.isNotEmpty(orgIds)) {
                assert orgIds != null;
                orgIds = orgIds.stream().filter(filteOrgIds::contains).collect(Collectors.toList());
            }else if (CollUtil.isNotEmpty(filteOrgIds) && orgIds == null) {
                orgIds =filteOrgIds;
            }
            dto.setIds(doEmployeesOfYourOrganization(orgIds, postId, gradeId));
            if (CollUtil.isEmpty(dto.getIds())) {
                return CultivatePage.coverPageList(page);
            }
        }
        managementVOPage = baseMapper.getTurnoverList(page, dto);
        List<FtbPersonnelsTurnoverManagementVO> records = managementVOPage.getRecords();
        Map<String, FtbPersonnelsBlacklist> blacklistMap = new HashMap<>();
        List<String> userIds = records.stream().map(FtbPersonnelsTurnoverManagementVO::getUserId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userIds)) {
            LambdaQueryWrapper<FtbPersonnelsBlacklist> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(FtbPersonnelsBlacklist::getUserId,userIds);
            List<FtbPersonnelsBlacklist> list = blacklistService.list(queryWrapper);
            blacklistMap =  list.stream().collect(Collectors.toMap(FtbPersonnelsBlacklist::getUserId, Function.identity(), (a, b) -> a));
        }
        String userId = UserProvider.getUser().getUserId();
        Map<String, FtbPersonnelsBlacklist> finalBlacklistMap = blacklistMap;
        replaceTheNameBatch(records);
        records.forEach(item->{
            // 计算司龄
            item.setSiLing(calculateTheAgeOfTheDivision(item.getResignationDate(),item.getDateOfEntry(), item.getWorkingCondition()));
            // 离职管理--状态为“已手动办理”，如果超过离职日期，操作项去掉撤销按钮
            if (item.getResignationDate() != null &&
                    FtbPersonnelsAuditTaskEnum.MANUAL_CONTROL.getCode().equals(dto.getApprovalStatus())
                    && item.getResignationDate().before(new Date())){
                item.setRemoveTheUndoButtonLogo("1");
            }else {
                item.setRemoveTheUndoButtonLogo("0");
            }

            if (StringUtils.isNotEmpty(item.getTaskInfoId())) {
                FlowTaskEntity byTaskId = flowTaskApi.findByTaskId(item.getTaskInfoId());
                if (ObjectUtil.isNotEmpty(byTaskId) &&  byTaskId.getCreatorUserId().equals(userId)) {
                    item.setCurrentSponsor(1);
                } else {
                    item.setCurrentSponsor(0);
                }
            }
            // 是否纳入黑名单
            item.setWhetherToBeIncluded(finalBlacklistMap.containsKey(item.getUserId()) ? 1 : 0);
        });
        return CultivatePage.coverPageList(managementVOPage);
    }

    /**
     * 查询下属的离职id
     * @param userId
     * @return
     */
    public List<String> inquireAboutSubordinates(String userId){
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark ,0);
        List<FtbPersonnelsTurnoverManagement> managements = baseMapper.selectList(wrapper);
        return managements.stream().filter(v -> {
            String organizationInfo = v.getOrganizationInfo();
            List<WorkerGroupDataDto> dataDto = JSONArray.parseArray(organizationInfo, WorkerGroupDataDto.class);
            if (CollUtil.isEmpty(dataDto)) {
                return false;
            }
            long count = dataDto.stream().filter(data -> data.getIsDefault() && userId.equals(data.getReportsTo())).count();
            return count > 0;
        }).map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList());
    }

    @Override
    public void getTurnoverListExport(PersonnelsQueryDTO dto, HttpServletResponse response) throws IOException {

        // 校验离职用户是否都已经过期
        List<FtbPersonnelsTurnoverManagementVO> listVO = getUsers(dto);
        // 转换数字->汉字
        listVO.parallelStream().forEach(a -> {
            // 是否纳入黑名单
            if ("305".equals(a.getWorkingCondition())){
                a.setWhetherToBeIncludedName(a.getWhetherToBeIncluded() == 1 ? "是" : "否" );
            }else {
                a.setWhetherToBeIncludedName("--");
            }
            // 工作状态
            FtbPersonnelsTurnoverManagementVO.changeWorkStatus(a);
            // 申请来源
            FtbPersonnelsTurnoverManagementVO.changeApplySource(a);
            // 审批状态
            FtbPersonnelsTurnoverManagementVO.changeApprovalStatus(a);
            Date resignationDate = a.getResignationDate();
            if (resignationDate != null) {
                a.setResignationDateStr(DateUtil.format(resignationDate, "yyyy-MM-dd"));
             }
            if (a.getDateOfEntry() != null) {
                a.setDateOfEntryStr(DateUtil.format(a.getDateOfEntry(), "yyyy-MM-dd"));
            }
        });
        List<String> userIds = listVO.stream().map(FtbPersonnelsTurnoverManagementVO::getUserId).collect(Collectors.toList());
        List<String> phones = listVO.stream().map(FtbPersonnelsTurnoverManagementVO::getPhone).collect(Collectors.toList());
        Map<String, FtbPersonnelsStaffRoster> staffRosterMap = new HashMap<>();
        if (CollUtil.isNotEmpty(userIds)) {
            // 封装数据
            LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.in(FtbPersonnelsStaffRoster::getUserId, userIds);
            List<FtbPersonnelsStaffRoster> personnelsStaffRosters = staffRosterService.list(lambdaQueryWrapper);
            if (CollUtil.isNotEmpty(personnelsStaffRosters)) {
                staffRosterMap = personnelsStaffRosters.stream().collect(Collectors.toMap(FtbPersonnelsStaffRoster::getUserId, Function.identity()));
            }
        }
        Map<String, List<FtbPersonnelsStaffRegistrationFormData>> listWithPhone = registrationFormDataService.queryFormFieldValueListWithPhone(phones);
        Map<String, FtbPersonnelsStaffRoster> finalStaffRosterMap = staffRosterMap;
        List<ExportRosterOneVo> rosterDataList = listVO.stream().map(v -> {
            FtbPersonnelsStaffRoster staffRoster = new FtbPersonnelsStaffRoster();
            staffRoster.setUserId(v.getUserId());
            staffRoster.setName(v.getUserName());
            if (finalStaffRosterMap.containsKey(v.getUserId())) {
                FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = finalStaffRosterMap.get(v.getUserId());
                staffRoster.setId(ftbPersonnelsStaffRoster.getId());
            }
            List<FtbPersonnelsStaffRegistrationFormData> formData = listWithPhone.get(v.getPhone());
            return new ExportRosterOneVo(staffRoster, formData);
        }).collect(Collectors.toList());
        List<List<String>> excelHeaderList = ExcelHeaderUtil.getExcelHeaderList(FtbPersonnelsTurnoverManagementVO.class);
        List<List<Object>> lists = rosterExportUtils.extractAnnotatedFieldValues(listVO,FtbPersonnelsTurnoverManagementVO.class);
        FtbRosterImportTemplateBO templateBO = new FtbRosterImportTemplateBO();
        templateBO.setHeader(excelHeaderList);
        templateBO.setSheetName("Sheet1");
        templateBO.setData(lists);
        // 入职所属组织
        //入职所属岗位
        //入职所属职级
        //入职直属主管
        //入职所属门店
        //入职班组
        String[] stringList = new String[]{"入职所属组织", "入职所属岗位", "入职所属职级", "入职直属主管", "入职所属门店", "入职班组"};
        List<ExportFormTypeDto> onboarding = rosterExportUtils.getExportFormTypesWithOnboarding(stringList);
        //查询选项
        QueryWrapper<FtbPersonnelsRegistrationFormFieldOption> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 0)
                .orderByAsc(FtbPersonnelsRegistrationFormFieldOption::getId);
        List<FtbPersonnelsRegistrationFormFieldOption> optionList = fieldOptionService.list(wrapper);
        List<FtbRosterImportTemplateBO> templateBOList = rosterExportUtils.convertToFtbRosterImportTemplateBO(onboarding, optionList, rosterDataList);
        templateBOList.add(templateBO);
        templateBOList.sort(Comparator.comparing(FtbRosterImportTemplateBO::getSheetName));
        EasyExcelUtils.dynamicHeaderGeneration(response, "离职员工信息", templateBOList);
    }
    public  List<FtbPersonnelsTurnoverManagementVO> getUsers(PersonnelsQueryDTO dto){
        List<FtbPersonnelsTurnoverManagementVO> filterList = new ArrayList<>();
        if (dto.getApprovalStatus() !=null &&  8 == dto.getApprovalStatus()){
            dto.setApprovalStatus(7);
        }
        // 如果有组织筛选且数据权限为管理员
        // 已筛序为准
        String postId = dto.getPostId();
        String gradeId = dto.getGradeId();
        List<String>  orgIds = null;
        List<String> filteOrgIds =  CollUtil.isNotEmpty(dto.getOrgIds()) ? dto.getOrgIds() : null;
        if (!UserProvider.getUser().getIsAdministrator() ) {
            // 数据权限userIds
            String userId = UserProvider.getUser().getUserId();
            orgIds =  permissionsUtils.obtainPersonnelOrganizationIdDataPermissions(userId);
            List<String> ids;
            PermissionsApplicableObject permissionsApplicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(UserProvider.getUser().getUserId());
            // 数据权限 仅下属单独处理
            if (permissionsApplicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE){
                // 查询当前登录人的下属
                ids = inquireAboutSubordinates(userId);
            } else {
                ids = doEmployeesOfYourOrganization(orgIds, postId, gradeId);
            }
            // 只要不是全部且数据为空
            if (!(orgIds  == null) && CollUtil.isEmpty(ids)) {
                return filterList;
            }
            dto.setIds(ids);
        }
        if ( filteOrgIds != null){
            if (CollUtil.isNotEmpty(filteOrgIds) && CollUtil.isNotEmpty(orgIds)) {
                assert orgIds != null;
                orgIds = orgIds.stream().filter(filteOrgIds::contains).collect(Collectors.toList());
            }else if (CollUtil.isNotEmpty(filteOrgIds) && orgIds == null) {
                orgIds =filteOrgIds;
            }
            dto.setIds(doEmployeesOfYourOrganization(orgIds, postId, gradeId));
            if (CollUtil.isEmpty(dto.getIds())) {
                return filterList;
            }
        }
        Page<FtbPersonnelsTurnoverManagementVO> page = new Page<>();
        page.setSize(-1);
        Page<FtbPersonnelsTurnoverManagementVO>  managementVOPage = baseMapper.getTurnoverList(page, dto);
        filterList  = managementVOPage.getRecords();
        Map<String, FtbPersonnelsBlacklist> blacklistMap = new HashMap<>();
        List<String> userIds = filterList.stream().map(FtbPersonnelsTurnoverManagementVO::getUserId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userIds)) {
            LambdaQueryWrapper<FtbPersonnelsBlacklist> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(FtbPersonnelsBlacklist::getUserId,userIds);
            List<FtbPersonnelsBlacklist> list = blacklistService.list(queryWrapper);
            blacklistMap =  list.stream().collect(Collectors.toMap(FtbPersonnelsBlacklist::getUserId, Function.identity(), (a, b) -> a));
        }
        Map<String, FtbPersonnelsBlacklist> finalBlacklistMap = blacklistMap;
        filterList.forEach(item->{
            // 是否纳入黑名单
            item.setWhetherToBeIncluded(finalBlacklistMap.containsKey(item.getUserId()) ? 1 : 0);
        });
        replaceTheNameBatch(filterList);
        return filterList;
    }

    @Override
    public FtbPersonnelsTurOrgInfo getUserOrganizeInfo(String userId, String phone) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(StringUtils.isNotEmpty(userId), FtbPersonnelsTurnoverManagement::getUserId, userId);
        queryWrapper.eq(StringUtils.isNotEmpty(phone), FtbPersonnelsTurnoverManagement::getPhoneNumber, phone);
        queryWrapper.orderByAsc(FtbPersonnelsTurnoverManagement::getCreatorTime);
        queryWrapper.last("limit 1");
        FtbPersonnelsTurnoverManagement management = baseMapper.selectOne(queryWrapper);
        // idCardNum
        if (management == null) return null;
        LambdaQueryWrapper<FtbPersonnelsStaffRegistrationFormData> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsStaffRegistrationFormData::getFormFieldId,"idCardNum");
        wrapper.eq(FtbPersonnelsStaffRegistrationFormData::getPhone, management.getPhoneNumber());
        wrapper.last("limit 1");
        FtbPersonnelsStaffRegistrationFormData formData = dataMapper.selectOne(wrapper);
        List<WorkerGroupDataDto> dtos = new ArrayList<>();
        if (StringUtils.isNotEmpty(management.getOrganizationInfo())) {
            dtos = JSONArray.parseArray(management.getOrganizationInfo(), WorkerGroupDataDto.class);
        }
        FtbPersonnelsTurOrgInfo ftbPersonnelsTurOrgInfo = new FtbPersonnelsTurOrgInfo();
        ftbPersonnelsTurOrgInfo.setIdCard(formData == null ? "" : formData.getValue());
        ftbPersonnelsTurOrgInfo.setUserId(management.getUserId());
        ftbPersonnelsTurOrgInfo.setUserName(management.getUserName());
        ftbPersonnelsTurOrgInfo.setPhone(management.getPhoneNumber());
        ftbPersonnelsTurOrgInfo.setWorkerGroupDataDto(dtos.stream().filter(v -> v.getIsPrimaryPosition() || v.getIsDefault()).findFirst().orElse(new WorkerGroupDataDto()));
        return ftbPersonnelsTurOrgInfo;
    }
    @Override
    public List<UserBoundVO> getInformationAboutTheDepartingPerson(FtbDepUserDTO dto) {
        List<String> ids = null;
        if (ObjectUtil.isNotEmpty(dto) &&  (CollUtil.isNotEmpty(dto.getOrganizeIds())|| CollUtil.isNotEmpty(dto.getPositionIds()))) {
            ids = getStrings(dto.getOrganizeIds(), dto.getPositionIds(), null);
            // 只要不是全部且数据为空
            if (CollUtil.isEmpty(ids))return null;
        }
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollUtil.isNotEmpty(ids), SuperBaseEntity.SuperIBaseEntity::getId, ids);
        queryWrapper.in(ObjectUtil.isNotEmpty(dto) && CollUtil.isNotEmpty(dto.getUserIds()),
                FtbPersonnelsTurnoverManagement::getUserId, dto.getUserIds());
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getWorkingCondition ,"305");
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark ,0);
        List<FtbPersonnelsTurnoverManagement> turnoverManagements = baseMapper.selectList(queryWrapper);
        if(CollUtil.isEmpty(turnoverManagements)) return null;
        return turnoverManagements.stream().map(item -> {
            UserBoundVO userBoundVO = FtbPersonnelsTurnoverManagement.coverUserBoundVO(item);
            List<WorkerGroupDataDto> dataDto = JSONArray.parseArray(item.getOrganizationInfo(), WorkerGroupDataDto.class);
            if (CollUtil.isEmpty(dataDto)) {
                return userBoundVO;
            }
            WorkerGroupDataDto groupDataDto = dataDto.stream().filter(v -> v.getIsPrimaryPosition() || v.getIsDefault()).findFirst().orElse(new WorkerGroupDataDto());
            userBoundVO.setOrganizeId(groupDataDto.getAffiliatedOrg());
            userBoundVO.setOrganizeName(groupDataDto.getAffiliatedOrgName());
            userBoundVO.setPositionId(groupDataDto.getAffiliatedPosition());
            userBoundVO.setPositionName(groupDataDto.getAffiliatedPositionName());
            userBoundVO.setGradeId(groupDataDto.getAffiliatedRank());
            userBoundVO.setGradeName(groupDataDto.getAffiliatedRankName());
            return userBoundVO;
        }).collect(Collectors.toList());
    }

    private List<String> doEmployeesOfYourOrganization(List<String> orgIds, String postId,String grade) {
        List<String> postIds = new ArrayList<>();
        List<String> grades = new ArrayList<>();
        if (StringUtils.isNotEmpty(postId)) {
            postIds =List.of(postId);
        }
        if (StringUtils.isNotEmpty(grade)) {
            grades =List.of(grade);
        }
        List<String> managements = getStrings(orgIds, postIds, grades);
        if (managements != null) return managements;
        return null;
    }

    @Nullable
    private List<String> getStrings(List<String> orgIds, List<String> postIds, List<String> grades) {
        if (CollUtil.isNotEmpty(orgIds)){
            LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark ,0);
            List<FtbPersonnelsTurnoverManagement> managements = baseMapper.selectList(wrapper);
            if (CollUtil.isNotEmpty(orgIds) && CollUtil.isEmpty(postIds)  && CollUtil.isEmpty(grades))
                return managements.stream().filter(vo -> StringUtils.isNotEmpty(vo.getOrganizationInfo()))
                        .filter(vo -> CollUtil.isNotEmpty( JSONObject.parseArray(vo.getOrganizationInfo(), WorkerGroupDataDto.class)
                                .stream().map(WorkerGroupDataDto::getAffiliatedOrg).collect(Collectors.toList()).stream().filter(orgIds::contains).collect(Collectors.toList()))
                        ).map(FtbPersonnelsTurnoverManagement::getId).collect(Collectors.toList());

            if (CollUtil.isNotEmpty(orgIds) && CollUtil.isNotEmpty(postIds) && CollUtil.isEmpty(grades)) {
                List<String> finalPostIds = postIds;
                return managements.stream().filter(vo -> StringUtils.isNotEmpty(vo.getOrganizationInfo()))
                        .filter(vo ->CollUtil.isNotEmpty(
                                JSONObject.parseArray(
                                                vo.getOrganizationInfo(), WorkerGroupDataDto.class)
                                        .stream().filter(po->orgIds.contains(po.getAffiliatedOrg()) && finalPostIds.contains(po.getAffiliatedPosition())).collect(Collectors.toList()))
                        ).map(FtbPersonnelsTurnoverManagement::getId).collect(Collectors.toList());
            }
            if (CollUtil.isNotEmpty(orgIds) && CollUtil.isNotEmpty(postIds) && CollUtil.isNotEmpty(grades)) {
                List<String> finalPostIds1 = postIds;
                List<String> finalGrades = grades;
                return managements.stream().filter(vo -> StringUtils.isNotEmpty(vo.getOrganizationInfo()))
                        .filter(vo ->CollUtil.isNotEmpty(
                                JSONObject.parseArray(
                                                vo.getOrganizationInfo(), WorkerGroupDataDto.class)
                                        .stream().filter(po->orgIds.contains(po.getAffiliatedOrg())
                                                && finalPostIds1.contains(po.getAffiliatedPosition())
                                                && finalGrades.contains(po.getAffiliatedRank())).collect(Collectors.toList()))
                        ).map(FtbPersonnelsTurnoverManagement::getId).collect(Collectors.toList());
            }
        }
        return null;
    }
    private String calculateTheAgeOfTheDivision(Date resignationDate, Date dateOfEntry, String workingCondition) {
        // 离职到入职时间
        String calculated ="0天";
        if ("305".equals(workingCondition) && ObjectUtil.isNotEmpty(resignationDate) && ObjectUtil.isNotEmpty(dateOfEntry)){
            // 离职时间
            //入职时间
            calculated = CompanyAgeUtil.calculateSeniority(dateOfEntry,resignationDate);
        } else if (ObjectUtil.isNotEmpty(dateOfEntry)){
            // 未填写离职时间
            calculated = CompanyAgeUtil.calculateSeniority(dateOfEntry,new Date());
        }
        return calculated;
    }

    @Deprecated(since = "优化为批量处理")
    private void replaceTheName(FtbPersonnelsTurnoverManagementVO item) {
        List<WorkerGroupDataDto> workerGroupDataDtos = new ArrayList<>();
        if (StringUtils.isNotEmpty(item.getOrganizationInfo())){
            workerGroupDataDtos = JSONObject.parseArray(item.getOrganizationInfo(), WorkerGroupDataDto.class);
        }else {
            workerGroupDataDtos = personnelOrgUtils.getUserOrgBoundInfo(item.getUserId());
        }
        if (CollUtil.isNotEmpty(workerGroupDataDtos)) {
            String affiliatedOrg = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedOrg).collect(Collectors.joining(","));
            String affiliatedOrgName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedOrgName).collect(Collectors.joining(","));
            String affiliatedPosition = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedPosition).collect(Collectors.joining(","));
            String affiliatedPositionName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedPositionName).collect(Collectors.joining(","));
            String affiliatedRank = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedRank).collect(Collectors.joining(","));
            String affiliatedRankName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedRankName).collect(Collectors.joining(","));
            item.setOrgId(affiliatedOrg);
            item.setOrgName(affiliatedOrgName);
            item.setEntryPostId(affiliatedPosition);
            item.setEntryPostName(affiliatedPositionName);
            item.setEntryGradeId(affiliatedRank);
            item.setEntryGradeName(affiliatedRankName);
        }
    }

    private void replaceTheNameBatch(List<FtbPersonnelsTurnoverManagementVO> item) {
        List<String> userIds = item.stream().map(FtbPersonnelsTurnoverManagementVO::getUserId).collect(Collectors.toList());
        Map<String, List<WorkerGroupDataDto>> orgUtilsUserOrgBoundInfo = new HashMap<>();
        if (CollUtil.isNotEmpty(item)){
            orgUtilsUserOrgBoundInfo =   item.stream().filter(vo -> StringUtils.isNotEmpty(vo.getOrganizationInfo()))
                    .collect(Collectors.toMap(FtbPersonnelsTurnoverManagementVO::getUserId, vo -> JSONObject.parseArray(vo.getOrganizationInfo(), WorkerGroupDataDto.class),(a1, a2)-> a1
                    ));
        }else {
            orgUtilsUserOrgBoundInfo = personnelOrgUtils.getUserOrgBoundInfo(userIds);
        }
        Map<String, List<WorkerGroupDataDto>> finalOrgUtilsUserOrgBoundInfo = orgUtilsUserOrgBoundInfo;
        item.forEach(vo ->{
            if (finalOrgUtilsUserOrgBoundInfo.containsKey(vo.getUserId())) {
                List<WorkerGroupDataDto> workerGroupDataDtos = finalOrgUtilsUserOrgBoundInfo.get(vo.getUserId());
                String affiliatedOrg = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedOrg).collect(Collectors.joining(","));
                String affiliatedOrgName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedOrgName).collect(Collectors.joining(","));
                String affiliatedPosition = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedPosition).collect(Collectors.joining(","));
                String affiliatedPositionName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedPositionName).collect(Collectors.joining(","));
                String affiliatedRank = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedRank).collect(Collectors.joining(","));
                String affiliatedRankName = workerGroupDataDtos.stream().map(WorkerGroupDataDto::getAffiliatedRankName).collect(Collectors.joining(","));
                vo.setOrgId(affiliatedOrg);
                vo.setOrgName(affiliatedOrgName);
                vo.setEntryPostId(affiliatedPosition);
                vo.setEntryPostName(affiliatedPositionName);
                vo.setEntryGradeId(affiliatedRank);
                vo.setEntryGradeName(affiliatedRankName);
            }
        });

    }


    @Override
    public PageListVO<FtbPersonnelsTurnoverManagementVO> getTurnoverForList(FtbPersonnelsForAppQueryDTO dto, CultivatePage cultivatePage) {
        Page<FtbPersonnelsTurnoverManagementVO> page = cultivatePage.coverCultivatePage();
        // 1.办理 2.我的审批 3 抄送我的 4 我的申请
        String flagByApp = dto.getFlagByApp();
        // 初始化抄送人
        String userId = UserProvider.getUser().getUserId();
        dto.setUserId(userId);
        if ("1".equals(flagByApp)) {
            // 数据权限 orgIds
            if ( !UserProvider.getUser().getIsAdministrator() ) {
                // 数据权限userIds
                List<String> orgIds = permissionsUtils.obtainPersonnelOrganizationIdDataPermissions(userId);
                List<String> ids;
                PermissionsApplicableObject permissionsApplicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(UserProvider.getUser().getUserId());
                // 数据权限 仅下属单独处理
                if (permissionsApplicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE){
                    // 查询当前登录人的下属
                    ids = inquireAboutSubordinates(userId);
                } else {
                    ids = doEmployeesOfYourOrganization(orgIds,null,null);
                }
                // 只要不是全部且数据为空
                if (!(orgIds  == null) && CollUtil.isEmpty(ids)) {
                    return CultivatePage.coverPageList(page);
                }
                dto.setIds(ids);
            }
        }
        Page<FtbPersonnelsTurnoverManagementVO> mapperList = baseMapper.getListForApp(page, dto);
        List<FtbPersonnelsTurnoverManagementVO> records = mapperList.getRecords();
        List<String> userIds = records.stream().map(FtbPersonnelsTurnoverManagementVO::getUserId).collect(Collectors.toList());
        Map<String, FtbPersonnelsBlacklist> blacklistMap = new HashMap<>();
        if (CollUtil.isNotEmpty(userIds)) {
            LambdaQueryWrapper<FtbPersonnelsBlacklist> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(FtbPersonnelsBlacklist::getUserId,userIds);
            List<FtbPersonnelsBlacklist> list = blacklistService.list(queryWrapper);
            blacklistMap = list.stream().collect(Collectors.toMap(FtbPersonnelsBlacklist::getUserId, Function.identity(), (a, b) -> a));
        }
        Map<String, FtbPersonnelsBlacklist> finalBlacklistMap = blacklistMap;
        mapperList.getRecords().forEach(item->{
            if (StringUtils.isNotEmpty(item.getTaskInfoId())) {
                FlowTaskEntity byTaskId = flowTaskApi.findByTaskId(item.getTaskInfoId());
                if (ObjectUtil.isNotEmpty(byTaskId) &&  userId.equals(byTaskId.getCreatorUserId())) {
                    item.setCurrentSponsor(1);
                } else {
                    item.setCurrentSponsor(0);
                }
            }
            // 是否纳入黑名单
            item.setWhetherToBeIncluded(finalBlacklistMap.containsKey(item.getUserId()) ? 1 : 0);
        });
        return CultivatePage.coverPageList(mapperList);
    }

    @NotNull
    private List<String> getStrings(Integer configType, String userId) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsTurnoverManagement::getEnableMark,0);
        List<Integer> list = new ArrayList<>();
        list.add(0);
        list.add(1);
        wrapper.in(FtbPersonnelsTurnoverManagement::getTurnoverStatus,list);
        List<FtbPersonnelsTurnoverManagement> managements = baseMapper.selectList(wrapper);
        List<String> ids  = new ArrayList<>();
        for (int i = 0; i < managements.size(); i++){
            FtbPersonnelsTurnoverManagement turnoverManagement = managements.get(i);
            Boolean b = runTaskService.checkWhetherTheCurrentSignIsOr(turnoverManagement.getId(),configType,userId);
            if (b) {
                ids.add(turnoverManagement.getUserId());
            }
        }
        return ids;
    }

    @Override
    public void closeUserAccountRegularlyAfterResignation(String tenantId) {
        LambdaQueryWrapper<FtbPersonnelsTurnoverAccountRegistration> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getEnableMark,0);
        // 是否已经签署离职解除协议(0 : 否 1:是)
        List<FtbPersonnelsTurnoverAccountRegistration> registrations = registrationMapper.selectList(wrapper);
        if (CollUtil.isEmpty(registrations)){
            return;
        }
        List<FtbPersonnelsTurnoverAccountRegistration> deleteInfoList = new ArrayList<>();
        List<String> userIdList = new ArrayList<>();
        // 当前时间
        LocalDateTime nowDate = LocalDateTime.now();
        for (FtbPersonnelsTurnoverAccountRegistration  registration: registrations){
            Date resignationDate = registration.getResignationDate();
            String userId = registration.getUserId();
            if(ObjectUtil.isEmpty(resignationDate)){
                userIdList.add(userId);
                deleteInfoList.add(registration);
                continue;
            }
            // 离职时间
            LocalDateTime localDate = resignationDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            if (nowDate.isAfter(localDate)){
                // 调用关停账号接口
                userIdList.add(userId);
                deleteInfoList.add(registration);
            }
        }
        if(CollUtil.isNotEmpty(userIdList)) {
            extracted(tenantId, userIdList,deleteInfoList);
        }
    }
    private void extracted(String tenantId, List<String> userIdList, List<FtbPersonnelsTurnoverAccountRegistration> deleteInfoList) {
        Map<String, List<FtbPersonnelsTurnoverAccountRegistration>> listMap = deleteInfoList.stream().collect(Collectors.groupingBy(FtbPersonnelsTurnoverAccountRegistration::getUserId));
        List<String> noDataExists = new ArrayList<>();
        userIdList.forEach(item -> {
            List<FtbPersonnelsTurnoverAccountRegistration> accountRegistrations = listMap.get(item);
            FtbPersonnelsTurnoverAccountRegistration registration = accountRegistrations.stream().findFirst().orElse(new FtbPersonnelsTurnoverAccountRegistration());
            if (ObjectUtil.isNotEmpty(registration)) {
                FtbPersonnelsTurnoverManagement turnoverManagement = baseMapper.selectById(registration.getBussesId());
                if(ObjectUtil.isEmpty(turnoverManagement)){
                    noDataExists.add(registration.getId());
                    return;
                }
                // 工作状态，301、预入职 302、试用 303、正式 304、待离职 305 离职
                StaffDepartDto dtoList = getStaffDepartDtos(turnoverManagement, 1);
                Date resignationDate = turnoverManagement.getResignationDate()  ==  null ? turnoverManagement.getEmpResignationDate() : turnoverManagement.getResignationDate();
                staffRosterService.innerChangeDepart(turnoverManagement.getUserId(), dtoList, turnoverManagement.getReasonForResignation(),resignationDate, tenantId);
                LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> lambdaUpdate = Wrappers.lambdaUpdate();
                // 修改为离职
                lambdaUpdate.set(FtbPersonnelsTurnoverManagement::getWorkingCondition, "305");
                //lambdaUpdate.set(FtbPersonnelsTurnoverManagement::getEnableMark,"1");
                lambdaUpdate.set(SuperBaseEntity.SuperCUDBaseEntity::getDeleteTime, new Date());
                lambdaUpdate.eq(SuperBaseEntity.SuperIBaseEntity::getId, turnoverManagement.getId());
                baseMapper.update(null, lambdaUpdate);
            }
        });
        if (CollUtil.isNotEmpty(noDataExists))   registrationMapper.deleteBatchIds(noDataExists);
        LambdaUpdateWrapper<FtbPersonnelsTurnoverAccountRegistration> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(FtbPersonnelsTurnoverAccountRegistration::getEnableMark, 1);
        updateWrapper.in(FtbPersonnelsTurnoverAccountRegistration::getUserId, userIdList);
        registrationMapper.update(new FtbPersonnelsTurnoverAccountRegistration(), updateWrapper);
        //清楚考勤组
        if(CollectionUtil.isNotEmpty(userIdList)) {
            GroupUpdateByUserDTO groupUpdateByUserDTO = new GroupUpdateByUserDTO();
            groupUpdateByUserDTO.setTenantId(tenantId);
            groupUpdateByUserDTO.setType(2);//1入职 2离职 3调岗
            groupUpdateByUserDTO.setUserIds(userIdList);
            personnelOrgUtils.syncAttendanceGroup(groupUpdateByUserDTO);
        }

        // 关闭用户
        userIdList.forEach(str->{
            v2UserApi.removeUser(str, UserWorkStatusEnums.RESIGNED);
            pTenantAccountApi.deleteUserWithPlatform(str);
        });
        // 转正,
        regularManagementService.clearHistoricalConversionData(userIdList);
        // 晋升,
        personnelsPostApplyService.clearPromotionData(userIdList);
        // 调岗数据 清除
        transferPositionService.clearJobTransferData(userIdList);
        // 调动数据 清楚
        // 调岗数据
        transferManageService.clearTransferData(userIdList);
        // 人事权限配置删除
        userIdList.forEach(str-> personnelsPermissionsService.clearUserPermissions(str));
        ftbPermissionRoleAuthorizePersonService.deleteEmployeeAllPermission(userIdList);
        // 回退整改任务
        userIdList.forEach(v-> evaluateManageApi.revertTaskStatus(v));
        // 借调结束
        userIdList.forEach(v->{
            FtbPersonnelsTurnoverAccountRegistration registration = listMap.get(v).stream().findFirst().orElse(new FtbPersonnelsTurnoverAccountRegistration());
            secondmentManagementService.endByUserConfirm(v,registration.getResignationDate());
        });
        userIdList.forEach(v->UserProvider.kickoutByUserId(v,tenantId));
        RTopic theCompany_topic = redissonClient.getTopic("leavingTheCompany_topic");
        JSONObject args = new JSONObject();
        args.put("userIdList", userIdList);
        args.put("tenantId", tenantId);
        theCompany_topic.publish(args.toJSONString());
        // 清楚缓存
        userIdList.forEach(s -> staffRosterService.logout(tenantId,s));
    }

    @Override
    public FtbPersonnelsTurnoverInfoVO detailsOfResignationApprovalProcess(String id) {
        FtbPersonnelsTurnoverManagement management = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(management)){
            return null;
        }
        FtbPersonnelsTurnoverInfoVO turnoverInfoVO = FtbPersonnelsTurnoverManagement.coverFtbPersonnelsTurnoverInfoVO(management);
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPersonnelsStaffRoster::getUserId,turnoverInfoVO.getUserId());
        FtbPersonnelsStaffRoster one = staffRosterService.getOne(wrapper);
        turnoverInfoVO.setUserName(one.getName());
        if(StringUtils.isNotEmpty(turnoverInfoVO.getBlackTypeId())) turnoverInfoVO.setBlackTypeName(ftbPersonnelsBlacklistTypeMapper.selectById(turnoverInfoVO.getBlackTypeId()).getRegularName());
        turnoverInfoVO.setAuditInfo(subConfigService.queryAuditSubConfig(turnoverInfoVO.getOrgId(),FtbPersonnelsCofigEnum.RESIGNATION_APPROVAL_CONFIGURATION));
        turnoverInfoVO.setWorkingCondition(one.getWorkerStatus());
        // 查询当前申请时上传的文件信息
        List<FtbCultivateFile> list = ftbCultivateFileService.lambdaQuery().eq(FtbCultivateFile::getBusinessId, id)
                .eq(FtbCultivateFile::getType,FileEventDTO.FileType.RESIGNATION_MANAGEMENT.getType()).list();
        List<FtbCultivateOfflineFileVO> fileVOS = list.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        turnoverInfoVO.setFiles(fileVOS);
        List<FtbPersonnelsTurnoverHandover> turnoverHandovers = handoverService.lambdaQuery().eq(FtbPersonnelsTurnoverHandover::getManagementId, id).list();
        Map<String, FtbPersonnelsStaffRosterDto> userMaps =new HashMap<>();
        if (CollectionUtil.isNotEmpty(turnoverHandovers)) {
            StaffRosterListReq listReq = new StaffRosterListReq();
            listReq.setIsQueryAuth("0");
            listReq.setPageSize(-1);
            listReq.setUserIds(turnoverHandovers.stream().map(FtbPersonnelsTurnoverHandover::getArticleRecipientId).collect(Collectors.toList()));
            PageInfo<FtbPersonnelsStaffRosterDto> ftbPersonnelsStaffRosterDtoPageInfo = staffRosterService.postWithSalary(listReq);
            if (CollUtil.isNotEmpty(ftbPersonnelsStaffRosterDtoPageInfo.getList())) userMaps = ftbPersonnelsStaffRosterDtoPageInfo.getList().stream().collect(Collectors.toMap(FtbPersonnelsStaffRosterDto::getUserId, Function.identity(), (k1, k2) -> k1));
        }
        Map<String, List<FtbPersonnelsTurnoverHandover>> listMap = turnoverHandovers.stream().collect(Collectors.groupingBy(FtbPersonnelsTurnoverHandover::getTurnoverType, Collectors.toList()));
        if (CollUtil.isNotEmpty(listMap)) {
            //(1,物品,)类型
            if (listMap.containsKey("1")){
                List<FtbPersonnelsTurnoverHandover> ftbPersonnelsTurnoverHandovers = listMap.get("1");
                Map<String, FtbPersonnelsStaffRosterDto> finalUserMaps = userMaps;
                ftbPersonnelsTurnoverHandovers.forEach(item->{
                    if(finalUserMaps.containsKey(item.getArticleRecipientId())){
                        item.setArticleRecipientId(finalUserMaps.get(item.getArticleRecipientId()).getUserId());
                        item.setSystemWokerId(finalUserMaps.get(item.getArticleRecipientId()).getSystemWokerId());
                        item.setWorkerStatus(finalUserMaps.get(item.getArticleRecipientId()).getWorkerStatus());
                    }
                });
                turnoverInfoVO.setHandover(ftbPersonnelsTurnoverHandovers);
            }
            //2工作
            if (listMap.containsKey("2")){
                List<FtbPersonnelsTurnoverHandover> ftbPersonnelsTurnoverHandovers = listMap.get("2");
                Map<String, FtbPersonnelsStaffRosterDto> finalUserMaps = userMaps;
                ftbPersonnelsTurnoverHandovers.forEach(item->{
                    if(finalUserMaps.containsKey(item.getArticleRecipientId())){
                        item.setArticleRecipientId(finalUserMaps.get(item.getArticleRecipientId()).getUserId());
                        item.setSystemWokerId(finalUserMaps.get(item.getArticleRecipientId()).getSystemWokerId());
                        item.setWorkerStatus(finalUserMaps.get(item.getArticleRecipientId()).getWorkerStatus());
                    }
                });
                turnoverInfoVO.setHandoverWork(ftbPersonnelsTurnoverHandovers);
            }
        }
        // 计算司龄
        turnoverInfoVO.setSiLing(calculateTheAgeOfTheDivision(turnoverInfoVO.getResignationDate(),turnoverInfoVO.getDateOfEntry(),turnoverInfoVO.getWorkingCondition()));
        Integer applicationSource = management.getApplicationSource();
        String userId = UserProvider.getUser().getUserId();
        if ( 0 == applicationSource ){
            turnoverInfoVO.setMarkFlag("0");
        }else {
            turnoverInfoVO.setMarkFlag("1");
        }
        if (StringUtils.isNotEmpty(management.getOrganizationInfo())){
            String organizationInfo = management.getOrganizationInfo();
            List<WorkerGroupDataDto> dataDtos = JSONObject.parseArray(organizationInfo, WorkerGroupDataDto.class);
            turnoverInfoVO.setOrganizationInfo(dataDtos);
        }
        return turnoverInfoVO;
    }

    @Override
    @GlobalTransactional
    public void withdrawResignationApplication(String id, String taskId) {
        if (StringUtils.isEmpty(id) && StringUtils.isEmpty(taskId)){
            throw new RuntimeException("参数错误!");
        }
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(StringUtils.isNotEmpty(id),FtbPersonnelsTurnoverManagement::getId,id);
        queryWrapper.eq(StringUtils.isNotEmpty(taskId),FtbPersonnelsTurnoverManagement::getTaskInfoId,taskId);
        // 撤销
        FtbPersonnelsTurnoverManagement vo =  baseMapper.selectOne(queryWrapper);
        Integer turnoverStatus = vo.getTurnoverStatus();
        if (!(Objects.equals(turnoverStatus, FtbPersonnelsAuditTaskEnum.UNDER_REVIEW.getCode()) || Objects.equals(turnoverStatus, FtbPersonnelsAuditTaskEnum.MANUAL_CONTROL.getCode()))) {
            throw new RuntimeException("该审批无法撤销!");
        }
        // 撤销离职
        String userId = vo.getUserId();
        String canceldepart = staffRosterService.canceldepart(userId);
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(FtbPersonnelsTurnoverManagement::getTurnoverStatus,FtbPersonnelsAuditTaskEnum.CANCEL.getCode());
        if(Objects.equals(turnoverStatus, FtbPersonnelsAuditTaskEnum.MANUAL_CONTROL.getCode())){
            wrapper.set(FtbPersonnelsTurnoverManagement::getTaskInfoId,null);
        }
        wrapper.set(FtbPersonnelsTurnoverManagement::getWorkingCondition,canceldepart);
        wrapper.set(FtbPersonnelsTurnoverManagement::getVersionNum,null);
        wrapper.eq(StringUtils.isNotEmpty(id),FtbPersonnelsTurnoverManagement::getId,id);
        wrapper.eq(StringUtils.isNotEmpty(taskId),FtbPersonnelsTurnoverManagement::getTaskInfoId,taskId);
        baseMapper.update(null,wrapper);
        // 删除已经提交的离职申请账号
        LambdaUpdateWrapper<FtbPersonnelsTurnoverAccountRegistration> lambdaUpdate = Wrappers.lambdaUpdate();
        lambdaUpdate.set(FtbPersonnelsTurnoverAccountRegistration::getEnableMark,1);
        lambdaUpdate.eq(FtbPersonnelsTurnoverAccountRegistration::getBussesId,id);
        registrationMapper.delete(lambdaUpdate);
        if (vo.getIsBeBlackList() == 1) {
            // 删除黑名单接口
            LambdaUpdateWrapper<FtbPersonnelsBlacklist> lambdaed = Wrappers.lambdaUpdate();
            lambdaed.eq(FtbPersonnelsBlacklist::getUserId, vo.getUserId());
            blacklistService.remove(lambdaed);
        }
        // 修改状态
        UpdateUserDTO userDTO = new UpdateUserDTO();
        userDTO.setWorkerStatus(canceldepart);
        v2UserApi.updateUserInfo(userId,userDTO);
    }

    @Override
    @Transactional
    public String reviewResignationApplication(FtbPersonnelsTurnoverDTO auditDto) {
        if (ObjectUtil.isNotEmpty(auditDto.getIsBeBlackList()) && auditDto.getIsBeBlackList() == 1){
            LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getIsBeBlackList,auditDto.getIsBeBlackList());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlackListPeriod,auditDto.getBlackListPeriod());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlackTypeId,auditDto.getBlackTypeId());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlacklistCause,auditDto.getBlacklistCause());
            updateWrapper.eq(FtbPersonnelsTurnoverManagement::getId,auditDto.getBusinessId());
            baseMapper.update(null,updateWrapper);
        }
        // 校验
        FtbPersonnelsTurnoverManagement turnoverManagement = baseMapper.selectById(auditDto.getBusinessId());
        String userId = turnoverManagement.getUserId();
        String number = null;
        if ( "1".equals(auditDto.getFlag())) number =calibrationNumber(userId);
        // 强制申请 或者审核通过
        if (!"1".equals(auditDto.getForceDelete())  && number != null ) return number;
        FtbPersonnelsAuditTaskEnum performReview = runTaskService.performReview(auditDto);
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(FtbPersonnelsTurnoverManagement::getTurnoverStatus,performReview.getCode());
        if (ObjectUtil.isNotEmpty(auditDto.getResignationDate())) {
            wrapper.set(FtbPersonnelsTurnoverManagement::getResignationDate, auditDto.getResignationDate());
        }
        // 不足时间关停账号
        if (FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED.equals(performReview)) {
            //v1.1 加入黑名单
            if (ObjectUtil.isNotEmpty(turnoverManagement.getIsBeBlackList()) &&
                    turnoverManagement.getIsBeBlackList() == 1){
                // 加入黑名单
                FtbPersonnelsBlacklistAddDTO ftbPersonnelsBlacklistAddDTO =
                        FtbPersonnelsTurnoverCreateDTO.covertBlacklist(turnoverManagement);
                blacklistService.addBlacklist(ftbPersonnelsBlacklistAddDTO);
            }
            // 修改状态
            UserEntity user = new UserEntity();
            user.setId(userId);
            user.setEnabledMark(3);
            userApi.updateUserStatusById(user);
            // 到当前时间了
            removeAccountAndAddDataSynchronizationStatus(turnoverManagement.getId(),turnoverManagement.getResignationDate(), userId,turnoverManagement.getUserName());
        }else if (FtbPersonnelsAuditTaskEnum.AUDIT_NOT_PASSED.equals(performReview)){
            // 审批不通过
            String canceldepart = staffRosterService.canceldepart(userId);
            wrapper.set(FtbPersonnelsTurnoverManagement::getWorkingCondition,canceldepart);
        }
        wrapper.eq(FtbPersonnelsTurnoverManagement::getId,auditDto.getBusinessId());
        baseMapper.update(null,wrapper);
        return null;
    }

    @Override
    @GlobalTransactional
    public ActionResult<Void> reviewResignationApplicationWithOA(FtbPersonnelsTurnoverDTO auditDto) {
        ActionResult<Void> actionResult = new ActionResult<>();
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg() );
        log.error("人事入转调离审核->{}", JSONObject.toJSONString(auditDto));
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsTurnoverManagement::getTaskInfoId,auditDto.getTaskId());
        if (ObjectUtil.isNotEmpty(auditDto.getIsBeBlackList()) && auditDto.getIsBeBlackList() == 1){
            LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getIsBeBlackList,auditDto.getIsBeBlackList());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlackListPeriod,auditDto.getBlackListPeriod());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlackTypeId,auditDto.getBlackTypeId());
            updateWrapper.set(FtbPersonnelsTurnoverManagement::getBlacklistCause,auditDto.getBlacklistCause());
            updateWrapper.eq(FtbPersonnelsTurnoverManagement::getTaskInfoId, auditDto.getTaskId());
            baseMapper.update(null,updateWrapper);
        }
        // 校验
        FtbPersonnelsTurnoverManagement turnoverManagement = baseMapper.selectOne(queryWrapper);
        if (ObjectUtil.isEmpty(turnoverManagement))  throw new RuntimeException("审批数据不存在");
        String managementId = turnoverManagement.getId();
        String userId = turnoverManagement.getUserId();
        // 强制申请 或者审核通过
        // 离职校验
        String flag = auditDto.getFlag();
        if ("1".equals(flag)) actionResult = resignationPreCheck(userId,"", flag);
        // 如果是拒绝不能进行离职申请, 警告继续执行
        if (FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode() == actionResult.getCode() ) return  actionResult;
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaUpdate();
        FtbPersonnelsAuditTaskEnum performReview = "0".equals(flag) ? FtbPersonnelsAuditTaskEnum.AUDIT_NOT_PASSED : FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED;
        wrapper.set(FtbPersonnelsTurnoverManagement::getTurnoverStatus,performReview.getCode());
        if (ObjectUtil.isNotEmpty(auditDto.getResignationDate())) {
            wrapper.set(FtbPersonnelsTurnoverManagement::getResignationDate, auditDto.getResignationDate());
        }
        // 不足时间关停账号
        if (FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED.equals(performReview)) {
            // 补充 自动通过表单没有选择离职时间 使用员工期望离职时间作为离职时间
            //v1.1 加入黑名单
            if (ObjectUtil.isNotEmpty(turnoverManagement.getIsBeBlackList()) &&
                    turnoverManagement.getIsBeBlackList() == 1){
                // 加入黑名单
                FtbPersonnelsBlacklistAddDTO ftbPersonnelsBlacklistAddDTO =
                        FtbPersonnelsTurnoverCreateDTO.covertBlacklist(turnoverManagement);
                blacklistService.addBlacklist(ftbPersonnelsBlacklistAddDTO);
            }
            // 离职时间
            Date resignationDate = turnoverManagement.getResignationDate();
            if (ObjectUtil.isEmpty(resignationDate)) {
                if (ObjectUtil.isNotEmpty(auditDto.getResignationDate())) {
                    resignationDate = auditDto.getResignationDate();
                } else if (ObjectUtil.isNotEmpty(turnoverManagement.getEmpResignationDate())) {
                    resignationDate = turnoverManagement.getEmpResignationDate();
                    wrapper.set(FtbPersonnelsTurnoverManagement::getResignationDate,resignationDate);
                }
            }
            // 添加同意借调提示
            int record = secondmentManagementService.checkWhetherThereIsASecondmentRecord(userId,resignationDate);
            if (record > 0){
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_WARNING.getCode());
                actionResult.setMsg("该员工离职日期处于借调时间段中，到达离职日期将自动结束借调！");
            }
            removeAccountAndAddDataSynchronizationStatus(managementId, resignationDate, userId,turnoverManagement.getUserName());
        }else {
            // 审批不通过
            String canceldepart = staffRosterService.canceldepart(userId);
            // 修改状态
            UpdateUserDTO userDTO = new UpdateUserDTO();
            userDTO.setWorkerStatus(canceldepart);
            v2UserApi.updateUserInfo(userId,userDTO);
            wrapper.set(FtbPersonnelsTurnoverManagement::getWorkingCondition,canceldepart);
        }
        wrapper.eq(FtbPersonnelsTurnoverManagement::getId, managementId);
        baseMapper.update(null,wrapper);
        return actionResult;
    }

    @Override
    public List<FtbPersonnelsTurnoverManagementVO> queryTurnoverList() {
        List<FtbPersonnelsTurnoverManagementVO> ftbPersonnelsTurnoverManagementVOS = baseMapper.queryTurnoverList(null);
        ftbPersonnelsTurnoverManagementVOS.forEach(item->{
            if (StringUtils.isNotEmpty(item.getOrganizationInfo())){
                item.setOrganizationList(JSONObject.parseArray(item.getOrganizationInfo(), WorkerGroupDataDto.class));
            }
        });
        return ftbPersonnelsTurnoverManagementVOS;
    }

    @Override
    public List<FtbPersonnelsTurnoverManagementVO> queryTurnoverList(List<String> userIds) {
        List<FtbPersonnelsTurnoverManagementVO> ftbPersonnelsTurnoverManagementVOS = baseMapper.queryTurnoverList(userIds);
        ftbPersonnelsTurnoverManagementVOS.forEach(item->{
            if (StringUtils.isNotEmpty(item.getOrganizationInfo())){
                item.setOrganizationList(JSONObject.parseArray(item.getOrganizationInfo(), WorkerGroupDataDto.class));
            }
        });
        return ftbPersonnelsTurnoverManagementVOS;
    }




    /**
     *移除账号添加数据同步状态
     */
    private void removeAccountAndAddDataSynchronizationStatus(String businessId, Date resignationDate, String userId,String userName) {
        // 避免重复添加
        LambdaQueryWrapper<FtbPersonnelsTurnoverAccountRegistration> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getBussesId,businessId);
        queryWrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getUserId,userId);
        queryWrapper.eq(FtbPersonnelsTurnoverAccountRegistration::getEnableMark,0);
        FtbPersonnelsTurnoverAccountRegistration accountRegistration = registrationMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(accountRegistration)) return;
        FtbPersonnelsTurnoverAccountRegistration registration = new FtbPersonnelsTurnoverAccountRegistration();
        registration.setUserId(userId);
        registration.setBussesId(businessId);
        registration.setUserName(userName);
        registration.setResignationDate(resignationDate);
        registrationMapper.insert(registration);
        Date date = new Date();
        if (date.after(resignationDate)){
            extracted(UserProvider.getUser().getTenantId(),List.of(userId),List.of(registration));
        }
    }


    /**
     * 校验逾期未办理
     */
    @Deprecated
    private void extracted() {
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(FtbPersonnelsTurnoverManagement::getTurnoverStatus, FtbPersonnelsAuditTaskEnum.NOT_PROCESSED.getCode());
        List<FtbPersonnelsTurnoverManagement> managements = baseMapper.selectList(lambdaQuery);
        Date date = new Date();
        managements.forEach(item->{
            if (ObjectUtil.isNotEmpty(item.getResignationDate()) ){
                if (date.after(item.getResignationDate())){
                    updateOverdueStatus(item);
                }
            }else {
                if (ObjectUtil.isNotEmpty(item.getEmpResignationDate())) {
                    if (date.after(item.getEmpResignationDate())) {
                        updateOverdueStatus(item);
                    }
                }
            }
        });
    }

    /**
     * 更新状态
     * @param item
     */
    private void updateOverdueStatus(FtbPersonnelsTurnoverManagement item) {
        LambdaUpdateWrapper<FtbPersonnelsTurnoverManagement> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(FtbPersonnelsTurnoverManagement::getTurnoverStatus,FtbPersonnelsAuditTaskEnum.OVERDUE_FOR_APPROVAL.getCode());
        wrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, item.getId());
        baseMapper.update(new FtbPersonnelsTurnoverManagement(),wrapper);
    }


    @Nullable
    private String calibrationNumber(String userId) {
        //  离职校验
        //  1.是否为审批人
        ActionResult actionResult = flowTaskApi.checkReloadWait(userId);
        if (actionResult !=null && actionResult.getCode() == 200  && (boolean)actionResult.getData()){
            log.error("当前用户为审批人，不能申请离职");
            return "1";
        }
        //  2是否为门店负责人
        Long aLong = storeService.lambdaQuery().eq(StoreEntity::getStoreheaduserid, userId).count();
        if (aLong > 0){
            log.error("当前用户为门店负责人，不能申请离职");
            return "2";
        }
//        // 直属主管
//        List<SubordinateUserInfoVO> subordinateUserInfoVOS = userApi.userInfoByLeaderId(userId);
//        if (CollUtil.isNotEmpty(subordinateUserInfoVOS)) {
//            return "4";
//        }
//        List<RoleUserBoundVO> userBoundRolesList = roleApi.getUserBoundRolesList(userId);
//        if (CollUtil.isNotEmpty(userBoundRolesList)){
//            List<Map<String, Object>> maps = getMaps(userBoundRolesList);
//            log.error("当前用户有角色组，不能申请离职");
//            if (CollUtil.isNotEmpty(maps) || maps.get(0) != null){
//                return "3";
//            }
//        }
        return null;
    }
}
