Lius
2025-06-18 db8133b419aeceed88dbfc2c48cd35509c782375
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentFaultInfoServiceImpl.java
@@ -10,6 +10,7 @@
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;
@@ -47,12 +48,31 @@
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void runningAllEquFaultStatistical(String dateTime) {
        String validDate = LocalDate.now().minusDays(1).toString().replaceAll("-", "");
        Date initDate = null;
        if (StringUtils.isNotBlank(dateTime)) {
            validDate = DateUtils.format(DateUtils.toDate(dateTime, DateUtils.STRDATE), DateUtils.STRDATE);
            initDate = DateUtils.toDate(dateTime, DateUtils.STRDATE);
        } else {
            // 取最后的统计时间
            String date = this.baseMapper.getMaxStaticsData();
            if (date != null) {
                initDate = DateUtils.toDate(date, DateUtils.STRDATE);
            } else {
                // 初次取值 取最早时间记录
                MdcEquipmentRunningSection equipmentRunningSection = mdcEquipmentRunningSectionService.getFirstRecord();
                if (equipmentRunningSection != null) {
                    initDate = equipmentRunningSection.getStartTime();
                }
            }
        }
        Date endDate = DateUtils.addDays(DateUtils.getNow(), -1);
        List<String> dateList = DateUtils.getDatesStringList2(initDate, endDate);
        if (dateList.isEmpty()) {
            return;
        }
        try {
            this.remove(new LambdaQueryWrapper<MdcEquipmentFaultInfo>().eq(MdcEquipmentFaultInfo::getTheDate, validDate));
            this.remove(new LambdaQueryWrapper<MdcEquipmentFaultInfo>().in(MdcEquipmentFaultInfo::getTheDate, dateList));
        } catch (Exception e) {
            log.error("参数格式不对", e);
        }
@@ -62,13 +82,6 @@
            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) {
@@ -76,62 +89,104 @@
        }
        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);
        for (String validDate : dateList) {
            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 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));
                map.forEach((key, value1) -> {
                    MdcEquipmentFaultInfo equFaultRecords = value1;
                    if (equFaultRecordMap.containsKey(key)) {
                        List<EquFaultRecord> value = equFaultRecordMap.get(key);
                        long faultLong = calculateTotalFaultDuration(value, start, end);
                        equFaultRecords.setFaultLong((int) faultLong);
                        if (faultLong != 0) {
                            // 计算去除故障时长的利用率
                            BigDecimal removeFaultRate = new BigDecimal(processingTime).divide(new BigDecimal("86400").subtract(new BigDecimal(faultLong)), 2, RoundingMode.HALF_UP);
                            equFaultRecords.setRemoveFaultRate(removeFaultRate);
                            equFaultRecords.setFaultRate(new BigDecimal(faultLong).divide(new BigDecimal("864"), 2, RoundingMode.HALF_UP));
                        }
                        // 计算去除故障时长的加工时间
                        // step.1 查询加工时间
                        List<MdcEquipmentRunningSection> mdcEquipmentRunningSections = mdcEquipmentRunningSectionService.listEquipmentRunningSectionRun(key, start.getTime(), end.getTime());
                        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);
                                }
                            }
                            List<MdcEquipmentRunningSection> collect = mdcEquipmentRunningSections.stream().filter(mdcEquipmentRunningSection -> mdcEquipmentRunningSection.getStatus() == 3).collect(Collectors.toList());
                            if (!collect.isEmpty()) {
                                // step.2 计算去除故障时长的加工时间
                                long processingTime = calculateProcessingTimeWithoutFaults(collect, value, start, end);
                                equFaultRecords.setRemoveFaultRunLong((int) processingTime);
                                if (faultLong != 0 && faultLong != 86400) {
                                    // 计算去除故障时长的利用率
                                    BigDecimal removeFaultRate = new BigDecimal(processingTime).divide(new BigDecimal("864").subtract(new BigDecimal(faultLong)), 2, RoundingMode.HALF_UP);
                                    equFaultRecords.setRemoveFaultRate(removeFaultRate);
                                }
                            }
                        }
                    } else {
                        List<MdcEquipmentRunningSection> mdcEquipmentRunningSections = mdcEquipmentRunningSectionService.listEquipmentRunningSectionRun(key, start.getTime(), end.getTime());
                        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);
                                }
                            }
                            List<MdcEquipmentRunningSection> collect = mdcEquipmentRunningSections.stream().filter(mdcEquipmentRunningSection -> mdcEquipmentRunningSection.getStatus() == 3).collect(Collectors.toList());
                            if (!collect.isEmpty()) {
                                long totalProcessingTime = 0;
                                for (MdcEquipmentRunningSection mdcEquipmentRunningSection : collect) {
                                    totalProcessingTime += ChronoUnit.SECONDS.between(DateUtils.convertToLocalDateTime(mdcEquipmentRunningSection.getStartTime()), DateUtils.convertToLocalDateTime(mdcEquipmentRunningSection.getEndTime()));
                                }
                                equFaultRecords.setRemoveFaultRunLong((int) totalProcessingTime);
                                // 计算去除故障时长的利用率
                                BigDecimal removeFaultRate = new BigDecimal(totalProcessingTime).divide(new BigDecimal("864"), 2, RoundingMode.HALF_UP);
                                equFaultRecords.setRemoveFaultRate(removeFaultRate);
                            }
                        }
                    }
                    map.put(key, equFaultRecords);
                }
            });
        }
        if (!map.isEmpty()) {
            this.saveBatch(new ArrayList<>(map.values()));
                });
            }
            if (!map.isEmpty()) {
                this.saveBatch(new ArrayList<>(map.values()));
            }
        }
    }
    public static long calculateTotalFaultDuration(List<EquFaultRecord> records, Date startTime, Date endTime) {
        LocalDateTime start = convertToLocalDateTime(startTime);
        LocalDateTime end = convertToLocalDateTime(endTime);
        LocalDateTime start = DateUtils.convertToLocalDateTime(startTime);
        LocalDateTime end = DateUtils.convertToLocalDateTime(endTime);
        // 修正记录时间
        List<EquFaultRecord> correctedRecords = correctRecordTimes(records, start, end);
@@ -144,16 +199,16 @@
        // 计算总时长(秒)
        return mergedIntervals.stream()
                .mapToLong(interval -> ChronoUnit.SECONDS.between(interval.start, interval.end))
                .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 = convertToLocalDateTime(record.getStartTime());
                    LocalDateTime recordStart = DateUtils.convertToLocalDateTime(record.getStartTime());
                    LocalDateTime recordEnd = record.getEndTime() != null ?
                            convertToLocalDateTime(record.getEndTime()) : null;
                            DateUtils.convertToLocalDateTime(record.getEndTime()) : null;
                    // 修正开始时间
                    LocalDateTime correctedStart = recordStart.isBefore(startTime) ?
@@ -166,8 +221,8 @@
                    // 创建修正后的记录
                    return new EquFaultRecord(
                            record.getEquipmentId(),
                            convertToDate(correctedStart),
                            convertToDate(correctedEnd)
                            DateUtils.convertToDate(correctedStart),
                            DateUtils.convertToDate(correctedEnd)
                    );
                })
                .collect(Collectors.toList());
