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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
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.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.dto.CountDto;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.common.biz.refresh.DataRefreshEvent;
import com.yeejoin.amos.boot.module.jg.api.dto.EquipRequestParamsDto;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistrationManage;
import com.yeejoin.amos.boot.module.jg.api.enums.CompanyTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.EquipSourceEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.IsIntoManagementEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.PipelineEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.CommonMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgVehicleInformationMapper;
import com.yeejoin.amos.boot.module.jg.api.vo.SortVo;
import com.yeejoin.amos.boot.module.jg.biz.core.BaseEntityService;
import com.yeejoin.amos.boot.module.jg.biz.event.publisher.EventPublisher;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgProjectContraptionService;
import com.yeejoin.amos.boot.module.ymt.api.dto.IdxBizJgProjectContraptionDto;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgProjectContraptionMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.alibaba.fastjson.JSON.toJSONString;
/**
 * 管道工程装置表服务实现类
 *
 * @author system_generator
 * @date 2024-12-11
 */
@Slf4j
@Service
public class IdxBizJgProjectContraptionServiceImplService extends BaseEntityService<IdxBizJgProjectContraptionMapper, IdxBizJgProjectContraption> implements IIdxBizJgProjectContraptionService {

    public static final String[] jsonFields = {"PRODUCT_PHOTO", "OTHER_ACCESSORIES", "PRODUCT_QUALIFICATION_CERTIFICATE", "START_LATITUDE_LONGITUDE",
            "END_LATITUDE_LONGITUDE"};
    public static final String IS_INTO_MANAGEMENT = "isIntoManagement";
    public static final String USE_REGISTRATION_CODE = "useRegistrationCode";
    public static final String REG_CODE_IS_NULL = "regCodeIsNull";
    public static final String PROJECT_CONTRAPTION = "projectContraption";
    public static final String EQU_CATEGORY = "equCategory";
    public static final String EQU_DEFINE = "equDefine";
    public static final String PROJECT_CONTRAPTION_NO = "projectContraptionNo";
    public static final String ORG_BRANCH_CODE = "orgBranchCode";
    public static final String DATA_SOURCE = "dataSource";

    public static final String DATA_QUALITY_SCORE = "dataQualityScore";
    public static final String DATA_QUALITY = "dataQuality";
    // 设备基本信息表单id
    private static final String EQUIP_INFO_FORM_ID = "equipInfo";
    public static final String USE_UNIT_CREDIT_CODE = "useUnitCreditCode";
    public static final String USE_UNIT_NAME = "useUnitName";
    public static final String EXPORT_SUMMARY_TABLE = "exportSummaryTable";
    @Resource
    private IdxBizJgUseInfoServiceImpl useInfoService;
    @Resource
    private IdxBizJgRegisterInfoServiceImpl registerInfoService;
    @Autowired
    private IdxBizJgInspectionDetectionInfoServiceImpl detectionInfoService;
    @Autowired
    private TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;
    @Autowired
    @Lazy
    private CommonServiceImpl commonService;
    @Autowired
    private JgVehicleInformationMapper jgVehicleInformationMapper;
    @Autowired
    private JgInstallationNoticeServiceImpl jgInstallationNoticeService;
    @Autowired
    private IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;
    @Autowired
    private IdxBizJgDesignInfoServiceImpl idxBizJgDesignInfoService;
    @Autowired
    private IdxBizJgFactoryInfoServiceImpl idxBizJgFactoryInfoService;
    @Autowired
    private IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;
    @Autowired
    private IdxBizJgSupervisionInfoServiceImpl idxBizJgSupervisionInfoService;
    @Autowired
    private IdxBizJgOtherInfoServiceImpl idxBizJgOtherInfoService;
    @Autowired
    private IdxBizJgTechParamsPipelineServiceImpl idxBizJgTechParamsPipelineService;
    @Autowired
    private IdxBizJgInspectionDetectionInfoServiceImpl idxBizJgInspectionDetectionInfoService;
    @Autowired
    private IdxBizJgConstructionInfoServiceImpl idxBizJgConstructionInfoService;
    @Autowired
    private ESEquipmentCategory esEquipmentCategory;
    @Autowired
    private DataDictionaryServiceImpl dataDictionaryServiceImpl;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private JgUseRegistrationManageServiceImpl registrationManageService;
    @Autowired
    private CommonMapper commonMapper;
    @Autowired
    private EventPublisher eventPublisher;

    @Override
    public boolean saveOrUpdateData(IdxBizJgProjectContraption projectContraption) {
        return super.saveOrUpdateWithNull(projectContraption);
    }

    public static String[] getJsonFieldsCamel(){
        List<String> camelFields = new ArrayList<>();
        for(String field : jsonFields) {
            camelFields.add(CharSequenceUtil.toCamelCase(field));
        }
        return camelFields.toArray(new String[0]);
    }

    /**
     * 根据证的seq查询其下的工程装置
     */
    public List<IdxBizJgProjectContraption> queryProConByCertSeq(String certSeq) {
        JgUseRegistrationManage certManage = registrationManageService.getBaseMapper().selectById(certSeq);
        List<IdxBizJgProjectContraption> result = this.lambdaQuery()
                .eq(IdxBizJgProjectContraption::getIsDelete, Boolean.FALSE)
                .isNull(IdxBizJgProjectContraption::getProjectContraptionParentId)
                .eq(IdxBizJgProjectContraption::getUseRegistrationCode, certManage.getUseRegistrationCode())
                .list();

        if (!ValidationUtil.isEmpty(result)) {
            result.forEach(record -> {
                BigDecimal pipelineLength = BigDecimal.valueOf(record.getPipelineLength());
                BigDecimal roundedValue = pipelineLength.setScale(3, RoundingMode.HALF_UP);
                BigDecimal strippedValue = roundedValue.stripTrailingZeros();
                record.setPipelineLength(Double.valueOf(strippedValue.toPlainString()));
                record.setDataSourceName(EquipSourceEnum.getDataSourceName(record.getDataSource()));
                record.setFullAddress(
                        Stream.of(record.getProvinceName(), record.getCityName(), record.getCountyName(), record.getStreetName(), record.getAddress())
                                .map(value -> value == null || "null".equals(value) ? "" : value)
                                .collect(Collectors.joining())
                );
            });
        }
        return result;
    }

