/*
 *    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 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.constants.EmployeeConstants;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.FddContractAttachInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmployeeContractInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmployeeInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmployeeProjectMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.archives.util.IdCardUtil;
import com.yifu.cloud.plus.v1.yifu.archives.utils.DoJointTask;
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.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.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 法大大合同附属信息表
 *
 * @author fxj
 * @date 2022-06-28 16:24:12
 */
@Service
@RequiredArgsConstructor
@EnableConfigurationProperties(DaprUpmsProperties.class)
@Log4j2
public class FddContractAttachInfoServiceImpl extends ServiceImpl<FddContractAttachInfoMapper, FddContractAttachInfo> implements FddContractAttachInfoService {

	@Autowired
	private FddPersonAccountService fddPersonAccountService;

	@Autowired
	private FddContractInfoService fddContractInfoService;

	@Autowired
	private TEmployeeInfoMapper tEmployeeInfoMapper;

	@Autowired
	private TEmployeeProjectService tEmployeeProjectService;

	@Autowired
	private TEmployeeContractInfoMapper employeeContractInfoMapper;

	@Autowired
	private TSettleDomainService tSettleDomainService;

	@Autowired
	private TCustomerInfoService tCustomerInfoService;

	@Autowired
	private FddContractTemplateService fddContractTemplateService;

	@Autowired
	private TEmployeeInfoService employeeInfoService;

	@Autowired
	private TEmployeeProjectMapper employeeProjectMapper;

	@Autowired
	private TEmployeeLogService tEmployeeLogService;

	// 缓存信息
	@Autowired
	private CacheManager cacheManager;

	@Autowired
	@Lazy
	private DoJointTask doJointTask;

	@Autowired
	private EmployeeRegistrationPreService registrationPreService;

	ExecutorService executorService = Executors.newFixedThreadPool(10);

	public static final String NO_VALID_CONTRACT_FOUND = "未获取到有效在用合同，请确认存在对应姓名、身份证、合同起始时间的合同数据";

	/**
	 * 法大大合同附属信息表简单分页查询
	 *
	 * @param fddContractAttachInfo 法大大合同附属信息表
	 * @return
	 */
	@Override
	public IPage<FddContractAttachInfo> getFddContractAttachInfoPage(Page<FddContractAttachInfo> page, FddContractAttachInfo fddContractAttachInfo) {
		return baseMapper.getFddContractAttachInfoPage(page, fddContractAttachInfo);
	}

	/**
	 * 获取有附属信息但是没有法大大电子合同的数据
	 *
	 * @param empIdcard
	 * @return
	 */
	@Override
	public List<FddContractAttachInfo> getListByNoInfoByEmpIdcard(@Param("empIdcard") String empIdcard) {
		return baseMapper.getListByNoInfoByEmpIdcard(empIdcard);
	}

