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

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Sets;
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.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
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.CodeGenerateDto;
import com.yeejoin.amos.boot.module.jg.api.dto.EquipRequestParamsDto;
import com.yeejoin.amos.boot.module.jg.api.dto.JgResumeInfoDto;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.CompanyTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.UseRegisterCancelEquipEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgUseRegistrationEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgVehicleInformationMapper;
import com.yeejoin.amos.boot.module.jg.biz.edit.utils.JsonDiffUtil;
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.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.util.*;
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.IdxBizJgRegisterInfoServiceImpl.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class EquipClaimServiceImpl {

    private static final String JG_ALL_INDEX = "idx_biz_view_jg_all";

    private static final String NUMBER = "number";
    private static final String SIZE = "size";
    private static final String SEQUENCE_NBR = "SEQUENCE_NBR";
    private static final String EQU_STATE = "EQU_STATE";
    private static final String record = "record";
    private static final String RECORD = "RECORD";
    private static final String CREATE_DATE = "CREATE_DATE";
    private static final String DATA_SOURCE = "DATA_SOURCE";
    private static final String IS_INTO_MANAGEMENT = "IS_INTO_MANAGEMENT";
    private static final String EQU_LIST_CODE = "EQU_LIST_CODE";
    private static final String EQU_CATEGORY_CODE = "EQU_CATEGORY_CODE";
    private static final String EQU_DEFINE_CODE = "EQU_DEFINE_CODE";
    private static final String PRODUCT_NAME = "PRODUCT_NAME";
    private static final String EQU_CODE = "EQU_CODE";
    private static final String USE_UNIT_NAME = "USE_UNIT_NAME";
    private static final String ORG_BRANCH_CODE = "ORG_BRANCH_CODE";
    private static final String ADDRESS = "ADDRESS";
    private static final String data_source = "data_source";
    private static final String jg_his_xa = "jg_his_xa";
    private static final String is_into_management = "is_into_management";
    private static final String equ_list = "equ_list";
    private static final String create_date = "create_date";
    public static final String JG_HIS_XA_CLAIM = "jg_his_xa_claim";
    public static final String USE_REGISTRATION_CODE = "useRegistrationCode";
    public static final String PROJECT_CONTRAPTION_NO = "PROJECT_CONTRAPTION_NO";
    public static final String PROJECT_CONTRAPTION = "PROJECT_CONTRAPTION";

    private final RedisUtils redisUtils;
    private final CommonServiceImpl commonService;
    private final RestHighLevelClient restHighLevelClient;
    private final JgResumeInfoServiceImpl jgResumeInfoService;
    private final IdxBizJgProjectContraptionServiceImplService projectContraptionServiceImplService;
    private final IdxBizJgRegisterInfoServiceImpl jgRegisterInfoService;
    private final IIdxBizJgConstructionInfoService iIdxBizJgConstructionInfoService;
    private final IIdxBizJgUseInfoService idxBizJgUseInfoService;
    private final IIdxBizJgDesignInfoService iIdxBizJgDesignInfoService;
    private final IIdxBizJgFactoryInfoService iIdxBizJgFactoryInfoService;
    private final IIdxBizJgOtherInfoService iIdxBizJgOtherInfoService;
    private final IIdxBizJgSupervisionInfoService iIdxBizJgSupervisionInfoService;
    private final IIdxBizJgInspectionDetectionInfoService iIdxBizJgInspectionDetectionInfoService;
    private final JgUseRegistrationServiceImpl useRegistrationService;
    private final JgUseRegistrationEqMapper jgRelationEquipMapper;
    private final TzsServiceFeignClient tzsServiceFeignClient;
    private final IdxBizJgSupervisionInfoMapper idxBizJgSupervisionInfoMapper;
    private final IdxBizJgRegisterInfoMapper idxBizJgRegisterInfoMapper;
    private final IdxBizJgDesignInfoServiceImpl idxBizJgDesignInfoService;
    private final IdxBizJgDesignInfoMapper idxBizJgDesignInfoMapper;
    private final IdxBizJgFactoryInfoServiceImpl idxBizJgFactoryInfoService;
    private final IdxBizJgFactoryInfoMapper idxBizJgFactoryInfoMapper;
    private final IdxBizJgUseInfoMapper useInfoMapper;
    private final IdxBizJgOtherInfoMapper otherInfoMapper;
    private final SnowflakeIdUtil sequence;
    private final IIdxBizJgProjectContraptionService idxBizJgProjectContraptionService;
    private final JgUseRegistrationManageServiceImpl jgUseRegistrationManageService;
    private final JgVehicleInformationMapper jgVehicleInformationMapper;
    private final IIdxBizJgTechParamsPipelineService iIdxBizJgTechParamsPipelineService;
    private final ESEquipmentCategory esEquipmentCategory;
    private final JgRegistrationHistoryServiceImpl jgRegistrationHistoryService;
    private final JgUseRegistrationEqServiceImpl jgUseRegistrationEqServiceImpl;
    private final JgCertificateChangeRecordServiceImpl certificateChangeRecordService;
    private final JgCertificateChangeRecordEqServiceImpl certificateChangeRecordEqService;
    private final DataDockServiceImpl dockService;
    private final IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoServiceImpl;
    private final CodeUtil codeUtil;
    private final TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;

    private final EventPublisher eventPublisher;

    /**
     * 当前登录人信息
     *
     * @return 当前登录人信息
     */
    protected ReginParams getSelectedOrgInfo() {
        return JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
    }

    /**
     * 待认领-台套设备分页
     *
     * @param params 筛选条件
     * @return result
     */
    public Page<JSONObject> setEquipPage(JSONObject params) {
        int number = Integer.parseInt((String) params.getOrDefault(NUMBER, "1"));
        int size = Integer.parseInt((String) params.getOrDefault(SIZE, "20"));
        long totle = 0;
        Page<JSONObject> result = new Page<>(number, size);

        SearchRequest request = new SearchRequest();
        request.indices(JG_ALL_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        // 默认条件 DATA_SOURCE == jg_his_xa && IS_INTO_MANAGEMENT == false && EQU_LIST_CODE ！= 8000
        BoolQueryBuilder dBuilder = QueryBuilders.boolQuery();
        dBuilder.must(QueryBuilders.termQuery(DATA_SOURCE, jg_his_xa));
        dBuilder.mustNot(QueryBuilders.termQuery(EQU_LIST_CODE, EquipmentClassifityEnum.YLGD.getCode()));
        dBuilder.must(QueryBuilders.matchQuery(IS_INTO_MANAGEMENT, false));
        boolMust.must(dBuilder);

        // 待认领设备使用单位单位统一社会信用代码如果已在系统中存在则不显示
        List<String> unitCreditCodes = tzBaseEnterpriseInfoMapper.getUseUnitCreditCodes();
        if (!ValidationUtil.isEmpty(unitCreditCodes)) {
            boolMust.mustNot(QueryBuilders.termsQuery("USE_UNIT_CREDIT_CODE.keyword", unitCreditCodes));
        }
        // --------------------------------   参数过滤
        this.buildSetSearchParams(params, boolMust);

        // --------------------------------   字段排序
        builder.sort(CREATE_DATE, SortOrder.DESC);
        builder.query(boolMust);
        builder.from((number - 1) * size);
        builder.size(size);
        request.source(builder);
        List<JSONObject> list = new LinkedList<>();

        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                JSONObject sourceAsJSON = JSONObject.parseObject(toJSONString(hit.getSourceAsMap()));
                // 设备状态转化
                if (!ValidationUtil.isEmpty(sourceAsJSON.get(EQU_STATE))) {
                    sourceAsJSON.put(EQU_STATE, EquipmentEnum.getName.get(Integer.valueOf(sourceAsJSON.get(EQU_STATE).toString())));
                }
                sourceAsJSON.put(record, sourceAsJSON.get(SEQUENCE_NBR));
                // 录入时间如果CREATE_DATE为空则使用REC_DATE
                // 日期转化
                if (ValidationUtil.isEmpty(sourceAsJSON.get(CREATE_DATE))) {
                    sourceAsJSON.put(CREATE_DATE, Instant.ofEpochMilli(Long.parseLong(sourceAsJSON.getString("REC_DATE"))).atZone(ZoneId.systemDefault()).toLocalDate());
                } else {
                    sourceAsJSON.put(CREATE_DATE, Instant.ofEpochMilli(Long.parseLong(sourceAsJSON.getString(CREATE_DATE))).atZone(ZoneId.systemDefault()).toLocalDate());
                }
                list.add(sourceAsJSON);
            }
            if (response.getInternalResponse().hits().getTotalHits() != null) {
                totle = response.getInternalResponse().hits().getTotalHits().value;
            }
            result.setRecords(list);
            result.setTotal(totle);
        } catch (IOException e) {
            log.error("查询待认领台套设备，分页异常:{}", e.getMessage());
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 台套查询条件组装
     *
     * @param params
     * @param boolMust
     */
    private void buildSetSearchParams(JSONObject params, BoolQueryBuilder boolMust) {
        // 设备种类编码
        if (!ObjectUtils.isEmpty(params.getString(EQU_LIST_CODE))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(params.getString(EQU_LIST_CODE));
            elcBuilder.must(QueryBuilders.matchPhraseQuery(EQU_LIST_CODE, test));
            boolMust.must(elcBuilder);
        }
        // 设备类别编码
        if (!ObjectUtils.isEmpty(params.getString(EQU_CATEGORY_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(params.getString(EQU_CATEGORY_CODE));
            pBuilder.must(QueryBuilders.termQuery(EQU_CATEGORY_CODE, test));
            boolMust.must(pBuilder);
        }
        // 设备品种编码
        if (!ObjectUtils.isEmpty(params.getString(EQU_DEFINE_CODE))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(params.getString(EQU_DEFINE_CODE));
            elcBuilder.must(QueryBuilders.matchPhraseQuery(EQU_DEFINE_CODE, test));
            boolMust.must(elcBuilder);
        }
        // 设备名称
        if (!ObjectUtils.isEmpty(params.getString(PRODUCT_NAME))) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(params.getString(PRODUCT_NAME));
            elcBuilder.must(QueryBuilders.matchPhraseQuery(PRODUCT_NAME, test));
            boolMust.must(elcBuilder);
        }
        // 设备代码模糊查询
        if (!ObjectUtils.isEmpty(params.getString(EQU_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String test = QueryParser.escape(params.getString(EQU_CODE));
            pBuilder.must(QueryBuilders.wildcardQuery(EQU_CODE, "*" + QueryParser.escape(test.toLowerCase()) + "*"));
            boolMust.must(pBuilder);
        }
        // 出厂编号模糊查询
        if (!ObjectUtils.isEmpty(params.getString(FACTORY_NUM))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String factoryNum = params.getString(FACTORY_NUM);
            // 使用match_phrase进行精确匹配
            pBuilder.must(QueryBuilders.matchPhraseQuery(FACTORY_NUM, factoryNum));
            boolMust.must(pBuilder);
        }

        // 使用单位 名称模糊查询
        if (!ObjectUtils.isEmpty(params.getString(USE_UNIT_NAME))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            String text = params.getString(USE_UNIT_NAME);
            pBuilder.must(QueryBuilders.matchQuery(USE_UNIT_NAME, text).operator(Operator.AND));
            boolMust.must(pBuilder);
        }
        // 属地监管部门
        if (!ObjectUtils.isEmpty(params.getString(ORG_BRANCH_CODE))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            pBuilder.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(params.getString(ORG_BRANCH_CODE)) + "*"));
            boolMust.must(pBuilder);
        }
        // 设备使用地址 名称模糊查询
        if (!ObjectUtils.isEmpty(params.getString(ADDRESS))) {
            BoolQueryBuilder pBuilder = QueryBuilders.boolQuery();
            pBuilder.must(QueryBuilders.matchQuery(ADDRESS, params.getString(ADDRESS))
                    .operator(Operator.AND));
            boolMust.must(pBuilder);
        }
        // 设备状态
        if (!ObjectUtils.isEmpty(params.getString("EQU_STATE"))) {
            BoolQueryBuilder esBuilder = QueryBuilders.boolQuery();
            if (EquipmentEnum.WEIDENGJI.getCode().toString().equals(params.getString("EQU_STATE"))) {
                esBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
            } else {
                String param = QueryParser.escape(params.getLong("EQU_STATE").toString());
                esBuilder.must(QueryBuilders.matchQuery("EQU_STATE", param));
            }
            boolMust.must(esBuilder);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 创建时间范围查询
        if (!ObjectUtils.isEmpty(params.getString(CREATE_DATE_RANGE))) {

            String createDateRangeObj = params.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();
            }
        }
    }

    /**
     * 待认领-管道装置设备分页
     *
     * @param params
     * @return
     */
    public IPage<IdxBizJgProjectContraption> pipeEquipPage(JSONObject params) {
        int number = Integer.parseInt((String) params.getOrDefault(NUMBER, "1"));
        int size = Integer.parseInt((String) params.getOrDefault(SIZE, "20"));
        Page<IdxBizJgProjectContraption> page = new Page<>(number, size);
        QueryWrapper<IdxBizJgProjectContraption> queryWrapper = new QueryWrapper<IdxBizJgProjectContraption>();
        // 默认条件 DATA_SOURCE == jg_his_xa && IS_INTO_MANAGEMENT == false && EQU_LIST_CODE == 8000
        queryWrapper.eq(data_source, jg_his_xa);
        queryWrapper.eq(is_into_management, false);
        queryWrapper.eq(equ_list, EquipmentClassifityEnum.YLGD.getCode());
        // --------------------------------   参数过滤
        this.buildPipeSearchParams(params, queryWrapper);

        queryWrapper.orderByDesc(create_date);
        return projectContraptionServiceImplService.page(page, queryWrapper);
    }

    /**
     * 管道装置查询条件组装
     *
     * @param params
     * @param queryWrapper
     */
    private void buildPipeSearchParams(JSONObject params, QueryWrapper<IdxBizJgProjectContraption> queryWrapper) {
        queryWrapper.eq(!ObjectUtils.isEmpty(params.getString("equCategoryCode")), "equ_category", params.getString("equCategoryCode"));
        queryWrapper.eq(!ObjectUtils.isEmpty(params.getString("equDefineCode")), "equ_define", params.getString("equDefineCode"));
        queryWrapper.like(!ObjectUtils.isEmpty(params.getString("projectContraption")), "project_contraption", params.getString("projectContraption"));
        queryWrapper.like(!ObjectUtils.isEmpty(params.getString("projectContraptionNo")), "project_contraption_no", params.getString("projectContraptionNo"));
        queryWrapper.like(!ObjectUtils.isEmpty(params.getString("useUnitName")), "use_unit_name", params.getString("useUnitName"));
        queryWrapper.likeRight(!ObjectUtils.isEmpty(params.getString("orgBranchCode")), "org_code", params.getString("orgBranchCode"));
    }


    /**
     * 认领-台套设备
     *
     * @param json
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public Object setEquipClaim(JSONObject json) {
        JSONObject equipInfo = JSON.parseObject(toJSONString(json.get(EQUIP_INFO_FORM_ID)));
        JSONObject equipParams = JSON.parseObject(toJSONString(json.get(EQUIP_PARAMS_FORM_ID)));
        CompanyBo company = getSelectedOrgInfo().getCompany();
        String useRegistrationCode = Objects.toString(equipInfo.get(USE_REGISTRATION_CODE), null);
        // 屏蔽掉气瓶的认领
        this.interceptGasCylinderClaim(equipInfo);

        // 参数校验 - 同 设备录入的逻辑
        this.checkParams(new LinkedHashMap<>(equipInfo));

        if (StringUtils.isEmpty(useRegistrationCode)) {
            // 认领到自己单位下 -> 未纳管设备列表 ， dataSource 变为 -> jg_his_xa_claim

            // 认领 更新设备信息
            this.updateEquipInfoWithClaim(equipInfo, equipParams, false);
            // 添加设备的业务履历
            this.addEquipResume(equipInfo, BusinessTypeEnum.JG_EQUIP_CLAIM, new JgUseRegistration());
        } else {
            // 认领到自己单位下 -> 已纳管设备列表 ， + 历史设备登记

            // 认领 更新设备信息
            this.updateEquipInfoWithClaim(equipInfo, equipParams, false);
            // 历史设备登记
//            JgUseRegistration useRegistration = this.addHistoryEquipRegistration(equipInfo);
            // 添加设备的业务履历
            this.addEquipResume(equipInfo, BusinessTypeEnum.JG_EQUIP_CLAIM, new JgUseRegistration());
        }
        // 添加es中的使用单位信息
        HashMap<String, Map<String, Object>> objMap = new HashMap<>();
        HashMap<String, Object> param = new HashMap<>();
        param.put("USE_UNIT_CREDIT_CODE", company.getCompanyCode());
        param.put("USE_UNIT_NAME", company.getCompanyName());
        objMap.put(equipInfo.get(RECORD).toString(), param);
        tzsServiceFeignClient.commonUpdateEsDataByIds(objMap);
        return Boolean.TRUE;
    }

    /**
     * 屏蔽掉气瓶的认领
     *
     * @param equipInfo
     */
    private void interceptGasCylinderClaim(JSONObject equipInfo) {
        // 设备种类
        String equList = Objects.toString(equipInfo.get(EQU_LIST));
        // 设备类别
        String equCategory = Objects.toString(equipInfo.get(EQU_CATEGORY));
        if (!StringUtils.isEmpty(equList) && equList.equals(EquipmentClassifityEnum.YLRQ.getCode()) && !StringUtils.isEmpty(equCategory) && equCategory.equals(UseRegisterCancelEquipEnum.qp.getCode())) {
            throw new BadRequest("气瓶设备认领暂未开放！");
        }
    }

    /**
     * 台套历史设备登记
     *
     * @param equipInfo
     * @return
     */
    public JgUseRegistration addHistoryEquipRegistration(JSONObject equipInfo) {
        String record = (String) equipInfo.get(RECORD);
        CompanyBo company = getSelectedOrgInfo().getCompany();
        AgencyUserModel userModel = getSelectedOrgInfo().getUserModel();

        equipInfo.put("useUnitCreditCode", company.getCompanyCode());
        equipInfo.put("useUnitName", company.getCompanyName());
        equipInfo.put("useInnerCode", equipInfo.get("USE_INNER_CODE"));
        // 历史使用登记信息
        JgUseRegistration jgUseRegistration = new JgUseRegistration();
        jgUseRegistration.setSequenceNbr(sequence.nextId());
        try {
            jgUseRegistration.setRegDate(ValidationUtil.isEmpty(equipInfo.get("oRegDate")) ? new Date() :
                    DateUtils.dateParse((String) equipInfo.get("oRegDate"), DateUtils.DATE_PATTERN));
        } catch (Exception e) {
            log.error("设备认领，历史使用登记信息转换日期失败：", e);
        }
        jgUseRegistration.setInputUnitNo(Objects.toString(equipInfo.get("oRegUnit"), null));
        if (!ObjectUtils.isEmpty(equipInfo.get("otherAccessories"))) {
            jgUseRegistration.setOtherAccessories(toJSONString(equipInfo.get("otherAccessories")));
        }
        if (equipInfo.containsKey("receiveOrgCode")) {
            // 接收单位信息
            String[] splitMaintenanceUnitCode = Objects.toString(equipInfo.getString("receiveOrgCode"), "").split("_");
            jgUseRegistration.setReceiveCompanyCode(splitMaintenanceUnitCode[0]);
            jgUseRegistration.setReceiveOrgName(splitMaintenanceUnitCode[1]);
            jgUseRegistration.setReceiveCompanyOrgCode(commonService.getOneCompany(jgUseRegistration.getReceiveCompanyCode()).getOrgCode());
        }
        if (equipInfo.containsKey("orgBranchCode") && !ObjectUtils.isEmpty(equipInfo.get("orgBranchCode"))) {
            // 监察处置机构代码
            String[] splitOrgBranchCode = Objects.toString(equipInfo.getString("orgBranchCode"), "").split("_");
            jgUseRegistration.setSupervisionOrgCode(splitOrgBranchCode[0]);
        }
        // 使用单位提交
        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(userModel.getUserId());
        jgUseRegistration.setCreateUserName(userModel.getRealName());
        jgUseRegistration.setManageType("set");
        if (!ObjectUtils.isEmpty(equipInfo.get("inspectUnitCreditCode"))) {
            jgUseRegistration.setInspectUnitCreditCode(equipInfo.get("inspectUnitCreditCode").toString());
        }
        if (!ObjectUtils.isEmpty(equipInfo.get("inspectOrgName"))) {
            jgUseRegistration.setInspectUnitName(equipInfo.get("inspectOrgName").toString());
        }
        // 是否西咸
        if (!ObjectUtils.isEmpty(equipInfo.get("isXixian"))) {
            jgUseRegistration.setIsXixian(Objects.toString(equipInfo.get("isXixian"), null));
        }
        CityCountyStreet result = getCityCountStreet(equipInfo, jgUseRegistration);
        jgUseRegistration.setUseAddress(jgUseRegistration.getUseAddress() + JsonDiffUtil.nullToEmpty(equipInfo.getString("address")));


        ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.SYDJ.getCode(), 1);
        if (!ObjectUtils.isEmpty(listResponseModel)) {
            jgUseRegistration.setApplyNo(listResponseModel.getResult().get(0));
        }
        jgUseRegistration.setAuditPassDate(new Date());
        jgUseRegistration.setAuditStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
        jgUseRegistration.setStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
        jgUseRegistration.setUseRegistrationCode(ValidationUtil.isEmpty(equipInfo.get("useRegistrationCode")) ? "" : Objects.toString(equipInfo.get("useRegistrationCode"), null));
        jgUseRegistration.setRegType("1");// 历史登记


        // 暂存历史表
        useRegistrationService.updateHistory(equipInfo, Objects.toString(record, null), Objects.toString(jgUseRegistration.getSequenceNbr(), null), jgUseRegistration.getSupervisoryCode());
        // 监督管理信息
        LambdaQueryWrapper<IdxBizJgSupervisionInfo> lambdaSup = new QueryWrapper<IdxBizJgSupervisionInfo>().lambda();
        lambdaSup.eq(IdxBizJgSupervisionInfo::getRecord, record);
        IdxBizJgSupervisionInfo supervisionInfo = idxBizJgSupervisionInfoMapper.selectOne(lambdaSup);
        if (supervisionInfo != null && !ObjectUtils.isEmpty(equipInfo.get("orgBranchCode"))) {
            supervisionInfo.setOrgBranchCode(Objects.toString(equipInfo.get("orgBranchCode"), "").split("_")[0]);
            supervisionInfo.setOrgBranchName(Objects.toString(equipInfo.get("orgBranchCode"), "").split("_")[1]);
            idxBizJgSupervisionInfoMapper.updateById(supervisionInfo);
        }
        // 注册信息
        LambdaQueryWrapper<IdxBizJgRegisterInfo> lambdaReg = new QueryWrapper<IdxBizJgRegisterInfo>().lambda();
        lambdaReg.eq(IdxBizJgRegisterInfo::getRecord, record);
        IdxBizJgRegisterInfo registerInfo = idxBizJgRegisterInfoMapper.selectOne(lambdaReg);
        String equCode = Objects.toString(equipInfo.get("EQU_CODE"), null);
        if (registerInfo != null) {
            registerInfo.setUseOrgCode(jgUseRegistration.getUseRegistrationCode());
            registerInfo.setEquCodeType(Objects.toString(equipInfo.get("EQU_CODE_TYPE"), null));
            // 新提交或暂存后提交需生成设备代码
            if (ObjectUtils.isEmpty(equCode) && !StringUtils.isEmpty(jgUseRegistration.getReceiveCompanyCode())) {
                equCode = useRegistrationService.getEquCode(registerInfo, jgUseRegistration.getReceiveCompanyCode());
            }
            registerInfo.setEquCode(equCode);// 设备代码
            registerInfo.setEquPrice(Objects.toString(equipInfo.get("EQU_PRICE"), null));
            registerInfo.setInstallationIsComplete(equipInfo.getOrDefault("installationIsComplete", "1").toString());
            if (EquipmentClassifityEnum.CC.getCode().equals(equipInfo.get(EQU_LIST))) {
                registerInfo.setCarNumber((String) equipInfo.get("CAR_NUMBER"));
            }
            idxBizJgRegisterInfoMapper.updateById(registerInfo);
        }
        // 设计信息
        LambdaQueryWrapper<IdxBizJgDesignInfo> lambdaDes = new QueryWrapper<IdxBizJgDesignInfo>().lambda();
        lambdaDes.eq(IdxBizJgDesignInfo::getRecord, record);
        IdxBizJgDesignInfo designInfo = idxBizJgDesignInfoService.getOne(lambdaDes);
        if (designInfo != null) {
            designInfo.setDesignUnitCreditCode(MapUtil.getStr(equipInfo, "designUnitCreditCode"));
            designInfo.setDesignUnitName(MapUtil.getStr(equipInfo, "designUnitName"));
            designInfo.setDesignLicenseNum(MapUtil.getStr(equipInfo, "designLicenseNum"));
            designInfo.setDesignUseDate(MapUtil.getStr(equipInfo, "designUseDate"));
            designInfo.setDesignDate(!StringUtils.isEmpty(equipInfo.get("designDate")) ? DateUtil.parse(Objects.toString(equipInfo.get("designDate"), null), "yyyy-MM-dd") : null);
            designInfo.setDrawingDo(ObjectUtils.isEmpty(equipInfo.get("drawingDo")) ? null : Objects.toString(equipInfo.get("drawingDo"), null));
            designInfo.setAppraisalUnit(ObjectUtils.isEmpty(equipInfo.get("appraisalUnit")) ? null : Objects.toString(equipInfo.get("appraisalUnit"), null));
            designInfo.setAppraisalDate(ObjectUtils.isEmpty(equipInfo.get("appraisalDate")) ? null : Objects.toString(equipInfo.get("appraisalDate"), null));
            designInfo.setDesignDoc(ObjectUtils.isEmpty(equipInfo.get("DESIGN_DOC")) ? null : toJSONString(equipInfo.get("DESIGN_DOC")));
            designInfo.setDesignStandard(ObjectUtils.isEmpty(equipInfo.get("designStandard")) ? null : toJSONString(equipInfo.get("designStandard")));
            designInfo.setOtherAccessoriesDes(ObjectUtils.isEmpty(equipInfo.get("otherAccessoriesDes")) ? null : toJSONString(equipInfo.get("otherAccessoriesDes")));
            idxBizJgDesignInfoMapper.updateById(designInfo);
        }
        // 制造信息
        LambdaQueryWrapper<IdxBizJgFactoryInfo> factoryInfoWrapper = new LambdaQueryWrapper<>();
        factoryInfoWrapper.eq(IdxBizJgFactoryInfo::getRecord, record);
        IdxBizJgFactoryInfo idxBizJgFactoryInfo = idxBizJgFactoryInfoService.getOne(factoryInfoWrapper);
        if (idxBizJgFactoryInfo != null) {
            idxBizJgFactoryInfo.setProduceUnitCreditCode(MapUtil.getStr(equipInfo, "produceUnitCreditCode"));
            idxBizJgFactoryInfo.setProduceUnitName(MapUtil.getStr(equipInfo, "produceUnitName"));
            idxBizJgFactoryInfo.setFactoryNum(MapUtil.getStr(equipInfo, "factoryNum"));
            idxBizJgFactoryInfo.setProduceLicenseNum(MapUtil.getStr(equipInfo, "produceLicenseNum"));
            idxBizJgFactoryInfo.setProduceDate(!StringUtils.isEmpty(equipInfo.get("produceDate")) ? DateUtil.parse(Objects.toString(equipInfo.get("produceDate"), null), "yyyy-MM-dd") : null);
            idxBizJgFactoryInfo.setImported(ObjectUtils.isEmpty(equipInfo.get("imported")) ? null : Objects.toString(equipInfo.get("imported"), null));
            idxBizJgFactoryInfo.setProduceCountry(ObjectUtils.isEmpty(equipInfo.get("produceCountry")) ? null : Objects.toString(equipInfo.get("produceCountry"), null));
            idxBizJgFactoryInfo.setOtherAccessoriesFact(ObjectUtils.isEmpty(equipInfo.get("otherAccessoriesFact")) ? null : toJSONString(equipInfo.get("otherAccessoriesFact")));
            idxBizJgFactoryInfo.setInsUseMaintainExplain(ObjectUtils.isEmpty(equipInfo.get("insUseMaintainExplain")) ? null : toJSONString(equipInfo.get("insUseMaintainExplain")));
            idxBizJgFactoryInfo.setFactoryStandard(ObjectUtils.isEmpty(equipInfo.get("factoryStandard")) ? null : toJSONString(equipInfo.get("factoryStandard")));
            idxBizJgFactoryInfo.setFactSupervisionInspectionReport(ObjectUtils.isEmpty(equipInfo.get("factSupervisionInspectionReport")) ? null : toJSONString(equipInfo.get("factSupervisionInspectionReport")));
            idxBizJgFactoryInfo.setBoilerEnergyEfficiencyCertificate(ObjectUtils.isEmpty(equipInfo.get("boilerEnergyEfficiencyCertificate")) ? null : toJSONString(equipInfo.get("boilerEnergyEfficiencyCertificate")));
            idxBizJgFactoryInfoMapper.updateById(idxBizJgFactoryInfo);
        }

        // 使用信息
        LambdaQueryWrapper<IdxBizJgUseInfo> lambda = new QueryWrapper<IdxBizJgUseInfo>().lambda();
        lambda.eq(IdxBizJgUseInfo::getRecord, record);
        IdxBizJgUseInfo useInfo = useInfoMapper.selectOne(lambda);
        String usePlace = "";
        if (useInfo != null) {
            useInfo.setIsIntoManagement(Boolean.TRUE);
            useInfo.setUseUnitCreditCode(Objects.toString(equipInfo.get("useUnitCreditCode"), null));
            useInfo.setUseUnitName(Objects.toString(equipInfo.get("useUnitName"), null));
            useInfo.setProvince("610000");
            useInfo.setProvinceName("陕西省");
            useInfo.setCity(Objects.toString(equipInfo.get("city"), null));
            useInfo.setUseInnerCode(Objects.toString(equipInfo.get("useInnerCode"), null));
            useInfo.setCityName(result.useCityName);
            useInfo.setCounty(Objects.toString(equipInfo.get("county"), null));
            useInfo.setCountyName(result.useCountyName);
            useInfo.setFactoryUseSiteStreet(Objects.toString(equipInfo.get("factoryUseSiteStreet"), null));
            useInfo.setStreetName(result.useStreetName);
            useInfo.setAddress(Objects.toString(equipInfo.get("address"), null));
            useInfo.setIsNotXiXian(Objects.toString(equipInfo.get("isXixian"), null));
            useInfo.setEstateUnitCreditCode(Optional.ofNullable(equipInfo.get("estateUnitName"))
                    .map(Object::toString)
                    .filter(s -> s.contains("_"))
                    .map(s -> s.split("_", 2))
                    .filter(parts -> parts.length == 2)
                    .map(parts -> parts[0])
                    .orElse(null));
            useInfo.setEstateUnitName(Optional.ofNullable(equipInfo.get("estateUnitName"))
                    .map(Object::toString)
                    .filter(s -> s.contains("_"))
                    .map(s -> s.split("_", 2))
                    .filter(parts -> parts.length == 2)
                    .map(parts -> parts[1])
                    .orElse(null));
            useInfo.setPhone(Objects.toString(equipInfo.get("phone"), null));
            useInfo.setSafetyManager(Objects.toString(Optional.ofNullable(equipInfo.get("safetyManager"))
                    .map(Object::toString)
                    .filter(s -> s.contains("_"))
                    .map(s -> s.split("_", 2))
                    .filter(parts -> parts.length == 2)
                    .map(parts -> parts[1])
                    .orElse(null), null));
            useInfo.setUseDate(Objects.toString(equipInfo.get("useDate"), null));
            useInfo.setLongitudeLatitude(toJSONString(equipInfo.get("longitudeLatitude")));
            useInfo.setUsePlace((String) equipInfo.get("usePlace"));
            useInfo.setOldUseRegistrationTable(toJSONString(equipInfo.get("oldUseRegistrationTable")));
            useInfo.setOldUseRegistrationCertificate(toJSONString(equipInfo.get("oldUseRegistrationCertificate")));
            useInfo.setORegDate(Objects.toString(equipInfo.get("oRegDate"), null));
            useInfo.setORegUnit(Objects.toString(equipInfo.get("oRegUnit"), null));
            // 历史平台登记，将设备状态改为在用
            if (useInfo.getEquState() == null) {
                useInfo.setEquState(EquipmentEnum.ZAIYONG.getCode().toString());
            }
            usePlace = useInfo.getProvinceName() + "/" + useInfo.getCityName() + "/" + useInfo.getCountyName() + "/" + useInfo.getStreetName();
            useInfoMapper.updateById(useInfo);
        }

        LambdaQueryWrapper<IdxBizJgOtherInfo> otherLambda = new QueryWrapper<IdxBizJgOtherInfo>().lambda();
        otherLambda.eq(IdxBizJgOtherInfo::getRecord, record);
        IdxBizJgOtherInfo otherInfo = otherInfoMapper.selectOne(otherLambda);

        // 生成监管码 96333码
        useRegistrationService.createCode(equipInfo, jgUseRegistration, registerInfo, useInfo, otherInfo);
        equipInfo.put("equCode", equCode);
        // 更新es
        equipInfo.put("equipId", record);
        useRegistrationService.updateEsData2(usePlace, equipInfo, otherInfo, useInfo, jgUseRegistration, equipInfo);
        useRegistrationService.updateById(jgUseRegistration);
        useRegistrationService.historyEquGenManageRelated(equipInfo, jgUseRegistration, registerInfo, idxBizJgFactoryInfo);
        String routePath = useRegistrationService.buildTaskModel(jgUseRegistration, equipInfo, getSelectedOrgInfo());
        jgResumeInfoService.createWithModel(JgResumeInfoDto.builder()
                .applyNo(jgUseRegistration.getApplyNo())
                .businessType(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName())
                .businessId(jgUseRegistration.getSequenceNbr() + "")
                .equId(Objects.toString(record, null))
                .approvalUnit(jgUseRegistration.getReceiveOrgName())
                .approvalUnitCode(jgUseRegistration.getReceiveOrgCode())
                .status("正常")
                .routePath(routePath)
                .changeContent(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName() + "业务")
                .build());
        jgUseRegistration.setCreateDate(new Date());
        useRegistrationService.save(jgUseRegistration);
        // 业务管理设备信息保存
        JgUseRegistrationEq jgRelationEquip = new JgUseRegistrationEq();
        jgRelationEquip.setEquId(record);
        jgRelationEquip.setEquipTransferId(jgUseRegistration.getSequenceNbr().toString());
        jgRelationEquipMapper.insert(jgRelationEquip);
        // todo 流水
        return useRegistrationService.getBaseMapper().selectById(jgUseRegistration.getSequenceNbr());
    }

    private CityCountyStreet getCityCountStreet(JSONObject equipInfo, JgUseRegistration jgUseRegistration) {
        // 使用地点
        String useCityName = "";
        String useCountyName = "";
        String useStreetName = "";
        // 市
        List<LinkedHashMap> city = (List<LinkedHashMap>) redisUtils.get("CITY");
        // 区
        List<LinkedHashMap> region = (List<LinkedHashMap>) redisUtils.get("REGION");
        // 街道
        List<LinkedHashMap> street = (List<LinkedHashMap>) redisUtils.get("STREET");
        jgUseRegistration.setUseAddress("陕西省");
        // 城市
        if (!ObjectUtils.isEmpty(equipInfo.get("city")) && !ObjectUtils.isEmpty(city)) {
            AtomicReference<String> atomicUseCity = new AtomicReference<>(useCityName);
            city.forEach(item -> {
                if (Objects.toString(item.get("regionCode")).equals(Objects.toString(equipInfo.get("city")))) {
                    atomicUseCity.set("" + item.get("regionName"));
                    jgUseRegistration.setUseAddress(jgUseRegistration.getUseAddress() + item.get("regionName"));
                }
            });
            useCityName = atomicUseCity.get();
        }
        // 区县
        if (!ObjectUtils.isEmpty(equipInfo.get("county")) && !ObjectUtils.isEmpty(city)) {
            AtomicReference<String> atomicUseCounty = new AtomicReference<>(useCountyName);
            region.forEach(item -> {
                if (Objects.toString(item.get("regionCode")).equals(Objects.toString(equipInfo.get("county")))) {
                    atomicUseCounty.set("" + item.get("regionName"));
                    jgUseRegistration.setUseAddress(jgUseRegistration.getUseAddress() + item.get("regionName"));
                }
            });
            useCountyName = atomicUseCounty.get();
        }
        // 街道
        if (!ObjectUtils.isEmpty(equipInfo.get("factoryUseSiteStreet")) && !ObjectUtils.isEmpty(city)) {
            JSONObject finalMap2 = equipInfo;
            AtomicReference<String> atomicUseStreet = new AtomicReference<>(useStreetName);
            street.forEach(item -> {
                if (Objects.toString(item.get("regionCode")).equals(Objects.toString(finalMap2.get("factoryUseSiteStreet")))) {
                    atomicUseStreet.set("" + item.get("regionName"));
                    jgUseRegistration.setUseAddress(jgUseRegistration.getUseAddress() + item.get("regionName"));
                }
            });
            useStreetName = atomicUseStreet.get();
        }
        return new CityCountyStreet(useCityName, useCountyName, useStreetName);
    }

    public static class CityCountyStreet {
        public final String useCityName;
        public final String useCountyName;
        public final String useStreetName;

        public CityCountyStreet(String useCityName, String useCountyName, String useStreetName) {
            this.useCityName = useCityName;
            this.useCountyName = useCountyName;
            this.useStreetName = useStreetName;
        }
    }

    /**
     * 添加设备的业务履历
     */
    public void addEquipResume(JSONObject equipInfo, BusinessTypeEnum businessTypeEnum, JgUseRegistration useRegistration) {
        String record = (String) equipInfo.get(RECORD);
        JgResumeInfo resumeInfo = JgResumeInfo.builder()
                .applyNo(null)
                .businessType(businessTypeEnum.getName())
                .businessId(record)
                .equId(record)
                .approvalUnit(useRegistration.getReceiveOrgName())
                .approvalUnitCode(useRegistration.getReceiveOrgName())
                .status("正常")
                .changeContent(businessTypeEnum.getName() + "业务")
                .build();
        if (!ObjectUtils.isEmpty(useRegistration.getSequenceNbr())) {
            resumeInfo.setRoutePath(useRegistrationService.buildTaskModel(useRegistration, equipInfo, getSelectedOrgInfo()));
        }
        jgResumeInfoService.save(resumeInfo);
    }

    /**
     * 参数校验 - 同 设备录入的逻辑
     */
    public void checkParams(LinkedHashMap equipInfo) {
        String dataSource = (String) equipInfo.get(DATA_SOURCE);
        String record = (String) equipInfo.get(RECORD);
        String useRegistrationCode = Optional.ofNullable(equipInfo.get("useRegistrationCode"))
                .map(String::valueOf)
                .map(String::trim)
                .orElse(null);
        // 使用登记证校验
        if (!ObjectUtils.isEmpty(useRegistrationCode)) {
            jgRegisterInfoService.checkUseRegistrationCode(equipInfo);
        }
        // 设备代码 字段的唯一性校验
        jgRegisterInfoService.checkEquCodeUniqueness(equipInfo);
        // 车用气瓶业务里面的 产品编号 校验唯一性（产品编号在车用气瓶范围内全局唯一）
        jgRegisterInfoService.checkFactoryNumUniqueness(equipInfo);
        // 96333码 字段的唯一性校验
        jgRegisterInfoService.check96333Code(equipInfo);
        // 气瓶 校验制造单位统一信用代码与出场编码唯一
        jgRegisterInfoService.checkFactoryNumUniqueWithGasCylinder(equipInfo, record);
        // 历史（车用气瓶）设备校验使用登记证编号 VIN 全库唯一
        jgRegisterInfoService.hisEquCheckUseRegCodeAndVINUniqueness(equipInfo, record);
        // 历史有使用登记证的场车设备校验车牌号的唯一性
        jgRegisterInfoService.checkCarNumberUniquenessWithHisCC(equipInfo, record, dataSource);
    }

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

    /**
     * 认领 更新设备信息
     *
     * @param equipInfo
     */
    public void updateEquipInfoWithClaim(JSONObject equipInfo, JSONObject equipParams, boolean isIntoManagement) {
        Date timestamp = new Date();
        AgencyUserModel userModel = getSelectedOrgInfo().getUserModel();
        CompanyBo company = getSelectedOrgInfo().getCompany();
        // 设备种类
        String equList = Objects.toString(equipInfo.get(EQU_LIST));
        String record = equipInfo.get(RECORD).toString();

        // 使用信息
        IdxBizJgUseInfo useInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgUseInfo.class);
        useInfo.setRecord(record);
        useInfo.setRecDate(timestamp);
        useInfo.setCreateDate(timestamp);
        useInfo.setDataSource(JG_HIS_XA_CLAIM);
        useInfo.setIsIntoManagement(isIntoManagement);
        useInfo.setUseUnitCreditCode(company.getCompanyCode());
        useInfo.setUseUnitName(company.getCompanyName());
        useInfo.setSequenceNbr(Objects.toString(equipInfo.get("USEINFO_SEQ"), null));
        // 产权单位
        if (!ObjectUtils.isEmpty(equipInfo.getString("estateUnitSeq"))) {
            String estateUnitSeq = equipInfo.getString("estateUnitSeq");
            TzBaseEnterpriseInfo enterpriseInfo = tzBaseEnterpriseInfoMapper.selectBySeq(Long.valueOf(estateUnitSeq));
            useInfo.setEstateUnitCreditCode(enterpriseInfo.getUseCode());
            useInfo.setEstateUnitName(enterpriseInfo.getUseUnit());
        }
        if (ObjectUtils.isEmpty(useInfo.getEquState()) && isIntoManagement) {
            // 有证纳管状态 没填写 给默认值
            useInfo.setEquState(EquipmentEnum.ZAIYONG.getCode().toString());
        }
        if (!ObjectUtils.isEmpty(useInfo.getProvince())) {
            useInfo.setProvinceName("陕西省");
        }
        if (!ObjectUtils.isEmpty(useInfo.getCity())) {
            useInfo.setCityName(this.getRegionName("CITY", "CITY".toLowerCase(), equipInfo));
        }
        if (!ObjectUtils.isEmpty(useInfo.getCounty())) {
            useInfo.setCountyName(this.getRegionName("REGION", "COUNTY".toLowerCase(), equipInfo));
        }
        if (!ObjectUtils.isEmpty(useInfo.getFactoryUseSiteStreet())) {
            useInfo.setStreetName(this.getRegionName("STREET", "factoryUseSiteStreet", equipInfo));
        }
        idxBizJgUseInfoService.saveOrUpdateData(useInfo);
        // 设计信息
        IdxBizJgDesignInfo designInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgDesignInfo.class);
        designInfo.setRecord(record);
        designInfo.setRecDate(timestamp);
        designInfo.setSequenceNbr(Objects.toString(equipInfo.get("DESIGNINFO_SEQ"), null));
        iIdxBizJgDesignInfoService.saveOrUpdateData(designInfo);
        // 制造信息
        IdxBizJgFactoryInfo factoryInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgFactoryInfo.class);
        factoryInfo.setRecord(record);
        factoryInfo.setRecDate(timestamp);
        factoryInfo.setProductQualityYieldProve(ValidationUtil.isEmpty(equipInfo.get("PRODUCT_QUALITY_YIELD_PROVE")) ? null : toJSONString(equipInfo.get("PRODUCT_QUALITY_YIELD_PROVE")));
        factoryInfo.setSequenceNbr(Objects.toString(equipInfo.get("FACTORYINFO_SEQ"), null));
        iIdxBizJgFactoryInfoService.saveOrUpdateData(factoryInfo);
        // 施工信息
        IdxBizJgConstructionInfo constructionInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgConstructionInfo.class);
        constructionInfo.setRecord(record);
        constructionInfo.setRecDate(timestamp);
        constructionInfo.setSequenceNbr(Objects.toString(equipInfo.get("CONSTRUCTIONINFO_SEQ"), null));
        if (!ObjectUtils.isEmpty(constructionInfo.getConstructionProvince())) {
            constructionInfo.setConstructionProvinceName("陕西省");
        }
        if (!ObjectUtils.isEmpty(constructionInfo.getConstructionCity())) {
            constructionInfo.setConstructionCityName(this.getRegionName("CITY", "constructionCity", equipInfo));
        }
        if (!ObjectUtils.isEmpty(constructionInfo.getConstructionCounty())) {
            constructionInfo.setConstructionCountyName(this.getRegionName("REGION", "constructionCounty", equipInfo));
        }
        if (!ObjectUtils.isEmpty(constructionInfo.getConstructionStreet())) {
            constructionInfo.setConstructionStreetName(this.getRegionName("STREET", "constructionStreet", equipInfo));
        }
        iIdxBizJgConstructionInfoService.saveOrUpdateData(constructionInfo);
        // 注册登记信息
        IdxBizJgRegisterInfo registerInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgRegisterInfo.class);
        registerInfo.setRecord(record);
        registerInfo.setRecDate(timestamp);
        registerInfo.setEquDefine(ValidationUtil.isEmpty(Objects.toString(equipInfo.get("EQU_DEFINE"), null)) ? "" : Objects.toString(equipInfo.get("EQU_DEFINE"), null));
        registerInfo.setRegisterState(jgRegisterInfoService.getRegCode());
        registerInfo.setUseOrgCode(Objects.toString(equipInfo.get("useRegistrationCode"), null));
        registerInfo.setProductPhoto(ValidationUtil.isEmpty(equipInfo.get("PRODUCT_PHOTO")) ? null : toJSONString(equipInfo.get("PRODUCT_PHOTO")));
        registerInfo.setOtherAccessoriesReg(ValidationUtil.isEmpty(equipInfo.get("OTHER_ACCESSORIES_REG")) ? null : toJSONString(equipInfo.get("OTHER_ACCESSORIES_REG")));
        registerInfo.setSequenceNbr(Objects.toString(equipInfo.get("REGISTERINFO_SEQ"), null));
        jgRegisterInfoService.saveOrUpdate(registerInfo);
        // 监督管理
        IdxBizJgSupervisionInfo supervisionInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgSupervisionInfo.class);
        supervisionInfo.setRecord(record);
        supervisionInfo.setRecDate(timestamp);
        supervisionInfo.setSequenceNbr(Objects.toString(equipInfo.get("SUPERVISIONINFO_SEQ"), null));
        if (!ValidationUtil.isEmpty(equipInfo.get("orgBranchCode")) && Objects.toString(equipInfo.get("orgBranchCode"), null).contains("_")) {
            supervisionInfo.setOrgBranchCode(Objects.toString(equipInfo.get("orgBranchCode"), null).split("_")[0]);
            supervisionInfo.setOrgBranchName(Objects.toString(equipInfo.get("orgBranchCode"), null).split("_")[1]);
        }
        iIdxBizJgSupervisionInfoService.saveOrUpdateData(supervisionInfo);
        // 其他信息
        IdxBizJgOtherInfo otherInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgOtherInfo.class);
        otherInfo.setRecord(record);
        otherInfo.setClaimStatus("已认领");
        otherInfo.setRecDate(timestamp);
        otherInfo.setSequenceNbr(Objects.toString(equipInfo.get("OTHERINFO_SEQ"), null));
        iIdxBizJgOtherInfoService.saveOrUpdateData(otherInfo);
        // 检验检测信息
        IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = JSON.parseObject(toJSONString(equipInfo), 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(timestamp);
        if (inspectionDetectionInfo.getNextInspectDate() != null) {
            inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
        }
        inspectionDetectionInfo.setSequenceNbr(Objects.toString(equipInfo.get("INSPECTIONDETECTIONINFO_SEQ"), null));
        iIdxBizJgInspectionDetectionInfoService.saveOrUpdateData(inspectionDetectionInfo);
        // 技术参数
        jgRegisterInfoService.saveOrUpdateEquParams(new LinkedHashMap<>(equipInfo), new LinkedHashMap<>(equipParams), equList, record, timestamp, "edit");
        // 更新es
        jgRegisterInfoService.saveEsData(record);

        eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), Sets.newHashSet(record), EquipCreateOrEditEvent.EquipType.equip));

    }

    /**
     * 认领-管道设备
     *
     * @param json
     * @return result
     */
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public Object pipeEquipClaim(JSONObject json) {
        JSONObject equipInfo = JSON.parseObject(toJSONString(json.get(EQUIP_INFO_FORM_ID)));

        // 校验
        this.checkPipeParams(equipInfo);

        // 认领 工程装置及管道设备信息 及历史登记
        this.updateConProEquipInfoWithClaim(equipInfo);

        return Boolean.TRUE;
    }

    private <T> List<T> initializeList() {
        return new ArrayList<>(15);
    }

    /**
     * 工程装置及管道设备信息
     *
     * @param equipInfo
     */
    public void updateConProEquipInfoWithClaim(JSONObject equipInfo) {

        CompanyBo company = getSelectedOrgInfo().getCompany();
        String proConNo = equipInfo.getString(PROJECT_CONTRAPTION_NO);

        IdxBizJgProjectContraption oldProCon = idxBizJgProjectContraptionService.getBaseMapper().selectOne(new LambdaQueryWrapper<IdxBizJgProjectContraption>()
                .eq(IdxBizJgProjectContraption::getUseUnitCreditCode, company.getCompanyCode())
                .eq(IdxBizJgProjectContraption::getProjectContraptionNo, proConNo)
                .eq(IdxBizJgProjectContraption::getIsDelete, Boolean.FALSE)
                .isNull(IdxBizJgProjectContraption::getProjectContraptionParentId));
        boolean hasThisProCon = !ObjectUtils.isEmpty(oldProCon);

        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_LIST"));
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_CATEGORY"));
        String equDefineName = jgVehicleInformationMapper.getEquCategoryNameByCode(Objects.toString(equipInfo.get("EQU_DEFINE"), null));
        // 是否工业管道
        boolean isGYGD = "8300".equals(equipInfo.get("EQU_CATEGORY").toString());
        // 1. 本单位下无该工程装置
        if (!hasThisProCon) {
            // 是否进行登记 和 纳管同一状态
            boolean registerFlag = !ObjectUtils.isEmpty(equipInfo.get(USE_REGISTRATION_CODE)) && isGYGD;
            List<Map<String, Object>> pipelineList = (List<Map<String, Object>>) equipInfo.get(PIPELINE_LIST);
            String[] splitOrgBranchCode = Objects.toString(equipInfo.getString("orgBranchCode"), "").split("_");
            // 工程装置
            IdxBizJgProjectContraption projectContraption = JSON.parseObject(toJSONString(equipInfo), IdxBizJgProjectContraption.class);
            projectContraption.setDataSource(JG_HIS_XA_CLAIM);
            projectContraption.setIsIntoManagement(registerFlag);
            projectContraption.setProvinceName("陕西省");
            CityCountyStreet result = getCityCountStreet(equipInfo, new JgUseRegistration());
            projectContraption.setCityName(result.useCityName);
            projectContraption.setCountyName(result.useCountyName);
            projectContraption.setStreetName(result.useStreetName);
            projectContraption.setEquListName(equListName);
            projectContraption.setEquCategoryName(equCategoryName);
            projectContraption.setEquDefineName(equDefineName);
            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()
            );
            projectContraption.setUseUnitName(company.getCompanyName());
            projectContraption.setUseUnitCreditCode(company.getCompanyCode());
            projectContraption.setIsFirstMerge(false);
            projectContraption.setCreateDate(new Date());
            projectContraption.setOrgCode(splitOrgBranchCode[0]);
            projectContraption.setOrgName(splitOrgBranchCode.length > 1 ? splitOrgBranchCode[1] : null);
            // 监管码
            if (!ObjectUtils.isEmpty(equipInfo.get(USE_REGISTRATION_CODE))) {
                projectContraption.setSupervisoryCode(idxBizJgRegisterInfoServiceImpl.getSupervisoryCode(Objects.toString(equipInfo.get("city"), null), equipInfo.get("EQU_CATEGORY").toString()));
            }

            // 设备
            this.addOrUpdatePipeEquip(equipInfo, projectContraption, registerFlag);
            // 历史管道登记
            if (registerFlag) {
                this.pipeHistoryRegister(equipInfo, projectContraption);
            }
            // 更新
            idxBizJgProjectContraptionService.updateById(projectContraption);
        }

        // 2. 本单位下有该工程装置
        if (hasThisProCon) {
            boolean hasRegister = !ObjectUtils.isEmpty(oldProCon.getUseRegistrationCode());
            // 2.1 已经有的工程装置【未登记】
            // 更新管道长度
            List<Map<String, Object>> pipelineList = (List<Map<String, Object>>) equipInfo.get(PIPELINE_LIST);
            BigDecimal oldPipeLengthBd = BigDecimal.valueOf(oldProCon.getPipelineLength());
            BigDecimal newPipeLengthBd = BigDecimal.valueOf(pipelineList.stream()
                            .map(pipeline -> pipeline.get("pipeLength"))
                            .filter(Objects::nonNull)
                            .mapToDouble(pipeLength -> {
                                if (pipeLength instanceof Number) {
                                    return ((Number) pipeLength).doubleValue();
                                }
                                return Double.parseDouble(String.valueOf(pipeLength));
                            })
                            .sum())
                    .setScale(2, RoundingMode.HALF_UP); // 保持为 BigDecimal
            BigDecimal totalPipeLengthBd = oldPipeLengthBd.add(newPipeLengthBd);
            oldProCon.setPipelineLength(totalPipeLengthBd.doubleValue());
            // 更新设备
            this.addOrUpdatePipeEquip(equipInfo, oldProCon, true);

            // 2.1 已经有的工程装置【已登记】
            String useRegistrationCode1 = oldProCon.getUseRegistrationCode();
            String useRegistrationCode2 = Objects.toString(equipInfo.get(USE_REGISTRATION_CODE), null);
            if (hasRegister && isGYGD && useRegistrationCode1.equals(useRegistrationCode2)) {
                // 更新原使用登记
                JgUseRegistration useRegistration = useRegistrationService.lambdaQuery().eq(JgUseRegistration::getUseRegistrationCode, useRegistrationCode1).eq(JgUseRegistration::getIsDelete, Boolean.FALSE).ne(JgUseRegistration::getStatus, FlowStatusEnum.TO_BE_DISCARD.getName()).one();
                if (!ObjectUtils.isEmpty(useRegistration.getSequenceNbr())) {
                    // 更新历史表中的数据 changeData中的【管道设备】equipmentLists 【管道长度】pipelineLength
                    JgRegistrationHistory history = jgRegistrationHistoryService.lambdaQuery().select(JgRegistrationHistory::getSequenceNbr, JgRegistrationHistory::getChangeData).eq(JgRegistrationHistory::getCurrentDocumentId, useRegistration.getSequenceNbr().toString()).one();
                    Optional.ofNullable(history).ifPresent(his -> {
                        JSONObject changeDataJSON = JSON.parseObject(toJSONString(his.getChangeData()));
                        JSONArray equipmentLists = JSON.parseArray(toJSONString(changeDataJSON.get("equipmentLists")));
                        equipmentLists.add(pipelineList);
                        changeDataJSON.put("pipelineLength", totalPipeLengthBd.doubleValue());
                        his.setChangeData(JSON.toJSONString(changeDataJSON));
                        jgRegistrationHistoryService.updateById(his);
                    });
                }
            }
        }

    }

    /**
     * 管道历史登记
     *
     * @param equipInfo
     */
    public void pipeHistoryRegister(JSONObject equipInfo, IdxBizJgProjectContraption projectContraption) {
        CompanyBo company = getSelectedOrgInfo().getCompany();
        AgencyUserModel userModel = getSelectedOrgInfo().getUserModel();
        String proConName = equipInfo.getString(PROJECT_CONTRAPTION);
        List<Map<String, Object>> pipelineList = (List<Map<String, Object>>) equipInfo.get(PIPELINE_LIST);
        // 使用登记表 eq关系表
        ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.SYDJ.getCode(), 1);
        String applyNo = listResponseModel.getResult().get(0);
        Long useRegseq = sequence.nextId();
        JgUseRegistration useReg = JSON.parseObject(toJSONString(equipInfo), JgUseRegistration.class);
        String[] splitMaintenanceUnitCode = Objects.toString(equipInfo.getString("receiveOrgCode"), "").split("_");
        String[] splitOrgBranchCode = Objects.toString(equipInfo.getString("orgBranchCode"), "").split("_");
        useReg.setUseUnitCreditCode(company.getCompanyCode())
                .setUseUnitName(company.getCompanyName())
                .setApplyNo(applyNo)
                .setSupervisoryCode(projectContraption.getSupervisoryCode())
                .setAuditStatus(FlowStatusEnum.TO_BE_FINISHED.getName())
                .setStatus(FlowStatusEnum.TO_BE_FINISHED.getName())
                .setReceiveOrgName(splitMaintenanceUnitCode[1])
                .setAuditPassDate(new Date()).setRegType("1")
                .setRegDate(new Date())
                .setUseRegistrationCode(equipInfo.get(USE_REGISTRATION_CODE).toString())
                .setReceiveOrgCode(splitMaintenanceUnitCode[0])
                .setReceiveCompanyCode(splitMaintenanceUnitCode[0])
                .setUseAddress("")
                .setManageType("unit")
                .setCreateDate(new Date())
                .setCreateUserId(userModel.getUserId())
                .setCreateUserName(userModel.getRealName())
                .setProjectContraptionId(projectContraption.getSequenceNbr().toString())
                .setProjectContraption(proConName)
                .setSupervisionOrgCode(splitOrgBranchCode[0])
                .setRegDate(new Date());
        useReg.setSequenceNbr(useRegseq);
        useRegistrationService.save(useReg);

        pipelineList.forEach(pipe -> {
            JgUseRegistrationEq useRegEq = new JgUseRegistrationEq();
            useRegEq.setEquipTransferId(String.valueOf(useReg.getSequenceNbr()));
            useRegEq.setRecDate(new Date());
            useRegEq.setEquId(pipe.get(record).toString());
            useRegEq.setRecUserId(userModel.getUserId());
            useRegEq.setRecUserName(userModel.getRealName());
            jgUseRegistrationEqServiceImpl.save(useRegEq);
        });
        // 历史表
        JSONObject changeData = getJgUseRegistrationChangeData(equipInfo, projectContraption, applyNo);
        JgRegistrationHistory registrationHistory = JgRegistrationHistory.builder()
                .registrationClass("使用登记")
                .changeData(JSON.toJSONString(changeData))
                .status("history")
                .currentDocumentId(String.valueOf(useRegseq))
                .build();
        registrationHistory.setRecDate(new Date());
        registrationHistory.setCreateDate(new Date());
        registrationHistory.setRecUserId(userModel.getUserId());
        registrationHistory.setCreateUserId(userModel.getUserId());
        registrationHistory.setRecUserName(userModel.getRealName());
        jgRegistrationHistoryService.save(registrationHistory);
        EquipRequestParamsDto paramsDto = new EquipRequestParamsDto();
        paramsDto.setEquipId(useReg.getProjectContraptionId());
        paramsDto.setEquListCode(EquipmentClassifityEnum.YLGD.getCode());
        String routePath = dockService.buildTaskModel(useReg, paramsDto);
        jgResumeInfoService.createWithModel(JgResumeInfoDto.builder()
                .applyNo(useReg.getApplyNo())
                .businessType(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName())
                .businessId(useReg.getSequenceNbr() + "")
                .equId(useReg.getProjectContraptionId())
                .approvalUnit(useReg.getReceiveOrgName())
                .approvalUnitCode(useReg.getReceiveOrgCode())
                .status("正常")
                .routePath(routePath)
                .changeContent(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName() + "业务办理")
                .build());
        // 证管理表
        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_LIST"));
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_CATEGORY"));
        String equDefineName = jgVehicleInformationMapper.getEquCategoryNameByCode(Objects.toString(equipInfo.get("EQU_DEFINE"), null));
        Map<String, String> equType = new HashMap<>();
        equType.put("equListCode", equipInfo.get("EQU_LIST").toString());
        equType.put("equCategoryCode", equipInfo.get("EQU_CATEGORY").toString());
        JgUseRegistrationManage registrationManage = JgUseRegistrationManage.builder()
                .equListCode(equipInfo.get("EQU_LIST").toString())
                .equList(equListName)
                .equCategoryCode(equipInfo.get("EQU_CATEGORY").toString())
                .equCategory(equCategoryName)
                .equDefineCode(Objects.toString(equipInfo.get("EQU_DEFINE"), null))
                .equDefine(equDefineName)
                .useUnitName(company.getCompanyName())
                .useUnitCreditCode(company.getCompanyCode())
                .applyNo(useReg.getApplyNo())
                .receiveCompanyCode(splitMaintenanceUnitCode[0])
                .receiveOrgName(splitMaintenanceUnitCode[1])
                .auditPassDate(new Date())
                .useRegistrationCode(equipInfo.get(USE_REGISTRATION_CODE).toString())
                .certificateNo(commonService.generateCertificateNo(equType, new Date(), useReg.getReceiveOrgCode()))
                .regType(BusinessTypeEnum.JG_HISTORY_USAGE_REGISTRATION.getName())
                .certificateStatus("已登记")
                .registrationType("1")
                .regDate(new Date())
                .createDate(new Date())
                .createUserId(userModel.getUserId())
                .useUnitAddress(company.getAddress())
                .manageType("unit")
                .isScrap("0")
                .version(1)
                .superviseOrgCode(splitOrgBranchCode[0])
                .superviseOrgName(splitOrgBranchCode.length > 1 ? splitOrgBranchCode[1] : null)
                .build();
        jgUseRegistrationManageService.save(registrationManage);
        // 流水表
        Long changeRecordSeq = sequence.nextId();
        JgCertificateChangeRecord changeRecord = new JgCertificateChangeRecord()
                .setApplyNo(useReg.getApplyNo())
                .setReceiveOrgName(useReg.getReceiveOrgName())
                .setAuditPassDate(new Date())
                .setRegType(BusinessTypeEnum.JG_USAGE_REGISTRATION.getName())
                .setRegDate(useReg.getCreateDate())
                .setChangeContent(company.getCompanyName() + "的" + userModel.getRealName() + "办理了【" + "历史设备登记" + "】，" +
                        "单号【" + useReg.getApplyNo() + "】，办理日期" + new SimpleDateFormat("yyyy年MM月dd日").format(new Date()))
                .setUseRegistrationCode(useReg.getUseRegistrationCode())
                .setReceiveCompanyCode(useReg.getReceiveCompanyOrgCode())
                .setCertificateNo(registrationManage.getCertificateNo())
                .setUseUnitCreditCode(useReg.getUseUnitCreditCode())
                .setUseUnitName(useReg.getUseUnitName())
                .setEquCategory(equCategoryName)
                .setCreateDate(new Date());
        changeRecord.setSequenceNbr(changeRecordSeq);
        certificateChangeRecordService.save(changeRecord);
        pipelineList.forEach(pipe -> {
            JgCertificateChangeRecordEq changeRecordEq = new JgCertificateChangeRecordEq();
            changeRecordEq.setChangeRecordId(String.valueOf(changeRecordSeq));
            changeRecordEq.setEquId(pipe.get(record).toString());
            certificateChangeRecordEqService.save(changeRecordEq);
        });
    }

    /**
     * 组装使用登记表单的回显数据
     *
     * @return
     */
    private JSONObject getJgUseRegistrationChangeData(JSONObject equipInfo, IdxBizJgProjectContraption proCon, String spplyNo) {
        CompanyBo company = getSelectedOrgInfo().getCompany();
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(equipInfo);
        jsonObject.put("receiveOrgCode", equipInfo.getString("receiveOrgCode"));
        jsonObject.put("status", FlowStatusEnum.TO_BE_FINISHED.getName());
        jsonObject.put("applyNo", spplyNo);
        jsonObject.remove("submit");
        jsonObject.remove("instanceId");
        if (!ObjectUtils.isEmpty(jsonObject.get("factoryUseSiteStreet"))) {
            jsonObject.put("factoryUseSiteStreet", String.valueOf(Long.valueOf(jsonObject.get("factoryUseSiteStreet").toString())));
        }
        IdxBizJgProjectContraption projectContraption = idxBizJgProjectContraptionService.getById(proCon.getSequenceNbr());
        jsonObject.put("pipelineLength", projectContraption.getPipelineLength());
        jsonObject.put("useUnitCreditCode", company.getCompanyCode());
        jsonObject.put("useUnitName", company.getCompanyName());
        // IdxBizJgConstructionInfo constructionInfo = idxBizJgConstructionInfoService.lambdaQuery().eq(IdxBizJgConstructionInfo::getRecord, record).orderByDesc(IdxBizJgConstructionInfo::getRecDate).one();
        // jsonObject.put("uscUnitCreditCode", constructionInfo.getUscUnitCreditCode());
        // jsonObject.put("uscUnitName", constructionInfo.getUscUnitName());
        // IdxBizJgInspectionDetectionInfo inspectionDetectionInfo = iIdxBizJgInspectionDetectionInfoService.lambdaQuery().eq(IdxBizJgInspectionDetectionInfo::getRecord, record).orderByDesc(IdxBizJgInspectionDetectionInfo::getRecDate).one();
        // JSONObject inspectionDetectionInfoJO = (JSONObject) JSON.toJSON(inspectionDetectionInfo);
        // jsonObject.putAll(inspectionDetectionInfoJO);
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // jsonObject.put("inspectDate", Optional.ofNullable(inspectionDetectionInfo.getInspectDate())
        //         .map(sdf::format)
        //         .orElse(null));
        // jsonObject.put("nextInspectDate", Optional.ofNullable(inspectionDetectionInfo.getNextInspectDate())
        //         .map(sdf::format)
        //         .orElse(null));
        jsonObject.put("orgBranchCode", equipInfo.getString("orgBranchCode"));
        jsonObject.put("projectContraption", projectContraption.getProjectContraption());
        jsonObject.put("projectContraptionNo", projectContraption.getProjectContraptionNo());
        JSONArray pipeArray = JSON.parseArray(toJSONString(equipInfo.get(PIPELINE_LIST)));
        pipeArray.forEach(item -> {
            JSONObject itemObj = JSON.parseObject(toJSONString(item));
            itemObj.put("productName", itemObj.get("pipeName"));
        });
        jsonObject.put("equipmentLists", pipeArray);
        jsonObject.put("useRegistrationCode", equipInfo.get(USE_REGISTRATION_CODE).toString());
        // 转化 附件 字段
        dockService.convertStringToJsonObject(jsonObject, JgUseRegistrationServiceImpl.jsonFields);
        return jsonObject;
    }

    public String getEquCode(String equListCode, String equCategoryCode, String equDefineCode, Date now, String receiveCompanyCode) {
        CodeGenerateDto codeGenerateDto = new CodeGenerateDto();
        codeGenerateDto.setEquList(equListCode);
        codeGenerateDto.setEquCategory(equCategoryCode);
        codeGenerateDto.setEquDefine(equDefineCode);
        codeGenerateDto.setProduceDate(now);
        codeGenerateDto.setReceiveCompanyCode(receiveCompanyCode);
        return codeUtil.generateEquipmentCode(codeGenerateDto);
    }

    public void addOrUpdatePipeEquip(JSONObject equipInfo, IdxBizJgProjectContraption projectContraption, Boolean isIntoManagement) {
        Date nowDate = new Date();
        List<Map<String, Object>> pipelineList = (List<Map<String, Object>>) equipInfo.get(PIPELINE_LIST);
        CompanyBo company = getSelectedOrgInfo().getCompany();
        String proConName = equipInfo.getString(PROJECT_CONTRAPTION);
        String proConNo = equipInfo.getString(PROJECT_CONTRAPTION_NO);
        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_LIST"));
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode((String) equipInfo.get("EQU_CATEGORY"));
        List<IdxBizJgUseInfo> toUpdateUseInfoList = initializeList();
        List<IdxBizJgUseInfo> toAddUseInfoList = initializeList();
        List<IdxBizJgDesignInfo> toUpdateDesignInfoList = initializeList();
        List<IdxBizJgDesignInfo> toAddDesignInfoList = initializeList();
        List<IdxBizJgFactoryInfo> toUpdateFactoryInfoList = initializeList();
        List<IdxBizJgFactoryInfo> toAddFactoryInfoList = initializeList();
        List<IdxBizJgConstructionInfo> toUpdateConstructionInfoList = initializeList();
        List<IdxBizJgConstructionInfo> toAddConstructionInfoList = initializeList();
        List<IdxBizJgRegisterInfo> toUpdateRegisterInfoList = initializeList();
        List<IdxBizJgRegisterInfo> toAddRegisterInfoList = initializeList();
        List<IdxBizJgSupervisionInfo> toUpdateSupervisionInfoList = initializeList();
        List<IdxBizJgSupervisionInfo> toAddSupervisionInfoList = initializeList();
        List<IdxBizJgOtherInfo> toUpdateOtherInfoList = initializeList();
        List<IdxBizJgOtherInfo> toAddOtherInfoList = initializeList();
        List<IdxBizJgInspectionDetectionInfo> toUpdateInspectionDetectionInfoList = initializeList();
        List<IdxBizJgInspectionDetectionInfo> toAddInspectionDetectionInfoList = initializeList();
        List<IdxBizJgTechParamsPipeline> toUpdateParamsPipelineList = initializeList();
        List<IdxBizJgTechParamsPipeline> toAddParamsPipelineList = initializeList();
        List<ESEquipmentCategoryDto> esEquipmentCategoryList = initializeList();
        String equCode = this.getEquCode(equipInfo.get("EQU_LIST").toString(), equipInfo.get("EQU_CATEGORY").toString(), Objects.toString(equipInfo.get("EQU_DEFINE"), null), new Date(), Objects.toString(equipInfo.getString("receiveOrgCode"), "").split("_")[0]);
        projectContraption.setEquCode(equCode);
        // 设备信息
        for (Map<String, Object> pipeline : pipelineList) {
            boolean hasRecord = !ObjectUtils.isEmpty(pipeline.get("record"));
            String record = hasRecord ? pipeline.get("record").toString() : UUID.randomUUID().toString();
            pipeline.put("record", record);
            // 更新时工业管道（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.setInspectConclusion((String) pipeline.getOrDefault("inspectConclusionCode", ""));
                inspectionDetectionInfo.setRecord(record);
                inspectionDetectionInfo.setRecDate(nowDate);
                inspectionDetectionInfo.setSequenceNbr(null);
                if (inspectionDetectionInfo.getNextInspectDate() != null) {
                    inspectionDetectionInfo.setNextInspectDate(DateUtil.parse(DateUtil.format(inspectionDetectionInfo.getNextInspectDate(), DatePattern.NORM_DATE_PATTERN)));
                }
                if (hasRecord) {
                    toUpdateInspectionDetectionInfoList.add(inspectionDetectionInfo);
                } else {
                    toAddInspectionDetectionInfoList.add(inspectionDetectionInfo);
                }
            }

            // 使用信息
            IdxBizJgUseInfo useInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgUseInfo.class);
            // 使用信息
            useInfo.setRecord(record);
            useInfo.setSequenceNbr(null);
            useInfo.setRecDate(nowDate);
            if (!hasRecord) {
                useInfo.setCreateDate(nowDate);
            }
            useInfo.setDataSource(JG_HIS_XA_CLAIM);
            useInfo.setIsIntoManagement(isIntoManagement);
            useInfo.setUseUnitCreditCode(company.getCompanyCode());
            useInfo.setUseUnitName(company.getCompanyName());
            useInfo.setEquState("");
            useInfo.setProjectContraption(proConName);
            useInfo.setProjectContraptionId(projectContraption.getSequenceNbr().toString());
            if (hasRecord) {
                toUpdateUseInfoList.add(useInfo);
            } else {
                toAddUseInfoList.add(useInfo);
            }


            // 设计信息
            IdxBizJgDesignInfo designInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgDesignInfo.class);
            designInfo.setRecord(record);
            designInfo.setRecDate(nowDate);
            designInfo.setSequenceNbr(null);
            if (hasRecord) {
                toUpdateDesignInfoList.add(designInfo);
            } else {
                toAddDesignInfoList.add(designInfo);
            }

            // 制造信息
            IdxBizJgFactoryInfo factoryInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgFactoryInfo.class);
            factoryInfo.setRecord(record);
            factoryInfo.setRecDate(nowDate);
            factoryInfo.setSequenceNbr(null);
            if (hasRecord) {
                toUpdateFactoryInfoList.add(factoryInfo);
            } else {
                toAddFactoryInfoList.add(factoryInfo);
            }

            // 施工信息
            JSONObject pipeJSON = JSON.parseObject(JSON.toJSONString(pipeline));
            pipeJSON.remove("uscDate");
            IdxBizJgConstructionInfo constructionInfo = JSON.parseObject(toJSONString(pipeJSON), IdxBizJgConstructionInfo.class);
            constructionInfo.setUscDate(ValidationUtil.isEmpty(pipeline.get("uscDate")) ? null : DateUtil.parse(pipeline.get("uscDate").toString(), DatePattern.NORM_MONTH_FORMAT));
            constructionInfo.setRecord(record);
            constructionInfo.setRecDate(nowDate);
            constructionInfo.setSequenceNbr(null);
            if (hasRecord) {
                toUpdateConstructionInfoList.add(constructionInfo);
            } else {
                toAddConstructionInfoList.add(constructionInfo);
            }

            // 监督管理
            IdxBizJgSupervisionInfo supervisionInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgSupervisionInfo.class);
            supervisionInfo.setRecord(record);
            supervisionInfo.setRecDate(nowDate);
            supervisionInfo.setSequenceNbr(null);
            if (hasRecord) {
                toUpdateSupervisionInfoList.add(supervisionInfo);
            } else {
                toAddSupervisionInfoList.add(supervisionInfo);
            }


            // 其他信息
            IdxBizJgOtherInfo otherInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgOtherInfo.class);
            otherInfo.setRecord(record);
            otherInfo.setSequenceNbr(null);
            otherInfo.setClaimStatus("已认领");
            otherInfo.setRecDate(nowDate);
            otherInfo.setSupervisoryCode(projectContraption.getSupervisoryCode());
            otherInfo.setCylinderStampAttachment("");
            otherInfo.setInformationSituation("");
            otherInfo.setInformationManageCode("");
            if (hasRecord) {
                toUpdateOtherInfoList.add(otherInfo);
            } else {
                toAddOtherInfoList.add(otherInfo);
            }


            // 管道技术参数
            IdxBizJgTechParamsPipeline pipelineInfo = JSON.parseObject(toJSONString(pipeline), IdxBizJgTechParamsPipeline.class);
            if (!ValidationUtil.isEmpty(pipelineInfo)) {
                pipelineInfo.setRecord(record);
                pipelineInfo.setRecDate(nowDate);
                pipelineInfo.setSequenceNbr(null);
                if (hasRecord) {
                    toUpdateParamsPipelineList.add(pipelineInfo);
                } else {
                    toAddParamsPipelineList.add(pipelineInfo);
                }
            }

            // 注册登记信息
            IdxBizJgRegisterInfo registerInfo = JSON.parseObject(toJSONString(equipInfo), IdxBizJgRegisterInfo.class);
            registerInfo.setRecord(record);
            registerInfo.setRecDate(nowDate);
            registerInfo.setSequenceNbr(null);
            registerInfo.setEquCodeType("2");
            registerInfo.setEquCode(equCode);
            registerInfo.setRegisterState(jgRegisterInfoService.getRegCode());
            registerInfo.setProductName(pipelineInfo.getPipeName());
            if (hasRecord) {
                toUpdateRegisterInfoList.add(registerInfo);
            } else {
                toAddRegisterInfoList.add(registerInfo);
            }

            ESEquipmentCategoryDto esEquipmentDto = JSON.parseObject(toJSONString(equipInfo), ESEquipmentCategoryDto.class);
            esEquipmentDto.setDATA_SOURCE(useInfo.getDataSource());
            if (inspectionDetectionInfo.getNextInspectDate() != null) {
                esEquipmentDto.setNEXT_INSPECT_DATE(inspectionDetectionInfo.getNextInspectDate().getTime());
            }
            esEquipmentDto.setREC_DATE(System.currentTimeMillis());
            if (!hasRecord) {
                esEquipmentDto.setCREATE_DATE(System.currentTimeMillis());
            } else {
                IdxBizJgUseInfo existUseInfo = idxBizJgUseInfoService.lambdaQuery().eq(IdxBizJgUseInfo::getRecord, record).one();
                if (ValidationUtil.isEmpty(existUseInfo)) {
                    esEquipmentDto.setCREATE_DATE(System.currentTimeMillis());
                }  else {
                    esEquipmentDto.setCREATE_DATE(existUseInfo.getCreateDate().getTime());
                }
            }
            esEquipmentDto.setSEQUENCE_NBR(record);
            esEquipmentDto.setIS_INTO_MANAGEMENT(false);
            esEquipmentDto.setEQU_CATEGORY_CODE(registerInfo.getEquCategory());
            esEquipmentDto.setEQU_CATEGORY(equCategoryName);
            esEquipmentDto.setEQU_LIST_CODE(registerInfo.getEquList());
            esEquipmentDto.setEQU_LIST(equListName);
            esEquipmentDto.setEQU_DEFINE_CODE(registerInfo.getEquDefine());
            esEquipmentDto.setEQU_DEFINE(equListName);
            esEquipmentDto.setSTATUS("已认领");
            esEquipmentDto.setUSC_UNIT_CREDIT_CODE(null);
            esEquipmentDto.setUSC_UNIT_NAME(null);
            esEquipmentDto.setUSE_UNIT_CREDIT_CODE(company.getCompanyCode());
            esEquipmentDto.setUSE_UNIT_NAME(company.getCompanyName());
            esEquipmentDto.setPROJECT_CONTRAPTION(proConName);
            esEquipmentDto.setPRODUCT_NAME(pipelineInfo.getPipeName());
            esEquipmentDto.setProjectContraptionId(proConNo);
            if (inspectionDetectionInfo.getNextInspectDate() != null) {
                esEquipmentDto.setNEXT_INSPECT_DATE(inspectionDetectionInfo.getNextInspectDate().getTime());
            }
            esEquipmentCategoryList.add(esEquipmentDto);
        }
        // 使用信息
        if (!toAddUseInfoList.isEmpty()) {
            idxBizJgUseInfoService.saveBatch(toAddUseInfoList);
        }
        if (!toUpdateUseInfoList.isEmpty()) {
            idxBizJgUseInfoService.updateBatchByRecord(toUpdateUseInfoList);
        }

