package com.jiayue.ipfcst.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.core.util.DateMomentUtil;
import com.jiayue.ipfcst.common.core.util.DateTimeUtil;
import com.jiayue.ipfcst.common.data.constant.enums.AlarmTypeEnum;
import com.jiayue.ipfcst.common.data.constant.enums.EquipmentTypeEnum;
import com.jiayue.ipfcst.common.data.constant.enums.FileStatusEnum;
import com.jiayue.ipfcst.common.data.constant.enums.FileTypeEnum;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.entity.gathertunnelinfo.*;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.Sender104TcpTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderCdtRtuTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusRtuTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusTcpTunnelInfo;
import com.jiayue.ipfcst.common.data.repository.*;
import com.jiayue.ipfcst.common.data.service.BaseService;
import com.jiayue.ipfcst.common.data.service.uploadfilerule.IUploadFileRuleService;
import com.jiayue.ipfcst.dto.ChannelStatusDto;
import com.jiayue.ipfcst.dto.DashboardEquipmentDto;
import com.jiayue.ipfcst.dto.TimeAndDataDto;
import com.jiayue.ipfcst.dto.UploadRateDto;
import com.jiayue.ipfcst.repository.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * 首页服务类
 *
 * @author xsl
 * @version 3.0
 */
@Service
@Slf4j
public class DashboardService extends BaseService {
  private final UploadObjectRepository uploadObjectRepository;

  private final UploadFileChannelRepository uploadFileChannelRepository;

  private final UploadFileLogRepository uploadFileLogRepository;

  private final WeatherStationInfoRepository weatherStationInfoRepository;

  private final WindTowerInfoRepository windTowerInfoRepository;

  private final FileAnalysisRecordRepository fileAnalysisRecordRepository;

  private final ProtocolGatherDataPointRepository protocolGatherDataPointRepository;

  private final WeatherStationStatusDataRepository weatherStationStatusDataRepository;

  private final WindTowerStatusDataRepository windTowerStatusDataRepository;

  private final Gather104TcpTunnelRepository gather104TcpTunnelRepository;

  private final GatherCdtRtuTunnelRepository gatherCdtRtuTunnelRepository;

  private final GatherModbusRtuTunnelRepository gatherModbusRtuTunnelRepository;

  private final GatherModbusRtuWithTcpServerTunnelRepository gatherModbusRtuWithTcpServerTunnelRepository;

  private final GatherModbusTcpTunnelRepository gatherModbusTcpTunnelRepository;

  private final Sender104TcpTunnelRepository sender104TcpTunnelRepository;

  private final SenderCdtRtuTunnelRepository senderCdtRtuTunnelRepository;

  private final SenderModbusRtuTunnelRepository senderModbusRtuTunnelRepository;

  private final SenderModbusTcpTunnelRepository senderModbusTcpTunnelRepository;

  private final ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository;
  private final ForecastPowerUltraShortTermOneHisRepository forecastPowerUltraShortTermOneHisRepository;

  private final ForecastPowerShortTermHisRepository forecastPowerShortTermHisRepository;
  private final ForecastPowerShortTermOneHisRepository forecastPowerShortTermOneHisRepository;

  private final PowerStationStatusDataRepository powerStationStatusDataRepository;
  private final PowerStationStatusDataOneRepository powerStationStatusDataOneRepository;

  private final ChannelDisconLogRepository channelDisconLogRepository;

  private final PowerLimitPlanSignRepository powerLimitPlanSignRepository;

  private final ChannelAlarmInfoRepository channelAlarmInfoRepository;

  private final QuartzRepository quartzRepository;

  private final FileParseTunnelInfoRepository fileParseTunnelInfoRepository;

  private final ElectricFieldRepository electricFieldRepository;
  private final SysParameterRepository sysParameterRepository;

  @Autowired
  private Map<String, IUploadFileRuleService> uploadFileRuleServiceMap;

  public DashboardService(UploadObjectRepository uploadObjectRepository, UploadFileChannelRepository uploadFileChannelRepository, UploadFileLogRepository uploadFileLogRepository, WeatherStationInfoRepository weatherStationInfoRepository, WindTowerInfoRepository windTowerInfoRepository, FileAnalysisRecordRepository fileAnalysisRecordRepository, ProtocolGatherDataPointRepository protocolGatherDataPointRepository, WeatherStationStatusDataRepository weatherStationStatusDataRepository, WindTowerStatusDataRepository windTowerStatusDataRepository, Gather104TcpTunnelRepository gather104TcpTunnelRepository, GatherCdtRtuTunnelRepository gatherCdtRtuTunnelRepository, GatherModbusRtuTunnelRepository gatherModbusRtuTunnelRepository, GatherModbusRtuWithTcpServerTunnelRepository gatherModbusRtuWithTcpServerTunnelRepository, GatherModbusTcpTunnelRepository gatherModbusTcpTunnelRepository, Sender104TcpTunnelRepository sender104TcpTunnelRepository, SenderCdtRtuTunnelRepository senderCdtRtuTunnelRepository, SenderModbusRtuTunnelRepository senderModbusRtuTunnelRepository, SenderModbusTcpTunnelRepository senderModbusTcpTunnelRepository, ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository, ForecastPowerUltraShortTermOneHisRepository forecastPowerUltraShortTermOneHisRepository, ForecastPowerShortTermHisRepository forecastPowerShortTermHisRepository, ForecastPowerShortTermOneHisRepository forecastPowerShortTermOneHisRepository, PowerStationStatusDataRepository powerStationStatusDataRepository, PowerStationStatusDataOneRepository powerStationStatusDataOneRepository, ChannelDisconLogRepository channelDisconLogRepository, PowerLimitPlanSignRepository powerLimitPlanSignRepository, ChannelAlarmInfoRepository channelAlarmInfoRepository, QuartzRepository quartzRepository, FileParseTunnelInfoRepository fileParseTunnelInfoRepository, ElectricFieldRepository electricFieldRepository, SysParameterRepository sysParameterRepository) {
    this.uploadObjectRepository = uploadObjectRepository;
    this.uploadFileChannelRepository = uploadFileChannelRepository;
    this.uploadFileLogRepository = uploadFileLogRepository;
    this.weatherStationInfoRepository = weatherStationInfoRepository;
    this.windTowerInfoRepository = windTowerInfoRepository;
    this.fileAnalysisRecordRepository = fileAnalysisRecordRepository;
    this.protocolGatherDataPointRepository = protocolGatherDataPointRepository;
    this.weatherStationStatusDataRepository = weatherStationStatusDataRepository;
    this.windTowerStatusDataRepository = windTowerStatusDataRepository;
    this.gather104TcpTunnelRepository = gather104TcpTunnelRepository;
    this.gatherCdtRtuTunnelRepository = gatherCdtRtuTunnelRepository;
    this.gatherModbusRtuTunnelRepository = gatherModbusRtuTunnelRepository;
    this.gatherModbusRtuWithTcpServerTunnelRepository = gatherModbusRtuWithTcpServerTunnelRepository;
    this.gatherModbusTcpTunnelRepository = gatherModbusTcpTunnelRepository;
    this.sender104TcpTunnelRepository = sender104TcpTunnelRepository;
    this.senderCdtRtuTunnelRepository = senderCdtRtuTunnelRepository;
    this.senderModbusRtuTunnelRepository = senderModbusRtuTunnelRepository;
    this.senderModbusTcpTunnelRepository = senderModbusTcpTunnelRepository;
    this.forecastPowerUltraShortTermHisRepository = forecastPowerUltraShortTermHisRepository;
    this.forecastPowerUltraShortTermOneHisRepository = forecastPowerUltraShortTermOneHisRepository;
    this.forecastPowerShortTermHisRepository = forecastPowerShortTermHisRepository;
    this.forecastPowerShortTermOneHisRepository = forecastPowerShortTermOneHisRepository;
    this.powerStationStatusDataRepository = powerStationStatusDataRepository;
    this.powerStationStatusDataOneRepository = powerStationStatusDataOneRepository;
    this.channelDisconLogRepository = channelDisconLogRepository;
    this.powerLimitPlanSignRepository = powerLimitPlanSignRepository;
    this.channelAlarmInfoRepository = channelAlarmInfoRepository;
    this.quartzRepository = quartzRepository;
    this.fileParseTunnelInfoRepository = fileParseTunnelInfoRepository;
    this.electricFieldRepository = electricFieldRepository;
    this.sysParameterRepository = sysParameterRepository;
  }

