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.dao.EsEquipmentDao;
import com.yeejoin.amos.boot.module.common.api.dto.ESEquipmentCategoryDto;
import com.yeejoin.amos.boot.module.common.api.entity.ESEquipmentInfo;
import com.yeejoin.amos.boot.module.common.api.enums.ConstructionTypeEnum;
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.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.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 java.util.stream.StreamSupport;

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 JgResumeInfoEqMapper jgResumeInfoEqMapper;
    @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;

    @Autowired
    private EsEquipmentDao esEquipmentDao;

    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) {
        List<ESEquipmentCategoryDto> addEsEquipCategoryDtos = new ArrayList<>();
        List<ESEquipmentCategoryDto> deleteEsEquipCategoryDtos = new ArrayList<>();
        List<ESEquipmentInfo> addEsEquipInfos = new ArrayList<>();
        List<ESEquipmentInfo> deleteEsEquipInfos = new ArrayList<>();
        // 获取表单数据并进行类型检查
        LinkedHashMap equipmentInfoForm = castToLinkedHashMap(paramMap.get(EQUIP_INFO_FORM_ID));
        try {
            String submitType = String.valueOf(paramMap.get("submitType"));
            return ResponseHelper.buildResponse(batchSubmitOrUpdatePipeline(equipmentInfoForm, submitType, company, addEsEquipCategoryDtos, deleteEsEquipCategoryDtos, addEsEquipInfos, deleteEsEquipInfos));
        } catch (Exception e) {
            log.error("操作失败，数据异常: {}", e.getMessage(), e);
            // 回滚es：新增的需要删除、删除的需要用快照数据保存
            if (!ValidationUtil.isEmpty(addEsEquipCategoryDtos)) {
                esEquipmentCategory.deleteAll(addEsEquipCategoryDtos);
                esEquipmentDao.deleteAll(this.buildEquipData(addEsEquipCategoryDtos.stream().map(ESEquipmentCategoryDto::getSEQUENCE_NBR).collect(Collectors.toList())));
            }
            if (!ValidationUtil.isEmpty(deleteEsEquipCategoryDtos)) {
                esEquipmentCategory.saveAll(deleteEsEquipCategoryDtos);
            }
            if (!ValidationUtil.isEmpty(deleteEsEquipInfos)) {
                esEquipmentDao.saveAll(deleteEsEquipInfos);
            }
            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, List<ESEquipmentCategoryDto> addEsEquipCategoryDtos, List<ESEquipmentCategoryDto> deleteEsEquipCategoryDtos, List<ESEquipmentInfo> addEsEquipInfos, List<ESEquipmentInfo> deleteEsEquipInfos) {
        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());
            // 删除涉及的19张表的数据
            superviseInfoMapper.deleteDataAll(records);
            // 先查询旧es数据，用于后续报错回滚
            deleteEsEquipCategoryDtos.addAll(StreamSupport.stream(esEquipmentCategory.findAllById(records).spliterator(), false).collect(Collectors.toList()));
            deleteEsEquipInfos.addAll(StreamSupport.stream(esEquipmentDao.findAllById(records).spliterator(), false).collect(Collectors.toList()));
            // 删除两个es
            esEquipmentCategory.deleteAll(this.buildEquipCategoryData(records));
            esEquipmentDao.deleteAll(this.buildEquipData(records));
        }

        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.setCREATE_DATE(date.getTime());
            esEquipmentDto.setREC_DATE(date.getTime());
            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(equDefineName);
            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));
            esEquipmentCategoryList.add(esEquipmentDto);
            addEsEquipCategoryDtos.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);
        // 更新管道长度
        updatePipelineLength(projectContraption, paramsPipelineList);
        if(OPERATESAVE.equals(operateType)){
            // 记录设备创建履历
            this.createResumePipeline(sequenceNbr, String.format(pipelineRoutePath, sequenceNbr + ""), company);
        }
        // 最后更新es
        esEquipmentCategory.saveAll(esEquipmentCategoryList);
        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 operateType = ValidationUtil.isEmpty(equipmentInfoForm.get(SEQUENCE_NBR)) ? OPERATESAVE : OPERATEEDIT;
        // 设备是否复制而来，复制来的设备走新增
        boolean isCopy = !ValidationUtil.isEmpty(equipmentInfoForm.get(IS_COPY));
        operateType = isCopy ? OPERATESAVE : operateType;
        String submitType = String.valueOf(paramMap.get("submitType"));
        String record = (String) equipmentInfoForm.get(RECORD);
        ESEquipmentCategoryDto esEquipmentCategoryDto = esEquipmentCategory.findById(record).orElse(null);
        try {
            // 设备代码 字段的唯一性校验
            checkEquCodeUniqueness(equipmentInfoForm);
            // 车用气瓶业务里面的 产品编号 校验唯一性（产品编号在车用气瓶范围内全局唯一）
            checkFactoryNumUniqueness(equipmentInfoForm);
            // 96333码 字段的唯一性校验
            check96333Code(equipmentInfoForm);
        } catch (Exception e) {
            handleError(e, null, null, null);
        }
        // 操作类型
        try {
            // 保存数据
            record = batchSubmitOrUpdate(equipmentClassForm, equipmentInfoForm, equipmentParamsForm, submitType, company);
            // 保存Es数据
            if (!ObjectUtils.isEmpty(record)) {
                saveEsData(record);
            }
        } catch (Exception e) {
            log.error("操作失败，数据异常: " + e.getMessage(), e);
            handleError(e, record, operateType, esEquipmentCategoryDto);
        }
        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);
        ESEquipmentCategoryDto esEquipmentCategoryDto = esEquipmentCategory.findById(record).orElse(null);
        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, null, null);
        }

        // 使用登记按照单位办理除外，其余进行编辑校验
        Object manageType = equipmentInfoForm.get(MANAGE_TYPE);
        boolean isManageType = (!ObjectUtils.isEmpty(manageType) && MANAGE_TYPE_UNIT.equals(manageType));
        if (!isManageType) {
            // 编辑校验
            this.checkForEquipEdit(record);
        }
        // 操作类型
        String operateType = ValidationUtil.isEmpty(equipmentInfoForm.get(SEQUENCE_NBR)) ? OPERATESAVE : OPERATEEDIT;
        // 设备是否复制而来，复制来的设备走新增
        boolean isCopy = !ValidationUtil.isEmpty(equipmentInfoForm.get(IS_COPY));
        operateType = isCopy ? OPERATESAVE : operateType;
        try {
            // 保存数据
            record = batchSubmitOrUpdate(equipmentClassForm, equipmentInfoForm, equipmentParamsForm, submitType, company);
            // 保存Es数据
            if (!ObjectUtils.isEmpty(record)) {
                saveEsData(record);
            }
        } catch (Exception e) {
            log.error("操作失败，数据异常: " + e.getMessage(), e);

            handleError(e, record, operateType, esEquipmentCategoryDto);
        }
        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, String operateType, ESEquipmentCategoryDto esEquipmentCategoryDto) {
        log.error("处理设备新增或更新异常: " + e.getMessage(), e);
        // 删除数据库数据和ES数据
        if (!ObjectUtils.isEmpty(record) && OPERATESAVE.equals(operateType)) {
            List<String> records = new ArrayList<>();
            records.add(record);
            superviseInfoMapper.deleteDataAll(records);
            esEquipmentCategory.deleteById(record);
        }
        if (!ValidationUtil.isEmpty(record) && OPERATEEDIT.equals(operateType) && !ValidationUtil.isEmpty(esEquipmentCategoryDto)) {
            esEquipmentCategory.save(esEquipmentCategoryDto);
        }
        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) {
        List<String> records = new ArrayList<>();
        List<ESEquipmentCategoryDto> originalEsList1 = new ArrayList<>();
        List<ESEquipmentInfo> originalEsList2 = new ArrayList<>();
        try {
            Object recordList = map.get("recordList");
            // 删除ES数据
            if (recordList.toString().contains("[")) {
                records.addAll((List<String>) recordList);
            } else {
                records.add(recordList.toString());
            }
            this.checkForDelete(records);
            if (CollUtil.isNotEmpty(records)) {
                // 删除涉及的19张表的数据
                superviseInfoMapper.deleteDataAll(records);
            }
            if (CollUtil.isNotEmpty(records)) {
                originalEsList1 = StreamSupport.stream(esEquipmentCategory.findAllById(records).spliterator(), false).collect(Collectors.toList());
                originalEsList2 = StreamSupport.stream(esEquipmentDao.findAllById(records).spliterator(), false).collect(Collectors.toList());
                // 删除es中的数据
                esEquipmentCategory.deleteAll(this.buildEquipCategoryData(records));
                esEquipmentDao.deleteAll(this.buildEquipData(records));
            }
            return true;
        } catch (Exception e) {
            log.error("批量删除设备注册信息异常: " + e.getMessage(), e);
            this.rollbackEsInfo(originalEsList1, originalEsList2);
            throw new BadRequest(e.getMessage());
        }
    }

    /**
     * 回滚es删除的数据
     * @param originalEsList1 esEquipmentCategoryDto集合
     * @param originalEsList2 esEquipmentInfo集合
     */
    private void rollbackEsInfo(List<ESEquipmentCategoryDto> originalEsList1, List<ESEquipmentInfo> originalEsList2) {
        if (CollUtil.isNotEmpty(originalEsList1)) {
            esEquipmentCategory.saveAll(originalEsList1);
        }
        if (CollUtil.isNotEmpty(originalEsList2)) {
            esEquipmentDao.saveAll(originalEsList2);
        }
    }

    private Iterable<? extends ESEquipmentInfo> buildEquipData(List<String> records) {
        return records.stream().map(record->{
            ESEquipmentInfo esEquipmentInfo = new ESEquipmentInfo();
            esEquipmentInfo.setSEQUENCE_NBR(record);
            return esEquipmentInfo;
        }).collect(Collectors.toList());
    }

    private Iterable<? extends ESEquipmentCategoryDto> buildEquipCategoryData(List<String> records) {
        return records.stream().map(record->{
            ESEquipmentCategoryDto esEquipmentInfo = new ESEquipmentCategoryDto();
            esEquipmentInfo.setSEQUENCE_NBR(record);
            return esEquipmentInfo;
        }).collect(Collectors.toList());
    }

    /**
     * 删除校验，被引用时不可删除
     *
     * @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", this.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);
        }
        // objMap中值为"null"的替换为null
        objMap.entrySet().removeIf(e -> "null".equals(e.getValue()));
        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 whetherVehicleCylinder = MapUtil.getStr(objMap, "WHETHER_VEHICLE_CYLINDER");

        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,
                            JgUseRegistrationManage::getRegDate)
                    .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());
                // 如果设备使用信息表里的首次登记日期为空则用使用登记证表里的登记日期
                if (ObjectUtils.isEmpty(objMap.get("O_REG_DATE")) || "null".equals(objMap.get("O_REG_DATE"))) {
                    objMap.put("O_REG_DATE", jgUseRegistrationManage.getRegDate());
                }
            }

            // 普通气瓶（非车用气瓶）的登记机关和登记日期从增补当时的单据信息取
            if (CylinderTypeEnum.CYLINDER.getCode().equals(equCategoryStr) && "0".equals(whetherVehicleCylinder)) {
                Map<String, String> useRegistration = commonMapper.queryUseRegistrationByRecord(record);
                if (!ValidationUtil.isEmpty(useRegistration)) {
                    objMap.put("receiveCompanyCode", MapUtil.getStr(useRegistration, "receiveCompanyCode"));
                    objMap.put("O_REG_DATE", MapUtil.getStr(useRegistration,"auditPassDate"));
                }
            }
        }

        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, EquipmentEnum.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 = EquipmentEnum.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, EquipmentEnum.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(EquipmentEnum.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 = EquipmentEnum.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, EquipmentEnum.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 = EquipmentEnum.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 (!registerInfo.getEquList().equals("5000") && !registerInfo.getEquCategory().equals("4400") && !registerInfo.getEquCategory().equals("2300")) {
            constructionInfo.setConstructionType(ConstructionTypeEnum.AZ.getCode());
        }

        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)){
            // 记录设备创建履历
            if (CylinderTypeEnum.CYLINDER.getCode().equals(equCategory)){
                this.createResumeForCylinder(record, String.format(equipRoutePath, record, useInfo.getDataSource()), company);
            } else {
                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())
        );
    }

    public void createResumeForCylinder(String record, String routePath, CompanyBo company) {
        JgResumeInfo info = new JgResumeInfo();
        String businessType = BusinessTypeEnum.JG_NEW_EQUIP.getName();
        info.setBusinessType(businessType);
        info.setBusinessId(record);
        info.setStatus("正常");
        info.setApprovalUnitCode(company.getCompanyCode());
        info.setApprovalUnit(company.getCompanyName());
        info.setChangeContent(businessType + "业务办理");
        info.setRoutePath(routePath);
        jgResumeInfoService.save(info);
        jgResumeInfoEqMapper.insert(JgResumeInfoEq.builder()
                .resumeId(info.getSequenceNbr())
                .equId(record)
                .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 saveEsData(String id) {
        Map<String, Object> map = categoryOtherInfoMapper.selectJgAllViewDataById(id);
        ESEquipmentCategoryDto dto = JSON.parseObject(toJSONString(map), ESEquipmentCategoryDto.class);
        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, MapUtil.getStr(i, "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不能为空");
        }
        try {
            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);
                Date now = new Date();
                useInfo.setRecDate(now);
                useInfo.setCreateDate(now);
                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(EquipmentEnum.ZAIYONG.getCode())))
                        : String.valueOf(EquipmentEnum.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(now);
                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(now);
                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(now);
                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(now);
                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(now);
                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(now);
                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(now.getTime());
                esEquipmentDto.setREC_DATE(now.getTime());
                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);
            });
            JgResumeInfo info = new JgResumeInfo();
            info.setStatus("正常");
            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());
                String businessType = BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName();
                info.setBusinessType(businessType);
                info.setBusinessId(String.valueOf(jgUseRegistration.getSequenceNbr()));
                info.setApplyNo(jgUseRegistration.getApplyNo());
                info.setApprovalUnitCode(jgUseRegistration.getReceiveOrgName());
                info.setApprovalUnit(jgUseRegistration.getReceiveCompanyCode());
                info.setChangeContent(businessType + "业务办理");
                info.setRoutePath(routePath);
            } else {
                String businessType = BusinessTypeEnum.JG_NEW_EQUIP.getName();
                info.setBusinessType(businessType);
                info.setApprovalUnitCode(reginParams.getCompany().getCompanyCode());
                info.setApprovalUnit(reginParams.getCompany().getCompanyName());
                info.setChangeContent(businessType + "业务办理");
                info.setRoutePath(equipRoutePath);
            }
            jgResumeInfoService.save(info);
            commonServiceImpl.batchInsertResumeEq(info.getSequenceNbr(), equipmentLists);

            batchInsert(idxBizJgUseInfoMapper, useInfoList, "使用信息");
            batchInsert(idxBizJgRegisterInfoMapper, registerInfoList, "注册信息");
            batchInsert(idxBizJgSupervisionInfoMapper, supervisionInfoList, "监督信息");
            batchInsert(idxBizJgDesignInfoMapper, designInfoList, "设计信息");
            batchInsert(idxBizJgFactoryInfoMapper, factoryInfoList, "制造信息");
            batchInsert(otherInfoMapper, otherInfoList, "其他信息");
            batchInsert(idxBizJgTechParamsVesselMapper, paramsVesselList, "容器参数信息");
            batchInsert(idxBizJgInspectionDetectionInfoMapper, inspectionDetectionInfoList, "检验检测信息");
            batchInsert(certificateChangeRecordEqMapper, jgCertificateChangeRecordEqList, "登记证关系信息");
            esEquipmentCategory.saveAll(esEquipmentCategoryList);
            // 事务提交成功后，发送消息
            eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), recordSet, EquipCreateOrEditEvent.EquipType.equip));
        } catch (Exception e) {
            if(!esEquipmentCategoryList.isEmpty()){
                log.error("导入失败,开始回滚删除数据:{}", JSONObject.toJSONString(esEquipmentCategoryList));
                esEquipmentCategory.deleteAll(esEquipmentCategoryList);
            }
            throw e;
        }
        return String.format("导入完成，成功导入: %d 条数据！", useInfoList.size());
    }

    /** 通用批量插入方法 */
    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 + codeUtil.getCityRegionCode(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", EquipmentEnum.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);
    }
}