	@Override
	public List<ErrorMessage> sendTask(List<FddContractAttachInfo> entityList) {
		List<ErrorMessage> errorList = new ArrayList<>();
		int i = 1;
		YifuUser user = SecurityUtils.getUser();
		for (FddContractAttachInfo attachInfo : entityList) {
			//保存合同数据
			attachInfo.setContractId(CommonConstants.EMPTY_STRING);

			R<String> employeeParamR;
			//新签
			employeeParamR = fddContractInfoService.generalEmployeeParam(attachInfo, false);
			if (CommonConstants.FAIL == employeeParamR.getCode()) {
				errorList.add(new ErrorMessage(i, employeeParamR.getMsg(), CommonConstants.RED));
				continue;
			}
			//保存数据
			this.save(attachInfo);
			attachInfo.setContractId(attachInfo.getId());
			this.updateById(attachInfo);
			//判断员工是否有实名数据，如果没有插入是实名数据
			long fddPersonCount = fddPersonAccountService.count(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getMoblie, attachInfo.getEmpPhone())
					.eq(FddPersonAccount::getIdCard, attachInfo.getEmpIdcard()).eq(FddPersonAccount::getName, attachInfo.getEmpName())
					.eq(FddPersonAccount::getSystemFlag, CommonConstants.ONE_STRING));
			if (fddPersonCount == CommonConstants.ZERO_INT) {
				FddPersonAccount fddPersonAccount = new FddPersonAccount();
				fddPersonAccount.setMoblie(attachInfo.getEmpPhone());
				fddPersonAccount.setName(attachInfo.getEmpName());
				fddPersonAccount.setIdCard(attachInfo.getEmpIdcard());
				fddPersonAccount.setSystemFlag(CommonConstants.ONE_STRING);
				fddPersonAccount.setRealStatus(CommonConstants.ZERO_STRING);
				fddPersonAccountService.save(fddPersonAccount);
				executorService.submit(() -> {
					try {
						fddPersonAccountService.sendAuthMessage(fddPersonAccount.getId());
					} catch (Exception e) {
						log.error("执行异常", e);
					}
				});
			} else {
				executorService.submit(() -> {
					try {
						//如果已经实名发送电子合同
						FddContractAttachInfo fddContractAttachInfo = this.getById(attachInfo.getId());
						R<String> returnR = fddContractInfoService.saveEmpContract(fddContractAttachInfo, user);
						if (returnR != null) {
							//记录返回信息
							if (returnR.getCode() == CommonConstants.SUCCESS) {
								fddContractAttachInfo.setRemark("成功");
							} else {
								fddContractAttachInfo.setRemark(returnR.getMsg());
							}
							this.updateById(fddContractAttachInfo);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				});
			}
			i++;
		}
		return errorList;
	}

	/**
	 * @param fddContractInfo
	 * @return R
	 * @Author hyc
	 * @Date 2022-06-02
	 **/
	@Override
	@Transactional
	public R<String> saveEmpAndAttarch(FddContractInfo fddContractInfo,YifuUser user) {
		List<TEmployeeInfo> updateList = new ArrayList();
		try {
			FddContractAttachInfo fddContractAttachInfo = this.getOne(Wrappers.<FddContractAttachInfo>query().lambda().eq(FddContractAttachInfo::getContractId, fddContractInfo.getContractId())
					.eq(FddContractAttachInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
			if (fddContractAttachInfo != null && fddContractAttachInfo.getContractId().equals(fddContractAttachInfo.getId())) {
				FddContractTemplate fddContractTemplate = fddContractTemplateService.getOne(Wrappers.<FddContractTemplate>query().lambda()
						.eq(FddContractTemplate::getId, fddContractInfo.getFddTemplateId()));
				TSettleDomain settleDomain = tSettleDomainService.getOne(Wrappers.<TSettleDomain>query().lambda().eq(TSettleDomain::getDepartNo, fddContractAttachInfo.getDepartNo())
						.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING).eq(TSettleDomain::getStopFlag, CommonConstants.ZERO_STRING));
				TCustomerInfo tCustomerInfo = tCustomerInfoService.getOne(Wrappers.<TCustomerInfo>query().lambda().eq(TCustomerInfo::getId, settleDomain.getCustomerId())
						.eq(TCustomerInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
				//查询项目档案
				TEmployeeProject tEmployeeProject = employeeProjectMapper.selectOne(Wrappers.<TEmployeeProject>query().lambda()
						.eq(TEmployeeProject::getDeptNo, settleDomain.getDepartNo())
						.eq(TEmployeeProject::getEmpIdcard, fddContractAttachInfo.getEmpIdcard())
						.eq(TEmployeeProject::getDeleteFlag, CommonConstants.ZERO_STRING)
						.last(CommonConstants.LAST_ONE_SQL));

				//查询人员档案
				TEmployeeInfo tEmployeeInfo = employeeInfoService.getOne(Wrappers.<TEmployeeInfo>query().lambda().eq(TEmployeeInfo::getDeleteFlag, CommonConstants.ZERO_STRING)
						.eq(TEmployeeInfo::getEmpIdcard, fddContractAttachInfo.getEmpIdcard()));

				//该人员该项目有项目档案
				if (null != tEmployeeProject) {
					//如果是减项状态就复项
					TEmployeeProject tEmployeeProjectCompare = employeeProjectMapper.selectById(tEmployeeProject.getId());
					if (CommonConstants.ONE_INT == tEmployeeProject.getProjectStatus()) {
						tEmployeeProject.setProjectStatus(CommonConstants.ZERO_INT);
						tEmployeeProject.setLeaveReason(CommonConstants.EMPTY_STRING);
						tEmployeeProject.setLeaveTime(null);
						tEmployeeProject.setLeaveRemark(CommonConstants.EMPTY_STRING);
						tEmployeeProject.setLeaveUser(CommonConstants.EMPTY_STRING);

						// 增-同步处理CSP入离职申请为已处理，加日志
						tEmployeeProjectService.doSaveBelongDept(tEmployeeProject, CommonConstants.ONE_STRING);
						// 更新入职待建档状态为已完成
						registrationPreService.updatePreStatusToEnd(tEmployeeProject.getDeptNo(),tEmployeeProject.getEmpIdcard());
					}

					//判断人员档案的状态，如果是减档状态就复档
					if (CommonConstants.ONE_INT == tEmployeeInfo.getFileStatus()) {
						tEmployeeInfo.setFileStatus(CommonConstants.ZERO_INT);
						tEmployeeInfo.setLeaveReason(CommonConstants.EMPTY_STRING);
						tEmployeeInfo.setLeaveTime(null);
						tEmployeeInfo.setLeaveRemark(CommonConstants.EMPTY_STRING);
						tEmployeeInfo.setLeaveUser(CommonConstants.EMPTY_STRING);
						tEmployeeInfo.setLeaveUserName(CommonConstants.EMPTY_STRING);
					}

					//更新项目档案
					tEmployeeProject.setEmpNatrue(fddContractAttachInfo.getEmpNatrue());
					tEmployeeProject.setPost(fddContractAttachInfo.getPost());
					tEmployeeProject.setContractStatus(CommonConstants.ONE_INT);
					employeeProjectMapper.updateById(tEmployeeProject);
					//保存操作记录
					tEmployeeLogService.saveModificationRecord(CommonConstants.dingleDigitIntArray[1], "", tEmployeeProject.getId(), tEmployeeProjectCompare, tEmployeeProject,fddContractAttachInfo);

					//更新人员档案
					tEmployeeInfo.setEmpPhone(fddContractAttachInfo.getEmpPhone());
					tEmployeeInfo.setContractStatus(CommonConstants.ONE_INT);
					updateList.add(tEmployeeInfo);

					TEmployeeContractInfo employeeContractInfo = employeeContractInfoMapper.selectOne(Wrappers.<TEmployeeContractInfo>query().lambda()
							.eq(TEmployeeContractInfo::getEmpIdcard, fddContractAttachInfo.getEmpIdcard()).eq(TEmployeeContractInfo::getSettleDomain, settleDomain.getId())
							.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING)
							.eq(TEmployeeContractInfo::getDeleteFlag, CommonConstants.ZERO_INT)
							.last(CommonConstants.LAST_ONE_SQL));
					//无可用合同
					if (null == employeeContractInfo) {
						//新增合同
						TEmployeeContractInfo newEmployeeContractInfo = new TEmployeeContractInfo();
						newEmployeeContractInfo.setAuditUserName(user.getNickname());
						saveTEmployeeContractInfo(newEmployeeContractInfo, fddContractAttachInfo, settleDomain, fddContractTemplate, tEmployeeInfo, tCustomerInfo, tEmployeeProject);
						//更新合同id
						updateContractId(fddContractInfo, fddContractAttachInfo, newEmployeeContractInfo);
					} else {
						//已有合同设置状态为不在用
						employeeContractInfo.setInUse(CommonConstants.ONE_STRING);
						employeeContractInfoMapper.updateById(employeeContractInfo);
						//新增合同
						TEmployeeContractInfo newEmployeeContractInfo2 = new TEmployeeContractInfo();
						newEmployeeContractInfo2.setAuditUserName(user.getNickname());
						saveTEmployeeContractInfo(newEmployeeContractInfo2, fddContractAttachInfo, settleDomain, fddContractTemplate, tEmployeeInfo, tCustomerInfo, tEmployeeProject);
						//更新合同id
						updateContractId(fddContractInfo, fddContractAttachInfo, newEmployeeContractInfo2);
					}
					doJointTask.updateFddEmployeeInfo(updateList, fddContractAttachInfo);
				} else {
					//判断人员档案是否存在，不存在就新增人员档案，存在则判断档案状态，如果是减档就复档
					if (Common.isNotNull(tEmployeeInfo)) {
						if (CommonConstants.ONE_INT == tEmployeeInfo.getFileStatus()) {
							tEmployeeInfo.setFileStatus(CommonConstants.ZERO_INT);
							tEmployeeInfo.setLeaveReason(CommonConstants.EMPTY_STRING);
							tEmployeeInfo.setLeaveTime(null);
							tEmployeeInfo.setLeaveRemark(CommonConstants.EMPTY_STRING);
							tEmployeeInfo.setLeaveUser(CommonConstants.EMPTY_STRING);
							tEmployeeInfo.setLeaveUserName(CommonConstants.EMPTY_STRING);
						}
						//更新人员档案
						tEmployeeInfo.setEmpPhone(fddContractAttachInfo.getEmpPhone());
						tEmployeeInfo.setContractStatus(CommonConstants.ONE_INT);
						updateList.add(tEmployeeInfo);

						//新增项目档案
						TEmployeeProject project = new TEmployeeProject();
						saveEmployeeproject(fddContractAttachInfo, settleDomain, fddContractTemplate, tEmployeeInfo, tCustomerInfo, project);

						//新增合同
						TEmployeeContractInfo newEmployeeContractInfo1 = new TEmployeeContractInfo();
						newEmployeeContractInfo1.setAuditUserName(user.getNickname());
						saveTEmployeeContractInfo(newEmployeeContractInfo1, fddContractAttachInfo, settleDomain, fddContractTemplate, tEmployeeInfo, tCustomerInfo, project);
						//更新合同id
						updateContractId(fddContractInfo, fddContractAttachInfo, newEmployeeContractInfo1);
						doJointTask.updateFddEmployeeInfo(updateList, fddContractAttachInfo);
					} else {
						//新增人员档案
						TEmployeeInfo newEmployeeInfo = new TEmployeeInfo();
						newEmployeeInfo.setEmpName(fddContractAttachInfo.getEmpName());
						newEmployeeInfo.setEmpIdcard(fddContractAttachInfo.getEmpIdcard());
						newEmployeeInfo.setEmpPhone(fddContractAttachInfo.getEmpPhone());
						newEmployeeInfo.setEmpNatrue(fddContractAttachInfo.getEmpNatrue());
						newEmployeeInfo.setEmpCode(getCode());
						newEmployeeInfo.setFileStatus(CommonConstants.ZERO_INT);
						newEmployeeInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
						newEmployeeInfo.setStatus(CommonConstants.ZERO_INT);
						newEmployeeInfo.setProjectNum(CommonConstants.ONE_INT);
						newEmployeeInfo.setFileSource(CommonConstants.dingleDigitStrArray[6]);
						newEmployeeInfo.setCreateBy(fddContractAttachInfo.getCreateBy());
						newEmployeeInfo.setCreateName(fddContractAttachInfo.getCreateName());
						newEmployeeInfo.setUpdateBy(fddContractAttachInfo.getUpdateBy());
						newEmployeeInfo.setContractStatus(CommonConstants.ONE_INT);
						java.sql.Date date = IdCardUtil.getBirthdate(fddContractAttachInfo.getEmpIdcard());

						if (null != date) {
							//初始化年龄
							newEmployeeInfo.setEmpAge(IdCardUtil.IdNOToAge(fddContractAttachInfo.getEmpIdcard()));
							newEmployeeInfo.setEmpBirthday(date);
						}
						newEmployeeInfo.setEmpSex(IdCardUtil.getSex(fddContractAttachInfo.getEmpIdcard()));
						tEmployeeInfoMapper.insert(newEmployeeInfo);

						//新增项目档案
						TEmployeeProject newTEmpProject = new TEmployeeProject();
						saveEmployeeproject(fddContractAttachInfo, settleDomain, fddContractTemplate, newEmployeeInfo, tCustomerInfo, newTEmpProject);

						//新增合同
						TEmployeeContractInfo newEmployeeContractInfo1 = new TEmployeeContractInfo();
						newEmployeeContractInfo1.setAuditUserName(user.getNickname());
						saveTEmployeeContractInfo(newEmployeeContractInfo1, fddContractAttachInfo, settleDomain, fddContractTemplate, newEmployeeInfo, tCustomerInfo, newTEmpProject);
						//更新合同id
						updateContractId(fddContractInfo, fddContractAttachInfo, newEmployeeContractInfo1);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("保存异常：" + e.getMessage());
			return R.failed("保存异常：" + e.getMessage());
		}
		return R.ok();
	}

	@Override
	public List<ErrorMessage> batchAdd(List<FddContractAttachInfo> entityList) {
		List<ErrorMessage> errorList = new ArrayList<>();
		YifuUser user = SecurityUtils.getUser();

		Map<String, Integer> sameCheck = new HashMap<>();
		int i = 1;
		try {
			if (null != entityList && !entityList.isEmpty()) {
				for (FddContractAttachInfo attachInfo : entityList) {
					i++;
					String sameInfo = attachInfo.getEmpIdcard() + "_" + attachInfo.getDepartNo()
							+ "_" + attachInfo.getFddTemplateId() + "_" + attachInfo.getContractStart()
							+ "_" + attachInfo.getContractEnd();
					if (sameCheck.get(sameInfo) != null) {
						errorList.add(new ErrorMessage(i, "第" + (i) + "行与第" + sameCheck.get(sameInfo) + "行重复！", CommonConstants.RED));
						continue;
					} else {
						sameCheck.put(sameInfo, i);
					}
					//判断计时计件工资必填
					if (CommonConstants.ONE_STRING.equals(attachInfo.getSalaryType()) && Common.isEmpty(attachInfo.getSalaryStandardPerHour())) {
						errorList.add(new ErrorMessage(i, "计时工资不能为空", CommonConstants.RED));
						continue;
					}
					if (CommonConstants.TWO_STRING.equals(attachInfo.getSalaryType()) && Common.isEmpty(attachInfo.getSalaryStandardPerPiece())) {
						errorList.add(new ErrorMessage(i, "计件工资不能为空", CommonConstants.RED));
						continue;
					}
					//项目编码是否准确
					TSettleDomain settleDomain = tSettleDomainService.getOne(Wrappers.<TSettleDomain>query().lambda().eq(TSettleDomain::getDepartNo, attachInfo.getDepartNo())
							.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING).eq(TSettleDomain::getStopFlag, CommonConstants.ZERO_STRING));
					if (Common.isEmpty(settleDomain)) {
						errorList.add(new ErrorMessage(i, "项目编码有误", CommonConstants.RED));
						continue;
					}
					//查询员工合同
					TEmployeeContractInfo employeeContractInfo = employeeContractInfoMapper.selectOne(Wrappers.<TEmployeeContractInfo>query().lambda()
							.eq(TEmployeeContractInfo::getEmpIdcard, attachInfo.getEmpIdcard()).eq(TEmployeeContractInfo::getSettleDomain, settleDomain.getId())
							.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING)
							.eq(TEmployeeContractInfo::getDeleteFlag, CommonConstants.ZERO_STRING)
							.last(CommonConstants.LAST_ONE_SQL));
					if (employeeContractInfo != null) {
						long count = this.count(Wrappers.<FddContractAttachInfo>query().lambda().eq(FddContractAttachInfo::getContractId, employeeContractInfo.getId()));
						if (count > CommonConstants.ZERO_INT && attachInfo.getContractStart().before(employeeContractInfo.getContractEnd())) {
							errorList.add(new ErrorMessage(i, "已导入合同相关基础数据", CommonConstants.RED));
							continue;
						}

						List<FddContractTemplate> fddContractTemplateList = fddContractTemplateService.list(Wrappers.<FddContractTemplate>query().lambda()
								.eq(FddContractTemplate::getFddTemplateId, attachInfo.getFddTemplateId())
								.eq(FddContractTemplate::getModifyUploadStatus, CommonConstants.dingleDigitStrArray[1]));
						//如果模板存在则生成法大大电子合同数据
						if (fddContractTemplateList.size() == CommonConstants.ZERO_INT) {
							errorList.add(new ErrorMessage(i, "未获取到有效的合同模板", CommonConstants.RED));
							continue;
						}
						if (fddContractTemplateList.size() != CommonConstants.ONE_INT) {
							errorList.add(new ErrorMessage(i, "法大大合同有效合同模板存在多条", CommonConstants.RED));
							continue;
						} else {
							errorList.add(new ErrorMessage(i, "存在“在用”的合同", CommonConstants.RED));
							continue;
						}
					}

					//校验数据
					R<String> employeeParamR;
					//新签
					employeeParamR = fddContractInfoService.generalEmployeeParam(attachInfo, false);
					if (CommonConstants.FAIL == employeeParamR.getCode()) {
						errorList.add(new ErrorMessage(i, employeeParamR.getMsg(), CommonConstants.RED));
						continue;
					}

					//保存合同数据
					attachInfo.setContractId(CommonConstants.EMPTY_STRING);
					attachInfo.setCreateTime(LocalDateTime.now());
					//保存数据
					this.save(attachInfo);
					attachInfo.setContractId(attachInfo.getId());
					this.updateById(attachInfo);
					//判断员工是否有实名数据，如果没有插入是实名数据
					long fddPersonCount = fddPersonAccountService.count(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getMoblie, attachInfo.getEmpPhone())
							.eq(FddPersonAccount::getIdCard, attachInfo.getEmpIdcard()).eq(FddPersonAccount::getName, attachInfo.getEmpName())
							.eq(FddPersonAccount::getSystemFlag, CommonConstants.ONE_STRING));
					if (fddPersonCount == CommonConstants.ZERO_INT) {
						FddPersonAccount fddPersonAccount = new FddPersonAccount();
						fddPersonAccount.setMoblie(attachInfo.getEmpPhone());
						fddPersonAccount.setName(attachInfo.getEmpName());
						fddPersonAccount.setIdCard(attachInfo.getEmpIdcard());
						fddPersonAccount.setSystemFlag(CommonConstants.ONE_STRING);
						fddPersonAccount.setRealStatus(CommonConstants.ZERO_STRING);
						fddPersonAccountService.save(fddPersonAccount);
						executorService.submit(() -> {
							try {
								fddPersonAccountService.sendAuthMessage(fddPersonAccount.getId());
							} catch (Exception e) {
								log.error("执行异常", e);
							}
						});
					} else {
						executorService.submit(() -> {
							try {
								//如果已经实名发送电子合同
								FddContractAttachInfo fddContractAttachInfo = this.getById(attachInfo.getId());
								R<String> returnR = fddContractInfoService.saveEmpContract(fddContractAttachInfo, user);
								if (returnR != null) {
									//记录返回信息
									if (returnR.getCode() == CommonConstants.SUCCESS) {
										fddContractAttachInfo.setRemark("成功");
									} else {
										fddContractAttachInfo.setRemark(returnR.getMsg());
									}
									this.updateById(fddContractAttachInfo);
								}
							} catch (Exception e) {
								e.printStackTrace();
							}
						});
					}
				}
			} else {
				errorList.add(new ErrorMessage(i, "无数据保存"));
			}
		} catch (Exception e) {
			log.error("合同数据批量新增异常" + e.getMessage());
			errorList.add(new ErrorMessage(i, "合同数据批量新增异常:" + e.getMessage()));
			return errorList;
		}
		return errorList;
	}

	@Override
	public List<ErrorMessage> batchUpdate(List<FddContractAttachInfo> entityList) {
		List<ErrorMessage> errorList = new ArrayList<>();
		int i = 1;
		try {
			if (null != entityList && !entityList.isEmpty()) {
				for (FddContractAttachInfo attachInfo : entityList) {
					//查询员工合同
					TEmployeeContractInfo employeeContractInfoValid = employeeContractInfoMapper.selectOne(Wrappers.<TEmployeeContractInfo>query().lambda()
							.eq(TEmployeeContractInfo::getEmpName, attachInfo.getEmpName()).eq(TEmployeeContractInfo::getEmpIdcard, attachInfo.getEmpIdcard())
							.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING).eq(TEmployeeContractInfo::getIsObsolete, CommonConstants.ZERO_STRING)
							.eq(TEmployeeContractInfo::getContractStart, attachInfo.getContractStart())
							.last(CommonConstants.LAST_ONE_SQL));
					if (employeeContractInfoValid == null) {
						errorList.add(new ErrorMessage(i, NO_VALID_CONTRACT_FOUND, CommonConstants.RED));
						continue;
					}
					if (StringUtils.equals(CommonConstants.ONE_STRING, employeeContractInfoValid.getContractType())) {
						if (employeeContractInfoValid.getContractEnd() == null) {
							errorList.add(new ErrorMessage(i, "员工合同结束时间为空", CommonConstants.RED));
							continue;
						}
					}
					//查询员工合同是否存在
					TEmployeeContractInfo employeeContractInfo = employeeContractInfoMapper.selectOne(Wrappers.<TEmployeeContractInfo>query().lambda()
							.eq(TEmployeeContractInfo::getEmpName, attachInfo.getEmpName()).eq(TEmployeeContractInfo::getEmpIdcard, attachInfo.getEmpIdcard())
							.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING)
							.and(wrapper -> wrapper.and(wrapper2 -> wrapper2.eq(TEmployeeContractInfo::getContractStart, attachInfo.getContractStart())
											.eq(TEmployeeContractInfo::getContractEnd, attachInfo.getContractEnd()).eq(TEmployeeContractInfo::getContractType, CommonConstants.ONE_STRING))//有合同截止日期
									.or(wrapper1 -> wrapper1.eq(TEmployeeContractInfo::getContractStart, attachInfo.getContractStart()).in(TEmployeeContractInfo::getContractType, CommonConstants.ZERO_STRING, CommonConstants.TWO_STRING))//无合同截止时间
							).last(CommonConstants.LAST_ONE_SQL));
					if (employeeContractInfo == null) {
						errorList.add(new ErrorMessage(i, NO_VALID_CONTRACT_FOUND, CommonConstants.RED));
						continue;
					}
					FddContractAttachInfo fddContractAttachInfo = this.getOne(Wrappers.<FddContractAttachInfo>query().lambda().eq(FddContractAttachInfo::getContractId, employeeContractInfo.getId()));
					if (fddContractAttachInfo == null) {
						errorList.add(new ErrorMessage(i, "为获取到电子合同数据", CommonConstants.RED));
						continue;
					}
					BeanUtils.copyProperties(attachInfo, fddContractAttachInfo);
					//保存合同数据
					this.updateById(fddContractAttachInfo);
					i++;
					errorList.add(new ErrorMessage(i, "更新成功", CommonConstants.GREEN));
				}
			} else {
				errorList.add(new ErrorMessage(i, EmployeeConstants.NO_DATA_UPDATE));
			}
		} catch (Exception e) {
			log.error("合同数据批量新增异常" + e.getMessage());
			return errorList;
		}
		return errorList;
	}

	/**
	 * @param fddContractInfo
	 * @param fddContractAttachInfo
	 * @param newEmployeeContractInfo
	 * @Author: huyc
	 * @Date: 2022/06/01
	 * @Description: 更新合同id
	 * @return:
	 **/
	public void updateContractId(FddContractInfo fddContractInfo, FddContractAttachInfo fddContractAttachInfo, TEmployeeContractInfo newEmployeeContractInfo) {
		//更新合同id
		fddContractAttachInfo.setContractId(newEmployeeContractInfo.getId());
		this.updateById(fddContractAttachInfo);
		//更新合同id
		fddContractInfo.setContractId(newEmployeeContractInfo.getId());
		fddContractInfoService.updateById(fddContractInfo);
	}

	/**
	 * @param newEmployeeContractInfo
	 * @param fddContractAttachInfo
	 * @param settleDomain
	 * @param fddContractTemplate
	 * @param tEmployeeInfo
	 * @param tEmployeeProject
	 * @Author: huyc
	 * @Date: 2022/06/01
	 * @Description: 新增合同
	 * @return:
	 **/
	public void saveTEmployeeContractInfo(TEmployeeContractInfo newEmployeeContractInfo, FddContractAttachInfo fddContractAttachInfo, TSettleDomain settleDomain, FddContractTemplate fddContractTemplate,
										  TEmployeeInfo tEmployeeInfo, TCustomerInfo tCustomerInfo, TEmployeeProject tEmployeeProject) {
		TEmployeeContractInfo employeeContractCount = employeeContractInfoMapper.selectOne(Wrappers.<TEmployeeContractInfo>query().lambda()
				.eq(TEmployeeContractInfo::getEmpIdcard, fddContractAttachInfo.getEmpIdcard()).eq(TEmployeeContractInfo::getSettleDomain, settleDomain.getId())
				.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING)
				.eq(TEmployeeContractInfo::getDeleteFlag, CommonConstants.ZERO_INT)
				.last(CommonConstants.LAST_ONE_SQL));
		//合同表里没有在用的合同
		if (null == employeeContractCount) {
			newEmployeeContractInfo.setEmpName(fddContractAttachInfo.getEmpName());
			newEmployeeContractInfo.setEmpIdcard(fddContractAttachInfo.getEmpIdcard());
			newEmployeeContractInfo.setSettleDomain(settleDomain.getId());
			newEmployeeContractInfo.setSubjectDepart(settleDomain.getDepartName());
			newEmployeeContractInfo.setSubjectUnit(tCustomerInfo.getCustomerName());
			newEmployeeContractInfo.setContractType(CommonConstants.ONE_STRING);
			newEmployeeContractInfo.setContractStart(fddContractAttachInfo.getContractStart());
			newEmployeeContractInfo.setContractEnd(fddContractAttachInfo.getContractEnd());
			newEmployeeContractInfo.setPost(fddContractAttachInfo.getPost());
			newEmployeeContractInfo.setWorkingHours("");
			newEmployeeContractInfo.setSituation("正常签订");
			newEmployeeContractInfo.setIsObsolete(CommonConstants.ZERO_STRING);
			newEmployeeContractInfo.setEmpId(tEmployeeInfo.getId());
			newEmployeeContractInfo.setWorkFlag(CommonConstants.ZERO_STRING);
			newEmployeeContractInfo.setIsFile(CommonConstants.ONE_STRING);
			newEmployeeContractInfo.setEmpNo(tEmployeeProject.getEmpNo());
			newEmployeeContractInfo.setFileCity(tEmployeeInfo.getFileCity());
			newEmployeeContractInfo.setFileProvince(tEmployeeInfo.getFileProvince());
			newEmployeeContractInfo.setFileTown(tEmployeeInfo.getFileTown());
			newEmployeeContractInfo.setInUse(CommonConstants.ZERO_STRING);
			newEmployeeContractInfo.setIsSign(CommonConstants.dingleDigitIntArray[1]);
			newEmployeeContractInfo.setAuditStatus(CommonConstants.dingleDigitIntArray[2]);
			newEmployeeContractInfo.setAuditTimeLast(LocalDateTime.now());
			newEmployeeContractInfo.setCustomerId(tCustomerInfo.getId());
			newEmployeeContractInfo.setDeptNo(fddContractAttachInfo.getDepartNo());
			newEmployeeContractInfo.setUnitNo(tCustomerInfo.getCustomerCode());
			newEmployeeContractInfo.setFddFlag(CommonConstants.ONE_STRING);
			newEmployeeContractInfo.setEmpNatrue(fddContractAttachInfo.getEmpNatrue());
			newEmployeeContractInfo.setCreateBy(fddContractAttachInfo.getCreateBy());
			newEmployeeContractInfo.setCreateName(fddContractAttachInfo.getCreateName());
			newEmployeeContractInfo.setUpdateBy(fddContractAttachInfo.getUpdateBy());
			if (Common.isNotNull(fddContractAttachInfo.getPeriodStart())) {
				newEmployeeContractInfo.setPeriodStart(localDate2Date(fddContractAttachInfo.getPeriodStart()));
			}
			if (Common.isNotNull(fddContractAttachInfo.getPeriodEnd())) {
				newEmployeeContractInfo.setPeriodEnd(localDate2Date(fddContractAttachInfo.getPeriodEnd()));
			}
			if (Common.isNotNull(fddContractAttachInfo.getPeriodSalaryPerMonth())) {
				newEmployeeContractInfo.setPeriodSalaryPerMonth(fddContractAttachInfo.getPeriodSalaryPerMonth());
			}
			newEmployeeContractInfo.setSalaryType(fddContractAttachInfo.getSalaryType());
			if (Common.isNotNull(fddContractAttachInfo.getSalaryStandardPerHour())) {
				newEmployeeContractInfo.setSalaryStandardPerHour(fddContractAttachInfo.getSalaryStandardPerHour());
			}
			if (Common.isNotNull(fddContractAttachInfo.getSalaryStandardPerPiece())) {
				newEmployeeContractInfo.setSalaryStandardPerPiece(fddContractAttachInfo.getSalaryStandardPerPiece());
			}
			String contractName = "";
			// 渲染字典值
			Map<String, String> dicObj = (Map<String, String>) RedisUtil.redis.opsForValue()
					.get(CacheConstants.DICT_DETAILS
							+ CommonConstants.COLON_STRING
							+ "personnel_type");
			if (Common.isNotNull(dicObj)) {
				contractName = dicObj.get(fddContractTemplate.getType());
			}
			newEmployeeContractInfo.setContractName(contractName);

			int monthDiff = DateUtil.getMonthDiff(fddContractAttachInfo.getContractStart(), fddContractAttachInfo.getContractEnd());
			BigDecimal b = new BigDecimal(String.valueOf(monthDiff / 12.0));
			b = b.setScale(1, BigDecimal.ROUND_HALF_UP);
			newEmployeeContractInfo.setContractTerm(String.valueOf(b));
			newEmployeeContractInfo.setApplyNo(this.getSqCode());
			employeeContractInfoMapper.insert(newEmployeeContractInfo);
		}
	}

