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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.enums.TcmUnitTypeEnum;
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.module.common.api.dto.FormValue;
import com.yeejoin.amos.boot.module.common.api.enums.CylinderTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.dto.JgUseRegistrationManageDto;
import com.yeejoin.amos.boot.module.jg.api.dto.UseFlagParamDto;
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.CertificateStatusEnum;
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.mapper.*;
import com.yeejoin.amos.boot.module.jg.api.service.IJgUseRegistrationManageService;
import com.yeejoin.amos.boot.module.jg.api.vo.SortVo;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.biz.utils.CodeUtil;
import com.yeejoin.amos.boot.module.ymt.api.common.StringUtil;
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.EquipmentCategoryEnum;
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.IdxBizJgRegisterInfoMapper;
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 com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.search.ClearScrollRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
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.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.alibaba.fastjson.JSON.parseArray;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgProjectContraptionServiceImplService.toZipFile;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.JgUseRegistrationServiceImpl.getAuditPassedDate;
import static com.yeejoin.amos.boot.module.jg.biz.service.impl.JgUseRegistrationServiceImpl.getReissueDate;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2024-07-03
 */
@Service
public class JgUseRegistrationManageServiceImpl extends BaseService<JgUseRegistrationManageDto, JgUseRegistrationManage, JgUseRegistrationManageMapper> implements IJgUseRegistrationManageService {
    public static final String CERTIFICATE_NORMAL = "certificateNormalPrint";
    public static final String CERTIFICATE_NESTED = "certificateNestedPrint";
    public static final String USE_FLAG_NORMAL = "useFlagNormalPrint";
    public static final String USE_FLAG_NESTED = "useFlagNestedPrint";
    public static final String EXPORT_SUMMARY_TABLE = "exportSummaryTable";
    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    private JgUseRegistrationManageMapper jgUseRegistrationManageMapper;

    @Autowired
    private JgUseRegistrationMapper jgUseRegistrationMapper;

    @Autowired
    private JgUseRegistrationEqMapper jgUseRegistrationEqMapper;

    @Autowired
    private CommonServiceImpl commonServiceImpl;

    @Autowired
    private IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;

    @Autowired
    private JgVehicleInformationMapper jgVehicleInformationMapper;


    @Autowired
    private JgCertificateChangeRecordServiceImpl jgCertificateChangeRecordService;

    @Autowired
    private JgUseRegistrationServiceImpl jgUseRegistrationService;

    @Autowired
    private IdxBizJgProjectContraptionServiceImplService jgProjectContraptionService;

    @Autowired
    private IdxBizJgProjectContraptionMapper jgProjectContraptionMapper;
    @Autowired
    private IdxBizJgRegisterInfoMapper idxBizJgRegisterInfoMapper;

    @Autowired
    private CommonServiceImpl commonService;

    @Autowired
    private IdxBizJgMaintenanceRecordInfoServiceImpl idxBizJgMaintenanceRecordInfoService;

    @Value("classpath:/json/registrationBasic.json")
    private Resource registrationBasicJson;

    private static final Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();
    @Autowired
    CommonMapper commonMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;

    @Autowired
    private JgCertificateChangeRecordMapper certificateChangeRecordMapper;
    @Autowired
    private TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;

    @Autowired
    private CodeUtil codeUtil;

    private static final long SCROLL_TIMEOUT = 180000;
    private static final int SIZE = 1000;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 用户选择信心redis获取
     **/
    protected ReginParams getSelectedOrgInfo() {
        return JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
    }


