From b5d02520af582a86aa95d7903558a5bf50a77aa7 Mon Sep 17 00:00:00 2001
From: cuilei <ray_tsu1@163.com>
Date: 星期二, 17 六月 2025 16:12:46 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentFaultInfoServiceImpl.java |  298 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 298 insertions(+), 0 deletions(-)

diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentFaultInfoServiceImpl.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentFaultInfoServiceImpl.java
new file mode 100644
index 0000000..df0f7c6
--- /dev/null
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentFaultInfoServiceImpl.java
@@ -0,0 +1,298 @@
+package org.jeecg.modules.mdc.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.apache.commons.lang.StringUtils;
+import org.jeecg.modules.mdc.entity.*;
+import org.jeecg.modules.mdc.mapper.MdcEquipmentFaultInfoMapper;
+import org.jeecg.modules.mdc.service.IEquipmentService;
+import org.jeecg.modules.mdc.service.IMdcEquipmentFaultInfoService;
+import org.jeecg.modules.mdc.service.IMdcEquipmentRunningSectionService;
+import org.jeecg.modules.mdc.service.IMdcSystemParametersService;
+import org.jeecg.modules.mdc.util.DateUtils;
+import org.jeecg.modules.mdc.vo.EquFaultRecord;
+import org.jeecg.modules.mdc.vo.TimeInterval;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 鏁呴殰鐜囪〃
+ * @Author: Lius
+ * @Date: 2025-06-16
+ * @Version: V1.0
+ */
+@Service
+public class MdcEquipmentFaultInfoServiceImpl extends ServiceImpl<MdcEquipmentFaultInfoMapper, MdcEquipmentFaultInfo> implements IMdcEquipmentFaultInfoService {
+
+    @Resource
+    private IEquipmentService equipmentService;
+
+    @Resource
+    private IMdcSystemParametersService mdcSystemParametersService;
+
+    @Resource
+    private IMdcEquipmentRunningSectionService mdcEquipmentRunningSectionService;
+
+    @Override
+    @Transactional(rollbackFor = {Exception.class})
+    public void runningAllEquFaultStatistical(String dateTime) {
+        String validDate = LocalDate.now().minusDays(1).toString().replaceAll("-", "");
+        if (StringUtils.isNotBlank(dateTime)) {
+            validDate = DateUtils.format(DateUtils.toDate(dateTime, DateUtils.STRDATE), DateUtils.STRDATE);
+        }
+        try {
+            this.remove(new LambdaQueryWrapper<MdcEquipmentFaultInfo>().eq(MdcEquipmentFaultInfo::getTheDate, validDate));
+        } catch (Exception e) {
+            log.error("鍙傛暟鏍煎紡涓嶅", e);
+        }
+
+        List<Equipment> equipmentList = equipmentService.list();
+        if (equipmentList == null || equipmentList.isEmpty()) {
+            return;
+        }
+
+        Map<String, MdcEquipmentFaultInfo> map = new HashMap<>();
+        String finalValidDate = validDate;
+        equipmentList.forEach(equipment -> {
+            MdcEquipmentFaultInfo mdcEquipmentFaultInfo = new MdcEquipmentFaultInfo(equipment.getEquipmentid(), finalValidDate);
+            map.put(equipment.getEquipmentid(), mdcEquipmentFaultInfo);
+        });
+
+        String planTime = "00:00:00";
+        MdcSystemParameters mdcSystemParameters = mdcSystemParametersService.getOne(new LambdaQueryWrapper<MdcSystemParameters>().eq(MdcSystemParameters::getCode, "equip_log_statis_time"));
+        if (mdcSystemParameters != null) {
+            planTime = mdcSystemParameters.getValue();
+        }
+
+        List<String> equipmentIdList = equipmentList.stream().map(Equipment::getEquipmentid).collect(Collectors.toList());
+        String startTime = DateUtils.format(DateUtils.setTimeForDay(DateUtils.toDate(validDate, DateUtils.STRDATE), planTime), DateUtils.STR_DATE_TIME_SMALL);
+        Date start = DateUtils.toDate(startTime, DateUtils.STR_DATE_TIME_SMALL);
+        String endTime = DateUtils.format(DateUtils.addDays(DateUtils.toDate(startTime, DateUtils.STR_DATE_TIME_SMALL), 1), DateUtils.STR_DATE_TIME_SMALL);
+        Date end = DateUtils.toDate(endTime, DateUtils.STR_DATE_TIME_SMALL);
+        //鏌ヨ鏁呴殰璁板綍
+        List<EquFaultRecord> equFaultRecordList = this.baseMapper.findFaultRecord(equipmentIdList, startTime, endTime);
+        if (equFaultRecordList != null && !equFaultRecordList.isEmpty()) {
+            // 淇暣鏃堕棿
+            Map<String, List<EquFaultRecord>> equFaultRecordMap = equFaultRecordList.stream().collect(Collectors.groupingBy(EquFaultRecord::getEquipmentId));
+            equFaultRecordMap.forEach((key, value) -> {
+                if (map.containsKey(key)) {
+                    MdcEquipmentFaultInfo equFaultRecords = map.get(key);
+                    long faultLong = calculateTotalFaultDuration(value, start, end);
+                    equFaultRecords.setFaultLong((int) faultLong);
+                    if (faultLong != 0) {
+                        equFaultRecords.setFaultRate(new BigDecimal(faultLong).divide(new BigDecimal("86400"), 2, RoundingMode.HALF_UP));
+                    }
+
+                    // 璁$畻鍘婚櫎鏁呴殰鏃堕暱鐨勫姞宸ユ椂闂�
+                    // step.1 鏌ヨ鍔犲伐鏃堕棿
+                    List<MdcEquipmentRunningSection> mdcEquipmentRunningSections = mdcEquipmentRunningSectionService.selectRunningData(key, start, end);
+                    if (mdcEquipmentRunningSections != null && !mdcEquipmentRunningSections.isEmpty()) {
+                        // 鏃堕棿淇
+                        if (mdcEquipmentRunningSections.get(0).getStartTime().before(start)) {
+                            mdcEquipmentRunningSections.get(0).setStartTime(start);
+                        }
+                        if (mdcEquipmentRunningSections.size() > 1) {
+                            if (mdcEquipmentRunningSections.get(mdcEquipmentRunningSections.size() - 1).getEndTime().after(end)) {
+                                mdcEquipmentRunningSections.get(mdcEquipmentRunningSections.size() - 1).setEndTime(end);
+                            }
+                        } else {
+                            if (mdcEquipmentRunningSections.get(0).getEndTime().after(end)) {
+                                mdcEquipmentRunningSections.get(0).setEndTime(end);
+                            }
+                        }
+                        // step.2 璁$畻鍘婚櫎鏁呴殰鏃堕暱鐨勫姞宸ユ椂闂�
+                        long processingTime = calculateProcessingTimeWithoutFaults(mdcEquipmentRunningSections, value, start, end);
+                        equFaultRecords.setRemoveFaultRunLong((int) processingTime);
+                        if (faultLong != 0) {
+                            // 璁$畻鍘婚櫎鏁呴殰鏃堕暱鐨勫埄鐢ㄧ巼
+                            BigDecimal removeFaultRate = new BigDecimal(processingTime).divide(new BigDecimal("86400").subtract(new BigDecimal(faultLong)), 2, RoundingMode.HALF_UP);
+                            equFaultRecords.setRemoveFaultRate(removeFaultRate);
+                        }
+                    }
+                    map.put(key, equFaultRecords);
+                }
+            });
+        }
+        if (!map.isEmpty()) {
+            this.saveBatch(new ArrayList<>(map.values()));
+        }
+    }
+
+    public static long calculateTotalFaultDuration(List<EquFaultRecord> records, Date startTime, Date endTime) {
+        LocalDateTime start = DateUtils.convertToLocalDateTime(startTime);
+        LocalDateTime end = DateUtils.convertToLocalDateTime(endTime);
+
+        // 淇璁板綍鏃堕棿
+        List<EquFaultRecord> correctedRecords = correctRecordTimes(records, start, end);
+
+        // 鎸夊紑濮嬫椂闂存帓搴�
+        correctedRecords.sort(Comparator.comparing(EquFaultRecord::getStartTime));
+
+        // 鍚堝苟閲嶅彔鏃堕棿娈�
+        List<TimeInterval> mergedIntervals = mergeIntervals(correctedRecords);
+
+        // 璁$畻鎬绘椂闀匡紙绉掞級
+        return mergedIntervals.stream()
+                .mapToLong(interval -> ChronoUnit.SECONDS.between(interval.getStart(), interval.getEnd()))
+                .sum();
+    }
+
+    private static List<EquFaultRecord> correctRecordTimes(List<EquFaultRecord> records, LocalDateTime startTime, LocalDateTime endTime) {
+        return records.stream()
+                .map(record -> {
+                    LocalDateTime recordStart = DateUtils.convertToLocalDateTime(record.getStartTime());
+                    LocalDateTime recordEnd = record.getEndTime() != null ?
+                            DateUtils.convertToLocalDateTime(record.getEndTime()) : null;
+
+                    // 淇寮�濮嬫椂闂�
+                    LocalDateTime correctedStart = recordStart.isBefore(startTime) ?
+                            startTime : recordStart;
+
+                    // 淇缁撴潫鏃堕棿
+                    LocalDateTime correctedEnd = recordEnd == null || recordEnd.isAfter(endTime) ?
+                            endTime : recordEnd;
+
+                    // 鍒涘缓淇鍚庣殑璁板綍
+                    return new EquFaultRecord(
+                            record.getEquipmentId(),
+                            DateUtils.convertToDate(correctedStart),
+                            DateUtils.convertToDate(correctedEnd)
+                    );
+                })
+                .collect(Collectors.toList());
+    }
+
+    private static List<TimeInterval> mergeIntervals(List<EquFaultRecord> records) {
+        List<TimeInterval> intervals = records.stream()
+                .map(record -> new TimeInterval(
+                        DateUtils.convertToLocalDateTime(record.getStartTime()),
+                        DateUtils.convertToLocalDateTime(record.getEndTime())))
+                .collect(Collectors.toList());
+
+        if (intervals.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<TimeInterval> merged = new ArrayList<>();
+        TimeInterval current = intervals.get(0);
+
+        for (int i = 1; i < intervals.size(); i++) {
+            TimeInterval next = intervals.get(i);
+            if (next.getStart().isBefore(current.getEnd()) || next.getStart().equals(current.getEnd())) {
+                // 鏈夐噸鍙狅紝鍚堝苟鍖洪棿
+                current.setEnd(current.getEnd().isAfter(next.getEnd()) ? current.getEnd() : next.getEnd());
+            } else {
+                // 鏃犻噸鍙狅紝娣诲姞褰撳墠鍖洪棿骞舵洿鏂板綋鍓嶅尯闂�
+                merged.add(current);
+                current = next;
+            }
+        }
+        merged.add(current); // 娣诲姞鏈�鍚庝竴涓尯闂�
+
+        return merged;
+    }
+
+    // 璁$畻鍘婚櫎鏁呴殰鏃堕暱鍚庣殑鍔犲伐鏃堕棿
+    private long calculateProcessingTimeWithoutFaults(
+            List<MdcEquipmentRunningSection> runningSections,
+            List<EquFaultRecord> faultRecords,
+            Date startTime,
+            Date endTime) {
+
+        // 杞崲涓篖ocalDateTime杩涜澶勭悊
+        LocalDateTime start = DateUtils.convertToLocalDateTime(startTime);
+        LocalDateTime end = DateUtils.convertToLocalDateTime(endTime);
+
+        // 灏嗘晠闅滆褰曡浆鎹负鏃堕棿鍖洪棿骞跺悎骞堕噸鍙犻儴鍒�
+//        List<TimeInterval> faultIntervals = faultRecords.stream()
+//                .map(record -> new TimeInterval(
+//                        convertToLocalDateTime(record.getStartTime()),
+//                        convertToLocalDateTime(record.getEndTime())))
+//                .collect(Collectors.toList());
+        List<TimeInterval> mergedFaultIntervals = mergeIntervals(faultRecords);
+
+        long totalProcessingTime = 0;
+
+        // 閬嶅巻姣忎釜鍔犲伐鍖洪棿锛屾帓闄ゆ晠闅滄椂闂�
+        for (MdcEquipmentRunningSection section : runningSections) {
+            LocalDateTime sectionStart = DateUtils.convertToLocalDateTime(section.getStartTime());
+            LocalDateTime sectionEnd = DateUtils.convertToLocalDateTime(section.getEndTime());
+
+            // 鎺掗櫎鏁呴殰鏃堕棿鍚庣殑鏈夋晥鍔犲伐鏃堕棿
+            List<TimeInterval> validIntervals = excludeFaultsFromSection(
+                    new TimeInterval(sectionStart, sectionEnd),
+                    mergedFaultIntervals);
+
+            // 绱姞鏈夋晥鍔犲伐鏃堕棿锛堢锛�
+            for (TimeInterval interval : validIntervals) {
+                totalProcessingTime += ChronoUnit.SECONDS.between(interval.getStart(), interval.getEnd());
+            }
+        }
+
+        return totalProcessingTime;
+    }
+
+    // 浠庤繍琛屽尯闂翠腑鎺掗櫎鏁呴殰鏃堕棿
+    private List<TimeInterval> excludeFaultsFromSection(
+            TimeInterval section,
+            List<TimeInterval> faultIntervals) {
+
+        List<TimeInterval> validIntervals = new ArrayList<>();
+        validIntervals.add(section);
+
+        // 閬嶅巻姣忎釜鏁呴殰鍖洪棿锛屼粠鏈夋晥鍖洪棿涓墸闄�
+        for (TimeInterval fault : faultIntervals) {
+            List<TimeInterval> newValidIntervals = new ArrayList<>();
+
+            for (TimeInterval valid : validIntervals) {
+                // 璁$畻鏈夋晥鍖洪棿涓庢晠闅滃尯闂寸殑浜ら泦
+                if (isOverlapping(valid, fault)) {
+                    // 鍒嗗壊鏈夋晥鍖洪棿
+                    splitInterval(valid, fault, newValidIntervals);
+                } else {
+                    // 鏃犱氦闆嗭紝淇濈暀鍘熸湁鏁堝尯闂�
+                    newValidIntervals.add(valid);
+                }
+            }
+
+            validIntervals = newValidIntervals;
+        }
+
+        return validIntervals;
+    }
+
+    // 鍒ゆ柇涓や釜鏃堕棿鍖洪棿鏄惁閲嶅彔
+    private boolean isOverlapping(TimeInterval a, TimeInterval b) {
+        return a.getStart().isBefore(b.getEnd()) && b.getStart().isBefore(a.getEnd());
+    }
+
+    // 鍒嗗壊鍖洪棿锛堟墸闄ら噸鍙犻儴鍒嗭級
+    private void splitInterval(
+            TimeInterval valid,
+            TimeInterval fault,
+            List<TimeInterval> result) {
+
+        // 閲嶅彔鍓嶇殑閮ㄥ垎
+        if (valid.getStart().isBefore(fault.getStart())) {
+            result.add(new TimeInterval(valid.getStart(), fault.getStart()));
+        }
+
+        // 閲嶅彔鍚庣殑閮ㄥ垎
+        if (valid.getEnd().isAfter(fault.getEnd())) {
+            result.add(new TimeInterval(fault.getEnd(), valid.getEnd()));
+        }
+    }
+
+}

--
Gitblit v1.9.3