| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | |
| | | private Map<String, Object> buildAnalysisResult(List<WrkAnalysis> list, String timeField) { |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | Map<String, Object> summary = new LinkedHashMap<>(); |
| | | Date taskStartTime = list.stream() |
| | | .map(WrkAnalysis::getAppeTime) |
| | | .filter(Objects::nonNull) |
| | | .min(Date::compareTo) |
| | | .orElse(null); |
| | | Date taskEndTime = list.stream() |
| | | .map(WrkAnalysis::getFinishTime) |
| | | .filter(Objects::nonNull) |
| | | .max(Date::compareTo) |
| | | .orElse(null); |
| | | summary.put("taskCount", list.size()); |
| | | summary.put("taskStartTime", taskStartTime); |
| | | summary.put("taskStartTime$", formatDate(taskStartTime)); |
| | | summary.put("taskEndTime", taskEndTime); |
| | | summary.put("taskEndTime$", formatDate(taskEndTime)); |
| | | summary.put("taskDurationMs", taskStartTime == null || taskEndTime == null ? null : durationMs(taskStartTime, taskEndTime)); |
| | | summary.put("avgTaskBeatDurationMs", list.isEmpty() || taskStartTime == null || taskEndTime == null |
| | | ? null |
| | | : durationMs(taskStartTime, taskEndTime) / list.size()); |
| | | summary.put("avgTaskPerHour", calculateAvgTaskPerHour(list.size(), summary.get("taskDurationMs"))); |
| | | summary.put("avgTotalDurationMs", average(list, item -> item.getTotalDurationMs() != null, WrkAnalysis::getTotalDurationMs)); |
| | | summary.put("avgStationDurationMs", average(list, item -> !METRIC_PARTIAL.equals(item.getMetricCompleteness()) && item.getStationDurationMs() != null, WrkAnalysis::getStationDurationMs)); |
| | | summary.put("avgCraneDurationMs", average(list, item -> !METRIC_PARTIAL.equals(item.getMetricCompleteness()) && item.getCraneDurationMs() != null, WrkAnalysis::getCraneDurationMs)); |
| | |
| | | } |
| | | |
| | | private List<Map<String, Object>> buildFaultDuration(List<WrkAnalysis> list) { |
| | | Map<String, Long> durationMap = new LinkedHashMap<>(); |
| | | for (WrkAnalysis item : list) { |
| | | addDeviceFaultDuration(durationMap, "单堆垛机", item.getCrnNo(), item.getCrnFaultDurationMs()); |
| | | addDeviceFaultDuration(durationMap, "双工位堆垛机", item.getDualCrnNo(), item.getDualCrnFaultDurationMs()); |
| | | addDeviceFaultDuration(durationMap, "RGV", item.getRgvNo(), item.getRgvFaultDurationMs()); |
| | | } |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | result.add(slice("单堆垛机", list.stream().map(WrkAnalysis::getCrnFaultDurationMs).filter(Objects::nonNull).reduce(0L, Long::sum))); |
| | | result.add(slice("双工位堆垛机", list.stream().map(WrkAnalysis::getDualCrnFaultDurationMs).filter(Objects::nonNull).reduce(0L, Long::sum))); |
| | | result.add(slice("RGV", list.stream().map(WrkAnalysis::getRgvFaultDurationMs).filter(Objects::nonNull).reduce(0L, Long::sum))); |
| | | durationMap.forEach((name, durationMs) -> result.add(slice(name, durationMs))); |
| | | return result; |
| | | } |
| | | |
| | | private void addDeviceFaultDuration(Map<String, Long> durationMap, String deviceLabel, Integer deviceNo, Long durationMs) { |
| | | long value = defaultLong(durationMs); |
| | | if (value <= 0L) { |
| | | return; |
| | | } |
| | | String key = deviceNo == null ? deviceLabel : deviceLabel + deviceNo; |
| | | durationMap.merge(key, value, Long::sum); |
| | | } |
| | | |
| | | private List<Map<String, Object>> buildDetailRows(List<WrkAnalysis> list) { |
| | |
| | | return count == 0 ? null : total / count; |
| | | } |
| | | |
| | | private Double calculateAvgTaskPerHour(int taskCount, Object taskDurationMsValue) { |
| | | if (taskCount <= 0 || !(taskDurationMsValue instanceof Number)) { |
| | | return null; |
| | | } |
| | | long taskDurationMs = ((Number) taskDurationMsValue).longValue(); |
| | | if (taskDurationMs <= 0L) { |
| | | return null; |
| | | } |
| | | return BigDecimal.valueOf(taskCount * 3600000D / taskDurationMs) |
| | | .setScale(2, RoundingMode.HALF_UP) |
| | | .doubleValue(); |
| | | } |
| | | |
| | | private void applyRange(QueryWrapper<WrkMastLog> wrapper, String column, String rawValue) { |
| | | if (Cools.isEmpty(rawValue) || !rawValue.contains("~")) { |
| | | return; |