package com.yifu.cloud.plus.v1.yifu.social.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.yifu.cloud.plus.v1.csp.vo.EmployeeRegistrationCustomerUserUpdateVo;
import com.yifu.cloud.plus.v1.csp.vo.TEmployeeContractDateVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ClientNameConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.BaseSearchVO;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.social.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.TDispatchInfoPre;
import com.yifu.cloud.plus.v1.yifu.social.entity.TFundPreDetail;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialAutoLog;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialPreDetail;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TDispatchInfoPreMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.*;
import com.yifu.cloud.plus.v1.yifu.social.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 社保待购买表
 *
 * @author huych
 * @date 2025-09-30 16:40:07
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class TDispatchInfoPreServiceImpl extends ServiceImpl<TDispatchInfoPreMapper, TDispatchInfoPre> implements TDispatchInfoPreService {

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;

	@Autowired
	private WxConfig wxConfig;

	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	private final TSocialPreDetailService socialPreDetailService;

	private final TFundPreDetailService fundPreDetailService;

	private final THolidayInfoService tHolidayInfoService;

	private final TDispatchInfoService dispatchInfoService;

	private final TSocialAutoLogService socialAutoLogService;

	@Autowired
	private final THouseHoldLimitService houseHoldLimitService;

	/**
     * 社保待购买表简单分页查询
     * @param tDispatchInfoPre 社保待购买表
     * @return
     */
    @Override
    public IPage<TDispatchInfoPre> getTDispatchInfoPrePage(Page<TDispatchInfoPre> page, TDispatchInfoPreSearchVo tDispatchInfoPre){
		//权限赋值
		initSearchVo(tDispatchInfoPre);
        return baseMapper.getTDispatchInfoPrePage(page,tDispatchInfoPre);
    }

    /**
     * 社保待购买表批量导出
     * @param searchVo 社保待购买表
     * @return
     */
    @Override
    public void listExport(HttpServletResponse response, TDispatchInfoPreSearchVo searchVo){
        String fileName = "社保待购买批量导出" + DateUtil.getThisTime() + ".xlsx";
        //获取要导出的列表
        List<TDispatchInfoPreExportVo> list = new ArrayList<>();
		initSearchVo(searchVo);
        long count = baseMapper.selectExportCount(searchVo);
        try (ServletOutputStream out= response.getOutputStream();){
            response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
            response.setCharacterEncoding("utf-8");
            response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName  , CommonConstants.UTF8));
            // 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
            ExcelWriter excelWriter = EasyExcel.write(out, TDispatchInfoPreExportVo.class).build();
            int index = 0;
            if (count >  CommonConstants.ZERO_INT){
                for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
                    // 获取实际记录
                    searchVo.setLimitStart(i);
                    searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
                    list = baseMapper.selectExportList(searchVo);
                    if (Common.isNotNull(list)){
                        WriteSheet writeSheet = EasyExcel.writerSheet("社保待购买"+index).build();
                        excelWriter.write(list,writeSheet);
                        index++;
                    }
                    if (Common.isNotNull(list)){
                        list.clear();
                    }
                }
            }else {
                WriteSheet writeSheet = EasyExcel.writerSheet("社保待购买"+index).build();
                excelWriter.write(list,writeSheet);
            }
            if (Common.isNotNull(list)){
                list.clear();
            }
            excelWriter.finish();
        }catch (Exception e){
            log.error("执行异常" ,e);
        }
    }

	@Override
	public List<TDispatchInfoPre> getNoPageList(TDispatchInfoPreSearchVo searchVo) {
		searchVo.setType(CommonConstants.ONE_STRING);
		initSearchVo(searchVo);
		if (Common.isEmpty(searchVo.getStatusList())) {
			searchVo.setStatusList(Stream.of("0").collect(Collectors.toList()));
		}
		return baseMapper.geNoPageList(searchVo);
	}

	@Override
	public List<TDispatchInfoPre> getNoPageListNew(TDispatchInfoPreSearchVo searchVo) {
		searchVo.setType(CommonConstants.ONE_STRING);
		initSearchVo(searchVo);
		if (Common.isEmpty(searchVo.getStatusList())) {
			searchVo.setStatusList(Stream.of("0").collect(Collectors.toList()));
		}
		return baseMapper.geNoPageListNew(searchVo);
	}

	@Override
	public R confirm(List<String> idList) {
		List<TDispatchInfoPre> socialPreList = baseMapper.selectList(Wrappers.<TDispatchInfoPre>query()
				.lambda().in(TDispatchInfoPre::getId, idList)
				.eq(TDispatchInfoPre::getProcessStatus, CommonConstants.ZERO_STRING));
		if (Common.isEmpty(socialPreList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.in(TDispatchInfoPre::getId,idList)
				.eq(TDispatchInfoPre::getProcessStatus, CommonConstants.ZERO_STRING)
				.set(TDispatchInfoPre::getProcessStatus, CommonConstants.ONE_STRING);
		this.update(updateWrapper);
		return R.ok();
	}

	@Override
	public R confirmFund(List<String> idList) {
		List<TDispatchInfoPre> preList = baseMapper.selectList(Wrappers.<TDispatchInfoPre>query()
				.lambda().in(TDispatchInfoPre::getId, idList)
				.eq(TDispatchInfoPre::getProcessStatus, CommonConstants.ZERO_STRING));
		if (Common.isEmpty(preList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.in(TDispatchInfoPre::getId,idList)
				.eq(TDispatchInfoPre::getProcessStatus, CommonConstants.ZERO_STRING)
				.set(TDispatchInfoPre::getProcessStatus, CommonConstants.ONE_STRING);
		this.update(updateWrapper);
		return R.ok();
	}

	@Override
	public long getDispatchInfoCount(TDispatchInfoPreSearchVo searchVo) {
		initSearchVo(searchVo);
		return baseMapper.selectSocialCount(searchVo);
	}

	@Override
	public long getDispatchInfoFundCount(TDispatchInfoPreSearchVo searchVo) {
		searchVo.setType(CommonConstants.ONE_STRING);
		initSearchVo(searchVo);
		return baseMapper.selectFundCount(searchVo);
	}

	@Override
	public Boolean saveSocialPreInfo(EmployeeRegistrationPreVo registrationPreVo) {
		if (Common.isNotNull(registrationPreVo.getSocialIsBuy())
				&& registrationPreVo.getSocialIsBuy().equals(CommonConstants.ZERO_STRING)
				&& !registrationPreVo.getExitSocialInfoList().isEmpty()) {
			//删除已存在的入职确认信息对应的社保明细
			socialPreDetailService.remove(Wrappers.<TSocialPreDetail>lambdaQuery()
					.eq(TSocialPreDetail::getRegisterId, registrationPreVo.getExitSocialInfoList()
							.get(0).getRegisterId()));
			//批量新增
			for (TSocialPreDetailVo vo : registrationPreVo.getExitSocialInfoList()) {
				TSocialPreDetail preDetal = new TSocialPreDetail();
				BeanUtils.copyProperties(vo, preDetal);
				preDetal.setId(null);
				socialPreDetailService.save(preDetal);
			}
			//批量删除社保待购买列表中的待确认、待派单、派单失败、审核、办理失败的数据
			baseMapper.delete(Wrappers.<TDispatchInfoPre>query().lambda()
					.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING)
					.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4", "8"))
					.eq(TDispatchInfoPre::getRegisterId, registrationPreVo.getExitSocialInfoList()
							.get(0).getRegisterId()));
		} else {
			//删除已存在的入职确认信息对应的社保明细
			TDispatchInfoPreVo preVo = registrationPreVo.getDispatchInfoPreVo();
			socialPreDetailService.remove(Wrappers.<TSocialPreDetail>lambdaQuery()
					.eq(TSocialPreDetail::getRegisterId, preVo.getRegisterId()));
			try {

				if (Common.isNotNull(preVo)) {
					//判断是否存在社保待购买信息
					TDispatchInfoPre preExit = baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
							.eq(TDispatchInfoPre::getRegisterId, preVo.getRegisterId())
							.eq(TDispatchInfoPre::getEmpIdcard, preVo.getEmpIdcard())
							.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING)
							.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4", "8"))
							.last(CommonConstants.LAST_ONE_SQL));
					TDispatchInfoPre pre = new TDispatchInfoPre();
					BeanUtils.copyProperties(preVo, pre);
					//时间格式转化
					if (Common.isNotNull(preVo.getExpectedCollectionTime())) {
						preVo.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
								preVo.getExpectedCollectionTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " 15:20", DateUtil.DATETIME_PATTERN_MINUTE));
						pre.setExpectedCollectionTime(LocalDateTimeUtils.dateToLocalDateTime(preVo.getExpectedCollectionTime()));
					}
					if (Common.isNotNull(preVo.getExpectedConfirmTime())) {
						preVo.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
								preVo.getExpectedCollectionTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " 09:00", DateUtil.DATETIME_PATTERN_MINUTE));
						pre.setExpectedConfirmTime(LocalDateTimeUtils.dateToLocalDateTime(preVo.getExpectedConfirmTime()));
					}
					if (Common.isEmpty(pre.getDispatchItem())) {
						pre.setDispatchItem("养老、医疗、生育、失业、工伤、大病");
					}
					//如果自动触发派增为是，计算派单发起时间和派单确认时间
					if (Common.isNotNull(preVo.getIsAutoDis()) && CommonConstants.ZERO_STRING.equals(preVo.getIsAutoDis())
							&& Common.isEmpty(preVo.getExpectedCollectionTime())) {
						initExpectedCollectionTime(preVo.getSocialHouseholdName(), preVo.getSocialStartDate(), preVo);
					}
					if (Common.isNotNull(preExit)) {
						pre.setId(preExit.getId());
						baseMapper.deleteById(preExit);
					}
					baseMapper.insert(pre);
				}
			} catch (Exception e) {
				log.error("执行异常", e);
				return false;
			}
		}
		return true;
	}
	/**
	 * 新增公积金待购买信息
	 * @param registrationPreVo
	 * @return
	 */
	@Override
	public Boolean saveFundPreInfo(EmployeeRegistrationPreVo registrationPreVo) {
		if (Common.isNotNull(registrationPreVo.getFundIsBuy())
				&& registrationPreVo.getFundIsBuy().equals(CommonConstants.ZERO_STRING)
				&& !registrationPreVo.getExitFundInfoList().isEmpty()) {
			//删除已存在的入职确认信息对应的公积金明细
			fundPreDetailService.remove(Wrappers.<TFundPreDetail>lambdaQuery()
					.eq(TFundPreDetail::getRegisterId, registrationPreVo.getExitFundInfoList()
							.get(0).getRegisterId()));
			//批量新增
			for (TFundPreDetailVo vo : registrationPreVo.getExitFundInfoList()) {
				TFundPreDetail preDetal = new TFundPreDetail();
				BeanUtils.copyProperties(vo, preDetal);
				preDetal.setId(null);
				fundPreDetailService.save(preDetal);
			}
			//批量删除公积金待购买列表中的待确认、待派单、派单失败、审核、办理失败的数据
			baseMapper.delete(Wrappers.<TDispatchInfoPre>query().lambda()
					.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING)
					.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4", "8"))
					.eq(TDispatchInfoPre::getRegisterId, registrationPreVo.getExitFundInfoList()
							.get(0).getRegisterId()));
		} else {
			//删除已存在的入职确认信息对应的公积金明细
			TDispatchInfoPreVo preVo = registrationPreVo.getDispatchInfoFundPreVo();
			fundPreDetailService.remove(Wrappers.<TFundPreDetail>lambdaQuery()
					.eq(TFundPreDetail::getRegisterId, preVo.getRegisterId()));
			try {
				if (Common.isNotNull(preVo)) {
					//判断是否存在公积金待购买信息
					TDispatchInfoPre preExit = baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
							.eq(TDispatchInfoPre::getRegisterId, preVo.getRegisterId())
							.eq(TDispatchInfoPre::getEmpIdcard, preVo.getEmpIdcard())
							.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING)
							.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4", "8"))
							.last(CommonConstants.LAST_ONE_SQL));
					TDispatchInfoPre pre = new TDispatchInfoPre();
					BeanUtils.copyProperties(preVo, pre);
					//时间格式转化
					if (Common.isNotNull(preVo.getExpectedCollectionTime())) {
						preVo.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
								preVo.getExpectedCollectionTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " 15:20", DateUtil.DATETIME_PATTERN_MINUTE));
						pre.setExpectedCollectionTime(LocalDateTimeUtils.dateToLocalDateTime(preVo.getExpectedCollectionTime()));
					}
					if (Common.isNotNull(preVo.getExpectedConfirmTime())) {
						preVo.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
								preVo.getExpectedCollectionTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " 09:00", DateUtil.DATETIME_PATTERN_MINUTE));
						pre.setExpectedConfirmTime(LocalDateTimeUtils.dateToLocalDateTime(preVo.getExpectedConfirmTime()));
					}
					if (Common.isEmpty(pre.getDispatchItem())) {
						pre.setDispatchItem("公积金");
					}
					//如果自动触发派增为是，计算派单发起时间和派单确认时间
					if (Common.isNotNull(preVo.getIsAutoDis()) && CommonConstants.ZERO_STRING.equals(preVo.getIsAutoDis())
							&& Common.isEmpty(preVo.getExpectedCollectionTime())) {
						initExpectedCollectionTime(preVo.getProvidentHouseholdName(), preVo.getFundStartDate(), preVo);
					}
					if (Common.isNotNull(preExit)) {
						pre.setId(preExit.getId());
						baseMapper.deleteById(preExit);
					}
					pre.setTypeSub(CommonConstants.ONE_STRING);
					baseMapper.insert(pre);
				}
			} catch (Exception e) {
				log.error("执行异常", e);
				return false;
			}
		}
		return true;
	}

	@Override
	public void updateSocialPreCustomerName(EmployeeRegistrationCustomerUserUpdateVo updateVo) {
		//批量更新前端客服名称
		if (Common.isNotNull(updateVo) && Common.isNotNull(updateVo.getDeptNo())) {
			LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
			updateWrapper.eq(TDispatchInfoPre::getDeptNo, updateVo.getDeptNo())
					.set(TDispatchInfoPre::getCustomerUsername, updateVo.getCustomerUserName())
					.set(TDispatchInfoPre::getCustomerUserLoginName, updateVo.getCustomerUserLoginName());
			this.update(updateWrapper);
		}
	}

	@Override
	public EmployeePreSocialListVo getSocialPreInfoList(String id) {
		EmployeePreSocialListVo preSocialListVo = new EmployeePreSocialListVo();
		//获取社保已购买和待购买信息
		List<TSocialPreDetail> exitSocialInfoList = socialPreDetailService.list(Wrappers.<TSocialPreDetail>query().lambda()
				.eq(TSocialPreDetail::getRegisterId, id));
		if (Common.isNotNull(exitSocialInfoList) && !exitSocialInfoList.isEmpty()) {
			List<TSocialPreDetailVo> exitSocialInfoListVo = exitSocialInfoList.stream()
					.map(detail -> {
						TSocialPreDetailVo vo = new TSocialPreDetailVo();
						BeanUtils.copyProperties(detail, vo);
						return vo;
					})
					.collect(Collectors.toList());
			preSocialListVo.setExitSocialInfoList(exitSocialInfoListVo);
			return preSocialListVo;
		}
		TDispatchInfoPre preExit = baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
				.eq(TDispatchInfoPre::getRegisterId, id)
				.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING)
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(preExit)) {
			TDispatchInfoPreVo pre = new TDispatchInfoPreVo();

			BeanUtils.copyProperties(preExit, pre);
			if (Common.isNotNull(preExit.getExpectedCollectionTime())) {
				pre.setExpectedCollectionTime(LocalDateTimeUtils.convertLDTToDate(preExit.getExpectedCollectionTime()));
				pre.setExpectedConfirmTime(LocalDateTimeUtils.convertLDTToDate(preExit.getExpectedConfirmTime()));
			}
			preSocialListVo.setDispatchInfoPreVo(pre);
		}
		return preSocialListVo;
	}
	/**
	 * @Author fxj
	 * @Description 入职确认信息详情中的公积金明细信息
	 * @Date 14:07 2025/11/7
	 * @Param
	 * @return
	**/
	public EmployeePreSocialListVo getFundPreInfoList(String id) {
		EmployeePreSocialListVo preFundListVo = new EmployeePreSocialListVo();
		//获取公积金已购买和待购买信息
		List<TFundPreDetail> exitFundInfoList = fundPreDetailService.list(Wrappers.<TFundPreDetail>query().lambda()
				.eq(TFundPreDetail::getRegisterId, id));
		if (Common.isNotNull(exitFundInfoList) && !exitFundInfoList.isEmpty()) {
			List<TFundPreDetailVo> exitFundInfoListVo = exitFundInfoList.stream()
					.map(detail -> {
						TFundPreDetailVo vo = new TFundPreDetailVo();
						BeanUtils.copyProperties(detail, vo);
						return vo;
					})
					.collect(Collectors.toList());
			preFundListVo.setExitFundInfoList(exitFundInfoListVo);
			return preFundListVo;
		}
		TDispatchInfoPre preExit = baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
				.eq(TDispatchInfoPre::getTypeSub, CommonConstants.ONE_STRING)
				.eq(TDispatchInfoPre::getRegisterId, id)
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(preExit)) {
			TDispatchInfoPreVo pre = new TDispatchInfoPreVo();

			BeanUtils.copyProperties(preExit, pre);
			if (Common.isNotNull(preExit.getExpectedCollectionTime())) {
				pre.setExpectedCollectionTime(LocalDateTimeUtils.convertLDTToDate(preExit.getExpectedCollectionTime()));
				pre.setExpectedConfirmTime(LocalDateTimeUtils.convertLDTToDate(preExit.getExpectedConfirmTime()));
			}
			preFundListVo.setDispatchInfoPreFundVo(pre);
		}
		return preFundListVo;
	}

	@Override
	public EmployeePreSocialListVo getSocialPreInfoStatus(String id) {
		EmployeePreSocialListVo preSocialListVo = new EmployeePreSocialListVo();
		//获取社保已购买信息
		TDispatchInfoPre preExit = baseMapper.selectById(id);
		if (Common.isNotNull(preExit)) {
			TDispatchInfoPreVo pre = new TDispatchInfoPreVo();
			BeanUtils.copyProperties(preExit, pre);
			preSocialListVo.setDispatchInfoPreVo(pre);
		}
		return preSocialListVo;
	}

	@Override
	public Boolean deleteUnProcessSocialPreInfo(String id) {
		//删除未处理的社保待购买信息
		return this.remove(Wrappers.<TDispatchInfoPre>query().lambda()
				.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING)
				.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8"))
				.eq(TDispatchInfoPre::getRegisterId, id));
	}

	@Override
	public Boolean deleteUnProcessFundPreInfo(String id) {
		//删除未处理的公积金待购买信息
		return  this.remove(Wrappers.<TDispatchInfoPre>query().lambda()
				.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING)
				.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8"))
				.eq(TDispatchInfoPre::getRegisterId, id));

	}

	@Override
	public R dispatcherSocial(List<String> idList,String type) {
		YifuUser user = SecurityUtils.getUser();
		List<TDispatchInfoPre> contractPreList = baseMapper.selectList(Wrappers.<TDispatchInfoPre>query()
				.lambda().in(TDispatchInfoPre::getId, idList)
				.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING)
				.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("1","2","4","8","9")));
		// 如果没有找到任何未处理的社保待购买数据，返回失败消息
		if (Common.isEmpty(contractPreList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		//发起派单
		List<ErrorMessage> errorMessageListAll = new ArrayList<>();
		List<TDispatchImportVo> excelVOList = baseMapper.getDisPatcherSocialList(idList,Arrays.asList("1","2","4","8","9"),type);
		if (Common.isNotNull(excelVOList) && !excelVOList.isEmpty()) {
			List<TDispatchImportVo> disList;
			int k = 0;
			int i = (int) Math.ceil((double) excelVOList.size() / CommonConstants.INTEGER_HUNDRED);
			//前端客服对应的成功和失败数量
			Map<String,Integer> sumMap = new HashMap<>();
			Map<String,Integer> falureMap = new HashMap<>();
			// 先统计每个登录名的总派单数量
			for (TDispatchImportVo vo : excelVOList) {
				String preLoginName = vo.getPreLoginName();
				sumMap.put(preLoginName, sumMap.getOrDefault(preLoginName, 0) + 1);
				// 初始化失败数量为0
				falureMap.putIfAbsent(preLoginName, 0);
			}
			Map<String, String> loginNameMap = new HashMap<>();
			for (int j = 0; j < i; j++) {
				if (j == i - 1) {
					disList = excelVOList.subList(k, excelVOList.size());
				} else {
					disList = excelVOList.subList(k, k + 100);
				}
				k = k + 100;
				if (Common.isNotNull(disList)) {
					//调用批量派单接口100条处理一次，同原合同派单保持一致
					List<ErrorMessage> errorMessageList = new ArrayList<>();
					dispatchInfoService.importTDispatchInfo(disList, errorMessageList,user, null, new HashMap<>(),CommonConstants.ZERO_STRING);
					if (!errorMessageList.stream().allMatch(message -> message.getMessage().equals(CommonConstants.SAVE_SUCCESS))) {
						List<ErrorMessage> relErrorMessageList = errorMessageList.stream().filter(message -> !message.getMessage().equals(CommonConstants.SAVE_SUCCESS)).collect(Collectors.toList());
						errorMessageListAll.addAll(relErrorMessageList);
						//更新社保状态为2发起失败
						for (ErrorMessage errorMessage : errorMessageList) {
							if (!errorMessage.getMessage().equals(CommonConstants.SAVE_SUCCESS)) {
								TDispatchImportVo contractVO = disList.stream().filter(vo -> Objects.equals(
										vo.getRowIndex(), errorMessage.getLineNum())).collect(Collectors.toList()).get(0);
								LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
								updateWrapper.in(TDispatchInfoPre::getId, contractVO.getPreId())
										.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("1","2","4","8","9"))
										.set(TDispatchInfoPre::getProcessStatus, CommonConstants.TWO_STRING)
										.set(TDispatchInfoPre::getErrorInfo, errorMessage.getMessage())
										.set(TDispatchInfoPre::getErrorTime, LocalDateTime.now());
								// 执行更新操作
								errorMessage.setData(contractVO);
								this.update(updateWrapper);
								// 统计失败数量
								String preLoginName = contractVO.getPreLoginName();
								falureMap.put(preLoginName, falureMap.getOrDefault(preLoginName, 0) + 1);
								//生成快照数据
								if(type.equals("2")) {
									if (null == loginNameMap.get(preLoginName)) {
										UUID uuid = UUID.randomUUID();
										loginNameMap.put(preLoginName, uuid.toString());
									}
									TSocialAutoLog socialAutoLog = new TSocialAutoLog();
									socialAutoLog.setSocialId(loginNameMap.get(preLoginName));
									socialAutoLog.setEmpName(contractVO.getEmpName());
									socialAutoLog.setEmpIdcard(contractVO.getEmpIdcard());
									socialAutoLog.setErrorInfo(errorMessage.getMessage());
									socialAutoLog.setType(CommonConstants.ZERO_STRING);
									socialAutoLogService.save(socialAutoLog);
								}
							}
						}
					}
				}
			}
			//针对定时任务派单的记录失败次数，集中提醒至该项目的“前端客服”
			if (!falureMap.isEmpty() && type.equals("2")) {
				for (Map.Entry<String, Integer> entry : falureMap.entrySet()) {
					String preLoginName = entry.getKey();
					int failureCount = entry.getValue();
					int sum = sumMap.get(preLoginName);
					sendDisFalureMessageToWx(preLoginName ,sum, failureCount, loginNameMap,"社保");
				}

			}
		}
		return R.ok(errorMessageListAll);
	}

	@Override
	public void pushWxConfrimMessage() {
		//获取所有预计派单时间为当天而且状态是待确认的社保待签署数据
		List<TDispatchInfoPre> unConfirmList = baseMapper.getAllUnDisSocialData();
		if (Common.isNotNull(unConfirmList) && !unConfirmList.isEmpty()) {
			for (TDispatchInfoPre pre : unConfirmList) {
				try {
					sendMessageToWx(pre);
				} catch (Exception e) {
					log.error("执行异常", e);
				}
			}
		}
		//获取所有预计派单时间为当天而且状态是待确认的公积金待签署数据
		List<TDispatchInfoPre> unConfirmFundList = baseMapper.getAllUnDisFundData();
		if (Common.isNotNull(unConfirmFundList) && !unConfirmFundList.isEmpty()) {
			for (TDispatchInfoPre pre : unConfirmFundList) {
				try {
					sendMessageToWx(pre);
				} catch (Exception e) {
					log.error("执行异常", e);
				}
			}
		}
	}

	@Override
	public void pushDisConfrimSocial() {
		//获取所有待派单的社保数据
		List<String> unConfirmList = baseMapper.getAllUnDisDataIdList();
		if (null != unConfirmList && !unConfirmList.isEmpty()) {
			try {
				this.dispatcherSocial(unConfirmList,"2");
			} catch (Exception e) {
				log.error("执行异常", e);
			}
		}
		//获取所有待派单的公积金数据
		List<String> unConfirmFundList = baseMapper.getAllUnDisDataIdFundList();
		if (null != unConfirmFundList && !unConfirmFundList.isEmpty()) {
			try {
				this.dispatcherFund(unConfirmFundList,"2");
			} catch (Exception e) {
				log.error("执行异常", e);
			}
		}
	}

	//发送企业微信待办
	private void sendMessageToWx(TDispatchInfoPre pre) {
		String code = "04";
		String item = "社保";
		if (CommonConstants.ONE_STRING.equals(pre.getTypeSub())){
			code = "05";
			item = "公积金";
		}
		//获取前端客服
		SysUser user;
		if (Common.isEmpty(pre.getCustomerUserLoginName())) {
			return;
		}
		R<SysUser> res = upmsDaprUtils.getSimpleUserByLoginName(pre.getCustomerUserLoginName());
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
			user = res.getData();
		} else {
			return;
		}
		StringBuilder sendUser = null;
		if (Common.isNotKong(user.getWxMessage())) {
			sendUser = new StringBuilder(user.getWxMessage());
		}
		if (sendUser != null) {
			RestTemplate restTemplate = new RestTemplate();
			Map<String, Object> requestMap = new HashMap<>();
			Map<String, Object> textcard = new HashMap<>();
			String authUrl = String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid(), wxConfig.getDomainName() + "/auth/oauth/wxLogin", code + pre.getCustomerUserLoginName());
			StringBuilder description = new StringBuilder();
			String title = item+"购买确认";
			description.append("您有新的"+item+"待购买确认数据，请及时确认").append("<br>");
			textcard.put("title", title);
			textcard.put("url", authUrl);
			textcard.put("description", description.toString());
			requestMap.put("touser", sendUser);
			requestMap.put("agentid", wxConfig.getAgentid());
			requestMap.put("msgtype", "textcard");
			requestMap.put("textcard", textcard);
			// 必须加上header说明
			if (!wxConfig.sendTextCard(restTemplate, requestMap)) {
				wxConfig.sendTextCard(restTemplate, requestMap);
			}
		}
	}

	//发送企业微信待办
	private void sendDisFalureMessageToWx(String LoginName, int sum, int falureNum,Map<String, String> loginNameMap,String item) {
		String code = "67";
		if ("公积金".equals(item)){
			code = "74";
		}
		//获取前端客服
		SysUser user;
		if (Common.isEmpty(LoginName)) {
			return;
		}
		R<SysUser> res = upmsDaprUtils.getSimpleUserByLoginName(LoginName);
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
			user = res.getData();
		} else {
			return;
		}
		StringBuilder sendUser = null;
		if (Common.isNotKong(user.getWxMessage())) {
			sendUser = new StringBuilder(user.getWxMessage());
		}
		if (sendUser != null) {
			RestTemplate restTemplate = new RestTemplate();
			Map<String, Object> requestMap = new HashMap<>();
			Map<String, Object> textcard = new HashMap<>();
			String authUrl = String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid(), wxConfig.getDomainName() + "/auth/oauth/wxLogin", code + loginNameMap.get(LoginName));
			StringBuilder description = new StringBuilder();
			String title = "作业自动化——"+item+"派单发起失败提醒";
			description.append(item+"派单数：").append(sum).append("份，失败份数：").append(falureNum).append("份；").append("<br>");
			description.append("点击查看详情").append("<br>");
			description.append("<br>");
			description.append("请及时至HRO系统处理，以免耽误购买进度！").append("<br>");
			textcard.put("title", title);
			textcard.put("url", authUrl);
			textcard.put("description", description.toString());
			requestMap.put("touser", sendUser);
			requestMap.put("agentid", wxConfig.getAgentid());
			requestMap.put("msgtype", "textcard");
			requestMap.put("textcard", textcard);
			// 必须加上header说明
			if (!wxConfig.sendTextCard(restTemplate, requestMap)) {
				wxConfig.sendTextCard(restTemplate, requestMap);
			}
		}
	}

	/**
	 * @Description: 获取前端客服的所有项目权限
	 * @Author: huych
	 * @Date: 2025/3/13 17:02
	 * @return:
	 **/
	public void initSearchVo(TDispatchInfoPreSearchVo searchVo) {
		YifuUser user = SecurityUtils.getUser();
		long roleId = 1839501715787390978L;
		boolean isSsc = this.haveRole(user, roleId);
		if (isSsc || CommonConstants.ZERO_STRING.equals(user.getSystemFlag())) {
			searchVo.setAuthSql(null);
			return;
		}
		if (Common.isNotNull(searchVo.getType()) && CommonConstants.ONE_STRING.equals(searchVo.getType())) {
			searchVo.setAuthSql(null);
			//获取项目信息
			R<TSettleDomainRegistListVo> domainR = archivesDaprUtil.getAllDeptByCustomerLoginName(user.getUsername());
			if (null != domainR && null != domainR.getData() && null != domainR.getData().getDeptNos() && !domainR.getData().getDeptNos().isEmpty()) {
				searchVo.setDeptNoList(domainR.getData().getDeptNos());
			} else {
				domainR = archivesDaprUtil.getAllDeptByCustomerLoginName(user.getUsername());
				if (null != domainR && null != domainR.getData() && null != domainR.getData().getDeptNos() && !domainR.getData().getDeptNos().isEmpty()) {
					searchVo.setDeptNoList(domainR.getData().getDeptNos());
				} else {
					searchVo.setId(CommonConstants.ONE_STRING_NEGATE);
				}
			}
		}
	}

	public boolean haveRole(YifuUser user, long roleId) {
		List<Long> roleList = user.getClientRoleMap().get(ClientNameConstants.CLIENT_MVP);
		for (Long role : roleList) {
			if (role == roleId) {
				return true;
			}
		}
		return false;
	}

	public Date addYearsMonths(TEmployeeContractDateVo vo) {
		if (vo == null || vo.getRegistDate() == null) return null;

		// 转换为LocalDate（自动处理时区）
		LocalDate localDate = vo.getRegistDate().toInstant()
				.atZone(ZoneId.systemDefault())
				.toLocalDate();
		// 添加年数和月数
		if (vo.getMonthAfter() == 0 && vo.getYearAfter() == 0) {
			// 转回Date类型
			return Date.from(localDate.atStartOfDay()
					.atZone(ZoneId.systemDefault())
					.toInstant());
		} else {
			localDate = localDate
					.plusYears(vo.getYearAfter())
					.plusMonths(vo.getMonthAfter())
					.minusDays(1);
			// 转回Date类型
			return Date.from(localDate.atStartOfDay()
					.atZone(ZoneId.systemDefault())
					.toInstant());
		}
	}

	/**
	 * @Author fxj
	 * @Description 手动派单-公积金待购买信息单个/批量发起购买任务
	 * @Date 11:53 2025/11/7
	 * @Param
	 * @return
	**/
	@Override
	public R dispatcherFund(List<String> idList,String type) {
		YifuUser user = SecurityUtils.getUser();
		List<TDispatchInfoPre> contractPreList = baseMapper.selectList(Wrappers.<TDispatchInfoPre>query()
				.lambda().in(TDispatchInfoPre::getId, idList)
				.eq(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING)
				.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("1","2","4","8")));
		// 如果没有找到任何未处理的公积金待购买数据，返回失败消息
		if (Common.isEmpty(contractPreList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		//发起派单
		List<ErrorMessage> errorMessageListAll = new ArrayList<>();
		List<TDispatchImportVo> excelVOList = baseMapper.getDisPatcherFundList(idList,Arrays.asList("1","2","4","8"),type);
		if (Common.isNotNull(excelVOList) && !excelVOList.isEmpty()) {
			List<TDispatchImportVo> disList;
			int k = 0;
			int i = (int) Math.ceil((double) excelVOList.size() / CommonConstants.INTEGER_HUNDRED);
			//前端客服对应的成功和失败数量
			Map<String,Integer> sumMap = new HashMap<>();
			Map<String,Integer> falureMap = new HashMap<>();
			// 先统计每个登录名的总派单数量
			for (TDispatchImportVo vo : excelVOList) {
				String preLoginName = vo.getPreLoginName();
				sumMap.put(preLoginName, sumMap.getOrDefault(preLoginName, 0) + 1);
				// 初始化失败数量为0
				falureMap.putIfAbsent(preLoginName, 0);
			}
			Map<String, String> loginNameMap = new HashMap<>();
			for (int j = 0; j < i; j++) {
				if (j == i - 1) {
					disList = excelVOList.subList(k, excelVOList.size());
				} else {
					disList = excelVOList.subList(k, k + 100);
				}
				k = k + 100;
				if (Common.isNotNull(disList)) {
					//调用批量派单接口100条处理一次，同原合同派单保持一致
					List<ErrorMessage> errorMessageList = new ArrayList<>();
					dispatchInfoService.importTDispatchInfo(disList, errorMessageList,user, null, new HashMap<>(),null);
					if (!errorMessageList.stream().allMatch(message -> message.getMessage().equals(CommonConstants.SAVE_SUCCESS))) {
						List<ErrorMessage> relErrorMessageList = errorMessageList.stream().filter(message -> !message.getMessage().equals(CommonConstants.SAVE_SUCCESS)).collect(Collectors.toList());
						errorMessageListAll.addAll(relErrorMessageList);
						//更新公积金状态为2发起失败
						for (ErrorMessage errorMessage : errorMessageList) {
							if (!errorMessage.getMessage().equals(CommonConstants.SAVE_SUCCESS)) {
								TDispatchImportVo contractVO = disList.stream().filter(vo -> Objects.equals(
										vo.getRowIndex(), errorMessage.getLineNum())).collect(Collectors.toList()).get(0);
								LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
								updateWrapper.in(TDispatchInfoPre::getId, contractVO.getPreId())
										.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("1","2","4","8"))
										.set(TDispatchInfoPre::getProcessStatus, CommonConstants.TWO_STRING)
										.set(TDispatchInfoPre::getErrorInfo, errorMessage.getMessage())
										.set(TDispatchInfoPre::getErrorTime, LocalDateTime.now());
								// 执行更新操作
								errorMessage.setData(contractVO);
								this.update(updateWrapper);
								// 统计失败数量
								String preLoginName = contractVO.getPreLoginName();
								falureMap.put(preLoginName, falureMap.getOrDefault(preLoginName, 0) + 1);
								//生成快照数据
								if(type.equals("2")) {
									if (null == loginNameMap.get(preLoginName)) {
										UUID uuid = UUID.randomUUID();
										loginNameMap.put(preLoginName, uuid.toString());
									}
									TSocialAutoLog socialAutoLog = new TSocialAutoLog();
									socialAutoLog.setSocialId(loginNameMap.get(preLoginName));
									socialAutoLog.setEmpName(contractVO.getEmpName());
									socialAutoLog.setEmpIdcard(contractVO.getEmpIdcard());
									socialAutoLog.setErrorInfo(errorMessage.getMessage());
									socialAutoLog.setType(CommonConstants.ONE_STRING);
									socialAutoLogService.save(socialAutoLog);
								}
							}
						}
					}
				}
			}
			//针对定时任务派单的记录失败次数，集中提醒至该项目的“前端客服”
			if (!falureMap.isEmpty() && type.equals("2")) {
				for (Map.Entry<String, Integer> entry : falureMap.entrySet()) {
					String preLoginName = entry.getKey();
					int failureCount = entry.getValue();
					int sum = sumMap.get(preLoginName);
					sendDisFalureMessageToWx(preLoginName ,sum, failureCount, loginNameMap, "公积金");
				}

			}
		}
		return R.ok(errorMessageListAll);
	}

	/**
	 * 公积金待购买表批量导出
	 * @param searchVo 公积金待购买表
	 * @return
	 */
	@Override
	public void listExportFund(HttpServletResponse response, TDispatchInfoPreSearchVo searchVo){
		String fileName = "公积金待购买批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TDispatchInfoPreFundExportVo> list = new ArrayList<>();
		initSearchVo(searchVo);
		long count = baseMapper.selectFundExportCount(searchVo);
		try (ServletOutputStream out= response.getOutputStream();){
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName  , CommonConstants.UTF8));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, TDispatchInfoPreFundExportVo.class).build();
			int index = 0;
			if (count >  CommonConstants.ZERO_INT){
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.selectFundExportList(searchVo);
					if (Common.isNotNull(list)){
						WriteSheet writeSheet = EasyExcel.writerSheet("公积金待购买"+index).build();
						excelWriter.write(list,writeSheet);
						index++;
					}
					if (Common.isNotNull(list)){
						list.clear();
					}
				}
			}else {
				WriteSheet writeSheet = EasyExcel.writerSheet("公积金待购买"+index).build();
				excelWriter.write(list,writeSheet);
			}
			if (Common.isNotNull(list)){
				list.clear();
			}
			excelWriter.finish();
		}catch (Exception e){
			log.error("执行异常" ,e);
		}
	}

	@Override
	public EmployeePreSocialListVo getFundPreInfoStatus(String id) {
		EmployeePreSocialListVo preSocialListVo = new EmployeePreSocialListVo();
		//获取社保已购买信息
		TDispatchInfoPre preExit = baseMapper.selectById(id);
		if (Common.isNotNull(preExit)) {
			TDispatchInfoPreVo pre = new TDispatchInfoPreVo();
			BeanUtils.copyProperties(preExit, pre);
			preSocialListVo.setDispatchInfoPreFundVo(pre);
		}
		return preSocialListVo;
	}

	/**
	 * @Author fxj
	 * @Description 查询公积金待待购买的状态：
	 * 待审核、待办理、办理成功——为在途或在保
	 * 待确认   待派单   派单失败   审核不通过    办理失败    ——为不在途不在保
	 * 公积金购买状态，0待确认，1待派单，2派单失败，3待审核，4审核不通过，5待办理，7办理成功，8办理失败
	 * @Date 9:50 2025/11/17
	 * @Param
	 * @return true：  在途 或 在保  false：  不在途不在保
	**/
	@Override
	public Boolean getFundPreStatus(String id) {
		//获取公积金已购买信息
		TDispatchInfoPre preExit = baseMapper.selectById(id);
		if (Common.isNotNull(preExit)
				&& (CommonConstants.THREE_STRING.equals(preExit.getProcessStatus())
				|| CommonConstants.FIVE_STRING.equals(preExit.getProcessStatus())
				|| CommonConstants.SEVEN_STRING.equals(preExit.getProcessStatus()) )) {
			return true;
		}
		return false;
	}

	/**
	 * @Author fxj
	 * @Description 初始化预计派单发起时间、预计派单确认时间
	 * @Date 17:06 2025/12/12
	 **/
	private void initExpectedCollectionTime(String houseName, Date startDate, TDispatchInfoPreVo preVo2) throws ParseException {
		//获取当前月是否可办理状态：获取办理截止日往前最近的工昨日，当前日及截止日前(含截止日)有工作日就是可办理
		BaseSearchVO paramVo = new BaseSearchVO();
		paramVo.setName(houseName);
		paramVo.setType(CommonConstants.ZERO_STRING);
		THouseHoldLimitInnerVo innerVo =  houseHoldLimitService.getWorkDayByDeadLineDay(paramVo);
		if (Common.isEmpty(innerVo)){
			throw new RuntimeException("获取截止日信息失败");
		}
		boolean canBeHandle = innerVo.getCanBeHandle();
		LocalTime currentTime = LocalTime.now();
		LocalTime thresholdTime = LocalTime.of(15, 20);
		boolean isBeforeThreshold = currentTime.isBefore(thresholdTime) || currentTime.equals(thresholdTime);

		// 时间格式常量
		String collectionTimeFormat = " 15:20";
		String confirmTimeFormat = " 09:00";

		//获取次月1号日期
		Date nextMonthFirstDay = DateUtil.addMonthByDate(DateUtil.formatDateByPatten(new Date(), DateUtil.ISO_EXPANDED_DATE_FORMAT), 1);
		nextMonthFirstDay = DateUtil.setDayByDate(nextMonthFirstDay, 1);

		//获取起缴月份1号
		Date startDateFirstDay = DateUtil.addDayByDate(DateUtil.formatDateByPatten(startDate, DateUtil.ISO_EXPANDED_DATE_FORMAT), 0);
		startDateFirstDay = DateUtil.setDayByDate(startDateFirstDay, 1);

		//获取起缴月-1日期
		Date startDatePrevMonth = DateUtil.addMonthByDate(startDateFirstDay, -1);

		//获取次日
		Date tomorrow = DateUtil.getDateByDayNum(1);
		//1.起缴月份为当月及之前的月份
		if (DateUtil.isCurrentOrBeforeMonth(startDate)){
			if (canBeHandle){
				//发起时间不看工作日
				if (isBeforeThreshold) {
					Date today = new Date();
					preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
							today, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
					preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
							today, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				} else {
					preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
							tomorrow, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
					preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
							tomorrow, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				}
			} else {
				preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
						nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
						nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
			}
		}
		//2.起缴月份为次月
		else if (DateUtil.isNextMonth(startDate)){
			//当月办次月生效
			if (CommonConstants.ONE_STRING.equals(innerVo.getAddHandleRule())){
				if (canBeHandle){
					//发起时间不看工作日
					if (isBeforeThreshold) {
						Date today = new Date();
						preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
								today, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
						preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
								today, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
					}else {
						preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
								tomorrow, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
						preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
								tomorrow, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
					}

				} else {
					preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
							nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
					preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
							nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				}
				//当月办当月生效
			} else if (CommonConstants.ZERO_STRING.equals(innerVo.getAddHandleRule())){
				preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
						nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
						nextMonthFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
			}
		}
		//3.起缴月份为次月之后的月份
		else if (DateUtil.isNextNextMonthOrAfter(startDate)){
			//当月办次月生效
			if (CommonConstants.ONE_STRING.equals(innerVo.getAddHandleRule())){
				preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
						startDatePrevMonth, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
				preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
						startDatePrevMonth, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
			} else if (CommonConstants.ZERO_STRING.equals(innerVo.getAddHandleRule())){
				preVo2.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
						startDateFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + collectionTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));

				preVo2.setExpectedConfirmTime(DateUtil.parseDate(DateUtil.dateToString(
						startDateFirstDay, DateUtil.ISO_EXPANDED_DATE_FORMAT) + confirmTimeFormat, DateUtil.DATETIME_PATTERN_MINUTE));
			}
		}
	}
	@Override
	public R<TDispatchInfoPre> getInfoByRegistId(String registId,String type) {
		if (Common.isEmpty(registId) || Common.isEmpty(type)) {
			return R.failed(CommonConstants.PARAM_INFO_ERROR);
		}
		return R.ok(baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
				.notIn(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4", "8"))
				.eq(TDispatchInfoPre::getTypeSub,type)
				.eq(TDispatchInfoPre::getRegisterId, registId).last(CommonConstants.LAST_ONE_SQL)));
	}

	@Override
	public Boolean updateRefuseSocialPreInfo(String id) {
		//更新未处理的社保待购买信息
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(TDispatchInfoPre::getIsRefuse, CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8"));
		updateWrapper.eq(TDispatchInfoPre::getRegisterId, id);
		return this.update(updateWrapper);
	}

	@Override
	public Boolean updateLeaveSocialPreInfo(String id) {
		//更新未处理的社保待购买信息
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(TDispatchInfoPre::getIsLeave, CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getTypeSub,CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8","9"));
		updateWrapper.eq(TDispatchInfoPre::getRegisterId, id);
		return this.update(updateWrapper);
	}


	@Override
	public Boolean updateRefuseFundPreInfo(String id) {
		//删除未处理的公积金待购买信息
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(TDispatchInfoPre::getIsRefuse, CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING);
		updateWrapper.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8"));
		updateWrapper.eq(TDispatchInfoPre::getRegisterId, id);
		return this.update(updateWrapper);
	}
	@Override
	public Boolean updateLeaveFundPreInfo(String id) {
		//删除未处理的公积金待购买信息
		LambdaUpdateWrapper<TDispatchInfoPre> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(TDispatchInfoPre::getIsLeave, CommonConstants.ZERO_STRING);
		updateWrapper.in(TDispatchInfoPre::getTypeSub,CommonConstants.ONE_STRING);
		updateWrapper.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("0", "1", "2", "4","8"));
		updateWrapper.eq(TDispatchInfoPre::getRegisterId, id);
		return this.update(updateWrapper);
	}

	// 获取处理中的自动化社保公积金（3待审核、5待办理、6办理中）
	@Override
	public boolean judgeHaveProcessingSocialOrFund(BaseSearchVO paramVo) {
		if (Common.isNotNull(paramVo.getEmpIdCard()) && Common.isNotNull(paramVo.getDeptNo())) {
			TDispatchInfoPre pre = baseMapper.selectOne(Wrappers.<TDispatchInfoPre>query().lambda()
					.in(TDispatchInfoPre::getProcessStatus, Arrays.asList("3", "5", "6"))
					.eq(TDispatchInfoPre::getIsRefuse, CommonConstants.ONE_STRING)
					.eq(TDispatchInfoPre::getIsLeave, CommonConstants.ONE_STRING)
					.eq(TDispatchInfoPre::getEmpIdcard, paramVo.getEmpIdCard())
					.eq(TDispatchInfoPre::getDeptNo, paramVo.getDeptNo())
					.eq(TDispatchInfoPre::getTypeSub, paramVo.getType())
					.last(CommonConstants.LAST_ONE_SQL));
			// 找到了才阻断，不允许离职确认
			return pre != null;
		} else {
			return false;
		}
	}

}
