/*
 *    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.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
import com.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.constants.EmployeeContractConstants;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmployeeContractInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.archives.vo.EmployeeContractExportVO;
import com.yifu.cloud.plus.v1.yifu.archives.vo.EmployeeContractUpdateVO;
import com.yifu.cloud.plus.v1.yifu.archives.vo.EmployeeContractVO;
import com.yifu.cloud.plus.v1.yifu.archives.vo.ErrorVO;
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.ResultConstants;
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.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 员工合同
 *
 * @author hgw
 * @date 2022-06-29 20:45:22
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class TEmployeeContractInfoServiceImpl extends ServiceImpl<TEmployeeContractInfoMapper, TEmployeeContractInfo> implements TEmployeeContractInfoService {

	private static final String ID_NOT_EMPTY = "ID,EMP_ID不可为空";

	private static final String EMPINFO_IS_NOT_EXITS_BYID = "未找到人员档案与项目档案！";

	private final TEmployeeInfoService tEmployeeInfoService;
	private final TEmployeeProjectService tEmployeeProjectService;
	private final TSettleDomainService tSettleDomainService;
	private final TCustomerInfoService tCustomerInfoService;
	private final TAttaInfoService tAttaInfoService;
	private final TEmployeeContractAuditService tEmployeeContractAuditService;
	private final TEmployeeLogService tEmployeeLogService;

	// 缓存信息
	private final CacheManager cacheManager;

	/**
	 * 员工合同信息表简单分页查询
	 *
	 * @param tEmployeeContractInfo 员工合同信息表
	 * @return
	 */
	@Override
	public IPage<TEmployeeContractInfo> getTEmployeeContractInfoPage(Page<TEmployeeContractInfo> page, TEmployeeContractInfo tEmployeeContractInfo) {
		return baseMapper.getTEmployeeContractInfoPage(page, tEmployeeContractInfo);
	}

	@Override
	public List<TEmployeeContractInfo> getTEmployeeContractList(TEmployeeContractInfo tEmployeeContractInfo) {
		return baseMapper.getTEmployeeContractList(tEmployeeContractInfo);
	}

	@Override
	public List<EmployeeContractExportVO> getTEmployeeContractExport(TEmployeeContractInfo tEmployeeContractInfo) {
		return baseMapper.getTEmployeeContractExport(tEmployeeContractInfo);
	}

	@Override
	public List<EmployeeContractExportVO> getTEmployeeContractExportHistory(TEmployeeContractInfo tEmployeeContractInfo) {
		return baseMapper.getTEmployeeContractExportHistory(tEmployeeContractInfo);
	}

	@Override
	public R<List<ErrorMessage>> saveNewContract(TEmployeeContractInfo tEmployeeContractInfo) {
		try {
			if (Common.isEmpty(tEmployeeContractInfo.getEmpId()) || Common.isEmpty(tEmployeeContractInfo.getSettleDomain())) {
				return R.failed(EmployeeConstants.EMPID_NOT_EMPTY);
			}
			return this.setBaseInfo(tEmployeeContractInfo, null);
		} catch (Exception e) {
			log.error("员工合同保存异常：" + e.getMessage());
			return R.failed("员工合同保存系统异常！");
		}
	}

	private R<List<ErrorMessage>> setBaseInfo(TEmployeeContractInfo tEmployeeContractInfo, TEmployeeProject tEmployeeProject) {
		// 获取人员档案
		TEmployeeInfo tEmployeeInfo = tEmployeeInfoService.getById(tEmployeeContractInfo.getEmpId());
		// 获取项目
		if (tEmployeeProject == null) {
			tEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query()
					.lambda().eq(TEmployeeProject::getEmpId, tEmployeeContractInfo.getEmpId())
					.eq(TEmployeeProject::getDeptId, tEmployeeContractInfo.getSettleDomain())
					.eq(TEmployeeProject::getProjectStatus, CommonConstants.ZERO_INT)
					.eq(TEmployeeProject::getDeleteFlag, CommonConstants.STATUS_NORMAL)
					.last(CommonConstants.LAST_ONE_SQL));
		}
		if (null == tEmployeeInfo || tEmployeeProject == null) {
			return R.failed(EMPINFO_IS_NOT_EXITS_BYID);
		}
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getId())) {
			return R.failed(CommonConstants.PLEASE_LOG_IN);
		}
		// 初始化
		this.initEmployeeContract(tEmployeeContractInfo, tEmployeeInfo, tEmployeeProject, user);

		//是否归档：否
		tEmployeeContractInfo.setIsFile(CommonConstants.ONE_STRING);

		//是否在用：否
		tEmployeeContractInfo.setInUse(CommonConstants.ONE_STRING);

		ExcelAttributeValidityUtil<TEmployeeContractInfo> validity = new ExcelAttributeValidityUtil<>(TEmployeeContractInfo.class);
		validity.ValidityObj(tEmployeeContractInfo);
		if (null != validity.getErrorInfo() && !validity.getErrorInfo().isEmpty()) {
			return R.failed(validity.getErrorInfo(), ResultConstants.VALIDITY_FAIL);
		}

		return this.saveContractAndAtta(tEmployeeContractInfo);
	}

	@Override
	public R<List<ErrorMessage>> updateContract(TEmployeeContractInfo tEmployeeContractInfo) {
		try {
			if (Common.isEmpty(tEmployeeContractInfo.getId()) || Common.isEmpty(tEmployeeContractInfo.getEmpId())) {
				return R.failed(ID_NOT_EMPTY);
			}
			YifuUser user = SecurityUtils.getUser();
			if (user == null || Common.isEmpty(user.getId())) {
				return R.failed(CommonConstants.PLEASE_LOG_IN);
			}
			// 初始化
			tEmployeeContractInfo.setUpdateBy(user.getId());
			tEmployeeContractInfo.setUpdateTime(LocalDateTime.now());

			//是否归档：否
			tEmployeeContractInfo.setIsFile(CommonConstants.ONE_STRING);
			//是否在用：否
			tEmployeeContractInfo.setInUse(CommonConstants.ONE_STRING);

			ExcelAttributeValidityUtil<TEmployeeContractInfo> validity = new ExcelAttributeValidityUtil<>(TEmployeeContractInfo.class);
			validity.ValidityObj(tEmployeeContractInfo);
			if (null != validity.getErrorInfo() && !validity.getErrorInfo().isEmpty()) {
				return R.failed(validity.getErrorInfo(), ResultConstants.VALIDITY_FAIL);
			}
			return this.saveContractAndAtta(tEmployeeContractInfo);
		} catch (Exception e) {
			log.error("员工合同保存异常：" + e.getMessage());
			return R.failed("员工合同保存系统异常！");
		}
	}


	private void initEmployeeContract(TEmployeeContractInfo tEmployeeContractInfo, TEmployeeInfo tEmployeeInfo
			, TEmployeeProject tEmployeeProject, YifuUser user) {
		tEmployeeContractInfo.setEmpId(tEmployeeInfo.getId());
		tEmployeeContractInfo.setEmpNatrue(tEmployeeProject.getEmpNatrue());
		tEmployeeContractInfo.setEmpIdcard(tEmployeeInfo.getEmpIdcard());
		tEmployeeContractInfo.setEmpName(tEmployeeInfo.getEmpName());
		tEmployeeContractInfo.setEmpNo(tEmployeeProject.getEmpNo());
		if (Common.isEmpty(tEmployeeContractInfo.getCreateBy())) {
			tEmployeeContractInfo.setCreateBy(null == user ? "" : user.getId());
			tEmployeeContractInfo.setCreateName(null == user ? "" : user.getNickname());
			tEmployeeContractInfo.setCreateTime(LocalDateTime.now());
		}
		tEmployeeContractInfo.setUpdateBy(null == user ? "" : user.getId());
		tEmployeeContractInfo.setUpdateTime(LocalDateTime.now());
		tEmployeeContractInfo.setSettleDomain(tEmployeeProject.getDeptId());
		tEmployeeContractInfo.setCustomerId(tEmployeeProject.getUnitId());
		tEmployeeContractInfo.setSubjectUnit(tEmployeeProject.getUnitName());
		tEmployeeContractInfo.setUnitNo(tEmployeeProject.getUnitNo());
		tEmployeeContractInfo.setSubjectDepart(tEmployeeProject.getDeptName());
		tEmployeeContractInfo.setDeptNo(tEmployeeProject.getDeptNo());
		tEmployeeContractInfo.setFileProvince(tEmployeeInfo.getFileProvince());
		tEmployeeContractInfo.setFileCity(tEmployeeInfo.getFileCity());
		tEmployeeContractInfo.setFileTown(tEmployeeInfo.getFileTown());
		tEmployeeContractInfo.setWorkFlag(String.valueOf(tEmployeeInfo.getFileStatus()));
		tEmployeeContractInfo.setWorkingStatusSub(CommonConstants.ZERO_STRING);
		//是否作废：否
		tEmployeeContractInfo.setIsObsolete(CommonConstants.ZERO_STRING);
		tEmployeeContractInfo.setDeleteFlag(CommonConstants.ZERO_INT);
		if (Common.isEmpty(tEmployeeContractInfo.getApplyNo())) {
			tEmployeeContractInfo.setApplyNo(this.getCode(false));
		}
	}

	/**
	 * @param isNew true:取数据库最新的
	 * @Description: 获取 申请编码
	 * @Author: hgw
	 * @Date: 2022/6/22 17:52
	 * @return: java.lang.String
	 **/
	private synchronized String getCode(boolean isNew) {
		String nowDay = DateUtil.getThisDay();
		int nowNums;
		String empCode = null;
		Cache cache = cacheManager.getCache(CacheConstants.EVERYDAY_EMP_CONTRACT_CODE);
		if (isNew) {
			empCode = baseMapper.getMaxContractCode();
			nowNums = Integer.parseInt(empCode) + 1;
		} else {
			try {
				Object nowNumObj = cache.get(nowDay);
				if (Common.isNotNull(nowNumObj)) {
					SimpleValueWrapper value = (SimpleValueWrapper) nowNumObj;
					nowNums = (Integer) value.get() + 1;
				} else {
					empCode = baseMapper.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;
	}

	/**
	 * 保存员工合同表及附件关系表
	 *
	 * @param tEmployeeContractInfo
	 * @return
	 * @Author fxj
	 * @Date 2019-09-09
	 **/
	private R<List<ErrorMessage>> saveContractAndAtta(TEmployeeContractInfo tEmployeeContractInfo) {
		//档案柜存在就自动归档
		if (Common.isNotNull(tEmployeeContractInfo.getAttaList())) {
			tEmployeeContractInfo.setIsFile(CommonConstants.ZERO_STRING);
		}
		if (null != tEmployeeContractInfo.getSettleDomain()
				&& (Common.isEmpty(tEmployeeContractInfo.getSubjectUnit())
				|| Common.isEmpty(tEmployeeContractInfo.getSubjectDepart()))) {
			TSettleDomain settleDomain = tSettleDomainService.getById(tEmployeeContractInfo.getSettleDomain());
			if (null != settleDomain) {
				if (Common.isEmpty(tEmployeeContractInfo.getSubjectDepart())) {
					tEmployeeContractInfo.setSubjectDepart(settleDomain.getDepartName());
					tEmployeeContractInfo.setDeptNo(settleDomain.getDepartNo());
				}
				if (null != settleDomain.getCustomerId() && Common.isEmpty(tEmployeeContractInfo.getSubjectUnit())) {
					TCustomerInfo customerInfo = tCustomerInfoService.getById(settleDomain.getCustomerId());
					if (null != customerInfo) {
						tEmployeeContractInfo.setSubjectUnit(customerInfo.getCustomerName());
						tEmployeeContractInfo.setUnitNo(customerInfo.getCustomerCode());
					}
				}
			}
		}
		if (Common.isEmpty(tEmployeeContractInfo.getId())) {
			// 针对编码再做一次重复性校验
			String isCur = baseMapper.getContractByApplyNo(tEmployeeContractInfo.getApplyNo());
			if (Common.isNotNull(isCur)) {
				String code = this.getCode(true);
				tEmployeeContractInfo.setApplyNo(code);
			}
			baseMapper.insert(tEmployeeContractInfo);
			if (Common.isNotNull(tEmployeeContractInfo.getAttaList()) && Common.isNotNull(tEmployeeContractInfo.getId())) {
				this.updateFileMainId(tEmployeeContractInfo);
			}
		} else {
			baseMapper.updateById(tEmployeeContractInfo);
		}
		// 不是待提交，记录审核记录
		this.setAuditInfo(tEmployeeContractInfo);

		// 更新档案合同状态
		this.updateEmployeeContractStatus(tEmployeeContractInfo.getEmpId());
		return R.ok(null, CommonConstants.SAVE_SUCCESS);
	}

	/**
	 * @param tEmployeeContractInfo
	 * @Description: 更新附件的合同id
	 * @Author: hgw
	 * @Date: 2022/7/20 10:07
	 * @return: void
	 **/
	private void updateFileMainId(TEmployeeContractInfo tEmployeeContractInfo) {
		List<String> attaList = tEmployeeContractInfo.getAttaList();
		if (null != attaList && !attaList.isEmpty()) {
			TAttaInfo contractAtta;
			for (String attaId : attaList) {
				contractAtta = tAttaInfoService.getById(attaId);
				if (contractAtta != null && Common.isEmpty(contractAtta.getDomainId())) {
					contractAtta.setDomainId(tEmployeeContractInfo.getId());
					tAttaInfoService.updateById(contractAtta);
				}
			}
		}
	}

	/**
	 * @param tEmployeeContractInfo
	 * @Description: 保存审核操作记录
	 * @Author: hgw
	 * @Date: 2022/7/1 10:16
	 * @return: void
	 **/
	private void setAuditInfo(TEmployeeContractInfo tEmployeeContractInfo) {
		if (Common.isNotNull(tEmployeeContractInfo.getAuditStatus())
				&& CommonConstants.ZERO_INT != tEmployeeContractInfo.getAuditStatus()) {
			TEmployeeContractAudit audit = new TEmployeeContractAudit();
			if (CommonConstants.ONE_INT == tEmployeeContractInfo.getAuditStatus()) {
				audit.setRootName("提交申请");
			}
			if (CommonConstants.dingleDigitIntArray[2] == tEmployeeContractInfo.getAuditStatus()) {
				audit.setRootName("合同审核");
				audit.setAuditStatus("审核通过");
				audit.setRemark(tEmployeeContractInfo.getAuditRemark());
			}
			if (CommonConstants.dingleDigitIntArray[3] == tEmployeeContractInfo.getAuditStatus()) {
				audit.setRootName("合同审核");
				audit.setAuditStatus("审核不通过");
				audit.setRemark(tEmployeeContractInfo.getAuditRemark());
			}
			audit.setLinkId(tEmployeeContractInfo.getId());
			audit.setLinkType(CommonConstants.ONE_INT);
			tEmployeeContractAuditService.save(audit);
		}
	}

	/**
	 * @Description: 合同归档记录
	 * @Author: hgw
	 * @Date: 2022/7/7 10:28
	 * @return: void
	 **/
	private void setFileInfo(String id, String remark) {
		TEmployeeContractAudit audit = new TEmployeeContractAudit();
		audit.setRootName("合同归档");
		audit.setLinkId(id);
		audit.setLinkType(CommonConstants.ONE_INT);
		audit.setRemark(remark);
		tEmployeeContractAuditService.save(audit);
	}

	private void updateEmployeeContractStatus(String empId) {
		//查看未作废合同数
		TEmployeeInfo employeeInfo = tEmployeeInfoService.getById(empId);
		if (employeeInfo != null) {
			employeeInfo.setContractStatus(CommonConstants.ONE_INT);
		}
	}

	@Override
	public R<String> auditContract(TEmployeeContractInfo tEmployeeContractInfo) {
		if (tEmployeeContractInfo != null) {
			if (Common.isEmpty(tEmployeeContractInfo.getId()) || Common.isEmpty(tEmployeeContractInfo.getAuditStatus())) {
				return R.failed("id、意见必填");
			}
			TEmployeeContractInfo contractInfo = this.getById(tEmployeeContractInfo.getId());
			if (contractInfo.getAuditStatus() != CommonConstants.ONE_INT) {
				return R.failed("不是待审核状态！");
			}
			if (tEmployeeContractInfo.getAuditStatus() == CommonConstants.dingleDigitIntArray[2]) {

				// 非作废、终止，本条变为在用
				if (Common.isEmpty(contractInfo.getSituation())
						|| (!EmployeeConstants.SITUATION_SIX.equals(contractInfo.getSituation())
						&& !EmployeeConstants.SITUATION_SEVEN.equals(contractInfo.getSituation()))) {
					// 其他变为不在用
					baseMapper.updateInUseStatusById(contractInfo.getEmpId(), contractInfo.getSettleDomain(), contractInfo.getId(), CommonConstants.ONE_STRING);
					tEmployeeContractInfo.setAuditTimeLast(LocalDateTime.now());
					tEmployeeContractInfo.setInUse(CommonConstants.ZERO_STRING);
					// 更新档案、项目合同状态为（1可用）
					TEmployeeProject tEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query()
							.lambda().eq(TEmployeeProject::getEmpId, contractInfo.getEmpId())
							.eq(TEmployeeProject::getDeptId, contractInfo.getSettleDomain())
							.eq(TEmployeeProject::getProjectStatus, CommonConstants.ZERO_INT)
							.eq(TEmployeeProject::getDeleteFlag, CommonConstants.STATUS_NORMAL)
							.last(CommonConstants.LAST_ONE_SQL));
					if (tEmployeeProject != null) {
						tEmployeeProject.setContractStatus(CommonConstants.ONE_INT);
						tEmployeeProjectService.updateById(tEmployeeProject);
					}
					// 更新档案、项目合同状态为（1在用）
					TEmployeeInfo tEmployeeInfo = tEmployeeInfoService.getById(contractInfo.getEmpId());
					if (tEmployeeInfo != null) {
						tEmployeeInfo.setContractStatus(CommonConstants.ONE_INT);
						tEmployeeInfoService.updateById(tEmployeeInfo);
					}
				} else {
					//先停用项目内的其他的员工合同————不要这个逻辑了
					// 2022-7-22 16:54:12 产品倩倩与测试说，作废终止审核通过，仅将原先选择的合同不在用即可
					//baseMapper.updateInUseStatusById(contractInfo.getEmpId(), contractInfo.getSettleDomain(), contractInfo.getId(), CommonConstants.ONE_STRING)
					if (Common.isNotNull(contractInfo.getOldContractId())) {
						TEmployeeContractInfo old = this.getById(contractInfo.getOldContractId());
						if (old != null && Common.isNotNull(old.getId())) {
							if (!CommonConstants.ZERO_STRING.equals(old.getInUse())) {
								return R.failed("关联的原合同已不在用");
							} else {
								old.setInUse(CommonConstants.ONE_STRING);
								this.updateById(old);
							}
						} else {
							return R.failed("未找到关联的原合同");
						}
					} else {
						return R.failed("未找到关联的原合同");
					}

					// 作废、终止审核通过：
					// 更新项目合同状态为（2不在用），档案状态要判断
					TEmployeeProject tEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query()
							.lambda().eq(TEmployeeProject::getEmpId, contractInfo.getEmpId())
							.eq(TEmployeeProject::getDeptId, contractInfo.getSettleDomain())
							.eq(TEmployeeProject::getProjectStatus, CommonConstants.ZERO_INT)
							.eq(TEmployeeProject::getDeleteFlag, CommonConstants.STATUS_NORMAL)
							.last(CommonConstants.LAST_ONE_SQL));
					if (tEmployeeProject != null) {
						tEmployeeProject.setContractStatus(CommonConstants.TWO_INT);
						tEmployeeProjectService.updateById(tEmployeeProject);
					}

					// 更新档案、项目合同状态为（0无合同 1在用 2不在用）
					TEmployeeInfo tEmployeeInfo = tEmployeeInfoService.getById(contractInfo.getEmpId());
					if (tEmployeeInfo != null) {
						// 判断人员有无审核通过的其他合同
						TEmployeeContractInfo contractInfoInUse = this.getOne(Wrappers.<TEmployeeContractInfo>query()
								.lambda().eq(TEmployeeContractInfo::getEmpId, contractInfo.getEmpId())
								.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_INT)
								.eq(TEmployeeContractInfo::getDeleteFlag, CommonConstants.ZERO_INT)
								.last(CommonConstants.LAST_ONE_SQL));
						if (contractInfoInUse != null) {
							tEmployeeInfo.setContractStatus(CommonConstants.ONE_INT);
						} else {
							tEmployeeInfo.setContractStatus(CommonConstants.TWO_INT);
						}
						tEmployeeInfoService.updateById(tEmployeeInfo);
					}
				}
			}
			// 不是待提交，记录审核记录
			this.setAuditInfo(tEmployeeContractInfo);
			this.updateById(tEmployeeContractInfo);
			return R.ok();
		}
		return R.failed("参数不可为空");
	}

	@Override
	public R<String> deleteContract(@RequestParam String id) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getId())) {
			return R.failed(CommonConstants.PLEASE_LOG_IN);
		}
		TEmployeeContractInfo contractInfo = this.getById(id);
		if (contractInfo == null) {
			return R.failed("未找到记录");
		} else {
			if (!user.getId().equals(contractInfo.getCreateBy())) {
				return R.failed(EmployeeContractConstants.NOT_CREATE_USER);
			}
			if (contractInfo.getAuditStatus() != CommonConstants.ZERO_INT
					&& contractInfo.getAuditStatus() != CommonConstants.dingleDigitIntArray[3]) {
				return R.failed(EmployeeContractConstants.NOT_AUDIT_STATUS);
			}
			contractInfo.setDeleteFlag(CommonConstants.ONE_INT);
			this.updateById(contractInfo);
		}
		return R.ok();
	}

	@Override
	public R<List<ErrorVO>> batchDeleteContract(List<String> idList) {
		if (idList == null || idList.isEmpty()) {
			return R.failed("请选择！");
		}
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getId())) {
			return R.failed(CommonConstants.PLEASE_LOG_IN);
		}
		List<ErrorVO> returnList = new ArrayList<>();
		TEmployeeContractInfo contractInfo;
		String id;
		ErrorVO errorVo;
		for (int i = 0; i < idList.size(); i++) {
			errorVo = new ErrorVO();
			errorVo.setResult(CommonConstants.ZERO_INT);
			errorVo.setLineNum(i + 1);
			id = idList.get(i);
			contractInfo = this.getById(id);
			if (contractInfo == null) {
				errorVo.setErrorInfo(EmployeeContractConstants.NO_INFO);
			} else {
				errorVo.setMainName(contractInfo.getApplyNo());
				if (!user.getId().equals(contractInfo.getCreateBy())) {
					errorVo.setErrorInfo(EmployeeContractConstants.NOT_CREATE_USER);
				} else if (contractInfo.getAuditStatus() != CommonConstants.ZERO_INT
						&& contractInfo.getAuditStatus() != CommonConstants.dingleDigitIntArray[3]) {
					errorVo.setErrorInfo(EmployeeContractConstants.NOT_AUDIT_STATUS);
				} else {
					errorVo.setResult(CommonConstants.ONE_INT);
					contractInfo.setDeleteFlag(CommonConstants.ONE_INT);
					this.updateById(contractInfo);
				}
			}
			returnList.add(errorVo);
		}
		return R.ok(returnList);
	}

	@Override
	public R<String> filingContract(TEmployeeContractInfo tEmployeeContractInfo) {
		if (tEmployeeContractInfo != null) {
			if (Common.isEmpty(tEmployeeContractInfo.getContractNo())
					|| Common.isEmpty(tEmployeeContractInfo.getFileCabinetNo())) {
				return R.failed("合同编号、档案柜号必填！");
			}
			if (tEmployeeContractInfo.getContractNo().length() > 50
					|| tEmployeeContractInfo.getFileCabinetNo().length() > 50) {
				return R.failed("合同编号、档案柜号不可超过50字！");
			}
			//档案柜存在就自动归档
			if (Common.isNotNull(tEmployeeContractInfo.getAttaList())) {
				this.updateFileMainId(tEmployeeContractInfo);
				this.setFileInfo(tEmployeeContractInfo.getId(), "添加附件");
				tEmployeeContractInfo.setIsFile(CommonConstants.ZERO_STRING);
			} else {
				this.setFileInfo(tEmployeeContractInfo.getId(), "清空附件");
				tEmployeeContractInfo.setIsFile(CommonConstants.ONE_STRING);
			}
			this.updateById(tEmployeeContractInfo);
			return R.ok();
		}
		return R.failed("参数不可为空");
	}

	@Override
	public R<List<ErrorMessage>> batchUpdate(InputStream inputStream) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<EmployeeContractUpdateVO> util1 = new ExcelUtil<>(EmployeeContractUpdateVO.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {

			EasyExcel.read(inputStream, EmployeeContractUpdateVO.class, new ReadListener<EmployeeContractUpdateVO>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<EmployeeContractUpdateVO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

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

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

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

	/**
	 * @Author hgw
	 * @Description 批量导入
	 * @Date 2022-7-1 18:48:01
	 **/
	@Transactional
	public void updateContract(List<EmployeeContractUpdateVO> excelVOList, List<ErrorMessage> errorMessageList) {
		/// 个性化校验逻辑
		EmployeeContractUpdateVO excel;
		TEmployeeContractInfo contractInfo;
		TEmployeeContractInfo newContractInfo;
		// 执行数据插入操作 组装
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			if (excel != null) {
				if (Common.isNotNull(excel.getContractNo()) || Common.isNotNull(excel.getFileCabinetNo())) {
					if (Common.isNotNull(excel.getApplyNo())) {
						// 存储
						contractInfo = baseMapper.getOneContractByApplyNo(excel.getApplyNo());
						if (contractInfo != null && Common.isNotNull(contractInfo.getId())) {
							if (CommonConstants.dingleDigitIntArray[2] != contractInfo.getAuditStatus()) {
								errorMessageList.add(new ErrorMessage(excel.getRowIndex(), EmployeeContractConstants.NOT_AUDIT));
							} else if (EmployeeConstants.SITUATION_SIX.equals(contractInfo.getSituation())
									|| EmployeeConstants.SITUATION_SEVEN.equals(contractInfo.getSituation())) {
								errorMessageList.add(new ErrorMessage(excel.getRowIndex(), EmployeeContractConstants.INVALID));
							} else {
								newContractInfo = new TEmployeeContractInfo();
								newContractInfo.setId(contractInfo.getId());
								newContractInfo.setContractNo(excel.getContractNo());
								newContractInfo.setFileCabinetNo(excel.getFileCabinetNo());
								this.updateById(newContractInfo);
								// 记录变更日志
								tEmployeeLogService.saveModificationRecord(CommonConstants.dingleDigitIntArray[3], contractInfo.getId(), "", contractInfo, newContractInfo);
								errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_SUCCESS));
							}
						} else {
							errorMessageList.add(new ErrorMessage(excel.getRowIndex(), EmployeeContractConstants.NO_INFO));
						}
					}
				} else {
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), EmployeeContractConstants.NO_CONTRACT_FILE_CABINET));
				}
			} else {
				errorMessageList.add(new ErrorMessage(CommonConstants.ZERO_INT, EmployeeContractConstants.NO_INFO));
			}
		}
	}

	@Override
	public R<List<ErrorMessage>> batchImport(InputStream inputStream) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<EmployeeContractVO> util1 = new ExcelUtil<>(EmployeeContractVO.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {

			EasyExcel.read(inputStream, EmployeeContractVO.class, new ReadListener<EmployeeContractVO>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<EmployeeContractVO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

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


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

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

	/**
	 * @Author hgw
	 * @Description 批量导入
	 * @Date 2022-7-1 18:48:01
	 **/
	@Transactional
	public void importContract(List<EmployeeContractVO> excelVOList, List<ErrorMessage> errorMessageList) {
		/// 个性化校验逻辑
		EmployeeContractVO excel;
		// 执行数据插入操作 组装
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			// 存储
			this.insertExcel(excel, errorMessageList);
		}
	}

	/**
	 * 插入excel education
	 */
	private void insertExcel(EmployeeContractVO excel, List<ErrorMessage> errorMessageList) {
		TEmployeeContractInfo insert = new TEmployeeContractInfo();
		BeanUtil.copyProperties(excel, insert);

		try {
			StringBuilder errorInfo = new StringBuilder();
			if (EmployeeConstants.OTHERS.equals(insert.getContractName()) && Common.isEmpty(insert.getContractSubName())) {
				errorInfo.append(EmployeeConstants.SUB_MUST);
			}
			if (Common.isEmpty(insert.getEmpIdcard()) || Common.isEmpty(insert.getDeptNo())) {
				errorInfo.append(EmployeeConstants.EMPID_NOT_EMPTY);
			} else {
				if (EmployeeConstants.SITUATION_SIX.equals(insert.getSituation())
						|| EmployeeConstants.SITUATION_SEVEN.equals(insert.getSituation())) {
					TEmployeeContractInfo contractInfo = this.getOne(Wrappers.<TEmployeeContractInfo>query().lambda()
							.eq(TEmployeeContractInfo::getEmpIdcard, insert.getEmpIdcard())
							.eq(TEmployeeContractInfo::getDeptNo, insert.getDeptNo())
							.eq(TEmployeeContractInfo::getDeleteFlag, CommonConstants.ZERO_INT)
							.eq(TEmployeeContractInfo::getInUse, CommonConstants.ZERO_STRING).last(CommonConstants.LAST_ONE_SQL));
					if (contractInfo == null) {
						errorInfo.append(EmployeeConstants.CONTRACT_NO_IN_USE);
					} else {
						insert.setOldContractId(contractInfo.getId());
						insert.setContractName(contractInfo.getContractName());
						insert.setContractSubName(contractInfo.getContractSubName());
						insert.setReason(contractInfo.getReason());
						insert.setSubjectUnit(contractInfo.getSubjectUnit());
						insert.setContractParty(contractInfo.getContractParty());
						insert.setContractType(contractInfo.getContractType());
						insert.setContractStart(contractInfo.getContractStart());
						insert.setContractEnd(contractInfo.getContractEnd());
					}
				} else {
					if (!EmployeeConstants.CONTRACT_TYPE_TWO.equals(insert.getContractType())
							&& Common.isEmpty(insert.getContractEnd())) {
						errorInfo.append(EmployeeConstants.CONTRACT_END_MUST);
					}
					if (Common.isEmpty(insert.getContractName())) {
						errorInfo.append(EmployeeConstants.CONTRACT_NAME_EMPTY);
					}
					if (Common.isEmpty(insert.getContractParty())) {
						errorInfo.append(EmployeeConstants.CONTRACT_PARTY_EMPTY);
					}
					if (Common.isEmpty(insert.getContractType())) {
						errorInfo.append(EmployeeConstants.CONTRACT_TYPE_EMPTY);
					}
					if (Common.isEmpty(insert.getContractStart())) {
						errorInfo.append(EmployeeConstants.CONTRACT_START_EMPTY);
					}
					if (Common.isEmpty(insert.getPost())) {
						errorInfo.append(EmployeeConstants.POST_EMPTY);
					}
					if (Common.isEmpty(insert.getWorkingHours())) {
						errorInfo.append(EmployeeConstants.WORKING_HOURS_EMPTY);
					}
				}
			}
			if (Common.isEmpty(errorInfo.toString())) {
				TEmployeeProject project = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query().lambda()
						.eq(TEmployeeProject::getEmpIdcard, insert.getEmpIdcard())
						.eq(TEmployeeProject::getDeptNo, insert.getDeptNo())
						.eq(TEmployeeProject::getDeleteFlag, CommonConstants.STATUS_NORMAL)
						.eq(TEmployeeProject::getProjectStatus, CommonConstants.ZERO_INT).last(CommonConstants.LAST_ONE_SQL));
				if (project == null) {
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), EMPINFO_IS_NOT_EXITS_BYID));
				} else {
					insert.setEmpId(project.getEmpId());
					insert.setSettleDomain(project.getDeptId());
					// 批量直接待审核
					insert.setAuditStatus(CommonConstants.ONE_INT);
					if (Common.isEmpty(insert.getContractTerm())
							&& Common.isNotNull(insert.getContractStart())
							&& Common.isNotNull(insert.getContractEnd())) {
						int monthDiff = DateUtil.getMonthDiff(insert.getContractStart(), insert.getContractEnd());
						BigDecimal b = new BigDecimal(String.valueOf(monthDiff / 12.0));
						b = b.setScale(1, BigDecimal.ROUND_HALF_UP);
						insert.setContractTerm(String.valueOf(b));
					}
					// 核心保存
					R<List<ErrorMessage>> info = this.setBaseInfo(insert, project);
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), info.getMsg()));
				}
			} else {
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), errorInfo.toString()));
			}
		} catch (Exception e) {
			log.error("员工合同保存异常：" + e.getMessage());
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_FAILED));
		}
	}

	/**
	 * 导出
	 */
	@Override
	public void exportContractInfo(TEmployeeContractInfo contractInfo, HttpServletResponse response) {
		if (contractInfo != null && contractInfo.getExportFields() != null && !contractInfo.getExportFields().isEmpty()) {
			String fileName = "员工合同批量导出" + DateUtil.getThisTime() + ".xlsx";
			//获取要导出的列表
			List<EmployeeContractExportVO> list = baseMapper.getTEmployeeContractExport(contractInfo);
			ServletOutputStream out = null;
			if (list == null || list.isEmpty()) {
				list = new ArrayList<>();
			}
			try {
				ExcelUtil<EmployeeContractExportVO> util = new ExcelUtil<>(EmployeeContractExportVO.class);
				for (EmployeeContractExportVO vo : list) {
					util.convertEntity(vo, null, null, null);
				}
				out = response.getOutputStream();
				response.setContentType("multipart/form-data");
				response.setCharacterEncoding("utf-8");
				response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, CommonConstants.UTF8));
				// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
				EasyExcel.write(out, EmployeeContractExportVO.class).includeColumnFiledNames(contractInfo.getExportFields())
						.sheet("员工合同").doWrite(list);
				out.flush();
			} catch (Exception e) {
				log.error("员工合同导出异常：", e);
			} finally {
				try {
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					log.error("员工合同导出异常：", e);
				}
			}
		}
	}

	/**
	 * 导出历史合并
	 */
	@Override
	public void exportContractInfoHistory(TEmployeeContractInfo contractInfo, HttpServletResponse response) {
		if (contractInfo != null && contractInfo.getExportFields() != null && !contractInfo.getExportFields().isEmpty()) {
			String fileName = "员工合同批量导出【合并历史】" + DateUtil.getThisTime() + ".xlsx";
			//获取要导出的列表
			List<EmployeeContractExportVO> list = baseMapper.getTEmployeeContractExportHistory(contractInfo);
			ServletOutputStream out = null;
			if (list == null || list.isEmpty()) {
				list = new ArrayList<>();
			}
			try {
				ExcelUtil<EmployeeContractExportVO> util = new ExcelUtil<>(EmployeeContractExportVO.class);
				for (EmployeeContractExportVO vo : list) {
					util.convertEntity(vo, null, null, null);
				}
				out = response.getOutputStream();
				response.setContentType("multipart/form-data");
				response.setCharacterEncoding("utf-8");
				response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, CommonConstants.UTF8));
				// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
				EasyExcel.write(out, EmployeeContractExportVO.class).includeColumnFiledNames(contractInfo.getExportFields())
						.sheet("员工合同【合并历史】").doWrite(list);
				out.flush();
			} catch (Exception e) {
				log.error(EmployeeConstants.CONCART_ALL_EXPORT_EXCEPTION, e);
			} finally {
				try {
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					log.error(EmployeeConstants.CONCART_ALL_EXPORT_EXCEPTION, e);
				}
			}

		}
	}

}
