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

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmployeePreLogMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TEmployeeContractPreService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TEmployeePreLogDetailService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TEmployeePreLogService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.LocalDateTimeUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.equator.HrEquator;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprInsurancesProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SocialDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TEmployeeInsurancePre;
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.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

import static com.alibaba.fastjson.serializer.SerializerFeature.*;

/**
 * 入职确认信息变更日志表
 *
 * @author hgw
 * @date 2025-04-07 15:35:05
 */
@Log4j2
@Service
@AllArgsConstructor
@EnableConfigurationProperties(DaprInsurancesProperties.class)
public class TEmployeePreLogServiceImpl extends ServiceImpl<TEmployeePreLogMapper, TEmployeePreLog> implements TEmployeePreLogService {
	private final DaprInsurancesProperties daprInsurancesProperties;
	private final TEmployeePreLogDetailService tEmployeePreLogDetailService;
	@Lazy
	private final TEmployeeContractPreService contractPreService;
	@Lazy
	private final TAttaInfoService attaInfoService;

	@Autowired
	private SocialDaprUtils socialDaprUtils;

	/**
	 * 入职确认信息变更日志表简单分页查询
	 *
	 * @param tEmployeePreLog 入职确认信息变更日志表
	 * @return
	 */
	@Override
	public IPage<TEmployeePreLog> getTEmployeePreLogPage(Page<TEmployeePreLog> page, TEmployeePreLogSearchVo tEmployeePreLog) {
		if (Common.isNotNull(tEmployeePreLog.getPreId())) {
			IPage<TEmployeePreLog> pageList = baseMapper.getTEmployeePreLogPage(page, tEmployeePreLog);
			List<TEmployeePreLogDetail> detailList = tEmployeePreLogDetailService.getTEmployeePreLogDetailList(tEmployeePreLog.getPreId());
			Map<String, List<TEmployeePreLogDetail>> detailMap = new HashMap<>();
			if (detailList != null && !detailList.isEmpty()) {
				List<TEmployeePreLogDetail> detailList1;
				for (TEmployeePreLogDetail detail : detailList) {
					detailList1 = detailMap.get(detail.getPreLogId());
					if (detailList1 == null) {
						detailList1 = new ArrayList<>();
					}
					detailList1.add(detail);
					detailMap.put(detail.getPreLogId(), detailList1);
				}
			}
			for (TEmployeePreLog tEmployeePreLog1 : pageList.getRecords()) {
				if (detailMap.get(tEmployeePreLog1.getId()) != null) {
					tEmployeePreLog1.setDetailList(detailMap.get(tEmployeePreLog1.getId()));
				}
			}
			return pageList;
		}
		return null;
	}


