package com.zcxk.service.impl;

import com.zcxk.dao.DeviceSceneMapper;
import com.zcxk.dao.MonitorDataReportMapper;
import com.zcxk.dto.*;
import com.zcxk.dto.generalView.*;
import com.zcxk.dto.scene.SceneIdDto;
import com.zcxk.entity.DeviceEntity;
import com.zcxk.entity.MonitorDataEntity;
import com.zcxk.entity.MonitorDataValueEntity;
import com.zcxk.entity.SceneEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.service.*;
import com.zcxk.util.ByteArrayUtils;
import com.zcxk.util.OrgInfoUtil;
import com.zcxk.util.RedisUtil;
import com.zcxk.util.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description
 * @auto wangli
 * @data 2020/12/7 20:23
 */
@Service
public class MonitorDataReportServiceImpl implements MonitorDataReportService {

    @Resource
    private MonitorDataReportMapper monitorDataReportMapper;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OrgInfoUtil orgInfoUtil;

    @Autowired
    private SceneService sceneService;
    @Autowired
    private MonitorInfoService monitorInfoService;
    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DeviceSceneMapper deviceSceneMapper;


    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataChartReportByDay(Long sceneId, Integer year, Integer month , Integer day) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos =  monitorDataReportMapper.MonitorDataChartReportByDay(year,month,day,sceneId,
                loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        FillLoseData(monitorDataChartReportDeviceDtos,3,year,month,day);
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataChartReportByMonth(Long sceneId, Integer year, Integer month ) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataChartReportByMonth(year,month,sceneId,
                loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        FillLoseData(monitorDataChartReportDeviceDtos,2,year,month,1);
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> monthMonitorData(Long sceneId, String startTime, String endTime) {
        startTime += " 00:00:00";
        endTime   += " 23:59:59";
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = monitorDataReportMapper.monthMonitorData(startTime, endTime,sceneId,
                loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        FillLoseData(startTime, endTime, monitorDataChartReportDeviceDtos);
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataChartReportByYear(Long sceneId, Integer year) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataChartReportByYear(year,sceneId,
                loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        FillLoseData(monitorDataChartReportDeviceDtos,1,year,1,1);
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> deviceAlarmReport(Integer type, List<Long>  sceneIds, Integer year, Integer month , Integer day, String startTime, String endTime) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        LocalDate beginDate = null;
        LocalDate endDate   = null;
        String dateType     = null;
        if (type == null){
            return new ArrayList<>();
        }
        if (type ==1) {
            beginDate=LocalDate.of(year,1,1);
            endDate=beginDate.plusYears(1);
            dateType="month";
        }else  if(type ==2) {
            beginDate=LocalDate.of(year,month,1);
            endDate=beginDate.plusMonths(1);
            dateType="day";
        } else if(type ==3) {
            beginDate=LocalDate.of(year,month,day);
            endDate=beginDate.plusDays(1);
            dateType="hour";
        } else if (type == 4){
            startTime += " 00:00:00";
            endTime   += " 23:59:59";
            beginDate = LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            endDate   = LocalDate.parse(endTime,   DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            dateType="day";
        }
        if (beginDate == null || endDate == null){
            return new ArrayList<>();
        }
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = monitorDataReportMapper.DeviceAlarmReport(dateType,sceneIds,beginDate,endDate,
                loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        if (monitorDataChartReportDeviceDtos != null && type == 4){
            FillLoseData(startTime, endTime, monitorDataChartReportDeviceDtos);
        } else  if (monitorDataChartReportDeviceDtos != null){
            FillLoseData(monitorDataChartReportDeviceDtos,type,year,month,day);
        }
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataQualityReport(Integer type, List<Long>  sceneIds, Integer year, Integer month , Integer day, String startTime, String endTime) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = null;
        if (type == null) {
            return monitorDataChartReportDeviceDtos;
        }
        if(type == 3){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataQualityReportByDay(sceneIds,year,month,day,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if(type == 2){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataQualityReportByMonth(sceneIds,year,month,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if(type == 1){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataQualityReportByYear(sceneIds,year,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if (type == 4) {
            startTime += " 00:00:00";
            endTime   += " 23:59:59";
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataQualityReport(sceneIds,startTime,endTime,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        }
        if (monitorDataChartReportDeviceDtos != null && type == 4){
            FillLoseData(startTime, endTime, monitorDataChartReportDeviceDtos);
        } else  if (monitorDataChartReportDeviceDtos != null){
            FillLoseData(monitorDataChartReportDeviceDtos,type,year,month,day);
        }
        return monitorDataChartReportDeviceDtos;
    }

    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataEnergyReport(Integer type, List<Long> sceneIds, Integer year, Integer month , Integer day, Integer sceneType,String startTime, String endTime) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = null;
        if (type == null) {
            return monitorDataChartReportDeviceDtos;
        }
        Integer stype = sceneType == 2 || sceneType == 3 ? 0 : sceneType ;
        if(type == 3){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByDay(stype,sceneIds,year,month,day,
                   loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
       } else if(type == 2){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByMonth(stype,sceneIds,year,month,
                   loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
       } else if(type == 1){
           monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByYear(stype,sceneIds,year,
                   loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
       } else if (type == 4) {
            startTime += " 00:00:00";
            endTime   += " 23:59:59";
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReport(stype,sceneIds,startTime,endTime,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        }
        if (monitorDataChartReportDeviceDtos != null && type == 4) {
            FillLoseData(startTime, endTime, monitorDataChartReportDeviceDtos);
        }else if (monitorDataChartReportDeviceDtos != null){
            FillLoseData(monitorDataChartReportDeviceDtos,type,year,month,day);
        }
        // 场景类型为泵站的不需要转换
        if (sceneType == 3){
            return monitorDataChartReportDeviceDtos;
        }
        // 其他场景需要转换为单位“万”
        for(MonitorDataChartReportDeviceDto monitorDataChartReportDeviceDto : monitorDataChartReportDeviceDtos){
            for(MonitorDataChartReportAttributeDto monitorDataChartReportAttributeDto:monitorDataChartReportDeviceDto.getAttributeData()){
                String unit = monitorDataChartReportAttributeDto.getUnit() == null ? "" : monitorDataChartReportAttributeDto.getUnit();
                monitorDataChartReportAttributeDto.setUnit("万"+ unit);
                for(MonitorDataChartReportValueDto monitorDataChartReportValueDto: monitorDataChartReportAttributeDto.getMonitorDataChartReportValue()){
                    monitorDataChartReportValueDto.setData(new BigDecimal(monitorDataChartReportValueDto.getData()).divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP).doubleValue());
                    monitorDataChartReportValueDto.setMonitorData(monitorDataChartReportValueDto.getData()+monitorDataChartReportAttributeDto.getUnit());
                }
            }
        }
        return monitorDataChartReportDeviceDtos;
    }
    @Override
    public List<MonitorDataChartReportDeviceDto> monitorWaterPowerConsumptionReport(Integer type, List<Long> sceneIds, Integer year, Integer month , Integer day, Integer sceneType, String startTime, String endTime) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = null;
        if (type == null) {
            return monitorDataChartReportDeviceDtos;
        }
        Integer stype = sceneType == 2 || sceneType == 3 ? 0 : sceneType ;
        if ( type == 3){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByDay(stype,sceneIds,year,month,day,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if(type == 2){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByMonth(stype,sceneIds,year,month,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if(type == 1){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReportByYear(stype,sceneIds,year,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        } else if (type == 4) {
            startTime += " 00:00:00";
            endTime   += " 23:59:59";
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataEnergyReport(stype,sceneIds,startTime,endTime,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        }
        if (monitorDataChartReportDeviceDtos != null && type == 4){
            FillLoseData(startTime, endTime, monitorDataChartReportDeviceDtos);
        } else if (monitorDataChartReportDeviceDtos != null) {
            FillLoseData(monitorDataChartReportDeviceDtos,type,year,month,day);
        }
        for (MonitorDataChartReportDeviceDto water: monitorDataChartReportDeviceDtos) {
            List<MonitorDataChartReportAttributeDto> newAttrDataList  = new ArrayList();
            MonitorDataChartReportAttributeDto newAttrData = new MonitorDataChartReportAttributeDto();
            List<MonitorDataChartReportAttributeDto> attributeDtos =  water.getAttributeData();
            newAttrData.setAttributeName("水电耗");
            newAttrData.setUnit("kwh/m³");
            newAttrData.setAttributeType("99");
            // 计算水电耗=每日电量/每日用水量*100
            // 缺失每日电量或者每日水量将不进行计算
            if (attributeDtos.size()  == 2) {
                // 获取每日电量和每日水量
                MonitorDataChartReportAttributeDto attributeDto1 = attributeDtos.get(0);
                MonitorDataChartReportAttributeDto attributeDto2 = attributeDtos.get(1);
                // attributeType ==  5 --> 每日电量
                // attributeType ==  4 --> 每日用水量
                if ("5".equals(attributeDto1.getAttributeType())) {
                    Map<Integer,MonitorDataChartReportValueDto> map2 = attributeDto2.getMonitorDataChartReportValue().stream().collect(Collectors.toMap(MonitorDataChartReportValueDto::getDateLabel, a -> a,(k1, k2)->k1));
                    calculation(attributeDto1, map2);
                    newAttrData.setMonitorDataChartReportValue(attributeDto1.getMonitorDataChartReportValue());
                } else {
                    Map<Integer,MonitorDataChartReportValueDto> map1 = attributeDto1.getMonitorDataChartReportValue().stream().collect(Collectors.toMap(MonitorDataChartReportValueDto::getDateLabel, a -> a,(k1, k2)->k1));
                    calculation(attributeDto2, map1);
                    newAttrData.setMonitorDataChartReportValue(attributeDto2.getMonitorDataChartReportValue());
                }
            }
            newAttrDataList.add(newAttrData);
            water.setAttributeData(newAttrDataList);
        }
        return monitorDataChartReportDeviceDtos;
    }

    // 计算水电耗=每日电量/每日用水量*100
    private void calculation(MonitorDataChartReportAttributeDto attributeDto, Map<Integer,MonitorDataChartReportValueDto> map){
        for (MonitorDataChartReportValueDto valueDto : attributeDto.getMonitorDataChartReportValue()) {
            BigDecimal b1 = new BigDecimal(valueDto.getData());
            BigDecimal b2 = new BigDecimal(map.get(valueDto.getDateLabel()).getData());
            valueDto.setMonitorData("");
            if (b1.compareTo(new BigDecimal(0)) == 0 || b2.compareTo(new BigDecimal(0)) == 0) {
                valueDto.setData(0d);
                valueDto.setMonitorData("0 kwh/m³");
            } else {
                valueDto.setData(b1.divide(b2, 3, RoundingMode.HALF_UP).doubleValue());
                valueDto.setMonitorData(valueDto.getData() + " kwh/m³");
            }
        }
    }
    @Override
    public List<DeviceEntity> getDeviceBySceneTypeName(String sceneTypeName){
        LoginUser loginUser = UserUtil.getCurrentUser();
        return monitorDataReportMapper.getDeviceBySceneTypeName(sceneTypeName,loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
    }
    @Override
    public List<MonitorDataChartReportDeviceDto> monitorDataDeviceReport(Integer type, List<Long>  deviceIds, Integer searchType, Integer year, Integer month , Integer day, String startTime, String endTime){
        Long sceneId =null;
        String name = searchType == 1 ? "压力" : ((searchType == 2) ?  "流量" : "水质");
        SceneIdDto sceneIdDto = deviceSceneMapper.findSceneId("管网",name, deviceIds.get(0));
        if (sceneIdDto != null) {
            sceneId = sceneIdDto.getSceneId();
        }
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos = null;
        if (type == null) {
            return monitorDataChartReportDeviceDtos;
        }
        if (type == 3){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataDeviceReportByDay(deviceIds,searchType,year,month,day,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList(),sceneId);
        } else if(type == 2){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataDeviceReportByMonth(deviceIds,searchType,year,month,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList(),sceneId);
        } else if(type == 1){
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataDeviceReportByYear(deviceIds,searchType,year,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList(),sceneId);
        } else if (type == 4){
            startTime += " 00:00:00";
            endTime   += " 23:59:59";
            monitorDataChartReportDeviceDtos = monitorDataReportMapper.MonitorDataDeviceReport(deviceIds,searchType,startTime,endTime,
                    loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList(),sceneId);
        }
        if (monitorDataChartReportDeviceDtos != null && type == 4){
            FillLoseData(startTime,endTime, monitorDataChartReportDeviceDtos);
        } else if (monitorDataChartReportDeviceDtos != null){
            FillLoseData(monitorDataChartReportDeviceDtos,type,year,month,day);
        }
        return monitorDataChartReportDeviceDtos;
    }

    /**
     * 补充数据里日期时间缺失的
     */
    private static void FillLoseData(List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos,Integer type,Integer year,Integer month ,Integer day){
        for(MonitorDataChartReportDeviceDto monitorDataChartReportDeviceDto: monitorDataChartReportDeviceDtos){
            if(monitorDataChartReportDeviceDto != null && monitorDataChartReportDeviceDto.getAttributeData() != null){
                for(MonitorDataChartReportAttributeDto monitorDataChartReportAttributeDto:monitorDataChartReportDeviceDto.getAttributeData()){
                    if(monitorDataChartReportAttributeDto != null && monitorDataChartReportAttributeDto.getMonitorDataChartReportValue() != null){
                        String unit = monitorDataChartReportAttributeDto.getUnit();
                        unit= StringUtils.isNotBlank(unit)?unit:"";
                        List<MonitorDataChartReportValueDto> monitorDataChartReportValueDtos = monitorDataChartReportAttributeDto.getMonitorDataChartReportValue();
                        Integer maxValue =0;
                        LocalDateTime localDateTime=LocalDateTime.now();
                        Integer growingBase = 1;
                        if(type != null && type ==3){
                            growingBase = 0;
                            maxValue = 24;
                            localDateTime=LocalDateTime.of(year,month,day,0,0,0);
                        }else if(type != null && type ==2){
                            localDateTime=LocalDateTime.of(year,month,1,0,0,0);
                            maxValue = localDateTime.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
                        }else if(type != null && type ==1){
                            localDateTime=LocalDateTime.of(year,1,1,0,0,0);
                            maxValue=12;
                        }
                        for(int i=0;i<maxValue;i++){
                            if(i == monitorDataChartReportValueDtos.size() || !monitorDataChartReportValueDtos.get(i).getDateLabel().equals(i+growingBase)){
                                MonitorDataChartReportValueDto monitorDataChartReportValueDto = new MonitorDataChartReportValueDto();
                                monitorDataChartReportValueDto.setData(0.0);
                                LocalDateTime dateTime=localDateTime.now();
                                if(type != null && type ==3){
                                    dateTime= localDateTime.plusHours(i);
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue())+"-"+
                                                    String.format("%02d",dateTime.getDayOfMonth())+" "+
                                                    String.format("%02d",dateTime.getHour())+":00");
                                }
                                if(type != null && type ==2){
                                    dateTime= localDateTime.plusDays(i);
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue())+"-"+
                                                    String.format("%02d",dateTime.getDayOfMonth()));
                                }
                                if(type != null && type ==1){
                                    dateTime= localDateTime.plusMonths(i);
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue()));
                                }
                                monitorDataChartReportValueDto.setDate(dateTime);

                                monitorDataChartReportValueDto.setDateLabel(i+growingBase);
                                monitorDataChartReportValueDto.setMonitorData("");
                                monitorDataChartReportValueDtos.add(i,monitorDataChartReportValueDto);
                            }else{
                                MonitorDataChartReportValueDto monitorDataChartReportValueDto =monitorDataChartReportValueDtos.get(i);
                                monitorDataChartReportValueDto.setMonitorData(monitorDataChartReportValueDto.getData()+""+unit);
                                LocalDateTime dateTime = monitorDataChartReportValueDto.getDate();
                                if(type != null && type ==3){
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue())+"-"+
                                                    String.format("%02d",dateTime.getDayOfMonth())+" "+
                                                    String.format("%02d",dateTime.getHour())+":00");
                                }
                                if(type != null && type ==2){
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue())+"-"+
                                                    String.format("%02d",dateTime.getDayOfMonth()));
                                }
                                if(type != null && type ==1){
                                    monitorDataChartReportValueDto.setDateStringLabel(
                                            dateTime.getYear()+"-"+
                                                    String.format("%02d",dateTime.getMonthValue()));
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private static void FillLoseData(List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos,Integer type,Integer year,Integer month
                ,int startTime, int endTime) {
        LocalDateTime localDateTime = LocalDateTime.of(year, month,1,0,0,0);
        for(MonitorDataChartReportDeviceDto monitorDataChartReportDeviceDto: monitorDataChartReportDeviceDtos){
            if(monitorDataChartReportDeviceDto == null || monitorDataChartReportDeviceDto.getAttributeData() == null) {
                continue;
            }
            for(MonitorDataChartReportAttributeDto monitorDataChartReportAttributeDto:monitorDataChartReportDeviceDto.getAttributeData()){
                if (monitorDataChartReportAttributeDto == null ||
                        monitorDataChartReportAttributeDto.getMonitorDataChartReportValue() == null) {
                    continue;
                }
                String unit = monitorDataChartReportAttributeDto.getUnit();
                unit = StringUtils.isNotBlank(unit) ? unit : "";
                List<MonitorDataChartReportValueDto> monitorDataChartReportValueDtos = monitorDataChartReportAttributeDto.getMonitorDataChartReportValue();
                Map<String,MonitorDataChartReportValueDto> mmp = toMap(monitorDataChartReportValueDtos);
                for (int i = startTime; i <= endTime; i++ ) {
                    MonitorDataChartReportValueDto monitorDataChartReportValueDto =  mmp.get(year + "" + month + "" + i);
                    if (monitorDataChartReportValueDto == null){
                        monitorDataChartReportValueDto = new MonitorDataChartReportValueDto();
                        monitorDataChartReportValueDto.setData(0.0);
                        LocalDateTime dateTime = yearMonthDay(year,month, i);
                        setDateStringLabel(localDateTime, dateTime, i-1, monitorDataChartReportValueDto, type, true);
                        monitorDataChartReportValueDto.setDate(dateTime);
                        monitorDataChartReportValueDto.setDateLabel(i);
                        monitorDataChartReportValueDto.setMonitorData("");
                        monitorDataChartReportValueDtos.add(monitorDataChartReportValueDto);
                    } else {
                        monitorDataChartReportValueDto.setMonitorData(monitorDataChartReportValueDto.getData()+""+unit);
                        LocalDateTime dateTime = yearMonthDay(year,month, i);
                        if (StringUtils.isEmpty(monitorDataChartReportValueDto.getDateStringLabel())){
                            setDateStringLabel(localDateTime, dateTime, i , monitorDataChartReportValueDto, type, false);
                        }
                    }
                }
            }
        }
    }

    private static LocalDateTime yearMonthDay(Integer year, Integer month, Integer day){
        String monthStr = month + "";
        String dayStr   = day + "";
        if (month < 10) {
            monthStr = 0 + "" + month;
        }
        if (day < 10) {
            dayStr = 0 + "" + day;
        }
        String time = year+ "-" + monthStr + "-" +  dayStr;
        return LocalDateTime.parse(time + " 00:00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") );
    }

    private static Map<String, MonitorDataChartReportValueDto> toMap (List<MonitorDataChartReportValueDto> monitorDataChartReportValueDtos) {
        LocalDateTime localDateTime = null;
        Map<String, MonitorDataChartReportValueDto> result = new HashMap<>();
        for (MonitorDataChartReportValueDto monitorDataChartReportValueDto:monitorDataChartReportValueDtos) {
            if (StringUtils.isEmpty(monitorDataChartReportValueDto.getDateStringLabel())) {
                localDateTime = monitorDataChartReportValueDto.getDate();
            } else {
                localDateTime = LocalDateTime.parse(monitorDataChartReportValueDto.getDateStringLabel() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            result.put(localDateTime.getYear() + "" +  localDateTime.getMonthValue() +"" + localDateTime.getDayOfMonth() , monitorDataChartReportValueDto);
        }
        return result;
    }

    private static void setDateStringLabel(LocalDateTime localDateTime,LocalDateTime dateTime, int i , MonitorDataChartReportValueDto monitorDataChartReportValueDto,
                    Integer type, boolean isNull) {
        if (type == null) {
            return;
        }
        if(type ==3){
            dateTime= isNull ? localDateTime.plusHours(i) : dateTime;
            monitorDataChartReportValueDto.setDateStringLabel(
                    dateTime.getYear()+"-"+ String.format("%02d",dateTime.getMonthValue())+"-"+  String.format("%02d",dateTime.getDayOfMonth())
                            + " "+String.format("%02d",dateTime.getHour())+":00");
        }
        if(type ==2){
            //dateTime = isNull ? localDateTime.plusDays(i): dateTime;
            monitorDataChartReportValueDto.setDateStringLabel(dateTime.getYear()+"-" + String.format("%02d",dateTime.getMonthValue())+
                    "-"+ String.format("%02d",dateTime.getDayOfMonth()));
        }
        if (type ==1) {
            dateTime = isNull ? localDateTime.plusMonths(i) : dateTime;
            monitorDataChartReportValueDto.setDateStringLabel(dateTime.getYear()+"-" + String.format("%02d", dateTime.getMonthValue()));
        }
    }


    @Override
    public GeneralViewResults monitorDataGeneralView() {
        GeneralViewResults generalViewResults = new GeneralViewResults();
//        LoginUser loginUser = UserUtil.getCurrentUser();
//        String tenantId = loginUser.getTenantId();
//        //查询设备编码
//        List<String> deviceCodes = monitorDataReportMapper.selectDeviceCode(tenantId);
//        //根据编码获取redis中的实时数据
//        List<MonitorDataEntity> monitorDataEntities = new ArrayList<>();
//        for (String deviceCode : deviceCodes) {
//            //先取缓存里的数据
//            byte[] bytes = redisUtil.get(("sms_water_" + deviceCode).getBytes());
//            if (bytes != null && bytes.length > 0) {
//                monitorDataEntities.add((MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get());
//            }
//        }
//        //将获取到 实时数据转换为map，方便匹配数据deviceId
//        Map<Integer, MonitorDataEntity> MonitorDataMap = monitorDataEntities.stream().collect(Collectors.toMap(MonitorDataEntity::getDeviceId, a -> a, (k1, k2) -> k1));
//
//
//        LocalDate localDate = LocalDate.now();
//        //水厂近30天供水量
//        List<DeviceWaterSupply> deviceWaterSupplies = monitorDataReportMapper.getDeviceWaterFor30Day(tenantId);
//        for (int i = 0; i < 30; i++) {
//            LocalDate newLocalDate = localDate.plusDays(-i - 1);
//            if (i <= deviceWaterSupplies.size()
//                    || !newLocalDate.isEqual(LocalDate.of(deviceWaterSupplies.get(i).getYear(),
//                    deviceWaterSupplies.get(i).getMonth(),
//                    deviceWaterSupplies.get(i).getDay()))) {
//
//                DeviceWaterSupply deviceWaterSupply = new DeviceWaterSupply();
//                deviceWaterSupply.setOrderNo(i + 1);
//                deviceWaterSupply.setAmount(BigDecimal.ZERO);
//                deviceWaterSupply.setYear(newLocalDate.getYear());
//                deviceWaterSupply.setMonth(newLocalDate.getMonthValue());
//                deviceWaterSupply.setDay(newLocalDate.getDayOfMonth());
//                deviceWaterSupply.setDate(newLocalDate);
//                deviceWaterSupplies.add(i, deviceWaterSupply);
//            } else {
//                deviceWaterSupplies.get(i).setOrderNo(i + 1);
//                deviceWaterSupplies.get(i).setDate(newLocalDate);
//            }
//        }
//        //0 30天水量
//        generalViewResults.setDeviceWaterSupplies(deviceWaterSupplies);
//
//        //供水详情数据（合计：瞬时、本天、本月、本年）
//        DeviceWaterAmount deviceWaterAmount = new DeviceWaterAmount();
//        //14瞬时流量
//        List<DeviceWaterDetail> deviceSupplyWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow("水厂", 14, tenantId);
//        List<DeviceWaterDetail> deviceIntakeWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow("水源", 14, tenantId);
//
//        //水厂获取实时流量并计算出当天流量
//        for (DeviceWaterDetail deviceWaterDetail : deviceSupplyWaterDetailsForNow) {
//            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
//                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
//                        //水厂累计瞬时流量
//                        deviceWaterAmount.addWaterSupplyAmountForNow(new BigDecimal(monitorDataValueEntity.getDataValue()));
//                    }
//                }
//            }
//
//        }
//        //水源获取实时流量并计算出当天流量
//        for (DeviceWaterDetail deviceWaterDetail : deviceIntakeWaterDetailsForNow) {
//            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
//                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
//                        //水源累计瞬时流量
//                        deviceWaterAmount.addWaterIntakeAmountForNow(new BigDecimal(monitorDataValueEntity.getDataValue()));
//                    }
//                }
//            }
//        }
//
//        //3供水 4取水
//        List<DeviceWaterDetail> deviceSupplyWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay("水厂", 3, tenantId, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth());
//        List<DeviceWaterDetail> deviceIntakeWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay("水源", 4, tenantId, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth());
//
//        //水厂获取实时流量并计算出当天流量
//        for (DeviceWaterDetail deviceWaterDetail : deviceSupplyWaterDetailsForDay) {
//            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
//                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
//                        //累计当天流量
//                        deviceWaterAmount.addWaterSupplyAmountForDay(new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue()).add(deviceWaterDetail.getAmount()));
//                    }
//                }
//            }
//
//        }
//        //水源获取实时流量并计算出当天流量
//        for (DeviceWaterDetail deviceWaterDetail : deviceIntakeWaterDetailsForDay) {
//            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
//                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
//                        //累计当天流量
//                        deviceWaterAmount.addWaterIntakeAmountForDay(new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue()).add(deviceWaterDetail.getAmount()));
//                    }
//                }
//            }
//        }
//
//        BigDecimal waterSupplyAmountForMonth = monitorDataReportMapper.getDeviceWaterDetailForMonth("水厂", 3, tenantId, localDate.getYear(), localDate.getMonthValue());
//        BigDecimal waterSupplyAmountForYear = monitorDataReportMapper.getDeviceWaterDetailForYear("水厂", 3, tenantId, localDate.getYear());
//        if (waterSupplyAmountForMonth == null) {
//            waterSupplyAmountForMonth = BigDecimal.ZERO;
//        }
//        if (waterSupplyAmountForYear == null) {
//            waterSupplyAmountForYear = BigDecimal.ZERO;
//        }
//        //水厂当月流量
//        if (deviceWaterAmount.getWaterSupplyAmountForDay() == null) {
//            deviceWaterAmount.setWaterSupplyAmountForMonth(waterSupplyAmountForMonth);
//        } else {
//            deviceWaterAmount.setWaterSupplyAmountForMonth(waterSupplyAmountForMonth.add(deviceWaterAmount.getWaterSupplyAmountForDay()));
//        }
//        //水厂当年流量
//        if (deviceWaterAmount.getWaterSupplyAmountForMonth() == null) {
//            deviceWaterAmount.setWaterSupplyAmountForYear(waterSupplyAmountForYear);
//        } else {
//            deviceWaterAmount.setWaterSupplyAmountForYear(waterSupplyAmountForYear.add(deviceWaterAmount.getWaterSupplyAmountForMonth()));
//        }
//
//
//        BigDecimal waterIntakeAmountForMonth = monitorDataReportMapper.getDeviceWaterDetailForMonth("水源", 4, tenantId, localDate.getYear(), localDate.getMonthValue());
//        BigDecimal waterIntakeAmountForYear = monitorDataReportMapper.getDeviceWaterDetailForYear("水源", 4, tenantId, localDate.getYear());
//        if (waterIntakeAmountForMonth == null) {
//            waterIntakeAmountForMonth = BigDecimal.ZERO;
//        }
//        if (waterIntakeAmountForYear == null) {
//            waterIntakeAmountForYear = BigDecimal.ZERO;
//        }
//        //水源当月流量
//        if (deviceWaterAmount.getWaterIntakeAmountForDay() == null) {
//            deviceWaterAmount.setWaterIntakeAmountForMonth(waterIntakeAmountForMonth);
//        } else {
//            deviceWaterAmount.setWaterIntakeAmountForMonth(waterIntakeAmountForMonth.add(deviceWaterAmount.getWaterIntakeAmountForDay()));
//        }
//        //水源当年流量
//        if (deviceWaterAmount.getWaterIntakeAmountForMonth() == null) {
//            deviceWaterAmount.setWaterIntakeAmountForYear(waterIntakeAmountForYear);
//        } else {
//            deviceWaterAmount.setWaterIntakeAmountForYear(waterIntakeAmountForYear.add(deviceWaterAmount.getWaterIntakeAmountForMonth()));
//        }
//        //1
//        generalViewResults.setDeviceWaterAmount(deviceWaterAmount);
//
//        //实时报警信息
//        List<SceneAlarm> sceneAlarms = monitorDataReportMapper.getAlarmInfoForScene(tenantId);
//
//        //2报警
//        generalViewResults.setSceneAlarms(sceneAlarms);
//        //管网水质（水质 -1、8PH、10浊度、11余氯）
//        List<SceneNormalRate> SceneNormalRates = new ArrayList<>();
//        //水质
//        SceneNormalRate sceneNormalRate1 = monitorDataReportMapper.getQualificationForScene(tenantId, -1);
//        //PH
//        SceneNormalRate sceneNormalRate2 = monitorDataReportMapper.getQualificationForScene(tenantId, 8);
//        //浊度
//        SceneNormalRate sceneNormalRate3 = monitorDataReportMapper.getQualificationForScene(tenantId, 10);
//        //余氯
//        SceneNormalRate sceneNormalRate4 = monitorDataReportMapper.getQualificationForScene(tenantId, 11);
//        SceneNormalRates.add(sceneNormalRate1);
//        SceneNormalRates.add(sceneNormalRate2);
//        SceneNormalRates.add(sceneNormalRate3);
//        SceneNormalRates.add(sceneNormalRate4);
//        //3水质情况
//        generalViewResults.setSceneNormalRates(SceneNormalRates);
//
//        //压力分布
//        List<DeviceWaterDetail> devicePressureWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow("水厂", 13, tenantId);
//
//        List<SceneWaterAmount> sceneWaterPressureAmounts = new ArrayList<>();
//
//        devicePressureWaterDetailsForNow.stream()
//                .filter(item -> StringUtils.isNotBlank(item.getSceneName()))
//                .collect(Collectors.groupingBy(item -> item.getSceneName(), Collectors.toList()))
//                .forEach((key, value) -> {
//                    SceneWaterAmount sceneWaterAmount = new SceneWaterAmount();
//                    sceneWaterAmount.setSceneName(key);
//                    sceneWaterAmount.setWaterAmount(BigDecimal.ZERO);
//                    value.stream().forEach(deviceWaterDetail -> {
//                        MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//                        if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                            monitorDataEntity.getDataValues().stream()
//                                    .filter(monitorDataValueEntity -> monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId()))
//                                    .forEach(monitorDataValueEntity ->
//                                            //累计当前压力
//                                            sceneWaterAmount.setWaterAmount(sceneWaterAmount.getWaterAmount().add(new BigDecimal(monitorDataValueEntity.getDataValue())))
//                                    );
//                        }
//                    });
//                    sceneWaterPressureAmounts.add(sceneWaterAmount);
//                });
//
//        //进行压力分组
//        SceneWaterPressure sceneWaterPressure = new SceneWaterPressure();
//        SceneWaterAmount amountMax = null;
//        SceneWaterAmount amountMin = null;
//        for (SceneWaterAmount waterPressure : sceneWaterPressureAmounts) {
//            if (StringUtils.isNotBlank(waterPressure.getSceneName()) && waterPressure.getWaterAmount() != null) {
//                BigDecimal amount = waterPressure.getWaterAmount();
//                amountMax = amountMax == null || amount.compareTo(amountMax.getWaterAmount()) == 1 ? waterPressure : amountMax;
//                amountMin = amountMin == null || amount.compareTo(amountMin.getWaterAmount()) == -1 ? waterPressure : amountMin;
//
//                if (amount.compareTo(new BigDecimal(0.15)) == -1) {
//                    sceneWaterPressure.setPressureLevel1(sceneWaterPressure.getPressureLevel1() + 1);
//                } else if (amount.compareTo(new BigDecimal(0.15)) != 1 && amount.compareTo(new BigDecimal(0.30)) == -1) {
//                    sceneWaterPressure.setPressureLevel2(sceneWaterPressure.getPressureLevel2() + 1);
//                } else if (amount.compareTo(new BigDecimal(0.30)) != -1 && amount.compareTo(new BigDecimal(0.40)) == -1) {
//                    sceneWaterPressure.setPressureLevel3(sceneWaterPressure.getPressureLevel3() + 1);
//                } else if (amount.compareTo(new BigDecimal(0.40)) != -1 && amount.compareTo(new BigDecimal(0.50)) == -1) {
//                    sceneWaterPressure.setPressureLevel4(sceneWaterPressure.getPressureLevel4() + 1);
//                } else if (amount.compareTo(new BigDecimal(0.50)) != -1) {
//                    sceneWaterPressure.setPressureLevel5(sceneWaterPressure.getPressureLevel5() + 1);
//                }
//            }
//        }
//        if (amountMax != null) {
//            sceneWaterPressure.setMaxPressureSceneName(amountMax.getSceneName());
//            sceneWaterPressure.setMaxPressureValue(amountMax.getWaterAmount());
//        }
//        if (amountMax != null) {
//            sceneWaterPressure.setMinPressureSceneName(amountMin.getSceneName());
//            sceneWaterPressure.setMinPressureValue(amountMin.getWaterAmount());
//        }
//
//        //4压力分组
//        generalViewResults.setSceneWaterPressure(sceneWaterPressure);
//
//        //今日水厂制水量排行
////        deviceSupplyWaterDetailsForDay
//        List<SceneWaterAmount> sceneWaterAmounts = new ArrayList<>();
//        deviceSupplyWaterDetailsForDay.stream()
//                .filter(item -> StringUtils.isNotBlank(item.getSceneName()))
//                .collect(Collectors.groupingBy(item -> item.getSceneName(), Collectors.toList()))
//                .forEach((key, value) -> {
//                    SceneWaterAmount sceneWaterAmount = new SceneWaterAmount();
//                    sceneWaterAmount.setSceneName(key);
//                    sceneWaterAmount.setWaterAmount(BigDecimal.ZERO);
//                    value.stream().forEach(deviceWaterDetail -> {
//                        MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
//                        if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
//                            monitorDataEntity.getDataValues().stream()
//                                    .filter(monitorDataValueEntity -> monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId()))
//                                    .forEach(monitorDataValueEntity ->
//                                            //累计当天流量
//                                            sceneWaterAmount.setWaterAmount(sceneWaterAmount.getWaterAmount().add(
//                                                    new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue()).add(deviceWaterDetail.getAmount())))
//                                    );
//                        }
//                    });
//                    sceneWaterAmounts.add(sceneWaterAmount);
//                });
//        //倒序排序
//        sceneWaterAmounts.sort(Comparator.comparing(SceneWaterAmount::getWaterAmount).reversed());
//        //5水量排行
//        generalViewResults.setSceneWaterAmounts(sceneWaterAmounts);
//
//        //水厂制水、药耗、电耗对比曲线
//        List<WaterSupplyData> waterSupplyDatas = monitorDataReportMapper.getWaterSupplyData(tenantId);
//        List<WaterSupplyChart> waterSupplyCharts = new ArrayList<>();
//        waterSupplyDatas.stream()
//                .collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth() + "-" + item.getDay()))
//                .forEach((key, value) -> {
//                    WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
//                    waterSupplyChart.setDate(key);
//                    value.stream().forEach(waterSupplyData -> {
//                        Period period = Period.between(LocalDate.of(waterSupplyData.getYear(), waterSupplyData.getMonth(), waterSupplyData.getDay()), localDate);
//                        waterSupplyChart.setSort(period.getDays());
//
//                        if (waterSupplyData.getParmType() == 3) { //供水
//                            waterSupplyChart.setWaterData(waterSupplyData.getAmount());
//                        } else if (waterSupplyData.getParmType() == 5) {//电耗
//                            waterSupplyChart.setPowerData(waterSupplyData.getAmount());
//                        } else if (waterSupplyData.getParmType() == 6) {//药耗
//                            waterSupplyChart.setDrugData(waterSupplyData.getAmount());
//                        }
//                    });
//                    waterSupplyCharts.add(waterSupplyChart);
//                });
//        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort));
//
//        //6曲线图
//        generalViewResults.setWaterSupplyCharts(waterSupplyCharts);
//
        return generalViewResults;
    }

    //水厂近30天供水量
    @Override
    public List<DeviceWaterSupply> deviceWaterSupplie() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();
        List<DeviceWaterSupply> deviceWaterSupplies = monitorDataReportMapper.getDeviceWaterFor30Day(tenantId,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        LocalDate localDate = LocalDate.now();
        BigDecimal amountCountDay  =  getAmountCount(null,null,"水厂",3,1);
        DeviceWaterSupply deviceWaterSupplyDay = new DeviceWaterSupply();
        deviceWaterSupplyDay.setOrderNo( 1);
        deviceWaterSupplyDay.setAmount(amountCountDay != null?amountCountDay.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP):BigDecimal.ZERO);
        deviceWaterSupplyDay.setYear(localDate.getYear());
        deviceWaterSupplyDay.setMonth(localDate.getMonthValue());
        deviceWaterSupplyDay.setDay(localDate.getDayOfMonth());
        deviceWaterSupplyDay.setDate(localDate);
        deviceWaterSupplies.add(0, deviceWaterSupplyDay);


        for (int i = 0; i < 15; i++) {
            LocalDate newLocalDate = localDate.plusDays(-i);
            if (i == deviceWaterSupplies.size()
                    || !newLocalDate.isEqual(LocalDate.of(deviceWaterSupplies.get(i).getYear(),
                    deviceWaterSupplies.get(i).getMonth(),
                    deviceWaterSupplies.get(i).getDay()))) {

                DeviceWaterSupply deviceWaterSupply = new DeviceWaterSupply();
                deviceWaterSupply.setOrderNo(i + 1);
                deviceWaterSupply.setAmount(BigDecimal.ZERO);
                deviceWaterSupply.setYear(newLocalDate.getYear());
                deviceWaterSupply.setMonth(newLocalDate.getMonthValue());
                deviceWaterSupply.setDay(newLocalDate.getDayOfMonth());
                deviceWaterSupply.setDate(newLocalDate);
                deviceWaterSupplies.add(i, deviceWaterSupply);
            } else {
                deviceWaterSupplies.get(i).setOrderNo(i + 1);
                deviceWaterSupplies.get(i).setDate(newLocalDate);
            }
        }
        deviceWaterSupplies.sort(Comparator.comparing(DeviceWaterSupply::getOrderNo).reversed());
        return deviceWaterSupplies;
    }

    //供水详情数据（合计：瞬时、本天、本月、本年）
    @Override
    public DeviceWaterAmount deviceWaterAmount() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();

        Map<Integer, MonitorDataEntity> MonitorDataMap = getIntegerMonitorDataEntityMap(loginUser);

        LocalDate localDate = LocalDate.now();

        DeviceWaterAmount deviceWaterAmount = new DeviceWaterAmount();
        //14瞬时流量
        List<DeviceWaterDetail> deviceSupplyWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow("水厂", 14, tenantId,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        List<DeviceWaterDetail> deviceIntakeWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow("水源", 14, tenantId,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        //水厂获取实时流量
        for (DeviceWaterDetail deviceWaterDetail : deviceSupplyWaterDetailsForNow) {
            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
                        //水厂累计瞬时流量
                        deviceWaterAmount.addWaterSupplyAmountForNow(new BigDecimal(monitorDataValueEntity.getDataValue()));
                    }
                }
            }

        }
        //水源获取实时流量
        for (DeviceWaterDetail deviceWaterDetail : deviceIntakeWaterDetailsForNow) {
            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
                        //水源累计瞬时流量
                        deviceWaterAmount.addWaterIntakeAmountForNow(new BigDecimal(monitorDataValueEntity.getDataValue()));
                    }
                }
            }
        }

        //3供水 4取水
        List<DeviceWaterDetail> deviceSupplyWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay(null,null,"水厂", 3, tenantId, localDate.plusDays(-1).getYear(), localDate.plusDays(-1).getMonthValue(), localDate.plusDays(-1).getDayOfMonth(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        List<DeviceWaterDetail> deviceIntakeWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay(null,null,"水源", 4, tenantId, localDate.plusDays(-1).getYear(), localDate.plusDays(-1).getMonthValue(), localDate.plusDays(-1).getDayOfMonth(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        //水厂计算出当天流量
        for (DeviceWaterDetail deviceWaterDetail : deviceSupplyWaterDetailsForDay) {
            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0
                && deviceWaterDetail != null && deviceWaterDetail.getLatestValue() != null) {
                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
                        //累计当天流量
                        deviceWaterAmount.addWaterSupplyAmountForDay((new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue())
                        ).divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
                    }
                }
            }

        }
        //水源计算出当天流量
        for (DeviceWaterDetail deviceWaterDetail : deviceIntakeWaterDetailsForDay) {
            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0
                    && deviceWaterDetail != null && deviceWaterDetail.getLatestValue() != null) {
                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
                        //累计当天流量
                        deviceWaterAmount.addWaterIntakeAmountForDay((new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue())
                        ).divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
                    }
                }
            }
        }

        BigDecimal waterSupplyAmountForMonth = monitorDataReportMapper.getDeviceWaterDetailForMonth(null,null,"水厂", 3, tenantId, localDate.getYear(), localDate.getMonthValue(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        BigDecimal waterSupplyAmountForYear = monitorDataReportMapper.getDeviceWaterDetailForYear(null,null,"水厂", 3, tenantId, localDate.getYear(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        if (waterSupplyAmountForMonth == null) {
            waterSupplyAmountForMonth = BigDecimal.ZERO;
        }
        if (waterSupplyAmountForYear == null) {
            waterSupplyAmountForYear = BigDecimal.ZERO;
        }
        waterSupplyAmountForMonth =waterSupplyAmountForMonth.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP);
        waterSupplyAmountForYear =waterSupplyAmountForYear.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP);
        //水厂当月流量
        if (deviceWaterAmount.getWaterSupplyAmountForDay() == null) {
            deviceWaterAmount.setWaterSupplyAmountForMonth(waterSupplyAmountForMonth);
        } else {
            deviceWaterAmount.setWaterSupplyAmountForMonth(waterSupplyAmountForMonth.add(deviceWaterAmount.getWaterSupplyAmountForDay()));
        }
        //水厂当年流量
        if (deviceWaterAmount.getWaterSupplyAmountForMonth() == null) {
            deviceWaterAmount.setWaterSupplyAmountForYear(waterSupplyAmountForYear);
        } else {
            deviceWaterAmount.setWaterSupplyAmountForYear(waterSupplyAmountForYear.add(deviceWaterAmount.getWaterSupplyAmountForMonth()));
        }


        BigDecimal waterIntakeAmountForMonth = monitorDataReportMapper.getDeviceWaterDetailForMonth(null,null,"水源", 4, tenantId, localDate.getYear(), localDate.getMonthValue(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        BigDecimal waterIntakeAmountForYear = monitorDataReportMapper.getDeviceWaterDetailForYear(null,null,"水源", 4, tenantId, localDate.getYear(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        if (waterIntakeAmountForMonth == null) {
            waterIntakeAmountForMonth = BigDecimal.ZERO;
        }
        if (waterIntakeAmountForYear == null) {
            waterIntakeAmountForYear = BigDecimal.ZERO;
        }
        waterIntakeAmountForMonth =waterIntakeAmountForMonth.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP);
        waterIntakeAmountForYear =waterIntakeAmountForYear.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP);
        //水源当月流量
        if (deviceWaterAmount.getWaterIntakeAmountForDay() == null) {
            deviceWaterAmount.setWaterIntakeAmountForMonth(waterIntakeAmountForMonth);
        } else {
            deviceWaterAmount.setWaterIntakeAmountForMonth(waterIntakeAmountForMonth.add(deviceWaterAmount.getWaterIntakeAmountForDay()));
        }
        //水源当年流量
        if (deviceWaterAmount.getWaterIntakeAmountForMonth() == null) {
            deviceWaterAmount.setWaterIntakeAmountForYear(waterIntakeAmountForYear);
        } else {
            deviceWaterAmount.setWaterIntakeAmountForYear(waterIntakeAmountForYear.add(deviceWaterAmount.getWaterIntakeAmountForMonth()));
        }

        return deviceWaterAmount;
    }

    //实时报警信息
    @Override
    public List<SceneAlarm> sceneAlarms() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();
        return monitorDataReportMapper.getAlarmInfoForScene(tenantId,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
    }

    //管网水质（水质 -1、8PH、10浊度、11余氯）
    @Override
    public List<SceneNormalRate> SceneNormalRates() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();

        List<SceneNormalRate> SceneNormalRates = new ArrayList<>();
        //水质
        SceneNormalRate sceneNormalRate1 = monitorDataReportMapper.getQualificationForScene(tenantId, -1,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //PH
        SceneNormalRate sceneNormalRate2 = monitorDataReportMapper.getQualificationForScene(tenantId, 8,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //浊度
        SceneNormalRate sceneNormalRate3 = monitorDataReportMapper.getQualificationForScene(tenantId, 10,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //余氯
        SceneNormalRate sceneNormalRate4 = monitorDataReportMapper.getQualificationForScene(tenantId, 11,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        if(sceneNormalRate1 == null){
            sceneNormalRate1 =new SceneNormalRate();
        }
        if(sceneNormalRate2 == null){
            sceneNormalRate2 =new SceneNormalRate();
        }
        if(sceneNormalRate3 == null){
            sceneNormalRate3 =new SceneNormalRate();
        }
        if(sceneNormalRate4 == null){
            sceneNormalRate4 =new SceneNormalRate();
        }

        sceneNormalRate1.setTypeName("水质");
        sceneNormalRate2.setTypeName("PH");
        sceneNormalRate3.setTypeName("浊度");
        sceneNormalRate4.setTypeName("余氯");
        SceneNormalRates.add(sceneNormalRate1);
        SceneNormalRates.add(sceneNormalRate2);
        SceneNormalRates.add(sceneNormalRate3);
        SceneNormalRates.add(sceneNormalRate4);

        return SceneNormalRates;
    }

    //压力分布
    @Override
    public SceneWaterPressure sceneWaterPressure(String sceneType) {

        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();
        Map<Integer, MonitorDataEntity> MonitorDataMap = getIntegerMonitorDataEntityMap(loginUser);

        List<DeviceWaterDetail> devicePressureWaterDetailsForNow = monitorDataReportMapper.getDeviceWaterDetailForNow(sceneType, 13, tenantId,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        List<SceneWaterAmount> sceneWaterPressureAmounts = new ArrayList<>();

        devicePressureWaterDetailsForNow.stream()
                .filter(item -> StringUtils.isNotBlank(item.getSceneName()))
                .collect(Collectors.groupingBy(item -> item.getSceneName(), Collectors.toList()))
                .forEach((key, value) -> {
                    SceneWaterAmount sceneWaterAmount = new SceneWaterAmount();
                    sceneWaterAmount.setSceneName(key);
                    sceneWaterAmount.setWaterAmount(BigDecimal.ZERO);
                    value.stream().forEach(deviceWaterDetail -> {
                        MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
                        if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
                            monitorDataEntity.getDataValues().stream()
                                    .filter(monitorDataValueEntity -> monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId()))
                                    .forEach(monitorDataValueEntity -> {
                                            //累计当前压力
                                            if (monitorDataValueEntity.getDataValue() != null) {
                                                sceneWaterAmount.setWaterAmount(sceneWaterAmount.getWaterAmount().add(new BigDecimal(monitorDataValueEntity.getDataValue())));
                                            }
                                        }
                                    );
                        }
                    });
                    sceneWaterPressureAmounts.add(sceneWaterAmount);
                });

        //进行压力分组
        SceneWaterPressure sceneWaterPressure = new SceneWaterPressure();
        SceneWaterAmount amountMax = null;
        SceneWaterAmount amountMin = null;
        BigDecimal amountSum = BigDecimal.ZERO;
        for (SceneWaterAmount waterPressure : sceneWaterPressureAmounts) {
            if (StringUtils.isNotBlank(waterPressure.getSceneName()) && waterPressure.getWaterAmount() != null) {
                amountSum = amountSum.add(waterPressure.getWaterAmount());
                BigDecimal amount = waterPressure.getWaterAmount();
                amountMax = amountMax == null || amount.compareTo(amountMax.getWaterAmount()) == 1 ? waterPressure : amountMax;
                amountMin = amountMin == null || amount.compareTo(amountMin.getWaterAmount()) == -1 ? waterPressure : amountMin;

                if (amount.compareTo(new BigDecimal(0.15)) == -1) {
                    sceneWaterPressure.setPressureLevel1(sceneWaterPressure.getPressureLevel1() + 1);
                } else if (amount.compareTo(new BigDecimal(0.15)) != 1 && amount.compareTo(new BigDecimal(0.30)) == -1) {
                    sceneWaterPressure.setPressureLevel2(sceneWaterPressure.getPressureLevel2() + 1);
                } else if (amount.compareTo(new BigDecimal(0.30)) != -1 && amount.compareTo(new BigDecimal(0.40)) == -1) {
                    sceneWaterPressure.setPressureLevel3(sceneWaterPressure.getPressureLevel3() + 1);
                } else if (amount.compareTo(new BigDecimal(0.40)) != -1 && amount.compareTo(new BigDecimal(0.50)) == -1) {
                    sceneWaterPressure.setPressureLevel4(sceneWaterPressure.getPressureLevel4() + 1);
                } else if (amount.compareTo(new BigDecimal(0.50)) != -1) {
                    sceneWaterPressure.setPressureLevel5(sceneWaterPressure.getPressureLevel5() + 1);
                }
            }
        }
        if(sceneWaterPressureAmounts.size()>0){
            sceneWaterPressure.setAvgPressureValue(amountSum.divide(new BigDecimal(sceneWaterPressureAmounts.size()),2,BigDecimal.ROUND_HALF_UP));
        }
        if (amountMax != null) {
            sceneWaterPressure.setMaxPressureSceneName(amountMax.getSceneName());
            sceneWaterPressure.setMaxPressureValue(amountMax.getWaterAmount());
        }
        if (amountMax != null) {
            sceneWaterPressure.setMinPressureSceneName(amountMin.getSceneName());
            sceneWaterPressure.setMinPressureValue(amountMin.getWaterAmount());
        }
        List<Integer> pressureLevels = new ArrayList<>();
        pressureLevels.add(sceneWaterPressure.getPressureLevel1());
        pressureLevels.add(sceneWaterPressure.getPressureLevel2());
        pressureLevels.add(sceneWaterPressure.getPressureLevel3());
        pressureLevels.add(sceneWaterPressure.getPressureLevel4());
        pressureLevels.add(sceneWaterPressure.getPressureLevel5());
        sceneWaterPressure.setPressureLevels(pressureLevels);
        return sceneWaterPressure;
    }

    //今日水厂制水量排行
    @Override
    public List<SceneWaterAmount> sceneWaterAmounts() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();
        //查询设备数据
        Map<Integer, MonitorDataEntity> MonitorDataMap = getIntegerMonitorDataEntityMap(loginUser);

        LocalDate localDate = LocalDate.now();
        List<DeviceWaterDetail> deviceSupplyWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay(null,null,"水厂", 3, tenantId, localDate.plusDays(-1).getYear(), localDate.plusDays(-1).getMonthValue(), localDate.plusDays(-1).getDayOfMonth(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());

        List<SceneWaterAmount> sceneWaterAmounts = new ArrayList<>();
        deviceSupplyWaterDetailsForDay.stream()
                .filter(item -> StringUtils.isNotBlank(item.getSceneName()) && item != null && item.getLatestValue() != null )
                .collect(Collectors.groupingBy(item -> item.getSceneName(), Collectors.toList()))
                .forEach((key, value) -> {
                    SceneWaterAmount sceneWaterAmount = new SceneWaterAmount();
                    sceneWaterAmount.setSceneName(key);
                    sceneWaterAmount.setWaterAmount(BigDecimal.ZERO);
                    value.stream().forEach(deviceWaterDetail -> {
                        MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
                        if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0) {
                            monitorDataEntity.getDataValues().stream()
                                    .filter(monitorDataValueEntity ->
                                            monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())
                                    )
                                    .forEach(monitorDataValueEntity ->
                                            //累计当天流量
                                            sceneWaterAmount.setWaterAmount((sceneWaterAmount.getWaterAmount().add(
                                                    new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue()))))
                                    );
                        }
                    });
                    sceneWaterAmount.setWaterAmount(sceneWaterAmount.getWaterAmount().divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
                    sceneWaterAmounts.add(sceneWaterAmount);
                });
        //倒序排序
        sceneWaterAmounts.sort(Comparator.comparing(SceneWaterAmount::getWaterAmount).reversed());
        return sceneWaterAmounts;
    }

    //水厂制水、药耗、电耗对比曲线
    @Override
    public List<WaterSupplyChart> waterSupplyCharts(String sceneTypeName) {

        BigDecimal multipleData;
        if (sceneTypeName.equals("泵站")) {
            multipleData = new BigDecimal("1");
        } else {
            multipleData = new BigDecimal("10000");
        }
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();

        List<WaterSupplyData> waterSupplyDatas = monitorDataReportMapper.getWaterSupplyData(tenantId, sceneTypeName, loginUser.getType(), loginUser.getPermissonType(), loginUser.getProgramItemList());
        List<WaterSupplyChart> waterSupplyCharts = new ArrayList<>();
        waterSupplyDatas.stream()
                .collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth() + "-" + item.getDay()))
                .forEach((key, value) -> {
                    WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
                    waterSupplyChart.setDate(key);
                    value.stream().forEach(waterSupplyData -> {
                        Period period = Period.between(LocalDate.of(waterSupplyData.getYear(), waterSupplyData.getMonth(), waterSupplyData.getDay()), LocalDate.now());
                        waterSupplyChart.setSort(period.getDays());
                        if (waterSupplyData.getParmType() == 3 && waterSupplyData.getAmount() != null) { //供水
                            waterSupplyChart.setWaterData(waterSupplyData.getAmount().divide(multipleData, 3, RoundingMode.HALF_UP));
                        } else if (waterSupplyData.getParmType() == 5 && waterSupplyData.getAmount() != null) {//电耗
                            waterSupplyChart.setPowerData(waterSupplyData.getAmount().divide(multipleData, 3, RoundingMode.HALF_UP));
                        } else if (waterSupplyData.getParmType() == 6 && waterSupplyData.getAmount() != null) {//药耗
                            waterSupplyChart.setDrugData(waterSupplyData.getAmount());
                        }
                    });
                    waterSupplyCharts.add(waterSupplyChart);
                });

        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort));
        for (int i = 0; i < 7; i++) {
            if (i == waterSupplyCharts.size() || !waterSupplyCharts.get(i).getSort().equals(i + 1)) {
                waterSupplyCharts.add(i, new WaterSupplyChart(i + 1));
            }
        }
        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort).reversed());
        return waterSupplyCharts;
    }

    //水厂制水、药耗、电耗对比曲线
    @Override
    public List<WaterSupplyChart> waterSupplyChartsForCurrentMonth(String sceneTypeName,Long sceneId) {

        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();
        List<Long> sceneIds = sceneService.findByParentIdsLike(sceneId);
        List<WaterSupplyData> waterSupplyDatas = monitorDataReportMapper.getWaterSupplyDataForCurrentMonth(tenantId, sceneTypeName, sceneIds, loginUser.getType(), loginUser.getPermissonType(), loginUser.getProgramItemList());
        List<WaterSupplyChart> waterSupplyCharts = new ArrayList<>();
        BigDecimal per = BigDecimal.valueOf(1);
        if (!sceneTypeName.equals("泵站"))
            per = BigDecimal.valueOf(10000);
        BigDecimal finalPer = per;
        waterSupplyDatas.stream()
                .collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth() + "-" + item.getDay()))
                .forEach((key, value) -> {
                    WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
                    waterSupplyChart.setDate(key);
                    value.stream().forEach(waterSupplyData -> {
                        //Period period = Period.between(LocalDate.of(waterSupplyData.getYear(), waterSupplyData.getMonth(), waterSupplyData.getDay()), LocalDate.now());
                        //waterSupplyChart.setSort(period.getDays());
                        waterSupplyChart.setSort(waterSupplyData.getDay());
                        if (waterSupplyData.getParmType() == 3 && waterSupplyData.getAmount() != null) { //供水
                            waterSupplyChart.setWaterData(waterSupplyData.getAmount().divide(finalPer, 3, RoundingMode.HALF_UP));
                        } else if (waterSupplyData.getParmType() == 5 && waterSupplyData.getAmount() != null) {//电耗
                            waterSupplyChart.setPowerData(waterSupplyData.getAmount().divide(finalPer, 3, RoundingMode.HALF_UP));
                        } else if (waterSupplyData.getParmType() == 6 && waterSupplyData.getAmount() != null) {//药耗
                            waterSupplyChart.setDrugData(waterSupplyData.getAmount());
                        }
                    });
                    waterSupplyCharts.add(waterSupplyChart);
                });

        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort));

        //获取当日水量
        BigDecimal waterDataAmountCountMonth = getAmountCount(null, sceneId.intValue(), sceneTypeName, 3, 1);
        //获取当日电耗
        BigDecimal powerDataAmountCountMonth = getAmountCount(null, sceneId.intValue(), sceneTypeName, 5, 1);
        LocalDate localDate = LocalDate.now();
        WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
        waterSupplyChart.setDate(LocalDate.now().getYear() + "-" + LocalDate.now().getMonthValue() + "-" + LocalDate.now().getDayOfMonth());
        waterSupplyChart.setWaterData(waterDataAmountCountMonth.divide(finalPer, 3, RoundingMode.HALF_UP));
        waterSupplyChart.setPowerData(powerDataAmountCountMonth.divide(finalPer, 3, RoundingMode.HALF_UP));
        waterSupplyChart.setSort(localDate.getDayOfMonth());
        //waterSupplyChart.setSort(0);
        //waterSupplyCharts.add(waterSupplyChart);

        Integer maxDay =  LocalDate.now().getDayOfMonth();
        for(int i=0;i<maxDay;i++) {
            if (i + 1 == localDate.getDayOfMonth()) {
                waterSupplyCharts.add(i, waterSupplyChart);
            } else if (i == waterSupplyCharts.size() || !waterSupplyCharts.get(i).getSort().equals(i+1)) {
                WaterSupplyChart temp=   new WaterSupplyChart(i + 1, localDate.getYear() + "-" + localDate.getMonthValue() + "-" + (i + 1));
                temp.setWaterData(BigDecimal.valueOf(0));
                temp.setPowerData(BigDecimal.valueOf(0));
                waterSupplyCharts.add(i, temp);
            }
        }
        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort));
        return waterSupplyCharts;
    }

    public ComUsageDto getYieldPowerUsage(Long companyOrgId) {
        ComUsageDto sceneUsageDto = new ComUsageDto();
        //查询公司下的场景
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setSceneTypeName("水厂");
        List<SceneEntity> sceneEntities = sceneService.selectByTypeNameForCom(sceneEntity, companyOrgId);
        for (SceneEntity itemScene : sceneEntities) {
            //查询场景下的所有设备信息
            List<DeviceDto> devices = new ArrayList<>();
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setSceneIds(sceneService.findByParentIdsLike(itemScene.getId()));
            if (deviceDto.getSceneIds().size() == 0)
                continue;
            devices.addAll(deviceService.selectList(deviceDto));
            //取前一天
            LocalDateTime dateTime = LocalDateTime.now().plusDays(-1);
            for (DeviceDto item : devices) {
                //设备的几个参数值
                SceneDeviceAttributeDto sceneDeviceAttributeDto = new SceneDeviceAttributeDto();
                sceneDeviceAttributeDto.setDeviceId(item.getId());
                sceneDeviceAttributeDto.setYear(dateTime.getYear());
                sceneDeviceAttributeDto.setMonth(dateTime.getMonthValue());
                sceneDeviceAttributeDto.setDay(dateTime.getDayOfMonth());
                sceneDeviceAttributeDto.setSceneId(itemScene.getId());
                List<SceneDeviceAttributeDto> sceneDeviceAttributeDtos = monitorInfoService.findAttributeList(sceneDeviceAttributeDto);
                //取缓存里的数据
                byte[] bytes = redisUtil.get(("sms_water_" + item.getDeviceCode()).getBytes());
                if (bytes != null && bytes.length > 0) {
                    MonitorDataEntity monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                    //筛选该设备相同属性的值
                    Map<Long, MonitorDataValueEntity> map = new HashMap<>();
                    //将缓存中的实时数据放到map中方便进行遍历
                    for (MonitorDataValueEntity dateValue : monitorDataEntity.getDataValues()) {
                        map.put(dateValue.getAttributeId(), dateValue);
                    }
                    for (SceneDeviceAttributeDto itemAttribute : sceneDeviceAttributeDtos) {
                        Double attributeDiffValue = 0d;
                        if (!map.containsKey(itemAttribute.getAttributeId())) {
                            continue;
                        }
                        if (map.get(itemAttribute.getAttributeId()).getDataValue() != null && itemAttribute.getLatestValue() != null) {
                            attributeDiffValue = map.get(itemAttribute.getAttributeId()).getDataValue() - itemAttribute.getLatestValue();
                        } else if (map.get(itemAttribute.getAttributeId()).getDataValue() != null && itemAttribute.getLatestValue() == null) {
                            attributeDiffValue = map.get(itemAttribute.getAttributeId()).getDataValue();
                        }
                        switch (itemAttribute.getAttributeType()) {
                            case "3":
                                sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage() != null ? (double) Math.round((sceneUsageDto.getYieldWaterUsage() + attributeDiffValue) * 1000) / 1000 : (double) Math.round((attributeDiffValue) * 1000) / 1000);
                                break;
                            case "5":
                                sceneUsageDto.setPowerUsage(sceneUsageDto.getPowerUsage() != null ? (double) Math.round((sceneUsageDto.getPowerUsage() + attributeDiffValue) * 1000) / 1000 : (double) Math.round((attributeDiffValue) * 1000) / 1000);
                                break;
                        }
                    }
                    if (sceneUsageDto.getYieldWaterUsage() == null)
                        sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage());
                    if (sceneUsageDto.getPowerUsage() == null)
                        sceneUsageDto.setPowerUsage(sceneUsageDto.getPowerUsage());
                }
            }
        }

        if (sceneUsageDto.getPowerUsage() != null && sceneUsageDto.getYieldWaterUsage() != null && sceneUsageDto.getPowerUsage() != 0) {
            sceneUsageDto.setYieldPowerUsage((double) Math.round((sceneUsageDto.getPowerUsage() / sceneUsageDto.getYieldWaterUsage()) * 100) / 100);
        } else {
            sceneUsageDto.setYieldPowerUsage(0d);
        }
        //对数据进行单位转换 按万进行统计
        sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage() != null ? (double) Math.round(sceneUsageDto.getYieldWaterUsage() / (float) 100) / 100 : 0);
        return sceneUsageDto;
    }

    @Override
    public List<WaterSupplyChart> waterSupplyChartsByMonth(String sceneTypeName, Integer companyOrgId) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();

        List<WaterSupplyData> waterSupplyDatas = monitorDataReportMapper.getWaterSupplyDataByMonth(tenantId,companyOrgId,sceneTypeName,loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //获取本月水量
        BigDecimal waterDataAmountCountMonth = getAmountCount(companyOrgId,null, sceneTypeName, 3,2 );
        //获取本月电耗
        BigDecimal powerDataAmountCountMonth = getAmountCount(companyOrgId,null, sceneTypeName, 5,2 );

        List<WaterSupplyChart> waterSupplyCharts = new ArrayList<>();
        waterSupplyDatas.stream()
                .collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth()))
                .forEach((key, value) -> {
                    WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
                    waterSupplyChart.setDate(key);
                    value.stream().forEach(waterSupplyData -> {
                        Period period = Period.between(LocalDate.of(waterSupplyData.getYear(), waterSupplyData.getMonth(),1), LocalDate.now());
                        waterSupplyChart.setSort(period.getMonths()+1);
                        if (waterSupplyData.getParmType() == 3) { //供水
                            waterSupplyChart.setWaterData(waterSupplyData.getAmount().divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
                        } else if (waterSupplyData.getParmType() == 5) {//电耗
                            waterSupplyChart.setPowerData(waterSupplyData.getAmount().divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
                        }
                    });
                    waterSupplyCharts.add(waterSupplyChart);
                });
        WaterSupplyChart waterSupplyChart = new WaterSupplyChart();
        waterSupplyChart.setSort(1);
        waterSupplyChart.setDate(LocalDate.now().getYear()+"-"+LocalDate.now().getMonthValue());
        waterSupplyChart.setPowerData(powerDataAmountCountMonth.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
        waterSupplyChart.setWaterData(waterDataAmountCountMonth.divide(BigDecimal.valueOf(10000),3, RoundingMode.HALF_UP));
        waterSupplyCharts.add(waterSupplyChart);

        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort));
        for(int i=0;i<6;i++){
            if(i == waterSupplyCharts.size() || !waterSupplyCharts.get(i).getSort().equals(i+1)){
                waterSupplyCharts.add(i,new WaterSupplyChart(i+1, 1));
            }
        }
        waterSupplyCharts.sort(Comparator.comparing(WaterSupplyChart::getSort).reversed());
        return waterSupplyCharts;
    }