	/**
	 * @param fddContractAttachInfo
	 * @param settleDomain
	 * @param fddContractTemplate
	 * @param newEmployeeInfo
	 * @param tCustomerInfo
	 * @param newTEmpProject
	 * @Author: huyc
	 * @Date: 2022/06/01
	 * @Description: 新增项目档案
	 * @return:
	 **/
	public void saveEmployeeproject(FddContractAttachInfo fddContractAttachInfo, TSettleDomain settleDomain, FddContractTemplate fddContractTemplate,
									TEmployeeInfo newEmployeeInfo, TCustomerInfo tCustomerInfo, TEmployeeProject newTEmpProject) {
		//新增项目档案
		newTEmpProject.setEmpName(fddContractAttachInfo.getEmpName());
		newTEmpProject.setEmpId(newEmployeeInfo.getId());
		newTEmpProject.setEmpIdcard(fddContractAttachInfo.getEmpIdcard());
		newTEmpProject.setEmpPhone(fddContractAttachInfo.getEmpPhone());
		newTEmpProject.setDeptId(settleDomain.getId());
		newTEmpProject.setDeptNo(settleDomain.getDepartNo());
		newTEmpProject.setDeptName(settleDomain.getDepartName());
		newTEmpProject.setPost(fddContractAttachInfo.getPost());
		newTEmpProject.setUnitId(tCustomerInfo.getId());
		newTEmpProject.setUnitName(tCustomerInfo.getCustomerName());
		newTEmpProject.setUnitNo(tCustomerInfo.getCustomerCode());
		newTEmpProject.setContractType(fddContractTemplate.getType());
		newTEmpProject.setStatus(CommonConstants.dingleDigitIntArray[0]);
		newTEmpProject.setEmpNatrue(fddContractAttachInfo.getEmpNatrue());
		newTEmpProject.setEmpCode(newEmployeeInfo.getEmpCode());
		newTEmpProject.setBusinessPrimaryType(settleDomain.getBusinessPrimaryType());
		newTEmpProject.setBusinessSecondType(settleDomain.getBusinessSecondType());
		newTEmpProject.setBusinessThirdType(settleDomain.getBusinessThirdType());
		newTEmpProject.setProjectSource(CommonConstants.dingleDigitStrArray[7]);
		newTEmpProject.setContractStatus(CommonConstants.ONE_INT);
		newTEmpProject.setCreateBy(fddContractAttachInfo.getCreateBy());
		newTEmpProject.setCreateName(fddContractAttachInfo.getCreateName());
		newTEmpProject.setUpdateBy(fddContractAttachInfo.getUpdateBy());
		String empNO = "";
		empNO = getEmpNo(newTEmpProject.getDeptNo());
		newTEmpProject.setEmpNo(empNO);
		//新增档案
		employeeProjectMapper.insert(newTEmpProject);
	}

