فهرست منبع

搞定日统计,界面数据统计

wukai 1 سال پیش
والد
کامیت
a291b79f80

+ 7 - 1
ruoyi-admin/src/main/java/com/ruoyi/biz/domain/TwinCalcDay.java

@@ -50,6 +50,9 @@ public class TwinCalcDay extends BaseEntity {
         this.stop2B = 0L;
         this.stop3A = 0L;
         this.stop3B = 0L;
+
+        this.setEfficiencyA(BigDecimal.ONE);
+        this.setEfficiencyB(BigDecimal.ONE);
     }
 
     private static final long serialVersionUID = 1L;
@@ -290,17 +293,20 @@ public class TwinCalcDay extends BaseEntity {
             this.length = length.add(hour.getLength());
             this.weight = weight.add(hour.getWeight());
             this.kwh = kwh.add(hour.getKwh());
-
             if (hour.getHour() >= 7 && hour.getHour() < 19) {
                 //A班
                 this.lengthA = lengthA.add(hour.getLength());
                 this.weightA = weightA.add(hour.getWeight());
                 this.kwhA = kwhA.add(hour.getKwh());
+                this.openTimeA = openTimeA.add(BigDecimal.valueOf(hour.getOpenTime()));
+                this.closeTimeA = closeTimeA.add(BigDecimal.valueOf(hour.getCloseTime()));
             } else {
                 //B班
                 this.lengthB = lengthB.add(hour.getLength());
                 this.weightB = weightB.add(hour.getWeight());
                 this.kwhB = kwhB.add(hour.getKwh());
+                this.openTimeB = openTimeB.add(BigDecimal.valueOf(hour.getOpenTime()));
+                this.closeTimeB = closeTimeB.add(BigDecimal.valueOf(hour.getCloseTime()));
             }
         });
     }

+ 15 - 8
ruoyi-admin/src/main/java/com/ruoyi/biz/mapper/TwinCalcHourMapper.java

@@ -5,15 +5,15 @@ import com.ruoyi.biz.domain.TwinCalcHour;
 
 /**
  * 1小时统计数据Mapper接口
- * 
+ *
  * @author ruoyi
  * @date 2024-06-28
  */
-public interface TwinCalcHourMapper 
+public interface TwinCalcHourMapper
 {
     /**
      * 查询1小时统计数据
-     * 
+     *
      * @param id 1小时统计数据主键
      * @return 1小时统计数据
      */
@@ -21,7 +21,7 @@ public interface TwinCalcHourMapper
 
     /**
      * 查询1小时统计数据列表
-     * 
+     *
      * @param twinCalcHour 1小时统计数据
      * @return 1小时统计数据集合
      */
@@ -29,7 +29,7 @@ public interface TwinCalcHourMapper
 
     /**
      * 新增1小时统计数据
-     * 
+     *
      * @param twinCalcHour 1小时统计数据
      * @return 结果
      */
@@ -37,7 +37,7 @@ public interface TwinCalcHourMapper
 
     /**
      * 修改1小时统计数据
-     * 
+     *
      * @param twinCalcHour 1小时统计数据
      * @return 结果
      */
@@ -45,7 +45,7 @@ public interface TwinCalcHourMapper
 
     /**
      * 删除1小时统计数据
-     * 
+     *
      * @param id 1小时统计数据主键
      * @return 结果
      */
@@ -53,9 +53,16 @@ public interface TwinCalcHourMapper
 
     /**
      * 批量删除1小时统计数据
-     * 
+     *
      * @param ids 需要删除的数据主键集合
      * @return 结果
      */
     public int deleteTwinCalcHourByIds(String[] ids);
+
+    /**
+     * 获取数据库最后一条记录
+     *
+     * @return 对象
+     */
+    TwinCalcHour lastHour();
 }

+ 7 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/service/ITwinCalcDayService.java

@@ -80,4 +80,11 @@ public interface ITwinCalcDayService {
      * @param localDate 指定日期
      */
     void calc4date(LocalDate localDate);
+
+    /**
+     * 统计今天的产量数据
+     *
+     * @return 当日数据 7:00至第二天7点(不含)
+     */
+    TwinCalcDay calcToday();
 }

+ 7 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/service/ITwinCalcHourService.java

@@ -68,4 +68,11 @@ public interface ITwinCalcHourService {
      * @return 查询列表
      */
     List<TwinCalcHour> selectTwinCalcHourListByDate(Date sTime, Date eTime);
+
+    /**
+     * 获取数据库最后一条记录
+     *
+     * @return 对象
+     */
+    TwinCalcHour lastHour();
 }

+ 15 - 11
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/ApiServiceImpl.java

