kaiyu
2021-09-27 2a781bbf1d42191c3b8225a9973bf3d0ecccd66b
screen-aqi
增加获取监测站数据显示接口
6 files added
8 files modified
784 ■■■■■ changed files
screen-api/src/main/java/com/moral/api/controller/DataDisplayController.java 78 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/pojo/dto/dataDisplay/MonitorPointDataDisplayDTO.java 25 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/pojo/form/dataDisplay/MonitorPointDataDisplayForm.java 82 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/pojo/form/uav/UAVQueryTimeSlotForm.java 5 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/DataDisplayService.java 22 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java 29 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/MonitorPointService.java 7 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/OrganizationService.java 9 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/impl/DataDisplayServiceImpl.java 173 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java 36 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/impl/OrganizationServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
screen-common/src/main/java/com/moral/constant/Constants.java 20 ●●●●● patch | view | raw | blame | history
screen-common/src/main/java/com/moral/util/ComprehensiveIndexUtils.java 164 ●●●●● patch | view | raw | blame | history
screen-common/src/main/java/com/moral/util/DateUtils.java 129 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/controller/DataDisplayController.java
New file
@@ -0,0 +1,78 @@
package com.moral.api.controller;
import com.moral.api.pojo.dto.dataDisplay.MonitorPointDataDisplayDTO;
import com.moral.api.pojo.form.dataDisplay.MonitorPointDataDisplayForm;
import com.moral.constant.ResponseCodeEnum;
import com.moral.constant.ResultMessage;
import com.moral.util.DateUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @ClassName DataDisplayController
 * @Description TODO
 * @Author 陈凯裕
 * @Date 2021/9/26 9:59
 * @Version TODO
 **/
@Slf4j
@Api(tags = {"数据显示"})
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/dataDisplay")
public class DataDisplayController {
    @GetMapping("monitorPointDataDisplay")
    public ResultMessage monitorPointDataDisplay(MonitorPointDataDisplayForm form){
        //判断是否缺少参数
        if (!form.valid())
            return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(),
                    ResponseCodeEnum.PARAMETERS_IS_MISSING.getMsg());
        MonitorPointDataDisplayDTO dto = new MonitorPointDataDisplayDTO();
        MonitorPointDataDisplayDTO dto1 = new MonitorPointDataDisplayDTO();
        MonitorPointDataDisplayDTO dto2 = new MonitorPointDataDisplayDTO();
        dto.setDeviceName("模拟设备1");
        dto1.setDeviceName("模拟设备2");
        dto2.setDeviceName("模拟设备3");
        dto.setTime("yyyy-MM-dd HH:mm:ss");
        dto1.setTime("yyyy-MM-dd HH:mm:ss");
        dto2.setTime("yyyy-MM-dd HH:mm:ss");
        dto.setOrganizationName("模拟组织1");
        dto1.setOrganizationName("模拟组织2");
        dto2.setOrganizationName("模拟组织3");
        Map<String,Object> valueMap = new HashMap<>();
        valueMap.put("a21026",1);
        valueMap.put("a21004",1);
        valueMap.put("a34002",1);
        valueMap.put("a34004",1);
        valueMap.put("a21005",1);
        valueMap.put("a05024",1);
        valueMap.put("a99054",1);
        valueMap.put("AQI",1);
        dto.setValues(valueMap);
        dto1.setValues(valueMap);
        dto2.setValues(valueMap);
        List<MonitorPointDataDisplayDTO> list = new ArrayList<>();
        list.add(dto);
        list.add(dto1);
        list.add(dto2);
        return new ResultMessage(ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg(),list);
    }
}
screen-api/src/main/java/com/moral/api/pojo/dto/dataDisplay/MonitorPointDataDisplayDTO.java
New file
@@ -0,0 +1,25 @@
package com.moral.api.pojo.dto.dataDisplay;
import lombok.Data;
import java.util.Map;
/**
 * @ClassName DataDisplayDTO
 * @Description TODO
 * @Author 陈凯裕
 * @Date 2021/9/26 16:53
 * @Version TODO
 **/
