package cn.cecep.talroad.service.impl;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.web.domain.BaseEntity;
import cn.cecep.talroad.domain.*;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisRun;
import cn.cecep.talroad.domain.vo.MonElecRealVO;
import cn.cecep.talroad.enums.TimeTypeEnum;
import cn.cecep.talroad.mapper.*;
import cn.cecep.talroad.mapper.analysis.SRaRealTimeAnalysisRunMapper;
import cn.cecep.talroad.service.ElectricityMeterService;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @className: ElectricityMeterServiceImpl
 * @description: TODO 类描述
 * @author: Mr.Yanghongtao
 * @date: 2023/03/30 5:26 PM
 * @Company: Copyright© [2023/03/30 5:26 PM] by [Mr.Yanghongtao]
 **/
@Service
@Slf4j
public class ElectricityMeterServiceImpl implements ElectricityMeterService {
    @Autowired
    private ElectricityMeterMapper electricityMeterMapper;

    @Autowired
    private PcFactoryMapper pcFactoryMapper;

    @Autowired
    private SRaRealTimeAnalysisRunMapper sRaRealTimeAnalysisRunMapper;

    @Autowired
    private SRaDayMonTimeFbjdMapper sRaDayMonTimeFbjdMapper;

    @Autowired
    private AmProblemFiMapper amProblemFiMapper;

    @Autowired
    private OdsElectricityElecPsEquipRelationTsAMapper odsElectricityElecPsEquipRelationTsAMapper;

    @Autowired
    private MonElecHourMapper monElecHourMapper;

    @Autowired
    private MonElecOtherMapper monElecOtherMapper;

