package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.dto.CountDto;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.*;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.common.api.dto.ESEquipmentCategoryDto;
import com.yeejoin.amos.boot.module.common.api.enums.CylinderTypeEnum;
import com.yeejoin.amos.boot.module.common.api.mapper.CustomBaseMapper;
import com.yeejoin.amos.boot.module.common.biz.refresh.DataRefreshEvent;
import com.yeejoin.amos.boot.module.common.biz.service.impl.EquipmentCategoryService;
import com.yeejoin.amos.boot.module.jg.api.common.DataDockTemplateVersionUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.*;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.api.enums.*;
import com.yeejoin.amos.boot.module.jg.api.mapper.*;
import com.yeejoin.amos.boot.module.jg.biz.config.PressureVesselListener;
import com.yeejoin.amos.boot.module.jg.biz.context.EquipUsedCheckStrategyContext;
import com.yeejoin.amos.boot.module.jg.biz.core.BaseService;
import com.yeejoin.amos.boot.module.jg.biz.edit.backup.TechParamsBackupService;
import com.yeejoin.amos.boot.module.jg.biz.event.publisher.EventPublisher;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.biz.reminder.core.event.EquipCreateOrEditEvent;
import com.yeejoin.amos.boot.module.jg.biz.service.*;
import com.yeejoin.amos.boot.module.jg.biz.utils.CodeUtil;
import com.yeejoin.amos.boot.module.jg.biz.utils.JsonUtils;
import com.yeejoin.amos.boot.module.ymt.api.dto.TzBaseEnterpriseInfoDto;
import com.yeejoin.amos.boot.module.ymt.api.dto.TzsUserInfoDto;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.*;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.feign.utils.FeignUtil;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.amos.feign.systemctl.model.SmsRecordModel;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Sets;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.alibaba.fastjson.JSON.toJSONString;
import static com.yeejoin.amos.boot.module.common.api.enums.CylinderTypeEnum.SPECIAL_CYLINDER;
import static com.yeejoin.amos.boot.module.jg.api.enums.CertificateStatusEnum.YIDENGJI;
import static com.yeejoin.amos.boot.module.jg.api.enums.VehicleApanageEnum.XIAN_YANG;
import static com.yeejoin.amos.boot.module.jg.api.enums.VehicleApanageEnum.XI_XIAN;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.DataHandlerServiceImpl.IDX_BIZ_EQUIPMENT_INFO;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.DataHandlerServiceImpl.IDX_BIZ_VIEW_JG_ALL;


/**
 * 注册登记信息表服务实现类
 *
 * @author system_generator
 * @date 2023-08-17
 */
@Service
@Slf4j
public class IdxBizJgRegisterInfoServiceImpl extends BaseService<IdxBizJgRegisterInfoMapper, IdxBizJgRegisterInfo> implements IIdxBizJgRegisterInfoService {
    public final static String USE_TYPE_NAME = "使用单位";
    public final static String INDIVIDUAL_TYPE_NAME = "个人主体";
    public final static String MAINTENANCE_TYPE_NAME = "安装改造维修单位";
    // 设备种类
    public static final String EQU_LIST = "EQU_LIST";
    // 管道信息
    public static final String PIPELINE_LIST = "pipelineList";
    // 模版上传集合
    public static final String EQU_LISTS = "equLists";
    // 设备类别
    public static final String EQU_CATEGORY = "EQU_CATEGORY";
    // 设备品种
    public static final String EQU_DEFINE = "EQU_DEFINE";
    // 是否车用气瓶
    public static final String WHETHER_VEHICLE_CYLINDER = "WHETHER_VEHICLE_CYLINDER";
    // 是否撬装式压力容器
    public static final String WHETHER_SKID_MOUNTED_PRESSURE_VESSEL = "WHETHER_SKID_MOUNTED_PRESSURE_VESSEL";
    // 设备纳管  纳管：true 未纳管：false
    public static final String IS_INTO_MANAGEMENT = "IS_INTO_MANAGEMENT";
    public static final String IS_INTO_MANAGEMENT_NAME = "IS_INTO_MANAGEMENT_NAME";
    public static final String IS_DO_BUSINESS = "IS_DO_BUSINESS";
    // 设备来源 jg：新设备录入  jg_his：历史数据录入
    public static final String DATA_SOURCE = "DATA_SOURCE";
    // 设备来源名称 jg：新设备  jg_his：历史数据
    public static final String DATA_SOURCE_NAME = "DATA_SOURCE_NAME";
    public static final String USE_PLACE_CODE = "USE_PLACE_CODE";
    public static final String EQU_CATEGORY_CODE = "EQU_CATEGORY_CODE";
    public static final String EQU_LIST_CODE = "EQU_LIST_CODE";
    public static final String DEVICE_TYPE = "DEVICE_TYPE";
    public static final String PROJECT_CONTRAPTION = "PROJECT_CONTRAPTION";// 工程装置名称
    public static final String CREATE_DATE_RANGE = "CREATE_DATE_RANGE";// 创建时间范围查询
    public static final String CREATE_DATE = "CREATE_DATE";// 创建时间范围查询
    public static final String USE_UNIT_CREDIT_CODE = "useUnitCreditCode";// 创建时间范围查询
    /**
     * 业务类型 0：单个新增 1:批量导入
     */
    public static final String BUSINESS_SCENARIOS = "businessScenarios";
    // 设备分类表单id
    public static final String EQUIP_CLASS_FORM_ID = "equipClass";
    // 设备基本信息表单id
    public static final String EQUIP_INFO_FORM_ID = "equipInfo";
    // 设备技术参数表单id
    public static final String EQUIP_PARAMS_FORM_ID = "equipParams";
    // 主要零部件
    private static final String EQUIP_MAINPARTS_FORM_ID = "mainParts";
    // 安全附件
    private static final String EQUIP_PROTECTIONDEVICES_FORM_ID = "protectionDevices";
    public static final String EQUSTATE = "EQU_STATE";
    private static final String CONSTRUCTIONTYPE = "CONSTRUCTION_TYPE";
    // 新增修改标识
    private static final String OPERATESAVE = "save";
    private static final String OPERATEEDIT = "edit";

    private static final String ADD = "add";

    private static final String EDIT = "edit";
    //市区县
    private static final String CITY = "CITY";
    private static final String COUNTY = "COUNTY";
    private static final String REGION = "REGION";
    private static final String STREET = "STREET";
    // 单位办理类型
    private static final String MANAGE_TYPE_UNIT = "unit";
    private static final String RECORD = "RECORD";
    private static final String MANAGE_TYPE = "manageType";
    // 设备代码
    public static final String EQU_CODE = "EQU_CODE";
    // 96333识别码
    private static final String CODE96333 = "CODE96333";
    private static final String SEQUENCE_NBR = "SEQUENCE_NBR";
    private static final String OTHERINFO_SEQ = "OTHERINFO_SEQ";
    public static final String FACTORY_NUM = "FACTORY_NUM";
    // 新增设备是否复制而来
    private static final String IS_COPY = "isCopy";
    private static final String ATTACHMENT_UPLOAD = "attachmentUpload";
    private static final Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();
    public static final String CAR_NUMBER = "CAR_NUMBER";
    public static final String USE_UNIT_NAME = "USE_UNIT_NAME";
    private static final String PRODUCT_NAME = "PRODUCT_NAME";
    // 需要转化成jsonObject的附件字段
    public static String[] jsonFields = {"insOtherAccessories", "installContractAttachment", "installProxyStatementAttachment"};
    private final List<String> resultError = new ArrayList<>();
    List<String> useInnerCodeList = new ArrayList<>();// 单位内部编号集合
    List<String> equCodeList = new ArrayList<>();// 设备代码集合
    List<String> factoryNumList = new ArrayList<>();
    private static final int MAX_UPLOAD = 2000; // 最大上传条数
    // 出厂编码集合
    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Autowired
    private IdxBizJgRegisterInfoMapper idxBizJgRegisterInfoMapper;
    @Autowired
    private IdxBizJgDesignInfoMapper idxBizJgDesignInfoMapper;
    @Autowired
    private IdxBizJgUseInfoMapper idxBizJgUseInfoMapper;
    @Autowired
    private IdxBizJgFactoryInfoMapper idxBizJgFactoryInfoMapper;
    @Autowired
    private IdxBizJgSupervisionInfoMapper idxBizJgSupervisionInfoMapper;
    @Autowired
    private IdxBizJgTechParamsVesselMapper idxBizJgTechParamsVesselMapper;
    @Autowired
    private IdxBizJgInspectionDetectionInfoMapper idxBizJgInspectionDetectionInfoMapper;
    @Autowired
    IdxBizJgOtherInfoMapper otherInfoMapper;
    @Autowired
    IIdxBizJgUseInfoService idxBizJgUseInfoService;
    @Autowired
    IIdxBizJgDesignInfoService iIdxBizJgDesignInfoService;
    @Autowired
    IIdxBizJgFactoryInfoService iIdxBizJgFactoryInfoService;
    @Autowired
    IIdxBizJgConstructionInfoService iIdxBizJgConstructionInfoService;
    @Autowired
    IIdxBizJgMaintenanceRecordInfoService iIdxBizJgMaintenanceRecordInfoService;
    @Autowired
    IIdxBizJgSupervisionInfoService iIdxBizJgSupervisionInfoService;
    @Autowired
    IIdxBizJgOtherInfoService iIdxBizJgOtherInfoService;
    @Autowired
    IIdxBizJgInspectionDetectionInfoService iIdxBizJgInspectionDetectionInfoService;
    @Autowired
    IIdxBizJgTechParamsElevatorService iIdxBizJgTechParamsElevatorService;
    @Autowired
    IIdxBizJgTechParamsVehicleService iIdxBizJgTechParamsVehicleService;
    @Autowired
    IIdxBizJgTechParamsRopewayService iIdxBizJgTechParamsRopewayService;
    @Autowired
    IIdxBizJgTechParamsRidesService iIdxBizJgTechParamsRidesService;
    @Autowired
    IIdxBizJgTechParamsBoilerService iIdxBizJgTechParamsBoilerService;

    @Autowired
    IIdxBizJgTechParamsVesselService iIdxBizJgTechParamsVesselService;
    @Autowired
    IIdxBizJgTechParamsPipelineService iIdxBizJgTechParamsPipelineService;
    @Autowired
    IIdxBizJgTechParamsLiftingService iIdxBizJgTechParamsLiftingService;
    @Autowired
    IIdxBizJgMainPartsService iIdxBizJgMainPartsService;
    @Autowired
    IIdxBizJgProtectionDevicesService iIdxBizJgProtectionDevicesService;
    @Autowired
    ESEquipmentCategory esEquipmentCategory;
    @Autowired
    EquipmentCategoryService equipmentCategoryService;
    @Autowired
    ICommonService commonService;
    @Autowired
    CommonMapper commonMapper;
    @Autowired
    DataDictionaryServiceImpl iDataDictionaryService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private CategoryOtherInfoMapper categoryOtherInfoMapper;
    @Autowired
    private SuperviseInfoMapper superviseInfoMapper;
    @Autowired
    private JgUseRegistrationMapper jgUseRegistrationMapper;
    @Autowired
    private JgInstallationNoticeServiceImpl jgInstallationNoticeService;
    @Value("${add.equip.dict.code.suffix:CATEGORY_LIST_ADD}")
    private String equipAddDictCodeSuffix;
    @Value("${task.licenseExpiration.enabled:false}")
    private boolean licenseExpirationEnabled;
    @Autowired
    private IdxBizJgDesignInfoServiceImpl idxBizJgDesignInfoService;
    @Autowired
    private IdxBizJgFactoryInfoServiceImpl idxBizJgFactoryInfoService;
    @Autowired
    private IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;
    @Autowired
    private IdxBizJgTechParamsVesselServiceImpl idxBizJgTechParamsVesselService;
    @Autowired
    private IdxBizJgInspectionDetectionInfoServiceImpl idxBizJgInspectionDetectionInfoService;
    @Autowired
    private IIdxBizJgOtherInfoService idxBizJgOtherInfoService;
    @Autowired
    private CodeUtil codeUtil;
    @Autowired
    private TzsServiceFeignClient tzsServiceFeignClient;
    @Autowired
    private JgUseRegistrationManageServiceImpl jgUseRegistrationManageService;
    @Autowired
    private JgVehicleInformationMapper jgVehicleInformationMapper;
    @Autowired
    private JgCertificateChangeRecordServiceImpl certificateChangeRecordService;
    @Autowired
    private SnowflakeIdUtil sequence;
    @Autowired
    private JgCertificateChangeRecordEqMapper certificateChangeRecordEqMapper;
    @Autowired
    private JgUseRegistrationServiceImpl jgUseRegistrationService;
    @Autowired
    private JgUseRegistrationEqMapper jgRelationEquipMapper;
    @Autowired
    private JgResumeInfoServiceImpl jgResumeInfoService;
    @Autowired
    private JgRegistrationHistoryServiceImpl jgRegistrationHistoryService;
    @Autowired
    private SafetyProblemTracingMapper safetyProblemTracingMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private TzBaseEnterpriseInfoMapper baseEnterpriseInfoMapper;
    @Autowired
    private TzsUserInfoMapper tzsUserInfoMapper;
    @Autowired
    private IdxBizJgProjectContraptionServiceImplService idxBizJgProjectContraptionService;
    @Value("classpath:/json/urlInfo.json")
    private Resource urlInfo;

    @Value("${equip.detail.path:/mixuap?appId=1742358052905971713&id=1734100233714954241&formType=detail&record=%s&DATA_SOURCE=%s}")
    private String equipRoutePath;

    @Value("${pipeline.detail.path:/mixuap?appId=1742358052905971713&id=1867406434120003586&formType=detail&sequenceNbr=%s}")
    private String pipelineRoutePath;

    @Lazy
    @Autowired
    private CommonServiceImpl commonServiceImpl;

    @Autowired
    private EventPublisher eventPublisher;

    @Autowired
    private TechParamsBackupService techParamsBackupService;

    public static final String DATA_QUALITY_SCORE = "DATA_QUALITY_SCORE";
    public static final String DATA_QUALITY_SCORE_JG = "DATA_QUALITY";

    private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    public IdxBizJgRegisterInfo getOneData(String record) {
        return this.getOne(new QueryWrapper<IdxBizJgRegisterInfo>().eq("RECORD", record));
    }

    /**
     * 将对象的属性由驼峰转为纯大写下划线格式
     *
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static Map<String, Object> convertCamelToUnderscore(Object object, String[] strToJsonArrayFields) {
        Map<String, Object> result = new HashMap<>();
        Class<?> clazz = object.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            String fieldName = field.getName();
            field.setAccessible(true);
            String underscoreFieldName = StringUtils.camelToUnderline(fieldName).toUpperCase();
            Object value = null;
            try {
                value = field.get(object);
                // 需要转为jsonArray的字段
                if (!ValidationUtil.isEmpty(strToJsonArrayFields) && Arrays.asList(strToJsonArrayFields).contains(underscoreFieldName) && value instanceof String) {
                    value = JSON.parse((String) field.get(object));
                }
            } catch (Exception e) {
                log.warn("JSON转化失败：{}",e.getMessage());
            }
            if (!ValidationUtil.isEmpty(value)) {
                result.put(underscoreFieldName.toUpperCase(), value);
            }
        }
        return result;
    }

    /**
     * 将List<Map<String, Object>>中的字段名从大写转换为驼峰格式
     *
     * @param originalList 源List<Map<String, Object>>对象
     * @return 转换后的List<Map < String, Object>>对象
     */
    public static List<Map<String, Object>> convertKeysToCamelCase(List<Map<String, Object>> originalList) {
        List<Map<String, Object>> camelCaseList = new ArrayList<>();

        for (Map<String, Object> originalMap : originalList) {
            Map<String, Object> camelCaseMap = new HashMap<>();

            for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
                String camelCaseKey = toCamelCase(entry.getKey());
                camelCaseMap.put(camelCaseKey, entry.getValue());
            }

            camelCaseList.add(camelCaseMap);
        }

        return camelCaseList;
    }

    /**
     * 将大写加下划线的字符串转换为驼峰命名法
     *
     * @param input 需要转换的字符串
     * @return 驼峰格式的字符串
     */
    public static String toCamelCase(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        StringBuilder result = new StringBuilder();
        boolean toUpperCase = false;

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);

            if (c == '_') {
                toUpperCase = true;
            } else if (toUpperCase) {
                result.append(Character.toUpperCase(c));
                toUpperCase = false;
            } else {
                result.append(Character.toLowerCase(c));
            }
        }

        return result.toString();
    }

    /**
     * 设备注册信息
     *
     * @param paramMap
     * @param company
     * @return
     */
    @Transactional
    public ResponseModel equipmentRegisterSubmit(Map<String, Object> paramMap, CompanyBo company) {
        if (paramMap == null) {
            throw new IllegalArgumentException("参数Map不能为空");
        }
        LinkedHashMap equipmentInfoForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_INFO_FORM_ID));
        String dataSource = (String) equipmentInfoForm.get(DATA_SOURCE);
        String equListCode = (String) equipmentInfoForm.get(EQU_LIST);
        //管道添加设备
        if (PipelineEnum.PRESSURE_PIPELINE.getCode().equals(equListCode)) {
            ResponseModel responseModel = this.pipelineEquipCreateOrUpdate(paramMap, company);
            Long projectContraptionId = (Long)responseModel.getResult();
            eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_PROJECT.name(), Sets.newHashSet(projectContraptionId.toString()), EquipCreateOrEditEvent.EquipType.project));
            return responseModel;
        }
        if(dataSource.contains("black")){
            ResponseModel responseModel = this.blackEquipCreateOrUpdate(paramMap, company);
            String record = (String)responseModel.getResult();
            eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), Sets.newHashSet(record), EquipCreateOrEditEvent.EquipType.equip));
            return responseModel;
        } else {
            ResponseModel responseModel = this.otherEquipCreateOrUpdate(paramMap, company);
            String record = (String)responseModel.getResult();
            eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), Sets.newHashSet(record), EquipCreateOrEditEvent.EquipType.equip));
            return responseModel;
        }
    }


    /**
     * 管道设备新增或更新
     *
     * @param paramMap 前端参数
     * @param company
     * @return record
     */
    private ResponseModel pipelineEquipCreateOrUpdate(Map<String, Object> paramMap, CompanyBo company) {
        try {
            // 获取表单数据并进行类型检查
            LinkedHashMap equipmentInfoForm = castToLinkedHashMap(paramMap.get(EQUIP_INFO_FORM_ID));
            String submitType = String.valueOf(paramMap.get("submitType"));
            return ResponseHelper.buildResponse(batchSubmitOrUpdatePipeline(equipmentInfoForm, submitType, company));
        } catch (Exception e) {
            log.error("操作失败，数据异常: {}", e.getMessage(), e);
            handleError(e, String.valueOf(paramMap.getOrDefault(SEQUENCE_NBR, "")));
            return ResponseHelper.buildResponse(null);
        }
    }

    /**
     * 检查并转换对象为 LinkedHashMap
     *
     * @param obj 要转换的对象
     * @return LinkedHashMap
     * @throws IllegalArgumentException 如果类型不匹配
     */
    @SuppressWarnings("unchecked")
    private LinkedHashMap castToLinkedHashMap(Object obj) {
        if (obj instanceof LinkedHashMap) {
            return (LinkedHashMap) obj;
        }
        throw new IllegalArgumentException("参数类型错误，期望 LinkedHashMap 类型: " + obj);
    }

    // 通用方法初始化 List
    private <T> List<T> initializeList() {
        return new ArrayList<>(15);
    }

    private Long batchSubmitOrUpdatePipeline(LinkedHashMap equipmentInfoForm, String submitType, CompanyBo company) {
        Date date = new Date();
        String operateType = ValidationUtil.isEmpty(equipmentInfoForm.get(SEQUENCE_NBR)) ? OPERATESAVE : OPERATEEDIT;
        // 设备是否复制而来，复制来的设备走新增
        boolean isCopy = !ValidationUtil.isEmpty(equipmentInfoForm.get(IS_COPY));
        operateType = isCopy ? OPERATESAVE : operateType;
        // 新增设备保存时 : 历史设备=》dataSource为"his" jg新录入设备dataSource为"jg"
        String dataSource = this.getDataSource(operateType, equipmentInfoForm);
        Long sequenceNbr = OPERATESAVE.equals(operateType)
                ? sequence.nextId()
                : Optional.ofNullable(equipmentInfoForm.get(SEQUENCE_NBR))
                .map(String::valueOf)
                .map(Long::valueOf)
                .orElseThrow(() -> new IllegalArgumentException("Invalid SEQUENCE_NBR value"));

        if ("edit".equals(submitType)) {
            List<String> records = idxBizJgUseInfoService.lambdaQuery()
                    .select(IdxBizJgUseInfo::getRecord)
                    .eq(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr)
                    .list()
                    .stream()
                    .map(IdxBizJgUseInfo::getRecord)
                    .collect(Collectors.toList());
            idxBizJgRegisterInfoService.batchDeleteByRecord(MapBuilder.<String, Object>create()
                    .put("recordList", records)
                    .put("equList", equipmentInfoForm.get("EQU_LIST"))
                    .build());
        }

        List<Map<String, Object>> pipelineList  = (List<Map<String, Object>>) equipmentInfoForm.get(PIPELINE_LIST);

        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipmentInfoForm.get("EQU_LIST"));
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode( (String) equipmentInfoForm.get("EQU_CATEGORY"));
        String equDefineName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipmentInfoForm.get("EQU_DEFINE"));

        // 单位类型
        Map<String, Object> companyInfoMap = jgInstallationNoticeService.getCompanyType();
        String companyTypeStr = companyInfoMap.get("companyType").toString();
