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

import com.alibaba.excel.EasyExcel;
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.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
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.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.redis.RedisDistributedLock;
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.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SocialDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TAuditRecord;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TInsuranceUnpurchaseApply;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TInsuranceUnpurchasePerson;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAtta;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.TInsuranceUnpurchaseApplyMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.TAuditRecordService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TInsuranceUnpurchaseApplyService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TInsuranceUnpurchasePersonService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAttaService;
import com.yifu.cloud.plus.v1.yifu.salary.service.impl.process.TInsuranceUnpurchaseApplyAuditProcess;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchaseApplySearchVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchaseApplyVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonAddVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonCardVo;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
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 javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URL;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 含风险项目不购买申请表
 *
 * @author huych
 * @date 2025-01-10 11:24:38
 */
@Log4j2
@Service
public class TInsuranceUnpurchaseApplyServiceImpl extends ServiceImpl<TInsuranceUnpurchaseApplyMapper, TInsuranceUnpurchaseApply> implements TInsuranceUnpurchaseApplyService {

	@Resource
	private TInsuranceUnpurchasePersonService personService;
	@Resource
	private SocialDaprUtils socialDaprUtil;
	@Resource
	private ArchivesDaprUtil archivesDaprUtil;
	@Resource
	private TSalaryAttaService tSalaryAttaService;
	@Resource
	private UpmsDaprUtils upmsDaprUtils;
	@Resource
	@Lazy
	private TAuditRecordService auditRecordService;
	@Resource
	private OSSUtil ossUtil;
	@Resource
	@Lazy
	private TInsuranceUnpurchaseApplyAuditProcess tInsuranceUnpurchaseApplyAuditProcess;
	// 缓存信息
	@Resource
	private CacheManager cacheManager;

	/**
	 * 含风险项目不购买申请表简单分页查询
	 *
	 * @param tInsuranceUnpurchaseApply 含风险项目不购买申请表
	 * @return
	 */
	@Override
	public IPage<TInsuranceUnpurchaseApply> getTInsuranceUnpurchaseApplyPage(Page<TInsuranceUnpurchaseApply> page, TInsuranceUnpurchaseApplySearchVo tInsuranceUnpurchaseApply) {
		return baseMapper.getTInsuranceUnpurchaseApplyPage(page, tInsuranceUnpurchaseApply);
	}

