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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
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.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.dao.mapper.DataDictionaryMapper;
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.utils.SnowflakeIdUtil;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.common.api.dto.ESEquipmentCategoryDto;
import com.yeejoin.amos.boot.module.jg.api.dto.JgInstallationNoticeEqDto;
import com.yeejoin.amos.boot.module.jg.api.dto.PieLineEquipContraptionDto;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.api.enums.CompanyTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.PipelineEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.DataHandlerMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgInstallationNoticeEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgInstallationNoticeMapper;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgInspectionDetectionInfoService;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquimentEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.toJSONString;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.JgInstallationNoticeServiceImpl.CONSTRUCTION_TYPE;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.JgInstallationNoticeServiceImpl.CONSTRUCTION_TYPE_NAME;

/**
 * 用于业务变更过程中的历史数据处理的service层
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DataHandlerServiceImpl {

    private final ObjectMapper objectMapper;
    private final JgRegistrationHistoryServiceImpl registrationHistoryService;
    private final JgInstallationNoticeServiceImpl installationNoticeService;
    private final JgUseRegistrationServiceImpl useRegistrationService;
    private final JgVehicleInformationServiceImpl jgVehicleInformationService;
    private final JgUseRegistrationEqServiceImpl useRegistrationEqService;
    private final JgInstallationNoticeEqServiceImpl installationNoticeEqService;
    private final IdxBizJgUseInfoServiceImpl useInfoService;
    private final SnowflakeIdUtil sequence;
    private final IdxBizJgProjectContraptionServiceImpl projectContraptionService;
    private final IdxBizJgProjectConstructionMapper projectConstructionMapper;
    private final IdxBizJgTechParamsPipelineServiceImpl techParamsPipelineService;
    private final EquipmentCategoryMapper equipmentCategoryMapper;
    private final IdxBizJgRegisterInfoServiceImpl registerInfoService;
    private final IdxBizJgSupervisionInfoServiceImpl supervisionInfoService;
    private final IdxBizJgFactoryInfoServiceImpl factoryInfoService;
    private final ESEquipmentCategory esEquipmentCategory;
    private final TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;
    private final JgInstallationNoticeEqMapper jgInstallationNoticeEqMapper;
    private final DataDictionaryMapper dataDictionaryMapper;
    private final IdxBizJgProjectInspectionMapper projectInspectionMapper;
    private final IIdxBizJgInspectionDetectionInfoService iIdxBizJgInspectionDetectionInfoService;
    private final IdxBizJgProjectContraptionMapper idxBizJgProjectContraptionMapper;
    private final JgInstallationNoticeMapper jgInstallationNoticeMapper;
    private final DataHandlerMapper dataHandlerMapper;
    private final CategoryOtherInfoMapper categoryOtherInfoMapper;
    ;


    /**
     * 安装告知压力管道历史数据修复-详情中的设备列表修改为汇总表格式
     *
     * @return result
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deviceListInFormWithInstallNotice() {
        List<JgInstallationNotice> noticeList = installationNoticeService.list(new LambdaQueryWrapper<JgInstallationNotice>().eq(JgInstallationNotice::getEquCategoryCode, "8300"));

        List<JgRegistrationHistory> jgRegistrationHistories = noticeList.stream()
                .map(notice -> {
                    JgRegistrationHistory history = getRegistrationHistory(String.valueOf(notice.getSequenceNbr()));
                    if (history == null)
                        return null;
                    try {
                        Map<String, Object> hisData = objectMapper.readValue(
                                history.getChangeData(),
                                new TypeReference<Map<String, Object>>() {
                                }
                        );
                        // 获取设备列表并处理每个设备信息
                        List<Map<String, Object>> deviceList = objectMapper.readValue(
                                objectMapper.writeValueAsString(hisData.get("deviceList")),
                                new TypeReference<ArrayList<Map<String, Object>>>() {
                                }
                        );
                        if (!ValidationUtil.isEmpty(deviceList)) {
                            List<Map<String, Object>> pipelineListInfo = installationNoticeService.getBaseMapper().getPipelineEquInfoByRecords(deviceList.stream().map(device -> String.valueOf(device.get("record"))).collect(Collectors.toList()));
                            // 更新处理后的数据回到 history 对象
                            hisData.put("deviceList", pipelineListInfo);
                        }
                        history.setChangeData(objectMapper.writeValueAsString(hisData)); // 更新 changeData 字段
                    } catch (Exception e) {
                        log.error("JSON 数据处理失败!", e);
                        throw new RuntimeException(e.getMessage());
                    }
                    return history;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        // 批量更新历史表数据
        registrationHistoryService.updateBatchById(jgRegistrationHistories);
        return Boolean.TRUE;
    }

    // 辅助方法：根据 DocumentId 获取历史记录
    private JgRegistrationHistory getRegistrationHistory(String documentId) {
        return registrationHistoryService.getBaseMapper().selectOne(
                new QueryWrapper<JgRegistrationHistory>().lambda()
                        .eq(JgRegistrationHistory::getCurrentDocumentId, documentId)
                        .eq(JgRegistrationHistory::getIsDelete, false)
        );
    }

    /**
     * 向新增的工程装置表刷入数据
     *
     * @return result
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean writeData2ProjectContraption() {

        // projectContraptionService.getBaseMapper().delete(null);

        List<IdxBizJgUseInfo> collect = useInfoService.lambdaQuery()
                .select(IdxBizJgUseInfo::getRecord, IdxBizJgUseInfo::getProjectContraption, IdxBizJgUseInfo::getUseUnitCreditCode, IdxBizJgUseInfo::getUseUnitName, IdxBizJgUseInfo::getIsIntoManagement)
                .isNotNull(IdxBizJgUseInfo::getProjectContraption)
                .ne(IdxBizJgUseInfo::getProjectContraption, "")
                .groupBy(IdxBizJgUseInfo::getProjectContraption, IdxBizJgUseInfo::getUseUnitCreditCode)
                .list().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        log.info("查询到的工程装置集合: {}", JSON.toJSONString(collect));


        List<IdxBizJgProjectContraption> projectContraptionList = new ArrayList<>();
        Iterator<IdxBizJgUseInfo> iterator = collect.iterator();
        while (iterator.hasNext()) {
            IdxBizJgUseInfo useInfo = iterator.next();
            boolean isLast = !iterator.hasNext();

            String record = useInfo.getRecord();
            Boolean isIntoManagement = ObjectUtils.isEmpty(useInfo.getIsIntoManagement()) ? Boolean.FALSE : useInfo.getIsIntoManagement();
            String projectContraption = useInfo.getProjectContraption();
            String useUnitCreditCode = useInfo.getUseUnitCreditCode();

            Long sequenceNbr = sequence.nextId();

            List<String> installNotSeqs = installationNoticeEqService.lambdaQuery()
                    .eq(JgInstallationNoticeEq::getEquId, record)
                    .list().stream()
                    .filter(Objects::nonNull)
                    .map(JgInstallationNoticeEq::getEquipTransferId)
                    .collect(Collectors.toList());

            JgInstallationNotice installationNotice = installNotSeqs.isEmpty() ? null : installationNoticeService.lambdaQuery()
                    .in(JgInstallationNotice::getSequenceNbr, installNotSeqs)
                    .eq(JgInstallationNotice::getUseUnitCreditCode, useUnitCreditCode)
                    .eq(JgInstallationNotice::getNoticeStatus, FlowStatusEnum.TO_BE_FINISHED.getCode())
                    .list().stream()
                    .findFirst().orElse(null);

            List<String> useRegSeqs = useRegistrationEqService.lambdaQuery()
                    .eq(JgUseRegistrationEq::getEquId, record)
                    .list().stream()
                    .filter(Objects::nonNull)
                    .map(JgUseRegistrationEq::getEquipTransferId)
                    .collect(Collectors.toList());

            JgUseRegistration useRegistration = useRegSeqs.isEmpty() ? null : useRegistrationService.lambdaQuery()
                    .in(JgUseRegistration::getSequenceNbr, useRegSeqs)
                    .eq(JgUseRegistration::getUseUnitCreditCode, useUnitCreditCode)
                    .eq(JgUseRegistration::getStatus, FlowStatusEnum.TO_BE_FINISHED.getName())
                    .list().stream()
                    .findFirst().orElse(null);

            List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery()
                    .eq(IdxBizJgUseInfo::getProjectContraption, projectContraption)
                    .eq(IdxBizJgUseInfo::getUseUnitCreditCode, useUnitCreditCode)
                    .list();

            List<IdxBizJgTechParamsPipeline> idxBizJgTechParamsPipelines = useInfos.isEmpty() ? new ArrayList<>() : techParamsPipelineService
                    .lambdaQuery()
                    .in(IdxBizJgTechParamsPipeline::getRecord, useInfos.stream()
                            .map(IdxBizJgUseInfo::getRecord)
                            .collect(Collectors.toList()))
                    .list();

            double pipeLengthSum = idxBizJgTechParamsPipelines.stream()
                    .filter(Objects::nonNull)
                    .filter(pip -> Objects.nonNull(pip.getPipeLength()))
                    .mapToDouble(pipeline -> Double.parseDouble(pipeline.getPipeLength()))
                    .sum();

            IdxBizJgRegisterInfo registerInfo = registerInfoService.lambdaQuery()
                    .eq(IdxBizJgRegisterInfo::getRecord, useInfos
                            .stream().findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgSupervisionInfo supervisionInfo = supervisionInfoService.lambdaQuery()
                    .eq(IdxBizJgSupervisionInfo::getRecord, useInfos
                            .stream()
                            .findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgFactoryInfo factoryInfo = factoryInfoService.lambdaQuery()
                    .eq(IdxBizJgFactoryInfo::getRecord, useInfos
                            .stream()
                            .findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgProjectContraption idxBizJgProjectContraption = IdxBizJgProjectContraption.builder()
                    .projectContraption(projectContraption)
                    .projectContraptionNo(projectContraption)
                    .useUnitCreditCode(isIntoManagement ? (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getUseUnitCreditCode()) : null)
                    .useUnitName(isIntoManagement ? (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getUseUnitName()) : null)
                    .uscUnitCreditCode(isIntoManagement ? (ObjectUtils.isEmpty(useRegistration) ? (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getInstallUnitCreditCode()) : null) : null)
                    .uscUnitName(isIntoManagement ? (ObjectUtils.isEmpty(useRegistration) ? (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getInstallUnitName()) : null) : null)
                    .equList(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquListCode())
                    .equListName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquList())
                    .equCategory(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode())
                    .equCategoryName(ObjectUtils.isEmpty(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode()))).getName())
                    .equDefine(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine())
                    .equDefineName(ObjectUtils.isEmpty(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, (ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine()))).getName())
                    .content(null)
                    .pipelineLength(pipeLengthSum)
                    .productPhoto(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getProductPhoto())
                    .otherAccessories(null)
                    .orgCode(ObjectUtils.isEmpty(supervisionInfo) ? null : supervisionInfo.getOrgBranchCode())
                    .orgName(ObjectUtils.isEmpty(supervisionInfo) ? null : supervisionInfo.getOrgBranchName())
                    .productQualificationCertificate(ObjectUtils.isEmpty(factoryInfo) ? null : factoryInfo.getProductQualityYieldProve())
                    .province(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getProvince())
                    .provinceName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getProvinceName())
                    .city(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCity())
                    .cityName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCityName())
                    .county(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCounty())
                    .countyName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCountyName())
                    .street(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getStreet())
                    .streetName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getStreetName())
                    .address(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getAddress())
                    .startLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getStartePosition())
                    .endLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getEndPosition())
                    .supervisoryCode(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getSupervisoryCode())
                    .useRegistrationCode(ObjectUtils.isEmpty(useRegistration) ? null : useRegistration.getUseRegistrationCode())
                    .isIntoManagement(isIntoManagement)
                    .dataSource("jg")
                    .build();
            idxBizJgProjectContraption.setSequenceNbr(sequenceNbr);
            idxBizJgProjectContraption.setRecDate(new Date());
            idxBizJgProjectContraption.setIsDelete(Boolean.FALSE);
            projectContraptionList.add(idxBizJgProjectContraption);
            if (projectContraptionList.size() % 1000 == 0 || isLast) {
                projectContraptionService.saveBatch(projectContraptionList);
                projectContraptionList.clear();
            }

            useInfoService.lambdaUpdate()
                    .set(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr)
                    .eq(IdxBizJgUseInfo::getProjectContraption, projectContraption)
                    .eq(IdxBizJgUseInfo::getUseUnitCreditCode, useUnitCreditCode)
                    .update();

            if (!installNotSeqs.isEmpty()) {
                installationNoticeService.lambdaUpdate()
                        .set(JgInstallationNotice::getProjectContraptionId, sequenceNbr)
                        .in(JgInstallationNotice::getSequenceNbr, installNotSeqs)
                        .eq(JgInstallationNotice::getProjectContraption, projectContraption)
                        .eq(JgInstallationNotice::getUseUnitCreditCode, useUnitCreditCode)
                        .update();
            }

            if (!useRegSeqs.isEmpty()) {
                useRegistrationService.lambdaUpdate()
                        .set(JgUseRegistration::getProjectContraptionId, sequenceNbr)
                        .in(JgUseRegistration::getSequenceNbr, useRegSeqs)
                        .eq(JgUseRegistration::getProjectContraption, projectContraption)
                        .eq(JgUseRegistration::getUseUnitCreditCode, useUnitCreditCode)
                        .update();
            }

        }
        return Boolean.TRUE;
    }

    /**
     * 刷入工程装置id到es的idx_biz_view_jg_all索引
     *
     * @return result
     */
    public String writeProjectContraptionId() {
        AtomicReference<Long> size = new AtomicReference<>(0L);
        StopWatch stopWatch = new StopWatch("writeProjectContraptionId");
        stopWatch.start();
        List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery()
                .select(IdxBizJgUseInfo::getRecord, IdxBizJgUseInfo::getProjectContraptionId)
                .isNotNull(IdxBizJgUseInfo::getProjectContraptionId)
                .list();
        for (IdxBizJgUseInfo useInfo : useInfos) {
            Optional<ESEquipmentCategoryDto> equInfosWithEs = esEquipmentCategory.findById(useInfo.getRecord());
            equInfosWithEs.ifPresent(equInfoEs -> {
                if (PipelineEnum.INDUSTRIAL_PIPELINE.getCode().equals(equInfoEs.getEQU_CATEGORY_CODE())) {
                    equInfoEs.setProjectContraptionId(useInfo.getProjectContraptionId());
                    esEquipmentCategory.save(equInfoEs);
                    size.getAndSet(size.get() + 1);
                }
            });
        }
        stopWatch.stop();
        return String.format("接口调用成功，更新数据：%s条，耗时：%s s", size.get(), stopWatch.getTotalTimeSeconds());
    }

    public Boolean writeDataUseCodeIsNull2ProjectContraption() {
        List<IdxBizJgUseInfo> collect = useInfoService.lambdaQuery()
                .select(IdxBizJgUseInfo::getRecord, IdxBizJgUseInfo::getProjectContraption, IdxBizJgUseInfo::getUseUnitCreditCode, IdxBizJgUseInfo::getUseUnitName, IdxBizJgUseInfo::getIsIntoManagement)
                .isNotNull(IdxBizJgUseInfo::getProjectContraption)
                .ne(IdxBizJgUseInfo::getProjectContraption, "")
                .isNull(IdxBizJgUseInfo::getUseUnitCreditCode)
                .groupBy(IdxBizJgUseInfo::getProjectContraption)
                .list().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        log.info("查询到的工程装置集合: {},总数：{}", JSON.toJSONString(collect), collect.size());

        List<IdxBizJgProjectContraption> projectContraptionList = new ArrayList<>();
        Iterator<IdxBizJgUseInfo> iterator = collect.iterator();
        while (iterator.hasNext()) {
            IdxBizJgUseInfo useInfo = iterator.next();
            boolean isLast = !iterator.hasNext();

            String record = useInfo.getRecord();
            Boolean isIntoManagement = ObjectUtils.isEmpty(useInfo.getIsIntoManagement()) ? Boolean.FALSE : useInfo.getIsIntoManagement();
            String projectContraption = useInfo.getProjectContraption();
            Long sequenceNbr = sequence.nextId();

            List<String> installNotSeqs = installationNoticeEqService.lambdaQuery()
                    .eq(JgInstallationNoticeEq::getEquId, record)
                    .list().stream()
                    .filter(Objects::nonNull)
                    .map(JgInstallationNoticeEq::getEquipTransferId)
                    .collect(Collectors.toList());

            JgInstallationNotice installationNotice = installNotSeqs.isEmpty() ? null : installationNoticeService.lambdaQuery()
                    .in(JgInstallationNotice::getSequenceNbr, installNotSeqs)
                    .list().stream()
                    .findFirst().orElse(null);

            List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery()
                    .eq(IdxBizJgUseInfo::getProjectContraption, projectContraption)
                    .list();

            // 技术参数表
            List<IdxBizJgTechParamsPipeline> idxBizJgTechParamsPipelines = useInfos.isEmpty() ? new ArrayList<>() : techParamsPipelineService
                    .lambdaQuery()
                    .in(IdxBizJgTechParamsPipeline::getRecord, useInfos.stream()
                            .map(IdxBizJgUseInfo::getRecord)
                            .collect(Collectors.toList()))
                    .list();

            double pipeLengthSum = idxBizJgTechParamsPipelines.stream()
                    .filter(Objects::nonNull)
                    .filter(pip -> Objects.nonNull(pip.getPipeLength()))
                    .mapToDouble(pipeline -> Double.parseDouble(pipeline.getPipeLength()))
                    .sum();

            IdxBizJgRegisterInfo registerInfo = registerInfoService.lambdaQuery()
                    .eq(IdxBizJgRegisterInfo::getRecord, useInfos
                            .stream().findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgSupervisionInfo supervisionInfo = supervisionInfoService.lambdaQuery()
                    .eq(IdxBizJgSupervisionInfo::getRecord, useInfos
                            .stream()
                            .findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgFactoryInfo factoryInfo = factoryInfoService.lambdaQuery()
                    .eq(IdxBizJgFactoryInfo::getRecord, useInfos
                            .stream()
                            .findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgProjectContraption idxBizJgProjectContraption = IdxBizJgProjectContraption.builder()
                    .projectContraption(projectContraption)
                    .projectContraptionNo(projectContraption)
                    .uscUnitCreditCode(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getInstallUnitCreditCode())
                    .uscUnitName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getInstallUnitName())
                    .equList(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquListCode())
                    .equListName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquList())
                    .equCategory(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode())
                    .equCategoryName(ObjectUtils.isEmpty(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, (ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getEquCategoryCode()))).getName())
                    .equDefine(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine())
                    .equDefineName(ObjectUtils.isEmpty(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, (ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine()))).getName())
                    .content(null)
                    .pipelineLength(pipeLengthSum)
                    .productPhoto(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getProductPhoto())
                    .otherAccessories(null)
                    .orgCode(ObjectUtils.isEmpty(supervisionInfo) ? null : supervisionInfo.getOrgBranchCode())
                    .orgName(ObjectUtils.isEmpty(supervisionInfo) ? null : supervisionInfo.getOrgBranchName())
                    .productQualificationCertificate(ObjectUtils.isEmpty(factoryInfo) ? null : factoryInfo.getProductQualityYieldProve())
                    .province(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getProvince())
                    .provinceName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getProvinceName())
                    .city(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCity())
                    .cityName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCityName())
                    .county(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCounty())
                    .countyName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getCountyName())
                    .street(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getStreet())
                    .streetName(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getStreetName())
                    .address(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getAddress())
                    .startLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getStartePosition())
                    .endLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getEndPosition())
                    .supervisoryCode(ObjectUtils.isEmpty(installationNotice) ? null : installationNotice.getSupervisoryCode())
                    .isIntoManagement(isIntoManagement)
                    .dataSource("jg")
                    .build();
            idxBizJgProjectContraption.setSequenceNbr(sequenceNbr);
            idxBizJgProjectContraption.setRecDate(new Date());
            idxBizJgProjectContraption.setIsDelete(Boolean.FALSE);
            projectContraptionList.add(idxBizJgProjectContraption);
            if (projectContraptionList.size() % 1000 == 0 || isLast) {
                projectContraptionService.saveBatch(projectContraptionList);
                projectContraptionList.clear();
            }

            useInfoService.lambdaUpdate()
                    .set(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr)
                    .eq(IdxBizJgUseInfo::getProjectContraption, projectContraption)
                    .update();

            if (!installNotSeqs.isEmpty()) {
                installationNoticeService.lambdaUpdate()
                        .set(JgInstallationNotice::getProjectContraptionId, sequenceNbr)
                        .in(JgInstallationNotice::getSequenceNbr, installNotSeqs)
                        .eq(JgInstallationNotice::getProjectContraption, projectContraption)
                        .update();
            }
        }
        return Boolean.TRUE;
    }

    public void writeSupervisionOrgCode2UseRegister() {
        // 使用历史表补充属地监管部门字段
        filledDataFromHistory();
        // 查询历史登记且单位办理的数据进行刷库（历史气瓶导入，manage_type=unit and reg_type=1）
        filledHisRegCylinderByUnit();
    }

    private void filledHisRegCylinderByUnit() {
        List<JgUseRegistration> useRegistrations = useRegistrationService.list(new LambdaQueryWrapper<JgUseRegistration>().isNull(JgUseRegistration::getSupervisionOrgCode).eq(JgUseRegistration::getManageType, "unit").eq(JgUseRegistration::getRegType, "1").select(BaseEntity::getSequenceNbr, JgUseRegistration::getUseUnitCreditCode));
        Map<String, String> unitSuperOrgCodeMap = new ConcurrentHashMap<>();
        useRegistrations.parallelStream().forEach(u -> {
            LambdaUpdateWrapper<JgUseRegistration> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(JgUseRegistration::getSequenceNbr, u.getSequenceNbr());
            if (unitSuperOrgCodeMap.get(u.getUseUnitCreditCode()) != null) {
                updateWrapper.set(JgUseRegistration::getSupervisionOrgCode, unitSuperOrgCodeMap.get(u.getUseUnitCreditCode()));
            } else {
                TzBaseEnterpriseInfo baseEnterpriseInfo = tzBaseEnterpriseInfoMapper.selectByUseUnitCode(u.getUseUnitCreditCode());
                if (baseEnterpriseInfo != null) {
                    unitSuperOrgCodeMap.put(u.getUseUnitCreditCode(), baseEnterpriseInfo.getSuperviseOrgCode());
                    updateWrapper.set(JgUseRegistration::getSupervisionOrgCode, baseEnterpriseInfo.getSuperviseOrgCode());
                } else {
                    updateWrapper.set(JgUseRegistration::getSupervisionOrgCode, null);
                }
            }
            useRegistrationService.update(null, updateWrapper);
        });
    }

    private void filledDataFromHistory() {
        List<JgUseRegistration> useRegistrations = useRegistrationService.list(new LambdaQueryWrapper<JgUseRegistration>().isNull(JgUseRegistration::getSupervisionOrgCode).select(BaseEntity::getSequenceNbr));
        useRegistrations.parallelStream().forEach(u -> {
            JgRegistrationHistory history = getRegistrationHistory(u.getSequenceNbr() + "");
            if (history != null) {
                JSONObject jsonObject = JSON.parseObject(history.getChangeData());
                String orgBranchCodeWithName = jsonObject.getString("orgBranchCode");
                if (orgBranchCodeWithName != null && !orgBranchCodeWithName.isEmpty()) {
                    u.setSupervisionOrgCode(orgBranchCodeWithName.split("_")[0]);
                    LambdaUpdateWrapper<JgUseRegistration> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.set(JgUseRegistration::getSupervisionOrgCode, u.getSupervisionOrgCode());
                    updateWrapper.eq(JgUseRegistration::getSequenceNbr, u.getSequenceNbr());
                    useRegistrationService.update(null, updateWrapper);
                }
            }
        });
    }

    @Transactional(rollbackFor = Exception.class)
    public void projectContraptionNoticeDataDeal() {
        // 1.安装告知完成但是设备状态未非已纳管状态：设备的idx_biz_jg_use_info表的IS_INTO_MANAGEMENT刷为已纳管, es的IS_INTO_MANAGEMENT刷为已纳管
        List<JgInstallationNoticeEq> eqs = jgInstallationNoticeEqMapper.selectErrorRecordOfInIntoManage();
        log.info("处理前统计：1.安装告知完成但是设备状态未非已纳管状态的设备数量：{}", eqs.size());
        for (JgInstallationNoticeEq eq : eqs) {
            // 使用信息表刷已纳管
            useInfoService.lambdaUpdate()
                    .set(IdxBizJgUseInfo::getIsIntoManagement, true)
                    .eq(IdxBizJgUseInfo::getRecord, eq.getEquId())
                    .update();
            // es刷已纳管
            Optional<ESEquipmentCategoryDto> equInfosWithEs = esEquipmentCategory.findById(eq.getEquId());
            equInfosWithEs.ifPresent(equInfoEs -> {
                equInfoEs.setIS_INTO_MANAGEMENT(true);
                esEquipmentCategory.save(equInfoEs);
            });
        }
        // 2.安装告知非已作废，但是缺少装置id的数据处理：创建装置、写入安装告知表project_contraption_id、写入设备es的装置id，设备使用信息表的projectContraptionId
        List<JgInstallationNotice> noticeList = getErrorInstallNoticeData();
        log.info("处理前统计：2.安装告知非已作废，但是缺少装置id安装告知单据数量：{}", noticeList.size());
        List<IdxBizJgProjectContraption> projectContraptionList = new ArrayList<>();
        Map<Long, List<String>> projectContraptionIdRecordsMap = new HashMap<>();
        for (JgInstallationNotice installationNotice : noticeList) {
            List<JgInstallationNoticeEq> noticeEqs = installationNoticeEqService.list(new LambdaQueryWrapper<JgInstallationNoticeEq>().eq(JgInstallationNoticeEq::getEquipTransferId, installationNotice.getSequenceNbr()).select(JgInstallationNoticeEq::getEquId, JgInstallationNoticeEq::getInformNumber));
            if (noticeEqs.isEmpty()) {
                continue;
            }
            List<String> records = noticeEqs.stream().map(JgInstallationNoticeEq::getEquId).collect(Collectors.toList());
            List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().in(IdxBizJgUseInfo::getRecord, records).list();
            // 技术参数表
            List<IdxBizJgTechParamsPipeline> idxBizJgTechParamsPipelines = useInfos.isEmpty() ? new ArrayList<>() : techParamsPipelineService
                    .lambdaQuery()
                    .in(IdxBizJgTechParamsPipeline::getRecord, records)
                    .list();
            double pipeLengthSum = idxBizJgTechParamsPipelines.stream()
                    .filter(Objects::nonNull)
                    .filter(pip -> Objects.nonNull(pip.getPipeLength()))
                    .mapToDouble(pipeline -> Double.parseDouble(pipeline.getPipeLength()))
                    .sum();
            BigDecimal pipeLengthSumBig = new BigDecimal(String.valueOf(pipeLengthSum)).setScale(3, RoundingMode.HALF_UP);

            IdxBizJgRegisterInfo registerInfo = registerInfoService.lambdaQuery()
                    .eq(IdxBizJgRegisterInfo::getRecord, useInfos
                            .stream().findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();

            IdxBizJgFactoryInfo factoryInfo = factoryInfoService.lambdaQuery()
                    .eq(IdxBizJgFactoryInfo::getRecord, useInfos
                            .stream()
                            .findFirst().orElse(new IdxBizJgUseInfo())
                            .getRecord())
                    .one();
            Long sequenceNbr = sequence.nextId();
            installationNotice.setProjectContraptionId(sequenceNbr + "");
            // key为装置id,value为此装置下的管道数组
            projectContraptionIdRecordsMap.put(sequenceNbr, records);
            boolean isFinish = String.valueOf(FlowStatusEnum.TO_BE_FINISHED.getCode()).equals(installationNotice.getNoticeStatus());
            IdxBizJgProjectContraption idxBizJgProjectContraption = IdxBizJgProjectContraption.builder()
                    .projectContraption(installationNotice.getProjectContraption())
                    .projectContraptionNo(installationNotice.getProjectContraption())
                    .useUnitCreditCode(isFinish ? installationNotice.getUseUnitCreditCode() : null)
                    .useUnitName(isFinish ? installationNotice.getUseUnitName() : null)
                    .uscUnitCreditCode(installationNotice.getInstallUnitCreditCode())
                    .uscUnitName(installationNotice.getInstallUnitName())
                    .equList(installationNotice.getEquListCode())
                    .equListName(installationNotice.getEquList())
                    .equCategory(installationNotice.getEquCategoryCode())
                    .equCategoryName(ObjectUtils.isEmpty(installationNotice.getEquCategoryCode()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, installationNotice.getEquCategoryCode())).getName())
                    .equDefine(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine())
                    .equDefineName(ObjectUtils.isEmpty(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getEquDefine()) ? null : equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, registerInfo.getEquDefine())).getName())
                    .content(null)
                    .pipelineLength(pipeLengthSumBig.doubleValue())
                    .productPhoto(ObjectUtils.isEmpty(registerInfo) ? null : registerInfo.getProductPhoto())
                    .productQualificationCertificate(ObjectUtils.isEmpty(factoryInfo) ? null : factoryInfo.getProductQualityYieldProve())
                    .otherAccessories(installationNotice.getOtherAccessories())
                    .orgCode(installationNotice.getOrgBranchCode())
                    .orgName(installationNotice.getOrgBranchName())
                    .province(installationNotice.getProvince())
                    .provinceName(installationNotice.getProvinceName())
                    .city(installationNotice.getCity())
                    .cityName(installationNotice.getCityName())
                    .county(installationNotice.getCounty())
                    .countyName(installationNotice.getCountyName())
                    .street(installationNotice.getFactoryUseSiteStreet())
                    .streetName(installationNotice.getStreetName())
                    .address(installationNotice.getAddress())
                    .startLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getStartePosition())
                    .endLatitudeLongitude(ObjectUtils.isEmpty(idxBizJgTechParamsPipelines) ? null : idxBizJgTechParamsPipelines.get(0).getEndPosition())
                    .supervisoryCode(installationNotice.getSupervisoryCode())
                    .isIntoManagement(isFinish)
                    .dataSource("jg")
                    .build();
            idxBizJgProjectContraption.setSequenceNbr(sequenceNbr);
            idxBizJgProjectContraption.setRecDate(new Date());
            idxBizJgProjectContraption.setIsDelete(Boolean.FALSE);
            // 安装告知完成后，创建装置的施工信息表
            saveProjectConstructionAfterFinish(installationNotice, isFinish, noticeEqs, sequenceNbr, records);
            // 安装告知表写入装置id
            updateProjectContraptionId2Notice(installationNotice, idxBizJgProjectContraption);
            projectContraptionList.add(idxBizJgProjectContraption);
        }
        // 创建装置
        if (!projectContraptionList.isEmpty()) {
            projectContraptionService.saveBatch(projectContraptionList);
        }
        // 更新设备es的装置id、使用信息的装置id
        projectContraptionIdRecordsMap.forEach((k,v)->{
            IdxBizJgProjectContraption idxBizJgProjectContraption = projectContraptionService.getById(k);
            Iterable<ESEquipmentCategoryDto> equipmentCategories = esEquipmentCategory.findAllById(v);
            equipmentCategories.forEach(e-> e.setProjectContraptionId(k + ""));
            esEquipmentCategory.saveAll(equipmentCategories);
            Collection<IdxBizJgUseInfo> useInfos = useInfoService.getUseInfoListByEquIds(v);
            useInfos.forEach(u->{
                LambdaUpdateWrapper<IdxBizJgUseInfo> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(IdxBizJgUseInfo::getRecord, u.getRecord());
                updateWrapper.set(IdxBizJgUseInfo::getProjectContraptionId, k);
                updateWrapper.set(IdxBizJgUseInfo::getProjectContraption, idxBizJgProjectContraption.getProjectContraption());
                useInfoService.update(updateWrapper);
            });
        });
        List<JgInstallationNoticeEq> eqsAfter = jgInstallationNoticeEqMapper.selectErrorRecordOfInIntoManage();
        log.info("处理后统计：3.安装告知完成但是设备状态未非已纳管状态的设备数量：{}", eqsAfter.size());
        List<JgInstallationNotice> noticeListAfter = getErrorInstallNoticeData();
        log.info("处理后统计：4.安装告知非已作废，但是缺少装置id安装告知单据数量：{}", noticeListAfter.size());
    }

    private void updateProjectContraptionId2Notice(JgInstallationNotice installationNotice, IdxBizJgProjectContraption idxBizJgProjectContraption) {
        LambdaUpdateWrapper<JgInstallationNotice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(JgInstallationNotice::getProjectContraptionId, installationNotice.getProjectContraptionId());
        updateWrapper.eq(BaseEntity::getSequenceNbr, installationNotice.getSequenceNbr());
        installationNoticeService.update(null, updateWrapper);
    }

    private void saveProjectConstructionAfterFinish(JgInstallationNotice installationNotice, boolean isFinish, List<JgInstallationNoticeEq> eqs, Long sequenceNbr, List<String> records) {
        if (isFinish) {
            IdxBizJgProjectConstruction idxBizJgProjectConstruction = new IdxBizJgProjectConstruction();
            idxBizJgProjectConstruction.setUscUnitCreditCode(installationNotice.getInstallUnitCreditCode());
            idxBizJgProjectConstruction.setUscUnitName(installationNotice.getInstallUnitName());
            idxBizJgProjectConstruction.setUscDate(installationNotice.getInstallStartDate());
            idxBizJgProjectConstruction.setRecord(String.valueOf(installationNotice.getSequenceNbr()));
            idxBizJgProjectConstruction.setSequenceCode(String.valueOf(installationNotice.getSequenceNbr()));
            idxBizJgProjectConstruction.setNoticeId(String.valueOf(installationNotice.getSequenceNbr()));
            idxBizJgProjectConstruction.setInformCode(eqs.stream().findFirst().orElse(new JgInstallationNoticeEq()).getInformNumber());
            idxBizJgProjectConstruction.setConstructionLeaderId(installationNotice.getInstallLeaderId());
            idxBizJgProjectConstruction.setConstructionLeaderName(installationNotice.getInstallLeaderName());
            idxBizJgProjectConstruction.setConstructionLeaderPhone(installationNotice.getInstallLeaderPhone());
            idxBizJgProjectConstruction.setAddress(installationNotice.getAddress());
            idxBizJgProjectConstruction.setProvinceName(installationNotice.getProvinceName());
            idxBizJgProjectConstruction.setCityName(installationNotice.getCityName());
            idxBizJgProjectConstruction.setCountyName(installationNotice.getCountyName());
            idxBizJgProjectConstruction.setStreetName(installationNotice.getStreetName());
            idxBizJgProjectConstruction.setIsXixian(installationNotice.getIsXixian());
            idxBizJgProjectConstruction.setProjectContraptionId(sequenceNbr + "");
            idxBizJgProjectConstruction.setEquipRecords(StringUtils.join(records, ","));
            idxBizJgProjectConstruction.setConstructionContractAttachment(installationNotice.getInstallContractAttachment());
            idxBizJgProjectConstruction.setProxyStatementAttachment(installationNotice.getProxyStatementAttachment());
            idxBizJgProjectConstruction.setConstructionOtherAccessories(installationNotice.getOtherAccessories());
            idxBizJgProjectConstruction.setRecDate(new Date());
            idxBizJgProjectConstruction.setRecUserId(RequestContext.getExeUserId());
            LambdaQueryWrapper<DataDictionary> lambda = new LambdaQueryWrapper<>();
            // 获取施工类型id
            lambda.eq(DataDictionary::getType, CONSTRUCTION_TYPE);
            lambda.eq(DataDictionary::getName, CONSTRUCTION_TYPE_NAME);
            List<DataDictionary> dataDictionaries = dataDictionaryMapper.selectList(lambda);
            if (!CollectionUtils.isEmpty(dataDictionaries)) {
                idxBizJgProjectConstruction.setConstructionType(String.valueOf(dataDictionaries.get(0).getSequenceNbr()));
            }
            projectConstructionMapper.insert(idxBizJgProjectConstruction);
        }
    }

    private List<JgInstallationNotice> getErrorInstallNoticeData() {
        return installationNoticeService.list(new LambdaQueryWrapper<JgInstallationNotice>().ne(JgInstallationNotice::getNoticeStatus, FlowStatusEnum.TO_BE_DISCARD.getCode()).ne(JgInstallationNotice::getProjectContraption, "").isNull(JgInstallationNotice::getProjectContraptionId));
    }

    /**
     * 刷使用登记缺少装置id的管道的登记数据：1.填充装置id；2.已完成状状态清除装置表的安装单位信息字段,补充使用信息字段
     */
    @Transactional(rollbackFor = Exception.class)
    public void projectContraptionUseRegisterDataDeal() {
        // 查询使用登记：非作废状态 有装置名称但是缺少装置id的使用登记单据进行数据处理
        List<JgUseRegistration> useRegistrations = getUseRegisterOfError();
        log.info("处理前统计：1.使用登记装置id历史数据填充，存在缺少装置id的单据数量：{}", useRegistrations.size());
        // 循环按照使用登记的eq表关联安装告知eq表，在安装告知主表查询装置id
        for (JgUseRegistration useRegistration : useRegistrations) {
            // 登记的关联的告知单据【逻辑按照eq进行关联】
            JgInstallationNotice installationNotice = installationNoticeService.getBaseMapper().selectNoticeDataByUseRegisterId(useRegistration.getSequenceNbr() + "");
            if (installationNotice != null && StringUtils.isNotEmpty(installationNotice.getProjectContraptionId())) {
                // 0.填充装置id
                useRegistration.setProjectContraptionId(installationNotice.getProjectContraptionId());
                // 1.已完成状状态清除装置表的安装单位信息字段,填充使用信息数据，创建装置检验信息表
                if (FlowStatusEnum.TO_BE_FINISHED.getName().equals(useRegistration.getStatus())) {
                    updateProjectContraptionAfter(useRegistration, installationNotice);
                    // 创建装置检验流水信息
                    createProjectInspectInfoAfter(useRegistration);
                }
                // 2.使用登记写入装置id
                LambdaUpdateWrapper<JgUseRegistration> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(JgUseRegistration::getProjectContraptionId, useRegistration.getProjectContraptionId());
                updateWrapper.eq(BaseEntity::getSequenceNbr, useRegistration.getSequenceNbr());
                useRegistrationService.update(null, updateWrapper);
            }
        }
        List<JgUseRegistration> useRegistrationsAfter = getUseRegisterOfError();
        log.info("处理后统计：2.使用登记装置id历史数据填充，存在缺少装置id的单据数量：{}", useRegistrationsAfter.size());
    }

    private void updateProjectContraptionAfter(JgUseRegistration useRegistration, JgInstallationNotice installationNotice) {
        // 特殊处理 将任意一个的 record 放入到remark字段
        IdxBizJgUseInfo useInfo = getIdxBizJgUseInfo(installationNotice.getRemark());
        if (useInfo != null) {
            LambdaUpdateWrapper<IdxBizJgProjectContraption> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(BaseEntity::getSequenceNbr, installationNotice.getProjectContraptionId());
            updateWrapper.set(IdxBizJgProjectContraption::getUscUnitCreditCode, null);
            updateWrapper.set(IdxBizJgProjectContraption::getUscUnitName, null);
            updateWrapper.set(IdxBizJgProjectContraption::getUseRegistrationCode, useRegistration.getUseRegistrationCode());
            updateWrapper.set(IdxBizJgProjectContraption::getProvince, useInfo.getProvince());
            updateWrapper.set(IdxBizJgProjectContraption::getProvinceName, useInfo.getProvinceName());
            updateWrapper.set(IdxBizJgProjectContraption::getCity, useInfo.getCity());
            updateWrapper.set(IdxBizJgProjectContraption::getCityName, useInfo.getCityName());
            updateWrapper.set(IdxBizJgProjectContraption::getCounty, useInfo.getCounty());
            updateWrapper.set(IdxBizJgProjectContraption::getCountyName, useInfo.getCountyName());
            updateWrapper.set(IdxBizJgProjectContraption::getStreet, useInfo.getFactoryUseSiteStreet());
            updateWrapper.set(IdxBizJgProjectContraption::getStreetName, useInfo.getStreetName());
            updateWrapper.set(IdxBizJgProjectContraption::getAddress, useInfo.getAddress());
            updateWrapper.set(IdxBizJgProjectContraption::getUseDate, useRegistration.getAuditPassDate());
            projectContraptionService.update(null, updateWrapper);
        }
    }

    private void createProjectInspectInfoAfter(JgUseRegistration useRegistration) {
        JgRegistrationHistory jgRegistrationHistory = getRegistrationHistory(useRegistration.getSequenceNbr() + "");
        if (jgRegistrationHistory != null) {
            JSONObject mapData = JSONObject.parseObject(jgRegistrationHistory.getChangeData());
            IdxBizJgProjectInspection inspectionDetectionInfo = new IdxBizJgProjectInspection();
            BeanUtil.copyProperties(mapData, inspectionDetectionInfo);
            // 兼容最早的老数据，管道的检验信息单独维护
            if (inspectionDetectionInfo.getInspectConclusion() == null && mapData.containsKey("equipmentLists")) {
                List<Map<String, Object>> equipmentLists = null;
                try {
                    equipmentLists = objectMapper.readValue(
                            objectMapper.writeValueAsString(mapData.get("equipmentLists")),
                            new TypeReference<ArrayList<Map<String, Object>>>() {
                            }
                    );
                    if (!equipmentLists.isEmpty()) {
                        Object record = equipmentLists.get(0).get("record");
                        IdxBizJgInspectionDetectionInfo idxBizJgInspectionDetectionInfo = iIdxBizJgInspectionDetectionInfoService.queryNewestDetailByRecord(String.valueOf(record));
                        BeanUtil.copyProperties(idxBizJgInspectionDetectionInfo, inspectionDetectionInfo);
                        inspectionDetectionInfo.setRecord(null);
                    }
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            }
            inspectionDetectionInfo.setProjectContraptionId(useRegistration.getProjectContraptionId());
            inspectionDetectionInfo.setRecDate(new Date());

            // 使用登记创建新增的检验信息id设置为使用登记的主键id,在作废时级联作废
            inspectionDetectionInfo.setSequenceNbr(useRegistration.getSequenceNbr() + "");
            projectInspectionMapper.insert(inspectionDetectionInfo);
        }

    }

    private IdxBizJgUseInfo getIdxBizJgUseInfo(String record) {
        return useInfoService.getOneData(record);
    }

    /**
     * 查询非作废状态的装置名称不为空，装置id为空或者null的使用登记数据
     *
     * @return 符合条件列表
     */
    private List<JgUseRegistration> getUseRegisterOfError() {
        return useRegistrationService.getBaseMapper().selectList(new LambdaQueryWrapper<JgUseRegistration>().ne(JgUseRegistration::getStatus, FlowStatusEnum.TO_BE_DISCARD.getName()).ne(JgUseRegistration::getProjectContraption, "").isNull(JgUseRegistration::getProjectContraptionId).select(BaseEntity::getSequenceNbr, JgUseRegistration::getProjectContraption, JgUseRegistration::getUseRegistrationCode, JgUseRegistration::getStatus, JgUseRegistration::getAuditPassDate));
    }

    /**
     * 处理管道-安装告知审批完成但是装置是否纳管状态不正确的数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void projectContraptionInfoUpdateV2() {
        List<IdxBizJgProjectContraption> projectConstructions = idxBizJgProjectContraptionMapper.selectErrorManagementProject();
        log.info("处理前：安装告知审批完成但是装置是否纳管状态不正确的数据量：{}", projectConstructions.size());
        projectConstructions.parallelStream().forEach(p -> {
            LambdaUpdateWrapper<IdxBizJgProjectContraption> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(BaseEntity::getSequenceNbr, p.getSequenceNbr());
            updateWrapper.set(IdxBizJgProjectContraption::getUscUnitName, p.getUscUnitName());
            updateWrapper.set(IdxBizJgProjectContraption::getUscUnitCreditCode, p.getUscUnitCreditCode());
            updateWrapper.set(IdxBizJgProjectContraption::getUseUnitName, p.getUseUnitName());
            updateWrapper.set(IdxBizJgProjectContraption::getUseUnitCreditCode, p.getUseUnitCreditCode());
            updateWrapper.set(BaseEntity::getRecDate, p.getRecDate());
            updateWrapper.set(IdxBizJgProjectContraption::getIsIntoManagement, true);
            projectContraptionService.update(null, updateWrapper);
        });
        List<IdxBizJgProjectContraption> projectConstructionsAfter = idxBizJgProjectContraptionMapper.selectErrorManagementProject();
        log.info("处理后：安装告知审批完成但是装置是否纳管状态不正确的数据量：{}", projectConstructionsAfter.size());
    }

    @Transactional(rollbackFor = Exception.class)
    public void projectUseInfoUpdateV3() {
        List<JgInstallationNoticeEq> eqs = jgInstallationNoticeEqMapper.selectPCIdNeErrorPieLineInUseInfo();
        log.info("处理前：查询安装告知（非删除、已作废）的装置id和设备的使用信息装置id不一样的设备：{}", eqs.size());
        eqs.forEach(eq -> {
            Optional<ESEquipmentCategoryDto> equInfosWithEs = esEquipmentCategory.findById(eq.getEquId());
            equInfosWithEs.ifPresent(equInfoEs -> {
                if(StringUtils.isNotEmpty(equInfoEs.getProjectContraptionId())){
                    IdxBizJgProjectContraption idxBizJgProjectContraption = projectContraptionService.getById(equInfoEs.getProjectContraptionId());
                    LambdaUpdateWrapper<IdxBizJgUseInfo> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(IdxBizJgUseInfo::getRecord, equInfoEs.getSEQUENCE_NBR());
                    updateWrapper.set(IdxBizJgUseInfo::getProjectContraptionId, idxBizJgProjectContraption.getSequenceNbr());
                    updateWrapper.set(IdxBizJgUseInfo::getProjectContraption, idxBizJgProjectContraption.getProjectContraption());
                    useInfoService.update(updateWrapper);
                }
            });
        });
        List<JgInstallationNoticeEq> eqsAfter = jgInstallationNoticeEqMapper.selectPCIdNeErrorPieLineInUseInfo();
        log.info("处理后：查询安装告知（非删除、已作废）的装置id和设备的使用信息装置id不一样的设备：{}", eqsAfter.size());
    }

    @Transactional(rollbackFor = Exception.class)
    public void projectContraptionInfoUpdateV3() {
        // 1220上线时, 已完成安装告知管道未写入装置的施工信息表的告知单据查询
        List<JgInstallationNotice> noticeList = getNotInsertProjectConstructionInstallNotice();
        log.info("处理前统计：1.管道已完成安装告知，但是未写入装置的施工信息表的告知单据数量：{}", noticeList.size());
        for (JgInstallationNotice installationNotice : noticeList) {
            List<JgInstallationNoticeEq> noticeEqs = installationNoticeEqService.list(new LambdaQueryWrapper<JgInstallationNoticeEq>().eq(JgInstallationNoticeEq::getEquipTransferId, installationNotice.getSequenceNbr()).select(JgInstallationNoticeEq::getEquId));
            if (noticeEqs.isEmpty()) {
                continue;
            }
            List<String> records = noticeEqs.stream().map(JgInstallationNoticeEq::getEquId).collect(Collectors.toList());
            // 安装告知完成后，创建装置的施工信息表
            saveProjectConstructionAfterFinish(installationNotice, true, noticeEqs, Long.parseLong(installationNotice.getProjectContraptionId()), records);
        }
        List<JgInstallationNotice> noticeListAfter = getNotInsertProjectConstructionInstallNotice();
        log.info("处理后统计：1.管道已完成安装告知，但是未写入装置的施工信息表的告知单据数量：{}", noticeListAfter.size());

    }

    private List<JgInstallationNotice> getNotInsertProjectConstructionInstallNotice() {
        return jgInstallationNoticeMapper.selectNotInsertProjectConstructionInstallNoticeList();
    }

    /**
     * 之前刷库问题导致的管道的装置id与安装告知的装置id的不一样的数据刷库
     * 已安装告知为准，刷1.使用信息表的装置id；2.es的装置id。进行比对装置的安装信息与安装告知的信息安装信息对上才刷【使用登记审批完成后，装置表的安装单位信息回清空，故不包括这部分数据】】
     */
    @Transactional(rollbackFor = Exception.class)
    public void projectUseInfoUpdateV4() {
        List<PieLineEquipContraptionDto> eqs = jgInstallationNoticeEqMapper.selectPCIdNeErrorPieLineInUseInfo2();
        log.info("处理前：查询管道的装置id与安装告知的装置id的不一样管道设备：{}", eqs.size());
        eqs.forEach(eq -> {
            // 1.已安装告知单据为准更新es
            Optional<ESEquipmentCategoryDto> equInfosWithEs = esEquipmentCategory.findById(eq.getRecord());
            equInfosWithEs.ifPresent(equInfoEs -> {
                equInfoEs.setProjectContraptionId(eq.getProjectContraptionId());
                equInfoEs.setPROJECT_CONTRAPTION(eq.getProjectContraption());
                esEquipmentCategory.save(equInfoEs);
            });
            // 2.已安装告知单据为准更新use_info
            LambdaUpdateWrapper<IdxBizJgUseInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(IdxBizJgUseInfo::getRecord, eq.getRecord());
            updateWrapper.set(IdxBizJgUseInfo::getProjectContraptionId, eq.getProjectContraptionId());
            updateWrapper.set(IdxBizJgUseInfo::getProjectContraption, eq.getProjectContraption());
            useInfoService.update(updateWrapper);
        });
        List<PieLineEquipContraptionDto> eqsAfter = jgInstallationNoticeEqMapper.selectPCIdNeErrorPieLineInUseInfo2();
        log.info("处理后：查询管道装置id与安装告知的装置id的不一样管道设备：{}", eqsAfter.size());
    }

    /**
     * 处理一个管道在多个安装告知里，刷管道的use_info、es的装置id,已最新安装告知为准
     */
    @Transactional(rollbackFor = Exception.class)
    public void projectUseInfoUpdateV5() {
        List<PieLineEquipContraptionDto> eqs = jgInstallationNoticeEqMapper.selectPCIdNeErrorPieLineInUseInfo3();
        log.info("处理前：一个管道在多个安装告知里，安装告知的装置id的不一样管道设备：{}", eqs.size());
        eqs.forEach(eq -> {
            JgInstallationNoticeEqDto jgInstallationNoticeEqDto = jgInstallationNoticeEqMapper.selectLatestNoticeByRecord(eq.getRecord());
            JgInstallationNotice jgInstallationNotice = jgInstallationNoticeMapper.selectOne(new LambdaQueryWrapper<JgInstallationNotice>().eq(BaseEntity::getSequenceNbr, jgInstallationNoticeEqDto.getEquipTransferId()).select(JgInstallationNotice::getProjectContraptionId, JgInstallationNotice::getProjectContraption));
            // 1.已安装告知单据为准更新es
            Optional<ESEquipmentCategoryDto> equInfosWithEs = esEquipmentCategory.findById(eq.getRecord());
            equInfosWithEs.ifPresent(equInfoEs -> {
                equInfoEs.setProjectContraptionId(jgInstallationNotice.getProjectContraptionId());
                equInfoEs.setPROJECT_CONTRAPTION(jgInstallationNotice.getProjectContraption());
                esEquipmentCategory.save(equInfoEs);
            });
            // 2.已安装告知单据为准更新use_info
            LambdaUpdateWrapper<IdxBizJgUseInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(IdxBizJgUseInfo::getRecord, eq.getRecord());
            updateWrapper.set(IdxBizJgUseInfo::getProjectContraptionId, jgInstallationNotice.getProjectContraptionId());
            updateWrapper.set(IdxBizJgUseInfo::getProjectContraption, jgInstallationNotice.getProjectContraption());
            useInfoService.update(updateWrapper);
        });
    }

    public Boolean writeProjectContraptionIdInJgUseRegistration() {
        List<JgUseRegistration> useRegistrations = useRegistrationService.list(
                new LambdaQueryWrapper<JgUseRegistration>()
                        .isNotNull(JgUseRegistration::getProjectContraptionId)
                        .isNull(JgUseRegistration::getOriginProjectContraptionIds)
                        .select(BaseEntity::getSequenceNbr, JgUseRegistration::getProjectContraptionId)
        );

        for (JgUseRegistration u : useRegistrations) {
            // 更新 JgUseRegistration 表
            useRegistrationService.lambdaUpdate()
                    .set(JgUseRegistration::getOriginProjectContraptionIds, u.getProjectContraptionId())
                    .eq(JgUseRegistration::getSequenceNbr, u.getSequenceNbr())
                    .update();

            // 更新 JgUseRegistrationEq 表
            LambdaQueryWrapper<JgUseRegistrationEq> lambda = new QueryWrapper<JgUseRegistrationEq>().lambda();
            lambda.eq(JgUseRegistrationEq::getEquipTransferId, u.getSequenceNbr());
            List<JgUseRegistrationEq> jgUseRegistrationEqList = useRegistrationEqService.getBaseMapper().selectList(lambda);

            if (jgUseRegistrationEqList != null) {
                for (JgUseRegistrationEq eq : jgUseRegistrationEqList) {
                    useRegistrationEqService.lambdaUpdate()
                            .set(JgUseRegistrationEq::getOriginProjectContraptionId, u.getProjectContraptionId())
                            .eq(JgUseRegistrationEq::getSequenceNbr, eq.getSequenceNbr())
                            .update();
                }
            }
        }
        return true;
    }

    /**
     * 将历史导入的普通气瓶和正常导入的普通气瓶刷入设备状态
     *
     * @return result
     */
    public String ordinaryGasCylinderWriteEquState() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 所有的历史导入的普通气瓶 dataSource = 'jg_his' + 过滤出做了报废注销启用停用的业务设备 设备状态为 在用 （EquimentEnum.ZAIYONG.getCode()）
        List<String> allHisRecords = dataHandlerMapper.selectOrdinaryHisGasCylinder();
        useInfoService.lambdaUpdate().in(IdxBizJgUseInfo::getRecord, allHisRecords).set(IdxBizJgUseInfo::getEquState, EquimentEnum.ZAIYONG.getCode()).update();
        allHisRecords.forEach(record -> {
            Optional<ESEquipmentCategoryDto> categoryDto = esEquipmentCategory.findById(record);
            categoryDto.ifPresent(categoryEs -> {
                categoryEs.setEQU_STATE(EquimentEnum.ZAIYONG.getCode());
                esEquipmentCategory.save(categoryEs);
            });
        });
        // 所有的正常导入的普通气瓶 dataSource = 'jg' + 过滤出做了使用登记业务的设备 设备状态为 未登记 （EquimentEnum.WEIDENGJI.getCode()）
        List<String> allRecords = dataHandlerMapper.selectOrdinaryGasCylinder();
        useInfoService.lambdaUpdate().in(IdxBizJgUseInfo::getRecord, allRecords).set(IdxBizJgUseInfo::getEquState, EquimentEnum.WEIDENGJI.getCode()).update();
        allRecords.forEach(record -> {
            Optional<ESEquipmentCategoryDto> categoryDto = esEquipmentCategory.findById(record);
            categoryDto.ifPresent(categoryEs -> {
                categoryEs.setEQU_STATE(EquimentEnum.WEIDENGJI.getCode());
                esEquipmentCategory.save(categoryEs);
            });
        });

        stopWatch.stop();

        return String.format("刷入数据%s条，耗时：%s秒", allHisRecords.size() + allRecords.size(), stopWatch.getTotalTimeSeconds());
    }

    public void initFormUrl() {
        jgVehicleInformationService.initFormUrl();
        useRegistrationService.initFormUrl();
    }

    public void synchronizeEqData2ES(String records, Boolean isAgw, Boolean isIntoManagement) {
        if (records == null || records.isEmpty()) {
            return;
        }
        String[] recordArr = records.trim().split(",");
        for (String record : recordArr) {
            Map<String, Object> map = categoryOtherInfoMapper.selectDataById(record);
            categoryOtherInfoMapper.updateEsStatus(record);
            ESEquipmentCategoryDto dto = JSON.parseObject(toJSONString(map), ESEquipmentCategoryDto.class);
            Optional<ESEquipmentCategoryDto> data = esEquipmentCategory.findById(record);
            if (!ObjectUtils.isEmpty(data)) {
                esEquipmentCategory.deleteById(record);
            }
            if (!ObjectUtils.isEmpty(dto)) {
                long time = Timestamp.valueOf(map.get("REC_DATE").toString().substring(0, 19)).getTime();
                dto.setREC_DATE(time);
                // 需要安装的设备 安装告知审批通过 清除设备的USC_UNIT_CREDIT_CODE安装单位信息
                // 使用单位编辑 防止更新设备时将安改维单位信息更新到es中
                if (!isAgw) {
                    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());
                }
                dto.setIS_INTO_MANAGEMENT(isIntoManagement);
                IdxBizJgUseInfo useInfo = useInfoService.lambdaQuery().eq(IdxBizJgUseInfo::getRecord, record).one();
                dto.setUSE_PLACE_CODE(useInfo.getProvince() + "#" + useInfo.getCity() + "#" + useInfo.getCounty() + "#" + useInfo.getFactoryUseSiteStreet());
                dto.setUSE_SITE_CODE(useInfo.getUsePlace());
                esEquipmentCategory.save(dto);
            }
        }
    }
}