//去掉同一装置管道编号唯一性校验
//        if (CollectionUtils.isEmpty(pipelineList) || pipelineList.size() != pipelineList.stream()
//                .map(v -> (String) v.get("pipelineNumber")).distinct().count()) {
//            throw new BadRequest(CollectionUtils.isEmpty(pipelineList) ? "请填写管道信息!" : "同一工程装置下管道编号不能重复！");
//        }

        // 工程装置信息
        IdxBizJgProjectContraption projectContraption = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgProjectContraption.class);
        projectContraption.setSequenceNbr(sequenceNbr);
        projectContraption.setDataSource(dataSource);
        List<String> managedCategories = Arrays.asList("8200", "8100");
        projectContraption.setIsIntoManagement(dataSource.contains("jg_his_black") && managedCategories.contains(equipmentInfoForm.get("EQU_CATEGORY")));
        projectContraption.setProvinceName("陕西省");
        projectContraption.setCityName(getRegionName(CITY, CITY, equipmentInfoForm));
        projectContraption.setCountyName(getRegionName(REGION, COUNTY, equipmentInfoForm));
        projectContraption.setStreetName(getRegionName(STREET, STREET, equipmentInfoForm));
        projectContraption.setEquListName(equListName);
        projectContraption.setEquCategoryName(equCategoryName);
        projectContraption.setEquDefineName(equDefineName);
        if (!ObjectUtils.isEmpty(projectContraption.getOrgCode()) && projectContraption.getOrgCode().contains("_")) {
            String[] split = projectContraption.getOrgCode().split("_");
            projectContraption.setOrgCode(split[0]);
            projectContraption.setOrgName(split[1]);
        }
        projectContraption.setPipelineLength(
                BigDecimal.valueOf(pipelineList.stream()
                                .map(pipeline -> pipeline.get("pipeLength"))
                                .filter(Objects::nonNull)
                                .mapToDouble(pipeLength -> Double.parseDouble(String.valueOf(pipeLength)))
                                .sum())
                        .setScale(2, RoundingMode.HALF_UP)
                        .doubleValue()
        );

        // 历史黑设备新增由使用单位新增
        if(dataSource.contains("black")){
            projectContraption.setUseUnitName(companyInfoMap.get("companyName").toString());
            projectContraption.setUseUnitCreditCode(companyInfoMap.get("creditCode").toString());
        } else {
            projectContraption.setUscUnitName(companyInfoMap.get("companyName").toString());
            projectContraption.setUscUnitCreditCode(companyInfoMap.get("creditCode").toString());
        }
        projectContraption.setIsFirstMerge(false);
        if ("add".equals(submitType)) {
            projectContraption.setCreateDate(date);
        }
        if (Stream.of(projectContraption.getProjectContraption(), projectContraption.getProjectContraptionNo())
                .anyMatch(StringUtils::isEmpty)) {
            throw new BadRequest("请填写工程（装置）名称/项目名称/工程装置编号后暂存！");
        }
        idxBizJgProjectContraptionService.checkTheUnitProConMatching(EquipRequestParamsDto.builder()
                .projectContraptionNo(projectContraption.getProjectContraptionNo())
                .projectContraption(projectContraption.getProjectContraption())
                .companyCode(MapUtil.getStr(companyInfoMap,"creditCode"))
                .build());
        idxBizJgProjectContraptionService.saveOrUpdateData(projectContraption);

        List<IdxBizJgUseInfo> useInfoList = initializeList();
        List<IdxBizJgDesignInfo> designInfoList = initializeList();
        List<IdxBizJgFactoryInfo> factoryInfoList = initializeList();
        List<IdxBizJgConstructionInfo> constructionInfoList = initializeList();
        List<IdxBizJgRegisterInfo> registerInfoList = initializeList();
        List<IdxBizJgSupervisionInfo> supervisionInfoList = initializeList();
        List<IdxBizJgOtherInfo> otherInfoList = initializeList();
        List<IdxBizJgInspectionDetectionInfo> inspectionDetectionInfoList = initializeList();
        List<IdxBizJgTechParamsPipeline> paramsPipelineList = initializeList();
        List<ESEquipmentCategoryDto> esEquipmentCategoryList = initializeList();

        //设备信息
        for (Map<String, Object> pipeline : pipelineList) {
            String record = UUID.randomUUID().toString();
            if (isCopy) {
                String sourceRecord = pipeline.get(RECORD).toString();
                // bug-21203
                if (equipmentInfoForm.containsKey("DATA_SOURCE")) {
                    String dataSourceCopy = equipmentInfoForm.get("DATA_SOURCE").toString();
                    if (dataSourceCopy.startsWith("jg_his_black")) {
                        dataSource = "jg_his_black_" + sourceRecord;
                    } else if (dataSourceCopy.startsWith("jg_his")) {
                        dataSource = "jg_his_" + sourceRecord;
                    } else {
                        dataSource = "jg_" + sourceRecord;
                    }
                } else {
                    throw new BadRequest("数据异常,请联系管理员");
                }
            }
            //更新时工业管道（8300）检验检测信息
            IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgInspectionDetectionInfo.class);
            if (!ValidationUtil.isEmpty(inspectionDetectionInfo)) {
                List<Map<String, Object>> inspectionAndTestingInstitutions = commonService.getUnitListByType("inspection", "gasCylindersForCars", false);
                Optional<Map<String, Object>> optional = inspectionAndTestingInstitutions.stream().filter(x -> x.get("useCode").equals(inspectionDetectionInfo.getInspectOrgCode())).findFirst();
                Map<String, Object> mapOrDefault = optional.orElse(Collections.emptyMap());
                inspectionDetectionInfo.setInspectOrgName((String) mapOrDefault.getOrDefault("useUnit", inspectionDetectionInfo.getInspectOrgName()));
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(date);
                inspectionDetectionInfo.setSequenceNbr(null);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                inspectionDetectionInfoList.add(inspectionDetectionInfo);
            }

            // 使用信息
            IdxBizJgUseInfo useInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgUseInfo.class);
            // 使用信息
            if(!ObjectUtils.isEmpty(projectContraption.getProvince())){
                useInfo.setProvince(projectContraption.getProvince());
                useInfo.setProvinceName(projectContraption.getProvinceName());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getCity())){
                useInfo.setCity(projectContraption.getCity());
                useInfo.setCityName(projectContraption.getCityName());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getCounty())){
                useInfo.setCounty(projectContraption.getCounty());
                useInfo.setCountyName(projectContraption.getCountyName());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getStreet())){
                useInfo.setFactoryUseSiteStreet(projectContraption.getStreet());
                useInfo.setStreetName(projectContraption.getStreetName());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getAddress())){
                useInfo.setAddress(projectContraption.getAddress());
                useInfo.setProvinceName(projectContraption.getProvinceName());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getUseUnitName())){
                useInfo.setUseUnitName(projectContraption.getUseUnitName());
                useInfo.setUseUnitCreditCode(projectContraption.getUseUnitCreditCode());
            }
            if(!ObjectUtils.isEmpty(projectContraption.getUseDate())){
                useInfo.setUseDate(projectContraption.getUseDate());
            }

            useInfo.setRecord(record);
            useInfo.setSequenceNbr(null);
            useInfo.setRecDate(date);
            useInfo.setCreateDate(date);
            useInfo.setDataSource(dataSource);
            useInfo.setIsIntoManagement(dataSource.contains("jg_his_black") && managedCategories.contains(equipmentInfoForm.get("EQU_CATEGORY")));
            if (companyTypeStr.contains(CompanyTypeEnum.USE.getCode()) || companyTypeStr.contains(CompanyTypeEnum.INDIVIDUAL.getCode())) {
                useInfo.setUseUnitCreditCode(companyInfoMap.get("creditCode").toString());
                useInfo.setUseUnitName(companyInfoMap.get("companyName").toString());
            }

            if (isCopy) {
                // 设备状态置空
                useInfo.setEquState("");
                // 如果为安改维单位复制设备，则将使用单位信息置空
                if (companyTypeStr.equals(CompanyTypeEnum.CONSTRUCTION.getCode())) {
                    useInfo.setUseUnitCreditCode("");
                    useInfo.setUseUnitName("");
                }
            }
            useInfo.setProjectContraption(((String) equipmentInfoForm.get("PROJECT_CONTRAPTION")).trim());
            useInfo.setProjectContraptionId(String.valueOf(sequenceNbr));
            useInfoList.add(useInfo);

            // 设计信息
            IdxBizJgDesignInfo designInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgDesignInfo.class);
            designInfo.setRecord(record);
            designInfo.setRecDate(date);
            designInfo.setSequenceNbr(null);
            designInfoList.add(designInfo);

            // 制造信息
            IdxBizJgFactoryInfo factoryInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgFactoryInfo.class);
            factoryInfo.setRecord(record);
            factoryInfo.setRecDate(date);
            factoryInfo.setSequenceNbr(null);
            factoryInfoList.add(factoryInfo);

            // 施工信息
            IdxBizJgConstructionInfo constructionInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgConstructionInfo.class);
            String companyName = companyInfoMap.get("companyName").toString();
            String companyCode = companyInfoMap.get("creditCode").toString();
            constructionInfo.setRecord(record);
            constructionInfo.setRecDate(date);

            if (companyTypeStr.contains(CompanyTypeEnum.CONSTRUCTION.getCode())) {
                constructionInfo.setUscUnitCreditCode(companyCode);
                constructionInfo.setUscUnitName(companyName);
            }

            if (isCopy) {
                if (companyTypeStr.equals(CompanyTypeEnum.USE.getCode()) || companyTypeStr.equals(CompanyTypeEnum.INDIVIDUAL.getCode())) {
                    constructionInfo.setUscUnitCreditCode("");
                    constructionInfo.setUscUnitName("");
                }
            }
            constructionInfo.setSequenceNbr(null);
            constructionInfoList.add(constructionInfo);

            // 注册登记信息
            IdxBizJgRegisterInfo registerInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgRegisterInfo.class);
            registerInfo.setRecord(record);
            registerInfo.setRecDate(date);
            registerInfo.setSequenceNbr(null);
            registerInfo.setEquCodeType("2");
            registerInfo.setRegisterState(this.getRegCode());
            // 补丁：saveOrUpdate在update数据时不会更新字段为null的字段，但是编辑设备的代码时，从有改成无，equCode解析成null，但是此时需要将equcode删掉
            registerInfo.setEquCode(ObjectUtils.isEmpty(registerInfo.getEquCode()) ? "" : registerInfo.getEquCode());

            // 监督管理
            IdxBizJgSupervisionInfo supervisionInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgSupervisionInfo.class);
            if(!ObjectUtils.isEmpty(projectContraption.getOrgCode())){
                supervisionInfo.setOrgBranchCode(projectContraption.getOrgCode());
                supervisionInfo.setOrgBranchName(projectContraption.getOrgName());
            }
            supervisionInfo.setRecord(record);
            supervisionInfo.setRecDate(date);
            supervisionInfo.setSequenceNbr(null);
            supervisionInfoList.add(supervisionInfo);

            // 其他信息
            IdxBizJgOtherInfo otherInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgOtherInfo.class);
            otherInfo.setRecord(record);
            otherInfo.setSequenceNbr(null);
            otherInfo.setClaimStatus("已认领");
            otherInfo.setRecDate(date);
            if (isCopy) {
                // 监管码置空
                otherInfo.setSupervisoryCode("");
                otherInfo.setCylinderStampAttachment("");
                otherInfo.setInformationSituation("");
                otherInfo.setInformationManageCode("");
            }
            otherInfoList.add(otherInfo);

            //管道技术参数
            IdxBizJgTechParamsPipeline pipelineInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgTechParamsPipeline.class);
            if (!ValidationUtil.isEmpty(pipelineInfo)) {
                pipelineInfo.setRecord(record);
                pipelineInfo.setRecDate(date);
                pipelineInfo.setSequenceNbr(null);
                paramsPipelineList.add(pipelineInfo);
            }
            registerInfo.setProductName(pipelineInfo.getPipeName());
            registerInfoList.add(registerInfo);

            ESEquipmentCategoryDto esEquipmentDto = JSON.parseObject(toJSONString(equipmentInfoForm), ESEquipmentCategoryDto.class);
            esEquipmentDto.setDATA_SOURCE(useInfo.getDataSource());
            if (inspectionDetectionInfo.getNextInspectDate() != null) {
                esEquipmentDto.setNEXT_INSPECT_DATE(inspectionDetectionInfo.getNextInspectDate().getTime());
            }
            esEquipmentDto.setREC_DATE(System.currentTimeMillis());
            esEquipmentDto.setSEQUENCE_NBR(record);
            esEquipmentDto.setIS_INTO_MANAGEMENT(dataSource.contains("jg_his_black") && managedCategories.contains(equipmentInfoForm.get("EQU_CATEGORY")));
            esEquipmentDto.setEQU_CATEGORY_CODE(registerInfo.getEquCategory());
            esEquipmentDto.setEQU_CATEGORY(equCategoryName);
            esEquipmentDto.setEQU_LIST_CODE(registerInfo.getEquList());
            esEquipmentDto.setEQU_LIST(equListName);
            esEquipmentDto.setEQU_DEFINE_CODE(registerInfo.getEquDefine());
            esEquipmentDto.setEQU_DEFINE(equListName);
            esEquipmentDto.setSTATUS("已认领");
            esEquipmentDto.setUSC_UNIT_CREDIT_CODE(projectContraption.getUscUnitCreditCode());
            esEquipmentDto.setUSC_UNIT_NAME(projectContraption.getUscUnitName());
            esEquipmentDto.setUSE_UNIT_CREDIT_CODE(projectContraption.getUseUnitCreditCode());
            esEquipmentDto.setUSE_UNIT_NAME(projectContraption.getUseUnitName());
            esEquipmentDto.setPROJECT_CONTRAPTION(projectContraption.getProjectContraption());
            esEquipmentDto.setPRODUCT_NAME(pipelineInfo.getPipeName());
            esEquipmentDto.setProjectContraptionId(String.valueOf(sequenceNbr));
            if (inspectionDetectionInfo.getNextInspectDate() != null) {
                esEquipmentDto.setNEXT_INSPECT_DATE(inspectionDetectionInfo.getNextInspectDate().getTime());
            }
            esEquipmentCategoryList.add(esEquipmentDto);
        }
        idxBizJgUseInfoService.saveOrUpdateBatch(useInfoList);
        iIdxBizJgDesignInfoService.saveOrUpdateBatch(designInfoList);
        iIdxBizJgConstructionInfoService.saveOrUpdateBatch(constructionInfoList);
        iIdxBizJgFactoryInfoService.saveOrUpdateBatch(factoryInfoList);
        super.saveOrUpdateBatch(registerInfoList);
        iIdxBizJgOtherInfoService.saveOrUpdateBatch(otherInfoList);
        iIdxBizJgSupervisionInfoService.saveOrUpdateBatch(supervisionInfoList);
        iIdxBizJgInspectionDetectionInfoService.saveOrUpdateBatch(inspectionDetectionInfoList);
        iIdxBizJgTechParamsPipelineService.saveOrUpdateBatch(paramsPipelineList);
        esEquipmentCategory.saveAll(esEquipmentCategoryList);
        // 更新管道长度
        updatePipelineLength(projectContraption, paramsPipelineList);
        if(OPERATESAVE.equals(operateType)){
            // 记录设备创建履历
            this.createResumePipeline(sequenceNbr, String.format(pipelineRoutePath, sequenceNbr + ""), company);
        }
        return sequenceNbr;
    }

    private void updatePipelineLength(IdxBizJgProjectContraption projectContraption, List<IdxBizJgTechParamsPipeline> paramsPipelineList) {
        projectContraption.setPipelineLength(
                paramsPipelineList.stream()
                                .map(IdxBizJgTechParamsPipeline::getPipeLength)
                                .filter(Objects::nonNull)
                                .map(BigDecimal::new)
                                .reduce(BigDecimal.ZERO, BigDecimal::add)
                        .setScale(2, RoundingMode.HALF_UP)
                        .doubleValue()
        );
        LambdaUpdateWrapper<IdxBizJgProjectContraption> updateWrapper  = new LambdaUpdateWrapper<>();
        updateWrapper.set(IdxBizJgProjectContraption::getPipelineLength, projectContraption.getPipelineLength());
        updateWrapper.eq(BaseEntity::getSequenceNbr, projectContraption.getSequenceNbr());
        idxBizJgProjectContraptionService.update(updateWrapper);
    }

    private void createResumePipeline(Long sequenceNbr, String routePath, CompanyBo company) {
        jgResumeInfoService.saveBatchResume(Collections.singletonList(JgResumeInfoDto.builder()
                .businessType(BusinessTypeEnum.JG_NEW_PROJECT.getName())
                .businessId(sequenceNbr + "")
                .equId(sequenceNbr + "")
                .status("正常")
                .approvalUnitCode(company.getCompanyCode())
                .approvalUnit(company.getCompanyName())
                .changeContent(BusinessTypeEnum.JG_NEW_PROJECT.getName() + "业务办理")
                .routePath(routePath)
                .build())
        );
    }

    /**
     * 根据code获取市区县名字
     * @param key key
     * @param codeKey codeKey
     * @param equipmentInfoForm 表单信息
     * @return name
     */
    private String getRegionName(String key, String codeKey, Map<String, Object> equipmentInfoForm) {
        return Optional.ofNullable((List<LinkedHashMap>) redisUtils.get(key))
                .flatMap(list -> list.stream()
                        .filter(item -> String.valueOf(item.get("regionCode"))
                                .equals(String.valueOf(equipmentInfoForm.get(codeKey))))
                        .map(item -> (String) item.get("regionName"))
                        .findFirst())
                .orElse("");
    }

    private ResponseModel blackEquipCreateOrUpdate(Map<String, Object> paramMap, CompanyBo company) {
        LinkedHashMap equipmentClassForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_CLASS_FORM_ID));
        LinkedHashMap equipmentInfoForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_INFO_FORM_ID));
        LinkedHashMap equipmentParamsForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_PARAMS_FORM_ID));
        String submitType = String.valueOf(paramMap.get("submitType"));
        String record = (String) equipmentInfoForm.get(RECORD);
        try {
            // 设备代码 字段的唯一性校验
            checkEquCodeUniqueness(equipmentInfoForm);
            // 车用气瓶业务里面的 产品编号 校验唯一性（产品编号在车用气瓶范围内全局唯一）
            checkFactoryNumUniqueness(equipmentInfoForm);
            // 96333码 字段的唯一性校验
            check96333Code(equipmentInfoForm);
        } catch (Exception e) {
            handleError(e, null);
        }
        // 操作类型
        try {
            // 保存数据
            record = batchSubmitOrUpdate(equipmentClassForm, equipmentInfoForm, equipmentParamsForm, submitType, company);
            // 保存Es数据
            if (!ObjectUtils.isEmpty(record)) {
                checkEsData(record);
            }
        } catch (Exception e) {
            log.error("操作失败，数据异常: " + e.getMessage(), e);
            handleError(e, record);
        }
        return ResponseHelper.buildResponse(record);
    }

    private ResponseModel otherEquipCreateOrUpdate(Map<String, Object> paramMap, CompanyBo company) {
        if (paramMap == null) {
            throw new IllegalArgumentException("参数Map不能为空");
        }
        LinkedHashMap equipmentClassForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_CLASS_FORM_ID));
        LinkedHashMap equipmentInfoForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_INFO_FORM_ID));
        LinkedHashMap equipmentParamsForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_PARAMS_FORM_ID));
        String submitType = String.valueOf(paramMap.get("submitType"));
        String record = (String) equipmentInfoForm.get(RECORD);
        String dataSource = (String) equipmentInfoForm.get(DATA_SOURCE);

        if (dataSource.contains("his")) {
            // 使用登记证编号校验
            this.checkUseRegistrationCodeIsNotNUll(equipmentInfoForm);
            this.checkUseRegistrationCode(equipmentInfoForm);
        }

        try {
            // 设备代码 字段的唯一性校验
            checkEquCodeUniqueness(equipmentInfoForm);
            // 车用气瓶业务里面的 产品编号 校验唯一性（产品编号在车用气瓶范围内全局唯一）
            checkFactoryNumUniqueness(equipmentInfoForm);
            // 96333码 字段的唯一性校验
            check96333Code(equipmentInfoForm);
            // 气瓶 校验制造单位统一信用代码与出场编码唯一
            checkFactoryNumUniqueWithGasCylinder(equipmentInfoForm, record);
            // 历史（车用气瓶）设备校验使用登记证编号 VIN 全库唯一
            hisEquCheckUseRegCodeAndVINUniqueness(equipmentInfoForm, record);
            // 历史有使用登记证的场车设备校验车牌号的唯一性
            checkCarNumberUniquenessWithHisCC(equipmentInfoForm, record, dataSource);
        } catch (Exception e) {
            handleError(e, null);
        }

        // 使用登记按照单位办理除外，其余进行编辑校验
        Object manageType = equipmentInfoForm.get(MANAGE_TYPE);
        boolean isManageType = (!ObjectUtils.isEmpty(manageType) && MANAGE_TYPE_UNIT.equals(manageType));
        if (!isManageType) {
            // 编辑校验
            this.checkForEquipEdit(record);
        }
        // 操作类型
        try {
            // 保存数据
            record = batchSubmitOrUpdate(equipmentClassForm, equipmentInfoForm, equipmentParamsForm, submitType, company);
            // 保存Es数据
            if (!ObjectUtils.isEmpty(record)) {
                checkEsData(record);
            }
        } catch (Exception e) {
            log.error("操作失败，数据异常: " + e.getMessage(), e);

            handleError(e, record);
        }
        return ResponseHelper.buildResponse(record);
    }

    /**
     * 使用登记证编号相关校验
     * @param equipmentInfoForm
     */
    public void checkUseRegistrationCode(LinkedHashMap equipmentInfoForm) {
        String useRegistrationCode = Optional.ofNullable(equipmentInfoForm.get("useRegistrationCode"))
                .map(String::valueOf)
                .map(String::trim)
                .orElse(null);
        String equipId = String.valueOf(equipmentInfoForm.get("RECORD"));
        // 校验使用登记证编号的唯一性
        if (!CylinderTypeEnum.CYLINDER.getCode().equals(equipmentInfoForm.get("EQU_CATEGORY")) && commonService.useRegistrationCertificateAccountUnique(useRegistrationCode, equipId)) {
            throw new BadRequest("使用登记证编号已存在！");
        } else {
            if (CylinderTypeEnum.CYLINDER.getCode().equals(equipmentInfoForm.get("EQU_CATEGORY"))) {
                // 需求 35094 历史设备（有使用登记证）需按证录入。录入时先录入使用登记证编号。
                // 需验证录入的使用登记证编号平台是否跟当前用户（使用单位类型）一致，如跟当前用户不一致，系统给出提示“该使用登记证编号”已被“单位名称“使用”，请确认后再录入”。
                // 历史设备不限制使用登记证编号在一个单位重复录入，但需验证使用登记证编号+单位内编号唯一。（下面方法checkFactoryNumUniqueWithGasCylinder中已经校验）
                String occupiedUseUnitName = commonService.isRegistrationNumberUsedByOtherUnits(useRegistrationCode);
                if (!ValidationUtil.isEmpty(occupiedUseUnitName)) {
                    throw new BadRequest("该使用登记证编号已被【" + occupiedUseUnitName + "】使用，请确认后再录入！");
                }
            }
        }
        String regType = Optional.ofNullable(equipmentInfoForm.get("EQU_LIST"))
                .filter(code -> CylinderTypeEnum.CYLINDER.getCode().equals(code))
                .map(code -> "1".equals(equipmentInfoForm.get("WHETHER_VEHICLE_CYLINDER")) ? "vehicle" : "cylinder")
                .orElse("set");
        // 判断是否使用未来系统生成编号
        idxBizJgRegisterInfoService.checkUseRegistrationCode(useRegistrationCode, regType);
    }

    /**
     * 使用登记证编号为空相关校验
     * @param equipmentInfoForm
     */
    private void checkUseRegistrationCodeIsNotNUll(LinkedHashMap equipmentInfoForm) {
        String useRegistrationCode = Optional.ofNullable(equipmentInfoForm.get("useRegistrationCode"))
                .map(String::valueOf)
                .map(String::trim)
                .orElse(null);
        if (useRegistrationCode == null) {
            throw new BadRequest("请填写使用登记证编号后进行暂存！");
        }
    }


    private Object checkAndCast(Object obj) {
        if (obj instanceof LinkedHashMap) {
            return obj;
        } else {
            throw new ClassCastException("对象类型不匹配");
        }
    }

    public void checkEquCodeUniqueness(LinkedHashMap equipmentInfoForm) {
        // 根据设备代码检查唯一性
        String equCode = (String) equipmentInfoForm.get(EQU_CODE);
        String sequenceNbr = (String) equipmentInfoForm.get(SEQUENCE_NBR);
        if(StringUtils.isNotEmpty(equCode)) {
            List<Integer> results = Stream.of(idxBizJgRegisterInfoMapper.selectByEquCodeAndClaimStatus(equCode, sequenceNbr, null),
                    idxBizJgRegisterInfoMapper.selectInstallNoticeEqByEquCode(equCode, sequenceNbr)
            ).collect(Collectors.toList());

            if (results.stream().anyMatch(count -> count > 0)) {
                throw new BadRequest("设备代码已存在，请重新输入！");
            }
        }
    }

    /**
     * 历史有使用登记证的场车设备校验车牌号的唯一性
     * @param equipmentInfoForm
     * @param record
     * @param dataSource
     */
    public void checkCarNumberUniquenessWithHisCC(LinkedHashMap<?, ?> equipmentInfoForm, String record, String dataSource) {
        if (dataSource.contains("his") && EquipmentClassifityEnum.CC.getCode().equals(equipmentInfoForm.get(EQU_LIST)) && !ValidationUtil.isEmpty(equipmentInfoForm.get(CAR_NUMBER))) {
            String carNumber = String.valueOf(equipmentInfoForm.get(CAR_NUMBER));
            if (!"无".equals(carNumber)) {
                Integer count = idxBizJgRegisterInfoMapper.checkCarNumberUniquenessWithHisCC(carNumber, record);
                if (count > 0) {
                    throw new BadRequest("车牌号已存在，请重新输入！");
                }
            }
        }
    }

    public void check96333Code(LinkedHashMap equipmentInfoForm) {
        if (!ObjectUtils.isEmpty(equipmentInfoForm.get(CODE96333))) {
            // 根据96333码检查唯一性
            LambdaQueryWrapper<IdxBizJgOtherInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(IdxBizJgOtherInfo::getCode96333, equipmentInfoForm.get(CODE96333));
            wrapper.notIn(IdxBizJgOtherInfo::getClaimStatus, "待认领,已拒领,草稿");
            wrapper.ne(!ObjectUtils.isEmpty(equipmentInfoForm.get(OTHERINFO_SEQ)), IdxBizJgOtherInfo::getSequenceNbr, equipmentInfoForm.get(OTHERINFO_SEQ));
            Integer count = otherInfoMapper.selectCount(wrapper);
            if (count > 0) {
                throw new BadRequest("96333码已存在，请确认后重新输入！");
            }
        }
    }

    public void checkFactoryNumUniqueWithGasCylinder(LinkedHashMap equipmentInfoForm, String record) {
        if (equipmentInfoForm.get(EQU_LIST).equals("2000")
                && equipmentInfoForm.get(EQU_CATEGORY).equals("2300")
                && commonMapper.checkFactoryNumUnique(String.valueOf(equipmentInfoForm.get(FACTORY_NUM)), record, String.valueOf(equipmentInfoForm.get("PRODUCE_UNIT_CREDIT_CODE"))) > 0) {
            throw new BadRequest("出厂编号/产品编码在该企业中已存在！");
        }
    }

    public void checkFactoryNumUniqueness(LinkedHashMap equipmentInfoForm) {
        // 车用气瓶业务里面的 出厂编号/产品编码 校验唯一性（产品编号在车用气瓶范围内全局唯一）
        Integer factoryNum = commonMapper.checkFactoryNumUniquenessForVehicleCylinder((String) equipmentInfoForm.get(FACTORY_NUM), (String) equipmentInfoForm.get(RECORD));
        if (factoryNum > 0) {
            throw new BadRequest("出厂编号/产品编码 已存在，请重新输入！");
        }
    }

    public void hisEquCheckUseRegCodeAndVINUniqueness(LinkedHashMap<?, ?> equipmentInfoForm, String record) {
        // 历史（车用气瓶）设备校验使用登记证编号 VIN 全库唯一
        if ("2000".equals(equipmentInfoForm.get(EQU_LIST)) && "2300".equals(equipmentInfoForm.get(EQU_CATEGORY)) && "23T0".equals(equipmentInfoForm.get(EQU_DEFINE)) && "1".equals(equipmentInfoForm.get(WHETHER_VEHICLE_CYLINDER))) {
            String dataSource = (String) equipmentInfoForm.get(DATA_SOURCE);
            if (ValidationUtil.isEmpty(dataSource)) {
                throw new BadRequest("参数异常！");
            }
            if (dataSource.contains("his")) {
                String VIN = (String) equipmentInfoForm.get("identificationCode");
                String useRegistrationCode = (String) equipmentInfoForm.get("useRegistrationCode");
                if (!ValidationUtil.isEmpty(VIN) && !ValidationUtil.isEmpty(useRegistrationCode)) {
                    ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
                    String companyType = reginParams.getCompany().getCompanyType();
                    String companyCode = "个人主体".equals(companyType) ? reginParams.getCompany().getCompanyCode().split("_")[1] : reginParams.getCompany().getCompanyCode();
                    // 匹配使用登记证编号
                    List<Map<String, String>> useRegMapList = commonMapper.useRegCertAccountUniqueWithVehGasCyl(useRegistrationCode, record);
                    boolean hasUseReg = !useRegMapList.isEmpty();
                    boolean certificateOfTheEnterprise = hasUseReg ? toJSONString(useRegMapList).contains(companyCode) : Boolean.FALSE;
                    // 匹配车辆VIN码
                    List<Map<String, String>> VINMapList = commonMapper.VINAccountUniqueWithVehGasCyl(VIN, record);
                    boolean hasVIN = !VINMapList.isEmpty();
                    boolean VINOfTheEnterprise = hasVIN ? toJSONString(VINMapList).contains(companyCode) : Boolean.FALSE;
                    // 无证无VIN  和 本企业的证本企业的VIN 两种情况可以放行
                    if ((!hasUseReg && !hasVIN) || (certificateOfTheEnterprise && VINOfTheEnterprise)) {
                        return;
                    }
                    if (log.isDebugEnabled()) {
                        log.info("历史车用气瓶==输入的==>使用登记证编号：{}，车辆VIN码：{}", useRegistrationCode, VIN);
                        log.info("历史车用气瓶==匹配到的==>使用登记证编号：{}，车辆VIN码：{}", toJSONString(useRegMapList), toJSONString(VINMapList));
                        log.info("历史车用气瓶====>是否本企业使用登记证编号：{}，是否本企业车辆VIN码：{}", certificateOfTheEnterprise, VINOfTheEnterprise);
                    }
                    // 本企业存在证 + 无VIN  无证 + 本企业存在VIN
                    if ((certificateOfTheEnterprise && !hasVIN) || (!hasUseReg && VINOfTheEnterprise)) {
                        throw new BadRequest("使用的登记证号，车辆VIN码与本企业原先录入的数据不一致！");
                    }
                    // 本企业存在证 + VIN属于其他企业  无证 + VIN属于其他企业
                    if ((certificateOfTheEnterprise && hasVIN && !VINOfTheEnterprise) || (!hasUseReg && hasVIN && !VINOfTheEnterprise)) {
                        throw new BadRequest("车辆VIN码已被其他企业使用！");
                    }
                    // 其他企业存在证 + 本企业存在VIN  其他企业存在证 + 无VIN
                    if ((hasUseReg && !certificateOfTheEnterprise && VINOfTheEnterprise) || (hasUseReg && !certificateOfTheEnterprise && !hasVIN)) {
                        throw new BadRequest("使用的登记证号已被其他企业使用！");
                    }
                    // 其他企业存在证 + 其他企业存在VIN
                    throw new BadRequest("使用的登记证号，车辆VIN码已被其他企业使用！");
                }
            }
        }
    }

    private void checkFactoryNumUnique(String factoryNum, String produceUnitCreditCode,String produceUnitName, StringBuilder result) {
        // 车用气瓶业务里面的 出厂编号/产品编码 校验唯一性（产品编号在车用气瓶范围内全局唯一）
        List<Map<String, Object>> unitList = commonMapper.checkFactoryNumUniqueWithUseName(factoryNum, produceUnitCreditCode);
        String duplicateUnits = unitList.stream()
                .filter(m -> {
                    Object count = m.get("count");
                    return count != null && Integer.parseInt(String.valueOf(count)) > 0;
                })
                .map(m -> String.valueOf(m.get("useUnitName")))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.joining("，"));
        if (!duplicateUnits.isEmpty()) {
            result.append(String.format(
                    "制造单位[%s]生产的出厂编号为[%s]的气瓶，已被[%s]录入系统，请核实！",
                    produceUnitName, factoryNum, duplicateUnits
            ));
        }
    }

    private void handleError(Exception e, String record) {
        log.error("处理异常: " + e.getMessage(), e);
        // 删除数据库数据和ES数据
        if (!ObjectUtils.isEmpty(record)) {
            List<String> records = new ArrayList<>();
            records.add(record);
            superviseInfoMapper.deleteDataAll(records);
            esEquipmentCategory.deleteById(record);
        }
        throw new BadRequest(e.getMessage());
    }

    private void checkForEquipEdit(String record) {
        // 标识编辑
        if (!ValidationUtil.isEmpty(record)) {
            Integer inUseTime = commonService.countEquipInUseTimesForEdit(record);
            if (inUseTime > 0) {
                throw new BadRequest("此设备在被其他业务引用，不可编辑！");
            }
        }
    }

    private Boolean checkEquipIsCanEdit(String record) {
        Integer inUseTime = commonService.countEquipInUseTimesForEdit(record);
        return inUseTime <= 0;
    }

    /**
     * 删除设备注册信息（批量删除）
     *
     * @param map records
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteByRecord(Map<String, Object> map) {
        Object recordList = map.get("recordList");
        List<String> records = new ArrayList<>();
        List<ESEquipmentCategoryDto> list = new ArrayList<>();
        // 删除ES数据
        if (recordList.toString().contains("[")) {
            for (String record : (List<String>) recordList) {
                records.add(record);
                ESEquipmentCategoryDto esEquipmentCategoryDto = new ESEquipmentCategoryDto();
                esEquipmentCategoryDto.setSEQUENCE_NBR(record);
                list.add(esEquipmentCategoryDto);
            }
        } else {
            records.add(recordList.toString());
            ESEquipmentCategoryDto esEquipmentCategoryDto = new ESEquipmentCategoryDto();
            esEquipmentCategoryDto.setSEQUENCE_NBR(recordList.toString());
            list.add(esEquipmentCategoryDto);
        }
        // 删除校验，被引用时不可删除。管道不做是否引用校验，直接删除已有管道(20251121注释，管道引用不能删除)
        //if(!PipelineEnum.PRESSURE_PIPELINE.getCode().equals(map.get("equList"))) {
            //this.checkForDelete(records);
        //}
        this.checkForDelete(records);
        if (CollUtil.isNotEmpty(records)) {
            // 删除涉及的19张表的数据
            superviseInfoMapper.deleteDataAll(records);
        }
        if (CollUtil.isNotEmpty(list)) {
            // 删除es中的数据
            esEquipmentCategory.deleteAll(list);
        }
        eventPublisher.publish(new DataRefreshEvent(this, records, DataRefreshEvent.DataType.equipment.name(), DataRefreshEvent.Operation.DELETE));
        return true;
    }

    /**
     * 删除校验，被引用时不可删除
     *
     * @param records 设备record集合
     */
    private void checkForDelete(List<String> records) {
        List<CountDto> useCounts = commonMapper.countEquipInUseTimesWithOutZFBatch(records);
        Map<String, Long> recordUseNumMap = useCounts.stream().collect(Collectors.toMap(CountDto::getKeyStr, CountDto::getLongValue));
        long sum = recordUseNumMap.values().stream().reduce(0L,Long::sum);
        if(sum > 0){
            String msg = getTipMsgString(recordUseNumMap, records);
            throw new BadRequest(msg);
        }
    }

    private String getTipMsgString(Map<String, Long> recordUseNumMap, List<String> records) {
        List<String> inUsedNames = new ArrayList<>();
        List<String> recordsInUsed = recordUseNumMap.entrySet().stream().filter(e->e.getValue() > 0).map(Map.Entry::getKey).collect(Collectors.toList());
        Map<String, String> recordNameMap = idxBizJgRegisterInfoService.list(new LambdaQueryWrapper<IdxBizJgRegisterInfo>()
                        .in(IdxBizJgRegisterInfo::getRecord, recordsInUsed)
                        .select(IdxBizJgRegisterInfo::getRecord, IdxBizJgRegisterInfo::getProductName))
                .stream().collect(Collectors.toMap(IdxBizJgRegisterInfo::getRecord, IdxBizJgRegisterInfo::getProductName));
        for (String record : recordsInUsed) {
            inUsedNames.add(recordNameMap.get(record));
        }
        if (records.size() > 1) {
            return String.format("选择的设备：%s，已经在业务办理中，不能删除，请先取消勾选！", String.join("、", inUsedNames));
        } else {
            return "设备已经在业务办理中，不能删除！";
        }
    }

    private Boolean checkEquipIsCanDelete(String record) {
        // 无使用（已作废也算未使用）则可删除
        return !commonService.checkEquipIsUsed(record);
    }

    /**
     * 查询设备注册信息详情
     *
     * @param record
     * @return
     */
    public Map<String, Map<String, Object>> getEquipmentRegisterByRecord(String record, String isCopy) {
        CompanyBo companyBo = getSelectedOrgInfo().getCompany();
        String companyLevel;
        if(companyBo.getLevel().equals(BaseController.COMPANY_TYPE_COMPANY)){
            companyLevel = companyBo.getLevel();
        } else {
            companyLevel = BaseController.COMPANY_TYPE_SUPERVISION;
        }
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        // 设备种类
        Map<String, Object> equIpClassMap = this.getEquIpClassMap(record, "");
        // 设备注册信息
        Map<String, Object> equipInfoMap = this.getEquipInfoMap(record, "");
        if (!ValidationUtil.isEmpty(equIpClassMap)) {
            equIpClassMap.put(DATA_SOURCE,equipInfoMap.get(DATA_SOURCE));
            resultMap.put(EQUIP_CLASS_FORM_ID, equIpClassMap);
        }
        equipInfoMap.put("companyLevel", companyLevel);
        equipInfoMap.put("type", equIpClassMap.get("type"));
        String formType = Optional.ofNullable(equIpClassMap.get("formType"))
                .map(Object::toString)
                .filter(s -> !s.trim().isEmpty())
                .orElse("add");
        equipInfoMap.put("formType", formType);
        // 设备参数
        if (equIpClassMap.containsKey(EQU_LIST) && !ValidationUtil.isEmpty(equIpClassMap.get(EQU_LIST).toString())) {
            Map<String, Object> equipParamsMap = this.getEquipParamsMap(record, "", equIpClassMap.get(EQU_LIST).toString());
            equipParamsMap.put(EQU_LIST, String.valueOf(equIpClassMap.get(EQU_LIST)));
            equipParamsMap.put(EQU_CATEGORY, String.valueOf(equIpClassMap.get(EQU_CATEGORY)));
            equipParamsMap.put(EQU_DEFINE, String.valueOf(equIpClassMap.get(EQU_DEFINE)));
            if (!ValidationUtil.isEmpty(equipParamsMap)) {
                // 给技术参数中添加设备种类，标记技术参数属于那个设备
                resultMap.put(EQUIP_PARAMS_FORM_ID, equipParamsMap);
            }
            equipInfoMap.put("identificationCode", equipParamsMap.get("VIN"));
        }

        if (!ValidationUtil.isEmpty(equipInfoMap)) {
            resultMap.put(EQUIP_INFO_FORM_ID, equipInfoMap);
        }
        if (ValidationUtil.isEmpty(equipInfoMap.get("useRegistrationCode"))) {
            equipInfoMap.put("hasUseReg", 0);
        } else {
            equipInfoMap.put("hasUseReg", 1);
        }
        // 处理复制设备信息
        if ("1".equals(isCopy)) {
            equipInfoMap.put("EQU_CODE_TYPE", "1");
            equipInfoMap.put("SUPERVISORY_CODE", null);
            equipInfoMap.put("CAR_NUMBER", null);
            equipInfoMap.put("useRegistrationCode", null);
            // 气瓶的部分信息赋空
            equipInfoMap.put("INFORMATION_SITUATION", null);
            equipInfoMap.put("INFORMATION_MANAGE_CODE", null);
            equipInfoMap.put("CYLINDER_STAMP_ATTACHMENT", null);
            equipInfoMap.put("identificationCode", null);
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> getDetailByRecord(String record) {
        Map<String, Object> resultMap = new HashMap<>();
        // 设备种类
        Map<String, Object> equIpClassMap = this.getEquIpClassMap(record, "");
        // 设备注册信息
        Map<String, Object> equipInfoMap = this.getEquipInfoMap(record, "");
        if (!ValidationUtil.isEmpty(equIpClassMap)) {
            resultMap.putAll(equIpClassMap);
        }
        if (!ValidationUtil.isEmpty(equipInfoMap)) {
            resultMap.putAll(equipInfoMap);
        }
        // 设备参数
        if (equIpClassMap.containsKey(EQU_LIST) && !ValidationUtil.isEmpty(equIpClassMap.get(EQU_LIST).toString())) {
            Map<String, Object> equipParamsMap = this.getEquipParamsMap(record, "", equIpClassMap.get(EQU_LIST).toString());

            if (!ValidationUtil.isEmpty(equipParamsMap)) {
                resultMap.putAll(equipParamsMap);
            }
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> getDetailFieldCamelCaseByRecord(String record) {
        Map<String, Object> resultMap = new HashMap<>();
        // 设备种类
        Map<String, Object> equIpClassMap = this.getEquIpClassMap(record, "CamelCase");
        // 设备注册信息
        Map<String, Object> equipInfoMap = this.getEquipInfoMap(record, "CamelCase");
        SuperviseInfo superviseInfo = superviseInfoMapper.selectOne(new LambdaQueryWrapper<SuperviseInfo>().eq(AbstractEquipBaseEntity::getRecord, record));
        if (!ValidationUtil.isEmpty(equIpClassMap)) {
            resultMap.putAll(equIpClassMap);
        }
        if (!ValidationUtil.isEmpty(equipInfoMap)) {
            resultMap.putAll(equipInfoMap);
        }
        // 设备参数
        if (equIpClassMap.containsKey("equList") && !ValidationUtil.isEmpty(equIpClassMap.get("equList").toString())) {
            Map<String, Object> equipParamsMap = this.getEquipParamsMap(record, "CamelCase", equIpClassMap.get("equList").toString());
            if (!ValidationUtil.isEmpty(equipParamsMap)) {
                resultMap.putAll(equipParamsMap);
            }
        }
        if (!ValidationUtil.isEmpty(superviseInfo)) {
            resultMap.put("orgBranchCode", superviseInfo.getOrgBranchCode());
            resultMap.put("orgBranchName", superviseInfo.getOrgBranchName());
        }
        resultMap.remove("instanceId");
        for (String field : jsonFields) {
            if (resultMap.get(field) != null && resultMap.get(field) instanceof String) {
                resultMap.put(field, JSON.parse(resultMap.get(field).toString()));
            }
        }
        return resultMap;
    }

    @Override
    public List<DictionarieValueModel> equCategoryListByCompanyType(ReginParams selectedOrgInfo, String equList, String businessScenarios, String dataSource, String type) {
        // 历史设备录入(有证-his,无证-black) 直接取所有的设备种类（equList）下的所有设备类别
        if ("his".equals(dataSource) || "black".equals(dataSource)) {
            // 历史数据导入设备类别限制  bug-21172
            if (!ObjectUtils.isEmpty(type) && "PL_DR".equals(type)) {
                if (EquipmentClassifityEnum.YLRQ.getCode().equals(equList)) {
                    return this.baseMapper.queryAllEquCategoriesUnderTheEquList(equList).stream()
                            .filter(x -> !"2200".equals(x.getDictDataKey()))
                            .collect(Collectors.toList());
                }
                if (EquipmentClassifityEnum.YLGD.getCode().equals(equList) && "his".equals(dataSource)) {
                    return this.baseMapper.queryAllEquCategoriesUnderTheEquList(equList).stream()
                            .filter(x -> "8300".equals(x.getDictDataKey()))
                            .collect(Collectors.toList());
                }
                if (EquipmentClassifityEnum.YLGD.getCode().equals(equList)) {
                    return this.baseMapper.queryAllEquCategoriesUnderTheEquList(equList).stream()
                            .filter(x -> !"8300".equals(x.getDictDataKey()))
                            .collect(Collectors.toList());
                }
            }
            return this.baseMapper.queryAllEquCategoriesUnderTheEquList(equList);
        }

        String companyType = selectedOrgInfo.getCompany().getCompanyType();
        String dictCodePrefix = getDictCodePrefix(companyType, equList);
        if (StringUtils.isEmpty(dictCodePrefix)) {
            return new ArrayList<>();
        }
        String dictCode = String.format("%s_%s", dictCodePrefix, equipAddDictCodeSuffix);
        List<DictionarieValueModel> result = FeignUtil.remoteCall(() -> Systemctl.dictionarieClient.dictValues(dictCode));
        if (CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType) || ValidationUtil.isEmpty(businessScenarios)) {
            return result;
        }
        // 初始化collect列表
        List<DictionarieValueModel> collect = new ArrayList<>();
        // 使用单位 包含 企业的使用单位类型 or 个人主体
        // 使用单位 && 业务场景businessScenarios为1（场景选择）&& 设备种类为2000（压力容器） =》 设备类别只保留固定式压力容器（2100）
        // 使用单位 && 业务场景businessScenarios为0（场景选择）&& 设备种类为2000（压力容器） =》 设备类别排除固定式压力容器（2100）
        boolean shouldInclude2100 = (CompanyTypeEnum.USE.getName().equals(companyType) || CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType)) && "1".equals(businessScenarios) && "2000".equals(equList);
        collect = result.stream()
                .filter(x -> shouldInclude2100 == "2100".equals(x.getDictDataKey()))
                .collect(Collectors.toList());

        return collect;
    }

    private String getDictCodePrefix(String companyType, String equList) {
        String dictCodePrefix = "";
        if ((companyType.contains(USE_TYPE_NAME) || companyType.contains(INDIVIDUAL_TYPE_NAME)) && !companyType.contains(MAINTENANCE_TYPE_NAME)) { // 使用单位
            dictCodePrefix = "USE";
        }
        if (companyType.contains(MAINTENANCE_TYPE_NAME) && !companyType.contains(USE_TYPE_NAME)) { // 安改维单位
            dictCodePrefix = "MAINTENANCE";
        }
        if (companyType.contains(MAINTENANCE_TYPE_NAME) && companyType.contains(USE_TYPE_NAME)) { // 所有单位
            dictCodePrefix = "ALL";
        }
        return StringUtils.isNotEmpty(equList) ? equList + "_" + dictCodePrefix : dictCodePrefix;
    }

    /**
     * 查询设备种类信息
     *
     * @param record    设备Id
     * @param fieldType 返回字段类型【CamelCase:驼峰命名，“”：纯大写加下划线】
     * @return
     */
    private Map<String, Object> getEquIpClassMap(String record, String fieldType) {
        Map<String, Object> objMap = new HashMap<>();
        // 注册登记
        IdxBizJgRegisterInfo registerInfo = this.getOne(new QueryWrapper<IdxBizJgRegisterInfo>().eq("RECORD", record));
        if (!ValidationUtil.isEmpty(registerInfo)) {
            String equList = registerInfo.getEquList();// 设备种类
            String equCategory = registerInfo.getEquCategory();// 设备类别
            String equDefine = registerInfo.getEquDefine();// 设备品种
            List<EquipmentCategory> categoryList0 = commonService.getEquipmentCategoryList(equList, null);
            List<EquipmentCategory> categoryList1 = commonService.getEquipmentCategoryList(equCategory, null);
            List<EquipmentCategory> categoryList2 = commonService.getEquipmentCategoryList(equDefine, null);
            Map<String, Object> registerInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                registerInfoMap = Bean.BeantoMap(registerInfo);
                registerInfoMap.put("registerinfoSeq", registerInfo.getSequenceNbr());
                registerInfoMap.put("sequenceNbr", registerInfo.getSequenceNbr());
                registerInfoMap.put("productPhoto", JSON.parseArray(registerInfo.getProductPhoto()));
                registerInfoMap.put("useRegistrationCode", registerInfo.getUseOrgCode());
                if (CollectionUtils.isNotEmpty(categoryList0)) {
                    registerInfoMap.put("equListDesc", categoryList0.get(0).getName());
                }
                if (CollectionUtils.isNotEmpty(categoryList1)) {
                    registerInfoMap.put("equCategoryDesc", categoryList1.get(0).getName());
                }
                if (CollectionUtils.isNotEmpty(categoryList2)) {
                    registerInfoMap.put("equDefineDesc", categoryList2.get(0).getName());
                }
            } else {
                String[] fields = {"PRODUCT_PHOTO"};
                registerInfoMap = convertCamelToUnderscore(registerInfo, fields);
                registerInfoMap.put("REGISTERINFO_SEQ", registerInfo.getSequenceNbr());
                registerInfoMap.put(SEQUENCE_NBR, registerInfo.getSequenceNbr());
                if (CollectionUtils.isNotEmpty(categoryList1)) {
                    registerInfoMap.put("EQU_CATEGORY_DESC", categoryList1.get(0).getName());
                }
                if (CollectionUtils.isNotEmpty(categoryList2)) {
                    registerInfoMap.put("EQU_DEFINE_DESC", categoryList2.get(0).getName());
                }
            }
            if (!registerInfoMap.isEmpty()) {
                Map<String, Object> filterMap = registerInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
            //处理前端返回特种气瓶(车用气瓶)和特种气瓶(非车用气瓶)
            String equDefineStr = (String) objMap.get("EQU_DEFINE");
            String whetherVehicleCylinderStr = (String)objMap.get("WHETHER_VEHICLE_CYLINDER");
            String equCategoryStr = (String)objMap.get("EQU_CATEGORY");
            if(CylinderTypeEnum.CYLINDER.getCode().equals(equCategoryStr)){
                if(SPECIAL_CYLINDER.getCode().equals(equDefineStr)){
                    if("1".equals(whetherVehicleCylinderStr)){
                        equDefineStr="23T0_1";
                    }else if("0".equals(whetherVehicleCylinderStr)){
                        equDefineStr="23T0_2";
                    }
                }
                objMap.put("EQU_DEFINE_DEAL",equDefineStr);
            }
        }
        return objMap;
    }

    /**
     * 查询设备基本信息
     *
     * @param record    设备Id
     * @param fieldType 返回字段类型【CamelCase:驼峰命名，“”：纯大写加下划线】
     * @return
     */
    private Map<String, Object> getEquipInfoMap(String record, String fieldType) {
        Map<String, Object> objMap = new HashMap<>();
        String province = "";
        String city = "";
        String county = "";
        String street = "";
        String fullAddress = "";

        // 设备问题信息（大屏二级页面使用）
        LambdaQueryWrapper<SafetyProblemTracing> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SafetyProblemTracing::getSourceId, record);
        lambdaQueryWrapper.orderByDesc(SafetyProblemTracing::getRecDate);
        List<SafetyProblemTracing> safetyProblemTracings = safetyProblemTracingMapper.selectList(lambdaQueryWrapper);
        if (!ObjectUtils.isEmpty(safetyProblemTracings)) {
            objMap.put("problemStatus", ProblemStatusEnum.getNameByDesc.get(safetyProblemTracings.get(0).getProblemStatus()));
            objMap.put("problemTime", safetyProblemTracings.get(0).getProblemTime());
        }

        // 使用信息
        IdxBizJgUseInfo useInfo = idxBizJgUseInfoService.getOneData(record);
        if (!ValidationUtil.isEmpty(useInfo)) {

            if (!ValidationUtil.isEmpty(useInfo.getProvince()) && !ValidationUtil.isEmpty(useInfo.getProvinceName())) {
                province = useInfo.getProvince() + "_" + useInfo.getProvinceName();
                fullAddress += useInfo.getProvinceName();
            }
            if (!ValidationUtil.isEmpty(useInfo.getCity()) && !ValidationUtil.isEmpty(useInfo.getCityName())) {
                city = useInfo.getCity() + "_" + useInfo.getCityName();
                fullAddress += useInfo.getCityName();
            }
            if (!ValidationUtil.isEmpty(useInfo.getCounty()) && !ValidationUtil.isEmpty(useInfo.getCountyName())) {
                county = useInfo.getCounty() + "_" + useInfo.getCountyName();
                fullAddress += useInfo.getCountyName();
            }
            if (!ValidationUtil.isEmpty(useInfo.getFactoryUseSiteStreet()) && !ValidationUtil.isEmpty(useInfo.getStreetName())) {
                street = useInfo.getFactoryUseSiteStreet() + "_" + useInfo.getStreetName();
                fullAddress += useInfo.getStreetName();
            }
            if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                fullAddress += useInfo.getAddress();
            }

            Map<String, Object> useInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                useInfoMap = Bean.BeantoMap(useInfo);
                if (!ValidationUtil.isEmpty(province)) {
                    useInfoMap.put("province", province);
                }
                if (!ValidationUtil.isEmpty(city)) {
                    useInfoMap.put("city", city);
                }
                if (!ValidationUtil.isEmpty(county)) {
                    useInfoMap.put("county", county);
                }
                if (!ValidationUtil.isEmpty(street)) {
                    useInfoMap.put("street", street);
                }
                if (!ValidationUtil.isEmpty(fullAddress)) {
                    useInfoMap.put("fullAddress", fullAddress);
                }
                useInfoMap.put("useinfoSeq", useInfo.getSequenceNbr());
                if (!ValidationUtil.isEmpty(useInfo.getLongitudeLatitude())) {
                    useInfoMap.put("longitudeLatitude", JSON.parseObject(useInfo.getLongitudeLatitude()));
                    useInfoMap.put("useLongitudeLatitude", JSON.parseObject(useInfo.getLongitudeLatitude()));
                }
                if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                    useInfoMap.put("useAddress", useInfo.getAddress());
                }

            } else {
                useInfoMap = convertCamelToUnderscore(useInfo, null);
                if (!ValidationUtil.isEmpty(province)) {
                    useInfoMap.put("PROVINCE", province);
                }
                if (!ValidationUtil.isEmpty(city)) {
                    useInfoMap.put("CITY", city);
                }
                if (!ValidationUtil.isEmpty(county)) {
                    useInfoMap.put("COUNTY", county);
                }
                if (!ValidationUtil.isEmpty(street)) {
                    useInfoMap.put("STREET", street);
                }
                if (!ValidationUtil.isEmpty(fullAddress)) {
                    useInfoMap.put("FULLADDRESS", fullAddress);
                }
                useInfoMap.put("USEINFO_SEQ", useInfo.getSequenceNbr());
                useInfoMap.put("USE_PLACE", useInfo.getUsePlace());
                if (!ValidationUtil.isEmpty(useInfo.getLongitudeLatitude())) {
                    useInfoMap.put("LONGITUDE_LATITUDE", JSON.parseObject(useInfo.getLongitudeLatitude()));
                    useInfoMap.put("USE_LONGITUDE_LATITUDE", JSON.parseObject(useInfo.getLongitudeLatitude()));
                }
                if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                    useInfoMap.put("USE_ADDRESS", useInfo.getAddress());
                    useInfoMap.put("FULL_ADDRESS", useInfo.getAddress());
                }
                // bug--22325 一码通过来的数据去掉【DATA_SOURCE】，保存设备时 【batchSubmitOrUpdate方法】 会对 DATA_SOURCE字段进行处理
                // 一码通数据："must": [
                //                 {
                //                     "term": {
                //                         "STATUS": "已认领"
                //                     }
                //                 }
                //             ],
                //             "must_not": [
                //                 {
                //                     "wildcard": {
                //                         "DATA_SOURCE.keyword": "jg*"
                //                     }
                //                 }
                //             ]
                boolean isYmtData = !String.valueOf(useInfoMap.get(DATA_SOURCE)).startsWith("jg");
                if (isYmtData) {
                    useInfoMap.put(DATA_SOURCE, "jg_his_ymt");// 将原先未处理为ymt的设备来源修复为jg_his_ymt
                }
            }
            if (!useInfoMap.isEmpty()) {
                Map<String, Object> filterMap = useInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }
        objMap.put(DATA_SOURCE_NAME, EquipSourceEnum.getDataSourceName(useInfo.getDataSource()));
        objMap.put(DATA_SOURCE, EquipSourceEnum.getDataSourceType(useInfo.getDataSource()));
        // 设计制造
        IdxBizJgDesignInfo designInfo = iIdxBizJgDesignInfoService.getOneData(record);
        if (!ValidationUtil.isEmpty(designInfo)) {
            Map<String, Object> designInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                designInfoMap = Bean.BeantoMap(designInfo);
                designInfoMap.put("designinfoSeq", designInfo.getSequenceNbr());
                designInfoMap.put("designDoc", JSON.parseArray(designInfo.getDesignDoc()));
                designInfoMap.put("designStandard", JSON.parseArray(designInfo.getDesignStandard()));
                if (!ObjectUtils.isEmpty(designInfoMap.get("otherAccessoriesDes"))) {
                    designInfoMap.put("otherAccessoriesDes", JSON.parse(String.valueOf(designInfoMap.get("otherAccessoriesDes"))));
                }
            } else {
                String[] fields = {"DESIGN_DOC", "DESIGN_STANDARD", "OTHER_ACCESSORIES_DES"};
                designInfoMap = convertCamelToUnderscore(designInfo, fields);
                designInfoMap.put("DESIGNINFO_SEQ", designInfo.getSequenceNbr());
            }
            if (!designInfoMap.isEmpty()) {
                Map<String, Object> filterMap = designInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }
        // 制造信息
        IdxBizJgFactoryInfo factoryInfo = iIdxBizJgFactoryInfoService.getOneData(record);
        if (!ValidationUtil.isEmpty(factoryInfo)) {
            Map<String, Object> factoryInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                factoryInfoMap = Bean.BeantoMap(factoryInfo);
                String imported = factoryInfo.getImported();
                if ("0".equals(imported)) {
                    factoryInfoMap.put("importedDesc", "否");
                } else if ("1".equals(imported)) {
                    factoryInfoMap.put("importedDesc", "是");
                }
                factoryInfoMap.put("factoryinfoSeq", factoryInfo.getSequenceNbr());
                factoryInfoMap.put("factoryStandard", JSON.parseArray(factoryInfo.getFactoryStandard()));
                factoryInfoMap.put("productQualityYieldProve", JSON.parseArray(factoryInfo.getProductQualityYieldProve()));
                factoryInfoMap.put("insUseMaintainExplain", JSON.parseArray(factoryInfo.getInsUseMaintainExplain()));
                factoryInfoMap.put("factSupervisionInspectionReport", JSON.parseArray(factoryInfo.getFactSupervisionInspectionReport()));
                factoryInfoMap.put("boilerEnergyEfficiencyCertificate", JSON.parseArray(factoryInfo.getBoilerEnergyEfficiencyCertificate()));
                if (!ObjectUtils.isEmpty(factoryInfoMap.get("otherAccessoriesFact"))) {
                    factoryInfoMap.put("otherAccessoriesFact", JSON.parse(String.valueOf(factoryInfoMap.get("otherAccessoriesFact"))));
                }
            } else {
                String[] fields = {"FACTORY_STANDARD", "PRODUCT_QUALITY_YIELD_PROVE", "INS_USE_MAINTAIN_EXPLAIN",
                        "OTHER_ACCESSORIES_FACT", "FACT_SUPERVISION_INSPECTION_REPORT", "BOILER_ENERGY_EFFICIENCY_CERTIFICATE"};
                factoryInfoMap = convertCamelToUnderscore(factoryInfo, fields);
                String imported = factoryInfo.getImported();
                if ("0".equals(imported)) {
                    factoryInfoMap.put("IMPORTED_DESC", "否");
                } else if ("1".equals(imported)) {
                    factoryInfoMap.put("IMPORTED_DESC", "是");
                }
                factoryInfoMap.put("FACTORYINFO_SEQ", factoryInfo.getSequenceNbr());
            }
            if (!factoryInfoMap.isEmpty()) {
                Map<String, Object> filterMap = factoryInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }

        // 注册登记
        IdxBizJgRegisterInfo registerInfo = this.getOne(new QueryWrapper<IdxBizJgRegisterInfo>().eq("RECORD", record));
        if (!ValidationUtil.isEmpty(registerInfo)) {
            String equCategory = registerInfo.getEquCategory();// 设备类别
            String equDefine = registerInfo.getEquDefine();// 设备品种
            List<EquipmentCategory> categoryList1 = commonService.getEquipmentCategoryList(equCategory, null);
            List<EquipmentCategory> categoryList2 = commonService.getEquipmentCategoryList(equDefine, null);
            Map<String, Object> registerInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                registerInfoMap = Bean.BeantoMap(registerInfo);
                registerInfoMap.put("registerinfoSeq", registerInfo.getSequenceNbr());
                registerInfoMap.put("sequenceNbr", registerInfo.getSequenceNbr());
                registerInfoMap.put("productPhoto", JSON.parseArray(registerInfo.getProductPhoto()));
                if (CollectionUtils.isNotEmpty(categoryList1)) {
                    registerInfoMap.put("equCategoryDesc", categoryList1.get(0).getName());
                }
                if (CollectionUtils.isNotEmpty(categoryList2)) {
                    registerInfoMap.put("equDefineDesc", categoryList2.get(0).getName());
                }
                if (!ObjectUtils.isEmpty(registerInfoMap.get("otherAccessoriesReg"))) {
                    registerInfoMap.put("otherAccessoriesReg", JSON.parse(String.valueOf(registerInfoMap.get("otherAccessoriesReg"))));
                }
            } else {
                String[] fields = {"PRODUCT_PHOTO", "OTHER_ACCESSORIES_REG"};
                registerInfoMap = convertCamelToUnderscore(registerInfo, fields);
                registerInfoMap.put("REGISTERINFO_SEQ", registerInfo.getSequenceNbr());
                registerInfoMap.put(SEQUENCE_NBR, registerInfo.getSequenceNbr());
                if (CollectionUtils.isNotEmpty(categoryList1)) {
                    registerInfoMap.put("EQU_CATEGORY_DESC", categoryList1.get(0).getName());
                }
                if (CollectionUtils.isNotEmpty(categoryList2)) {
                    registerInfoMap.put("EQU_DEFINE_DESC", categoryList2.get(0).getName());
                }
            }
            if (!registerInfoMap.isEmpty()) {
                Map<String, Object> filterMap = registerInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
            objMap.put("useRegistrationCode", registerInfo.getUseOrgCode());
        }
        String equListStr = (String) objMap.get("EQU_LIST");
        String equCategoryStr = (String) objMap.get("EQU_CATEGORY");

        // 仅做施工告知的设备查询施工信息。厂车=5000、流动式起重机=4400、气瓶=2300不查询施工信息
        if (!(EquipmentClassifityEnum.CC.getCode().equals(equListStr) || "4400".equals(equCategoryStr) || CylinderTypeEnum.CYLINDER.getCode().equals(equCategoryStr))) {
            // 施工信息 【一对多，暂时只取最新一条数据】
            IdxBizJgConstructionInfo constructionInfo = iIdxBizJgConstructionInfoService.queryNewestDetailByRecord(record);
            if (!ValidationUtil.isEmpty(constructionInfo)) {
                Map<String, Object> constructionInfoMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    constructionInfoMap = Bean.BeantoMap(constructionInfo);
                    constructionInfoMap.put("constructioninfoSeq", constructionInfo.getSequenceNbr());
                } else {
                    constructionInfoMap = convertCamelToUnderscore(constructionInfo, null);
                    constructionInfoMap.put("CONSTRUCTIONINFO_SEQ", constructionInfo.getSequenceNbr());
                }
                if (!constructionInfoMap.isEmpty()) {
                    Map<String, Object> filterMap = constructionInfoMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
        }

        // 仅电梯查询维保信息
        if (EquipmentClassifityEnum.DT.getCode().equals(equListStr)) {
            // 维保备案【一对多，暂时只取最新一条数据】
            IdxBizJgMaintenanceRecordInfo maintenanceRecordInfo = iIdxBizJgMaintenanceRecordInfoService.queryNewestDetailByRecord(record);
            if (!ValidationUtil.isEmpty(maintenanceRecordInfo)) {
                Map<String, Object> maintenanceRecordInfoMap;
                if (fieldType != null && !fieldType.isEmpty()) {
                    maintenanceRecordInfoMap = Bean.BeantoMap(maintenanceRecordInfo);
                    maintenanceRecordInfoMap.put("repairInform", JSON.parse(maintenanceRecordInfo.getRepairInform()));
                    maintenanceRecordInfoMap.put("maintenancerecordinfoSeq", maintenanceRecordInfo.getSequenceNbr());
                } else {
                    String[] toArrayFields = {"REPAIR_INFORM"};
                    maintenanceRecordInfoMap = convertCamelToUnderscore(maintenanceRecordInfo, toArrayFields);
                    maintenanceRecordInfoMap.put("MAINTENANCERECORDINFO_SEQ", maintenanceRecordInfo.getSequenceNbr());
                }
                if (!maintenanceRecordInfoMap.isEmpty()) {
                    Map<String, Object> filterMap = maintenanceRecordInfoMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
        }

        // 监督管理
        IdxBizJgSupervisionInfo supervisionInfo = iIdxBizJgSupervisionInfoService.getOneData(record);
        if (!ValidationUtil.isEmpty(supervisionInfo)) {
            Map<String, Object> supervisionInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                supervisionInfoMap = Bean.BeantoMap(supervisionInfo);
                supervisionInfoMap.put("supervisioninfoSeq", supervisionInfo.getSequenceNbr());
            } else {
                supervisionInfoMap = convertCamelToUnderscore(supervisionInfo, null);
                supervisionInfoMap.put("SUPERVISIONINFO_SEQ", supervisionInfo.getSequenceNbr());
            }
            if (!supervisionInfoMap.isEmpty()) {
                Map<String, Object> filterMap = supervisionInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }
        // 其他信息
        IdxBizJgOtherInfo otherInfo = iIdxBizJgOtherInfoService.getOneData(record);
        if (!ValidationUtil.isEmpty(otherInfo)) {
            Map<String, Object> otherInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                otherInfoMap = Bean.BeantoMap(otherInfo);
                otherInfoMap.put("otherinfoSeq", otherInfo.getSequenceNbr());
                otherInfoMap.put("cylinderStampAttachment", JSON.parse(otherInfo.getCylinderStampAttachment()));
            } else {
                otherInfoMap = convertCamelToUnderscore(otherInfo, null);
                otherInfoMap.put("OTHERINFO_SEQ", otherInfo.getSequenceNbr());
                otherInfoMap.put("CYLINDER_STAMP_ATTACHMENT", JSON.parse(otherInfo.getCylinderStampAttachment()));
            }
            if (!otherInfoMap.isEmpty()) {
                Map<String, Object> filterMap = otherInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }
        // 检验检测【一对多，暂时只取最新一条数据】
        IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = iIdxBizJgInspectionDetectionInfoService.queryNewestDetailByRecord(record);
        if (!ValidationUtil.isEmpty(inspectionDetectionInfo)) {
            Map<String, Object> inspectionDetectionInfoMap;
            if (!ValidationUtil.isEmpty(fieldType)) {
                inspectionDetectionInfoMap = Bean.BeantoMap(inspectionDetectionInfo);
                inspectionDetectionInfoMap.put("inspectiondetectioninfoSeq", inspectionDetectionInfo.getSequenceNbr());
                inspectionDetectionInfoMap.put("inspectReport", JSON.parseArray(inspectionDetectionInfo.getInspectReport()));
            } else {
                String[] fields = {"INSPECT_REPORT"};
                inspectionDetectionInfoMap = convertCamelToUnderscore(inspectionDetectionInfo, fields);
                inspectionDetectionInfoMap.put("INSPECTIONDETECTIONINFO_SEQ", inspectionDetectionInfo.getSequenceNbr());
            }
            if (!inspectionDetectionInfoMap.isEmpty()) {
                Map<String, Object> filterMap = inspectionDetectionInfoMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
        }

        objMap.put("completedBusinessTypes", judgeTheBusinessAccordingByRecord(record, objMap));
        // 账号类型（用于车用气瓶流程页面-》监管审核-》打开设备详情 时隐藏保存按钮）
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        objMap.put("accountType", reginParams.getCompany().getCompanyType());
        //处理前端返回特种气瓶(车用气瓶)和特种气瓶(非车用气瓶)
        String equDefineStr = (String) objMap.get("EQU_DEFINE");
        String whetherVehicleCylinderStr = (String)objMap.get("WHETHER_VEHICLE_CYLINDER");

        if(CylinderTypeEnum.CYLINDER.getCode().equals(equCategoryStr)){
            if(SPECIAL_CYLINDER.getCode().equals(equDefineStr)){
                if("1".equals(whetherVehicleCylinderStr)){
                    equDefineStr="23T0_1";
                }else if("0".equals(whetherVehicleCylinderStr)){
                    equDefineStr="23T0_2";
                }
            }
            objMap.put("EQU_DEFINE_DEAL",equDefineStr);
        }
        return objMap;
    }

    /**
     * 根据record判断设备完成了哪些业务（安装告知/维保备案/使用登记）
     *
     * @return
     */
    public String judgeTheBusinessAccordingByRecord(String record, Map<String, Object> objMap) {
        String equListStr = (String) objMap.get("EQU_LIST");
        String equCategoryStr = (String) objMap.get("EQU_CATEGORY");
        String useRegistrationCode = (String) objMap.get("useRegistrationCode");

        String business = "";
        // 仅做施工告知的设备查询施工信息。厂车=5000、流动式起重机=4400、气瓶=2300不查询施工信息
        if (!(EquipmentClassifityEnum.CC.getCode().equals(equListStr) || "4400".equals(equCategoryStr) || CylinderTypeEnum.CYLINDER.getCode().equals(equCategoryStr))) {
            // TODO 兼容历史有证、无证数据，根本原因idx_biz_jg_construction_info施工信息字段不全，字段补全后还是要查idx_biz_jg_construction_info，否则改造告知
            // 安装信息，优先查询安装告知信息没有再查设备的施工信息表
            // 安装告知信息表查询，做过安装告知的施工信息优先
            Map<String, Object> constructInfo = jgUseRegistrationMapper.getInstallDetail(record);
            if(constructInfo == null){
                // 施工信息表查询
                constructInfo = jgUseRegistrationMapper.getiInstallDetailByIdx(record);
            }
            if (!ObjectUtils.isEmpty(constructInfo)) {
                business = business + ",安装告知";
                objMap.putAll(constructInfo);
                objMap.put("insOtherAccessories", JSON.parse(Optional.ofNullable(constructInfo.get("insOtherAccessories")).orElse("").toString()));
                objMap.put("installProxyStatementAttachment", JSON.parse(Optional.ofNullable(constructInfo.get("installProxyStatementAttachment")).orElse("").toString()));
                objMap.put("installContractAttachment", JSON.parse(Optional.ofNullable(constructInfo.get("installContractAttachment")).orElse("").toString()));
            }
        }

        // 仅电梯查询维保信息
        if (EquipmentClassifityEnum.DT.getCode().equals(equListStr)) {
            // 维保备案
            Map<String, Object> maintenanceDetail = jgUseRegistrationMapper.getMaintenanceDetailByIdx(record);
            if (!ObjectUtils.isEmpty(maintenanceDetail)) {
                business = business + ",维保合同备案";
                objMap.putAll(maintenanceDetail);
                objMap.put("maintenanceContract", JSON.parse(Optional.ofNullable(maintenanceDetail.get("maintenanceContract")).orElse("").toString()));
                objMap.put("maintOtherAccessories", JSON.parse(Optional.ofNullable(maintenanceDetail.get("maintOtherAccessories")).orElse("").toString()));
            }
        }
        // 使用登记
//        Map<String, Object> useRegistrationDetail = jgUseRegistrationMapper.getUseRegistrationDetail(record);
        // 查询使用登记
        StringBuilder businessBuilder = new StringBuilder(business);
        if (!ObjectUtils.isEmpty(useRegistrationCode)) {
            List<JgUseRegistrationManage> regs = jgUseRegistrationManageService.lambdaQuery()
                    .select(JgUseRegistrationManage::getSequenceNbr,
                            JgUseRegistrationManage::getReceiveOrgName,
                            JgUseRegistrationManage::getReceiveCompanyCode)
                    .eq(JgUseRegistrationManage::getUseRegistrationCode, useRegistrationCode)
                    .eq(JgUseRegistrationManage::getIsDelete, false)
                    .eq(JgUseRegistrationManage::getCertificateStatus, YIDENGJI.getName())
                    .list();
            if (regs.size() > 1) {
                throw new BadRequest("使用登记重复"+ useRegistrationCode);
            }

            if (!regs.isEmpty()) {
                JgUseRegistrationManage jgUseRegistrationManage = regs.get(0);
                businessBuilder.append(",使用登记");
                objMap.put("receiveCompanyCode", jgUseRegistrationManage.getReceiveCompanyCode());
            }
        }

        return businessBuilder.toString();
    }

    /**
     * 查询设备技术参数
     *
     * @param record    设备Id
     * @param fieldType 返回字段类型【CamelCase:驼峰命名，“”：纯大写加下划线】
     * @return
     */
    public Map<String, Object> getEquipParamsMap(String record, String fieldType, String equipCode) {

        Map<String, Object> objMap = new HashMap<>();
        if (EquipmentClassifityEnum.DT.getCode().equals(equipCode)) {
            // 电梯
            IdxBizJgTechParamsElevator elevator = iIdxBizJgTechParamsElevatorService.getOneData(record);
            if (!ValidationUtil.isEmpty(elevator)) {
                Map<String, Object> elevatorMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    elevatorMap = Bean.BeantoMap(elevator);
                    elevatorMap.put("elevatorSeq", elevator.getSequenceNbr());
                    elevatorMap.put("explosionproofSignComplete", JSON.parseArray(elevator.getExplosionproofSignComplete()));
                } else {
                    String[] fields = {"EXPLOSIONPROOF_SIGN_COMPLETE"};
                    elevatorMap = convertCamelToUnderscore(elevator, fields);
                    elevatorMap.put("ELEVATOR_SEQ", elevator.getSequenceNbr());
                }
                if (!elevatorMap.isEmpty()) {
                    Map<String, Object> filterMap = elevatorMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
        } else if (EquipmentClassifityEnum.CC.getCode().equals(equipCode)) {
            // 厂车
            IdxBizJgTechParamsVehicle vehicle = iIdxBizJgTechParamsVehicleService.getOneData(record);
            if (!ValidationUtil.isEmpty(vehicle)) {
                Map<String, Object> vehicleMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    vehicleMap = Bean.BeantoMap(vehicle);
                    vehicleMap.put("vehicleSeq", vehicle.getSequenceNbr());
                } else {
                    vehicleMap = convertCamelToUnderscore(vehicle, null);
                    vehicleMap.put("VEHICLE_SEQ", vehicle.getSequenceNbr());
                }
                if (!vehicleMap.isEmpty()) {
                    Map<String, Object> filterMap = vehicleMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
            // 主要零部件
            List<Map<String, Object>> mainPartsMapsByRecord = this.getMainPartsMapsByRecord(record, fieldType);
            objMap.put("subForm_sey164b51a", mainPartsMapsByRecord);
            objMap.put("subForm_tef7yf5fbr", mainPartsMapsByRecord);
        } else if (EquipmentClassifityEnum.KYSD.getCode().equals(equipCode)) {
            // 索道
            IdxBizJgTechParamsRopeway ropeway = iIdxBizJgTechParamsRopewayService.getOneData(record);
            if (!ValidationUtil.isEmpty(ropeway)) {
                Map<String, Object> ropewayMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    ropewayMap = Bean.BeantoMap(ropeway);
                    ropewayMap.put("ropewaySeq", ropeway.getSequenceNbr());
                } else {
                    ropewayMap = convertCamelToUnderscore(ropeway, null);
                    ropewayMap.put("ROPEWAY_SEQ", ropeway.getSequenceNbr());
                }
                if (!ropewayMap.isEmpty()) {
                    Map<String, Object> filterMap = ropewayMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
            // 主要零部件
            List<Map<String, Object>> mainPartsMapsByRecord = this.getMainPartsMapsByRecord(record, fieldType);
            objMap.put("subForm_5fi0jewuyh", mainPartsMapsByRecord);
        } else if (EquipmentClassifityEnum.YLSS.getCode().equals(equipCode)) {
            // 游乐设施
            IdxBizJgTechParamsRides rides = iIdxBizJgTechParamsRidesService.getOneData(record);
            if (!ValidationUtil.isEmpty(rides)) {
                Map<String, Object> ridesMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    ridesMap = Bean.BeantoMap(rides);
                    ridesMap.put("ridesSeq", rides.getSequenceNbr());
                } else {
                    ridesMap = convertCamelToUnderscore(rides, null);
                    ridesMap.put("RIDES_SEQ", rides.getSequenceNbr());
                }
                if (!ridesMap.isEmpty()) {
                    Map<String, Object> filterMap = ridesMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }

        } else if (EquipmentClassifityEnum.GL.getCode().equals(equipCode)) {
            // 锅炉
            IdxBizJgTechParamsBoiler boiler = iIdxBizJgTechParamsBoilerService.getOneData(record);
            if (!ValidationUtil.isEmpty(boiler)) {
                Map<String, Object> boilerMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    boilerMap = Bean.BeantoMap(boiler);
                    boilerMap.put("boilerSeq", boiler.getSequenceNbr());
                } else {
                    boilerMap = convertCamelToUnderscore(boiler, null);
                    boilerMap.put("BOILER_SEQ", boiler.getSequenceNbr());
                }
                if (!boilerMap.isEmpty()) {
                    Map<String, Object> filterMap = boilerMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
            // 安全附件
            List<Map<String, Object>> protectionDevicesMapsByRecord = this.getProtectionDevicesMapsByRecord(record, fieldType);
            objMap.put("subForm_1hh88r4m69", protectionDevicesMapsByRecord);
        } else if (EquipmentClassifityEnum.YLRQ.getCode().equals(equipCode)) {
            // 压力容器
            IdxBizJgTechParamsVessel vessel = iIdxBizJgTechParamsVesselService.getOneData(record);
            if (!ValidationUtil.isEmpty(vessel)) {
                Map<String, Object> vesselMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    vesselMap = Bean.BeantoMap(vessel);
                    vesselMap.put("vesselSeq", vessel.getSequenceNbr());
                } else {
                    vesselMap = convertCamelToUnderscore(vessel, null);
                    vesselMap.put("VESSEL_SEQ", vessel.getSequenceNbr());
                }
                if (!vesselMap.isEmpty()) {
                    Map<String, Object> filterMap = vesselMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }
            // 主要零部件和安全附件
            List<Map<String, Object>> mainPartsMapsByRecord = this.getMainPartsMapsByRecord(record, fieldType);
            List<Map<String, Object>> protectionDevicesMapsByRecord = this.getProtectionDevicesMapsByRecord(record, fieldType);
            objMap.put("subForm_fie04854f2", mainPartsMapsByRecord);
            objMap.put("subForm_d4xdzhsgdj", protectionDevicesMapsByRecord);
        } else if (EquipmentClassifityEnum.YLGD.getCode().equals(equipCode)) {
            // 压力管道
            IdxBizJgTechParamsPipeline pipeline = iIdxBizJgTechParamsPipelineService.getOneData(record);
            if (!ValidationUtil.isEmpty(pipeline)) {
                Map<String, Object> pipelineMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    pipelineMap = Bean.BeantoMap(pipeline);
                    pipelineMap.put("pipelineSeq", pipeline.getSequenceNbr());
                } else {
                    pipelineMap = convertCamelToUnderscore(pipeline, null);
                    pipelineMap.put("PIPELINE_SEQ", pipeline.getSequenceNbr());
                    pipelineMap.put("STARTE_POSITION", JSONObject.parseObject(pipeline.getStartePosition()));
                }
                Map<String, Object> filterMap = pipelineMap.entrySet()
                        .stream()
                        .filter(e -> e.getValue() != null && e.getValue() != "")
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                objMap.putAll(filterMap);
            }
            // 主要零部件
            List<Map<String, Object>> mainPartsMapsByRecord = this.getMainPartsMapsByRecord(record, fieldType);
            objMap.put("subForm_9n7nu55z8r", mainPartsMapsByRecord);
        } else if (EquipmentClassifityEnum.QZJX.getCode().equals(equipCode)) {
            // 起重机械
            IdxBizJgTechParamsLifting lifting = iIdxBizJgTechParamsLiftingService.getOneData(record);
            if (!ValidationUtil.isEmpty(lifting)) {
                Map<String, Object> liftingMap;
                if (!ValidationUtil.isEmpty(fieldType)) {
                    liftingMap = Bean.BeantoMap(lifting);
                    liftingMap.put("liftingSeq", lifting.getSequenceNbr());
                } else {
                    String[] fields = {"EXPLOSIONPROOF_SIGN_COMPLETE"};
                    liftingMap = convertCamelToUnderscore(lifting, fields);
                    liftingMap.put("LIFTING_SEQ", lifting.getSequenceNbr());
                }
                if (!liftingMap.isEmpty()) {
                    Map<String, Object> filterMap = liftingMap.entrySet()
                            .stream()
                            .filter(e -> e.getValue() != null && e.getValue() != "")
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    objMap.putAll(filterMap);
                }
            }

            // 主要零部件和安全附件
            List<Map<String, Object>> mainPartsMapsByRecord = this.getMainPartsMapsByRecord(record, fieldType);
            List<Map<String, Object>> protectionDevicesMapsByRecord = this.getProtectionDevicesMapsByRecord(record, fieldType);
            objMap.put("subForm_bqirdyvztt", mainPartsMapsByRecord);
            objMap.put("subForm_29yy3pdzhl", protectionDevicesMapsByRecord);
            objMap.put("subForm_h5h4x0zhur", protectionDevicesMapsByRecord);

        }

        return objMap;
    }

    /**
     * 查询指定设备的主要零部件【一对多，查出多条数据】
     *
     * @param record
     * @param fieldType
     * @return
     */
    private List<Map<String, Object>> getMainPartsMapsByRecord(String record, String fieldType) {
        List<Map<String, Object>> resultListMap = new ArrayList<>();
        List<IdxBizJgMainParts> mainParts = iIdxBizJgMainPartsService.queryListByRecord(record);
        if (!ValidationUtil.isEmpty(mainParts)) {
            if (!ValidationUtil.isEmpty(fieldType)) {
                for (IdxBizJgMainParts mainPart : mainParts) {
                    Map<String, Object> mainPartsMap = null;
                    mainPartsMap = Bean.BeantoMap(mainPart);
                    mainPartsMap.put("mainpartsSeq", mainPart.getSequenceNbr());
                    resultListMap.add(mainPartsMap);
                }
            } else {
                for (IdxBizJgMainParts mainPart : mainParts) {
                    Map<String, Object> mainPartsMap = null;
                    mainPartsMap = convertCamelToUnderscore(mainPart, null);
                    mainPartsMap.put("MAINPARTS_SEQ", mainPart.getSequenceNbr());
                    resultListMap.add(mainPartsMap);
                }
            }
        }
        return resultListMap;
    }

//    private void setRepeatUsedCheckFilterByType(BoolQueryBuilder boolMust, String companyCode, String queryType) {
//        if ("AZ".equals(queryType)) {// 安装告知
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "installNotice");
//        } else if ("GZ_GZ".equals(queryType)) {// 改造告知
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "renovationNoticeNew");
//        } else if ("GZ_WX".equals(queryType)) {// 维修告知
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "maintainInfo");
//        } else if ("GZ_YZ".equals(queryType)) {// 移装告知
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "transferNotice");
//        } else if ("SY".equals(queryType)) {// 使用登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "useRegistration");
//        } else if ("DJ_GZ".equals(queryType)) {// 改造变更登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "changeRegistration");
//        } else if ("DJ_YZ".equals(queryType)) {// 移装变更登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "changeRegistrationTransfer");
//        } else if ("DJ_DW".equals(queryType)) {// 单位变更登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "unitChange");
//        } else if ("DJ_GM".equals(queryType)) {// 更名变更登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "changeName");
//        } else if ("BF_YZ".equals(queryType)) {// 注销
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "");
//        } else if ("BF_ZX".equals(queryType)) {// 报废
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "");
//        } else if ("SB_QY".equals(queryType)) {// 启用
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "");
//        } else if ("SB_TY".equals(queryType)) {// 停用
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "");
//        } else if ("WB_BA".equals(queryType)) {// 维保备案
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "maintenanceFiling");
//        } else if ("SB_YJ".equals(queryType)) {// 设备移交
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "equipmentHandover");
//        } else if ("QP_BG".equals(queryType)) {// 车用气瓶变更
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "vehicleGasCylinderChange");
//        } else if ("QP_DJ".equals(queryType)) {// 车用气瓶登记
//            this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "vehicleInformation");
//        }
//    }

    /**
     * 查询指定设备的安全附件【一对多，查出多条数据】
     *
     * @param record
     * @param fieldType
     * @return
     */
    private List<Map<String, Object>> getProtectionDevicesMapsByRecord(String record, String fieldType) {
        List<Map<String, Object>> resultListMap = new ArrayList<>();
        List<IdxBizJgProtectionDevices> protectionDevices = iIdxBizJgProtectionDevicesService.queryListByRecord(record);
        if (!ValidationUtil.isEmpty(protectionDevices)) {
            if (!ValidationUtil.isEmpty(fieldType)) {
                for (IdxBizJgProtectionDevices protectionDevice : protectionDevices) {
                    Map<String, Object> protectionDeviceMap = null;
                    protectionDeviceMap = Bean.BeantoMap(protectionDevice);
                    protectionDeviceMap.put("protectiondevicesSeq", protectionDevice.getSequenceNbr());
                    resultListMap.add(protectionDeviceMap);
                }
            } else {
                for (IdxBizJgProtectionDevices protectionDevice : protectionDevices) {
                    Map<String, Object> protectionDeviceMap = null;
                    protectionDeviceMap = convertCamelToUnderscore(protectionDevice, null);
                    protectionDeviceMap.put("PROTECTIONDEVICES_SEQ", protectionDevice.getSequenceNbr());
                    resultListMap.add(protectionDeviceMap);
                }
            }
        }
        return resultListMap;
    }

    @Override
    public Page<JSONObject> queryHisNoCertEquipPage(JSONObject map) {
        if (map.containsKey("flag") && !map.containsKey("USE_UNIT_CREDIT_CODE")) {
            return new Page<>();
        }

        Integer pageNumber = ObjectUtils.isEmpty(map.getInteger("number")) ? 1 : map.getInteger("number");
        Integer size = ObjectUtils.isEmpty(map.getInteger("size")) ? 20 : map.getInteger("size");

        Page<JSONObject> result = new Page<>(pageNumber, size);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        // 获取当前登录人单位类型
        JSONObject company = getCompanyType();
        if (ValidationUtil.isEmpty(company)) {
            result.setRecords(new ArrayList<>());
            result.setTotal(0);
            return result;
        }
        String companyCode = company.getString("companyCode").contains("_") ?
                company.getString("companyCode").split("_")[1] : company.getString("companyCode");
        String type = company.getString("companyType");

        // 根据当前登录人查询
        if (!ValidationUtil.isEmpty(map.get(EQUSTATE))) {
            map.put(EQUSTATE, EquimentEnum.getCode.get(map.get(EQUSTATE).toString()).toString());
        }

        // 根据当前登录用户类型及管辖机构筛选条件添加对应参数
        if (ObjectUtils.isEmpty(map.getString(SEQUENCE_NBR)) && ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
            if (!ValidationUtil.isEmpty(type) && type.contains("使用单位")) {
                if (ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE"))) {
                    map.put("USE_UNIT_CREDIT_CODE", companyCode);
                }
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("安装改造维修单位")) {
                map.put("USC_UNIT_CREDIT_CODE", companyCode);
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("个人主体")) {
                map.put("USE_UNIT_CREDIT_CODE", companyCode);
            }
        }

        // 默认条件【STATUS==="" || null】
        BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
        meBuilder.should(QueryBuilders.matchQuery("STATUS", "已认领"));
        meBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("STATUS")));
        meBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("STATUS", "")));
        meBuilder.minimumShouldMatch(1);
        boolMust.must(meBuilder);

        // 查询下次检验日期大于当前天的设备
        //long currentDayTime = DateUtil.parse(DateUtil.now(), "yyy-MM-dd").getTime();
        //boolMust.must(QueryBuilders.rangeQuery("NEXT_INSPECT_DATE").gte(currentDayTime));

        // DATA_SOURCE 为“jg”开头的数据（从监管新加或复制的设备）
        // 20240314 提出的监管业务不要让企业用户选到之前一码通认领或补录的设备，让从监管业务中去新增
        BoolQueryBuilder dBuilder = QueryBuilders.boolQuery();
        String queryType = map.getString("QUERY_TYPE");
        if (map.containsKey("DATA_SOURCE") && !ObjectUtils.isEmpty(map.get("DATA_SOURCE"))) {
            String dataSource = map.getString("DATA_SOURCE");
            if ("jg_his_black".equals(dataSource)) {
                // 只查历史，前缀为 jg_his
                dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his_black"));
            }
        }
        boolMust.must(dBuilder);

        if (!ObjectUtils.isEmpty(map.getString(IS_INTO_MANAGEMENT))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(IS_INTO_MANAGEMENT));
            pBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, param));
            boolMust.must(pBuilder);
        }

        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(EQU_CATEGORY));
            pBuilder.must(QueryBuilders.matchPhraseQuery(EQU_CATEGORY, "*" + param + "*"));
            boolMust.must(pBuilder);

        }

        // 使用单位 //安装改造维修单位
        if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) && !ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
            BoolQueryBuilder ubuilder = QueryBuilders.boolQuery();
            String useCode = QueryParser.escape(map.getString("USE_UNIT_CREDIT_CODE"));
            useCode = useCode.contains("_") ? useCode.split("_")[0] : useCode;
            ubuilder.must(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", useCode));

            String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
            ubuilder.must(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + QueryParser.escape(uscCode) + "*"));
            boolMust.must(ubuilder);
        } else {
            if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) || !ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uucc = !ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) ? map.getString("USE_UNIT_CREDIT_CODE") : map.getString("useUnitCreditCode");
                String param = QueryParser.escape(uucc);
                param = param.contains("_") ? param.split("_")[0] : param;
                uuccBuilder.must(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", param));
                boolMust.must(uuccBuilder);
            }
            if (!ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
                uuccBuilder.must(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + QueryParser.escape(uscCode) + "*"));
                boolMust.must(uuccBuilder);
            }
        }

        // 设备种类编码
        if (!ObjectUtils.isEmpty(map.getString("EQU_LIST_CODE"))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("EQU_LIST_CODE"));
            elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_LIST_CODE", test));
            boolMust.must(elcBuilder);
        }
        // 设备类别编码
        if (!ObjectUtils.isEmpty(map.getString("EQU_DEFINE_CODE"))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("EQU_DEFINE_CODE"));
            elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_DEFINE_CODE", test));
            boolMust.must(elcBuilder);
        }
        // 设备种类名称
        if (!ObjectUtils.isEmpty(map.getString(EQU_LIST))) {
            BoolQueryBuilder elBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_LIST));
            elBuilder.must(QueryBuilders.matchPhraseQuery(EQU_LIST, "*" + test + "*"));
            boolMust.must(elBuilder);
        }

        // 设备类别
        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CATEGORY_CODE));
            pBuilder.must(QueryBuilders.termQuery(EQU_CATEGORY_CODE, test));
            boolMust.must(pBuilder);
        }

        // 设备代码模糊查询
        if (!ObjectUtils.isEmpty(map.getString(EQU_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CODE));
            pBuilder.must(QueryBuilders.wildcardQuery(EQU_CODE, "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 单位内部编号模糊查询
        if (!ObjectUtils.isEmpty(map.getString("USE_INNER_CODE"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("USE_INNER_CODE"));
            pBuilder.must(QueryBuilders.wildcardQuery("USE_INNER_CODE", "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 出厂编号/产品编码模糊查询
        if (!ObjectUtils.isEmpty(map.getString(FACTORY_NUM))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(FACTORY_NUM));
            pBuilder.must(QueryBuilders.wildcardQuery(FACTORY_NUM, "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 制造单位（生产单位）名称模糊查询
        if (!ObjectUtils.isEmpty(map.getString("PRODUCE_UNIT_NAME"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("PRODUCE_UNIT_NAME"));
            pBuilder.must(QueryBuilders.wildcardQuery("PRODUCE_UNIT_NAME", "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 模糊查询
        if (!ObjectUtils.isEmpty(map.getString(USE_PLACE_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(USE_PLACE_CODE));
            pBuilder.must(QueryBuilders.wildcardQuery(USE_PLACE_CODE, "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 工程装置名称模糊查询
        if (!ObjectUtils.isEmpty(map.getString(PROJECT_CONTRAPTION))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            pBuilder.must(QueryBuilders.termsQuery("PROJECT_CONTRAPTION.keyword", map.getString(PROJECT_CONTRAPTION)));
            boolMust.must(pBuilder);
        }

        // 查询 使用登记【可选设备列表】【(EQU_STATUS=== null || "" ) && (USE_ORG_CODE（使用登记证编号） ==="" || null)】
        BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
        //syBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
        // syBuilder.mustNot(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
        boolMust.must(syBuilder);
        this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "useRegistration");

        builder.query(boolMust);
        builder.sort("REC_DATE", SortOrder.DESC);
        builder.from((pageNumber - 1) * size);
        builder.size(size);
        request.source(builder);
        List<JSONObject> list = new LinkedList<>();
        long totle = 0;
        if (log.isDebugEnabled()) {
            log.debug("查询es 的查询条件: {}", request);
        }
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                System.out.println(hit);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
                JSONObject dto2 = jsonObject.getJSONObject("sourceAsMap");
                if (!ValidationUtil.isEmpty(dto2.get(CONSTRUCTIONTYPE))) {
                    // 转化施工类型
                    String constructionType = dto2.get(CONSTRUCTIONTYPE).toString();
                    if (!ValidationUtil.isEmpty(constructionType)) {
                        String[] constructionTypeList = constructionType.split(",");
                        List<String> statusList = new ArrayList<>();
                        for (String cType : constructionTypeList) {
                            Integer integer = Integer.valueOf(cType);
                            String status = ConstructionEnum.getName.get(integer);
                            statusList.add(status);
                        }
                        dto2.put(CONSTRUCTIONTYPE, Joiner.on(",").join(statusList));
                    }
                }
                if (!ValidationUtil.isEmpty(dto2.get(EQUSTATE))) {
                    Integer integer = Integer.valueOf(dto2.get(EQUSTATE).toString());
                    String status = EquimentEnum.getName.get(integer);
                    dto2.put(EQUSTATE, status);
                }
                if (!ValidationUtil.isEmpty(dto2.get(DATA_SOURCE))) {
                    String s = dto2.get(DATA_SOURCE).toString();
                    dto2.put(DATA_SOURCE, s);
                    dto2.put(DATA_SOURCE_NAME, Arrays.stream(EquipSourceEnum.values())
                            .filter(e -> s.startsWith(e.getCode()))
                            .map(EquipSourceEnum::getName)
                            .findFirst()
                            .orElse(EquipSourceEnum.jg.getName()));
                }
                dto2.put("record", dto2.get(SEQUENCE_NBR));
                list.add(dto2);
            }
            // 获取所有设备的Id
            List<String> equIds = null;
            if (!ValidationUtil.isEmpty(list)) {
                equIds = list.stream().map(item -> item.get(SEQUENCE_NBR).toString()).collect(Collectors.toList());
            }
            if (!ValidationUtil.isEmpty(equIds)) {
                // 查询设备地址
                List<IdxBizJgUseInfo> useInfoListByEquIds = idxBizJgUseInfoService.getUseInfoListByEquIds(equIds);
                Map<String, String> equAddressMap = new HashMap<>();
                if (!ValidationUtil.isEmpty(useInfoListByEquIds)) {
                    equAddressMap = useInfoListByEquIds.stream().collect(Collectors.toMap(IdxBizJgUseInfo::getRecord,
                                    useInfo -> {
                                        String fulladdress = "";
                                        if (!ValidationUtil.isEmpty(useInfo.getProvinceName())) {
                                            fulladdress += useInfo.getProvinceName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getCityName())) {
                                            fulladdress += useInfo.getCityName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getCountyName())) {
                                            fulladdress += useInfo.getCountyName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getStreetName())) {
                                            fulladdress += useInfo.getStreetName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                                            fulladdress += useInfo.getAddress();
                                        }
                                        return fulladdress;
                                    }
                            )
                    );
                }
                // 更新设备使用情况和设备地址
                for (JSONObject item : list) {
                    String fullAddress = equAddressMap.get(item.getString(SEQUENCE_NBR));
                    item.put("ADDRESS", !ValidationUtil.isEmpty(fullAddress) ? fullAddress : "");
                    item.put("CAN_EDIT", this.checkEquipIsCanEdit(item.getString(SEQUENCE_NBR)));
                    item.put("CAN_DELETE", this.checkEquipIsCanDelete(item.getString(SEQUENCE_NBR)));
                }
            }
            totle = response.getInternalResponse().hits().getTotalHits().value;
            result.setRecords(list);
            result.setTotal(totle);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 设备注册信息分页查询
     *
     * @param map
     * @return
     */
    @Override
    public Page<JSONObject> queryForEquipmentRegisterPage(JSONObject map) {

        if (map.containsKey("flag") && !map.containsKey("USE_UNIT_CREDIT_CODE")) {
            return new Page<>();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Integer pageNumber = ObjectUtils.isEmpty(map.getInteger("number")) ? 1 : map.getInteger("number");
        Integer size = ObjectUtils.isEmpty(map.getInteger("size")) ? 20 : map.getInteger("size");
        Page<JSONObject> result = new Page<>(pageNumber, size);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        // 获取当前登录人单位类型
        JSONObject company = getCompanyType();
        if (ValidationUtil.isEmpty(company)) {
            result.setRecords(new ArrayList<>());
            result.setTotal(0);
            return result;
        }
        String companyCode = company.getString("companyCode").contains("_") ?
                company.getString("companyCode").split("_")[1] : company.getString("companyCode");
        String type = company.getString("companyType");
        // 根据当前登录人查询
        if (!ValidationUtil.isEmpty(map.get(EQUSTATE))) {
            map.put(EQUSTATE, EquimentEnum.getCode.get(map.get(EQUSTATE).toString()).toString());
        }
        // 登录人公司类型：企业，监管
        String companyLevel = this.getCompanyLevel(company);
        // 根据当前登录用户类型及管辖机构筛选条件添加对应参数
        if (ObjectUtils.isEmpty(map.getString(SEQUENCE_NBR)) && ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
            if (!ValidationUtil.isEmpty(type) && type.contains("使用单位")) {
                if (ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE"))) {
                    map.put("USE_UNIT_CREDIT_CODE", companyCode);
                }
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("安装改造维修单位")) {
                map.put("USC_UNIT_CREDIT_CODE", companyCode);
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("个人主体")) {
                map.put("USE_UNIT_CREDIT_CODE", companyCode);
            }
        }

        // 默认条件【STATUS==="" || null】
        BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
        meBuilder.should(QueryBuilders.termQuery("STATUS", "已认领"));
        meBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("STATUS")));
        meBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("STATUS", "")));
        meBuilder.minimumShouldMatch(1);
        boolMust.must(meBuilder);

//        //默认条件 限制西安电梯隶属导入数据不可做业务
//        if (ObjectUtils.isEmpty(map.getString(IS_DO_BUSINESS))) {
//            BoolQueryBuilder tBuilder = QueryBuilders.boolQuery();
//            tBuilder.should(QueryBuilders.matchQuery(IS_DO_BUSINESS, true));
//            tBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(IS_DO_BUSINESS)));
//            tBuilder.minimumShouldMatch(1);
//            boolMust.must(tBuilder);
//        }

        // DATA_SOURCE 为“jg”开头的数据（从监管新加或复制的设备）
        // 20240314 提出的监管业务不要让企业用户选到之前一码通认领或补录的设备，让从监管业务中去新增
        BoolQueryBuilder dBuilder = QueryBuilders.boolQuery();
        String queryType = map.getString("QUERY_TYPE");
        if (map.containsKey("DATA_SOURCE") && !ObjectUtils.isEmpty(map.get("DATA_SOURCE"))) {
            String dataSource = map.getString("DATA_SOURCE");
            if ("jg_his".equals(dataSource)) {
                // 只查历史，前缀为 jg_his
                dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his"));
                dBuilder.mustNot(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his_black"));// 排除黑设备
            } else if("jg_his_black".equals(dataSource)) {
                // 只查黑设备，前缀为 jg_his_black
                dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his_black"));
            }else {
                // 只查新增，前缀为 jg 且前缀不为 jg_his
                dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg"))
                        .mustNot(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his"));
            }
        } else if (ValidationUtil.equals(queryType, "WB")) {
            // 既要控制电梯-历史设备新增后，只能走历史平台登记，不能走维保备案-新设备登记
            // 又要控制电梯历史设备在历史登记完成后。可以做维保备案
            // 历史设备且做过历史登记
            BoolQueryBuilder hisBuilder = QueryBuilders.boolQuery();
            hisBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his"));
            hisBuilder.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
            dBuilder.should(hisBuilder);
            // 或新设备
            BoolQueryBuilder jgBuilder = QueryBuilders.boolQuery();
            jgBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg"));
            jgBuilder.mustNot(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his"));
            dBuilder.should(jgBuilder);
        } else {
            // 查所有，前缀 jg
            dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg"));
        }
        boolMust.must(dBuilder);

        if (!ObjectUtils.isEmpty(queryType)) {
            // 查询 安装告知【可告知设备列表】【USE_UNIT_CREDIT_CODE=== null ||  ""】
            if (ValidationUtil.equals(queryType, "AZ")) {// 安装
                BoolQueryBuilder nullOrEmptyQuery = QueryBuilders.boolQuery()
                        .mustNot(QueryBuilders.wildcardQuery("USE_UNIT_CREDIT_CODE", "*"));
                boolMust.must(nullOrEmptyQuery);
                this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "installNotice");
                // 安装告知设备选择 - 业务限制
                // 根据设备类别（EQU_CATEGORY）、安装单位过滤设备（USC_UNIT_CREDIT_CODE）  下面过滤条件已有
                // 设备类别为工业管道（8300）时，用工程装置名称过滤
                if (!ValidationUtil.isEmpty(map.get(EQU_CATEGORY_CODE)) && ValidationUtil.equals(map.get(EQU_CATEGORY_CODE), "8300")) {
                    if (ValidationUtil.isEmpty(map.get("projectContraption"))) {
                        throw new BadRequest("请先选择工程装置信息！");
                    }
                    map.put(PROJECT_CONTRAPTION, String.valueOf(map.get("projectContraption")));
                }
            } else if (ValidationUtil.equals(queryType, "WB")) {// 维保
                this.setRepeatUsedCheckFilterParam(boolMust, companyCode, JgMaintenanceContractServiceImpl.WB_PROCESS_DEFINITION_KEY);
            } else if (ValidationUtil.equals(queryType, "SY")) {// 使用
                // 查询 使用登记【可选设备列表】【(EQU_STATUS=== null || "" ) && (USE_ORG_CODE（使用登记证编号） ==="" || null)】
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
                // syBuilder.mustNot(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                boolMust.must(syBuilder);
                this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "useRegistration");
            } else if (ValidationUtil.equals(queryType, "FINISH_SY")) {
                // 注意：上面条件是过滤出【未做过】某个业务的设备，下面部分是过滤出【做过】某个业务的设备
                // 查询 已经做过【使用登记】 的设备 【(EQU_STATUS != 空 ) && (USE_ORG_CODE（使用登记证编号） != 空)】
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
                boolMust.must(syBuilder);
            } else if (ValidationUtil.equals(queryType, "GZ_GZ") || ValidationUtil.equals(queryType, "GZ_WX") || ValidationUtil.equals(queryType, "GZ_YZ")) {
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.must(QueryBuilders.existsQuery("EQU_STATE"));
                // 设备类别为工业管道（8300）时，用工程装置名称过滤
                if (!ValidationUtil.isEmpty(map.get(EQU_CATEGORY_CODE)) && ValidationUtil.equals(map.get(EQU_CATEGORY_CODE), "8300")) {
                    syBuilder.must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                    if (ValidationUtil.isEmpty(map.get("projectContraption"))) {
                        throw new BadRequest("请先选择工程装置信息！");
                    }
                    map.put(PROJECT_CONTRAPTION, String.valueOf(map.get("projectContraption")));
                }
                boolMust.must(syBuilder);
                if (ValidationUtil.equals(queryType, "GZ_GZ")) {// 改造告知设备选择 - 业务限制
                    // 设备类别（EQU_CATEGORY）、安装单位（USC_UNIT_CREDIT_CODE）、选择的使用单位（USE_UNIT_CREDIT_CODE）、选择的区县（USE_PLACE_CODE）过滤数据
                    if (ValidationUtil.isEmpty(map.get("useUnitCreditCode")) || ValidationUtil.isEmpty(map.get("county"))) {
                        throw new BadRequest("请先选择使用单位，施工区县等信息！");
                    }
                    map.put("USE_UNIT_CREDIT_CODE", String.valueOf(map.get("useUnitCreditCode")).split("_")[0]);
                    map.put(USE_PLACE_CODE, String.valueOf(map.get("county")).split("_")[0]);
                    map.put("USC_UNIT_CREDIT_CODE", companyCode);
                    this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "renovationNoticeNew");
                } else if (ValidationUtil.equals(queryType, "GZ_WX")) {// 维修告知设备选择 - 业务限制
                    // 设备类别（EQU_CATEGORY）、安装单位（USC_UNIT_CREDIT_CODE）、选择的使用单位（USE_UNIT_CREDIT_CODE）、选择的区县（USE_PLACE_CODE）过滤数据
                    if (ValidationUtil.isEmpty(map.get("useUnitCreditCode")) || ValidationUtil.isEmpty(map.get("county"))) {
                        throw new BadRequest("请先选择使用单位，施工区县等信息！");
                    }
                    map.put("USE_UNIT_CREDIT_CODE", String.valueOf(map.get("useUnitCreditCode")).split("_")[0]);
                    map.put(USE_PLACE_CODE, String.valueOf(map.get("county")).split("_")[0]);
                    map.put("USC_UNIT_CREDIT_CODE", companyCode);
                    this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "maintainNotice");
                } else if (ValidationUtil.equals(queryType, "GZ_YZ")) {// 移装告知设备选择 - 业务限制
                    // 设备类别（EQU_CATEGORY）、安装单位（USC_UNIT_CREDIT_CODE）、选择的使用单位（USE_UNIT_CREDIT_CODE）、（区内移装（transferType=区内移装）根据区县(USE_PLACE_CODE)）过滤数据
                    if (ValidationUtil.isEmpty(map.get("useUnitCreditCode"))) {
                        throw new BadRequest("请先选择使用单位等信息！");
                    }
                    if (!ValidationUtil.isEmpty(map.get("transferType")) && ValidationUtil.equals(map.get("transferType"), "区内移装")) {
                        if (ValidationUtil.isEmpty(map.get("city"))) {
                            throw new BadRequest("请先选择施工区域-市！");
                        } else {
                            map.put(USE_PLACE_CODE, String.valueOf(map.get("city")).split("_")[0]);
                        }
                    }
                    map.put("USE_UNIT_CREDIT_CODE", String.valueOf(map.get("useUnitCreditCode")).split("_")[0]);
                    map.put("USC_UNIT_CREDIT_CODE", companyCode);
                    this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "transferNotice");
                }
            }
//            this.setRepeatUsedCheckFilterByType(boolMust,companyCode,queryType);
        }

        // 通用匹配规则，其他条件构建
        if (!ObjectUtils.isEmpty(map.getString(SEQUENCE_NBR))) {
            BoolQueryBuilder seqBuilder = QueryBuilders.boolQuery();
            String param = map.getString(SEQUENCE_NBR);
            List<String> strings = Arrays.asList(param.split(","));
            seqBuilder.must(QueryBuilders.termsQuery("SEQUENCE_NBR.keyword", strings));
            boolMust.must(seqBuilder);
        }

        if (!ObjectUtils.isEmpty(map.getString(DATA_QUALITY_SCORE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(DATA_QUALITY_SCORE));
            pBuilder.must(QueryBuilders.termQuery(DATA_QUALITY_SCORE, param));
            boolMust.must(pBuilder);
        }

        if (!ObjectUtils.isEmpty(map.getString(IS_INTO_MANAGEMENT))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(IS_INTO_MANAGEMENT));
            pBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, param));
            boolMust.must(pBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(EQU_CATEGORY));
            pBuilder.must(QueryBuilders.matchPhraseQuery(EQU_CATEGORY, "*" + param + "*"));
            boolMust.must(pBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("USE_PLACE"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString("USE_PLACE"));
            pBuilder.must(QueryBuilders.matchPhraseQuery("USE_PLACE", "*" + param + "*"));
            boolMust.must(pBuilder);
        }
        // 设备名称
        if (!ObjectUtils.isEmpty(map.getString(PRODUCT_NAME))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(PRODUCT_NAME));
            elcBuilder.must(QueryBuilders.matchPhraseQuery(PRODUCT_NAME, test));
            boolMust.must(elcBuilder);
        }
        // 设备状态
        if (!ObjectUtils.isEmpty(map.getString("EQU_STATE"))) {
            BoolQueryBuilder esBuilder = QueryBuilders.boolQuery();
            if (map.getString("EQU_STATE").equals(EquimentEnum.WEIDENGJI.getCode().toString())) {
                esBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
            } else {
                String param = QueryParser.escape(map.getLong("EQU_STATE").toString());
                esBuilder.must(QueryBuilders.matchQuery("EQU_STATE", param));
            }
            boolMust.must(esBuilder);
        }

        // 使用单位 //安装改造维修单位
        if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) && !ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
            BoolQueryBuilder ubuilder = QueryBuilders.boolQuery();
            String useCode = QueryParser.escape(map.getString("USE_UNIT_CREDIT_CODE"));
            useCode = useCode.contains("_") ? useCode.split("_")[0] : useCode;
            ubuilder.must(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", useCode));

            String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
            ubuilder.must(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + uscCode + "*"));
            boolMust.must(ubuilder);
        } else {
            if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) || !ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uucc = !ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) ? map.getString("USE_UNIT_CREDIT_CODE") : String.valueOf(map.get("useUnitCreditCode")).split("_")[0];
                String param = QueryParser.escape(uucc);
                param = param.contains("_") ? param.split("_")[0] : param;
                uuccBuilder.must(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", param));
                boolMust.must(uuccBuilder);
            }
            if (!ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
                uuccBuilder.must(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + uscCode + "*"));
                boolMust.must(uuccBuilder);
            }
        }

        // 监管码
        if (!ObjectUtils.isEmpty(map.getString("SUPERVISORY_CODE"))) {
            BoolQueryBuilder scBuilder = QueryBuilders.boolQuery();
            String param = map.getString("SUPERVISORY_CODE");
            //List<String> strings = Arrays.asList(param.split(","));
            scBuilder.must(QueryBuilders.wildcardQuery("SUPERVISORY_CODE", "*" + param+ "*"));
            boolMust.must(scBuilder);
        }
        // 使用登记证编号
        if (!ObjectUtils.isEmpty(map.getString("USE_ORG_CODE"))) {
            BoolQueryBuilder scBuilder = QueryBuilders.boolQuery();
            String param = map.getString("USE_ORG_CODE");
            //List<String> strings = Arrays.asList(param.split(","));
            scBuilder.must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*" + param+ "*"));
            boolMust.must(scBuilder);
        }
        // 设备种类编码
        if (!ObjectUtils.isEmpty(map.getString(EQU_LIST_CODE))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_LIST_CODE));
            elcBuilder.must(QueryBuilders.matchPhraseQuery(EQU_LIST_CODE, test));
            boolMust.must(elcBuilder);
        } else {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape("8000");//不查管道，管道新菜单查询
            pBuilder.mustNot(QueryBuilders.termQuery(EQU_LIST_CODE, test));
            boolMust.must(pBuilder);
        }
        String deviceType = map.getString(DEVICE_TYPE);
        if ("set".equals(deviceType) || "cylinder".equals(deviceType)) {
            BoolQueryBuilder scBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape("2300");
            scBuilder = "set".equals(deviceType)? scBuilder.mustNot(QueryBuilders.wildcardQuery(EQU_CATEGORY_CODE, test))
                    : scBuilder.must(QueryBuilders.wildcardQuery(EQU_CATEGORY_CODE, test));
            boolMust.must(scBuilder);
        }

        //监管查看
        if (!ObjectUtils.isEmpty(map.getString(DATA_QUALITY_SCORE_JG))) {
            BoolQueryBuilder scBuilder = QueryBuilders.boolQuery();
            String param = map.getString(DATA_QUALITY_SCORE_JG);
            List<String> strings = Arrays.stream(param.replaceAll("^\\[|\\]$", "").split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toList());
            scBuilder.must(QueryBuilders.termsQuery("DATA_QUALITY_SCORE", strings));
            boolMust.must(scBuilder);
        }

        // 设备品种编码
        if (!ObjectUtils.isEmpty(map.getString("EQU_DEFINE_CODE"))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("EQU_DEFINE_CODE"));
            elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_DEFINE_CODE", test));
            boolMust.must(elcBuilder);
        }
        // 设备种类名称
        if (!ObjectUtils.isEmpty(map.getString(EQU_LIST))) {
            BoolQueryBuilder elBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_LIST));
            elBuilder.must(QueryBuilders.matchPhraseQuery(EQU_LIST, "*" + test + "*"));
            boolMust.must(elBuilder);
        }

        // 设备类别
        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CATEGORY_CODE));
            pBuilder.must(QueryBuilders.termQuery(EQU_CATEGORY_CODE, test));
            boolMust.must(pBuilder);
        }
        //设备类别为气瓶时，添加是否车用气瓶字段
        if (CylinderTypeEnum.CYLINDER.getCode().equals(map.getString(EQU_CATEGORY_CODE))) {
            Optional.ofNullable(map.getString(WHETHER_VEHICLE_CYLINDER))
                    .filter(s -> !s.trim().isEmpty())
                    .ifPresent(cylinder -> boolMust.must(
                            QueryBuilders.boolQuery()
                                    .must(QueryBuilders.termQuery(WHETHER_VEHICLE_CYLINDER, QueryParser.escape(cylinder)))
                    ));
        }
        // 是否撬装式压力容器
        if ("2100".equals(map.getString(EQU_CATEGORY_CODE))){
            if (!ObjectUtils.isEmpty(map.getString(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL))) {
                if ("1".equals(map.getString(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL))){
                    BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
                    String test = QueryParser.escape(map.getString(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL));
                    pBuilder.must(QueryBuilders.termQuery(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL, test));
                    boolMust.must(pBuilder);
                }else{
                    BoolQueryBuilder orBuilder = QueryBuilders.boolQuery();
                    orBuilder.should(QueryBuilders.termQuery(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL, "0"));
                    orBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL)));
                    orBuilder.minimumShouldMatch(1);
                    boolMust.must(orBuilder);
                }
            }
        }
        // 设备代码查询
        if (!ObjectUtils.isEmpty(map.getString(EQU_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CODE));
            pBuilder.must(QueryBuilders.matchPhraseQuery(EQU_CODE, test.toLowerCase()));
            boolMust.must(pBuilder);
        }
        // 单位内部编号查询
        if (!ObjectUtils.isEmpty(map.getString("USE_INNER_CODE"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("USE_INNER_CODE"));
            pBuilder.must(QueryBuilders.matchPhraseQuery("USE_INNER_CODE", test.toLowerCase()));
            boolMust.must(pBuilder);
        }
        // 出厂编号/产品编码查询
        if (!ObjectUtils.isEmpty(map.getString(FACTORY_NUM))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(FACTORY_NUM));
            pBuilder.must(QueryBuilders.matchPhraseQuery(FACTORY_NUM, test.toLowerCase()));
            boolMust.must(pBuilder);
        }
        // 制造单位（生产单位）名称查询
        if (!ObjectUtils.isEmpty(map.getString("PRODUCE_UNIT_NAME"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("PRODUCE_UNIT_NAME"));
            pBuilder.must(QueryBuilders.matchPhraseQuery("PRODUCE_UNIT_NAME", test.toLowerCase()));
            boolMust.must(pBuilder);
        }
        // 使用单位 名称模糊查询
        if (!ObjectUtils.isEmpty(map.getString(USE_UNIT_NAME))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String text = map.getString(USE_UNIT_NAME);
            pBuilder.must(QueryBuilders.matchQuery(USE_UNIT_NAME, text).operator(Operator.AND));
            boolMust.must(pBuilder);
        }
        // 模糊查询
        if (!ObjectUtils.isEmpty(map.getString(USE_PLACE_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(USE_PLACE_CODE));
            pBuilder.must(QueryBuilders.wildcardQuery(USE_PLACE_CODE, "*" + test.toLowerCase() + "*"));
            boolMust.must(pBuilder);
        }
        // 工程装置名称模糊查询
        if (!ObjectUtils.isEmpty(map.getString(PROJECT_CONTRAPTION))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            pBuilder.must(QueryBuilders.termsQuery("PROJECT_CONTRAPTION.keyword", map.getString(PROJECT_CONTRAPTION)));
            boolMust.must(pBuilder);
        }
        // 增加监管端查询, 查询规则看到本级及之下的设备
        if(companyLevel.equals(BaseController.COMPANY_TYPE_SUPERVISION)){
            boolMust.must(QueryBuilders.prefixQuery("ORG_BRANCH_CODE.keyword", company.getString("orgCode")));
        }
        // 属地监管部门过滤
        if(!ObjectUtils.isEmpty(map.getString("ORG_BRANCH_CODE"))){
            if(companyLevel.equals(BaseController.COMPANY_TYPE_SUPERVISION)) { // 监管 右模糊查询
                boolMust.must(QueryBuilders.prefixQuery("ORG_BRANCH_CODE.keyword", map.getString("ORG_BRANCH_CODE")));
            } else {                                                           // 企业 等于查询
                boolMust.must(QueryBuilders.termQuery("ORG_BRANCH_CODE.keyword", map.getString("ORG_BRANCH_CODE")));
            }
        }
        // 创建时间范围查询
        if (!ObjectUtils.isEmpty(map.getString(CREATE_DATE_RANGE))) {

            String createDateRangeObj = map.getString(CREATE_DATE_RANGE);
            String[] split = createDateRangeObj.replace("[", "").replace("]", "").split(",");
            String startDateStr = split[0];
            String endDateStr = split[1];
            try {

                Date startDate = sdf.parse(startDateStr);
                Date endDate = sdf.parse(endDateStr);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(endDate);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                endDate = calendar.getTime();
                long startDateMillis = startDate.getTime();
                long endDateMillis = endDate.getTime();
                BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
                pBuilder.must(QueryBuilders.rangeQuery("CREATE_DATE")
                        .gte(startDateMillis)  // 大于等于开始日期的时间戳
                        .lte(endDateMillis)    // 小于等于结束日期的时间戳
                );
                boolMust.must(pBuilder);
            } catch (Exception e) {
                log.error("日期转化异常：{}", e.getMessage());
                e.printStackTrace();
            }
        }
        // 字段排序
        if (!ObjectUtils.isEmpty(map.get("sort"))){
            String[] sorts = Objects.toString(map.get("sort")).split(",");
            builder.sort(sorts[0], "descend".equals(sorts[1]) ? SortOrder.DESC : SortOrder.ASC);
        }else {
            builder.sort("REC_DATE", SortOrder.DESC);
        }
        builder.query(boolMust);
        builder.from((pageNumber - 1) * size);
        builder.size(size);
        request.source(builder);
        List<JSONObject> list = new LinkedList<>();
        long totle = 0;
        if (log.isDebugEnabled()) {
            log.debug("查询es 的查询条件: {}", request);
        }
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                System.out.println(hit);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
                JSONObject dto2 = jsonObject.getJSONObject("sourceAsMap");
                if (!ValidationUtil.isEmpty(dto2.get(CONSTRUCTIONTYPE))) {
                    // 转化施工类型
                    String constructionType = dto2.get(CONSTRUCTIONTYPE).toString();
                    if (!ValidationUtil.isEmpty(constructionType)) {
                        String[] constructionTypeList = constructionType.split(",");
                        List<String> statusList = new ArrayList<>();
                        for (String cType : constructionTypeList) {
                            Integer integer = Integer.valueOf(cType);
                            String status = ConstructionEnum.getName.get(integer);
                            statusList.add(status);
                        }
                        dto2.put(CONSTRUCTIONTYPE, Joiner.on(",").join(statusList));
                    }
                }
                if (!ValidationUtil.isEmpty(dto2.get(EQUSTATE))) {
                    Integer integer = Integer.valueOf(dto2.get(EQUSTATE).toString());
                    String status = EquimentEnum.getName.get(integer);
                    dto2.put(EQUSTATE, status);
                }
                if (!ValidationUtil.isEmpty(dto2.get(DATA_SOURCE))) {
                    String s = dto2.get(DATA_SOURCE).toString();
                    dto2.put(DATA_SOURCE, s);
                    dto2.put(DATA_SOURCE_NAME, EquipSourceEnum.getDataSourceName(s));
                }
                dto2.computeIfPresent(IS_INTO_MANAGEMENT, (k, v) -> {
                    dto2.put(IS_INTO_MANAGEMENT_NAME, IsIntoManagementEnum.getName(Boolean.parseBoolean(v.toString())));
                    return v;
                });
                dto2.put("record", dto2.get(SEQUENCE_NBR));
                list.add(dto2);
            }
            // 获取所有设备的Id
            List<String> equIds = null;
            if (!ValidationUtil.isEmpty(list)) {
                equIds = list.stream().map(item -> item.get(SEQUENCE_NBR).toString()).collect(Collectors.toList());
            }
            if (!ValidationUtil.isEmpty(equIds)) {
                // 查询设备地址
                List<IdxBizJgUseInfo> useInfoListByEquIds = idxBizJgUseInfoService.getUseInfoListByEquIds(equIds);
                Map<String, String> equAddressMap = new HashMap<>();
                if (!ValidationUtil.isEmpty(useInfoListByEquIds)) {
                    equAddressMap = useInfoListByEquIds.stream().collect(Collectors.toMap(
                            IdxBizJgUseInfo::getRecord,
                            useInfo -> {
                                String fulladdress = "";
                                if (!ValidationUtil.isEmpty(useInfo.getProvinceName())) {
                                    fulladdress += useInfo.getProvinceName();
                                }
                                if (!ValidationUtil.isEmpty(useInfo.getCityName())) {
                                    fulladdress += useInfo.getCityName();
                                }
                                if (!ValidationUtil.isEmpty(useInfo.getCountyName())) {
                                    fulladdress += useInfo.getCountyName();
                                }
                                if (!ValidationUtil.isEmpty(useInfo.getStreetName())) {
                                    fulladdress += useInfo.getStreetName();
                                }
                                if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                                    fulladdress += useInfo.getAddress();
                                }
                                return fulladdress;
                            },
                            (v1, v2) -> v1)
                    );
                }

                // 获取是否发生过后续业务集合
                Map<String, Boolean> afterBizMap = getHasHappenAfterBiz(equIds);

                // 更新设备使用情况和设备地址
                for (JSONObject item : list) {
                    item.put("REC_DATE", Instant.ofEpochMilli(Long.parseLong(item.getString("REC_DATE")))
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate());
                    if (!ValidationUtil.isEmpty(item.getString(CREATE_DATE))){
                        item.put(CREATE_DATE, Instant.ofEpochMilli(Long.parseLong(item.getString(CREATE_DATE)))
                                .atZone(ZoneId.systemDefault())
                                .toLocalDate());
                    }
                    String fullAddress = equAddressMap.get(item.getString(SEQUENCE_NBR));
                    item.put("ADDRESS", !ValidationUtil.isEmpty(fullAddress) ? fullAddress : "");
                     item.put("CAN_EDIT", this.checkEquipIsCanEdit(item.getString(SEQUENCE_NBR)));
                    // TODO 未纳管设备删除使用此字段，调整为前端始终显示删除按钮
                    // item.put("CAN_DELETE", this.checkEquipIsCanDelete(item.getString(SEQUENCE_NBR)));
                    // 单位类型区分是监管还是企业
                    item.put("companyType", companyLevel);
                    // 区分新增设备、历史有证设备、历史无证设备，与使用登记一致：0-新设备、1-历史有证设备、2-历史无证设备
                    item.put("regType", CommonServiceImpl.genRegTypeByDataSource(item.getString(DATA_SOURCE)));
                    // 是否发生后续业务，前端控制是否可编辑
                    item.put(BaseUseRegisterResultData.HAPPEN_AFTER_BIZ, afterBizMap.getOrDefault(item.getString(SEQUENCE_NBR), false));
                    item.put("DATA_QUALITY_SCORE", commonServiceImpl.castDataQualityScore2Name(item.getString(DATA_QUALITY_SCORE), item.getBoolean(IS_INTO_MANAGEMENT)));
                    item.replaceAll((key, value) -> "null".equals(value) ? null : value);
                }
            }
            totle = response.getInternalResponse().hits().getTotalHits().value;
            result.setRecords(list);
            result.setTotal(totle);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    private Map<String, Boolean> getHasHappenAfterBiz(List<String> equIds) {
        List<CountDto> countDtoList = commonMapper.countBizNumAfterUseRegBatchEquip(equIds);
       return countDtoList.stream().collect(Collectors.toMap(CountDto::getKeyStr, e-> e.getLongValue() > 0));
    }


    private String getCompanyLevel(JSONObject company) {
        if (BaseController.COMPANY_TYPE_COMPANY.equals(company.getString("level"))) {
            return BaseController.COMPANY_TYPE_COMPANY;
        } else {
            return BaseController.COMPANY_TYPE_SUPERVISION;
        }
    }


    /**
     * 设备注册信息分页查询
     *
     * @param map
     * @return
     */
    @Override
    public Page<JSONObject> queryForEquipmentRegisterPageHistory(JSONObject map) {

        if (map.containsKey("flag") && !map.containsKey("USE_UNIT_CREDIT_CODE")) {
            return new Page<>();
        }


        Integer pageNumber = ObjectUtils.isEmpty(map.getInteger("number")) ? 1 : map.getInteger("number");
        Integer size = ObjectUtils.isEmpty(map.getInteger("size")) ? 20 : map.getInteger("size");
        Page<JSONObject> result = new Page<>(pageNumber, size);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        // 获取当前登录人单位类型
        JSONObject company = getCompanyType();
        if (ValidationUtil.isEmpty(company)) {
            result.setRecords(new ArrayList<>());
            result.setTotal(0);
            return result;
        }
        String companyCode = company.getString("companyCode").contains("_") ?
                company.getString("companyCode").split("_")[1] : company.getString("companyCode");
        String type = company.getString("companyType");


        // 根据当前登录人查询
        if (!ValidationUtil.isEmpty(map.get(EQUSTATE))) {
            map.put(EQUSTATE, EquimentEnum.getCode.get(map.get(EQUSTATE).toString()).toString());
        }

        // 根据当前登录用户类型及管辖机构筛选条件添加对应参数
        if (ObjectUtils.isEmpty(map.getString(SEQUENCE_NBR)) && ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
            if (!ValidationUtil.isEmpty(type) && type.contains("使用单位")) {
                if (ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE"))) {
                    map.put("USE_UNIT_CREDIT_CODE", companyCode);
                }
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("安装改造维修单位")) {
                map.put("USC_UNIT_CREDIT_CODE", companyCode);
            }
            if (!ValidationUtil.isEmpty(type) && type.contains("个人主体")) {
                map.put("USE_UNIT_CREDIT_CODE", companyCode);
            }
        }

        // 默认条件【STATUS==="" || null】
        BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
        meBuilder.should(QueryBuilders.matchQuery("STATUS", "已认领"));
        meBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("STATUS")));
        meBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("STATUS", "")));
        meBuilder.minimumShouldMatch(1);
        boolMust.must(meBuilder);

        // DATA_SOURCE 为“jg”开头的数据（从监管新加或复制的设备）
        // 20240314 提出的监管业务不要让企业用户选到之前一码通认领或补录的设备，让从监管业务中去新增
        BoolQueryBuilder dBuilder = QueryBuilders.boolQuery();
        dBuilder.must(QueryBuilders.prefixQuery("DATA_SOURCE", "jg_his"));
        boolMust.must(dBuilder);

        String queryType = map.getString("QUERY_TYPE");
        if (!ObjectUtils.isEmpty(queryType)) {
            // 查询 安装告知【可告知设备列表】【USE_UNIT_CREDIT_CODE=== null ||  ""】
            if (ValidationUtil.equals(queryType, "AZ")) {
                BoolQueryBuilder nullOrEmptyQuery = QueryBuilders.boolQuery()
                        .mustNot(QueryBuilders.wildcardQuery("USE_UNIT_CREDIT_CODE", "*"));
                boolMust.must(nullOrEmptyQuery);
                this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "installNotice");
            } else if (ValidationUtil.equals(queryType, "WB")) {
                // 查询 维保备案【可绑定设备列表】【(EQU_STATE=== null ||  ""）】
                BoolQueryBuilder wbBuilder = QueryBuilders.boolQuery();
                wbBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
                boolMust.must(wbBuilder);
            } else if (ValidationUtil.equals(queryType, "SY")) {
                // 查询 使用登记【可选设备列表】【(EQU_STATUS=== null || "" ) && (USE_ORG_CODE（使用登记证编号） ==="" || null)】
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
                syBuilder.mustNot(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                boolMust.must(syBuilder);
                this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "useRegistration");
            } else if (ValidationUtil.equals(queryType, "FINISH_SY")) {
                // 注意：上面条件是过滤出【未做过】某个业务的设备，下面部分是过滤出【做过】某个业务的设备
                // 查询 已经做过【使用登记】 的设备 【(EQU_STATUS != 空 ) && (USE_ORG_CODE（使用登记证编号） != 空)】
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.must(QueryBuilders.existsQuery("EQU_STATE"))
                        .must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                boolMust.must(syBuilder);
            } else if (ValidationUtil.equals(queryType, "GZ_GZ") || ValidationUtil.equals(queryType, "GZ_WX") || ValidationUtil.equals(queryType, "GZ_YZ")) {
                BoolQueryBuilder syBuilder = QueryBuilders.boolQuery();
                syBuilder.must(QueryBuilders.existsQuery("EQU_STATE"));
                syBuilder.must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
                boolMust.must(syBuilder);
            }
        }

        // 通用匹配规则，其他条件构建
        if (!ObjectUtils.isEmpty(map.getString(SEQUENCE_NBR))) {
            BoolQueryBuilder seqBuilder = QueryBuilders.boolQuery();
            String param = map.getString(SEQUENCE_NBR);
            List<String> strings = Arrays.asList(param.split(","));
            seqBuilder.must(QueryBuilders.termsQuery("SEQUENCE_NBR.keyword", strings));
            boolMust.must(seqBuilder);
        }

        if (!ObjectUtils.isEmpty(map.getString(IS_INTO_MANAGEMENT))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(IS_INTO_MANAGEMENT));
            pBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, param));
            boolMust.must(pBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString(EQU_CATEGORY));
            pBuilder.must(QueryBuilders.matchPhraseQuery(EQU_CATEGORY, "*" + param + "*"));
            boolMust.must(pBuilder);

        }
        if (!ObjectUtils.isEmpty(map.getString("USE_PLACE"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getString("USE_PLACE"));
            pBuilder.must(QueryBuilders.matchPhraseQuery("USE_PLACE", "*" + param + "*"));
            boolMust.must(pBuilder);
        }
        // 设备状态
        if (!ObjectUtils.isEmpty(map.getString("EQU_STATE"))) {
            BoolQueryBuilder esBuilder = QueryBuilders.boolQuery();
            String param = QueryParser.escape(map.getLong("EQU_STATE").toString());
            esBuilder.must(QueryBuilders.matchQuery("EQU_STATE", param));
            boolMust.must(esBuilder);
        }

        // 使用单位 //安装改造维修单位
        if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) && !ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
            BoolQueryBuilder ubuilder = QueryBuilders.boolQuery();
            String useCode = QueryParser.escape(map.getString("USE_UNIT_CREDIT_CODE"));
            useCode = useCode.contains("_") ? useCode.split("_")[0] : useCode;
            ubuilder.should(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", useCode));

            String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
            ubuilder.should(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + uscCode + "*"));
            ubuilder.minimumShouldMatch(1);
            boolMust.must(ubuilder);
        } else {
            if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) || !ObjectUtils.isEmpty(map.getString("useUnitCreditCode"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uucc = !ValidationUtil.isEmpty(map.getString("USE_UNIT_CREDIT_CODE")) ? map.getString("USE_UNIT_CREDIT_CODE") : String.valueOf(map.get("useUnitCreditCode")).split("_")[0];
                String param = QueryParser.escape(uucc);
                param = param.contains("_") ? param.split("_")[0] : param;
                uuccBuilder.must(QueryBuilders.matchQuery("USE_UNIT_CREDIT_CODE", param));
                boolMust.must(uuccBuilder);
            }
            if (!ObjectUtils.isEmpty(map.getString("USC_UNIT_CREDIT_CODE"))) {
                BoolQueryBuilder uuccBuilder = QueryBuilders.boolQuery();
                String uscCode = QueryParser.escape(map.getString("USC_UNIT_CREDIT_CODE")).toLowerCase();
                uuccBuilder.must(QueryBuilders.wildcardQuery("USC_UNIT_CREDIT_CODE", "*" + uscCode + "*"));
                boolMust.must(uuccBuilder);
            }
        }

        // 监管码
        if (!ObjectUtils.isEmpty(map.getString("SUPERVISORY_CODE"))) {
            BoolQueryBuilder scBuilder = QueryBuilders.boolQuery();
            String param = map.getString("SUPERVISORY_CODE");
            List<String> strings = Arrays.asList(param.split(","));
            scBuilder.must(QueryBuilders.termsQuery("SUPERVISORY_CODE", strings));
            boolMust.must(scBuilder);
        }
        // 设备种类编码
        if (!ObjectUtils.isEmpty(map.getString("EQU_LIST_CODE"))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("EQU_LIST_CODE"));
            elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_LIST_CODE", test));
            boolMust.must(elcBuilder);
        }
        // 设备类别编码
        if (!ObjectUtils.isEmpty(map.getString("EQU_DEFINE_CODE"))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("EQU_DEFINE_CODE"));
            elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_DEFINE_CODE", test));
            boolMust.must(elcBuilder);
        }
        // 设备种类名称
        if (!ObjectUtils.isEmpty(map.getString(EQU_LIST))) {
            BoolQueryBuilder elBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_LIST));
            elBuilder.must(QueryBuilders.matchPhraseQuery(EQU_LIST, "*" + test + "*"));
            boolMust.must(elBuilder);
        }

        // 设备类别
        if (!ObjectUtils.isEmpty(map.getString(EQU_CATEGORY_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CATEGORY_CODE));
            pBuilder.must(QueryBuilders.termQuery(EQU_CATEGORY_CODE, test));
            boolMust.must(pBuilder);
        }
        // 是否车用气瓶
        if (!ObjectUtils.isEmpty(map.getString(WHETHER_VEHICLE_CYLINDER))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(WHETHER_VEHICLE_CYLINDER));
            pBuilder.must(QueryBuilders.termQuery(WHETHER_VEHICLE_CYLINDER, test));
            boolMust.must(pBuilder);
        }
        // 是否撬装式压力容器
        if (!ObjectUtils.isEmpty(map.getString(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL));
            pBuilder.must(QueryBuilders.termQuery(WHETHER_SKID_MOUNTED_PRESSURE_VESSEL, test));
            boolMust.must(pBuilder);
        }
        // 设备代码模糊查询
        if (!ObjectUtils.isEmpty(map.getString(EQU_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(EQU_CODE));
            pBuilder.must(QueryBuilders.wildcardQuery(EQU_CODE, "*" + test.toLowerCase() + "*"));
            boolMust.must(pBuilder);
        }
        // 单位内部编号模糊查询
        if (!ObjectUtils.isEmpty(map.getString("USE_INNER_CODE"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("USE_INNER_CODE"));
            pBuilder.must(QueryBuilders.wildcardQuery("USE_INNER_CODE", "*" + test.toLowerCase() + "*"));
            boolMust.must(pBuilder);
        }
        // 出厂编号/产品编码模糊查询
        if (!ObjectUtils.isEmpty(map.getString(FACTORY_NUM))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString(FACTORY_NUM));
            pBuilder.must(QueryBuilders.wildcardQuery(FACTORY_NUM, "*" + test.toLowerCase() + "*"));
            boolMust.must(pBuilder);
        }
        // 制造单位（生产单位）名称模糊查询
        if (!ObjectUtils.isEmpty(map.getString("PRODUCE_UNIT_NAME"))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(map.getString("PRODUCE_UNIT_NAME"));
            pBuilder.must(QueryBuilders.wildcardQuery("PRODUCE_UNIT_NAME", "*" + test.toLowerCase() + "*"));
            boolMust.must(pBuilder);
        }
        builder.query(boolMust);
        builder.sort("REC_DATE", SortOrder.DESC);
        builder.from((pageNumber - 1) * size);
        builder.size(size);
        request.source(builder);
        List<JSONObject> list = new LinkedList<>();
        long totle = 0;
        if (log.isDebugEnabled()) {
            log.debug("查询es 的查询条件: {}", request);
        }
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                System.out.println(hit);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
                JSONObject dto2 = jsonObject.getJSONObject("sourceAsMap");
                if (!ValidationUtil.isEmpty(dto2.get(CONSTRUCTIONTYPE))) {
                    // 转化施工类型
                    String constructionType = dto2.get(CONSTRUCTIONTYPE).toString();
                    if (!ValidationUtil.isEmpty(constructionType)) {
                        String[] constructionTypeList = constructionType.split(",");
                        List<String> statusList = new ArrayList<>();
                        for (String cType : constructionTypeList) {
                            Integer integer = Integer.valueOf(cType);
                            String status = ConstructionEnum.getName.get(integer);
                            statusList.add(status);
                        }
                        dto2.put(CONSTRUCTIONTYPE, Joiner.on(",").join(statusList));
                    }
                }
                if (!ValidationUtil.isEmpty(dto2.get(EQUSTATE))) {
                    Integer integer = Integer.valueOf(dto2.get(EQUSTATE).toString());
                    String status = EquimentEnum.getName.get(integer);
                    dto2.put(EQUSTATE, status);
                }
                if (!ValidationUtil.isEmpty(dto2.get(DATA_SOURCE))) {
                    String s = dto2.get(DATA_SOURCE).toString();
                    dto2.put(DATA_SOURCE, s);
                    dto2.put(DATA_SOURCE_NAME, EquipSourceEnum.getDataSourceName(s));
                }
                dto2.put("record", dto2.get(SEQUENCE_NBR));
                list.add(dto2);
            }
            // 获取所有设备的Id
            List<String> equIds = null;
            if (!ValidationUtil.isEmpty(list)) {
                equIds = list.stream().map(item -> item.get(SEQUENCE_NBR).toString()).collect(Collectors.toList());
            }
            if (!ValidationUtil.isEmpty(equIds)) {
                // 查询设备地址
                List<IdxBizJgUseInfo> useInfoListByEquIds = idxBizJgUseInfoService.getUseInfoListByEquIds(equIds);
                Map<String, String> equAddressMap = new HashMap<>();
                if (!ValidationUtil.isEmpty(useInfoListByEquIds)) {
                    equAddressMap = useInfoListByEquIds.stream().collect(Collectors.toMap(IdxBizJgUseInfo::getRecord,
                                    useInfo -> {
                                        String fulladdress = "";
                                        if (!ValidationUtil.isEmpty(useInfo.getProvinceName())) {
                                            fulladdress += useInfo.getProvinceName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getCityName())) {
                                            fulladdress += useInfo.getCityName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getCountyName())) {
                                            fulladdress += useInfo.getCountyName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getStreetName())) {
                                            fulladdress += useInfo.getStreetName();
                                        }
                                        if (!ValidationUtil.isEmpty(useInfo.getAddress())) {
                                            fulladdress += useInfo.getAddress();
                                        }
                                        return fulladdress;
                                    }
                            )
                    );
                }
                // 更新设备使用情况和设备地址
                for (JSONObject item : list) {
                    String fullAddress = equAddressMap.get(item.getString(SEQUENCE_NBR));
                    item.put("ADDRESS", !ValidationUtil.isEmpty(fullAddress) ? fullAddress : "");
                    item.put("CAN_EDIT", this.checkEquipIsCanEdit(item.getString(SEQUENCE_NBR)));
                    item.put("CAN_DELETE", this.checkEquipIsCanDelete(item.getString(SEQUENCE_NBR)));
                }
            }
            totle = response.getInternalResponse().hits().getTotalHits().value;
            result.setRecords(list);
            result.setTotal(totle);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 设置安装告知使用的设备不能包括正在进行中的流程
     *
     * @param boolMust
     * @param companyCode
     */
    private void setRepeatUsedCheckFilterParam(BoolQueryBuilder boolMust, String companyCode, String bizType) {
        Set<String> records = EquipUsedCheckStrategyContext.getUsedStrategy(bizType).getEquipInFlow(companyCode);
        if (records != null && !records.isEmpty()) {
            boolMust.mustNot(QueryBuilders.termsQuery("SEQUENCE_NBR.keyword", records));
        }
    }

    /**
     * 获取当前登录人单位类型
     *
     * @return
     */
    public JSONObject getCompanyType() {

        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        CompanyBo company = reginParams.getCompany();

        JSONObject object = new JSONObject();
        if (!ValidationUtil.isEmpty(company)) {
            object.put("level", company.getLevel());
            object.put("orgCode", company.getOrgCode());
            object.put("companyName", company.getCompanyName());
            object.put("companyCode", company.getCompanyCode());
            object.put("companyType", company.getCompanyType());
        }
        return object;
    }

    /**
     * 获取类型为ZC的“未注册”的字典值
     *
     * @return code
     */
    public String getRegCode() {
        QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", "ZC");
        queryWrapper.eq("name", "未注册");
        queryWrapper.eq("is_delete", false);
        List<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
        if (!list.isEmpty() && list.get(0) != null) {
            DataDictionary dictionary = list.get(0);
            return Optional.ofNullable(dictionary).map(DataDictionary::getCode).orElse("");
        }
        return "";
    }

    private String batchSubmitOrUpdate(LinkedHashMap equipmentClassForm, LinkedHashMap equipmentInfoForm, LinkedHashMap equipmentParamsForm, String submitType, CompanyBo company) {
        Date date = new Date();
        String record = null;

        // 设备种类
        String equList = String.valueOf(equipmentInfoForm.get(EQU_LIST));
        // 设备类别
        String equCategory = String.valueOf(equipmentInfoForm.get(EQU_CATEGORY));
        // 设备品种
        String equDefine = String.valueOf(equipmentInfoForm.get(EQU_DEFINE));
        // 业务场景
        String businessScenarios = String.valueOf(equipmentClassForm.get(BUSINESS_SCENARIOS));
        // 操作类型
        String operateType = ValidationUtil.isEmpty(equipmentInfoForm.get(SEQUENCE_NBR)) ? OPERATESAVE : OPERATEEDIT;
        // 设备是否复制而来，复制来的设备走新增
        boolean isCopy = !ValidationUtil.isEmpty(equipmentInfoForm.get(IS_COPY));
        operateType = isCopy ? OPERATESAVE : operateType;
        // 新增设备保存时 : 历史设备=》dataSource为"his" jg新录入设备dataSource为"jg"
        String dataSource = this.getDataSource(operateType, equipmentInfoForm);
        if (isCopy) {
            String sourceRecord = equipmentClassForm.get(RECORD).toString();
            // bug-21203
            if (equipmentInfoForm.containsKey("DATA_SOURCE")) {
                String dataSourceCopy = dataSource;
                if (dataSourceCopy.startsWith("jg_his_black")) {
                    dataSource = "jg_his_black_" + sourceRecord;
                } else if (dataSourceCopy.startsWith("jg_his")) {
                    dataSource = "jg_his_" + sourceRecord;
                } else {
                    dataSource = "jg_" + sourceRecord;
                }
            } else {
                throw new BadRequest("数据异常,请联系管理员");
            }
        }
        record = OPERATESAVE.equals(operateType) ? UUID.randomUUID().toString() : equipmentInfoForm.get(RECORD).toString();

        // 单位类型
        Map<String, Object> companyInfoMap = jgInstallationNoticeService.getCompanyType();
        String companyTypeStr = companyInfoMap.get("companyType").toString();

        // 使用信息
        IdxBizJgUseInfo useInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgUseInfo.class);
        // 设计信息
        IdxBizJgDesignInfo designInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgDesignInfo.class);
        // 维保信息
        IdxBizJgMaintenanceRecordInfo maintenanceInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgMaintenanceRecordInfo.class);
        // 制造信息
        IdxBizJgFactoryInfo factoryInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgFactoryInfo.class);
        // 施工信息
        IdxBizJgConstructionInfo constructionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgConstructionInfo.class);
        // 注册登记信息
        IdxBizJgRegisterInfo registerInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgRegisterInfo.class);
        // 监督管理
        IdxBizJgSupervisionInfo supervisionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgSupervisionInfo.class);
        // 其他信息
        IdxBizJgOtherInfo otherInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgOtherInfo.class);
        // 检验检测 【新增时】 固定式压力容器（2100）和 气瓶（2300）可以添加检验检测信息
        if (ADD.equals(submitType) || isCopy) {
            // 历史无证设备创建且是检验信息齐全时才创建检验信息
            if (dataSource.contains("jg_his_black") && InspectIsInPeriodEnum.IN_PERIOD_YES.getValue().equals(registerInfo.getInInspectionPeriod())) {
                IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgInspectionDetectionInfo.class);
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(date);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                inspectionDetectionInfo.setSequenceNbr(null);
                iIdxBizJgInspectionDetectionInfoService.saveOrUpdateData(inspectionDetectionInfo);
            } else if (CylinderTypeEnum.CYLINDER.getCode().equals(equCategory) || "2100".equals(equCategory)) {
                IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgInspectionDetectionInfo.class);
                List<Map<String, Object>> inspectionAndTestingInstitutions = commonService.getUnitListByType("inspection", "gasCylindersForCars", false);
                Optional<Map<String, Object>> optional = inspectionAndTestingInstitutions.stream().filter(x -> x.get("useCode").equals(inspectionDetectionInfo.getInspectOrgCode())).findFirst();
                Map<String, Object> mapOrDefault = optional.orElse(Collections.emptyMap());
                inspectionDetectionInfo.setInspectOrgName((String) mapOrDefault.getOrDefault("useUnit", inspectionDetectionInfo.getInspectOrgName()));
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(date);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                inspectionDetectionInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("INSPECTIONDETECTIONINFO_SEQ")));
                iIdxBizJgInspectionDetectionInfoService.saveOrUpdateData(inspectionDetectionInfo);
            }
        } else {
            if(dataSource.contains("jg_his_black") && InspectIsInPeriodEnum.IN_PERIOD_YES.getValue().equals(registerInfo.getInInspectionPeriod())){
                // 历史无证设备编辑时，只有在选择检验信息齐全时，才更新或者插入检验信息数据[在原本检验信息齐全，而在编辑时选择不齐全时，不修改原有的检验信息]
                IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgInspectionDetectionInfo.class);
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(date);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                inspectionDetectionInfo.setSequenceNbr(String.valueOf(equipmentInfoForm.get("INSPECTIONDETECTIONINFO_SEQ")));
                iIdxBizJgInspectionDetectionInfoService.saveOrUpdateData(inspectionDetectionInfo);
            } else if (CylinderTypeEnum.CYLINDER.getCode().equals(equCategory) || "2100".equals(equCategory)) {
                //更新时 固定式压力容器（2100）和 气瓶（2300）可以更新检验检测信息
                IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(equipmentInfoForm), IdxBizJgInspectionDetectionInfo.class);
                List<Map<String, Object>> inspectionAndTestingInstitutions = commonService.getUnitListByType("inspection", "gasCylindersForCars", false);
                Optional<Map<String, Object>> optional = inspectionAndTestingInstitutions.stream().filter(x -> x.get("useCode").equals(inspectionDetectionInfo.getInspectOrgCode())).findFirst();
                Map<String, Object> mapOrDefault = optional.orElse(Collections.emptyMap());
                inspectionDetectionInfo.setInspectOrgName((String) mapOrDefault.getOrDefault("useUnit", inspectionDetectionInfo.getInspectOrgName()));
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(date);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                inspectionDetectionInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("INSPECTIONDETECTIONINFO_SEQ")));
                iIdxBizJgInspectionDetectionInfoService.saveOrUpdateData(inspectionDetectionInfo);
            }
        }
        // 删除使用信息中的省、市、区下滑线数据，来源详情的getEquipInfoMap的放入
        this.removeDescAfterCode(useInfo);
        // 使用信息
        useInfo.setRecord(record);
        useInfo.setRecDate(date);
        useInfo.setDataSource(dataSource);
        useInfo.setIsIntoManagement(Boolean.FALSE);
        useInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("USEINFO_SEQ")));
        if (companyTypeStr.contains(CompanyTypeEnum.USE.getCode()) || companyTypeStr.contains(CompanyTypeEnum.INDIVIDUAL.getCode())) {
            useInfo.setUseUnitCreditCode(companyInfoMap.get("creditCode").toString());
            useInfo.setUseUnitName(companyInfoMap.get("companyName").toString());
        }
        if (OPERATESAVE.equals(operateType)) {
            useInfo.setCreateDate(date);
        }

        if (isCopy) {
            // 设备状态置空
            useInfo.setEquState("");
            // 如果为安改维单位复制设备，则将使用单位信息置空
            if (companyTypeStr.equals(CompanyTypeEnum.CONSTRUCTION.getCode())) {
                useInfo.setUseUnitCreditCode("");
                useInfo.setUseUnitName("");
            }
            // 如果既为安改维单位又是使用单位，则将厂车、起重机械-流动式起重机、压力容器-气瓶安改维单位信息置空
            if (companyTypeStr.contains(CompanyTypeEnum.CONSTRUCTION.getCode()) && companyTypeStr.contains(CompanyTypeEnum.USE.getCode())) {
                if (!registerInfo.getEquList().equals("5000") && !registerInfo.getEquCategory().equals("4400") && !registerInfo.getEquCategory().equals("2300")) {
                    constructionInfo.setUscUnitCreditCode("");
                    constructionInfo.setUscUnitName("");
                }
            }
        }
        idxBizJgUseInfoService.saveOrUpdateData(useInfo);

        // 设计信息
        designInfo.setRecord(record);
        designInfo.setRecDate(date);
        designInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("DESIGNINFO_SEQ")));
        iIdxBizJgDesignInfoService.saveOrUpdateData(designInfo);

        if (EquipmentClassifityEnum.DT.getCode().equals(equList)) {
            // 维保信息
            maintenanceInfo.setRecord(record);
            maintenanceInfo.setRecDate(date);
            maintenanceInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("MAINTENANCERECORDINFO_SEQ")));
            iIdxBizJgMaintenanceRecordInfoService.saveOrUpdateData(maintenanceInfo);
        }

        // 制造信息
        factoryInfo.setRecord(record);
        factoryInfo.setRecDate(date);
        factoryInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("FACTORYINFO_SEQ")));
        iIdxBizJgFactoryInfoService.saveOrUpdateData(factoryInfo);

        // 施工信息
        String companyName = companyInfoMap.get("companyName").toString();
        String companyCode = companyInfoMap.get("creditCode").toString();
        constructionInfo.setRecord(record);
        constructionInfo.setRecDate(date);

        if (companyTypeStr.contains(CompanyTypeEnum.CONSTRUCTION.getCode())) {
            constructionInfo.setUscUnitCreditCode(companyCode);
            constructionInfo.setUscUnitName(companyName);
        }

        if (isCopy) {
            if (companyTypeStr.equals(CompanyTypeEnum.USE.getCode()) || companyTypeStr.equals(CompanyTypeEnum.INDIVIDUAL.getCode())) {
                constructionInfo.setUscUnitCreditCode("");
                constructionInfo.setUscUnitName("");
            }
            // 如果既为安改维单位又是使用单位，则将厂车、起重机械-流动式起重机、压力容器-气瓶安改维单位信息置空
            if (companyTypeStr.contains(CompanyTypeEnum.CONSTRUCTION.getCode()) && companyTypeStr.contains(CompanyTypeEnum.USE.getCode())) {
                if (registerInfo.getEquList().equals("5000") || registerInfo.getEquCategory().equals("4400") || registerInfo.getEquCategory().equals("2300")) {
                    constructionInfo.setUscUnitCreditCode("");
                    constructionInfo.setUscUnitName("");
                }
            }
        }

        constructionInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("CONSTRUCTIONINFO_SEQ")));
        iIdxBizJgConstructionInfoService.saveOrUpdateData(constructionInfo);

        // 注册登记
        registerInfo.setRecord(record);
        registerInfo.setRecDate(date);
        registerInfo.setRegisterState(this.getRegCode());
        registerInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("REGISTERINFO_SEQ")));
        // 补丁：saveOrUpdate在update数据时不会更新字段为null的字段，但是编辑设备的代码时，从有改成无，equCode解析成null，但是此时需要将equcode删掉
        registerInfo.setEquCode(ObjectUtils.isEmpty(registerInfo.getEquCode()) ? "" : registerInfo.getEquCode());
        // copy设备 =》 使用登记证号置空
        String useOrgCode = ValidationUtil.isEmpty(equipmentInfoForm.get("useRegistrationCode")) ? "" : String.valueOf(equipmentInfoForm.get("useRegistrationCode"));
        registerInfo.setUseOrgCode(isCopy && !"1".equals(equipmentInfoForm.get("WHETHER_VEHICLE_CYLINDER")) ? "" : useOrgCode);
        this.saveOrUpdate(registerInfo);

        // 监督管理
        supervisionInfo.setRecord(record);
        supervisionInfo.setRecDate(date);
        supervisionInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("SUPERVISIONINFO_SEQ")));
        iIdxBizJgSupervisionInfoService.saveOrUpdateData(supervisionInfo);

        // 其他信息
        otherInfo.setRecord(record);
        otherInfo.setClaimStatus("已认领");
        otherInfo.setRecDate(date);
        otherInfo.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentInfoForm.get("OTHERINFO_SEQ")));
        if (isCopy) {
            // 复制且有无96333识别码选择 无 96333码置空
            if ("2".equals(otherInfo.getCode96333Type())) {
                otherInfo.setCode96333(null);
            }
            // 监管码置空
            otherInfo.setSupervisoryCode("");
            otherInfo.setCylinderStampAttachment("");
            otherInfo.setInformationSituation("");
            otherInfo.setInformationManageCode("");
        }
        // 编辑时，如果选择<无96333识别码>，则把已经入库的数据清除掉
        if (OPERATEEDIT.equals(operateType) && "2".equals(otherInfo.getCode96333Type())) {
            otherInfo.setCode96333(null);
        }
        iIdxBizJgOtherInfoService.saveOrUpdateData(otherInfo);
        // 保存或者更新设备技术参数
        this.saveOrUpdateEquParams(equipmentInfoForm, equipmentParamsForm, equList, record, date, operateType);
        if(OPERATESAVE.equals(operateType)){
            // 记录设备创建履历
            this.createResume(record, String.format(equipRoutePath, record, useInfo.getDataSource()), company);
        }
        return record;
    }

    private void createResume(String record, String routePath, CompanyBo company) {
        jgResumeInfoService.saveBatchResume(Collections.singletonList(JgResumeInfoDto.builder()
                .businessType(BusinessTypeEnum.JG_NEW_EQUIP.getName())
                .businessId(record)
                .equId(record)
                .status("正常")
                .approvalUnitCode(company.getCompanyCode())
                .approvalUnit(company.getCompanyName())
                .changeContent(BusinessTypeEnum.JG_NEW_EQUIP.getName() + "业务办理")
                .routePath(routePath)
                .build())
        );
    }

    /**
     * 保存或者更新设备技术参数
     * @param equipmentInfoForm
     * @param equipmentParamsForm
     * @param equList
     * @param record
     * @param date
     * @param operateType
     */
    public void saveOrUpdateEquParams(LinkedHashMap equipmentInfoForm, LinkedHashMap equipmentParamsForm, String equList, String record, Date date, String operateType) {
        // 八大类技术参数和主要零部件和安全附件表
        List<IdxBizJgMainParts> mainPartsList = new ArrayList<>();
        List<IdxBizJgProtectionDevices> protectionDevicesList = new ArrayList<>();
        // 统一设置所有 SEQ 字段
        Object params = techParamsBackupService.getTechParams(equList, record);

        // 电梯
        if (EquipmentClassifityEnum.DT.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsElevator) {
                equipmentParamsForm.put("ELEVATOR_SEQ", ((IdxBizJgTechParamsElevator) params).getSequenceNbr());
            }
            IdxBizJgTechParamsElevator elevator = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsElevator.class);
            if (!ValidationUtil.isEmpty(elevator)) {
                elevator.setRecord(record);
                elevator.setRecDate(date);
                elevator.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("ELEVATOR_SEQ")));
                iIdxBizJgTechParamsElevatorService.saveOrUpdateData(elevator);
            }
        }
        // 厂车
        else if (EquipmentClassifityEnum.CC.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsVehicle) {
                equipmentParamsForm.put("VEHICLE_SEQ", ((IdxBizJgTechParamsVehicle) params).getSequenceNbr());
            }
            IdxBizJgTechParamsVehicle vehicle = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsVehicle.class);
            if (!ValidationUtil.isEmpty(vehicle)) {
                vehicle.setRecord(record);
                vehicle.setRecDate(date);
                vehicle.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("VEHICLE_SEQ")));
                iIdxBizJgTechParamsVehicleService.saveOrUpdateData(vehicle);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_sey164b51a");
            subFormMainPartsList.add("subForm_tef7yf5fbr");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);

        }
        // 索道
        else if (EquipmentClassifityEnum.KYSD.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsRopeway) {
                equipmentParamsForm.put("ROPEWAY_SEQ", ((IdxBizJgTechParamsRopeway) params).getSequenceNbr());
            }
            IdxBizJgTechParamsRopeway ropeway = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsRopeway.class);
            if (!ValidationUtil.isEmpty(ropeway)) {
                ropeway.setRecord(record);
                ropeway.setRecDate(date);
                ropeway.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("ROPEWAY_SEQ")));
                iIdxBizJgTechParamsRopewayService.saveOrUpdateData(ropeway);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_5fi0jewuyh");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);

        }
        // 游乐设施
        else if (EquipmentClassifityEnum.YLSS.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsRides) {
                equipmentParamsForm.put("RIDES_SEQ", ((IdxBizJgTechParamsRides) params).getSequenceNbr());
            }
            IdxBizJgTechParamsRides rides = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsRides.class);
            if (!ValidationUtil.isEmpty(rides)) {
                rides.setRecord(record);
                rides.setRecDate(date);
                rides.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("RIDES_SEQ")));
                iIdxBizJgTechParamsRidesService.saveOrUpdateData(rides);
            }
        }
        // 锅炉
        else if (EquipmentClassifityEnum.GL.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsBoiler) {
                equipmentParamsForm.put("BOILER_SEQ", ((IdxBizJgTechParamsBoiler) params).getSequenceNbr());
            }
            IdxBizJgTechParamsBoiler boiler = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsBoiler.class);
            if (!ValidationUtil.isEmpty(boiler)) {
                boiler.setRecord(record);
                boiler.setRecDate(date);
                boiler.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("BOILER_SEQ")));
                iIdxBizJgTechParamsBoilerService.saveOrUpdateData(boiler);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_1hh88r4m69");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);
        }
        // 压力容器
        else if (EquipmentClassifityEnum.YLRQ.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsVessel) {
                equipmentParamsForm.put("VESSEL_SEQ", ((IdxBizJgTechParamsVessel) params).getSequenceNbr());
            }
            IdxBizJgTechParamsVessel vessel = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsVessel.class);
            if (!ValidationUtil.isEmpty(vessel)) {
                vessel.setRecord(record);
                vessel.setRecDate(date);
                String VIN = ValidationUtil.isEmpty(equipmentInfoForm.get("identificationCode")) ? "" : (String) equipmentInfoForm.get("identificationCode");
                vessel.setVin(VIN);
                vessel.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("VESSEL_SEQ")));
                iIdxBizJgTechParamsVesselService.saveOrUpdateData(vessel);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_fie04854f2");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);

            // 安全附件
            List<String> subFormProtectionDevicesList = new ArrayList<>();
            subFormProtectionDevicesList.add("subForm_d4xdzhsgdj");
            protectionDevicesList = this.getAccessoryEntity(equipmentParamsForm, subFormProtectionDevicesList, EQUIP_PROTECTIONDEVICES_FORM_ID, record, date, operateType);

        }
        // 压力管道
        else if (EquipmentClassifityEnum.YLGD.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsPipeline) {
                equipmentParamsForm.put("PIPELINE_SEQ", ((IdxBizJgTechParamsPipeline) params).getSequenceNbr());
            }
            IdxBizJgTechParamsPipeline pipeline = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsPipeline.class);
            if (!ValidationUtil.isEmpty(pipeline)) {
                pipeline.setRecord(record);
                pipeline.setRecDate(date);
                pipeline.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("PIPELINE_SEQ")));
                iIdxBizJgTechParamsPipelineService.saveOrUpdateData(pipeline);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_9n7nu55z8r");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);

        }
        // 起重机械
        else if (EquipmentClassifityEnum.QZJX.getCode().equals(equList)) {
            if (params instanceof IdxBizJgTechParamsLifting) {
                equipmentParamsForm.put("LIFTING_SEQ", ((IdxBizJgTechParamsLifting) params).getSequenceNbr());
            }
            IdxBizJgTechParamsLifting lifting = JSON.parseObject(toJSONString(equipmentParamsForm), IdxBizJgTechParamsLifting.class);
            if (!ValidationUtil.isEmpty(lifting)) {
                lifting.setRecord(record);
                lifting.setRecDate(date);
                lifting.setSequenceNbr(OPERATESAVE.equals(operateType) ? null : String.valueOf(equipmentParamsForm.get("LIFTING_SEQ")));
                iIdxBizJgTechParamsLiftingService.saveOrUpdateData(lifting);
            }

            // 主要零部件
            List<String> subFormMainPartsList = new ArrayList<>();
            subFormMainPartsList.add("subForm_bqirdyvztt");
            mainPartsList = this.getAccessoryEntity(equipmentParamsForm, subFormMainPartsList, EQUIP_MAINPARTS_FORM_ID, record, date, operateType);

            // 安全附件
            List<String> subFormProtectionDevicesList = new ArrayList<>();
            subFormProtectionDevicesList.add("subForm_29yy3pdzhl");
            subFormProtectionDevicesList.add("subForm_h5h4x0zhur");
            protectionDevicesList = this.getAccessoryEntity(equipmentParamsForm, subFormProtectionDevicesList, EQUIP_PROTECTIONDEVICES_FORM_ID, record, date, operateType);

        }

        // 八大类技术参数和主要零部件和安全附件表
        if (!ValidationUtil.isEmpty(mainPartsList)) {
            iIdxBizJgMainPartsService.saveOrUpdateBatchData(mainPartsList);
        }
        if (!ValidationUtil.isEmpty(protectionDevicesList)) {
            iIdxBizJgProtectionDevicesService.saveOrUpdateBatchData(protectionDevicesList);
        }
    }

    /**
     * province、city、county
     * 删除由于详情返回拼接的code_name的_name,只保留code，否则回导致数据被保存为610423_泾阳县这样结构
     * @param useInfo 使用信息
     */
    private void removeDescAfterCode(IdxBizJgUseInfo useInfo) {
        if(useInfo.getProvince() != null && useInfo.getProvince().contains("_")){
            String[] str = useInfo.getProvince().split("_");
            useInfo.setProvince(str[0]);
        }
        if(useInfo.getCity() != null && useInfo.getCity().contains("_")){
            String[] str = useInfo.getCity().split("_");
            useInfo.setCity(str[0]);
        }
        if(useInfo.getCounty() != null && useInfo.getCounty().contains("_")){
            String[] str = useInfo.getCounty().split("_");
            useInfo.setCounty(str[0]);
        }
    }

    private String getDataSource(String operateType, LinkedHashMap equipmentInfoForm) {
        // 数据来源 历史数据his 新数据new
        String equipSource = String.valueOf(equipmentInfoForm.get(DATA_SOURCE));
        return "new".equals(equipSource) ? "jg"
                : "his".equals(equipSource) ? "jg_his"
                : "black".equals(equipSource) ? "jg_his_black"
                : equipSource;
    }

    public void checkEsData(String id) {
        Map<String, Object> map = categoryOtherInfoMapper.selectDataById(id);
        categoryOtherInfoMapper.updateEsStatus(id);
        ESEquipmentCategoryDto dto = JSON.parseObject(toJSONString(map), ESEquipmentCategoryDto.class);
        Optional<ESEquipmentCategoryDto> data = esEquipmentCategory.findById(id);
        if (!ObjectUtils.isEmpty(data)) {
            esEquipmentCategory.deleteById(id);
        }
        if (!ObjectUtils.isEmpty(dto)) {
            long recTime;
            long createTime;
            if (ValidationUtil.isEmpty(map.get("CREATE_DATE"))) {
                createTime = System.currentTimeMillis();
            } else {
                createTime = Timestamp.valueOf(map.get("CREATE_DATE").toString().substring(0, 19)).getTime();
            }
            if (ValidationUtil.isEmpty(map.get("REC_DATE"))) {
                recTime = System.currentTimeMillis();
            } else {
                recTime = Timestamp.valueOf(map.get("REC_DATE").toString().substring(0, 19)).getTime();
            }
            dto.setREC_DATE(recTime);
            dto.setCREATE_DATE(createTime);
            // 需要安装的设备 安装告知审批通过 清除设备的USC_UNIT_CREDIT_CODE安装单位信息
            // 使用单位编辑 防止更新设备时将安改维单位信息更新到es中
            CompanyBo company = getSelectedOrgInfo().getCompany();
            if (CompanyTypeEnum.USE.getName().equals(company.getCompanyType())) {
                dto.setUSC_UNIT_CREDIT_CODE(null);
                dto.setUSC_UNIT_NAME(null);
            }
            if (map.get("NEXT_INSPECT_DATE") != null) {
                Date nextInspectDate = (Date) map.get("NEXT_INSPECT_DATE");
                dto.setNEXT_INSPECT_DATE(DateUtil.parse(DateUtil.format(nextInspectDate, DatePattern.NORM_DATE_PATTERN)).getTime());
            }
            this.setWhetherSphericalTank(dto);
            equipmentCategoryService.saveWithImmediateRefresh(dto);
        }
    }

    private void setWhetherSphericalTank(ESEquipmentCategoryDto dto) {
        IdxBizJgRegisterInfo registerInfo = idxBizJgRegisterInfoService.getOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, dto.getSEQUENCE_NBR()).select(IdxBizJgRegisterInfo::getRecord, IdxBizJgRegisterInfo::getWhetherSphericalTank));
        dto.setWhetherSphericalTank(registerInfo.getWhetherSphericalTank());
    }

    private List getAccessoryEntity(Map<String, Object> map, List<String> list, String subFormType, String record, Date date, String type) {
        List<IdxBizJgMainParts> mainPartsList = new ArrayList<>();
        List<IdxBizJgProtectionDevices> protectionDevicesList = new ArrayList<>();

        if (EQUIP_MAINPARTS_FORM_ID.equals(subFormType) && !ValidationUtil.isEmpty(list)) {
            for (Object s : list) {
                JSONArray subFormMainPartsList = JSON.parseArray(toJSONString(map.get(s)));
                if (!ObjectUtils.isEmpty(subFormMainPartsList)) {
                    subFormMainPartsList.forEach(data -> {
                        JSONObject jsonObject = (JSONObject) data;
                        IdxBizJgMainParts mainParts = jsonObject.toJavaObject(IdxBizJgMainParts.class);
                        mainParts.setRecord(record);
                        mainParts.setRecDate(date);
                        mainParts.setSequenceNbr("save".equals(type) ? null : String.valueOf(jsonObject.get("MAINPARTS_SEQ")));
                        mainPartsList.add(mainParts);
                    });
                }
            }
            return mainPartsList;
        } else if (EQUIP_PROTECTIONDEVICES_FORM_ID.equals(subFormType) && !ValidationUtil.isEmpty(list)) {
            for (Object s : list) {
                JSONArray subFormProtectionDevicesList = JSON.parseArray(toJSONString(map.get(s)));
                if (!ObjectUtils.isEmpty(subFormProtectionDevicesList)) {
                    for (Object obj : subFormProtectionDevicesList) {
                        JSONObject jsonObject = (JSONObject) obj;
                        IdxBizJgProtectionDevices protectionDevices = jsonObject.toJavaObject(IdxBizJgProtectionDevices.class);
                        protectionDevices.setRecord(record);
                        protectionDevices.setRecDate(date);
                        protectionDevices.setSequenceNbr("save".equals(type) ? null : String.valueOf(jsonObject.get("PROTECTIONDEVICES_SEQ")));
                        protectionDevicesList.add(protectionDevices);
                    }
                }
            }
            return protectionDevicesList;
        }
        return null;
    }

    @Override
    public Page<JSONObject> queryForUnitEquipmentPage(JSONObject jsonObject) {
        String useUnitCreditCode = Objects.toString(jsonObject.get(USE_UNIT_CREDIT_CODE), "");
        String[] recordList = null;
        if (ValidationUtil.isEmpty(useUnitCreditCode)) {
            String redisVal = String.valueOf(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())));
            if (StringUtils.isNotEmpty(redisVal)) {
                ReginParams params = JSON.parseObject(redisVal, ReginParams.class);
                useUnitCreditCode = Optional.ofNullable(params)
                        .map(ReginParams::getCompany)
                        .map(CompanyBo::getCompanyCode)
                        .orElse("");
                useUnitCreditCode = useUnitCreditCode.contains("_") ? useUnitCreditCode.split("_")[1] : useUnitCreditCode;
            }
            Set<String> records = EquipUsedCheckStrategyContext.getUsedStrategy("useRegistration").getEquipInFlow(useUnitCreditCode);
            recordList= ValidationUtil.isEmpty(records) ? null : records.toArray(new String[records.size()]);
        } else {
            useUnitCreditCode = useUnitCreditCode.contains("_") ? useUnitCreditCode.split("_")[0] : useUnitCreditCode;
        }
        jsonObject.put(USE_UNIT_CREDIT_CODE, useUnitCreditCode);
        Page<JSONObject> page = new Page<>(jsonObject.getLong("number"), jsonObject.getLong("size"));
        if ("2300".equals(jsonObject.get(EQU_CATEGORY_CODE))) {// 气瓶
            List<DictionarieValueModel> fillingMedium = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM").getResult();
            Map<String, Object> fillingMediumMap = fillingMedium.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));
            Page<JSONObject> result = jgUseRegistrationMapper.queryForUnitVesselEquipmentPage(page, jsonObject, recordList);
            result.getRecords().forEach(i -> {
                i.put("chargingMedium", MapUtil.getStr(fillingMediumMap, "chargingMedium", ""));
                i.put("sequenceNbr", MapUtil.getStr(i, "record"));
                i.put("productPhoto", JSONArray.parseArray(i.getString("productPhoto")));
                i.put("cylinderStampAttachment", JSONArray.parseArray(i.getString("cylinderStampAttachment")));
                i.put("informationSituation",InformationManageTypeEnum.getName(i.getString("informationSituation")));
                i.put("dataQualityScore", commonServiceImpl.castDataQualityScore2Name(i.getString("dataQualityScore"), !ValidationUtil.isEmpty(i.getString("isIntoManagement")) && (Boolean) i.get("isIntoManagement")));
            });
            return result;
        }
        return page;
    }

    @Override
    public Page<JSONObject> queryEquipCanUsedByVesselPage(JSONObject jsonObject) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        String useUnitCreditCode = reginParams.getCompany().getCompanyCode();
        // 使用单位为个人时候 特殊处理
        if (useUnitCreditCode.split("_").length > 1) {
            useUnitCreditCode = useUnitCreditCode.split("_")[1];
        }
        jsonObject.put("useUnitCreditCode", useUnitCreditCode);
        Page<JSONObject> page = new Page<>(jsonObject.getLong("number"), jsonObject.getLong("size"));
        List<DictionarieValueModel> fillingMedium = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM").getResult();
        Map<String, Object> fillingMediumMap = fillingMedium.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));
        Page<JSONObject> result = jgUseRegistrationMapper.queryForEquipUsedByVehiclePage(page, jsonObject);
        result.getRecords().forEach(i -> {
            i.put("chargingMedium", Optional.ofNullable(fillingMediumMap.get(i.get("chargingMedium"))).orElse(""));
            i.put("productPhoto", JSONArray.parseArray(i.getString("productPhoto")));
            i.put("cylinderStampAttachment", JSONArray.parseArray(i.getString("cylinderStampAttachment")));
            i.put("informationSituation",InformationManageTypeEnum.getName(i.getString("informationSituation")));
        });
        return result;
    }

    @Override
    public Page<JSONObject> queryEquipCanUsedByVesselPageHistory(JSONObject jsonObject) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        String useUnitCreditCode = reginParams.getCompany().getCompanyCode();
        // 使用单位为个人时候 特殊处理
        if (useUnitCreditCode.split("_").length > 1) {
            useUnitCreditCode = useUnitCreditCode.split("_")[1];
        }
        jsonObject.put("useUnitCreditCode", useUnitCreditCode);
        Page<JSONObject> page = new Page<>(jsonObject.getLong("number"), jsonObject.getLong("size"));
        List<DictionarieValueModel> fillingMedium = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM").getResult();
        Map<String, Object> fillingMediumMap = fillingMedium.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));
        Page<JSONObject> result = jgUseRegistrationMapper.queryForEquipUsedByVehiclePageHistory(page, jsonObject);
        result.getRecords().forEach(i -> {
            i.put("chargingMedium", Optional.ofNullable(fillingMediumMap.get(i.get("chargingMedium"))).orElse(""));
            i.put("productPhoto", JSONArray.parseArray(i.getString("productPhoto")));
            i.put("cylinderStampAttachment", JSONArray.parseArray(i.getString("cylinderStampAttachment")));
            i.put("informationSituation",InformationManageTypeEnum.getName(i.getString("informationSituation")));
        });
        return result;
    }

    @Override
    public String importPressureVesselData(Map<String, Object> paramMap, MultipartFile multipartFile) {
        try {
            PressureVesselListener pressureVesselListener = new PressureVesselListener();
            LinkedHashMap equipmentInfoForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_INFO_FORM_ID));
            injectDependencies(pressureVesselListener, equipmentInfoForm);
            EasyExcel.read(multipartFile.getInputStream(), EquipInfoCylinderExcelDto.class, pressureVesselListener)
                    .headRowNumber(4)
                    .sheet()
                    .doRead();
            return pressureVesselListener.getResult();
        } catch (Exception e) {
            String err = (e.getCause() instanceof BadRequest) ? "模版数据填写有误：" + e.getCause().getMessage() : "导入时出现异常：请联系管理员！";
            throw new BadRequest(err);
        }
    }

    @Override
    public Object importPressureData(MultipartFile multipartFile) throws Exception {
        List<EquipInfoCylinderExcelDto> aircraftList = new ArrayList<>();
        resultError.clear();
        useInnerCodeList.clear();
        equCodeList.clear();
        factoryNumList.clear();
        try {
            String templateVersionError = DataDockTemplateVersionUtils.checkTemplateVersion(multipartFile);
            if (!ValidationUtil.isEmpty(templateVersionError)) {
                resultError.add(templateVersionError);
                throw new BadRequest(templateVersionError);
            }

            EasyExcel.read(multipartFile.getInputStream(), EquipInfoCylinderExcelDto.class,
                    new AnalysisEventListener<EquipInfoCylinderExcelDto>() {
                        @Override
                        public void invoke(EquipInfoCylinderExcelDto data, AnalysisContext context) {
                            EquipInfoCylinderExcelDto copy = new EquipInfoCylinderExcelDto();
                            BeanUtils.copyProperties(data, copy);
                            aircraftList.add(copy);
                            useInnerCodeList.add(data.getUseInnerCode());
                            String checkMsg = checkExcelData(data, context).toString();
                            if (!checkMsg.isEmpty()) {
                                resultError.add(checkMsg);
                            }
                            // 限制最大上传数量
                            if (aircraftList.size() > MAX_UPLOAD) {
                                resultError.add("每次最多允许上传 " + MAX_UPLOAD + " 条数据，请分批上传！");
                                throw new BadRequest(resultError.stream().filter(s -> !s.isEmpty()).collect(Collectors.joining("<br/>")));
                            }
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                            if (CollectionUtils.isEmpty(aircraftList)) {
                                String msg = "你上传了一个空数据的Excel文档!";
                                resultError.add(msg);
                                throw new BadRequest(msg);
                            }
                        }
                    }).headRowNumber(4).sheet().doRead();

            if (resultError.stream().anyMatch(s -> !s.isEmpty())) {
                throw new BadRequest("上传失败！");
            }

            List<String> warnings = checkExcelDuplicates(aircraftList);

            Set<String> nonVehicleKeys = new HashSet<>();
            Set<String> vehicleFactoryNums = new HashSet<>();
            Set<String> equCodeKeys = new HashSet<>();

            for (EquipInfoCylinderExcelDto data : aircraftList) {
                if ("1".equals(data.getEquCodeType()) && StringUtils.isNotEmpty(data.getEquCode())) {
                    equCodeKeys.add(data.getEquCode());
                }
                if ("0".equals(data.getWhetherVehicleCylinder())) { // 非车用
                    if (StringUtils.isNotEmpty(data.getProduceUnitCreditCode()) &&
                            StringUtils.isNotEmpty(data.getFactoryNum())) {
                        nonVehicleKeys.add(data.getProduceUnitCreditCode() + "_" + data.getFactoryNum());
                    }
                } else { // 车用
                    if (StringUtils.isNotEmpty(data.getFactoryNum())) {
                        vehicleFactoryNums.add(data.getFactoryNum());
                    }
                }
            }

            Map<String, String> nonVehicleMap = batchQueryEs(nonVehicleKeys, true);//普通气瓶
            Map<String, String> vehicleMap = batchQueryEs(vehicleFactoryNums, false);//车用气瓶

            List<String> equCodes = new ArrayList<>();
            for (EquipInfoCylinderExcelDto data : aircraftList) {
                String exist;
                if ("0".equals(data.getWhetherVehicleCylinder())) {
                    exist = nonVehicleMap.get(data.getFactoryNum());
                } else {
                    exist = vehicleMap.get(data.getFactoryNum());
                }
                if (exist != null) {
                    warnings.add(String.format("制造单位[%s]生产的出厂编号为[%s]的气瓶，已被[%s]录入系统，请核实！", data.getProduceUnitName(), data.getFactoryNum(), exist));
                }
                //校验设备代码重复
                equCodes = this.checkEquCodeExist(equCodeKeys);
            }
            if (!equCodes.isEmpty()) {
                resultError.add("导入气瓶模板中，以下设备代码系统中已存在: " + String.join(",", equCodes));
            }
            if (!warnings.isEmpty()) {
                resultError.addAll(warnings);
                throw new BadRequest(resultError.stream().filter(s -> !s.isEmpty()).collect(Collectors.joining("<br/>")));
            }
            return aircraftList;
        } catch (Exception e) {
            throw new Exception(resultError.stream().filter(s -> !s.isEmpty()).collect(Collectors.joining("<br/>")));
        }
    }

    private List<String> checkEquCodeExist(Set<String> equCodeKeys) throws IOException {
        List<String> equCodes;
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
                .must(QueryBuilders.termsQuery("EQU_CODE", equCodeKeys))
                .must(QueryBuilders.termQuery("STATUS", "已认领"));

        SearchRequest request = new SearchRequest(IDX_BIZ_VIEW_JG_ALL);
        request.source(new SearchSourceBuilder()
                .query(boolQuery)
                .fetchSource(new String[]{"EQU_CODE"}, null)
                .size(10000)
        );

        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        equCodes = Arrays.stream(response.getHits().getHits())
                .map(hit -> (String) hit.getSourceAsMap().get("EQU_CODE"))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        return equCodes;
    }

    /** Excel 内部重复校验 */
    private List<String> checkExcelDuplicates(List<EquipInfoCylinderExcelDto> list) {
        List<String> warnings = new ArrayList<>();
        Set<String> nonVehicleSet = new HashSet<>();
        Set<String> vehicleSet = new HashSet<>();

        for (EquipInfoCylinderExcelDto data : list) {
            if ("0".equals(data.getWhetherVehicleCylinder())) {
                String key = data.getProduceUnitCreditCode() + "_" + data.getFactoryNum();
                if (!nonVehicleSet.add(key)) {
                    warnings.add(String.format(
                            "您上传的Excel内部发现重复：制造单位[%s]生产的出厂编号为[%s]的气瓶重复！",
                            data.getProduceUnitName(), data.getFactoryNum()));
                }
            } else {
                String key = data.getFactoryNum();
                if (!vehicleSet.add(key)) {
                    warnings.add(String.format(
                            "您上传的Excel内部发现重复：车用气瓶出厂编号[%s]重复！",
                            data.getFactoryNum()));
                }
            }
        }
        return warnings;
    }

    /** 批量查询 ES */
    private Map<String, String> batchQueryEs(Set<String> keys, boolean nonVehicle) throws IOException {
        Map<String, String> resultMap = new HashMap<>();
        if (CollectionUtils.isEmpty(keys)) return resultMap;

        SearchRequest request = new SearchRequest(IDX_BIZ_EQUIPMENT_INFO);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().size(10000)
                .fetchSource(new String[]{"FACTORY_NUM", "USE_UNIT_NAME"}, null);

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("EQU_LIST_CODE", "2000"))
                .must(QueryBuilders.termQuery("EQU_CATEGORY_CODE", "2300"))
                .must(QueryBuilders.termQuery("STATUS", "已认领"));
        if (nonVehicle) {
            List<String> creditCodes = keys.stream()
                    .map(k -> k.substring(0, k.indexOf('_')))
                    .collect(Collectors.toList());
            List<String> factoryNums = keys.stream()
                    .map(k -> k.substring(k.indexOf('_') + 1))
                    .collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery("FACTORY_NUM", factoryNums))
                    .must(QueryBuilders.termsQuery("produceUnitCreditCode", creditCodes));
        } else {
            boolQuery.must(QueryBuilders.termsQuery("FACTORY_NUM", keys))
                    .must(QueryBuilders.termQuery("EQU_DEFINE_CODE", "23T0"))
                    .must(QueryBuilders.termQuery("WHETHER_VEHICLE_CYLINDER", "1"));
        }
        sourceBuilder.query(boolQuery);
        request.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> src = hit.getSourceAsMap();
            String factoryNum = Objects.toString(src.get("FACTORY_NUM"), "");
            String useUnitName = Objects.toString(src.get("USE_UNIT_NAME"), "");
            resultMap.put(factoryNum, useUnitName);
        }
        return resultMap;
    }

    private String getUrlByKey(List<Map<String, Object>> dataList, String key) {
        if (dataList == null || dataList.isEmpty()) {
            return null;
        }
        for (Map<String, Object> item : dataList) {
            if (key.equals(item.get("key"))) {
                return toJSONString(item.get("value"));
            }
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object savePressureVesselData(Map<String, Object> paramMap) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        CompanyBo company = reginParams.getCompany();
        List<IdxBizJgUseInfo> useInfoList = new ArrayList<>();
        List<IdxBizJgRegisterInfo> registerInfoList = new ArrayList<>();
        List<IdxBizJgDesignInfo> designInfoList = new ArrayList<>();
        List<IdxBizJgFactoryInfo> factoryInfoList = new ArrayList<>();
        List<IdxBizJgOtherInfo> otherInfoList = new ArrayList<>();
        List<IdxBizJgTechParamsVessel> paramsVesselList = new ArrayList<>();
        List<IdxBizJgInspectionDetectionInfo> inspectionDetectionInfoList = new ArrayList<>();
        List<ESEquipmentCategoryDto> esEquipmentCategoryList = new ArrayList<>();
        List<JgUseRegistrationEq> jgRelationEquipList = new ArrayList<>();
        List<Map<String, Object>> equipmentLists = new ArrayList<>();
        List<IdxBizJgSupervisionInfo> supervisionInfoList = new ArrayList<>();
        List<JgCertificateChangeRecordEq> jgCertificateChangeRecordEqList = new ArrayList<>();

        if (paramMap == null) {
            throw new IllegalArgumentException("参数Map不能为空");
        }
        LinkedHashMap equipmentInfoForm = (LinkedHashMap) checkAndCast(paramMap.get(EQUIP_INFO_FORM_ID));
        LinkedHashMap attachmentUpload = (LinkedHashMap) checkAndCast(paramMap.get(ATTACHMENT_UPLOAD));
        EquipmentInfoDto equipInfoDto = this.createEquipmentInfoDto(equipmentInfoForm, jgVehicleInformationMapper);
        // 登记证记录表主键
        Long changeRecordId = sequence.nextId();
        List<EquipInfoCylinderExcelDto> equipInfoCylinderExcelDtoList = JSON.parseArray(toJSONString(attachmentUpload.get(EQU_LISTS)), EquipInfoCylinderExcelDto.class);
        // 属地监管部门
        String orgBranchCode = equipInfoDto.getOrgBranchCode();
        String orgBranchName = equipInfoDto.getOrgBranchName();
        Set<String> recordSet = new HashSet<>();
        List<DictionarieValueModel> fillingMedium = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM").getResult();
        Map<String, Object> fillingMediumMap = fillingMedium.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataValue,
                DictionarieValueModel::getDictDataKey));
        Iterator<String> supervisoryCodeIterator;
        if ("his".equals(equipInfoDto.getDataSource())) {
            supervisoryCodeIterator = this
                    .getSupervisoryCodeBatch(equipInfoDto.getPossession(), equipInfoDto.getEquCategoryCode(), equipInfoCylinderExcelDtoList.size())
                    .iterator();
        } else {
            supervisoryCodeIterator = Collections.emptyIterator();
        }
        equipInfoCylinderExcelDtoList.forEach(data -> {
            JgUseRegistrationEq jgRelationEquip = new JgUseRegistrationEq();
            if ("his".equals(equipInfoDto.getDataSource()) && "1".equals(data.getWhetherVehicleCylinder())) {
                throw new BadRequest("车用气瓶历史设备不能批量导入!");
            }
            if ("1".equals(data.getWhetherVehicleCylinder()) && !SPECIAL_CYLINDER.getCode().equals(equipInfoDto.getEquDefineCode())) {
                throw new BadRequest("车用气瓶只能选择特种气瓶进行导入!");
            }

            if ("his".equals(equipInfoDto.getDataSource())) {
                //使用登记证编号判断是否使用未来系统生成编号
                this.checkUseRegistrationCode(equipInfoDto.getUseOrgCode(), "cylinder");
            }
            String record = UUID.randomUUID().toString();
            recordSet.add(record);
            jgRelationEquip.setEquId(record);
            jgRelationEquip.setSequenceNbr(sequence.nextId());
            jgRelationEquipList.add(jgRelationEquip);

            List<Map<String, Object>> fileDataList = (List<Map<String, Object>>) (data.getFileData());
            String productPhoto = getUrlByKey(fileDataList, "PRODUCT_PHOTO");
            String otherAccessoriesReg = getUrlByKey(fileDataList, "OTHER_ACCESSORIES_REG");
            String designDoc = getUrlByKey(fileDataList, "DESIGN_DOC");
            String designStandard = getUrlByKey(fileDataList, "DESIGN_STANDARD");
            String otherAccessoriesDes = getUrlByKey(fileDataList, "OTHER_ACCESSORIES_DES");
            String productQualityYieldProve = getUrlByKey(fileDataList, "PRODUCT_QUALITY_YIELD_PROVE");
            String factoryStandard = getUrlByKey(fileDataList, "FACTORY_STANDARD");
            String insUseMaintainExplain = getUrlByKey(fileDataList, "INS_USE_MAINTAIN_EXPLAIN");
            String otherAccessoriesFact = getUrlByKey(fileDataList, "OTHER_ACCESSORIES_FACT");
            String factSupervisionInspectionReport = getUrlByKey(fileDataList, "FACT_SUPERVISION_INSPECTION_REPORT");
            // 使用信息
            IdxBizJgUseInfo useInfo = new IdxBizJgUseInfo();
            BeanUtils.copyProperties(data, useInfo);
            useInfo.setRecord(record);
            useInfo.setRecDate(new Date());
            useInfo.setCreateDate(new Date());
            String source = equipInfoDto.getDataSource();
            useInfo.setDataSource("his".equals(source) ? "jg_his_pl" : "black".equals(source) ? "jg_his_black_pl" : "jg_pl");// 区分历史设备和新增设备
            useInfo.setIsIntoManagement("his".equals(equipInfoDto.getDataSource()));// 历史气瓶导入为已纳管设备

            // 历史气瓶导入设备状态为在用
            String equState = "his".equals(equipInfoDto.getDataSource())
                    ? (Optional.ofNullable(equipInfoDto.getEquState())
                    .filter(s -> !s.isEmpty())
                    .orElse(String.valueOf(EquimentEnum.ZAIYONG.getCode())))
                    : String.valueOf(EquimentEnum.WEIDENGJI.getCode());
            useInfo.setEquState(equState);
            useInfo.setDataQualityScore(StringUtils.isEmpty(equipInfoDto.getUseOrgCode()) ? 3 : 1);
            // 使用单位信息
            if ("个人主体".equals(company.getCompanyType())) {
                useInfo.setUseUnitCreditCode(company.getCompanyCode().split("_")[1]);
                useInfo.setUseUnitName(company.getCompanyName().split("_")[1]);
            } else {
                useInfo.setUseUnitCreditCode(company.getCompanyCode());
                useInfo.setUseUnitName(company.getCompanyName());
            }
            useInfoList.add(useInfo);

            // 设计信息
            IdxBizJgDesignInfo designInfo = new IdxBizJgDesignInfo();
            BeanUtils.copyProperties(data, designInfo);
            designInfo.setRecord(record);
            designInfo.setRecDate(new Date());
            if (data.getDesignDate() != null) {
                designInfo.setDesignDate(DateUtil.parse(data.getDesignDate(), "yyyy-MM-dd"));
            }
            designInfo.setDesignDoc(designDoc);
            designInfo.setDesignStandard(designStandard);
            designInfo.setDesignIsComplete("2");
            designInfo.setOtherAccessoriesDes(otherAccessoriesDes);
            designInfoList.add(designInfo);

            // 制造信息
            IdxBizJgFactoryInfo factoryInfo = new IdxBizJgFactoryInfo();
            BeanUtils.copyProperties(data, factoryInfo);
            factoryInfo.setRecord(record);
            factoryInfo.setRecDate(new Date());
            factoryInfo.setProductQualityYieldProve(productQualityYieldProve);
            factoryInfo.setFactoryStandard(factoryStandard);
            factoryInfo.setInsUseMaintainExplain(insUseMaintainExplain);
            factoryInfo.setOtherAccessoriesFact(otherAccessoriesFact);
            factoryInfo.setFactSupervisionInspectionReport(factSupervisionInspectionReport);
            Optional.ofNullable(data.getProduceDate())
                    .filter(s -> !s.trim().isEmpty())
                    .map(d -> DateUtil.parse(d, "yyyy-MM-dd"))
                    .ifPresent(factoryInfo::setProduceDate);
            factoryInfo.setImported(Optional.ofNullable(data.getImported()).orElse("0"));
            factoryInfo.setFactoryIsComplete("2");
            factoryInfoList.add(factoryInfo);

            // 注册登记
            IdxBizJgRegisterInfo registerInfo = new IdxBizJgRegisterInfo();
            BeanUtils.copyProperties(data, registerInfo);
            registerInfo.setEquCode("2".equals(data.getEquCodeType()) ? "" : registerInfo.getEquCode());
            registerInfo.setRecord(record);
            registerInfo.setRecDate(new Date());
            registerInfo.setEquCategory(equipInfoDto.getEquCategoryCode());
            registerInfo.setEquDefine(equipInfoDto.getEquDefineCode());
            registerInfo.setEquList(equipInfoDto.getEquListCode());
            registerInfo.setRegisterState("his".equals(equipInfoDto.getDataSource()) ? "6045":"6046");
            registerInfo.setProductPhoto(productPhoto);
            registerInfo.setOtherAccessoriesReg(otherAccessoriesReg);
            registerInfo.setUseOrgCode(equipInfoDto.getUseOrgCode());
            registerInfo.setCylinderCategory(data.getCylinderCategory());
            registerInfo.setInInspectionPeriod("1");
            if ("his".equals(equipInfoDto.getDataSource())) {
                registerInfo.setStatus("在用");
                registerInfo.setEquCode(this.getEquCode(registerInfo, factoryInfo, equipInfoDto.getReceiveOrgCode()));
            }
            registerInfoList.add(registerInfo);

            // 检验检测
            IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = new IdxBizJgInspectionDetectionInfo();
            BeanUtils.copyProperties(data, inspectionDetectionInfo);
            inspectionDetectionInfo.setInspectOrgCode(data.getInspectOrgCode());
            inspectionDetectionInfo.setRecord(record);
            inspectionDetectionInfo.setRecDate(new Date());
            inspectionDetectionInfo.setInspectType("ZZJDJY");
            inspectionDetectionInfo.setInspectConclusion("6040");// 默认合格
            Optional.ofNullable(data.getInspectDate())
                    .filter(StrUtil::isNotBlank)
                    .map(s -> DateUtil.parse(s, "yyyy-MM-dd"))
                    .ifPresent(inspectionDetectionInfo::setInspectDate);
            Optional.ofNullable(data.getNextInspectDate())
                    .filter(StrUtil::isNotBlank)
                    .map(s -> DateUtil.parse(s, "yyyy-MM-dd"))
                    .ifPresent(inspectionDetectionInfo::setNextInspectDate);
            // 根据条件确定增加的年数(杨生元说监管让去掉，企业自己输入)
//            Optional.ofNullable(data.getInspectDate())
//                    .filter(s -> !s.trim().isEmpty())
//                    .map(dateStr -> LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
//                    .ifPresent(inspectDate -> {
//                        inspectionDetectionInfo.setInspectDate(Date.from(inspectDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
//                        // 计算下次检测日期（加 3 年或 4 年）
//                        int plusYears = SPECIAL_CYLINDER.getCode().equals(equipInfoDto.getEquDefineCode()) ? 3 : 4;
//                        LocalDate nextInspectDate = inspectDate.plusYears(plusYears);
//                        inspectionDetectionInfo.setNextInspectDate(Date.from(nextInspectDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
//                    });
            inspectionDetectionInfoList.add(inspectionDetectionInfo);

            // 其他信息
            String cylinderStampAttachment = getUrlByKey(fileDataList, "CYLINDER_STAMP_ATTACHMENT");
            IdxBizJgOtherInfo otherInfo = new IdxBizJgOtherInfo();
            BeanUtils.copyProperties(data, otherInfo);
            otherInfo.setRecord(record);
            otherInfo.setRecDate(new Date());
            otherInfo.setCylinderStampAttachment(cylinderStampAttachment);
            if ("his".equals(equipInfoDto.getDataSource())) {
                otherInfo.setSupervisoryCode(supervisoryCodeIterator.next());
            }
            otherInfo.setClaimStatus("已认领");
            otherInfoList.add(otherInfo);

            //监督管理信息
            setSupervisionInfo(orgBranchCode, orgBranchName, record, supervisionInfoList);

            // 技术参数
            IdxBizJgTechParamsVessel paramsVessel = new IdxBizJgTechParamsVessel();
            BeanUtils.copyProperties(data, paramsVessel);
            paramsVessel.setRecord(record);
            paramsVessel.setRecDate(new Date());
            paramsVessel.setChargingMedium((String) fillingMediumMap.get(data.getChargingMedium()));
            paramsVesselList.add(paramsVessel);

            ESEquipmentCategoryDto esEquipmentDto = JSON.parseObject(toJSONString(data), ESEquipmentCategoryDto.class);
            esEquipmentDto.setDATA_SOURCE(useInfo.getDataSource());
            if (inspectionDetectionInfo.getNextInspectDate() != null) {
                esEquipmentDto.setNEXT_INSPECT_DATE(inspectionDetectionInfo.getNextInspectDate().getTime());
            }
            esEquipmentDto.setCREATE_DATE(System.currentTimeMillis());
            esEquipmentDto.setREC_DATE(System.currentTimeMillis());
            esEquipmentDto.setSEQUENCE_NBR(record);
            esEquipmentDto.setFACTORY_NUM(factoryInfo.getFactoryNum());
            esEquipmentDto.setUSE_INNER_CODE(useInfo.getUseInnerCode());
            esEquipmentDto.setUSE_ORG_CODE(equipInfoDto.getUseOrgCode());
            esEquipmentDto.setIS_INTO_MANAGEMENT("his".equals(equipInfoDto.getDataSource()));
            esEquipmentDto.setEQU_CODE(registerInfo.getEquCode());
            esEquipmentDto.setEQU_CATEGORY_CODE(equipInfoDto.getEquCategoryCode());
            esEquipmentDto.setEQU_CATEGORY(equipInfoDto.getEquCategory());
            esEquipmentDto.setEQU_LIST_CODE(equipInfoDto.getEquListCode());
            esEquipmentDto.setEQU_LIST(equipInfoDto.getEquList());
            esEquipmentDto.setEQU_DEFINE_CODE(equipInfoDto.getEquDefineCode());
            esEquipmentDto.setSUPERVISORY_CODE(otherInfo.getSupervisoryCode());
            esEquipmentDto.setOrgBranchCode(orgBranchCode);
            esEquipmentDto.setORG_BRANCH_NAME(orgBranchName);
            esEquipmentDto.setEQU_DEFINE(equipInfoDto.getEquDefine());
            esEquipmentDto.setINFORMATION_SITUATION(otherInfo.getInformationSituation());
            esEquipmentDto.setSTATUS("已认领");
            esEquipmentDto.setEQU_STATE(Integer.valueOf(equState));

            // 使用单位信息
            if ("个人主体".equals(company.getCompanyType())) {
                esEquipmentDto.setUSE_UNIT_CREDIT_CODE(company.getCompanyCode().split("_")[1]);
                esEquipmentDto.setUSE_UNIT_NAME(company.getCompanyName().split("_")[1]);
            } else {
                esEquipmentDto.setUSE_UNIT_CREDIT_CODE(company.getCompanyCode());
                esEquipmentDto.setUSE_UNIT_NAME(company.getCompanyName());
            }
            esEquipmentCategoryList.add(esEquipmentDto);
            if ("his".equals(equipInfoDto.getDataSource())) {
                // 生成tzs_jg_certificate_change_record_eq记录
                JgCertificateChangeRecordEq changeRecordEq = new JgCertificateChangeRecordEq();
                changeRecordEq.setChangeRecordId(String.valueOf(changeRecordId));// 登记证记录主键
                changeRecordEq.setEquId(registerInfo.getRecord());// 设备主键
                changeRecordEq.setProductCode(factoryInfo.getFactoryNum());// 产品编号
                jgCertificateChangeRecordEqList.add(changeRecordEq);
            }
            String nextInspectDateStr = Optional.ofNullable(inspectionDetectionInfo.getNextInspectDate())
                    .map(date -> date.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate()
                            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                    .orElse(null);
            Map<String, Object> equipMap = MapBuilder.<String, Object>create()
                    .put("factoryNum", factoryInfo.getFactoryNum())
                    .put("chargingMedium", data.getChargingMedium())
                    .put("productName", data.getProductName())
                    .put("produceUnitName", factoryInfo.getProduceUnitName())
                    .put("produceDate", esEquipmentDto.getPRODUCE_DATE())
                    .put("nominalWorkingPressure", data.getNominalWorkingPressure())
                    .put("singleBottleVolume", data.getSingleBottleVolume())
                    .put("inspectDate", data.getInspectDate())
                    .put("equList", equipInfoDto.getEquListCode())
                    .put("equListName", equipInfoDto.getEquList())
                    .put("equCategory", equipInfoDto.getEquCategoryCode())
                    .put("equCategoryName", equipInfoDto.getEquCategory())
                    .put("equDefine", equipInfoDto.getEquDefineCode())
                    .put("equDefineName", equipInfoDto.getEquDefine())
                    .put("manageType", "unit")
                    .put("record", esEquipmentDto.getSEQUENCE_NBR())
                    .put("nextInspectDate", nextInspectDateStr)
                    .put("useInnerCode", useInfo.getUseInnerCode())
                    .put("informationSituation", data.getInformationSituation())
                    .put("dataSource", useInfo.getDataSource())
                    .build();
            equipmentLists.add(equipMap);
        });

        if ("his".equals(equipInfoDto.getDataSource())) {
            // 生成证书管理表记录
            LambdaQueryWrapper<JgUseRegistrationManage> queryWrapper = new LambdaQueryWrapper<JgUseRegistrationManage>()
                    .eq(JgUseRegistrationManage::getUseRegistrationCode, equipInfoDto.getUseOrgCode())
                    .eq(JgUseRegistrationManage::getIsDelete, 0)
                    .eq(JgUseRegistrationManage::getCertificateStatus, "已登记");
            JgUseRegistrationManage jgUseRegistrationManage = jgUseRegistrationManageService.getBaseMapper().selectOne(queryWrapper);
            // 使用登记信息
            JgUseRegistration jgUseRegistration = new JgUseRegistration();
            //历史增补
            if (!ValidationUtil.isEmpty(jgUseRegistrationManage)) {
                jgUseRegistration.setIsAddEquip("1");
                if (jgUseRegistrationManage.getUseUnitCreditCode().equals(company.getCompanyCode())) {
                    jgUseRegistrationManage.setAuditPassDate(new Date());
                    jgUseRegistrationManage.setRegDate(new Date());
                    jgUseRegistrationManage.setManageType("unit");
                    jgUseRegistrationManage.setApplyNo(this.getApplicationNo());
                    jgUseRegistrationManage.setUseUnitCreditCode(company.getCompanyCode());
                    if(!equipInfoDto.getReceiveOrgName().equals(jgUseRegistrationManage.getReceiveOrgName()) || company.getCompanyName().equals(jgUseRegistrationManage.getUseUnitName())){
                        jgUseRegistrationManage.setVersion(jgUseRegistrationManage.getVersion() + 1);
                        jgUseRegistrationManage.setChangeReason(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName());
                    }
                    jgUseRegistrationManage.setUseUnitName(company.getCompanyName());
                    jgUseRegistrationManage.setReceiveOrgName(equipInfoDto.getReceiveOrgName());
                    jgUseRegistrationManage.setReceiveCompanyCode(equipInfoDto.getReceiveOrgCode());
                    jgUseRegistrationManage.setSuperviseOrgName(orgBranchName);
                    jgUseRegistrationManage.setSuperviseOrgCode(orgBranchCode);
                    jgUseRegistrationManageService.updateById(jgUseRegistrationManage);
                } else {
                    throw new BadRequest("该使用登记证编号系统已存在，请核对使用登记证编号后，重新上传!");
                }
            } else {
                jgUseRegistration.setIsAddEquip("0");
                jgUseRegistrationManage = this.saveRegistrationManage(equipInfoDto, company, orgBranchCode, orgBranchName);
            }
            // 生成一条tzs_jg_certificate_change_record记录
            generateCertificateChangeRecord(jgUseRegistrationManage, changeRecordId);

            jgUseRegistration.setRegDate(new Date());
            jgUseRegistration.setReceiveCompanyCode(equipInfoDto.getReceiveOrgCode());
            jgUseRegistration.setReceiveOrgName(equipInfoDto.getReceiveOrgName());
            jgUseRegistration.setManageType("unit");
            jgUseRegistration.setCylinderCategory(registerInfoList.get(0).getCylinderCategory());
            jgUseRegistration.setReceiveCompanyOrgCode(commonService.getOneCompany(jgUseRegistration.getReceiveCompanyCode()).getOrgCode());
            //使用单位提交
            jgUseRegistration.setUseUnitName(CompanyTypeEnum.INDIVIDUAL.getName().equals(company.getCompanyType()) ?
                    company.getCompanyName().split("_")[1] : company.getCompanyName());
            jgUseRegistration.setUseUnitCreditCode(CompanyTypeEnum.INDIVIDUAL.getName().equals(company.getCompanyType()) ?
                    company.getCompanyCode().split("_")[1] : company.getCompanyCode());
            jgUseRegistration.setCreateUserId(reginParams.getUserModel().getUserId());
            jgUseRegistration.setCreateUserName(reginParams.getUserModel().getRealName());
            jgUseRegistration.setApplyNo(jgUseRegistrationManage.getApplyNo());
            jgUseRegistration.setAuditPassDate(new Date());
            jgUseRegistration.setAuditStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
            jgUseRegistration.setStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
            jgUseRegistration.setUseRegistrationCode(jgUseRegistrationManage.getUseRegistrationCode());
            jgUseRegistration.setRegType("1");//历史登记
            jgUseRegistration.setSupervisionOrgCode(orgBranchCode);
            jgUseRegistration.setCreateDate(new Date());
            jgUseRegistrationService.save(jgUseRegistration);
            jgRelationEquipMapper.batchInsert(String.valueOf(jgUseRegistration.getSequenceNbr()), jgRelationEquipList);

            JSONObject objectHashMap = new JSONObject();
            BeanUtil.beanToMap(jgUseRegistration, objectHashMap, false, false);
            objectHashMap.put("equipmentLists", equipmentLists);
            objectHashMap.put("EQU_CATEGORY_CODE", equipInfoDto.getEquCategoryCode());
            objectHashMap.put("orgBranchCode", equipInfoDto.getOrgBranchCode());
            updateHistory(objectHashMap, String.valueOf(jgUseRegistration.getSequenceNbr()));

            String routePath = this.buildTaskModel(jgUseRegistration, equipInfoDto.getEquListCode());
            jgResumeInfoService.saveBatchResume(
                    equipmentLists.stream()
                            .map(equipId -> JgResumeInfoDto.builder()
                                    .applyNo(jgUseRegistration.getApplyNo())
                                    .businessType(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName())
                                    .businessId(String.valueOf(jgUseRegistration.getSequenceNbr()))
                                    .equId(String.valueOf(equipId.get("record")))
                                    .approvalUnit(jgUseRegistration.getReceiveOrgName())
                                    .approvalUnitCode(jgUseRegistration.getReceiveCompanyCode())
                                    .status("正常")
                                    .changeContent(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName() + "业务办理")
                                    .routePath(routePath)
                                    .build())
                            .collect(Collectors.toList())
            );
        } else {
            jgResumeInfoService.saveBatchResume(
                    equipmentLists.stream()
                            .map(equipId -> JgResumeInfoDto.builder()
                                    .businessType(BusinessTypeEnum.JG_NEW_EQUIP.getName())
                                    .businessId(String.valueOf(equipId.get("record")))
                                    .equId(String.valueOf(equipId.get("record")))
                                    .approvalUnit(reginParams.getCompany().getCompanyName())
                                    .approvalUnitCode(reginParams.getCompany().getCompanyCode())
                                    .status("正常")
                                    .changeContent(BusinessTypeEnum.JG_NEW_EQUIP.getName() + "业务办理")
                                    .routePath(String.format(equipRoutePath, equipId.get("record"), equipId.get("dataSource")))
                                    .build())
                            .collect(Collectors.toList())
            );
        }
        batchInsert(idxBizJgUseInfoMapper, useInfoList, "使用信息");
        batchInsert(idxBizJgRegisterInfoMapper, registerInfoList, "注册信息");
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        futures.add(CompletableFuture.runAsync(() -> batchInsert(idxBizJgSupervisionInfoMapper, supervisionInfoList, "监督信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(idxBizJgDesignInfoMapper, designInfoList, "设计信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(idxBizJgFactoryInfoMapper, factoryInfoList, "制造信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(otherInfoMapper, otherInfoList, "其他信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(idxBizJgTechParamsVesselMapper, paramsVesselList, "容器参数信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(idxBizJgInspectionDetectionInfoMapper, inspectionDetectionInfoList, "检验检测信息"), executor));
        futures.add(CompletableFuture.runAsync(() -> batchInsert(certificateChangeRecordEqMapper, jgCertificateChangeRecordEqList, "登记证关系信息"), executor));

        futures.add(CompletableFuture.runAsync(() -> esEquipmentCategory.saveAll(esEquipmentCategoryList), executor));

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        // 使用事务同步回调确保事件在事务提交后发送
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                eventPublisher.publish(
                        new EquipCreateOrEditEvent(
                                this,
                                BusinessTypeEnum.JG_NEW_EQUIP.name(),
                                recordSet,
                                EquipCreateOrEditEvent.EquipType.equip
                        )
                );
            }
        });
        return String.format("导入完成，成功导入: %d 条数据！", useInfoList.size());
    }
    // 定义线程池，CPU 核数 * 2，避免阻塞主线程
    ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);

    /** 通用批量插入方法 */
    public <T> void batchInsert(CustomBaseMapper<T> mapper, List<T> list, String name) {
        if (list != null && !list.isEmpty()) {
            mapper.insertBatchSomeColumn(list, 200);
            log.info("{} 批量插入完成，数量：{}", name, list.size());
        }
    }

    public String buildTaskModel(JgUseRegistration jgUseRegistration, String equListCode) {
        TaskModelDto modelDto = new TaskModelDto();
        modelDto.setNextExecuteUser(jgUseRegistration.getNextExecuteUserIds());
        modelDto.setPageType("look");
        modelDto.setStartUserId(RequestContext.getExeUserId());
        modelDto.setStartDate(new Date());

        TaskMessageDto taskMessageDto = new TaskMessageDto();
        BeanUtil.copyProperties(jgUseRegistration, taskMessageDto);
        taskMessageDto.setRegType("历史登记");
        taskMessageDto.setEQU_LIST_CODE(equListCode);
        taskMessageDto.setAuditStatus(null);
        taskMessageDto.setEquipId((jgUseRegistration.getProjectContraptionId()));
        modelDto.setModel(taskMessageDto);

        // 获取URL配置并匹配对应业务类型和pageType
        List<Map> urlList = JsonUtils.getResourceList(urlInfo);
        if (CollectionUtils.isEmpty(urlList)) {
            throw new IllegalStateException("URL配置未初始化");
        }

        final String targetType = BusinessTypeEnum.JG_USAGE_REGISTRATION.getCode();
        final String targetPageType = modelDto.getPageType();

        for (Map urlMap : urlList) {
            Object type = urlMap.get("type");
            Object pageType = urlMap.get("pageType");
            if (Objects.equals(type, targetType) && Objects.equals(pageType, targetPageType)) {
                String baseUrl = String.valueOf(urlMap.get("url"));
                try {
                    String queryParams = commonServiceImpl.toQueryParams(modelDto.getModel());
                    String roleIds = Optional.ofNullable(modelDto.getNextExecuteUser()).orElse("");
                    return baseUrl.replace("{roleIds}", roleIds)
                            .replace("{userId}", taskMessageDto.getCreateUserId())
                            + "&" + queryParams
                            + "&nextExecuteUserIds=" + Optional.ofNullable(modelDto.getExecuteUserIds()).orElse("");
                } catch (UnsupportedEncodingException e) {
                    // 建议记录日志，便于排查问题
                    log.error("URL参数编码失败", e);
                    throw new IllegalStateException("构建任务模型URL失败", e);
                }
            }
        }

        throw new IllegalStateException("未找到匹配的URL配置项，type=" + targetType + ", pageType=" + targetPageType);
    }

    private static void setSupervisionInfo(String orgBranchCode, String orgBranchName, String record, List<IdxBizJgSupervisionInfo> supervisionInfoList) {
        IdxBizJgSupervisionInfo supervisionInfo = new IdxBizJgSupervisionInfo();
        supervisionInfo.setOrgBranchCode(orgBranchCode);
        supervisionInfo.setOrgBranchName(orgBranchName);
        supervisionInfo.setRecord(record);
        supervisionInfo.setRecDate(new Date());
        supervisionInfo.setRecUserId(RequestContext.getExeUserId());
        supervisionInfoList.add(supervisionInfo);
    }

    /**
     * 使用登记证编号判断是否使用未来系统生成编号
     * @param useRegistrationCode 使用登记证编号
     * @param regType 历史登记类别（台套set，车用vehicle，气瓶Cylinder）
     */
    public void checkUseRegistrationCode(String useRegistrationCode, String regType) {
        // 使用登记证编号判断是否使用未来系统生成编号
        String key = useRegistrationCode.length() >= 5 ? useRegistrationCode.substring(0, 5) : useRegistrationCode;
        List<String> prefixes = Collections.unmodifiableList(Arrays.asList("容", "锅", "管", "瓶", "梯", "起", "索", "游", "车"));
        if (useRegistrationCode.length() < 3) {
            throw new IllegalArgumentException("请输入正确的使用登记证编号: " + useRegistrationCode);
        }
        String prefix = useRegistrationCode.substring(0, 3);
        if (useRegistrationCode.length() == 14 && prefixes.stream().anyMatch(key::startsWith) && !"容3T".equals(prefix)) {
            // 如果 prefix 不等于 "瓶31" 或 "瓶32" 则继续执行逻辑
            ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
            String currentSequenceStr = valueOps.get(key);
            String extractedValue = useRegistrationCode.substring(5, 10);
            String extractedYearStr = useRegistrationCode.substring(useRegistrationCode.indexOf('(') + 1, useRegistrationCode.indexOf(')'));
            int currentYearLastTwoDigits = LocalDate.now().getYear() % 100;

            // 提取年份
            int extractedYear = Integer.parseInt(extractedYearStr);
            if (currentYearLastTwoDigits == extractedYear) {
                if (redisUtils.hasKey(useRegistrationCode.substring(0, 5))) {

                    // 检查regType是否为Cylinder，如果是，才执行"瓶31" 和 "瓶32" 的条件判断
                    if (!"cylinder".equals(regType) || Stream.of("瓶31", "瓶32").noneMatch(prefix::equals)) {
                        if (currentSequenceStr != null) {
                            try {
                                if (Character.isLetter(extractedValue.charAt(0))) {
                                    // 提取字母部分并比较
                                    char extractedLetter = extractedValue.charAt(0);
                                    int extractedNumber = Integer.parseInt(extractedValue.substring(1)); // 提取数字部分

                                    // 提取 Redis 中的字母和数字部分
                                    char redisLetter = currentSequenceStr.charAt(0);

                                    // redis中不是字母开头，输入的是字母开头
                                    if (!Character.isLetter(redisLetter)) {
                                        throw new BadRequest("登记证编号不能使用系统还未生成编号!");
                                    }
                                    int redisNumber = Integer.parseInt(currentSequenceStr.substring(1));

                                    // 比较字母和数字
                                    if ((extractedLetter > redisLetter || (extractedLetter == redisLetter && extractedNumber > redisNumber))) {
                                        throw new BadRequest("登记证编号不能使用系统还未生成编号!");
                                    }
                                } else {
                                    // 如果首字符不是字母，直接进行字符串比较
                                    if (extractedValue.compareTo(currentSequenceStr) > 0) {
                                        throw new BadRequest("登记证编号不能使用系统还未生成编号!");
                                    }
                                }
                            } catch (NumberFormatException e) {
                                throw new BadRequest("数据格式错误");
                            }
                        }
                    }
                } else {
                    throw new BadRequest("登记证编号不能使用系统还未生成编号!");
                }
            } else if (currentYearLastTwoDigits <= extractedYear){
                throw new BadRequest("登记证编号不能使用超出当年年份编号!");
            }
        }
    }

    public void updateHistory(JSONObject map, String currentDocumentId) {
        JgRegistrationHistory jgRegistrationHistory = new JgRegistrationHistory();
        LambdaQueryWrapper<JgRegistrationHistory> lambda = new QueryWrapper<JgRegistrationHistory>().lambda();
        // lambda.eq(JgRegistrationHistory::getEquId, equipId);
        lambda.eq(JgRegistrationHistory::getCurrentDocumentId, currentDocumentId);
        lambda.eq(JgRegistrationHistory::getIsDelete, false);
        lambda.eq(JgRegistrationHistory::getRegistrationClass, "使用登记");
        Integer integer = jgRegistrationHistoryService.getBaseMapper().selectCount(lambda);
        jgRegistrationHistory.setChangeData(toJSONString(map));
        if (integer > 0) {
            jgRegistrationHistoryService.update(jgRegistrationHistory, lambda);
        } else {
            jgRegistrationHistory.setStatus("new");
            jgRegistrationHistory.setRegistrationClass("使用登记");
            //jgRegistrationHistory.setSupervisoryCode(supervisoryCode);
            //jgRegistrationHistory.setEquId(equipId);
            jgRegistrationHistory.setCurrentDocumentId(currentDocumentId);
            jgRegistrationHistoryService.save(jgRegistrationHistory);
        }
    }

    private EquipmentInfoDto createEquipmentInfoDto
            (Map<String, Object> equipmentInfoForm, JgVehicleInformationMapper jgVehicleInformationMapper) {
        String[] parts = Optional.ofNullable(equipmentInfoForm.get("orgBranchCode"))
                .map(Object::toString)
                .map(s -> s.split("_", 2))
                .orElse(new String[0]);
        String orgBranchCode = parts.length > 0 ? parts[0] : "";
        String orgBranchName = parts.length > 1 ? parts[1] : "";
        EquipmentInfoDto dto = new EquipmentInfoDto();
        String equListCode = (String) equipmentInfoForm.get("EQU_LIST");
        String equCategoryCode = (String) equipmentInfoForm.get("EQU_CATEGORY");
        String equDefineCode = (String) equipmentInfoForm.get("EQU_DEFINE");
        dto.setEquListCode(equListCode);
        dto.setEquCategoryCode(equCategoryCode);
        dto.setEquDefineCode(equDefineCode);
        dto.setEquList(jgVehicleInformationMapper.getEquCategoryNameByCode(equListCode));
        dto.setEquCategory(jgVehicleInformationMapper.getEquCategoryNameByCode(equCategoryCode));
        dto.setEquDefine(jgVehicleInformationMapper.getEquCategoryNameByCode(equDefineCode));
        dto.setDataSource((String) equipmentInfoForm.get("DATA_SOURCE"));
        dto.setUseOrgCode((String) equipmentInfoForm.get("USE_ORG_CODE"));
        dto.setOrgBranchCode(orgBranchCode);
        dto.setOrgBranchName(orgBranchName);
        if ("his".equals(equipmentInfoForm.get("DATA_SOURCE"))) {
            dto.setReceiveOrgCode(((String) equipmentInfoForm.get("RECEIVE_ORG_CODE")).split("_")[0]);
            dto.setReceiveOrgName(((String) equipmentInfoForm.get("RECEIVE_ORG_CODE")).split("_")[1]);
            dto.setEquState(Optional.ofNullable(equipmentInfoForm.get("EQU_STATE")).map(Object::toString).orElse(""));
        }
        dto.setPossession(Optional.ofNullable(equipmentInfoForm.get("VEHICLE_APANAGE")).map(Object::toString).orElse(""));
        return dto;
    }

    private JgUseRegistrationManage saveRegistrationManage(EquipmentInfoDto equipInfoDto, CompanyBo company, String orgBranchCode, String orgBranchName) {
        JgUseRegistrationManage jgUseRegistrationManage = new JgUseRegistrationManage();
        jgUseRegistrationManage.setApplyNo(this.getApplicationNo());
        jgUseRegistrationManage.setCertificateStatus(CertificateStatusEnum.YIDENGJI.getName());
        jgUseRegistrationManage.setReceiveOrgName(equipInfoDto.getReceiveOrgName());
        jgUseRegistrationManage.setAuditPassDate(new Date());
        jgUseRegistrationManage.setRegType(BusinessTypeEnum.JG_USAGE_REGISTRATION.getName());
        jgUseRegistrationManage.setRegDate(new Date());
        jgUseRegistrationManage.setEquList(equipInfoDto.getEquList());
        jgUseRegistrationManage.setEquListCode(equipInfoDto.getEquListCode());
        jgUseRegistrationManage.setEquCategory(equipInfoDto.getEquCategory());
        jgUseRegistrationManage.setEquCategoryCode(equipInfoDto.getEquCategoryCode());
        jgUseRegistrationManage.setEquDefine(equipInfoDto.getEquDefine());
        jgUseRegistrationManage.setEquDefineCode(equipInfoDto.getEquDefineCode());
        jgUseRegistrationManage.setIsDelete(Boolean.FALSE);
        jgUseRegistrationManage.setEquUseAddress("");
        jgUseRegistrationManage.setManageType("unit");
        jgUseRegistrationManage.setCreateDate(new Date());
        jgUseRegistrationManage.setSuperviseOrgName(orgBranchName);
        jgUseRegistrationManage.setSuperviseOrgCode(orgBranchCode);
        jgUseRegistrationManage.setUseUnitAddress(!ValidationUtil.isEmpty(baseEnterpriseInfoMapper.selectByUseUnit(company.getCompanyName())) ? baseEnterpriseInfoMapper.selectByUseUnit(company.getCompanyName()).getAddress() : "");
        jgUseRegistrationManage.setUseRegistrationCode(equipInfoDto.getUseOrgCode());
        jgUseRegistrationManage.setUseUnitName(CompanyTypeEnum.INDIVIDUAL.getName().equals(company.getCompanyType()) ?
                company.getCompanyName().split("_")[1] : company.getCompanyName());
        jgUseRegistrationManage.setUseUnitCreditCode(CompanyTypeEnum.INDIVIDUAL.getName().equals(company.getCompanyType()) ?
                company.getCompanyCode().split("_")[1] : company.getCompanyCode());
        jgUseRegistrationManage.setReceiveCompanyCode(equipInfoDto.getReceiveOrgCode());
        jgUseRegistrationManage.setCertificateNo(generateCertificateNo(equipInfoDto, new Date(), equipInfoDto.getReceiveOrgCode()));
        jgUseRegistrationManage.setRegistrationType("1");
        jgUseRegistrationManageService.save(jgUseRegistrationManage);
        return jgUseRegistrationManage;
    }

    private void generateCertificateChangeRecord(JgUseRegistrationManage registrationManage, Long changeRecordId) {
        JgCertificateChangeRecord changeRecord = new JgCertificateChangeRecord();
        changeRecord.setApplyNo(registrationManage.getApplyNo());
        changeRecord.setReceiveOrgName(registrationManage.getReceiveOrgName());
        changeRecord.setAuditPassDate(new Date());
        changeRecord.setRegType(BusinessTypeEnum.JG_USAGE_REGISTRATION.getName());
        changeRecord.setRegDate(registrationManage.getCreateDate());
        changeRecord.setChangeContent(this.buildRecordContent(registrationManage));// 变更内容
        changeRecord.setUseRegistrationCode(registrationManage.getUseRegistrationCode());// 使用登记编号
        changeRecord.setReceiveCompanyCode(registrationManage.getReceiveCompanyCode());// 接收机构公司代码
        changeRecord.setCertificateNo(registrationManage.getCertificateNo());// 登记证书唯一码
        changeRecord.setUseUnitCreditCode(registrationManage.getUseUnitCreditCode());// 使用单位统一信用代码
        changeRecord.setUseUnitName(registrationManage.getUseUnitName());// 使用单位名称
        changeRecord.setEquCategory(registrationManage.getEquCategory());// 设备类别编码
        changeRecord.setRoutePath("");
        changeRecord.setCreateDate(new Date());
        changeRecord.setSequenceNbr(changeRecordId);
        certificateChangeRecordService.save(changeRecord);
    }

    private String buildRecordContent(JgUseRegistrationManage registrationManage) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        return registrationManage.getRecUserName() + "批量上传了【" + BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName() + "】，" +
                "单号【" + registrationManage.getApplyNo() + "】，上传日期" + simpleDateFormat.format(registrationManage.getRecDate());
    }

    /**
     * 生成使用登记证书唯一标识
     *
     * @param dto                包含有 设备种类 & 设备类别 & 设备品种 的map
     * @param date               生成证日期 （不传取当前时间）
     * @param receiveCompanyCode 接收机构统一信用代码
     * @return 使用登记证书唯一标识
     */
    private String generateCertificateNo(EquipmentInfoDto dto, Date date, String receiveCompanyCode) {
        String ym = "";
        try {
            ym = Optional.of(DateUtils.dateFormat(date, DateUtils.DATE_PATTERN_MM)).orElse(DateUtils.dateFormat(new Date(), DateUtils.DATE_PATTERN_MM));
        } catch (ParseException e) {
            log.error("日期转换失败：", e);
        }
        String equCode = Optional.ofNullable(dto.getEquDefineCode()).orElse(dto.getEquCategoryCode());
        String registrationCode = equCode + receiveCompanyCode + ym;
        ResponseModel<String> responseModel = tzsServiceFeignClient.deviceRegistrationCode(registrationCode);
        return responseModel.getResult();
    }

    private String getApplicationNo() {
        ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.SYDJ.getCode(), 1);
        if (!ObjectUtils.isEmpty(listResponseModel) && listResponseModel.getStatus() != HttpStatus.OK.value()) {
            log.error("车用气瓶使用登记申请单单号获取失败！");
            throw new BadRequest("车用气瓶使用登记申请单单号获取失败！");
        }
        return listResponseModel.getResult().get(0);
    }

    public StringBuilder checkExcelData(EquipInfoCylinderExcelDto data, AnalysisContext context) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        CompanyBo company = reginParams.getCompany();

        StringBuilder result = new StringBuilder();
        ReadRowHolder readRowHolder = context.readRowHolder();
        int rowIndex = readRowHolder.getRowIndex() + 1;
        try {
            log.info("解析第{}行数据：{}", rowIndex, toJSONString(data));
            // 检查各字段是否为空，如果为空则追加错误信息
            checkNotBlank(data.getProductName(), "设备名称不能为空；", result);
            //checkNotBlank(data.getBrandName(), "品牌名称不能为空；", result);
//            checkNotBlank(data.getEquType(), "设备型号不能为空；", result);
            //checkNotBlank(data.getUseInnerCode(), "单位内部编号不能为空；", result);
//            if (useInnerCodeList.contains(data.getUseInnerCode())) {
//                result.append("单位内部编号不能重复；");
//            }
            checkNotBlank(data.getWhetherVehicleCylinder(), "是否车用气瓶不能为空；", result);
            checkNotBlank(data.getEquCodeType(), "是否有设备代码不能为空；", result);
            if ("1".equals(data.getEquCodeType())) {
                checkNotBlank(data.getEquCode(), "设备代码不能为空；", result);
                Optional.ofNullable(data.getEquCode())
                        .ifPresent(equCode -> {
                            // 设备代码去掉特殊字符校验
//                            if (!equCode.matches("[a-zA-Z0-9]+")) {
//                                result.append("设备代码不能包含特殊字符；");
//                            } else {
//                                //this.checkEquCodeUniqueness(equCode, result);
//                            }
                            String code = equCode.trim();
                            Stream.of(code.length() < 16 ? "设备代码不能小于16位；" : "",
                                      code.length() > 22 ? "设备代码不能大于22位；" : ""
                                    ).filter(msg -> !msg.isEmpty())
                                    .forEach(result::append);
                            if (equCodeList.contains(code)) {
                                result.append("设备代码不能重复").append(code);
                            }
                            equCodeList.add(data.getEquCode());
                        });
            } else {
                data.setEquCode("");
            }
            //checkNotBlank(data.getDesignUnitCreditCode(), "设计单位统一社会信用代码不能为空；", result);
            //checkNotBlank(data.getDesignUnitName(), "设计单位名称不能为空；", result);
            Optional.ofNullable(data.getDesignDate()).ifPresent(v -> checkDateFormatCorrect(v, "设计日期格式不正确；", result));
            Optional.ofNullable(data.getAppraisalDate()).ifPresent(v -> checkDateFormatCorrect(v, "设计文件鉴定日期格式不正确；", result));
            //checkNotBlank(data.getProduceUnitCreditCode(), "制造单位统一社会信用代码不能为空；", result);
            //checkNotBlank(data.getProduceUnitName(), "制造单位名称不能为空；", result);
//            checkNotBlank(data.getProduceLicenseNum(), "制造许可编号不能为空；", result);
            //checkNotBlank(data.getFactoryNum(), "出厂编号/产品编码不能为空；", result);
//            if ("0".equals(data.getWhetherVehicleCylinder())) {
////                checkNotBlank(data.getCylinderCategory(), "气瓶分类不能为空；", result);
//                if (!StringUtils.isEmpty(data.getFactoryNum()) && !StringUtils.isEmpty(data.getProduceUnitCreditCode())){
//                    checkFactoryNumUnique(data.getFactoryNum(), data.getProduceUnitCreditCode(), data.getProduceUnitName(), result);
//                    if (factoryNumList.contains(data.getProduceUnitCreditCode() + "_" +data.getFactoryNum())){
//                        result.append("同一制造单位下，出厂编码不能重复！；");
//                    }
//                }
//            } else {
//                if (!StringUtils.isEmpty(data.getFactoryNum())){
//                    checkFactoryNumUniquenessForVehicleCylinder(data.getFactoryNum(), result);
//                }
//            }
//            checkNotBlank(data.getProduceDate(), "制造日期不能为空；", result);
            Optional.ofNullable(data.getProduceDate()).ifPresent(v -> checkDateFormatCorrect(v, "制造日期格式不正确；", result));
            //checkNotBlank(data.getInspectOrgName(), "检测机构名称不能为空；", result);
            //checkNotBlank(data.getInspectOrgCode(), "检测机构代码不能为空；", result);
            //checkInspectOrg(data.getInspectOrgCode(), result);//查询检验机构\检测机构
            //checkNotBlank(data.getInspectStaff(), "检测人员名称不能为空；", result);
            //checkNotBlank(data.getInspectDate(), "检测日期不能为空；", result);
            //checkNotBlank(data.getInspectReportNo(), "检验报告编号不能为空；", result);
            Optional.ofNullable(data.getInspectDate()).ifPresent(v -> checkDateFormatCorrect(v, "检测日期格式不正确；", result));
            //checkNotBlank(data.getSingleBottleVolume(), "单瓶容积不能为空；", result);
            //checkNotBlank(data.getChargingMedium(), "充装介质不能为空；", result);
            //checkNotBlank(data.getNominalWorkingPressure(), "公称工作压力不能为空；", result);
            //checkNotBlank(data.getInformationSituation(), "信息化管理情况(二维码、电子标签、无)不能为空；", result);
            // 信息化管理情况校验
            //checkInformatManageInfo(data, result);
            // 如果存在错误信息，则抛出 BadRequest 异常
            if (result.length() > 0) {
                result.insert(0, "Excel第[" + rowIndex + "]行 -> ");
            }

        } catch (Exception e) {
            log.error(String.format("行索引数: [%s] -> 失败的 Excel 数据: [%s]", rowIndex, toJSONString(data)), e);
            throw e;
        }
        return result;
    }

    private void checkInformatManageInfo(EquipInfoCylinderExcelDto data, StringBuilder result) {
        // 非车用气瓶时（0）时且信息化管理情况非无时检验二维码编号/电子标签编号必填
        if (data.getInformationSituation() != null && !"99".equals(data.getInformationSituation()) && "0".equals(data.getWhetherVehicleCylinder())) {
            checkNotBlank(data.getInformationManageCode(), "二维码编号/电子标签编号不能为空；", result);
        }
    }

    private void checkEquCodeUniqueness(String equCode, StringBuilder result) {
        // 根据设备代码检查唯一性
        Integer count = idxBizJgRegisterInfoMapper.selectByEquCodeAndClaimStatus(equCode, "", null);
        if (count > 0) {
            result.append("设备代码系统中已存在；");
        }
    }

    // 检查上传Excel中的日期格式是否正确
    private void checkDateFormatCorrect(String date, String errorMessage, StringBuilder result) {
        if (!date.matches("(?!1905)\\d{4}-\\d{2}-\\d{2}")) {
            result.append(errorMessage);
        }
    }

    // 检查字段是否为空，如果为空则追加错误信息到result
    private void checkNotBlank(String value, String errorMessage, StringBuilder result) {
        if (org.apache.commons.lang3.StringUtils.isBlank(value)) {
            result.append(errorMessage);
        }
    }

    private void checkFactoryNumUniquenessForVehicleCylinder(String factoryNum, StringBuilder result) {
        // 车用气瓶业务里面的 出厂编号/产品编码 校验唯一性（产品编号在车用气瓶范围内全局唯一）
        if (commonService.checkFactoryNumUniquenessForVehicleCylinder(factoryNum, null) > 0) {
            result.append("出厂编号/产品编码系统中已存在！");
        }
    }

    /**
     * 生成设备代码
     *
     * @param registerInfo       registerInfo
     * @param factoryInfo        factoryInfo
     * @param receiveCompanyCode 接收机构
     * @return 设备代码
     */
    public String getEquCode(IdxBizJgRegisterInfo registerInfo, IdxBizJgFactoryInfo factoryInfo, String
            receiveCompanyCode) {
        CodeGenerateDto codeGenerateDto = new CodeGenerateDto();
        codeGenerateDto.setEquList(registerInfo.getEquList());
        codeGenerateDto.setEquCategory(registerInfo.getEquCategory());
        codeGenerateDto.setEquDefine(registerInfo.getEquDefine());
        codeGenerateDto.setProduceDate(factoryInfo.getProduceDate());
        codeGenerateDto.setReceiveCompanyCode(receiveCompanyCode);
        return codeUtil.generateEquipmentCode(codeGenerateDto);
    }

    /**
     * 生成监管码
     */
    public String getSupervisoryCode(String possession, String equCategory) {
        Map<String, Object> map = new HashMap<>();
        boolean isXiXian = XI_XIAN.getCode().equals(possession);
        String cityOrCountyCode = isXiXian ? XIAN_YANG.getCode() : possession;
        map.put("cityCode", cityOrCountyCode);
        map.put("isXiXian", isXiXian ? 1 : 0);
        map.put("equCategory", equCategory);
        map.put("countyCode", cityOrCountyCode);
        return Optional.ofNullable(tzsServiceFeignClient.createCode(map).getResult())
                .filter(res -> !res.isEmpty())
                .map(res -> String.valueOf(res.get("superviseCode")))
                .orElse("");
    }

    /**
     * 批量生成监管码
     */
    public List<String> getSupervisoryCodeBatch(String possession, String equCategory, int batchSize) {
        boolean isXiXian = XI_XIAN.getCode().equals(possession);
        String cityOrCountyCode = isXiXian ? XIAN_YANG.getCode() : possession;

        Map<String, Object> params = new HashMap<>();
        params.put("cityCode", cityOrCountyCode);
        params.put("isXiXian", isXiXian ? 1 : 0);
        params.put("equCategory", equCategory);
        params.put("countyCode", cityOrCountyCode);
        params.put("batchSize", batchSize);
        return Optional.ofNullable(tzsServiceFeignClient.createCodeBatch(params).getResult())
                .map(list -> list.stream()
                        .map(res -> String.valueOf(res.get("superviseCode")))
                        .collect(Collectors.toList()))
                .orElse(Collections.emptyList());
    }

    // 注入依赖
    private void injectDependencies(PressureVesselListener listener, Map<String, Object> paramMap) {
        listener.setIdxBizJgRegisterInfoService(idxBizJgRegisterInfoService);
        listener.setJgInstallationNoticeService(jgInstallationNoticeService);
        listener.setIdxBizJgUseInfoService(idxBizJgUseInfoService);
        listener.setIdxBizJgDesignInfoService(idxBizJgDesignInfoService);
        listener.setIdxBizJgFactoryInfoService(idxBizJgFactoryInfoService);
        listener.setIdxBizJgOtherInfoService(iIdxBizJgOtherInfoService);
        listener.setIdxBizJgTechParamsVesselService(idxBizJgTechParamsVesselService);
        listener.setIdxBizJgInspectionDetectionInfoService(idxBizJgInspectionDetectionInfoService);
        listener.setCommonService(commonService);
        listener.setIdxBizJgRegisterInfoMapper(idxBizJgRegisterInfoMapper);
        listener.setEsEquipmentCategory(esEquipmentCategory);
        listener.setCategoryOtherInfoMapper(categoryOtherInfoMapper);
        listener.setSuperviseInfoMapper(superviseInfoMapper);
        listener.setParamMap(paramMap);
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        CompanyBo company = reginParams.getCompany();
        listener.setCompany(company);
    }

    public String findUseCode(List<Map<String, Object>> unitList, String inspectOrgCode) {
        Optional<Map<String, Object>> optional = unitList.stream()
                .filter(map -> map.get("useCode").equals(inspectOrgCode))
                .findFirst();
        return optional.map(map -> (String) map.get("useCode")).orElse(null);
    }

    @Override
    public Object getProjectContraption(String uscUnitCreditCode, String useUnitCreditCode,String equCategoryCode, String city) {
        return this.baseMapper.getProjectContraption(uscUnitCreditCode, useUnitCreditCode, equCategoryCode, city);
    }

    @Override
    public Boolean esSynchronousProjectContraption() {
        List<Map<String, Object>> list = this.baseMapper.esSynchronousProjectContraption();
        if (!ObjectUtils.isEmpty(list)) {
            HashMap<String, Map<String, Object>> objMap = new HashMap<>();
            list.forEach(item -> {
                HashMap<String, Object> param = new HashMap<>();
                param.put("PROJECT_CONTRAPTION", item.get("PROJECT_CONTRAPTION"));
                objMap.put(item.get("SEQUENCE_NBR").toString(), param);
            });
            // 更新es
            tzsServiceFeignClient.commonUpdateEsDataByIds(objMap);
        }
        return Boolean.TRUE;
    }

    @Override
    public List<Map<String, Object>> getProjectContraptionList(String useUnitCreditCode) {
        List<Map<String, Object>> list = this.baseMapper.getProjectContraptionList(useUnitCreditCode);
        return list.stream().filter(map -> map.values().stream().noneMatch(value -> value instanceof String && ((String) value).isEmpty())).collect(Collectors.toList());
    }

    @Override
    public Page<Map<String, Object>> getElevatorInfo(String equCode, Date startTime, Date endTime, int current, int size) {
        Page<Map<String, Object>> result = new Page<>(current, size);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        //榆林市审批局
        String orgCode = this.getAndSetOrgCode("610800");
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));

        //默认查询电梯
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.matchPhraseQuery("EQU_LIST_CODE", QueryParser.escape("3000")));
        boolMust.must(query);

        BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
        String param = QueryParser.escape("true");
        pBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, param));
        boolMust.must(pBuilder);
        boolMust.must(QueryBuilders.rangeQuery("REC_DATE").gte(startTime.getTime()).lte(endTime.getTime()));

        if (!ObjectUtils.isEmpty(equCode)) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(equCode);
            meBuilder.must(QueryBuilders.matchPhraseQuery("EQU_CODE", "*" + test + "*"));
            boolMust.must(meBuilder);
        }

        builder.query(boolMust);
        builder.sort("REC_DATE", SortOrder.DESC);
        builder.from((current - 1) * size);
        builder.size(size);
        request.source(builder);
        List<Map<String, Object>> elevatorModelVoList = Collections.emptyList();
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            List<String> equIds = Arrays.stream(response.getHits().getHits())
                    .map(hit -> {
                        JSONObject dto2 = ((JSONObject) JSONObject.toJSON(hit)).getJSONObject("sourceAsMap");
                        dto2.put("record", dto2.getString(SEQUENCE_NBR));
                        return dto2.getString(SEQUENCE_NBR);
                    })
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (!equIds.isEmpty()) {
                elevatorModelVoList = jgUseRegistrationMapper.getElevatorModeList(equIds);
            }
            result.setRecords(convertKeysToCamelCase(elevatorModelVoList));
            result.setTotal(Objects.requireNonNull(response.getHits().getTotalHits()).value);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getCylinderStationInfo() {
        return commonMapper.getCylinderStationInfo(this.getAndSetOrgCode("610800"));
    }

    @Override
    public List<Map<String, Object>> getVehicleCylinderInfo(String useCode) {
        return commonMapper.getVehicleCylinderInfo(useCode);
    }

    @Override
    public Page<Map<String, Object>> getCylinderInfo(String equCode, Date startTime, Date endTime, int current, int size) {
        Page<Map<String, Object>> result = new Page<>(current, size);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        //榆林市审批局
        String orgCode = this.getAndSetOrgCode("610800");
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));

        //默认查询电梯
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.matchPhraseQuery("EQU_CATEGORY_CODE", QueryParser.escape("2300")));
        boolMust.must(query);

        BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
        String param = QueryParser.escape("true");
        pBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, param));
        boolMust.must(pBuilder);
        boolMust.must(QueryBuilders.rangeQuery("REC_DATE").gte(startTime.getTime()).lte(endTime.getTime()));

        if (!ObjectUtils.isEmpty(equCode)) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(equCode);
            meBuilder.must(QueryBuilders.matchPhraseQuery("EQU_CODE", "*" + test + "*"));
            boolMust.must(meBuilder);
        }

        builder.query(boolMust);
        builder.sort("REC_DATE", SortOrder.DESC);
        builder.from((current - 1) * size);
        builder.size(size);
        request.source(builder);
        List<Map<String, Object>> cylinderInfoList = Collections.emptyList();
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            List<String> equIds = Arrays.stream(response.getHits().getHits())
                    .map(hit -> {
                        JSONObject dto2 = ((JSONObject) JSONObject.toJSON(hit)).getJSONObject("sourceAsMap");
                        dto2.put("record", dto2.getString(SEQUENCE_NBR));
                        return dto2.getString(SEQUENCE_NBR);
                    })
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (!equIds.isEmpty()) {
                // 查询设备信息
                cylinderInfoList = jgUseRegistrationMapper.getCylinderInfoList(equIds);
                Map<String, Object> fillingMediumMap = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM")
                        .getResult()
                        .stream()
                        .collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));
                cylinderInfoList.forEach(i -> i.computeIfPresent("chargingMedium", (key, value) -> fillingMediumMap.get(value)));
            }
            result.setRecords(convertKeysToCamelCase(cylinderInfoList));
            result.setTotal(Objects.requireNonNull(response.getHits().getTotalHits()).value);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public String getAndSetOrgCode(String cityCode) {
        String orgCode = regionCodeOrgCodeMap.get(cityCode);
        if (orgCode == null) {
            orgCode = commonMapper.getOrgCodeByCompanyCode(cityCode);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(cityCode, orgCode);
            }
        }
        return orgCode;
    }

    private ReginParams getSelectedOrgInfo() {
        return JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
    }

    /**
     * 根据ids查询设备
     */
    public List<JSONObject> queryEquipInIds(List<String> ids) {
        List<JSONObject> result = new ArrayList<>();
        RequestContextWrapper contextWrapper = RequestContextWrapper.capture();
        List<CompletableFuture<JSONObject>> futures = new ArrayList<>();
        ids.forEach(record ->{
            CompletableFuture<JSONObject> future = CompletableFuture.supplyAsync(() -> {
                JSONObject itemJsonObject = new JSONObject();
                contextWrapper.apply();
                Map<String, Map<String, Object>> registerByRecord = idxBizJgRegisterInfoService.getEquipmentRegisterByRecord(record, "0");
                registerByRecord.values().forEach(i -> CommonUtils.deepMergeJSONObject(new JSONObject(i),itemJsonObject));
                return itemJsonObject;
            }, executorService);
            futures.add(future);
        });
        for (CompletableFuture<JSONObject> future : futures) {
            try {
                result.add(future.get());
            } catch (InterruptedException | ExecutionException e) {
                log.error("执行失败", e);
            }
        }
        return result;
    }



    /**
     * 定时任务，每天9点执行一次
     * 企业许可到期提醒
     */
    @Scheduled(cron = "0 0 9 * * ?")
    @SchedulerLock(name="enterpriseLicenseExpirationTask",lockAtMostFor = "PT6H")
    public void enterpriseLicenseExpirationTask() {
        if (licenseExpirationEnabled) {
            this.enterpriseLicenseExpiration("=");
        }
    }

    /**
     * 定时任务，每天9点执行一次
     * 人员资质到期提醒
     */
    @Scheduled(cron = "0 0 9 * * ?")
    @SchedulerLock(name="userExpirationReminderTask",lockAtMostFor = "PT6H")
    public void userExpirationReminderTask() {
        if (licenseExpirationEnabled) {
            this.userExpirationReminder("=");
        }
    }

    /**
     * 定时任务，每天9点执行一次
     * 检验有效期到期提醒
     */
    @Scheduled(cron = "0 0 9 * * ?")
    @SchedulerLock(name="inspectionExpirationReminderTask",lockAtMostFor = "PT6H")
    public void inspectionExpirationReminderTask() {
        if (licenseExpirationEnabled) {
            this.inspectionExpirationReminder("=");
        }
    }

    /**
     * 初始化接口，调用一次，企业许可到期提醒
     */
    public void initEnterpriseLicenseExpirationOnce() {
        enterpriseLicenseExpiration("<");
    }

    /**
     * 初始化接口，调用一次，人员资质过期提醒
     */
    public void initUserExpirationReminderOnce() {
        this.userExpirationReminder("<");
    }

    /**
     * 初始化接口，调用一次，检验有效期到期提醒
     */
    public void inspectionExpirationReminderOnce() {
        this.inspectionExpirationReminder("<");
    }

    private void enterpriseLicenseExpiration(String operator) {
        List<TzBaseEnterpriseInfoDto> enterpriseInfoDtoList = baseEnterpriseInfoMapper.selectExpiringUnits(operator);
        if (enterpriseInfoDtoList != null && !enterpriseInfoDtoList.isEmpty()) {
            for (TzBaseEnterpriseInfoDto dto : enterpriseInfoDtoList) {
                // 获取当前日期并动态生成短信内容
                String currentDate = getCurrentFormattedDate();
                String content = generateSmsContent(currentDate, "企业许可");
                // 构建发送短信的请求
                HashMap<String, String> sendSmsMap = buildSmsMap(dto.getUseContact(), content);
                // 发送短信
                sendSms(sendSmsMap);
            }
        }
    }

    private void userExpirationReminder(String operator) {
        //查询检验人员，检测人员，从业人员，资质到期时间
        List<TzsUserInfoDto> tzsUserInfoDtoList = tzsUserInfoMapper.selectUserPermission(operator, Arrays.asList("66152", "6552", "66151"));
        if (tzsUserInfoDtoList != null && !tzsUserInfoDtoList.isEmpty()) {
            for (TzsUserInfoDto dto : tzsUserInfoDtoList) {
                // 获取当前日期并动态生成短信内容
                String currentDate = getCurrentFormattedDate();
                String content = generateSmsContent(currentDate, "从业人员资质");
                // 构建发送短信的请求
                HashMap<String, String> sendSmsMap = buildSmsMap(dto.getPhone(), content);
                // 发送短信
                sendSms(sendSmsMap);
            }
        }
    }

    private void inspectionExpirationReminder(String operator) {
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
        String param = QueryParser.escape("true");
        pBuilder.must(QueryBuilders.matchQuery("IS_INTO_MANAGEMENT", param));
        boolMust.must(pBuilder);
        boolMust.must(QueryBuilders.termQuery("EQU_STATE", EquimentEnum.ZAIYONG.getCode()));
        // 获取今天的开始时间戳
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        long todayStartTimestamp = startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

        // 获取明天的开始时间戳（用于不等于今天的其他数据范围）
        LocalDateTime startOfNextDay = today.plusDays(1).atStartOfDay();
        long nextDayStartTimestamp = startOfNextDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

        if ("=".equals(operator)){
            boolMust.must(QueryBuilders.rangeQuery("NEXT_INSPECT_DATE")
                    .gte(todayStartTimestamp)  // 大于等于今天的开始时间戳
                    .lt(nextDayStartTimestamp)); // 小于明天的开始时间戳
        }else{
            // 使用 range 查询来查找 `NEXT_INSPECT_DATE` 小于今天的数据
            boolMust.must(QueryBuilders.rangeQuery("NEXT_INSPECT_DATE")
                    .lt(todayStartTimestamp));  // 小于今天的开始时间戳
        }

        builder.query(boolMust);
        request.source(builder);

        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

            List<String> useUnitCreditCodeList = Arrays.stream(response.getHits().getHits())
                    .map(hit -> ((JSONObject) JSONObject.toJSON(hit)).getJSONObject("sourceAsMap"))
                    .map(dto2 -> dto2.getString("USE_UNIT_CREDIT_CODE"))
                    .filter(Objects::nonNull)
                    .distinct()  // 去除重复的 USE_UNIT_CREDIT_CODE
                    .collect(Collectors.toList());

            if (!useUnitCreditCodeList.isEmpty()) {
                List<TzBaseEnterpriseInfoDto> enterpriseInfoDtoList = baseEnterpriseInfoMapper.queryByUseCode(useUnitCreditCodeList);
                if (enterpriseInfoDtoList != null && !enterpriseInfoDtoList.isEmpty()) {
                    for (TzBaseEnterpriseInfoDto dto : enterpriseInfoDtoList) {
                        // 获取当前日期并动态生成短信内容
                        String currentDate = getCurrentFormattedDate();
                        String content = generateSmsContent(currentDate, "下次检验有效期");
                        // 构建发送短信的请求
                        HashMap<String, String> sendSmsMap = buildSmsMap("18629351226", content);
                        // 发送短信
                        sendSms(sendSmsMap);
                    }
                }
            }

        } catch (IOException e) {
            log.error("Error executing search request: {}", e.getMessage(), e);
            throw new RuntimeException("Failed to execute search request", e);
        }
    }

    /**
     * 获取当前日期并格式化为 "yyyy年MM月dd日"
     */
    private String getCurrentFormattedDate() {
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        return now.format(formatter);
    }

    /**
     * 动态生成短信内容
     */
    private String generateSmsContent(String expiryDate, String content) {
        return String.format("尊敬的用户，截止【%s】，您的%s已经到期，请您登录系统查看或处理（电脑端地址：http://sxtzsb.sxsei.com）！", expiryDate, content);
    }

    /**
     * 构建发送短信的参数Map
     */
    private HashMap<String, String> buildSmsMap(String mobile, String content) {
        HashMap<String, String> sendSmsMap = new HashMap<>();
        sendSmsMap.put("mobile", mobile);
        sendSmsMap.put("smsCode", "SMS_TZS_0006");
        sendSmsMap.put("content", content);
        return sendSmsMap;
    }

    /**
     * 发送短信并处理结果
     */
    private void sendSms(HashMap<String, String> sendSmsMap) {
        FeignClientResult<SmsRecordModel> sendVerifyCodeResult = Systemctl.smsClient.sendCommonSms(sendSmsMap);
        if (sendVerifyCodeResult.getStatus() != 200) {
            logAndThrowSmsError(sendVerifyCodeResult);
        }
    }

    /**
     * 日志记录和异常处理
     */
    private void logAndThrowSmsError(FeignClientResult<SmsRecordModel> sendVerifyCodeResult) {
        if (log.isErrorEnabled()) {
            log.error("调用平台发短信失败:{}", sendVerifyCodeResult.getDevMessage());
        }
        throw new RuntimeException(sendVerifyCodeResult.getMessage());
    }

    /**
     * 根据工程装置ids设备数据
     */
    public List<JSONObject> queryPipeEquipInIds(List<String> proConSeqs) {
        List<JSONObject> result = new ArrayList<>();
        RequestContextWrapper contextWrapper = RequestContextWrapper.capture();
        List<CompletableFuture<JSONArray>> futures = new ArrayList<>();
        proConSeqs.forEach(seq ->{
            CompletableFuture<JSONArray> future = CompletableFuture.supplyAsync(() -> {
                JSONArray resultArray = new JSONArray();
                contextWrapper.apply();
                Map<String, Map<String, Object>> details = idxBizJgProjectContraptionService.details(seq);
                Map<String, Object> objectMap = details.get(EQUIP_INFO_FORM_ID);
                JSONArray pipeList = JSON.parseArray(toJSONString(objectMap.get(PIPELINE_LIST)));
                // 列表有条数据，详情没有管道信息的情况
                if (pipeList.isEmpty()) {
                    JSONObject jsonObject = new JSONObject();
                    for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
                        if (!PIPELINE_LIST.equals(entry.getKey())) {
                            jsonObject.put(entry.getKey(), entry.getValue());
                        }
                    }
                    resultArray.add(jsonObject);
                }
                pipeList.forEach(pipeEqu -> {
                    JSONObject jsonObject = JSON.parseObject(toJSONString(pipeEqu));
                    for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
                        if (!PIPELINE_LIST.equals(entry.getKey())) {
                            jsonObject.put(entry.getKey(), entry.getValue());
                        }
                    }
                    resultArray.add(jsonObject);
                });
                return resultArray;
            }, executorService);
            futures.add(future);
        });
        for (CompletableFuture<JSONArray> future : futures) {
            try {
                future.get().stream()
                        .filter(o -> o instanceof JSONObject)
                        .map(o -> (JSONObject) o)
                        .forEach(result::add);
            } catch (InterruptedException | ExecutionException e) {
                log.error("执行失败", e);
            }
        }
        return result;
    }

    public void updateBatchByRecord(List<IdxBizJgRegisterInfo> toUpdateRegisterInfoList) {
        toUpdateRegisterInfoList.forEach(info -> super.update(info, new LambdaUpdateWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, info.getRecord())));
    }

    public boolean saveOrUpdateData(IdxBizJgRegisterInfo registerInfo) {
        return super.saveOrUpdateWithNull(registerInfo);
    }
}