ソースを参照

Merge remote-tracking branch 'origin/20210223' into 20210223

yuejiaying 4 年 前
コミット
9ce7574f34

+ 24 - 7
operation_manager/src/main/java/com/huaxu/order/controller/WorkOrderStatisticsController.java

@@ -58,7 +58,7 @@ public class WorkOrderStatisticsController {
             endDate = subMonth(startDate, 1);
 
             sameStartDate = subYear(startDate, -1);
-            sameEndDate = subYear(sameStartDate, 1);
+            sameEndDate = subMonth(sameStartDate, 1);
 
             chainStartDate = subMonth(startDate, -1);
             chainEndDate = subMonth(chainStartDate, 1);
@@ -74,6 +74,7 @@ public class WorkOrderStatisticsController {
         } else if (statsType == 2) {
             startDate = String.format("%s-01", startDate);
             endDate = String.format("%s-01", endDate);
+            endDate = subMonth(endDate,1);
         }
         //根据用户编号,获取用户的权限
         LoginUser loginUser = UserUtil.getCurrentUser();
@@ -96,42 +97,54 @@ public class WorkOrderStatisticsController {
         workOrderManageDto.setEndDate(sameEndDate);
         //同比
         Map<String, Object> sameStatistic = workOrderManageService.workOrderStatistics(workOrderManageDto);
+        if(!sameStatistic.containsKey("工单完成数")){
+            sameStatistic.put("工单完成数",0);
+        }
+        if(!sameStatistic.containsKey("工单完成率")){
+            sameStatistic.put("工单完成率",0);
+        }
         //环比
         workOrderManageDto.setStartDate(chainStartDate);
         workOrderManageDto.setEndDate(chainEndDate);
         Map<String, Object> chainStatistic = workOrderManageService.workOrderStatistics(workOrderManageDto);
+        if(!chainStatistic.containsKey("工单完成数")){
+            chainStatistic.put("工单完成数",0);
+        }
+        if(!chainStatistic.containsKey("工单完成率")){
+            chainStatistic.put("工单完成率",0);
+        }
 
         DecimalFormat df = new DecimalFormat("#0.00");
 
         if (sameStatistic.get("工单完成率") == null || sameStatistic.get("工单完成率").toString().equals("0")) {
-            statistics.put("工单完成率同比", 0);
+            statistics.put("工单完成率同比", "-");
         } else {
             Double finishedSameRate = (Double.parseDouble(statistics.get("工单完成率").toString()) - Double.parseDouble(sameStatistic.get("工单完成率").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单完成率").toString());
             statistics.put("工单完成率同比", df.format(finishedSameRate));
         }
 
         if (chainStatistic.get("工单完成率") == null || chainStatistic.get("工单完成率").toString().equals("0")) {
-            statistics.put("工单完成率环比", 0);
+            statistics.put("工单完成率环比", "-");
         } else {
             Double finishedChainRate = (Double.parseDouble(statistics.get("工单完成率").toString()) - Double.parseDouble(chainStatistic.get("工单完成率").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单完成率").toString());
             statistics.put("工单完成率环比", df.format(finishedChainRate));
         }
         
         if (sameStatistic.get("工单总数") == null || sameStatistic.get("工单总数").toString().equals("0")) {
-            statistics.put("工单总数同比", 0);
+            statistics.put("工单总数同比", "-");
         } else {
             Double orderSameTotalNumberRate = (Double.parseDouble(statistics.get("工单总数").toString()) - Double.parseDouble(sameStatistic.get("工单总数").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单总数").toString());
             statistics.put("工单总数同比", df.format(orderSameTotalNumberRate));
         }
         if (chainStatistic.get("工单总数") == null || chainStatistic.get("工单总数").toString().equals("0")) {
-            statistics.put("工单总数环比", 0);
+            statistics.put("工单总数环比", "-");
         } else {
             Double orderChainTotalNumberRate = (Double.parseDouble(statistics.get("工单总数").toString()) - Double.parseDouble(chainStatistic.get("工单总数").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单总数").toString());
             statistics.put("工单总数环比", df.format(orderChainTotalNumberRate));
         }
 
         if (sameStatistic.get("工单完成数") == null || sameStatistic.get("工单完成数").toString().equals("0")) {
-            statistics.put("工单完成数同比", 0);
+            statistics.put("工单完成数同比", "-");
 
         } else {
             Double finishedSameNumber = (Double.parseDouble(statistics.get("工单完成数").toString()) - Double.parseDouble(sameStatistic.get("工单完成数").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单完成数").toString());
@@ -139,7 +152,7 @@ public class WorkOrderStatisticsController {
         }
 
         if (chainStatistic.get("工单完成数") == null || chainStatistic.get("工单完成数").toString().equals("0")) {
-            statistics.put("工单完成数环比", 0);
+            statistics.put("工单完成数环比", "-");
         } else {
             Double finishedChainNumber = (Double.parseDouble(statistics.get("工单完成数").toString()) - Double.parseDouble(chainStatistic.get("工单完成数").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单完成数").toString());
             statistics.put("工单完成数环比", df.format(finishedChainNumber));
@@ -180,6 +193,7 @@ public class WorkOrderStatisticsController {
                 maintainerCount = userCenterClient.findMaintainerCount(endDate);
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 break;
         }
         workOrderManageDto.setStartDate(startDate);
@@ -235,6 +249,7 @@ public class WorkOrderStatisticsController {
             case 2:
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 break;
         }
         workOrderManageDto.setStartDate(startDate);
@@ -268,6 +283,7 @@ public class WorkOrderStatisticsController {
             case 2:
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 break;
         }
         workOrderManageDto.setStartDate(startDate);
@@ -315,6 +331,7 @@ public class WorkOrderStatisticsController {
         } else if (statsType == 2) {
             startDate = String.format("%s-01", startDate);
             endDate = String.format("%s-01", endDate);
+            endDate = subMonth(endDate,1);
         }
         workOrderManageDto.setStartDate(startDate);
         workOrderManageDto.setEndDate(endDate);

+ 3 - 2
operation_manager/src/main/java/com/huaxu/order/service/WorkOrderManageService.java

@@ -9,6 +9,7 @@ import com.huaxu.order.dto.WorkOrderManageDto;
 import com.huaxu.order.entity.WorkOrderManage;
 import org.apache.ibatis.annotations.Param;
 
+import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
 
@@ -92,7 +93,7 @@ public interface WorkOrderManageService {
     Map<String,Object> workOrderStatistics(@Param("order") WorkOrderManageDto workOrderManageDto);
 
 
-    List<Map<String,Object>> eventMonthStatistics(@Param("order") WorkOrderManageDto workOrderManageDto);
+    List<Map<String,Object>> eventMonthStatistics(@Param("order") WorkOrderManageDto workOrderManageDto) throws ParseException;
 
     List<Map<String,Object>> eventYearStatistics(@Param("order") WorkOrderManageDto workOrderManageDto);
     /**
@@ -133,7 +134,7 @@ public interface WorkOrderManageService {
     /**
      * 判单次数月统计
      */
-    List<Map<String,Object>> dispatchTimesMonthStatistics(@Param("order") WorkOrderManageDto workOrderManageDto,@Param("idList") List<Integer> idList);
+    List<Map<String,Object>> dispatchTimesMonthStatistics(@Param("order") WorkOrderManageDto workOrderManageDto,@Param("idList") List<Integer> idList) throws ParseException;
 
     /**
      * 判单次数年统计

+ 27 - 23
operation_manager/src/main/java/com/huaxu/order/service/impl/WorkOrderManageServiceImpl.java

@@ -10,10 +10,11 @@ import com.huaxu.order.dto.WorkOrderManageDto;
 import com.huaxu.order.entity.WorkOrderManage;
 import com.huaxu.order.service.WorkOrderManageService;
 import com.huaxu.util.UserUtil;
-import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 
@@ -160,13 +161,12 @@ public class WorkOrderManageServiceImpl implements WorkOrderManageService {
     }
 
     @Override
-    public List<Map<String, Object>> eventMonthStatistics(WorkOrderManageDto workOrderManageDto) {
-        String strMonth = workOrderManageDto.getStartDate().substring(5,7);
-        int days = getDaysByYearMonth(Integer.parseInt(strMonth));
+    public List<Map<String, Object>> eventMonthStatistics(WorkOrderManageDto workOrderManageDto) throws ParseException {
+        int days = differentDaysByMillisecond(workOrderManageDto.getStartDate(),workOrderManageDto.getEndDate());
         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
         List<Map<String,Object>> list = workOrderManageMapper.eventMonthStatistics(workOrderManageDto);
         for(int i=0; i<days; i++) {
-            String strDate = workOrderManageDto.getStartDate().substring(0, 7) + String.format("-%02d", i + 1);
+            String strDate =  subDay(workOrderManageDto.getStartDate(),i);
             Map<String, Object> data = new HashMap<>();
             data.put("数量", 0);
             data.put("日期", strDate);
@@ -252,13 +252,12 @@ public class WorkOrderManageServiceImpl implements WorkOrderManageService {
     }
 
     @Override
-    public List<Map<String, Object>> dispatchTimesMonthStatistics(WorkOrderManageDto workOrderManageDto,List<Integer> idList) {
-        String strMonth = workOrderManageDto.getStartDate().substring(5,7);
-        int days = getDaysByYearMonth(Integer.parseInt(strMonth));
+    public List<Map<String, Object>> dispatchTimesMonthStatistics(WorkOrderManageDto workOrderManageDto,List<Integer> idList) throws ParseException {
+        int days = differentDaysByMillisecond(workOrderManageDto.getStartDate(),workOrderManageDto.getEndDate());
         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
         List<Map<String,Object>> list = workOrderManageMapper.dispatchTimesMonthStatistics(workOrderManageDto,idList);
         for(int i=0; i<days; i++) {
-            String strDate = workOrderManageDto.getStartDate().substring(0, 7) + String.format("-%02d", i + 1);
+            String strDate =  subDay(workOrderManageDto.getStartDate(),i);
             Map<String, Object> data = new HashMap<>();
             data.put("数量", 0);
             data.put("日期", strDate);
@@ -304,22 +303,27 @@ public class WorkOrderManageServiceImpl implements WorkOrderManageService {
         return workOrderManageMapper.findWorkFlowById(id);
     }
 
-    /**
-     *获取某月有多少天
-     */
-    private int getDaysByYearMonth(int month) {
-
-        Calendar a =Calendar.getInstance();
-
-        a.set(Calendar.MONTH, month- 1);
-
-        a.set(Calendar.DATE, 1);
 
-        a.roll(Calendar.DATE,-1);
-
-        int maxDate =a.get(Calendar.DATE);
+    public int differentDaysByMillisecond(String date1,String date2) throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date dt1 = sdf.parse(date1);
+        Date dt2 = sdf.parse(date2);
+        int days = (int) ((dt2.getTime() - dt1.getTime()) / (1000*3600*24));
+        return days;
+    }
 
-        return maxDate;
 
+    /**
+     *日期加一天
+     */
+    private String subDay(String date, int n) throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date dt = sdf.parse(date);
+        Calendar rightNow = Calendar.getInstance();
+        rightNow.setTime(dt);
+        rightNow.add(Calendar.DATE, n);
+        Date dt1 = rightNow.getTime();
+        String reStr = sdf.format(dt1);
+        return reStr;
     }
 }

+ 4 - 2
operation_manager/src/main/java/com/huaxu/utils/EvaluationUtil.java

@@ -36,10 +36,11 @@ public class EvaluationUtil {
     }
 
     public static BigDecimal divide(Integer completeCount, Integer total){
+        String defaultValue = "0";
         BigDecimal bigDecimalComplete =  new BigDecimal(completeCount.toString());
         BigDecimal bigDecimalTotal =  new BigDecimal(total.toString());
-        if (bigDecimalTotal.compareTo(new BigDecimal("0")) == 0){
-            return new BigDecimal("0");
+        if (bigDecimalTotal.compareTo(new BigDecimal(defaultValue)) == 0){
+            return new BigDecimal(defaultValue);
         }
         return bigDecimalComplete.divide(bigDecimalTotal,2, RoundingMode.HALF_UP);
     }
@@ -164,6 +165,7 @@ public class EvaluationUtil {
                 return 2;
             case 10 :
                 return 3;
+            default: ;
         }
         return null;
     }

+ 10 - 1
sms_water/src/main/java/com/huaxu/controller/SceneController.java

@@ -225,6 +225,9 @@ public class SceneController {
             @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
             @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
             @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
+
+        LocalDate localDate = LocalDate.now();
+
         LoginUser loginUser = UserUtil.getCurrentUser();
         SceneEntity sceneEntity = new SceneEntity();
         sceneEntity.setTenantId(loginUser.getTenantId());
@@ -238,6 +241,10 @@ public class SceneController {
                 startDate = String.format("%s-01", startDate);
                 endDate = subMonth(startDate, 1);
                 days =getDaysOfMonth(startDate);
+                if(localDate.getYear() == Integer.parseInt(startDate.substring(0,4))&&
+                localDate.getMonthValue() == Integer.parseInt(startDate.substring(5,7))){
+                    days = localDate.getDayOfMonth();
+                }
                 break;
             case 1:
                 days =LocalDate.of(Integer.parseInt(startDate),1,1).lengthOfYear();
@@ -247,6 +254,7 @@ public class SceneController {
             case 2:
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 days = differentDaysByMillisecond(startDate,endDate);
                 break;
         }
@@ -302,7 +310,6 @@ public class SceneController {
             @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
             @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
             @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
-        LoginUser loginUser = UserUtil.getCurrentUser();
         SceneEntity sceneEntity = new SceneEntity();
         sceneEntity.setId(Long.parseLong(String.valueOf(id)));
         switch (statsType) {
@@ -317,6 +324,7 @@ public class SceneController {
             case 2:
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 break;
         }
         List<Map<String,Object>> list = new ArrayList<>();
@@ -363,6 +371,7 @@ public class SceneController {
             case 2:
                 startDate = String.format("%s-01", startDate);
                 endDate = String.format("%s-01", endDate);
+                endDate = subMonth(endDate,1);
                 break;
         }
         List<Map<String,Object>> list = sceneService.selectAlarmLable(sceneEntity,startDate,endDate,sort);

+ 2 - 0
sms_water/src/main/java/com/huaxu/dao/SceneMapper.java

@@ -48,6 +48,8 @@ public interface SceneMapper extends BaseMapper<SceneEntity> {
 
     List<Map<String,Object>> selectMonthAlarmTimes(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("sort") int sort);
 
+    List<Map<String,Object>> selectYearAlarmTimes(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("sort") int sort);
+
     List<Map<String,Object>> selectAlarmDeviceIdBySenceId(@Param("id") int id);
 
     List<Map<String,Object>> selectAlarmLable(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("sort") int sort);

+ 111 - 0
sms_water/src/main/java/com/huaxu/quartz/service/MonitorReportJobService.java

@@ -0,0 +1,111 @@
+package com.huaxu.quartz.service;
+
+import com.huaxu.dao.MonitorDataMapper;
+import com.huaxu.entity.DayReportEntity;
+import com.huaxu.service.MonitorDataService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 报表业务处理
+ * @author lihui
+ * @version V1.0
+ * @date 2021/5/18
+ **/
+@Component
+@Slf4j
+public class MonitorReportJobService {
+
+    @Resource
+    private MonitorDataService monitorDataService;
+
+    @Resource
+    private MonitorDataMapper monitorDataMapper;
+
+    /***
+     * 数据补充
+     * @Author lihui
+     * @Date 9:55 2021/5/18
+     * @param dateTime :   时间
+     * @param lastHourDataMap : 上一个小时的数据
+     * @return void
+     **/
+    public void replenishHistoryData(LocalDateTime dateTime, Map<String,DayReportEntity> lastHourDataMap){
+        List<Integer> deviceIds = null;
+        List<DayReportEntity> hourData = null;
+        List<DayReportEntity> lastHourData = null;
+        int total = 1;
+        // 最多向前补一个月的数据
+        int maxHour = 24 * 30;
+        while (true) {
+            if (total >= maxHour) {
+                break;
+            }
+            dateTime = dateTime.plusHours(-1);
+            // 设备id
+            deviceIds = lastHourDataMap.values().stream().map(d -> d.getDeviceId().intValue()).distinct().collect(Collectors.toList());
+            if (deviceIds.size() ==0) {
+                break;
+            }
+            // 前1小时有统计数据的设备id
+            List<Integer> deviceIdsIsExit = monitorDataMapper.checkReportDataExit(dateTime.getYear(),dateTime.getMonthValue(),dateTime.getDayOfMonth(),
+                    dateTime.getHour(),deviceIds);
+            // 需要补充数据的设备
+            deviceIds = deviceIds.stream().filter(deviceId -> !deviceIdsIsExit.contains(deviceId)).collect(Collectors.toList());
+            if (deviceIds.size() == 0) {
+                break;
+            }
+            // 查询需要补充数据的设备数据信息
+            hourData = lastHourDataMap.values().stream().filter(d -> !deviceIdsIsExit.contains(d.getDeviceId().intValue())).collect(Collectors.toList());
+            lastHourData   = monitorDataService.getMonitorDataGroupByHour(dateTime.plusHours(-1), deviceIds);
+            lastHourDataMap = lastHourData.stream().collect(Collectors.toMap(DayReportEntity::getMapkey, a -> a, (k1, k2) -> k1));
+            // 保存日报表数据
+            saveReportDataByHour(hourData, lastHourDataMap);
+            total++;
+        }
+
+    }
+
+    /***
+     * 数据保存
+     * @Author lihui
+     * @Date 9:55 2021/5/18
+     * @param hourData :
+     * @param lastHourDataMap :
+     * @return void
+     **/
+    public void saveReportDataByHour(List<DayReportEntity> hourData, Map<String, DayReportEntity> lastHourDataMap) {
+        if (hourData.size() == 0) {
+            return;
+        }
+        // 计算累计值
+        for (DayReportEntity dayReportEntity : hourData) {
+            if (dayReportEntity.getLatestValue() != null && lastHourDataMap.containsKey(dayReportEntity.getMapkey())) {
+                // 上一个小时有值
+                if (lastHourDataMap.get(dayReportEntity.getMapkey()).getLatestValue() != null) {
+                    dayReportEntity.setSumValue(new BigDecimal(dayReportEntity.getLatestValue().toString()).subtract(new BigDecimal(lastHourDataMap.get(dayReportEntity.getMapkey()).getLatestValue().toString())).doubleValue());
+                } else {
+                    // 上一个小时没有值,取本小时的初始值
+                    if (dayReportEntity.getFirstValue() != null) {
+                        dayReportEntity.setSumValue(new BigDecimal(dayReportEntity.getLatestValue().toString()).subtract(new BigDecimal(dayReportEntity.getFirstValue().toString())).doubleValue());
+                    }
+                    lastHourDataMap.remove(dayReportEntity.getMapkey());
+                }
+            }
+            // 对平均值小数位处理
+            dayReportEntity.setAvgValue(new BigDecimal(dayReportEntity.getAvgValue()).setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue());
+        }
+        monitorDataMapper.batchInsertDayReport(hourData);
+    }
+
+
+}

+ 2 - 5
sms_water/src/main/java/com/huaxu/rabbitmq/ReceiveClearData.java

@@ -76,9 +76,10 @@ public class ReceiveClearData {
     }
 
     public void receivedDataHandle(byte[] receivedData){
-        long begin = System.currentTimeMillis();
         JSONObject jsonObject = JSONObject.parseObject(new String(receivedData));
         String eventTime      = jsonObject.getString("eventTime");
+        String deviceCode     = jsonObject.getString("unitIdentifier");
+        log.info("【数据采集】deviceCode : {},时间: {}", deviceCode ,eventTime);
         // 对象有时间、有设备编码、有数据则解析,任何一个位空直接退出
         if (!jsonObject.containsKey("eventTime") || !jsonObject.containsKey("unitIdentifier") ||
                 !jsonObject.containsKey("parsedData")) {
@@ -89,8 +90,6 @@ public class ReceiveClearData {
             log.error("报警信息查询时间转换错误,原数据:eventTime:{}", eventTime);
             return;
         }
-
-        String deviceCode      = jsonObject.getString("unitIdentifier");
         JSONObject receiveData = JSONObject.parseObject(jsonObject .getString("parsedData"));
         if (StringUtils.isBlank(deviceCode)) {
             log.error("deviceCode为空退出。");
@@ -131,8 +130,6 @@ public class ReceiveClearData {
         reportWaterPumpStateHandler.handler(monitorDataEntity, receiveData, receiveDateTime);
         // 异步处理报警信息
         alarmDataHandler.hanlder(monitorDataEntity, receiveData, receiveDateTime);
-        long end = System.currentTimeMillis();
-        log.info("rabbitmq队列消息处理完成,耗时:" + (end-begin) + "毫秒");
     }
 
 

+ 24 - 20
sms_water/src/main/java/com/huaxu/service/SceneService.java

@@ -31,6 +31,8 @@ import javax.annotation.Resource;
 
 import org.springframework.transaction.annotation.Transactional;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -459,13 +461,12 @@ public class SceneService extends ServiceImpl<SceneMapper, SceneEntity> {
         return sceneMapper.selectAlarmSceneAndDevice(sceneEntity, startDate, endDate);
     }
 
-    public List<Map<String,Object>> selectMonthAlarmTimes(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate,@Param("sort") int sort){
-        String strMonth = startDate.substring(5,7);
-        int days = getDaysByYearMonth(Integer.parseInt(strMonth));
+    public List<Map<String,Object>> selectMonthAlarmTimes(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate,@Param("sort") int sort) throws ParseException {
+        int days = differentDaysByMillisecond(startDate,endDate);
         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
         List<Map<String,Object>> list = sceneMapper.selectMonthAlarmTimes(sceneEntity,startDate,endDate,sort);
         for(int i=0; i<days; i++) {
-            String strDate = startDate.substring(0, 7) + String.format("-%02d", i + 1);
+            String strDate =  subDay(startDate,i);
             Map<String, Object> data = new HashMap<>();
             data.put("数量", 0);
             data.put("日期", strDate);
@@ -481,7 +482,7 @@ public class SceneService extends ServiceImpl<SceneMapper, SceneEntity> {
     }
 
     public List<Map<String,Object>> selectYearAlarmTimes(@Param("scene") SceneEntity sceneEntity, @Param("startDate") String startDate, @Param("endDate") String endDate,@Param("sort") int sort){
-        List<Map<String,Object>> list = sceneMapper.selectMonthAlarmTimes(sceneEntity,startDate,endDate,sort);
+        List<Map<String,Object>> list = sceneMapper.selectYearAlarmTimes(sceneEntity,startDate,endDate,sort);
         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
         for(int i=0; i<12; i++) {
             String strDate = startDate.substring(0, 4) + String.format("-%02d", i + 1);
@@ -507,23 +508,26 @@ public class SceneService extends ServiceImpl<SceneMapper, SceneEntity> {
         return sceneMapper.selectAlarmDeviceIdBySenceId(id);
     }
 
+    public int differentDaysByMillisecond(String date1,String date2) throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date dt1 = sdf.parse(date1);
+        Date dt2 = sdf.parse(date2);
+        int days = (int) ((dt2.getTime() - dt1.getTime()) / (1000*3600*24));
+        return days;
+    }
+
     /**
-     *获取某月有多少天
+     *日期加一
      */
-    private int getDaysByYearMonth(int month) {
-
-        Calendar a =Calendar.getInstance();
-
-        a.set(Calendar.MONTH, month- 1);
-
-        a.set(Calendar.DATE, 1);
-
-        a.roll(Calendar.DATE,-1);
-
-        int maxDate =a.get(Calendar.DATE);
-
-        return maxDate;
-
+    private String subDay(String date, int n) throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date dt = sdf.parse(date);
+        Calendar rightNow = Calendar.getInstance();
+        rightNow.setTime(dt);
+        rightNow.add(Calendar.DATE, n);
+        Date dt1 = rightNow.getTime();
+        String reStr = sdf.format(dt1);
+        return reStr;
     }
 
 

+ 41 - 84
sms_water/src/main/java/com/huaxu/service/impl/MonitorDataServiceImpl.java

@@ -8,12 +8,11 @@ import com.huaxu.quartz.job.MonitorDataReportByDayJob;
 import com.huaxu.quartz.job.MonitorDataReportByMonthJob;
 import com.huaxu.quartz.job.MonitorDataReportByYearJob;
 import com.huaxu.quartz.service.JobAndTriggerService;
+import com.huaxu.quartz.service.MonitorReportJobService;
 import com.huaxu.service.MonitorDataService;
 import com.huaxu.util.ByteArrayUtils;
 import com.huaxu.util.RedisUtil;
-import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
@@ -27,17 +26,13 @@ import org.springframework.data.mongodb.core.query.Update;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.math.BigDecimal;
-import java.time.Duration;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
  * @description
- * @auto wangli
+ * @author  wangli
  * @data 2020-12-01 11:09
  */
 @Service
@@ -56,7 +51,9 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
     @Autowired
     private JobAndTriggerService jobAndTriggerService;
 
-    //避免同时执行先后顺序造成取数据不准确,时间隔开执行
+    @Autowired
+    private MonitorReportJobService monitorReportJobServcie;
+
     @Override
     public void afterPropertiesSet() {
         saveQrtzTask("0 0 */1 * * ? ","日报生成任务","smsWaterMonitorDataReportByDayJob",MonitorDataReportByDayJob.class.getName());
@@ -64,9 +61,17 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
         saveQrtzTask("0 10 0 1 * ? ","年报生成任务","smsWaterMonitorDataReportByYearJob", MonitorDataReportByYearJob.class.getName());
     }
 
-    public void saveQrtzTask(String cron, String jobGroup ,String jobName,String JobClassName) {
-        // 1,查询需要批量推送的配置项目并构建定时任务
-        // 2,若对应定时任务不存在则创建
+    /***
+     * 1,查询需要批量推送的配置项目并构建定时任务
+     * 2,若对应定时任务不存在则创建
+     * @Author wangli
+     * @param cron :
+     * @param jobGroup :
+     * @param jobName :
+     * @param jobClassName :
+     * @return void
+     **/
+    public void saveQrtzTask(String cron, String jobGroup ,String jobName,String jobClassName) {
         QuartzEntity entity = new QuartzEntity();
         entity.setJobGroup(jobGroup);
         entity.setJobName(jobName);
@@ -74,23 +79,24 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
         boolean exists = jobAndTriggerService.isExists(entity);
         if(!exists){
             entity.setCronExpression(cron);
-            entity.setJobClassName(JobClassName);
+            entity.setJobClassName(jobClassName);
             jobAndTriggerService.save(entity);
         }
     }
 
     @Override
     public MonitorDataEntity save(MonitorDataEntity monitorDataEntity) {
-        //缓存数据
+        // 缓存数据
         redisUtil.setExpire(("sms_water_"+monitorDataEntity.getDeviceCode()).getBytes(), ByteArrayUtils.objectToBytes(monitorDataEntity).get());
-        //把没有数据的属性去掉再保存
+        // 把没有数据的属性去掉再保存
         monitorDataEntity.setDataValues(monitorDataEntity.getDataValues().stream().filter(m -> m.getDataValue()!=null).collect(Collectors.toList()));
 
         return mongoTemplate.save(monitorDataEntity);
     }
 
+    @Override
     public MonitorDataEntity getDeviceMonitorInfoByDeviceCode(String deviceCode){
-        //先取缓存里的数据
+        // 先取缓存里的数据
         byte[] bytes = redisUtil.get(("sms_water_"+deviceCode).getBytes());
         if(bytes != null && bytes.length>0){
             return (MonitorDataEntity)ByteArrayUtils.bytesToObject(bytes).get();
@@ -106,11 +112,8 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
     @Override
     public void update(MonitorDataEntity monitorDataEntity) {
         Query query = new Query(Criteria.where("id").is(monitorDataEntity.getId()));
-
         Update update = new Update();
         update.set("deviceName", monitorDataEntity.getDeviceName());
-
-
         mongoTemplate.updateFirst(query, update, MonitorDataEntity.class);
     }
 
@@ -123,8 +126,7 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
 
     @Override
     public List<DayReportEntity> getMonitorDataGroupByHour(LocalDateTime dateTime ,List<Integer> deviceIds ){
-
-        if(dateTime == null ){
+        if (dateTime == null ){
             return null;
         }
         Criteria criteria = new Criteria();
@@ -137,9 +139,12 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
         }
         AggregationOptions aggregationOptions = AggregationOptions.builder().allowDiskUse(true).build();
         Aggregation agg = Aggregation.newAggregation(
-                Aggregation.match(criteria),    //查询条件
-                Aggregation.unwind("dataValues"),//将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
-                Aggregation.sort(Sort.Direction.ASC, "collectDate"),//在聚合之前对数据进行排序
+                // 查询条件
+                Aggregation.match(criteria),
+                // 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
+                Aggregation.unwind("dataValues"),
+                // 在聚合之前对数据进行排序
+                Aggregation.sort(Sort.Direction.ASC, "collectDate"),
                 Aggregation.group("year","month","day","hour","tenantId","deviceId","deviceName","deviceCode","dataValues.attributeId","dataValues.attributeName" )
                         .min("$dataValues.dataValue").as("minValue")
                         .max("$dataValues.dataValue").as("maxValue")
@@ -152,75 +157,25 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
         ).withOptions(aggregationOptions);
         AggregationResults<DayReportEntity> durationData =
                 mongoTemplate.aggregate(agg, "SMS_MONITOR_DATA", DayReportEntity.class);
-        //获取查询结果
-        List<DayReportEntity> monthReportEntities = durationData.getMappedResults();
-        return monthReportEntities;
+        return durationData.getMappedResults();
     }
 
     @Override
     public void getMonitorDataReportByHour(){
-    /*    LocalDateTime dateTime =
-                LocalDateTime.parse("2021-04-19 14:59:58", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-*/
-        //取前一个小时的时间
+        // 取前一个小时的时间
         LocalDateTime dateTime = LocalDateTime.now().plusHours(-1);
-
         // 取前一个小时的时间(取19点) sumValue  -> 1-10,2-20
-        List<DayReportEntity> hourDatas = getMonitorDataGroupByHour(dateTime,null);
+        List<DayReportEntity> hourData     = getMonitorDataGroupByHour(dateTime,null);
         // 取前一个小时的时间(取18点)
-        List<DayReportEntity> lastHourDatas = getMonitorDataGroupByHour(dateTime.plusHours(-1),null);
-
-        Map<String,DayReportEntity> lastHourDataMap = lastHourDatas.stream().collect(Collectors.toMap(DayReportEntity::getMapkey, a -> a,(k1, k2)->k1));
-        //保存日报表数据
-        saveReportDataByHour(hourDatas, lastHourDataMap);
-
-        //补数据,前24小时没有统计数据的
-        List<Integer> deviceIds ;
-        if(lastHourDataMap.values().size()>0){
-            for(int i=1;i<24;i++){
-                dateTime = dateTime.plusHours(-1);
-                //设备id
-                deviceIds = lastHourDataMap.values().stream().map(d -> d.getDeviceId().intValue()).distinct().collect(Collectors.toList());
-                if(deviceIds.size() ==0){break;}
-
-                //前1小时有统计数据的设备id
-                List<Integer> deviceIdsIsExit = monitorDataMapper.checkReportDataExit(dateTime.getYear(),dateTime.getMonthValue(),dateTime.getDayOfMonth(),dateTime.getHour(),deviceIds);
-                //需要补充数据的设备
-                deviceIds = deviceIds.stream().filter(deviceId -> !deviceIdsIsExit.contains(deviceId)).collect(Collectors.toList());
-                if(deviceIds.size() ==0){break;}
-
-                //查询需要补充数据的设备数据信息
-                hourDatas = lastHourDataMap.values().stream().filter(d -> !deviceIdsIsExit.contains(d.getDeviceId().intValue())).collect(Collectors.toList());
-
-                lastHourDatas = getMonitorDataGroupByHour(dateTime.plusHours(-1), deviceIds);
-                lastHourDataMap = lastHourDatas.stream().collect(Collectors.toMap(DayReportEntity::getMapkey, a -> a, (k1, k2) -> k1));
-                //保存日报表数据
-                saveReportDataByHour(hourDatas, lastHourDataMap);
-            }
-        }
-
-    }
-    //保存日报表数据
-    private void saveReportDataByHour(List<DayReportEntity> hourDatas, Map<String, DayReportEntity> lastHourDataMap) {
-        if (hourDatas.size() > 0) {
-            //计算累计值
-            for (DayReportEntity dayReportEntity : hourDatas) {
-                if (dayReportEntity.getLatestValue() != null && lastHourDataMap.containsKey(dayReportEntity.getMapkey())) {
-                    //上一个小时有值
-                    if (lastHourDataMap.get(dayReportEntity.getMapkey()).getLatestValue() != null) {
-                        dayReportEntity.setSumValue(new BigDecimal(dayReportEntity.getLatestValue().toString()).subtract(new BigDecimal(lastHourDataMap.get(dayReportEntity.getMapkey()).getLatestValue().toString())).doubleValue());
-                    } else {
-                        if (dayReportEntity.getFirstValue() != null) {//上一个小时没有值,取本小时的初始值
-                            dayReportEntity.setSumValue(new BigDecimal(dayReportEntity.getLatestValue().toString()).subtract(new BigDecimal(dayReportEntity.getFirstValue().toString())).doubleValue());
-                        }
-                        lastHourDataMap.remove(dayReportEntity.getMapkey());
-                    }
-                }
-                //对平均值小数位处理
-                dayReportEntity.setAvgValue(new BigDecimal(dayReportEntity.getAvgValue()).setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue());
-            }
-            monitorDataMapper.batchInsertDayReport(hourDatas);
+        List<DayReportEntity> lastHourData = getMonitorDataGroupByHour(dateTime.plusHours(-1),null);
+        Map<String,DayReportEntity> lastHourDataMap = lastHourData.stream().collect(Collectors.toMap(DayReportEntity::getMapkey, a -> a,(k1, k2)->k1));
+        // 保存日报表数据
+        monitorReportJobServcie.saveReportDataByHour(hourData, lastHourDataMap);
+        if (lastHourDataMap.values().size() == 0){
+            return;
         }
+        // 补充数据
+        monitorReportJobServcie.replenishHistoryData(dateTime, lastHourDataMap);
     }
 
     @Override
@@ -239,4 +194,6 @@ public class MonitorDataServiceImpl implements MonitorDataService , Initializing
         monitorDataMapper.batchInsertYearReport(dateTime.getYear(),dateTime.getMonthValue());
     }
 
+
+
 }

+ 22 - 3
sms_water/src/main/resources/mapper/SceneMapper.xml

@@ -477,7 +477,7 @@
         select count(1) amount, d.id, d.DEVICE_NAME name,1 sort
         from sms_alarm_details c
         INNER JOIN sms_device d on c.DEVICE_ID=d.ID
-        INNER JOIN sms_scene a on  c.PARENT_SCENE_ID=a.ID
+        INNER JOIN sms_scene a on  c.SCENE_ID=a.ID
         INNER JOIN sms_scene_type b on a.SCENE_TYPE_ID=b.ID
         <where>
             a.PARENT_SCENE_ID=0 and a.STATUS=1
@@ -554,25 +554,44 @@
     <select id="selectAlarmLable" resultType="map">
         select amount 数量, label 标签 from
             (
-                select count(1) amount, label from
+                select count(1) amount, concat(label,op) label from
                     (
-                        select if(d.REMARK is null,e.NAME,d.REMARK) label
+                        select if(d.REMARK is null,e.NAME,d.REMARK) label,CASE WHEN ALARM_CONDITION='&gt;' OR ALARM_CONDITION='&gt;=' then '高' WHEN ALARM_CONDITION='&lt;' OR ALARM_CONDITION='&lt;=' then '低' end op
                         <if test="sort == 2">
                             from sms_scene a INNER JOIN sms_scene_type b on a.SCENE_TYPE_ID=b.ID
                             INNER JOIN sms_alarm_details c on c.PARENT_SCENE_ID=a.ID
                             INNER JOIN sms_device_attribute e on e.ID = c.ATTRIBUTE_ID and e.STATUS=1
                             LEFT JOIN sms_device_parm d on d.ATTRIBUTE_ID = c.ATTRIBUTE_ID and d.DEVICE_ID=c.DEVICE_ID and d.TENANT_ID=c.TENANT_ID and d.PARENT_SCENE_ID=c.PARENT_SCENE_ID and d.STATUS=1
+                            INNER JOIN sms_alarm_setting f on f.device_id = c.device_id and f.SCENE_ID=c.SCENE_ID and f.STATUS=1
                             where a.ID = #{scene.id}
                         </if>
                         <if test="sort == 1">
                             from sms_alarm_details c
                             INNER JOIN sms_device_attribute e on e.ID = c.ATTRIBUTE_ID and e.STATUS=1
                             LEFT JOIN sms_device_parm d on d.ATTRIBUTE_ID = c.ATTRIBUTE_ID and d.DEVICE_ID=c.DEVICE_ID and d.TENANT_ID=c.TENANT_ID and d.PARENT_SCENE_ID=c.PARENT_SCENE_ID and d.STATUS=1
+                            INNER JOIN sms_alarm_setting f on f.device_id = c.device_id and f.SCENE_ID=c.SCENE_ID and f.STATUS=1
                             where c.device_id = #{scene.id}
                         </if>
                         and c.date_create &gt;= date_format(#{startDate,jdbcType=VARCHAR},'%Y-%m-%d')
                         and c.date_create &lt; date_format(#{endDate,jdbcType=VARCHAR},'%Y-%m-%d')
                     ) t1
+                group by concat(label,op)
+                union all
+                select count(1) amount, label from
+                (
+                    select '离线' label
+                    <if test="sort == 2">
+                        from sms_scene a INNER JOIN sms_scene_type b on a.SCENE_TYPE_ID=b.ID
+                        INNER JOIN sms_alarm_details c on c.PARENT_SCENE_ID=a.ID
+                        where a.ID = #{scene.id} and alarm_type='状态报警'
+                    </if>
+                    <if test="sort == 1">
+                        from sms_alarm_details c
+                        where c.device_id = #{scene.id} and alarm_type='状态报警'
+                    </if>
+                    and c.date_create &gt;= date_format(#{startDate,jdbcType=VARCHAR},'%Y-%m-%d')
+                    and c.date_create &lt; date_format(#{endDate,jdbcType=VARCHAR},'%Y-%m-%d')
+                ) t1
                 group by label
             ) t2
         order by amount desc