/*
 *    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.bean.BeanUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.admin.api.vo.AreaMap;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.*;
import com.yifu.cloud.plus.v1.yifu.archives.service.LGuaziOfferRecordService;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.archives.service.TPreEmpDeclarationService;
import com.yifu.cloud.plus.v1.yifu.archives.util.IdCardUtil;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
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.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprUpmsProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 瓜子档案表
 *
 * @author chenyx
 * @date 2025-06-13 15:19:03
 */
@Log4j2
@Service
@RequiredArgsConstructor
@EnableConfigurationProperties(DaprUpmsProperties.class)
public class TGzEmpInfoServiceImpl extends ServiceImpl<TGzEmpInfoMapper, TGzEmpInfo> implements TGzEmpInfoService {

	private final TGzOfferInfoMapper gzOfferInfoMapper;

	private final TGzEmpContactInfoMapper gzEmpContactInfoMapper;

	private final TGzEmpEducationMapper gzEmpEducationMapper;

	private final TGzEmpFamilyMapper gzEmpFamilyMapper;

	private final TGzEmpSkillMapper gzEmpSkillMapper;

	private final TGzEmpWorkMapper gzEmpWorkMapper;

	private final TAttaInfoService attaInfoService;

	// 拿区域
	private final DaprUpmsProperties daprUpmsProperties;

	@Autowired
	private OSSUtil ossUtil;

	private final LGuaziOfferRecordService lGuaziOfferRecordService;

	private final TPreEmpDeclarationService tPreEmpDeclarationService;

	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	// 项目
	private final TSettleDomainService tSettleDomainService;
	// 人员档案表
	private final TEmployeeInfoService tEmployeeInfoService;
	// 项目档案表
	private final TEmployeeProjectService tEmployeeProjectService;
	// 员工职业资格信息表
	private final TEmpProfessionalQualificationService tEmpProfessionalService;
	// 员工工作履历信息表
	private final TEmpWorkRecordingService tEmpWorkRecordingService;
	// 紧急联络人
	private final TEmpContactInfoService tEmpContactInfoService;
	// 员工学历信息表
	private final TEmpEducationService tEmpEducationService;
	// 员工家庭信息表
	private final TEmpFamilyService tEmpFamilyService;


	/**
	 * 瓜子档案表简单分页查询
	 *
	 * @param tGzEmpInfo 瓜子档案表
	 * @return
	 */
	@Override
	public IPage<TGzEmpInfo> getTGzEmpInfoPage(Page<TGzEmpInfo> page, TGzEmpInfoSearchVo tGzEmpInfo) {
		return baseMapper.getTGzEmpInfoPage(page, tGzEmpInfo);
	}