    /**
     * 检查本单位下工程装置名称和工程装置编号是不是一一对应的
     * 不对应抛出异常
     *
     * @param paramsDto
     */
    void checkTheUnitProConMatching(EquipRequestParamsDto paramsDto) {
        Integer existsConflictNum = this.lambdaQuery().eq(IdxBizJgProjectContraption::getUseUnitCreditCode, paramsDto.getCompanyCode()).eq(IdxBizJgProjectContraption::getUseUnitName, paramsDto.getCompanyName())
                .eq(IdxBizJgProjectContraption::getIsIntoManagement, Boolean.TRUE)
                .eq(IdxBizJgProjectContraption::getIsDelete, Boolean.FALSE)
                .and(wrapper -> wrapper.ne(IdxBizJgProjectContraption::getProjectContraptionNo, paramsDto.getProjectContraptionNo()).eq(IdxBizJgProjectContraption::getProjectContraption, paramsDto.getProjectContraption())
                        .or().eq(IdxBizJgProjectContraption::getProjectContraptionNo, paramsDto.getProjectContraptionNo()).ne(IdxBizJgProjectContraption::getProjectContraption, paramsDto.getProjectContraption())
                )
                .count();
        if (existsConflictNum > 0) {
            throw new BadRequest("工程装置名称或编号与本单位下的已存在的数据冲突！");
        }
    }