    @Autowired
    private SRaRealTimeAnalysisRunOneMapper sRaRealTimeAnalysisRunOneMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    ThreadPoolExecutor controlTasksExecutor = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("Thread-ControlTasks-pool%d").build(), new ThreadPoolExecutor.AbortPolicy());



    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/3/30 5:26 PM
     * @Deseription: 统计设备运行状态
     * 按照规则，15分钟执行一次，但是数据接入可能会慢一些，所以定时任务执行时间往后延长2分钟 02 17 32 47 执行，
     * @Params: time 参数为 yyyy-MM-dd HH:mm:ss 时间为定时任务执行时间往前推一个小时
     * @Params: deviceType 参数为 0-生产设施，1-治理设施
     * @Params: cepAndProIds 参数为 治理设施和生产设施对应关系
     * @Return:
     * @Throws:
     */
    @Override
    public void statisticsDeviceRunningState(String time, String deviceType, Map<String, List<String>> cepAndProIds) throws ParseException {
        Date updateTime = new Date();
        BigDecimal sixty = new BigDecimal(60);
//        log.info("统计设备运行状态,当前时间为：{},传入时间为：{},传入参数为：{}",updateTime,time,deviceType);
        if (StringUtils.isEmpty(time) || time.length() < 19) {
            return;
        } else {
            Date date = DateUtils.parseDate(time);
            if ("02".equals(time.substring(14, 16))) {
                // 更新日期
                updateTime = DateUtils.parseDate(
                        DateUtils.parseDateToStr("yyyy-MM-dd HH:00:00", date)
                );
            } else if ("17".equals(time.substring(14, 16))) {
                updateTime = DateUtils.parseDate(
                        DateUtils.parseDateToStr("yyyy-MM-dd HH:15:00", date)
                );
            } else if ("32".equals(time.substring(14, 16))) {
                updateTime = DateUtils.parseDate(
                        DateUtils.parseDateToStr("yyyy-MM-dd HH:30:00", date)
                );
            } else if ("47".equals(time.substring(14, 16))) {
                updateTime = DateUtils.parseDate(
                        DateUtils.parseDateToStr("yyyy-MM-dd HH:45:00", date)
                );
            } else {
                log.info("统计设备运行状态,传入参数错误,本次任务已终止");
                return;
            }
        }
        // 02查询的数据为上个小时45分至当前小时02分的数据
        String startTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", DateUtils.addDateMinutes(DateUtils.parseDate(time), -17));
        List<MonElecRealVO> monElecRealVOS = electricityMeterMapper.selectDeviceSiteList(Timestamp.valueOf(startTime),Timestamp.valueOf(time), Integer.valueOf(deviceType));
        // 转成map ，key为设备ID，value为监测点（额定功率和数值）
        Map<String, List<MonElecRealVO>> collect = monElecRealVOS.stream().collect(Collectors.groupingBy(MonElecRealVO::getDeviceId));
        Date finalUpdateTime = updateTime;

        // 查询15分钟前企业装备运行情况实时分析的数据
        Date date = DateUtils.addDateMinutes(finalUpdateTime, -15);
        // 从Redis里查询上个15分钟前企业装备运行情况实时分析的数据
        String beforeReidsKey = "FBJD:FBJD_" + deviceType +"_" +  DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", date);
        List<SRaRealTimeAnalysisRun> beforeList = new ArrayList<>();
        if (redisTemplate.hasKey(beforeReidsKey)) {
           beforeList = redisTemplate.opsForList().range(beforeReidsKey, 0,-1);
        }
        Map<String, SRaRealTimeAnalysisRun> beforeCollect = beforeList.stream().collect(Collectors.toMap(SRaRealTimeAnalysisRun::getDeviceId, Function.identity(), (oldValue, newValue) -> oldValue));

        // 查询所有企业信息
        List<PcFactory> pcFactories = pcFactoryMapper.selectPcFactory();
        Map<String, PcFactory> collectPcFactories = pcFactories.stream().collect(Collectors.toMap(PcFactory::getId, Function.identity(), (oldValue, newValue) -> oldValue));
        // key为设备ID，value为SRaRealTimeAnalysisRun
        Map<String, SRaRealTimeAnalysisRun> deviceStatusMap = new HashMap<>();
        // key为设备ID，value为监测点ID
        Map<String, List<String>> basDeviceSiteMap = new HashMap<>();

        List<SRaRealTimeAnalysisRunOne> sRaRealTimeAnalysisRunOneListInsert = new ArrayList<>();
        List<SRaRealTimeAnalysisRunOne> sRaRealTimeAnalysisRunOneListUpdate = new ArrayList<>();
        List<String> sRaRealTimeAnalysisRunOneDeviceIds = sRaRealTimeAnalysisRunOneMapper.selectAllDeviceId(deviceType);
        collect.forEach((k, v) -> {
            List<MonElecRealVO> list = v;
            List<String> basDeviceSiteIds = list.stream().map(MonElecRealVO::getDeviceSiteId).collect(Collectors.toList());
            basDeviceSiteMap.put(k,basDeviceSiteIds);
            // 通过设备ID查询企业信息
            PcFactory pcFactory = collectPcFactories.get(list.get(0).getFactoryId());
            // 封装企业装备运行情况实时分析
            SRaRealTimeAnalysisRun sRaRealTimeAnalysisRun = new SRaRealTimeAnalysisRun();
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            sRaRealTimeAnalysisRun.setDataId(uuid);
            sRaRealTimeAnalysisRun.setFactoryId(pcFactory.getId());
            sRaRealTimeAnalysisRun.setFactoryName(pcFactory.getFactoryName());
            sRaRealTimeAnalysisRun.setIndustryCategoryCode(pcFactory.getIndustryCategory());
            sRaRealTimeAnalysisRun.setIndustryCategoryName(pcFactory.getIndusName());
            sRaRealTimeAnalysisRun.setDistrictCode(pcFactory.getCountryCode());
            sRaRealTimeAnalysisRun.setDistrictName(pcFactory.getCountryName());
            sRaRealTimeAnalysisRun.setPerformanceLevel(pcFactory.getPreConLevel());
            sRaRealTimeAnalysisRun.setDeviceId(k);
            sRaRealTimeAnalysisRun.setDeviceName(list.get(0).getDeviceName());
            // 设备类型(生产设备/治理设备) 1-生产，2-治理
            sRaRealTimeAnalysisRun.setDeviceType(deviceType);
            // [运行状态(1=运行,2=停运,3=启停,4=停启,5=数据缺失)]
            sRaRealTimeAnalysisRun.setOperationStatus("1");
            if (beforeCollect.containsKey(k)) {
                sRaRealTimeAnalysisRun.setRunEtc(beforeCollect.get(k).getUpdateTime() + "-" + finalUpdateTime + "运行");
            }
            // 判断依据(1=工况数据,2=分表计电数据,3=数据缺失,4=无法判断)
            sRaRealTimeAnalysisRun.setJudgementBasis("2");
            // 计算本次监测点一共用电量
            long count = list.stream().filter(x -> x.getActivePowerQuantity() != null).count();
            if (count == 0) {
                // 无有效数据
                // 本次15分钟用电量数据设置为NULL
                sRaRealTimeAnalysisRun.setActivePowerQuantity(null);
                sRaRealTimeAnalysisRun.setActivePowerQuantityTmp(null);
            } else {
                BigDecimal activePowerCount = list.stream().filter(x -> x.getActivePowerQuantity() != null).map(x -> new BigDecimal(x.getActivePowerQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add);
                sRaRealTimeAnalysisRun.setActivePowerQuantityTmp(activePowerCount.toString());
                if (beforeCollect != null && beforeCollect.containsKey(k) && StringUtils.isNotBlank(beforeCollect.get(k).getActivePowerQuantityTmp())) {
                    // 本次设备用电总和 - 上次用电设备总和
                    BigDecimal beforeActivePowerCount = new BigDecimal(beforeCollect.get(k).getActivePowerQuantityTmp());
                    BigDecimal l = activePowerCount.subtract(beforeActivePowerCount);
                    sRaRealTimeAnalysisRun.setActivePowerQuantity(l.toString());
                } else {
                    // 如果上个15分钟没有用电总和，那就用本次15分钟监测点用电总和
                    sRaRealTimeAnalysisRun.setActivePowerQuantity(activePowerCount.toString());
                }
            }
            sRaRealTimeAnalysisRun.setCreateTime(new Date());
            sRaRealTimeAnalysisRun.setUpdateTime(finalUpdateTime);
            // 取出停运的数量
            BigDecimal isStopRunCount = new BigDecimal(list.stream().filter(x -> !x.getIsRun()).count());
            // 取出监测点的总数
            BigDecimal isCount = new BigDecimal(list.stream().count());
            // 求出停运监测点占比
            BigDecimal proportion = isStopRunCount.divide(isCount, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            // 停运监测点占比大于百分之60，认定这个设备就是停运状态
            if (proportion.compareTo(sixty) == 1) {
                // 入库，该设备当前时间处于停运状态 [运行状态(1=运行,2=停运,3=启停,4=停启,5=数据缺失)]
                sRaRealTimeAnalysisRun.setOperationStatus("2");
                if (beforeCollect.containsKey(k)) {
                    sRaRealTimeAnalysisRun.setRunEtc(beforeCollect.get(k).getUpdateTime() + "-" + finalUpdateTime + "停运");
                }
            }

            // 2023年04月07日10:10:40 新增规则， 如果监测点百分之60的数据是无效数据（activePower是null 或者设备没有额定功率），那这个设备就算做数据缺失
            BigDecimal activePowerIsNullCount  = new BigDecimal(list.stream().filter(x -> StringUtils.isEmpty(x.getActivePower()) || StringUtils.isEmpty(x.getPowerRating())).count());
            BigDecimal isValid  =  activePowerIsNullCount.divide(isCount,2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            if (isValid.compareTo(sixty) == 1 || isValid.compareTo(sixty) == 0) {
                sRaRealTimeAnalysisRun.setOperationStatus("5");
                if (beforeCollect.containsKey(k)) {
                    sRaRealTimeAnalysisRun.setRunEtc(beforeCollect.get(k).getUpdateTime() + "-" + finalUpdateTime + "数据缺失");
                }
            }
            // 设置使用的监测点ID
            sRaRealTimeAnalysisRun.setBasDeviceSiteIds(basDeviceSiteIds);

            deviceStatusMap.put(k, sRaRealTimeAnalysisRun);

            SRaRealTimeAnalysisRunOne sRaRealTimeAnalysisRunOne = new SRaRealTimeAnalysisRunOne();
            sRaRealTimeAnalysisRunOne.setDataId(uuid);
            sRaRealTimeAnalysisRunOne.setFactoryId(pcFactory.getId());
            sRaRealTimeAnalysisRunOne.setFactoryName(pcFactory.getFactoryName());
            sRaRealTimeAnalysisRunOne.setIndustryCategoryCode(pcFactory.getIndustryCategory());
            sRaRealTimeAnalysisRunOne.setIndustryCategoryName(pcFactory.getIndusName());
            sRaRealTimeAnalysisRunOne.setIndustryPermissionName(pcFactory.getIndustryPermissionName());
            sRaRealTimeAnalysisRunOne.setDistrictCode(pcFactory.getCityCode());
            sRaRealTimeAnalysisRunOne.setDistrictName(pcFactory.getCityName());
            sRaRealTimeAnalysisRunOne.setPerformanceLevel(pcFactory.getPreConLevel());
            sRaRealTimeAnalysisRunOne.setDeviceId(k);
            sRaRealTimeAnalysisRunOne.setDeviceName(list.get(0).getDeviceName());
            sRaRealTimeAnalysisRunOne.setDeviceType(deviceType);
            sRaRealTimeAnalysisRunOne.setOperationStatus(sRaRealTimeAnalysisRun.getOperationStatus());
            sRaRealTimeAnalysisRunOne.setJudgementBasis(sRaRealTimeAnalysisRun.getJudgementBasis());
            sRaRealTimeAnalysisRunOne.setActivePowerQuantityTmp(sRaRealTimeAnalysisRun.getActivePowerQuantityTmp());
            sRaRealTimeAnalysisRunOne.setActivePowerQuantity(sRaRealTimeAnalysisRun.getActivePowerQuantity());
            sRaRealTimeAnalysisRunOne.setCreateTime(new Date());
            sRaRealTimeAnalysisRunOne.setUpdateTime(finalUpdateTime);
            sRaRealTimeAnalysisRunOne.setRunEtc(sRaRealTimeAnalysisRun.getRunEtc());
            if (sRaRealTimeAnalysisRunOneDeviceIds.indexOf(k) != -1) {
                sRaRealTimeAnalysisRunOneListUpdate.add(sRaRealTimeAnalysisRunOne);
            } else {
                sRaRealTimeAnalysisRunOneListInsert.add(sRaRealTimeAnalysisRunOne);
            }
        });

        // 存入Redis， key为 flag+时间    DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime)
        List<SRaRealTimeAnalysisRun> redisDeviceStatusMap = deviceStatusMap.values().stream().map(x->x).collect(Collectors.toList());
        String redisKey = "FBJD:FBJD_" + deviceType +"_" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime);
        if (!CollectionUtils.isEmpty(redisDeviceStatusMap)) {
            redisTemplate.opsForList().leftPushAll(redisKey, redisDeviceStatusMap);
            redisTemplate.expire(redisKey, 1000 * 60 * 60, TimeUnit.MILLISECONDS);

            // 批量插入数据库
            List<List<SRaRealTimeAnalysisRun>> dataList = subList(redisDeviceStatusMap, 1000);
            for (int i = 0; i < dataList.size(); i++) {
                sRaRealTimeAnalysisRunMapper.insertSRaRealTimeAnalysisRuns(dataList.get(i));
            }

            List<List<SRaRealTimeAnalysisRunOne>> dataList1 = subList(sRaRealTimeAnalysisRunOneListInsert, 1000);
            for (int i = 0; i < dataList1.size(); i++) {
                sRaRealTimeAnalysisRunOneMapper.batchInsert(dataList1.get(i));
            }

            List<List<SRaRealTimeAnalysisRunOne>> dataList2 = subList(sRaRealTimeAnalysisRunOneListUpdate, 1000);
            for (int i = 0; i < dataList2.size(); i++) {
                sRaRealTimeAnalysisRunOneMapper.updateBatchSelective(dataList2.get(i));
            }

        }

        // 更新监测点的运行状态
        if (CollectionUtils.isNotEmpty(monElecRealVOS)) {
            for (List<MonElecRealVO> list : subList(monElecRealVOS, 1000)) {
                electricityMeterMapper.updateBatchStatus(list);
            }
        }


        // 生产设施的启停状态
        if ("0".equals(deviceType)) {
            // 查询生产设施上个15分钟的状态
            // 设备从生产到停产算启停，从停产到生产算停启 date = 15分钟前的时间
            List<AmProblemFi> insertAmProblemFis = new ArrayList<>();
            for (SRaRealTimeAnalysisRun sRaRealTimeAnalysisRun : beforeList) {
                // 当前状态
                String status = deviceStatusMap.get(sRaRealTimeAnalysisRun.getDeviceId()).getOperationStatus();
                // 当前状态处于 数据缺失的话，不在判断启停行为
                if ("5".equals(status) || "5".equals(sRaRealTimeAnalysisRun.getOperationStatus()) ) {
                    break;
                }

                // 15分钟前分析的状态 // 两次状态不相等，代表发生了 启停或者停起
                if (!status.equals(sRaRealTimeAnalysisRun.getOperationStatus())) {
                    String message = "企业：" + sRaRealTimeAnalysisRun.getFactoryName() + "，" +
                            "生产设施：" + sRaRealTimeAnalysisRun.getDeviceName() + "，" +
                            "于" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime);
                    // 判断15分钟前的数据为运行还是停止 1-启动 ，2 -停止
                    if ("1".equals(sRaRealTimeAnalysisRun.getOperationStatus())) {
                        // 插入报警表， 发生了启停  “企业名称”“设施名称”于“启停/停启发现时间”存在启停行为，请注意。
                        message += "存在启停行为，请注意！";
                    } else {
                        // 插入报警表， 发生了停启
                        message += "存在停启行为，请注意！";
                    }
                    // 插入报警表
                    AmProblemFi amProblemFi = new AmProblemFi();
                    String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
                    amProblemFi.setId(uuid);
                    amProblemFi.setFactoryId(sRaRealTimeAnalysisRun.getFactoryId());
                    // 问题来源 1:关联分析系统, 2:分表计电系统, 3:动态管控系统
                    amProblemFi.setProblemSources("1");
                    // 新增一条，代表企业生产设施运行分析
                    amProblemFi.setProblemType("002002");
                    amProblemFi.setProblemDetails(message);
                    amProblemFi.setStationName(sRaRealTimeAnalysisRun.getDeviceName());
                    amProblemFi.setProblemStartTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                    amProblemFi.setProblemEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                    amProblemFi.setAnalyseTime(finalUpdateTime);
                    amProblemFi.setAnalyseTimeEnd(finalUpdateTime);

                    // 循环该治理设施下所有点位ID
                    List<String> basDeviceSiteIds = Optional.ofNullable(basDeviceSiteMap.get(sRaRealTimeAnalysisRun.getDeviceId())).orElse(new ArrayList<>());
                    Map<String,Object> map = new HashMap<>(basDeviceSiteIds.size());
                    List<Map<String,Object>> elecDeviceSiteList = new ArrayList<>(basDeviceSiteIds.size());
                    for (String basDeviceSiteId : basDeviceSiteIds) {
                        Map m = new HashMap(basDeviceSiteIds.size());
                        m.put("deviceSiteId",basDeviceSiteId);
                        m.put("params",Arrays.asList(new String[]{"activePower"}));
                        elecDeviceSiteList.add(m);
                    }
                    map.put("elecDeviceSiteList",elecDeviceSiteList);
                    amProblemFi.setExtra(JSON.toJSONString(map).toString());
                    // 处理状态（1待处理 、2 已处理）
                    amProblemFi.setProblemTreatmentState("1");
                    // 类型 0-预警，1-报警
                    amProblemFi.setType(0);
                    insertAmProblemFis.add(amProblemFi);
                }
            }

            // 批量插入数据库
            List<List<AmProblemFi>> dataList = subList(insertAmProblemFis, 1000);
            for (int i = 0; i < dataList.size(); i++) {
                amProblemFiMapper.insertAmProblemFis(dataList.get(i));
            }
        }


        // 治理设施未有效运行
        if ("1".equals(deviceType)) {

            // 从Redis里查询当前时间 "生产设备" 企业装备运行情况实时分析的数据
            String reidsKeyProd = "FBJD:FBJD_0_" +  DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime);
            List<SRaRealTimeAnalysisRun> sRaRealTimeAnalysisRunProds = new ArrayList<>();
            if (redisTemplate.hasKey(reidsKeyProd)) {
                sRaRealTimeAnalysisRunProds = redisTemplate.opsForList().range(reidsKeyProd, 0,-1);
            }
            // 如果当前时间 "生产设备" 没有数据 直接跳出
            if (CollectionUtils.isEmpty(sRaRealTimeAnalysisRunProds)) {
                return;
            }
            List<AmProblemFi> insertAmProblemFis = new ArrayList<>();
            // key为生产设施ID
            Map<String, SRaRealTimeAnalysisRun> collect1 = sRaRealTimeAnalysisRunProds.stream().collect(Collectors.toMap(SRaRealTimeAnalysisRun::getDeviceId, Function.identity(), (oldValue, newValue) -> oldValue));
            // 首先过滤出本次定时任务执行完，治理设施为"停运"的数据
            redisDeviceStatusMap.stream().filter(x-> "2".equals(x.getOperationStatus())).forEach(x->{
                // 查询它对应的生产设施IDs
                List<String> proIds = cepAndProIds.containsKey(x.getDeviceId()) ? cepAndProIds.get(x.getDeviceId()) : new ArrayList<>();
                proIds.forEach(p->{
                    SRaRealTimeAnalysisRun sRaRealTimeAnalysisRun = collect1.get(p);
                    if (sRaRealTimeAnalysisRun!= null && "1".equals(sRaRealTimeAnalysisRun.getOperationStatus())) {
                        String message = "企业：" + x.getFactoryName() + "，" +
                                "治理设施：" + x.getDeviceName() + "，" +
                                "于" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime) + "处于停运状态，对应生产设施：" +
                                sRaRealTimeAnalysisRun.getDeviceName() + "正常运行，存在生产治理未同步运行的情况。";
                        // 插入报警表
                        AmProblemFi amProblemFi = new AmProblemFi();
                        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
                        amProblemFi.setId(uuid);
                        amProblemFi.setFactoryId(x.getFactoryId());
                        // 问题来源 1:关联分析系统, 2:分表计电系统, 3:动态管控系统
                        amProblemFi.setProblemSources("1");
                        // 新增一条，代表企业生产设施运行分析
                        amProblemFi.setProblemType("004001001");
                        amProblemFi.setProblemDetails(message);
                        amProblemFi.setStationName("生产设施：" + sRaRealTimeAnalysisRun.getDeviceName() + "，治理设施" + x.getDeviceName());
                        amProblemFi.setProblemStartTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                        amProblemFi.setProblemEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                        amProblemFi.setAnalyseTime(finalUpdateTime);
                        amProblemFi.setAnalyseTimeEnd(finalUpdateTime);
                        Map<String,Object> map = new HashMap<>();
                        // 循环该治理设施下所有点位ID
                        List<Map<String,Object>> l = new ArrayList<>();
                        List<String> governanceBasDeviceSiteIds = Optional.ofNullable(basDeviceSiteMap.get(x.getDeviceId())).orElse(new ArrayList<>());
                        // 生产设施所使用的监测点ID
                        List<String> productionBasDeviceSiteIds = sRaRealTimeAnalysisRun.getBasDeviceSiteIds();
                        governanceBasDeviceSiteIds.addAll(productionBasDeviceSiteIds);
                        for (String basDeviceSiteId : governanceBasDeviceSiteIds) {
                            Map m = new HashMap();
                            m.put("deviceSiteId",basDeviceSiteId);
                            m.put("params",Arrays.asList(new String[]{"activePower"}));
                            l.add(m);
                        }
                        map.put("elecDeviceSiteList",l);
                        amProblemFi.setExtra(JSON.toJSONString(map).toString());
                        // 处理状态（1待处理 、2 已处理）
                        amProblemFi.setProblemTreatmentState("1");
                        // 类型 0-预警，1-报警
                        amProblemFi.setType(0);
                        amProblemFi.setCreateTime(new Date());
//                    amProblemFiMapper.insert(amProblemFi);
                        insertAmProblemFis.add(amProblemFi);
                    }
                });
            });

        /*
            List<SRaRealTimeAnalysisRun> sRaRealTimeAnalysisRuns = beforeListNew.stream().filter(x -> "2".equals(deviceStatusMap.get(x.getDeviceId()).getOperationStatus())).collect(Collectors.toList());
            for (SRaRealTimeAnalysisRun sRaRealTimeAnalysisRun : sRaRealTimeAnalysisRuns) {
                // 治理设施当前状态 getDeviceId SQL查询的是治理设施的ID
                String status = deviceStatusMap.get(sRaRealTimeAnalysisRun.getDeviceId()).getOperationStatus();
                // 当前状态处于 数据缺失的话，不在判断启停行为
                if ("5".equals(status) || "5".equals(sRaRealTimeAnalysisRun.getOperationStatus()) ) {
                    continue;
                }
                // 判断治理设施当前状态与对应的生产设施状态是否一致，不一致就代表治理设施停止运行，但是生产设施是运行状态
                if (!status.equals(sRaRealTimeAnalysisRun.getOperationStatus())) {
                    String message = "企业：" + sRaRealTimeAnalysisRun.getFactoryName() + "，" +
                            "治理设施：" + deviceStatusMap.get(sRaRealTimeAnalysisRun.getDeviceId()).getDeviceName() + "，" +
                            "于" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime) + "处于停运状态，对应生产设施：" +
                            sRaRealTimeAnalysisRun.getDeviceName() + "正常运行，存在生产治理未同步运行的情况。";
                    // 插入报警表
                    AmProblemFi amProblemFi = new AmProblemFi();
                    String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
                    amProblemFi.setId(uuid);
                    amProblemFi.setFactoryId(sRaRealTimeAnalysisRun.getFactoryId());
                    // 问题来源 1:关联分析系统, 2:分表计电系统, 3:动态管控系统
                    amProblemFi.setProblemSources("1");
                    // 新增一条，代表企业生产设施运行分析
                    amProblemFi.setProblemType("004001001");
                    amProblemFi.setProblemDetails(message);
                    amProblemFi.setStationName("生产设施：" + sRaRealTimeAnalysisRun.getDeviceName() + "，治理设施" + deviceStatusMap.get(sRaRealTimeAnalysisRun.getDeviceId()).getDeviceName());
                    amProblemFi.setProblemStartTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                    amProblemFi.setProblemEndTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", finalUpdateTime));
                    amProblemFi.setAnalyseTime(finalUpdateTime);
                    amProblemFi.setAnalyseTimeEnd(finalUpdateTime);
                    Map<String,Object> map = new HashMap<>();
                    // 循环该治理设施下所有点位ID
                    List<Map<String,Object>> l = new ArrayList<>();
                    List<String> basDeviceSiteIds = Optional.ofNullable(basDeviceSiteMap.get(sRaRealTimeAnalysisRun.getDeviceId())).orElse(new ArrayList<>());
                    for (String basDeviceSiteId : basDeviceSiteIds) {
                        Map m = new HashMap();
                        m.put("deviceSiteId",basDeviceSiteId);
                        m.put("params",Arrays.asList(new String[]{"activePower"}));
                        l.add(m);
                    }
                    map.put("elecDeviceSiteList",l);
                    amProblemFi.setExtra(JSON.toJSONString(map).toString());
                    // 处理状态（1待处理 、2 已处理）
                    amProblemFi.setProblemTreatmentState("1");
                    // 类型 0-预警，1-报警
                    amProblemFi.setType(0);
                    amProblemFi.setCreateTime(new Date());
//                    amProblemFiMapper.insert(amProblemFi);
                    insertAmProblemFis.add(amProblemFi);
                }
            }
        */
            // 批量插入数据库
            List<List<AmProblemFi>> dataList = subList(insertAmProblemFis, 1000);
            for (int i = 0; i < dataList.size(); i++) {
                amProblemFiMapper.insertAmProblemFis(dataList.get(i));
            }
        }
    }


    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/3/31 2:56 PM
     * @Deseription: 统计设备运行时间 每日0点10分执行，统计昨日数据
     * @Params: null
     * @Return:
     * @Throws:
     */
    public void statisticsDeviceRunningTime(String startTime,String endTime) throws Exception {
        // 获取昨日日期
        Date beforeDate = DateUtils.addDateDays(new Date(), -1);
        if (StringUtils.isNotEmpty(startTime)) {
            beforeDate = DateUtils.parseDate(startTime);
        }
        startTime = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", beforeDate);
        endTime = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", DateUtils.addDateDays(beforeDate, 1));

        List<SRaDayMonTimeFbjd> insertSRaDayMonTimeFbjd = new ArrayList<>();

        // 一天的数据大约有277万条，所以改成线程查询，24个线程，每个线程查询一个小时的数据
        List<Future<List<SRaRealTimeAnalysisRun>>> threadDataList = new ArrayList<>();
        List<SRaRealTimeAnalysisRun> resultList = new ArrayList<>();
        // 获取日期封装
        List<String[]> dateList = getDateList(startTime, endTime);

        for (String[] strings : dateList) {
            Future<List<SRaRealTimeAnalysisRun>> submit = controlTasksExecutor.submit(new ThreadQuerySRaRealTimeAnalysisRunData(strings[0], strings[1]));
            threadDataList.add(submit);
        }
        Long st = System.currentTimeMillis() + (1000 * 60 * 20);
        // 保证获取到全部的线程查询结果
        while (true){
            // 一条数据都查询不出来就跳出循环 或者 循环时间大于20分钟
            if (threadDataList.isEmpty() || System.currentTimeMillis() > st) {
                break;
            }
            // 循环获取
            for (int i = 0; i < threadDataList.size(); i++) {
                if (threadDataList.get(i).isDone()) {
                    resultList.addAll(threadDataList.get(i).get());
                    threadDataList.remove(i--);
                }
            }
            // 每隔0.5秒 检测一次
            TimeUnit.MILLISECONDS.sleep(500);
        }


        // 查询昨日设备运行状态+时间，倒序查询
//        List<SRaRealTimeAnalysisRun> sRaRealTimeAnalysisRuns = sRaRealTimeAnalysisRunMapper.selectListByDate(Timestamp.valueOf(startTime), Timestamp.valueOf(endTime), null);
        // 根据设备进行分组 key为设备ID
        Map<String, List<SRaRealTimeAnalysisRun>> collect = resultList.stream().collect(Collectors.groupingBy(SRaRealTimeAnalysisRun::getDeviceId));
        Date finalBeforeDate = beforeDate;
        collect.forEach((k, v) -> {
            // 取出本设备昨日的运行状态+时间
            List<SRaRealTimeAnalysisRun> list = v;
            // 根据更新日期正序
            Collections.sort(list, Comparator.comparing(BaseEntity::getUpdateTime));

            SRaDayMonTimeFbjd sRaDayMonTimeFbjd = new SRaDayMonTimeFbjd();
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            sRaDayMonTimeFbjd.setDataId(uuid);
            sRaDayMonTimeFbjd.setFactoryId(list.get(0).getFactoryId());
            sRaDayMonTimeFbjd.setDeviceId(k);
            sRaDayMonTimeFbjd.setTimeType(TimeTypeEnum.DAY.getCode());
            sRaDayMonTimeFbjd.setDataTime(DateUtils.parseDateToStr("yyyy-MM-dd", finalBeforeDate));
            sRaDayMonTimeFbjd.setCreateTime(new Date());
            sRaDayMonTimeFbjd.setRunTime("0");

            // 删除无效数据
            list.removeIf(x->"5".equals(x.getOperationStatus()));
            // 使用迭代器，循环删除停运状态数据，直至数据是运行状态
            Iterator<SRaRealTimeAnalysisRun> it = list.iterator();
            while (it.hasNext()) {
                SRaRealTimeAnalysisRun next = it.next();
                if (!"1".equals(next.getOperationStatus())) {
                    it.remove();
                } else {
                    break;
                }
            }

            // 判读List大小， 如果为0 ，则代表一天都是停运状态
            if (list.size() == 0) {
                // 入库 当前设备昨日运行时间为0小时
//                sRaDayMonTimeFbjdMapper.insert(sRaDayMonTimeFbjd);
                insertSRaDayMonTimeFbjd.add(sRaDayMonTimeFbjd);
                return;
            }

            // 首条数据状态 一定为运行状态
            boolean firstFlag = true;
            // 首条数据时间
            Date firstTime = list.get(0).getUpdateTime();
            // 设备运行总时间
            double countTime = 0;

            for (int i = 0; i < list.size(); i++) {
                // status = true 代表运行
                boolean status = "1".equals(list.get(i).getOperationStatus()) ? true : false;
                // 判断数据状态与flag是否一致
                if (status != firstFlag) {
                    if (firstFlag) {
                        // 本条数据是停运状态 , 计算本次启停时间
                        double runTime = (double) (list.get(i).getUpdateTime().getTime() - firstTime.getTime()) / 1000 / (60 * 60);
                        countTime += runTime;
                    }
                    firstFlag = status;

                    // 如果数据变为启动状态，则更新时间
                    if (status) {
                        firstTime = list.get(i).getUpdateTime();
                    }
                } else {
                    // 第一条为运行状态，第二条依然为运行状态，要把这两条时间加起来,得是运行状态
                    if (i != 0 && firstFlag) {
                        double runTime = (double) (list.get(i).getUpdateTime().getTime() - firstTime.getTime()) / 1000 / (60 * 60);
                        countTime += runTime;
                        firstTime = list.get(i).getUpdateTime();
                    }
                }
                // 一般最后一条数据为23:45:00 。 判断此条数据运行状态是否为运行，运行的话，给countTime在加15分钟的时间
                if ("23:45:00".equals(DateUtils.parseDateToStr("HH:mm:ss", list.get(i).getUpdateTime()))) {
                    if (status) {
                        countTime += 0.25;
                    }
                }
                // 1条数据，代表当天只有一条启动状态的数据，按照新规则，代表这条数据至晚上23点59分59秒都是运行状态
                if (list.size() == 1) {
                    // 获取本条数据当天时间
                    Date toDay = DateUtils.parseFormatDate("yyyy-MM-dd 23:59:59", list.get(i).getUpdateTime());
                    double runTime = (toDay.getTime() - list.get(i).getUpdateTime().getTime())  / 1000 / (60 * 60);
                    countTime += runTime;
                }
            }

            sRaDayMonTimeFbjd.setRunTime(String.valueOf(countTime));
            insertSRaDayMonTimeFbjd.add(sRaDayMonTimeFbjd);
        });

        // 批量插入数据库
        List<List<SRaDayMonTimeFbjd>> dataList = subList(insertSRaDayMonTimeFbjd, 1000);
        for (int i = 0; i < dataList.size(); i++) {
            sRaDayMonTimeFbjdMapper.insertinsertSRaDayMonTimeFbjds(dataList.get(i));
        }
    }


    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/3/31 5:03 PM
     * @Deseription: 统计设备运行时间 每月1日执行，统计上个月数据
     * @Params: null
     * @Return:
     * @Throws:
     */
    public void statisticsDeviceRunningTimeByMonth(String startTime,String endTime) throws Exception {
        // 查询上个月数据
        if (StringUtils.isEmpty(startTime)) {
            startTime = DateUtils.getLastMonthBegin();
        }
        if (StringUtils.isEmpty(endTime)) {
            endTime = DateUtils.getLastMonthEnd();
        }
        List<SRaDayMonTimeFbjd> insertSRaDayMonTimeFbjd = new ArrayList<>();

        List<Future<List<SRaDayMonTimeFbjd>>> threadDataList = new ArrayList<>();
        List<SRaDayMonTimeFbjd> resultList = new ArrayList<>();
        // 一个月数据大概有90万条数据，分成10天查询一次
        List<String[]> dateListMonth = getDateListMonth(startTime, endTime);
        for (String[] strings : dateListMonth) {
            Future<List<SRaDayMonTimeFbjd>> submit = controlTasksExecutor.submit(new ThreadQuerySRaDayMonTimeFbjdData(strings[0], strings[1]));
            threadDataList.add(submit);
        }

        Long st = System.currentTimeMillis() + (1000 * 60 * 20);
        // 保证获取到全部的线程查询结果
        while (true){
            // 一条数据都查询不出来就跳出循环 或者 循环时间大于20分钟
            if (threadDataList.isEmpty() || System.currentTimeMillis() > st) {
                break;
            }
            // 循环获取
            for (int i = 0; i < threadDataList.size(); i++) {
                if (threadDataList.get(i).isDone()) {
                    resultList.addAll(threadDataList.get(i).get());
                    threadDataList.remove(i--);
                }
            }
            // 每隔0.5秒 检测一次
            TimeUnit.MILLISECONDS.sleep(500);
        }

//        List<SRaDayMonTimeFbjd> sRaDayMonTimeFbjds = sRaDayMonTimeFbjdMapper.selectListByDate(Timestamp.valueOf(startTime), Timestamp.valueOf(endTime));
        // 根据设备进行分组
        Map<String, List<SRaDayMonTimeFbjd>> collect = resultList.stream().collect(Collectors.groupingBy(SRaDayMonTimeFbjd::getDeviceId));
        String finalStartTime = startTime;
        collect.forEach((k, v) -> {
            // 统计总运行时间
            double sum = v.stream().mapToDouble((x) -> Double.valueOf(x.getRunTime())).summaryStatistics().getSum();
            SRaDayMonTimeFbjd sRaDayMonTimeFbjd = new SRaDayMonTimeFbjd();
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            sRaDayMonTimeFbjd.setDataId(uuid);
            sRaDayMonTimeFbjd.setFactoryId(v.get(0).getFactoryId());
            sRaDayMonTimeFbjd.setDeviceId(k);
            sRaDayMonTimeFbjd.setTimeType(TimeTypeEnum.MONTH.getCode());
            sRaDayMonTimeFbjd.setDataTime(finalStartTime.substring(0, 7));
            sRaDayMonTimeFbjd.setCreateTime(new Date());
            sRaDayMonTimeFbjd.setRunTime(String.valueOf(sum));
            insertSRaDayMonTimeFbjd.add(sRaDayMonTimeFbjd);
        });

        // 批量插入数据库
        List<List<SRaDayMonTimeFbjd>> dataList = subList(insertSRaDayMonTimeFbjd, 1000);
        for (int i = 0; i < dataList.size(); i++) {
            sRaDayMonTimeFbjdMapper.insertinsertSRaDayMonTimeFbjds(dataList.get(i));
        }
    }


    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/4/1 7:05 PM
     * @Deseription: 统计设备用电数据，一个小时一次
     * 每小时统计上一个小时的用电量，监测时间设置为上一个小时
     * @Params: null
     * @Return:
     * @Throws:
     */
    public void statisticsDeviceUsePowerCount(String startTime, String endTime) {
        // 每个小时运行一次，统计上个小时的设备用电数据
        // 获取上个小时的时间
        if (StringUtils.isEmpty(startTime)) {
            startTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:00:00", DateUtils.addDateHours(new Date(), -1));
        }
        if (StringUtils.isEmpty(endTime)) {
            endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:59:59", DateUtils.addDateHours(new Date(), -1));
        }
        List<MonElecHour> insertMonElecHours = new ArrayList<>();

        List<SRaRealTimeAnalysisRun> sRaRealTimeAnalysisRuns = sRaRealTimeAnalysisRunMapper.selectListByDate(Timestamp.valueOf(startTime), Timestamp.valueOf(endTime), null);
        // 根据设备进行分组
        Map<String, List<SRaRealTimeAnalysisRun>> collect = sRaRealTimeAnalysisRuns.stream().collect(Collectors.groupingBy(SRaRealTimeAnalysisRun::getDeviceId));
        String finalStartTime = startTime;
        collect.forEach((k, v) -> {
            // 统计该设备下上一个小时的用电数据
            BigDecimal count = v.stream().filter(x -> x.getActivePowerQuantity() != null).map(x -> new BigDecimal(x.getActivePowerQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add);
            // 存入某个表
            MonElecHour monElecHour = new MonElecHour();
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            monElecHour.setDataId(uuid);
            monElecHour.setDeviceId(k);
            monElecHour.setTimeType(TimeTypeEnum.HOUR.getCode());
            monElecHour.setDataTime(DateUtils.parseDate(finalStartTime));
            monElecHour.setCreateTime(new Date());
            monElecHour.setActivePowerQuantity(count.toString());
            insertMonElecHours.add(monElecHour);
        });
        // 批量插入数据库
        List<List<MonElecHour>> dataList = subList(insertMonElecHours, 1000);
        for (int i = 0; i < dataList.size(); i++) {
            monElecHourMapper.insertMonElecHours(dataList.get(i));
        }
    }



    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/4/1 7:05 PM
     * @Deseription: 统计设备用电数据，每日统计一次
     * @Params: null
     * @Return:
     * @Throws:
     */
    public void statisticsDeviceUsePowerCountByDay(String startTime, String endTime) throws Exception {
        // 每日统计一次，统计昨日小时的设备用电数据
        if (StringUtils.isEmpty(startTime)) {
            startTime = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", DateUtils.addDateDays(new Date(), -1));
        }
        if (StringUtils.isEmpty(endTime)) {
            endTime = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", new Date());
        }
        // 一天的数据大约有277万条，所以改成线程查询，24个线程，每个线程查询一个小时的数据
        List<Future<List<SRaRealTimeAnalysisRun>>> threadDataList = new ArrayList<>();
        List<SRaRealTimeAnalysisRun> resultList = new ArrayList<>();
        // 获取日期封装
        List<String[]> dateList = getDateList(startTime, endTime);

        for (String[] strings : dateList) {
            Future<List<SRaRealTimeAnalysisRun>> submit = controlTasksExecutor.submit(new ThreadQuerySRaRealTimeAnalysisRunData(strings[0], strings[1]));
            threadDataList.add(submit);
        }
        Long st = System.currentTimeMillis() + (1000 * 60 * 20);
        // 保证获取到全部的线程查询结果
        while (true){
            // 一条数据都查询不出来就跳出循环 或者 循环时间大于20分钟
            if (threadDataList.isEmpty() || System.currentTimeMillis() > st) {
                break;
            }
            // 循环获取
            for (int i = 0; i < threadDataList.size(); i++) {
                if (threadDataList.get(i).isDone()) {
                    resultList.addAll(threadDataList.get(i).get());
                    threadDataList.remove(i--);
                }
            }
            // 每隔0.5秒 检测一次
            TimeUnit.MILLISECONDS.sleep(500);
        }
        List<MonElecOther> insertMonElecOther = new ArrayList<>();

        // 根据设备进行分组
        Map<String, List<SRaRealTimeAnalysisRun>> collect = resultList.stream().collect(Collectors.groupingBy(SRaRealTimeAnalysisRun::getDeviceId));
        String finalStartTime = startTime;
        collect.forEach((k, v) -> {
            // 统计该设备下上一个小时的用电数据
            BigDecimal count = v.stream().filter(x -> x.getActivePowerQuantity() != null).map(x -> new BigDecimal(x.getActivePowerQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add);
            // 存入某个表
            MonElecOther monElecOther = new MonElecOther();
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            monElecOther.setDataId(uuid);
            monElecOther.setDeviceId(k);
            monElecOther.setTimeType(TimeTypeEnum.DAY.getCode());
            monElecOther.setDataTime(DateUtils.parseDate(finalStartTime));
            monElecOther.setActivePowerQuantity(count.toString());
            monElecOther.setCreateTime(new Date());
            insertMonElecOther.add(monElecOther);
        });

        // 批量插入数据库
        List<List<MonElecOther>> dataList = subList(insertMonElecOther, 1000);
        for (int i = 0; i < dataList.size(); i++) {
            monElecOtherMapper.insertMonElecOther(dataList.get(i));
        }
    }


    /**
     * 截取List
     * @param tList
     * @param subNum
     * @param <T>
     * @return
     */
    public static<T>  List<List<T>> subList(List<T> tList, Integer subNum) {
        // 新的截取到的list集合
        List<List<T>> tNewList = new ArrayList<List<T>>();
        // 要截取的下标上限
        Integer priIndex = 0;
        // 要截取的下标下限
        Integer lastIndex = 0;
        // 每次插入list的数量
        // Integer subNum = 500;
        // 查询出来list的总数目
        Integer totalNum = tList.size();
        // 总共需要插入的次数
        Integer insertTimes = totalNum / subNum;
        List<T> subNewList = new ArrayList<T>();
        for (int i = 0; i <= insertTimes; i++) {
            // [0--20) [20 --40) [40---60) [60---80) [80---100)
            priIndex = subNum * i;
            lastIndex = priIndex + subNum;
            // 判断是否是最后一次
            if (i == insertTimes) {
                //logger.info("最后一次截取："+priIndex + "," + lastIndex);
                subNewList = tList.subList(priIndex, tList.size());
            } else {
                // 非最后一次
                subNewList = tList.subList(priIndex, lastIndex);
            }
            if (subNewList.size() > 0) {
                //logger.info("开始将截取的list放入新的list中");
                tNewList.add(subNewList);
            }
        }
        return tNewList;
    }


    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/4/24 11:01
     * @Deseription: 获取24条数据 [yyyy-MM-dd 00:00:00,yyyy-MM-dd 01:00:00] ... [yyyy-MM-dd 23:00:00,yyyy-MM-dd+1 00:00:00]
     * @Params: null
     * @Return:
     * @Throws:
     */
    private List<String[]> getDateList(String startTime, String endTime) {
        List<String[]> list = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            String[] dateArr = new String[2];
            dateArr[0] = startTime.substring(0,11) + (i < 10 ? "0" + i : String.valueOf(i)) + ":00:00";
            if (i == 23) {
                dateArr[1] = endTime;
            } else {
                dateArr[1] = startTime.substring(0,11) + ((i + 1) < 10 ? "0" + (i + 1) : String.valueOf((i + 1))) + ":00:00";
            }
            list.add(dateArr);
        }
        return list;
    }

    /**
     * @Author: Mr.Yanghongtao
     * @data: 2023/4/24 12:42
     * @Deseription: 传入月初和月末，每5天分隔一条
     * @Params: null
     * @Return:
     * @Throws:
     */
    private List<String[]> getDateListMonth(String startTime, String endTime) {
        List<String[]> list = new ArrayList<>();
        for (int i = 5; i < 31; i+=5) {
            String[] dateArr = new String[2];
            if (i == 5) {
                dateArr[0] = startTime;
                dateArr[1] = DateUtils.getLastMonth() + "-" + (i < 10 ? "0" + i : i) + " 00:00:00";
                list.add(dateArr);
            } else if (i == 30) {
                dateArr[0] = DateUtils.getLastMonth() + "-" + ((i - 5) < 10 ? "0" + (i - 5) : (i - 5)) + " 00:00:00";
                dateArr[1] = endTime;;
                list.add(dateArr);
            } else {
                dateArr[0] = DateUtils.getLastMonth() + "-" + ((i - 5) < 10 ? "0" + (i - 5) : (i - 5)) + " 00:00:00";
                dateArr[1] = DateUtils.getLastMonth() + "-" + (i < 10 ? "0" + i : i) + " 00:00:00";
                list.add(dateArr);
            }
        }
        return list;
    }
}