	//获取员工编码
	public String getEmpNo(String deptNo) {
		String str = "";
		String EmpNo = employeeProjectMapper.findEmployeeMaxOnlyNoByDepId(deptNo);
		if (!Common.isEmpty(EmpNo)) {
			str = NoUtil.productionNo(EmpNo, CommonConstants.EMPLOYEE_INIT_NO_START);
		} else {
			str = deptNo + CommonConstants.EMPLOYEE_INIT_NO;
		}
		return str;
	}

	//获取员工主码
	private synchronized String getCode() {
		String nowDay = DateUtil.getThisDay();
		Cache cache = cacheManager.getCache(CacheConstants.EVERYDAY_EMP_CODE);
		Object nowNumObj = cache.get(nowDay);
		int nowNums = 1;
		if (Common.isNotNull(nowNumObj)) {
			SimpleValueWrapper value = (SimpleValueWrapper) nowNumObj;
			nowNums = (Integer) value.get() + 1;
		}
		cache.put(nowDay, nowNums);
		return "ZM" + nowDay + this.getFiveNum(String.valueOf(nowNums));
	}

	/**
	 * @param nowNums 数字
	 * @Description: 获取五位字符型数字
	 * @Author: hgw
	 * @Date: 2022/6/21 17:35
	 * @return: 五位字符型数字
	 **/
	private String getFiveNum(String nowNums) {
		if (nowNums.length() >= 5) {
			return nowNums.substring(0, 5);
		}
		String[] zeroArr = {"0", "00", "000", "0000"};
		int num = 4 - nowNums.length();
		return zeroArr[num] + nowNums;
	}