    /**
     * 将已经通过使用登记审批的证信息录入到 jg-use-registration-manage 表中
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean brushHistoryCertificate(String type) {

        if (type.equals("1")){
            this.baseMapper.delete(new LambdaQueryWrapper<JgUseRegistrationManage>().eq(JgUseRegistrationManage::getRegType, BusinessTypeEnum.JG_USAGE_REGISTRATION.getName()));
            // 使用登记表中已经审批通过的单子
            List<JgUseRegistration> jgUseRegistrations = jgUseRegistrationMapper.selectList(new LambdaQueryWrapper<JgUseRegistration>()
                    .eq(JgUseRegistration::getStatus, "已完成")
                    .eq(JgUseRegistration::getIsDelete, false));
            for (JgUseRegistration useRegistration : jgUseRegistrations) {
                // 使用单位信息
                Map<String, Object> enterpriseInfo = commonServiceImpl.getEnterpriseInfo(useRegistration.getUseUnitCreditCode());
                // 设备使用地址
                String fullAddress = "";
                // 设备种类/类别/品种
                Map<String, String> equType = jgUseRegistrationMapper.getEquTypeByUseRegSeq(String.valueOf(useRegistration.getSequenceNbr()));
                if (!"unit".equals(useRegistration.getManageType())) {
                    List<JgUseRegistrationEq> jgUseRegistrationEqs = jgUseRegistrationEqMapper.selectList(new LambdaQueryWrapper<JgUseRegistrationEq>()
                            .eq(JgUseRegistrationEq::getEquipTransferId, useRegistration.getSequenceNbr()));
                    if (!ValidationUtil.isEmpty(jgUseRegistrationEqs)) {
                        String equId = jgUseRegistrationEqs.get(0).getEquId();
                        IdxBizJgUseInfo useInfo = idxBizJgUseInfoService.getOne(new QueryWrapper<IdxBizJgUseInfo>()
                                .eq("RECORD", equId));
                        if (!ObjectUtils.isEmpty(useInfo.getProvinceName())) {
                            fullAddress += useInfo.getProvinceName();
                        }
                        if (!ObjectUtils.isEmpty(useInfo.getCityName())) {
                            fullAddress += useInfo.getCityName();
                        }
                        if (!ObjectUtils.isEmpty(useInfo.getCountyName())) {
                            fullAddress += useInfo.getCountyName();
                        }
                        if (!ObjectUtils.isEmpty(useInfo.getStreetName())) {
                            fullAddress += useInfo.getStreetName();
                        }
                        if (!ObjectUtils.isEmpty(useInfo.getAddress())) {
                            fullAddress += useInfo.getAddress();
                        }
                    }
                }
                // 组装数据
                JgUseRegistrationManage jgUseRegistrationManage = new JgUseRegistrationManage();
                jgUseRegistrationManage.setUseUnitName(useRegistration.getUseUnitName());
                jgUseRegistrationManage.setApplyNo(useRegistration.getApplyNo());
                jgUseRegistrationManage.setCertificateStatus(CertificateStatusEnum.YIDENGJI.getName());
                jgUseRegistrationManage.setReceiveOrgName(useRegistration.getReceiveOrgName());
                jgUseRegistrationManage.setAuditPassDate(useRegistration.getAuditPassDate());
                jgUseRegistrationManage.setRegType(BusinessTypeEnum.JG_USAGE_REGISTRATION.getName());
                jgUseRegistrationManage.setRegDate(useRegistration.getRegDate());
                jgUseRegistrationManage.setEquList(equType.get("equList"));
                jgUseRegistrationManage.setEquListCode(equType.get("equListCode"));
                jgUseRegistrationManage.setEquCategory(equType.get("equCategory"));
                jgUseRegistrationManage.setEquCategoryCode(equType.get("equCategoryCode"));
                jgUseRegistrationManage.setEquDefine(equType.get("equDefine"));
                jgUseRegistrationManage.setEquDefineCode(equType.get("equDefineCode"));
                jgUseRegistrationManage.setIsDelete(Boolean.FALSE);
                jgUseRegistrationManage.setRecUserId(useRegistration.getRecUserId());
                jgUseRegistrationManage.setRecUserName(useRegistration.getRecUserName());
                jgUseRegistrationManage.setRecDate(useRegistration.getRecDate());
                jgUseRegistrationManage.setCreateUserId(useRegistration.getCreateUserId());
                jgUseRegistrationManage.setCreateDate(useRegistration.getRecDate());
                jgUseRegistrationManage.setEquUseAddress(fullAddress);
                jgUseRegistrationManage.setManageType(useRegistration.getManageType());
                jgUseRegistrationManage.setUseUnitAddress(!ValidationUtil.isEmpty(enterpriseInfo) ? (String) enterpriseInfo.get("address") : "");
                jgUseRegistrationManage.setUseRegistrationCode(useRegistration.getUseRegistrationCode());
                jgUseRegistrationManage.setRegistrationType("1".equals(useRegistration.getRegType()) ? "1" : "0");
                jgUseRegistrationManage.setUseUnitCreditCode(useRegistration.getUseUnitCreditCode());
                jgUseRegistrationManage.setReceiveCompanyCode(useRegistration.getReceiveCompanyCode());
                jgUseRegistrationManage.setCertificateNo(commonServiceImpl.generateCertificateNo(equType, useRegistration.getAuditPassDate(), useRegistration.getReceiveCompanyCode()));
                this.baseMapper.insert(jgUseRegistrationManage);
            }
        }
        if (type.equals("2")){
            this.baseMapper.delete(new LambdaQueryWrapper<JgUseRegistrationManage>().eq(JgUseRegistrationManage::getRegType, BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName()));
            // 车用气瓶使用登记表中已经审批通过的单子
            List<JgVehicleInformation> jgVehicleInformations = jgVehicleInformationMapper.selectList(new LambdaQueryWrapper<JgVehicleInformation>()
                    .eq(JgVehicleInformation::getStatus, "已完成")
                    .eq(JgVehicleInformation::getIsDelete, false));
            for (JgVehicleInformation vehicleInformation : jgVehicleInformations) {
                // 使用单位信息
                Map<String, Object> enterpriseInfo = commonServiceImpl.getEnterpriseInfo(vehicleInformation.getUseUnitCreditCode());
                // 设备种类/类别/品种
                Map<String, String> equType = jgUseRegistrationMapper.getEquTypeByVehSeq(String.valueOf(vehicleInformation.getSequenceNbr()));
                // 组装数据
                JgUseRegistrationManage jgUseRegistrationManage = new JgUseRegistrationManage();
                jgUseRegistrationManage.setUseUnitName(vehicleInformation.getUseUnitName());
                jgUseRegistrationManage.setApplyNo(vehicleInformation.getApplyNo());
                jgUseRegistrationManage.setCertificateStatus(CertificateStatusEnum.YIDENGJI.getName());
                jgUseRegistrationManage.setReceiveOrgName(vehicleInformation.getReceiveOrgName());
                jgUseRegistrationManage.setAuditPassDate(vehicleInformation.getAuditPassDate());
                jgUseRegistrationManage.setRegType(BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName());
                jgUseRegistrationManage.setRegDate(vehicleInformation.getRegDate());
                jgUseRegistrationManage.setEquList(equType.get("equList"));
                jgUseRegistrationManage.setEquListCode(equType.get("equListCode"));
                jgUseRegistrationManage.setEquCategory(equType.get("equCategory"));
                jgUseRegistrationManage.setEquCategoryCode(equType.get("equCategoryCode"));
                jgUseRegistrationManage.setEquDefine(equType.get("equDefine"));
                jgUseRegistrationManage.setEquDefineCode(equType.get("equDefineCode"));
                jgUseRegistrationManage.setIsDelete(Boolean.FALSE);
                jgUseRegistrationManage.setRecUserId(vehicleInformation.getRecUserId());
                jgUseRegistrationManage.setRecUserName(vehicleInformation.getRecUserName());
                jgUseRegistrationManage.setRecDate(vehicleInformation.getRecDate());
                jgUseRegistrationManage.setCreateUserId(vehicleInformation.getCreateUserId());
                jgUseRegistrationManage.setCreateDate(vehicleInformation.getRecDate());
                jgUseRegistrationManage.setEquUseAddress("");
                jgUseRegistrationManage.setManageType("unit");
                jgUseRegistrationManage.setCarNumber(vehicleInformation.getCarNumber());
                jgUseRegistrationManage.setUseUnitAddress(!ValidationUtil.isEmpty(enterpriseInfo) ? (String) enterpriseInfo.get("address") : "");
                jgUseRegistrationManage.setUseRegistrationCode(vehicleInformation.getUseRegistrationCode());
                jgUseRegistrationManage.setRegistrationType("1".equals(vehicleInformation.getRegType()) ? "1" : "0");
                jgUseRegistrationManage.setUseUnitCreditCode(vehicleInformation.getUseUnitCreditCode());
                jgUseRegistrationManage.setReceiveCompanyCode(vehicleInformation.getReceiveCompanyCode());
                jgUseRegistrationManage.setGasNum(vehicleInformation.getGasNum());
                jgUseRegistrationManage.setFillingMedium(vehicleInformation.getFillingMedium());
                jgUseRegistrationManage.setVolume(vehicleInformation.getVolume());
                jgUseRegistrationManage.setCertificateNo(commonServiceImpl.generateCertificateNo(equType, vehicleInformation.getAuditPassDate(), vehicleInformation.getReceiveCompanyCode()));
                this.baseMapper.insert(jgUseRegistrationManage);
            }
        }

        return Boolean.TRUE;
    }

    public Page<JgUseRegistrationManageDto> buildFilter(JgUseRegistrationManageDto dto, int current, int size) {
        Page<JgUseRegistrationManageDto> page = new Page<JgUseRegistrationManageDto>();
        page.setCurrent(current);
        page.setSize(size);
        ReginParams info = getSelectedOrgInfo();
        if (info.getCompany().getLevel().equals(BaseController.COMPANY_TYPE_COMPANY)) {
            dto.setDataType(BaseController.COMPANY_TYPE_COMPANY);
            dto.setUseUnitCreditCode(CompanyTypeEnum.INDIVIDUAL.getName().equals(info.getCompany().getCompanyType()) ?
                    info.getCompany().getCompanyCode().split("_")[1] : info.getCompany().getCompanyCode());
        } else {
            dto.setDataType(BaseController.COMPANY_TYPE_SUPERVISION);
            dto.setReceiveCompanyCode(info.getCompany().getCompanyCode());
        }
        dto.setIsDoBusiness(ValidationUtil.isEmpty(dto.getIsDoBusiness()) ? "1" : "");
        return page;
    }


    /**
     * 分页查询
     */
    public Page<JgUseRegistrationManageDto> queryForJgUseRegistrationManagePage(Page<JgUseRegistrationManageDto> page,
                                                                                JgUseRegistrationManageDto dto,
                                                                                String sort) {
        SortVo sortMap = commonServiceImpl.sortFieldConversion(sort);
        if (ApplicationFormTypeEnum.BF.getBusinessCode().equals(dto.getApplyType()) && (!CylinderTypeEnum.CYLINDER.getCode().equals(dto.getEquCategoryCode()) || dto.getRegType().equals(BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName()))){
            dto.setCertificateStatus(null);
            dto.setIsScrap("0");
        }
        return jgUseRegistrationManageMapper.queryForPage(page, dto, sortMap);
    }