@Data
public class MonitorPointDataDisplayDTO {
    private String deviceName;
    private String organizationName;
    private String time;
    private Map<String,Object> values;
}
screen-api/src/main/java/com/moral/api/pojo/form/dataDisplay/MonitorPointDataDisplayForm.java
New file
@@ -0,0 +1,82 @@
package com.moral.api.pojo.form.dataDisplay;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.moral.constant.Constants;
import com.moral.util.DateUtils;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @ClassName MonitorPointDataDisplayForm
 * @Description TODO
 * @Author 陈凯裕
 * @Date 2021/9/26 10:03
 * @Version TODO
 **/
@Data
public class MonitorPointDataDisplayForm {
    /*
     * 站点id
     * */
    private Integer monitorPointId;
    /*
     * 开始时间
     * */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date startTime;
    /*
     * 结束时间
     * */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date endTime;
    /*
     * 时报,日报,周报,月报类型
     * */
    private String reportType;
    /*
     * 检测数据是否有效
     * */
    public boolean valid() {
        if (monitorPointId == null)
            return false;
        if (reportType == null) {
            if (startTime == null || endTime == null)
                return false;
            reportType = Constants.DAILYREPORT;
            //结束时间获取当天最后一个小时
            String endTimeStr = DateUtils.dateToDateString(endTime,"yyyy-MM-dd");
            endTimeStr+=" 23:59:59";
            endTime = DateUtils.getDate(endTimeStr,"yyyy-MM-dd HH:mm:ss");
        } else {
            if (reportType.equals(Constants.HOURYLYREPORT)) {
                //时报选项默认为上个小时的数据
                Date previousHour = DateUtils.getDateOfMin(new Date(), -60);
                startTime = DateUtils.getHourlyStartTime(previousHour);
            } else if (reportType.equals(Constants.DAILYREPORT)) {
                //日报选项默认为昨天的数据
                Date yesterday = DateUtils.getDateOfDay(new Date(),-1);
                startTime = DateUtils.getDailyStartTime(yesterday);
            } else if (reportType.equals(Constants.WEEKLYREPORT)) {
                //周报选项默认为上周的数据
                Date previous = DateUtils.getDateOfDay(new Date(),-7);
                startTime = DateUtils.getWeeklyStartTime(previous);
            } else if (reportType.equals(Constants.MONTHLYREPORT)) {
                //月报选项默认为上月的数据
                Date lastMonthFirstDay = DateUtils.getFirstDayOfLastMonth();
                startTime = DateUtils.getMonthlyStartTime(lastMonthFirstDay);
            } else
                return false;
        }
        return true;
    }
}
screen-api/src/main/java/com/moral/api/pojo/form/uav/UAVQueryTimeSlotForm.java
@@ -49,9 +49,8 @@
                )
            return false;
        //将日期转换为开始结束时间
        List<Date> dates = DateUtils.dateToStartAndEndTime(date);
        startDate = dates.get(0);
        endDate = dates.get(1);
        startDate = DateUtils.getDailyStartTime(date);
        endDate = DateUtils.getDailyEndTime(date);
        return true;
    }
}
screen-api/src/main/java/com/moral/api/service/DataDisplayService.java
New file
@@ -0,0 +1,22 @@
package com.moral.api.service;
import com.moral.api.pojo.form.dataDisplay.MonitorPointDataDisplayForm;
/**
* @Description: 数据显示服务层接口
        * @Param:
        * @return:
        * @Author: 陈凯裕
        * @Date: 2021/9/26
        */
