package com.yifu.cloud.plus.v1.business.service.cert.impl;

import cn.hutool.core.collection.CollUtil;
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.business.dto.vacation.UpdateVacationRedundancyDTO;
import com.yifu.cloud.plus.v1.business.entity.cert.TCertInfo;
import com.yifu.cloud.plus.v1.business.entity.cert.TUpdateRecord;
import com.yifu.cloud.plus.v1.business.entity.system.SysBusDict;
import com.yifu.cloud.plus.v1.business.entity.system.TBusAttaInfo;
import com.yifu.cloud.plus.v1.business.mapper.cert.TCertInfoMapper;
import com.yifu.cloud.plus.v1.business.service.cert.TCertInfoService;
import com.yifu.cloud.plus.v1.business.service.cert.TUpdateRecordService;
import com.yifu.cloud.plus.v1.business.service.system.SysBusDictService;
import com.yifu.cloud.plus.v1.business.service.system.TBusAttaInfoService;
import com.yifu.cloud.plus.v1.business.vo.cert.TCertInfoVo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TBusinessEmployeeExtendInfo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.BusinessEmployeeListVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.UpdateEmployeeExtendRedundancyDTO;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ExcelUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprArchivesProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URLDecoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 人员证书信息表
 *
 * @author fxj
 * @date 2021-08-16 15:34:16
 */
@AllArgsConstructor
@Service
public class TCertInfoServiceImpl extends ServiceImpl<TCertInfoMapper, TCertInfo> implements TCertInfoService {

    private final DaprArchivesProperties daprArchivesProperties;

    private final SysBusDictService busDictService;

    private final TUpdateRecordService recordService;

    private final TBusAttaInfoService busAttaInfoService;

    private static final String CERT_TYPE = "cert_type";

    /**
     * 人员证书信息表简单分页查询
     *
     * @param tCertInfo 人员证书信息表
     * @return
     */
    @Override
    public IPage<TCertInfo> getTCertInfoPage(Page<TCertInfo> page, TCertInfo tCertInfo) {
        tCertInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
        return baseMapper.getTCertInfoPage(page, tCertInfo);
    }

