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

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
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.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.csp.config.WxConfig;
import com.yifu.cloud.plus.v1.csp.constants.RegistConstants;
import com.yifu.cloud.plus.v1.csp.entity.EmployeeRegistration;
import com.yifu.cloud.plus.v1.csp.entity.TCspAttaInfo;
import com.yifu.cloud.plus.v1.csp.entity.TOperationLog;
import com.yifu.cloud.plus.v1.csp.mapper.EmployeeRegistrationMapper;
import com.yifu.cloud.plus.v1.csp.service.EmployeeRegistrationService;
import com.yifu.cloud.plus.v1.csp.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.csp.service.TOperationLogService;
import com.yifu.cloud.plus.v1.csp.vo.*;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysCspDeptVo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.SysAutoDictItem;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProjectBelongDept;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ClientNameConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.UserPermissionVo;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprArchivesProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.*;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TEmployeeInsurancePre;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceDetail;
import com.yifu.cloud.plus.v1.yifu.insurances.util.ValidityUtil;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.TEmployeeInsuranceExitCheckVo;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.TEmployeeInsurancePreVo;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.TEmployeeInsuranceSelectVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TEmployeeInsuranceWorkDayVo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;

/**
 * 入离职登记表
 *
 * @author huych
 * @date 2025-02-25 14:48:11
 */
@Log4j2
@Service
@AllArgsConstructor
@EnableConfigurationProperties(DaprArchivesProperties.class)
public class EmployeeRegistrationServiceImpl extends ServiceImpl<EmployeeRegistrationMapper, EmployeeRegistration> implements EmployeeRegistrationService {

	private final DaprArchivesProperties archivesProperties;

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;

	@Autowired
	private SocialDaprUtils socialDaprUtils;

	@Autowired
	private WxConfig wxConfig;

	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	@Autowired
	private InsuranceDaprUtil insuranceDaprUtil;

	@Autowired
	private OSSUtil ossUtil;

	@Autowired
	private final CheckDaprUtil checkDaprUtil;

	private final TAttaInfoService tAttaInfoService;

	private final TOperationLogService logService;

	/**
	 * 入离职登记表简单分页查询
	 *
	 * @param employeeRegistration 入离职登记表
	 * @return
	 */
	@Override
	public IPage<EmployeeRegistration> getEmployeeRegistrationPage(Page<EmployeeRegistration> page, EmployeeRegistrationSearchVo employeeRegistration) {
		getDtpeAuth(employeeRegistration);
		return baseMapper.getEmployeeRegistrationPage(page, employeeRegistration);
	}

	/**
	 * hr入离职登记表代办列表简单分页查询
	 *
	 * @param employeeRegistration 入离职登记表
	 * @return
	 */
	@Override
	public IPage<EmployeeRegistration> getHrEmployeeRegistrationPage(Page<EmployeeRegistration> page, EmployeeRegistrationSearchVo employeeRegistration) {
		YifuUser user = SecurityUtils.getUser();
		// 全服管理者
		long roleId = 1839501715787390978L;
		boolean isSsc = this.haveRole(user, roleId);
		if (isSsc) {
			employeeRegistration.setCustomerUserLoginname(null);
		}
		return baseMapper.getEmployeeRegistrationPage(page, employeeRegistration);
	}

	/**
	 * 作业自动化-入离职登记列表简单分页查询
	 *
	 * @param employeeRegistration 入离职登记表
	 * @return
	 */
	@Override
	public IPage<EmployeeRegistration> getHrAutoEmployeeRegistrationPage(Page<EmployeeRegistration> page, EmployeeRegistrationSearchVo employeeRegistration) {
		employeeRegistration.setCustomerUserLoginname(null);
		// 项目权限赋值
		employeeRegistration.setType(CommonConstants.TWO_STRING);
		initSearchVo(employeeRegistration);
		return baseMapper.getEmployeeRegistrationPage(page, employeeRegistration);
	}

	/**
	 * 入职待确认简单分页查询表简单分页查询
	 *
	 * @param employeeRegistration 入离职登记表
	 * @return
	 */
	@Override
	public IPage<EmployeeRegistration> getHrConfirmEmployeeRegistrationPage(Page<EmployeeRegistration> page, EmployeeRegistrationSearchVo employeeRegistration) {
		//权限和条件赋值
		initSearchVo(employeeRegistration);
		if (Common.isEmpty(employeeRegistration.getStatusList())) {
			employeeRegistration.setStatusList(CommonConstants.processPreStatus);
		}
		employeeRegistration.setTypeList(CommonConstants.processPreStatus);
		return baseMapper.getEmployeeRegistrationPage(page, employeeRegistration);
	}

	@Override
	public List<EmployeeRegistration> getHrConfirmIdcardList(EmployeeRegistrationSearchVo searchVo) {
		//权限和条件赋值
		initSearchVo(searchVo);
		if (Common.isEmpty(searchVo.getStatusList())) {
			searchVo.setStatusList(CommonConstants.processPreStatus);
		}
		searchVo.setTypeList(CommonConstants.processPreStatus);
		return baseMapper.getHrConfirmIdcardList(searchVo);
	}

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

