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

import cn.hutool.core.date.DateUtil;
import com.yeejoin.amos.boot.biz.common.dto.CountDto;
import com.yeejoin.amos.boot.module.common.api.constant.TZSCommonConstant;
import com.yeejoin.amos.boot.module.common.api.dto.DPFilterParamDto;
import com.yeejoin.amos.boot.module.common.api.dto.LegendDataDto;
import com.yeejoin.amos.boot.module.common.api.enums.ReginStepEnum;
import com.yeejoin.amos.boot.module.jg.api.dto.EquipBizCountDto;
import com.yeejoin.amos.boot.module.jg.api.dto.FourColorCountDataDto;
import com.yeejoin.amos.boot.module.jg.api.enums.DPMapStatisticsItemEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.FourColorCountItemEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.FourColorEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.*;
import com.yeejoin.amos.boot.module.ymt.api.dto.EquipmentCategoryDto;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquimentEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.EquipTechParamPipelineMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.EquipmentCategoryMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzsUserInfoMapper;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 大屏统计实现类
 *
 * @author Administrator
 */
@Service
@Slf4j
public class DPStatisticsServiceImpl {

    /**
     * 压力容器设备种类
     */
    private final static String EQU_LIST_CYLINDER = "2000";

    /**
     * 气瓶设备类别
     */
    private final static String EQU_CATEGORY_CYLINDER = "2300";

    /**
     * 单位类型-使用单位
     */
    private final static String COMPANY_TYPE_USE = "使用单位";

    /**
     * 单位类型-安装改造维修单位
     */
    private final static String COMPANY_TYPE_MAINTENANCE = "安装改造维修单位";

    /**
     * 单位类型-制造单位
     */
    private final static String COMPANY_TYPE_MANUFACTURE = "制造单位";

    /**
     * 单位类型-充装单位
     */
    private final static String COMPANY_TYPE_FILLING = "充装单位";

    /**
     * 监管-中屏-地图行政区划code
     */
    private final static String REGION_CODE = "regionCode";

    /**
     * 监管-中屏-地图行政区划code
     */
    private final static String REGION_NAME = "regionName";


    @Autowired
    private EquipmentCategoryMapper equipmentCategoryMapper;

    private JgUseRegistrationMapper useRegistrationMapper;

    private EquipTechParamPipelineMapper techParamsPipelineMapper;

    private JgEnableDisableMapper enableDisableMapper;

    private JgScrapCancelMapper scrapCancelMapper;

    private RestHighLevelClient restHighLevelClient;

    private TzBaseEnterpriseInfoMapper enterpriseInfoMapper;

    private CommonMapper commonMapper;

    private static List<EquipmentCategoryDto> equipmentCategoryDtos;

    private TzsUserInfoMapper userInfoMapper;


    private static Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();

    private static List<RegionModel> regionModels = new ArrayList<>();
    @Resource
    private DPStatisticsMapper dpStatisticsMapper;

    @Autowired
    private JgUseRegistrationManageMapper jgUseRegistrationManageMapper;

    public DPStatisticsServiceImpl(EquipmentCategoryMapper equipmentCategoryMapper, JgUseRegistrationMapper useRegistrationMapper, EquipTechParamPipelineMapper techParamsPipelineMapper, JgEnableDisableMapper enableDisableMapper, JgScrapCancelMapper scrapCancelMapper, RestHighLevelClient restHighLevelClient, TzBaseEnterpriseInfoMapper enterpriseInfoMapper, CommonMapper commonMapper, TzsUserInfoMapper userInfoMapper) {
        this.equipmentCategoryMapper = equipmentCategoryMapper;
        this.useRegistrationMapper = useRegistrationMapper;
        this.techParamsPipelineMapper = techParamsPipelineMapper;
        this.enableDisableMapper = enableDisableMapper;
        this.scrapCancelMapper = scrapCancelMapper;
        this.restHighLevelClient = restHighLevelClient;
        this.enterpriseInfoMapper = enterpriseInfoMapper;
        this.commonMapper = commonMapper;
        this.userInfoMapper = userInfoMapper;
    }

    public void init() {
        // 数据不变所以放到内存，提高响应时间
        equipmentCategoryDtos = equipmentCategoryMapper.selectClassify();
        initReginCode();
    }


    private List<LegendDataDto> buildLegendDataList() {
        List<LegendDataDto> legendDataDtos = new ArrayList<>();
        legendDataDtos.add(LegendDataDto.builder().dataKey("newDevice").value("新增登记设备").build());
        legendDataDtos.add(LegendDataDto.builder().dataKey("stoppedDevice").value("报停设备").build());
        legendDataDtos.add(LegendDataDto.builder().dataKey("scrappedDevice").value("报废设备").build());
        return legendDataDtos;
    }

    public Map<String, Object> useRegisterCountByEquList(DPFilterParamDto dpFilterParamDto) {
        // 1.查询条件构造未上送时间时，默认查询数据为近一个月数据
        this.setDefaultFilter(dpFilterParamDto);
        // 2.按照前端约定格式返回数据
        Map<String, Object> result = new HashMap<>();
        List<LegendDataDto> legendDataDtos = this.buildLegendDataList();
        //2.1 图列数据构造
        result.put("legendData", legendDataDtos);
        //2.2 x轴数据构造
        result.put("xdata", this.getXData(equipmentCategoryDtos));
        //2.3 y轴数据构造
        this.buildYData(result, dpFilterParamDto, equipmentCategoryDtos);
        return result;
    }

    private void buildYData(Map<String, Object> result, DPFilterParamDto dpFilterParamDto, List<EquipmentCategoryDto> equipmentCategoryDtos) {
        // 待统计的数据本来sql可以单独统计，但是要求气瓶单独从压力容器里拎出来，与八大类同级，故java处理
        // 1.新增登记统计
        result.put("newDevice", this.getNewDeviceCountData(dpFilterParamDto, equipmentCategoryDtos));
        // 2.新增报停设备统计
        result.put("stoppedDevice", this.getStoppedDeviceCountData(dpFilterParamDto, equipmentCategoryDtos));
        // 3.新增报废设备统计
        result.put("scrappedDevice", this.getScrappedDeviceCountData(dpFilterParamDto, equipmentCategoryDtos));
    }

    private List<Integer> getNewDeviceCountData(DPFilterParamDto dpFilterParamDto, List<EquipmentCategoryDto> equipmentCategoryDtos) {
        List<EquipBizCountDto> staticsData = useRegistrationMapper.queryNewDeviceStaticListData(dpFilterParamDto);
        return countNumByEquList(equipmentCategoryDtos, staticsData);
    }

    private List<Integer> getStoppedDeviceCountData(DPFilterParamDto dpFilterParamDto, List<EquipmentCategoryDto> equipmentCategoryDtos) {
        List<EquipBizCountDto> staticsData = enableDisableMapper.queryStoppedDeviceStaticListData(dpFilterParamDto);
        return countNumByEquList(equipmentCategoryDtos, staticsData);
    }

    private List<Integer> getScrappedDeviceCountData(DPFilterParamDto dpFilterParamDto, List<EquipmentCategoryDto> equipmentCategoryDtos) {
        List<EquipBizCountDto> staticsData = scrapCancelMapper.queryScrappedDeviceStaticListData(dpFilterParamDto);
        return countNumByEquList(equipmentCategoryDtos, staticsData);
    }


    private List<Integer> countNumByEquList(List<EquipmentCategoryDto> equipmentCategoryDtos, List<EquipBizCountDto> bizCountDtos) {
        List<Integer> lineData = new ArrayList<>();
        // 8大类数据统计数量
        equipmentCategoryDtos.forEach(equipmentCategoryDto -> {
            int num = 0;
            // 压力容器要去掉气瓶2300，气瓶单独统计
            if (EQU_LIST_CYLINDER.equals(equipmentCategoryDto.getCode())) {
                num = bizCountDtos.stream().filter(c -> c.getEquList().equals(equipmentCategoryDto.getCode()) && !EQU_CATEGORY_CYLINDER.equals(c.getEquCategory())).mapToInt(EquipBizCountDto::getNum).sum();
            } else {
                num = bizCountDtos.stream().filter(c -> c.getEquList().equals(equipmentCategoryDto.getCode())).mapToInt(EquipBizCountDto::getNum).sum();
            }
            lineData.add(num);
        });
        // 再增加气瓶(设备类别2300)专项
        int num = bizCountDtos.stream().filter(c -> EQU_CATEGORY_CYLINDER.equals(c.getEquCategory())).mapToInt(EquipBizCountDto::getNum).sum();
        lineData.add(num);
        return lineData;
    }