	/**
	 * 通过OfferId查询瓜子档案详情
	 *
	 * @param offerId OfferId
	 * @return R
	 */
	@Override
	public R<TGzEmpInfoSearchVo> getInfoByOfferId(Integer offerId) {
		TGzEmpInfoSearchVo gzEmpInfoVo = new TGzEmpInfoSearchVo();

		TGzOfferInfo gzOfferInfo = gzOfferInfoMapper.getInfoById(offerId);
		if(Common.isEmpty(gzOfferInfo)){
			return R.failed("数据异常，禁止操作");
		}


		TGzEmpInfo gzEmpInfo = baseMapper.getInfoByOfferId(offerId);

		// 还未生成档案，取offer里的信息
		if(Common.isEmpty(gzEmpInfo)){
			gzEmpInfoVo.setBizId(gzOfferInfo.getBizId());
			gzEmpInfoVo.setOfferId(offerId);
			gzEmpInfoVo.setName(gzOfferInfo.getName());
			gzEmpInfoVo.setNameAc(gzOfferInfo.getNameAc());
			gzEmpInfoVo.setNationalIdType(gzOfferInfo.getNationalIdType());
			gzEmpInfoVo.setNationalId(gzOfferInfo.getNationalId());
			// 根据身份证得出 出生日期和性别
			if(Common.isNotNull(gzEmpInfoVo.getNationalId()) && gzEmpInfoVo.getNationalId().length() > 14){
				String idCard = gzEmpInfoVo.getNationalId();
				gzEmpInfoVo.setBirthdate(IdCardUtil.getBirthdate(idCard));
				// 性别: F:女,M:男
				if (idCard.length() > 17) {
					if (Integer.parseInt(idCard.substring(16, 17)) % 2 == 1) {
						gzEmpInfoVo.setSex("M");
					} else {
						gzEmpInfoVo.setSex("F");
					}
				}
			}
			gzEmpInfoVo.setPhone(gzOfferInfo.getPhone());
			gzEmpInfoVo.setMail(gzOfferInfo.getEmail());
			// 地址类型: 系统存默认值“现住址”:1A
			gzEmpInfoVo.setAddressType("1A");
		} else {
			BeanUtil.copyProperties(gzEmpInfo, gzEmpInfoVo);
			// 获取瓜子档案附属信息

			// 紧急联系人
			LambdaQueryWrapper<TGzEmpContactInfo> queryContactInfo = Wrappers.<TGzEmpContactInfo>lambdaQuery()
					.eq(TGzEmpContactInfo::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpContactInfo::getDelFlag, CommonConstants.ZERO_STRING)
					.eq(TGzEmpContactInfo::getPrimaryNid, "Y")
					.last(" limit 1 ");
			List<TGzEmpContactInfo> emergContactList = gzEmpContactInfoMapper.selectList(queryContactInfo);
			gzEmpInfoVo.setEmergContactList(emergContactList);
			// 教育经历
			LambdaQueryWrapper<TGzEmpEducation> queryEduInfo = Wrappers.<TGzEmpEducation>lambdaQuery()
					.eq(TGzEmpEducation::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpEducation::getDelFlag, CommonConstants.ZERO_STRING)
					.eq(TGzEmpEducation::getHighEduQualFlag, "Y")
					.last(" limit 1 ");
			List<TGzEmpEducation> eduList = gzEmpEducationMapper.selectList(queryEduInfo);
			gzEmpInfoVo.setEduExpList(eduList);

			// 工作经历列表
			LambdaQueryWrapper<TGzEmpWork> queryWorkInfo = Wrappers.<TGzEmpWork>lambdaQuery()
					.eq(TGzEmpWork::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpWork::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpWork::getCreateTime).orderByAsc(TGzEmpWork::getId);
			List<TGzEmpWork> workList = gzEmpWorkMapper.selectList(queryWorkInfo);
			gzEmpInfoVo.setWorkExpList(workList);
			// 家庭成员列表
			LambdaQueryWrapper<TGzEmpFamily> queryFamilyInfo = Wrappers.<TGzEmpFamily>lambdaQuery()
					.eq(TGzEmpFamily::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpFamily::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpFamily::getCreateTime).orderByAsc(TGzEmpFamily::getId);
			List<TGzEmpFamily> familyList = gzEmpFamilyMapper.selectList(queryFamilyInfo);
			gzEmpInfoVo.setFamilyList(familyList);
			// 技能证书列表
			LambdaQueryWrapper<TGzEmpSkill> querySkillInfo = Wrappers.<TGzEmpSkill>lambdaQuery()
					.eq(TGzEmpSkill::getEmpId, gzEmpInfo.getId())
					.eq(TGzEmpSkill::getDelFlag, CommonConstants.ZERO_STRING)
					.orderByAsc(TGzEmpSkill::getCreateTime).orderByAsc(TGzEmpSkill::getId);
			List<TGzEmpSkill> skillList = gzEmpSkillMapper.selectList(querySkillInfo);
			gzEmpInfoVo.setSkillList(skillList);

			// 附件
			List<TAttaInfo> attaInfos = attaInfoService.list(Wrappers.<TAttaInfo>query().lambda().eq(TAttaInfo::getDomainId, gzEmpInfo.getId()));
			if (Common.isNotNull(attaInfos)) {
				URL url;
				for (TAttaInfo atta : attaInfos) {
					url = ossUtil.getObjectUrl(null, atta.getAttaSrc());
					if (Common.isNotNull(url)) {
						atta.setAttaUrl(url.toString());
					}
				}
			}
			gzEmpInfoVo.setAttaList(attaInfos);
		}

		TPreEmpDeclaration declaration = tPreEmpDeclarationService.getTPreEmpDeclarationList();
		gzEmpInfoVo.setTPreEmpDeclaration(declaration);

		return R.ok(gzEmpInfoVo);
	}