	/**
	 * 入离职代办表批量导出
	 *
	 * @param searchVo 入离职登记表
	 */
	@Override
	public void listHrExport(HttpServletResponse response, EmployeeRegistrationSearchVo searchVo) {
		// 1.9.8: 前端客服去掉指定人查询
		YifuUser user = SecurityUtils.getUser();
		long roleId = 1839501715787390978L;
		boolean isSsc = this.haveRole(user, roleId);
		if (isSsc) {
			searchVo.setCustomerUserLoginname(null);
		}

		String fileName = "入离职待办任务表批量导出" + DateUtil.getThisTime() + ".xlsx";

		//获取要导出的列表
		List<EmployeeRegistrationHrExportVo> list = new ArrayList<>();
		long count = baseMapper.selectExportCount(searchVo);
		try (ServletOutputStream out = response.getOutputStream()) {
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, EmployeeRegistrationHrExportVo.class).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.selectHrExportList(searchVo);
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcel.writerSheet("入离职待办任务表" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcel.writerSheet("入离职待办任务表" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		}
	}

	/**
	 * 作业自动化-入离职登记导出
	 *
	 * @param searchVo 入离职登记表
	 * @since 1.9.8
	 * @author chenyuxi
	 */
	@Override
	public void hrRegistrationExport(HttpServletResponse response, EmployeeRegistrationSearchVo searchVo) {
		// 1.9.8: 前端客服去掉指定人查询
		searchVo.setCustomerUserLoginname(null);
		// 1.9.8: 项目权限赋值
		searchVo.setType(CommonConstants.TWO_STRING);
		initSearchVo(searchVo);

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

	}

	/**
	 * 入职待确认批量导出
	 * @param searchVo 入职待确认
	 * @return
	 */
	@Override
	public void hrConfirmExport(HttpServletResponse response, EmployeeRegistrationSearchVo searchVo) {
		String fileName = "入职待确认批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<EmployeeRegistrationHrPreExportVo> list = new ArrayList<>();
		//前端客服的所有项目权限赋值
		initSearchVo(searchVo);
		//待办列表只查看未处理的数据
		if (Common.isEmpty(searchVo.getStatusList())) {
			searchVo.setStatusList(CommonConstants.processPreStatus);
		}
		searchVo.setTypeList(CommonConstants.processPreStatus);
		long count = baseMapper.selectExportCount(searchVo);
		try (ServletOutputStream out = response.getOutputStream()) {
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, EmployeeRegistrationHrPreExportVo.class).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.selectHrPreExportList(searchVo);
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcel.writerSheet("入职待确认表" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcel.writerSheet("入职待确认表" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		}
	}

	@Override
	public R<List<ErrorMessage>> importDiy(InputStream inputStream, String deptId, String dataSource) {

		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<EmployeeRegistrationVo> util1 = new ExcelUtil<>(EmployeeRegistrationVo.class);
		YifuUser user = SecurityUtils.getUser();
		//获取项目信息
		R<TSettleDomainSelectVo> domainR = archivesDaprUtil.getSettleDomainSelectVoById(deptId);

		if (null == domainR || null == domainR.getData()) {
			errorMessageList.add(new ErrorMessage(-1, "访问员工基础服务异常："));
			return R.ok(errorMessageList);
		}
		TSettleDomainSelectVo selectVo = domainR.getData();

		// 1.9.8：获取项目配置的字典值
		List<String> postConfigList = new ArrayList<>();
		R<SysAutoDictItemVo> domainDictR = archivesDaprUtil.getDictListByDeptNo(deptId);
		if (Common.isNotNull(domainDictR) && Common.isNotNull(domainDictR.getData()) && Common.isNotNull(domainDictR.getData().getSysAutoDictItemList())) {
			List<SysAutoDictItem> dictItemList = domainDictR.getData().getSysAutoDictItemList();
			for(SysAutoDictItem sysAutoDictItem : dictItemList){
				if("post_type".equals(sysAutoDictItem.getType())){
					postConfigList.add(sysAutoDictItem.getLabel());
				}
			}
		}

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

				@Override
				public void invoke(EmployeeRegistrationVo 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)) {
						errorMessage.setData(data);
						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());
					importEmployeeRegistration(cachedDataList, errorMessageList, user, selectVo, postConfigList, dataSource);
					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 importEmployeeRegistration(List<EmployeeRegistrationVo> excelVOList,
											List<ErrorMessage> errorMessageList, YifuUser user, TSettleDomainSelectVo selectVo,
											List<String> postConfigList, String dataSource) {
		// 1.9.8新增来源区分
		// 没有来源默认是：1客户端
		if(Common.isEmpty(dataSource)){
			dataSource = CommonConstants.ONE_STRING;
		}

		Map<String, String> exitMap = new HashMap<>();
		EmployeeRegistrationVo excel;
		int inNum = 0;
		int outNum = 0;
		List<EmployeeRegistration> insertList = new ArrayList<>();
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			// 插入
			EmployeeRegistration insert = new EmployeeRegistration();
			BeanUtil.copyProperties(excel, insert);
			//表数据验重
			//表内数据重复 员工姓名、员工身份证号码、反馈类型
			StringBuilder errorTemp = new StringBuilder();
			errorTemp.append(excel.getEmployeeName());
			errorTemp.append("_");
			errorTemp.append(excel.getEmpIdcard());
			errorTemp.append("_");
			errorTemp.append(excel.getFeedbackType());
			if (null == exitMap.get(errorTemp.toString())) {
				exitMap.put(errorTemp.toString(), "1");
			} else {
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), RegistConstants.IMPORT_EXIT_CHECK, excel));
				continue;
			}
			insert.setDeptNo(selectVo.getDepartNo());
			// 1.9.8：新增校验
			if(CommonConstants.TWO_STRING.equals(dataSource) && Common.isNotNull(postConfigList) && !postConfigList.contains(insert.getPosition())){
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "岗位不在项目配置的岗位配置项里", excel));
				continue;
			}

			String error = registCheck(insert);
			if (null != error) {
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), error, excel));
				continue;
			}
			// 1.9.8：新增赋值
			insert.setDataSource(dataSource);
			initRegistInfo(insert, user, selectVo);
			insertList.add(insert);
			//新增记录,新增操作记录
			baseMapper.insert(insert);
			if (CommonConstants.ONE_STRING.equals(insert.getFeedbackType())) {
				inNum++;
			} else {
				outNum++;
			}
			logService.saveLog(insert.getId(), CommonConstants.ZERO_STRING, RegistConstants.MESSAGE_REGIST, LocalDateTime.now(),
					insert.getRegistorUsername(), null);
		}
		if (!Common.isEmpty(insertList)) {
			insertList.clear();
			//发送企业微信待办
			EmployeeRegistration msgRegistration = new EmployeeRegistration();
			msgRegistration.setInNum(inNum);
			msgRegistration.setOutNum(outNum);
			msgRegistration.setCustomerUserLoginname(selectVo.getCsLoginName());
			msgRegistration.setDeptName(selectVo.getDepartName());
			msgRegistration.setDeptNo(selectVo.getDepartNo());
			//企业微信消息提醒
			sendMessageToWx(msgRegistration, CommonConstants.THREE_STRING);
		}

	}

	/**
	 * 入职待确认表确认接收
	 *
	 * @param preVo 确认接受vo
	 * @return
	 */
	@Override
	public R confirmReceive(EmployeeRegistrationPreVo preVo) {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(preVo)) {
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		EmployeeRegistration registration = baseMapper.selectById(preVo.getId());
		if (Common.isEmpty(registration) || (Common.isNotNull(registration) &&
				!CommonConstants.ONE_STRING.equals(registration.getProcessStatus()))) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		if (preVo.getServerItem().contains("商险") && !preVo.getEmployeeInsurancePreVos().isEmpty()) {
			List<TEmployeeInsuranceExitCheckVo> errorList = new ArrayList<>();
			TEmployeeInsuranceExitCheckVo checkVo;
			String key;
			// 判断重复性MAP
			Map<String, Integer> keyMap = new HashMap<>();
			for (TEmployeeInsurancePreVo insurancePreVo : preVo.getEmployeeInsurancePreVos()) {
				// 1：重复性判断
				key = this.getFiveKey(insurancePreVo);
				if (keyMap.get(key) == null) {
					keyMap.put(key, CommonConstants.ONE_INT);
				} else {
					return R.other(CommonConstants.TWO_INT,null,"保险公司、险种、购买标准、保单起/止日期不可同时重复！");
				}
				insurancePreVo.setEmpIdcard(registration.getEmpIdcard());
				insurancePreVo.setDeptNo(registration.getDeptNo());
				//商险是否存在判断
				checkVo = checkInsuranceExit(insurancePreVo,registration.getEmployeeName(),registration.getEmpIdcard());
				if (null != checkVo) {
					errorList.add(checkVo);
				} else {
					if (Common.isEmpty(insurancePreVo.getProcessStatus())) {
						insurancePreVo.setProcessStatus(CommonConstants.ZERO_STRING);
					}
				}
			}
			if (!errorList.isEmpty()) {
				return R.other(CommonConstants.TWO_INT,null,errorList);
			}
		}

		//点击“接收确认”的时候，监测到该人员该项目下已有在项的档案时，再次提醒：该人员已在项，
		//状态将更新成“已处理”；处理记录中，针对此情况，记录真实的进项时间，备注：先于登记入项
		EmpProjectStatusVo vo = new EmpProjectStatusVo();
		vo.setEmpIdcard(registration.getEmpIdcard());
		vo.setDeptNo(registration.getDeptNo());
		EmpProjectStatusVo exit = getEmpProjectStatus(vo);
		if (Common.isNotNull(exit)) {
			EmployeeRegistrationReceiveVo receiveVo = new EmployeeRegistrationReceiveVo();
			receiveVo.setId(registration.getId());
			receiveVo.setEmployeeName(registration.getEmployeeName());
			receiveVo.setEmpIdcard(registration.getEmpIdcard());
			receiveVo.setReason(RegistConstants.BEFORE_IN_PROJECT);
			receiveVo.setEmpProjectId(exit.getEmpProjectId());
			receiveVo.setProjectCreateTime(exit.getProjectTime());
			receiveVo.setPreVo(preVo);
			return R.ok(receiveVo);
		}
		registration.setProcessStatus(CommonConstants.ZERO_STRING);
		baseMapper.updateById(registration);
		logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.CONFIRM_SUBMIT, LocalDateTime.now(),
				user.getNickname(), null);
		try {
			//生成档案待建档数据
			initRegistPreInfo(registration, preVo, user, CommonConstants.ZERO_STRING);
			R<String> domainR = archivesDaprUtil.saveRegistPreInfo(preVo);
			if (Common.isNotNull(domainR) && Common.isNotNull(domainR.getData()) &&
					preVo.getServerItem().contains("商险") && !preVo.getEmployeeInsurancePreVos().isEmpty()) {
				//生成商险待购买的数据
				for (TEmployeeInsurancePreVo insurancePreVo : preVo.getEmployeeInsurancePreVos()) {
					initInsruancePreInfo(registration, insurancePreVo, user,domainR.getData());
				}
				insuranceDaprUtil.saveInsurancePreInfo(preVo);
			}
		} catch (Exception e) {
			log.error("执行异常", e);
		}
		return R.ok();
	}

	/**
	 * 入职待确认表确认接收
	 *
	 * @param preVo 确认接受vo
	 * @return
	 */
	@Override
	public R batchConfirmReceive(EmployeeRegistrationPreVo preVo) {
		if (Common.isEmpty(preVo)) {
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		//查询该项目该前端客服下所有待接收的入职登记
		//前端客服的所有项目权限赋值
		EmployeeRegistrationSearchVo searchVo = new EmployeeRegistrationSearchVo();
		initSearchVo(searchVo);
		searchVo.setStatusList(CommonConstants.processPreStatus);
		searchVo.setTypeList(CommonConstants.processPreStatus);
		searchVo.setDeptNo(preVo.getDeptNo());
		if (Common.isNotNull(preVo.getIdcardList())) {
			searchVo.setIdcardList(preVo.getIdcardList());
		}
		List<EmployeeRegistration> registrationList = baseMapper.getEmployeeRegistrationList(searchVo);
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(registrationList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		//商险存在校验
		List<TEmployeeInsuranceExitCheckVo> errorList = new ArrayList<>();
		TEmployeeInsuranceExitCheckVo checkVo;

		List<EmployeeRegistrationReceiveVo> receiveVoList = new ArrayList<>();
		R<TEmployeeInsuranceWorkDayVo> dataR;
		for (EmployeeRegistration registration:registrationList) {
			if (preVo.getServerItem().contains("商险") && !preVo.getEmployeeInsurancePreVos().isEmpty()) {
				TEmployeeInsurancePreVo insurancePreVo = preVo.getEmployeeInsurancePreVos().get(0);
				insurancePreVo.setEmpIdcard(registration.getEmpIdcard());
				insurancePreVo.setDeptNo(registration.getDeptNo());
				//日期赋值
				TEmployeeInsuranceWorkDayVo dayVo = new TEmployeeInsuranceWorkDayVo();
				dayVo.setType(CommonConstants.TWO_STRING);
				dayVo.setRegistDate(registration.getJoinLeaveDate());
				if (insurancePreVo.getBuyType() ==1) {
					dayVo.setAddOrBatch(CommonConstants.ONE_STRING);
				}
				dataR = socialDaprUtils.getBeforeOrAfterWorkDay(dayVo);
				if (Common.isNotNull(dataR) && Common.isNotNull(dataR.getData())
						&& Common.isNotNull(dataR.getData().getRegistDate())
						&& Common.isNotNull(dataR.getData().getPriDisDate())) {
					insurancePreVo.setExpectedCollectionTime(dataR.getData().getPriDisDate());
					insurancePreVo.setPolicyEffect(dataR.getData().getRegistDate());
					if (Common.isEmpty(insurancePreVo.getPolicyStart())) {
						insurancePreVo.setPolicyStart(dataR.getData().getRegistDate());
					}
				} else {
					insurancePreVo.setExpectedCollectionTime(registration.getJoinLeaveDate());
					insurancePreVo.setPolicyEffect(registration.getJoinLeaveDate());
					insurancePreVo.setPolicyStart(registration.getJoinLeaveDate());
				}
				//入职日期需要小于保单截止日期
				if ((DateUtil.dateToString(registration.getJoinLeaveDate(),DateUtil.ISO_EXPANDED_DATE_FORMAT).
						compareTo(DateUtil.dateToString(insurancePreVo.getPolicyEnd(),DateUtil.ISO_EXPANDED_DATE_FORMAT)) > 0)
						|| (DateUtil.dateToString(insurancePreVo.getPolicyStart(),DateUtil.ISO_EXPANDED_DATE_FORMAT).
						compareTo(DateUtil.dateToString(insurancePreVo.getPolicyEnd(),DateUtil.ISO_EXPANDED_DATE_FORMAT)) > 0)) {
					TEmployeeInsuranceExitCheckVo exitCheckVo = new TEmployeeInsuranceExitCheckVo();
					exitCheckVo.setBuyType(insurancePreVo.getBuyType());
					exitCheckVo.setEmployeeName(registration.getEmployeeName());
					exitCheckVo.setEmpIdcard(registration.getEmpIdcard());
					exitCheckVo.setPolicyStart(insurancePreVo.getPolicyStart());
					exitCheckVo.setPolicyEnd(insurancePreVo.getPolicyEnd());
					exitCheckVo.setBuyStandard(insurancePreVo.getBuyStandard());
					exitCheckVo.setInsuranceCompanyName(insurancePreVo.getInsuranceCompanyName());
					exitCheckVo.setInsuranceTypeName(insurancePreVo.getInsuranceTypeName());
					exitCheckVo.setErrorMsg("入职日期需要小于等于保单截止日期/保单开始日期需小于等于保单截止日期");
					errorList.add(exitCheckVo);
					continue;
				}
				//商险是否存在判断
				checkVo = checkInsuranceExit(insurancePreVo, registration.getEmployeeName(), registration.getEmpIdcard());
				if (null != checkVo) {
					errorList.add(checkVo);
					continue;
				} else {
					if (Common.isEmpty(insurancePreVo.getProcessStatus())) {
						insurancePreVo.setProcessStatus(CommonConstants.ZERO_STRING);
					}
				}
			}
			//点击“接收确认”的时候，监测到该人员该项目下已有在项的档案时，再次提醒：该人员已在项，
			//状态将更新成“已处理”；处理记录中，针对此情况，记录真实的进项时间，备注：先于登记入项
			EmpProjectStatusVo vo = new EmpProjectStatusVo();
			vo.setEmpIdcard(registration.getEmpIdcard());
			vo.setDeptNo(registration.getDeptNo());
			EmpProjectStatusVo exit = getEmpProjectStatus(vo);
			if (Common.isNotNull(exit)) {
				EmployeeRegistrationReceiveVo receiveVo = new EmployeeRegistrationReceiveVo();
				receiveVo.setId(registration.getId());
				receiveVo.setEmployeeName(registration.getEmployeeName());
				receiveVo.setEmpIdcard(registration.getEmpIdcard());
				receiveVo.setReason(RegistConstants.BEFORE_IN_PROJECT);
				receiveVo.setEmpProjectId(exit.getEmpProjectId());
				receiveVo.setProjectCreateTime(exit.getProjectTime());
				receiveVo.setPreVo(preVo);
				receiveVoList.add(receiveVo);
				continue;
			}
			registration.setProcessStatus(CommonConstants.ZERO_STRING);
			baseMapper.updateById(registration);
			logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.CONFIRM_SUBMIT, LocalDateTime.now(),
					user.getNickname(), null);
			try {
				//生成档案待建档数据
				initRegistPreInfo(registration, preVo, user, CommonConstants.ZERO_STRING);
				R<String> domainR = archivesDaprUtil.saveRegistPreInfo(preVo);
				if (Common.isNotNull(domainR) && Common.isNotNull(domainR.getData()) &&
						preVo.getServerItem().contains("商险") && !preVo.getEmployeeInsurancePreVos().isEmpty()) {
					//生成商险待购买的数据
					TEmployeeInsurancePreVo insurancePreVo = preVo.getEmployeeInsurancePreVos().get(0);
					initInsruancePreInfo(registration, insurancePreVo, user,domainR.getData());
					insuranceDaprUtil.saveInsurancePreInfo(preVo);
				}
			}catch (Exception e) {
				log.error("执行异常", e);
			}
		}
		EmployeeRegistrationBatchErrorVo batchErrorVo = new EmployeeRegistrationBatchErrorVo();
		batchErrorVo.setRegistrationReceiveVoList(receiveVoList);
		batchErrorVo.setErrorList(errorList);
		if (!errorList.isEmpty()) {
			return R.other(CommonConstants.TWO_INT, null, batchErrorVo);
		}
		if (!receiveVoList.isEmpty() && Common.isNotNull(receiveVoList)) {
			return R.ok(receiveVoList);
		}
		return R.ok();
	}

	@Override
	public R registAdd(EmployeeRegistration registration) {
		//提交校验内容：
		//1、身份证号位数、手机号码位数及格式，就职岗位下拉选择“内勤、揽投员、其他”
		//2、按照类型、按照身份证号、按照项目进行去重校验
		String errorInfo = registCheck(registration);
		if (null != errorInfo) {
			return R.failed(errorInfo);
		} else {
			// 1.9.8: 没有来源默认是：1客户端
			if(Common.isEmpty(registration.getDataSource())){
				registration.setDataSource(CommonConstants.ONE_STRING);
			}
			// 1.9.8: 赋值【最新的客服名称】
			registration.setCustomerUsernameNew(registration.getCustomerUsername());
			baseMapper.insert(registration);
			//更新附件
			updateFileId(registration);
		}
		//企业微信消息提醒
		sendMessageToWx(registration, registration.getFeedbackType());
		//操作记录
		logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.MESSAGE_REGIST, LocalDateTime.now(),
				registration.getRegistorUsername(), null);
		return R.ok();
	}

	@Override
	public R confirmSubmit(EmployeeRegistration registration) {
		YifuUser user = SecurityUtils.getUser();
		EmployeeRegistration registrationNow = baseMapper.selectById(registration.getId());
		if (Common.isEmpty(registrationNow) || !CommonConstants.ONE_STRING.equals(registrationNow.getProcessStatus())) {
			return R.failed(RegistConstants.NO_DATA_TO_HANDLE);
		}
		//点击“接收确认”的时候，监测到该人员该项目下已有在项的档案时，再次提醒：该人员已在项，
		//状态将更新成“已处理”；处理记录中，针对此情况，记录真实的进项时间，备注：先于登记入项
		EmpProjectStatusVo vo = new EmpProjectStatusVo();
		vo.setEmpIdcard(registrationNow.getEmpIdcard());
		vo.setDeptNo(registrationNow.getDeptNo());
		EmpProjectStatusVo exit;
		if (CommonConstants.ONE_STRING.equals(registrationNow.getFeedbackType())) {
			exit = getEmpProjectStatus(vo);
		} else {
			exit = getOutEmpProjectStatus(vo);
		}
		if (Common.isNotNull(exit)) {
			return R.ok(exit);
		}
		registrationNow.setProcessStatus(CommonConstants.ZERO_STRING);
		baseMapper.updateById(registrationNow);
		logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.CONFIRM_SUBMIT, LocalDateTime.now(),
				user.getNickname(), null);
		return R.ok();
	}

	@Override
	public R updateRegist(EmployeeRegistration registration) {
		YifuUser user = SecurityUtils.getUser();
		EmployeeRegistration registrationNow = baseMapper.selectById(registration.getId());
		if (Common.isEmpty(registrationNow) || !CommonConstants.ONE_STRING.equals(registrationNow.getProcessStatus())) {
			return R.failed(RegistConstants.NO_DATA_TO_HANDLE);
		}
		registrationNow.setProcessStatus(CommonConstants.TWO_STRING);
		logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.CONFIRM_SUBMIT, LocalDateTime.now(),
				user.getNickname(), null);
		logService.saveLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.MESSAGE_FINISH, registration.getProjectCreateTime(),
				user.getNickname(), CommonConstants.ONE_STRING.equals(registrationNow.getFeedbackType())
						? RegistConstants.BEFORE_IN_PROJECT : RegistConstants.BEFORE_OUT_PROJECT);
		SysCspDeptVo vo = new SysCspDeptVo();
		if (CommonConstants.ONE_STRING.equals(registrationNow.getFeedbackType())) {
			if (Common.isNotNull(registrationNow.getEmpDeptid())) {
				vo.setDepartName(registrationNow.getEmpDeptname());
				vo.setDepartId(Long.valueOf(registrationNow.getEmpDeptid()));
				vo.setProjectId(registrationNow.getEmpProjectId());
				archivesDaprUtil.saveOrDeleteDeptRelation(vo);
			}
		} else {
			vo.setProjectId(registration.getEmpProjectId());
			archivesDaprUtil.saveOrDeleteDeptRelation(vo);
		}
		baseMapper.updateById(registrationNow);
		return R.ok();
	}

	@Override
	public R batchUpdatePreById(List<EmployeeRegistrationReceiveVo> employeeRegistList) {
		YifuUser user = SecurityUtils.getUser();
		EmployeeRegistration registrationNow;
		for (EmployeeRegistrationReceiveVo vo : employeeRegistList) {
			registrationNow = baseMapper.selectById(vo.getId());
			if (Common.isEmpty(registrationNow) || !CommonConstants.ONE_STRING.equals(registrationNow.getProcessStatus())) {
				return R.failed(RegistConstants.NO_DATA_TO_HANDLE);
			}
			registrationNow.setProcessStatus(CommonConstants.TWO_STRING);
			logService.saveLog(registrationNow.getId(), CommonConstants.ZERO_STRING, RegistConstants.CONFIRM_SUBMIT, LocalDateTime.now(),
					user.getNickname(), null);
			logService.saveLog(registrationNow.getId(), CommonConstants.ZERO_STRING, RegistConstants.MESSAGE_FINISH, vo.getProjectCreateTime(),
					user.getNickname(), CommonConstants.ONE_STRING.equals(registrationNow.getFeedbackType())
							? RegistConstants.BEFORE_IN_PROJECT : RegistConstants.BEFORE_OUT_PROJECT);
			SysCspDeptVo deptVo = new SysCspDeptVo();
			if (CommonConstants.ONE_STRING.equals(registrationNow.getFeedbackType())) {
				if (Common.isNotNull(registrationNow.getEmpDeptid())) {
					deptVo.setDepartName(registrationNow.getEmpDeptname());
					deptVo.setDepartId(Long.valueOf(registrationNow.getEmpDeptid()));
					deptVo.setProjectId(vo.getEmpProjectId());
					archivesDaprUtil.saveOrDeleteDeptRelation(deptVo);
				}
				//生成入职确认信息
				try {
					EmployeeRegistrationPreVo preVo = vo.getPreVo();
					initRegistPreInfo(registrationNow, preVo, user, CommonConstants.FOUR_STRING);
					R<String> domainR = archivesDaprUtil.saveRegistPreInfo(preVo);
					if (Common.isNotNull(domainR) && Common.isNotNull(domainR.getData()) &&
							preVo.getServerItem().contains("商险") && !preVo.getEmployeeInsurancePreVos().isEmpty()) {
						//生成商险待购买的数据
						for (TEmployeeInsurancePreVo insurancePreVo : preVo.getEmployeeInsurancePreVos()) {
							initInsruancePreInfo(registrationNow, insurancePreVo, user, domainR.getData());
						}
						insuranceDaprUtil.saveInsurancePreInfo(preVo);
					}
				}catch (Exception e) {
					log.error("执行异常", e);
				}
			} else {
				deptVo.setProjectId(vo.getEmpProjectId());
				archivesDaprUtil.saveOrDeleteDeptRelation(deptVo);
			}
			baseMapper.updateById(registrationNow);
		}
		return R.ok();
	}

	@Override
	public Boolean updateRegistByPreInfo(EmployeeRegistrationUpdateVo updateVo) {
		EmployeeRegistration registration = baseMapper.selectOne(Wrappers.<EmployeeRegistration>query().lambda()
				.eq(EmployeeRegistration::getDeptNo, updateVo.getDeptNo())
				.eq(EmployeeRegistration::getEmpIdcard, updateVo.getEmpIdcard())
				.in(EmployeeRegistration::getProcessStatus, CommonConstants.processStatus)
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(registration)) {
			registration.setProcessStatus(CommonConstants.THREE_STRING);
			baseMapper.updateById(registration);
			//新增拒绝入职操作记录
			logService.saveInnerLog(registration.getId(), CommonConstants.ZERO_STRING, RegistConstants.BACK_RECEIVE, LocalDateTime.now(),
					updateVo.getEmployeeName(), updateVo.getReason(),updateVo.getEmployeeId());
		}
		return true;
	}

	@Override
	public Boolean updateRegistCustomerUserInfo(EmployeeRegistrationCustomerUserUpdateVo updateVo) {
		LambdaUpdateWrapper<EmployeeRegistration> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(EmployeeRegistration::getDeptNo,updateVo.getDeptNo())
				.eq(EmployeeRegistration::getFeedbackType, CommonConstants.ONE_STRING)
				.set(EmployeeRegistration::getCustomerUsernameNew, updateVo.getCustomerUserName());
		this.update(updateWrapper);
		return true;
	}

	@Override
	public long getRegisterPreCount(EmployeeRegistrationSearchVo employeeRegistration) {
		//权限和条件赋值
		initSearchVo(employeeRegistration);
		employeeRegistration.setStatusList(CommonConstants.processPreStatus);
		employeeRegistration.setTypeList(CommonConstants.processPreStatus);
		return baseMapper.selectExportCount(employeeRegistration);
	}

	//单个新增、导入校验
	private String registCheck(EmployeeRegistration registration) {
		//定义判别用户身份证号的正则表达式（要么是15位，要么是18位，最后一位可以为字母）
		Pattern idNumPattern = compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])");
		//通过Pattern获得Matcher
		Matcher idNumMatcher = idNumPattern.matcher(registration.getEmpIdcard());
		if (!idNumMatcher.matches()) {
			return RegistConstants.IDCARD_FORMAT_ERROR;
		}
		if (!ValidityUtil.validateEmpPhone(registration.getEmpPhone())) {
			return RegistConstants.PHONE_FORMAT_ERROR;
		}
		//姓名、身份证+手机号真实性校验
		R<Boolean> checkRes = checkDaprUtil.checkIdCardAndMobile(registration.getEmployeeName(),
				registration.getEmpIdcard(),registration.getEmpPhone());
		if (Common.isEmpty(checkRes) || checkRes.getCode() != CommonConstants.SUCCESS){
			return checkRes.getMsg();
		}
		EmployeeRegistration exit = baseMapper.selectOne(Wrappers.<EmployeeRegistration>query().lambda()
				.eq(EmployeeRegistration::getEmpIdcard, registration.getEmpIdcard())
				.eq(EmployeeRegistration::getDeptNo, registration.getDeptNo())
				.eq(EmployeeRegistration::getFeedbackType, registration.getFeedbackType())
				.in(EmployeeRegistration::getProcessStatus, CommonConstants.processStatus)
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(exit)) {
			return RegistConstants.REGIST_SAME_CHECK;
		}
		//针对离职的判断人员项目档案状态是否正常
		if (CommonConstants.TWO_STRING.equals(registration.getFeedbackType())) {
			EmpProjectStatusVo vo = new EmpProjectStatusVo();
			vo.setEmpIdcard(registration.getEmpIdcard());
			vo.setDeptNo(registration.getDeptNo());
			EmpProjectStatusVo exitVo = getEmpProjectStatus(vo);
			if (Common.isEmpty(exitVo)) {
				return RegistConstants.EMP_PROJECT_EXIT_CHECK;
			}
		}
		return null;
	}

	//获取人员档案信息
	private EmpProjectStatusVo getEmpProjectStatus(EmpProjectStatusVo vo) {
		//找到不在项人员的身份证信息
		R<EmpProjectStatusVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
				, "/temployeeproject/inner/getEmpProjectStatus", vo, EmpProjectStatusVo.class, SecurityConstants.FROM_IN);
		if (sdr != null && sdr.getData() != null) {
			vo = sdr.getData();
			return vo;
		} else {
			return null;
		}
	}

	//获取减项人员档案信息
	private EmpProjectStatusVo getOutEmpProjectStatus(EmpProjectStatusVo vo) {
		//找到不在项人员的身份证信息
		R<EmpProjectStatusVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
				, "/temployeeproject/inner/getOutEmpProjectStatus", vo, EmpProjectStatusVo.class, SecurityConstants.FROM_IN);
		if (sdr != null && sdr.getData() != null) {
			vo = sdr.getData();
			return vo;
		} else {
			return null;
		}
	}

	//数据初始化
	private void initRegistInfo(EmployeeRegistration insert, YifuUser user, TSettleDomainSelectVo selectVo) {
		SysCspDeptVo vo = new SysCspDeptVo();
		vo.setUserId(user.getId());
		vo.setProjectId(selectVo.getId());
		// 1.9.8: 从客服端导入，入职部门默认为空
		if(CommonConstants.ONE_STRING.equals(insert.getDataSource())){
			R<SysCspDeptVo> booleanR = upmsDaprUtils.selectCspDeptByUserDeptId(vo);
			if (Common.isNotNull(booleanR) && Common.isNotNull(booleanR.getData())
					&& Common.isNotNull(booleanR.getData().getDepartId()) && Common.isNotNull(booleanR.getData().getDepartName())) {
				vo = booleanR.getData();
				insert.setRegistorDeptname(vo.getDepartName());
				insert.setRegistorDeptid(vo.getDepartId().toString());
				insert.setEmpDeptid(vo.getDepartId().toString());
				insert.setEmpDeptname(vo.getDepartName());
			} else {
				insert.setRegistorDeptname(user.getDeptName());
				insert.setRegistorDeptid(user.getDeptId().toString());
				insert.setEmpDeptid(user.getDeptId().toString());
				insert.setEmpDeptname(user.getDeptName());
			}
		}

		insert.setRegistorUsername(user.getNickname());
		insert.setRegistorPhone(user.getPhone());
		insert.setCustomerPhone(selectVo.getCsPhone());
		insert.setCustomerUsername(selectVo.getCsName());
		insert.setCustomerUserLoginname(selectVo.getCsLoginName());
		insert.setDeptName(selectVo.getDepartName());
		insert.setDeptId(selectVo.getId());

		// 1.9.8: 新增字段
		insert.setCustomerUsernameNew(selectVo.getCsName());
	}

	//发送企业微信待办
	private void sendMessageToWx(EmployeeRegistration registration, String type) {
		//获取前端客服
		SysUser user;
		if (Common.isEmpty(registration.getCustomerUserLoginname())) {
			return;
		}
		R<SysUser> res = upmsDaprUtils.getSimpleUserByLoginName(registration.getCustomerUserLoginname());
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
			user = res.getData();
		} else {
			return;
		}
		StringBuilder sendUser = null;
		if (Common.isNotKong(user.getWxMessage())) {
			sendUser = new StringBuilder(user.getWxMessage());
		}
		if (sendUser != null) {
			RestTemplate restTemplate = new RestTemplate();
			Map<String, Object> requestMap = new HashMap<>();
			Map<String, Object> textcard = new HashMap<>();
			String authUrl = String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid(), wxConfig.getDomainName() + "/auth/oauth/wxLogin", "66" + registration.getId());
			StringBuilder description = new StringBuilder();
			String title = "";
			if (CommonConstants.ONE_STRING.equals(type) || CommonConstants.TWO_STRING.equals(type)) {
				title = CommonConstants.ONE_STRING.equals(type) ? "人员入职提醒：" : "人员离职提醒：";
				description.append(CommonConstants.ONE_STRING.equals(type) ? "入职日期：" : "离职日期：")
						.append(DateUtil.dateToString(registration.getJoinLeaveDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT)).append("<br>");
				description.append("项目名称：").append(registration.getDeptName()).append("<br>");
				description.append("项目编码：").append(registration.getDeptNo()).append("<br>");
				description.append("员工姓名：").append(registration.getEmployeeName()).append("<br>");
				description.append("身份证号：").append(registration.getEmpIdcard()).append("<br>");
				description.append("手机号码：").append(registration.getEmpPhone()).append("<br>");
			} else {
				title = "人员批量入离职提醒";
				description.append("项目名称：").append(registration.getDeptName()).append("<br>");
				description.append("项目编码：").append(registration.getDeptNo()).append("<br>");
				description.append("入职人数：").append(registration.getInNum()).append("<br>");
				description.append("离职人数：").append(registration.getOutNum()).append("<br>");
			}
			textcard.put("title", title);
			textcard.put("url", authUrl);
			textcard.put("description", description.toString());
			requestMap.put("touser", sendUser);
			requestMap.put("agentid", wxConfig.getAgentid());
			requestMap.put("msgtype", "textcard");
			requestMap.put("textcard", textcard);
			// 必须加上header说明
			if (!wxConfig.sendTextCard(restTemplate, requestMap)) {
				wxConfig.sendTextCard(restTemplate, requestMap);
			}
			//企业微信发送记录
			logService.saveLog(user.getUserId(), CommonConstants.ZERO_STRING, "企业微信消息提醒", LocalDateTime.now(),
					registration.getRegistorUsername(), "提醒人：" + user.getNickname());
		}
	}

	/**
	 * @param searchCspVo 身份证与类型
	 * @Description: 获取已接收的入离职申请，同步所属部门到项目档案里
	 * @Author: hgw
	 * @Date: 2025/3/3 16:57
	 * @return: com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProjectBelongDept
	 **/
	@Override
	public TEmployeeProjectBelongDept getZeroRegistrationAndUpdateTwo(TEmployeeProjectBelongDeptSearchCspVo searchCspVo) {
		List<TEmployeeProjectBelongDept> belongDeptList = baseMapper.getZeroRegistrationByIdCard(searchCspVo);
		if (belongDeptList != null && !belongDeptList.isEmpty()) {
			// 1：加日志
			if (doSaveLogBatch(searchCspVo, belongDeptList)) return null;
			// 更新为已处理
			baseMapper.updateTwoRegistrationByIdCard(searchCspVo);
			return belongDeptList.get(0);
		} else {
			return null;
		}
	}

	/**
	 * 根据ID获取员工注册的详细信息
	 * 此方法首先通过ID从数据库中获取员工注册信息，然后查询与该员工相关的附件信息，
	 * 并为每个附件生成可访问的URL，最后将这些信息一起封装返回
	 * @Author: huych
	 * @param id 员工注册信息的唯一标识符
	 * @return 返回一个封装了员工注册详细信息的结果对象，包括附件信息
	 */
	@Override
	public R<EmployeeRegistration> getDetailInfoById(String id) {
	    // 根据ID从数据库中获取员工注册信息
	    EmployeeRegistration employeeRegistration = baseMapper.selectById(id);
	    // 如果员工注册信息为空，则返回失败结果
	    if (Common.isEmpty(employeeRegistration)) {
	        return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
	    }
	    // 查询与员工相关的附件信息
	    List<TCspAttaInfo> attaInfo = tAttaInfoService.list(Wrappers.<TCspAttaInfo>query().lambda().eq(TCspAttaInfo::getDomainId, id));
	    // 如果附件信息非空，则为每个附件生成可访问的URL，并将其添加到员工注册信息中
	    if (attaInfo != null && !attaInfo.isEmpty()) {
	        URL url;
	        for (TCspAttaInfo a: attaInfo) {
	            url = ossUtil.getObjectUrl(null, a.getAttaSrc());
	            a.setAttaUrl(url.toString());
	        }
	        employeeRegistration.setAttaInfoList(attaInfo);
	    }
	    // 返回封装了员工注册详细信息的成功结果
	    return R.ok(employeeRegistration);
	}

	/**
	 * @Description: 批量处理日志
	 * @Author: hgw
	 * @Date: 2025/3/4 10:41
	 * @return: boolean
	 **/
	private boolean doSaveLogBatch(TEmployeeProjectBelongDeptSearchCspVo searchCspVo, List<TEmployeeProjectBelongDept> belongDeptList) {
		TOperationLog log;
		List<TOperationLog> logList = new ArrayList<>();
		String title = "已处理";
		for (TEmployeeProjectBelongDept belongDept : belongDeptList) {
			log = new TOperationLog();
			log.setMainId(belongDept.getId());
			log.setType(CommonConstants.ZERO_STRING);
			log.setTitle(title);
			log.setOperationName(searchCspVo.getEmpCreateAndLeaveUser());
			log.setOperationTime(searchCspVo.getEmpCreateAndLeaveTime());
			if (searchCspVo.getEmpCreateAndLeaveTime() != null && belongDept.getLogCreateTime() != null
					&& searchCspVo.getEmpCreateAndLeaveTime().isBefore(belongDept.getLogCreateTime())) {
				if (CommonConstants.ONE_STRING.equals(searchCspVo.getFeedbackType())) {
					log.setRemark("入职登记前已增员");
				} else {
					log.setRemark("离职登记前已减员");
				}
			}
			log.setCreateBy(searchCspVo.getUserId());
			log.setCreateName(searchCspVo.getUserName());
			log.setCreateTime(LocalDateTime.now());
			logList.add(log);
		}
		if (!logList.isEmpty()) {
			logService.saveBatch(logList);
		}
		return false;
	}

	/**
	 * @Description: 获取部门权限
	 * @Author: huych
	 * @Date: 2025/3/4 10:41
	 * @return:
	 **/
	private void getDtpeAuth(EmployeeRegistrationSearchVo searchVo) {
		YifuUser user = SecurityUtils.getUser();
		if (null != user && Common.isNotNull(user.getId())) {
			List<UserPermissionVo> cspPermList = user.getCspPermMap();
			if (Common.isNotNull(cspPermList)) {
				// 获取用户在当前项目下的权限
				UserPermissionVo authority = null;
				for (UserPermissionVo userPermissionVo : cspPermList) {
					if (searchVo.getDeptNo().equals(userPermissionVo.getProjectNo())) {
						authority = userPermissionVo;
					}
				}
				if (Common.isNotNull(authority) && !authority.isHaveAll()) {
					if (Common.isNotNull(authority.getDepartIdSet())) {
						searchVo.setDepartIdSet(authority.getDepartIdSet());
					} else {
						searchVo.setId(CommonConstants.ONE_STRING_NEGATE);
					}
				}
			}
		}
	}

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

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

	//入职待建档数据初始化
	private void initRegistPreInfo(EmployeeRegistration registration,EmployeeRegistrationPreVo preVo,
								   YifuUser user,String status) throws ParseException {
		preVo.setId(registration.getId());
		preVo.setCustomerUsername(registration.getCustomerUsernameNew());
		preVo.setCustomerUserLoginname(registration.getCustomerUserLoginname());
		preVo.setDeptName(registration.getDeptName());
		preVo.setDeptId(registration.getDeptId());
		preVo.setDataSource(registration.getDataSource());
		preVo.setPosition(registration.getPosition());
		preVo.setJoinLeaveDate(registration.getJoinLeaveDate());
		preVo.setConfirmTime(DateUtil.getCurrentDateTime());
		preVo.setDeptNo(registration.getDeptNo());
		preVo.setConfirmUser(user.getNickname());
		preVo.setCustomerUsernameNew(registration.getCustomerUsernameNew());
		preVo.setEmpPhone(registration.getEmpPhone());
		preVo.setEmployeeName(registration.getEmployeeName());
		preVo.setEmpIdcard(registration.getEmpIdcard());
		preVo.setCreateBy(user.getId());
		preVo.setCreateName(user.getNickname());
		preVo.setUpdateBy(user.getId());
		preVo.setProcessStatus(status);
		if (Common.isNotNull(preVo.getPushDate())) {
			preVo.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
					registration.getJoinLeaveDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " " + preVo.getPushDate(), DateUtil.DATETIME_PATTERN_MINUTE));
		}
		//附件赋值
		List<TCspAttaInfo> attaInfoList = tAttaInfoService.list(Wrappers.<TCspAttaInfo>query().lambda().eq(TCspAttaInfo::getDomainId, registration.getId()));
		if (attaInfoList != null && !attaInfoList.isEmpty()) {
			List<TAttaInfoSaveVo> attaInfos = new ArrayList<>();
			for (TCspAttaInfo cspAttaInfo : attaInfoList) {
				TAttaInfoSaveVo attaInfo = new TAttaInfoSaveVo();
				BeanUtils.copyProperties(cspAttaInfo,attaInfo);
				if (CommonConstants.ONE_STRING.equals(cspAttaInfo.getRelationType())) {
					attaInfo.setRelationType("31");
				} else if (CommonConstants.TWO_STRING.equals(cspAttaInfo.getRelationType())) {
					attaInfo.setRelationType("32");
				}
				attaInfo.setDomainId(preVo.getId());
				attaInfos.add(attaInfo);
			}
			preVo.setAttaList(attaInfos);
		}

	}

	//商险待购买数据初始化
	private void initInsruancePreInfo(EmployeeRegistration registration,TEmployeeInsurancePreVo preVo,
									  YifuUser user,String id) throws ParseException {
		preVo.setRegisterId(id);
		preVo.setCustomerUsername(registration.getCustomerUsernameNew());
		preVo.setCustomerUserLoginname(registration.getCustomerUserLoginname());
		preVo.setDeptName(registration.getDeptName());
		preVo.setDeptId(registration.getDeptId());
		preVo.setDataSource(registration.getDataSource());
		preVo.setPosition(registration.getPosition());
		preVo.setJoinLeaveDate(registration.getJoinLeaveDate());
		preVo.setDeptNo(registration.getDeptNo());
		preVo.setEmpPhone(registration.getEmpPhone());
		preVo.setEmployeeName(registration.getEmployeeName());
		preVo.setEmpIdcard(registration.getEmpIdcard());
		preVo.setCreateBy(user.getId());
		preVo.setCreateName(user.getNickname());
		preVo.setUpdateBy(user.getId());
		preVo.setRegistTime(LocalDateTimeUtils.convertLDTToDate(registration.getCreateTime()));
		preVo.setRegistUser(registration.getCreateName());

		//预计派单日期
//		if (Common.isEmpty(preVo.getExpectedCollectionTime()) && Common.isNotNull(preVo.getPolicyStartType()) && CommonConstants.ONE_STRING.equals(preVo.getPolicyStartType())) {
//			//新增选择保单开始日期类型= 默认等于入职日期
//			TEmployeeInsuranceWorkDayVo dayVo = new TEmployeeInsuranceWorkDayVo();
//			dayVo.setType(CommonConstants.TWO_STRING);
//			dayVo.setRegistDate(preVo.getJoinLeaveDate());
//			R<TEmployeeInsuranceWorkDayVo> dataR = socialDaprUtils.getBeforeOrAfterWorkDay(dayVo);
//			if (Common.isNotNull(dataR) && Common.isNotNull(dataR.getData())
//					&& Common.isNotNull(dataR.getData().getRegistDate())
//					&& Common.isNotNull(dataR.getData().getPriDisDate())) {
//				preVo.setExpectedCollectionTime(dataR.getData().getPriDisDate());
//				preVo.setPolicyEffect(dataR.getData().getRegistDate());
//				preVo.setPolicyStart(dataR.getData().getRegistDate());
//			} else {
//				preVo.setExpectedCollectionTime(preVo.getJoinLeaveDate());
//				preVo.setPolicyEffect(preVo.getJoinLeaveDate());
//				preVo.setPolicyStart(preVo.getJoinLeaveDate());
//			}
//		}
		preVo.setExpectedCollectionTime(DateUtil.parseDate(DateUtil.dateToString(
				preVo.getExpectedCollectionTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT) + " 15:20", DateUtil.DATETIME_PATTERN_MINUTE));
	}

	//商险是否存在判断
	private TEmployeeInsuranceExitCheckVo checkInsuranceExit(TEmployeeInsurancePreVo preVo,String empName,String empIdcard) {
		//查询入职确认信息数据
		TEmployeeInsuranceExitCheckVo exitCheckVo = new TEmployeeInsuranceExitCheckVo();
		boolean erorFlag = false;
		R<TEmployeeInsuranceSelectVo> dataR = insuranceDaprUtil.selectInsurancePreInfoList(preVo);
		//查询商险数据
		TInsuranceDetail insuranceDetail= null;
		R<TEmployeeInsuranceSelectVo> dataInsurR = insuranceDaprUtil.selectInsuranceInfo(preVo);
		if (Common.isNotNull(dataInsurR) && Common.isNotNull(dataInsurR.getData())&& Common.isNotNull(dataInsurR.getData().getInsuranceDetail())) {
			insuranceDetail = dataInsurR.getData().getInsuranceDetail();
		}
		//二次确认接收场景
		if (Common.isNotNull(dataR) && Common.isNotNull(dataR.getData().getInsurancePreList())
				&& !dataR.getData().getInsurancePreList().isEmpty()) {
			//已存在该身份证的商险入职确认信息
			List<TEmployeeInsurancePre> list = dataR.getData().getInsurancePreList();
			for (TEmployeeInsurancePre pre : list) {
				//项目不同
				if (!preVo.getDeptNo().equals(pre.getDeptNo()) && (pre.getProcessStatus().equals(CommonConstants.ZERO_STRING) ||
						pre.getProcessStatus().equals(CommonConstants.ONE_STRING) ||
						pre.getProcessStatus().equals(CommonConstants.TWO_STRING))) {
					erorFlag = true;
					break;
				}
				//项目相同
				if (null != insuranceDetail && preVo.getDeptNo().equals(insuranceDetail.getDeptNo()) &&
						insuranceDetail.getBuyHandleStatus() != CommonConstants.FIVE_INT &&
						insuranceDetail.getBuyHandleStatus() != CommonConstants.FOUR_INT) {
					erorFlag = true;
					break;
				}
				if (null != insuranceDetail && !preVo.getDeptNo().equals(insuranceDetail.getDeptNo())
						&& insuranceDetail.getBuyHandleStatus() != CommonConstants.FIVE_INT) {
					erorFlag = true;
					break;
				}
			}
		} else {
			//第一次确认接收场景
			if (Common.isNotNull(insuranceDetail)) {
				//项目不同
				if (!preVo.getDeptNo().equals(insuranceDetail.getDeptNo()) && (insuranceDetail.getBuyHandleStatus() == CommonConstants.ONE_INT ||
						insuranceDetail.getBuyHandleStatus() == CommonConstants.TWO_INT ||
						insuranceDetail.getBuyHandleStatus() == CommonConstants.THREE_INT)) {
					erorFlag = true;
				}
				//项目相同带回状态
				if (preVo.getDeptNo().equals(insuranceDetail.getDeptNo()) && insuranceDetail.getBuyHandleStatus() != CommonConstants.FIVE_INT) {
					if (insuranceDetail.getBuyHandleStatus() == CommonConstants.ONE_INT) {
						preVo.setProcessStatus(CommonConstants.THREE_STRING);
					} else if (insuranceDetail.getBuyHandleStatus() == CommonConstants.TWO_INT) {
						preVo.setProcessStatus(CommonConstants.FOUR_STRING);
					} else if (insuranceDetail.getBuyHandleStatus() == CommonConstants.THREE_INT) {
						preVo.setProcessStatus(CommonConstants.SIX_STRING);
					} else if (insuranceDetail.getBuyHandleStatus() == CommonConstants.FOUR_INT) {
						preVo.setProcessStatus(CommonConstants.FIVE_STRING);
					}
					//是否地市自购
					preVo.setIsAddress(insuranceDetail.getIsAdress());
					preVo.setInsurancesId(insuranceDetail.getId());
				}
			}
		}
		//组装错误信息
		if (erorFlag) {
			exitCheckVo.setBuyType(preVo.getBuyType());
			exitCheckVo.setEmployeeName(empName);
			exitCheckVo.setEmpIdcard(empIdcard);
			exitCheckVo.setPolicyStart(preVo.getPolicyStart());
			exitCheckVo.setPolicyEnd(preVo.getPolicyEnd());
			exitCheckVo.setBuyStandard(preVo.getBuyStandard());
			exitCheckVo.setInsuranceCompanyName(preVo.getInsuranceCompanyName());
			exitCheckVo.setInsuranceTypeName(preVo.getInsuranceTypeName());
			exitCheckVo.setErrorMsg("存在流程中/已完结的商险数据");
		} else {
			return null;
		}
		return exitCheckVo;
	}

	/**
	 * @param insurancePreVo
	 * @Description: 获取5个字段构成的关键字
	 * @Author: hgw
	 * @Date: 2025/4/9 11:23
	 * @return: java.lang.String
	 **/
	private String getFiveKey(TEmployeeInsurancePreVo insurancePreVo) {
		// 1：重复性判断
		return isNullToEmpty(insurancePreVo.getBuyStandard()) + CommonConstants.DOWN_LINE_STRING
				+ isNullToEmpty(insurancePreVo.getInsuranceTypeName()) + CommonConstants.DOWN_LINE_STRING
				+ isNullToEmpty(insurancePreVo.getInsuranceCompanyName()) + CommonConstants.DOWN_LINE_STRING
				+ isNullToEmpty(insurancePreVo.getPolicyStart()) + CommonConstants.DOWN_LINE_STRING + isNullToEmpty(insurancePreVo.getPolicyEnd());
	}

	/**
	 * @param str
	 * @Description: 空转化为空字符
	 * @Author: hgw
	 * @Date: 2025/4/9 11:29
	 * @return: java.lang.String
	 **/
	private String isNullToEmpty(Object str) {
		return null == str ? "" : str.toString();
	}

	/**
	 * 更新附件的ID
	 * 当员工注册时，此方法会更新附件信息表中相关记录的ID
	 * 首先，它会将所有与当前员工注册记录关联的附件的ID清空
	 * 然后，对于员工注册记录中的每个附件ID，它会更新附件信息表中对应记录的ID为当前员工的注册ID
	 * @Author: huych
	 * @param registration 员工注册对象，包含附件ID列表
	 */
	private void updateFileId(EmployeeRegistration registration) {
		// 创建更新条件构造器
		LambdaUpdateWrapper<TCspAttaInfo> updateWrapper = new LambdaUpdateWrapper<>();
		// 设置更新条件和新值
		updateWrapper.eq(TCspAttaInfo::getDomainId, registration.getId())
				.set(TCspAttaInfo::getDomainId, CommonConstants.EMPTY_STRING);
		// 执行更新操作，清空附件的域名ID
		tAttaInfoService.update(updateWrapper);
	    // 检查附件ID列表是否不为空
	    if (Common.isNotNull(registration.getAttaIdList()) && !registration.getAttaIdList().isEmpty()) {
	        // 遍历员工注册记录中的附件ID列表
			TCspAttaInfo atta;
	        for (String id : registration.getAttaIdList()) {
	            // 根据ID获取附件信息
	            atta = tAttaInfoService.getById(id);
	            // 更新附件的域名ID为当前员工的注册ID
				if (Common.isNotNull(atta)) {
					atta.setDomainId(registration.getId());
					// 保存更新后的附件信息
					tAttaInfoService.updateById(atta);
				}
	        }
	    }
	}

}