	@Override
	public List<TEmployeePreLog> noPageDiy(TEmployeePreLogSearchVo searchVo) {
		LambdaQueryWrapper<TEmployeePreLog> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TEmployeePreLog::getId, idList);
		}
		if (searchVo.getLimitStart() >= 0 && searchVo.getLimitEnd() > 0) {
			wrapper.last(" limit " + searchVo.getLimitStart() + "," + searchVo.getLimitEnd());
		}
		wrapper.orderByDesc(BaseEntity::getCreateTime);
		return baseMapper.selectList(wrapper);
	}


	private LambdaQueryWrapper<TEmployeePreLog> buildQueryWrapper(TEmployeePreLogSearchVo entity) {
		LambdaQueryWrapper<TEmployeePreLog> wrapper = Wrappers.lambdaQuery();
		if (ArrayUtil.isNotEmpty(entity.getCreateTimes())) {
			wrapper.ge(TEmployeePreLog::getCreateTime, entity.getCreateTimes()[0])
					.le(TEmployeePreLog::getCreateTime,
							entity.getCreateTimes()[1]);
		}
		if (Common.isNotNull(entity.getCreateName())) {
			wrapper.eq(TEmployeePreLog::getCreateName, entity.getCreateName());
		}
		return wrapper;
	}

	private static final SerializerFeature[] features = new SerializerFeature[]{
			WriteMapNullValue, WriteNullNumberAsZero, WriteNullListAsEmpty,
			WriteNullStringAsEmpty, WriteDateUseDateFormat
	};

	// 修改入职确认信息，忽略的字段变更日志。
	// 2025-4-15 15:44:34 倩倩与龙弟确认：processStatus 不做忽略，如果点确认重置了状态，要有日志，只是目前日志没体现状态。
	private static final List<String> IGNORE_FIELD = new ArrayList<>();
	static {
		IGNORE_FIELD.add("joinLeaveDate");
		IGNORE_FIELD.add("createTime");
		IGNORE_FIELD.add("modelType");

		IGNORE_FIELD.add("empPhone");
		IGNORE_FIELD.add("employeeName");
		IGNORE_FIELD.add("empIdcard");
		IGNORE_FIELD.add("deptNo");
		IGNORE_FIELD.add("deptName");
		IGNORE_FIELD.add("deptId");
		IGNORE_FIELD.add("customerUsername");
		IGNORE_FIELD.add("customerUserLoginname");
		IGNORE_FIELD.add("dataSource");
		IGNORE_FIELD.add("position");
		IGNORE_FIELD.add("createBy");
		IGNORE_FIELD.add("createName");
		IGNORE_FIELD.add("updateBy");
		IGNORE_FIELD.add("isAddress");
	}

	private static final List<String> PRE_IGNORE_FIELD = new ArrayList<>();
	static {
		IGNORE_FIELD.add("createTime");
		IGNORE_FIELD.add("deptId");
		IGNORE_FIELD.add("dataSource");
		IGNORE_FIELD.add("createBy");
		IGNORE_FIELD.add("createName");
		IGNORE_FIELD.add("updateBy");
	}

	private static final List<String> CONTRACT_IGNORE_FIELD = new ArrayList<>();
	static {
		IGNORE_FIELD.add("joinLeaveDate");
		IGNORE_FIELD.add("createTime");
		IGNORE_FIELD.add("empPhone");
		IGNORE_FIELD.add("employeeName");
		IGNORE_FIELD.add("empIdcard");
		IGNORE_FIELD.add("deptNo");
		IGNORE_FIELD.add("deptName");
		IGNORE_FIELD.add("deptId");
		IGNORE_FIELD.add("customerUsername");
		IGNORE_FIELD.add("customerUserLoginname");
		IGNORE_FIELD.add("dataSource");
		IGNORE_FIELD.add("position");
		IGNORE_FIELD.add("contractId");
		IGNORE_FIELD.add("registerId");
		IGNORE_FIELD.add("createBy");
		IGNORE_FIELD.add("createName");
		IGNORE_FIELD.add("updateBy");
		IGNORE_FIELD.add("isAddress");
		IGNORE_FIELD.add("internshipPeriodNum");
		IGNORE_FIELD.add("tryPeriodNum");
		IGNORE_FIELD.add("id");
	}

	@Override
	public void saveModifyAndUpdateInsurance(String empPreId, EmployeeRegistrationPre oldInfo
			, EmployeeRegistrationPre newInfo, YifuUser user, Map<String, TEmployeeInsurancePre> oldMap,
											 TEmployeeContractPre contractOld) {
		try {
			//1.9.11 huych 附件类型不比较差异
			oldInfo.setAttaIdList(null);
			newInfo.setAttaIdList(null);
			oldInfo.setAttaList(null);
			newInfo.setAttaList(null);
			//商险是否已购买list不做比较
			oldInfo.setExitInsuranceInfoList(newInfo.getExitInsuranceInfoList());
			//比较记录不影响业务逻辑，用try套住

			//记录社保是否已购买日志
			String isSocailBuyOld = oldInfo.getSocialIsBuy();
			String isSocailBuyNew = newInfo.getSocialIsBuy();
			//社保是否已购买list不做比较
			oldInfo.setExitSocialInfoList(newInfo.getExitSocialInfoList());
			oldInfo.setSocialIsBuy(newInfo.getSocialIsBuy());

			//记录商险是否已购买日志
			String isBuyOld = oldInfo.getInsuranceIsBuy();
			String isBuyNew = newInfo.getInsuranceIsBuy();
			oldInfo.setInsuranceIsBuy(newInfo.getInsuranceIsBuy());
			//比较差异
			String differenceKey = HrEquator.comparisonValue(oldInfo, newInfo);
			//如果有差异保存差异
			List<TEmployeeInsurancePre> newList = newInfo.getInsurancePreList();
			String diffTitle = null;
			String logId = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
			// 要保存的明细
			List<TEmployeePreLogDetail> detailList = new ArrayList<>();
			// 档案信息修改
			TEmployeePreLogDetail detailEmpLog = null;
			if (Common.isNotNull(differenceKey) && !"insurancePreList".equals(differenceKey)
					&& !"attaIdList".equals(differenceKey) && !"employeeContractPre".equals(differenceKey)
					&& !"dispatchInfoPreVo".equals(differenceKey)) {
				differenceKey = differenceKey.replace("insurancePreList","");
				differenceKey = differenceKey.replace("employeeContractPre","");
				differenceKey = differenceKey.replace("dispatchInfoPreVo","");
				diffTitle = "档案信息";
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.TWO_STRING);
				detailEmpLog.setType(CommonConstants.ONE_STRING);
				this.setLogBaseInfo(empPreId, oldInfo, newInfo, user, differenceKey, logId, detailEmpLog);
				detailList.add(detailEmpLog);
			}
			// 有ID，修改或删除
			if (oldMap == null) {
				oldMap = new HashMap<>();
			}
			List<TEmployeeInsurancePre> saveOrUpdateList = new ArrayList<>();
			// 是否修改了商险
			boolean isModifyInsurance = false;
			TEmployeeInsurancePre oldInsurance;
			TEmployeePreLogDetail detailInsuranceLog;
			String differenceInsuranceKey;
			//如果服务类型包含商险处理商险明细数据
			newInfo.setId(empPreId);
			if (Common.isNotNull(newInfo.getServerItem()) && newInfo.getServerItem().contains("商险")) {
				//是否已购买商险单独加日志
				if (Common.isEmpty(isBuyOld) || (Common.isNotNull(isBuyOld) && !isBuyOld.equals(isBuyNew))) {
					//单独记录是否已购买商险的变更记录
					differenceInsuranceKey = "insuranceIsBuy";
					detailInsuranceLog = new TEmployeePreLogDetail();
					detailInsuranceLog.setModelType(CommonConstants.TWO_STRING);
					detailInsuranceLog.setType(CommonConstants.TWO_STRING);
					Map<String, Object> old = new HashMap<>();
					old.put("insuranceIsBuy", isBuyOld);
					Map<String, Object> simNew = new HashMap<>();
					simNew.put("insuranceIsBuy", isBuyNew);
					this.setLogBaseInfo(empPreId, old, simNew, user, differenceInsuranceKey, logId, detailInsuranceLog);
					isModifyInsurance = true;
					detailList.add(detailInsuranceLog);
				}
				if (!newInfo.getExitInsuranceInfoList().isEmpty()) {
					newInfo.getExitInsuranceInfoList().forEach(insurancePreVo -> insurancePreVo.setRegisterId(empPreId));
				}
				HttpDaprUtil.invokeMethodPost(daprInsurancesProperties.getAppUrl(), daprInsurancesProperties.getAppId()
						, "/temployeeinsurancepre/inner/updateInfoSaveInsurancePreInfo"
						, newInfo, Boolean.class, SecurityConstants.FROM_IN);
			}
			//如果服务类型不包含商险删除商险明细数据
			if (Common.isNotNull(newInfo.getServerItem()) && !newInfo.getServerItem().contains("商险")) {
				HttpDaprUtil.invokeMethodPost(daprInsurancesProperties.getAppUrl(), daprInsurancesProperties.getAppId()
						, "/temployeeinsurancepre/inner/deleteInsurancePreInfo"
						, newInfo, Boolean.class, SecurityConstants.FROM_IN);
			}

			if (newList != null && !newList.isEmpty()) {
				for (TEmployeeInsurancePre newInsurance : newList) {
					differenceInsuranceKey = null;
					if (Common.isNotNull(newInsurance.getModelType())) {
						// 1：新增
						if (CommonConstants.ONE_STRING.equals(newInsurance.getModelType())) {
							saveOrUpdateList.add(newInsurance);
							detailInsuranceLog = new TEmployeePreLogDetail();
							detailInsuranceLog.setModelType(newInsurance.getModelType());
							detailInsuranceLog.setType(CommonConstants.TWO_STRING);
							this.setLogBaseInfo(empPreId, null, newInsurance, user, differenceInsuranceKey, logId, detailInsuranceLog);
							isModifyInsurance = true;
							detailList.add(detailInsuranceLog);
						} else if (CommonConstants.TWO_STRING.equals(newInsurance.getModelType())) {

							// 2：修改有老ID
							if (Common.isNotNull(newInsurance.getId())) {
								oldInsurance = oldMap.get(newInsurance.getId());
								if (oldInsurance != null) {
									differenceInsuranceKey = HrEquator.comparisonValueIgnoreField(oldInsurance, newInsurance, IGNORE_FIELD);
								}
								if (Common.isNotNull(differenceInsuranceKey) || oldInsurance == null) {
									detailInsuranceLog = new TEmployeePreLogDetail();
									detailInsuranceLog.setModelType(CommonConstants.TWO_STRING);
									detailInsuranceLog.setType(CommonConstants.TWO_STRING);
									this.setLogBaseInfo(empPreId, oldInsurance, newInsurance, user, differenceInsuranceKey, logId, detailInsuranceLog);
									isModifyInsurance = true;
									detailList.add(detailInsuranceLog);
								}
							} else {
								// 2：修改无老ID
								detailInsuranceLog = new TEmployeePreLogDetail();
								detailInsuranceLog.setModelType(CommonConstants.ONE_STRING);
								detailInsuranceLog.setType(CommonConstants.TWO_STRING);
								this.setLogBaseInfo(empPreId, null, newInsurance, user, differenceInsuranceKey, logId, detailInsuranceLog);
								isModifyInsurance = true;
								detailList.add(detailInsuranceLog);
							}
							saveOrUpdateList.add(newInsurance);
						} else if (CommonConstants.THREE_STRING.equals(newInsurance.getModelType())) {
							// 3：删除
							detailInsuranceLog = new TEmployeePreLogDetail();
							detailInsuranceLog.setModelType(newInsurance.getModelType());
							detailInsuranceLog.setType(CommonConstants.TWO_STRING);
							this.setLogBaseInfo(empPreId, newInsurance, null, user, differenceInsuranceKey, logId, detailInsuranceLog);
							isModifyInsurance = true;
							detailList.add(detailInsuranceLog);
						}
					} else {
						// 没有调整的
						isModifyInsurance = true;
						saveOrUpdateList.add(newInsurance);
					}
				}
				// 如果变更了
				if (isModifyInsurance) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、商险信息";
					} else {
						diffTitle = "商险信息";
					}
				}
			} else {
				// 没有变更
				if (Common.isNotNull(diffTitle)) {
					diffTitle += "、商险信息";
				} else {
					diffTitle = "商险信息";
				}
			}

			String differenceContractKey = null;
			TEmployeeContractPre employeeContractPre = newInfo.getEmployeeContractPre();
			if (!newInfo.getServerItem().contains("合同") && oldInfo.getServerItem().contains("合同") && Common.isNotNull(contractOld)) {
				//记录操作记录
				contractOld.setAttaList(null);
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.THREE_STRING);
				detailEmpLog.setType(CommonConstants.THREE_STRING);
				this.setLogBaseInfo(empPreId, contractOld, null, user, differenceContractKey, logId, detailEmpLog);
				detailList.add(detailEmpLog);
				if (Common.isNotNull(diffTitle)) {
					diffTitle += "、合同信息";
				} else {
					diffTitle = "合同信息";
				}
				// 创建更新条件构造器
				LambdaUpdateWrapper<TAttaInfo> updateWrapperContract = new LambdaUpdateWrapper<>();
				// 设置更新条件和新值
				updateWrapperContract.eq(TAttaInfo::getDomainId, contractOld.getId())
						.set(TAttaInfo::getDomainId, CommonConstants.EMPTY_STRING);
				// 执行更新操作，清空附件的关联ID
				attaInfoService.update(updateWrapperContract);
				//删除历史的合同待签订数据
				contractPreService.removeById(contractOld.getId());
			}
			if (newInfo.getServerItem().contains("合同") && contractOld != null && employeeContractPre != null) {
				//1.9.11 huych 附件类型不比较差异
				contractOld.setAttaList(null);
				employeeContractPre.setAttaList(null);
				differenceContractKey = HrEquator.comparisonValueIgnoreField(contractOld, employeeContractPre, CONTRACT_IGNORE_FIELD);
				if (differenceContractKey.length() > 0) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、合同信息";
					} else {
						diffTitle = "合同信息";
					}
					detailEmpLog = new TEmployeePreLogDetail();
					detailEmpLog.setModelType(CommonConstants.TWO_STRING);
					detailEmpLog.setType(CommonConstants.THREE_STRING);
					this.setLogBaseInfo(empPreId, contractOld, employeeContractPre, user, differenceContractKey, logId, detailEmpLog);
					detailList.add(detailEmpLog);
				}
			}

			String differenceSocialKey;
			if (newInfo.getServerItem().contains("社保") && (Common.isEmpty(isSocailBuyOld) ||
					(Common.isNotNull(isSocailBuyOld) && !isSocailBuyOld.equals(isSocailBuyNew)))) {
				//单独记录是否已购买社保的变更记录
				differenceSocialKey = "socialIsBuy";
				TEmployeePreLogDetail detailSocialLog = new TEmployeePreLogDetail();
				detailSocialLog.setModelType(CommonConstants.TWO_STRING);
				detailSocialLog.setType(CommonConstants.FOUR_STRING);
				Map<String,Object> old = new HashMap<>();
				old.put("socialIsBuy", isSocailBuyOld);
				Map<String,Object> simNew = new HashMap<>();
				simNew.put("socialIsBuy", isSocailBuyNew);
				this.setLogBaseInfo(empPreId, old, simNew, user, differenceSocialKey, logId, detailSocialLog);
				detailList.add(detailSocialLog);
			}
			//查询老的社保明细
			R<EmployeePreSocialListVo> socialSdr = socialDaprUtils.getSocialPreInfoList(empPreId);
			TDispatchInfoPreVo dispatchInfoPreOldVo = null;
			if (socialSdr != null && socialSdr.getData() != null && null != socialSdr.getData().getDispatchInfoPreVo()) {
				dispatchInfoPreOldVo = socialSdr.getData().getDispatchInfoPreVo();
			}

			TDispatchInfoPreVo dispatchInfoPreVo = newInfo.getDispatchInfoPreVo();
			if (!newInfo.getServerItem().contains("社保") && oldInfo.getServerItem().contains("社保")
					&& Common.isNotNull(dispatchInfoPreOldVo)) {
				//记录操作记录
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.THREE_STRING);
				detailEmpLog.setType(CommonConstants.FOUR_STRING);
				this.setLogBaseInfo(empPreId, dispatchInfoPreOldVo, null, user, null
						, logId, detailEmpLog);
				detailList.add(detailEmpLog);
				if (Common.isNotNull(diffTitle)) {
					diffTitle += "、社保信息";
				} else {
					diffTitle = "社保信息";
				}
			}
			if (newInfo.getServerItem().contains("社保") && dispatchInfoPreOldVo != null && dispatchInfoPreVo != null) {
				differenceSocialKey = HrEquator.comparisonValueIgnoreField(dispatchInfoPreOldVo
						, dispatchInfoPreVo, CONTRACT_IGNORE_FIELD);
				if (differenceSocialKey.length() > 0) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、社保信息";
					} else {
						diffTitle = "社保信息";
					}
					detailEmpLog = new TEmployeePreLogDetail();
					detailEmpLog.setModelType(CommonConstants.TWO_STRING);
					detailEmpLog.setType(CommonConstants.FOUR_STRING);
					this.setLogBaseInfo(empPreId, dispatchInfoPreOldVo, dispatchInfoPreVo, user,
							differenceSocialKey, logId, detailEmpLog);
					detailList.add(detailEmpLog);
				}
			}

			// 有修改，则加日志
			if (Common.isNotNull(diffTitle)) {
				TEmployeePreLog empPreLog = new TEmployeePreLog();
				empPreLog.setId(logId);
				empPreLog.setPreId(empPreId);
				empPreLog.setDiffTitle(diffTitle);
				empPreLog.setCreateTime(LocalDateTime.now());
				if (Common.isNotNull(user)) {
					empPreLog.setCreateBy(user.getId());
					empPreLog.setCreateName(user.getNickname());
				}
				baseMapper.insert(empPreLog);
				if (!detailList.isEmpty()) {
					tEmployeePreLogDetailService.saveBatch(detailList);
				}
			}
			//保存合同待签订数据
			if (newInfo.getServerItem().contains("合同") && employeeContractPre != null) {
				TEmployeeContractPreVo preVo = new TEmployeeContractPreVo();
				BeanUtils.copyProperties(employeeContractPre,preVo);
				if (Common.isNotNull(employeeContractPre.getExpectedCollectionTime()) ) {
					preVo.setExpectedCollectionTime(LocalDateTimeUtils.convertLDTToDate(employeeContractPre.getExpectedCollectionTime()));
				}
				if (Common.isNotNull(employeeContractPre.getExpectedConfirmTime()) ) {
					preVo.setExpectedConfirmTime(LocalDateTimeUtils.convertLDTToDate(employeeContractPre.getExpectedConfirmTime()));
				}
				contractPreService.saveContractPreInfo(preVo);
			}
			//社保待购买数据处理
			if (newInfo.getServerItem().contains("社保")) {
				EmployeeRegistrationPreVo preVo = new EmployeeRegistrationPreVo();
				BeanUtils.copyProperties(newInfo,preVo);
				socialDaprUtils.saveSocialPreInfo(preVo);
			}
			if (!saveOrUpdateList.isEmpty()) {
				HttpDaprUtil.invokeMethodPost(daprInsurancesProperties.getAppUrl(), daprInsurancesProperties.getAppId()
						, "/temployeeinsurancepre/inner/saveOrUpdateInsuranceList"
						, saveOrUpdateList, Boolean.class, SecurityConstants.FROM_IN);
			} else {
				HttpDaprUtil.invokeMethodPost(daprInsurancesProperties.getAppUrl(), daprInsurancesProperties.getAppId()
						, "/temployeeinsurancepre/inner/deleteInsuranceByPreId"
						, empPreId, Boolean.class, SecurityConstants.FROM_IN);
			}
		} catch (Exception e) {
			log.error(JSON.toJSON(newInfo) + "插入修改记录报错>>>", e);
		}
	}

	@Override
	public void saveUpdateInsurance(String empPreId, EmployeeRegistrationPre oldInfo
			, EmployeeRegistrationPre newInfo, String userId, String nickName, Map<String, TEmployeeInsurancePre> oldMap
			, TEmployeeContractPre contractOld) {
		try {
			//1.9.11 huych 附件类型不比较差异
			oldInfo.setAttaIdList(null);
			newInfo.setAttaIdList(null);
			oldInfo.setAttaList(null);
			newInfo.setAttaList(null);
			//记录商险是否已购买日志
			String isBuyOld = oldInfo.getInsuranceIsBuy();
			String isBuyNew = newInfo.getInsuranceIsBuy();
			//记录社保是否已购买日志
			String isSocailBuyOld = oldInfo.getSocialIsBuy();
			String isSocailBuyNew = newInfo.getSocialIsBuy();
			//社保是否已购买list不做比较
			oldInfo.setExitSocialInfoList(newInfo.getExitSocialInfoList());
			oldInfo.setSocialIsBuy(newInfo.getSocialIsBuy());
			//商险是否已购买list不做比较
			oldInfo.setExitInsuranceInfoList(newInfo.getExitInsuranceInfoList());
			oldInfo.setInsuranceIsBuy(newInfo.getInsuranceIsBuy());
			//比较记录不影响业务逻辑，用try套住
			//比较差异
			String differenceKey = HrEquator.comparisonValue(oldInfo, newInfo);
			//如果有差异保存差异
			List<TEmployeeInsurancePre> newList = newInfo.getInsurancePreList();
			String diffTitle = null;
			String logId = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
			// 要保存的明细
			List<TEmployeePreLogDetail> detailList = new ArrayList<>();
			// 档案信息修改
			TEmployeePreLogDetail detailEmpLog = null;

			if (Common.isNotNull(differenceKey) && !"insurancePreList".equals(differenceKey)
					&& !"attaIdList".equals(differenceKey) && !"employeeContractPre".equals(differenceKey)
					&& !"dispatchInfoPreVo".equals(differenceKey)) {
				differenceKey = differenceKey.replace("insurancePreList","");
				differenceKey = differenceKey.replace("employeeContractPre","");
				differenceKey = differenceKey.replace("dispatchInfoPreVo","");
				diffTitle = "档案信息二次确认";
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.TWO_STRING);
				detailEmpLog.setType(CommonConstants.ONE_STRING);
				this.setPreLogBaseInfo(empPreId, oldInfo, newInfo, userId, nickName, differenceKey, logId, detailEmpLog);
				detailList.add(detailEmpLog);
			}
			if (newList != null && !newList.isEmpty()) {
				// 是否修改了商险
				boolean isModifyInsurance = false;
				TEmployeeInsurancePre oldInsurance;
				String differenceInsuranceKey;
				TEmployeePreLogDetail detailInsuranceLog;
				if (Common.isEmpty(isBuyOld) ||(Common.isNotNull(isBuyOld) && !isBuyOld.equals(isBuyNew))) {
					//单独记录是否已购买商险的变更记录
					differenceInsuranceKey = "insuranceIsBuy";
					detailInsuranceLog = new TEmployeePreLogDetail();
					detailInsuranceLog.setModelType(CommonConstants.TWO_STRING);
					detailInsuranceLog.setType(CommonConstants.TWO_STRING);
					Map<String,Object> old = new HashMap<>();
					old.put("insuranceIsBuy", isBuyOld);
					Map<String,Object> simNew = new HashMap<>();
					simNew.put("insuranceIsBuy", isBuyNew);
					this.setPreLogBaseInfo(empPreId, old, simNew, userId, nickName, differenceInsuranceKey, logId, detailInsuranceLog);
					isModifyInsurance = true;
					detailList.add(detailInsuranceLog);
				}
				for (TEmployeeInsurancePre newInsurance : newList) {
					differenceInsuranceKey = null;
					if (CommonConstants.THREE_STRING.equals(newInsurance.getModelType())) {
						// 3：删除
						detailInsuranceLog = new TEmployeePreLogDetail();
						detailInsuranceLog.setModelType(newInsurance.getModelType());
						detailInsuranceLog.setType(CommonConstants.TWO_STRING);
						this.setPreLogBaseInfo(empPreId, newInsurance, null, userId, nickName, differenceInsuranceKey, logId, detailInsuranceLog);
						isModifyInsurance = true;
						detailList.add(detailInsuranceLog);
						continue;
					}
					// 2：修改有老ID
					if (Common.isNotNull(newInsurance.getId())) {
						oldInsurance = oldMap.get(newInsurance.getId());
						if (oldInsurance != null) {
							differenceInsuranceKey = HrEquator.comparisonValueIgnoreField(oldInsurance, newInsurance,PRE_IGNORE_FIELD);
						}
						if (Common.isNotNull(differenceInsuranceKey) || oldInsurance == null) {
							detailInsuranceLog = new TEmployeePreLogDetail();
							detailInsuranceLog.setModelType(CommonConstants.TWO_STRING);
							detailInsuranceLog.setType(CommonConstants.TWO_STRING);
							this.setPreLogBaseInfo(empPreId, oldInsurance, newInsurance, userId, nickName, differenceInsuranceKey, logId, detailInsuranceLog);
							isModifyInsurance = true;
							detailList.add(detailInsuranceLog);
						}
					}
				}
				// 如果变更了
				if (isModifyInsurance) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、商险信息";
					} else {
						diffTitle = "商险信息";
					}
				}
			}

			String differenceContractKey = null;
			TEmployeeContractPre employeeContractPre = newInfo.getEmployeeContractPre();
			if (!newInfo.getServerItem().contains("合同") && oldInfo.getServerItem().contains("合同") && Common.isNotNull(contractOld)) {
				//记录操作记录
				contractOld.setAttaList(null);
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.THREE_STRING);
				detailEmpLog.setType(CommonConstants.THREE_STRING);
				this.setPreLogBaseInfo(empPreId, contractOld, null, userId, nickName,
						differenceContractKey, logId, detailEmpLog);
				detailList.add(detailEmpLog);
				if (Common.isNotNull(diffTitle)) {
					diffTitle += "、合同信息";
				} else {
					diffTitle = "合同信息";
				}
				// 创建更新条件构造器
				LambdaUpdateWrapper<TAttaInfo> updateWrapperContract = new LambdaUpdateWrapper<>();
				// 设置更新条件和新值
				updateWrapperContract.eq(TAttaInfo::getDomainId, contractOld.getId())
						.set(TAttaInfo::getDomainId, CommonConstants.EMPTY_STRING);
				// 执行更新操作，清空附件的关联ID
				attaInfoService.update(updateWrapperContract);
				//删除历史的合同待签订数据
				contractPreService.removeById(contractOld.getId());
			}
			if (newInfo.getServerItem().contains("合同") && contractOld != null && employeeContractPre != null) {
				//1.9.11 huych 附件类型不比较差异
				contractOld.setAttaList(null);
				employeeContractPre.setAttaList(null);
				differenceContractKey = HrEquator.comparisonValueIgnoreField(contractOld, employeeContractPre, CONTRACT_IGNORE_FIELD);
				if (differenceContractKey.length() > 0) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、合同信息";
					} else {
						diffTitle = "合同信息";
					}
					detailEmpLog = new TEmployeePreLogDetail();
					detailEmpLog.setModelType(CommonConstants.TWO_STRING);
					detailEmpLog.setType(CommonConstants.THREE_STRING);
					this.setPreLogBaseInfo(empPreId, contractOld, employeeContractPre, userId, nickName,
							differenceContractKey, logId, detailEmpLog);
					detailList.add(detailEmpLog);
				}
			}

			String differenceSocialKey;
			if (Common.isEmpty(isSocailBuyOld) ||(Common.isNotNull(isSocailBuyOld) && !isSocailBuyOld.equals(isSocailBuyNew))) {
				//单独记录是否已购买社保的变更记录
				differenceSocialKey = "socialIsBuy";
				TEmployeePreLogDetail detailSocialLog = new TEmployeePreLogDetail();
				detailSocialLog.setModelType(CommonConstants.TWO_STRING);
				detailSocialLog.setType(CommonConstants.FOUR_STRING);
				Map<String,Object> old = new HashMap<>();
				old.put("socialIsBuy", isSocailBuyOld);
				Map<String,Object> simNew = new HashMap<>();
				simNew.put("socialIsBuy", isSocailBuyNew);
				this.setPreLogBaseInfo(empPreId, old, simNew, userId, nickName, differenceSocialKey, logId, detailSocialLog);
				detailList.add(detailSocialLog);
			}
			//查询老的社保明细
			R<EmployeePreSocialListVo> socialSdr = socialDaprUtils.getSocialPreInfoList(empPreId);
			TDispatchInfoPreVo dispatchInfoPreOldVo = null;
			if (socialSdr != null && socialSdr.getData() != null && null != socialSdr.getData().getDispatchInfoPreVo()) {
				dispatchInfoPreOldVo = socialSdr.getData().getDispatchInfoPreVo();
			}

			TDispatchInfoPreVo dispatchInfoPreVo = newInfo.getDispatchInfoPreVo();
			if (!newInfo.getServerItem().contains("社保") && oldInfo.getServerItem().contains("社保") && Common.isNotNull(dispatchInfoPreOldVo)) {
				//记录操作记录
				detailEmpLog = new TEmployeePreLogDetail();
				detailEmpLog.setModelType(CommonConstants.THREE_STRING);
				detailEmpLog.setType(CommonConstants.FOUR_STRING);
				this.setPreLogBaseInfo(empPreId, dispatchInfoPreOldVo, null, userId, nickName,
						null, logId, detailEmpLog);
				detailList.add(detailEmpLog);
				if (Common.isNotNull(diffTitle)) {
					diffTitle += "、社保信息";
				} else {
					diffTitle = "社保信息";
				}
			}
			if (newInfo.getServerItem().contains("社保") && dispatchInfoPreOldVo != null && dispatchInfoPreVo != null) {
				differenceSocialKey = HrEquator.comparisonValueIgnoreField(dispatchInfoPreOldVo, dispatchInfoPreVo, CONTRACT_IGNORE_FIELD);
				if (differenceSocialKey.length() > 0) {
					if (Common.isNotNull(diffTitle)) {
						diffTitle += "、社保信息";
					} else {
						diffTitle = "社保信息";
					}
					detailEmpLog = new TEmployeePreLogDetail();
					detailEmpLog.setModelType(CommonConstants.TWO_STRING);
					detailEmpLog.setType(CommonConstants.FOUR_STRING);
					this.setPreLogBaseInfo(empPreId, dispatchInfoPreOldVo, dispatchInfoPreVo, userId, nickName,
							differenceSocialKey, logId, detailEmpLog);
					detailList.add(detailEmpLog);
				}
			}

			// 有修改，则加日志
			if (Common.isNotNull(diffTitle)) {
				TEmployeePreLog empPreLog = new TEmployeePreLog();
				empPreLog.setId(logId);
				empPreLog.setPreId(empPreId);
				empPreLog.setDiffTitle(diffTitle);
				empPreLog.setCreateTime(LocalDateTime.now());
				if (Common.isNotNull(userId) && Common.isNotNull(nickName)) {
					empPreLog.setCreateBy(userId);
					empPreLog.setCreateName(nickName);
				}
				baseMapper.insert(empPreLog);
				if (!detailList.isEmpty()) {
					tEmployeePreLogDetailService.saveBatch(detailList);
				}
			}
		} catch (Exception e) {
			log.error(JSON.toJSON(newInfo) + "插入修改记录报错>>>", e);
		}
	}

	/**
	 * @Description: 填充基本信息
	 * @Author: hgw
	 * @Date: 2025/4/8 10:49
	 * @return: void
	 **/
	private void setLogBaseInfo(String empPreId, Object oldInfo, Object newInfo
			, YifuUser user, String differenceKey, String logId, TEmployeePreLogDetail detailEmpLog) {
		detailEmpLog.setPreId(empPreId);
		detailEmpLog.setPreLogId(logId);
		detailEmpLog.setDifferenceInfo(differenceKey);
		detailEmpLog.setCreateTime(LocalDateTime.now());
		if (Common.isNotNull(user)) {
			detailEmpLog.setCreateBy(user.getId());
			detailEmpLog.setCreateName(user.getNickname());
		}
		if (Common.isNotNull(oldInfo)) {
			detailEmpLog.setOldInfo(JSON.toJSONString(oldInfo, features));
		}
		if (Common.isNotNull(newInfo)) {
			detailEmpLog.setNewInfo(JSON.toJSONString(newInfo, features));
		}
	}

	/**
	 * @Description: 填充基本信息
	 * @Author: huyc
	 * @Date: 2025/4/11 10:49
	 * @return: void
	 **/
	private void setPreLogBaseInfo(String empPreId, Object oldInfo, Object newInfo
			, String userId, String nickName, String differenceKey, String logId, TEmployeePreLogDetail detailEmpLog) {
		detailEmpLog.setPreId(empPreId);
		detailEmpLog.setPreLogId(logId);
		detailEmpLog.setDifferenceInfo(differenceKey);
		detailEmpLog.setCreateTime(LocalDateTime.now());
		detailEmpLog.setCreateBy(userId);
		detailEmpLog.setCreateName(nickName);
		if (Common.isNotNull(oldInfo)) {
			detailEmpLog.setOldInfo(JSON.toJSONString(oldInfo, features));
		}
		if (Common.isNotNull(newInfo)) {
			detailEmpLog.setNewInfo(JSON.toJSONString(newInfo, features));
		}
	}

}
