/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.csp.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
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.constants.RegistConstants;
import com.yifu.cloud.plus.v1.csp.entity.EmployeeRegistration;
import com.yifu.cloud.plus.v1.csp.entity.EmployeeRegistrationLeave;
import com.yifu.cloud.plus.v1.csp.entity.EmployeeRegistrationLeaveInsurance;
import com.yifu.cloud.plus.v1.csp.entity.EmployeeRegistrationLeaveLog;
import com.yifu.cloud.plus.v1.csp.mapper.EmployeeRegistrationLeaveInsuranceMapper;
import com.yifu.cloud.plus.v1.csp.mapper.EmployeeRegistrationLeaveMapper;
import com.yifu.cloud.plus.v1.csp.mapper.EmployeeRegistrationMapper;
import com.yifu.cloud.plus.v1.csp.service.EmployeeRegistrationLeaveLogService;
import com.yifu.cloud.plus.v1.csp.service.EmployeeRegistrationLeaveService;
import com.yifu.cloud.plus.v1.csp.service.TOperationLogService;
import com.yifu.cloud.plus.v1.csp.vo.*;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainRegistListVo;
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.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.BaseSearchListVO;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.BaseSearchVO;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.BaseServiceParamListVO;
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.InsuranceDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SocialDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.util.LocalDateUtil;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.HolidayListVO;
import com.yifu.cloud.plus.v1.yifu.social.vo.TDispatchReduceListVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TDispatchReduceVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

/**
 * 自动化离职待办
 *
 * @author hgw
 * @date 2025-11-19 19:23:15
 */
@Log4j2
@Service
public class EmployeeRegistrationLeaveServiceImpl extends ServiceImpl<EmployeeRegistrationLeaveMapper, EmployeeRegistrationLeave> implements EmployeeRegistrationLeaveService {

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;
	@Autowired
	private SocialDaprUtils socialDaprUtils;
	@Autowired
	private InsuranceDaprUtil insuranceDaprUtil;
	@Autowired
	private EmployeeRegistrationMapper employeeRegistrationMapper;
	@Autowired
	private EmployeeRegistrationLeaveInsuranceMapper leaveInsuranceMapper;
	@Autowired
	private EmployeeRegistrationLeaveLogService leaveLogService;
	@Autowired
	private TOperationLogService logService;

	/**
	 * 自动化离职待办简单分页查询
	 *
	 * @param employeeRegistrationLeave 自动化离职待办
	 * @return
	 */
	@Override
	public IPage<EmployeeRegistrationLeaveTableVo> getEmployeeRegistrationLeaveTablePage(Page<EmployeeRegistrationLeaveTableVo> page, EmployeeRegistrationLeaveSearchVo employeeRegistrationLeave) {
		initSearchVo(employeeRegistrationLeave);
		return baseMapper.getEmployeeRegistrationLeaveTablePage(page, employeeRegistrationLeave);
	}

	@Override
	public List<EmployeeRegistrationLeaveTableVo> getEmployeeRegistrationLeaveTablePage2000(EmployeeRegistrationLeaveSearchVo employeeRegistrationLeave) {
		initSearchVo(employeeRegistrationLeave);
		return baseMapper.getEmployeeRegistrationLeaveTablePage2000(employeeRegistrationLeave);
	}

	@Override
	public long getRegistrationLeaveCount(EmployeeRegistrationLeaveSearchVo searchVo) {
		initSearchVo(searchVo);
		return baseMapper.getEmployeeRegistrationLeaveTableCount(searchVo);
	}

	@Override
	public IPage<EmployeeRegistrationLeaveTableVo> getEmployeeRegistrationLeaveConfirmTablePage(Page<EmployeeRegistrationLeaveTableVo> page, EmployeeRegistrationLeaveSearchVo employeeRegistrationLeave) {
		initSearchVo(employeeRegistrationLeave);
		return baseMapper.getEmployeeRegistrationLeaveConfirmTablePage(page, employeeRegistrationLeave);
	}