    private List<String> getXData(List<EquipmentCategoryDto> equipmentCategoryDtos) {
        // 8大类  + 气瓶 注意数据顺序和要和这个x轴一致
        List<String> names = equipmentCategoryDtos.stream().map(EquipmentCategoryDto::getName).collect(Collectors.toList());
        names.add("气瓶");
        return names;
    }


    private void setDefaultFilter(DPFilterParamDto dpFilterParamDto) {
        if (StringUtils.isEmpty(dpFilterParamDto.getBeginDate())) {
            dpFilterParamDto.setBeginDate(DateUtil.lastMonth().toDateStr());
        }
        if (StringUtils.isEmpty(dpFilterParamDto.getEndDate())) {
            dpFilterParamDto.setEndDate(DateUtil.today());
        }
    }


    public Map<String, Object> getCenterMapCountDataForGlobal(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        String orgCode = this.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 1.气瓶数量统计
        long cylinderNum = this.staticsCenterMapCountDataForCylinder(result, orgCode);
        //1.8大类设备数量统计,压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
        this.staticsCenterMapCountDataForEquip(result, cylinderNum, orgCode);
        //2.压力管道长度统计
        this.staticsCenterMapCountDataForPipeline(result, orgCode);
        //3.单位数量统计
        this.staticsCenterMapCountDataForCompany(result, orgCode);
        //4.人员数量统计
        this.staticsCenterMapCountDataForPerson(result, dpFilterParamDto, orgCode);
        return result;
    }

    private Map<String, Object> getCenterMapOverviewData(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        String orgCode = this.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 0. 气瓶数量统计
        long cylinderNum = this.staticsCenterMapCountDataForCylinder(result, orgCode);
        // 1. 8大类设备数量统计,压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
        this.staticsCenterMapCountDataForEquip(result, cylinderNum, orgCode);
        // 2. 压力管道长度统计
        this.staticsCenterMapCountDataForPipeline(result, orgCode);
        // 3. 人员数量统计
        this.staticsCenterMapCountDataForPerson(result, dpFilterParamDto, orgCode);
        return result;
    }

    private void staticsCenterMapCountDataForPerson(Map<String, Object> result, DPFilterParamDto dpFilterParamDto, String orgCode) {
        if (orgCode == null) {
            result.put(DPMapStatisticsItemEnum.OPERATORS.getCode(), 0);
            return;
        }
        Long num = userInfoMapper.countUserByPostAndAreaCode(orgCode, "6552", dpFilterParamDto.getCityCode());
        result.put(DPMapStatisticsItemEnum.OPERATORS.getCode(), num);
    }