// 设计信息
        if (!toAddDesignInfoList.isEmpty()) {
            iIdxBizJgDesignInfoService.saveOrUpdateBatch(toAddDesignInfoList);
        }
        if (!toUpdateDesignInfoList.isEmpty()) {
            iIdxBizJgDesignInfoService.updateBatchByRecord(toUpdateDesignInfoList);
        }

// 施工信息
        if (!toAddConstructionInfoList.isEmpty()) {
            iIdxBizJgConstructionInfoService.saveBatch(toAddConstructionInfoList);
        }
        if (!toUpdateConstructionInfoList.isEmpty()) {
            iIdxBizJgConstructionInfoService.updateBatchByRecord(toUpdateConstructionInfoList);
        }

// 厂信息
        if (!toAddFactoryInfoList.isEmpty()) {
            iIdxBizJgFactoryInfoService.saveOrUpdateBatch(toAddFactoryInfoList);
        }
        if (!toUpdateFactoryInfoList.isEmpty()) {
            iIdxBizJgFactoryInfoService.updateBatchByRecord(toUpdateFactoryInfoList);
        }

// 注册信息
        if (!toAddRegisterInfoList.isEmpty()) {
            jgRegisterInfoService.saveOrUpdateBatch(toAddRegisterInfoList);
        }
        if (!toUpdateRegisterInfoList.isEmpty()) {
            jgRegisterInfoService.updateBatchByRecord(toUpdateRegisterInfoList);
        }