    //查询设备实时数据
    public Map<Integer, MonitorDataEntity> getIntegerMonitorDataEntityMap(LoginUser loginUser) {

        //查询设备编码
        List<String> deviceCodes = monitorDataReportMapper.selectDeviceCode(loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //根据编码获取redis中的实时数据
        List<MonitorDataEntity> monitorDataEntities = new ArrayList<>();
        for (String deviceCode : deviceCodes) {
            //先取缓存里的数据
            byte[] bytes = redisUtil.get(("sms_water_" + deviceCode).getBytes());
            if (bytes != null && bytes.length > 0) {
                monitorDataEntities.add((MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get());
            }
        }
        //将获取到 实时数据转换为map，方便匹配数据deviceId
        return monitorDataEntities.stream().collect(Collectors.toMap(MonitorDataEntity::getDeviceId, a -> a, (k1, k2) -> k1));
    }

    /**
     * 获取设备的最后采集时间
     * @param companyOrgId
     * @param sceneId
     * @param sceneTypeName
     * @param parmType
     * @param searchType
     * @return
     */
   public Date getLastCollectTime(Integer companyOrgId, Integer sceneId, String sceneTypeName, Integer parmType,Integer searchType)
   {
       LoginUser loginUser = UserUtil.getCurrentUser();
       String tenantId = loginUser.getTenantId();
       //查询设备编码
       List<String> deviceCodes = monitorDataReportMapper.selectDeviceCodeByConditions(companyOrgId,sceneId,sceneTypeName, loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
       //根据编码获取redis中的实时数据
       List<MonitorDataEntity> monitorDataEntities = new ArrayList<>();
       for (String deviceCode : deviceCodes) {
           //先取缓存里的数据
           byte[] bytes = redisUtil.get(("sms_water_" + deviceCode).getBytes());
           if (bytes != null && bytes.length > 0) {
               monitorDataEntities.add((MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get());
           }
       }
       if(monitorDataEntities.size()>0) {
           monitorDataEntities.sort(Comparator.comparing(MonitorDataEntity::getCollectDate).reversed());
           return  monitorDataEntities.get(0).getCollectDate();
       }
       return  null;
   }

    /**
     * 查询设备某个属性值
     * @param deviceCode
     * @param attributeId
     * @return
     */
   public BigDecimal getDeviceAttributeValue(String deviceCode,Long attributeId) {
       BigDecimal amount = BigDecimal.ZERO;
       MonitorDataEntity monitorDataEntitie = new MonitorDataEntity();
       //先取缓存里的数据
       byte[] bytes = redisUtil.get(("sms_water_" + deviceCode).getBytes());
       if (bytes != null && bytes.length > 0) {
           monitorDataEntitie = ((MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get());
           for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntitie.getDataValues()) {
               if (monitorDataValueEntity.getAttributeId().equals(attributeId)) {
                   //获取当前数据
                   amount = new BigDecimal(monitorDataValueEntity.getDataValue());
               }
           }
       }
       return amount;
   }
    /**
     *
     * @param companyOrgId 公司id
     * @param sceneId 场景类型
     * @param sceneTypeName 场景类型
     * @param parmType  标记值
     * @param searchType 查询类型：1日 2月 3年
     * @return
     */
    public BigDecimal getAmountCount(Integer companyOrgId, Integer sceneId, String sceneTypeName, Integer parmType,Integer searchType){
        LoginUser loginUser = UserUtil.getCurrentUser();
        String tenantId = loginUser.getTenantId();


        //查询设备编码
        List<String> deviceCodes = monitorDataReportMapper.selectDeviceCodeByConditions(companyOrgId,sceneId,sceneTypeName, loginUser.getTenantId(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //根据编码获取redis中的实时数据
        List<MonitorDataEntity> monitorDataEntities = new ArrayList<>();
        for (String deviceCode : deviceCodes) {
            //先取缓存里的数据
            byte[] bytes = redisUtil.get(("sms_water_" + deviceCode).getBytes());
            if (bytes != null && bytes.length > 0) {
                monitorDataEntities.add((MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get());
            }
        }
        //将获取到 实时数据转换为map，方便匹配数据deviceId
        Map<Integer, MonitorDataEntity> MonitorDataMap =  monitorDataEntities.stream().collect(Collectors.toMap(MonitorDataEntity::getDeviceId, a -> a, (k1, k2) -> k1));
        LocalDate localDate = LocalDate.now();
        BigDecimal amountDay =BigDecimal.ZERO;
        List<DeviceWaterDetail> deviceSupplyWaterDetailsForDay = monitorDataReportMapper.getDeviceWaterDetailForDay(companyOrgId,sceneId,sceneTypeName, parmType, tenantId, localDate.plusDays(-1).getYear(), localDate.plusDays(-1).getMonthValue(), localDate.plusDays(-1).getDayOfMonth(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        //获取实时数据并计算出当天数据
        for (DeviceWaterDetail deviceWaterDetail : deviceSupplyWaterDetailsForDay) {
            MonitorDataEntity monitorDataEntity = MonitorDataMap.get(deviceWaterDetail.getDeviceId());
            if (monitorDataEntity != null && monitorDataEntity.getDataValues() != null && monitorDataEntity.getDataValues().size() > 0
                    && deviceWaterDetail != null && deviceWaterDetail.getLatestValue() != null) {
                for (MonitorDataValueEntity monitorDataValueEntity : monitorDataEntity.getDataValues()) {
                    if (monitorDataValueEntity.getAttributeId().equals(deviceWaterDetail.getAttributeId())) {
                        //累计当天数据
                        amountDay = amountDay.add(new BigDecimal(monitorDataValueEntity.getDataValue()).subtract(deviceWaterDetail.getLatestValue()));
                    }
                }
            }
        }
        if(searchType == null || searchType == 1){
            return amountDay;
        }
        BigDecimal amountMonth =BigDecimal.ZERO;
        //当月数据
        BigDecimal waterSupplyAmountForMonth = monitorDataReportMapper.getDeviceWaterDetailForMonth(companyOrgId,sceneId,sceneTypeName, parmType, tenantId, localDate.getYear(), localDate.getMonthValue(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        if (waterSupplyAmountForMonth != null) {
            amountMonth = waterSupplyAmountForMonth.add(amountDay);
        }
        if(searchType != null && searchType == 2){
            return amountMonth;
        }
        //当年数据
        BigDecimal amountYear =BigDecimal.ZERO;
        BigDecimal waterSupplyAmountForYear = monitorDataReportMapper.getDeviceWaterDetailForYear(companyOrgId,sceneId,sceneTypeName, parmType, tenantId, localDate.getYear(),loginUser.getType(),loginUser.getPermissonType(),loginUser.getProgramItemList());
        if (waterSupplyAmountForYear != null) {
            amountYear = waterSupplyAmountForYear.add(amountMonth);
        }
        if(searchType != null && searchType == 3){
            return amountYear;
        }
        return BigDecimal.ZERO;
    }

    @Override
    public BigDecimal getUseAmount(Integer companyOrgId, Integer searchType) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        BigDecimal amountMonth = BigDecimal.ZERO;
        amountMonth = monitorDataReportMapper.getUseAmount(companyOrgId, loginUser.getTenantId(), searchType, loginUser.getType(), loginUser.getPermissonType(), loginUser.getProgramItemList());
        if (amountMonth == null)
            amountMonth = BigDecimal.ZERO;
        return amountMonth;
    }


    private void FillLoseData(String startTime, String endTime,List<MonitorDataChartReportDeviceDto> monitorDataChartReportDeviceDtos){
        LocalDateTime  startDate =  LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime  endDate   =  LocalDateTime.parse(endTime,   DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        int startDay = 0;
        int endDay   = 0;
        if (startDate.getYear() == endDate.getYear()){
            boolean sameMonth = startDate.getMonth().getValue() == endDate.getMonth().getValue();
            for (int i = startDate.getMonth().getValue(); i <= endDate.getMonth().getValue(); i++){
                startDay = (sameMonth || i == startDate.getMonth().getValue()) ? startDate.getDayOfMonth() : 1;
                endDay   = sameMonth  || i == endDate.getMonth().getValue() ? endDate.getDayOfMonth() :
                        startDate.withMonth(i).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
                FillLoseData(monitorDataChartReportDeviceDtos,2, startDate.getYear(), i, startDay, endDay);
            }
        } else {
            int start = 0;
            int end = 0;
            for (int i = startDate.getYear(); i <= endDate.getYear(); i++){
                start = i == startDate.getYear() ? startDate.getMonth().getValue() : 1;
                end   = i == endDate.getYear()   ? endDate.getMonthValue() : 12;
                for (int m = start; m <= end; m++){
                    startDay =  i == startDate.getYear() && m == start ? startDate.getDayOfMonth() : 1;
                    endDay   =  i == endDate.getYear() && m ==  endDate.getMonth().getValue() ?
                            endDate.getDayOfMonth() : startDate.withMonth(m).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
                    FillLoseData(monitorDataChartReportDeviceDtos,2, i, m, startDay, endDay);
                }
            }
        }
        for (MonitorDataChartReportDeviceDto dto : monitorDataChartReportDeviceDtos ) {
            for (MonitorDataChartReportAttributeDto attributeDto : dto.getAttributeData() ) {
                Collections.sort(attributeDto.getMonitorDataChartReportValue());
            }
        }
    }
}