public interface DataDisplayService {
    /**
    * @Description: 获取监测站点展示数据
            * @Param: [form]
            * @return: void
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    void getMonitorPointDisplayData(MonitorPointDataDisplayForm form);
}
screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java
@@ -1,5 +1,7 @@
package com.moral.api.service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.moral.api.entity.HistoryDaily;
@@ -18,4 +20,31 @@
    //获取某设备某因子月均值
    Map<String, Object> getMonthAvg(Map<String, Object> params);
    /**
    * @Description: 查询某一设备某日的数据
            * @Param: [mac, date]
            * @return: com.moral.api.entity.HistoryDaily
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    HistoryDaily getHistoryDailyByMacAndDate(String mac,Date date);
    /**
    * @Description: 根据多个mac和指定日期查询日数据,key为mac,value为数据
            * @Param: [mac, date]
            * @return: java.util.Map<java.lang.String,com.moral.api.entity.HistoryDaily>
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    Map<String,HistoryDaily> getHistoryDailyByMacsAndDate(List<String> mac, Date date);
    /**
    * @Description: 根据一个mac查询时间段内的数据
            * @Param: [mac, startDate, endDate]
            * @return: java.util.Map<java.lang.String,com.moral.api.entity.HistoryDaily>
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    List<HistoryDaily> getHistoryDailyByMacAndTimeSlot( String mac, Date startDate,Date endDate);
}
screen-api/src/main/java/com/moral/api/service/MonitorPointService.java
@@ -25,6 +25,13 @@
            */
    List<MonitorPoint> queryByOrgIdAndRegionCode(MonitorPointQueryForm form);
    /**
    * @Description: 根据组织id,查询所有的站点
            * @Param: [organizationId]
            * @return: java.util.List<com.moral.api.entity.MonitorPoint>
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    List<MonitorPoint> queryAllMonitorPoints(Integer organizationId);
screen-api/src/main/java/com/moral/api/service/OrganizationService.java
@@ -24,4 +24,13 @@
            */
    List<Organization> getChildrenOrganizationsById(Integer id);
    /**
    * @Description: 根据id获取组织
            * @Param: [id]
            * @return: com.moral.api.entity.Organization
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    Organization getOrganizationById(Integer id);
}
screen-api/src/main/java/com/moral/api/service/impl/DataDisplayServiceImpl.java
New file
@@ -0,0 +1,173 @@
package com.moral.api.service.impl;
import com.alibaba.fastjson.JSON;
import com.moral.api.entity.Device;
import com.moral.api.entity.HistoryDaily;
import com.moral.api.pojo.dto.dataDisplay.MonitorPointDataDisplayDTO;
import com.moral.api.pojo.form.dataDisplay.MonitorPointDataDisplayForm;
import com.moral.api.service.DataDisplayService;
import com.moral.api.service.DeviceService;
import com.moral.api.service.HistoryDailyService;
import com.moral.api.service.OrganizationService;
import com.moral.util.AQIUtils;
import com.moral.util.AmendUtils;
import com.moral.util.DateUtils;
import com.moral.util.MathUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
/**
 * @ClassName DataDisplayServiceImpl
 * @Description TODO
 * @Author 陈凯裕
 * @Date 2021/9/26 9:55
 * @Version TODO
 **/
public class DataDisplayServiceImpl implements DataDisplayService {
    @Autowired
    DeviceService deviceService;
    @Autowired
    HistoryDailyService historyDailyService;
    @Autowired
    OrganizationService organizationService;
    @Override
    public void getMonitorPointDisplayData(MonitorPointDataDisplayForm form) {
        //取参
        Integer monitorPointId = form.getMonitorPointId();
        String reportType = form.getReportType();
        Date startTime = form.getStartTime();
        Date endTime = form.getEndTime();
        //根据站点id获取站点下所有的设备
        List<Device> devices = deviceService.getDevicesByMonitorPointId(monitorPointId);
        Map<String, Device> deviceMap = new HashMap<>();
        List<String> macs = new ArrayList<>();
        devices.forEach(value -> {
            macs.add(value.getMac());
            deviceMap.put(value.getMac(), value);
        });
        //如果报表类型是null,则为自定义。用开始结束时间查询日表
        if (reportType == null) {
            Map<String, List<HistoryDaily>> macDataMap = new HashMap<>();//key为mac
            macs.forEach(value -> {
                List<HistoryDaily> datas = historyDailyService.getHistoryDailyByMacAndTimeSlot(value, startTime, endTime);
                macDataMap.put(value, datas);
            });
        }
    }
    /**
     * @Description: 计算自定义报表的数据
     * @Param: [macDatasMap] key为mac,value为数据集合,数据为日数据
     * @return: void
     * @Author: 陈凯裕
     * @Date: 2021/9/26
     */
    private void calculateCustomData(Map<String, List<HistoryDaily>> macDataMap, Map<String, Device> deviceMap, Date startDate, Date endDate) {
        List<MonitorPointDataDisplayDTO> dtos = new ArrayList<>();
        macDataMap.forEach((key, value) -> {
            MonitorPointDataDisplayDTO dto = new MonitorPointDataDisplayDTO();
            //获取设备名称
            String deviceName = deviceMap.get(key).getName();
            //获取组织名称
            organizationService.getOrganizationById(deviceMap.get(key).getOrganizationId());
            //拼接时间
            String startTime = DateUtils.dateToDateString(startDate, "yyyy-MM-dd");
            String endTime = DateUtils.dateToDateString(endDate, "yyyy-MM-dd");
            String time = startTime + " - " + endTime;
            //计算数据个数
            Double AQINum = 0d;
            Double PM25Num = 0d;
            Double PM10Num = 0d;
            Double SO2Num = 0d;
            Double NO2Num = 0d;
            Double CONum = 0d;
            Double O3Num = 0d;
            Double TVOCNum = 0d;
            //计算AQI,PM2.5,PM10,SO2,NO2,CO,O3,TVOC总值,
            Double AQISum = 0d;
            Double PM25Sum = 0d;
            Double PM10Sum = 0d;
            Double SO2Sum = 0d;
            Double NO2Sum = 0d;
            Double COSum = 0d;
            Double O3Sum = 0d;
            Double TVOCSum = 0d;
            for (HistoryDaily historyDaily : value) {
                //获取数据map
                Map<String, Object> valueMap = JSON.parseObject(historyDaily.getValue(), Map.class);
                Object SO2 = valueMap.get("a21026");
                Object NO2 = valueMap.get("a21004");
                Object PM10 = valueMap.get("a34002");
                Object PM25 = valueMap.get("a34004");
                Object CO = valueMap.get("a21005");
                Object O3 = valueMap.get("a05024");
                Object TVOC = valueMap.get("a99054");
                if (SO2 != null) {
                    SO2Sum = MathUtils.add(SO2Sum, Double.valueOf(SO2.toString()));
                    SO2Num++;
                }
                if (NO2 != null) {
                    NO2Sum = MathUtils.add(NO2Sum, Double.valueOf(NO2.toString()));
                    NO2Num++;
                }
                if (PM10 != null) {
                    PM10Sum = MathUtils.add(PM10Sum, Double.valueOf(PM10.toString()));
                    PM10Num++;
                }
                if (CO != null) {
                    COSum = MathUtils.add(COSum, Double.valueOf(CO.toString()));
                    CONum++;
                }
                if (PM25 != null) {
                    PM25Sum = MathUtils.add(PM25Sum, Double.valueOf(PM25.toString()));
                    PM25Num++;
                }
                if (O3 != null) {
                    O3Sum = MathUtils.add(O3Sum, Double.valueOf(O3.toString()));
                    O3Num++;
                }
                if (TVOC != null) {
                    TVOCSum = MathUtils.add(TVOCSum, Double.valueOf(TVOC.toString()));
                    TVOCNum++;
                }
                //加AQI
                int aqi = AQIUtils.hourlyAqi(valueMap);
                if (aqi != 0) {
                    AQISum += Double.valueOf(aqi);
                }
            }
            //计算aqi均值
            double AQID = AmendUtils.sciCal(AQISum / AQINum, 0);
            int AQIAvg = new Double(AQID).intValue();
            //计算PM2.5均值
            double PM25D = AmendUtils.sciCal(PM25Sum / PM25Num, 0);
            int PM25Avg = new Double(PM25D).intValue();
            //计算PM10均值
            double PM10D = AmendUtils.sciCal(PM10Sum / PM10Num,0);
            int PM10Avg = new Double(PM10D).intValue();
            //计算SO2均值
            double SO2D = AmendUtils.sciCal(SO2Sum / SO2Num,0);
            int SO2Avg = new Double(SO2D).intValue();
            //计算NO2均值
            double NO2D = AmendUtils.sciCal(NO2Sum / NO2Num,0);
            int NO2Avg = new Double(NO2D).intValue();
            //计算CO均值,保留两位小数
            double COAvg = AmendUtils.sciCal(COSum / CONum,2);
            //计算O3均值
            double O3D = AmendUtils.sciCal(O3Sum / O3Num,0);
            int O3Avg = new Double(O3D).intValue();
            //计算TVOC均值,保留两位小数
            double TVOCAvg = AmendUtils.sciCal(TVOCSum / TVOCNum,2);
        });
    }
}
screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java
@@ -1,5 +1,6 @@
package com.moral.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.moral.api.entity.HistoryDaily;
import com.moral.api.mapper.HistoryDailyMapper;
import com.moral.api.service.HistoryDailyService;
@@ -11,7 +12,9 @@
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -41,4 +44,37 @@
        result.put("avg", data.get(params.get("sensorCode")));
        return result;
    }
    @Override
    public HistoryDaily getHistoryDailyByMacAndDate(String mac, Date date) {
        QueryWrapper<HistoryDaily> wrapper = new QueryWrapper<>();
        wrapper.eq("mac",mac);
        wrapper.eq("time",date);
        List<HistoryDaily> historyDailies = historyDailyMapper.selectList(wrapper);
        return historyDailies.get(0);
    }
    @Override
    public Map<String, HistoryDaily> getHistoryDailyByMacsAndDate(List<String> mac, Date date) {
        QueryWrapper<HistoryDaily> wrapper = new QueryWrapper<>();
        wrapper.in("mac",mac);
        wrapper.eq("time",date);
        List<HistoryDaily> historyDailies = historyDailyMapper.selectList(wrapper);
        Map<String,HistoryDaily> map = new HashMap<>();
        for (HistoryDaily historyDaily : historyDailies) {
            map.put(historyDaily.getMac(),historyDaily);
        }
        return map;
    }
    @Override
    public List<HistoryDaily> getHistoryDailyByMacAndTimeSlot(String mac, Date startDate, Date endDate) {
        QueryWrapper<HistoryDaily> wrapper = new QueryWrapper<>();
        wrapper.in("mac",mac);
        wrapper.between("time",startDate,endDate);
        List<HistoryDaily> historyDailies = historyDailyMapper.selectList(wrapper);
        return historyDailies;
    }
}
screen-api/src/main/java/com/moral/api/service/impl/OrganizationServiceImpl.java
@@ -35,6 +35,11 @@
        return childrenOrganization;
    }
    @Override
    public Organization getOrganizationById(Integer id) {
        return organizationMapper.selectById(id);
    }
    /**
    * @Description: 通过父组织查询下面所有的子组织放到children中
screen-common/src/main/java/com/moral/constant/Constants.java
@@ -219,5 +219,25 @@
     * */
    public static final String SPECIAL_DEVICE_UAV = "1";
    /*
    * 时报
    * */
    public static final String HOURYLYREPORT = "0";
    /*
    * 日报
    * */
    public static final String DAILYREPORT = "1";
    /*
    * 周报
    * */
    public static final String WEEKLYREPORT = "2";
    /*
    * 月报
    * */
    public static final String MONTHLYREPORT = "3";
    
}
screen-common/src/main/java/com/moral/util/ComprehensiveIndexUtils.java
New file
@@ -0,0 +1,164 @@
package com.moral.util;
import java.util.*;
/**
 * @ClassName ComprehensiveIndexUtils
 * @Description 综合指数计算工具类
 * @Author 陈凯裕
 * @Date 2021/9/27 9:40
 * @Version TODO
 **/