// 其他信息
        if (!toAddOtherInfoList.isEmpty()) {
            iIdxBizJgOtherInfoService.saveOrUpdateBatch(toAddOtherInfoList);
        }
        if (!toUpdateOtherInfoList.isEmpty()) {
            iIdxBizJgOtherInfoService.updateBatchByRecord(toUpdateOtherInfoList);
        }

// 监督信息
        if (!toAddSupervisionInfoList.isEmpty()) {
            iIdxBizJgSupervisionInfoService.saveOrUpdateBatch(toAddSupervisionInfoList);
        }
        if (!toUpdateSupervisionInfoList.isEmpty()) {
            iIdxBizJgSupervisionInfoService.updateBatchByRecord(toUpdateSupervisionInfoList);
        }

// 检验检测信息
        if (!toAddInspectionDetectionInfoList.isEmpty()) {
            iIdxBizJgInspectionDetectionInfoService.saveOrUpdateBatch(toAddInspectionDetectionInfoList);
        }
        if (!toUpdateInspectionDetectionInfoList.isEmpty()) {
            iIdxBizJgInspectionDetectionInfoService.updateBatchByRecord(toUpdateInspectionDetectionInfoList);
        }

// 技术参数管道信息
        if (!toAddParamsPipelineList.isEmpty()) {
            iIdxBizJgTechParamsPipelineService.saveOrUpdateBatch(toAddParamsPipelineList);
        }
        if (!toUpdateParamsPipelineList.isEmpty()) {
            iIdxBizJgTechParamsPipelineService.updateBatchByRecord(toUpdateParamsPipelineList);
        }
        equipInfo.put(PIPELINE_LIST, pipelineList);
        esEquipmentCategory.saveAll(esEquipmentCategoryList);

        eventPublisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_PROJECT.name(), Sets.newHashSet(projectContraption.getSequenceNbr() + ""), EquipCreateOrEditEvent.EquipType.project));
    }

    /**
     * 使用登记证校验 + 工程装置编号名称组合校验
     *
     * @param equipInfo
     */
    public void checkPipeParams(JSONObject equipInfo) {
        CompanyBo company = getSelectedOrgInfo().getCompany();

        // 管道校验
        //同一工程装置下管道编号不能重复校验
        List<Map<String, Object>> pipelineList = (List<Map<String, Object>>) equipInfo.get(PIPELINE_LIST);
//        if (CollectionUtils.isEmpty(pipelineList) || pipelineList.size() != pipelineList.stream()
//                .map(v -> (String) v.get("pipelineNumber")).distinct().count()) {
//            throw new BadRequest(CollectionUtils.isEmpty(pipelineList) ? "请填写管道信息!" : "同一工程装置下管道编号不能重复！");
//        }
        // 需要融合的判断融合后的管道编号是否重复
        String proConNo = equipInfo.getString(PROJECT_CONTRAPTION_NO);
        IdxBizJgProjectContraption oldProCon = idxBizJgProjectContraptionService.getBaseMapper().selectOne(new LambdaQueryWrapper<IdxBizJgProjectContraption>()
                .eq(IdxBizJgProjectContraption::getUseUnitCreditCode, company.getCompanyCode())
                .eq(IdxBizJgProjectContraption::getProjectContraptionNo, proConNo)
                .eq(IdxBizJgProjectContraption::getIsDelete, Boolean.FALSE)
                .isNull(IdxBizJgProjectContraption::getProjectContraptionParentId));
        boolean hasThisProCon = !ObjectUtils.isEmpty(oldProCon);
        if (hasThisProCon) {
            List<String> records = idxBizJgUseInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord).eq(IdxBizJgUseInfo::getProjectContraptionId, oldProCon.getSequenceNbr()).list().stream().map(IdxBizJgUseInfo::getRecord).collect(Collectors.toList());
            List<String> oldPipelineNumber = iIdxBizJgTechParamsPipelineService.lambdaQuery().select(IdxBizJgTechParamsPipeline::getPipelineNumber).in(IdxBizJgTechParamsPipeline::getRecord, records).list().stream().map(IdxBizJgTechParamsPipeline::getPipelineNumber).collect(Collectors.toList());
            List<String> newPipelineNumber = pipelineList.stream().map(item -> item.get("pipelineNumber").toString()).collect(Collectors.toList());
            boolean noCommonElements = Collections.disjoint(oldPipelineNumber, newPipelineNumber);
            if (!noCommonElements) {
                throw new BadRequest("管道编号与本单位原装置下的重复！");
            }
        }

    }
}