	@Override
	public R deleteById(String id) {
		TInsuranceUnpurchaseApply apply = baseMapper.selectById(id);
		if (Common.isNotNull(apply)) {
			String[] allowDel = {CommonConstants.ZERO_STRING,CommonConstants.ONE_STRING, CommonConstants.FOUR_STRING};
			if(!ArrayUtils.contains(allowDel, apply.getStatus())) {
				return R.failed("数据状态发生改变，不能删除");
			}
			baseMapper.deleteById(apply);
			personService.remove(Wrappers.<TInsuranceUnpurchasePerson>query().lambda().eq(TInsuranceUnpurchasePerson::getParnetId, id));
			return R.ok();
		} else {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
	}

	/**
	 * 含风险项目不购买申请表批量导出
	 *
	 * @param searchVo 含风险项目不购买申请表
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TInsuranceUnpurchaseApplySearchVo searchVo) {
		String fileName = "含风险项目不购买申请表批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TInsuranceUnpurchaseApplyVo> list = new ArrayList<>();
		long count = baseMapper.getTInsuranceUnpurchaseApplyExportCount(searchVo);
		try(ServletOutputStream out = response.getOutputStream();) {
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, TInsuranceUnpurchaseApplyVo.class).build();
			int index = 0;

			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; i = i + CommonConstants.EXCEL_EXPORT_LIMIT_NEW) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT_NEW);
					list = baseMapper.getTInsuranceUnpurchaseApplyExportList(searchVo);
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcel.writerSheet("含风险项目不购买申请表" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcel.writerSheet("含风险项目不购买申请表" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		}
	}

	@Override
	public R addApply(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply) {
		YifuUser user = SecurityUtils.getUser();
		// 获取redis分布式事务锁
		String key = CacheConstants.UNBUY_ADD_LOCK + CommonConstants.DOWN_LINE_STRING
				+ tInsuranceUnpurchaseApply.getDeptNo() + CommonConstants.DOWN_LINE_STRING
				+ tInsuranceUnpurchaseApply.getReasonType();
		String requestId;
		try {
			requestId = RedisDistributedLock.getLock(key,"10");
		} catch (Exception e) {
			throw new RuntimeException(ResultConstants.NO_UNBUY_GETLOCK_DATA+CommonConstants.DOWN_LINE_STRING+e.getMessage());
		}
		try {
			if (Common.isNotNull(requestId)) {
				if (Common.isNotNull(tInsuranceUnpurchaseApply.getId())) {
					TInsuranceUnpurchaseApply apply = baseMapper.selectById(tInsuranceUnpurchaseApply.getId());
					if (Common.isNotNull(apply) && !CommonConstants.ZERO_STRING.equals(apply.getStatus()) &&
							!CommonConstants.ONE_STRING.equals(apply.getStatus()) && !CommonConstants.FOUR_STRING.equals(apply.getStatus())) {
						return R.failed("当前数据已被提交！");
					}
				}
				//字段长度校验
				if (Common.isNotNull(tInsuranceUnpurchaseApply.getReasonInfo()) && tInsuranceUnpurchaseApply.getReasonInfo().length() > 200) {
					return R.failed("原因说明不能超过两百个字符");
				}
				//暂存不做校验
				if (CommonConstants.ONE_STRING.equals(tInsuranceUnpurchaseApply.getSaveFlag())) {
					if (Common.isEmpty(tInsuranceUnpurchaseApply.getId())) {
//					tInsuranceUnpurchaseApply.setApplyNo(applyNo);
						tInsuranceUnpurchaseApply.setCreateBy(user.getId());
						tInsuranceUnpurchaseApply.setCreateName(user.getNickname());
						tInsuranceUnpurchaseApply.setCreateUserDeptName(user.getDeptName());
						tInsuranceUnpurchaseApply.setCreateUserDeptId(user.getDeptId().toString());
						baseMapper.insert(tInsuranceUnpurchaseApply);
					} else {
						baseMapper.updateById(tInsuranceUnpurchaseApply);
					}
					//更新附件
					updateFileId(tInsuranceUnpurchaseApply);
					//先删除明细表数据再重新生成
					if (Common.isNotNull(tInsuranceUnpurchaseApply.getId())) {
						personService.remove(Wrappers.<TInsuranceUnpurchasePerson>lambdaQuery()
								.eq(TInsuranceUnpurchasePerson::getParnetId, tInsuranceUnpurchaseApply.getId()));
					}
					List<TInsuranceUnpurchasePerson> personList = new ArrayList<>();
					if (Common.isNotNull(tInsuranceUnpurchaseApply.getPersonList()) && !tInsuranceUnpurchaseApply.getPersonList().isEmpty()) {
						for (TInsuranceUnpurchasePersonAddVo vo : tInsuranceUnpurchaseApply.getPersonList()) {
							TInsuranceUnpurchasePerson person = new TInsuranceUnpurchasePerson();
							person.setEmpIdcardNo(vo.getEmpIdcardNo());
							person.setEmpName(vo.getEmpName());
							person.setPost(vo.getPost());
							initValue(tInsuranceUnpurchaseApply, person);
							personList.add(person);
						}
						personService.saveBatch(personList);
					}
					return R.ok();
				} else if (CommonConstants.TWO_STRING.equals(tInsuranceUnpurchaseApply.getSaveFlag())) {
					TInsuranceUnpurchaseApply apply = baseMapper.selectById(tInsuranceUnpurchaseApply.getId());
					if (Common.isNotNull(apply) && (CommonConstants.TWO_STRING.equals(apply.getStatus()) ||
							CommonConstants.THREE_STRING.equals(apply.getStatus()))) {
						return R.failed("当前数据已被提交！");
					}

					//校验若该项目&该人员身份证号是否已经有过“已购买社保”的不购买商险明细，若有也会禁止重复提交！提示：姓名+身份证号、姓名+身份证号、已有申请记录，无需重复提交，可删除后再提交；
					//校验该身份证&姓名组合的数据能否找到在途或在保的社保-工伤险数据，即是否为-“工伤”险正常参保的人员，不受项目限制，若“工伤”险皆正常在保或有在途“待审核、待办理”，则可正常提交，若未正常参保或无在途的参保数据，则提示“姓名+身份证号、姓名+身份证号无正常参保或派单中的数据，禁止提交！”
					List<TInsuranceUnpurchasePersonAddVo> personList = addAndUpdCheck(tInsuranceUnpurchaseApply);
					if (Common.isNotNull(personList) && !personList.isEmpty() &&
							personList.stream().noneMatch(e -> CommonConstants.ONE_STRING.equals(e.getCode()))) {
						//申请编号
						String applyNo = getCode();
						tInsuranceUnpurchaseApply.setUnbuyNum(String.valueOf(personList.size()));
						if (Common.isNotNull(tInsuranceUnpurchaseApply.getId())) {
							if (Common.isEmpty(tInsuranceUnpurchaseApply.getApplyNo())) {
								tInsuranceUnpurchaseApply.setApplyNo(applyNo);
							}
							//申请人是否属于子分公司和该项目是否有审批通过记录赋值
							setValue(tInsuranceUnpurchaseApply, user);
							// 1.9.7 人员离职判断
							setPersonnelResignationValue(tInsuranceUnpurchaseApply, personList);

							tInsuranceUnpurchaseApply.setCreateTimeZc(LocalDateTime.now());
							baseMapper.updateById(tInsuranceUnpurchaseApply);
							// 有提交即审核通过的，记录审批日志
							// 1.9.7 增加人员离职自动审批处理
							createProcessLog(tInsuranceUnpurchaseApply, user);
							//更新附件
							updateFileId(tInsuranceUnpurchaseApply);
							//先删除明细表数据再重新生成
							personService.remove(Wrappers.<TInsuranceUnpurchasePerson>lambdaQuery()
									.eq(TInsuranceUnpurchasePerson::getParnetId, tInsuranceUnpurchaseApply.getId()));
							List<TInsuranceUnpurchasePerson> personInfoList = new ArrayList<>();
							for (TInsuranceUnpurchasePersonAddVo vo : personList) {
								TInsuranceUnpurchasePerson person = new TInsuranceUnpurchasePerson();
								person.setEmpIdcardNo(vo.getEmpIdcardNo());
								person.setEmpName(vo.getEmpName());
								person.setPost(vo.getPost());
								person.setApplyNoDetail(getCodeDetail());
								person.setCreateTime(tInsuranceUnpurchaseApply.getCreateTimeZc());
								// 1.9.7 增加: 历史申请日期(流程通过)
								person.setHistoricalApplicationDate(vo.getHistoricalApplicationDate());
								initValue(tInsuranceUnpurchaseApply, person);
								personInfoList.add(person);
							}
							personService.saveBatch(personInfoList);
						} else {
							//申请人是否属于子分公司和该项目是否有审批通过记录赋值
							setValue(tInsuranceUnpurchaseApply, user);
							// 1.9.7 人员离职判断
							setPersonnelResignationValue(tInsuranceUnpurchaseApply, personList);

							tInsuranceUnpurchaseApply.setCreateTimeZc(LocalDateTime.now());
							tInsuranceUnpurchaseApply.setCreateBy(user.getId());
							tInsuranceUnpurchaseApply.setCreateName(user.getNickname());
							tInsuranceUnpurchaseApply.setCreateUserDeptName(user.getDeptName());
							tInsuranceUnpurchaseApply.setCreateUserDeptId(user.getDeptId().toString());
							tInsuranceUnpurchaseApply.setApplyNo(applyNo);
							baseMapper.insert(tInsuranceUnpurchaseApply);
							// 有提交即审核通过的，记录审批日志
							// 1.9.7 增加人员离职自动审批处理
							createProcessLog(tInsuranceUnpurchaseApply, user);
							//更新附件
							updateFileId(tInsuranceUnpurchaseApply);
							List<TInsuranceUnpurchasePerson> personInfoList = new ArrayList<>();
							for (TInsuranceUnpurchasePersonAddVo vo : personList) {
								TInsuranceUnpurchasePerson person = new TInsuranceUnpurchasePerson();
								person.setEmpIdcardNo(vo.getEmpIdcardNo());
								person.setEmpName(vo.getEmpName());
								person.setPost(vo.getPost());
								person.setApplyNoDetail(getCodeDetail());
								person.setCreateTime(tInsuranceUnpurchaseApply.getCreateTimeZc());
								// 1.9.7 增加: 历史申请日期(流程通过)
								person.setHistoricalApplicationDate(vo.getHistoricalApplicationDate());
								initValue(tInsuranceUnpurchaseApply, person);
								personInfoList.add(person);
							}
							personService.saveBatch(personInfoList);
						}
					} else {
						return R.failed(personList);
					}
				}
				return R.ok(tInsuranceUnpurchaseApply);
			}else {
				return R.failed(ResultConstants.NO_UNBUY_GETLOCK_DATA);
			}
		} finally {
			//主动释放锁
			RedisDistributedLock.unlock(key, requestId);
		}
	}

	@Override
	public R<TInsuranceUnpurchaseApply> getDetailInfoById(String id) {
		TInsuranceUnpurchaseApply apply = baseMapper.selectById(id);
		if (Common.isEmpty(apply)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		List<TInsuranceUnpurchasePersonAddVo> personList = personService.getTInsuranceUnpurchasePersonList(id);
		apply.setPersonList(personList);
		//查询就职岗位和人数
		if (Common.isNotNull(personList) && !personList.isEmpty()) {
			Map<String, Long> map = personList.stream().collect(Collectors.groupingBy(TInsuranceUnpurchasePersonAddVo::getPost,Collectors.counting()));
			apply.setPersonMap(map);
		}
		List<TSalaryAtta> attaInfo = tSalaryAttaService.list(Wrappers.<TSalaryAtta>query().lambda().eq(TSalaryAtta::getLinkId, id));
		if (attaInfo != null && !attaInfo.isEmpty()) {
			URL url;
			for (TSalaryAtta a: attaInfo) {
				url = ossUtil.getObjectUrl(null, a.getAttaSrc());
				a.setAttaUrl(url.toString());
			}
		}
		apply.setAttaInfoList(attaInfo);
		return R.ok(apply);
	}

	public List<TInsuranceUnpurchasePersonAddVo> addAndUpdCheck(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply) {
		Map<String,String> sameCheckMap = new HashMap<>();

		List<TInsuranceUnpurchasePersonAddVo> personList = tInsuranceUnpurchaseApply.getPersonList();
		if (Common.isNotNull(personList) && !personList.isEmpty()) {
			R<Boolean> flagSocial;
			R<Boolean> flagArc;
			for (TInsuranceUnpurchasePersonAddVo vo : personList) {
				StringBuilder sameCheck = new StringBuilder();
				sameCheck.append(vo.getEmpIdcardNo());
				sameCheck.append("_");
				sameCheck.append(vo.getEmpName());
				if (null == sameCheckMap.get(sameCheck.toString())) {
					sameCheckMap.put(sameCheck.toString(), "1");
				} else {
					vo.setCode(CommonConstants.ONE_STRING);
					vo.setMessage(vo.getEmpName() + "_" + vo.getEmpIdcardNo() + ":存在重复的身份证+姓名信息，可删除后再提交");
				}
				long count = 0;
				if (CommonConstants.ONE_STRING.equals(tInsuranceUnpurchaseApply.getReasonType())) {
					count = baseMapper.selectSocialCount(tInsuranceUnpurchaseApply.getDeptNo(), vo.getEmpIdcardNo(), tInsuranceUnpurchaseApply.getId());
				} else {
					count = baseMapper.selectArchCount(tInsuranceUnpurchaseApply.getDeptNo(), vo.getEmpIdcardNo(), tInsuranceUnpurchaseApply.getId());
				}
				if (count > 0) {
					vo.setCode(CommonConstants.ONE_STRING);
					vo.setMessage(vo.getEmpName() + "_" + vo.getEmpIdcardNo() + ":已有申请记录，无需重复提交，可删除后再提交");
					continue;
				}
				//人员有项目档案且未减项拦截
				TInsuranceUnpurchasePersonCardVo cardVo = new TInsuranceUnpurchasePersonCardVo();
				cardVo.setEmpIdcardNo(vo.getEmpIdcardNo());
				cardVo.setEmpName(vo.getEmpName());
				if (CommonConstants.ONE_STRING.equals(tInsuranceUnpurchaseApply.getReasonType())) {
					flagSocial = socialDaprUtil.selectExitSocialInjury(cardVo);
					if (Common.isEmpty(flagSocial) || Boolean.FALSE.equals(flagSocial.getData())) {
						vo.setCode(CommonConstants.ONE_STRING);
						vo.setMessage(vo.getEmpName() + "_" + vo.getEmpIdcardNo() + ":无正常参保或派单中的数据，禁止提交！");
					}
				} else {
					cardVo.setDeptNo(tInsuranceUnpurchaseApply.getDeptNo());
					flagArc = archivesDaprUtil.selectExitEmpProject(cardVo);
					if (Common.isEmpty(flagArc) || Boolean.TRUE.equals(flagArc.getData())) {
						vo.setCode(CommonConstants.ONE_STRING);
						vo.setMessage(vo.getEmpName() + "_" + vo.getEmpIdcardNo() + ":人员正常在项，可项目档案减项后再次提交！");
					}
				}
			}
		}
		return personList;
	}

	// 提交自动审核通过，加审核日志
	private void createProcessLog(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply,YifuUser user){
		// 是 “已购买社保”并且 有审核通过的项目：提交即审核通过
		if (CommonConstants.ONE_STRING.equals(tInsuranceUnpurchaseApply.getReasonType())
				&& Common.isNotNull(tInsuranceUnpurchaseApply.getAuditFlag()) &&
				tInsuranceUnpurchaseApply.getAuditFlag().equals(CommonConstants.ZERO_STRING)) {
			// 记录提交审核日志
			TAuditRecord submitAuditRecord = new TAuditRecord();
			submitAuditRecord.setDomainId(tInsuranceUnpurchaseApply.getId());
			submitAuditRecord.setFlowId(CommonConstants.EMPTY_STRING);
			submitAuditRecord.setNodeId(CommonConstants.EMPTY_STRING);
			submitAuditRecord.setApprovalMan(user.getId());
			submitAuditRecord.setApprovalManName(user.getNickname());
			// 审批结果为“提交”
			submitAuditRecord.setApprovalResult(CommonConstants.dingleDigitStrArray[3]);
			submitAuditRecord.setDeleteFlag(CommonConstants.NOT_DELETE_FLAG);
			submitAuditRecord.setApprovalTime(LocalDateTime.now());
			// 审核记录标识 1当前审核记录
			submitAuditRecord.setPreFlag(CommonConstants.ONE_STRING);
			submitAuditRecord.setSubmitMan(user.getId());
			submitAuditRecord.setSubmitManName(user.getNickname());
			// 申请原因
//				submitAuditRecord.setReason(reason);
			// 审核类型
			submitAuditRecord.setAuditType(CommonConstants.ZERO_STRING);
			submitAuditRecord.setCreateTime(LocalDateTime.now());
			// 提交节点名称
			submitAuditRecord.setNodeName("提交即审核通过");
			submitAuditRecord.setSubmitCreateTime(LocalDateTime.now());
			submitAuditRecord.setEntityName(tInsuranceUnpurchaseApply.getApplyNo());
			auditRecordService.save(submitAuditRecord);
		}
		if(CommonConstants.TWO_STRING.equals(tInsuranceUnpurchaseApply.getReasonType()) && CommonConstants.THREE_STRING.equals(tInsuranceUnpurchaseApply.getStatus())){
			// 是“人员已离职”并且 申请已审核通过
			// 记录提交审核日志
			TAuditRecord submitAuditRecord = new TAuditRecord();
			submitAuditRecord.setDomainId(tInsuranceUnpurchaseApply.getId());
			submitAuditRecord.setFlowId(CommonConstants.EMPTY_STRING);
			submitAuditRecord.setNodeId(CommonConstants.EMPTY_STRING);
			submitAuditRecord.setApprovalMan(user.getId());
			submitAuditRecord.setApprovalManName(user.getNickname());
			submitAuditRecord.setApprovalResult(CommonConstants.dingleDigitStrArray[3]);
			submitAuditRecord.setDeleteFlag(CommonConstants.NOT_DELETE_FLAG);
			submitAuditRecord.setApprovalTime(LocalDateTime.now());
			submitAuditRecord.setPreFlag(CommonConstants.ONE_STRING);
			submitAuditRecord.setSubmitMan(user.getId());
			submitAuditRecord.setSubmitManName(user.getNickname());
			submitAuditRecord.setAuditType(CommonConstants.ZERO_STRING);
			submitAuditRecord.setCreateTime(LocalDateTime.now());
			submitAuditRecord.setNodeName("提交");
			submitAuditRecord.setSubmitCreateTime(LocalDateTime.now());
			submitAuditRecord.setEntityName(tInsuranceUnpurchaseApply.getApplyNo());
			auditRecordService.save(submitAuditRecord);
			// 记录系统自动审核通过日志
			TAuditRecord autoAuditRecord = new TAuditRecord();
			autoAuditRecord.setDomainId(tInsuranceUnpurchaseApply.getId());
			autoAuditRecord.setFlowId(CommonConstants.EMPTY_STRING);
			autoAuditRecord.setNodeId(CommonConstants.EMPTY_STRING);
			autoAuditRecord.setNodeName("SSC审核");
			autoAuditRecord.setApprovalMan(CommonConstants.ONE_STRING);
			autoAuditRecord.setApprovalManName("首次申请，系统默认审核通过");
			autoAuditRecord.setApprovalOpinion("默认审核通过");
			autoAuditRecord.setApprovalTime(LocalDateTime.now());
			autoAuditRecord.setDeleteFlag(CommonConstants.NOT_DELETE_FLAG);
			autoAuditRecord.setPreFlag(CommonConstants.ONE_STRING);
			autoAuditRecord.setApprovalResult(CommonConstants.ZERO_STRING);
			autoAuditRecord.setSubmitMan(user.getId());
			autoAuditRecord.setSubmitManName(user.getNickname());
			autoAuditRecord.setSubmitCreateTime(submitAuditRecord.getSubmitCreateTime());
			autoAuditRecord.setAuditType(CommonConstants.ZERO_STRING);
			autoAuditRecord.setCreateTime(LocalDateTime.now());
			autoAuditRecord.setEntityName(tInsuranceUnpurchaseApply.getApplyNo());
			auditRecordService.save(autoAuditRecord);
		}
	}

	//申请人是否属于子分公司和该项目是否有审批通过记录赋值
	private void setValue(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply,YifuUser user) {
		if (Common.isNotNull(tInsuranceUnpurchaseApply.getDeptNo())) {
			String deptId = user.getDeptId().toString();

			R<Boolean> booleanR = upmsDaprUtils.selectExitDeptCompany(deptId);
			if (Common.isEmpty(booleanR) || Boolean.FALSE.equals(booleanR.getData())) {
				tInsuranceUnpurchaseApply.setCompanyFlag(CommonConstants.ONE_STRING);
			} else {
				tInsuranceUnpurchaseApply.setCompanyFlag(CommonConstants.ZERO_STRING);
			}
			if (CommonConstants.ONE_STRING.equals(tInsuranceUnpurchaseApply.getReasonType())) {
				long count = baseMapper.selectCount(Wrappers.<TInsuranceUnpurchaseApply>query().lambda()
						.eq(TInsuranceUnpurchaseApply::getDeptNo, tInsuranceUnpurchaseApply.getDeptNo())
						.eq(TInsuranceUnpurchaseApply::getReasonType, tInsuranceUnpurchaseApply.getReasonType())
						.eq(TInsuranceUnpurchaseApply::getStatus, CommonConstants.THREE_STRING)
						.eq(TInsuranceUnpurchaseApply::getDeleteFlag, CommonConstants.ZERO_STRING)
						.last(CommonConstants.LAST_ONE_SQL));
				tInsuranceUnpurchaseApply.setAuditFlag(count > 0 ? CommonConstants.ZERO_STRING : CommonConstants.ONE_STRING);
				tInsuranceUnpurchaseApply.setStatus(count > 0 ? CommonConstants.THREE_STRING : tInsuranceUnpurchaseApply.getStatus());
			}
		}
	}

	// 1.9.7：人员离职 判断本批人员是否之前有审核通过的记录
	private void setPersonnelResignationValue(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply, List<TInsuranceUnpurchasePersonAddVo> personList) {
		if (CommonConstants.TWO_STRING.equals(tInsuranceUnpurchaseApply.getReasonType()) && Common.isNotNull(personList)) {
			// 判断本批人员是否之前在同一个项目下有审核通过的明细记录, 都没审核过，可以变为自动审核通过
			Set<String> idcardSet = personList.stream().map(TInsuranceUnpurchasePersonAddVo::getEmpIdcardNo).collect(Collectors.toSet());

			LambdaQueryWrapper<TInsuranceUnpurchasePerson> personQuery = Wrappers.<TInsuranceUnpurchasePerson>query().lambda()
					.eq(TInsuranceUnpurchasePerson::getDeptNo, tInsuranceUnpurchaseApply.getDeptNo())
					.eq(TInsuranceUnpurchasePerson::getReasonType, CommonConstants.TWO_STRING)
					.eq(TInsuranceUnpurchasePerson::getStatus, CommonConstants.THREE_STRING)
					.in(TInsuranceUnpurchasePerson::getEmpIdcardNo, idcardSet).orderByAsc(TInsuranceUnpurchasePerson::getCreateTime);
			List<TInsuranceUnpurchasePerson> findList = personService.list(personQuery);
			// 存有记录的 历史申请日期
			if (Common.isNotNull(findList)) {
				Map<String,String> dateMap = new HashMap<>();
				for (TInsuranceUnpurchasePerson personInfo : findList) {
					// 组装【历史申请日期】
					String dateStr = dateMap.get(personInfo.getEmpIdcardNo());
					if(Common.isEmpty(dateStr)){
						dateStr = LocalDateTimeUtils.formatTime(personInfo.getCreateTime(),LocalDateTimeUtils.DATE_SHORT_PATTERN);
					} else {
						dateStr = dateStr+"、"+LocalDateTimeUtils.formatTime(personInfo.getCreateTime(),LocalDateTimeUtils.DATE_SHORT_PATTERN);
					}
					dateMap.put(personInfo.getEmpIdcardNo(), dateStr);
				}
				for(TInsuranceUnpurchasePersonAddVo person : personList){
					String dateStr = dateMap.get(person.getEmpIdcardNo());
					if(Common.isNotNull(dateStr)){
						person.setHistoricalApplicationDate(dateStr);
					} else {
						person.setHistoricalApplicationDate("");
					}
				}
			} else {
				tInsuranceUnpurchaseApply.setStatus(CommonConstants.THREE_STRING);
			}
		}
	}

	private void initValue(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply,TInsuranceUnpurchasePerson person) {
		person.setParnetId(tInsuranceUnpurchaseApply.getId());
		person.setApplyNo(tInsuranceUnpurchaseApply.getApplyNo());
		person.setDeptId(tInsuranceUnpurchaseApply.getDeptId());
		person.setDeptNo(tInsuranceUnpurchaseApply.getDeptNo());
		person.setDeptName(tInsuranceUnpurchaseApply.getDeptName());
		person.setDivision(tInsuranceUnpurchaseApply.getDivision());
		person.setNewLine(tInsuranceUnpurchaseApply.getNewLine());
		person.setReasonType(tInsuranceUnpurchaseApply.getReasonType());
		person.setHasContainRisks(tInsuranceUnpurchaseApply.getHasContainRisks());
		person.setInsuranceFlag(tInsuranceUnpurchaseApply.getInsuranceFlag());
		person.setReasonInfo(tInsuranceUnpurchaseApply.getReasonInfo());
		person.setCreateBy(tInsuranceUnpurchaseApply.getCreateBy());
		person.setCreateName(tInsuranceUnpurchaseApply.getCreateName());
		person.setCreateUserDeptName(tInsuranceUnpurchaseApply.getCreateUserDeptName());
		person.setStatus(tInsuranceUnpurchaseApply.getStatus());
		person.setCreateUserDeptId(tInsuranceUnpurchaseApply.getCreateUserDeptId());
	}

	private void updateFileId(TInsuranceUnpurchaseApply tInsuranceUnpurchaseApply) {
		if (Common.isNotNull(tInsuranceUnpurchaseApply.getAttaIdList())) {
			LambdaUpdateWrapper<TSalaryAtta> updateWrapper = new LambdaUpdateWrapper<>();
			updateWrapper.eq(TSalaryAtta::getLinkId,tInsuranceUnpurchaseApply.getId())
					.set(TSalaryAtta::getLinkId, CommonConstants.EMPTY_STRING);
			tSalaryAttaService.update(updateWrapper);
			TSalaryAtta atta;
			for (String id : tInsuranceUnpurchaseApply.getAttaIdList())  {
				atta = tSalaryAttaService.getById(id);
				atta.setLinkId(tInsuranceUnpurchaseApply.getId());
				tSalaryAttaService.updateById(atta);
			}
		}
	}

	//获取申请编码
	public synchronized String getCode() {
		String nowDay = DateUtil.getThisDay();
		int nowNums;
		String empCode = null;
		Cache cache = cacheManager.getCache(CacheConstants.EVERYDAY_UNBUY_FORM_CODE);
		if (cache != null) {
			try {
				Object nowNumObj = cache.get(nowDay);
				if (Common.isNotNull(nowNumObj)) {
					SimpleValueWrapper value = (SimpleValueWrapper) nowNumObj;
					nowNums = (Integer) value.get() + 1;
				} else {
					empCode = baseMapper.getMaxInusuranceCode();
					nowNums = Integer.parseInt(empCode) + 1;
				}
			} catch (NumberFormatException e) {
				log.error("获取含风险项目不购买商险申请时出错：" + empCode);
				nowNums = 1;
			}
			cache.put(nowDay, nowNums);
		} else {
			empCode = baseMapper.getMaxInusuranceCode();
			nowNums = Integer.parseInt(empCode) + 1;
		}
		return "SXBGM" + nowDay + this.getThreeNum(String.valueOf(nowNums));
	}

	public synchronized String getCodeDetail() {
		String nowDay = DateUtil.getThisDay();
		int nowNums;
		String empCode = null;
		Cache cache = cacheManager.getCache(CacheConstants.EVERYDAY_UNBUYINFO_FORM_CODE);
		if (cache != null) {
			try {
				Object nowNumObj = cache.get(nowDay);
				if (Common.isNotNull(nowNumObj)) {
					SimpleValueWrapper value = (SimpleValueWrapper) nowNumObj;
					nowNums = (Integer) value.get() + 1;
				} else {
					empCode = baseMapper.getMaxInusuranceDetailCode();
					nowNums = Integer.parseInt(empCode) + 1;
				}
			} catch (NumberFormatException e) {
				log.error("获取含风险项目不购买商险申请明细时出错：" + empCode);
				nowNums = 1;
			}
			cache.put(nowDay, nowNums);
		} else {
			empCode = baseMapper.getMaxInusuranceDetailCode();
			nowNums = Integer.parseInt(empCode) + 1;
		}
		return "SXBGMMX" + nowDay + this.getFiveNum(String.valueOf(nowNums));
	}

	/**
	 * @param nowNums 数字
	 * @Description: 获取三位字符型数字
	 * @Author: huych
	 * @Date: 2025/1/14 17:35
	 * @return: 三位字符型数字
	 **/
	private String getThreeNum(String nowNums) {
		if (nowNums.length() >= 3) {
			return nowNums.substring(0, 3);
		}
		String[] zeroArr = {"0", "00", "000", "0000"};
		int num = 2 - nowNums.length();
		return zeroArr[num] + nowNums;
	}

	/**
	 * @param nowNums 数字
	 * @Description: 获取五位字符型数字
	 * @Author: huych
	 * @Date: 2025/1/14 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 page                    分页信息
	 * @param unpurchaseApplySearchVo 不购买申请查询信息
	 * @param userId                  登录用户id
	 * @param type                    0待审核、1已处理、2抄送我
	 * @return IPage
	 */
	@Override
	public IPage<TInsuranceUnpurchaseApply> getAuditPage(Page<TInsuranceUnpurchaseApply> page, TInsuranceUnpurchaseApplySearchVo unpurchaseApplySearchVo, String userId, String type) {
		IPage<TInsuranceUnpurchaseApply> auditUnpurchaseIPage;
		if (StringUtils.equals(CommonConstants.ZERO_STRING, type)) {
			auditUnpurchaseIPage = baseMapper.getAuditPage(page, unpurchaseApplySearchVo, userId);
		} else if (StringUtils.equals(CommonConstants.ONE_STRING, type)) {
			auditUnpurchaseIPage = baseMapper.getHistoryHandlePage(page, unpurchaseApplySearchVo, userId);
		} else if (StringUtils.equals(CommonConstants.TWO_STRING, type)) {
			auditUnpurchaseIPage = baseMapper.getCopyPage(page, unpurchaseApplySearchVo, userId);
		}else {
			return null;
		}

		return auditUnpurchaseIPage;
	}

	/**
	 * 审核数量
	 *
	 * @param userId  登录用户id
	 * @return Map<String, Integer>
	 */
	@Override
	public Map<String, Integer> getAuditCount(String userId) {
		Map<String, Integer> auditCountMap = new HashMap<>();
		Integer pendingCount = baseMapper.getAuditCount(userId);
		Integer processedCount = baseMapper.getHistoryHandleCount(userId);
		auditCountMap.put("pending", pendingCount);
		auditCountMap.put("processed", processedCount);
		auditCountMap.put("copy",0);

		return auditCountMap;
	}

	/**
	 * 提交审核
	 * @param id  实体id
	 * @return R<String>
	 **/
	@Transactional
	@Override
	public R<String> commitOne(String id,YifuUser user) {
		TInsuranceUnpurchaseApply entity = this.getById(id);
		if(entity==null){
			return R.failed(ResultConstants.FAIL_INFO_NO_MODEL);
		}
		if(!CommonConstants.ONE_STRING.equals(entity.getStatus())){
			return R.failed("当前记录不为待提交状态");
		}
		String[] reasonType = {"1", "2"};
		if(!ArrayUtils.contains(reasonType, entity.getReasonType())) {
			return R.failed("未维护【不购买原因】选项，请联系管理员");
		}
		// “已购买社保" 并且“项目有审批通过记录”，无需发起审核流程
		if(CommonConstants.ONE_STRING.equals(entity.getReasonType()) && CommonConstants.ZERO_STRING.equals(entity.getAuditFlag())){
			return R.failed("【已购买社保】并且【项目有审批通过记录】，无需发起审核流程");
		}
		String[] companyFlag = {"0", "1"};
		if(!ArrayUtils.contains(companyFlag, entity.getCompanyFlag())) {
			return R.failed("未维护【申请人是否属于子分公司】，请联系管理员");
		}
		if(Common.isEmpty(entity.getCreateUserDeptId())){
			return R.failed("申请人所属部门id不能为空");
		}
	    // 传：流程类型 1不购买商险申请；审核类型 0不购买商险审核
		R<List<SysUser>> auditUserListR = tInsuranceUnpurchaseApplyAuditProcess.getAuditUserList(id, user, entity.getCreateUserDeptId(),
				CommonConstants.ONE_STRING, CommonConstants.ZERO_STRING,
				"", entity.getApplyNo(), entity);
		if (auditUserListR == null || auditUserListR.getCode() != CommonConstants.SUCCESS || auditUserListR.getData() == null) {
			throw new CheckedException("获取审批人失败,请联系管理员");
		}
		// 存即将审批人的信息
		String auditUserNameStrs = "";
		String auditUserIdStrs = "";
		for(SysUser userInfo : auditUserListR.getData()){
			auditUserIdStrs = auditUserIdStrs.concat(";").concat(userInfo.getUserId());
			auditUserNameStrs = auditUserNameStrs.concat(";").concat(userInfo.getNickname());

		}
		if(Common.isNotNull(auditUserNameStrs)){
			auditUserNameStrs = auditUserNameStrs.substring(1);
		}
		if(Common.isNotNull(auditUserIdStrs)){
			auditUserIdStrs = auditUserIdStrs.substring(1);
		}
		entity.setAuditUser(auditUserNameStrs);
		entity.setAuditUserId(auditUserIdStrs);
		entity.setStatus(CommonConstants.TWO_STRING);
		this.updateById(entity);
		return R.ok(null,"提交成功");
	}

	@Override
	@Transactional
	public R<String> auditAndCommit(TInsuranceUnpurchaseApply insuranceUnpurchaseApply, String approvalResult, String approvalOpinion, YifuUser user) {
		return tInsuranceUnpurchaseApplyAuditProcess.auditUserList(insuranceUnpurchaseApply.getId(), approvalResult, approvalOpinion, user, CommonConstants.ZERO_STRING,
				insuranceUnpurchaseApply, insuranceUnpurchaseApply.getCreateUserDeptId());
	}
}
