/*
 *    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.salary.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
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.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.check.entity.TCheckIdCard;
import com.yifu.cloud.plus.v1.yifu.archives.vo.ProjectSetInfoVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.SetInfoVo;
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.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.CheckDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.util.ValidityUtil;
import com.yifu.cloud.plus.v1.yifu.salary.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryZero;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.TSalaryZeroMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAccountService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryZeroService;
import com.yifu.cloud.plus.v1.yifu.salary.util.SalaryConstants;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryZeroExportVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryZeroSearchVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryZeroVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
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.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 0申报
 *
 * @author hgw
 * @date 2026-03-18 14:47:00
 */
@Log4j2
@Service
public class TSalaryZeroServiceImpl extends ServiceImpl<TSalaryZeroMapper, TSalaryZero> implements TSalaryZeroService {

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private WxConfig wxConfig;

	@Autowired
	private TSalaryAccountService salaryAccountService;

	@Resource
	private CheckDaprUtil checkDaprUtil;

	private static final Random RANDOM = new Random();

	// 批量更新状态(deleteFlag0,1,2：0：正常；1：已删除；2存在报账假删除)
	@Override
	public synchronized int updateDeleteFlagByIdList(String invoiceTitle, String settleMonth, String year, Integer deleteFlag, Integer oldDeleteFlag, String salaryId) {
		List<String> cardList;
		if (deleteFlag == CommonConstants.ZERO_INT) {
			cardList = salaryAccountService.getCardListBySalaryIdAndNotExists(salaryId, invoiceTitle, settleMonth);
		} else {
			cardList = salaryAccountService.getCardListBySalaryId(salaryId);
		}
		if (cardList == null || cardList.isEmpty()) {
			return CommonConstants.ZERO_INT;
		}
		String tableName = getSalaryTableName(year);
		if (Common.isEmpty(tableName)) {
			return CommonConstants.ZERO_INT;
		}
		// 1. 排序
		Collections.sort(cardList);
		// 2. 分批（每批50条）
		int batchSize = 50;
		int endIndex;
		List<String> batchCards;
		for (int i = 0; i < cardList.size(); i += batchSize) {
			endIndex = Math.min(i + batchSize, cardList.size());
			batchCards = cardList.subList(i, endIndex);
			// 每批执行一次批量更新
			try {
				baseMapper.updateDeleteFlagByIdList(
						tableName, deleteFlag, oldDeleteFlag,
						batchCards, invoiceTitle, settleMonth);
			} catch (Exception e) {
				// 3. 带重试机制
				// 随机退避，避免多个事务同时重试再次冲突
				try {
					Thread.sleep(RANDOM.nextInt(100) + 50);
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
				baseMapper.updateDeleteFlagByIdList(
						tableName, deleteFlag, oldDeleteFlag,
						batchCards, invoiceTitle, settleMonth);
			}
		}
		return CommonConstants.ONE_INT;
		//return baseMapper.updateDeleteFlagByIdList(tableName, deleteFlag, oldDeleteFlag, cardList, invoiceTitle, settleMonth)
	}

	/**
	 * 检查表是否存在并缓存结果
	 */
	public String getSalaryTableName(String year) {
		if (Common.isEmpty(year) || year.length() != CommonConstants.FOUR_INT) {
			return null;
		}
		String tableNameOld = SalaryConstants.TABLE_NAME_PRE + year;
		String tableName = wxConfig.getSalaryZeroTableName(tableNameOld);
		if (Common.isNotNull(tableName)) {
			return tableName;
		} else {
			int num = baseMapper.getTableExists(tableNameOld);
			if (num > CommonConstants.ZERO_INT) {
				wxConfig.setSalaryZeroTableName(tableNameOld);
				return tableNameOld;
			}
		}
		return null;
	}

	/**
	 * @param id id含有_year
	 * @return
	 */
	@Override
	public TSalaryZero getTSalaryZeroById(String id) {
		if (Common.isNotNull(id) && id.contains(CommonConstants.DOWN_LINE_STRING)) {
			String[] idArr = id.split(CommonConstants.DOWN_LINE_STRING);
			if (idArr.length == CommonConstants.TWO_INT) {
				String tableName = getSalaryTableName(idArr[1]);
				if (Common.isEmpty(tableName)) {
					return null;
				}
				return baseMapper.getTSalaryZeroById(tableName, idArr[0]);
			}
		}
		return null;
	}

	@Override
	public boolean deleteTSalaryZeroById(String id) {
		if (Common.isNotNull(id) && id.contains(CommonConstants.DOWN_LINE_STRING)) {
			String[] idArr = id.split(CommonConstants.DOWN_LINE_STRING);
			if (idArr.length == CommonConstants.TWO_INT) {
				String tableName = getSalaryTableName(idArr[1]);
				if (Common.isEmpty(tableName)) {
					return false;
				}
				baseMapper.deleteTSalaryZeroById(tableName, idArr[0]);
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean deleteTSalaryZeroByIdList(List<String> idList) {
		if (idList != null && !idList.isEmpty()) {
			for (String id : idList) {
				deleteTSalaryZeroById(id);
			}
		}
		return true;
	}

	/**
	 * 0申报简单分页查询
	 *
	 * @param searchVo 0申报
	 * @return
	 */
	@Override
	public IPage<TSalaryZero> getTSalaryZeroPage(Page<TSalaryZero> page, TSalaryZeroSearchVo searchVo) {
		if (Common.isNotNull(searchVo.getYear())) {
			String tableName = getSalaryTableName(searchVo.getYear());
			if (Common.isEmpty(tableName)) {
				return null;
			} else {
				return baseMapper.getTSalaryZeroPage(page, tableName, searchVo);
			}
		} else {
			return null;
		}

	}

	/**
	 * 0申报批量导出
	 *
	 * @param searchVo 0申报
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TSalaryZeroSearchVo searchVo) {
		String fileName = "0申报批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TSalaryZeroExportVo> list = new ArrayList<>();
		String tableName = getSalaryTableName(searchVo.getYear());
		if (Common.isEmpty(tableName)) {
			return;
		}
		long count = baseMapper.getTSalaryZeroCount(tableName, searchVo);
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, CommonConstants.UTF8));
			ExcelWriter excelWriter = EasyExcelFactory.write(out, TSalaryZeroExportVo.class).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				WriteSheet writeSheet;
				for (int i = 0; i <= count; i = i + CommonConstants.EXCEL_EXPORT_LIMIT) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = baseMapper.getTSalaryZeroExport(tableName, searchVo);
					if (Common.isNotNull(list)) {
						writeSheet = EasyExcelFactory.writerSheet("0申报" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
				}
				if (Common.isNotNull(list)) {
					list.clear();
				}
			} else {
				WriteSheet writeSheet = EasyExcelFactory.writerSheet("0申报" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public R<List<ErrorMessage>> importSalaryZero(InputStream inputStream, String settleMonth, String invoiceTitle) {
		YifuUser user = SecurityUtils.getUser();
		if (user == null || Common.isEmpty(user.getUsername())) {
			return R.failed("请登录！");
		}
		String userId = user.getId();
		String nickName = user.getNickname();
		if (Common.isEmpty(settleMonth) || settleMonth.length() != 6 || Common.isEmpty(invoiceTitle)) {
			return R.failed("请检查传参结算月与封面抬头！");
		}
		String year = settleMonth.substring(0, 4);
		String tableName = getSalaryTableName(year);
		if (Common.isEmpty(tableName)) {
			return R.failed("请检查结算月，若无问题，请联系管理员新建工资的0申报表：" + SalaryConstants.TABLE_NAME_PRE + year);
		}
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TSalaryZeroVo> util1 = new ExcelUtil<>(TSalaryZeroVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcelFactory.read(inputStream, TSalaryZeroVo.class, new ReadListener<TSalaryZeroVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int MAX_ROWS = 500;
				private int rowCount = CommonConstants.ZERO_INT;
				/**
				 *临时存储
				 */
				private List<TSalaryZeroVo> cachedDataList = new ArrayList<>();
				// 项目编码
				private List<String> codeList = new ArrayList<>();
				// 手机号码
				private List<String> phoneList = new ArrayList<>();
				// 查询条件（抬头、身份证、结算月）
				private List<String> cardList = new ArrayList<>();
				// 身份证重复
				Map<String, Integer> cardRepeatMap = new HashMap<>();
				// 实名校验
				List<TCheckIdCard> checkList = new ArrayList<>();

				TCheckIdCard idCardCheck;

				@Override
				public void invoke(TSalaryZeroVo data, AnalysisContext context) {
					rowCount++;
					// 超过500行时停止读取
					if (rowCount > MAX_ROWS) {
						errorMessageList.add(new ErrorMessage(-1, "超过500条，不存储数据，请处理导入表格"));
						cachedDataList.clear();
						// 中断读取
						throw new RuntimeException("超过500条，请减少数据条数！");
					}
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessage.setData(data);
						errorMessageList.add(errorMessage);
					} else {
						if (Common.isNotNull(data.getDeptNo())) {
							codeList.add(data.getDeptNo());
						}
						if (Common.isNotNull(data.getEmpPhone())) {
							if (!ValidityUtil.validateEmpPhone(data.getEmpPhone())) {
								errorMessageList.add(new ErrorMessage(data.getRowIndex(), "手机号码格式错误，请检查并修改后重新导入", data));
							} else {
								phoneList.add(data.getEmpPhone());
								if (Common.isNotNull(data.getEmpIdcard())) {
									if (regIdCard(data.getEmpIdcard())) {
										cardList.add(data.getEmpIdcard());
										if (cardRepeatMap.get(data.getEmpIdcard()) != null) {
											errorMessageList.add(new ErrorMessage(data.getRowIndex(), "该身份证在本次导入表中有重复，请检查并修改后重新导入", data));
										} else {
											cardRepeatMap.put(data.getEmpIdcard(), CommonConstants.ONE_INT);
											idCardCheck = new TCheckIdCard();
											idCardCheck.setIdCard(data.getEmpIdcard());
											idCardCheck.setName(data.getEmpName());
											idCardCheck.setCreateUser(userId);
											idCardCheck.setReason(nickName);
											checkList.add(idCardCheck);
											cachedDataList.add(data);
										}
									} else {
										errorMessageList.add(new ErrorMessage(data.getRowIndex(), "该身份证号基本格式不正确，请检查并修改后重新导入", data));
									}
								}
							}
						}
					}
				}

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

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					if (rowCount <= MAX_ROWS && cachedDataList != null && !cachedDataList.isEmpty()) {
						// 获取项目编码数据 以供校验
						Map<String, ProjectSetInfoVo> projectVoMap = getProjectVoMap(codeList);
						Map<String, Integer> accountMap = getAccountMap(cardList);
						Map<String, Boolean> idCardMap = getCardMap(checkList);
						Map<String, Boolean> phoneMap = getPhoneMap(phoneList);
						Map<String, Integer> zeroMap = getZeroMap(cardList);
						importTSalaryZero(cachedDataList, errorMessageList, settleMonth, invoiceTitle, nickName, projectVoMap
								, accountMap, idCardMap, phoneMap, zeroMap);
					}
				}

				// 获取项目id等信息
				private Map<String, ProjectSetInfoVo> getProjectVoMap(List<String> codes) {
					R<SetInfoVo> res = archivesDaprUtil.getSetInfoByCodes(codes);
					if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
						return res.getData().getProjectSetInfoVoMap();
					}
					return new HashMap<>();
				}

				// 获取报账信息等
				private Map<String, Integer> getAccountMap(List<String> cardList) {
					return salaryAccountService.getAccountMapByKey(invoiceTitle, settleMonth, cardList);
				}

				// 获取0申报表在用的信息等
				private Map<String, Integer> getZeroMap(List<String> cardList) {
					Map<String, Integer> zeroMap = new HashMap<>();
					List<String> list = baseMapper.getIdListByCardAndTitleAndMonth(tableName, invoiceTitle, settleMonth, cardList);
					if (list != null && !list.isEmpty()) {
						for (String id : list) {
							zeroMap.put(id, CommonConstants.ONE_INT);
						}
					}
					return zeroMap;
				}

				// 获取身份证实名信息等
				private Map<String, Boolean> getCardMap(List<TCheckIdCard> checkList) {
					return checkDaprUtil.checkIdCardBatch(checkList);
				}

				// 获取手机号校验信息等
				private Map<String, Boolean> getPhoneMap(List<String> phoneList) {
					return checkDaprUtil.checkPhoneBatch(phoneList);
				}

			}).sheet().doRead();
		} catch (Exception e) {
			// 判断 为RuntimeException
			if (e instanceof RuntimeException) {
				return R.failed(e.getMessage());
			}
			String errorInfo = "数据导入解析失败，请将单元格设为文本！" + e.getMessage();
			log.error(errorInfo, e);
			return R.failed(errorInfo);
		}
		boolean isTrue = true;
		for (ErrorMessage message : errorMessageList) {
			if (!CommonConstants.SAVE_SUCCESS.equals(message.getMessage())) {
				isTrue = false;
				break;
			}
		}
		if (isTrue) {
			return R.ok();
		} else {
			return R.ok(errorMessageList);
		}
	}

	private static boolean regIdCard(String content) {
		boolean flag = false;
		Pattern p = Pattern.compile("\\d{18}|\\d{17}X|\\d{15}|\\d{14}X");
		Matcher m = p.matcher(content);
		if (m.matches()) {
			flag = true;
		}
		return flag;
	}

	private void importTSalaryZero(List<TSalaryZeroVo> excelVOList, List<ErrorMessage> errorMessageList
			, String settleMonth, String invoiceTitle, String userName, Map<String, ProjectSetInfoVo> projectVoMap
			, Map<String, Integer> accountMap, Map<String, Boolean> idCardMap, Map<String, Boolean> phoneMap
			, Map<String, Integer> zeroMap) {

		String tableName = getSalaryTableName(settleMonth.substring(0, 4));
		if (Common.isEmpty(tableName)) {
			return;
		}
		// 执行数据插入操作 组装
		TSalaryZeroVo excel;
		List<TSalaryZero> insertList = new ArrayList<>();
		TSalaryZero insert;
		LocalDateTime now = LocalDateTime.now();

		ProjectSetInfoVo dept;

		int idCardFlag = 0;
		if (idCardMap != null && !idCardMap.isEmpty()) {
			if (idCardMap.get("全部正确") != null) {
				idCardFlag = 1;
			}
			if (idCardMap.get("全部错误") != null) {
				idCardFlag = 2;
			}
		}
		String idCard;
		Boolean resultB;
		BigDecimal costReduction;
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			if (Common.isNotNull(excel.getCostReduction())) {
				try {
					costReduction = new BigDecimal(excel.getCostReduction());
				} catch (Exception e) {
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.MONEY_NUM_ERROR, excel));
					continue;
				}
				if (costReduction.compareTo(SalaryConstants.COST_MONEY) < CommonConstants.ZERO_INT
						|| costReduction.compareTo(SalaryConstants.MAX_COST_MONEY) > CommonConstants.ZERO_INT
						|| costReduction.remainder(SalaryConstants.COST_MONEY).compareTo(BigDecimal.ZERO) != 0) {
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.MONEY_ERROR, excel));
				} else {
					if (Common.isNotNull(excel.getDeptNo()) && projectVoMap.get(excel.getDeptNo()) != null) {
						if (accountMap.get(excel.getEmpIdcard()) != null) {
							errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.HAVE_ACCOUNT, excel));
						} else {
							if (zeroMap.get(excel.getEmpIdcard()) != null) {
								errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.HAVE_ZERO, excel));
							} else {
								idCard = excel.getEmpIdcard();
								if (idCardFlag == 0) {
									if (Common.isNotNull(idCard)) {
										resultB = idCardMap.get(idCard + CommonConstants.DOWN_LINE_STRING + excel.getEmpName());
										if (resultB != null) {
											if (Boolean.FALSE.equals(resultB)) {
												errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "姓名&身份证号不一致，请检查并修改后重新导入", excel));
												continue;
											}
										} else {
											errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "姓名&身份证号不一致，请检查并修改后重新导入！", excel));
											continue;
										}
									}
								} else if (idCardFlag == 2) {
									errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "姓名&身份证号不一致，请检查并修改后重新导入！！", excel));
									continue;
								}
								resultB = phoneMap.get(excel.getEmpPhone());
								if (resultB != null) {
									if (Boolean.FALSE.equals(resultB)) {
										errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "手机号校验不通过，请更改手机号后重试", excel));
										continue;
									}
								} else {
									errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "手机号校验不通过，请更改手机号后重试！", excel));
									continue;
								}

								if (judgeTaxMonth(excel.getTaxMonth())) {
									errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "计税月份格式不正确！", excel));
									continue;
								}
								insert = new TSalaryZero();
								BeanUtil.copyProperties(excel, insert);
								insert.setSettleMonth(settleMonth);
								insert.setInvoiceTitle(invoiceTitle);
								insert.setDataSource(CommonConstants.THREE_STRING);
								insert.setImporterName(userName);
								insert.setCreateTime(now);
								dept = projectVoMap.get(excel.getDeptNo());
								if (dept != null) {
									insert.setDeptId(dept.getId());
									insert.setDeptName(dept.getDepartName());
									insert.setDeleteFlag(CommonConstants.ZERO_INT);
									insertList.add(insert);
									errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_SUCCESS, excel));
								} else {
									errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.DEPT_ERROR, excel));
								}

							}
						}
					} else {
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), SalaryConstants.DEPT_ERROR, excel));
					}
				}
			}
		}
		if (!insertList.isEmpty()) {
			this.saveBatchWithTableName(insertList, tableName);
		}
	}

	// 返回false则对
	private boolean judgeTaxMonth(String taxMonth) {
		if (Common.isEmpty(taxMonth)) {
			return true;
		}
		if (taxMonth.length() > CommonConstants.dingleDigitIntArray[6]) {
			taxMonth = taxMonth.substring(0, 6);
		} else if (taxMonth.length() < CommonConstants.dingleDigitIntArray[6]) {
			return true;
		}
		if (DateUtil.compareYearMonth(taxMonth, DateUtil.addMonth(0))) {
			return true;
		}
		return false;
	}
	// 批量新增0申报
	public void saveBatchWithTableName(List<TSalaryZero> insertList, String tableName) {
		if (insertList == null || insertList.isEmpty()) {
			return;
		}

		String sql = String.format(
				"INSERT INTO %s (ID, EMP_NAME, EMP_IDCARD, EMP_PHONE, DEPT_ID, DEPT_NAME, DEPT_NO, SETTLE_MONTH" +
						", INVOICE_TITLE, COST_REDUCTION, TAX_MONTH, DATA_SOURCE, IMPORTER_NAME, DELETE_FLAG, CREATE_TIME) " +
						"VALUES (REPLACE(UUID(),'-',''), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
				tableName
		);

		// 准备批量参数
		List<Object[]> batchArgs = new ArrayList<>(insertList.size());
		Object[] args;
		for (TSalaryZero item : insertList) {
			args = new Object[]{
					item.getEmpName(),                // EMP_NAME
					item.getEmpIdcard(),              // EMP_IDCARD
					item.getEmpPhone(),               // EMP_PHONE
					item.getDeptId(),                 // DEPT_ID
					item.getDeptName(),               // DEPT_NAME
					item.getDeptNo(),                  // DEPT_NO
					item.getSettleMonth(),             // SETTLE_MONTH
					item.getInvoiceTitle(),            // INVOICE_TITLE
					item.getCostReduction(),           // COST_REDUCTION
					item.getTaxMonth(),                // TAX_MONTH
					item.getDataSource(),              // DATA_SOURCE
					item.getImporterName(),            // IMPORTER_NAME
					item.getDeleteFlag(),              // DELETE_FLAG
					item.getCreateTime()               // CREATE_TIME
			};
			batchArgs.add(args);
		}

		// 执行批量插入
		jdbcTemplate.batchUpdate(sql, batchArgs);
	}


	// 每月1日1点生成0申报
	@Override
	public void createZeroByMonth() {
		// 判断是否为1月
		LocalDateTime now = LocalDateTime.now();
		int month = now.getMonthValue();
		int year = now.getYear();
		String tableName = SalaryConstants.TABLE_NAME_PRE + year;
		String viewYearName = SalaryConstants.VIEW_YEAR_NAME_PRE + year;
		String tableNameOrLastTable = tableName;
		// 判断是否为 1 月
		if (month == CommonConstants.ONE_INT) {
			int lastYear = year - 1;
			tableNameOrLastTable = SalaryConstants.TABLE_NAME_PRE + lastYear;
			// 创建0申报表
			baseMapper.createSalaryZeroYear(tableName);
		}
		TSalaryZeroSearchVo searchVo = new TSalaryZeroSearchVo();
		searchVo.setSettleMonth(DateUtil.addMonth(0));
		long count = baseMapper.getTSalaryZeroCount(tableName, searchVo);
		if (count == CommonConstants.ZERO_INT) {
			// 0：自动清理临时表
			baseMapper.clearTempZeroYear();
			// 1：核心逻辑：自动创建临时表（1月创建含去年12月的计税月份）（其他月更新成当年的上月的计税月份）
			baseMapper.createTempZeroYearView(viewYearName);
			baseMapper.createTempZeroYear(viewYearName);
			// 2：更新减除费用与计税月
			baseMapper.updateTempZeroYear(tableNameOrLastTable);
			// 3：同步到目标表
			baseMapper.insertIntoSalaryZeroYear(tableName);
		}
	}

	// 每日23点生成增量0申报
	@Override
	public void createZeroByDay() {
		// 判断是否为1月
		LocalDateTime now = LocalDateTime.now();
		int day = now.getDayOfMonth();
		int month = now.getMonthValue();
		int year = now.getYear();
		String tableName = SalaryConstants.TABLE_NAME_PRE + year;
		String viewDayName = SalaryConstants.VIEW_DAY_NAME_PRE + year;
		String tableNameOrLastTable = tableName;
		// 判断是否为 1 月
		if (month == CommonConstants.ONE_INT) {
			int lastYear = year - 1;
			tableNameOrLastTable = SalaryConstants.TABLE_NAME_PRE + lastYear;
			if (day == CommonConstants.ONE_INT) {
				baseMapper.createSalaryZeroYear(tableName);
			}
		}

		// 0：自动清理临时表
		baseMapper.clearTempZeroDay();
		// 1：核心逻辑：自动创建临时表（1月创建含去年12月的计税月份）（其他月更新成当年的上月的计税月份）
		baseMapper.createTempZeroDayView(viewDayName);
		baseMapper.createTempZeroDay(viewDayName);
		// 2.1：将已存在0申报表的数据清理掉
		baseMapper.deleteCurTempZeroDay(tableName);
		// 2.2：将已存在报账的数据更新掉
		baseMapper.updateTempZeroDayDelete();
		// 2.3：更新减除费用与计税月
		baseMapper.updateTempZeroDay(tableNameOrLastTable);
		// 3：同步到目标表
		baseMapper.insertIntoSalaryZeroDay(tableName);

	}


}