    /**
     * 批量更新证件信息
     *
     * @param jsonStr
     * @return
     */
    @Transactional
    @Override
    public R<List<ErrorMessage>> batchUpdateCertByJsonStr(String jsonStr) {
        //用于返回错误信息
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        YifuUser user = SecurityUtils.getUser();
        if (null == user || null == user.getId()) {
            errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,CommonConstants.USER_FAIL, CommonConstants.RED));
            return R.failed(errorMessageList);
        }
        ExcelUtil<TCertInfo> util1;
        //需要转换的数据
        HashMap<String, String> otherMap = new HashMap<>();
        // 导入字段封装
        initBusiDict(otherMap, CommonConstants.ZERO_INT);
        try {
			String json = jsonStr.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
			jsonStr = URLDecoder.decode(json, CommonConstants.UTF8).replace("=", "");
            util1 = new ExcelUtil<>(TCertInfo.class);
            util1.getJsonStringToList(jsonStr, initMapForImport(otherMap));
            List<TCertInfo> list = util1.getEntityList();
            Map<String, ErrorMessage> messageMap = new HashMap<>();
            if (null != util1.getErrorInfo() && !util1.getErrorInfo().isEmpty()) {
                for (ErrorMessage msg:util1.getErrorInfo()){
                    messageMap.put(null==msg.getLineNum()?"":msg.getLineNum().toString(),msg);
                }
            }
            if (Common.isNotNull(list)) {
                Map<String, TCertInfo> existMap = new HashMap<>();
                // 初始化MAP
                initExistMap(existMap, list);
                TCertInfo temp;
                List<TCertInfo> certInfoList;
                LocalDate date = null;
                LocalDate now = LocalDate.now();
                // 数据导入
                int i = 1;
                for (TCertInfo cert : list) {
                    i++;
                    if (null != messageMap.get(Integer.toString(i))){
                        errorMessageList.add(messageMap.get(Integer.toString(i)));
                        continue;
                    }
                    temp = existMap.get(cert.getCertNum());
                    // 验证信息
                    if (Common.isEmpty(temp)) {
                        errorMessageList.add(new ErrorMessage(i, "未找到对应证书号的数据！", CommonConstants.RED));
                        continue;
                    }
                    cert.setId(temp.getId());
                    cert.setLabel(temp.getLabel());
                    cert.setBusinessTelecomNumber(temp.getBusinessTelecomNumber());
                    cert.setOrganId(temp.getOrganId());
                    cert.setPost(temp.getPost());
                    cert.setCreateTime(temp.getCreateTime());
                    cert.setCreateUser(temp.getCreateUser());
                    cert.setDeleteFlag(temp.getDeleteFlag());
                    cert.setEmpName(temp.getEmpName());
                    cert.setEmpIdcard(temp.getEmpIdcard());
                    cert.setOssUrlBack(temp.getOssUrlBack());
                    cert.setOssUrlFront(temp.getOssUrlFront());
                    if (Common.isNotNull(cert.getReviewDate())) {
                        date = getDayOfAdd(cert.getReviewDate(),CommonConstants.THIRTY_INT_NEGATIVE);
                    }
                    initCertStatusbByTime(date, cert, now);
                    if (baseMapper.updateById(cert) > 0) {
                        certInfoList = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                                .eq(TCertInfo::getEmpIdcard, cert.getEmpIdcard()).eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
                        // 按身份证更新证件类型的冗余信息
                        updateExtendCertOfUpdate(errorMessageList, otherMap, certInfoList, i);
                    } else {
                        errorMessageList.add(new ErrorMessage(i, CommonConstants.UPDATE_DATA_FAIL,CommonConstants.RED));
                    }
                }
            }else{
                errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,"证件信息更新解析异常：" +CommonConstants.NO_DATA_TO_HANDLE, CommonConstants.RED));
                return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
            }
        } catch (Exception e) {
            log.error("证件信息更新解析异常!", e);
            errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,"证件信息更新异常:" + e.getMessage(),CommonConstants.RED));
            return R.failed(CommonConstants.UPDATE_DATA_FAIL);
        }
        return R.ok(errorMessageList);
    }

	public static LocalDate getDayOfAdd(LocalDate time,int d) {
		return time.plusDays(d);
	}

    /**
     * 证件状态逻辑产品确认：
     * ①有效期以内，到达复审时间--待复审； 到达复审时间：到达复审时间前30天 至 复审时间
     * ②超过有效期--失效（此时即时到了复审时间，也是失效）；
     * ③失效状态修改到期时间--状态 需要根据是否到达复审时间，来判断是 正常 还是 待复审
     * @param date 复审日期
     * @param cert
     * @param now
     */
    private static void initCertStatusbByTime(LocalDate date, TCertInfo cert, LocalDate now) {
        // 转成待审核  isBefore
        if (!CommonConstants.ONE_STRING.equals(cert.getStatus())
                && null != cert.getTermValidityEnd()
                && null != date
                && (date.isBefore(now) || date.equals(now))
                && (now.isBefore(cert.getTermValidityEnd()) || now.equals(cert.getTermValidityEnd()))) {
            cert.setStatus(CommonConstants.ONE_STRING);
        }
        // 转成 已失效 isAfter 不包含等于
        if (!CommonConstants.TWO_STRING.equals(cert.getStatus())
                && null != cert.getTermValidityEnd()
                && now.isAfter(cert.getTermValidityEnd())) {
            cert.setStatus(CommonConstants.TWO_STRING);
        }
        // 转成 正常
        if (!CommonConstants.ZERO_STRING.equals(cert.getStatus())
                && null != date
                && null != cert.getTermValidityEnd()
                && now.isBefore(date)
                && now.isBefore(cert.getTermValidityEnd())) {
            cert.setStatus(CommonConstants.ZERO_STRING);
        }
        if (Common.isEmpty(cert.getTermValidityEnd()) && Common.isNotNull(date)){
            if ((date.isBefore(now) || date.equals(now))){
                cert.setStatus(CommonConstants.ONE_STRING);
            }else {
                cert.setStatus(CommonConstants.ZERO_STRING);
            }
        }
    }

    private void updateExtendCertOfUpdate(List<ErrorMessage> errorMessageList,
                                          HashMap<String, String> otherMap,
                                          List<TCertInfo> certInfoList, int i) {
        if (Common.isNotNull(certInfoList)) {
            UpdateEmployeeExtendRedundancyDTO updateDto = new UpdateEmployeeExtendRedundancyDTO();
            for (TCertInfo c : certInfoList) {
                updateDto.setEmpIdcard(c.getEmpIdcard());
                c.setCertType(otherMap.get(CERT_TYPE + CommonConstants.DOWN_LINE_STRING + c.getCertType()));
            }
            initCertType(certInfoList, updateDto);
            handleUpdateEmp(errorMessageList, i, updateDto);
            errorMessageList.add(new ErrorMessage(i, CommonConstants.SAVE_SUCCESS, CommonConstants.GREEN));
        }
    }

    @Override
    public List<TCertInfo> getCertInfoForExport(TCertInfo tCertInfo) {
        tCertInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
        return baseMapper.getCertInfoNoPage(tCertInfo);
    }

    /**
     * 定时任务更新证件状态信息
     *
     * @return
     * @date 2021-08-23
     * @author: fxj
     */
    @Transactional
    @Override
    public R<Boolean> updateCertStatusTask() {
        List<TCertInfo> certInfos = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                .eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING)
                .ne(TCertInfo::getStatus, CommonConstants.TWO_STRING));
        try {
            if (Common.isNotNull(certInfos)) {
                LocalDate date;
                LocalDate now = LocalDate.now();
                for (TCertInfo certInfo : certInfos) {
                    date = getDayOfAdd(certInfo.getReviewDate(),CommonConstants.THIRTY_INT_NEGATIVE);
                    initCertStatusbByTime(date, certInfo, now);
                    baseMapper.updateById(certInfo);
                }
            }
        } catch (Exception e) {
            log.error("证件状态变更异常！", e);
            return R.failed(CommonConstants.RESULT_DATA_FAIL);
        }
        return R.ok();
    }

    @Override
    public R<List<ErrorMessage>> updateRedundancyEmpOfCert(List<UpdateVacationRedundancyDTO> dtoList) {
        if (!CollUtil.isEmpty(dtoList)) {
            dtoList.forEach(v -> {
                this.lambdaUpdate().eq(TCertInfo::getEmpIdcard, v.getEmpIdcard())
                        .set(TCertInfo::getEmpName, v.getEmpName())
                        .set(TCertInfo::getBusinessTelecomNumber, v.getBusinessTelecomNumber())
                        .set(TCertInfo::getPost, v.getBusinessPost())
                        .set(TCertInfo::getOrganId,v.getDepartId())
                        .set(TCertInfo::getLabel,v.getLabel())
                        .update();
            });
        }
        return R.ok();
    }

    private void initExistMap(Map<String, TCertInfo> existMap, List<TCertInfo> list) {
        List<String> certNums = new ArrayList<>();
        for (TCertInfo cert : list) {
            certNums.add(cert.getCertNum());
        }
        if (Common.isNotNull(certNums)) {
            List<TCertInfo> certRes = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                    .in(TCertInfo::getCertNum, certNums).eq(TCertInfo::getDeleteFlag,CommonConstants.ZERO_STRING));
            if (Common.isNotNull(certRes)) {
                for (TCertInfo certInfo : certRes) {
                    existMap.put(certInfo.getCertNum(), certInfo);
                }
            }
        }
    }

    /**
     * 批量导入证件信息
     *
     * @param jsonStr
     * @return
     */
    @Transactional
    @Override
    public R<List<ErrorMessage>> batchImportCertByJsonStr(String jsonStr) {
        //用于返回错误信息
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        YifuUser user = SecurityUtils.getUser();
        if (null == user || null == user.getId()) {
            errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,CommonConstants.USER_FAIL, CommonConstants.RED));
            return R.failed(errorMessageList);
        }
        ExcelUtil<TCertInfo> util;
        //需要转换的数据
        HashMap<String, String> otherMap = new HashMap<>();
        // 导入字段封装
        initBusiDict(otherMap, CommonConstants.ZERO_INT);
        try {
			String json = jsonStr.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
			jsonStr = URLDecoder.decode(json, CommonConstants.UTF8).replace("=", "");
            util = new ExcelUtil<>(TCertInfo.class);
            util.getJsonStringToList(jsonStr, initMapForImport(otherMap));
            List<TCertInfo> list = util.getEntityList();
            Map<String, ErrorMessage> messageMap = new HashMap<>();
            if (null != util.getErrorInfo() && !util.getErrorInfo().isEmpty()) {
                for (ErrorMessage msg:util.getErrorInfo()){
                    messageMap.put(null==msg.getLineNum()?"":msg.getLineNum().toString(),msg);
                }
            }
            if (!CollUtil.isEmpty(list)) {
                Map<String, TCertInfo> existMap = new HashMap<>();
                // 初始化MAP
                initExistMap(existMap, list);
                List<String> idCardList = new ArrayList<>();
                for (TCertInfo cert : list) {
					idCardList.add(cert.getEmpIdcard());
                }
                if (!Common.isNotNull(idCardList)) {
                    errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,"获取B端人员信息失败！", CommonConstants.RED));
                    return R.failed(errorMessageList);
                }
				R<BusinessEmployeeListVo> empRes = HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(), daprArchivesProperties.getAppId()
						, "/customerBusiness/temployeeBusiness/inner/getListByIdCartList", idCardList
						, BusinessEmployeeListVo.class, SecurityConstants.FROM_IN);
                Map<String, TBusinessEmployeeExtendInfo> empMap = new HashMap<>();
                // 初始化MAP
                initEmpMap(empRes, empMap);
                TBusinessEmployeeExtendInfo extendInfo;
                List<TCertInfo> certInfoList;
                TCertInfo temp;
                LocalDate now = LocalDate.now();
                LocalDate date = null;
                // 数据导入
                int i = 1;
                for (TCertInfo cert : list) {
                    i++;
                    if (null != messageMap.get(Integer.toString(i))){
                        errorMessageList.add(messageMap.get(Integer.toString(i)));
                        continue;
                    }
                    extendInfo = empMap.get(cert.getEmpIdcard() +
                            CommonConstants.DOWN_LINE_STRING +
                            cert.getBusinessTelecomNumber());
                    temp = existMap.get(cert.getCertNum());
                    // 验证信息
                    if (checkImport(errorMessageList, i, cert, extendInfo, temp)) {
                        continue;
                    }
                    cert.setLabel(extendInfo.getEmployeeTags());
                    cert.setBusinessTelecomNumber(extendInfo.getBusinessTelecomNumber());
                    cert.setOrganId(null == extendInfo.getDepartId() ? null : extendInfo.getDepartId().toString());
                    cert.setPost(extendInfo.getBusinessPost());
                    cert.setCreateTime(LocalDateTime.now());
                    cert.setCreateUser(user.getNickname());
                    cert.setEmpName(extendInfo.getEmpName());
                    cert.setEmpIdcard(extendInfo.getEmpIdcard());
                    cert.setDeleteFlag(CommonConstants.ZERO_STRING);
                    if (Common.isEmpty(cert.getStatus())){
                        cert.setStatus(CommonConstants.ZERO_STRING);
                    }
                    certInfoList = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                            .eq(TCertInfo::getEmpIdcard, cert.getEmpIdcard()).eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
                    if (Common.isNotNull(cert.getReviewDate())) {
                        date = getDayOfAdd(cert.getReviewDate(),CommonConstants.THIRTY_INT_NEGATIVE);
                    }
                    initCertStatusbByTime(date, cert, now);
                    if (baseMapper.insert(cert) > 0) {
                        existMap.put(cert.getCertNum(),cert);
                        // 更新证件信息
                        updateExtendCertInfo(errorMessageList, certInfoList, i, cert);
                    } else {
                        errorMessageList.add(new ErrorMessage(i, CommonConstants.SAVE_FAILED, CommonConstants.RED));
                    }
                }
            }else{
                errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,"证件信息数据导入解析异常：" +CommonConstants.NO_DATA_TO_HANDLE, CommonConstants.RED));
                return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
            }
        } catch (Exception e) {
            log.error("证件信息数据导入解析异常!", e);
            errorMessageList.add(new ErrorMessage(CommonConstants.ONE_INT_NEGATE,"证件信息数据导入解析异常：" + e.getMessage(), CommonConstants.RED));
            return R.failed(errorMessageList);
        }
        return R.ok(errorMessageList);
    }

	public static Map<String, String> initMapForImport(Map<String, String> otherMap) {
		HashMap<String, String> dicMap = new HashMap<>();
		if (null != otherMap){
			dicMap.putAll(otherMap);
		}
		return dicMap;
	}
	
    /**
     * B端字段数据封装
     *
     * @param otherMap
     * @param type     0 导入  1  导出
     */
    private void initBusiDict(HashMap<String, String> otherMap, int type) {
        List<SysBusDict> dictList = busDictService.list(Wrappers.<SysBusDict>query().lambda().eq(SysBusDict::getStatus, CommonConstants.ZERO_STRING));
        if (null != dictList) {
            for (SysBusDict dict : dictList) {
                if (CommonConstants.ZERO_INT == type) {
                    otherMap.put(dict.getItemType() + CommonConstants.DOWN_LINE_STRING + dict.getLabel(), dict.getValue());
                }
                if (CommonConstants.ONE_INT == type) {
                    otherMap.put(dict.getItemType() + CommonConstants.DOWN_LINE_STRING + dict.getValue(), dict.getLabel());
                }
            }
        }
    }

    /**
     * @auth fxj
     * 单个更新员工的证件类型数据
     * @param certInfoList
     * @param certInfo
     * @return
     */
    private String updateExtendCertSingle(List<TCertInfo> certInfoList, TCertInfo certInfo) {
        if (Common.isEmpty(certInfoList)) {
            certInfoList = new ArrayList<>();
        }
        certInfoList.add(certInfo);
        UpdateEmployeeExtendRedundancyDTO updateDto = new UpdateEmployeeExtendRedundancyDTO();
        updateDto.setEmpIdcard(certInfo.getEmpIdcard());
        initCertType(certInfoList, updateDto);
        if (Common.isNotNull(updateDto.getEmpIdcard())) {
			R<Boolean> remoteRes = HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(), daprArchivesProperties.getAppId()
					, "/customerBusiness/temployeeBusiness/inner/updateEmpExtendCertInfo", updateDto
					, Boolean.class, SecurityConstants.FROM_IN);
            if (null == remoteRes || CommonConstants.FAIL == remoteRes.getCode()) {
                return  "更新证件冗余信息异常！";
            }
        }
        return null;
    }

    private void initCertType(List<TCertInfo> certInfoList, UpdateEmployeeExtendRedundancyDTO updateDto) {
        Map<String, String> strMap = new HashMap<>();
        for (TCertInfo c : certInfoList) {
            strMap.put(c.getCertType(),c.getCertType());
        }
        if (Common.isNotNull(strMap)){
            for (String key:strMap.keySet()){
                if (Common.isEmpty(updateDto.getDocumentType())) {
                    updateDto.setDocumentType(key);
                } else {
                    updateDto.setDocumentType(updateDto.getDocumentType() +
                            CommonConstants.COMMA_STRING + key);
                }
            }
        }
    }

    private void updateExtendCertInfo(List<ErrorMessage> errorMessageList, List<TCertInfo> certInfoList, int i, TCertInfo certInfo) {
        if (Common.isEmpty(certInfoList)) {
            certInfoList = new ArrayList<>();
            certInfoList.add(certInfo);
        }
        UpdateEmployeeExtendRedundancyDTO updateDto = new UpdateEmployeeExtendRedundancyDTO();
        updateDto.setEmpIdcard(certInfo.getEmpIdcard());
        initCertType(certInfoList, updateDto);
        handleUpdateEmp(errorMessageList, i, updateDto);
        errorMessageList.add(new ErrorMessage(i, CommonConstants.SAVE_SUCCESS, CommonConstants.GREEN));
    }

    private void handleUpdateEmp(List<ErrorMessage> errorMessageList, int i, UpdateEmployeeExtendRedundancyDTO updateDto) {
        if (Common.isNotNull(updateDto.getEmpIdcard()) && Common.isNotNull(updateDto.getDocumentType())) {
			R<Boolean> remoteRes = HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(), daprArchivesProperties.getAppId()
					, "/customerBusiness/temployeeBusiness/inner/updateEmpExtendCertInfo", updateDto
					, Boolean.class, SecurityConstants.FROM_IN);
			if (null == remoteRes || CommonConstants.FAIL == remoteRes.getCode()) {
				errorMessageList.add(new ErrorMessage(i, "更新证件冗余信息异常！", CommonConstants.RED));
			}
        }
    }

    /**
     * 证件信息单个保持接口
     *
     * @param tCertInfo
     * @return
     */
    @Transactional
    @Override
    public R<TCertInfo> saveAsso(TCertInfo tCertInfo) {
        String checkRes = checkForSave(tCertInfo);
        if (Common.isNotNull(checkRes)) {
            return R.failed(checkRes);
        }
        tCertInfo.setDeleteFlag(CommonConstants.ZERO_STRING);
        initCertStatusbByTime(getDayOfAdd(tCertInfo.getReviewDate(),CommonConstants.THIRTY_INT_NEGATIVE), tCertInfo, LocalDate.now());
        if (baseMapper.insert(tCertInfo) > CommonConstants.ZERO_INT) {
            List<TCertInfo> certInfoList = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                    .eq(TCertInfo::getEmpIdcard, tCertInfo.getEmpIdcard()).eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
            String res = updateExtendCertSingle(certInfoList,tCertInfo);
            if (Common.isNotNull(res)){
                runTimeExceptionDiy("更新人员证件类型失败："+res);
            }
            return R.ok(tCertInfo);
        }
        return R.failed(CommonConstants.SAVE_FAILED);
    }

	public static void runTimeExceptionDiy(String errorInfo) {
		throw new CheckedException(errorInfo);
	}

    /**
     * 修改证件信息并保存记录信息
     *
     * @param certInfo
     * @return
     */
    @Transactional
    @Override
    public R<String> updateByIdDiy(TCertInfo certInfo) {
        if (null == certInfo || Common.isEmpty(certInfo.getId())) {
            return R.failed(CommonConstants.PARAM_INFO_ERROR);
        }
        TCertInfo cert = baseMapper.selectById(certInfo.getId());
        if (null == cert) {
            return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
        }
		TCertInfo certTemp = baseMapper.selectOne(Wrappers.<TCertInfo>query().lambda()
				.eq(TCertInfo::getCertNum, cert.getCertNum())
				.eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING)
				.ne(TCertInfo::getId,certInfo.getId())
				.last(CommonConstants.LAST_ONE_SQL));
		if (Common.isNotNull(certTemp)) {
			return R.failed("已存在对应证件编号的信息!");
		}
        certInfo.setCreateTime(cert.getCreateTime());
        certInfo.setCreateUser(cert.getCreateUser());
        certInfo.setPost(cert.getPost());
        certInfo.setOrganId(cert.getOrganId());
        certInfo.setLabel(cert.getLabel());
        certInfo.setBusinessTelecomNumber(cert.getBusinessTelecomNumber());
        certInfo.setEmpName(cert.getEmpName());
        certInfo.setEmpIdcard(cert.getEmpIdcard());
        certInfo.setDeleteFlag(cert.getDeleteFlag());
        recordService.saveModificationRecord(certInfo.getId(), CommonConstants.ZERO_STRING, cert, certInfo, TCertInfo.class);
        initCertStatusbByTime(getDayOfAdd(certInfo.getReviewDate(),CommonConstants.THIRTY_INT_NEGATIVE), certInfo, LocalDate.now());
        int res = baseMapper.updateById(certInfo);
        if (res >= CommonConstants.ZERO_INT) {
            updateEmpCertType(certInfo, res, certInfo.getCertNum());
            return R.ok(CommonConstants.SAVE_SUCCESS);
        }
        return R.failed(CommonConstants.SAVE_FAILED);
    }

    /**
     * 获取证件信息及变更记录信息
     *
     * @param id
     * @return
     */
    @Override
    public R<TCertInfoVo> getVoById(String id) {
        TCertInfoVo vo = new TCertInfoVo();
        if (Common.isEmpty(id)) {
            return R.failed(CommonConstants.PARAM_INFO_ERROR);
        }
        vo.setCertInfo(baseMapper.selectById(id));
        vo.setRecordList(recordService.list(Wrappers.<TUpdateRecord>query().lambda()
                .eq(TUpdateRecord::getModul, CommonConstants.ZERO_STRING).eq(TUpdateRecord::getDomainId, id)
                .orderByDesc(TUpdateRecord::getCreateTime)));
        List<TBusAttaInfo> busAttaInfos = busAttaInfoService.list(Wrappers.<TBusAttaInfo>query().lambda().eq(TBusAttaInfo::getRelationId,id));
        List<TBusAttaInfo> res = new ArrayList<>();
        if (Common.isNotNull(busAttaInfos)){
            for (TBusAttaInfo attaInfo:busAttaInfos){
                res.add(busAttaInfoService.getUrlByid(attaInfo.getId()));
            }
        }
        vo.setAttaInfos(res);
        return R.ok(vo);
    }

    /**
     * 按身份证查询所有证件信息
     *
     * @param empIdcard
     * @return
     */
    @Override
    public R<List<TCertInfoVo>> getByEmpIdcard(String empIdcard) {
        if (Common.isEmpty(empIdcard)) {
            return R.failed(CommonConstants.PARAM_INFO_ERROR);
        }
        TCertInfoVo vo;
        List<TCertInfoVo> voList = new ArrayList<>();
        List<TBusAttaInfo> busAttaInfos;
        List<TBusAttaInfo> res;
        List<TCertInfo> certInfos = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                .eq(TCertInfo::getEmpIdcard, empIdcard).eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
        if (Common.isNotNull(certInfos)){
            for (TCertInfo info:certInfos){
                vo = new TCertInfoVo();
                vo.setCertInfo(baseMapper.selectById(info.getId()));
                vo.setRecordList(recordService.list(Wrappers.<TUpdateRecord>query().lambda()
                        .eq(TUpdateRecord::getModul, CommonConstants.ZERO_STRING).eq(TUpdateRecord::getDomainId, info.getId())
                        .orderByDesc(TUpdateRecord::getCreateTime)));
                busAttaInfos = busAttaInfoService.list(Wrappers.<TBusAttaInfo>query().lambda().eq(TBusAttaInfo::getRelationId,info.getId()));
                res = new ArrayList<>();
                if (Common.isNotNull(busAttaInfos)){
                    for (TBusAttaInfo attaInfo:busAttaInfos){
                        res.add(busAttaInfoService.getUrlByid(attaInfo.getId()));
                    }
                }
                vo.setAttaInfos(res);
                voList.add(vo);
            }
        }
        return R.ok(voList);
    }

    /**
     * 删除证件信息
     *
     * @param id
     * @return
     */
    @Override
    public R<Boolean> removeByIdDiy(String id) {
        if (Common.isEmpty(id)) {
            return R.failed(CommonConstants.PARAM_INFO_ERROR);
        }
        TCertInfo certInfo = baseMapper.selectById(id);
        if (Common.isEmpty(certInfo)) {
            return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
        }
        certInfo.setDeleteFlag(CommonConstants.ONE_STRING);
        int res = baseMapper.updateById(certInfo);
        if (res > CommonConstants.ZERO_INT) {
            certInfo.setCertType(null);
            updateEmpCertType(certInfo, res, certInfo.getCertNum());
            return R.ok();
        }
        return R.failed(CommonConstants.RESULT_DATA_FAIL);
    }

    private void updateEmpCertType(TCertInfo certInfo, int res, String certNum) {
        List<TCertInfo> certInfoList = baseMapper.selectList(Wrappers.<TCertInfo>query().lambda()
                .eq(TCertInfo::getEmpIdcard, certInfo.getEmpIdcard())
                .ne(TCertInfo::getCertNum, certNum)
                .eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING));
        String result = updateExtendCertSingle(certInfoList, certInfo);
        if (Common.isNotNull(result)) {
            runTimeExceptionDiy("更新人员证件类型失败：" + res);
        }
    }

    private String checkForSave(TCertInfo cert) {
        if (Common.isEmpty(cert.getEmpName())
                || Common.isEmpty(cert.getEmpIdcard())
                || Common.isEmpty(cert.getCertNum())) {
            return "姓名|身份证号|证件号不可为空!";
        }
        List<String> idCardList = new ArrayList<>();
		idCardList.add(cert.getEmpIdcard());
		R<BusinessEmployeeListVo> empRes = HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(), daprArchivesProperties.getAppId()
				, "/customerBusiness/temployeeBusiness/inner/getListByIdCartList", idCardList
				, BusinessEmployeeListVo.class, SecurityConstants.FROM_IN);
        Map<String, TBusinessEmployeeExtendInfo> empMap = new HashMap<>();
        if (Common.isEmpty(cert.getBusinessTelecomNumber())) {
            return "暂无电信工号，请补充后，再添加证件信息！";
        }
        // 初始化MAP
        initEmpMap(empRes, empMap);
        TBusinessEmployeeExtendInfo extendInfo = empMap.get(cert.getEmpIdcard() +
                CommonConstants.DOWN_LINE_STRING +
                cert.getBusinessTelecomNumber());
        if (Common.isEmpty(extendInfo)) {
            return "未找到对应员工信息!";
        }
        cert.setLabel(extendInfo.getEmployeeTags());
        cert.setBusinessTelecomNumber(extendInfo.getBusinessTelecomNumber());
        cert.setPost(extendInfo.getBusinessPost());
        cert.setOrganId(null == extendInfo.getDepartId() ? null : extendInfo.getDepartId().toString());
        if (Common.isEmpty(cert.getCertType())) {
            return "证件类型不可为空!";
        }
        if (Common.isEmpty(cert.getStatus())) {
            return "证件状态不可为空!";
        }
        TCertInfo certTemp = baseMapper.selectOne(Wrappers.<TCertInfo>query().lambda()
                .eq(TCertInfo::getCertNum, cert.getCertNum())
                .eq(TCertInfo::getDeleteFlag, CommonConstants.ZERO_STRING).last(CommonConstants.LAST_ONE_SQL));
        if (Common.isNotNull(certTemp)) {
            return "已存在对应证件编号的信息!";
        }
        if (Common.isEmpty(cert.getJobClass())) {
            return "作业类别不可为空!";
        }
        if (Common.isEmpty(cert.getReviewDate())) {
            return "复审日期不可为空!";
        }
        return null;
    }

    private boolean checkImport(List<ErrorMessage> errorMessageList, int i, TCertInfo cert,
                                TBusinessEmployeeExtendInfo extendInfo, TCertInfo temp) {
        if (Common.isNotNull(temp)) {
            errorMessageList.add(new ErrorMessage(i, "已存在对应证件编号的信息!", CommonConstants.RED, cert.getEmpIdcard()));
            return true;
        }
        if (Common.isEmpty(extendInfo)) {
            errorMessageList.add(new ErrorMessage(i, "未找到对应身份证和电信编号的人员信息，请核实或补充后添加证件信息！", CommonConstants.RED, cert.getEmpIdcard()));
            return true;
        }
        if (Common.isEmpty(extendInfo.getBusinessTelecomNumber())) {
            errorMessageList.add(new ErrorMessage(i, "对应员工无电信工号，请去人员管理列表更新！", CommonConstants.RED, cert.getEmpIdcard()));
            return true;
        }
        return false;
    }

    private void initEmpMap(R<BusinessEmployeeListVo> empRes, Map<String, TBusinessEmployeeExtendInfo> empMap) {
        if (R.haveData(empRes)) {
            for (TBusinessEmployeeExtendInfo extendInfo : empRes.getData().getEmpList()) {
                empMap.put(extendInfo.getEmpIdcard()
                        + CommonConstants.DOWN_LINE_STRING
                        + extendInfo.getBusinessTelecomNumber(), extendInfo);
            }
        }
    }


}