@@ -58,16 +58,20 @@ public class ApiServiceImpl implements IApiService {
         List<WeekData> weekDataList = new ArrayList<>();
         IndexData indexData = new IndexData();
         IndexEfficiency efficiency = new IndexEfficiency();
-        efficiency.setAEfficiency(52.7f);
-        efficiency.setBEfficiency(52.7f);
-        efficiency.setTotalLength(1f);
-        efficiency.setALength(1f);
-        efficiency.setBLength(1f);
-        efficiency.setTotalWeight(1f);
-        efficiency.setAWeight(1f);
-        efficiency.setBWeight(1f);
-        efficiency.setATime(1f);
-        efficiency.setBTime(1f);
+        TwinCalcDay calcDay = twinCalcDayService.calcToday();
+        /*
+            获取当天产量数据
+         */
+        efficiency.setAEfficiency(calcDay.getEfficiencyA().floatValue());
+        efficiency.setBEfficiency(calcDay.getEfficiencyB().floatValue());
+        efficiency.setTotalLength(calcDay.getLength().floatValue());
+        efficiency.setALength(calcDay.getLengthA().floatValue());
+        efficiency.setBLength(calcDay.getLengthB().floatValue());
+        efficiency.setTotalWeight(calcDay.getWeight().floatValue());
+        efficiency.setAWeight(calcDay.getWeightA().floatValue());
+        efficiency.setBWeight(calcDay.getWeightB().floatValue());
+        efficiency.setATime(calcDay.getOpenTimeA().add(calcDay.getCloseTimeA()).divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP).floatValue());
+        efficiency.setBTime(calcDay.getOpenTimeB().add(calcDay.getCloseTimeB()).divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP).floatValue());
         indexData.setEfficiency(efficiency);
 
         /*
@@ -253,7 +257,7 @@ public class ApiServiceImpl implements IApiService {
         if (bl != null && flag.equals(bl)) {
             return;
         }
-//        taskService.calc2Curr();
+        taskService.calc2Curr();
         indexCalc();
         indexAlarms();
     }

+ 1 - 3
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/AsyncServiceImpl.java

@@ -5,8 +5,6 @@ import cn.hutool.json.JSONObject;
 import com.ruoyi.biz.domain.*;
 import com.ruoyi.biz.service.IIotService;
 import com.ruoyi.biz.tools.Tools;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.utils.CacheUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
@@ -214,7 +212,7 @@ public class AsyncServiceImpl {
         //存入最后一条记录的停机状态
 //        CacheUtils.put(Constants.IOT_TOKEN, table, values.getJSONArray(values.size() - 1));
 
-        total[3] = 3600 - total[4];
+        total[3] = (endTime - startTime) / 1000 + 1 - total[4];
 
         Map<String, Object> result = new HashMap<>(16);
         result.put("total", total);

+ 111 - 30
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TwinCalcDayServiceImpl.java

@@ -1,16 +1,11 @@
 package com.ruoyi.biz.service.impl;
 
-import com.ruoyi.biz.domain.TwinCalcAlarms;
-import com.ruoyi.biz.domain.TwinCalcDay;
-import com.ruoyi.biz.domain.TwinCalcHour;
-import com.ruoyi.biz.domain.TwinCalcStop;
+import com.ruoyi.biz.domain.*;
 import com.ruoyi.biz.mapper.TwinCalcDayMapper;
-import com.ruoyi.biz.service.ITwinCalcAlarmsService;
-import com.ruoyi.biz.service.ITwinCalcDayService;
-import com.ruoyi.biz.service.ITwinCalcHourService;
-import com.ruoyi.biz.service.ITwinCalcStopService;
+import com.ruoyi.biz.service.*;
 import com.ruoyi.biz.tools.Tools;
 import com.ruoyi.common.core.text.Convert;
+import com.ruoyi.common.utils.DateUtils;
 import javafx.util.Pair;
 import org.springframework.stereotype.Service;
 
@@ -18,10 +13,14 @@ import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.ZoneOffset;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
@@ -42,6 +41,12 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
     private ITwinCalcStopService stopService;
     @Resource
     private ITwinCalcAlarmsService alarmsService;
+    @Resource
+    private IotServiceImpl iotService;
+    @Resource
+    private ITwinDeviceService deviceService;
+    @Resource
+    private AsyncServiceImpl asyncService;
 
     /**
      * 查询日统计数据
@@ -145,9 +150,14 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
         List<TwinCalcHour> hourList = hourService.selectTwinCalcHourListByDate(sTime, eTime);
         List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
         List<TwinCalcAlarms> alarmsList = alarmsService.selectTwinCalcAlarmsListByDate(sTime, eTime);
-        Pair<Date, Date> teamPair = Tools.teamA(localDate);
-
-        Map<Long, List<TwinCalcHour>> stopDeviceGroup = hourList.stream().collect(Collectors.groupingBy(TwinCalcHour::getDeviceId));
+        Pair<Date, Date> teamPairA = Tools.teamA(localDate);
+        Pair<Date, Date> teamPairB = Tools.teamB(localDate);
+        // 提取A班和B班的开始和结束时间,避免在循环中重复调用
+        Date startTimeA = teamPairA.getKey();
+        Date endTimeA = teamPairA.getValue();
+        Date startTimeB = teamPairB.getKey();
+        Date endTimeB = teamPairB.getValue();
+        Map<Long, List<TwinCalcHour>> stopDeviceGroup = hourList.stream().collect(Collectors.groupingBy(TwinCalcHour::getDeviceId, LinkedHashMap::new, Collectors.toList()));
         for (Map.Entry<Long, List<TwinCalcHour>> entry : stopDeviceGroup.entrySet()) {
             List<TwinCalcHour> hours = entry.getValue();
             TwinCalcDay day = new TwinCalcDay(date);
@@ -189,25 +199,26 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
                 }
             };
 
-            stops.stream().peek(stop -> {
-                // 调整停止时间
-                if (stop.getEndTime().compareTo(eTime) > 0) {
-                    stop.setEndTime(eTime);
+            // 使用Stream API,结合if-else逻辑的优化
+            stops.stream().forEach(stop -> {
+                // 根据停机时间判断属于哪个班次
+                boolean isAshift = !stop.getStartTime().after(endTimeA) && !stop.getEndTime().before(startTimeA);
+                Date shiftStart = isAshift ? startTimeA : startTimeB;
+                Date shiftEnd = isAshift ? endTimeA : endTimeB;
+                AtomicLong totalStopTime = isAshift ? closeA : closeB;
+                BiConsumer<Integer, Integer> eventCounter = isAshift ? updateDayA : updateDayB;
+
+                // 调整停机时间
+                if (stop.getEndTime().compareTo(shiftEnd) > 0) {
+                    stop.setEndTime(shiftEnd);
                 }
-                //调整开始时间
-                if (stop.getStartTime().compareTo(sTime) < 0) {
-                    stop.setStartTime(sTime);
+                if (stop.getStartTime().compareTo(shiftStart) < 0) {
+                    stop.setStartTime(shiftStart);
                 }
-            }).forEach(stop -> {
-                //计算停机时间
+
+                // 计算并更新停机时间和事件计数
                 long stopTime = (stop.getEndTime().getTime() - stop.getStartTime().getTime()) / 1000;
-                if (!stop.getStartTime().after(teamPair.getValue()) && !stop.getEndTime().before(teamPair.getKey())) {
-                    // A班
-                    updateStopCounters(stopTime, stop.getStopType(), closeA, updateDayA);
-                } else {
-                    // B班
-                    updateStopCounters(stopTime, stop.getStopType(), closeB, updateDayB);
-                }
+                updateStopCounters(stopTime, stop.getStopType(), totalStopTime, eventCounter);
             });
 
             //计算稼动率
@@ -249,4 +260,74 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
         totalTimeCounter.addAndGet(stopTime);
         eventCounterUpdater.accept(stopType, 1);
     }
+
+    /**
+     * 统计今天的产量数据
+     *
+     * @return 当日数据 7:00至第二天7点(不含)
+     */
+    @Override
+    public TwinCalcDay calcToday() {
+        //计算统计时间
+        Pair<Date, Date> pair = Tools.calcToday();
+        Date sTime = pair.getKey();
+        Date eTime = pair.getValue();
+        List<TwinCalcHour> hourList = hourService.selectTwinCalcHourListByDate(sTime, eTime);
+        TwinCalcDay calcDay = new TwinCalcDay(sTime);
+        if (hourList.size() > 0) {
+            calcDay.calcHours(hourList);
+        }
+        List<TwinCalcHour> hours = new ArrayList<>();
+        TwinCalcHour lastHour = hourService.lastHour();
+        LocalDate localDate = DateUtils.toLocalDate(lastHour.getDataDate());
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(lastHour.getHour() + 1);
+        Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli();
+        Long endTime = eTime.getTime();
+
+        //为了避免多线程同时获取token导致重复执行,先执行一次获取token
+        iotService.getToken();
+        TwinDevice search = new TwinDevice();
+        //查询所有在线的设备
+        search.setOnline("1");
+        List<TwinDevice> list = deviceService.selectTwinDeviceList(search);
+        List<Future<Map<String, List<?>>>> futureList = new ArrayList<>();
+        for (int i = 0; i < list.size(); i++) {
+            TwinDevice twinDevice = list.get(i);
+            futureList.add(asyncService.process(twinDevice, sTime, startTime, endTime, start.getHour()));
+        }
+        try {
+            for (Future<Map<String, List<?>>> future : futureList) {
+                // 任务完成后获取结果
+                try {
+                    Map<String, List<?>> map = future.get(10L, TimeUnit.SECONDS);
+                    List<TwinCalcHour> calcHours = (List<TwinCalcHour>) map.get("calc");
+                    hours.addAll(calcHours);
+                } catch (TimeoutException e) {
+                    e.printStackTrace();
+                }
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+        if (hours.size() > 0) {
+            calcDay.calcHours(hours);
+        }
+
+
+        BigDecimal totalTimeA = calcDay.getOpenTimeA().add(calcDay.getCloseTimeA());
+        BigDecimal totalTimeB = calcDay.getOpenTimeB().add(calcDay.getCloseTimeB());
+        if (!totalTimeA.equals(BigDecimal.ZERO)) {
+            BigDecimal eff = calcDay.getOpenTimeA().divide(totalTimeA, 2, RoundingMode.HALF_UP);
+            calcDay.setEfficiencyA(eff);
+
+        }
+        if (!totalTimeB.equals(BigDecimal.ZERO)) {
+            BigDecimal eff = calcDay.getOpenTimeB().divide(totalTimeB, 2, RoundingMode.HALF_UP);
+            calcDay.setEfficiencyB(eff);
+        }
+        return calcDay;
+    }
+
 }

+ 10 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TwinCalcHourServiceImpl.java

@@ -104,4 +104,14 @@ public class TwinCalcHourServiceImpl implements ITwinCalcHourService {
         hour.setParams(params);
         return selectTwinCalcHourList(hour);
     }
+
+    /**
+     * 获取数据库最后一条记录
+     *
+     * @return 对象
+     */
+    @Override
+    public TwinCalcHour lastHour() {
+        return twinCalcHourMapper.lastHour();
+    }
 }