	/**
	 * @param
	 * @Description: 获取 申请编码
	 * @Author: hgw
	 * @Date: 2022/6/22 17:52
	 * @return: java.lang.String
	 **/
	private synchronized String getSqCode() {
		String nowDay = DateUtil.getThisDay();
		Cache cache = cacheManager.getCache(CacheConstants.EVERYDAY_EMP_CONTRACT_CODE);
		Object nowNumObj = cache.get(nowDay);
		int nowNums = 1;
		if (Common.isNotNull(nowNumObj)) {
			SimpleValueWrapper value = (SimpleValueWrapper) nowNumObj;
			nowNums = (Integer) value.get() + 1;
		} else {
			String empCode = null;
			try {
				empCode = employeeContractInfoMapper.getMaxContractCode();
				nowNums = Integer.parseInt(empCode) + 1;
			} catch (NumberFormatException e) {
				log.error("获取人员合同当日最大编码时出错：" + empCode);
				nowNums = 1;
			}
		}
		cache.put(nowDay, nowNums);
		return "HT" + nowDay + this.getFourNum(String.valueOf(nowNums));
	}

	/**
	 * @param nowNums 数字
	 * @Description: 获取四位字符型数字
	 * @Author: hgw
	 * @Date: 2022-6-30 16:05:25
	 * @return: 五位字符型数字
	 **/
	private String getFourNum(String nowNums) {
		if (nowNums.length() >= 4) {
			return nowNums.substring(0, 4);
		}
		String[] zeroArr = {"0", "00", "000"};
		int num = 3 - nowNums.length();
		return zeroArr[num] + nowNums;
	}

	public static Date localDate2Date(LocalDate localDate) {
		if (null == localDate) {
			return null;
		}
		ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
		return Date.from(zonedDateTime.toInstant());
	}
}