    private void staticsCenterMapCountDataForCompany(Map<String, Object> result, String orgCode) {
        if (orgCode == null) {
            setDefaultCompanyCountData(result);
            return;
        }
        List<CountDto> countDtos = enterpriseInfoMapper.countByUnitTypeAndOrgCode(orgCode);
        result.put(DPMapStatisticsItemEnum.USERS_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_USE)).mapToInt(CountDto::getIntValue).sum());
        result.put(DPMapStatisticsItemEnum.CONSTRUCTION_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_MAINTENANCE)).mapToInt(CountDto::getIntValue).sum());
        result.put(DPMapStatisticsItemEnum.MANUFACTURING_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_MANUFACTURE)).mapToInt(CountDto::getIntValue).sum());
        result.put(DPMapStatisticsItemEnum.GAS_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_FILLING)).mapToInt(CountDto::getIntValue).sum());
    }

    private long staticsCenterMapCountDataForCylinder(Map<String, Object> result, String orgCode) {
        long num = 0;
        CountRequest request = new CountRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 设备类别精确查询气瓶
        boolMust.must(QueryBuilders.termsQuery("EQU_CATEGORY_CODE", EQU_CATEGORY_CYLINDER));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        request.query(boolMust);
        try {
            CountResponse response = restHighLevelClient.count(request, RequestOptions.DEFAULT);
            num = response.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        result.put(DPMapStatisticsItemEnum.GAS.getCode(), num);
        return num;
    }

    private void staticsCenterMapCountDataForPipeline(Map<String, Object> result, String orgCode) {
        String length = techParamsPipelineMapper.sumPipeLengthByOrgCode(orgCode);
        BigDecimal lengthDecimal = new BigDecimal(length);
        if (lengthDecimal.compareTo(BigDecimal.ZERO) > 0) {
            length = lengthDecimal.divide(new BigDecimal("1000"), 3, RoundingMode.HALF_UP).toPlainString();
        }
        result.put(DPMapStatisticsItemEnum.PRESSURE_PIPELINES.getCode(), length);
    }


    private void staticsCenterMapCountDataForEquip(Map<String, Object> result, long cylinderNum, String orgCode) {
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(boolMust);
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("count_by_equ_list_code").field("EQU_LIST_CODE");
        builder.aggregation(aggregationBuilder);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Terms terms = response.getAggregations().get("count_by_equ_list_code");
            Map<String, Long> countMap = new HashMap<>();
            for (Terms.Bucket bucket : terms.getBuckets()) {
                // 压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
                if (bucket.getKeyAsString().equals(EQU_LIST_CYLINDER)) {
                    countMap.put(bucket.getKeyAsString(), bucket.getDocCount() - cylinderNum);
                } else {
                    countMap.put(bucket.getKeyAsString(), bucket.getDocCount());
                }
            }
            // 按照8大类枚举，进行加工。目的：固定八大类防止没统计数据导致缺少分类、将设备种类的code换成前端定义的key
            equipmentCategoryDtos.forEach(c -> {
                result.put(this.castCategoryCode2WebCode(c.getCode()), countMap.getOrDefault(c.getCode(), 0L));
            });
            result.put(DPMapStatisticsItemEnum.TOTAL.getCode(), countMap.values().stream().mapToLong(e -> e).sum() + cylinderNum);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        result.remove(DPMapStatisticsItemEnum.PRESSURE_PIPELINES.getCategory());
    }

    private String castCategoryCode2WebCode(String category) {
        DPMapStatisticsItemEnum itemEnum = DPMapStatisticsItemEnum.getInstanceByCategory(category);
        return itemEnum.getCode();
    }

    public Map<String, Object> useRegisterCount(DPFilterParamDto dpFilterParamDto) {
        // 2.按照前端约定格式返回数据
        Map<String, Object> result = new HashMap<>();

        List legendDataList = new ArrayList();
        Map<String, Object> newDeviceMap = new HashMap<>();
        newDeviceMap.put("dataKey", "newDevice");
        newDeviceMap.put("value", "新增登记设备");
        legendDataList.add(newDeviceMap);
        Map<String, Object> scrappedDeviceMap = new HashMap<>();
        scrappedDeviceMap.put("dataKey", "scrappedDevice");
        scrappedDeviceMap.put("value", "报废设备");
        legendDataList.add(scrappedDeviceMap);
        result.put("legendData", legendDataList);
        LocalDate today = LocalDate.now();
        List xDataList = new ArrayList();
        List<Integer> newDeviceList = new ArrayList();
        List<Integer> scrappedDeviceList = new ArrayList();
        DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (int i = 2; i >= 0; i--) {
            LocalDate firstDayOfPrevMonth = today.minusMonths(i).with(TemporalAdjusters.firstDayOfMonth());
            LocalDate lastDayOfPrevMonth = today.minusMonths(i).with(TemporalAdjusters.lastDayOfMonth());
            dpFilterParamDto.setBeginDate(LocalDateTime.of(firstDayOfPrevMonth, java.time.LocalTime.MIN).format(sdf));
            dpFilterParamDto.setEndDate(LocalDateTime.of(lastDayOfPrevMonth, java.time.LocalTime.MAX).format(sdf));
            Integer useRegisterCount = useRegistrationMapper.getUseRegisterCount(dpFilterParamDto);
            Integer scrappedDeviceCount = scrapCancelMapper.getScrappedDeviceCount(dpFilterParamDto);
            xDataList.add(firstDayOfPrevMonth.getMonthValue() + "月");
            newDeviceList.add(null == useRegisterCount ? 0 : useRegisterCount);
            scrappedDeviceList.add(null == scrappedDeviceCount ? 0 : scrappedDeviceCount);
        }
        result.put("xdata", xDataList);
        result.put("newDevice", newDeviceList);
        result.put("scrappedDevice", scrappedDeviceList);
        return result;

    }

    public List<Map<String, Object>> getCenterMapCountDataForOverview(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regionModels = this.setRegionIfRootParent(dpFilterParamDto);
        List<Map<String, Object>> result = regionModels.parallelStream().map(r -> {
            DPFilterParamDto filterParamDto = new DPFilterParamDto();
            filterParamDto.setCityCode(r.getRegionCode().toString());
            Map<String, Object> itemResult = getCenterMapOverviewData(filterParamDto);
            itemResult.put("cityCode", r.getRegionCode());
            return itemResult;
        }).collect(Collectors.toList());
        this.setCompanyDataBatch(result);
        return result;
    }

    private List<RegionModel> setRegionIfRootParent(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regions = regionModels.parallelStream().filter(e -> e.getParentRegionCode() != null && (e.getParentRegionCode().toString()).equals(dpFilterParamDto.getCityCode())).collect(Collectors.toList());
        // 陕西省时需要在地图返回独立的地级市:韩城、杨凌、西咸
        if (dpFilterParamDto.getCityCode().equals(TZSCommonConstant.SHAN_XI_REGION_CODE)) {
            List<RegionModel> independentRegions = ReginStepEnum.enum2RegionList("map");
            regions.addAll(independentRegions);
        }
        return regions;
    }

    private void setCompanyDataBatch(List<Map<String, Object>> result) {

        List<CountDto> countDtos = enterpriseInfoMapper.countByUnitTypeAndOrgCodeNoParam();
        result.forEach(m -> {
            String cityCode = m.get("cityCode").toString();
            String orgCode = regionCodeOrgCodeMap.get(cityCode);
            if (orgCode != null) {
                m.put(DPMapStatisticsItemEnum.USERS_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_USE) && c.getLabel().contains(orgCode)).mapToInt(CountDto::getIntValue).sum());
                m.put(DPMapStatisticsItemEnum.CONSTRUCTION_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_MAINTENANCE) && c.getLabel().contains(orgCode)).mapToInt(CountDto::getIntValue).sum());
                m.put(DPMapStatisticsItemEnum.MANUFACTURING_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_MANUFACTURE) && c.getLabel().contains(orgCode)).mapToInt(CountDto::getIntValue).sum());
                m.put(DPMapStatisticsItemEnum.GAS_UNITS.getCode(), countDtos.stream().filter(c -> c.getKeyStr().contains(COMPANY_TYPE_FILLING) && c.getLabel().contains(orgCode)).mapToInt(CountDto::getIntValue).sum());
            } else {
                setDefaultCompanyCountData(m);
            }
        });
    }

    private void setDefaultCompanyCountData(Map<String, Object> m) {
        m.put(DPMapStatisticsItemEnum.USERS_UNITS.getCode(), 0);
        m.put(DPMapStatisticsItemEnum.CONSTRUCTION_UNITS.getCode(), 0);
        m.put(DPMapStatisticsItemEnum.MANUFACTURING_UNITS.getCode(), 0);
        m.put(DPMapStatisticsItemEnum.GAS_UNITS.getCode(), 0);
    }

    private void initReginCode() {
        Collection<RegionModel> result = Systemctl.regionClient.queryForTree(null).getResult();
        result.forEach(r -> {
            regionModels.add(r);
            this.loopSetChildRegin(regionModels, r.getChildren());
        });
    }

    private void loopSetChildRegin(List<RegionModel> regionModels, Collection<RegionModel> children) {
        if (children != null && children.size() > 0) {
            children.forEach(c -> {
                regionModels.add(c);
                this.loopSetChildRegin(regionModels, c.getChildren());
            });
        }
    }

    public Map<String, Object> querySafetyIndex(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        result.put("riskScore", 12);
        return result;
    }

    public List<FourColorCountDataDto> queryFourColorManagerSafetyData(DPFilterParamDto dpFilterParamDto) {
        this.setDefaultFilter(dpFilterParamDto);
        Map<String, Map<String, CountDto>> dataMap = this.getAllDataMap(dpFilterParamDto);
        return Arrays.stream(FourColorCountItemEnum.values()).map(e -> {
            FourColorCountDataDto dataDto = new FourColorCountDataDto();
            dataDto.setKey(e.getKey());
            dataDto.setLabel(e.getLabel());
            dataDto.setChildren(this.buildFourColorItemData(dataMap.get(e.getKey())));
            return dataDto;
        }).collect(Collectors.toList());
    }

    private List<FourColorCountDataDto> buildFourColorItemData(Map<String, CountDto> colorCountDataMap) {
        return Arrays.stream(FourColorEnum.values()).filter(e -> colorCountDataMap.get(e.getCode()) != null).map(c -> {
            FourColorCountDataDto dataDto = new FourColorCountDataDto();
            dataDto.setKey(c.getCode());
            dataDto.setValue(colorCountDataMap.get(c.getCode()).getLongValue());
            dataDto.setLabel(colorCountDataMap.get(c.getCode()).getLabel());
            return dataDto;
        }).collect(Collectors.toList());
    }

    private Map<String, Map<String, CountDto>> getAllDataMap(DPFilterParamDto dpFilterParamDto) {
        Map<String, Map<String, CountDto>> countMap = new HashMap<>();
        countMap.put(FourColorCountItemEnum.EQUIP.getKey(), this.countEquipNum(dpFilterParamDto));
        countMap.put(FourColorCountItemEnum.COMPANY.getKey(), this.countCompanyNum(dpFilterParamDto));
        countMap.put(FourColorCountItemEnum.USER.getKey(), this.countUserNum(dpFilterParamDto));
        return countMap;
    }

    private Map<String, CountDto> countEquipNum(DPFilterParamDto dpFilterParamDto) {
        Map<String, CountDto> countMap = new HashMap<>();
        countMap.put(FourColorEnum.GREEN.getCode(), this.getGreenStatusEquip(dpFilterParamDto));
        countMap.put(FourColorEnum.RED.getCode(), this.getRedStatusEquip(dpFilterParamDto));
        countMap.put(FourColorEnum.YELLOW.getCode(), this.getYellowStatusEquip(dpFilterParamDto));
        countMap.put(FourColorEnum.GREY.getCode(), this.getGreyStatusEquip(dpFilterParamDto));
        return countMap;
    }

    private CountDto getGreenStatusEquip(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countEquipNumFromES(dpFilterParamDto, EquimentEnum.ZAIYONG.getCode()));
        countDto.setLabel("正常在用");
        return countDto;
    }

    private long countEquipNumFromES(DPFilterParamDto dpFilterParamDto, Integer... states) {
        long num;
        CountRequest request = new CountRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        // 设备状态过滤
        boolMust.must(QueryBuilders.termsQuery("EQU_STATE", states));
        request.query(boolMust);
        try {
            CountResponse response = restHighLevelClient.count(request, RequestOptions.DEFAULT);
            num = response.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return num;
    }

    private CountDto getRedStatusEquip(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("超期未检");
        return countDto;
    }

    private CountDto getYellowStatusEquip(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("临期告警");
        return countDto;
    }

    private CountDto getGreyStatusEquip(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countEquipNumFromES(dpFilterParamDto, EquimentEnum.BAOFEI.getCode(), EquimentEnum.ZHUXIAO.getCode()));
        countDto.setLabel("未注册、停用或注销");
        return countDto;
    }

    private Map<String, CountDto> countCompanyNum(DPFilterParamDto dpFilterParamDto) {
        Map<String, CountDto> countMap = new HashMap<>();
        countMap.put(FourColorEnum.GREEN.getCode(), this.getGreenStatusCompany(dpFilterParamDto));
        countMap.put(FourColorEnum.RED.getCode(), this.getRedStatusCompany(dpFilterParamDto));
        countMap.put(FourColorEnum.YELLOW.getCode(), this.getYellowStatusCompany(dpFilterParamDto));
        countMap.put(FourColorEnum.GREY.getCode(), this.getGreyStatusCompany(dpFilterParamDto));
        return countMap;
    }

    private CountDto getGreyStatusCompany(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLongValue(this.countCompanyByOperatingStatus(dpFilterParamDto, "停业"));
        countDto.setLabel("停业");
        return countDto;
    }

    private CountDto getYellowStatusCompany(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("临期告警");
        return countDto;
    }

    private CountDto getRedStatusCompany(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("超期未检");
        return countDto;
    }

    private CountDto getGreenStatusCompany(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countCompanyByOperatingStatus(dpFilterParamDto, "在业"));
        countDto.setLabel("正常在业");
        return countDto;
    }

    private long countCompanyByOperatingStatus(DPFilterParamDto dpFilterParamDto, String operatingStatus) {
        String orgCode = getAndSetOrgCode(dpFilterParamDto.getCityCode());
        return enterpriseInfoMapper.countByOperatingStatusAndOrgCode(orgCode, operatingStatus, dpFilterParamDto.getCityCode());
    }

    private Map<String, CountDto> countUserNum(DPFilterParamDto dpFilterParamDto) {
        Map<String, CountDto> countMap = new HashMap<>();
        countMap.put(FourColorEnum.GREEN.getCode(), this.getGreenStatusUser(dpFilterParamDto));
        countMap.put(FourColorEnum.RED.getCode(), this.getRedStatusUser(dpFilterParamDto));
        countMap.put(FourColorEnum.YELLOW.getCode(), this.getYellowStatusUser(dpFilterParamDto));
        return countMap;
    }

    private CountDto getYellowStatusUser(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("许可临期");
        return countDto;
    }

    private CountDto getRedStatusUser(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("许可超期");
        return countDto;
    }

    private CountDto getGreenStatusUser(DPFilterParamDto dpFilterParamDto) {
        // TODO 需求不明确
        CountDto countDto = new CountDto();
        countDto.setLongValue(0L);
        countDto.setLabel("许可正常");
        return countDto;
    }

    public Map<String, Object> queryBizCycleData(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        this.setDefaultFilter(dpFilterParamDto);
        result.put("xdata", Arrays.asList("安装告知", "监督检验", "使用登记", "定期检验", "变更登记", "注销报废"));
        List<Long> ydata = this.countBizFinishedNum(dpFilterParamDto);
        Long allFinishedCount = ydata.stream().mapToLong(e -> e).sum();
        result.put("ydata", ydata);
        result.put("allCount", allFinishedCount);
        result.put("completionRate", this.calPercentForBizCycleData(dpFilterParamDto, allFinishedCount));
        return result;
    }

    private String calPercentForBizCycleData(DPFilterParamDto dpFilterParamDto, Long allFinishedCount) {
        Long allBizDataInFlowingCount = this.countAllBizDataInFlowing(dpFilterParamDto);
        BigDecimal finish = new BigDecimal(String.valueOf(allFinishedCount));
        BigDecimal flowing = new BigDecimal(String.valueOf(allBizDataInFlowingCount));
        BigDecimal total = finish.add(flowing);
        if (total.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal result = finish.divide(total, 2, RoundingMode.HALF_UP);
            BigDecimal percentage = result.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP);
            return percentage.toPlainString();
        } else {
            return "0";
        }
    }

    private Long countAllBizDataInFlowing(DPFilterParamDto dpFilterParamDto) {
        String orgCode = getAndSetOrgCode(dpFilterParamDto.getCityCode());
        List<Long> inFlowingForDP = commonMapper.countAllInFlowingForDPNoFinishedBizData(orgCode, dpFilterParamDto);
        return inFlowingForDP.stream().mapToLong(e -> e).sum();
    }

    private List<Long> countBizFinishedNum(DPFilterParamDto dpFilterParamDto) {
        // 1.统计各业务办理量注意要和x轴顺序一致
        String orgCode = getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 省、市、区县为按照行政区划进行编码的，公司的code为行政区划编码
        if (orgCode == null) {
            return Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
        }
        return commonMapper.countBizFinishedNumForDP(orgCode, dpFilterParamDto);
    }

    private 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;
    }

    public List<Map<String, Object>> equStateCount(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = this.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(boolMust);
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("EQU_STATE_COUNT").field("EQU_STATE");
        builder.aggregation(aggregationBuilder);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Terms terms = response.getAggregations().get("EQU_STATE_COUNT");
            Map<String, Long> dataMap = new HashMap<>();
            Long total = terms.getBuckets().stream().mapToLong(Terms.Bucket::getDocCount).sum();
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String category = bucket.getKeyAsString(); // 或者使用 bucket.getKey() 对于非字符串类型
                long docCount = bucket.getDocCount();
                dataMap.put(category, docCount);
            }
            /**
             * 3	报废
             * 1	在用
             * 2	停用
             * 4	注销
             * 0	未登记
             */
            for (int i = 0; i < 5; i++) {
                Map<String, Object> map = new HashMap();
                if (i == 0) {
                    map.put("name", "未登记");
                } else if (i == 1) {
                    map.put("name", "在用");
                } else if (i == 2) {
                    map.put("name", "停用");
                } else if (i == 3) {
                    map.put("name", "报废");
                } else if (i == 4) {
                    map.put("name", "注销");
                }
                map.put("value", dataMap.getOrDefault(String.valueOf(i), 0L));
                resultList.add(map);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return resultList;
    }

    public Map<String, Object> equStopStateCount(DPFilterParamDto dpFilterParamDto) {
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = this.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(boolMust);
        // 设备状态
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("EQU_STATE_COUNT").field("EQU_STATE")
                //设备类型
                .subAggregation(AggregationBuilders.terms("EQU_LIST_CODE_COUNT").field("EQU_LIST_CODE"));
        builder.aggregation(aggregationBuilder);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Terms terms = response.getAggregations().get("EQU_STATE_COUNT");
            Map<String, Long> dataMap = new HashMap<>();
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String category = bucket.getKeyAsString(); // 或者使用 bucket.getKey() 对于非字符串类型
                Terms subTerms = bucket.getAggregations().get("EQU_LIST_CODE_COUNT");
                for (Terms.Bucket subBucket : subTerms.getBuckets()) {
                    String subCategory = subBucket.getKeyAsString();
                    long docCount = subBucket.getDocCount();
                    dataMap.put(category + "#" + subCategory, docCount);
                }
            }
            /**
             * 2300 气瓶
             * 3000	电梯
             * 4000	起重机械
             * 2000	压力容器
             * 5000	场（厂）内专用机动车辆
             * 1000	锅炉
             * 8000	压力管道
             * F000	安全附件
             * 7000	压力管道元件
             * 9000	客运索道
             * 6000	大型游乐设施
             */
            /**
             * 2	停用
             * 4	注销
             * 3	报废
             */
            List<Map<String, Object>> legendDataList = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
                Map<String, Object> map = new HashMap();
                if (i == 0) {
                    map.put("dataKey", "stop");
                    map.put("name", "停用");
                } else if (i == 1) {
                    map.put("dataKey", "logout");
                    map.put("name", "注销");
                } else if (i == 2) {
                    map.put("dataKey", "scrap");
                    map.put("name", "报废");
                }
                legendDataList.add(map);
            }
            List<String> xDataList = Arrays.asList("气瓶", "电梯", "压力容器", "锅炉", "起重机械", "场(厂)内专用", "大型游乐设施", "压力管道", "客运索道");
            List<Object> stop = new ArrayList<>();
            List<Object> logout = new ArrayList<>();
            List<Object> scrap = new ArrayList<>();
            for (int i = 0; i < 9; i++) {
                if (i == 0) {
                    stop.add(dataMap.getOrDefault("2#2300", 0L));
                    logout.add(dataMap.getOrDefault("4#2300", 0L));
                    scrap.add(dataMap.getOrDefault("3#2300", 0L));
                } else if (i == 1) {
                    stop.add(dataMap.getOrDefault("2#3000", 0L));
                    logout.add(dataMap.getOrDefault("4#3000", 0L));
                    scrap.add(dataMap.getOrDefault("3#3000", 0L));
                } else if (i == 2) {
                    stop.add(dataMap.getOrDefault("2#2000", 0L) - dataMap.getOrDefault("2#2300", 0L));
                    logout.add(dataMap.getOrDefault("4#2000", 0L) - dataMap.getOrDefault("4#2300", 0L));
                    scrap.add(dataMap.getOrDefault("3#2000", 0L) - dataMap.getOrDefault("3#2300", 0L));
                } else if (i == 3) {
                    stop.add(dataMap.getOrDefault("2#1000", 0L));
                    logout.add(dataMap.getOrDefault("4#1000", 0L));
                    scrap.add(dataMap.getOrDefault("3#1000", 0L));
                } else if (i == 4) {
                    stop.add(dataMap.getOrDefault("2#4000", 0L));
                    logout.add(dataMap.getOrDefault("4#4000", 0L));
                    scrap.add(dataMap.getOrDefault("3#4000", 0L));
                } else if (i == 5) {
                    stop.add(dataMap.getOrDefault("2#5000", 0L));
                    logout.add(dataMap.getOrDefault("4#5000", 0L));
                    scrap.add(dataMap.getOrDefault("3#5000", 0L));
                } else if (i == 6) {
                    stop.add(dataMap.getOrDefault("2#6000", 0L));
                    logout.add(dataMap.getOrDefault("4#6000", 0L));
                    scrap.add(dataMap.getOrDefault("3#6000", 0L));
                } else if (i == 7) {
                    stop.add(dataMap.getOrDefault("2#8000", 0L));
                    logout.add(dataMap.getOrDefault("4#8000", 0L));
                    scrap.add(dataMap.getOrDefault("3#8000", 0L));
                } else if (i == 8) {
                    stop.add(dataMap.getOrDefault("2#9000", 0L));
                    logout.add(dataMap.getOrDefault("4#9000", 0L));
                    scrap.add(dataMap.getOrDefault("3#9000", 0L));
                }
            }

            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("legendData", legendDataList);
            returnMap.put("xdata", xDataList);
            returnMap.put("stop", stop);
            returnMap.put("logout", logout);
            returnMap.put("scrap", scrap);

            return returnMap;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public List<Map<String, Object>> maintenanceCountTopTen(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> list = dpStatisticsMapper.maintenanceCountTopTen(dpFilterParamDto);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> result = new HashMap<>();
            result.put("key", i);
            result.put("city", list.get(i).get("regionName"));
            result.put("count", list.get(i).get("count"));
            result.put("name", list.get(i).get("companyName"));
            resultList.add(result);
        }
        return resultList;
    }

    public Map<String, Object> maintenanceCount(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> list = dpStatisticsMapper.maintenanceCount(dpFilterParamDto);
        Map<String, Object> resultMap = new HashMap<>();
        List xList = new ArrayList();
        List yList = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            xList.add(list.get(i).get("regionName"));
            yList.add(list.get(i).get("count"));
        }
        resultMap.put("xdata", xList);
        resultMap.put("ydata", yList);
        return resultMap;
    }

    public Map<String, Object> cityBusinessCount(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regionModels = setRegionIfRootParent(dpFilterParamDto);
        Map<String, Object> resultMap = new HashMap<>();
        /**
         * 业务类型0告知管理，1使用登记，2变更登记，3停用启用，4注销报废
         */
        if ("0".equals(dpFilterParamDto.getBusinessKey())) {
            resultMap = noticeCount(resultMap, regionModels);
        } else if ("1".equals(dpFilterParamDto.getBusinessKey())) {
            resultMap = useCount(resultMap, regionModels);
        } else if ("2".equals(dpFilterParamDto.getBusinessKey())) {
            resultMap = changeCount(resultMap, regionModels);
        } else if ("3".equals(dpFilterParamDto.getBusinessKey())) {
            resultMap = disableCount(resultMap, regionModels);
        } else if ("4".equals(dpFilterParamDto.getBusinessKey())) {
            resultMap = cancelCount(resultMap, regionModels);
        }

        return resultMap;
    }

    private Map<String, Object> cancelCount(Map<String, Object> resultMap, List<RegionModel> regionModelList) {

        Map<String,Integer> countMap = new HashMap<>();
        List<Object> xDataList = new ArrayList<>();
        List<Object> yDataList = new ArrayList<>();
        List<Integer> regionCodeList = regionModelList.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeByCompanyCodes = commonMapper.getOrgCodeByCompanyCodes(regionCodeList);
        Map<String, String> companyMap = new HashMap<>();
        List<String> orgCodes = new ArrayList<>();
        orgCodeByCompanyCodes.stream().forEach(t->{
            companyMap.put(t.get("regionName")+"",t.get("orgCode"));
            if(StringUtils.isNotBlank(t.get("orgCode"))) {
                orgCodes.add(t.get("orgCode"));
            }
        });
        //注销报废
        List<Map<String,Object>> cancelCoountList = dpStatisticsMapper.cancelCountByOrgCodes(orgCodes);
        countByMap(countMap,cancelCoountList);

        for(int i = 0; i < regionModelList.size(); i++){
            AtomicInteger count = new AtomicInteger();
            xDataList.add(regionModelList.get(i).getRegionName());
            if(StringUtils.isNotEmpty(companyMap.get(regionModelList.get(i).getRegionName()))){
                int finalI = i;
                countMap.forEach((k, v)->{
                    if(k.startsWith(companyMap.get(regionModelList.get(finalI).getRegionName()))){
                        if(null != v){
                            count.addAndGet(v);
                        }
                    }
                });
            }
            yDataList.add(count);
        }

        resultMap.put("xdata", xDataList);
        resultMap.put("ydata", yDataList);
        return resultMap;
    }

    private Map<String, Object> disableCount(Map<String, Object> resultMap, List<RegionModel> regionModelList) {

        Map<String,Integer> countMap = new HashMap<>();
        List<Object> xDataList = new ArrayList<>();
        List<Object> yDataList = new ArrayList<>();
        List<Integer> regionCodeList = regionModelList.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeByCompanyCodes = commonMapper.getOrgCodeByCompanyCodes(regionCodeList);
        Map<String, String> companyMap = new HashMap<>();
        List<String> orgCodes = new ArrayList<>();
        orgCodeByCompanyCodes.stream().forEach(t->{
            companyMap.put(t.get("regionName")+"",t.get("orgCode"));
            if(StringUtils.isNotBlank(t.get("orgCode"))) {
                orgCodes.add(t.get("orgCode"));
            }
        });
        //启用停用
        List<Map<String,Object>> disableCountList = dpStatisticsMapper.disableCountByOrgCodes(orgCodes);
        countByMap(countMap,disableCountList);

        for(int i = 0; i < regionModelList.size(); i++){
            AtomicInteger count = new AtomicInteger();
            xDataList.add(regionModelList.get(i).getRegionName());
            if(StringUtils.isNotEmpty(companyMap.get(regionModelList.get(i).getRegionName()))){
                int finalI = i;
                countMap.forEach((k, v)->{
                    if(k.startsWith(companyMap.get(regionModelList.get(finalI).getRegionName()))){
                        if(null != v){
                            count.addAndGet(v);
                        }
                    }
                });
            }
            yDataList.add(count);
        }

        resultMap.put("xdata", xDataList);
        resultMap.put("ydata", yDataList);
        return resultMap;
    }

    private Map<String, Object> changeCount(Map<String, Object> resultMap, List<RegionModel> regionModelList) {

        Map<String,Integer> countMap = new HashMap<>();
        List<Object> xDataList = new ArrayList<>();
        List<Object> yDataList = new ArrayList<>();
        List<Integer> regionCodeList = regionModelList.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeByCompanyCodes = commonMapper.getOrgCodeByCompanyCodes(regionCodeList);
        Map<String, String> companyMap = new HashMap<>();
        List<String> orgCodes = new ArrayList<>();
        orgCodeByCompanyCodes.stream().forEach(t->{
            companyMap.put(t.get("regionName")+"",t.get("orgCode"));
            if(StringUtils.isNotBlank(t.get("orgCode"))) {
                orgCodes.add(t.get("orgCode"));
            }
        });

        //更名变更登记
        List<Map<String,Object>> changeNameList = dpStatisticsMapper.changeNameCountByOrgCodes(orgCodes);
        countByMap(countMap,changeNameList);
        //改造变更登记
        List<Map<String,Object>> reformList = dpStatisticsMapper.changeReformCountByOrgCodes(orgCodes);
        countByMap(countMap,reformList);
        //移装变更登记
        List<Map<String,Object>> transferList = dpStatisticsMapper.changeTransferCountByOrgCodes(orgCodes);
        countByMap(countMap,transferList);
        //单位变更登记
        List<Map<String,Object>> unitList = dpStatisticsMapper.changeUnitCountByOrgCodes(orgCodes);
        countByMap(countMap,unitList);
        //单位变更登记
        List<Map<String,Object>> vehicleList = dpStatisticsMapper.changeVehicleCountByOrgCodes(orgCodes);
        countByMap(countMap,vehicleList);

        for(int i = 0; i < regionModelList.size(); i++){
            AtomicInteger count = new AtomicInteger();
            xDataList.add(regionModelList.get(i).getRegionName());
            if(StringUtils.isNotEmpty(companyMap.get(regionModelList.get(i).getRegionName()))){
                int finalI = i;
                countMap.forEach((k, v)->{
                    if(k.startsWith(companyMap.get(regionModelList.get(finalI).getRegionName()))){
                        if(null != v){
                            count.addAndGet(v);
                        }
                    }
                });
            }
            yDataList.add(count);
        }

        resultMap.put("xdata", xDataList);
        resultMap.put("ydata", yDataList);

        return resultMap;
    }

    private Map<String, Object> useCount(Map<String, Object> resultMap, List<RegionModel> regionModelList) {

        Map<String,Integer> countMap = new HashMap<>();
        List<Object> xDataList = new ArrayList<>();
        List<Object> yDataList = new ArrayList<>();
        List<Integer> regionCodeList = regionModelList.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeByCompanyCodes = commonMapper.getOrgCodeByCompanyCodes(regionCodeList);
        Map<String, String> companyMap = new HashMap<>();
        List<String> orgCodes = new ArrayList<>();
        orgCodeByCompanyCodes.stream().forEach(t->{
            companyMap.put(t.get("regionName")+"",t.get("orgCode"));
            if(StringUtils.isNotBlank(t.get("orgCode"))) {
                orgCodes.add(t.get("orgCode"));
            }
        });
        //使用告知
        List<Map<String,Object>> useCountList = dpStatisticsMapper.useCountByOrgCodes(orgCodes);
        countByMap(countMap,useCountList);
        //车用气瓶使用告知
        List<Map<String, Object>> vehicleCountList = dpStatisticsMapper.vehicleCountByOrgCodes(orgCodes);
        countByMap(countMap,vehicleCountList);
        for(int i = 0; i < regionModelList.size(); i++){
            AtomicInteger count = new AtomicInteger();
            xDataList.add(regionModelList.get(i).getRegionName());
            if(StringUtils.isNotEmpty(companyMap.get(regionModelList.get(i).getRegionName()))){
                int finalI = i;
                countMap.forEach((k, v)->{
                    if(k.startsWith(companyMap.get(regionModelList.get(finalI).getRegionName()))){
                        if(null != v){
                            count.addAndGet(v);
                        }
                    }
                });
            }
            yDataList.add(count);
        }

        resultMap.put("xdata", xDataList);
        resultMap.put("ydata", yDataList);

        return resultMap;
    }

    private Map<String, Object> noticeCount(Map<String, Object> resultMap, List<RegionModel> regionModelList) {
        Map<String,Integer> countMap = new HashMap<>();
        List<Object> xDataList = new ArrayList<>();
        List<Object> yDataList = new ArrayList<>();
        List<Integer> regionCodeList = regionModelList.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeByCompanyCodes = commonMapper.getOrgCodeByCompanyCodes(regionCodeList);
        Map<String, String> companyMap = new HashMap<>();
        List<String> orgCodes = new ArrayList<>();
        orgCodeByCompanyCodes.stream().forEach(t->{
            companyMap.put(t.get("regionName")+"",t.get("orgCode"));
            if(StringUtils.isNotBlank(t.get("orgCode"))) {
                orgCodes.add(t.get("orgCode"));
            }
        });
        //安装告知
        List<Map<String,Object>> installCountList = dpStatisticsMapper.installCountByOrgCodes(orgCodes);
        countByMap(countMap,installCountList);
        //维修告知
        List<Map<String, Object>> maintenanceCountList = dpStatisticsMapper.maintenanceNoticeCountByOrgCodes(orgCodes);
        countByMap(countMap,maintenanceCountList);
        //改造告知
        List<Map<String, Object>> reformCountList = dpStatisticsMapper.reformCountByOrgCodes(orgCodes);
        countByMap(countMap,reformCountList);
        //移装告知
        List<Map<String, Object>> transferCountList = dpStatisticsMapper.transferCountByOrgCodes(orgCodes);
        countByMap(countMap,transferCountList);
        for(int i = 0; i < regionModelList.size(); i++){
            AtomicInteger count = new AtomicInteger();
            xDataList.add(regionModelList.get(i).getRegionName());
            if(StringUtils.isNotEmpty(companyMap.get(regionModelList.get(i).getRegionName()))){
                int finalI = i;
                countMap.forEach((k, v)->{
                    if(k.startsWith(companyMap.get(regionModelList.get(finalI).getRegionName()))){
                        if(null != v){
                            count.addAndGet(v);
                        }
                    }
                });
            }
            yDataList.add(count);
        }

        resultMap.put("xdata", xDataList);
        resultMap.put("ydata", yDataList);
        return resultMap;
    }

    private void countByMap(Map<String, Integer> countMap, List<Map<String, Object>> list) {
        for (int i = 0; i < list.size(); i++) {
            if (null == countMap.get(list.get(i).get("orgCode"))) {
                countMap.put(list.get(i).get("orgCode").toString(), Integer.valueOf(list.get(i).get("count")+""));
            } else {
                countMap.put(list.get(i).get("orgCode").toString(), countMap.get(list.get(i).get("orgCode")) + Integer.valueOf(list.get(i).get("count")+""));
            }
        }
    }

    public List<Map<String, Object>> getBusinessKey(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        /**
         * 告知管理、使用登记、变更登记、停用启用、注销报废
         */
        for (int i = 0; i < 5; i++) {
            Map<String, Object> result = new HashMap<>();
            if (i == 0) {
                result.put("key", i + "");
                result.put("name", "告知管理");
            } else if (i == 1) {
                result.put("key", i + "");
                result.put("name", "使用登记");
            } else if (i == 2) {
                result.put("key", i + "");
                result.put("name", "变更登记");
            } else if (i == 3) {
                result.put("key", i + "");
                result.put("name", "停用启用");
            } else if (i == 4) {
                result.put("key", i + "");
                result.put("name", "注销报废");
            }
            resultList.add(result);

        }

        return resultList;
    }

    public Map<String, Object> getNoticeEquCount(DPFilterParamDto dpFilterParamDto) {
        String startTime = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //安装告知
        List<Map<String, Object>> installlist = dpStatisticsMapper.installEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> installCountMap = new HashMap<>();
        countNoticEquList(installCountMap, installlist);
        //维修告知
        List<Map<String, Object>> maintenancelist = dpStatisticsMapper.maintenanceEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> maintenanceCountMap = new HashMap<>();
        countNoticEquList(maintenanceCountMap, maintenancelist);
        //改造告知
        List<Map<String, Object>> reformlist = dpStatisticsMapper.reformEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> reformCountMap = new HashMap<>();
        countNoticEquList(reformCountMap, reformlist);
        //移装告知
        List<Map<String, Object>> transferlist = dpStatisticsMapper.transferEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> transferCountMap = new HashMap<>();
        countNoticEquList(transferCountMap, transferlist);

        Map<String, Object> resultMap = new HashMap<>();
        List legendData = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map<String, String> map = new HashMap<>();
            if (i == 0) {
                map.put("dataKey", "installNotify");
                map.put("value", "安装告知");
            } else if (i == 1) {
                map.put("dataKey", "transformNotify");
                map.put("value", "改造告知");
            } else if (i == 2) {
                map.put("dataKey", "maintainNotify");
                map.put("value", "维修告知");
            } else if (i == 3) {
                map.put("dataKey", "transloadingNotify");
                map.put("value", "移装告知");
            }
            legendData.add(map);
        }
        resultMap.put("legendData", legendData);
        List<String> xDataList = Arrays.asList("气瓶", "电梯", "压力容器", "锅炉", "起重机械", "场(厂)内专用", "大型游乐设施", "压力管道", "客运索道");
        resultMap.put("xdata", xDataList);
        List installNotify = new ArrayList<>();
        List transformNotify = new ArrayList<>();
        List maintainNotify = new ArrayList<>();
        List transloadingNotify = new ArrayList<>();
        /**
         * 2300 气瓶
         * 3000	电梯
         * 2000	压力容器
         * 1000	锅炉
         * 4000	起重机械
         * 5000	场（厂）内专用机动车辆
         * 6000	大型游乐设施
         * 8000	压力管道
         * 9000	客运索道
         */
        for (int i = 0; i < xDataList.size(); i++) {
            if (i == 0) {
                installNotify.add(installCountMap.getOrDefault("2300", 0));
                transformNotify.add(reformCountMap.getOrDefault("2300", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("2300", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("2300", 0));
            } else if (i == 1) {
                installNotify.add(installCountMap.getOrDefault("3000", 0));
                transformNotify.add(reformCountMap.getOrDefault("3000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("3000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("3000", 0));
            } else if (i == 2) {
                installNotify.add(installCountMap.getOrDefault("2000", 0));
                transformNotify.add(reformCountMap.getOrDefault("2000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("2000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("2000", 0));
            } else if (i == 3) {
                installNotify.add(installCountMap.getOrDefault("1000", 0));
                transformNotify.add(reformCountMap.getOrDefault("1000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("1000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("1000", 0));
            } else if (i == 4) {
                installNotify.add(installCountMap.getOrDefault("4000", 0));
                transformNotify.add(reformCountMap.getOrDefault("4000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("4000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("4000", 0));
            } else if (i == 5) {
                installNotify.add(installCountMap.getOrDefault("5000", 0));
                transformNotify.add(reformCountMap.getOrDefault("5000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("5000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("5000", 0));
            } else if (i == 6) {
                installNotify.add(installCountMap.getOrDefault("6000", 0));
                transformNotify.add(reformCountMap.getOrDefault("6000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("6000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("6000", 0));
            } else if (i == 7) {
                installNotify.add(installCountMap.getOrDefault("8000", 0));
                transformNotify.add(reformCountMap.getOrDefault("8000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("8000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("8000", 0));
            } else if (i == 8) {
                installNotify.add(installCountMap.getOrDefault("9000", 0));
                transformNotify.add(reformCountMap.getOrDefault("9000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("9000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("9000", 0));
            }
        }
        resultMap.put("installNotify", installNotify);
        resultMap.put("transformNotify", transformNotify);
        resultMap.put("maintainNotify", maintainNotify);
        resultMap.put("transloadingNotify", transloadingNotify);
        return resultMap;
    }

    private void countNoticEquList(Map<String, Integer> countMap, List<Map<String, Object>> list) {
        for (int i = 0; i < list.size(); i++) {
            if ("2300".equals(list.get(i).get("equCategory"))) {
                if (null == countMap.get("2300")) {
                    countMap.put("2300", Integer.valueOf(list.get(i).get("count") + ""));
                } else {
                    countMap.put("2300", countMap.get("2300") + Integer.valueOf(list.get(i).get("count") + ""));
                }
            } else {
                if (null == countMap.get(list.get(i).get("equList").toString())) {
                    countMap.put(list.get(i).get("equList").toString(), Integer.valueOf(list.get(i).get("count") + ""));
                } else {
                    countMap.put(list.get(i).get("equList").toString(), countMap.get(list.get(i).get("equList").toString()) + Integer.valueOf(list.get(i).get("count") + ""));
                }
            }
        }
    }

    public Map<String, Object> getRegEquCount(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> resultMap = new HashMap<>();
        String startTime = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //使用登记
        List<Map<String, Object>> uselist = dpStatisticsMapper.useEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> useCountMap = new HashMap<>();
        countNoticEquList(useCountMap, uselist);
        //气瓶使用登记
        List<Map<String, Object>> vehicleList = dpStatisticsMapper.vehicleEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> vehicleCountMap = new HashMap<>();
        countNoticEquList(vehicleCountMap, vehicleList);
        //改造变更登记
        List<Map<String, Object>> changeReformList = dpStatisticsMapper.changeReformEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> changeReformCountMap = new HashMap<>();
        countNoticEquList(changeReformCountMap, changeReformList);
        //移装变更登记
        List<Map<String, Object>> changeTransferList = dpStatisticsMapper.changeTransferEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> changeTransferCountMap = new HashMap<>();
        countNoticEquList(changeTransferCountMap, changeTransferList);
        //单位变更登记
        List<Map<String, Object>> changeUnitList = dpStatisticsMapper.changeUnitEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> changeUnitCountMap = new HashMap<>();
        countNoticEquList(changeUnitCountMap, changeUnitList);

        List legendData = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map<String, String> map = new HashMap<>();
            if (i == 0) {
                map.put("dataKey", "useRegistration");
                map.put("value", "使用登记");
            } else if (i == 1) {
                map.put("dataKey", "modificateModifyRegistration");
                map.put("value", "改造变更登记");
            } else if (i == 2) {
                map.put("dataKey", "transloadingModifyRegistration");
                map.put("value", "移装变更登记");
            } else if (i == 3) {
                map.put("dataKey", "unitModifyRegistration");
                map.put("value", "单位变更登记");
            }
            legendData.add(map);
        }
        resultMap.put("legendData", legendData);
        List<String> xDataList = Arrays.asList("气瓶", "电梯", "压力容器", "锅炉", "起重机械", "场(厂)内专用", "大型游乐设施", "压力管道", "客运索道");
        resultMap.put("xdata", xDataList);
        List useRegistration = new ArrayList<>();
        List modificateModifyRegistration = new ArrayList<>();
        List transloadingModifyRegistration = new ArrayList<>();
        List unitModifyRegistration = new ArrayList<>();
        for (int i = 0; i < xDataList.size(); i++) {
            if (i == 0) {
                useRegistration.add(vehicleCountMap.getOrDefault("2300", 0));
                modificateModifyRegistration.add(changeReformCountMap.getOrDefault("2300", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("2300", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("2300", 0));
            } else if (i == 1) {
                useRegistration.add(useCountMap.getOrDefault("3000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("3000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("3000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("3000", 0));
            } else if (i == 2) {
                useRegistration.add(useCountMap.getOrDefault("2000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("2000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("2000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("2000", 0));
            } else if (i == 3) {
                useRegistration.add(useCountMap.getOrDefault("1000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("1000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("1000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("1000", 0));
            } else if (i == 4) {
                useRegistration.add(useCountMap.getOrDefault("4000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("4000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("4000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("4000", 0));
            } else if (i == 5) {
                useRegistration.add(useCountMap.getOrDefault("5000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("5000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("5000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("5000", 0));
            } else if (i == 6) {
                useRegistration.add(useCountMap.getOrDefault("6000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("6000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("6000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("6000", 0));
            } else if (i == 7) {
                useRegistration.add(useCountMap.getOrDefault("8000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("8000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("8000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("8000", 0));
            } else if (i == 8) {
                useRegistration.add(useCountMap.getOrDefault("9000", 0));
                modificateModifyRegistration.add(changeTransferCountMap.getOrDefault("9000", 0));
                transloadingModifyRegistration.add(changeTransferCountMap.getOrDefault("9000", 0));
                unitModifyRegistration.add(changeUnitCountMap.getOrDefault("9000", 0));
            }
        }
        resultMap.put("useRegistration", useRegistration);
        resultMap.put("modificateModifyRegistration", modificateModifyRegistration);
        resultMap.put("transloadingModifyRegistration", transloadingModifyRegistration);
        resultMap.put("unitModifyRegistration", unitModifyRegistration);

        return resultMap;

    }

    public List<Map<String, Object>> dataStatisticByReginCode(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regionModels = setRegionIfRootParent(dpFilterParamDto);
        List<Map<String, Object>> result = regionModels.parallelStream().map(r -> {
            DPFilterParamDto filterParamDto = new DPFilterParamDto();
            filterParamDto.setCityCode(r.getRegionCode().toString());
            Map<String, Object> itemResult = staticsCenterMapCountDataForRegin(filterParamDto);
            if (itemResult == null) {
                itemResult = new HashMap<>();
            }
            itemResult.put(REGION_CODE, r.getRegionCode());
            itemResult.put(REGION_NAME, r.getRegionName());
            return itemResult;
        }).collect(Collectors.toList());
        return result;
    }


    private Map<String, Object> staticsCenterMapCountDataForRegin(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        String orgCode = regionCodeOrgCodeMap.get(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            orgCode = getAndSetOrgCode(dpFilterParamDto.getCityCode());
            if (orgCode == null) {
                result.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), 0);
                result.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), 0);
                return result;
            }
            regionCodeOrgCodeMap.put(dpFilterParamDto.getCityCode(), orgCode);
        }
        Long certificateCount = jgUseRegistrationManageMapper.countCertificateByReginCode(orgCode);
        Long deviceCount = countEquipByReginCode(orgCode);
        result.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), certificateCount);
        result.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), deviceCount);
        return result;
    }

    private Long countEquipByReginCode(String orgCode) {
        long num = 0;
        CountRequest request = new CountRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 纳管状态为已纳管
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", true));
        request.query(boolMust);
        try {
            CountResponse response = restHighLevelClient.count(request, RequestOptions.DEFAULT);
            num = response.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return num;
    }

    public Map<String, Object> dataStatisticCountByReginCode(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, Object>> mapList = this.dataStatisticByReginCode(dpFilterParamDto);
        if (ObjectUtils.isEmpty(mapList)) {
            resultMap.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), 0);
            resultMap.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), 0);
            return resultMap;
        }
        long certificateCount = mapList.stream().mapToLong(x -> (Long) x.get("certificateCount")).sum();
        long deviceCount = mapList.stream().mapToLong(x -> (Long) x.get("deviceCount")).sum();
        resultMap.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), certificateCount);
        resultMap.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), deviceCount);
        return resultMap;
    }

    public Map<String, Object> newRegEquCount(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("dataKey", "newRegisterEq");
        map.put("value", "新增登记设备");
        List<Map<String, Object>> legendData = new ArrayList<>();
        legendData.add(map);
        resultMap.put("legendData", legendData);
        List xDataList = new ArrayList<>();
        List newRegisterEq = new ArrayList<>();
        Map<String, Object> useCountMap = new HashMap<>();
        Map<String, Object> vehicleCountMap = new HashMap<>();
        if ("month".equals(dpFilterParamDto.getSearchType())) {
            List<Map<String, Object>> useCountList = dpStatisticsMapper.newRegEquCountByMonth(dpFilterParamDto.getCityCode());
            List<Map<String, Object>> vehicleCountList = dpStatisticsMapper.newVehicleEquCountByMonth(dpFilterParamDto.getCityCode());
            for (int i = 0; i < useCountList.size(); i++) {
                useCountMap.put(useCountList.get(i).getOrDefault("date_format", "") + "", Integer.valueOf(useCountList.get(i).getOrDefault("count", 0) + ""));
            }
            for (int i = 0; i < vehicleCountList.size(); i++) {
                vehicleCountMap.put(vehicleCountList.get(i).getOrDefault("date_format", "") + "", Integer.valueOf(vehicleCountList.get(i).getOrDefault("count", 0) + ""));
            }
            for (int i = 0; i < LocalDate.now().getDayOfMonth(); i++) {
                xDataList.add(LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                newRegisterEq.add(Integer.valueOf(useCountMap.getOrDefault(LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), 0) + "")
                        + Integer.valueOf(vehicleCountMap.getOrDefault(LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), 0) + ""));
            }

        } else if ("year".equals(dpFilterParamDto.getSearchType())) {
            List<Map<String, Object>> useCountList = dpStatisticsMapper.newRegEquCountByYear(dpFilterParamDto.getCityCode());
            List<Map<String, Object>> vehicleCountList = dpStatisticsMapper.newVehicleEquCountByYear(dpFilterParamDto.getCityCode());
            for (int i = 0; i < useCountList.size(); i++) {
                useCountMap.put(useCountList.get(i).getOrDefault("date_format", "") + "", Integer.valueOf(useCountList.get(i).getOrDefault("count", 0) + ""));
            }
            for (int i = 0; i < vehicleCountList.size(); i++) {
                vehicleCountMap.put(vehicleCountList.get(i).getOrDefault("date_format", "") + "", Integer.valueOf(vehicleCountList.get(i).getOrDefault("count", 0) + ""));
            }
            for (int i = 0; i < LocalDate.now().getMonth().getValue(); i++) {
                xDataList.add(LocalDate.now().minusMonths(i).format(DateTimeFormatter.ofPattern("yyyy-MM")));
                newRegisterEq.add(Integer.valueOf(useCountMap.getOrDefault(LocalDate.now().minusMonths(i).format(DateTimeFormatter.ofPattern("yyyy-MM")), 0) + "")
                        + Integer.valueOf(vehicleCountMap.getOrDefault(LocalDate.now().minusMonths(i).format(DateTimeFormatter.ofPattern("yyyy-MM")), 0) + ""));
            }

        }
        Collections.reverse(xDataList);
        Collections.reverse(newRegisterEq);
        resultMap.put("xdata", xDataList);
        resultMap.put("newRegisterEq", newRegisterEq);
        return resultMap;
    }

    public List<Map<String, Object>> newRegCount(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        //年使用登记设备
        List<Map<String, Object>> useEquCountListYear = dpStatisticsMapper.newRegEquCountByYear(dpFilterParamDto.getCityCode());
        //年气瓶使用登记设备
        List<Map<String, Object>> vehicleEquCountListYear = dpStatisticsMapper.newVehicleEquCountByYear(dpFilterParamDto.getCityCode());
        //月使用登记设备
        List<Map<String, Object>> useEquCountListMonth = dpStatisticsMapper.newRegEquCountByMonth(dpFilterParamDto.getCityCode());
        //月气瓶使用登记设备
        List<Map<String, Object>> vehicleEquCountListMonth = dpStatisticsMapper.newVehicleEquCountByMonth(dpFilterParamDto.getCityCode());
        //年气瓶使用登记
        String vehicleCountYear = dpStatisticsMapper.newVehicleCountByYear(dpFilterParamDto.getCityCode());
        //月气瓶使用登记
        String vehicleCountListMonth = dpStatisticsMapper.newVehicleCountByMonth(dpFilterParamDto.getCityCode());
        /**
         * [ { "name": "本年新增登记", "value": 52 }, { "name": "本年新增设备", "value": 83 },
         * { "name": "本月新增登记", "value": 16 }, { "name": "本月新增设备", "value": 50 } ]
         */
        int useYear = 0;
        int useMonth = 0;
        int usrEqYear = 0;
        int usrEqMonth = 0;
        //本年新增登记
        for (int i = 0; i < useEquCountListYear.size(); i++) {
            useYear += Integer.valueOf(useEquCountListYear.get(i).getOrDefault("count", 0) + "");
            usrEqYear += Integer.valueOf(useEquCountListYear.get(i).getOrDefault("count", 0) + "");
        }
        useYear += StringUtils.isBlank(vehicleCountYear) ? 0 : Integer.valueOf(vehicleCountYear);

        //本年新增设备
        for (int i = 0; i < vehicleEquCountListYear.size(); i++) {
            usrEqYear += Integer.valueOf(vehicleEquCountListYear.get(i).getOrDefault("count", 0) + "");
        }

        //本月新增登记
        for (int i = 0; i < useEquCountListMonth.size(); i++) {
            useMonth += Integer.valueOf(useEquCountListMonth.get(i).getOrDefault("count", 0) + "");
            usrEqMonth += Integer.valueOf(useEquCountListMonth.get(i).getOrDefault("count", 0) + "");
        }
        useMonth += StringUtils.isBlank(vehicleCountListMonth) ? 0 : Integer.valueOf(vehicleCountListMonth);
        //本月新增设备
        for (int i = 0; i < vehicleEquCountListMonth.size(); i++) {
            usrEqMonth += Integer.valueOf(vehicleEquCountListMonth.get(i).getOrDefault("count", 0) + "");
        }


        for (int i = 0; i < 4; i++) {
            Map<String, Object> map = new HashMap<>();
            if (i == 0) {
                map.put("name", "本年新增登记");
                map.put("value", useYear);
            } else if (i == 1) {
                map.put("name", "本年新增设备");
                map.put("value", usrEqYear);
            } else if (i == 2) {
                map.put("name", "本月新增登记");
                map.put("value", useMonth);
            } else if (i == 3) {
                map.put("name", "本月新增设备");
                map.put("value", usrEqMonth);
            }
            resultList.add(map);
        }

        return resultList;
    }
}