  /**
   * 获取首页通道状态
   * Map的key:analysisList,dataexchangeList,callBackList,uploadList
   *
   * @return
   */
  public Map getChannelStatus() {
    HttpURLConnection conn = null;
    InputStream is = null;
    Map<String, String> uploadFileMap = new HashMap();
    Map<String, String> dataexchangeMap = new HashMap();
    Map<String, String> callBackMap = new HashMap();
    String demo = super.getSysParameter("demo", "1");

    try {
//      URL url = new URL("https://localhost:9001/consoleOpenInterface/getChannelStatus");
//      //打开和url之间的连接
//      conn = (HttpURLConnection) url.openConnection();
//      conn.setRequestProperty("accept", "*/*");
//      conn.setRequestProperty("connection", "Keep-Alive");
//      conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//      conn.setDoOutput(true);
//      conn.setDoInput(true);
//      conn.setRequestMethod("GET");//GET和POST必须全大写
//      conn.connect();
//      //获取URLConnection对象对应的输入流
//      is = conn.getInputStream();
//      //构造一个字符流缓存
//      BufferedReader br = new BufferedReader(new InputStreamReader(is));
//      String str = "";
//      while ((str = br.readLine()) != null) {
//        str = new String(str.getBytes(), "UTF-8");//解决中文乱码问题
//        JSONObject jsonObject = JSONUtil.parseObj(str);
//        uploadFileMap = (Map) jsonObject.get("uploadFileMap");
//        dataexchangeMap = (Map) jsonObject.get("dataexchangeMap");
//        callBackMap = (Map) jsonObject.get("callBackMap");
//      }

      String body = HttpRequest.get("https://localhost:9001/consoleOpenInterface/getChannelStatus").execute().body();
      JSONObject json = JSONUtil.parseObj(body);
      uploadFileMap = (Map) json.get("uploadFileMap");
      dataexchangeMap = (Map) json.get("dataexchangeMap");
      callBackMap = (Map) json.get("callBackMap");
    } catch (Exception e) {
      log.error("获取console应用状态失败", e);
    } finally {
      if (is != null) {
        //关闭流
        try {
          is.close();
        } catch (IOException e) {
          log.error("关闭流失败", e);
        }
      }
      if (conn != null) {
        conn.disconnect();
      }
    }
    // 返回前端各通道状态的map
    Map resultMap = new HashMap();
    // 拼装接入通道状态
    List<Gather104TcpTunnelInfo> gather104TcpTunnelInfoList = gather104TcpTunnelRepository.findAll();
    gather104TcpTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<GatherCdtRtuTunnelInfo> gatherCdtRtuTunnelInfoList = gatherCdtRtuTunnelRepository.findAll();
    gatherCdtRtuTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<GatherModbusRtuTunnelInfo> gatherModbusRtuTunnelInfoList = gatherModbusRtuTunnelRepository.findAll();
    gatherModbusRtuTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<GatherModbusTcpTunnelInfo> gatherModbusTcpTunnelInfoList = gatherModbusTcpTunnelRepository.findAll();
    gatherModbusTcpTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<GatherModbusRtuWithTcpServerTunnelInfo> gatherModbusRtuWithTcpServerTunnelList = gatherModbusRtuWithTcpServerTunnelRepository.findAll();
    gatherModbusRtuWithTcpServerTunnelList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<Gather104TcpTunnelInfo> gather104TcpTunnelInfos = gather104TcpTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<GatherCdtRtuTunnelInfo> gatherCdtRtuTunnelInfos = gatherCdtRtuTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<GatherModbusRtuTunnelInfo> gatherModbusRtuTunnelInfos = gatherModbusRtuTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<GatherModbusTcpTunnelInfo> gatherModbusTcpTunnelInfos = gatherModbusTcpTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<FileParseTunnelInfo> fileParseTunnelInfoList = fileParseTunnelInfoRepository.findAll();
    List<GatherModbusRtuWithTcpServerTunnelInfo> gatherModbusRtuWithTcpServerTunnels = gatherModbusRtuWithTcpServerTunnelList.stream().filter(w -> w.getIsEnable() == true).collect(toList());
    List<ChannelStatusDto> dataexchangeList = new ArrayList();

    for (FileParseTunnelInfo fileParseTunnelInfo : fileParseTunnelInfoList) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(fileParseTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(fileParseTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(fileParseTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(fileParseTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("");
      dataexchangeList.add(uploadObjectStatusDto);
    }
    for (Gather104TcpTunnelInfo gather104TcpTunnelInfo : gather104TcpTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(gather104TcpTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(gather104TcpTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(gather104TcpTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(gather104TcpTunnelInfo.getId())) : "0");
      }

      uploadObjectStatusDto.setTips("本地IP:" + gather104TcpTunnelInfo.getSelfIp() + " 本地端口:" + gather104TcpTunnelInfo.getSelfPort() + " 远端IP:" + gather104TcpTunnelInfo.getRemoteIp() + " 远端端口:" + gather104TcpTunnelInfo.getRemotePort());
      dataexchangeList.add(uploadObjectStatusDto);
    }

    for (GatherModbusRtuWithTcpServerTunnelInfo gatherModbusRtuWithTcpServerTunnelInfo : gatherModbusRtuWithTcpServerTunnels) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(gatherModbusRtuWithTcpServerTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(gatherModbusRtuWithTcpServerTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(gatherModbusRtuWithTcpServerTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(gatherModbusRtuWithTcpServerTunnelInfo.getId())) : "0");
      }

      uploadObjectStatusDto.setTips("本地IP:" + gatherModbusRtuWithTcpServerTunnelInfo.getSelfIp() + " 本地端口:" + gatherModbusRtuWithTcpServerTunnelInfo.getSelfPort() + " 远端IP:" + gatherModbusRtuWithTcpServerTunnelInfo.getRemoteIp() );
      dataexchangeList.add(uploadObjectStatusDto);
    }
    for (GatherCdtRtuTunnelInfo gatherCdtRtuTunnelInfo : gatherCdtRtuTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(gatherCdtRtuTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(gatherCdtRtuTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(gatherCdtRtuTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(gatherCdtRtuTunnelInfo.getId())) : "0");
      }

      uploadObjectStatusDto.setTips("串口名称:" + gatherCdtRtuTunnelInfo.getSerialName());
      dataexchangeList.add(uploadObjectStatusDto);
    }
    for (GatherModbusRtuTunnelInfo gatherModbusRtuTunnelInfo : gatherModbusRtuTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(gatherModbusRtuTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(gatherModbusRtuTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(gatherModbusRtuTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(gatherModbusRtuTunnelInfo.getId())) : "0");
      }

      uploadObjectStatusDto.setTips("串口名称:" + gatherModbusRtuTunnelInfo.getSerialName());
      dataexchangeList.add(uploadObjectStatusDto);
    }
    for (GatherModbusTcpTunnelInfo gatherModbusTcpTunnelInfo : gatherModbusTcpTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(gatherModbusTcpTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(gatherModbusTcpTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else {
        uploadObjectStatusDto.setChannelStatus(dataexchangeMap.get(String.valueOf(gatherModbusTcpTunnelInfo.getId())) != null ? dataexchangeMap.get(String.valueOf(gatherModbusTcpTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("本地IP:" + gatherModbusTcpTunnelInfo.getSelfIp() + " 本地端口:" + gatherModbusTcpTunnelInfo.getSelfPort() + " 远端IP:" + gatherModbusTcpTunnelInfo.getRemoteIp() + " 远端端口:" + gatherModbusTcpTunnelInfo.getRemotePort());
      dataexchangeList.add(uploadObjectStatusDto);
    }
    resultMap.put("dataexchangeList", dataexchangeList);
    // 拼装回传通道状态
    List<Sender104TcpTunnelInfo> sender104TcpTunnelInfoList = sender104TcpTunnelRepository.findAll();
    sender104TcpTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<SenderCdtRtuTunnelInfo> senderCdtRtuTunnelInfoList = senderCdtRtuTunnelRepository.findAll();
    senderCdtRtuTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<SenderModbusRtuTunnelInfo> senderModbusRtuTunnelInfoList = senderModbusRtuTunnelRepository.findAll();
    senderModbusRtuTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<SenderModbusTcpTunnelInfo> senderModbusTcpTunnelInfoList = senderModbusTcpTunnelRepository.findAll();
    senderModbusTcpTunnelInfoList.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
    List<Sender104TcpTunnelInfo> sender104TcpTunnelInfos = sender104TcpTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<SenderCdtRtuTunnelInfo> senderCdtRtuTunnelInfos = senderCdtRtuTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<SenderModbusRtuTunnelInfo> senderModbusRtuTunnelInfos = senderModbusRtuTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<SenderModbusTcpTunnelInfo> senderModbusTcpTunnelInfos = senderModbusTcpTunnelInfoList.stream().filter(w -> w.getIsEnable() == true).collect(Collectors.toList());
    List<ChannelStatusDto> callBackList = new ArrayList();
    for (Sender104TcpTunnelInfo sender104TcpTunnelInfo : sender104TcpTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(sender104TcpTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(sender104TcpTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(callBackMap.get(String.valueOf(sender104TcpTunnelInfo.getId())) != null ? callBackMap.get(String.valueOf(sender104TcpTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("本地IP:" + sender104TcpTunnelInfo.getSelfIp() + " 本地端口:" + sender104TcpTunnelInfo.getSelfPort());
      callBackList.add(uploadObjectStatusDto);
    }
    for (SenderCdtRtuTunnelInfo senderCdtRtuTunnelInfo : senderCdtRtuTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(senderCdtRtuTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(senderCdtRtuTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(callBackMap.get(String.valueOf(senderCdtRtuTunnelInfo.getId())) != null ? callBackMap.get(String.valueOf(senderCdtRtuTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("串口名称:" + senderCdtRtuTunnelInfo.getSerialName());
      callBackList.add(uploadObjectStatusDto);
    }
    for (SenderModbusRtuTunnelInfo senderModbusRtuTunnelInfo : senderModbusRtuTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(senderModbusRtuTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(senderModbusRtuTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(callBackMap.get(String.valueOf(senderModbusRtuTunnelInfo.getId())) != null ? callBackMap.get(String.valueOf(senderModbusRtuTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("串口名称:" + senderModbusRtuTunnelInfo.getSerialName());
      callBackList.add(uploadObjectStatusDto);
    }
    for (SenderModbusTcpTunnelInfo senderModbusTcpTunnelInfo : senderModbusTcpTunnelInfos) {
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(senderModbusTcpTunnelInfo.getId()));
      uploadObjectStatusDto.setChannelName(senderModbusTcpTunnelInfo.getTunnelName());
      if ("1".equals(demo)){
        uploadObjectStatusDto.setChannelStatus("1");
      }
      else{
        uploadObjectStatusDto.setChannelStatus(callBackMap.get(String.valueOf(senderModbusTcpTunnelInfo.getId())) != null ? callBackMap.get(String.valueOf(senderModbusTcpTunnelInfo.getId())) : "0");
      }
      uploadObjectStatusDto.setTips("本地IP:" + senderModbusTcpTunnelInfo.getSelfIp() + " 本地端口:" + senderModbusTcpTunnelInfo.getSelfPort());
      callBackList.add(uploadObjectStatusDto);
    }
    resultMap.put("callBackList", callBackList);

    // 拼装上报通道状态
    Map<String, String> objectStatusMap = new HashMap<String, String>();
    Map<String, String> channelStatusDetailMap = new HashMap<String, String>();
    for (Map.Entry<String, String> entry : uploadFileMap.entrySet()) {
      String[] statusKeys = entry.getKey().toString().split("-");
      channelStatusDetailMap.put(statusKeys[1], entry.getValue().toString());
      if ("1".equals(entry.getValue().toString())) {
        // 将正常的通道获取
        objectStatusMap.put(statusKeys[0], "1");
      }
    }
    List<UploadObject> uploadObjectList = uploadObjectRepository.findAll();
    List<UploadFileChannel> uploadFileChannelList = uploadFileChannelRepository.findAll();

    ElectricField electricField = null;
    Optional<ElectricField> electricFieldOptional = Optional.ofNullable(electricFieldRepository.findByStationCodeIsNotNull());
    if (electricFieldOptional.isPresent()) {
      electricField = electricFieldOptional.get();
    } else {
      log.error("首页获取通道状态时,查到场站信息未维护！！！");
    }

    List<ChannelStatusDto> uploadList = new ArrayList();
    for (UploadObject uploadObject : uploadObjectList) {
      List<UploadFileChannel> uploadFileChannels = uploadFileChannelList.stream().filter(t -> t.getUploadObjectId() == uploadObject.getId()).collect(Collectors.toList());
      ChannelStatusDto uploadObjectStatusDto = new ChannelStatusDto();
      uploadObjectStatusDto.setChannelId(String.valueOf(uploadObject.getId()));
      uploadObjectStatusDto.setChannelName(uploadObject.getUploadObjectName() + ":" + uploadObject.getObjectNo());


      if ("E46".equals(electricField.getProvinceEnum().toString()) && uploadFileChannels.size() == 0) {
        // 针对海南上报打包特殊情况，允许上报对象下没有通道，也让对象状态为绿色
        uploadObjectStatusDto.setChannelStatus("1");
      } else {
        if ("1".equals(demo)){
          uploadObjectStatusDto.setChannelStatus(objectStatusMap.get(String.valueOf(uploadObject.getId())) != null ? "1" : "1");
        }
        else{
          uploadObjectStatusDto.setChannelStatus(objectStatusMap.get(String.valueOf(uploadObject.getId())) != null ? "1" : "0");
        }

      }

      uploadList.add(uploadObjectStatusDto);

      String tips = "";
      for (int i = 0; i < uploadFileChannels.size(); i++) {
        UploadFileChannel uploadFileChannel = uploadFileChannels.get(i);
        String statusColor = "";
        if ("1".equals(channelStatusDetailMap.get("" + uploadFileChannel.getId()))) {
          statusColor = "00CC66";
        } else {
          if ("1".equals(demo)){
            statusColor = "00CC66";
          }
          else{
            statusColor = "FF0033";
          }

        }
        tips = tips + uploadFileChannel.getChannelName() + " 状态:" + "<span style=\"border-radius:50%;height:10px;width:10px;display:inline-block;background:#" + statusColor + "\"></span>" + "&nbsp;&nbsp;" + "远端IP:" + uploadFileChannel.getRemoteIp() + " 远端端口:" + uploadFileChannel.getRemotePort();
        if (!"ftp".equals(uploadObject.getUploadProtocolEnum().getCode()) && !"sftp".equals(uploadObject.getUploadProtocolEnum().getCode())) {
          tips = tips + " 本地IP:" + uploadFileChannel.getLocalIp() + " 本地端口:" + uploadFileChannel.getLocalPort();
        }
        if (i + 1 != uploadFileChannels.size()) {
          tips = tips + "<br>";
        }
      }
      if ("".equals(tips)) {
        tips = "上报对象下没有通道";
      }
      uploadObjectStatusDto.setTips(tips);
    }
    resultMap.put("uploadList", uploadList);
    // 拼装解析文件通道状态
    Long time = new Date().getTime();
    List<FileAnalysisRecord> fileAnalysisRecordList = fileAnalysisRecordRepository.findByCreateTimeBetween(DateTimeUtil.getDayStartTime(time), DateTimeUtil.getDayLastTime(time));
    List<ChannelStatusDto> analysisList = new ArrayList<>();
    // 过滤出短期成功的
//    List<FileAnalysisRecord> dqList = fileAnalysisRecordList.stream().filter(w -> "DQ".equals(w.getFileType())).collect(Collectors.toList());
//    String dqStatus = "0";
//    String dqTips = "";
//    if (dqList.size() > 0) {
//      dqList.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
//      dqStatus = dqList.get(0).getFileStatus();
//      dqTips = "最后解析短期时间：" + DateFormatUtils.format(dqList.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
//    } else {
//      dqTips = "今日未解析过短期文件";
//    }
//    List<ChannelStatusDto> analysisList = new ArrayList<>();
//    ChannelStatusDto dqAnalysisDto = new ChannelStatusDto();
//    dqAnalysisDto.setChannelId("DQ");
//    dqAnalysisDto.setChannelName("短期文件");
//    dqAnalysisDto.setChannelStatus(dqStatus);
//    dqAnalysisDto.setTips(dqTips);
//    analysisList.add(dqAnalysisDto);
//
//    List<FileAnalysisRecord> nwpList = fileAnalysisRecordList.stream().filter(w -> "NWP".equals(w.getFileType())).collect(Collectors.toList());
//    String nwpStatus = "0";
//    String nwpTips = "";
//    if (nwpList.size() > 0) {
//      nwpList.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
//      nwpStatus = nwpList.get(0).getFileStatus();
//      nwpTips = "最后解析NWP时间：" + DateFormatUtils.format(nwpList.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
//    } else {
//      nwpTips = "今日未解析过NWP文件";
//    }
//    ChannelStatusDto nwpAnalysisDto = new ChannelStatusDto();
//    nwpAnalysisDto.setChannelId("NWP");
//    nwpAnalysisDto.setChannelName("NWP文件");
//    nwpAnalysisDto.setChannelStatus(nwpStatus);
//    nwpAnalysisDto.setTips(nwpTips);
//    analysisList.add(nwpAnalysisDto);

    // 短期一期
    List<FileAnalysisRecord> dqList1 = fileAnalysisRecordList.stream().filter(w -> "DQ".equals(w.getFileType())).collect(Collectors.toList());
    String dqStatus1 = "";
    String dqTips1 = "";
    if ("1".equals(demo)){
      dqStatus1 = "1";
      dqTips1 = "最后解析光伏短期时间：" + DateFormatUtils.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd HH:mm:ss");
    }
    else{
      dqStatus1 = "0";
      if (dqList1.size() > 0) {
        dqList1.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
        dqStatus1 = dqList1.get(0).getFileStatus();
        dqTips1 = "最后解析光伏短期时间：" + DateFormatUtils.format(dqList1.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
      } else {
        dqTips1 = "今日未解析过光伏短期文件";
      }
    }

    ChannelStatusDto dqAnalysisDto1 = new ChannelStatusDto();
    dqAnalysisDto1.setChannelId("DQ");
    dqAnalysisDto1.setChannelName("光伏短期文件");
    dqAnalysisDto1.setChannelStatus(dqStatus1);
    dqAnalysisDto1.setTips(dqTips1);
    analysisList.add(dqAnalysisDto1);
    // NWP一期
    List<FileAnalysisRecord> nwpList1 = fileAnalysisRecordList.stream().filter(w -> "NWP".equals(w.getFileType())).collect(Collectors.toList());
    String nwpStatus1 = "";
    String nwpTips1 = "";
    if ("1".equals(demo)){
      nwpStatus1 = "1";
      nwpTips1 = "最后解析光伏NWP时间：" + DateFormatUtils.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd HH:mm:ss");
    }
    else{
      nwpStatus1 = "0";
      if (nwpList1.size() > 0) {
        nwpList1.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
        nwpStatus1 = nwpList1.get(0).getFileStatus();
        nwpTips1 = "最后解析光伏NWP时间：" + DateFormatUtils.format(nwpList1.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
      } else {
        nwpTips1 = "今日未解析过光伏NWP文件";
      }
    }

    ChannelStatusDto nwpAnalysisDto1 = new ChannelStatusDto();
    nwpAnalysisDto1.setChannelId("NWP");
    nwpAnalysisDto1.setChannelName("光伏NWP文件");
    nwpAnalysisDto1.setChannelStatus(nwpStatus1);
    nwpAnalysisDto1.setTips(nwpTips1);
    analysisList.add(nwpAnalysisDto1);

    // 短期二期
    List<FileAnalysisRecord> dqList2 = fileAnalysisRecordList.stream().filter(w -> "DQ1".equals(w.getFileType())).collect(Collectors.toList());
    String dqStatus2 = "";
    String dqTips2 = "";
    if ("1".equals(demo)){
      dqStatus2 = "1";
      dqTips2 = "最后解析风电短期时间：" + DateFormatUtils.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd HH:mm:ss");
    }
    else{
      dqStatus2 = "0";
      if (dqList2.size() > 0) {
        dqList2.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
        dqStatus2 = dqList2.get(0).getFileStatus();
        dqTips2 = "最后解析风电短期时间：" + DateFormatUtils.format(dqList2.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
      } else {
        dqTips2 = "今日未解析过风电短期文件";
      }
    }


    ChannelStatusDto dqAnalysisDto2 = new ChannelStatusDto();
    dqAnalysisDto2.setChannelId("DQ1");
    dqAnalysisDto2.setChannelName("风电短期文件");
    dqAnalysisDto2.setChannelStatus(dqStatus2);
    dqAnalysisDto2.setTips(dqTips2);
    analysisList.add(dqAnalysisDto2);
    // NWP二期
    List<FileAnalysisRecord> nwpList2 = fileAnalysisRecordList.stream().filter(w -> "NWP1".equals(w.getFileType())).collect(Collectors.toList());
    String nwpStatus2 = "";
    String nwpTips2 = "";
    if ("1".equals(demo)){
      nwpStatus2 = "1";
      nwpTips2 = "最后解析风电NWP时间：" + DateFormatUtils.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd HH:mm:ss");
    }
    else{
      nwpStatus2 = "0";
      if (nwpList2.size() > 0) {
        nwpList2.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime).reversed());
        nwpStatus2 = nwpList2.get(0).getFileStatus();
        nwpTips2 = "最后解析风电NWP时间：" + DateFormatUtils.format(nwpList2.get(0).getCreateTime(), "yyyy-MM-dd HH:mm:ss");
      } else {
        nwpTips2 = "今日未解析过风电NWP文件";
      }
    }


    ChannelStatusDto nwpAnalysisDto2 = new ChannelStatusDto();
    nwpAnalysisDto2.setChannelId("NWP1");
    nwpAnalysisDto2.setChannelName("风电NWP文件");
    nwpAnalysisDto2.setChannelStatus(nwpStatus2);
    nwpAnalysisDto2.setTips(nwpTips2);
    analysisList.add(nwpAnalysisDto2);

    resultMap.put("analysisList", analysisList);

    return resultMap;
  }
  /**
   * 获取上报文件信息
   *
   * @return
   */
  public Map getUploadFileInfo() {
    // 返回前端结果Map,包含上报率及所有未上报集合
    Map resultMap = new HashMap();
    Specification<UploadFileLog> specification = this.getQuerySpecification(DateMomentUtil.getDayStartTime(new Date().getTime()));
    List<UploadFileLog> uploadFileLogList = uploadFileLogRepository.findAll(specification);
    // 定义查询结果List
    List<UploadFileLog> notUploadFileList = new ArrayList<>();
    // 除了上报正常的都找出来
    notUploadFileList.addAll(uploadFileLogList.stream().filter(uploadFileLog -> !uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E2)&& !uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E5)).collect(toList()));
    // 定义上报对象上报率
    List uploadObjectRateList = new ArrayList();
    List<UploadObject> uploadObjectList = uploadObjectRepository.findAll();
    // 获取未生成的文件信息
    if (uploadFileRuleServiceMap != null) {
      String pro = "";
      ElectricField electricField = null;
      try {
        electricField = super.getElectricField();
      } catch (BusinessException e) {
        e.printStackTrace();
      }
      if (electricField != null) {
        pro = electricField.getProvinceEnum().name();
      }
      IUploadFileRuleService uploadFileRuleService = uploadFileRuleServiceMap.get(pro.toLowerCase() + "UploadFileRuleService");
      if (uploadFileRuleService instanceof IUploadFileRuleService) {
        List<Quartz> quartzList = quartzRepository.findAll();
        for (UploadObject uploadObject : uploadObjectList) {
          // 查询所有类型
          String[] uploadFileTypes = uploadObject.getUploadFileType().split(",");
          List<UploadRateDto> uploadRateList = new ArrayList();
          for (int i = 0; i < uploadFileTypes.length; i++) {
            String executeClass = "com.jiayue.ipfcst.fileupload.job.UploadFile" + uploadFileTypes[i] + "Job";
            List<Quartz> quartzs = quartzList.stream().filter(u -> executeClass.equals(u.getExecuteClass())).collect(Collectors.toList());
            String cronStr = "";
            if (quartzs.size() > 0) {
              cronStr = quartzs.get(0).getCronExpression();
            }
            if (uploadFileTypes[i].equals("E156")||uploadFileTypes[i].equals("E154")||uploadFileTypes[i].equals("E158")){
              // 未来12个月预测发电量
              CronExpression cronExpression = null;
              try {
                cronExpression = new CronExpression(cronStr);
              } catch (ParseException e) {
                e.printStackTrace();
              }
              // cron表达式日期
              String str = cronExpression.getExpressionSummary();
              String tempCron = "{"+str.replaceAll("\n",",")+"}";
              JSONObject json = JSONUtil.parseObj(tempCron);
              String cronDaysOfMonth = json.get("daysOfMonth").toString();

              // 参数日期
              Calendar calendar = Calendar.getInstance();
              calendar.setTime(new Date());
              int paramDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
              if (paramDayOfMonth!=Integer.parseInt(cronDaysOfMonth)){
                continue;
              }
            }

            // 此类型应该上报的文件名称
            List<String> shoudFileNameList = uploadFileRuleService.getShouldFile(electricField, new Date(), uploadFileTypes[i], cronStr);
            String uploadFileType = uploadFileTypes[i];
            // 已经生成的文件
            List<UploadFileLog> filterList = uploadFileLogList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo())).collect(toList());
            // 过滤出未生成的文件名称
            List<String> noCreateFileNameList = shoudFileNameList.stream().filter(item ->
              !filterList.stream().map(e -> e.getFileName())
                .collect(Collectors.toList()).contains(item)).collect(Collectors.toList());

            for (String noCreateFileName : noCreateFileNameList) {
              UploadFileLog noCreateFileLog = new UploadFileLog();
              noCreateFileLog.setUploadObjectNo(uploadObject.getObjectNo());
              noCreateFileLog.setUploadObjectName(uploadObject.getUploadObjectName());
              noCreateFileLog.setFileStatusEnum(FileStatusEnum.E4);
              noCreateFileLog.setFileTypeEnum(FileTypeEnum.valueOf(uploadFileType));
              noCreateFileLog.setFileName(noCreateFileName);
              noCreateFileLog.setUploadProtocolEnum(uploadObject.getUploadProtocolEnum());
              notUploadFileList.add(noCreateFileLog);
            }
            // 统计每个类型上报率信息
            List<UploadFileLog> normalList = uploadFileLogList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo()) && uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E2)||uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo()) && uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E5)).collect(toList());
            UploadRateDto uploadRateDto = new UploadRateDto();
            uploadRateDto.setShouldUploadNums(String.valueOf(shoudFileNameList.size()));
            uploadRateDto.setUploadObjectName(uploadObject.getUploadObjectName());
            uploadRateDto.setUploadTypeName(FileTypeEnum.valueOf(uploadFileType).getMessage());
            uploadRateDto.setUploadNums(String.valueOf(normalList.size()));
            BigDecimal normalB = new BigDecimal(normalList.size());
            BigDecimal shouldB = new BigDecimal(shoudFileNameList.size());
            if (shouldB.compareTo(new BigDecimal(0)) == 0) {
              uploadRateDto.setUploadRate("未到时间");
            } else {
              BigDecimal rate = getRate(normalB, shouldB,uploadFileType);
              NumberFormat numberFormat = NumberFormat.getPercentInstance();
              numberFormat.setMaximumFractionDigits(0);
              uploadRateDto.setUploadRate(numberFormat.format(rate.doubleValue()));
            }

            uploadRateList.add(uploadRateDto);
          }
          uploadObjectRateList.add(uploadRateList);
        }
      }
    }

    List<UploadFileLog> returnUploadFileList = new ArrayList<>();
    if (notUploadFileList.size() > 0) {
      for (UploadObject uploadObject : uploadObjectList) {
        String[] uploadType = uploadObject.getUploadFileType().split(",");
        for (int j = 0; j < uploadType.length; j++) {
          String ut = uploadType[j];
          List<UploadFileLog> filterTypeList = notUploadFileList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(ut)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo())).collect(toList());
          returnUploadFileList.addAll(filterTypeList);
        }
      }
    }

    List<UploadFileLog> notUploadSortResultList = returnUploadFileList.stream()
      .sorted(Comparator.comparing((UploadFileLog p) -> p.getUploadObjectNo())
        .thenComparing(UploadFileLog::getFileTypeEnum).thenComparing(UploadFileLog::getFileName)).collect(Collectors.toList());

    resultMap.put("uploadObjectRateList", uploadObjectRateList);
    resultMap.put("notUploadSortResultList", notUploadSortResultList);
    return resultMap;
  }
  /**
   * 获取上报文件信息
   *
   * @return
   */
  public Map getDashboardUploadFileInfo() {
    // 返回前端结果Map,包含上报率及所有未上报集合
    Map resultMap = new HashMap();
    Specification<UploadFileLog> specification = this.getQuerySpecification(DateMomentUtil.getDayStartTime(new Date().getTime()));
    List<UploadFileLog> uploadFileLogList = uploadFileLogRepository.findAll(specification);
    // 定义查询结果List
    List<UploadFileLog> notUploadFileList = new ArrayList<>();
    // 除了上报正常的都找出来
    notUploadFileList.addAll(uploadFileLogList.stream().filter(uploadFileLog -> !uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E2)&& !uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E5)).collect(toList()));
    // 定义上报对象上报率
    List uploadObjectRateList = new ArrayList();
    List nameList = new ArrayList();
    List<UploadObject> uploadObjectList = uploadObjectRepository.findAll();
//    /*验证上报率是不是数字*/
//    String numReg = "/^[0-9]*$/";
//    Pattern pattern = Pattern.compile(numReg);
    // 获取未生成的文件信息
    if (uploadFileRuleServiceMap != null) {
      String pro = "";
      ElectricField electricField = null;
      try {
        electricField = super.getElectricField();
      } catch (BusinessException e) {
        e.printStackTrace();
      }
      if (electricField != null) {
        pro = electricField.getProvinceEnum().name();
      }
      IUploadFileRuleService uploadFileRuleService = uploadFileRuleServiceMap.get(pro.toLowerCase() + "UploadFileRuleService");
      if (uploadFileRuleService instanceof IUploadFileRuleService) {
        List<Quartz> quartzList = quartzRepository.findAll();
        for (UploadObject uploadObject : uploadObjectList) {
          // 查询所有类型
          String[] uploadFileTypes = uploadObject.getUploadFileType().split(",");
          List<UploadRateDto> uploadRateList = new ArrayList();
          //上报率标识：上报率不足100%为1  上报率100%为0
          int uploadRate = 0;
          for (int i = 0; i < uploadFileTypes.length; i++) {
            String executeClass = "com.jiayue.ipfcst.fileupload.job.UploadFile" + uploadFileTypes[i] + "Job";
            List<Quartz> quartzs = quartzList.stream().filter(u -> executeClass.equals(u.getExecuteClass())).collect(Collectors.toList());
            String cronStr = "";
            if (quartzs.size() > 0) {
              cronStr = quartzs.get(0).getCronExpression();
            }
            if (uploadFileTypes[i].equals("E156")||uploadFileTypes[i].equals("E154")||uploadFileTypes[i].equals("E158")){
              // 未来12个月预测发电量
              CronExpression cronExpression = null;
              try {
                cronExpression = new CronExpression(cronStr);
              } catch (ParseException e) {
                e.printStackTrace();
              }
              // cron表达式日期
              String str = cronExpression.getExpressionSummary();
              String tempCron = "{"+str.replaceAll("\n",",")+"}";
              JSONObject json = JSONUtil.parseObj(tempCron);
              String cronDaysOfMonth = json.get("daysOfMonth").toString();

              // 参数日期
              Calendar calendar = Calendar.getInstance();
              calendar.setTime(new Date());
              int paramDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
              if (paramDayOfMonth!=Integer.parseInt(cronDaysOfMonth)){
                continue;
              }
            }

            // 此类型应该上报的文件名称
            List<String> shoudFileNameList = uploadFileRuleService.getShouldFile(electricField, new Date(), uploadFileTypes[i], cronStr);
            String uploadFileType = uploadFileTypes[i];
            // 已经生成的文件
            List<UploadFileLog> filterList = uploadFileLogList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo())).collect(toList());
            // 过滤出未生成的文件名称
            List<String> noCreateFileNameList = shoudFileNameList.stream().filter(item ->
              !filterList.stream().map(e -> e.getFileName())
                .collect(Collectors.toList()).contains(item)).collect(Collectors.toList());

            for (String noCreateFileName : noCreateFileNameList) {
              UploadFileLog noCreateFileLog = new UploadFileLog();
              noCreateFileLog.setUploadObjectNo(uploadObject.getObjectNo());
              noCreateFileLog.setUploadObjectName(uploadObject.getUploadObjectName());
              noCreateFileLog.setFileStatusEnum(FileStatusEnum.E4);
              noCreateFileLog.setFileTypeEnum(FileTypeEnum.valueOf(uploadFileType));
              noCreateFileLog.setFileName(noCreateFileName);
              noCreateFileLog.setUploadProtocolEnum(uploadObject.getUploadProtocolEnum());
              notUploadFileList.add(noCreateFileLog);
            }
            // 统计每个类型上报率信息
            List<UploadFileLog> normalList = uploadFileLogList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo()) && uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E2)||uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(uploadFileType)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo()) && uploadFileLog.getFileStatusEnum().equals(FileStatusEnum.E5)).collect(toList());
            UploadRateDto uploadRateDto = new UploadRateDto();
            uploadRateDto.setShouldUploadNums(String.valueOf(shoudFileNameList.size()));
            uploadRateDto.setUploadObjectName(uploadObject.getUploadObjectName());
            uploadRateDto.setUploadTypeName(FileTypeEnum.valueOf(uploadFileType).getMessage());
            uploadRateDto.setUploadNums(String.valueOf(normalList.size()));
            BigDecimal normalB = new BigDecimal(normalList.size());
            BigDecimal shouldB = new BigDecimal(shoudFileNameList.size());
            if (shouldB.compareTo(new BigDecimal(0)) == 0) {
              uploadRateDto.setUploadRate("未到时间");
            } else {
              BigDecimal rate = getRate(normalB, shouldB,uploadFileType);
              NumberFormat numberFormat = NumberFormat.getPercentInstance();
              numberFormat.setMaximumFractionDigits(0);
              uploadRateDto.setUploadRate(numberFormat.format(rate.doubleValue()));
            }
//            /*若上报率不是数字，上报率算为100%*/
//            String rate =uploadRateDto.getUploadRate();
            if(uploadRate == 0){
              if(uploadRateDto.getUploadRate().equals("未到时间")){
                uploadRate = 0;
              }else{
                if(!uploadRateDto.getUploadRate().equals("100%")){
                  uploadRate = 1;
                }else{
                  uploadRate = 0;
                }
              }
            }
            uploadRateList.add(uploadRateDto);
          }
          Map map = new HashMap();
          map.put("uploadObjectName",uploadObject.getUploadObjectName());
          map.put("children",uploadRateList);
          map.put("uploadRate",uploadRate);
          Map map1 = new HashMap();
          map1.put("value",uploadObject.getUploadObjectName());
          map1.put("label",uploadObject.getUploadObjectName());

          uploadObjectRateList.add(map);
          nameList.add(map1);
        }
      }
    }

    List<UploadFileLog> returnUploadFileList = new ArrayList<>();
    if (notUploadFileList.size() > 0) {
      for (UploadObject uploadObject : uploadObjectList) {
        String[] uploadType = uploadObject.getUploadFileType().split(",");
        for (int j = 0; j < uploadType.length; j++) {
          String ut = uploadType[j];
          List<UploadFileLog> filterTypeList = notUploadFileList.stream().filter(uploadFileLog -> uploadFileLog.getFileTypeEnum().equals(FileTypeEnum.valueOf(ut)) && uploadFileLog.getUploadObjectNo().equals(uploadObject.getObjectNo())).collect(toList());
          returnUploadFileList.addAll(filterTypeList);
        }
      }
    }

    List<UploadFileLog> notUploadSortResultList = returnUploadFileList.stream()
      .sorted(Comparator.comparing((UploadFileLog p) -> p.getUploadObjectNo())
        .thenComparing(UploadFileLog::getFileTypeEnum).thenComparing(UploadFileLog::getFileName)).collect(Collectors.toList());

    resultMap.put("uploadObjectRateList", uploadObjectRateList);
    resultMap.put("notUploadSortResultList", notUploadSortResultList);
    resultMap.put("nameList", nameList);
    return resultMap;
  }



  public BigDecimal getRate(BigDecimal normalB, BigDecimal shouldB, String uploadFileType){
    BigDecimal rateB = normalB.divide(shouldB, 2, BigDecimal.ROUND_UP);
    String demo = super.getSysParameter("demo", "1");
    if ("1".equals(demo)) {
      rateB = new BigDecimal("1");
    }
    return rateB;
  }

  /**
   * 封装文件日志查询条件
   *
   * @param currentTime
   * @return
   */
  private Specification<UploadFileLog> getQuerySpecification(Long currentTime) {
    return (Specification<UploadFileLog>) (root, criteriaQuery, cb) -> {
      List<Predicate> predicates = new ArrayList<>();
      if (currentTime != null) {
        //大于或等于传入时间
        predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(String.class), DateFormatUtils.format(currentTime, "yyyy-MM-dd HH:mm:ss'")));
        predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(String.class), DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss'")));
      }
      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    };
  }

  /**
   * 获取设备ID及名称
   * nwp数据对比
   */
  public List<Map<String, String>> getEquipmentInfo() {
    ElectricField electricField = null;
    try {
      electricField = super.getElectricField();
    } catch (BusinessException e) {
      log.error("首页查询设备信息时获取场站信息失败", e);
    }
    List<Map<String, String>> equipmentInfoList = new ArrayList<>();
    if (electricField.getElectricFieldTypeEnum().getCode() == 1) {
      // 光伏
      List<WeatherStationInfo> weatherStationInfoList = weatherStationInfoRepository.findAllByOrderByIdAsc();
      for (WeatherStationInfo weatherStationInfo : weatherStationInfoList) {
        Map<String, String> equipmentInfoMap = new HashMap<>();
        equipmentInfoMap.put("equipmentId", String.valueOf(weatherStationInfo.getId()));
        equipmentInfoMap.put("equipmentName", weatherStationInfo.getName());
        equipmentInfoList.add(equipmentInfoMap);
      }
    } else {
      // 风电
      List<WindTowerInfo> windTowerInfoList = windTowerInfoRepository.findAllByOrderByIdAsc();
      for (WindTowerInfo windTowerInfo : windTowerInfoList) {
        Map<String, String> equipmentInfoMap = new HashMap<>();
        equipmentInfoMap.put("equipmentId", String.valueOf(windTowerInfo.getId()));
        equipmentInfoMap.put("equipmentName", windTowerInfo.getName());
        equipmentInfoList.add(equipmentInfoMap);
      }
    }
    return equipmentInfoList;
  }

  /**
   * 根据设备ID获取在首页显示的数据类型
   *
   * @param equipmentId
   * @return
   */
  public List<DashboardEquipmentDto> getEquipmentDataType(String equipmentId) {
    // 找出设备显示的数据类型
    ProtocolGatherDataPoint protocolGatherDataPoint = new ProtocolGatherDataPoint();
    protocolGatherDataPoint.setEquipmentId(Integer.parseInt(equipmentId));
    EquipmentAttribute att = new EquipmentAttribute();

    ElectricField electricField = null;
    try {
      electricField = super.getElectricField();
    } catch (BusinessException e) {
      log.error("首页查询设备信息时获取场站信息失败", e);
    }
    if (electricField.getElectricFieldTypeEnum().getCode() == 1) {
      // 光伏取气象站
      att.setEquipmentType(EquipmentTypeEnum.WEATHERSTATION);
    } else {
      // 风电取测风塔
      att.setEquipmentType(EquipmentTypeEnum.WINDTOWER);
    }
    protocolGatherDataPoint.setEquipmentAttribute(att);
    List<ProtocolGatherDataPoint> protocolGatherDataPointList = protocolGatherDataPointRepository.findAll(Example.of(protocolGatherDataPoint));
    List<ProtocolGatherDataPoint> displayDataTypeList = protocolGatherDataPointList.stream().filter(w -> w.getShowOnHomePage() > 0).collect(Collectors.toList());
    displayDataTypeList.sort(Comparator.comparing(ProtocolGatherDataPoint::getShowOnHomePage));
    List<DashboardEquipmentDto> equipmentDataTypeList = new ArrayList();
    if (electricField.getElectricFieldTypeEnum().getCode() == 1) {
      WeatherStationInfo weatherStationInfo = weatherStationInfoRepository.findById(Integer.parseInt(equipmentId)).get();
      long interval = 0;
      if (weatherStationInfo.getInterval().intValue() == 60) {
        // 每分钟接入数据
        interval = 60 * 1000;
      } else {
        // 按照5分钟接入显示
        interval = 60 * 1000 * 5;
      }
      Date endTime = new Date();
      long startDateTime = 0;
      long endDateTime = 0;
      try {
        startDateTime = DateMomentUtil.getMomentTime(endTime.getTime() - 60 * 1000 * 30, 1, interval);
        endDateTime = DateMomentUtil.getMomentTime(endTime.getTime(), 1, interval);
      } catch (Exception e) {
        log.error("获取环境数据出错：", e);
      }
      List tempList = new ArrayList();
      List timeList = new ArrayList();
      for (Long tempDateTime = startDateTime; tempDateTime <= endDateTime; tempDateTime = tempDateTime + interval) {
        // 获取map里的值
        tempList.add(DateFormatUtils.format(tempDateTime, "HH:mm"));
      }
      // 降序为了取最新时间的6个点
      tempList.sort(Comparator.reverseOrder());
      timeList.addAll(tempList.subList(0, 6));
      // 再变回升序排列
      Collections.sort(timeList);
      // 获取2小时内的气象站数据
      List<WeatherStationStatusData> weatherStationStatusDataList = weatherStationStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(new Date().getTime() - 1000 * 60 * 60 * 2), new Date(), Integer.parseInt(equipmentId));
      weatherStationStatusDataList.sort(Comparator.comparing(WeatherStationStatusData::getTime));
      for (ProtocolGatherDataPoint p : displayDataTypeList) {
        // 遍历出显示在首页的数据类型字段名称
        List<TimeAndDataDto> list = new ArrayList<>();
        String filedName = p.getEquipmentAttribute().getFieldName();//把字段名变为大写
        //得到get方法名
        filedName = "get" + filedName.toUpperCase().charAt(0) + filedName.substring(1);
        DashboardEquipmentDto dashboardEquipmentDto = new DashboardEquipmentDto();
        for (int i = 0; i < timeList.size(); i++) {
          int finalI = i;
          List<WeatherStationStatusData> dataList = weatherStationStatusDataList.stream().filter(a -> timeList.get(finalI).equals(DateFormatUtils.format(a.getTime(), "HH:mm"))).collect(Collectors.toList());
          if (dataList.size() > 0) {
            TimeAndDataDto timeAndDataDto = new TimeAndDataDto();
            timeAndDataDto.setTime(timeList.get(i).toString());
            timeAndDataDto.setVal(null);
            try {
              WeatherStationStatusData weatherStationStatusData = dataList.get(0);
              Method method = weatherStationStatusData.getClass().getMethod(filedName, new Class[]{});
              method.setAccessible(true);
              BigDecimal value = (BigDecimal) method.invoke(weatherStationStatusData, new Object[]{});
              timeAndDataDto.setVal(value.doubleValue() == -99 ? null : value.doubleValue());
            } catch (Exception e) {
              log.error("获取首页气象站字段" + filedName + "失败", e);
            }
            list.add(timeAndDataDto);
          }
        }
        dashboardEquipmentDto.setDataTypeName(p.getEquipmentAttribute().getExplanation());
        dashboardEquipmentDto.setDisplayOrder(p.getShowOnHomePage());
        dashboardEquipmentDto.setUnit(p.getEquipmentAttribute().getMeasurementUnits());
        dashboardEquipmentDto.setTimeAndDataDtoList(list);
        equipmentDataTypeList.add(dashboardEquipmentDto);
      }
    } else {
      WindTowerInfo windTowerInfo = windTowerInfoRepository.findById(Integer.parseInt(equipmentId)).get();
      long interval = 0;
      if (windTowerInfo.getInterval().intValue() == 60) {
        // 每分钟接入数据
        interval = 60 * 1000;
      } else {
        // 按照5分钟接入显示
        interval = 60 * 1000 * 5;
      }
      Date endTime = new Date();
      long startDateTime = 0;
      long endDateTime = 0;
      try {
        startDateTime = DateMomentUtil.getMomentTime(endTime.getTime() - 60 * 1000 * 30, 1, interval);
        endDateTime = DateMomentUtil.getMomentTime(endTime.getTime(), 1, interval);
      } catch (Exception e) {
        log.error("获取环境数据出错：", e);
      }
      List tempList = new ArrayList();
      List timeList = new ArrayList();
      for (Long tempDateTime = startDateTime; tempDateTime <= endDateTime; tempDateTime = tempDateTime + interval) {
        // 获取map里的值
        tempList.add(DateFormatUtils.format(tempDateTime, "HH:mm"));
      }
      // 降序为了取最新时间的6个点
      tempList.sort(Comparator.reverseOrder());
      timeList.addAll(tempList.subList(0, 6));
      // 再变回升序排列
      Collections.sort(timeList);
      // 获取2小时内的测风塔数据
      List<WindTowerStatusData> windTowerStatusDataList = windTowerStatusDataRepository.findByEquipmentNoAndTimeBetween(Integer.parseInt(equipmentId), new Date(new Date().getTime() - 1000 * 60 * 60 * 2), new Date());
      windTowerStatusDataList.sort(Comparator.comparing(WindTowerStatusData::getTime));
      for (ProtocolGatherDataPoint p : displayDataTypeList) {
        // 遍历出显示在首页的数据类型字段名称
        List<TimeAndDataDto> list = new ArrayList<>();
        String filedName = p.getEquipmentAttribute().getFieldName();//把字段名变为大写
        //得到get方法名
        filedName = "get" + filedName.toUpperCase().charAt(0) + filedName.substring(1);
        DashboardEquipmentDto dashboardEquipmentDto = new DashboardEquipmentDto();
        for (int i = 0; i < timeList.size(); i++) {
          int finalI = i;
          List<WindTowerStatusData> dataList = windTowerStatusDataList.stream().filter(a -> timeList.get(finalI).equals(DateFormatUtils.format(a.getTime(), "HH:mm"))).collect(Collectors.toList());
          if (dataList.size() > 0) {
            TimeAndDataDto timeAndDataDto = new TimeAndDataDto();
            timeAndDataDto.setTime(timeList.get(i).toString());
            timeAndDataDto.setVal(null);
            try {
              WindTowerStatusData windTowerStatusData = dataList.get(0);
              Method method = windTowerStatusData.getClass().getMethod(filedName, new Class[]{});
              BigDecimal value = (BigDecimal) method.invoke(windTowerStatusData, new Object[]{});
              timeAndDataDto.setVal(value.doubleValue() == -99 ? null : value.doubleValue());
            } catch (Exception e) {
              log.error("获取首页测风塔字段" + filedName + "失败", e);
            }
            list.add(timeAndDataDto);
          }
        }
        dashboardEquipmentDto.setDataTypeName(p.getEquipmentAttribute().getExplanation());
        dashboardEquipmentDto.setDisplayOrder(p.getShowOnHomePage());
        dashboardEquipmentDto.setUnit(p.getEquipmentAttribute().getMeasurementUnits());
        dashboardEquipmentDto.setTimeAndDataDtoList(list);
        equipmentDataTypeList.add(dashboardEquipmentDto);
      }
    }
    return equipmentDataTypeList;
  }

  /**
   * 获取首页短期、超短期、实际功率、可用功率、理论功率、轮毂高度风速数据
   * Map的key:sjList,dqList,cdqList,lggdfsList
   *
   * @return
   */
  public Map<String, List> getCompositeData() {
    Date d = new Date();
    Long startDateTime = DateMomentUtil.getDayStartTime(d.getTime());
    Long endDateTime = DateMomentUtil.getDayLastTime(d.getTime());
    // 取超短期
    String khPoint = "1";
    try {
      khPoint = super.getSysParameter("cst_kh_point", "1");
    } catch (RuntimeException e) {
      String errorInfo = "参数表cst_kh_point获取失败";
      log.error(errorInfo, e);
      String name = "参数表cst_kh_point获取失败";
      String describe = "参数表cst_kh_point获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    List<ForecastPowerUltraShortTermHis> forecastPowerUltraShortTermHisList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startDateTime, endDateTime, Integer.parseInt(khPoint));
    Map<Long, Double> cdqMap = new HashMap<>();
    for (ForecastPowerUltraShortTermHis forecastPowerUltraShortTermHis : forecastPowerUltraShortTermHisList) {
      cdqMap.put(forecastPowerUltraShortTermHis.getForecastTime(), forecastPowerUltraShortTermHis.getAbleValue().doubleValue());
    }
    // 取超短期
    String stkhPoint = "1";
    try {
      stkhPoint = super.getSysParameter("st_kh_point", "1");
    } catch (RuntimeException e) {
      String errorInfo = "参数表st_kh_point获取失败";
      log.error(errorInfo, e);
      String name = "参数表st_kh_point获取失败";
      String describe = "参数表st_kh_point获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    // 取短期
    List<ForecastPowerShortTermHis> forecastPowerShortTermHisList = forecastPowerShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startDateTime, endDateTime, Integer.parseInt(stkhPoint));
    Map<Long, Double> dqMap = new HashMap<>();
    for (ForecastPowerShortTermHis forecastPowerShortTermHis : forecastPowerShortTermHisList) {
      dqMap.put(forecastPowerShortTermHis.getForecastTime(), forecastPowerShortTermHis.getAbleValue().doubleValue());
    }
    // 实际功率
    List<PowerStationStatusData> powerStationStatusDataList = powerStationStatusDataRepository.findByTimeBetween(new Date(startDateTime), new Date(endDateTime));
    Map<Long, Double> sjMap = new HashMap<>();
    Map<Long, Double> kyMap = new HashMap<>();
    Map<Long, Double> llMap = new HashMap<>();
    for (PowerStationStatusData powerStationStatusData : powerStationStatusDataList) {
      Calendar date = Calendar.getInstance();
      date.setTimeInMillis(powerStationStatusData.getTime().getTime());
      date.set(Calendar.SECOND, 0);
      date.set(Calendar.MILLISECOND, 0);
      sjMap.put(date.getTimeInMillis(), powerStationStatusData.getRealValue().doubleValue());
      kyMap.put(date.getTimeInMillis(), powerStationStatusData.getAbleValue().doubleValue());
      llMap.put(date.getTimeInMillis(), powerStationStatusData.getTheoryValue().doubleValue());
    }
    //轮毂高度风速
    List<WindTowerStatusData> windTowerStatusDataList = windTowerStatusDataRepository.findByTimeBetween(new Date(startDateTime), new Date(endDateTime));
    Map<Long,Double> lggdfsMap = new HashMap<>();
    for (WindTowerStatusData windTowerStatusData : windTowerStatusDataList){
      Calendar date = Calendar.getInstance();
      date.setTimeInMillis(windTowerStatusData.getTime().getTime());
      lggdfsMap.put(date.getTimeInMillis(),windTowerStatusData.getWsInstHubHeight().doubleValue());
    }

    List cdqList = new ArrayList();
    List dqList = new ArrayList();
    List sjList = new ArrayList();
    List kyList = new ArrayList();
    List llList = new ArrayList();
    List timeList = new ArrayList();
    List lggdfsList = new ArrayList();
    long currentTime = System.currentTimeMillis();
    for (Long tempDateTime = startDateTime; tempDateTime < endDateTime; tempDateTime = tempDateTime + 15 * 60 * 1000) {
      String time = DateFormatUtils.format(tempDateTime, "HH:mm");
      //时间
      timeList.add(time);
      // 超短期
//      TimeAndDataDto cdqTimeAndDataDto = new TimeAndDataDto();
//      cdqTimeAndDataDto.setTime(time);
      if (cdqMap.get(tempDateTime) != null) {
        if (tempDateTime>currentTime + Long.parseLong(khPoint)*1000*60*15){
          cdqList.add(null);
        }
        else{
          cdqList.add(cdqMap.get(tempDateTime));
        }
//        cdqTimeAndDataDto.setVal();
      } else {
        cdqList.add(null);
//        cdqTimeAndDataDto.setVal(null);
      }

      // 短期
//      TimeAndDataDto dqTimeAndDataDto = new TimeAndDataDto();
//      dqTimeAndDataDto.setTime(time);
      if (dqMap.get(tempDateTime) != null) {
        dqList.add(dqMap.get(tempDateTime));
//        dqTimeAndDataDto.setVal(dqMap.get(tempDateTime));
      } else {
        dqList.add(null);
      }

      // 实际
//      TimeAndDataDto sjTimeAndDataDto = new TimeAndDataDto();
//      sjTimeAndDataDto.setTime(time);
      if (sjMap.get(tempDateTime) != null) {
        if (sjMap.get(tempDateTime) == -99) {
          sjList.add(null);
//          sjTimeAndDataDto.setVal(null);
        } else {
          if (tempDateTime>currentTime){
            sjList.add(null);
          }
          else{
            sjList.add(sjMap.get(tempDateTime));
          }

//          sjTimeAndDataDto.setVal(sjMap.get(tempDateTime));
        }
      } else {
        sjList.add(null);
//        sjTimeAndDataDto.setVal(null);
      }

      // 可用
//      TimeAndDataDto kyTimeAndDataDto = new TimeAndDataDto();
//      kyTimeAndDataDto.setTime(time);
      if (kyMap.get(tempDateTime) != null) {
        if (kyMap.get(tempDateTime) == -99) {
          kyList.add(null);
        } else {
          kyList.add(kyMap.get(tempDateTime));
        }
      } else {
        kyList.add(null);
      }
//      kyList.add(kyTimeAndDataDto);
      // 理论
//      TimeAndDataDto llTimeAndDataDto = new TimeAndDataDto();
//      llTimeAndDataDto.setTime(time);
      if (llMap.get(tempDateTime) != null) {
        if (llMap.get(tempDateTime) == -99) {
          llList.add(null);
        } else {
          llList.add(llMap.get(tempDateTime));
        }
      } else {
        llList.add(null);
      }
//      llList.add(llTimeAndDataDto);
      //轮毂高度风速
      if (lggdfsMap.get(tempDateTime) != null){
        if (lggdfsMap.get(tempDateTime) == -99){
          lggdfsList.add(null);
        } else {
          lggdfsList.add(lggdfsMap.get(tempDateTime));
        }
      }else {
        lggdfsList.add(null);
      }
    }

    Map resultMap = new HashMap();
    resultMap.put("sjList", sjList);
    resultMap.put("kyList", kyList);
    resultMap.put("llList", llList);
    resultMap.put("dqList", dqList);
    resultMap.put("cdqList", cdqList);
    resultMap.put("timeList", timeList);
    resultMap.put("lggdfsList",lggdfsList);
    // 默认显示可用、理论
    String displayKyLl = "1";
    String displayLggdfs = "0";
    try {
      displayKyLl = super.getSysParameter("DISPLAY_KY_LL", "1");
      displayLggdfs = super.getSysParameter("DISPLAY_LGGDFS","0");
    } catch (RuntimeException e) {
      String errorInfo = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      log.error(errorInfo, e);
      String name = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      String describe = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    resultMap.put("displayKyLl", displayKyLl);
    resultMap.put("displayLggdfs",displayLggdfs);
    return resultMap;
  }

  /**
   * 获取首页短期、超短期、实际功率、可用功率、理论功率、轮毂高度风速数据
   * Map的key:sjList,dqList,cdqList,lggdfsList
   *
   * @return
   */
  public Map<String, List> getCompositeDataOne() {
    Date d = new Date();
    Long startDateTime = DateMomentUtil.getDayStartTime(d.getTime());
    Long endDateTime = DateMomentUtil.getDayLastTime(d.getTime());
    // 取超短期
    String khPoint = "1";
    try {
      khPoint = super.getSysParameter("cst_kh_point", "1");
    } catch (RuntimeException e) {
      String errorInfo = "参数表cst_kh_point获取失败";
      log.error(errorInfo, e);
      String name = "参数表cst_kh_point获取失败";
      String describe = "参数表cst_kh_point获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    List<ForecastPowerUltraShortTermOneHis> forecastPowerUltraShortTermHisList = forecastPowerUltraShortTermOneHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startDateTime, endDateTime, Integer.parseInt(khPoint));
    Map<Long, Double> cdqMap = new HashMap<>();
    for (ForecastPowerUltraShortTermOneHis forecastPowerUltraShortTermOneHis : forecastPowerUltraShortTermHisList) {
      cdqMap.put(forecastPowerUltraShortTermOneHis.getForecastTime(), forecastPowerUltraShortTermOneHis.getAbleValue().doubleValue());
    }
    // 取超短期
    String stkhPoint = "1";
    try {
      stkhPoint = super.getSysParameter("st_kh_point", "1");
    } catch (RuntimeException e) {
      String errorInfo = "参数表st_kh_point获取失败";
      log.error(errorInfo, e);
      String name = "参数表st_kh_point获取失败";
      String describe = "参数表st_kh_point获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    // 取短期
    List<ForecastPowerShortTermOneHis> forecastPowerShortTermOneHisList = forecastPowerShortTermOneHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startDateTime, endDateTime, Integer.parseInt(stkhPoint));
    Map<Long, Double> dqMap = new HashMap<>();
    for (ForecastPowerShortTermOneHis forecastPowerShortTermOneHis : forecastPowerShortTermOneHisList) {
      dqMap.put(forecastPowerShortTermOneHis.getForecastTime(), forecastPowerShortTermOneHis.getAbleValue().doubleValue());
    }
    // 实际功率
    List<PowerStationStatusDataOne> powerStationStatusDataOneList = powerStationStatusDataOneRepository.findByTimeBetween(new Date(startDateTime), new Date(endDateTime));
    Map<Long, Double> sjMap = new HashMap<>();
    Map<Long, Double> kyMap = new HashMap<>();
    Map<Long, Double> llMap = new HashMap<>();
    for (PowerStationStatusDataOne powerStationStatusDataOne : powerStationStatusDataOneList) {
      Calendar date = Calendar.getInstance();
      date.setTimeInMillis(powerStationStatusDataOne.getTime().getTime());
      date.set(Calendar.SECOND, 0);
      date.set(Calendar.MILLISECOND, 0);
      sjMap.put(date.getTimeInMillis(), powerStationStatusDataOne.getRealValue().doubleValue());
      kyMap.put(date.getTimeInMillis(), powerStationStatusDataOne.getAbleValue().doubleValue());
      llMap.put(date.getTimeInMillis(), powerStationStatusDataOne.getTheoryValue().doubleValue());
    }
    //轮毂高度风速
    List<WindTowerStatusData> windTowerStatusDataList = windTowerStatusDataRepository.findByTimeBetween(new Date(startDateTime), new Date(endDateTime));
    Map<Long,Double> lggdfsMap = new HashMap<>();
    for (WindTowerStatusData windTowerStatusData : windTowerStatusDataList){
      Calendar date = Calendar.getInstance();
      date.setTimeInMillis(windTowerStatusData.getTime().getTime());
      lggdfsMap.put(date.getTimeInMillis(),windTowerStatusData.getWsInstHubHeight().doubleValue());
    }

    List cdqList = new ArrayList();
    List dqList = new ArrayList();
    List sjList = new ArrayList();
    List kyList = new ArrayList();
    List llList = new ArrayList();
    List timeList = new ArrayList();
    List lggdfsList = new ArrayList();
    long currentTime = System.currentTimeMillis();
    for (Long tempDateTime = startDateTime; tempDateTime < endDateTime; tempDateTime = tempDateTime + 15 * 60 * 1000) {
      String time = DateFormatUtils.format(tempDateTime, "HH:mm");
      //时间
      timeList.add(time);
      // 超短期
//      TimeAndDataDto cdqTimeAndDataDto = new TimeAndDataDto();
//      cdqTimeAndDataDto.setTime(time);
      if (cdqMap.get(tempDateTime) != null) {
        if (tempDateTime>currentTime + Long.parseLong(khPoint)*1000*60*15){
          cdqList.add(null);
        }
        else{
          cdqList.add(cdqMap.get(tempDateTime));
        }

//        cdqTimeAndDataDto.setVal();
      } else {
        cdqList.add(null);
//        cdqTimeAndDataDto.setVal(null);
      }

      // 短期
//      TimeAndDataDto dqTimeAndDataDto = new TimeAndDataDto();
//      dqTimeAndDataDto.setTime(time);
      if (dqMap.get(tempDateTime) != null) {
        dqList.add(dqMap.get(tempDateTime));
//        dqTimeAndDataDto.setVal(dqMap.get(tempDateTime));
      } else {
        dqList.add(null);
      }

      // 实际
//      TimeAndDataDto sjTimeAndDataDto = new TimeAndDataDto();
//      sjTimeAndDataDto.setTime(time);
      if (sjMap.get(tempDateTime) != null) {
        if (sjMap.get(tempDateTime) == -99) {
          sjList.add(null);
//          sjTimeAndDataDto.setVal(null);
        } else {
          if (tempDateTime>currentTime){
            sjList.add(null);
          }
          else{
            sjList.add(sjMap.get(tempDateTime));
          }
//          sjTimeAndDataDto.setVal(sjMap.get(tempDateTime));
        }
      } else {
        sjList.add(null);
//        sjTimeAndDataDto.setVal(null);
      }

      // 可用
//      TimeAndDataDto kyTimeAndDataDto = new TimeAndDataDto();
//      kyTimeAndDataDto.setTime(time);
      if (kyMap.get(tempDateTime) != null) {
        if (kyMap.get(tempDateTime) == -99) {
          kyList.add(null);
        } else {
          kyList.add(kyMap.get(tempDateTime));
        }
      } else {
        kyList.add(null);
      }
//      kyList.add(kyTimeAndDataDto);
      // 理论
//      TimeAndDataDto llTimeAndDataDto = new TimeAndDataDto();
//      llTimeAndDataDto.setTime(time);
      if (llMap.get(tempDateTime) != null) {
        if (llMap.get(tempDateTime) == -99) {
          llList.add(null);
        } else {
          llList.add(llMap.get(tempDateTime));
        }
      } else {
        llList.add(null);
      }
//      llList.add(llTimeAndDataDto);
      //轮毂高度风速
      if (lggdfsMap.get(tempDateTime) != null){
        if (lggdfsMap.get(tempDateTime) == -99){
          lggdfsList.add(null);
        } else {
          lggdfsList.add(lggdfsMap.get(tempDateTime));
        }
      }else {
        lggdfsList.add(null);
      }
    }

    Map resultMap = new HashMap();
    resultMap.put("sjList", sjList);
    resultMap.put("kyList", kyList);
    resultMap.put("llList", llList);
    resultMap.put("dqList", dqList);
    resultMap.put("cdqList", cdqList);
    resultMap.put("timeList", timeList);
    resultMap.put("lggdfsList",lggdfsList);
    // 默认显示可用、理论
    String displayKyLl = "1";
    String displayLggdfs = "0";
    try {
      displayKyLl = super.getSysParameter("DISPLAY_KY_LL", "1");
      displayLggdfs = super.getSysParameter("DISPLAY_LGGDFS","0");
    } catch (RuntimeException e) {
      String errorInfo = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      log.error(errorInfo, e);
      String name = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      String describe = "参数表DISPLAY_KY_LL或DISPLAY_LGGDFS获取失败";
      String solution = "使用默认值1";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
    }
    resultMap.put("displayKyLl", displayKyLl);
    resultMap.put("displayLggdfs",displayLggdfs);
    return resultMap;
  }

  /**
   * 获取首页当天通道断开日志
   *
   * @return
   */
  public List<ChannelDisconLog> getChannelDisconLog() {
    Long nowDate = new Date().getTime();
    Date startTime = DateTimeUtil.getDayStartTime(nowDate);
    Date endTime = DateTimeUtil.getDayLastTime(nowDate);
    List<ChannelDisconLog> channelDisconLogList = channelDisconLogRepository.findByCreateTimeBetween(startTime, endTime);
    channelDisconLogList.sort(Comparator.comparing(ChannelDisconLog::getCreateTime).reversed());
    return channelDisconLogList;
  }

  /**
   * 添加修改限电标识
   *
   * @return
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public void savePowerLimitPlanSign(PowerLimitPlanSign powerLimitPlanSign) {
    powerLimitPlanSignRepository.save(powerLimitPlanSign);
    Map<String, Object> map = new HashMap<>();
    map.put("id", powerLimitPlanSign.getId());
    map.put("sign", powerLimitPlanSign.getSign());
    String body = HttpRequest.post("https://localhost:9001/powerStationDataPacker").form(map).execute().body();
    // System.out.print(JSONUtil.parseObj(body));
  }

  /**
   * 查询限电标识
   *
   * @return
   */
  public PowerLimitPlanSign getPowerLimitPlanSign() {
    Optional<PowerLimitPlanSign> powerLimitPlanSignOptional = powerLimitPlanSignRepository.findById(1);
    if (powerLimitPlanSignOptional.isPresent()) {
      return powerLimitPlanSignOptional.get();
    } else {
      PowerLimitPlanSign powerLimitPlanSign = new PowerLimitPlanSign();
      powerLimitPlanSign.setId(1);
      powerLimitPlanSign.setSign(0);
      return powerLimitPlanSign;
    }
  }

  /**
   * 通道告警
   */
  public List<ChannelAlarmInfo> getChannelAlarmInfo() {
    List<ChannelAlarmInfo> list = channelAlarmInfoRepository.findAll();
    return list;
  }

  /**
   * 通道告警保存
   */
  public void saveChannelAlarmInfoAll(List<ChannelAlarmInfo> channelAlarmInfos) {
    channelAlarmInfoRepository.deleteAll();
    channelAlarmInfoRepository.saveAll(channelAlarmInfos);
  }

  /**
   * 获取系统版本号
   */
  public List getSysVersion() {
    List list = new ArrayList();
    Map map = new HashMap();
    String reportVersion = "";
    String consoleVersion = "";
    String monitorVersion = "";
    String libVersion = "";
    try {
      String body = HttpRequest.get("https://localhost:8088/version").execute().body();
      JSONObject json = JSONUtil.parseObj(body);
      ;
      reportVersion = json.get("reportVersion").toString();
      consoleVersion = json.get("consoleVersion").toString();
      monitorVersion = json.get("monitorVersion").toString();
      libVersion = json.get("libVersion").toString();
    } catch (Exception e) {
      log.error("从monitor获取版本号失败", e);
    }

    map.put("reportVersion", reportVersion);
    map.put("consoleVersion", consoleVersion);
    map.put("monitorVersion", monitorVersion);
    map.put("libVersion", libVersion);
    list.add(map);
    return list;
  }


  /**
   * 获取测风塔数据是否是正常
   */
  public Map<String,String> getIsAbnormal() {
    Map<String,String> map = new HashMap<>();
    String body;
    try {
      body = HttpRequest.get("https://localhost:9001/windTowerStatusData/isAbnormal").execute().body();
      JSONObject json = JSONUtil.parseObj(body);
      map.put("isAbnormalData",json.get("isAbnormalData").toString());
      map.put("isAbnormalInfo",json.get("isAbnormalInfo").toString());
    } catch (Exception e) {
      log.error("获取测风塔数据是否是正常失败", e);
    }
    return map;
  }


  /*获取上报对象中的上报文件类型*/
  public Object getUploadFileType(){
    try{
      List list = new ArrayList();
      List<UploadObject> allUploadObject = uploadObjectRepository.findAll();
      for (UploadObject u : allUploadObject) {
        String[] fileTypeArray = u.getUploadFileType().split(",");
        for (String fileType : fileTypeArray) {
          Map map = new HashMap();
          FileTypeEnum fileTypeEnum = FileTypeEnum.valueOf(fileType);
          map.put("value",fileTypeEnum.name());
          map.put("label",fileTypeEnum.getMessage());
          list.add(map);

        }
      }
      Object newList = list.stream().distinct().collect(Collectors.toList());
      return newList;
    }catch (Exception e){
      log.error("首页查询上报对象的文件类型失败：", e);
      return null;
    }

  }

  /**
   * 查询参数值
   *
   * @param sysKey 参数标识
   * @return 参数
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public SysParameter getParameterBySysKey(final String sysKey) {
    SysParameter sysParameter = sysParameterRepository.findBySysKeyEquals(sysKey);
    return sysParameter;
  }
}
