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

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.dto.CountDto;
import com.yeejoin.amos.boot.module.common.api.dto.DPFilterParamDto;
import com.yeejoin.amos.boot.module.common.api.dto.DPFilterParamForDetailDto;
import com.yeejoin.amos.boot.module.common.api.dto.LegendDataDto;
import com.yeejoin.amos.boot.module.common.api.enums.BusinessTypeEnum;
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.statistics.api.mapper.JGStatisticsMapper;
import com.yeejoin.amos.boot.module.statistics.api.mapper.ZLStatisticsMapper;
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.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzsUserInfoMapper;
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.stereotype.Service;
import org.springframework.util.ObjectUtils;

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.ThreadLocalRandom;
import java.util.function.Function;
import java.util.stream.Collectors;

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

    /**
     * 压力容器设备种类
     */
    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";


    private JgUseRegistrationMapper useRegistrationMapper;

    private JgEnableDisableMapper enableDisableMapper;

    private JgScrapCancelMapper scrapCancelMapper;

    private RestHighLevelClient restHighLevelClient;

    private TzBaseEnterpriseInfoMapper enterpriseInfoMapper;

    private CommonMapper commonMapper;

    private TzsUserInfoMapper userInfoMapper;

    private ZLStatisticsMapper zlStatisticsMapper;

    private JGStatisticsMapper jgStatisticsMapper;

    private JgUseRegistrationManageMapper jgUseRegistrationManageMapper;

    private StCommonServiceImpl stCommonService;

    public JGDPStatisticsServiceImpl(JgUseRegistrationMapper useRegistrationMapper, JgEnableDisableMapper enableDisableMapper, JgScrapCancelMapper scrapCancelMapper, RestHighLevelClient restHighLevelClient, TzBaseEnterpriseInfoMapper enterpriseInfoMapper, CommonMapper commonMapper, TzsUserInfoMapper userInfoMapper, ZLStatisticsMapper zlStatisticsMapper, JGStatisticsMapper jgStatisticsMapper, JgUseRegistrationManageMapper jgUseRegistrationManageMapper, StCommonServiceImpl stCommonService) {
        this.useRegistrationMapper = useRegistrationMapper;
        this.enableDisableMapper = enableDisableMapper;
        this.scrapCancelMapper = scrapCancelMapper;
        this.restHighLevelClient = restHighLevelClient;
        this.enterpriseInfoMapper = enterpriseInfoMapper;
        this.commonMapper = commonMapper;
        this.userInfoMapper = userInfoMapper;
        this.zlStatisticsMapper = zlStatisticsMapper;
        this.jgStatisticsMapper = jgStatisticsMapper;
        this.jgUseRegistrationManageMapper = jgUseRegistrationManageMapper;
        this.stCommonService = stCommonService;
    }

    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(StCommonServiceImpl.getEquipmentCategory()));
        //2.3 y轴数据构造
        this.buildYData(result, dpFilterParamDto, StCommonServiceImpl.getEquipmentCategory());
        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(cn.hutool.core.date.DateUtil.offsetDay(new Date(), -30).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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (StringUtils.isEmpty(orgCode)) {
            return new HashMap<>();
        }
        // 1.气瓶数量统计
        long cylinderNum = stCommonService.staticsCenterMapCountDataForCylinder(result, orgCode);
        //1.8大类设备数量统计,压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
        stCommonService.staticsCenterMapCountDataForEquip(result, cylinderNum, orgCode);
        //2.压力管道长度统计
        stCommonService.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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (StringUtils.isEmpty(orgCode)) {
            return new HashMap<>();
        }
        // 0. 气瓶数量统计
        long cylinderNum = stCommonService.staticsCenterMapCountDataForCylinder(result, orgCode);
        // 1. 8大类设备数量统计,压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
        stCommonService.staticsCenterMapCountDataForEquip(result, cylinderNum, orgCode);
        // 2. 压力管道长度统计
        stCommonService.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());
    }


    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 = stCommonService.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 void setCompanyDataBatch(List<Map<String, Object>> result) {
        List<CountDto> countDtos = enterpriseInfoMapper.countByUnitTypeAndOrgCodeNoParam();
        result.forEach(m -> {
            String cityCode = m.get("cityCode").toString();
            String orgCode = StCommonServiceImpl.getRegionCodeOrgCodeMap().get(cityCode);
            if (StringUtils.isNotEmpty(orgCode)) {
                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);
    }


    public Map<String, Object> querySafetyIndex(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        int riskScore = ThreadLocalRandom.current().nextInt(88, 93);
        result.put("riskScore", riskScore);
        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, 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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 只统计已纳管的设备
        boolMust.must(QueryBuilders.termsQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
        // 设备状态过滤
        boolMust.must(QueryBuilders.termsQuery("EQU_STATE", Arrays.asList(states)));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        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) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.staticsCenterMapCountDateOverdue(dpFilterParamDto));
        countDto.setLabel("超期未检");
        return countDto;
    }

    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 CountDto getYellowStatusEquip(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.staticsCenterMapCountDateTemporary(dpFilterParamDto));
        countDto.setLabel("临期告警");
        return countDto;
    }

    /**
     * 临期检验设备数统计
     *
     * @param dpFilterParamDto 过滤条件
     * @return 临期设备的数量
     */
    private Long staticsCenterMapCountDateTemporary(DPFilterParamDto dpFilterParamDto) {
        long num;
        CountRequest request = new CountRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 只统计已纳管设备
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
        // 且下次检验日期大于等于当天
        long currentDayTime = DateUtil.parse(DateUtil.today(), "yyy-MM-dd").getTime();
        // 且查询 下次检验日期 <= 当前天+30天 极为临期
        long currentDayAfter30DayTime = DateUtil.offsetDay(DateUtil.parse(DateUtil.today(), "yyy-MM-dd"), 30).getTime();
        boolMust.must(QueryBuilders.rangeQuery("NEXT_INSPECT_DATE").gte(currentDayTime).lte(currentDayAfter30DayTime));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        request.query(boolMust);
        try {
            CountResponse response = restHighLevelClient.count(request, RequestOptions.DEFAULT);
            num = response.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return num;
    }


    /**
     * 超期检验设备数统计
     *
     * @param dpFilterParamDto 过滤条件
     * @return 超期设备的数量
     */
    private Long staticsCenterMapCountDateOverdue(DPFilterParamDto dpFilterParamDto) {
        long num = 0;
        CountRequest request = new CountRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 只统计已纳管设备
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
        // 查询下次检验日期小于当前天的设备，即为超期检验超期设备
        long currentDayTime = DateUtil.parse(DateUtil.now(), "yyy-MM-dd").getTime();
        boolMust.must(QueryBuilders.rangeQuery("NEXT_INSPECT_DATE").lt(currentDayTime));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        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 getGreyStatusEquip(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countEquipNumFromES(dpFilterParamDto, EquimentEnum.BAOFEI.getCode(), EquimentEnum.ZHUXIAO.getCode(), EquimentEnum.TINGYONG.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(this.countCompanyByOperatingStatus(dpFilterParamDto, "停业"));
        countDto.setLabel("停业");
        return countDto;
    }


    private CountDto getRedStatusCompany(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countCompanyForCertDateTimeOut(dpFilterParamDto));
        countDto.setLabel("许可超期");
        return countDto;
    }

    private CountDto getYellowStatusCompany(DPFilterParamDto dpFilterParamDto) {
        CountDto countDto = new CountDto();
        countDto.setLongValue(this.countCompanyForCertDateTemporary(dpFilterParamDto));
        countDto.setLabel("许可临期");
        return countDto;
    }

    private long countCompanyForCertDateTemporary(DPFilterParamDto dpFilterParamDto) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        // 临期6个月
        String limitDate = DateUtil.offset(DateUtil.date(), DateField.DAY_OF_MONTH, 6).toDateStr();
        return zlStatisticsMapper.countCompanyForCertDateTemporary(dpFilterParamDto, orgCode, limitDate);
    }

    private long countCompanyForCertDateTimeOut(DPFilterParamDto dpFilterParamDto) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        String limitDate = DateUtil.today();
        return zlStatisticsMapper.countCompanyForCertDateTimeOut(dpFilterParamDto, orgCode, limitDate);
    }


    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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        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("percentData", this.calEveryPercent(dpFilterParamDto, ydata));
        result.put("completionRate", this.calPercentForBizCycleData(dpFilterParamDto, allFinishedCount));
        return result;
    }

    private List<String> calEveryPercent(DPFilterParamDto dpFilterParamDto, List<Long> everyFinished) {
        List<Long> everyInFlow = countBizDataInFlowing(dpFilterParamDto);
        List<String> percentArray = new ArrayList<>();
        for (int i = 0; i < everyInFlow.size(); i++) {
            Long flowIng = everyInFlow.get(i);
            Long finished = everyFinished.get(i);
            BigDecimal finishedBig = new BigDecimal(finished.toString());
            BigDecimal flowIngBig = new BigDecimal(flowIng.toString());
            BigDecimal all = flowIngBig.add(finishedBig);
            if (all.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal percent = finishedBig.divide(all, 2, RoundingMode.HALF_UP);
                BigDecimal percentX100 = percent.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP);
                percentArray.add(percentX100.toPlainString());
            } else {
                percentArray.add("0");
            }
        }
        return percentArray;
    }

    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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return 0L;
        }
        List<Long> inFlowingForDP = commonMapper.countAllInFlowingForDPNoFinishedBizData(orgCode, dpFilterParamDto);
        return inFlowingForDP.stream().mapToLong(e -> e).sum();
    }

    private List<Long> countBizDataInFlowing(DPFilterParamDto dpFilterParamDto) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
        }
        return commonMapper.countAllInFlowingForDPNoFinishedBizData(orgCode, dpFilterParamDto);
    }

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

    public List<Map<String, Object>> equStateCount(DPFilterParamDto dpFilterParamDto) {
        List<Map<String, Object>> resultList;
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return this.setDefaultEquStateCount();
        }
        // 按照管辖机构区域信息模糊查询
        boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
        // 只统计已纳管设备
        boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(boolMust);
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("EQU_STATE_COUNT").field("EQU_STATE").size(20);
        builder.aggregation(aggregationBuilder);
        builder.size(0);
        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();
                long docCount = bucket.getDocCount();
                dataMap.put(category, docCount);
            }
            resultList = Arrays.stream(EquimentEnum.values()).filter(e -> e.getCode() > 0).map(e -> {
                Map<String, Object> map = new HashMap<>();
                map.put("name", e.getName());
                map.put("value", dataMap.getOrDefault(e.getCode().toString(), 0L));
                return map;
            }).collect(Collectors.toList());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return resultList;
    }

    private List<Map<String, Object>> setDefaultEquStateCount() {
        return Arrays.stream(EquimentEnum.values()).filter(e -> e.getCode() > 0).map(e -> {
            Map<String, Object> map = new HashMap<>();
            map.put("name", e.getName());
            map.put("value", 0L);
            return map;
        }).collect(Collectors.toList());
    }

    public Map<String, Object> equStopStateCount(DPFilterParamDto dpFilterParamDto) {
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        Map<String, Long> dataMap = new HashMap<>();
        if (orgCode != null) {
            // 按照管辖机构区域信息模糊查询
            boolMust.must(QueryBuilders.wildcardQuery("ORG_BRANCH_CODE.keyword", QueryParser.escape(orgCode) + "*"));
            // 只统计已纳管设备
            boolMust.must(QueryBuilders.termQuery("IS_INTO_MANAGEMENT", Boolean.TRUE));
            // 且8大类，目的去掉脏数据
            boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
            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");

                for (Terms.Bucket bucket : terms.getBuckets()) {
                    // 或者使用 bucket.getKey() 对于非字符串类型
                    String category = bucket.getKeyAsString();
                    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);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        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("value", "停用");
            } else if (i == 1) {
                map.put("dataKey", "logout");
                map.put("value", "注销");
            } else {
                map.put("dataKey", "scrap");
                map.put("value", "报废");
            }
            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 {
                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;
    }

    public List<Map<String, Object>> maintenanceCountTopTen(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regionModels = stCommonService.setRegionIfRootParent(dpFilterParamDto);
        List<Integer> regionCodeList = regionModels.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        Map<Integer, RegionModel> regionMap = regionModels.stream().collect(Collectors.toMap(RegionModel::getRegionCode, Function.identity()));
        List<Map<String, Object>> list = jgStatisticsMapper.maintenanceCountTopTen(dpFilterParamDto, regionCodeList);
        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", regionMap.get(Integer.valueOf(list.get(i).get("companyCode") + "")).getRegionName());
            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<RegionModel> regionModels = stCommonService.setRegionIfRootParent(dpFilterParamDto);
        List<Integer> regionCodeList = regionModels.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        Map<Integer, RegionModel> regionMap = regionModels.stream().collect(Collectors.toMap(RegionModel::getRegionCode, Function.identity()));
        List<Map<String, Object>> list = jgStatisticsMapper.maintenanceCount(dpFilterParamDto, regionCodeList);
        Map<String, Object> resultMap = new HashMap<>();
        List xList = new ArrayList();
        List yList = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            xList.add(regionMap.get(Integer.valueOf(list.get(i).get("companyCode") + "")).getRegionName());
            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 = stCommonService.setRegionIfRootParentAndNoAccessIf3Level(dpFilterParamDto);
        Map<String, Object> resultMap = new HashMap<>();
        String orgCodeP = stCommonService.getAndSetOrgCode(dpFilterParamDto);
        if (orgCodeP == null) {
            return new HashMap<>();
        }
        List<CountDto> countDtos = getDealDayAvgList(dpFilterParamDto, orgCodeP);
        List<String> xData = new ArrayList<>();
        List<String> yData = new ArrayList<>();
        regionModels.forEach(r -> {
            xData.add(r.getRegionName());
            String orgCode = stCommonService.getAndSetOrgCode(r.getRegionCode().toString());
            yData.add(this.avgAndSumDealDate(countDtos.stream().filter(c -> c.getKeyStr().contains(orgCode)).collect(Collectors.toList())));
        });
        resultMap.put("xdata", xData);
        resultMap.put("ydata", yData);
        return resultMap;
    }

    private String avgAndSumDealDate(List<CountDto> collect) {
        BigDecimal sum = collect.stream().map(c -> new BigDecimal(c.getStrValue())).reduce(BigDecimal.ZERO, BigDecimal::add);
        if(collect.isEmpty()){
            return "0";
        }
        return sum.divide(BigDecimal.valueOf(collect.size()), 1, RoundingMode.HALF_UP).toPlainString();
    }

    private List<CountDto> getDealDayAvgList(DPFilterParamDto dpFilterParamDto, String orgCode) {
        List<CountDto> countDtos = new ArrayList<>();
        // 业务类型0告知管理，1使用登记，2变更登记，3停用启用，4注销报废
        if ("0".equals(dpFilterParamDto.getBusinessKey())) {
            countDtos = noticeCount(dpFilterParamDto, orgCode);
        } else if ("1".equals(dpFilterParamDto.getBusinessKey())) {
            countDtos = useCount(dpFilterParamDto, orgCode);
        } else if ("2".equals(dpFilterParamDto.getBusinessKey())) {
            countDtos = changeCount(dpFilterParamDto, orgCode);
        } else if ("3".equals(dpFilterParamDto.getBusinessKey())) {
            countDtos = disableCount(dpFilterParamDto, orgCode);
        } else if ("4".equals(dpFilterParamDto.getBusinessKey())) {
            countDtos = cancelCount(dpFilterParamDto, orgCode);
        }
        return countDtos;
    }

    private List<CountDto> cancelCount(DPFilterParamDto dpFilterParamDto, String orgCode) {
        //注销报废
        return jgStatisticsMapper.queryCancelAvgDayByReceiveCompany(dpFilterParamDto, orgCode);
    }

    private List<CountDto> disableCount(DPFilterParamDto dpFilterParamDto, String orgCode) {
        //启用停用
        return jgStatisticsMapper.queryDisableAvgDayByReceiveCompany(dpFilterParamDto, orgCode);
    }

    private List<CountDto> changeCount(DPFilterParamDto dpFilterParamDto, String orgCode) {
        //更名变更登记、改造变更登记、移装变更登记、单位变更登记、气瓶单位变更登记
        return jgStatisticsMapper.queryChangeAvgDayByReceiveCompany(dpFilterParamDto, orgCode);
    }

    private List<CountDto> useCount(DPFilterParamDto dpFilterParamDto, String orgCode) {
        //使用登记、车用气瓶使用登记
        return jgStatisticsMapper.queryUseAvgDayByReceiveCompany(dpFilterParamDto, orgCode);
    }

    private List<CountDto> noticeCount(DPFilterParamDto dpFilterParamDto, String orgCode) {
        //安装告知、维修告知、改造告知、移装告知
        return jgStatisticsMapper.queryNoticeAvgDayByReceiveCompany(dpFilterParamDto, orgCode);
    }

    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 = jgStatisticsMapper.installEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> installCountMap = new HashMap<>();
        countNoticEquList(installCountMap, installlist);
        //维修告知
        List<Map<String, Object>> maintenancelist = jgStatisticsMapper.maintenanceEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> maintenanceCountMap = new HashMap<>();
        countNoticEquList(maintenanceCountMap, maintenancelist);
        //改造告知
        List<Map<String, Object>> reformlist = jgStatisticsMapper.reformEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> reformCountMap = new HashMap<>();
        countNoticEquList(reformCountMap, reformlist);
        //移装告知
        List<Map<String, Object>> transferlist = jgStatisticsMapper.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("3000", 0));
                transformNotify.add(reformCountMap.getOrDefault("3000", 0));
                maintainNotify.add(maintenanceCountMap.getOrDefault("3000", 0));
                transloadingNotify.add(transferCountMap.getOrDefault("3000", 0));
            } else if (i == 1) {
                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 == 2) {
                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 == 3) {
                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 == 4) {
                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 == 5) {
                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 == 6) {
                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 == 7) {
                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 = jgStatisticsMapper.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 = jgStatisticsMapper.changeReformEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> changeReformCountMap = new HashMap<>();
        countNoticEquList(changeReformCountMap, changeReformList);
        //移装变更登记
        List<Map<String, Object>> changeTransferList = jgStatisticsMapper.changeTransferEquCount(dpFilterParamDto.getCityCode(), startTime);
        Map<String, Integer> changeTransferCountMap = new HashMap<>();
        countNoticEquList(changeTransferCountMap, changeTransferList);
        //单位变更登记
        List<Map<String, Object>> changeUnitList = jgStatisticsMapper.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(useCountMap.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 = stCommonService.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);
            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 = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (StringUtils.isEmpty(orgCode)) {
            result.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), 0L);
            result.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), 0L);
            return result;
        }
        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", Boolean.TRUE));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        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 = jgStatisticsMapper.newRegEquCountByMonth(dpFilterParamDto.getCityCode());
            List<Map<String, Object>> vehicleCountList = jgStatisticsMapper.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 = jgStatisticsMapper.newRegEquCountByYear(dpFilterParamDto.getCityCode());
            List<Map<String, Object>> vehicleCountList = jgStatisticsMapper.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 = jgStatisticsMapper.newRegEquCountByYear(dpFilterParamDto.getCityCode());
        //年气瓶使用登记设备
        List<Map<String, Object>> vehicleEquCountListYear = jgStatisticsMapper.newVehicleEquCountByYear(dpFilterParamDto.getCityCode());
        //月使用登记设备
        List<Map<String, Object>> useEquCountListMonth = jgStatisticsMapper.newRegEquCountByMonth(dpFilterParamDto.getCityCode());
        //月气瓶使用登记设备
        List<Map<String, Object>> vehicleEquCountListMonth = jgStatisticsMapper.newVehicleEquCountByMonth(dpFilterParamDto.getCityCode());
        //年气瓶使用登记
        String vehicleCountYear = jgStatisticsMapper.newVehicleCountByYear(dpFilterParamDto.getCityCode());
        //月气瓶使用登记
        String vehicleCountListMonth = jgStatisticsMapper.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;
    }

    public Map<String, Object> JGCenterMapCountForGlobal(DPFilterParamDto dpFilterParamDto) {
        Map<String, Object> result = new HashMap<>();
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (StringUtils.isEmpty(orgCode)) {
            return new HashMap<>();
        }
        // 0.气瓶数量统计
        long cylinderNum = stCommonService.staticsCenterMapCountDataForCylinder(result, orgCode);
        // 1.8大类设备数量统计,压力容器里包括气瓶所以需要特殊处理，在统计压力容器时去掉气瓶的数量
        stCommonService.staticsCenterMapCountDataForEquip(result, cylinderNum, orgCode);
        // 2.压力管道长度统计
        stCommonService.staticsCenterMapCountDataForPipeline(result, orgCode);
        // 3.已纳管设备总数
        this.staticsCenterMapCountDataForEquipIsManage(result, orgCode);
        // 4.登记证总数
        this.staticsCenterMapCountCertificate(result, orgCode);
        // 5.超过15年电梯数量
        this.staticsCenterMapCountDataForOver15Years(result, orgCode);
        // 6.使用登记办理量
        this.staticsCenterMapCountDataForUseReg(result, orgCode);
        // 7.施工告知办理量
        this.staticsCenterMapCountDataForConstructionNotice(result, orgCode);
        // 8.变更办理量
        this.staticsCenterMapCountDataForChange(result, orgCode);

        return result;
    }

    private void staticsCenterMapCountDataForChange(Map<String, Object> result, String orgCode) {
        Long num = jgStatisticsMapper.changeCountByOrgCode(orgCode);
        result.put(DPMapStatisticsItemEnum.CHANGE_COUNT.getCode(), num);
    }

    private void staticsCenterMapCountDataForConstructionNotice(Map<String, Object> result, String orgCode) {
        Long num = jgStatisticsMapper.constructionNoticeCount(orgCode);
        result.put(DPMapStatisticsItemEnum.CONSTRUCTION_NOTICE_COUNT.getCode(), num);
    }

    private void staticsCenterMapCountDataForOver15Years(Map<String, Object> result, String orgCode) {
        String time = LocalDate.now().minusYears(15).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Long num = jgStatisticsMapper.over15yearsCount(orgCode, time);
        result.put(DPMapStatisticsItemEnum.OVER15YEARS_ELEVATORS.getCode(), num);
    }

    private void staticsCenterMapCountDataForUseReg(Map<String, Object> result, String orgCode) {
        //使用告知
        long num = jgStatisticsMapper.useCountByOrgCode(orgCode);
        result.put(DPMapStatisticsItemEnum.USE_REGISTRATION_COUNT.getCode(), num);
    }

    private void staticsCenterMapCountCertificate(Map<String, Object> result, String orgCode) {
        long num = jgStatisticsMapper.certificateCountByOrgCode(orgCode);
        result.put(DPMapStatisticsItemEnum.CERTIFICATE_COUNT.getCode(), num);
    }

    private void staticsCenterMapCountDataForEquipIsManage(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.termQuery("IS_INTO_MANAGEMENT", true));
        // 且8大类，目的去掉脏数据
        boolMust.must(QueryBuilders.termsQuery("EQU_LIST_CODE", StCommonServiceImpl.getEquipmentCategory().stream().map(EquipmentCategoryDto::getCode).collect(Collectors.toList())));
        request.query(boolMust);
        try {
            CountResponse response = restHighLevelClient.count(request, RequestOptions.DEFAULT);
            num = response.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        result.put(DPMapStatisticsItemEnum.DEVICE_COUNT.getCode(), num);
    }

    public List<Map<String, Object>> JGCenterMapCountForOverview(DPFilterParamDto dpFilterParamDto) {
        List<RegionModel> regionModels = stCommonService.setRegionIfRootParent(dpFilterParamDto);
        List<Map<String, Object>> result = regionModels.parallelStream().map(r -> {
            DPFilterParamDto filterParamDto = new DPFilterParamDto();
            filterParamDto.setCityCode(r.getRegionCode().toString());
            Map<String, Object> itemResult = JGCenterMapCountForGlobal(filterParamDto);
            itemResult.put("regionCode", r.getRegionCode());
            itemResult.put("regionName", r.getRegionName());
            return itemResult;
        }).collect(Collectors.toList());
        return result;
    }

    public List<Map<String, Object>> noticeList(DPFilterParamDto dpFilterParamDto) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return new ArrayList<>();
        }
        String time = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return jgStatisticsMapper.selectNoticeList(orgCode, time);
    }

    public List<Map<String, Object>> noticeCountTop(DPFilterParamDto dpFilterParamDto) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if (orgCode == null) {
            return new ArrayList<>();
        }
        String time = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return jgStatisticsMapper.selectNoticeCountTopTen(orgCode, time);
    }

    private List<Long> countBizFinishedNumForDetail(DPFilterParamDto dpFilterParamDto,String businessType) {
        // 1.统计各业务办理量注意要和x轴顺序一致
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 省、市、区县为按照行政区划进行编码的，公司的code为行政区划编码
        if (orgCode == null) {
            return Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
        }
        if(BusinessTypeEnum.AZGZ.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPAZGZ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.JDJY.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPJDJY(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.SYDJ.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPSYDJ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.DQJY.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPDQJY(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.BGDJ.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPBGDJ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.ZXBX.getCode().equals(businessType)){
            return commonMapper.countBizFinishedNumForDPZXBX(orgCode, dpFilterParamDto);
        }else {
            return commonMapper.countBizFinishedNumForDP(orgCode, dpFilterParamDto);
        }
    }

    private List<Long> countBizDataInFlowingForDetail(DPFilterParamDto dpFilterParamDto,String businessType) {
        // 1.统计各业务办理量注意要和x轴顺序一致
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        // 省、市、区县为按照行政区划进行编码的，公司的code为行政区划编码
        if (orgCode == null) {
            return Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
        }
        if(BusinessTypeEnum.AZGZ.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataAZGZ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.JDJY.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataJDJY(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.SYDJ.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataSYDJ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.DQJY.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataDQJY(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.BGDJ.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataBGDJ(orgCode, dpFilterParamDto);
        }else if(BusinessTypeEnum.ZXBX.getCode().equals(businessType)){
            return commonMapper.countAllInFlowingForDPNoFinishedBizDataZXBX(orgCode, dpFilterParamDto);
        }else {
            return commonMapper.countAllInFlowingForDPNoFinishedBizData(orgCode, dpFilterParamDto);
        }
    }

    public Map<String,Object> queryBizCycleDataDetail(DPFilterParamForDetailDto dpFilterParamForDetailDto) {
        //查询子区域
        List<RegionModel> regionModels = stCommonService.setRegionIfRootParent(dpFilterParamForDetailDto.getCityCode());

        List<Map<String, Object>> result = regionModels.parallelStream().map(r -> {
            DPFilterParamDto filterParamDto = new DPFilterParamDto();
            filterParamDto.setCityCode(r.getRegionCode().toString());
            if (null != dpFilterParamForDetailDto.getTimeSearchOne()) {
                filterParamDto.setBeginDate(dpFilterParamForDetailDto.getTimeSearchOne().getBeginDate());
                filterParamDto.setEndDate(dpFilterParamForDetailDto.getTimeSearchOne().getEndDate());
            }
            Map<String, Object> itemResult = new HashMap<>();
            itemResult.put("xdata", r.getRegionName());
            List<Long> ydata = this.countBizFinishedNumForDetail(filterParamDto, dpFilterParamForDetailDto.getTreeValue());
            BigDecimal finishedNum = BigDecimal.valueOf(ydata.stream().mapToLong(Long::longValue).sum());
            List<Long> everyInFlow = countBizDataInFlowingForDetail(filterParamDto, dpFilterParamForDetailDto.getTreeValue());
            BigDecimal everyNum = BigDecimal.valueOf(everyInFlow.stream().mapToLong(Long::longValue).sum());
            BigDecimal all = everyNum.add(finishedNum);
            if (all.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal percent = finishedNum.divide(all, 2, RoundingMode.HALF_UP);
                BigDecimal percentX100 = percent.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP);
                itemResult.put("percentData", percentX100.toPlainString());
            } else {
                itemResult.put("percentData", "0");
            }
            itemResult.put("finishedNum", finishedNum);
            return itemResult;
        }).collect(Collectors.toList());

        Map<String,Object> returnMap = new HashMap<>();
        List<Map<String,Object>> legendData = new ArrayList<>();
        for(int i = 0;i<2; i++){
            Map<String,Object> map = new HashMap<>();
            if(i == 0){
                map.put("dataKey","finishedNum");
                map.put("value","总数");
                map.put("chartType","bar");
            }else{
                map.put("dataKey","percentData");
                map.put("value","完结率");
                map.put("chartType","line");
            }
            legendData.add(map);
        }
        returnMap.put("legendData",legendData);

        List xdata = new ArrayList();
        List finishedNum = new ArrayList();
        List percentData = new ArrayList();

        for(int i = 0;i<result.size();i++){
            xdata.add(result.get(i).get("xdata"));
            finishedNum.add(result.get(i).get("finishedNum"));
            percentData.add(result.get(i).get("percentData"));
        }

        returnMap.put("xdata",xdata);
        returnMap.put("finishedNum",finishedNum);
        returnMap.put("percentData",percentData);

        return returnMap;
    }

    public List<Map<String,Object>> getBusinessType(DPFilterParamForDetailDto dpFilterParamDto) {
        List<HashMap<String, Object>> enumList = BusinessTypeEnum.getEnumList();
        List<Map<String,Object>> result = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        map.put("title","业务类型");
        map.put("value","0");
        map.put("children",enumList);
        result.add(map);
        return result;
    }

    public Page<Map<String, Object>> queryBizCycleDataDetailList(DPFilterParamForDetailDto dpFilterParamForDetailDto, Page<Map<String, Object>> page) {
        String orgCode = stCommonService.getAndSetOrgCode(dpFilterParamForDetailDto.getCityCode());
        Page<Map<String, Object>> maps = null;
        DPFilterParamDto filterParamDto = new DPFilterParamDto();
        filterParamDto.setCityCode(dpFilterParamForDetailDto.getCityCode());
        filterParamDto.setCompanyName(dpFilterParamForDetailDto.getCompanyName());
        filterParamDto.setSuperviseUnitName(dpFilterParamForDetailDto.getSuperviseUnitName());
        if (null != dpFilterParamForDetailDto.getTimeSearchOne()) {
            filterParamDto.setBeginDate(dpFilterParamForDetailDto.getTimeSearchOne().getBeginDate());
            filterParamDto.setEndDate(dpFilterParamForDetailDto.getTimeSearchOne().getEndDate());
        }
        if(BusinessTypeEnum.AZGZ.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListAZGZ(page, orgCode, filterParamDto);
        }else if(BusinessTypeEnum.JDJY.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListJDJY(page, orgCode, filterParamDto);
        }else if(BusinessTypeEnum.SYDJ.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListSYDJ(page, orgCode, filterParamDto);
        }else if(BusinessTypeEnum.DQJY.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListDQJY(page, orgCode, filterParamDto);
        }else if(BusinessTypeEnum.BGDJ.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListBGDJ(page, orgCode, filterParamDto);
        }else if(BusinessTypeEnum.ZXBX.getCode().equals(dpFilterParamForDetailDto.getTreeValue())){
            maps = commonMapper.countBizFinishedNumForDPListZXBX(page, orgCode, filterParamDto);
        }else {
            maps = commonMapper.countBizFinishedNumForDPList(page, orgCode, filterParamDto);
        }
        return maps;
    }
}