    /**
     * 单位变更证-查询
     */
    public Page<JgUseRegistrationManageDto> queryForUnitChangePage(Page<JgUseRegistrationManageDto> page,
                                                                                JgUseRegistrationManageDto dto,
                                                                                String sort) {
        SortVo sortMap = commonServiceImpl.sortFieldConversion(sort);
        if (ApplicationFormTypeEnum.BF.getBusinessCode().equals(dto.getApplyType()) && (!CylinderTypeEnum.CYLINDER.getCode().equals(dto.getEquCategoryCode()) || dto.getRegType().equals(BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName()))){
            dto.setCertificateStatus(null);
            dto.setIsScrap("0");
        }
        return jgUseRegistrationManageMapper.queryForUnitChangePage(page, dto, sortMap);
    }

    /**
     * 分页查询证管理表-选择证使用，添加产权单位id
     */
    public Page<JgUseRegistrationManageDto> queryUseRegistrationManagePage(Page<JgUseRegistrationManageDto> page,
                                                                           JgUseRegistrationManageDto dto,
                                                                           String sort) {
        SortVo sortMap = commonServiceImpl.sortFieldConversion(sort);
        if (ApplicationFormTypeEnum.BF.getBusinessCode().equals(dto.getApplyType()) && (!CylinderTypeEnum.CYLINDER.getCode().equals(dto.getEquCategoryCode()) || dto.getRegType().equals(BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName()))){
            dto.setCertificateStatus(null);
            dto.setIsScrap("0");
        }
        return jgUseRegistrationManageMapper.queryUseRegistrationManagePage(page, dto, sortMap);
    }

    public Page<JgUseRegistrationManageDto> queryForJgUseRegistrationManagePageForJG(JgUseRegistrationManageDto dto, String sort, int current, int size) {
        Page<JgUseRegistrationManageDto> page = new Page<JgUseRegistrationManageDto>();
        page.setCurrent(current);
        page.setSize(size);
        SortVo sortMap = commonServiceImpl.sortFieldConversion(sort);
        if (ApplicationFormTypeEnum.BF.getBusinessCode().equals(dto.getApplyType()) && (!CylinderTypeEnum.CYLINDER.getCode().equals(dto.getEquCategoryCode()) || dto.getRegType().equals(BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName()))){
            dto.setCertificateStatus(null);
            dto.setIsScrap("0");
        }
        return jgUseRegistrationManageMapper.queryForPageForJG(page, dto, sortMap, getSelectedOrgInfo().getCompany().getOrgCode());
    }

    public Page<JgUseRegistrationManageDto> getRecords(Page<JgUseRegistrationManageDto> page, JgUseRegistrationManageDto dto, String cityCode) {
        String orgCode = getAndSetOrgCode(cityCode);
        return jgUseRegistrationManageMapper.getRecords(page, dto, orgCode);

    }

