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