package com.yifu.cloud.plus.v1.yifu.social.service.impl;/*
 *    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)
 */

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysArea;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainListVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ExcelAttributeConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
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.concurrent.threadpool.YFSocialImportThreadPoolExecutor;
import com.yifu.cloud.plus.v1.yifu.social.constants.PaymentConstants;
import com.yifu.cloud.plus.v1.yifu.social.constants.SocialConstants;
import com.yifu.cloud.plus.v1.yifu.social.entity.TPaymentInfo;
import com.yifu.cloud.plus.v1.yifu.social.entity.TProvidentFund;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TPaymentInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TProvidentFundMapper;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.TPaymentInfoImportLogService;
import com.yifu.cloud.plus.v1.yifu.social.service.TPaymentInfoService;
import com.yifu.cloud.plus.v1.yifu.social.util.ServiceUtil;
import com.yifu.cloud.plus.v1.yifu.social.vo.TPaymentHeFeiVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TPaymentInfoSearchVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TPaymentInfoVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
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.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 缴费库
 *
 * @author huyc
 * @date 2022-07-22 17:01:22
 */
@Log4j2
@Service
public class TPaymentInfoServiceImpl extends ServiceImpl<TPaymentInfoMapper, TPaymentInfo> implements TPaymentInfoService {

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private YFSocialImportThreadPoolExecutor yfSocialImportThreadPoolExecutor;

	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	@Autowired
	private TPaymentInfoImportLogService tPaymentInfoImportLogService;

	@Autowired
	private TSocialInfoMapper socialInfoMapper;

	@Autowired
	private TProvidentFundMapper providentFundMapper;

	private final int partSize = 30;

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;

	/**
	 * 缴费库简单分页查询
	 *
	 * @param tPaymentInfo 缴费库
	 * @return
	 */
	@Override
	public IPage<TPaymentInfo> getTPaymentInfoPage(Page<TPaymentInfo> page, TPaymentInfo tPaymentInfo) {
		return baseMapper.getTPaymentInfoPage(page, tPaymentInfo);
	}

	/**
	 * 缴费库批量导出
	 *
	 * @param searchVo 缴费库
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TPaymentInfoSearchVo searchVo) {
		String fileName = "缴费库批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TPaymentInfo> list = new ArrayList<>();
		Integer count = baseMapper.selectCountTPaymentInfo(searchVo);
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType("multipart/form-data");
			response.setCharacterEncoding("utf-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, TPaymentInfo.class).includeColumnFiledNames(searchVo.getExportFields()).build();
			;
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; ) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.getTPaymentInfoNoPage(searchVo);
					if (Common.isNotNull(list)) {
						ExcelUtil<TPaymentInfo> util = new ExcelUtil<>(TPaymentInfo.class);
						for (TPaymentInfo vo : list) {
							util.convertEntity(vo, null, null, null);
						}
					}
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcel.writerSheet("缴费库" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					i = i + CommonConstants.EXCEL_EXPORT_LIMIT;
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcel.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 R removeInFoById(String id) {
		YifuUser user = SecurityUtils.getUser();

		TPaymentInfo paymentInfo = baseMapper.selectById(id);
		if (!user.getId().equals(paymentInfo.getCreateBy()) && !CommonConstants.ONE_STRING.equals(user.getId())) {
			return R.failed("非本人创建的数据禁止删除！");
		}

		if (CommonConstants.ZERO_STRING.equals(paymentInfo.getPushStatus()) &&
				!CommonConstants.ONE_STRING.equals(user.getId())) {
			return R.failed("已推送至结算平台禁止删除！");
		}
		baseMapper.deleteById(id);
		return R.ok();
	}

	@Override
	public R<Boolean> removeAllInfoById(String ids) {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(ids)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		List<String> idList = Common.initStrToList(ids, CommonConstants.COMMA_STRING);
		TPaymentInfo paymentInfo = null;

		for (String id : idList) {
			paymentInfo = baseMapper.selectById(id);
			if (null != paymentInfo && Common.isNotNull(paymentInfo.getId())) {
				if ((!user.getId().equals(paymentInfo.getCreateBy()) ||
						CommonConstants.ZERO_STRING.equals(paymentInfo.getPushStatus()))
						&& !CommonConstants.ONE_STRING.equals(user.getId())) {
					return R.failed("存在不符合条件的数据(已推送至结算平台或非本人创建),禁止删除！");
				}
				baseMapper.deleteById(id);
			}
		}
		return R.ok();
	}

	/**
	 * 通过ID获取缴费库 及社保、公积金明细
	 *
	 * @param id
	 * @Author huyc
	 * @Date 2022-07-24
	 **/
	@Override
	public R getAllInfoById(String id) {
		TPaymentInfoVo vo = baseMapper.getAllInfoById(id);
		return R.ok(vo, "查询成功！");
	}