@@ -176,8 +231,8 @@
    private static List<TimeInterval> mergeIntervals(List<EquFaultRecord> records) {
        List<TimeInterval> intervals = records.stream()
                .map(record -> new TimeInterval(
                        convertToLocalDateTime(record.getStartTime()),
                        convertToLocalDateTime(record.getEndTime())))
                        DateUtils.convertToLocalDateTime(record.getStartTime()),
                        DateUtils.convertToLocalDateTime(record.getEndTime())))
                .collect(Collectors.toList());
        if (intervals.isEmpty()) {
@@ -189,9 +244,9 @@
        for (int i = 1; i < intervals.size(); i++) {
            TimeInterval next = intervals.get(i);
            if (next.start.isBefore(current.end) || next.start.equals(current.end)) {
            if (next.getStart().isBefore(current.getEnd()) || next.getStart().equals(current.getEnd())) {
                // 有重叠,合并区间
                current.end = current.end.isAfter(next.end) ? current.end : next.end;
                current.setEnd(current.getEnd().isAfter(next.getEnd()) ? current.getEnd() : next.getEnd());
            } else {
                // 无重叠,添加当前区间并更新当前区间
                merged.add(current);
@@ -203,33 +258,6 @@
        return merged;
    }
    // Date与LocalDateTime互相转换的工具方法
    private static LocalDateTime convertToLocalDateTime(Date date) {
        if (date == null) {
            return null;
        }
        return Instant.ofEpochMilli(date.getTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }
    private static Date convertToDate(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }
    static class TimeInterval {
        LocalDateTime start;
        LocalDateTime end;
        public TimeInterval(LocalDateTime start, LocalDateTime end) {
            this.start = start;
            this.end = end;
        }
    }
    // 计算去除故障时长后的加工时间
    private long calculateProcessingTimeWithoutFaults(
            List<MdcEquipmentRunningSection> runningSections,
@@ -238,23 +266,19 @@
            Date endTime) {
        // 转换为LocalDateTime进行处理
        LocalDateTime start = convertToLocalDateTime(startTime);
        LocalDateTime end = convertToLocalDateTime(endTime);
        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);
        // 修正记录时间
        List<EquFaultRecord> correctedRecords = correctRecordTimes(faultRecords, start, end);
        List<TimeInterval> mergedFaultIntervals = mergeIntervals(correctedRecords);
        long totalProcessingTime = 0;
        // 遍历每个加工区间,排除故障时间
        for (MdcEquipmentRunningSection section : runningSections) {
            LocalDateTime sectionStart = convertToLocalDateTime(section.getStartTime());
            LocalDateTime sectionEnd = convertToLocalDateTime(section.getEndTime());
            LocalDateTime sectionStart = DateUtils.convertToLocalDateTime(section.getStartTime());
            LocalDateTime sectionEnd = DateUtils.convertToLocalDateTime(section.getEndTime());
            // 排除故障时间后的有效加工时间
            List<TimeInterval> validIntervals = excludeFaultsFromSection(
@@ -263,7 +287,7 @@
            // 累加有效加工时间(秒)
            for (TimeInterval interval : validIntervals) {
                totalProcessingTime += ChronoUnit.SECONDS.between(interval.start, interval.end);
                totalProcessingTime += ChronoUnit.SECONDS.between(interval.getStart(), interval.getEnd());
            }
        }
@@ -301,7 +325,7 @@
    // 判断两个时间区间是否重叠
    private boolean isOverlapping(TimeInterval a, TimeInterval b) {
        return a.start.isBefore(b.end) && b.start.isBefore(a.end);
        return a.getStart().isBefore(b.getEnd()) && b.getStart().isBefore(a.getEnd());
    }
    // 分割区间(扣除重叠部分)
@@ -311,13 +335,13 @@
            List<TimeInterval> result) {
        // 重叠前的部分
        if (valid.start.isBefore(fault.start)) {
            result.add(new TimeInterval(valid.start, fault.start));
        if (valid.getStart().isBefore(fault.getStart())) {
            result.add(new TimeInterval(valid.getStart(), fault.getStart()));
        }
        // 重叠后的部分
        if (valid.end.isAfter(fault.end)) {
            result.add(new TimeInterval(fault.end, valid.end));
        if (valid.getEnd().isAfter(fault.getEnd())) {
            result.add(new TimeInterval(fault.getEnd(), valid.getEnd()));
        }
    }