|
@@ -1,16 +1,11 @@
|
|
package com.ruoyi.biz.service.impl;
|
|
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.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.biz.tools.Tools;
|
|
import com.ruoyi.common.core.text.Convert;
|
|
import com.ruoyi.common.core.text.Convert;
|
|
|
|
+import com.ruoyi.common.utils.DateUtils;
|
|
import javafx.util.Pair;
|
|
import javafx.util.Pair;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
@@ -18,10 +13,14 @@ import javax.annotation.Resource;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
import java.math.RoundingMode;
|
|
import java.math.RoundingMode;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
+import java.time.LocalTime;
|
|
import java.time.ZoneOffset;
|
|
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.concurrent.atomic.AtomicLong;
|
|
import java.util.function.BiConsumer;
|
|
import java.util.function.BiConsumer;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
@@ -42,6 +41,12 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
|
|
private ITwinCalcStopService stopService;
|
|
private ITwinCalcStopService stopService;
|
|
@Resource
|
|
@Resource
|
|
private ITwinCalcAlarmsService alarmsService;
|
|
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<TwinCalcHour> hourList = hourService.selectTwinCalcHourListByDate(sTime, eTime);
|
|
List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
|
|
List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
|
|
List<TwinCalcAlarms> alarmsList = alarmsService.selectTwinCalcAlarmsListByDate(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()) {
|
|
for (Map.Entry<Long, List<TwinCalcHour>> entry : stopDeviceGroup.entrySet()) {
|
|
List<TwinCalcHour> hours = entry.getValue();
|
|
List<TwinCalcHour> hours = entry.getValue();
|
|
TwinCalcDay day = new TwinCalcDay(date);
|
|
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;
|
|
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);
|
|
totalTimeCounter.addAndGet(stopTime);
|
|
eventCounterUpdater.accept(stopType, 1);
|
|
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;
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|