Преглед на файлове

每个月统计投用率以及回路健康等级的平均值

sl преди 7 месеца
родител
ревизия
d4c6153f9e
променени са 1 файла, в които са добавени 276 реда и са изтрити 3 реда
  1. 276 3
      jeecg-module-interlock/src/main/java/org/jeecg/modules/interlockjob/MonthStatisticsJob.java

+ 276 - 3
jeecg-module-interlock/src/main/java/org/jeecg/modules/interlockjob/MonthStatisticsJob.java

@@ -2,6 +2,7 @@ package org.jeecg.modules.interlockjob;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import javassist.expr.NewArray;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.util.DateUtils;
 import org.jeecg.modules.base.entity.InterlockBase;
@@ -19,11 +20,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import javax.management.Query;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -49,6 +49,7 @@ public class MonthStatisticsJob implements Job {
     @SuppressWarnings("all")
     private IInterlockBaseService baseService;
 
+    /*2024提需求之前备份,新需求:按日统计,计算每个月的联锁投用和回路健康等级平均值
     @Override
     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
@@ -234,4 +235,276 @@ public class MonthStatisticsJob implements Job {
         monthService.saveBatch(list);
         log.info("月统计任务执行成功!");
     }
+
+     */
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
+        LocalDate yesterDate = LocalDate.now().minusMonths(1);  // 当前 00:00:00 执行定时任务 减一天获取昨天的日期
+        String lastmonth = yesterDate.atStartOfDay().format(formatter); // 上个月的月份
+        //String lastmonth = "2024-06"; // 测试模拟上个月的月份
+        String year = lastmonth.split("-")[0];
+        int days = getDaysInMonth(lastmonth);//获取lastmonth这个月有多少天
+
+        // 统计健康等级 count_type = 0
+        List<InterlockCountDay> loopHealthLevelList = countDayService.getCountByYearmonth(CountType.LOOPHEALTHLEVEL,lastmonth);
+
+        HashMap<String, List<InterlockCountDay>> loopHealthLevelMap = new HashMap<>();
+
+        ArrayList<InterlockCountMonth> loopHealthLevelResultList = new ArrayList<>();
+
+        for (InterlockCountDay item:loopHealthLevelList) {
+            if (loopHealthLevelMap.containsKey(item.getInterlockSystemId())){
+                loopHealthLevelMap.get(item.getInterlockSystemId()).add(item);
+            }else {
+                ArrayList<InterlockCountDay> countList = new ArrayList<>();
+                countList.add(item);
+                loopHealthLevelMap.put(item.getInterlockSystemId(),countList);
+            }
+        }
+
+        for (String key : loopHealthLevelMap.keySet()) {
+            List<InterlockCountDay> sonList = loopHealthLevelMap.get(key);
+            int countAnum = 0;
+            int countBnum = 0;
+            int countCnum = 0;
+            int countDnum = 0;
+            for (InterlockCountDay item : sonList) {
+                int num = Integer.parseInt(item.getCountNum());
+                switch (item.getCountName()){
+                    case "A" :
+                        countAnum += num;
+                        break;
+                    case "B" :
+                        countBnum += num;
+                        break;
+                    case "C" :
+                        countCnum += num;
+                        break;
+                    case "D" :
+                        countDnum += num;
+                        break;
+                }
+            }
+            String[] arr1 = {"A", "B", "C", "D"};
+            int countLoopNumAvg = (countAnum+countBnum+countCnum+countDnum)/days;//上个月的平均联锁总数-取整数
+            BigDecimal countAAvg = new BigDecimal(countAnum/days).setScale(4, RoundingMode.HALF_UP);//保留四位小数
+            BigDecimal countBAvg = new BigDecimal(countBnum/days).setScale(4, RoundingMode.HALF_UP);//保留四位小数
+            BigDecimal countCAvg = new BigDecimal(countCnum/days).setScale(4, RoundingMode.HALF_UP);//保留四位小数
+            BigDecimal countDAvg = new BigDecimal(countDnum/days).setScale(4, RoundingMode.HALF_UP);//保留四位小数
+
+            int countAInteger = countAAvg.setScale(0, RoundingMode.DOWN).intValue();//取整数
+            int countBInteger = countBAvg.setScale(0, RoundingMode.DOWN).intValue();//取整数
+            int countCInteger = countCAvg.setScale(0, RoundingMode.DOWN).intValue();//取整数
+            int countDInteger = countDAvg.setScale(0, RoundingMode.DOWN).intValue();//取整数
+
+            int countADecimal = (countAAvg.subtract(countAAvg.setScale(0, RoundingMode.DOWN))).intValue();//取小数
+            int countBDecimal = (countBAvg.subtract(countBAvg.setScale(0, RoundingMode.DOWN))).intValue();//取小数
+            int countCDecimal = (countCAvg.subtract(countCAvg.setScale(0, RoundingMode.DOWN))).intValue();//取小数
+            int countDDecimal = (countDAvg.subtract(countDAvg.setScale(0, RoundingMode.DOWN))).intValue();//取小数
+
+
+            //计算abcd平均值
+            int[] arr2 = countLoopAvg(countLoopNumAvg, countAInteger, countBInteger, countCInteger, countDInteger, countADecimal, countBDecimal, countCDecimal, countDDecimal);
+
+//            int[] arr2 = {countAnum,countBnum,countCnum,countDnum};
+
+            for (int i = 0; i < arr1.length; i++){
+                InterlockCountMonth interlockCountMonth = new InterlockCountMonth();
+                interlockCountMonth.setDeviceId(sonList.get(0).getDeviceId());
+                interlockCountMonth.setInterlockSystemId(sonList.get(0).getInterlockSystemId());
+                interlockCountMonth.setInterlockName(sonList.get(0).getInterlockName());
+                interlockCountMonth.setCountName(arr1[i]);
+                interlockCountMonth.setCountNum(String.valueOf(arr2[i]));
+                interlockCountMonth.setCountType(CountType.LOOPHEALTHLEVEL);
+                interlockCountMonth.setTime(lastmonth);
+                interlockCountMonth.setYear(year);
+                loopHealthLevelResultList.add(interlockCountMonth);
+            }
+        }
+
+        // 统计联锁状态(投用/未投用)  count_type = 1
+        List<InterlockCountDay> interlockStatusList = countDayService.getCountByYearmonth(CountType.INTERLOCKSTATUS,lastmonth);
+
+        HashMap<String, List<InterlockCountDay>> interlockStatusMap = new HashMap<>();
+
+        ArrayList<InterlockCountMonth> interlockStatusResultList = new ArrayList<>();
+
+        for (InterlockCountDay item:interlockStatusList) {
+            if (interlockStatusMap.containsKey(item.getInterlockSystemId())){
+                interlockStatusMap.get(item.getInterlockSystemId()).add(item);
+            }else {
+                ArrayList<InterlockCountDay> countList = new ArrayList<>();
+                countList.add(item);
+                interlockStatusMap.put(item.getInterlockSystemId(),countList);
+            }
+        }
+
+        for (String key : interlockStatusMap.keySet()) {
+            InterlockBase base = baseService.getById(key);
+            String ty = base.getInterlockStatusTyName();
+            String wty = base.getInterlockStatusWtyName();
+            List<InterlockCountDay> sonList = interlockStatusMap.get(key);
+            int countTyNum = 0;
+            int countWtyNum = 0;
+            for (InterlockCountDay item : sonList) {
+                if (ty.equals(item.getCountName())){
+                    countTyNum += Integer.parseInt(item.getCountNum());
+                }
+                if (wty.equals(item.getCountName())){
+                    countWtyNum += Integer.parseInt(item.getCountNum());
+                }
+            }
+
+            InterlockCountMonth interlockCountMonthTy = new InterlockCountMonth();
+
+            interlockCountMonthTy.setDeviceId(sonList.get(0).getDeviceId());
+            interlockCountMonthTy.setInterlockSystemId(sonList.get(0).getInterlockSystemId());
+            interlockCountMonthTy.setInterlockName(sonList.get(0).getInterlockName());
+            interlockCountMonthTy.setCountName(ty);
+            interlockCountMonthTy.setCountNum(String.valueOf(countTyNum));
+            interlockCountMonthTy.setCountType(CountType.INTERLOCKSTATUS);
+            interlockCountMonthTy.setTime(lastmonth);
+            interlockCountMonthTy.setYear(year);
+
+            InterlockCountMonth interlockCountMonthWty = new InterlockCountMonth();
+
+            interlockCountMonthWty.setDeviceId(sonList.get(0).getDeviceId());
+            interlockCountMonthWty.setInterlockSystemId(sonList.get(0).getInterlockSystemId());
+            interlockCountMonthWty.setInterlockName(sonList.get(0).getInterlockName());
+            interlockCountMonthWty.setCountName(wty);
+            interlockCountMonthWty.setCountNum(String.valueOf(countWtyNum));
+            interlockCountMonthWty.setCountType(CountType.INTERLOCKSTATUS);
+            interlockCountMonthWty.setTime(lastmonth);
+            interlockCountMonthWty.setYear(year);
+
+            interlockStatusResultList.add(interlockCountMonthTy);
+            interlockStatusResultList.add(interlockCountMonthWty);
+        }
+
+        // 统计投用率  count_type = 2
+        List<InterlockCountDay> interlockStatusTylList = countDayService.getCountByYearmonth(CountType.UTILIZATIONRATE,lastmonth);
+        ArrayList<InterlockCountMonth> tylResultList = new ArrayList<>();
+
+        HashMap<String, List<InterlockCountDay>> tylMap = new HashMap<>();
+
+        for (InterlockCountDay item:interlockStatusTylList) {
+            if (tylMap.containsKey(item.getInterlockSystemId())){
+                tylMap.get(item.getInterlockSystemId()).add(item);
+            }else {
+                ArrayList<InterlockCountDay> countList = new ArrayList<>();
+                countList.add(item);
+                tylMap.put(item.getInterlockSystemId(),countList);
+            }
+        }
+
+        //上个月每天的投用率相加除以天数取平均值作为上个月的投用率
+        for (String key : tylMap.keySet()) {
+            InterlockBase base = baseService.getById(key);
+            String tyName = base.getInterlockStatusTyName();
+            String wtyName = base.getInterlockStatusWtyName();
+            List<InterlockCountDay> sonList = tylMap.get(key);
+            BigDecimal totalTyl = BigDecimal.valueOf(0);
+            BigDecimal tyl = BigDecimal.valueOf(0);
+            for (InterlockCountDay item : sonList) {
+                totalTyl = totalTyl.add(new BigDecimal(item.getCountNum()));
+            }
+            tyl = totalTyl.divide(new BigDecimal(days), 4, RoundingMode.HALF_UP);
+
+            InterlockCountMonth interlockCountMonthTyl = new InterlockCountMonth();
+            interlockCountMonthTyl.setDeviceId(sonList.get(0).getDeviceId());
+            interlockCountMonthTyl.setInterlockSystemId(key);
+            interlockCountMonthTyl.setInterlockName(sonList.get(0).getInterlockName());
+            interlockCountMonthTyl.setCountName("投用率");
+            interlockCountMonthTyl.setCountNum(String.valueOf(tyl));
+            interlockCountMonthTyl.setCountType(CountType.UTILIZATIONRATE);
+            interlockCountMonthTyl.setTime(lastmonth);
+            interlockCountMonthTyl.setYear(year);
+            tylResultList.add(interlockCountMonthTyl);
+        }
+
+
+        List<InterlockCountMonth> list = Stream.concat(Stream.concat(loopHealthLevelResultList.stream(), interlockStatusResultList.stream()),tylResultList.stream())
+                .collect(Collectors.toList());
+
+
+        QueryWrapper<InterlockCountMonth> queryWapper = new QueryWrapper<>();
+        queryWapper.eq("time",lastmonth);
+        boolean b = monthService.remove(queryWapper);
+
+        monthService.saveBatch(list);
+        log.info("月统计任务执行成功!");
+    }
+
+    //获取某个年月有多少天
+    public int getDaysInMonth(String yearMonth) {
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+            Date date = sdf.parse(yearMonth);
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+            return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+
+    //计算健康等级平均值
+    public int[] countLoopAvg(int countLoopNumAvg, int countAInteger, int countBInteger, int countCInteger, int countDInteger, int countADecimal, int countBDecimal, int countCDecimal, int countDDecimal){
+
+        //如果A,B,C,D的整数位相加后,和总数相等,直接返回整数位
+        if(countAInteger+countBInteger+countCInteger+countDInteger==countLoopNumAvg) return new int[]{countAInteger, countBInteger, countCInteger, countDInteger};
+
+        //如果A,B,C,D的整数位相加后,和总数不相等
+        //先给小数拍个顺序,顺序规则:
+        //1.按照小数位大小排序   2.出现小数位相同,就按照A、B、C、D顺序来
+        String[] loops = getSortFABCD(new ArrayList<>(Arrays.asList(countADecimal, countBDecimal, countCDecimal, countDDecimal)));
+        while (countAInteger+countBInteger+countCInteger+countDInteger!=countLoopNumAvg){
+            for(String loop:loops){
+                switch (loop) {
+                    case "A":
+                        countAInteger++;
+                        break;
+                    case "B":
+                        countBInteger++;
+                        break;
+                    case "C":
+                        countCInteger++;
+                        break;
+                    case "D":
+                        countDInteger++;
+                        break;
+                }
+                if(countAInteger+countBInteger+countCInteger+countDInteger==countLoopNumAvg){
+                    break;
+                }
+            }
+        }
+
+        return new int[]{countAInteger, countBInteger, countCInteger, countDInteger};
+    }
+
+    public String[] getSortFABCD(List<Integer> arrDecimal){
+        String[] loopNew;
+        loopNew = new String[arrDecimal.size()]; // 创建长度为4的数组,元素默认初始化为0
+        List<String> loop = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
+        for(int i=0;i<loopNew.length;i++){
+            //取到最大值后,要将其删掉重新取最大值,所以需要取到位号
+            int index=0;
+            int max = 0;
+            for(int j=0;j<arrDecimal.size();j++){
+                if(arrDecimal.get(j)>max){//取最大值  因为是按照abcd排着的,所以等于的时候也是取得前面得
+                    max = arrDecimal.get(j);
+                    index=j;
+                }
+            }
+            loopNew[i] = loop.get(index);//取最大值或abcd最前对应得ABCD
+            arrDecimal.remove(index);
+            loop.remove(index);
+        }
+        return loopNew;
+    }
+
 }