	@Override
	public R removeBatchByInfo(String empIdCard, String socialHouseId, String fundHouseId,
							   String socialCreateMonth, String socialPayMonth) {
		YifuUser user = SecurityUtils.getUser();

		LambdaQueryWrapper<TPaymentInfo> wrapper = Wrappers.lambdaQuery();
		if (Common.isNotNull(empIdCard)) {
			wrapper.eq(TPaymentInfo::getEmpIdcard, empIdCard);
		}
		if (Common.isNotNull(socialHouseId)) {
			wrapper.eq(TPaymentInfo::getSocialHousehold, socialHouseId);
		}
		if (Common.isNotNull(fundHouseId)) {
			wrapper.eq(TPaymentInfo::getProvidentHousehold, fundHouseId);
		}
		if (Common.isNotNull(socialCreateMonth)) {
			wrapper.eq(TPaymentInfo::getSocialCreateMonth, socialCreateMonth);
		}
		if (Common.isNotNull(socialPayMonth)) {
			wrapper.eq(TPaymentInfo::getSocialPayMonth, socialPayMonth);
		}

		List<TPaymentInfo> list = baseMapper.selectList(wrapper);
		List<String> idList = new ArrayList<>();
		if (Common.isNotNull(list)) {
			for (TPaymentInfo paymentInfo : list) {
				if ((!user.getId().equals(paymentInfo.getCreateBy()) ||
						CommonConstants.ZERO_STRING.equals(paymentInfo.getPushStatus()))
						&& !CommonConstants.ONE_STRING.equals(user.getId())) {
					return R.failed("存在不符合条件的数据(已推送至结算平台或非本人创建),禁止删除！");
				} else {
					idList.add(paymentInfo.getId());
				}
			}
		} else {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		baseMapper.deleteBatchIds(idList);
		return R.ok();
	}

	@Override
	public R<List<ErrorMessage>> importSocialDiy(InputStream inputStream, String random) {
		YifuUser user = SecurityUtils.getUser();
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TPaymentInfoVo> util1 = new ExcelUtil<>(TPaymentInfoVo.class);
		;
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TPaymentInfoVo.class, new ReadListener<TPaymentInfoVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TPaymentInfoVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TPaymentInfoVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTPaymentSocialInfo(cachedDataList, errorMessageList, random, user);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}

	private void importTPaymentSocialInfo(List<TPaymentInfoVo> list, List<ErrorMessage> errorMessageList,
										  String random, YifuUser user) {
		long start = System.currentTimeMillis();

		HashMap<String, String> areaMap = new HashMap<String, String>();
		HashMap<String, String> areaMap2 = new HashMap<String, String>();
		R<AreaVo> areaListR = upmsDaprUtils.getAreaListR();
		if (Common.isNotNull(areaListR)) {
			AreaVo areaList = areaListR.getData();
			if (null != areaList && !areaList.getSysAreaList().isEmpty()) {
				for (SysArea area : areaList.getSysAreaList()) {
					areaMap.put(Integer.toString(area.getId()), area.getAreaName());
					areaMap2.put(area.getAreaName() + CommonConstants.DOWN_LINE_STRING + (
							null == area.getParentId() ? "null" : (0 == area.getParentId().intValue() ? "null" : Integer.toString(
									area.getParentId()))), Integer.toString(area.getId()));
				}
			}
		}

		// 判断是否有相同的用户在导入社保费用 存在提示稍后重试
		String key = user.getId() + CommonConstants.DOWN_LINE_STRING + CommonConstants.PAYMENT_SOCIAL_IMPORT;
		if (redisUtil.exists(key)) {
			errorMessageList.add(new ErrorMessage(-1, "当前用户数据导入中，请稍后重试！"));
			redisUtil.remove(key);
		} else {
			redisUtil.set(key, user.getId(), 1800L);

			// 导入前做队列空闲判断，防止队列不足出现数据丢失的场景
			if (CollUtil.isNotEmpty(list)) {
				int taskSize = list.size() / partSize + CommonConstants.ONE_INT;
				int residualCapacity = yfSocialImportThreadPoolExecutor.getResidualCapacity();
				if (taskSize > residualCapacity) {
					errorMessageList.add(new ErrorMessage(-1, MsgUtils.getMessage(ErrorCodes.SOCIALINFO_LIST_NUM_LARGE)));
				}else {
					// -----------------------------生成paymentInfoMap本段开始--------------------------------
					//已存在的档案数据
					List<String> monthList = Common.listObjectToStrList(list, ExcelAttributeConstants.SOCIAL_PAY_MONTH).stream().distinct().collect(Collectors.toList());
					//已存在社保缴费库数据  非删除状态
					List<TPaymentInfo> paymentInfos = baseMapper.selectListForPaymentImport(monthList, Common.listObjectToStrList(list, ExcelAttributeConstants.EMPIDCARD));
					//养老
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoPensionMap = new ConcurrentHashMap<>();
					//大病救助金
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoBigMap = new ConcurrentHashMap<>();
					//失业
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoUnEmpMap = new ConcurrentHashMap<>();
					//生育
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoBirMap = new ConcurrentHashMap<>();
					//工伤
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoInjuryMap = new ConcurrentHashMap<>();
					//医保
					ConcurrentHashMap<String, TPaymentInfo> paymentInfoMedicalMap = new ConcurrentHashMap<>();
					if (Common.isNotNull(paymentInfos)) {
						for (TPaymentInfo info : paymentInfos) {
							if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitPensionMoney()),
									BigDecimalUtils.isNullToZero(info.getPersonalPensionMoney())).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoPensionMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.YL
										, info);
							}
							if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getPersonalBigmailmentMoney()),
									BigDecimalUtils.isNullToZero(info.getUnitBigmailmentMoney())).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoBigMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.DB
										, info);
							}
							if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitUnemploymentMoney()),
									BigDecimalUtils.isNullToZero(info.getPersonalUnemploymentMoney())).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoUnEmpMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.SY
										, info);
							}
							if (BigDecimalUtils.isNullToZero(info.getUnitBirthMoney()).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoBirMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.BIR
										, info);
							}
							if (BigDecimalUtils.isNullToZero(info.getUnitInjuryMoney()).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoInjuryMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.GS
										, info);
							}
							if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitMedicalMoney()),
									BigDecimalUtils.isNullToZero(info.getPersonalMedicalMoney())).compareTo(BigDecimal.ZERO) != 0) {
								paymentInfoMedicalMap.put(info.getSocialPayAddr()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getEmpIdcard()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialPayMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ info.getSocialCreateMonth()
												+ CommonConstants.DOWN_LINE_STRING
												+ SocialConstants.YB
										, info);
							}
						}
					}
					// -----------------------------生成paymentInfoMap本段结束--------------------------------
					/**
					 *  修改批量导入社保为线程池的方式。逻辑分析，根据前端传入的list，将list分成每份partSize个。
					 *  有以下3种情况。1.list数量不足partSize，直接进行处理;2.list数量正好可以根据partSize等分，循环处理;3.不能等分有剩余的情况
					 */

					// -----------------------------线程池处理list，批量保存社保信息开始--------------------------------
					List<TPaymentInfoVo> tempList = new ArrayList<>();
					AtomicInteger atomicLine = new AtomicInteger(CommonConstants.ZERO_INT);
					List<CompletableFuture<List<ErrorMessage>>> completableFutureList = new ArrayList<>();
					try {
						// 1.list.size()不足partSize，直接执行
						if (list.size() < partSize) {
							CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(() ->
									executeImportSocialList(user, atomicLine, random, list, areaMap, areaMap2,
											paymentInfoPensionMap, paymentInfoBigMap, paymentInfoBirMap,
											paymentInfoMedicalMap, paymentInfoUnEmpMap, paymentInfoInjuryMap,
											CommonConstants.ONE_INT, errorMessageList), yfSocialImportThreadPoolExecutor);
							completableFutureList.add(listCompletableFuture);
						}

						// 2.list.size()大于partSize，循环分批执行
						int lastIdx = 0;
						if (partSize <= list.size()) {
							// 处理第一个0位元素
							final List<TPaymentInfoVo> finalList = list.subList(0, 1);
							CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(() ->
									executeImportSocialList(user, atomicLine, random, finalList, areaMap, areaMap2,
											paymentInfoPensionMap, paymentInfoBigMap, paymentInfoBirMap,
											paymentInfoMedicalMap, paymentInfoUnEmpMap, paymentInfoInjuryMap,
											CommonConstants.ONE_INT, errorMessageList), yfSocialImportThreadPoolExecutor);
							completableFutureList.add(listCompletableFuture);

							lastIdx = 1;
							for (int i = 1; i < list.size(); i++) {
								// partSize数量的list为一个执行单元
								tempList.add(list.get(i));
								if (i % partSize == 0) {
									lastIdx = i;
									List<TPaymentInfoVo> finalTempList = tempList;
									final int idx = i - partSize + 2;
									CompletableFuture.supplyAsync(() ->
											executeImportSocialList(user, atomicLine, random, finalTempList, areaMap, areaMap2,
													paymentInfoPensionMap, paymentInfoBigMap, paymentInfoBirMap,
													paymentInfoMedicalMap, paymentInfoUnEmpMap, paymentInfoInjuryMap,
													idx, errorMessageList), yfSocialImportThreadPoolExecutor);
									tempList = new ArrayList<>();
								}
							}
						}

						// 3.第2种方式执行完后，有余数的情况下，执行3
						if (lastIdx != 0) {
							tempList = new ArrayList<>();
							if (lastIdx == 1) {
								for (int i = lastIdx; i < list.size(); i++) {
									tempList.add(list.get(i));
								}
							} else {
								for (int i = lastIdx + 1; i < list.size(); i++) {
									tempList.add(list.get(i));
								}
								lastIdx += 1;
							}

							List<TPaymentInfoVo> finalTempList = tempList;
							int finalLastIdx = lastIdx + 1;
							CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(() ->
									executeImportSocialList(user, atomicLine, random, finalTempList, areaMap, areaMap2,
											paymentInfoPensionMap, paymentInfoBigMap, paymentInfoBirMap,
											paymentInfoMedicalMap, paymentInfoUnEmpMap, paymentInfoInjuryMap,
											finalLastIdx, errorMessageList), yfSocialImportThreadPoolExecutor);
							completableFutureList.add(listCompletableFuture);
						}

						// 阻塞当前线程，等待所有的线程执行完毕
						boolean computeFlag;
						do {
							computeFlag = false;
							for (CompletableFuture<List<ErrorMessage>> listCompletableFuture : completableFutureList) {
								if (!listCompletableFuture.isDone()) {
									computeFlag = true;
								}
							}
						} while (computeFlag);

						String importSuccessKey = user.getId() + CommonConstants.DOWN_LINE_STRING + CommonConstants.PAYMENT_SOCIAL_WAIT_EXPORT;
						DecimalFormat df = new DecimalFormat("0.00000");
						String maerialRatio = df.format((float)atomicLine.get()/list.size());
						redisUtil.set(importSuccessKey, maerialRatio, 1800L);

					} catch (Exception e) {
						log.error("社保缴费库数据批量导入异常：" + e);
						redisUtil.remove(key);
					} finally {
						paymentInfoPensionMap.clear();
						paymentInfoBigMap.clear();
						paymentInfoBirMap.clear();
						paymentInfoMedicalMap.clear();
						paymentInfoUnEmpMap.clear();
						paymentInfoInjuryMap.clear();
					}
					// -----------------------------线程池处理list，批量保存社保信息结束--------------------------------
					//最后一个推送
					log.info("社保批量导入耗时:{}", (System.currentTimeMillis() - start) + "");
					redisUtil.remove(key);
				}
			}
		}
	}

	/**
	 * 转换缴纳地址为省市县ID
	 **/
	private TPaymentInfoVo initAddress(String[] areaArray, HashMap<String, String> areaMap2, TPaymentInfoVo s) {
		if (null == areaArray || null == areaMap2 || null == s) {
			return s;
		}
		String temp = null;
		if (areaArray.length >= CommonConstants.TWO_INT) {
			temp = areaMap2.get(areaArray[0] + CommonConstants.DOWN_LINE_STRING + "null");
			if (Common.isNotNull(temp)) {
				s.setSocialProvince(temp);
			}
			temp = areaMap2.get(areaArray[1] + CommonConstants.DOWN_LINE_STRING + (null == s.getSocialProvince()
					? "null" : s.getSocialProvince()));
			if (Common.isNotNull(temp)) {
				s.setSocialCity(temp);
			}
			if (areaArray.length >= CommonConstants.THREE_INT) {
				temp = areaMap2.get(areaArray[2] + CommonConstants.DOWN_LINE_STRING + (null == s.getSocialCity()
						? "null" : s.getSocialCity()));
				if (Common.isNotNull(temp)) {
					s.setSocialTown(temp);
				}
			}
		}
		return s;
	}

	/**
	 * @param user
	 * @param atomicLine
	 * @param list
	 * @param areaMap
	 * @param areaMap2
	 * @param paymentInfoPensionMap
	 * @param idx
	 * @description:
	 * @author: huyc
	 * @date: 2022/7/25
	 * @return:
	 */
	private List<ErrorMessage> executeImportSocialList(YifuUser user,
										 AtomicInteger atomicLine,
										 String random,
										 List<TPaymentInfoVo> list,
										 HashMap<String, String> areaMap,
										 HashMap<String, String> areaMap2,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoPensionMap,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoBigMap,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoBirMap,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoMedicalMap,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoUnEmpMap,
										 ConcurrentHashMap<String, TPaymentInfo> paymentInfoInjuryMap,
										 int idx, List<ErrorMessage> errorMessageList) {
		int i = idx;
		if (Common.isNotNull(list)) {
			TPaymentInfo paymentInfo = null;
			TSocialInfo socialInfo = null;
			String temp = null;
			int res = -1;
			// 全部办理成功 和 部分办理失败
			List<TSocialInfo> socialInfoList = socialInfoMapper.selectList(Wrappers.<TSocialInfo>query().lambda()
					.in(TSocialInfo::getEmpIdcard, Common.listObjectToStrList(list, ExcelAttributeConstants.EMPIDCARD))
					.and(obj -> obj.eq(TSocialInfo::getHandleStatus, CommonConstants.ONE_STRING)
							.or().eq(TSocialInfo::getHandleStatus, CommonConstants.FIVE_STRING))
					.eq(TSocialInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
			//已派减的
			List<TSocialInfo> socialInfoListTemp = socialInfoMapper.selectList(Wrappers.<TSocialInfo>query().lambda()
					.in(TSocialInfo::getEmpIdcard, Common.listObjectToStrList(list, ExcelAttributeConstants.EMPIDCARD))
					.eq(TSocialInfo::getHandleStatus, CommonConstants.THREE_STRING)
					.eq(TSocialInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
			//已存在的社保数据
			HashMap<String, TSocialInfo> socialMap = new HashMap<>();
			if (Common.isNotNull(socialInfoList)) {
				for (TSocialInfo tSocialInfo : socialInfoList) {
					socialMap.put(tSocialInfo.getEmpIdcard()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialProvince()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialCity()
							+ CommonConstants.DOWN_LINE_STRING + (null == tSocialInfo.getSocialTown()
							? "null" : tSocialInfo.getSocialTown()), tSocialInfo);
				}
			}

			//已存在的派减社保数据
			HashMap<String, TSocialInfo> socialMapTemp = new HashMap<>();
			if (Common.isNotNull(socialInfoListTemp)) {
				for (TSocialInfo tSocialInfo : socialInfoListTemp) {
					socialMapTemp.put(tSocialInfo.getEmpIdcard()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialProvince()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialCity()
							+ CommonConstants.DOWN_LINE_STRING + (null == tSocialInfo.getSocialTown()
							? "null" : tSocialInfo.getSocialTown()), tSocialInfo);
				}
			}

			String[] areaArray;
			String checkRes;

			Map<String,String> cusMap = new HashMap<>();
			Map<String,String> itemMap = new HashMap<>();
			List<TSettleDomainSelectVo> settleDomainR = null;
			R<TSettleDomainListVo> listVo = null;
			listVo = archivesDaprUtil.selectAllSettleDomainSelectVos();
			if (Common.isNotNull(listVo)) {
				TSettleDomainListVo tSettleDomainListVo = listVo.getData();
				if (Common.isNotNull(tSettleDomainListVo) && Common.isNotEmpty(tSettleDomainListVo.getListSelectVO())) {
					settleDomainR = tSettleDomainListVo.getListSelectVO();
				}
			}
			if(CollectionUtils.isNotEmpty(settleDomainR)){
				for (TSettleDomainSelectVo tSettleDomainSelectVo : settleDomainR) {
					cusMap.put(tSettleDomainSelectVo.getCustomerId(), tSettleDomainSelectVo.getCustomerName());
					itemMap.put(tSettleDomainSelectVo.getId(), tSettleDomainSelectVo.getDepartName());
				}
			}
			for (TPaymentInfoVo infoVo : list) {
				atomicLine.incrementAndGet();
				++i;
				if (Common.isNotNull(infoVo.getEmpIdcard())) {
					infoVo.setEmpIdcard(infoVo.getEmpIdcard().replace("x", "X"));
				}
				//导入校验
				if (!Common.isNotNull(infoVo.getSocialPayMonth())) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保缴纳月份不可为空！"));
					continue;
				}
				if (!Common.isNotNull(infoVo.getSocialCreateMonth())) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保生成月份不可为空！"));
					continue;
				}
				if (!Common.isNotNull(infoVo.getSocialPayAddr())) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保缴纳地不可为空！"));
					continue;
				}
				//无对应员工的社保数据
				if (null != socialMap || null != socialMapTemp) {
					//采用客服导入的地址
					areaArray = infoVo.getSocialPayAddr().split(CommonConstants.CENTER_SPLIT_LINE_STRING);
					infoVo = initAddress(areaArray, areaMap2, infoVo);
					if (null != socialMap) {
						socialInfo = socialMap.get(infoVo.getEmpIdcard()
								+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialProvince()
								+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialCity()
								+ CommonConstants.DOWN_LINE_STRING + (null == infoVo.getSocialTown()
								? "null" : infoVo.getSocialTown()));
					}
					//对身份证与人员姓名的对应关系进行校验
					if (socialInfo != null && !socialInfo.getEmpName().equals(infoVo.getEmpName())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "姓名与身份证信息不一致，请核实后再次尝试！"));
						continue;
					}
					if (socialInfo != null && socialInfo.getSocialStartDate() == null) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpIdcard() + "的社保起缴日期为空！"));
						continue;
					}
					if (null == socialInfo || (null != socialInfo && !ServiceUtil.checkMothForPaymentImport(
							socialInfo.getSocialStartDate(), infoVo.getSocialPayMonth(), socialInfo.getSocialReduceDate()))) {
						if (socialMapTemp.size() > CommonConstants.ZERO_INT) {
							socialInfo = socialMapTemp.get(infoVo.getEmpIdcard()
									+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialProvince()
									+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialCity()
									+ CommonConstants.DOWN_LINE_STRING + (null == infoVo.getSocialTown()
									? "null" : infoVo.getSocialTown()));
							//对身份证与人员姓名的对应关系进行校验
							if (socialInfo != null && !socialInfo.getEmpName().equals(infoVo.getEmpName())) {
								errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpIdcard() +
										"姓名与身份证信息不一致，请核实后再次尝试！"));
								continue;
							}
							if (null != socialInfo && !ServiceUtil.checkMothForPaymentImport(socialInfo.getSocialStartDate()
									, infoVo.getSocialPayMonth(), socialInfo.getSocialReduceDate())) {
								socialInfo = null;
								for (TSocialInfo s : socialInfoListTemp) {
									if (s.getEmpIdcard().equals(infoVo.getEmpIdcard()) && ServiceUtil.checkMothForPaymentImport(
											s.getSocialStartDate(), infoVo.getSocialPayMonth(), s.getSocialReduceDate())) {
										socialInfo = checkAddress(areaArray, areaMap, s);
										if (null != socialInfo) {
											break;
										}
									}
								}
							}
						}
					}
				}
				if (null == socialInfo) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "无对应员工" +
							infoVo.getEmpIdcard() + "的社保数据(请查验社保办理状态|缴纳地|起缴月份|停缴月份)"));
					continue;
				}
				//如果导入项目数大于办理成功项目数给提示，少于给进，有问题自行删除后导入
				checkRes = checkRepeatInfo(socialInfo, infoVo);
				if (null != checkRes) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), checkRes));
					continue;
				}

				//查看缴纳月是否为空
				if (!Common.isNotNull(infoVo.getSocialPayMonth())) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "必填项校验失败：社保缴纳月份不可为空！"));
					continue;
				}

				//判断是否存在养老缴费数据
				if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(infoVo.getUnitPensionMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalPensionMoney())).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoPensionMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.YL);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(infoVo.getUnitPensionMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalPensionMoney())), BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitPensionMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getPersonalPensionMoney()))).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的养老缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				//判断是否存在失业缴费数据
				if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(infoVo.getUnitUnemploymentMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalUnemploymentMoney())).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoUnEmpMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.SY);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(infoVo.getUnitUnemploymentMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalUnemploymentMoney())), BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitUnemploymentMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getPersonalUnemploymentMoney()))).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的失业缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				//判断是否存在医保缴费数据
				if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(infoVo.getUnitMedicalMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalMedicalMoney())).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoMedicalMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.YB);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(infoVo.getUnitMedicalMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalMedicalMoney())), BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitMedicalMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getPersonalMedicalMoney()))).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的医保缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				//判断是否存在医疗救助金缴费数据
				if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(infoVo.getPersonalBigmailmentMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getUnitBigmailmentMoney())).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoBigMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.DB);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(infoVo.getUnitBigmailmentMoney()),
						BigDecimalUtils.isNullToZero(infoVo.getPersonalBigmailmentMoney())), BigDecimalUtils.safeAdd(
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitBigmailmentMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getPersonalBigmailmentMoney()))).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的医疗救助金缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				//判断是否存在工伤缴费数据
				if (BigDecimalUtils.isNullToZero(infoVo.getUnitInjuryMoney()).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoInjuryMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.GS);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.isNullToZero(infoVo.getUnitInjuryMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitInjuryMoney())).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的单位工伤缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				//判断是否存在生育缴费数据
				if (BigDecimalUtils.isNullToZero(infoVo.getUnitBirthMoney()).compareTo(BigDecimal.ZERO) != 0) {
					paymentInfo = paymentInfoBirMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ SocialConstants.BIR);
				}
				//存在社保缴费数据
				if (null != paymentInfo && BigDecimalUtils.safeMultiply(BigDecimalUtils.isNullToZero(infoVo.getUnitBirthMoney()),
						BigDecimalUtils.isNullToZero(paymentInfo.getUnitBirthMoney())).compareTo(BigDecimal.ZERO) > 0) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
							+ "的单位生育缴费数据,请勿重复导入！"));
					continue;
				} else {
					paymentInfo = null;
				}

				if (null == paymentInfo) {
					paymentInfo = new TPaymentInfo();
					paymentInfo.setLockStatus(CommonConstants.ZERO_STRING);
					paymentInfo.setEmpId(socialInfo.getEmpId());
					paymentInfo.setEmpIdcard(socialInfo.getEmpIdcard());
					paymentInfo.setEmpName(socialInfo.getEmpName());
					paymentInfo.setEmpNo(socialInfo.getEmpNo());
					if (Common.isNotNull(itemMap) && Common.isNotNull(cusMap)) {
						paymentInfo.setSettleDomainId(itemMap.get(socialInfo.getSettleDomain()));
						paymentInfo.setUnitId(cusMap.get(socialInfo.getBelongUnit()));
					}
					paymentInfo.setInauguralTeam(socialInfo.getInauguralTeam());
					paymentInfo.setTelecomNumber(socialInfo.getTelecomNumber());

				}
				paymentInfo.setSocialProvince(socialInfo.getSocialProvince());
				paymentInfo.setSocialCity(socialInfo.getSocialCity());
				paymentInfo.setSocialTown(socialInfo.getSocialTown());


				paymentInfo.setSocialHousehold(socialInfo.getSocialHouseholdName());
				paymentInfo.setSocialPayMonth(infoVo.getSocialPayMonth());
				// 同时设置公积金缴纳日期方便导入处理
				paymentInfo.setProvidentPayMonth(infoVo.getSocialPayMonth());

				if (null != paymentInfo.getSocialProvince()) {
					temp = areaMap.get(paymentInfo.getSocialProvince());
					if (Common.isNotNull(temp)) {
						paymentInfo.setSocialPayAddr(temp);
					}
				}
				if (null != paymentInfo.getSocialCity()) {
					temp = areaMap.get(paymentInfo.getSocialCity());
					if (Common.isNotNull(temp)) {
						paymentInfo.setSocialPayAddr(paymentInfo.getSocialPayAddr() + CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
					}
				}
				if (null != paymentInfo.getSocialTown()) {
					temp = areaMap.get(paymentInfo.getSocialTown());
					if (Common.isNotNull(temp)) {
						paymentInfo.setSocialPayAddr(paymentInfo.getSocialPayAddr() + CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
					}
				}
				paymentInfo.setSocialSecurityNo(infoVo.getSocialSecurityNo());
				paymentInfo.setSocialCreateMonth(infoVo.getSocialCreateMonth());
				paymentInfo.setUnitPensionMoney(infoVo.getUnitPensionMoney());
				paymentInfo.setUnitMedicalMoney(infoVo.getUnitMedicalMoney());
				paymentInfo.setUnitBirthMoney(null == infoVo.getUnitBirthMoney() ? BigDecimal.ZERO : infoVo.getUnitBirthMoney());
				paymentInfo.setUnitBigmailmentMoney(infoVo.getUnitBigmailmentMoney());
				paymentInfo.setUnitInjuryMoney(infoVo.getUnitInjuryMoney());
				paymentInfo.setUnitUnemploymentMoney(infoVo.getUnitUnemploymentMoney());
				paymentInfo.setPersonalBigmailmentMoney(infoVo.getPersonalBigmailmentMoney());
				paymentInfo.setPersonalUnemploymentMoney(infoVo.getPersonalUnemploymentMoney());
				paymentInfo.setPersonalPensionMoney(infoVo.getPersonalPensionMoney());
				paymentInfo.setPersonalMedicalMoney(null == infoVo.getPersonalMedicalMoney()
						? BigDecimal.ZERO : infoVo.getPersonalMedicalMoney());
				paymentInfo.setUnitPensionSet(infoVo.getUnitPensionSet());
				paymentInfo.setUnitPensionPer(infoVo.getUnitPensionPer());
				paymentInfo.setUnitMedicalSet(infoVo.getUnitMedicalSet());
				paymentInfo.setUnitMedicalPer(infoVo.getUnitMedicalPer());
				paymentInfo.setUnitBirthSet(null == infoVo.getUnitBirthSet() ? BigDecimal.ZERO : infoVo.getUnitBirthSet());
				paymentInfo.setUnitBirthPer(infoVo.getUnitBirthPer());
				paymentInfo.setUnitInjurySet(infoVo.getUnitInjurySet());
				paymentInfo.setUnitInjuryPer(infoVo.getUnitInjuryPer());
				paymentInfo.setUnitUnemploymentSet(infoVo.getUnitUnemploymentSet());
				paymentInfo.setUnitUnemploymentPer(infoVo.getUnitUnemploymentPer());
				paymentInfo.setUnitBigailmentPer(infoVo.getUnitBigailmentPer());
				paymentInfo.setPersonalPensionSet(paymentInfo.getUnitPensionSet());
				paymentInfo.setPersonalPensionPer(infoVo.getPersonalPensionPer());
				paymentInfo.setPersonalMedicalPer(infoVo.getPersonalMedicalPer());
				paymentInfo.setPersonalMedicalSet(paymentInfo.getUnitMedicalSet());
				paymentInfo.setPersonalUnemploymentSet(paymentInfo.getUnitUnemploymentSet());
				paymentInfo.setPersonalUnemploymentPer(infoVo.getPersonalUnemploymentPer());
				paymentInfo.setPersonalBigailmentPer(infoVo.getPersonalBigailmentPer());
				paymentInfo.setCompanyAccrual(infoVo.getCompanyAccrual());
				paymentInfo.setPersonalAccrual(infoVo.getPersonalAccrual());
				paymentInfo.setUnitSocialSum(BigDecimalUtils.safeAdd(paymentInfo.getUnitPensionMoney()
						, paymentInfo.getUnitMedicalMoney(), paymentInfo.getUnitBirthMoney()
						, paymentInfo.getUnitInjuryMoney()
						, paymentInfo.getUnitUnemploymentMoney()
						, paymentInfo.getUnitBigmailmentMoney()
						, paymentInfo.getCompanyAccrual()));
				paymentInfo.setSocialSecurityPersonalSum(BigDecimalUtils.safeAdd(paymentInfo.getPersonalBigmailmentMoney()
						, paymentInfo.getPersonalPensionMoney()
						, paymentInfo.getPersonalMedicalMoney()
						, paymentInfo.getPersonalUnemploymentMoney()
						, paymentInfo.getPersonalAccrual()));
				paymentInfo.setSocialSum(BigDecimalUtils.safeAdd(
						paymentInfo.getUnitSocialSum(), paymentInfo.getSocialSecurityPersonalSum()));
				paymentInfo.setSumAll(paymentInfo.getSocialSum());
				paymentInfo.setCreateBy(user.getId());
				paymentInfo.setCreateName(user.getNickname());
				if (null != paymentInfo && Common.isEmpty(paymentInfo.getSocialId())) {
					paymentInfo.setSocialId(UUID.randomUUID().toString());
				}
				if (null != paymentInfo && Common.isNotNull(paymentInfo.getId())) {
					res = baseMapper.updateById(paymentInfo);
					if (res < 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName() + "_缴费库更新失败！"));
						continue;
					}
				} else {
					res = insertAndSTimestamp(paymentInfo);
					if (res < 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName() + "_缴费库保存失败！"));
						continue;
					}
				}
			}
			itemMap.clear();
			cusMap.clear();
		}
		return errorMessageList;
	}

	//比对缴纳地是否一致
	private TSocialInfo checkAddress(String[] areaArray, HashMap<String, String> areaMap, TSocialInfo s) {
		if (null == areaArray || null == areaMap || null == s) {
			return null;
		}
		if (areaArray.length >= CommonConstants.TWO_INT) {
			if (null != s.getSocialProvince()) {
				if (areaArray[0].equals(areaMap.get(s.getSocialProvince()))) {
					if (null != s.getSocialCity()) {
						if (areaArray[1].equals(areaMap.get(s.getSocialCity()))) {
							if (areaArray.length >= CommonConstants.THREE_INT) {
								if (null != s.getSocialTown() && areaArray[CommonConstants.TWO_INT].equals(
										areaMap.get(s.getSocialTown()))) {
									return s;
								}
							} else {
								if (null == s.getSocialTown()) {
									return s;
								}
							}
						}
					} else {
						return null;
					}
				}

			} else {
				return null;
			}

		}
		return null;
	}

	/**
	 * 验证部分办理失败的导入是否有超出部分的数据导入
	 *
	 * @param socialInfo
	 * @param infoVo
	 * @return
	 * @Author fxj
	 * @Date 2021-06-21
	 **/
	private String checkRepeatInfo(TSocialInfo socialInfo, TPaymentInfoVo infoVo) {
		if (checkHandleMoney(socialInfo.getPensionHandle(),
				infoVo.getUnitPensionMoney(), infoVo.getPersonalPensionMoney())) {
			return concatStr("养老");
		}
		if (checkHandleMoney(socialInfo.getMedicalHandle(),
				infoVo.getUnitMedicalMoney(), infoVo.getPersonalMedicalMoney())) {
			return concatStr("医疗");
		}
		if (checkHandleMoney(socialInfo.getUnemployHandle(),
				infoVo.getUnitUnemploymentMoney(), infoVo.getPersonalUnemploymentMoney())) {
			return concatStr("失业");
		}
		if (checkHandleMoney(socialInfo.getWorkInjuryHandle(),
				infoVo.getUnitInjuryMoney(), BigDecimal.ZERO)) {
			return concatStr("工伤");
		}
		if (checkHandleMoney(socialInfo.getBirthHandle(),
				infoVo.getUnitBirthMoney(), BigDecimal.ZERO)) {
			return concatStr("生育");
		}
		if (CommonConstants.ONE_STRING.equals(socialInfo.getIsIllness()) &&
				(Common.isBlankToBigDecimalZero(infoVo.getUnitBigmailmentMoney()).compareTo(
						BigDecimal.ZERO) > CommonConstants.ZERO_INT ||
						Common.isBlankToBigDecimalZero(infoVo.getPersonalBigmailmentMoney()).compareTo(
								BigDecimal.ZERO) > CommonConstants.ZERO_INT)) {
			return "无大病，无需导入大病！";
		}
		if (checkHandleMoney(socialInfo.getBigailmentHandle(),
				infoVo.getUnitBigmailmentMoney(), infoVo.getPersonalBigmailmentMoney())) {
			return concatStr("大病");
		}
		return null;
	}

	private String concatStr(String socialType) {
		return "存在未办理成功的险种：" + socialType + ",请办理成功后，再行导入！";
	}

	private boolean checkHandleMoney(String handleStatus, BigDecimal unitMoney, BigDecimal personalMoney) {
		return CommonConstants.TWO_STRING.equals(handleStatus) &&
				(Common.isBlankToBigDecimalZero(unitMoney).compareTo(BigDecimal.ZERO) > CommonConstants.ZERO_INT ||
						Common.isBlankToBigDecimalZero(personalMoney).compareTo(BigDecimal.ZERO) > CommonConstants.ZERO_INT);
	}

	/**
	 * 拼接排序字段并插入
	 *
	 * @param entity
	 * @return
	 * @Author huyc
	 * @Date 2022-07-25
	 **/
	private int insertAndSTimestamp(TPaymentInfo entity) {
		if (Common.isNotNull(entity.getSocialCreateMonth()) && Common.isNotNull(entity.getSocialPayMonth())) {
			entity.setSortTime(entity.getSocialCreateMonth().concat(entity.getSocialPayMonth()).concat(
					String.valueOf(System.currentTimeMillis())));
		}
		return baseMapper.insert(entity);
	}

	@Override
	public R<List<ErrorMessage>> importSocialHeFeiDiy(InputStream inputStream, String random, String type) {
		YifuUser user = SecurityUtils.getUser();
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TPaymentHeFeiVo> util1 = new ExcelUtil<>(TPaymentHeFeiVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TPaymentHeFeiVo.class, new ReadListener<TPaymentHeFeiVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TPaymentHeFeiVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TPaymentHeFeiVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTPaymentSocialHeFei(cachedDataList, errorMessageList, random, user, type);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}

	@Override
	public R<List<ErrorMessage>> batchImportPaymentFundInfo(InputStream inputStream) {
		YifuUser user = SecurityUtils.getUser();
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TPaymentInfoVo> util1 = new ExcelUtil<>(TPaymentInfoVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TPaymentInfoVo.class, new ReadListener<TPaymentInfoVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TPaymentInfoVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TPaymentInfoVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					batchSavePaymentFundInfo(cachedDataList, errorMessageList, user);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}

	private void batchSavePaymentFundInfo(List<TPaymentInfoVo> list, List<ErrorMessage> errorMessageList, YifuUser user) {

		HashMap<String, String> areaMap = new HashMap<String, String>();
		R<AreaVo> areaListR = upmsDaprUtils.getAreaListR();
		if (Common.isNotNull(areaListR)) {
			AreaVo areaList = areaListR.getData();
			if (null != areaList && !areaList.getSysAreaList().isEmpty()) {
				for (SysArea area : areaList.getSysAreaList()) {
					areaMap.put(Integer.toString(area.getId()), area.getAreaName());
				}
			}
		}
		try {
			if (Common.isNotNull(list)) {
				TPaymentInfo paymentInfo = null;
				TProvidentFund fund = null;
				String temp = null;
				int res = -1;

				//获取身份证列表
				List<String> idcards = list.stream().map(TPaymentInfoVo::getEmpIdcard).collect(Collectors.toList());
				//已存在档案数据
				//已存在派增公积金数据
				List<TProvidentFund> fundList = providentFundMapper.selectList(Wrappers.<TProvidentFund>query().lambda()
						.eq(TProvidentFund::getDeleteFlag, CommonConstants.ZERO_STRING)
						.eq(TProvidentFund::getHandleStatus, CommonConstants.ONE_STRING)
						.in(TProvidentFund::getEmpIdcard, idcards));
				HashMap<String, Object> fundMap = fundList.stream().collect(HashMap::new, (m, v) ->
						m.put(v.getEmpIdcard(), v), HashMap::putAll);

				//已存在派减的公积金数据
				List<TProvidentFund> fundListTemp = providentFundMapper.selectList(Wrappers.<TProvidentFund>query().lambda()
						.eq(TProvidentFund::getDeleteFlag, CommonConstants.ZERO_STRING)
						.eq(TProvidentFund::getHandleStatus, CommonConstants.THREE_STRING)
						.in(TProvidentFund::getEmpIdcard, idcards));
				HashMap<String, Object> fundMapTemp = fundListTemp.stream().collect(HashMap::new, (m, v) ->
						m.put(v.getEmpIdcard(), v), HashMap::putAll);

				List<String> monthList = list.stream().map(TPaymentInfoVo::getProvidentPayMonth).collect(Collectors.toList());

				//已存在社保缴费库数据  非删除状态
				List<TPaymentInfo> paymentInfos = baseMapper.selectListForPaymentImport(monthList, idcards);
				//公积金唯一性检验条件：身份证编码+公积金缴纳月份
				HashMap<String, Object> paymentInfoMap = new HashMap<>();
				if (Common.isNotNull(paymentInfos)) {
					for (TPaymentInfo info : paymentInfos) {
						paymentInfoMap.put(info.getProvidentPayAddr()
										+ CommonConstants.DOWN_LINE_STRING
										+ info.getEmpIdcard()
										+ CommonConstants.DOWN_LINE_STRING
										+ info.getProvidentPayMonth()
										+ CommonConstants.DOWN_LINE_STRING
										+ info.getProvidentCreateMonth()
										+ CommonConstants.DOWN_LINE_STRING
										+ BigDecimalUtils.safeAdd(info.getProvidentSum()).doubleValue()
								, info);
					}
				}
				String[] areaArray = null;

				Map<String,String> cusMap = new HashMap<>();
				Map<String,String> itemMap = new HashMap<>();
				List<TSettleDomainSelectVo> settleDomainR = null;
				R<TSettleDomainListVo> listVo = null;
				listVo = archivesDaprUtil.selectAllSettleDomainSelectVos();
				if (Common.isNotNull(listVo)) {
					TSettleDomainListVo tSettleDomainListVo = listVo.getData();
					if (Common.isNotNull(tSettleDomainListVo) && Common.isNotEmpty(tSettleDomainListVo.getListSelectVO())) {
						settleDomainR = tSettleDomainListVo.getListSelectVO();
					}
				}
				if(CollectionUtils.isNotEmpty(settleDomainR)){
					for (TSettleDomainSelectVo tSettleDomainSelectVo : settleDomainR) {
						cusMap.put(tSettleDomainSelectVo.getCustomerId(), tSettleDomainSelectVo.getCustomerName());
						itemMap.put(tSettleDomainSelectVo.getId(), tSettleDomainSelectVo.getDepartName());
					}
				}
				for (TPaymentInfoVo infoVo : list) {
					if (Common.isNotNull(infoVo.getEmpIdcard())) {
						infoVo.setEmpIdcard(infoVo.getEmpIdcard().replace("x", "X"));
					}
					//检查数据规范性
					if (!Common.isNotNull(infoVo.getEmpIdcard())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "员工身份证不可为空！"));
						continue;
					}
					if (!Common.isNotNull(infoVo.getProvidentPayMonth())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "公积金缴纳月份不可为空！"));
						continue;
					}
					if (!Common.isNotNull(infoVo.getProvidentCreateMonth())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "公积金生成月份不可为空！"));
						continue;
					}
					if (!Common.isNotNull(infoVo.getProvidentPercent())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "公积金单边比例不可为空！"));
						continue;
					}
					if (!Common.isNotNull(infoVo.getUnitProvidentSet())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "公积金单边基数不可为空！"));
						continue;
					}
					if (!Common.isNotNull(infoVo.getProvidentPayAddr())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
								+ CommonConstants.DOWN_LINE_STRING + "公积金缴纳地不可为空！"));
						continue;
					}
					if (fundMap.size() >CommonConstants.ZERO_INT || fundMapTemp.size() >CommonConstants.ZERO_INT) {
						if (fundMap.size() >CommonConstants.ZERO_INT) {
							fund = (TProvidentFund) fundMap.get(infoVo.getEmpIdcard());
							//对身份证与人员姓名的对应关系进行校验
							if (null != fund && !fund.getEmpName().equals(infoVo.getEmpName())) {
								errorMessageList.add
										(new ErrorMessage(infoVo.getRowIndex(), "姓名与身份证信息不一致，请核实后再次尝试！"));
								continue;
							}
						}
						areaArray = infoVo.getProvidentPayAddr().split(CommonConstants.CENTER_SPLIT_LINE_STRING);
						fund = checkAddress(areaArray, areaMap,fund);
						if (null == fund || (null != fund && !ServiceUtil.checkMothForPaymentImport(
								fund.getProvidentStart(), infoVo.getProvidentPayMonth(), fund.getFundReduceDate()))) {
							if (fundMapTemp.size() >CommonConstants.ZERO_INT) {
								fund = (TProvidentFund) fundMapTemp.get(infoVo.getEmpIdcard());
								//对身份证与人员姓名的对应关系进行校验
								if (null != fund && !fund.getEmpName().equals(infoVo.getEmpName())) {
									if (null != fund && !fund.getEmpName().equals(infoVo.getEmpName())) {
										errorMessageList.add
												(new ErrorMessage(infoVo.getRowIndex(), "姓名与身份证信息不一致，请核实后再次尝试！"));
										continue;
									}
									fund = checkAddress(areaArray, areaMap, fund);
									if (null != fund && !ServiceUtil.checkMothForPaymentImport(
											fund.getProvidentStart(), infoVo.getProvidentPayMonth(), fund.getFundReduceDate())) {
										fund = null;
										for (TProvidentFund f : fundListTemp) {
											if (f.getEmpIdcard().equals(infoVo.getEmpIdcard()) && ServiceUtil.checkMothForPaymentImport(
													f.getProvidentStart(), infoVo.getProvidentPayMonth(), f.getFundReduceDate())) {
												fund = checkAddress(areaArray, areaMap,f);
												if (null != fund) {
													break;
												}
											}
										}
									}
								}
							}
						}
						//无对应员工公积金数据
						if (null == fund) {
							errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "无对应员工" + infoVo.getEmpName() +
									CommonConstants.DOWN_LINE_STRING + infoVo.getEmpIdcard()
									+ "的公积金数据(请查验公积金办理状态|缴纳地|起缴月份|停缴月份)！"));
							continue;
						}
						//查看是否有操作对应主体的权限
						if (!Common.isNotNull(infoVo.getProvidentPayMonth())) {
							errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName() +
									CommonConstants.DOWN_LINE_STRING + "必填项校验失败：公积金缴纳月份不可为空！"));
							continue;
						}
						//计算公积金合计，个人金额和单位金额一致
						infoVo.setProvidentSum(BigDecimalUtils.safeAdd(infoVo.getUnitProvidentSum(), infoVo.getUnitProvidentSum()));
						// 判重
						if (paymentInfoMap.size() >CommonConstants.ZERO_INT) {
							paymentInfo = (TPaymentInfo) paymentInfoMap.get(infoVo.getProvidentPayAddr()
									+ CommonConstants.DOWN_LINE_STRING
									+ infoVo.getEmpIdcard().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ infoVo.getProvidentPayMonth().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ infoVo.getProvidentCreateMonth().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ Math.round(BigDecimalUtils.safeAdd(infoVo.getProvidentSum()).doubleValue() * 100) / 100.0);
						}
						//存在公积金缴费数据
						if (null != paymentInfo && ((BigDecimalUtils.isNullToZero(paymentInfo.getProvidentSum()).compareTo(BigDecimal.ZERO) != 0)
								|| ((BigDecimalUtils.isNullToZero(paymentInfo.getSocialSum()).compareTo(BigDecimal.ZERO) == 0)
								&& BigDecimalUtils.isNullToZero(paymentInfo.getProvidentSum()).compareTo(BigDecimal.ZERO) == 0))) {

							//允许覆盖，但已核准表或工资结算或已锁定不允许覆盖
							errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" +
									infoVo.getEmpName() + CommonConstants.DOWN_LINE_STRING + infoVo.getEmpIdcard()
									+ "公积金缴费数据，禁止覆盖！"));
							continue;

						} else {
							paymentInfo = null;
						}

						if (null == paymentInfo) {
							paymentInfo = new TPaymentInfo();
							paymentInfo.setLockStatus(CommonConstants.ZERO_STRING);
							paymentInfo.setEmpId(fund.getEmpId());
							paymentInfo.setEmpIdcard(fund.getEmpIdcard());
							paymentInfo.setEmpName(fund.getEmpName());
							paymentInfo.setEmpNo(fund.getEmpNo());
							if (Common.isNotNull(itemMap) && Common.isNotNull(cusMap)) {
								paymentInfo.setSettleDomainId(itemMap.get(fund.getSettleDomain()));
								paymentInfo.setUnitId(cusMap.get(fund.getBelongUnit()));
							}
							paymentInfo.setInauguralTeam(fund.getInauguralTeam());
							paymentInfo.setTelecomNumber(fund.getTelecomNumber());
						}
						paymentInfo.setProvidentPayMonth(infoVo.getProvidentPayMonth());
						//同时设置社保缴纳日期方便导入处理
						paymentInfo.setSocialPayMonth(infoVo.getProvidentPayMonth());
						paymentInfo.setFundProvince(fund.getFundProvince());
						paymentInfo.setFundCity(fund.getFundCity());
						paymentInfo.setFundTown(fund.getFundTown());
						paymentInfo.setProvidentHousehold(fund.getProvidentHouseholdName());
						if (null != paymentInfo.getFundProvince()) {
							temp = areaMap.get(paymentInfo.getFundProvince());
							if (Common.isNotNull(temp)) {
								paymentInfo.setProvidentPayAddr(temp);
							}
						}
						if (null != paymentInfo.getFundCity()) {
							temp = areaMap.get(paymentInfo.getFundCity());
							if (Common.isNotNull(temp)) {
								paymentInfo.setProvidentPayAddr(paymentInfo.getProvidentPayAddr()
										+ CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
							}
						}
						if (null != paymentInfo.getFundTown()) {
							temp = areaMap.get(paymentInfo.getFundTown());
							if (Common.isNotNull(temp)) {
								paymentInfo.setProvidentPayAddr(paymentInfo.getProvidentPayAddr()
										+ CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
							}
						}

						paymentInfo.setProvidentCreateMonth(infoVo.getProvidentCreateMonth());
						paymentInfo.setUnitProvidentSet(null == infoVo.getUnitProvidentSet() ? BigDecimal.ZERO : infoVo.getUnitProvidentSet());
						paymentInfo.setPersonalProidentSet(null == infoVo.getUnitProvidentSet() ? BigDecimal.ZERO : infoVo.getUnitProvidentSet());
						paymentInfo.setProvidentPercent(null == infoVo.getProvidentPercent() ? BigDecimal.ZERO : infoVo.getProvidentPercent());
						paymentInfo.setProvidentNo(infoVo.getProvidentNo());
						paymentInfo.setPersonalProvidentSum(null == infoVo.getUnitProvidentSum() ? BigDecimal.ZERO : infoVo.getUnitProvidentSum());
						paymentInfo.setUnitProvidentSum(null == infoVo.getUnitProvidentSum() ? BigDecimal.ZERO : infoVo.getUnitProvidentSum());
						paymentInfo.setProvidentSum(BigDecimalUtils.safeAdd(paymentInfo.getUnitProvidentSum(), paymentInfo.getPersonalProvidentSum()));
						paymentInfo.setSumAll(paymentInfo.getProvidentSum());
						if (null != paymentInfo && Common.isEmpty(paymentInfo.getFundId())) {
							paymentInfo.setFundId(UUID.randomUUID().toString());
						}
						if (null != paymentInfo && Common.isNotNull(paymentInfo.getId())) {
							res = baseMapper.updateById(paymentInfo);
							if (res < 0) {
								errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName() +
										infoVo.getEmpName() + "_缴费库覆盖更新失败！"));
								continue;
							}
						} else {
							res = insertAndSTimestamp(paymentInfo);
							if (res < 0) {
								errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpName()
										+ "_缴费库保存失败！"));
								continue;
							}
						}
						if (null != paymentInfo && Common.isNotNull(paymentInfo.getId()) && Common.isNotNull(paymentInfo.getFundId())) {
							paymentInfoMap.put(paymentInfo.getProvidentPayAddr()
									+ CommonConstants.DOWN_LINE_STRING
									+ paymentInfo.getEmpIdcard().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ paymentInfo.getProvidentPayMonth().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ paymentInfo.getProvidentCreateMonth().trim()
									+ CommonConstants.DOWN_LINE_STRING
									+ BigDecimalUtils.safeAdd(paymentInfo.getProvidentSum()).doubleValue(), paymentInfo);
						}
					}
				}
				itemMap.clear();
				cusMap.clear();
			} else {
				errorMessageList.add(new ErrorMessage(-1, "无数据可导入！"));
			}
		} catch (Exception e) {
			log.error("数据批量导入异常：" + e);
		}
	}

	private void importTPaymentSocialHeFei(List<TPaymentHeFeiVo> list, List<ErrorMessage> errorMessageList,
										   String random, YifuUser user, String type) {

		HashMap<String, String> areaMap = new HashMap<String, String>();
		HashMap<String, String> areaMap2 = new HashMap<String, String>();
		R<AreaVo> areaListR = upmsDaprUtils.getAreaListR();
		if (Common.isNotNull(areaListR)) {
			AreaVo areaList = areaListR.getData();
			if (null != areaList && !areaList.getSysAreaList().isEmpty()) {
				for (SysArea area : areaList.getSysAreaList()) {
					areaMap.put(Integer.toString(area.getId()), area.getAreaName());
					areaMap2.put(area.getAreaName() + CommonConstants.DOWN_LINE_STRING + (null == area.getParentId() ?
							"null" : (0 == area.getParentId().intValue() ? "null" : Integer.toString(
							area.getParentId()))), Integer.toString(area.getId()));
				}
			}
		}

		// 判断是否有相同的用户在导入社保费用 存在提示稍后重试
		String key = user.getId() + CommonConstants.DOWN_LINE_STRING + CommonConstants.PAYMENT_SOCIAL_IMPORT;

		// 将以下代码提取出来，使用paymentInfoMap提升性能，避免list多次循环查询数据库浪费性能
		// 导入前做队列空闲判断，防止队列不足出现数据丢失的场景
		if (CollUtil.isNotEmpty(list)) {
			int taskSize = list.size() / partSize + CommonConstants.ONE_INT;
			int residualCapacity = yfSocialImportThreadPoolExecutor.getResidualCapacity();
			if (taskSize > residualCapacity) {
				errorMessageList.add(new ErrorMessage(-1, MsgUtils.getMessage(ErrorCodes.SOCIALINFO_LIST_NUM_LARGE)));
			} else {
				// -----------------------------生成paymentInfoMap本段开始--------------------------------
				//已存在的档案数据
				List<String> monthList = Common.listObjectToStrList(list, ExcelAttributeConstants.SOCIAL_PAY_MONTH).stream().distinct().collect(Collectors.toList());
				//已存在社保缴费库数据  非删除状态
				List<TPaymentInfo> paymentInfos = baseMapper.selectListForPaymentImport(monthList,
						Common.listObjectToStrList(list, ExcelAttributeConstants.EMPIDCARD));
				//养老
				ConcurrentHashMap<String, TPaymentInfo> paymentInfoPensionMap = new ConcurrentHashMap<>();
				//大病救助金
				ConcurrentHashMap<String, TPaymentInfo> paymentInfoBigMap = new ConcurrentHashMap<>();
				//失业
				ConcurrentHashMap<String, TPaymentInfo> paymentInfoUnEmpMap = new ConcurrentHashMap<>();
				//工伤
				ConcurrentHashMap<String, TPaymentInfo> paymentInfoInjuryMap = new ConcurrentHashMap<>();
				//医保
				ConcurrentHashMap<String, TPaymentInfo> paymentInfoMedicalMap = new ConcurrentHashMap<>();
				if (Common.isNotNull(paymentInfos)) {
					for (TPaymentInfo info : paymentInfos) {

						if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitPensionMoney()),
								BigDecimalUtils.isNullToZero(info.getPersonalPensionMoney())).compareTo(BigDecimal.ZERO) != 0) {
							paymentInfoPensionMap.put(info.getSocialPayAddr()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getEmpIdcard()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialPayMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialCreateMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ PaymentConstants.PENSION_RISK
									, info);
						}
						if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitUnemploymentMoney()),
								BigDecimalUtils.isNullToZero(info.getPersonalUnemploymentMoney())).compareTo(BigDecimal.ZERO) != 0) {
							paymentInfoUnEmpMap.put(info.getSocialPayAddr()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getEmpIdcard()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialPayMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialCreateMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ PaymentConstants.UNEMPLOYEEMENT_RISK
									, info);
						}
						if (BigDecimalUtils.isNullToZero(info.getUnitInjuryMoney()).compareTo(BigDecimal.ZERO) != 0) {
							paymentInfoInjuryMap.put(info.getSocialPayAddr()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getEmpIdcard()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialPayMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialCreateMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ PaymentConstants.INJURY_RISK
									, info);
						}
						if (BigDecimalUtils.safeAdd(BigDecimalUtils.isNullToZero(info.getUnitMedicalMoney()),
								BigDecimalUtils.isNullToZero(info.getPersonalMedicalMoney())).compareTo(BigDecimal.ZERO) != 0) {
							paymentInfoMedicalMap.put(info.getSocialPayAddr()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getEmpIdcard()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialPayMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ info.getSocialCreateMonth()
											+ CommonConstants.DOWN_LINE_STRING
											+ PaymentConstants.MEDICAL
									, info);
						}
					}
				}
				// -----------------------------生成paymentInfoMap本段结束--------------------------------

				/**
				 *  修改批量导入社保为线程池的方式。逻辑分析，根据前端传入的list，将list分成每份partSize个。
				 *  有以下3种情况。1.list数量不足partSize，直接进行处理;2.list数量正好可以根据partSize等分，循环处理;3.不能等分有剩余的情况
				 */

				// -----------------------------线程池处理list，批量保存社保信息开始--------------------------------
				List<TPaymentHeFeiVo> tempList = new ArrayList<>();
				AtomicInteger atomicLine = new AtomicInteger(CommonConstants.ZERO_INT);
				List<CompletableFuture<List<ErrorMessage>>> completableFutureList = new ArrayList<>();
				try {
					// 1.list.size()不足partSize，直接执行
					if (list.size() < partSize) {
						CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(()
								-> executeImportSocialListThree(user, atomicLine, random, list, areaMap, areaMap2,
								paymentInfoPensionMap, paymentInfoMedicalMap, paymentInfoUnEmpMap, paymentInfoInjuryMap,
								CommonConstants.ONE_INT, type, errorMessageList), yfSocialImportThreadPoolExecutor);
						completableFutureList.add(listCompletableFuture);
					}

					// 2.list.size()大于partSize，循环分批执行
					int lastIdx = 0;
					if (partSize <= list.size()) {
						// 处理第一个0位元素
						final List<TPaymentHeFeiVo> finalList = list.subList(0, 1);
						CompletableFuture<List<ErrorMessage>> oneCompletableFuture = CompletableFuture.supplyAsync(()
										-> executeImportSocialListThree(user, atomicLine, random, finalList, areaMap,
										areaMap2, paymentInfoPensionMap, paymentInfoMedicalMap, paymentInfoUnEmpMap,
										paymentInfoInjuryMap, CommonConstants.ONE_INT, type, errorMessageList)
								, yfSocialImportThreadPoolExecutor);
						completableFutureList.add(oneCompletableFuture);
						lastIdx = 1;
						for (int i = 1; i < list.size(); i++) {
							// partSize数量的list为一个执行单元
							tempList.add(list.get(i));
							if (i % partSize == 0) {
								lastIdx = i;
								final int idx = i - partSize + 2;
								List<TPaymentHeFeiVo> finalTempList1 = tempList;
								CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(()
												-> executeImportSocialListThree(user, atomicLine, random, finalTempList1
												, areaMap, areaMap2, paymentInfoPensionMap, paymentInfoMedicalMap,
												paymentInfoUnEmpMap, paymentInfoInjuryMap, idx, type, errorMessageList)
												, yfSocialImportThreadPoolExecutor);
								completableFutureList.add(listCompletableFuture);
								tempList = new ArrayList<>();
							}
						}
					}

					// 3.第2种方式执行完后，有余数的情况下，执行3
					if (lastIdx != 0) {
						tempList = new ArrayList<>();
						if (lastIdx == 1) {
							for (int i = lastIdx; i < list.size(); i++) {
								tempList.add(list.get(i));
							}
						} else {
							for (int i = lastIdx + 1; i < list.size(); i++) {
								tempList.add(list.get(i));
							}
							lastIdx += 1;
						}

						List<TPaymentHeFeiVo> finalTempList = tempList;
						int finalLastIdx = lastIdx + 1;
						CompletableFuture<List<ErrorMessage>> listCompletableFuture = CompletableFuture.supplyAsync(()
										-> executeImportSocialListThree(user, atomicLine, random, finalTempList, areaMap,
											areaMap2, paymentInfoPensionMap, paymentInfoMedicalMap, paymentInfoUnEmpMap,
											paymentInfoInjuryMap, finalLastIdx, type, errorMessageList)
											, yfSocialImportThreadPoolExecutor);
						completableFutureList.add(listCompletableFuture);
					}

					// 阻塞当前线程，等待所有的线程执行完毕
					boolean computeFlag;
					do {
						computeFlag = false;
						for (CompletableFuture<List<ErrorMessage>> listCompletableFuture : completableFutureList) {
							if (!listCompletableFuture.isDone()) {
								computeFlag = true;
							}
						}
					} while (computeFlag);

					String importSuccessKey = user.getId() + CommonConstants.DOWN_LINE_STRING + CommonConstants.PAYMENT_SOCIAL_WAIT_EXPORT;
					redisUtil.set(importSuccessKey, random, 1800L);

				} catch (Exception e) {
					log.error("社保缴费库数据批量导入异常：" + e);
					redisUtil.remove(key);
				} finally {
					paymentInfoPensionMap.clear();
					paymentInfoBigMap.clear();
					paymentInfoMedicalMap.clear();
					paymentInfoUnEmpMap.clear();
					paymentInfoInjuryMap.clear();
				}
			}
		}
	}

	private List<ErrorMessage> executeImportSocialListThree(YifuUser user, AtomicInteger atomicLine,
											  String random,
											  List<TPaymentHeFeiVo> list,
											  HashMap<String, String> areaMap,
											  HashMap<String, String> areaMap2,
											  ConcurrentHashMap<String, TPaymentInfo> paymentInfoPensionMap,
											  ConcurrentHashMap<String, TPaymentInfo> paymentInfoMedicalMap,
											  ConcurrentHashMap<String, TPaymentInfo> paymentInfoUnEmpMap,
											  ConcurrentHashMap<String, TPaymentInfo> paymentInfoInjuryMap,
											  int idx, String type,List<ErrorMessage> errorMessageList) {
		int i = idx;
		if (Common.isNotNull(list)) {
			TPaymentInfo payExists = null;
			TSocialInfo socialInfo = null;
			String temp;
			int res = -1;
			List<String> idcards = Common.listObjectToStrList(list, ExcelAttributeConstants.EMPIDCARD);
			// 全部办理成功 和 部分办理失败
			List<TSocialInfo> socialInfoList = socialInfoMapper.selectList(Wrappers.<TSocialInfo>query().lambda()
					.in(TSocialInfo::getEmpIdcard, idcards)
					.and(obj -> obj.eq(TSocialInfo::getHandleStatus, CommonConstants.ONE_STRING)
							.or().eq(TSocialInfo::getHandleStatus, CommonConstants.FIVE_STRING))
					.eq(TSocialInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
			//已派减的
			List<TSocialInfo> socialInfoListTemp = socialInfoMapper.selectList(Wrappers.<TSocialInfo>query().lambda()
					.in(TSocialInfo::getEmpIdcard, idcards)
					.eq(TSocialInfo::getHandleStatus, CommonConstants.THREE_STRING)
					.eq(TSocialInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
			//已存在的社保数据
			HashMap<String, TSocialInfo> socialMap = new HashMap<>();
			if (Common.isNotNull(socialInfoList)) {
				for (TSocialInfo tSocialInfo : socialInfoList) {
					socialMap.put(tSocialInfo.getEmpIdcard()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialProvince()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialCity()
							+ CommonConstants.DOWN_LINE_STRING + (null == tSocialInfo.getSocialTown()
							? "null" : tSocialInfo.getSocialTown()), tSocialInfo);
				}
			}
			//已存在的派减社保数据
			HashMap<String, TSocialInfo> socialMapTemp = new HashMap<>();
			if (Common.isNotNull(socialInfoListTemp)) {
				for (TSocialInfo tSocialInfo : socialInfoListTemp) {
					socialMapTemp.put(tSocialInfo.getEmpIdcard()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialProvince()
							+ CommonConstants.DOWN_LINE_STRING + tSocialInfo.getSocialCity()
							+ CommonConstants.DOWN_LINE_STRING + (null == tSocialInfo.getSocialTown()
							? "null" : tSocialInfo.getSocialTown()), tSocialInfo);
				}
			}

			String[] areaArray;
			String checkRes;

			Map<String,String> cusMap = new HashMap<>();
			Map<String,String> itemMap = new HashMap<>();
			List<TSettleDomainSelectVo> settleDomainR = null;
			R<TSettleDomainListVo> listVo = null;
			listVo = archivesDaprUtil.selectAllSettleDomainSelectVos();
			if (Common.isNotNull(listVo)) {
				TSettleDomainListVo tSettleDomainListVo = listVo.getData();
				if (Common.isNotNull(tSettleDomainListVo) && Common.isNotEmpty(tSettleDomainListVo.getListSelectVO())) {
					settleDomainR = tSettleDomainListVo.getListSelectVO();
				}
			}
			if(CollectionUtils.isNotEmpty(settleDomainR)){
				for (TSettleDomainSelectVo tSettleDomainSelectVo : settleDomainR) {
					cusMap.put(tSettleDomainSelectVo.getCustomerId(), tSettleDomainSelectVo.getCustomerName());
					itemMap.put(tSettleDomainSelectVo.getId(), tSettleDomainSelectVo.getDepartName());
				}
			}
			for (TPaymentHeFeiVo infoVo : list) {
				atomicLine.incrementAndGet();
				++i;
				if (Common.isNotNull(infoVo.getEmpIdcard())) {
					infoVo.setEmpIdcard(infoVo.getEmpIdcard().replace("x", "X"));
				}
				//导入校验
				if (socialThreeCheckBase(random, i, errorMessageList, infoVo, type)) {
					continue;
				}
				//无对应员工的社保数据
				if (socialMap.size() >CommonConstants.ZERO_INT || socialMapTemp.size() >CommonConstants.ZERO_INT) {
					//采用客服导入的地址
					areaArray = infoVo.getSocialPayAddr().split(CommonConstants.CENTER_SPLIT_LINE_STRING);
					infoVo = initAddressThree(areaArray, areaMap2, infoVo);
					if (socialMap.size() >CommonConstants.ZERO_INT) {
						socialInfo = socialMap.get(infoVo.getEmpIdcard()
								+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialProvince()
								+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialCity()
								+ CommonConstants.DOWN_LINE_STRING + (null == infoVo.getSocialTown() ? "null" : infoVo.getSocialTown()));
					}
					//对身份证与人员姓名的对应关系进行校验
					if (socialInfo != null && !socialInfo.getEmpName().equals(infoVo.getEmpName())) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "姓名与身份证信息不一致，请核实后再次尝试！"));
						continue;
					}
					if (socialInfo != null && socialInfo.getSocialStartDate() == null) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpIdcard() + "的社保起缴日期为空！"));
						continue;
					}
					if (null == socialInfo || (null != socialInfo && !ServiceUtil.checkMothForPaymentImport(
							socialInfo.getSocialStartDate(), infoVo.getSocialPayMonth(), socialInfo.getSocialReduceDate()))) {
						if (socialMapTemp.size() >CommonConstants.ZERO_INT) {
							socialInfo = socialMapTemp.get(infoVo.getEmpIdcard()
									+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialProvince()
									+ CommonConstants.DOWN_LINE_STRING + infoVo.getSocialCity()
									+ CommonConstants.DOWN_LINE_STRING + (null == infoVo.getSocialTown() ? "null" : infoVo.getSocialTown()));
							//对身份证与人员姓名的对应关系进行校验
							if (socialInfo != null && !socialInfo.getEmpName().equals(infoVo.getEmpName())) {
								errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "姓名与身份证信息不一致，请核实后再次尝试！"));
								continue;
							}
							if (null != socialInfo && !ServiceUtil.checkMothForPaymentImport(socialInfo.getSocialStartDate()
									, infoVo.getSocialPayMonth(), socialInfo.getSocialReduceDate())) {
								socialInfo = null;
								for (TSocialInfo s : socialInfoListTemp) {
									if (s.getEmpIdcard().equals(infoVo.getEmpIdcard()) && ServiceUtil.checkMothForPaymentImport(
											s.getSocialStartDate(), infoVo.getSocialPayMonth(), s.getSocialReduceDate())) {
										socialInfo = checkAddress(areaArray, areaMap, s);
										if (null != socialInfo) {
											break;
										}
									}
								}
							}
						}
					}
				}
				if (null == socialInfo) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "无对应员工" + infoVo.getEmpIdcard() +
							"的社保数据(请查验社保办理状态|缴纳地|起缴月份|停缴月份)"));
					continue;
				}
				//如果导入项目数大于办理成功项目数给提示，少于给进，有问题自行删除后导入
				checkRes = checkRepeatInfoThree(socialInfo, infoVo, type);
				if (null != checkRes) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), checkRes));
					continue;
				}

				//查看缴纳月是否为空
				if (!Common.isNotNull(infoVo.getSocialPayMonth())) {
					errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "必填项校验失败：社保缴纳月份不可为空！"));
					continue;
				}

				//判断是否存在养老缴费数据
				if (PaymentConstants.PENSION_RISK.equals(infoVo.getRiskType())) {
					payExists = paymentInfoPensionMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ PaymentConstants.PENSION_RISK);
					//存在社保缴费数据
					if (null != payExists && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(infoVo.getPersonalMoney()),
							BigDecimalUtils.isNullToZero(infoVo.getUnitSet())), BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(payExists.getUnitPensionMoney()),
							BigDecimalUtils.isNullToZero(payExists.getPersonalPensionMoney()))).compareTo(BigDecimal.ZERO) > 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
								+ "的养老缴费数据,请勿重复导入！"));
						continue;
					} else {
						payExists = null;
					}
				}

				//判断是否存在失业缴费数据
				if (PaymentConstants.UNEMPLOYEEMENT_RISK.equals(infoVo.getRiskType())) {
					payExists = paymentInfoUnEmpMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ PaymentConstants.UNEMPLOYEEMENT_RISK);
					//存在社保缴费数据
					if (null != payExists && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(infoVo.getPersonalMoney()),
							BigDecimalUtils.isNullToZero(infoVo.getUnitSet())), BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(payExists.getUnitUnemploymentMoney()),
							BigDecimalUtils.isNullToZero(payExists.getPersonalUnemploymentMoney()))).compareTo(BigDecimal.ZERO) > 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
								+ "的失业缴费数据,请勿重复导入！"));
						continue;
					} else {
						payExists = null;
					}
				}

				//判断是否存在医保缴费数据
				if (CommonConstants.ONE_STRING.equals(type)) {
					payExists = paymentInfoMedicalMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ PaymentConstants.MEDICAL);

					//存在社保缴费数据
					if (null != payExists && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(infoVo.getUnitMedicalMoney()),
							BigDecimalUtils.isNullToZero(infoVo.getPersonalMedicalMoney())), BigDecimalUtils.safeAdd(
							BigDecimalUtils.isNullToZero(payExists.getUnitMedicalMoney()),
							BigDecimalUtils.isNullToZero(payExists.getPersonalMedicalMoney()))).compareTo(BigDecimal.ZERO) > 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
								+ "的医保缴费数据,请勿重复导入！"));
						continue;
					} else {
						payExists = null;
					}
				}

				//判断是否存在工伤缴费数据
				if (PaymentConstants.INJURY_RISK.equals(infoVo.getRiskType())) {
					payExists = paymentInfoInjuryMap.get(infoVo.getSocialPayAddr()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getEmpIdcard().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialPayMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ infoVo.getSocialCreateMonth().trim()
							+ CommonConstants.DOWN_LINE_STRING
							+ PaymentConstants.INJURY_RISK);

					//存在社保缴费数据
					if (null != payExists && BigDecimalUtils.safeMultiply(BigDecimalUtils.safeAdd(
									BigDecimalUtils.isNullToZero(infoVo.getUnitMedicalMoney()),
									BigDecimalUtils.isNullToZero(infoVo.getPersonalMedicalMoney())),
							BigDecimalUtils.isNullToZero(payExists.getUnitInjuryMoney())).compareTo(BigDecimal.ZERO) > 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "已存在对应员工身份证" + infoVo.getEmpIdcard()
								+ "的单位工伤缴费数据,请勿重复导入！"));
						continue;
					} else {
						payExists = null;
					}
				}

				if (null == payExists) {
					payExists = new TPaymentInfo();
					payExists.setLockStatus(CommonConstants.ZERO_STRING);
					payExists.setEmpId(socialInfo.getEmpId());
					payExists.setEmpIdcard(socialInfo.getEmpIdcard());
					payExists.setEmpName(socialInfo.getEmpName());
					payExists.setEmpNo(socialInfo.getEmpNo());
					if (Common.isNotNull(itemMap) && Common.isNotNull(cusMap)) {
						payExists.setSettleDomainId(itemMap.get(socialInfo.getSettleDomain()));
						payExists.setUnitId(cusMap.get(socialInfo.getBelongUnit()));
					}
					payExists.setInauguralTeam(socialInfo.getInauguralTeam());
					payExists.setTelecomNumber(socialInfo.getTelecomNumber());
				}
				payExists.setSocialProvince(socialInfo.getSocialProvince());
				payExists.setSocialCity(socialInfo.getSocialCity());
				payExists.setSocialTown(socialInfo.getSocialTown());

				payExists.setSocialHousehold(socialInfo.getSocialHouseholdName());
				payExists.setSocialPayMonth(infoVo.getSocialPayMonth());
				// 同时设置公积金缴纳日期方便导入处理
				payExists.setProvidentPayMonth(infoVo.getSocialPayMonth());

				if (null != payExists.getSocialProvince()) {
					temp = areaMap.get(payExists.getSocialProvince());
					if (Common.isNotNull(temp)) {
						payExists.setSocialPayAddr(temp);
					}
				}
				if (null != payExists.getSocialCity()) {
					temp = areaMap.get(payExists.getSocialCity());
					if (Common.isNotNull(temp)) {
						payExists.setSocialPayAddr(payExists.getSocialPayAddr() + CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
					}
				}
				if (null != payExists.getSocialTown()) {
					temp = areaMap.get(payExists.getSocialTown());
					if (Common.isNotNull(temp)) {
						payExists.setSocialPayAddr(payExists.getSocialPayAddr() + CommonConstants.CENTER_SPLIT_LINE_STRING + temp);
					}
				}
				payExists.setSocialSecurityNo(infoVo.getSocialSecurityNo());
				payExists.setSocialCreateMonth(infoVo.getSocialCreateMonth());
				if (PaymentConstants.PENSION_RISK.equals(infoVo.getRiskType())) {
					payExists.setUnitPensionMoney(infoVo.getUnitMoney());
					payExists.setPersonalPensionMoney(infoVo.getPersonalMoney());
					payExists.setUnitPensionSet(infoVo.getUnitSet());
					payExists.setPersonalPensionSet(infoVo.getPersonalSet());
					payExists.setUnitPensionMoney(infoVo.getUnitMoney());
					payExists.setPersonalPensionMoney(infoVo.getPersonalMoney());
					payExists.setUnitPensionSet(infoVo.getUnitSet());
					payExists.setPersonalPensionSet(infoVo.getPersonalSet());
					payExists.setUnitSocialSum(BigDecimalUtils.safeAdd(payExists.getUnitPensionMoney()
							, payExists.getUnitSocialSum()));
					payExists.setSocialSecurityPersonalSum(BigDecimalUtils.safeAdd(payExists.getPersonalPensionMoney()
							, payExists.getSocialSecurityPersonalSum()));
				}
				if (PaymentConstants.UNEMPLOYEEMENT_RISK.equals(infoVo.getRiskType())) {
					payExists.setUnitUnemploymentMoney(infoVo.getUnitMoney());
					payExists.setPersonalUnemploymentMoney(infoVo.getPersonalMoney());
					payExists.setUnitUnemploymentSet(infoVo.getUnitSet());
					payExists.setPersonalUnemploymentSet(infoVo.getPersonalSet());
					payExists.setUnitUnemploymentMoney(infoVo.getUnitMoney());
					payExists.setPersonalUnemploymentMoney(infoVo.getPersonalMoney());
					payExists.setUnitUnemploymentSet(infoVo.getUnitSet());
					payExists.setPersonalUnemploymentSet(infoVo.getPersonalSet());
					payExists.setUnitSocialSum(BigDecimalUtils.safeAdd(payExists.getUnitUnemploymentMoney()
							, payExists.getUnitSocialSum()));
					payExists.setSocialSecurityPersonalSum(BigDecimalUtils.safeAdd(payExists.getPersonalUnemploymentMoney()
							, payExists.getSocialSecurityPersonalSum()));
				}
				if (PaymentConstants.INJURY_RISK.equals(infoVo.getRiskType())) {
					payExists.setUnitInjuryMoney(infoVo.getUnitMoney());
					payExists.setUnitInjurySet(infoVo.getUnitSet());
					payExists.setUnitInjuryMoney(infoVo.getUnitMoney());
					payExists.setUnitInjurySet(infoVo.getUnitSet());
					payExists.setUnitSocialSum(BigDecimalUtils.safeAdd(payExists.getUnitInjuryMoney()
							, payExists.getUnitSocialSum()));
				}
				if (CommonConstants.ONE_STRING.equals(type)) {
					payExists.setUnitMedicalMoney(infoVo.getUnitMedicalMoney());
					payExists.setUnitMedicalSet(infoVo.getMedicalSet());
					payExists.setPersonalMedicalMoney(infoVo.getPersonalMedicalMoney());
					payExists.setPersonalMedicalSet(infoVo.getMedicalSet());
					payExists.setPersonalBigmailmentMoney(infoVo.getPersonalBigailmentMoney());
					payExists.setUnitBigmailmentMoney(infoVo.getUnitBigailmentMoney());
					payExists.setUnitMedicalMoney(infoVo.getUnitMedicalMoney());
					payExists.setUnitMedicalSet(infoVo.getMedicalSet());
					payExists.setPersonalMedicalMoney(infoVo.getPersonalMedicalMoney());
					payExists.setPersonalMedicalSet(infoVo.getMedicalSet());
					payExists.setPersonalBigmailmentMoney(infoVo.getPersonalBigailmentMoney());
					payExists.setUnitBigmailmentMoney(infoVo.getUnitBigailmentMoney());
					payExists.setSocialSecurityNo(infoVo.getSocialSecurityNo());

					payExists.setUnitSocialSum(BigDecimalUtils.safeAdd(payExists.getUnitMedicalMoney()
							, payExists.getUnitBigmailmentMoney()
							, payExists.getUnitSocialSum()));
					payExists.setSocialSecurityPersonalSum(BigDecimalUtils.safeAdd(payExists.getPersonalMedicalMoney()
							, payExists.getPersonalBigmailmentMoney()
							, payExists.getSocialSecurityPersonalSum()));
				}
				payExists.setSocialSum(BigDecimalUtils.safeAdd(payExists.getUnitSocialSum(), payExists.getSocialSecurityPersonalSum()));
				payExists.setSumAll(payExists.getSocialSum());
				payExists.setCreateBy(user.getId());
				payExists.setCreateName(user.getNickname());
				if (null != payExists && Common.isEmpty(payExists.getSocialId())) {
					payExists.setSocialId(UUID.randomUUID().toString());
				}
				if (null != payExists && Common.isNotNull(payExists.getId())) {
					res = baseMapper.updateById(payExists);
					if (res < 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpIdcard() + "_缴费库更新失败！"));
						continue;
					}
				} else {
					res = insertAndSTimestamp(payExists);
					if (res < 0) {
						errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), infoVo.getEmpIdcard() + "_缴费库保存失败！"));
						continue;
					}
				}
			}
			itemMap.clear();
			cusMap.clear();
		}
		return errorMessageList;
	}

	/**
	 * 导入校验
	 **/
	private boolean socialThreeCheckBase(String random, int i, List<ErrorMessage> errorMessageList, TPaymentHeFeiVo
			infoVo, String type) {
		if (!Common.isNotNull(infoVo.getSocialPayMonth())) {
			errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保缴纳月份不可为空！"));
			return true;
		}
		if (!Common.isNotNull(infoVo.getSocialCreateMonth())) {
			errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保生成月份不可为空！"));
			return true;
		}
		if (!Common.isNotNull(infoVo.getSocialPayAddr())) {
			errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "社保缴纳地不可为空！"));
			return true;
		}
		if (CommonConstants.ZERO_STRING.equals(type) && !PaymentConstants.PENSION_RISK.equals(infoVo.getRiskType())
				&& !PaymentConstants.UNEMPLOYEEMENT_RISK.equals(infoVo.getRiskType())
				&& !PaymentConstants.INJURY_RISK.equals(infoVo.getRiskType())) {
			errorMessageList.add(new ErrorMessage(infoVo.getRowIndex(), "无相关险种！"));
			return true;
		}
		return false;
	}

	/**
	 * 转换缴纳地址为省市县ID
	 **/
	private TPaymentHeFeiVo initAddressThree(String[]
													 areaArray, HashMap<String, String> areaMap2, TPaymentHeFeiVo s) {
		if (null == areaArray || null == areaMap2 || null == s) {
			return s;
		}
		String temp = null;
		if (areaArray.length >= CommonConstants.TWO_INT) {
			temp = areaMap2.get(areaArray[0] + CommonConstants.DOWN_LINE_STRING + "null");
			if (Common.isNotNull(temp)) {
				s.setSocialProvince(Integer.valueOf(temp));
			}
			temp = areaMap2.get(areaArray[1] + CommonConstants.DOWN_LINE_STRING + (null == s.getSocialProvince()
					? "null" : Integer.toString(s.getSocialProvince())));
			if (Common.isNotNull(temp)) {
				s.setSocialCity(Integer.valueOf(temp));
			}
			if (areaArray.length >= CommonConstants.THREE_INT) {
				temp = areaMap2.get(areaArray[2] + CommonConstants.DOWN_LINE_STRING + (null == s.getSocialCity()
						? "null" : Integer.toString(s.getSocialCity())));
				if (Common.isNotNull(temp)) {
					s.setSocialTown(Integer.valueOf(temp));
				}
			}
		}
		return s;
	}

	/**
	 * 验证部分办理失败的导入是否有超出部分的数据导入
	 *
	 * @param socialInfo
	 * @param infoVo
	 * @return
	 * @Author huyc
	 * @Date 2022-07-27
	 **/
	private String checkRepeatInfoThree(TSocialInfo socialInfo, TPaymentHeFeiVo infoVo, String type) {
		if (CommonConstants.ZERO_STRING.equals(type)) {
			if (PaymentConstants.PENSION_RISK.equals(infoVo.getRiskType())
					&& checkHandleMoney(socialInfo.getPensionHandle(),
					infoVo.getUnitMoney(), infoVo.getPersonalMoney())) {
				return concatStr(PaymentConstants.PENSION);
			}
			if (PaymentConstants.UNEMPLOYEEMENT_RISK.equals(infoVo.getRiskType())
					&& checkHandleMoney(socialInfo.getUnemployHandle(),
					infoVo.getUnitMoney(), infoVo.getPersonalMoney())) {
				return concatStr(PaymentConstants.UNEMPLOYEEMENT);
			}
			if (PaymentConstants.INJURY_RISK.equals(infoVo.getRiskType())
					&& checkHandleMoney(socialInfo.getWorkInjuryHandle(),
					infoVo.getUnitMoney(), infoVo.getPersonalMoney())) {
				return concatStr(PaymentConstants.INJURY);
			}
		} else if (CommonConstants.ONE_STRING.equals(type)) {
			if (checkHandleMoney(socialInfo.getMedicalHandle(),
					infoVo.getUnitMedicalMoney(), infoVo.getPersonalMedicalMoney())) {
				return concatStr(PaymentConstants.MEDICAL);
			}
			if (CommonConstants.ONE_STRING.equals(socialInfo.getIsIllness()) &&
					(BigDecimalUtils.isNullToZero(infoVo.getUnitBigailmentMoney()).compareTo(
							BigDecimal.ZERO) != CommonConstants.ZERO_INT)) {
				return "无大病，无需导入大病！";
			}
		}
		return null;
	}

	//比对缴纳地是否一致
	private TProvidentFund checkAddress(String[] areaArray, HashMap<String, String> areaMap, TProvidentFund s) {
		if (null == areaArray || null == areaMap || null == s) {
			return null;
		}
		if (areaArray.length >= CommonConstants.TWO_INT) {
			if (null != s.getFundProvince()) {
				if (areaArray[0].equals(areaMap.get(s.getFundProvince()))) {
					if (null != s.getFundCity()) {
						if (areaArray[1].equals(areaMap.get(s.getFundCity()))) {
							if (areaArray.length >= CommonConstants.THREE_INT) {
								if (null != s.getFundTown() && areaArray[CommonConstants.TWO_INT].equals(
										areaMap.get(s.getFundTown()))) {
									return s;
								}
							} else {
								if (null == s.getFundTown()) {
									return s;
								}
							}
						}
					} else {
						return null;
					}
				}

			} else {
				return null;
			}

		} else if (areaArray.length == 1) {
			if (null != s.getFundProvince() && null == s.getFundCity()) {
				if (areaArray[0].equals(areaMap.get(s.getFundProvince()))) {
					return s;
				}
			} else {
				return null;
			}
		}
		return null;
	}
}