    /**
     * 根据工程装置seq物理删除装置表数据和对应设备信息（数据库+es）
     *
     * @param sequenceNbr 工程装置表seq
     * @return result
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProjectAndEquInfoBySeq(Long sequenceNbr) {
        this.checkForDelete(Collections.singletonList(String.valueOf(sequenceNbr)));
        List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord).eq(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr).list();
        // 删除idx设备表信息 + 删除对应es数据
        List<String> records = useInfos.stream().map(IdxBizJgUseInfo::getRecord).collect(Collectors.toList());
        if (!records.isEmpty()){
            Map<String, Object> map = new HashMap<>();
            map.put("recordList", records);
            map.put("equList", PipelineEnum.PRESSURE_PIPELINE.getCode());
            registerInfoService.batchDeleteByRecord(map);
        }
        // 删除装置表信息
        this.removeById(sequenceNbr);
        return Boolean.TRUE;
    }

    private String getCompanyLevel(CompanyBo company) {
        if (BaseController.COMPANY_TYPE_COMPANY.equals(company.getLevel())) {
            return BaseController.COMPANY_TYPE_COMPANY;
        } else {
            return BaseController.COMPANY_TYPE_SUPERVISION;
        }
    }

    /**
     * 根据入参 分页查询（当前）单位下的工程管道
     *
     * @param params      查询参数 Map
     * @param reginParams 当前登录人信息
     * @return result
     */
    @Override
    public IPage<IdxBizJgProjectContraption> proConPageByParams(int current, int size, String sort, Map<String, String> params, ReginParams reginParams) {
        try {
            Page<IdxBizJgProjectContraption> page = new Page<>();
            page.setCurrent(current);
            page.setSize(size);
            CompanyBo company = reginParams.getCompany();
            String companyType = company.getCompanyType();
            String companyCode = company.getCompanyCode();
            SortVo sortVo = commonService.sortFieldConversion(sort);
            // 是否是否纳管：true - 已纳管 false-未纳管
            boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
            // 使用登记编号
            String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
            // 使用登记编号是否为空 true/false
            String regCodeIsNull = params.get(REG_CODE_IS_NULL);
            // 工程装置名称
            String projectContraption = params.get(PROJECT_CONTRAPTION);
            // 工程装置编号
            String projectContraptionNo = params.get(PROJECT_CONTRAPTION_NO);
            //属地监管部门code
            String orgBranchCode = params.get(ORG_BRANCH_CODE);
            String dataSource = params.get(DATA_SOURCE);
            // 设备类别code
            String equCategory = params.get(EQU_CATEGORY);
            // 设备类品种code
            String equDefine = params.get(EQU_DEFINE);

            String dataQualityScore = params.get(DATA_QUALITY_SCORE);
            String dataQuality = params.get(DATA_QUALITY);
            // 证详情-查询标识
            String useRegDetail = params.get("useRegDetail");
            // 登录人公司类型：企业，监管
            String companyLevel = this.getCompanyLevel(company);
            // 未在业务流程中
            boolean isNotInBusiness = !ValidationUtil.isEmpty(params.get("isNotInBusiness")) && params.get("isNotInBusiness").equals("true");
            // 查询在业务流程中sql
            String inBusinessSQL = "SELECT 1 FROM tzs_jg_change_registration_reform A WHERE\n" +
                    "  idx_biz_jg_project_contraption.sequence_nbr = A.\"project_contraption_id\" \n" +
                    "  AND A.\"is_delete\" = 0 \n" +
                    "  AND A.audit_status <> '使用单位待提交' \n" +
                    "  AND A.audit_status <> '一级受理已驳回' \n" +
                    "  AND A.audit_status <> '使用单位已撤回' \n" +
                    "  AND A.audit_status <> '已完成' \n" +
                    "  AND A.audit_status <> '已作废' UNION ALL\n" +
                    "SELECT 1 FROM tzs_jg_installation_notice A \n" +
                    "WHERE\n" +
                    "  idx_biz_jg_project_contraption.sequence_nbr = A.\"project_contraption_id\" \n" +
                    "  AND A.\"is_delete\" = 0 \n" +
                    "  AND A.notice_status <> '6614' \n" +
                    "  AND A.notice_status <> '6615' \n" +
                    "  AND A.notice_status <> '6610' \n" +
                    "  AND A.notice_status <> '6616' \n" +
                    "  AND A.notice_status <> '6617' UNION ALL\n" +
                    "SELECT 1 FROM tzs_jg_reform_notice A \n" +
                    "WHERE\n" +
                    "  idx_biz_jg_project_contraption.sequence_nbr = A.\"project_contraption_id\" \n" +
                    "  AND A.\"is_delete\" = 0 \n" +
                    "  AND A.notice_status <> '6614' \n" +
                    "  AND A.notice_status <> '6615' \n" +
                    "  AND A.notice_status <> '6610' \n" +
                    "  AND A.notice_status <> '6616' \n" +
                    "  AND A.notice_status <> '6617' UNION ALL\n" +
                    "SELECT 1 FROM  tzs_jg_use_registration A \n" +
                    "WHERE\n" +
                    "  idx_biz_jg_project_contraption.sequence_nbr = A.\"project_contraption_id\" \n" +
                    "  AND A.\"is_delete\" = 0 \n" +
                    "  AND A.status <> '使用单位待提交' \n" +
                    "  AND A.status <> '一级受理已驳回' \n" +
                    "  AND A.status <> '使用单位已撤回' \n" +
                    "  AND A.status <> '已完成' \n" +
                    "  AND A.status <> '已作废'";
            //获取省
            String province = params.get("province");
            if(!StringUtils.isEmpty(province) && province.contains("_")){
                province= province.split("_")[0];
            }
            //获取市
            String city = params.get("city");
            if(!StringUtils.isEmpty(city) && city.contains("_")){
                city= city.split("_")[0];
            }
            //获取区
            String county = params.get("county");
            if(!StringUtils.isEmpty(county) && county.contains("_")){
                county= county.split("_")[0];
            }
            //获取街道
            String street = params.get("street");
            if(!StringUtils.isEmpty(street) && street.contains("_")){
                street= street.split("_")[0];
            }
            String useUnitCreditCode = params.get(USE_UNIT_CREDIT_CODE);
            if(!StringUtils.isEmpty(useUnitCreditCode) && useUnitCreditCode.contains("_")){
                useUnitCreditCode= useUnitCreditCode.split("_")[0];
            }
            String useUnitName = params.get(USE_UNIT_NAME);
            LambdaQueryChainWrapper<IdxBizJgProjectContraption> queryWrapper = lambdaQuery()
                    // 企业按照公司类型进行过滤
                    .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                    .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                    .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                    // 监管机构按照属地监管部门orgCode进行过滤【最大数据集合】
                    .likeRight(ValidationUtil.isEmpty(useRegDetail) && BaseController.COMPANY_TYPE_SUPERVISION.equals(companyLevel), IdxBizJgProjectContraption::getOrgCode, company.getOrgCode())
                    .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                    .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                    .eq(!ValidationUtil.isEmpty(equCategory), IdxBizJgProjectContraption::getEquCategory, equCategory)
                    .eq(!ValidationUtil.isEmpty(equDefine), IdxBizJgProjectContraption::getEquDefine, equDefine)
                    .eq(!ValidationUtil.isEmpty(province), IdxBizJgProjectContraption::getProvince, province)
                    .eq(!ValidationUtil.isEmpty(city), IdxBizJgProjectContraption::getCity, city)
                    .eq(!ValidationUtil.isEmpty(county), IdxBizJgProjectContraption::getCounty, county)
                    .eq(!ValidationUtil.isEmpty(street), IdxBizJgProjectContraption::getStreet, street)
                    .eq(!ValidationUtil.isEmpty(dataQualityScore), IdxBizJgProjectContraption::getDataQualityScore, dataQualityScore)
                    .in(!ValidationUtil.isEmpty(dataQuality), IdxBizJgProjectContraption::getDataQualityScore, JSON.parseArray(dataQuality, String.class))
                    .eq(!ValidationUtil.isEmpty(useUnitCreditCode), IdxBizJgProjectContraption::getUseUnitCreditCode, useUnitCreditCode)
                    .like(!ValidationUtil.isEmpty(useUnitName), IdxBizJgProjectContraption::getUseUnitName, useUnitName)
                    .like(!ValidationUtil.isEmpty(projectContraption), IdxBizJgProjectContraption::getProjectContraption, projectContraption)
                    .eq(!ValidationUtil.isEmpty(orgBranchCode) && BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel), IdxBizJgProjectContraption::getOrgCode, orgBranchCode)            // 企业 等于匹配
                    .likeRight(!ValidationUtil.isEmpty(orgBranchCode) && BaseController.COMPANY_TYPE_SUPERVISION.equals(companyLevel), IdxBizJgProjectContraption::getOrgCode, orgBranchCode) // 监管 右模糊匹配
                    .like(!ValidationUtil.isEmpty(projectContraptionNo), IdxBizJgProjectContraption::getProjectContraptionNo, projectContraptionNo)
                    .and(!ValidationUtil.isEmpty(dataSource), w -> {
                        if ("jg".equals(dataSource)) {
                            w.likeRight(IdxBizJgProjectContraption::getDataSource, "jg").notLike(IdxBizJgProjectContraption::getDataSource, "jg_his");
                        } else if ("jg_his".equals(dataSource)) {
                            w.likeRight(IdxBizJgProjectContraption::getDataSource, "jg_his").notLike(IdxBizJgProjectContraption::getDataSource, "jg_his_black");
                        } else if ("jg_his_black".equals(dataSource)) {
                            w.eq(IdxBizJgProjectContraption::getDataSource, "jg_his_black").or().likeRight(IdxBizJgProjectContraption::getDataSource, "jg_his_black_");
                        } else {
                            w.eq(IdxBizJgProjectContraption::getDataSource, dataSource);
                        }
                    })
                    .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                    .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                    .isNull(IdxBizJgProjectContraption::getProjectContraptionParentId)
                    .notExists(isNotInBusiness, inBusinessSQL);

            if (sortVo != null && "ASC".equalsIgnoreCase(sortVo.getSortType())) {
                queryWrapper.orderByAsc(resolveField(sortVo.getField()));
            } else if (sortVo != null && "DESC".equalsIgnoreCase(sortVo.getSortType())) {
                queryWrapper.orderByDesc(resolveField(sortVo.getField()));
            } else {
                queryWrapper.orderByDesc(IdxBizJgProjectContraption::getRecDate);
            }

            IPage<IdxBizJgProjectContraption> pageList = queryWrapper.page(page);
            // 单位类型区分的企业还是监管
            String companyType2 = CommonServiceImpl.getCompanyType(company);

            if (!ValidationUtil.isEmpty(pageList.getRecords())) {
                Map<String, Boolean> projectContraptionUseMap = getPidUseMap(pageList);
                pageList.getRecords().forEach(record -> {
                    BigDecimal pipelineLength = BigDecimal.valueOf(record.getPipelineLength());
                    BigDecimal roundedValue = pipelineLength.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal strippedValue = roundedValue.stripTrailingZeros();
                    record.setPipelineLength(Double.valueOf(strippedValue.toPlainString()));
                    record.setDataSourceName(EquipSourceEnum.getDataSourceName(record.getDataSource()));
                    record.setDataQualityScore(commonService.castDataQualityScore2Name(record.getDataQualityScore(), record.getIsIntoManagement()));
                    record.setFullAddress(
                            Stream.of(record.getProvinceName(), record.getCityName(), record.getCountyName(), record.getStreetName(), record.getAddress())
                                    .map(value -> value == null || "null".equals(value) ? "" : value)
                                    .collect(Collectors.joining())
                    );
                    record.setCompanyType(companyType2);

                    // 来源类型：前端控制编辑按钮显示隐藏
                    record.setRegType(CommonServiceImpl.genRegTypeByDataSource(record.getDataSource()));
                    record.setIsIntoManagementName(IsIntoManagementEnum.getName(record.getIsIntoManagement()));
                    // 设置是否发生过后续业务：：前端控制编辑按钮显示隐藏
                    record.setHappenAfterBiz(projectContraptionUseMap.getOrDefault(record.getSequenceNbr() + "", false));
                });

                List<Long> projectContraptionIdList = pageList.getRecords().stream().map(IdxBizJgProjectContraption::getSequenceNbr).collect(Collectors.toList());
                Map<String, Boolean> canEditMap = this.checkContraptionIsCanEdit(projectContraptionIdList);
                pageList.getRecords().forEach(record -> record.setCanEdit(canEditMap.get(record.getSequenceNbr()+"")));
                // todo 删除按钮放开 全部显示 删除时进行校验
                // Map<String, Boolean> canDeleteMap = this.checkContraptionIsCanDelete(projectContraptionIdList, isIntoManagement);
                // pageList.getRecords().forEach(record -> record.setCanDelete(canDeleteMap.get(record.getSequenceNbr()+"")));
                //判断是否有检验结果录入
                judgeCheckResult(pageList.getRecords());
                List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord,IdxBizJgUseInfo::getPhone)
                        .in(IdxBizJgUseInfo::getProjectContraptionId, projectContraptionIdList).list();
                useInfos.forEach(info -> System.out.println("record=" + info.getRecord() + ", phone=" + info.getPhone()));
            }
            return pageList;
        } catch (Exception ex) {
            String msg = ex.getMessage() == null ? "" : ex.getMessage();
            if (msg.contains("eyibc decrypt error")
                    || msg.contains("EYIBCException")
                    || msg.contains("olym jdbc error")
                    || msg.contains("数据非法")
                    || msg.contains("Code: 100023:sql parse error")
                    || msg.contains("decrypt error, code: -65")) {
                throw new BadRequest("数据完整性被破坏（解密失败），请联系管理员。");
            }
            throw new BadRequest("系统内部错误，请联系管理员。");
        }
    }

    /**
     * 按照装置id查询 是否做过后续业务
     * @param pageList 装置集合
     * @return key-装置id;value-true（发生后续业务）、false（未发生后续业务）
     */
    private Map<String, Boolean> getPidUseMap(IPage<IdxBizJgProjectContraption> pageList) {
        List<CountDto> useCount =  commonMapper.countBizNumAfterUseRegBatchProjectContraption(pageList.getRecords().stream().map(BaseEntity::getSequenceNbr).collect(Collectors.toList()));
        return useCount.stream().collect(Collectors.toMap(CountDto::getKeyStr, e->e.getLongValue() > 0));
    }


    private SFunction<IdxBizJgProjectContraption, ?> resolveField(String field) {
        switch (field) {
            default:
                return IdxBizJgProjectContraption::getRecDate;  // 默认字段
        }
    }

    /**
     * 此处判断是否有检验结果 所有的管道信息都需要有检验结果才可以展示
     * @param records
     */
    private void judgeCheckResult(List<IdxBizJgProjectContraption> records) {
        List<IdxBizJgProjectContraption> pipelineList = records.stream().filter(record -> PipelineEnum.PRESSURE_PIPELINE.getCode().equals(record.getEquList())).collect(Collectors.toList());
        if (!ValidationUtil.isEmpty(pipelineList)) {
            StopWatch watch1 = new StopWatch();
            List<Long> projectContraptionIdList = pipelineList.stream().map(IdxBizJgProjectContraption::getSequenceNbr).collect(Collectors.toList());
            watch1.start();
            List<Map<String, Integer>> notNullCountList = this.baseMapper.selectCheckCountByNotNull(projectContraptionIdList);
            watch1.stop();
            System.out.println("watch1:" + watch1.getTotalTimeMillis());
            StopWatch watch2 = new StopWatch();
            watch2.start();
            List<Map<String, Integer>> totalList = this.baseMapper.selectEquipCount(projectContraptionIdList);
            watch2.stop();
            System.out.println("watch2:" + watch2.getTotalTimeMillis());
            for (IdxBizJgProjectContraption record : pipelineList) {
                Map<String, Integer> totalMap = totalList.stream().filter(item -> String.valueOf(record.getSequenceNbr()).equals(item.get("project_contraption_id"))).findFirst().orElse(new HashMap<>());
                Map<String, Integer> notNullCountMap = notNullCountList.stream().filter(item -> String.valueOf(record.getSequenceNbr()).equals(item.get("project_contraption_id"))).findFirst().orElse(new HashMap<>());
                Integer total = totalMap.get("count");
                Integer notNullCount = notNullCountMap.get("count");
                if(total != null && total.equals(notNullCount) && total != 0){
                    record.setDisableBasicButton(false);
                }
            }
        }
    }

    private Map<String, Boolean> checkContraptionIsCanEdit(List<Long> projectContraptionIdList) {
        Map<String, Boolean> resultMap = new HashMap<>();
        if (ValidationUtil.isEmpty(projectContraptionIdList)) {
            return resultMap;
        }

        List<Map<String, Integer>> inUseTimeMap = this.baseMapper.countContraptionInUseTimesForEdit(projectContraptionIdList);

        return getCheckResultMap(projectContraptionIdList, resultMap, inUseTimeMap);
    }


    private Map<String, Boolean> checkContraptionIsCanDelete(List<Long> projectContraptionIdList, Boolean isIntoManagement) {
        Map<String, Boolean> resultMap = new HashMap<>();
        if (ValidationUtil.isEmpty(projectContraptionIdList)) {
            return resultMap;
        }
        List<Map<String, Integer>> inUseTimeMap;
        if(isIntoManagement) {
            inUseTimeMap = this.baseMapper.countContraptionInUseTimesForDeleteByIntoManagementBatch(projectContraptionIdList);
        } else {
            inUseTimeMap = this.baseMapper.countContraptionInUseTimesForDelete(projectContraptionIdList);
        }
        return getCheckResultMap(projectContraptionIdList, resultMap, inUseTimeMap);
    }

    private Map<String, Boolean> getCheckResultMap(List<Long> projectContraptionIdList,Map<String, Boolean> resultMap,List<Map<String, Integer>> inUseTimeMap) {
        for (Long projectContraptionId : projectContraptionIdList) {
            Optional<Integer> inUseCountOpt = inUseTimeMap.stream()
                    .filter(map -> String.valueOf(projectContraptionId)
                            .equals(String.valueOf(map.get("project_contraption_id"))))
                    .map(map -> map.get("inUseNumber"))
                    .findFirst();
            Integer inUseCount = inUseCountOpt.orElse(0);
            resultMap.put(String.valueOf(projectContraptionId), inUseCount <= 0);
        }
        return resultMap;
    }

    @Override
    public List<IdxBizJgProjectContraption> proConListByParams(Map<String, String> params, ReginParams reginParams) {
        CompanyBo company = reginParams.getCompany();
        String companyType = company.getCompanyType();
        String companyCode = company.getCompanyCode();
        // 是否是否纳管：true - 已纳管 false-未纳管
        boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
        // 使用登记编号
        String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
        // 使用登记编号是否为空 true/false
        String regCodeIsNull = params.get(REG_CODE_IS_NULL);

        return lambdaQuery()
                .eq(CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .list();
    }

    /**
     * 分页查询
     */
    public Page<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionPage(Page<IdxBizJgProjectContraption> page) {
        IPage<IdxBizJgProjectContraption> tempPage = this.page(page, null);
        Page<IdxBizJgProjectContraptionDto> res = new Page<>(page.getCurrent(),page.getSize());
        res.setRecords(tempPage.getRecords().stream().map(p->{
            IdxBizJgProjectContraptionDto dto = new IdxBizJgProjectContraptionDto();
            BeanUtil.copyProperties(p, dto);
            return dto;
        }).collect(Collectors.toList()));
        res.setTotal(tempPage.getTotal());
        return res;
    }

    /**
     * 列表查询 示例
     */
    public List<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionList() {
        return this.list().stream().map(p->{
            IdxBizJgProjectContraptionDto dto = new IdxBizJgProjectContraptionDto();
            BeanUtil.copyProperties(p, dto);
            return dto;
        }).collect(Collectors.toList());
    }

    public Map<String, Map<String, Object>> details(String sequenceNbr) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())) + "", ReginParams.class);
        CompanyBo company = reginParams.getCompany();
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(sequenceNbr)) {
            resultMap.put(EQUIP_INFO_FORM_ID, Collections.emptyMap());
            return resultMap;
        }
        var baseMapper = this.getBaseMapper();
        Map<String, Object> projectContraptionMap = Optional.ofNullable(baseMapper.getDetail(sequenceNbr))
                .map(map -> {
                    commonService.convertStringToJsonobject(map, jsonFields);
                    map.put("unitType", company.getCompanyType());
                    map.put("pipelineList", this.getPipelineList(sequenceNbr));
                    return map;
                })
                .orElse(Collections.emptyMap());

        resultMap.put(EQUIP_INFO_FORM_ID, projectContraptionMap);
        return resultMap;
    }

    public Map<String, Object> detailsForReformNotice(String sequenceNbr) {
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())) + "", ReginParams.class);
        CompanyBo company = reginParams.getCompany();
        Map<String, Object> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(sequenceNbr)) {
            return resultMap;
        }
        var baseMapper = this.getBaseMapper();
        return Optional.ofNullable(baseMapper.getDetail(sequenceNbr))
                .map(map -> {
                    commonService.convertStringToJsonobject(map, jsonFields);
                    map.put("unitType", company.getCompanyType());
                    map.put("pipelineList", this.getPipelineListWithBf(sequenceNbr));
                    return map;
                })
                .orElse(Collections.emptyMap());
    }

    /**
     * 查询非作废状态的管道
     * @param sequenceNbr 装置id
     * @return 非作废状态的管道列表
     */
    private List<Map<String, Object>> getPipelineListWithBf(String sequenceNbr) {
        List<Map<String, Object>> pipelineList = baseMapper.selectEquipListWithOutBf(sequenceNbr);
        pipelineList.forEach(p -> {
            try {
                p.put("equStateName",
                        Optional.ofNullable(p.get("equState"))
                                .map(Object::toString)
                                .filter(org.apache.commons.lang3.StringUtils::isNotEmpty)
                                .map(Integer::parseInt)
                                .map(EquipmentEnum.getName::get)
                                .orElse("待用")
                );
            } catch (NumberFormatException e) {
                p.put("equStateName", "待用");
            }
        });
        return pipelineList;
    }

    private List<Map<String, Object>> getPipelineList(String sequenceNbr) {
        List<Map<String, Object>> pipelineList = baseMapper.selectEquipList(sequenceNbr);
        pipelineList.forEach(p -> {
            try {
                p.put("equStateName",
                        Optional.ofNullable(p.get("equState"))
                                .map(Object::toString)
                                .filter(org.apache.commons.lang3.StringUtils::isNotEmpty)
                                .map(Integer::parseInt)
                                .map(EquipmentEnum.getName::get)
                                .orElse("待用")
                );
            } catch (NumberFormatException e) {
                p.put("equStateName", "待用");
            }
        });
        return pipelineList;
    }




    public Page<Map<String, Object>> techParamsPipelinePage(String sequenceNbr,int current, int size) {
        Page<Map<String, Object>> page=new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        page.setRecords(baseMapper.selectEquipListPage(sequenceNbr, (current - 1) * size, size));
        Map<String, Integer> totalMap = baseMapper.selectEquipCount(new ArrayList<>(Collections.singletonList(Long.parseLong(sequenceNbr)))).get(0);
        page.setTotal(totalMap.get("count"));
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateDetectionInfo(IdxBizJgInspectionDetectionInfo detectionInfo) {
        detectionInfo.setRecDate(new Date());
        detectionInfoService.saveOrUpdateData(detectionInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateDetectionInfoBatch(JSONObject jsonObject) {
        if(Objects.nonNull(jsonObject)){
            JSONArray items = jsonObject.getJSONArray("records");
            Set<String> records = new HashSet<>();
            if(CollectionUtil.isNotEmpty(items)){
                List<IdxBizJgInspectionDetectionInfo> jgInspectionDetectionInfos= new ArrayList<>();
                for (Object record : items) {
                    IdxBizJgInspectionDetectionInfo detectionInfo = JSON.parseObject(JSONObject.toJSONString(record), IdxBizJgInspectionDetectionInfo.class);
                    if(Objects.nonNull(detectionInfo)){
                        if (record instanceof LinkedHashMap){
                          Map map = (LinkedHashMap)record;
                          detectionInfo.setRecDate(new Date());
                          detectionInfo.setSequenceNbr((String) map.get("detectionInfoSequenceNbr"));
                          detectionInfo.setInspectConclusion((String)map.get("inspectConclusionCode"));
                          records.add(detectionInfo.getRecord());
                          jgInspectionDetectionInfos.add(detectionInfo);
                        }
                    }
                }
                if(CollUtil.isNotEmpty(jgInspectionDetectionInfos)){
                    detectionInfoService.saveOrUpdateBatch(jgInspectionDetectionInfos);
                }
                eventPublisher.publish(new DataRefreshEvent(this, new ArrayList<>(records), DataRefreshEvent.DataType.equipment.name(), DataRefreshEvent.Operation.UPDATE));
            }
        }

    }

    public IdxBizJgInspectionDetectionInfo getDetectionInfoDetail(String sequenceNbr) {
        return detectionInfoService.getById(sequenceNbr);
    }

    public void exportSummaryBasicInfo(String sequenceNbr, HttpServletResponse response, String category) {
        // 长输/公共管道/工业管道汇总
        if ("8200".equals(category) || "8100".equals(category) || "8300".equals(category)) {
            // 总数
            double total;
            // 每页显示条数，默认 10
            int size = 10;
            IdxBizJgProjectContraption idxBizJgProjectContraption = baseMapper.selectById(sequenceNbr);
            if (ValidationUtil.isEmpty(idxBizJgProjectContraption)) {
                throw new BadRequest("没有查询到汇总信息！");
            }
            JSONObject tagJson = Optional.ofNullable(idxBizJgProjectContraption.getCertificatePrintTag())
                    .map(JSONObject::parseObject)
                    .orElse(new JSONObject());
            tagJson.put(EXPORT_SUMMARY_TABLE, 2);
            idxBizJgProjectContraption.setCertificatePrintTag(JSONObject.toJSONString(tagJson));
            List<Map<String, Object>> allEquipment = baseMapper.selectEquipListByExport(sequenceNbr);
            total = allEquipment.size();
            AgencyUserModel result = new AgencyUserModel();
            if (!ValidationUtil.isEmpty(idxBizJgProjectContraption.getRecUserId())) {
                result = Privilege.agencyUserClient.queryByUserId(idxBizJgProjectContraption.getRecUserId()).getResult();
            }
            // 模板
            String wordPath = "PressurePipeBasicInformationSummary.ftl";
            // 文件名前缀
            String filePrefix = "压力管道基本信息汇总表_";
            // 压力包名称
            String customFileName = filePrefix + idxBizJgProjectContraption.getProjectContraptionNo() + ".zip";
            // 总页数
            int page = (int) Math.ceil(total / size);
            // 异步获取数据
            List<CompletableFuture<byte[]>> futures = pressurePipeDataPreparation(page, idxBizJgProjectContraption, size, total, allEquipment, wordPath, filePrefix, result,category);
            // byte[]压缩zip
            toZipFile(response, futures, filePrefix, customFileName);
            baseMapper.updateById(idxBizJgProjectContraption);
        }
    }

    /**
     * 压力管道数据
     *
     * @return
     */
    public List<CompletableFuture<byte[]>> pressurePipeDataPreparation(int page,  IdxBizJgProjectContraption idxBizJgProjectContraption, int size, double total,  List<Map<String, Object>> equipmentLists, String wordPath, String filePrefix, AgencyUserModel result,String category) {
        Map<String, Object> exportParamsMap = new HashMap<>();
        exportParamsMap.put("page", page);
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = currentDate.format(formatter);
        exportParamsMap.put("printDate", formattedDate);
        //获取分类名称
        exportParamsMap.put("categoryName", PipelineEnum.getMessage(category));
        // 使用单位
        exportParamsMap.put("useUnitName", idxBizJgProjectContraption.getUseUnitName());
        // 使用单位地址
        String useUnitCreditCode = String.valueOf(idxBizJgProjectContraption.getUseUnitCreditCode());
        TzBaseEnterpriseInfo enterpriseInfo = tzBaseEnterpriseInfoMapper.selectOne(new LambdaQueryWrapper<TzBaseEnterpriseInfo>().eq(TzBaseEnterpriseInfo::getUseCode, useUnitCreditCode));
        exportParamsMap.put("fullAddress", enterpriseInfo.getAddress());
        exportParamsMap.put("nameOfProjectDevice", idxBizJgProjectContraption.getProjectContraption());
        // 安全管理部门
        exportParamsMap.put("orgBranchName", "");
        // 安全管理员
        exportParamsMap.put("safetyManager", "");
        // 联系电话
        exportParamsMap.put("phone", ValidationUtil.isEmpty(result.getMobile()) ? "" : result.getMobile());
        // 经办人
        exportParamsMap.put("agent", ValidationUtil.isEmpty(result.getRealName()) ? "" : result.getRealName());
        // 电子邮箱
        exportParamsMap.put("email", ValidationUtil.isEmpty(result.getEmail()) ? "" : result.getEmail());

        List<CompletableFuture<byte[]>> futures = IntStream.rangeClosed(1, page)
                .mapToObj(current -> CompletableFuture.supplyAsync(() -> {
                    // 创建独立的参数副本
                    Map<String, Object> currentExportParamsMap = new HashMap<>(exportParamsMap);
                    currentExportParamsMap.put("current", current);
                    // 数据分页
                    int start = (current - 1) * size;
                    int end = ((current - 1) * size + size) < total ? (current - 1) * size + size : (int) total;
                    // 数据截取
                    List<Map<String, Object>> equData = equipmentLists.subList(start, end);
                    // 设备数据填充
                    this.pressurePipeEquData(currentExportParamsMap, equData, current, size);
                    return commonService.generateSummaryOfCylinderInfo(currentExportParamsMap, wordPath, filePrefix);
                })).collect(Collectors.toList());
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[page])).join();
        return futures;
    }

    /**
     * 压力管道设备数据填充
     */
    public void pressurePipeEquData(Map<String, Object> exportParamsMap, List<Map<String, Object>> equData, int current, int size) {

        String[] fieldNames = {"productName", "pipelineNumber", "deviceLevel", "designUnitName", "uscUnitName",
                "uscDate", "useDate", "nominalDiameter", "wallThickness", "pipeLengthText", "pressure", "temperature",
                "medium", "inspectConclusion", "inspectOrgName", "nextInspectDate", "remarks"};
        // 填充有效数据
        for (int curr = 0; curr < equData.size(); curr++) {
            Map<String, Object> map = equData.get(curr);

            int serialNum = curr + 1;
            for (String fieldName : fieldNames) {
                exportParamsMap.put("num" + serialNum, (current - 1) * size + (curr + 1));
                exportParamsMap.put(fieldName + serialNum, setSpecialParamFields(fieldName, map));
            }
        }

        // 填充剩余空白项至指定总页数
        for (int curr = equData.size(); curr < size; curr++) {
            int serialNum = curr + 1;
            for (String fieldName : fieldNames) {
                exportParamsMap.put("num" + serialNum, "");
                exportParamsMap.put(fieldName + serialNum, ""); // 使用空字符串填充空白项
            }
        }
    }

    private Object trimIfEmpty(Object obj) {
        return ValidationUtil.isEmpty(obj) ? "" : obj;
    }

    private Object setSpecialParamFields(String fieldName, Map<String, Object> equip){
        switch (fieldName) {
            case "pressure":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workPressure"));
            case "temperature":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workTemperature"));
            case "medium":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workMedium"));
            default:
                return ValidationUtil.isEmpty(equip.get(fieldName)) ? "" : equip.get(fieldName);
        }
    }

    public static void toZipFile(HttpServletResponse response, List<CompletableFuture<byte[]>> futures, String filePrefix, String customFileName) {
        // 打包zip
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
             ZipOutputStream zip = new ZipOutputStream(outputStream)) {

            for (int i = 0; i < futures.size(); i++) {
                try {
                    zip.putNextEntry(new ZipEntry(filePrefix + "第" + (i + 1) + "页" + ".pdf"));
                    IOUtils.write(futures.get(i).join(), zip);
                    zip.closeEntry(); // 每个条目结束后关闭
                } catch (IOException e) {
                    log.error("打包zip失败：" + e.getMessage());
                    throw new BadRequest("打包zip失败");
                }
            }
            // 所有条目写入完成后关闭 ZipOutputStream
            zip.finish();
            // 设置响应头并将压缩文件写入 HttpServletResponse
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/zip");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(customFileName, "UTF-8"));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("导出异常：", e);
        }
    }

    public IdxBizJgProjectContraption saveFirstMergeProjectContraption(IdxBizJgProjectContraptionDto model) {
        // 单位类型
        Map<String, Object> companyInfoMap = jgInstallationNoticeService.getCompanyType();
        this.checkTheUnitProConMatching(EquipRequestParamsDto.builder()
                .projectContraptionNo(model.getProjectContraptionNo())
                .projectContraption(model.getProjectContraption())
                .companyCode(MapUtil.getStr(companyInfoMap,"creditCode"))
                .build());
        IdxBizJgProjectContraption projectContraption = JSON.parseObject(toJSONString(model), IdxBizJgProjectContraption.class);
        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquListCode());
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquCategoryCode());
        String equDefineName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquDefineCode());
        projectContraption.setDataSource("jg");
        projectContraption.setIsIntoManagement(false);
        projectContraption.setProvinceName("陕西省");
        projectContraption.setEquList(model.getEquListCode());
        projectContraption.setEquCategory(model.getEquCategoryCode());
        projectContraption.setEquDefine(model.getEquDefineCode());
        projectContraption.setEquListName(equListName);
        projectContraption.setEquCategoryName(equCategoryName);
        projectContraption.setEquDefineName(equDefineName);
        projectContraption.setPipelineLength(0.0);
        projectContraption.setUseUnitName(MapUtil.getStr(companyInfoMap,"companyName"));
        projectContraption.setUseUnitCreditCode(MapUtil.getStr(companyInfoMap,"creditCode"));
        this.saveOrUpdateData(projectContraption);
        return projectContraption;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByHisGdPl(Long sequenceNbr) {
        IdxBizJgProjectContraption idxBizJgProjectContraption = baseMapper.selectById(sequenceNbr);
        if(Objects.nonNull(idxBizJgProjectContraption)){
            String dataSource = idxBizJgProjectContraption.getDataSource();
            if(!"jg_his_gd_pl".equals(dataSource)){
                throw new BadRequest("数据源不是导入类型禁止删除");
            }
            // 删除管道对应的idx表数据
            this.deletePipInfoToIdxTables(idxBizJgProjectContraption);

            // 删除工程装置表信息
            removeById(idxBizJgProjectContraption.getSequenceNbr());

        }
        return Boolean.TRUE;
    }


    private void deletePipInfoToIdxTables(IdxBizJgProjectContraption idxBizJgProjectContraption) {
        Long jgProjectContraptionSequenceNbr = idxBizJgProjectContraption.getSequenceNbr();
        LambdaQueryWrapper<IdxBizJgUseInfo> jgUseInfoWrapper = new LambdaQueryWrapper<>();
        jgUseInfoWrapper.eq(IdxBizJgUseInfo::getProjectContraptionId,jgProjectContraptionSequenceNbr);
        List<IdxBizJgUseInfo> useInfos = idxBizJgUseInfoService.list(jgUseInfoWrapper);
        //获取records
        List<String> records = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(useInfos)){
            for (IdxBizJgUseInfo useInfo : useInfos) {
                records.add(useInfo.getRecord());
            }
        }

        if(CollectionUtil.isNotEmpty(records)){
            // 删除检验检测信息
            LambdaQueryWrapper<IdxBizJgInspectionDetectionInfo> inspectionDetectionInfoWrapper = new LambdaQueryWrapper<>();
            inspectionDetectionInfoWrapper.in(IdxBizJgInspectionDetectionInfo::getRecord,records);
            idxBizJgInspectionDetectionInfoService.remove(inspectionDetectionInfoWrapper);
            // 删除设计信息
            LambdaQueryWrapper<IdxBizJgDesignInfo> designInfoWrapper = new LambdaQueryWrapper<>();
            designInfoWrapper.in(IdxBizJgDesignInfo::getRecord,records);
            idxBizJgDesignInfoService.remove(designInfoWrapper);
            // 删除制造信息
            LambdaQueryWrapper<IdxBizJgFactoryInfo> factoryInfoWrapper = new LambdaQueryWrapper<>();
            factoryInfoWrapper.in(IdxBizJgFactoryInfo::getRecord,records);
            idxBizJgFactoryInfoService.remove(factoryInfoWrapper);
            // 删除施工信息
            LambdaQueryWrapper<IdxBizJgConstructionInfo> constructionInfoWrapper = new LambdaQueryWrapper<>();
            constructionInfoWrapper.in(IdxBizJgConstructionInfo::getRecord,records);
            idxBizJgConstructionInfoService.remove(constructionInfoWrapper);
            // 删除注册登记信息
            LambdaQueryWrapper<IdxBizJgRegisterInfo> registerInfoWrapper = new LambdaQueryWrapper<>();
            registerInfoWrapper.in(IdxBizJgRegisterInfo::getRecord,records);
            idxBizJgRegisterInfoService.remove(registerInfoWrapper);
            // 删除监督管理
            LambdaQueryWrapper<IdxBizJgSupervisionInfo> supervisionInfoWrapper = new LambdaQueryWrapper<>();
            supervisionInfoWrapper.in(IdxBizJgSupervisionInfo::getRecord,records);
            idxBizJgSupervisionInfoService.remove(supervisionInfoWrapper);
            // 删除其他信息
            LambdaQueryWrapper<IdxBizJgOtherInfo> otherInfoWrapper = new LambdaQueryWrapper<>();
            otherInfoWrapper.in(IdxBizJgOtherInfo::getRecord,records);
            idxBizJgOtherInfoService.remove(otherInfoWrapper);
            // 删除管道技术参数
            LambdaQueryWrapper<IdxBizJgTechParamsPipeline> techParamsPipelineWrapper = new LambdaQueryWrapper<>();
            techParamsPipelineWrapper.in(IdxBizJgTechParamsPipeline::getRecord,records);
            idxBizJgTechParamsPipelineService.remove(techParamsPipelineWrapper);
            //删除es数据
            for (String record : records) {
                esEquipmentCategory.deleteById(record);
            }
            // 删除使用信息
            idxBizJgUseInfoService.remove(jgUseInfoWrapper);

        }
    }

    public Map<String, Object> getNewInspectionDetailByRecord(String record) {
        IdxBizJgInspectionDetectionInfo info = detectionInfoService.queryNewestDetailByRecord(record);
        if (info == null) return Collections.emptyMap();
        Map<String, Object> result = new HashMap<>(Bean.BeantoMap(info));
        result.put("inspectReport", JSON.parseArray(info.getInspectReport()));
        result.put("inspectConclusionCode", info.getInspectConclusion());
        result.put("inspectConclusion", Optional.ofNullable(dataDictionaryServiceImpl.getByCode(info.getInspectConclusion(), "JYJL"))
                .map(DataDictionary::getName).orElse(""));
        result.put("jySeq", info.getSequenceNbr());
        return result;
    }

    public Page<Map<String, Object>> getPipelinePageByProjectContraptionSeq(String sequenceNbr, int current, int size) {

        Page<Map<String, Object>> page=new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        page.setRecords(baseMapper.selectPipelineListPage(sequenceNbr, (current - 1) * size, size));
        Map<String, Integer> totalMap = baseMapper.selectEquipCount(new ArrayList<>(Collections.singletonList(Long.parseLong(sequenceNbr)))).get(0);
        page.setTotal(totalMap.get("count"));
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProjectAndEquInfoBatch(List<String> ids) {
        // 检验
        this.checkForDelete(ids);
        List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord).in(IdxBizJgUseInfo::getProjectContraptionId, ids).list();
        // 删除idx设备表信息 + 删除对应es数据
        List<String> records = useInfos.stream().map(IdxBizJgUseInfo::getRecord).collect(Collectors.toList());
        if (!records.isEmpty()){
            Map<String, Object> map = new HashMap<>();
            map.put("recordList", records);
            map.put("equList", PipelineEnum.PRESSURE_PIPELINE.getCode());
            registerInfoService.batchDeleteByRecord(map);
        }
        // 删除装置表信息
        this.removeByIds(ids);
        return Boolean.TRUE;
    }



    /**
     * 删除校验，被引用时不可删除
     *
     * @param pIds 装置ids
     */
    private void checkForDelete(List<String> pIds) {
        List<CountDto> useCounts = this.getBaseMapper().countContraptionInUseTimesForDeleteBatch(pIds);
        Map<String, Long> projectContraptionIdUseNumMap = useCounts.stream().collect(Collectors.toMap(CountDto::getKeyStr, CountDto::getLongValue));
        long sum = projectContraptionIdUseNumMap.values().stream().reduce(0L,Long::sum);
        if(sum > 0){
            String msg = getTipMsgString(projectContraptionIdUseNumMap, pIds);
            throw new BadRequest(msg);
        }
    }

    private String getTipMsgString(Map<String, Long> projectContraptionIdUseNumMap, List<String> pIds) {
        List<String> projectContraptionNames = new ArrayList<>();
        List<String> projectContraptionIdInUsed =  projectContraptionIdUseNumMap.entrySet().stream().filter(e->e.getValue()>0).map(Map.Entry::getKey).collect(Collectors.toList());
        Map<String, String> projectContraptionIdNameMap = this.list(new LambdaQueryWrapper<IdxBizJgProjectContraption>()
                        .in(BaseEntity::getSequenceNbr, projectContraptionIdInUsed)
                .select(BaseEntity::getSequenceNbr, IdxBizJgProjectContraption::getProjectContraption))
                .stream().collect(Collectors.toMap(p->String.valueOf(p.getSequenceNbr()), IdxBizJgProjectContraption::getProjectContraption));
        for (String projectContraptionId : projectContraptionIdInUsed) {
            projectContraptionNames.add(projectContraptionIdNameMap.get(projectContraptionId));
        }
        if (pIds.size() > 1) {
            return String.format("选择的装置：%s，已经在业务办理中，不能删除，请先取消勾选！", String.join("、", projectContraptionNames));
        } else {
            return "装置已经在业务办理中，不能删除！";
        }
    }
}