    public String getAndSetOrgCode(String cityCode) {
        String orgCode = regionCodeOrgCodeMap.get(cityCode);
        if (orgCode == null) {
            orgCode = commonMapper.getOrgCodeByCompanyCode(cityCode);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(cityCode, orgCode);
            }
        }
        return orgCode;
    }
    /**
     * 根据sequenceNbr查询---使用登记证详情用
     *
     * @param sequenceNbr 主键
     * @return
     */
    public JgUseRegistrationManageDto queryDetailBySeq(String sequenceNbr) {
        JgUseRegistrationManage jgUseRegistrationManage = this.baseMapper.selectById(sequenceNbr);
        JgUseRegistrationManageDto jgUseRegistrationManageDto=new JgUseRegistrationManageDto();
        if(Objects.nonNull(jgUseRegistrationManage)){
            BeanUtil.copyProperties(jgUseRegistrationManage,jgUseRegistrationManageDto);
            try {
                jgUseRegistrationManageDto.setAuditPassDate(DateUtils.dateFormat(jgUseRegistrationManage.getAuditPassDate(),DateUtils.DATE_PATTERN));
                jgUseRegistrationManageDto.setRegDate(DateUtils.dateFormat(jgUseRegistrationManage.getRegDate(),DateUtils.DATE_PATTERN));
                jgUseRegistrationManageDto.setCreateDate(DateUtils.dateFormat(jgUseRegistrationManage.getCreateDate(),DateUtils.DATE_TIME_PATTERN));
            } catch (ParseException e) {
               log.error(e.getMessage(),e);
            }
        }
        return  jgUseRegistrationManageDto;
    }

    /**
     * 根据sequenceNbr查询使用登记证 操作流水---使用登记证详情用
     *
     * @param sequenceNbr 主键
     * @return
     */
    public List<Map<String, String>> operationRecord(String sequenceNbr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        JgUseRegistrationManage jgUseRegistrationManage = this.baseMapper.selectById(sequenceNbr);
        List<JgCertificateChangeRecord> changeRecordList = jgCertificateChangeRecordService.list(new LambdaQueryWrapper<JgCertificateChangeRecord>()
                .eq(JgCertificateChangeRecord::getUseRegistrationCode, jgUseRegistrationManage.getUseRegistrationCode())
                .or().eq(JgCertificateChangeRecord::getCertificateNo, jgUseRegistrationManage.getCertificateNo())
                .orderByDesc(JgCertificateChangeRecord::getCreateDate));
        return changeRecordList.stream()
                .map(x -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("operatingTime", simpleDateFormat.format(x.getRecDate()));
                    map.put("content", x.getChangeContent());
                    map.put("routePath", x.getRoutePath());
                    return map;
                }).collect(Collectors.toList());
    }

    /**
     * 根据sequenceNbr查询使用登记证对应设备列表---使用登记证详情用
     * 分页接口
     *
     * @param sequenceNbr 主键
     * @return
     */
    public Page<JSONObject> certificateEquList(int current, int size, String sequenceNbr) {
        return queryEquForPageByCertificateSeqList("",Collections.singletonList(Long.parseLong(sequenceNbr)), current, size);
    }

    /**
     * 列表查询
     */
    public List<JgUseRegistrationManageDto> queryByUseUnitCreditCode(JgUseRegistrationManageDto dto) {
        if("1".equals(dto.getWhetherVehicleCylinder())){
            dto.setEquCategoryCode(CylinderTypeEnum.CYLINDER.getCode());
        }
        return jgUseRegistrationManageMapper.queryByUseUnitCreditCode(dto);
    }

    /**
     * 根据证的sequenceNbr，查询证下面的所有【已认领】设备
     */
    public List<JSONObject> queryEquByCertificateSeq(Long sequenceNbr) {
        return queryEquByCertificateSeqList(Collections.singletonList(sequenceNbr));
    }

    /**
     * 根据证的sequenceNbr集合，批量查询证下面的所有【已认领】设备
     */
    public List<JSONObject> queryEquByCertificateSeqList(List<Long> sequenceNbrList) {
        List<JgUseRegistrationManage> jgUseRegistrationManageList = this.baseMapper.selectList(new LambdaQueryWrapper<JgUseRegistrationManage>()
                .in(JgUseRegistrationManage::getSequenceNbr, sequenceNbrList)
                .eq(JgUseRegistrationManage::getIsDelete, 0)
                .select(JgUseRegistrationManage::getUseRegistrationCode, BaseEntity::getSequenceNbr));
        if (ValidationUtil.isEmpty(jgUseRegistrationManageList)) {
            return new ArrayList<>();
        }
        // List<JSONObject> result = new ArrayList<>();
        Set<String> useOrgCodes = jgUseRegistrationManageList.stream().map(JgUseRegistrationManage::getUseRegistrationCode).filter(org.apache.commons.lang3.StringUtils::isNotEmpty).collect(Collectors.toSet());

        // es中通过查询【使用登记证编号】所有设备
        // SearchRequest request = new SearchRequest("idx_biz_view_jg_all");
        // SearchSourceBuilder builder = new SearchSourceBuilder();
        // builder.trackTotalHits(true);

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("USE_ORG_CODE", useOrgCodes);
        boolQuery.must(termsQuery);
        // builder.query(boolQuery);
        // builder.size(useOrgCodes.size());
        // request.source(builder);
        BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
        meBuilder.should(QueryBuilders.matchQuery("STATUS", "已认领"));
        meBuilder.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("STATUS")));
        meBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("STATUS", "")));
        meBuilder.minimumShouldMatch(1);
        boolQuery.must(meBuilder);

        List<JSONObject> result = Collections.emptyList();
        try {
            result = searchResponse("idx_biz_view_jg_all", boolQuery, hit -> JSONObject.parseObject(hit.getSourceAsString(), JSONObject.class));
        }catch (Exception ex){
            ex.printStackTrace();
        }
        // try {
        //     SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //     for (SearchHit hit : response.getHits().getHits()) {
        //         JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
        //         JSONObject dto2 = jsonObject.getJSONObject("sourceAsMap");
        //         result.add(dto2);
        //     }
        // } catch (Exception e) {
        //     e.printStackTrace();
        // }
        return result;
    }

    /**
     * 构建SearchResponse
     *
     * @param indices 索引
     * @param query   queryBuilder
     * @param fun     返回函数
     * @param <T>     返回类型
     * @return List, 可以使用fun转换为T结果
     * @throws Exception e
     */
    public <T> List<T> searchResponse(String indices, QueryBuilder query, Function<SearchHit, T> fun) throws Exception {
        SearchRequest request = new SearchRequest(indices);
        Scroll scroll = new Scroll(TimeValue.timeValueMillis(SCROLL_TIMEOUT));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(query);
        sourceBuilder.size(SIZE);

        request.scroll(scroll);
        request.source(sourceBuilder);

        List<String> scrollIdList = new ArrayList<>();
        List<T> result = new ArrayList<>();

        SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        String scrollId = searchResponse.getScrollId();
        SearchHit[] hits = searchResponse.getHits().getHits();
        scrollIdList.add(scrollId);

        try {
            while (ArrayUtils.isNotEmpty(hits)) {
                for (SearchHit hit : hits) {
                    result.add(fun.apply(hit));
                }
                if (hits.length < SIZE) {
                    break;
                }
                SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
                searchScrollRequest.scroll(scroll);
                SearchResponse searchScrollResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
                scrollId = searchScrollResponse.getScrollId();
                hits = searchScrollResponse.getHits().getHits();
                scrollIdList.add(scrollId);
            }
        } finally {
            ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
            clearScrollRequest.setScrollIds(scrollIdList);
            restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
        }
        return result;
    }

    /**
     * 根据证的sequenceNbr集合，批量查询证下面的所有设备
     *
     * @param enableType 启用停用/报废业务使用 - 过滤设备状态 （1：在用 2：停用） 对应枚举：EquimentEnum
     * @param sequenceNbrList 证的sequenceNbr集合
     * @param current         分页-当前页
     * @param size            分页-分页数
     * @return 查询结果
     */
    public Page<JSONObject> queryEquForPageByCertificateSeqList(String enableType, List<Long> sequenceNbrList, int current, int size) {
        List<JgUseRegistrationManage> jgUseRegistrationManageList = this.baseMapper.selectList(new LambdaQueryWrapper<JgUseRegistrationManage>()
                .in(JgUseRegistrationManage::getSequenceNbr, sequenceNbrList)
                .eq(JgUseRegistrationManage::getIsDelete, 0)
                .select(JgUseRegistrationManage::getUseRegistrationCode, BaseEntity::getSequenceNbr));
        if (ValidationUtil.isEmpty(jgUseRegistrationManageList)) {
            return new Page<>();
        }

        List<JSONObject> list = new LinkedList<>();
        long totle = 0;

        Page<JSONObject> result = new Page<>(Optional.of(current).orElse(1), Optional.of(size).orElse(10));
        Set<String> useOrgCodes = jgUseRegistrationManageList.stream().map(JgUseRegistrationManage::getUseRegistrationCode).filter(org.apache.commons.lang3.StringUtils::isNotEmpty).collect(Collectors.toSet());

        // es中通过查询【使用登记证编号】所有设备
        SearchRequest request = new SearchRequest("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);


        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 且登记证筛选
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("USE_ORG_CODE", useOrgCodes);
        boolQuery.must(termsQuery);
        // 且已认领状态
        boolQuery.must(QueryBuilders.termQuery("STATUS", EquipmentCategoryEnum.YRL.getName()));
        // 且已纳管状态
        boolQuery.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));

        // 设备状态 对应枚举EquimentEnum
        if (!ObjectUtils.isEmpty(enableType)) {
            BoolQueryBuilder elcBuilder = QueryBuilders.boolQuery();
            if (EquipmentEnum.BAOFEI.getCode().equals(Integer.valueOf(enableType))) { // 报废业务选择未报废的设备
                elcBuilder.mustNot(QueryBuilders.matchPhraseQuery("EQU_STATE", QueryParser.escape(enableType)));
            } else if (EquipmentEnum.TINGYONG.getCode().equals(Integer.valueOf(enableType))){
                elcBuilder.must(QueryBuilders.termsQuery("EQU_STATE", "2", "4"));
            }else if (EquipmentEnum.ZAIYONG.getCode().equals(Integer.valueOf(enableType))){
                elcBuilder.must(QueryBuilders.termsQuery("EQU_STATE", "1", "4"));
            }else{
                elcBuilder.must(QueryBuilders.matchPhraseQuery("EQU_STATE", QueryParser.escape(enableType)));
            }
            boolQuery.must(elcBuilder);
        }

        builder.query(boolQuery);
        builder.from((current - 1) * size);
        builder.size(size);
        request.source(builder);

        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
                JSONObject dto = jsonObject.getJSONObject("sourceAsMap");
                dto.put("record", dto.get("SEQUENCE_NBR"));
                dto.put("equipAddress", dto.get("USE_PLACE") + "/" + dto.get("ADDRESS"));
                dto.put("EQU_STATE_NAME", !ValidationUtil.isEmpty(dto.getString("EQU_STATE")) ? EquipmentEnum.getName.get(Integer.valueOf(dto.getString("EQU_STATE"))) : null);
                dto.put("NEXT_INSPECT_DATE", this.castDate2TimeStr(dto.getString("NEXT_INSPECT_DATE")));
                list.add(dto);
            }
            totle = Objects.requireNonNull(response.getInternalResponse().hits().getTotalHits()).value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.setRecords(list);
        result.setTotal(totle);
        return result;
    }

    private Date castDate2TimeStr(String nextInspectDate) {
        if (nextInspectDate != null) {
            try {
                long timestamp = Long.parseLong(nextInspectDate);
                return DateUtil.date(timestamp);
            } catch (NumberFormatException e) {
                return DateUtil.parse(nextInspectDate, "yyyy-MM-dd");
            }
        }
        return null;
    }

    /**
     * 标志/使用登记证/汇总表 打印
     *
     * @param response       响应
     * @param printType      打印类型
     * @param certificateSeq 使用登记证的seq
     */
    public void printCertificate(HttpServletResponse response, String printType, String certificateSeq) {
        if (StringUtils.isEmpty(printType) || StringUtils.isEmpty(certificateSeq)) {
            throw new BadRequest("打印失败，请联系管理员！");
        }
        JgUseRegistrationManage manage = this.baseMapper.selectById(certificateSeq);
        if (manage == null) {
            throw new BadRequest("未找到对应的使用登记信息！");
        }
        if (EXPORT_SUMMARY_TABLE.equals(printType)) {
            //打印汇总表
            handleExportSummaryTable(response, manage);
        } else {
            exportUseRegistrationCertificate(manage, response, printType);
        }
        this.updateById(manage);
    }

    /**
     * 证管理下载汇总表（需要查询最新数据）
     * @param response
     * @param manage
     */
    private void handleExportSummaryTable(HttpServletResponse response, JgUseRegistrationManage manage) {
        JSONObject tagJson = Optional.ofNullable(manage.getCertificatePrintTag())
                .map(JSONObject::parseObject)
                .orElse(new JSONObject());
        tagJson.put(EXPORT_SUMMARY_TABLE, 2);
        manage.setCertificatePrintTag(JSONObject.toJSONString(tagJson));
        final int size = 10;
        final String useRegCode = manage.getUseRegistrationCode();
        List<CompletableFuture<byte[]>> futures;
        if (Arrays.asList("8200", "8100", "8300").contains(manage.getEquCategoryCode())) {
            // ===== 压力管道逻辑 =====
            List<IdxBizJgProjectContraption> list = jgProjectContraptionService.lambdaQuery()
                    .in(IdxBizJgProjectContraption::getUseRegistrationCode, useRegCode)
                    .list();
            if (ValidationUtil.isEmpty(list)) throw new BadRequest("没有查询到汇总信息！");

            String wordPath = "PressurePipeBasicInformationSummary.ftl";
            String filePrefix = "压力管道基本信息汇总表_";

            futures = list.stream().flatMap(v -> {
                List<Map<String, Object>> eqs = jgProjectContraptionMapper
                        .selectEquipListByExport(String.valueOf(v.getSequenceNbr()));
                int total = eqs.size();
                int page = (total + size - 1) / size;

                AgencyUserModel result = Optional.ofNullable(v.getRecUserId())
                        .map(id -> Privilege.agencyUserClient.queryByUserId(id).getResult())
                        .orElseThrow(() -> new BadRequest("未获取到接收人信息！"));

                return jgProjectContraptionService
                        .pressurePipeDataPreparation(page, v, size, total, eqs, wordPath, filePrefix, result, manage.getEquCategoryCode())
                        .stream();
            }).collect(Collectors.toList());
            toZipFile(response, futures, filePrefix, filePrefix + useRegCode + ".zip");
        } else {
            // ===== 气瓶逻辑 =====
            String wordPath = "CylinderBasicInformationSummary.ftl";
            String filePrefix = "气瓶基本信息汇总表_";
            Map<String, Object> fillingMediumMap = Systemctl.dictionarieClient.dictValues("FILLING_MEDIUM").getResult()
                    .stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));
            List<IdxBizJgRegisterInfo> registerInfoList = idxBizJgRegisterInfoMapper.selectList(
                    new QueryWrapper<IdxBizJgRegisterInfo>().in("USE_ORG_CODE", useRegCode));

            List<Map<String, Object>> tableData = jgUseRegistrationMapper
                    .queryForUnitVesselEquipment(registerInfoList.stream().map(IdxBizJgRegisterInfo::getRecord).collect(Collectors.toList()));
            tableData.forEach(i -> i.put("chargingMedium", fillingMediumMap.get(i.get("chargingMedium"))));
            JSONArray allEquipment = new JSONArray();
            tableData.forEach(map -> {
                if (jgUseRegistrationService.checkEquStatusInUse((String) map.get("record"))) {
                    allEquipment.add(new JSONObject(map));
                }
            });
            int total = allEquipment.size();
            int page = (total + size - 1) / size;
            JSONObject jsonObject = new JSONObject().fluentPut("useUnitName", manage.getUseUnitName());
            AgencyUserModel result = Optional.ofNullable(manage.getCreateUserId())
                    .map(id -> Privilege.agencyUserClient.queryByUserId(id).getResult())
                    .orElse(new AgencyUserModel());
            futures = jgUseRegistrationService.cylinderDataPreparation(page, jsonObject, size, total, allEquipment, wordPath, filePrefix, result);
            toZipFile(response, futures, filePrefix, filePrefix + useRegCode + ".zip");
        }
    }

    public void exportUseRegistrationCertificate(JgUseRegistrationManage manage, HttpServletResponse response, String printType) {
        if (ValidationUtil.isEmpty(manage)) {
            throw new BadRequest("使用登记信息为空，导出失败！");
        }
        List<JSONObject> deviceList = this.queryEquByCertificate(manage);
        if (ValidationUtil.isEmpty(deviceList)) {
            throw new BadRequest("使用登记证下无设备，导出失败！");
        }
        Map<String, Object> params = buildExportParams(manage, deviceList);
        JSONObject tagJson = Optional.ofNullable(manage.getCertificatePrintTag())
                .map(JSONObject::parseObject)
                .orElse(new JSONObject());
        switch (printType) {
            case CERTIFICATE_NORMAL://证 普打
                commonService.generateCertificateReport(params, response);
                tagJson.put(CERTIFICATE_NORMAL, 2);
                break;
            case CERTIFICATE_NESTED://证 套打
                commonService.generateCertificateReportDoc(params, response);
                tagJson.put(CERTIFICATE_NESTED, 2);
                break;
            case USE_FLAG_NORMAL://标志 普打
                commonService.useFlagGenerate(this.buildUseFlagParamDto(deviceList, manage, params), response);
                tagJson.put(USE_FLAG_NORMAL, 2);
                break;
            case USE_FLAG_NESTED://标志 套打
                commonService.fightUseFlagGenerate(this.buildUseFlagParamDto(deviceList, manage, params), response);
                tagJson.put(USE_FLAG_NESTED, 2);
                break;
            default:
                throw new BadRequest("无效的打印类型！");
        }
        manage.setCertificatePrintTag(JSONObject.toJSONString(tagJson));
    }

    private Map<String, Object> buildExportParams(JgUseRegistrationManage manage, List<JSONObject> deviceList) {
        Map<String, Object> map = new HashMap<>();
        if (ValidationUtil.isEmpty(manage.getReceiveOrgName()) ||
                ValidationUtil.isEmpty(manage.getUseRegistrationCode()) ||
                ValidationUtil.isEmpty(manage.getUseUnitName())) {
            throw new BadRequest("导出失败，登记机关、编号或单位名称为空！");
        }
        map.put("receiveOrgName", manage.getReceiveOrgName());
        map.put("useRegistrationCode", manage.getUseRegistrationCode());
        map.put("useUnitName", manage.getUseUnitName());
        map.put("supervisoryCode", deviceList.get(0).get("SUPERVISORY_CODE"));

        if ("1".equals(manage.getIsOverDesign())) {
            map.put("overDesign", "超设计使用年限");
        }
        getAuditPassedDate(manage.getAuditPassDate(), map);
        getReissueDate(manage.getReissueDate(), map);
        map.put("equList", manage.getEquList());
        map.put("equCategory", manage.getEquCategory());
        map.put("equDefine", manage.getEquDefine());
        map.put("manageType", manage.getManageType());
        if (BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName().equals(manage.getRegType())) {
            map.put("fullAddress", manage.getUseUnitAddress());
            map.put("manageType", "");
            map.put("equDefineCode", "23T0");
            map.put("equCode", joinDeviceField(deviceList, "EQU_CODE"));
            map.put("factoryNum", joinDeviceField(deviceList, "FACTORY_NUM"));
            map.put("useInnerCode", joinDeviceFieldDistinct(deviceList, "USE_INNER_CODE"));
        } else {
            map.put("fullAddress", "unit".equals(manage.getManageType()) ? this.getUnitAddress(manage) : manage.getEquUseAddress());
            map.put("equCode", deviceList.get(0).get("EQU_CODE"));
            map.put("factoryNum", deviceList.get(0).get("FACTORY_NUM"));
            map.put("useInnerCode", deviceList.get(0).get("USE_INNER_CODE"));
        }
        map.put("certificateNo", manage.getCertificateNo());
        map.put("applyNo", manage.getCertificateNo());
        map.put("version", String.valueOf(manage.getVersion()));
        map.put("carNumber", manage.getCarNumber());
        map.put("equListCode", manage.getEquListCode());
        return map;
    }

    private String getUnitAddress(JgUseRegistrationManage manage) {
        TzBaseEnterpriseInfo tzBaseEnterpriseInfo = tzBaseEnterpriseInfoMapper.selectByUseUnitCode(manage.getUseUnitCreditCode());
        return ValidationUtil.isEmpty(tzBaseEnterpriseInfo) ? manage.getUseUnitAddress() : tzBaseEnterpriseInfo.getAddress();
    }
    
    private String joinDeviceField(List<JSONObject> devices, String field) {
        return devices.stream()
                .map(obj -> String.valueOf(obj.get(field)))
                .filter(Objects::nonNull)
                .collect(Collectors.joining(", "));
    }

    private String joinDeviceFieldDistinct(List<JSONObject> devices, String field) {
        return devices.stream()
                .map(obj -> String.valueOf(obj.get(field)))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.joining(", "));
    }

    /**
     * 查询本单位下设备，过滤三环数据
     * @param manage
     * @return
     */
    private List<JSONObject> queryEquByCertificate(JgUseRegistrationManage manage) {
        return queryEquByCertificateSeq(manage.getSequenceNbr()).stream()
                .filter(s -> Objects.equals(s.get("USE_UNIT_CREDIT_CODE"), manage.getUseUnitCreditCode()))
                .collect(Collectors.toList());
    }

    private UseFlagParamDto buildUseFlagParamDto(List<JSONObject> deviceList, JgUseRegistrationManage manage, Map<String, Object> exportParamsMap) {
        UseFlagParamDto useFlagParamDto = new UseFlagParamDto();
        useFlagParamDto.setReceiveCompanyCode(manage.getReceiveCompanyCode());
        useFlagParamDto.setEquList(exportParamsMap.get("equList").toString());
        if (BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.getName().equals(manage.getRegType())){
            useFlagParamDto.setEquListCode("0000");
            useFlagParamDto.setEquipDefine("车用气瓶");
        }else{
            useFlagParamDto.setEquListCode(manage.getEquListCode());
            useFlagParamDto.setEquipDefine(Optional.ofNullable(exportParamsMap.get("equDefine"))
                    .orElse(exportParamsMap.get("equCategory").toString())
                    .toString());
        }
        useFlagParamDto.setEquipCode(exportParamsMap.get("equCode").toString());
        useFlagParamDto.setEquipCategory(manage.getEquCategory());
        useFlagParamDto.setUseUnitName(exportParamsMap.get("useUnitName").toString());
        useFlagParamDto.setUseInnerCode(ValidationUtil.isEmpty(exportParamsMap.get("useInnerCode")) ? "" : exportParamsMap.get("useInnerCode").toString());
        useFlagParamDto.setReceiveOrgName(manage.getReceiveOrgName());
        useFlagParamDto.setUseRegistrationCode(exportParamsMap.get("useRegistrationCode").toString());
        useFlagParamDto.setFactoryNumber(ValidationUtil.isEmpty(exportParamsMap.get("factoryNum")) ? "" : exportParamsMap.get("factoryNum").toString());
        useFlagParamDto.setCarNumber(manage.getCarNumber());
        useFlagParamDto.setCertificateNo(manage.getCertificateNo());
        useFlagParamDto.setVersion(manage.getVersion());
        // 检验信息字段设置
        setInspectField((String) deviceList.get(0).get("SEQUENCE_NBR"), useFlagParamDto);
        // 电梯维保信息字段设置
        setMainInfoField((String) deviceList.get(0).get("SEQUENCE_NBR"), useFlagParamDto);
        // 车用气瓶专用字段
        useFlagParamDto.setCylinderNumOrVolume(manage.getGasNum() + "/" + manage.getVolume());
        useFlagParamDto.setFillingMedium(manage.getFillingMedium());
        return useFlagParamDto;
    }

    private void setInspectField(String record, UseFlagParamDto useFlagParamDto) {
        Map<String, Object> inspectDetail = jgUseRegistrationMapper.getInspectDetail(record, null);
        if (inspectDetail == null) {
            return;
        }
        useFlagParamDto.setInspectionUnitName(inspectDetail.get("inspectOrgName") == null ? "" : inspectDetail.get("inspectOrgName").toString());
        useFlagParamDto.setNextInspectionDate(inspectDetail.get("nextInspectDate") == null ? null : (Date) inspectDetail.get("nextInspectDate"));
    }

    private void setMainInfoField(String record, UseFlagParamDto useFlagParamDto) {
        IdxBizJgMaintenanceRecordInfo idxBizJgMaintenanceRecordInfo = idxBizJgMaintenanceRecordInfoService.queryNewestDetailByRecord(record);

        useFlagParamDto.setEmergencyTel(this.buildEmergencyTel(idxBizJgMaintenanceRecordInfo));
        useFlagParamDto.setMaintenanceUnitName(idxBizJgMaintenanceRecordInfo.getMeUnitName() == null ? "" : idxBizJgMaintenanceRecordInfo.getMeUnitName());
    }

    private String buildEmergencyTel(IdxBizJgMaintenanceRecordInfo idxBizJgMaintenanceRecordInfo) {
        if (StringUtil.isNotEmpty(idxBizJgMaintenanceRecordInfo.getMeMasterPhone()) && StringUtil.isNotEmpty(idxBizJgMaintenanceRecordInfo.getMeMaster1Phone())) {
            return idxBizJgMaintenanceRecordInfo.getMeMasterPhone() + "/" + idxBizJgMaintenanceRecordInfo.getMeMaster1Phone();
        }
        return StringUtil.isNotEmpty(idxBizJgMaintenanceRecordInfo.getMeMasterPhone()) ? idxBizJgMaintenanceRecordInfo.getMeMasterPhone() : StringUtil.isNotEmpty(idxBizJgMaintenanceRecordInfo.getMeMaster1Phone()) ? idxBizJgMaintenanceRecordInfo.getMeMaster1Phone() : "";
    }

    /**
     * 根据sequenceNbr查询---大屏使用
     *
     * @param sequenceNbr 主键
     * @return
     */
    public Object getDetail(String sequenceNbr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<FormValue> jsonData = getJsonData(registrationBasicJson);
        HashMap<String, Object> result = new HashMap<>();
        // 基本信息
        JgUseRegistrationManage jgUseRegistrationManage = this.baseMapper.selectById(sequenceNbr);
        Map<String, Object> objectMap = Bean.BeantoMap(jgUseRegistrationManage);
        jsonData.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
                if ("auditPassDate".equals(f.getKey())){
                    f.setValue(simpleDateFormat.format(jgUseRegistrationManage.getAuditPassDate()));
                }
            }
        });
        // 流水信息
        List<JgCertificateChangeRecord> changeRecordList = jgCertificateChangeRecordService.list(new LambdaQueryWrapper<JgCertificateChangeRecord>()
                .eq(JgCertificateChangeRecord::getUseRegistrationCode, jgUseRegistrationManage.getUseRegistrationCode())
                .or().eq(JgCertificateChangeRecord::getCertificateNo, jgUseRegistrationManage.getCertificateNo())
                .orderByDesc(JgCertificateChangeRecord::getCreateDate));
        List<Map<String, String>> collect = changeRecordList.stream()
                .map(x -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("operatingTime", simpleDateFormat.format(x.getRecDate()));
                    map.put("operater", x.getChangeContent());
                    map.put("label", simpleDateFormat.format(x.getRecDate()));
                    return map;
                }).collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap<>();
        map.put("datas", collect);
        map.put("title", "使用登记证流水");
        map.put("renderType", "timeline");
        result.put("title", objectMap.get("useUnitName"));
        result.put("keyParams", jsonData);
        result.put("infoRecords", map);
        return result;
    }


    private List<FormValue> getJsonData(Resource resource) {
        String json;
        try {
            json = IOUtils.toString(resource.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return parseArray(json, FormValue.class);
    }

    public void initUseRegistrationCodeIntoRedis(String year) {
        // 获取当前年份的两位数
        String currentYearSuffix = String.valueOf(LocalDate.now().getYear() % 100);
        Date endOfYear = com.yeejoin.amos.boot.module.ymt.api.common.DateUtils.calculateEndOfYear(new Date());
        // 非车用气瓶-从数据库中加载使用登记证最大序列码刷新到Redis中
        jgUseRegistrationManageMapper.initUseRegistrationCodeIntoRedis(year)
                .forEach(resultMap ->
                        Optional.ofNullable(resultMap)
                                .ifPresent(map -> setValueWithoutExpiration(map.get("prefix"), map.get("code")))
                );
        // 车用气瓶-从数据库中加载使用登记证最大序列码刷新到Redis中
        jgUseRegistrationManageMapper.initVehicleUseRegCodeIntoRedis(year)
                .forEach(resultMap ->
                        Optional.ofNullable(resultMap)
                                .ifPresent(map -> setValueWithoutExpiration(map.get("prefix"), map.get("code")))
                );
    }

    /**
     * redis 设置不过期的 key
     *
     * @param key   key
     * @param value value
     */
    public void setValueWithoutExpiration(String key, String value) {
        ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
        valueOps.set(key, value);
    }

    /**
     * redis设置key
     *
     * @param key            key
     * @param value          value
     * @param expirationDate 过期时间
     */
    public void setValueWithExpiration(String key, String value, Date expirationDate) {
        ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
        valueOps.set(key, value);

        long expirationTimeInSeconds = expirationDate.getTime() - System.currentTimeMillis();
        redisTemplate.expire(key, expirationTimeInSeconds, TimeUnit.MILLISECONDS);
    }

    public Object handleErrorDeviceCode(String applyNo) {
        LambdaQueryWrapper<JgUseRegistrationManage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(JgUseRegistrationManage::getApplyNo, applyNo);
        JgUseRegistrationManage jgUseRegistrationManage = jgUseRegistrationManageMapper.selectOne(queryWrapper);
        if (jgUseRegistrationManage != null) {
            String ym = "";
            try {
                ym = Optional.of(DateUtils.dateFormat(jgUseRegistrationManage.getAuditPassDate(), DateUtils.DATE_PATTERN_MM)).orElse(DateUtils.dateFormat(new Date(), DateUtils.DATE_PATTERN_MM));
            } catch (ParseException e) {
                log.error("日期转换失败：", e);
            }
            ResponseModel<String> responseModel;
            if (!ValidationUtil.isEmpty(jgUseRegistrationManage.getReceiveCompanyCode())) {
                String equCode = Optional.ofNullable(jgUseRegistrationManage.getEquDefineCode()).orElse(jgUseRegistrationManage.getEquCategoryCode());
                String registrationCode = equCode + codeUtil.getCityRegionCode(jgUseRegistrationManage.getReceiveCompanyCode()) + ym;
                responseModel = tzsServiceFeignClient.deviceRegistrationCode(registrationCode);
                jgUseRegistrationManage.setCertificateNo(responseModel.getResult());
                jgUseRegistrationManageMapper.updateById(jgUseRegistrationManage);

                LambdaUpdateWrapper<JgCertificateChangeRecord> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(JgCertificateChangeRecord::getApplyNo, applyNo);
                updateWrapper.set(JgCertificateChangeRecord::getCertificateNo, responseModel.getResult());
                certificateChangeRecordMapper.update(null, updateWrapper);
            }
        }
        return "修复成功！";
    }

    /**
     * 工程/装置分页查询
     * @param page
     * @param params
     * @param sort
     * @return
     */
    public Page<IdxBizJgProjectContraption> queryForUnitByProjectContraptionPage(Page<IdxBizJgProjectContraption> page, Map<String, String> params, String sort) {
        SortVo sortMap = commonServiceImpl.sortFieldConversion(sort);
        Page<IdxBizJgProjectContraption> projectContraptionPage = this.baseMapper.queryForUnitByProjectContraptionPage(page, params, sortMap);
        List<IdxBizJgProjectContraption> records = projectContraptionPage.getRecords();
        if (!ValidationUtil.isEmpty(records)) {
            records.forEach(item -> {
                BigDecimal pipelineLength = BigDecimal.valueOf(item.getPipelineLength());
                BigDecimal roundedValue = pipelineLength.setScale(3, RoundingMode.HALF_UP);
                BigDecimal strippedValue = roundedValue.stripTrailingZeros();
                item.setPipelineLength(Double.valueOf(strippedValue.toPlainString()));
                item.setDataSourceName(EquipSourceEnum.getDataSourceName(item.getDataSource()));
                item.setFullAddress(
                        Stream.of(item.getProvinceName(), item.getCityName(), item.getCountyName(), item.getStreetName(), item.getAddress())
                                .map(value -> value == null || "null".equals(value) ? "" : value)
                                .collect(Collectors.joining())
                );
                // 兼容历史数据，根据产权单位Seq（item.getEstateUnitName()）从tzs_tcm_unit_info表查询产权单位
                if (!ValidationUtil.isEmpty(item.getEstateUnitName())) {
                    Map<String, String> propertyUnitInfo = commonService.queryTcmUnitInfoBySeq(item.getEstateUnitName(), TcmUnitTypeEnum.CQ.getCode());
                    item.setEstateUnitName(MapUtil.getStr(propertyUnitInfo, "sequenceNbr"));
                }
            });
        }
        return projectContraptionPage;
    }

    public void batchUpdateManageBySeq(String newUseUnitName, String changeReason, String receiveCompanyCode, String receiveOrgName, List<String> seqBatch) {
        this.baseMapper.batchUpdateManageBySeq(newUseUnitName, changeReason, receiveCompanyCode, receiveOrgName, seqBatch);
    }
}