	/**
	 * @Description: 瓜子档案表批量导出
	 * @Author: hgw
	 * @Date: 2025/6/19 10:03
	 * @return: void
	 **/
	@Override
	public void listExport(HttpServletResponse response, TGzEmpInfoSearchVo searchVo) {
		String prfName = "瓜子员工档案信息";
		String fileName = prfName + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TGzEmpInfoExportMain> list = new ArrayList<>();
		long count = baseMapper.getTGzEmpInfoCount(searchVo);

		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			Map<String,String> redisLabelMap = (Map<String, String>) RedisUtil.redis.opsForValue().get(CacheConstants.REDIS_DICT_LABLE);
			Map<String,String> idLabelMap = (Map<String, String>) RedisUtil.redis.opsForValue().get(CacheConstants.AREA_VALUE_ALL);
			if (Common.isEmpty(idLabelMap) || idLabelMap.isEmpty()) {
				R<AreaMap> areaListR = HttpDaprUtil.invokeMethodPost(daprUpmsProperties.getAppUrl(), daprUpmsProperties.getAppId()
						, "/area/inner/getAreaMapAll", "", AreaMap.class, SecurityConstants.FROM_IN);
				if (Common.isNotNull(areaListR)) {
					idLabelMap = areaListR.getData().getIdLabelMap();
				}
			}
			if (redisLabelMap != null && idLabelMap != null) {
				redisLabelMap.putAll(idLabelMap);
			}

			Map<String,String> nameAndDicTypeMap = new HashMap<>();
			ExcelUtil.getDictMapAndExp(TGzEmpInfoExportMain.class, nameAndDicTypeMap, redisLabelMap);
			ExcelUtil.getDictMapAndExp(TGzEmpInfoExportEducation.class, nameAndDicTypeMap, redisLabelMap);
			ExcelUtil.getDictMapAndExp(TGzEmpInfoExportFamily.class, nameAndDicTypeMap, redisLabelMap);
			// ExcelWriter excelWriter = EasyExcelFactory.write(out, TGzEmpInfoExportMain.class).registerConverter(new DictConverter(nameAndDicTypeMap, redisLabelMap)).build()
			ExcelWriter excelWriter = EasyExcelFactory.write(out).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				// 1：主表+紧急联系人
				WriteSheet writeSheet;
				int sheetIndex = 1;
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.getTGzEmpInfoList(searchVo);
					if (Common.isNotNull(list)) {
						writeSheet = EasyExcelFactory.writerSheet(index, "基础信息" + (sheetIndex++))
								.head(TGzEmpInfoExportMain.class)
								.registerConverter(new DictConverter(nameAndDicTypeMap, redisLabelMap)).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}

				// 2附属表：
				// 2.1教育经历
				count = baseMapper.getTGzEmpInfoCountEducation(searchVo);
				if (count > CommonConstants.ZERO_INT) {
					sheetIndex = 1;
					List<TGzEmpInfoExportEducation> listEducation;
					for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
						// 获取实际记录
						searchVo.setLimitStart(i);
						searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
						listEducation = baseMapper.getTGzEmpInfoListEducation(searchVo);
						if (Common.isNotNull(listEducation)) {
							writeSheet = EasyExcelFactory.writerSheet(index,"教育经历" + (sheetIndex++)).head(TGzEmpInfoExportEducation.class)
									.registerConverter(new DictConverter(nameAndDicTypeMap, redisLabelMap)).build();
							excelWriter.write(listEducation, writeSheet);
							index++;
						}
						if (Common.isNotNull(listEducation)) {
							listEducation.clear();
						}
					}
				}
				// 2.2工作经历
				count = baseMapper.getTGzEmpInfoCountWork(searchVo);
				if (count > CommonConstants.ZERO_INT) {
					sheetIndex = 1;
					List<TGzEmpInfoExportWork> listWork;
					for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
						// 获取实际记录
						searchVo.setLimitStart(i);
						searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
						listWork = baseMapper.getTGzEmpInfoListWork(searchVo);
						if (Common.isNotNull(listWork)) {
							writeSheet = EasyExcelFactory.writerSheet(index,"工作经历" + (sheetIndex++)).head(TGzEmpInfoExportWork.class).build();
							excelWriter.write(listWork, writeSheet);
							index++;
						}
						if (Common.isNotNull(listWork)) {
							listWork.clear();
						}
					}
				}
				// 2.3家庭成员
				count = baseMapper.getTGzEmpInfoCountFamily(searchVo);
				if (count > CommonConstants.ZERO_INT) {
					sheetIndex = 1;
					List<TGzEmpInfoExportFamily> listFamily;
					for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
						// 获取实际记录
						searchVo.setLimitStart(i);
						searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
						listFamily = baseMapper.getTGzEmpInfoListFamily(searchVo);
						if (Common.isNotNull(listFamily)) {
							writeSheet = EasyExcelFactory.writerSheet(index,"家庭成员" + (sheetIndex++)).head(TGzEmpInfoExportFamily.class)
									.registerConverter(new DictConverter(nameAndDicTypeMap, redisLabelMap)).build();
							excelWriter.write(listFamily, writeSheet);
							index++;
						}
						if (Common.isNotNull(listFamily)) {
							listFamily.clear();
						}
					}
				}
				// 2.4技能证书
				count = baseMapper.getTGzEmpInfoCountSkill(searchVo);
				if (count > CommonConstants.ZERO_INT) {
					sheetIndex = 1;
					List<TGzEmpInfoExportSkill> listSkill;
					for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT) {
						// 获取实际记录
						searchVo.setLimitStart(i);
						searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
						listSkill = baseMapper.getTGzEmpInfoListSkill(searchVo);
						if (Common.isNotNull(listSkill)) {
							writeSheet = EasyExcelFactory.writerSheet(index,"技能证书" + (sheetIndex++)).head(TGzEmpInfoExportSkill.class).build();
							excelWriter.write(listSkill, writeSheet);
							index++;
						}
						if (Common.isNotNull(listSkill)) {
							listSkill.clear();
						}
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcelFactory.writerSheet(prfName + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public List<TGzEmpInfo> noPageDiy(TGzEmpInfoSearchVo searchVo) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TGzEmpInfo::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 Long noPageCountDiy(TGzEmpInfoSearchVo searchVo) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TGzEmpInfo::getId, idList);
		}
		return baseMapper.selectCount(wrapper);
	}

	private LambdaQueryWrapper buildQueryWrapper(TGzEmpInfoSearchVo entity) {
		LambdaQueryWrapper<TGzEmpInfo> wrapper = Wrappers.lambdaQuery();

		if (Common.isNotNull(entity.getCreateName())) {
			wrapper.eq(TGzEmpInfo::getCreateName, entity.getCreateName());
		}
		return wrapper;
	}

	/**
	 * @Description: 瓜子保存新建用户
	 * @Author: hgw
	 * @Date: 2025/6/20 12:01
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser
	 **/
	private YifuUser getNewYifuUser() {
		Set<String> dbAuthsSet = new HashSet<>();
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		return new YifuUser("3", 1L, "", "瓜子",
				"瓜子", "0", SecurityConstants.BCRYPT + "123456",
				"12345678911", true, true, true,
				true,
				"1", authorities, "1",
				null, null,
				null,null);
	}

	/**
	 * @Description: 保存瓜子档案表
	 * @Author: hgw
	 * @Date: 2025/6/19 18:14
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.Boolean>
	 **/
	@Override
	@Transactional
	public R<Boolean> saveTGzEmpInfo(TGzEmpInfoSearchVo tGzEmpInfoVo) {
		YifuUser user = getNewYifuUser();
		TGzEmpInfo tGzEmpInfo = tGzEmpInfoVo;
		Integer offerId = tGzEmpInfoVo.getOfferId();
		if (Common.isEmpty(offerId)) {
			return R.failed("请传参流程ID！");
		} else {
			TGzOfferInfo gzOfferInfo = gzOfferInfoMapper.getInfoById(offerId);
			if(gzOfferInfo == null || Common.isEmpty(gzOfferInfo) || Common.isEmpty(gzOfferInfo.getBizId())){
				return R.failed("未找到瓜子Offer数据，Offer的ID="+ offerId);
			}
			if (Common.isEmpty(gzOfferInfo.getOfferStatus()) || !"9".equals(gzOfferInfo.getOfferStatus())) {
				return R.failed("瓜子Offer状态不对（"+gzOfferInfo.getOfferStatus()+"），不可编辑，Offer的ID="+ offerId);
			}
			gzOfferInfo.setOfferStatus("12");
			gzOfferInfoMapper.updateById(gzOfferInfo);

			// 记录状态变更的offer操作日志 记录来源: 6：（系统触发）C端采集提交
			this.saveOfferStatusRecord(gzOfferInfo.getId(),CommonConstants.SIX_STRING,
					CommonConstants.NINE_STRING,gzOfferInfo.getOfferStatus(),"0","系统触发");
 		}
		String gzEmpId = tGzEmpInfoVo.getId();

		if (Common.isEmpty(gzEmpId)) {
			tGzEmpInfo.setCreateBy(user.getId());
			tGzEmpInfo.setCreateName(user.getNickname());
			tGzEmpInfo.setCreateTime(LocalDateTime.now());
			this.save(tGzEmpInfo);
			gzEmpId = tGzEmpInfo.getId();
		} else {
			tGzEmpInfo.setUpdateBy(user.getId());
			tGzEmpInfo.setUpdateTime(LocalDateTime.now());
			this.updateById(tGzEmpInfo);
		}
		// 获取瓜子档案附属信息：先删除后增加：
		// 紧急联系人
		gzEmpContactInfoMapper.deleteByEmpId(gzEmpId);
		List<TGzEmpContactInfo> emergContactList = tGzEmpInfoVo.getEmergContactList();
		if (emergContactList != null && !emergContactList.isEmpty()) {
			for (TGzEmpContactInfo a : emergContactList) {
				a.setEmpId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
				gzEmpContactInfoMapper.insert(a);
			}
		}
		// 教育经历
		gzEmpEducationMapper.deleteByEmpId(gzEmpId);
		List<TGzEmpEducation> eduExpList = tGzEmpInfoVo.getEduExpList();
		if (eduExpList != null && !eduExpList.isEmpty()) {
			for (TGzEmpEducation a : eduExpList) {
				a.setEmpId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
				gzEmpEducationMapper.insert(a);
			}
		}

		// 工作经历列表
		gzEmpWorkMapper.deleteByEmpId(gzEmpId);
		List<TGzEmpWork> workList = tGzEmpInfoVo.getWorkExpList();
		if (workList != null && !workList.isEmpty()) {
			for (TGzEmpWork a : workList) {
				a.setEmpId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
				gzEmpWorkMapper.insert(a);
			}
		}

		// 家庭成员列表
		gzEmpFamilyMapper.deleteByEmpId(gzEmpId);
		List<TGzEmpFamily> familyList = tGzEmpInfoVo.getFamilyList();
		if (familyList != null && !familyList.isEmpty()) {
			for (TGzEmpFamily a : familyList) {
				a.setEmpId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
				gzEmpFamilyMapper.insert(a);
			}
		}

		// 技能证书列表
		gzEmpSkillMapper.deleteByEmpId(gzEmpId);
		List<TGzEmpSkill> skillList = tGzEmpInfoVo.getSkillList();
		if (skillList != null && !skillList.isEmpty()) {
			for (TGzEmpSkill a : skillList) {
				a.setEmpId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
				gzEmpSkillMapper.insert(a);
			}
		}

		// 附件
		// * 41（瓜子申明签名）；42（瓜子确认签名）；43（瓜子pdf文件)
		//	 * CONTRACT（合同） NID_A（证件正面） NID_B（证件反面） BANK_FLOW（银行流水）
		//	 * EDUQ（学历） DEGRE（学位） PHOTO（头像） BANK_A（银行卡正面）
		//	 * BANK_B（银行卡反面） LEAVE_PRO（离职证明） EXAM_RPT（体检报告）
		attaInfoService.deleteByDomainId(gzEmpId);
		List<TAttaInfo> attaList = tGzEmpInfoVo.getAttaList();
		if (attaList != null && !attaList.isEmpty()) {
			for (TAttaInfo a : attaList) {
				a.setDomainId(gzEmpId);
				a.setCreateBy(user.getId());
				a.setCreateName(user.getNickname());
				a.setCreateTime(LocalDateTime.now());
			}
			attaInfoService.saveBatch(attaList);
		}

		return R.ok();
	}

	/**
	 * 记录单个状态变更的offer操作日志
	 * @param offerId offerId
	 * @param recordFrom 记录来源
	 * @param beforeStatus 变更前状态
	 * @param nowStatus 当前状态
	 * @param userId 触发人ID
	 * @param nickname 触发人名称
	 */
	private void saveOfferStatusRecord(Integer offerId, String recordFrom,
									   String beforeStatus, String nowStatus, String userId, String nickname){
		// 记录offer操作日志
		LGuaziOfferRecordVo lGuaziOfferRecordVo = new LGuaziOfferRecordVo();
		// 存变更前后的状态到 状态数组里
		List<String> changeStatusList = new ArrayList<>();
		changeStatusList.add(beforeStatus);
		changeStatusList.add(nowStatus);

		if(changeStatusList.size() > 0){
			lGuaziOfferRecordVo.setOfferId(offerId);
			// 记录来源
			lGuaziOfferRecordVo.setRecordFrom(recordFrom);
			lGuaziOfferRecordVo.setChangeStatusList(changeStatusList);
			lGuaziOfferRecordVo.setCreateBy(userId);
			lGuaziOfferRecordVo.setCreateName(nickname);
			lGuaziOfferRecordService.saveRecordOne(lGuaziOfferRecordVo);
		}
	}

	/**
	 * @Description: 保存到人员档案
	 * @Author: hgw
	 * @Date: 2025/6/20 16:44
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> saveEmpInfoByGz(TGzOfferInfo offerInfo) {
		TSettleDomainSelectVo dept = tSettleDomainService.getSettleDomainVoByNo(CommonConstants.GZ_DEPT_NO);
		if (dept == null || Common.isEmpty(dept.getId())) {
			return R.failed("未找到瓜子项目！项目编码："+CommonConstants.GZ_DEPT_NO);
		}
		String deptId = dept.getId();
		if (Common.isEmpty(offerInfo.getId())) {
			return R.failed("请传参Offer的ID！");
		}
		YifuUser user = getNewYifuUser();
		// 保存到人员档案
		// 先判断信息是否存在：
		TGzEmpInfo gzEmpInfo = baseMapper.getInfoByOfferId(offerInfo.getId());
		if (gzEmpInfo == null || Common.isEmpty(gzEmpInfo.getNationalId())) {
			return R.failed("未找到瓜子档案信息！");
		}
		String empIdCard = gzEmpInfo.getNationalId();

		// 翻译字典
		Map<String, Map<String,String>> dictMap = new HashMap<>();
		R<Map<String, Map<String,String>>> relDictMapR = upmsDaprUtils.getRelValueMapByOutDictType();
		if (null != relDictMapR
				&& relDictMapR.getCode() == CommonConstants.SUCCESS
				&& Common.isNotNull(relDictMapR.getData())) {
			dictMap = relDictMapR.getData();
		}
		// 1：档案
		TEmployeeInfo emp = this.saveEmployeeInfo(gzEmpInfo, user, empIdCard, dictMap);

		// 2：项目档案
		this.saveEmployeeProject(emp, user, empIdCard, deptId, dept);

		// TODO-3:其他附属信息与附件


		return R.ok();
	}

	private TEmployeeInfo saveEmployeeInfo(TGzEmpInfo gzEmpInfo, YifuUser user, String empIdCard, Map<String, Map<String,String>> dictMap) {
		// 查找档案、项目档案，无则新建
		TEmployeeInfo emp = tEmployeeInfoService.getInfoByIdcard(empIdCard);
		if (emp == null) {
			emp = tEmployeeInfoService.getInfoByDelete(empIdCard);
			if (emp != null) {
				emp.setCreateTime(LocalDateTime.now());
			}
		} else if (CommonConstants.ONE_INT == emp.getFileStatus()) {
			emp.setCreateTime(LocalDateTime.now());
		}
		boolean isNew = false;
		if (emp == null) {
			isNew = true;
			emp = new TEmployeeInfo();
		}
		// 转化瓜子属性
		this.setEmpInfoByGz(gzEmpInfo, emp, dictMap);
		// 新员工，塞基本属性
		if (isNew) {
			tEmployeeInfoService.setBaseData(emp, CommonConstants.NINE_STRING, user);
		}
		if (Common.isEmpty(emp.getEmpCode())) {
			emp.setEmpCode(tEmployeeInfoService.getCode());
		}
		emp.setUpdateBy(user.getId());
		emp.setUpdateTime(LocalDateTime.now());
		emp.setFileStatus(CommonConstants.ZERO_INT);
		emp.setDeleteFlag(CommonConstants.STATUS_NORMAL);
		tEmployeeInfoService.saveOrUpdate(emp);
		return emp;
	}

	private void saveEmployeeProject(TEmployeeInfo emp, YifuUser user, String empIdCard, String deptId, TSettleDomainSelectVo dept) {
		// 查找档案、项目档案，无则新建
		boolean isNew;
		TEmployeeProject project = tEmployeeProjectService.getByEmpIdCardAndDeptId(empIdCard, deptId);
		if (project == null) {
			project = tEmployeeProjectService.getByEmpIdCardAndDeptIdAndDelete(empIdCard, deptId);
			if (project != null) {
				project.setCreateTime(LocalDateTime.now());
				project.setProjectSource(CommonConstants.NINE_STRING);
				project.setDeleteFlag(CommonConstants.STATUS_NORMAL);
			}
		} else if (CommonConstants.ONE_INT == project.getProjectStatus()) {
			project.setCreateTime(LocalDateTime.now());
		}
		isNew = false;
		if (project == null) {
			isNew = true;
			project = new TEmployeeProject();
		}
		project.setProjectStatus(CommonConstants.ZERO_INT);
		if (Common.isEmpty(project.getStatus())) {
			project.setStatus(CommonConstants.ZERO_INT);
		}
		if (Common.isEmpty(project.getEmpId()) && emp != null) {
			project.setEmpId(emp.getId());
		}
		if (isNew) {
			// 新项目档案塞基本属性
			this.setNewEmpProjectBaseData(project, emp, dept, user);
		}
		tEmployeeProjectService.saveOrUpdate(project);
	}

	/**
	 * @Description: 新员工塞基本项目档案信息
	 * @Author: hgw
	 * @Date: 2024/6/19 14:26
	 * @return: void
	 **/
	private void setNewEmpProjectBaseData(TEmployeeProject insTEmployeePro, TEmployeeInfo tEmployeeInfo, TSettleDomain tSettleDomain, YifuUser user) {
		// 新增档案
		insTEmployeePro.setId(String.valueOf(UUID.randomUUID()).replace("-", ""));
		insTEmployeePro.setDeleteFlag(CommonConstants.STATUS_NORMAL);
		insTEmployeePro.setStatus(CommonConstants.ZERO_INT);

		//获取项目和单位信息
		if (Common.isNotNull(tSettleDomain)) {
			insTEmployeePro.setDeptId(tSettleDomain.getId());
			insTEmployeePro.setDeptName(tSettleDomain.getDepartName());
			insTEmployeePro.setBusinessPrimaryType(tSettleDomain.getBusinessPrimaryType());
			insTEmployeePro.setBusinessSecondType(tSettleDomain.getBusinessSecondType());
			insTEmployeePro.setBusinessThirdType(tSettleDomain.getBusinessThirdType());
			insTEmployeePro.setUnitId(tSettleDomain.getCustomerId());
			insTEmployeePro.setUnitNo(tSettleDomain.getCustomerNo());
			insTEmployeePro.setUnitName(tSettleDomain.getCustomerName());
			String empNO = tEmployeeProjectService.getEmpNo(insTEmployeePro.getDeptNo());
			insTEmployeePro.setEmpNo(empNO);
		}
		//员工编码生成规则
		if (tEmployeeInfo != null) {
			insTEmployeePro.setEmpId(tEmployeeInfo.getId());
			insTEmployeePro.setEmpName(tEmployeeInfo.getEmpName());
			insTEmployeePro.setEmpCode(tEmployeeInfo.getEmpCode());
		}
		insTEmployeePro.setCreateBy(user.getId());
		insTEmployeePro.setCreateTime(LocalDateTime.now());
		insTEmployeePro.setCreateName(user.getNickname());
		insTEmployeePro.setProjectSource(CommonConstants.NINE_STRING);
	}

	/**
	 * @Description: 转化瓜子属性
	 * @Author: hgw
	 * @Date: 2025/6/20 16:17
	 * @return: void
	 **/
	private void setEmpInfoByGz(TGzEmpInfo gzEmpInfo, TEmployeeInfo emp, Map<String, Map<String,String>> dictMap) {
		// TODO - 转化
		/*if (Common.isNotNull(gzEmpInfo.getEmpPhone())) {
			emp.setEmpPhone(gzEmpInfo.getEmpPhone());
		}
		if (Common.isNotNull(gzEmpInfo.getEmpNatrue())) {
			emp.setEmpNatrue(gzEmpInfo.getEmpNatrue());
		}
		emp.setEmpName(gzEmpInfo.getEmpName());
		emp.setEmpIdcard(gzEmpInfo.getEmpIdcard());
		emp.setEmpPhone(gzEmpInfo.getEmpPhone());
		emp.setContactAddress(gzEmpInfo.getContactAddress());
		emp.setContactProvince(gzEmpInfo.getContactProvince());
		emp.setContactCity(gzEmpInfo.getContactCity());
		emp.setContactTown(gzEmpInfo.getContactTown());
		emp.setEmpBirthday(gzEmpInfo.getEmpBirthday());
		emp.setEmpSex(gzEmpInfo.getEmpSex());
		emp.setEmpAge(gzEmpInfo.getEmpAge());
		emp.setBankProvince(gzEmpInfo.getBankProvince());
		emp.setBankCity(gzEmpInfo.getBankCity());
		emp.setBankName(gzEmpInfo.getBankName());
		emp.setBankSubName(gzEmpInfo.getBankSubName());
		emp.setBankNo(gzEmpInfo.getBankNo());

		emp.setFileProvince(gzEmpInfo.getFileProvince());
		emp.setFileCity(gzEmpInfo.getFileCity());
		emp.setFileTown(gzEmpInfo.getFileTown());

		
		emp.setEmpName(gzEmpInfo.getName());

		emp.setEmpIdcard(gzEmpInfo.getEmpIdcard());
		if (employee != null) {
			empId = employee.getId();
			BeanUtil.copyProperties(employee, tPreEmployeeInfo, ID);
			emp.setOldId(employee.getId());
			if (project != null) {
				BeanUtil.copyProperties(project, tPreEmployeeProject, ID);
				tPreEmployeeProject.setOldId(project.getId());
			}
		}

		emp.setPreMainId(mainId);
		emp.setCreateBy(user.getId());
		emp.setCreateName(user.getNickname());
		emp.setCreateTime(LocalDateTime.now());
		emp.setValidityStart(info.getValidityStartValue());
		if ("长期".equals(info.getValidityEnd())) {
			emp.setValidityEnd(endDate);
		} else {
			emp.setValidityEnd(info.getValidityEndValue());
		}
		emp.setEmpNatrue(info.getEmpNatrueValue());
		emp.setEmpSex(com.yifu.cloud.plus.v1.yifu.common.core.util.IdCardUtil.getSex(empIdCard));
		java.sql.Date empBirthday = com.yifu.cloud.plus.v1.yifu.archives.util.IdCardUtil.getBirthdate(empIdCard);
		emp.setEmpBirthday(empBirthday);
		emp.setEmpAge(com.yifu.cloud.plus.v1.yifu.common.core.util.IdCardUtil.IdNOToAge(empIdCard));
		emp.setEmpMarriStatus(info.getEmpMarriStatusValue());
		emp.setEmpNational(info.getEmpNationalValue());
		emp.setPoliticalStatus(info.getPoliticalStatusValue());
		emp.setEmpEmail(info.getEmpEmail());
		emp.setEmpPhone(info.getEmpPhone());
		// 2024-10-30 20:02:53 测试jld认为如果没写户籍省，则带出档案。我认为有道理
		if (Common.isNotNull(info.getIdProvinceValue())) {
			emp.setIdProvince(Integer.parseInt(info.getIdProvinceValue()));
			if (Common.isNotNull(info.getIdCityValue())) {
				emp.setIdCity(Integer.parseInt(info.getIdCityValue()));
			} else {
				emp.setIdCity(null);
			}
			if (Common.isNotNull(info.getIdTownValue())) {
				emp.setIdTown(Integer.parseInt(info.getIdTownValue()));
			} else {
				emp.setIdTown(null);
			}
		}
		emp.setEmpRegisType(info.getEmpRegisTypeValue());
		if (Common.isNotNull(info.getFileProvinceValue())) {
			emp.setFileProvince(Integer.parseInt(info.getFileProvinceValue()));
		}
		if (Common.isNotNull(info.getFileCityValue())) {
			emp.setFileCity(Integer.parseInt(info.getFileCityValue()));
		}
		if (Common.isNotNull(info.getFileTownValue())) {
			emp.setFileTown(Integer.parseInt(info.getFileTownValue()));
		} else {
			emp.setFileTown(null);
		}
		if (Common.isNotNull(info.getEducationNameValue())) {
			emp.setHignEducation(info.getEducationNameValue());
			if ("5".equals(info.getEducationNameValue())
					|| "6".equals(info.getEducationNameValue())
					|| "7".equals(info.getEducationNameValue())
					|| "8".equals(info.getEducationNameValue())) {
				emp.setIsCollege(CommonConstants.ONE_INT);
			} else {
				emp.setIsCollege(CommonConstants.ZERO_INT);
			}
		}
		emp.setSchool(info.getSchool());
		emp.setMajor(info.getMajor());
		emp.setAdmissionDate(info.getEntryDateValue());
		emp.setGradutionDate(info.getGradutionDateValue());
		emp.setContactAddress(info.getContactAddress());
		// 2024-10-17 14:30:06 倩倩上午测试用例评审会说要联动导入，没有卡号，后面填写的不生效：
		if (Common.isNotNull(info.getBankNo())) {
			emp.setBankName(info.getBankName());
			emp.setBankProvince(info.getBankProvinceValue());
			emp.setBankCity(info.getBankCityValue());
			emp.setBankSubName(info.getBankSubName());
			emp.setBankNo(info.getBankNo());
			emp.setTaxMonth(info.getTaxMonthValue());
		} else {
			preEmployeeInfoNeedSalaryList.add(tPreEmployeeInfo);
			needSalaryList.add(empIdCard);
		}
		emp.setTaxMonthFlag(CommonConstants.ONE_STRING);
		emp.setContactProvince(info.getContactProvinceValue());
		emp.setContactCity(info.getContactCityValue());
		emp.setContactTown(info.getContactTownValue());
		emp.setFirstWorkFlag(info.getFirstWorkFlagValue());
		emp.setHaveQualification(info.getHaveQualificationValue());
		emp.setFileSource(CommonConstants.SEVEN_STRING);*/
	}

}