	/**
	 * @Description: 前端客服的权限
	 * @Author: hgw
	 * @Date: 2025/11/20 10:37
	 * @return: void
	 **/
	private void initSearchVo(EmployeeRegistrationLeaveSearchVo searchVo) {
		YifuUser user = SecurityUtils.getUser();
		boolean isSsc = this.haveRole(user);
		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);
				}
			}
		}
	}

	private boolean haveRole(YifuUser user) {
		List<Long> roleList = user.getClientRoleMap().get(ClientNameConstants.CLIENT_MVP);
		for (Long role : roleList) {
			if (role == CommonConstants.CS_ROLE_ID) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 自动化离职待办批量导出
	 *
	 * @param searchVo 自动化离职待办
	 * @return
	 */
	@Override
	public void exportTable(HttpServletResponse response, EmployeeRegistrationLeaveSearchVo searchVo) {
		String fileName = "自动化离职待处理批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<EmployeeRegistrationLeaveExportVo> list = new ArrayList<>();
		//获取要导出的列表
		if (Common.isNotNull(searchVo.getIds())) {
			searchVo.setIdList(Common.getList(searchVo.getIds()));
		}
		//权限赋值
		initSearchVo(searchVo);
		long count = baseMapper.getEmployeeRegistrationLeaveTableCount(searchVo);
		ServletOutputStream out = null;
		try {
			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 = EasyExcelFactory.write(out, EmployeeRegistrationLeaveExportVo.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.getEmployeeRegistrationLeaveTableList(searchVo);
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcelFactory.writerSheet("自动化离职待处理" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcelFactory.writerSheet("自动化离职待处理" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public void exportConfirmTable(HttpServletResponse response, EmployeeRegistrationLeaveSearchVo searchVo) {
		String fileName = "自动化离职确认批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<EmployeeRegistrationLeaveConfirmExportVo> list = new ArrayList<>();
		long count = baseMapper.getEmployeeRegistrationLeaveConfirmTableCount(searchVo);
		ServletOutputStream out = null;
		try {
			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 = EasyExcelFactory.write(out, EmployeeRegistrationLeaveConfirmExportVo.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.getEmployeeRegistrationLeaveConfirmTableList(searchVo);
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcelFactory.writerSheet("自动化离职确认" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcelFactory.writerSheet("自动化离职确认" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public void saveLeaveInfo(EmployeeRegistration registration) {

		EmployeeRegistrationLeave leave = new EmployeeRegistrationLeave();
		leave.setId(registration.getId());
		leave.setLeaveStatus(CommonConstants.ZERO_STRING);

		// 设置执行状态为“未执行”
		leave.setDoStatus(CommonConstants.ZERO_STRING);

		// 1社保2公积金3商险4合同5项目档案6人员档案
		StringBuilder doType = new StringBuilder();

		BaseSearchVO paramVo = new BaseSearchVO();
		paramVo.setEmpIdCard(registration.getEmpIdcard());
		paramVo.setDeptNo(registration.getDeptNo());
		// 设置社保减员状态
		String socialId = "";
		String socialStatusOld = "";
		String fundId = "";
		String fundStatusOld = "";
		BaseSearchVO returnVo;
		R<BaseSearchVO> returnR = socialDaprUtils.getSocialAndFundStatus(paramVo);
		if (null != returnR && Common.isNotNull(returnR.getData())) {
			returnVo = returnR.getData();
			if (Common.isNotNull(returnVo.getResultIdOne())) {
				socialId = returnVo.getResultIdOne();
				socialStatusOld = returnVo.getResultIdOneStatus();
			}
			if (Common.isNotNull(returnVo.getResultIdTwo())) {
				fundId = returnVo.getResultIdTwo();
				fundStatusOld = returnVo.getResultIdTwoStatus();
			}
		}
		if (Common.isNotNull(socialId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.ONE_STRING);
			leave.setDoStatusSocial(CommonConstants.ZERO_STRING);
			leave.setSocialDispatchIdOld(socialId);
			leave.setSocialStatusOld(socialStatusOld);
		} else {
			leave.setDoStatusSocial(CommonConstants.ONE_STRING);
		}

		// 设置公积金减员状态
		if (Common.isNotNull(fundId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.TWO_STRING);
			leave.setDoStatusFund(CommonConstants.ZERO_STRING);
			leave.setFundDispatchIdOld(fundId);
			leave.setFundStatusOld(fundStatusOld);
		} else {
			leave.setDoStatusFund(CommonConstants.ONE_STRING);
		}

		// 设置商险退保状态
		String insuranceId = "";
		String insuranceStatusOld = "";
		returnR = insuranceDaprUtil.getInsurancesStatus(paramVo);
		if (null != returnR && Common.isNotNull(returnR.getData())) {
			returnVo = returnR.getData();
			if (Common.isNotNull(returnVo.getResultIdOne())) {
				insuranceId = returnVo.getResultIdOne();
				insuranceStatusOld = returnVo.getResultIdOneStatus();
			}
		}
		if (Common.isNotNull(insuranceId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.THREE_STRING);
			leave.setDoStatusInsurance(CommonConstants.ZERO_STRING);
			leave.setInsuranceIdOld(insuranceId);
			leave.setInsuranceStatusOld(insuranceStatusOld);
			String[] insuranceArr = insuranceId.split(CommonConstants.COMMA_STRING);
			EmployeeRegistrationLeaveInsurance sub;
			// 保存前，先删除，防止错误数据，导致状态判断失败
			leaveInsuranceMapper.deleteLeaveInsurance(leave.getId());
			for (String subId : insuranceArr) {
				sub = new EmployeeRegistrationLeaveInsurance();
				sub.setLeaveId(leave.getId());
				sub.setInsuranceId(subId);
				sub.setDoStatusInsurance(CommonConstants.ZERO_STRING);
				leaveInsuranceMapper.insert(sub);
			}
		} else {
			leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
		}
		// 设置合同终止状态
		String contractId = "";
		String contractStatusOld = "";
		String empProjectId = "";
		String empProjectStatusOld = "";
		String empId = "";
		String empStatusOld = "";
		// 是否多项目0否1是
		String isMultipleDept = CommonConstants.ZERO_STRING;
		returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
		if (null != returnR && Common.isNotNull(returnR.getData())) {
			returnVo = returnR.getData();
			if (Common.isNotNull(returnVo.getResultIdOne())) {
				empId = returnVo.getResultIdOne();
				empStatusOld = returnVo.getResultIdOneStatus();
			}
			if (Common.isNotNull(returnVo.getResultIdTwo())) {
				empProjectId = returnVo.getResultIdTwo();
				empProjectStatusOld = returnVo.getResultIdTwoStatus();
			}
			if (Common.isNotNull(returnVo.getResultIdThree())) {
				contractId = returnVo.getResultIdThree();
				contractStatusOld = returnVo.getResultIdThreeStatus();
			}
			if (Common.isNotNull(returnVo.getResultIdFour())) {
				isMultipleDept = returnVo.getResultIdFour();
			}
		}
		if (Common.isNotNull(contractId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.FOUR_STRING);
			leave.setDoStatusContract(CommonConstants.ZERO_STRING);
			leave.setContractIdOld(contractId);
			leave.setContractStatusOld(contractStatusOld);
		} else {
			leave.setDoStatusContract(CommonConstants.ONE_STRING);
		}

		leave.setIsMultipleDept(isMultipleDept);
		if (Common.isNotNull(empProjectId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.FIVE_STRING);
			leave.setDoStatusProject(CommonConstants.ZERO_STRING);
			leave.setEmpProjectIdOld(empProjectId);
			leave.setEmpProjectStatusOld(empProjectStatusOld);
		} else {
			leave.setDoStatusProject(CommonConstants.ONE_STRING);
		}
		if (Common.isNotNull(empId)) {
			if (Common.isNotNull(doType) && doType.length() > CommonConstants.ZERO_INT) {
				doType.append(",");
			}
			doType.append(CommonConstants.SIX_STRING);
			leave.setDoStatusEmp(CommonConstants.ZERO_STRING);
			leave.setEmpIdOld(empId);
			leave.setEmpStatusOld(empStatusOld);
		} else {
			leave.setDoStatusEmp(CommonConstants.ONE_STRING);
		}

		leave.setLeaveReasonName(RegistConstants.BASE_REASON_TYPE_NAME);
		leave.setLeaveReasonId(RegistConstants.BASE_REASON_TYPE);


		// 设置需处理项（1社保2公积金3商险4合同5项目档案6人员档案）
		leave.setDoType(doType.toString());
		// 设置联动端口（固定值：人员离职）
		leave.setLinkPort(RegistConstants.BASE_LINK_PORT);
		this.saveOrUpdate(leave);
	}

	@Override
	public EmployeeRegistrationLeave initLeaveInfo(String id) {
		EmployeeRegistration registration = employeeRegistrationMapper.selectById(id);
		EmployeeRegistrationLeave leave = this.getById(id);
		if (registration == null || leave == null) {
			return leave;
		}
		//获取假日信息
		Map<String, Integer> holidayMap = getHolidayMap();
		// 停缴社保日期
		if (Common.isNotNull(leave.getSocialDispatchIdOld()) && Common.isEmpty(leave.getSocialReduceDate())) {
			leave.setSocialReduceDate(DateUtil.addMonth(CommonConstants.ONE_INT));
		}
		// 停缴公积金日期
		if (Common.isNotNull(leave.getFundDispatchIdOld()) && Common.isEmpty(leave.getFundReduceDate())) {
			leave.setFundReduceDate(DateUtil.addMonth(CommonConstants.ONE_INT));
		}

		// 获取下个工作日，且大于等于今天，如果大于15点20，换下个工作日
		if (Common.isNotNull(leave.getSocialDispatchIdOld()) && Common.isEmpty(leave.getSocialExpectedTime())) {
			leave.setSocialExpectedTime(calculateNextWorkDays(holidayMap));
		}
		// 获取下个工作日，且大于等于今天，如果大于15点20，换下个工作日
		if (Common.isNotNull(leave.getFundDispatchIdOld()) && Common.isEmpty(leave.getFundExpectedTime())) {
			leave.setFundExpectedTime(calculateNextWorkDays(holidayMap));
		}

		// 设置商险退保状态
		initInsurance(registration, leave, holidayMap);
		// 设置合同终止状态
		if (Common.isNotNull(leave.getContractIdOld()) && Common.isEmpty(leave.getContractExpectedTime())) {
			leave.setContractExpectedTime(calculateNextWorkDays(holidayMap));
		}
		return leave;
	}

	// 初始化商险
	private void initInsurance(EmployeeRegistration registration, EmployeeRegistrationLeave leave, Map<String, Integer> holidayMap) {
		if (Common.isNotNull(leave.getInsuranceIdOld()) && Common.isNotNull(registration.getJoinLeaveDate()) && Common.isEmpty(leave.getInsuranceExpectedTime())) {
			// 获取下个工作日，且大于等于今天，如果大于15点20，换下个工作日
			leave.setInsuranceExpectedTime(calculateNextWorkDaysByDate(dateToLocalDate(registration.getJoinLeaveDate()), holidayMap));
			leave.setInsuranceExpectedTimeNext(leave.getInsuranceExpectedTime().plusDays(CommonConstants.ONE_INT));
		}
	}

	@Override
	public BatchSureLeaveVo initBatchSureInfo() {
		BatchSureLeaveVo vo = new BatchSureLeaveVo();

		//获取假日信息
		//获取假日信息
		Map<String, Integer> holidayMap = getHolidayMap();
		// 商险是否处理：0否1是
		vo.setDoTypeInsurance(CommonConstants.ONE_STRING);
		// 停缴社保日期
		vo.setSocialReduceDate(DateUtil.addMonth(CommonConstants.ONE_INT));
		// 停缴公积金日期
		vo.setFundReduceDate(DateUtil.addMonth(CommonConstants.ONE_INT));
		vo.setLeaveReasonId(RegistConstants.BASE_REASON_TYPE);
		vo.setLeaveReasonName(RegistConstants.BASE_REASON_TYPE_NAME);
		// 获取下个工作日，且大于等于今天，如果大于15点20，换下个工作日
		vo.setSocialExpectedTimeAndFund(calculateNextWorkDays(holidayMap));
		// 设置合同终止
		vo.setContractExpectedTime(calculateNextWorkDays(holidayMap));
		return vo;
	}

	private LocalDate dateToLocalDate(Date joinLeaveDate) {
		return joinLeaveDate.toInstant()
				.atZone(ZoneId.systemDefault())
				.toLocalDate();
	}

	// 获取下一个工作日：先比较与今天谁大，用大的，如果非工作日，或大于15点20，取下个工作日，否则用大的
	private LocalDateTime calculateNextWorkDaysByDate(LocalDate joinLeaveDate, Map<String, Integer> holidayMap) {
		// 获取下一个工作日：先比较与今天谁大，用大的，如果非工作日，或大于15点20，取下个工作日，否则用大的
		// 今天
		LocalDate today = LocalDate.now();
		LocalDateTime todayTime = LocalDateTime.now();
		// 创建今天的15点20时间
		LocalDateTime targetTime = LocalDateTime.now().withHour(15).withMinute(20).withSecond(0).withNano(0);
		// 判断是否大于15点20，大于则取明天
		if (todayTime.isAfter(targetTime)) {
			today = today.plusDays(1);
		}
		if (joinLeaveDate.isBefore(today)) {
			// 如果B小于今天，则B为今天
			joinLeaveDate = today;
		}
		// 如果今天是工作日，则为今天
		if (this.isWorkday(joinLeaveDate, holidayMap)) {
			return joinLeaveDate.atTime(15, 20, 0);
		} else {
			// 今天非工作日，顺延到工作日
			return getNextWorkday(joinLeaveDate, holidayMap).atTime(15, 20, 0);
		}
	}

	private LocalDateTime calculateNextWorkDays(Map<String, Integer> holidayMap) {
		// 获取下一个工作日：先比较与今天谁大，用大的，如果非工作日，或大于15点20，取下个工作日，否则用大的
		// 今天
		LocalDate today = LocalDate.now();
		LocalDateTime todayTime = LocalDateTime.now();
		// 创建今天的15点20时间
		LocalDateTime targetTime = LocalDateTime.now().withHour(15).withMinute(20).withSecond(0).withNano(0);
		// 判断是否大于15点20，大于则取明天
		if (todayTime.isAfter(targetTime)) {
			today = today.plusDays(1);
		}
		// 如果今天是工作日，则为今天
		if (this.isWorkday(today, holidayMap)) {
			return today.atTime(15, 20, 0);
		} else {
			// 今天非工作日，顺延到工作日
			return getNextWorkday(today, holidayMap).atTime(15, 20, 0);
		}
	}

	// 获取下一个工作日
	public LocalDate getNextWorkday(LocalDate date, Map<String, Integer> holidayMap) {
		LocalDate result = date.plusDays(CommonConstants.ONE_INT);
		int i=100;
		while (i>0 && !this.isWorkday(result, holidayMap)) {
			result = result.plusDays(CommonConstants.ONE_INT);
			i--;
		}
		return result;
	}

	/**
	 * 判断是否为工作日,true是，false否
	 */
	public boolean isWorkday(LocalDate date, Map<String, Integer> holidayMap) {
		String days = LocalDateUtil.getDateSrt(date, LocalDateUtil.NORM_DATE_PATTERN);
		return holidayMap.get(days) == null;
	}


	// 手动关闭：
	// 需处理项：1社保2公积金3商险4合同 6人员档案
	// doTypeWu 3商险6人员档案
	// doTypeYi 1社保2公积金3商险4合同
	@Override
	public R<String> doClose(String id, String remark, String doTypeWu, String doTypeYi) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null) {
			return R.failed("请登录");
		}
		EmployeeRegistrationLeave leave = this.getById(id);
		EmployeeRegistration registration = employeeRegistrationMapper.selectById(id);
		if (Common.isEmpty(doTypeWu) && Common.isEmpty(doTypeYi)) {
			return R.failed("请选择处理项");
		}
		if (Common.isNotNull(remark) && remark.length()>200) {
			return R.failed("无需处理原因超过200字！");
		}
		if (leave != null) {
			BaseSearchVO returnVo;
			BaseSearchVO paramVo = new BaseSearchVO();
			paramVo.setEmpIdCard(registration.getEmpIdcard());
			paramVo.setDeptNo(registration.getDeptNo());

			StringBuilder errorInfo = new StringBuilder();
			StringBuilder logInfo = new StringBuilder("手动关闭：");
			if (Common.isNotNull(doTypeWu)) {
				logInfo.append("无需处理标记：");
				if (doTypeWu.contains(CommonConstants.THREE_STRING)) {
					logInfo.append("商险;");
					if (CommonConstants.TWO_STRING.equals(leave.getDoStatusInsurance())
							|| CommonConstants.THREE_STRING.equals(leave.getDoStatusInsurance())
							|| CommonConstants.NINE_STRING.equals(leave.getDoStatusInsurance())) {
						leave.setInsuranceId(leave.getInsuranceIdOld());
						leave.setCloseRemarkInsurance(remark);
						leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
					} else {
						errorInfo.append("商险状态已处理，不可手动关闭！");
					}
				}
				if (doTypeWu.contains(CommonConstants.SIX_STRING)) {
					logInfo.append("人员档案;");
					if (CommonConstants.TWO_STRING.equals(leave.getDoStatusEmp())
							|| CommonConstants.NINE_STRING.equals(leave.getDoStatusEmp())) {
						leave.setEmpId(leave.getEmpIdOld());
						leave.setCloseRemarkEmp(remark);
						leave.setDoStatusEmp(CommonConstants.ONE_STRING);

						String isMultipleDept = CommonConstants.ZERO_STRING;
						R<BaseSearchVO> returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
						if (null != returnR && Common.isNotNull(returnR.getData())) {
							returnVo = returnR.getData();
							if (Common.isNotNull(returnVo.getResultIdFour())) {
								isMultipleDept = returnVo.getResultIdFour();
							}
						}
						if (CommonConstants.ZERO_STRING.equals(isMultipleDept)) {
							errorInfo.append("人员当下非多项目，不可无需处理！");
						}
					} else {
						errorInfo.append("人员状态已处理，不可手动关闭！");
					}

				}
			}
			if (Common.isNotNull(doTypeYi)) {
				String closeRemark = "已在其他入口处理";
				logInfo.append("已在其他入口处理：");
				String socialDispatchId = "";
				String fundDispatchId = "";
				R<BaseSearchVO> returnR = socialDaprUtils.getSocialAndFundStatusByClose(paramVo);
				if (null != returnR && Common.isNotNull(returnR.getData())) {
					returnVo = returnR.getData();
					if (Common.isNotNull(returnVo.getResultIdOne())) {
						socialDispatchId = returnVo.getResultIdOne();
					}
					if (Common.isNotNull(returnVo.getResultIdTwo())) {
						fundDispatchId = returnVo.getResultIdTwo();
					}
				}

				if (doTypeYi.contains(CommonConstants.ONE_STRING)) {
					logInfo.append("社保;");
					if (!CommonConstants.ONE_STRING.equals(leave.getDoStatusSocial())
							&& !CommonConstants.EIGHT_STRING.equals(leave.getDoStatusSocial())) {
						if (Common.isEmpty(socialDispatchId)) {
							errorInfo.append("社保未派减完结！");
						} else {
							leave.setSocialId(socialDispatchId);
							leave.setDoStatusSocial(CommonConstants.ONE_STRING);
							leave.setCloseRemarkSocial(closeRemark);
						}
					} else {
						errorInfo.append("社保状态已完结，不可处理！");
					}
				}
				if (doTypeYi.contains(CommonConstants.TWO_STRING)) {
					logInfo.append("公积金;");
					if (!CommonConstants.ONE_STRING.equals(leave.getDoStatusFund())
							&& !CommonConstants.EIGHT_STRING.equals(leave.getDoStatusFund())) {
						if (Common.isEmpty(fundDispatchId)) {
							errorInfo.append("公积金未派减完结！");
						} else {
							leave.setFundId(fundDispatchId);
							leave.setDoStatusFund(CommonConstants.ONE_STRING);
							leave.setCloseRemarkFund(closeRemark);
						}
					} else {
						errorInfo.append("公积金状态已完结，不可处理！");
					}
				}
				if (doTypeYi.contains(CommonConstants.THREE_STRING)) {
					logInfo.append("商险;");
					String insuranceId = "";
					returnR = insuranceDaprUtil.getInsurancesStatusByClose(paramVo);
					if (null != returnR && Common.isNotNull(returnR.getData())) {
						returnVo = returnR.getData();
						if (Common.isNotNull(returnVo.getResultIdOne())) {
							insuranceId = returnVo.getResultIdOne();
						}
					}
					if (!CommonConstants.ONE_STRING.equals(leave.getDoStatusInsurance())
							&& !CommonConstants.EIGHT_STRING.equals(leave.getDoStatusInsurance())) {
						// 这个反着查的，有未减完的，表示不可以关闭它，只能忽略它
						if (Common.isNotNull(insuranceId)) {
							errorInfo.append("商险未派减完结！");
						} else {
							leave.setInsuranceId(leave.getInsuranceIdOld());
							leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
							leave.setCloseRemarkInsurance(closeRemark);
						}
					} else {
						errorInfo.append("商险状态已完结，不可处理！");
					}
				}
				if (doTypeYi.contains(CommonConstants.FOUR_STRING)) {
					logInfo.append("合同;");
					String contractId = "";
					String contractIdEnd = "";
					returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
					if (null != returnR && Common.isNotNull(returnR.getData())) {
						returnVo = returnR.getData();
						if (Common.isNotNull(returnVo.getResultIdThree())) {
							contractId = returnVo.getResultIdThree();
						}
						if (Common.isNotNull(returnVo.getResultIdFourStatus())) {
							contractIdEnd = returnVo.getResultIdFourStatus();
						}
					}
					if (!CommonConstants.ONE_STRING.equals(leave.getDoStatusContract())
							&& !CommonConstants.EIGHT_STRING.equals(leave.getDoStatusContract())) {
						if (Common.isNotNull(contractId)) {
							errorInfo.append("存在可用的合同！");
						} else {
							if (Common.isNotNull(contractIdEnd)) {
								leave.setContractId(contractIdEnd);
								leave.setDoStatusContract(CommonConstants.ONE_STRING);
								leave.setCloseRemarkContract(closeRemark);
							} else {
								// errorInfo.append("未找到终止的合同！")
								// 社保派减，同步减合同，是没有终止的合同的，而是在合同本身改状态
								leave.setContractId(leave.getContractIdOld());
								leave.setDoStatusContract(CommonConstants.ONE_STRING);
								leave.setCloseRemarkContract(closeRemark);
							}
						}
					} else {
						errorInfo.append("合同状态已完结，不可处理！");
					}
				}
			}

			if (errorInfo.length() > 0) {
				return R.failed(errorInfo.toString());
			} else {
				this.judgeStatus(leave);
				this.updateById(leave);
				EmployeeRegistrationLeaveLog leaveLog = new EmployeeRegistrationLeaveLog();
				leaveLog.setLeaveId(leave.getId());
				leaveLog.setCreateName(user.getNickname());
				leaveLog.setCreateTime(LocalDateTime.now());
				leaveLog.setContent(logInfo.toString());
				leaveLogService.save(leaveLog);
				return R.ok();
			}
		} else {
			return R.failed("未找到该数据");
		}

	}

	// 判断状态
	private void judgeStatus(EmployeeRegistrationLeave leave) {
		// 收集所有分项状态
		String[] statusArray = {
				leave.getDoStatusContract(),
				leave.getDoStatusSocial(),
				leave.getDoStatusFund(),
				leave.getDoStatusInsurance(),
				leave.getDoStatusProject(),
				leave.getDoStatusEmp()
		};

		// 统计状态
		int total = 0;
		int initialCount = 0;
		int successCount = 0;
		int failedCount = 0;
		int noNeedCount = 0;

		for (String status : statusArray) {
			if (status == null) continue;

			total++;
			if ("1".equals(status)) {
				noNeedCount++;
			} else if ("0".equals(status) ||"2".equals(status) || status.isEmpty()) {
				initialCount++;
			} else if (status.endsWith("8")) {
				successCount++;
			} else if (status.endsWith("3") || status.endsWith("9") || status.endsWith("10")) {
				failedCount++;
			}
		}

		// 有效状态数量（排除无需处理的）
		int validCount = total - noNeedCount;

		String doStatus;
		if (validCount == 0) {
			doStatus = "6"; // 全部无需处理
		} else if (initialCount == validCount) {
			doStatus = "1"; // 未执行
		} else if (successCount == validCount) {
			doStatus = "5"; // 全部成功
		} else if (failedCount == validCount) {
			doStatus = "4"; // 全部失败
		} else if (successCount > 0 && failedCount > 0) {
			doStatus = "3"; // 部分成功
		} else {
			doStatus = "2"; // 执行中
		}

		leave.setDoStatus(doStatus);
		setLeaveStatusByDoStatus(leave);
	}

	/**
	 * 根据执行结果更新离职处理状态
	 * 规则：
	 * - 执行结果为"执行中(2)、部分成功(3)、全部失败(4)"，离职处理状态为"处理中(2)"
	 * - 执行结果为"全部成功(5)"，离职处理状态为"已处理(3)"
	 * - 其他情况保持原有离职处理状态不变（避免覆盖待确认、待处理状态）
	 */
	private void setLeaveStatusByDoStatus(EmployeeRegistrationLeave leave) {
		switch (leave.getDoStatus()) {
			case "2": // 执行中
			case "3": // 部分成功
			case "4": // 全部失败
				leave.setLeaveStatus("2"); // 处理中
				break;
			case "5": // 全部成功
				leave.setLeaveStatus("3"); // 已处理
				break;
			case "6": // 无需处理
				leave.setLeaveStatus("3"); // 已处理
				break;
			// case "1": // 未执行 - 保持原有状态（可能是待处理）
			// case "6": // 无需处理 - 保持原有状态
			// default:   // 其他情况保持原有状态不变
		}
	}

	@Override
	public R<String> doSure(EmployeeRegistrationLeave leave) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null) {
			return R.failed("请登录");
		}
		if (leave != null && Common.isNotNull(leave.getId())) {
			EmployeeRegistrationLeave leaveOld = this.getById(leave.getId());
			EmployeeRegistration registrationOld = employeeRegistrationMapper.selectById(leave.getId());
			if (leaveOld != null && Common.isNotNull(leaveOld.getId()) && registrationOld != null
					&& Common.isNotNull(registrationOld.getEmpIdcard()) && Common.isNotNull(registrationOld.getDeptNo())) {
				if (CommonConstants.ZERO_STRING.equals(leaveOld.getLeaveStatus())) {
					if (Common.isNotNull(leave.getDoType())) {
						if (leave.getDoType().contains(CommonConstants.THREE_STRING)) {
							leave.setDoStatusInsurance(CommonConstants.TWO_STRING);
						} else {
							leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
						}
						// 停缴社保日期
						if (Common.isNotNull(leave.getSocialDispatchIdOld())) {
							leave.setDoStatusSocial(CommonConstants.TWO_STRING);
						}
						// 停缴公积金日期
						if (Common.isNotNull(leave.getFundDispatchIdOld())) {
							leave.setDoStatusFund(CommonConstants.TWO_STRING);
						}
						// 设置合同终止状态
						if (Common.isNotNull(leave.getContractIdOld())) {
							leave.setDoStatusContract(CommonConstants.TWO_STRING);
						}
						if (Common.isNotNull(leave.getEmpProjectIdOld())) {
							leave.setDoStatusProject(CommonConstants.TWO_STRING);
						}
						if (Common.isNotNull(leave.getEmpIdOld())) {
							leave.setDoStatusEmp(CommonConstants.TWO_STRING);
						}
					}
					this.judgeStatus(leave);
					leave.setLeaveStatus(CommonConstants.ONE_STRING);
					leave.setConfirmUser(user.getNickname());
					leave.setConfirmTime(LocalDateTime.now());

					// 已确认离职
					// 判断是否有处理中的自动化数据，涉及到4个自动化：社保、公积金、商险、合同
					R<String> haveProcessingR = judgeHaveProcessingData(registrationOld.getEmpIdcard(), registrationOld.getDeptNo());
					if (haveProcessingR != null && Common.isNotNull(haveProcessingR.getCode()) && haveProcessingR.getCode() != CommonConstants.SUCCESS) {
						return haveProcessingR;
					}
					// 如果没有处理中的数据，则将待办状态改为"已确认离职"
					doUpdateAutoInfo(registrationOld.getEmpIdcard(), registrationOld.getDeptNo(), user.getId(), user.getNickname());

					this.updateById(leave);
					
					// 离职待办确认后，更新为商险续签待办为已离职
					BaseSearchVO paramVo = new BaseSearchVO();
					paramVo.setEmpIdCard(registrationOld.getEmpIdcard());
					paramVo.setDeptNo(registrationOld.getDeptNo());
					insuranceDaprUtil.updateInsurancePreRenewToIsLeave(paramVo);
					
					//不勾选商险后 离职确认后，对该人员在该项目下的已投保未过期且有效的商险数据进行打标“可替换”
					if (Common.isNotNull(leave.getDoType())) {
						if (!leave.getDoType().contains(CommonConstants.THREE_STRING)) {
							updateInsuranceReplaceTagBySingle(registrationOld.getEmpIdcard(), registrationOld.getDeptNo(), user.getNickname(),user.getId());
						}
					}
					return R.ok();
				} else {
					return R.failed("状态不是待确认");
				}
			} else {
				return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
			}
		} else {
			return R.failed("请传参ID");
		}
	}

	// 离职确认时，若作业自动化入职处还有该人员该项目处理中或未处理的待办数据时，系统进行判断后分别进行处理：

	//针对处理中的待办任务（商险：3待投保、4投保中、7待缴费；社保/公积金：3待审核、5待办理、6办理中；合同：2线下签待审核、6签署中），
	// 离职确认时系统会提示：存在办理中的数据：***、***，请联系处理人驳回或处理完结后，再进行确认；
	// 聊天记录在jld企微上，2026-03-26，搜索 “阻断”，有各种状态的截图
	private R<String> judgeHaveProcessingData(String empIdCard, String deptNo) {
		BaseSearchVO paramVo;
		if (Common.isNotNull(empIdCard) && Common.isNotNull(deptNo)) {
			paramVo = new BaseSearchVO();
			paramVo.setEmpIdCard(empIdCard);
			paramVo.setDeptNo(deptNo);
		} else {
			return R.failed("请传入身份证和项目编码");
		}
		// 判断是否有处理中的数据，true-有，false-无
		boolean haveData = false;
		String msgItem = "";
		// 合同
		R<Boolean> haveDataR = archivesDaprUtil.judgeHaveProcessingContracnt(paramVo);
		if (haveDataR == null || Common.isEmpty(haveDataR.getData()) || (Common.isNotNull(haveDataR.getCode()) && haveDataR.getCode() != CommonConstants.SUCCESS)) {
			return R.failed("档案服务未返回合同相关信息，请稍后再操作！");
		} else if (Common.isNotNull(haveDataR.getData()) && Boolean.TRUE.equals(haveDataR.getData())) {
			haveData = true;
			msgItem += "合同、";
		}
		// 商险
		haveDataR = insuranceDaprUtil.judgeHaveProcessingInsurance(paramVo);
		if (haveDataR == null || Common.isEmpty(haveDataR.getData()) || (Common.isNotNull(haveDataR.getCode()) && haveDataR.getCode() != CommonConstants.SUCCESS)) {
			return R.failed("商险服务未返回信息，请稍后再操作！");
		} else if (Common.isNotNull(haveDataR.getData()) && Boolean.TRUE.equals(haveDataR.getData())) {
			haveData = true;
			msgItem += "商险、";
		}
		// 0社保1公积金
		paramVo.setType(CommonConstants.ZERO_STRING);
		// 社保
		haveDataR = socialDaprUtils.judgeHaveProcessingSocialOrFund(paramVo);
		if (haveDataR == null || Common.isEmpty(haveDataR.getData()) || (Common.isNotNull(haveDataR.getCode()) && haveDataR.getCode() != CommonConstants.SUCCESS)) {
			return R.failed("社保服务未返回社保信息，请稍后再操作！");
		} else if (Common.isNotNull(haveDataR.getData()) && Boolean.TRUE.equals(haveDataR.getData())) {
			haveData = true;
			msgItem += "社保、";
		}
		paramVo = new BaseSearchVO();
		paramVo.setEmpIdCard(empIdCard);
		paramVo.setDeptNo(deptNo);
		// 0社保1公积金
		paramVo.setType(CommonConstants.ONE_STRING);
		// 公积金
		haveDataR = socialDaprUtils.judgeHaveProcessingSocialOrFund(paramVo);
		if (haveDataR == null || Common.isEmpty(haveDataR.getData()) || (Common.isNotNull(haveDataR.getCode()) && haveDataR.getCode() != CommonConstants.SUCCESS)) {
			return R.failed("公积金服务未返回公积金信息，请稍后再操作！");
		} else if (Common.isNotNull(haveDataR.getData()) && Boolean.TRUE.equals(haveDataR.getData())) {
			haveData = true;
			msgItem += "公积金、";
		}

		if (haveData) {
			msgItem = msgItem.substring(0, msgItem.length() - 1);
			String errMsg = "存在办理中的数据：" + msgItem + "，请联系处理人驳回或处理完结后，再进行确认";
			return R.failed(errMsg);
		} else {
			return R.ok();
		}
	}

	// 离职确认时，若作业自动化入职处还有该人员该项目处理中或未处理的待办数据时，系统进行判断后分别进行处理：

	//针对未处理的待办任务
	//商险：待确认、发起失败、待派单，投保退回；
	//社保/公积金：待确认、待派单、发起失败、审核不通过、办理失败、部分办理失败；
	//合同：待确认、待派单、发起失败、撤回（自动/手动）、审核不通过、签署失败——待归档时合同已经审核通过，因此不会处理入职处的待办，在具体离职事项处理的时候，才会处理。
	//档案：待建档；
	//离职确认时，系统会提示：会同步将未处理的以上状态的作业自动化的待办任务删除，删除后，作业自动化入职确认信息处该服务事项从上方的事项勾选，到具体事项详情处全部置灰，禁止修改；
	//在入职确认信息处，操作日志中，增加人员离职确认联动删除“社保、公积金、商险、合同”待办任务；同时在入职确认信息处，将“编辑”按钮置灰，后续再次登记入职后，入职确认信息可编辑操作再放开
	//入职登记增加状态“已确认离职”，流程进展明细处增加操作人、操作时间、离职确认动作；
	private R<String> doUpdateAutoInfo(String empIdCard, String deptNo, String userId, String userName) {
		BaseSearchVO paramVo;
		if (Common.isNotNull(empIdCard) && Common.isNotNull(deptNo)&& Common.isNotNull(userId)&& Common.isNotNull(userName)) {
			paramVo = new BaseSearchVO();
			paramVo.setEmpIdCard(empIdCard);
			paramVo.setDeptNo(deptNo);
			paramVo.setResultIdOne(userId);
			paramVo.setResultIdOneStatus(userName);
		} else {
			return R.failed("请传入身份证和项目编码");
		}
		// 很多
		R<Boolean> haveDataR = archivesDaprUtil.leaveToUpdateInfoByCardAndDeptNo(paramVo);
		if (haveDataR == null || Common.isEmpty(haveDataR.getData()) || (Common.isNotNull(haveDataR.getCode()) && haveDataR.getCode() != CommonConstants.SUCCESS)) {
			return R.failed("档案服务未返回合同相关信息，请稍后再操作！");
		}
		// 更新日志
		EmployeeRegistrationUpdateVo receiveVo = new EmployeeRegistrationUpdateVo();
		receiveVo.setEmployeeName(userName);
		receiveVo.setDeptNo(deptNo);
		receiveVo.setEmpIdcard(empIdCard);
		receiveVo.setReason("");
		receiveVo.setEmployeeId(userId);
		this.leaveToUpdateRegistByPreInfo(receiveVo);
		return R.ok();
	}

	// 离职确认后更新日志
	private void leaveToUpdateRegistByPreInfo(EmployeeRegistrationUpdateVo updateVo) {
		List<EmployeeRegistration> registrationList = employeeRegistrationMapper.selectList(Wrappers.<EmployeeRegistration>query().lambda()
				.eq(EmployeeRegistration::getDeptNo, updateVo.getDeptNo())
				.eq(EmployeeRegistration::getEmpIdcard, updateVo.getEmpIdcard())
				.in(EmployeeRegistration::getProcessStatus, Arrays.asList("0","1","2")));
		if (Common.isNotNull(registrationList)) {
			for (EmployeeRegistration registration : registrationList) {
				registration.setProcessStatus(CommonConstants.FIVE_STRING);
				employeeRegistrationMapper.updateById(registration);
				//新增拒绝入职操作记录
				logService.saveInnerLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.IS_LEAVE, LocalDateTime.now(),
						updateVo.getEmployeeName(), updateVo.getReason(), updateVo.getEmployeeId());
			}
		}
	}

	@Override
	public R<List<ErrorMessage>> doSureBatch(BatchSureLeaveVo vo) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null) {
			return R.failed("请登录");
		}
		List<String> ids = vo.getIds();
		if (Common.isEmpty(ids)) {
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		//获取假日信息
		Map<String, Integer> holidayMap = getHolidayMap();
		if (holidayMap == null) {
			return R.failed("未获取到假日信息，请检查社保服务！");
		}
		// 先查再更新
		List<EmployeeRegistrationLeave> alertList = baseMapper.selectLeaveListBySure(ids);
		List<EmployeeRegistration> registrationList = employeeRegistrationMapper.selectRegistrationListBySure(ids);
		if (alertList != null && !alertList.isEmpty() && registrationList != null && !registrationList.isEmpty()) {
			List<EmployeeRegistrationLeave> successList = new ArrayList<>();
			Map<String, EmployeeRegistrationLeave> alertMap = new HashMap<>();
			Map<String, EmployeeRegistration> registrationMap = new HashMap<>();
			for (EmployeeRegistrationLeave alert : alertList) {
				alertMap.put(alert.getId(), alert);
			}
			for (EmployeeRegistration registration : registrationList) {
				registrationMap.put(registration.getId(), registration);
			}
			EmployeeRegistrationLeave leave;
			EmployeeRegistration registration;
			int successNum = 0;

			// 离职待办确认后，更新为商险续签待办为已离职
			List<BaseSearchVO> paramVoList = new ArrayList<>();
			BaseSearchVO paramVo;

			R<String> haveProcessingR;
			String userId = user.getId();
			String userName = user.getNickname();
			List<ErrorMessage> errorMessageList = new ArrayList<>();
			int i=0;
			for (String id : ids) {
				i++;
				leave = alertMap.get(id);
				registration = registrationMap.get(id);
				if (registration != null && leave != null && CommonConstants.ZERO_STRING.equals(leave.getLeaveStatus())) {

					// 新逻辑，处理中的不可以离职确认
					haveProcessingR = judgeHaveProcessingData(registration.getEmpIdcard(), registration.getDeptNo());
					if (haveProcessingR != null && Common.isNotNull(haveProcessingR.getCode()) && haveProcessingR.getCode() != CommonConstants.SUCCESS) {
						errorMessageList.add(new ErrorMessage(i,haveProcessingR.getMsg(), registration));
						continue;
					}
					// 如果没有处理中的数据，则将待办状态改为"已确认离职"
					doUpdateAutoInfo(registration.getEmpIdcard(), registration.getDeptNo(), userId, userName);

					// 初始化信息
					if (Common.isNotNull(leave.getDoType())) {
						leave.setLeaveReasonId(vo.getLeaveReasonId());
						leave.setLeaveReasonName(vo.getLeaveReasonName());
						if (leave.getDoType().contains(CommonConstants.THREE_STRING)) {
							// 要处理商险初始值
							if (Common.isNotNull(vo.getDoTypeInsurance()) && CommonConstants.ONE_STRING.equals(vo.getDoTypeInsurance())) {
								// 初始化商险
								initInsurance(registration, leave, holidayMap);
								leave.setDoStatusInsurance(CommonConstants.TWO_STRING);
							} else {
								this.removeInsuranceToDoType(leave);
								leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
							}
						}
						// 停缴社保日期
						if (Common.isNotNull(leave.getSocialDispatchIdOld())) {
							leave.setSocialReduceDate(vo.getSocialReduceDate());
							leave.setSocialTrustRemark(vo.getSocialTrustRemarkAndFund());
							leave.setSocialExpectedTime(vo.getSocialExpectedTimeAndFund());
							leave.setDoStatusSocial(CommonConstants.TWO_STRING);
						}
						// 停缴公积金日期
						if (Common.isNotNull(leave.getFundDispatchIdOld())) {
							leave.setFundReduceDate(vo.getFundReduceDate());
							leave.setFundTrustRemark(vo.getSocialTrustRemarkAndFund());
							leave.setFundExpectedTime(vo.getSocialExpectedTimeAndFund());
							leave.setDoStatusFund(CommonConstants.TWO_STRING);
						}
						// 设置合同终止状态
						if (Common.isNotNull(leave.getContractIdOld())) {
							leave.setContractExpectedTime(vo.getContractExpectedTime());
							leave.setDoStatusContract(CommonConstants.TWO_STRING);
						}
						if (Common.isNotNull(leave.getEmpProjectIdOld())) {
							leave.setDoStatusProject(CommonConstants.TWO_STRING);
						}
						if (Common.isNotNull(leave.getEmpIdOld())) {
							leave.setDoStatusEmp(CommonConstants.TWO_STRING);
						}
					}
					paramVo = new BaseSearchVO();
					paramVo.setEmpIdCard(registration.getEmpIdcard());
					paramVo.setDeptNo(registration.getDeptNo());
					paramVoList.add(paramVo);
					this.judgeStatus(leave);
					leave.setLeaveStatus(CommonConstants.ONE_STRING);
					leave.setConfirmUser(user.getNickname());
					leave.setConfirmTime(LocalDateTime.now());
					successList.add(leave);
					successNum++;
				}
			}
			if (successNum == CommonConstants.ZERO_INT) {
				if (errorMessageList.isEmpty()) {
					return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
				} else {
					return R.failed(errorMessageList);
				}
			} else {
				this.updateBatchById(successList);
				// 离职待办确认后，更新为商险续签待办为已离职
				if (!paramVoList.isEmpty()) {
					BaseSearchListVO baseSearchListVO = new BaseSearchListVO();
					baseSearchListVO.setListParam(paramVoList);
					insuranceDaprUtil.updateInsurancePreRenewToIsLeaveList(baseSearchListVO);
								
					//不勾选商险后 离职确认后，对该人员在该项目下的已投保未过期且有效的商险数据进行打标"可替换"
					if (Common.isNotNull(vo.getDoTypeInsurance()) && CommonConstants.ZERO_STRING.equals(vo.getDoTypeInsurance())) {
						updateInsuranceReplaceTagByBatch(paramVoList, user.getNickname(),user.getId());
					}
				}
				if (errorMessageList.isEmpty()) {
					return R.ok();
				} else {
					return R.failed(errorMessageList);
				}
			}
		} else {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
	}

	private Map<String, Integer> getHolidayMap() {
		R<HolidayListVO> holidayListR = socialDaprUtils.getOneMonthDay();
		Map<String, Integer> holidayMap = null;
		if (null != holidayListR && Common.isNotNull(holidayListR.getData()) && Common.isNotNull(holidayListR.getData().getWorkDayMap())) {
			holidayMap = holidayListR.getData().getHolidayMap();
		}
		return holidayMap;
	}

	/**
	 * @Description: 单个离职确认后更新商险替换标签为“可替换”
	 * @Author: fxj
	 * @Date: 2026-03-19
	 * @param empIdcard: 身份证号
	 * @param deptNo: 项目编码
	 * @param operator: 操作人员
	 * @return: void
	 **/
	private void updateInsuranceReplaceTagBySingle(String empIdcard, String deptNo, String operator,String operatorId) {
		List<BaseSearchVO> paramVoList = new ArrayList<>();
		BaseSearchVO paramVo = new BaseSearchVO();
		paramVo.setEmpIdCard(empIdcard);
		paramVo.setDeptNo(deptNo);
		paramVoList.add(paramVo);
		updateInsuranceReplaceTagByBatch(paramVoList, operator,operatorId);
	}

	/**
	 * @Description: 批量离职确认后更新商险替换标签为“可替换”（调用商险服务接口）
	 * @Author: fxj
	 * @Date: 2026-03-19
	 * @param paramVoList: 查询参数列表（身份证 + 项目编码）
	 * @param operator: 操作人员
	 * @return: void
	 **/
	private void updateInsuranceReplaceTagByBatch(List<BaseSearchVO> paramVoList, String operator,String operatorId) {
		if (Common.isEmpty(paramVoList)) {
			log.warn("批量更新商险替换标签失败，参数列表为空");
			return;
		}
		
		try {
			// 调用商险服务批量更新替换标签和说明
			insuranceDaprUtil.batchUpdateInsuranceReplaceTagByParamList(paramVoList, operator, operatorId, "离职确认操作");
		} catch (Exception e) {
			log.warn("批量更新商险替换标签异常，参数列表大小：{}", paramVoList.size(), e);
		}
	}

	// 去除浮动的商险
	private void removeInsuranceToDoType(EmployeeRegistrationLeave alert) {
		if (alert.getDoType().contains(",3")) {
			alert.setDoType(alert.getDoType().replace(",3", ""));
		} else if (alert.getDoType().contains("3,")) {
			alert.setDoType(alert.getDoType().replace("3,", ""));
		} else if (CommonConstants.THREE_STRING.equals(alert.getDoType())) {
			alert.setDoType("");
		}
	}


	// @param isExit: 1仅发起日期为今日及之前的事项 0立即发起（全量）
	//	 * @param doType: 需处理项：1社保2公积金3商险4合同5项目档案6人员档案
	@Override
	public void autoDoLeave() {
		List<EmployeeRegistrationLeave> leaveList = baseMapper.selectLeaveListByDispatch(null);
		List<EmployeeRegistrationLeave> saveLeaveList = new ArrayList<>();
		String customerUsernameNew;

		YifuUser user;
		String userName = "自动化自动-";
		Set<String> dbAuthsSet = new HashSet<>();
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		for (int i=0; i<leaveList.size(); i++) {
			saveLeaveList.add(leaveList.get(i));
			customerUsernameNew = leaveList.get(i).getCustomerUsernameNew();
			if (i == leaveList.size()-1 || Common.isEmpty(customerUsernameNew)
					|| !customerUsernameNew.equals(leaveList.get(i+1).getCustomerUsernameNew())) {
				user = getNewYifuUser(authorities, userName + customerUsernameNew);
				batchDoLeaveCore(saveLeaveList, CommonConstants.ONE_STRING, null, user);
				saveLeaveList = new ArrayList<>();
			}
		}
	}

	// @param isExit: 1仅发起日期为今日及之前的事项 0立即发起（全量）
	//	 * @param doType: 需处理项：1社保2公积金3商险4合同5项目档案6人员档案
	@Override
	public R<List<EmployeeRegistrationLeave>> batchDoLeave(List<String> idList, String isExit, String doType) {
		List<EmployeeRegistrationLeave> leaveList = baseMapper.selectLeaveListByDispatch(idList);
		YifuUser user = SecurityUtils.getUser();
		String userName = "自动化手动-";
		Set<String> dbAuthsSet = new HashSet<>();
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		user = getNewYifuUser(authorities, userName + user.getNickname());
		return batchDoLeaveCore(leaveList, isExit, doType, user);
	}

	private YifuUser getNewYifuUser(Collection<? extends GrantedAuthority> authorities, String userName) {

		return new YifuUser("1", 1L, "", userName,
				userName, "0", SecurityConstants.BCRYPT + "123456",
				"12345678911", true, true, true,
				true,
				"1", authorities, "1",
				null, null,
				null, null);
	}

	// @param isExit: 1仅发起日期为今日及之前的事项 0立即发起（全量）
	//	 * @param doType: 需处理项：1社保2公积金3商险4合同5项目档案6人员档案
	private R<List<EmployeeRegistrationLeave>> batchDoLeaveCore(List<EmployeeRegistrationLeave> leaveList, String isExit
			, String doType, YifuUser user) {
		if (Common.isEmpty(leaveList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		String userName = user.getNickname();
		List<TDispatchReduceVo> socialOldList = new ArrayList<>();
		TDispatchReduceVo vo;
		List<TDispatchReduceVo> fundOldList = new ArrayList<>();
		List<String> insuranceOldList = new ArrayList<>();
		// 今天的最后时间，用于发起今日及之前的事项
		LocalDateTime nowTime = LocalDateTime.now().with(LocalTime.MAX);

		// 减少合同需要的传参
		List<BaseSearchVO> listParamContract = new ArrayList<>();
		List<BaseSearchVO> listParamProject = new ArrayList<>();
		List<BaseSearchVO> listParamEmp = new ArrayList<>();
		BaseSearchVO searchVo;
		// 离职待办与商险的映射
		Map<String, List<String>> leaveInsuranceMap = new HashMap<>();
		// 单一离职待办里的商险
		List<String> insuranceList;
		String[] insuranceArr;
		String errorMessage;

		// 1社保2公积金3商险4合同5项目档案6人员档案
		List<EmployeeRegistrationLeaveLog> logList = new ArrayList<>();
		EmployeeRegistrationLeaveLog leaveLog;
		String preContent = "立即发起全部日期的事项：";
		if (Common.isNotNull(isExit) && isExit.equals(CommonConstants.ONE_STRING)) {
			preContent = "立即发起今日及之前的事项：";
		}
		StringBuilder logSubType;
		for (EmployeeRegistrationLeave leave : leaveList) {
			//日志
			leaveLog = new EmployeeRegistrationLeaveLog();
			leaveLog.setLeaveId(leave.getId());
			leaveLog.setCreateName(user.getNickname());
			leaveLog.setCreateTime(LocalDateTime.now());
			leaveLog.setContent(preContent);
			logSubType = new StringBuilder();

			if (judgeToUpdateSocial(isExit, doType, nowTime, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.ONE_INT]).append(CommonConstants.DUNHAO_STRING);
				leave.setFailSocialUser(userName);
				vo = new TDispatchReduceVo();
				vo.setLeaveId(leave.getId());
				vo.setEmpName(leave.getEmployeeName());
				vo.setEmpIdcard(leave.getEmpIdcard());
				vo.setDepartNo(leave.getDeptNo());
				vo.setSocialReduceDate(leave.getSocialReduceDate());
				vo.setReasonType(leave.getLeaveReasonId());
				vo.setTrustRemark(leave.getSocialTrustRemark());
				vo.setChangeContractAndEmployee(CommonConstants.ONE_STRING);
				if (Common.isNotNull(leave.getJoinLeaveDate())) {
					try {
						vo.setLeaveDate(DateUtil.parseDate(leave.getJoinLeaveDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT));
					} catch (Exception e) {
					}
				}
				socialOldList.add(vo);
			}
			if (judgeToUpdateFund(isExit, doType, nowTime, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.TWO_INT]).append(CommonConstants.DUNHAO_STRING);
				leave.setFailFundUser(userName);
				vo = new TDispatchReduceVo();
				vo.setLeaveId(leave.getId());
				vo.setEmpName(leave.getEmployeeName());
				vo.setEmpIdcard(leave.getEmpIdcard());
				vo.setDepartNo(leave.getDeptNo());
				vo.setFundReduceDate(leave.getFundReduceDate());
				vo.setReasonType(leave.getLeaveReasonId());
				vo.setTrustRemark(leave.getFundTrustRemark());
				vo.setChangeContractAndEmployee(CommonConstants.ONE_STRING);
				if (Common.isNotNull(leave.getJoinLeaveDate())) {
					try {
						vo.setLeaveDate(DateUtil.parseDate(leave.getJoinLeaveDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT));
					} catch (Exception e) {
					}
				}
				fundOldList.add(vo);
			}
			if (judgeToUpdateInsurance(isExit, doType, nowTime, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.THREE_INT]).append(CommonConstants.DUNHAO_STRING);
				insuranceArr = leave.getInsuranceIdOld().split(",");
				insuranceList = new ArrayList<>();
				for (String id : insuranceArr) {
					insuranceList.add(id);
					insuranceOldList.add(id);
				}
				leaveInsuranceMap.put(leave.getId(), insuranceList);
			}
			if (judgeToUpdateContract(isExit, doType, nowTime, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.FOUR_INT]).append(CommonConstants.DUNHAO_STRING);
				leave.setFailContractUser(userName);
				searchVo = new BaseSearchVO();
				searchVo.setSearchKey(leave.getContractIdOld());
				searchVo.setResultIdOne(leave.getId());
				searchVo.setResultIdTwo(leave.getJoinLeaveDate());
				if (Common.isNotNull(leave.getLeaveReasonName())) {
					searchVo.setResultIdThree(leave.getLeaveReasonName());
				} else {
					searchVo.setResultIdThree(RegistConstants.BASE_REASON_TYPE_NAME);
				}
				listParamContract.add(searchVo);

			}
			if (judgeToUpdateProject(doType, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.FIVE_INT]).append(CommonConstants.DUNHAO_STRING);
				leave.setFailEmpUser(userName);
				searchVo = new BaseSearchVO();
				searchVo.setSearchKey(leave.getEmpProjectIdOld());
				searchVo.setEmpName(leave.getEmployeeName());
				searchVo.setEmpIdCard(leave.getEmpIdcard());
				searchVo.setDeptNo(leave.getDeptNo());
				searchVo.setResultIdOne(leave.getId());
				if (Common.isNotNull(leave.getLeaveReasonName())) {
					searchVo.setResultIdThree(leave.getLeaveReasonId());
				} else {
					searchVo.setResultIdThree(RegistConstants.BASE_REASON_TYPE);
				}
				listParamProject.add(searchVo);
			}
			if (judgeToUpdateEmp(doType, leave) ) {
				logSubType.append(RegistConstants.DO_TYPE_ARR[CommonConstants.SIX_INT]).append(CommonConstants.DUNHAO_STRING);
				leave.setFailEmpProjectUser(userName);
				searchVo = new BaseSearchVO();
				searchVo.setSearchKey(leave.getEmpProjectIdOld());
				searchVo.setEmpName(leave.getEmployeeName());
				searchVo.setEmpIdCard(leave.getEmpIdcard());
				searchVo.setResultIdOne(leave.getId());
				if (Common.isNotNull(leave.getLeaveReasonName())) {
					searchVo.setResultIdThree(leave.getLeaveReasonName());
				} else {
					searchVo.setResultIdThree(RegistConstants.BASE_REASON_TYPE_NAME);
				}
				listParamEmp.add(searchVo);
			}
			if (logSubType.length() > 0) {
				logSubType.setLength(logSubType.length() - 1); // 长度减1，去掉最后一个
				leaveLog.setContent(preContent + logSubType);
				logList.add(leaveLog);
			}
		}

		//组装返回给前端
		List<ErrorMessage> socialParamList ;
		List<ErrorMessage> fundParamList ;
		List<ErrorMessage> insuranceParamList ;
		List<ErrorMessage> contractParamList ;
		List<ErrorMessage> projectParamList ;
		List<ErrorMessage> empParamList ;
		String closeRemark = "已在其他入口处理";
		BaseSearchVO returnVo;
		BaseSearchVO paramVo;
		R<BaseSearchVO> returnR;
		// 社保-完成
		if (!socialOldList.isEmpty()) {
			TDispatchReduceListVo paramListVo = new TDispatchReduceListVo();
			paramListVo.setUserId(user.getId());
			paramListVo.setUserName(user.getNickname());
			paramListVo.setListParam(socialOldList);
			R<BaseSearchListVO> listR = socialDaprUtils.leaveToReduceSocialAndFund(paramListVo);
			// 成功+失败
			if (Common.isNotNull(listR) && Common.isNotNull(listR.getData())
					&& Common.isNotNull(listR.getData().getErrorMessageList())
					&& !listR.getData().getErrorMessageList().isEmpty()) {
				socialParamList = listR.getData().getErrorMessageList();
				Map<String, String> errorMap = new HashMap<>();
				// 存放成功的新ID
				Map<String, String> successMap = new HashMap<>();
				for (ErrorMessage message : socialParamList) {
					if (CommonConstants.SAVE_SUCCESS.equals(message.getMessage())) {
						successMap.put(message.getKey(), message.getName());
					} else {
						errorMap.put(message.getKey(), message.getMessage());
					}
				}
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateSocial(isExit, doType, nowTime, leave) ) {
						// 成功
						if (successMap.get(leave.getId()) != null) {
							leave.setSocialId(successMap.get(leave.getId()));
							leave.setDoStatusSocial(CommonConstants.FOUR_STRING);
						} else if (errorMap.get(leave.getId()) != null) {
							// 失败
							errorMessage = errorMap.get(leave.getId());
							if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
								errorMessage = errorMessage.substring(0, 300);
							}
							leave.setFailSocialRemark(errorMessage);
							leave.setFailSocialTime(LocalDateTime.now());
							leave.setDoStatusSocial(CommonConstants.THREE_STRING);
						}
					}
					// 1社保:加一重保险：失败的再查一下是否已完结，变为无需处理
					if (CommonConstants.THREE_STRING.equals(leave.getDoStatusSocial())) {
						paramVo = new BaseSearchVO();
						paramVo.setEmpIdCard(leave.getEmpIdcard());
						paramVo.setDeptNo(leave.getDeptNo());
						returnR = socialDaprUtils.getSocialAndFundStatusByClose(paramVo);
						if (null != returnR && Common.isNotNull(returnR.getData())) {
							returnVo = returnR.getData();
							if (Common.isNotNull(returnVo.getResultIdOne())) {
								leave.setSocialId(returnVo.getResultIdOne());
								leave.setDoStatusSocial(CommonConstants.ONE_STRING);
								leave.setCloseRemarkSocial(closeRemark);
							}
						}
					}
				}
			}
		}
		// 公积金-完成
		if (!fundOldList.isEmpty()) {
			TDispatchReduceListVo paramListVo = new TDispatchReduceListVo();
			paramListVo.setUserId(user.getId());
			paramListVo.setUserName(user.getNickname());
			paramListVo.setListParam(fundOldList);
			R<BaseSearchListVO> listR = socialDaprUtils.leaveToReduceSocialAndFund(paramListVo);
			// 成功+失败
			if (Common.isNotNull(listR) && Common.isNotNull(listR.getData())
					&& Common.isNotNull(listR.getData().getErrorMessageList())
					&& !listR.getData().getErrorMessageList().isEmpty()) {
				fundParamList = listR.getData().getErrorMessageList();
				Map<String, String> errorMap = new HashMap<>();
				// 存放成功的新ID
				Map<String, String> successMap = new HashMap<>();
				for (ErrorMessage message : fundParamList) {
					if (CommonConstants.SAVE_SUCCESS.equals(message.getMessage())) {
						successMap.put(message.getKey(), message.getName());
					} else {
						errorMap.put(message.getKey(), message.getMessage());
					}
				}
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateFund(isExit, doType, nowTime, leave) ) {
						// 成功
						if (successMap.get(leave.getId()) != null) {
							leave.setFundId(successMap.get(leave.getId()));
							leave.setDoStatusFund(CommonConstants.FOUR_STRING);
						} else if (errorMap.get(leave.getId()) != null) {
							// 失败
							errorMessage = errorMap.get(leave.getId());
							if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
								errorMessage = errorMessage.substring(0, 300);
							}
							leave.setFailFundRemark(errorMessage);
							leave.setFailFundTime(LocalDateTime.now());
							leave.setDoStatusFund(CommonConstants.THREE_STRING);
						}
					}
					// 2公积金:加一重保险：失败的再查一下是否已完结，变为无需处理
					if (CommonConstants.THREE_STRING.equals(leave.getDoStatusFund())) {
						paramVo = new BaseSearchVO();
						paramVo.setEmpIdCard(leave.getEmpIdcard());
						paramVo.setDeptNo(leave.getDeptNo());
						returnR = socialDaprUtils.getSocialAndFundStatusByClose(paramVo);
						if (null != returnR && Common.isNotNull(returnR.getData())) {
							returnVo = returnR.getData();
							if (Common.isNotNull(returnVo.getResultIdTwo())) {
								leave.setFundId(returnVo.getResultIdTwo());
								leave.setDoStatusFund(CommonConstants.ONE_STRING);
								leave.setCloseRemarkFund(closeRemark);
							}
						}
					}
				}
			}
		}
		// 商险-完成
		if (!insuranceOldList.isEmpty()) {
			// 查找是 2待派单3发起失败9减员退回 的再去办
			List<String> toDoList = leaveInsuranceMapper.getLeaveInsuranceListByIdAndStatus(insuranceOldList);
			if (toDoList != null && !toDoList.isEmpty()) {
				BaseSearchListVO paramVoInsurance = new BaseSearchListVO();
				paramVoInsurance.setUserId(user.getId());
				paramVoInsurance.setUserName(user.getNickname());
				paramVoInsurance.setListStringParam(toDoList);
				R<BaseSearchListVO> listR = insuranceDaprUtil.leaveToReduceInsurance(paramVoInsurance);
				if (Common.isNotNull(listR) && Common.isNotNull(listR.getData())) {
					// 部分失败
					if (!listR.getData().getErrorMessageList().isEmpty()) {
						insuranceParamList = listR.getData().getErrorMessageList();
						// 商险id与错误原因
						Map<String, String> errorMap = new HashMap<>();
						for (ErrorMessage message : insuranceParamList) {
							if (Common.isNotNull(message.getName())) {
								errorMap.put(message.getName(), message.getMessage());
							}
						}
						StringBuilder errorMsg;
						// 错误的商险派单
						List<String> errorList = new ArrayList<>();
						List<String> successList = new ArrayList<>();
						String insuranceIdTemp;
						for (EmployeeRegistrationLeave leave : leaveList) {
							if (judgeToUpdateInsurance(isExit, doType, nowTime, leave) ) {
								errorMsg = new StringBuilder();
								leave.setInsuranceId(leave.getInsuranceIdOld());
								insuranceList = leaveInsuranceMap.get(leave.getId());
								if (insuranceList != null) {
									// 处理每一条商险
									for (String insuranceId : insuranceList) {
										if (errorMap.get(insuranceId) != null) {
											errorMsg.append(errorMap.get(insuranceId)).append(CommonConstants.SEMICOLON_STRING);
											errorList.add(insuranceId);
										} else {
											successList.add(insuranceId);
										}
									}
									if (errorMsg.length() > CommonConstants.ZERO_INT) {
										leave.setFailInsuranceUser(userName);
										errorMessage = errorMsg.toString();
										if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
											errorMessage = errorMessage.substring(0, 300);
										}
										leave.setFailInsuranceRemark(errorMessage);
										leave.setFailInsuranceTime(LocalDateTime.now());
										leave.setDoStatusInsurance(CommonConstants.THREE_STRING);
									} else {
										// 待减员
										leave.setDoStatusInsurance(CommonConstants.FOUR_STRING);
									}
								}
							}

							// 3商险:加一重保险：失败的再查一下是否已完结，变为无需处理
							if (CommonConstants.THREE_STRING.equals(leave.getDoStatusInsurance())) {
								paramVo = new BaseSearchVO();
								paramVo.setEmpIdCard(leave.getEmpIdcard());
								paramVo.setDeptNo(leave.getDeptNo());
								insuranceIdTemp = "";
								returnR = insuranceDaprUtil.getInsurancesStatusByClose(paramVo);
								if (null != returnR && Common.isNotNull(returnR.getData())) {
									returnVo = returnR.getData();
									if (Common.isNotNull(returnVo.getResultIdOne())) {
										insuranceIdTemp = returnVo.getResultIdOne();
									}
								}
								// 这个反着查的，有未减完的，表示不可以关闭它，只能忽略它
								if (Common.isEmpty(insuranceIdTemp)) {
									leave.setInsuranceId(leave.getInsuranceIdOld());
									leave.setDoStatusInsurance(CommonConstants.ONE_STRING);
									leave.setCloseRemarkInsurance(closeRemark);
								}
							}
						}
						// 批量处理商险明细表的状态为失败：
						if (!errorList.isEmpty()) {
							// 可以再将【3商险:加一重保险】里无需处理的部分摘出来，改为无需处理，也可以不变，不影响总状态
							leaveInsuranceMapper.updateLeaveInsuranceListByIdAndStatus(CommonConstants.THREE_STRING, errorList);
						}
						if (!successList.isEmpty()) {
							leaveInsuranceMapper.updateLeaveInsuranceListByIdAndStatus(CommonConstants.FOUR_STRING, successList);
						}
					} else {
						// 全部成功
						for (EmployeeRegistrationLeave leave : leaveList) {
							if (judgeToUpdateInsurance(isExit, doType, nowTime, leave) ) {
								leave.setInsuranceId(leave.getInsuranceIdOld());
								// 待办理
								leave.setDoStatusInsurance(CommonConstants.FOUR_STRING);
							}
						}
						leaveInsuranceMapper.updateLeaveInsuranceListByIdAndStatus(CommonConstants.FOUR_STRING, insuranceOldList);
					}
				}
			}
		}
		// 合同-完成
		if (!listParamContract.isEmpty()) {
			BaseSearchListVO paramVoContract = new BaseSearchListVO();
			paramVoContract.setUserId(user.getId());
			paramVoContract.setUserName(user.getNickname());
			paramVoContract.setListParam(listParamContract);
			R<BaseSearchListVO> listR = archivesDaprUtil.leaveToReduceContract(paramVoContract);
			// 成功+失败
			if (Common.isNotNull(listR) && Common.isNotNull(listR.getData())
					&& Common.isNotNull(listR.getData().getErrorMessageList())
					&& !listR.getData().getErrorMessageList().isEmpty()) {
				contractParamList = listR.getData().getErrorMessageList();
				Map<String, String> errorMap = new HashMap<>();
				// 存放成功的新ID
				Map<String, String> successMap = new HashMap<>();
				Map<String, String> successAndAuditMap = new HashMap<>();
				for (ErrorMessage message : contractParamList) {
					if (CommonConstants.SAVE_SUCCESS.equals(message.getMessage())) {
						successMap.put(message.getKey(), message.getName());
					} else if (CommonConstants.SAVE_AND_UPDATE.equals(message.getMessage())) {
						successAndAuditMap.put(message.getKey(), message.getName());
					} else {
						errorMap.put(message.getKey(), message.getMessage());
					}
				}
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateContract(isExit, doType, nowTime, leave) ) {
						// 成功
						if (successMap.get(leave.getId()) != null) {
							leave.setContractId(successMap.get(leave.getId()));
							leave.setDoStatusContract(CommonConstants.FOUR_STRING);
						} else if (successAndAuditMap.get(leave.getId()) != null) {
							leave.setContractId(successAndAuditMap.get(leave.getId()));
							leave.setDoStatusContract(CommonConstants.EIGHT_STRING);
						} else if (errorMap.get(leave.getId()) != null) {
							// 失败
							errorMessage = errorMap.get(leave.getId());
							if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
								errorMessage = errorMessage.substring(0, 300);
							}
							leave.setFailContractRemark(errorMessage);
							leave.setFailContractTime(LocalDateTime.now());
							leave.setDoStatusContract(CommonConstants.THREE_STRING);
						}
					}
				}
			}
		}

		// 4合同:加一重保险：失败的再查一下是否已完结，变为无需处理
		String contractId = "";
		String contractIdEnd = "";
		for (EmployeeRegistrationLeave leave : leaveList) {
			// 判断了不等于 空、无需处理、完成，再去查合同
			if (judgeToQueryContract(isExit, doType, nowTime, leave) ) {
				contractId = "";
				contractIdEnd = "";
				paramVo = new BaseSearchVO();
				paramVo.setEmpIdCard(leave.getEmpIdcard());
				paramVo.setDeptNo(leave.getDeptNo());
				returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
				if (null != returnR && Common.isNotNull(returnR.getData())) {
					returnVo = returnR.getData();
					if (Common.isNotNull(returnVo.getResultIdThree())) {
						contractId = returnVo.getResultIdThree();
					}
					if (Common.isNotNull(returnVo.getResultIdFourStatus())) {
						contractIdEnd = returnVo.getResultIdFourStatus();
					}
				}
				if (Common.isEmpty(contractId)) {
					if (Common.isNotNull(contractIdEnd)) {
						leave.setContractId(contractIdEnd);
					} else {
						// errorInfo.append("未找到终止的合同！")
						// 社保派减，同步减合同，是没有终止的合同的，而是在合同本身改状态
						leave.setContractId(leave.getContractIdOld());
					}
					leave.setDoStatusContract(CommonConstants.ONE_STRING);
					leave.setCloseRemarkContract(closeRemark);
				}
			}
		}
		// 项目-完成
		if (!listParamProject.isEmpty()) {
			projectParamList = new ArrayList<>();
			List<BaseSearchVO> tempProject;
			BaseSearchListVO paramVoProject;
			for (BaseSearchVO proVo : listParamProject) {
				tempProject = new ArrayList<>();
				tempProject.add(proVo);
				paramVoProject = new BaseSearchListVO();
				paramVoProject.setUserId(user.getId());
				paramVoProject.setUserName(user.getNickname());
				paramVoProject.setListParam(tempProject);
				R<BaseSearchListVO> listR = archivesDaprUtil.leaveToReduceProject(paramVoProject);
				if (Common.isNotNull(listR) && Common.isNotNull(listR.getData()) && !listR.getData().getErrorMessageList().isEmpty()) {
					projectParamList.addAll(listR.getData().getErrorMessageList());
				}
			}
			if (!projectParamList.isEmpty()) {
				Map<String, String> errorMap = new HashMap<>();
				for (ErrorMessage message : projectParamList) {
					errorMap.put(message.getKey(), message.getMessage());
				}
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateProject(doType, leave)) {
						if (errorMap.get(leave.getId()) != null) {
							errorMessage = errorMap.get(leave.getId());
							if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
								errorMessage = errorMessage.substring(0, 300);
							}
							leave.setFailEmpProjectRemark(errorMessage);
							leave.setFailEmpProjectTime(LocalDateTime.now());
							leave.setDoStatusProject(CommonConstants.NINE_STRING);
						} else {
							leave.setEmpProjectId(leave.getEmpProjectIdOld());
							leave.setDoStatusProject(CommonConstants.EIGHT_STRING);
						}
					}

					// 5项目档案:加一重保险：失败的再查一下是否已完结，变为无需处理
					if (CommonConstants.NINE_STRING.equals(leave.getDoStatusProject())) {
						paramVo = new BaseSearchVO();
						paramVo.setEmpIdCard(leave.getEmpIdcard());
						paramVo.setDeptNo(leave.getDeptNo());
						returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
						if (null != returnR && Common.isNotNull(returnR.getData())) {
							returnVo = returnR.getData();
							if (Common.isEmpty(returnVo.getResultIdTwo())) {
								leave.setEmpProjectId(leave.getEmpProjectIdOld());
								leave.setCloseRemarkEmpProject(closeRemark);
								leave.setDoStatusProject(CommonConstants.ONE_STRING);
							}
						}
					}
				}
			} else {
				// 全部成功
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateProject(doType, leave)) {
						leave.setEmpProjectId(leave.getEmpProjectIdOld());
						leave.setDoStatusProject(CommonConstants.EIGHT_STRING);
					}
				}
			}
		}
		// 员工-完成
		if (!listParamEmp.isEmpty()) {

			empParamList = new ArrayList<>();
			List<BaseSearchVO> tempEmp;
			BaseSearchListVO paramVoEmp;
			for (BaseSearchVO empVo : listParamEmp) {

				tempEmp = new ArrayList<>();
				tempEmp.add(empVo);
				paramVoEmp = new BaseSearchListVO();
				paramVoEmp.setUserId(user.getId());
				paramVoEmp.setUserName(user.getNickname());
				paramVoEmp.setListParam(tempEmp);
				R<BaseSearchListVO> listR = archivesDaprUtil.leaveToReduceEmp(paramVoEmp);
				if (Common.isNotNull(listR) && Common.isNotNull(listR.getData()) && !listR.getData().getErrorMessageList().isEmpty()) {
					empParamList.addAll(listR.getData().getErrorMessageList());
				}
			}
			if (!empParamList.isEmpty()) {
				Map<String, String> errorMap = new HashMap<>();
				for (ErrorMessage message : empParamList) {
					errorMap.put(message.getKey(), message.getMessage());
				}
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateEmp(doType, leave)) {
						if (errorMap.get(leave.getId()) != null) {
							errorMessage = errorMap.get(leave.getId());
							if (Common.isNotNull(errorMessage) && errorMessage.length() > 300) {
								errorMessage = errorMessage.substring(0, 300);
							}
							leave.setFailEmpRemark(errorMessage);
							leave.setFailEmpTime(LocalDateTime.now());
							leave.setDoStatusEmp(CommonConstants.NINE_STRING);
						} else {
							leave.setEmpId(leave.getEmpIdOld());
							leave.setDoStatusEmp(CommonConstants.EIGHT_STRING);
						}
					}
					// 6人员档案:加一重保险：失败的再查一下是否已完结，变为无需处理
					if (CommonConstants.NINE_STRING.equals(leave.getDoStatusEmp())) {
						paramVo = new BaseSearchVO();
						paramVo.setEmpIdCard(leave.getEmpIdcard());
						paramVo.setDeptNo(leave.getDeptNo());
						returnR = archivesDaprUtil.getEmpAndContractStatus(paramVo);
						if (null != returnR && Common.isNotNull(returnR.getData())) {
							returnVo = returnR.getData();
							if (Common.isEmpty(returnVo.getResultIdOne())) {
								leave.setEmpId(leave.getEmpIdOld());
								leave.setCloseRemarkEmp(closeRemark);
								leave.setDoStatusEmp(CommonConstants.ONE_STRING);
							}
						}
					}
				}
			} else {
				// 全部成功
				for (EmployeeRegistrationLeave leave : leaveList) {
					if (judgeToUpdateEmp(doType, leave)) {
						leave.setEmpId(leave.getEmpIdOld());
						leave.setDoStatusEmp(CommonConstants.EIGHT_STRING);
					}
				}
			}
		}


		// 是否返回前端错误信息
		boolean isReturn = false;
		// 最终更新总状态
		for (EmployeeRegistrationLeave leave : leaveList) {
			judgeStatus(leave);
			if (!isReturn && (Common.isNotNull(leave.getDoStatusSocial()) && CommonConstants.THREE_STRING.equals(leave.getDoStatusSocial()))
						|| (Common.isNotNull(leave.getDoStatusFund()) && CommonConstants.THREE_STRING.equals(leave.getDoStatusFund()))
						|| (Common.isNotNull(leave.getDoStatusContract()) && CommonConstants.THREE_STRING.equals(leave.getDoStatusContract()))
						|| (Common.isNotNull(leave.getDoStatusInsurance()) && CommonConstants.THREE_STRING.equals(leave.getDoStatusInsurance()))
						|| (Common.isNotNull(leave.getDoStatusProject()) && CommonConstants.NINE_STRING.equals(leave.getDoStatusProject()))
						|| (Common.isNotNull(leave.getDoStatusEmp()) && CommonConstants.NINE_STRING.equals(leave.getDoStatusEmp()))
				) {
				isReturn = true;
			}
		}
		if (logList != null && !logList.isEmpty()) {
			leaveLogService.saveBatch(logList);
		}
		this.updateBatchById(leaveList);
		if (isReturn) {
			return R.failed(leaveList, "发起失败！");
		} else {
			return R.ok();
		}
	}

	private boolean judgeToUpdateEmp(String doType, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.SIX_STRING))
				&& Common.isNotNull(leave.getEmpIdOld())
				&& Common.isNotNull(leave.getDoStatusEmp())
				&& (leave.getDoStatusEmp().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusEmp().equals(CommonConstants.NINE_STRING)
		);
	}

	private boolean judgeToUpdateProject(String doType, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.FIVE_STRING))
				&& Common.isNotNull(leave.getEmpProjectIdOld())
				&& Common.isNotNull(leave.getDoStatusProject())
				&& (leave.getDoStatusProject().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusProject().equals(CommonConstants.NINE_STRING)
		);
	}

	// 判断是否要发起
	private boolean judgeToUpdateContract(String isExit, String doType, LocalDateTime nowTime, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.FOUR_STRING))
				&& Common.isNotNull(leave.getContractIdOld()) && (CommonConstants.ZERO_STRING.equals(isExit)
				|| (CommonConstants.ONE_STRING.equals(isExit) && Common.isNotNull(leave.getContractExpectedTime()) && leave.getContractExpectedTime().isBefore(nowTime)))
				&& Common.isNotNull(leave.getDoStatusContract())
				&& (leave.getDoStatusContract().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusContract().equals(CommonConstants.THREE_STRING)
				|| leave.getDoStatusContract().equals(CommonConstants.TEN_STRING)
		);
	}

	// 判断是否要关闭为无需处理
	private boolean judgeToQueryContract(String isExit, String doType, LocalDateTime nowTime, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.FOUR_STRING))
				&& Common.isNotNull(leave.getContractIdOld()) && (CommonConstants.ZERO_STRING.equals(isExit)
				|| (CommonConstants.ONE_STRING.equals(isExit) && Common.isNotNull(leave.getContractExpectedTime()) && leave.getContractExpectedTime().isBefore(nowTime)))
				&& Common.isNotNull(leave.getDoStatusContract())
				&& !leave.getDoStatusContract().equals(CommonConstants.ZERO_STRING)
				&& !leave.getDoStatusContract().equals(CommonConstants.ONE_STRING)
				&& !leave.getDoStatusContract().equals(CommonConstants.EIGHT_STRING);
	}

	private boolean judgeToUpdateSocial(String isExit, String doType, LocalDateTime nowTime, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.ONE_STRING))
				&& Common.isNotNull(leave.getSocialDispatchIdOld()) && (CommonConstants.ZERO_STRING.equals(isExit)
				|| (CommonConstants.ONE_STRING.equals(isExit) && Common.isNotNull(leave.getSocialExpectedTime()) && leave.getSocialExpectedTime().isBefore(nowTime)))
				&& Common.isNotNull(leave.getDoStatusSocial())
				&& (leave.getDoStatusSocial().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusSocial().equals(CommonConstants.THREE_STRING)
				|| leave.getDoStatusSocial().equals(CommonConstants.SIX_STRING)
				|| leave.getDoStatusSocial().equals(CommonConstants.NINE_STRING)
				|| leave.getDoStatusSocial().equals(CommonConstants.TEN_STRING)
		);
	}

	private boolean judgeToUpdateFund(String isExit, String doType, LocalDateTime nowTime, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.TWO_STRING))
				&& Common.isNotNull(leave.getFundDispatchIdOld()) && (CommonConstants.ZERO_STRING.equals(isExit)
				|| (CommonConstants.ONE_STRING.equals(isExit) && Common.isNotNull(leave.getFundExpectedTime()) && leave.getFundExpectedTime().isBefore(nowTime)))
				&& Common.isNotNull(leave.getDoStatusFund())
				&& (leave.getDoStatusFund().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusFund().equals(CommonConstants.THREE_STRING)
				|| leave.getDoStatusFund().equals(CommonConstants.NINE_STRING)
				|| leave.getDoStatusFund().equals(CommonConstants.TEN_STRING)
		);
	}

	// 派单时，判断是否需要办理此条商险
	private boolean judgeToUpdateInsurance(String isExit, String doType, LocalDateTime nowTime, EmployeeRegistrationLeave leave) {
		return (Common.isEmpty(doType) || doType.contains(CommonConstants.THREE_STRING))
				&& Common.isNotNull(leave.getInsuranceIdOld()) && (CommonConstants.ZERO_STRING.equals(isExit)
				|| (CommonConstants.ONE_STRING.equals(isExit) && Common.isNotNull(leave.getInsuranceExpectedTime()) && leave.getInsuranceExpectedTime().isBefore(nowTime)))
				&& Common.isNotNull(leave.getDoStatusInsurance())
				&& (leave.getDoStatusInsurance().equals(CommonConstants.TWO_STRING)
				|| leave.getDoStatusInsurance().equals(CommonConstants.THREE_STRING)
				|| leave.getDoStatusInsurance().equals(CommonConstants.NINE_STRING)
		);
	}

	@Override
	public void reduceHandleToLeave(BaseServiceParamListVO vo) {
		if (vo == null) {
			return;
		}
		String doType = vo.getDoType();
		String doStatus = vo.getDoStatus();
		// 0：失败；1：成功（失败要记录信息）
		String isSuccess = vo.getIsSuccess();
		String userName = vo.getUserName();
		// 最终成功，才更新执行详情
		boolean canUpdateFail = false;
		if (Common.isNotNull(isSuccess) && CommonConstants.ZERO_STRING.equals(isSuccess)) {
			canUpdateFail = true;
		}
		String doRemark = vo.getRemark();
		if (Common.isNotNull(doRemark) && doRemark.length()>50) {
			doRemark = doRemark.substring(0,50);
		}
		List<String> idList = vo.getListParam();
		if (idList != null && !idList.isEmpty() && Common.isNotNull(doType)) {
			// 需处理项：1社保2公积金3商险4合同5项目档案6人员档案
			List<EmployeeRegistrationLeave> leaveList;
			Map<String, Integer> insuranceMap = new HashMap<>();
			if (CommonConstants.THREE_STRING.equals(doType)) {
				leaveList = baseMapper.selectLeaveListByHandleAndInsuranceType(idList);
				for (String id:idList) {
					insuranceMap.put(id, CommonConstants.ONE_INT);
				}
			} else {
				leaveList = baseMapper.selectLeaveListByHandleAndType(idList, doType);
			}
			if (leaveList != null && !leaveList.isEmpty()) {
				List<EmployeeRegistrationLeaveInsurance> insuranceList;
				String minStatus;
				String currentStatus;
				for (EmployeeRegistrationLeave leave : leaveList) {
					// 处理社保
					if (CommonConstants.ONE_STRING.equals(doType)) {
						leave.setDoStatusSocial(doStatus);
						if (canUpdateFail) {
							leave.setFailSocialUser(userName);
							leave.setFailSocialTime(LocalDateTime.now());
							leave.setFailSocialRemark(doRemark);
						}
					}
					if (CommonConstants.TWO_STRING.equals(doType)) {
						leave.setDoStatusFund(doStatus);
						if (canUpdateFail) {
							leave.setFailFundUser(userName);
							leave.setFailFundTime(LocalDateTime.now());
							leave.setFailFundRemark(doRemark);
						}
					}
					if (CommonConstants.THREE_STRING.equals(doType)) {
						insuranceList = leaveInsuranceMapper.getLeaveInsuranceList(leave.getId(), null);
						minStatus = null;
						for (EmployeeRegistrationLeaveInsurance insurance : insuranceList) {
							if (insuranceMap.get(insurance.getInsuranceId()) != null) {
								insurance.setDoStatusInsurance(doStatus);
								leaveInsuranceMapper.updateById(insurance);
							}
							if (Common.isNotNull(insurance.getDoStatusInsurance())) {
								currentStatus = insurance.getDoStatusInsurance();
								if (Common.isEmpty(minStatus)) {
									minStatus = currentStatus;
								} else {
									minStatus = compareInsuranceStatus(minStatus, currentStatus);
								}
							}
						}
						if (canUpdateFail) {
							leave.setFailInsuranceUser(userName);
							leave.setFailInsuranceTime(LocalDateTime.now());
							leave.setFailInsuranceRemark(doRemark);
						}
						leave.setDoStatusInsurance(minStatus);
					}
					if (CommonConstants.FOUR_STRING.equals(doType)) {
						leave.setDoStatusContract(doStatus);
						if (canUpdateFail) {
							leave.setFailContractUser(userName);
							leave.setFailContractTime(LocalDateTime.now());
							leave.setFailContractRemark(doRemark);
						}
					}
					if (CommonConstants.FIVE_STRING.equals(doType)) {
						leave.setDoStatusProject(doStatus);
						if (canUpdateFail) {
							leave.setFailEmpProjectUser(userName);
							leave.setFailEmpProjectTime(LocalDateTime.now());
							leave.setFailEmpProjectRemark(doRemark);
						}
					}
					if (CommonConstants.SIX_STRING.equals(doType)) {
						leave.setDoStatusEmp(doStatus);
						if (canUpdateFail) {
							leave.setFailEmpUser(userName);
							leave.setFailEmpTime(LocalDateTime.now());
							leave.setFailEmpRemark(doRemark);
						}
					}
					judgeStatus( leave);
				}
				this.updateBatchById(leaveList);
			}
		}
	}

	/**
	 * 比较两个保险状态，返回较小的那个
	 * 特殊规则：8是最大的
	 * // 2待派单3发起失败4待减员5待办理6减员中8减员成功9减员退回
	 */
	private String compareInsuranceStatus(String status1, String status2) {
		// 如果其中一个状态是8，返回另一个状态
		if (CommonConstants.EIGHT_STRING.equals(status1)) {
			return status2;
		}
		if (CommonConstants.EIGHT_STRING.equals(status2)) {
			return status1;
		}
		// 其他情况正常比较数字大小
		try {
			return String.valueOf(Math.min(Integer.parseInt(status1), Integer.parseInt(status2)));
		} catch (Exception e) {
			return status1;
		}
	}

}