+ 1 - 1
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcAlarmsMapper.xml

@@ -49,7 +49,7 @@
             <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
             <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
             <if test="params.sTime != null and params.eTime != null">
-                and DATE_ADD(data_date, INTERVAL `HOUR` HOUR) between #{params.sTime} and #{params.eTime}
+                and (start_time&lt;=#{params.eTime} and end_time>=#{params.sTime})
             </if>
         </where>
     </select>

+ 6 - 1
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcHourMapper.xml

@@ -23,7 +23,8 @@
     </resultMap>
 
     <sql id="selectTwinCalcHourVo">
-        select ID, DATA_DATE, HOUR, DEVICE_ID, KWH, WEIGHT, LENGTH, OPEN_TIME, CLOSE_TIME, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
+        select ID,
+               DATA_DATE, HOUR, DEVICE_ID, KWH, WEIGHT, LENGTH, OPEN_TIME, CLOSE_TIME, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
         from twin_calc_hour
     </sql>
 
@@ -53,6 +54,10 @@
         <include refid="selectTwinCalcHourVo"/>
         where ID = #{id}
     </select>
+    <select id="lastHour" resultMap="TwinCalcHourResult">
+        <include refid="selectTwinCalcHourVo"/>
+        order by id desc limit 1
+    </select>
 
     <insert id="insertTwinCalcHour" parameterType="TwinCalcHour" useGeneratedKeys="true" keyProperty="id">
         insert into twin_calc_hour

+ 1 - 1
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcStopMapper.xml

@@ -49,7 +49,7 @@
             <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
             <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
             <if test="params.sTime != null and params.eTime != null">
-                and DATE_ADD(data_date, INTERVAL `HOUR` HOUR) between #{params.sTime} and #{params.eTime}
+                and (start_time&lt;=#{params.eTime} and end_time>=#{params.sTime})
             </if>
         </where>
         order by START_TIME

+ 10 - 4
ruoyi-admin/src/test/java/com/jjt/CalcDayTest.java

@@ -23,14 +23,20 @@ public class CalcDayTest {
     private ITwinCalcDayService dayService;
 
     public static void main(String[] args) {
+        LocalDate localDate = LocalDate.parse("2024-06-27");
+        for (int i = 0; i < 7; i++) {
+            System.err.println(localDate.plusDays(i));
+        }
     }
 
     @Test
     void test() {
-        LocalDate localDate = LocalDate.parse("2024-07-01");
-        dayService.calc4date(localDate);
-        localDate = LocalDate.parse("2024-07-02");
-        dayService.calc4date(localDate);
+        LocalDate localDate = LocalDate.parse("2024-06-27");
+        for (int i = 0; i < 7; i++) {
+            dayService.calc4date(localDate.plusDays(i));
+        }
+//        LocalDate localDate = LocalDate.parse("2024-07-03");
+//        dayService.calc4date(localDate);
     }
 
 }