public class ComprehensiveIndexUtils {
    /**
     * @Description: 获取月综合指数,参数为日数据的集合,map为每日的数据
     * @Param: [datas]
     * @return: Double
     * @Author: 陈凯裕
     * @Date: 2021/9/27
     */
    public static Double monthData(List<Map<String, Object>> datas) {
        //计算各污染物的统计量浓度值
        Map<String, Double> CValueMap = calCValue(datas);
        if (CValueMap == null)
            return null;
        Double CSO2 = CValueMap.get("CSO2");
        Double CNO2 = CValueMap.get("CNO2");
        Double CPM25 = CValueMap.get("CPM25");
        Double CPM10 = CValueMap.get("CPM10");
        Double CCO = CValueMap.get("CCO");
        Double CO3 = CValueMap.get("CO3");
        //S开头为污染物年均值二级标准(当污染物是CO时,采用日均值二级标准。当污染是O3时,采用八小时均值二级标准)
        //数据来源GB 3095-2012
        Double SSO2 = 60d;
        Double SNO2 = 40d;
        Double SPM25 = 35d;
        Double SPM10 = 70d;
        Double SCO = 4d;
        Double SO3 = 160d;
        //计算污染物单项指数
        Double ISO2 = CSO2 / SSO2;
        Double INO2 = CNO2 / SNO2;
        Double IPM25 = CPM25 / SPM25;
        Double IPM10 = CPM10 / SPM10;
        Double ICO = CCO / SCO;
        Double IO3 = CO3 / SO3;
        //计算综合指数
        Double ComprehensiveIndex = MathUtils.add(ISO2,INO2);
        ComprehensiveIndex = MathUtils.add(ComprehensiveIndex,IPM25);
        ComprehensiveIndex = MathUtils.add(ComprehensiveIndex,IPM10);
        ComprehensiveIndex = MathUtils.add(ComprehensiveIndex,ICO);
        ComprehensiveIndex = MathUtils.add(ComprehensiveIndex,IO3);
        return ComprehensiveIndex;
    }
    /**
     * @Description: 计算各因子浓度值
     * SO2 NO2 PM10 PM2.5为月均浓度,CO取日均值的第九十五百分位,O3取日最大八小时值的第九十百分位
     * @Param: [datas]
     * @return: java.util.Map<java.lang.String   ,   java.lang.Object>
     * @Author: 陈凯裕
     * @Date: 2021/9/27
     */
    private static Map<String, Double> calCValue(List<Map<String, Object>> datas) {
        //定义浓度值
        Double CSO2;//SO2统计量浓度值
        Double CNO2;//NO2统计量浓度值
        Double CPM10;//PM10统计量浓度值
        Double CPM25;//PM25统计量浓度值
        Double CCO;//CO统计量浓度值
        Double CO3;//O3统计量浓度值
        //计算SO2 NO2 PM10 PM2.5月均值
        Double SO2Sum = 0d;
        Double NO2Sum = 0d;
        Double PM10Sum = 0d;
        Double PM25Sum = 0d;
        Double SO2Num = 0d;
        Double NO2Num = 0d;
        Double PM10Num = 0d;
        Double PM25Num = 0d;
        for (Map<String, Object> data : datas) {
            Object SO2 = data.get("a21026");
            Object NO2 = data.get("a21004");
            Object PM10 = data.get("a34002");
            Object PM25 = data.get("a34004");
            if (SO2 != null) {
                SO2Num++;
                SO2Sum = MathUtils.add(SO2Sum, Double.valueOf(SO2.toString()));
            }
            if (NO2 != null) {
                NO2Num++;
                NO2Sum = MathUtils.add(NO2Sum, Double.valueOf(NO2.toString()));
            }
            if (PM10 != null) {
                PM10Num++;
                PM10Sum = MathUtils.add(PM10Sum, Double.valueOf(PM10.toString()));
            }
            if (PM25 != null) {
                PM25Num++;
                PM25Sum = MathUtils.add(PM25Sum, Double.valueOf(PM25.toString()));
            }
        }
        CSO2 = SO2Sum / SO2Num;
        CNO2 = NO2Sum / NO2Num;
        CPM10 = PM10Sum / PM10Num;
        CPM25 = PM25Sum / PM25Num;
        if (CSO2 == 0d || CNO2 == 0d || CPM10 == 0d || CPM25 == 0d)
            return null;
        /*计算CO统计量浓度值*/
        //获取CO从小到大排序的集合
        List<Double> COs = getSensorAsc(datas, "a21005");
        //取第95百分位
        if (COs.size() == 0)
            return null;
        Double COIndexd = COs.size() * 0.95;
        int COIndex = new Double(Math.ceil(COIndexd)).intValue();
        CCO = COs.get(COIndex - 1);
        /*计算O3统计量浓度*/
        //获取O3日八小时最大值从小到大排序的结婚
        List<Double> O3s = getSensorAsc(datas, "a05024");
        //取第90百分位
        if (O3s.size() == 0)
            return null;
        Double O3Indexd = O3s.size() * 0.9;
        int O3Index = new Double(Math.ceil(O3Indexd)).intValue();
        CO3 = O3s.get(O3Index - 1);
        Map<String, Double> result = new HashMap<>();
        result.put("CSO2", CSO2);
        result.put("CNO2", CNO2);
        result.put("CPM25", CPM25);
        result.put("CPM10", CPM10);
        result.put("CCO", CCO);
        result.put("CO3", CO3);
        return result;
    }
    /**
     * @Description: 获取因子的升序排序集合
     * @Param: [datas]
     * @return: java.util.List<java.lang.Double>
     * @Author: 陈凯裕
     * @Date: 2021/9/27
     */
    private static List<Double> getSensorAsc(List<Map<String, Object>> datas, String sensor) {
        List<Double> result = new ArrayList<>();
        datas.forEach(value -> {
            Object o = value.get(sensor);
            if (o != null)
                result.add(Double.valueOf(o.toString()));
        });
        Collections.sort(result, new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                return new Double(o1 - o2).intValue();
            }
        });
        return result;
    }
}
screen-common/src/main/java/com/moral/util/DateUtils.java
@@ -92,25 +92,139 @@
    /**
     * @Description: 将日期转换为当天的开始和结束时间
    * @Description: 获取指定小时的开始时间
            * @Param: [date]
            * @return: java.util.Date
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    public static Date getHourlyStartTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
        return cal.getTime();
    }
    /**
     * @Description: 获取指定小时的结束时间
     * @Param: [date]
     * @return: java.util.Date
     * @Author: 陈凯裕
     * @Date: 2021/9/26
     */
    public static Date getHourlyEndTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE,59);
        cal.set(Calendar.SECOND,59);
        return cal.getTime();
    }
    /**
     * @Description: 获取指定日期的第一个小时
     * @Param: [date]
     * @return: java.util.List<java.util.Date>
     * @Author: 陈凯裕
     * @Date: 2021/9/8
     */
    public static List<Date> dateToStartAndEndTime(Date date) {
    public static Date getDailyStartTime(Date date) {
        String dateStr = dateToDateString(date, "yyyy-MM-dd");
        String startDateStr = dateStr + " 00:00:00";
        String endDateStr = dateStr + " 23:59:59";
        Date startDate = getDate(startDateStr, "yyyy-MM-dd HH:mm:ss");
        return startDate;
    }
    /**
    * @Description: 获取指定日期的最后一个小时
            * @Param: [date]
            * @return: java.util.Date
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    public static Date getDailyEndTime(Date date) {
        String dateStr = dateToDateString(date, "yyyy-MM-dd");
        String endDateStr = dateStr + " 23:59:59";
        Date endDate = getDate(endDateStr, "yyyy-MM-dd HH:mm:ss");
        ArrayList<Date> dates = new ArrayList<>();
        dates.add(startDate);
        dates.add(endDate);
        return dates;
        return endDate;
    }
    /**
    * @Description: 获取指定日期那周的第一天第一个小时
            * @Param: [date]
            * @return: java.util.Date
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    public static Date getWeeklyStartTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (1 ==  cal.get(Calendar.DAY_OF_WEEK)) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);
        cal.set(Calendar.HOUR_OF_DAY,0);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
        return cal.getTime();
    }
    /**
    * @Description: 获取指定日期那周的最后一天最后一个小时
            * @Param: [date]
            * @return: java.util.Date
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    public static Date getWeeklyEndTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (1 !=  cal.get(Calendar.DAY_OF_WEEK)) {
            cal.add(Calendar.DAY_OF_MONTH, 7);
        }
        cal.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
        cal.set(Calendar.HOUR_OF_DAY,23);
        cal.set(Calendar.MINUTE,59);
        cal.set(Calendar.SECOND,59);
        return cal.getTime();
    }
    /**
    * @Description: 获取指定日期当月的第一天第一个小时
            * @Param: [date]
            * @return: java.util.Date
            * @Author: 陈凯裕
            * @Date: 2021/9/26
            */
    public static Date getMonthlyStartTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,0);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
        return cal.getTime();
    }
    /**
     * @Description: 获取指定日期当月的最后一天最后一个小时
     * @Param: [date]
     * @return: java.util.Date
     * @Author: 陈凯裕
     * @Date: 2021/9/26
     */
    public static Date getMonthlyEndTime(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,23);
        cal.set(Calendar.MINUTE,59);
        cal.set(Calendar.SECOND,59);
        return cal.getTime();
    }
    /**
     * @Description: Date的toString格式转为Date
     * @Param: []
@@ -482,6 +596,7 @@
        return dateToDateString(now.getTime(), formatStr);
    }
    /**
     * 获取指定日期day天后的一个(formatStr)的字符串
     *