From 7a4f8a4a29150672a487261995e4e871918318d5 Mon Sep 17 00:00:00 2001 From: wangyu <823267011@qq.com> Date: Wed, 13 May 2026 17:09:00 +0800 Subject: [PATCH] =?UTF-8?q?oee=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=8F=90?= =?UTF-8?q?=E4=BA=A4app=E5=90=8C=E6=AD=A5=E4=BB=A5=E5=8F=8A=E8=B4=A8?= =?UTF-8?q?=E4=BF=9D=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acid/service/impl/AcidOeeServiceImpl.java | 49 ++++++++------- .../service/impl/GalvanizeOeeServiceImpl.java | 61 +++++++++++++++++-- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/klp-pocket/src/main/java/com/klp/pocket/acid/service/impl/AcidOeeServiceImpl.java b/klp-pocket/src/main/java/com/klp/pocket/acid/service/impl/AcidOeeServiceImpl.java index 81954864..077ce185 100644 --- a/klp-pocket/src/main/java/com/klp/pocket/acid/service/impl/AcidOeeServiceImpl.java +++ b/klp-pocket/src/main/java/com/klp/pocket/acid/service/impl/AcidOeeServiceImpl.java @@ -63,8 +63,9 @@ public class AcidOeeServiceImpl implements IAcidOeeService { if (summaries == null || summaries.isEmpty()) { return Collections.emptyList(); } - // 2. 查询停机事件,按日期聚合停机时间 - Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate); + // 2. 按日聚合:计划停机、非计划停机(一次拉取,按 stopType 分流) + Map plannedDowntimeByDate = new HashMap<>(); + Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate, plannedDowntimeByDate); // 3. 查询产量明细,用于良品/次品判定 Map> coilInfoByDate = getCoilNosByDate(startDate, endDate); @@ -76,10 +77,14 @@ public class AcidOeeServiceImpl implements IAcidOeeService { summary.setLineId("SY"); summary.setLineName("酸轧线"); + Long plannedDowntime = plannedDowntimeByDate.getOrDefault(statDate, 0L); + Long loadingTime = Math.max(0, 1440 - plannedDowntime); + summary.setPlannedDowntimeMin(plannedDowntime); + summary.setLoadingTimeMin(loadingTime); + Long downtime = downtimeByDate.getOrDefault(statDate, 0L); summary.setDowntimeMin(downtime); - Long loadingTime = summary.getLoadingTimeMin() != null ? summary.getLoadingTimeMin() : 0L; Long runTime = Math.max(0, loadingTime - downtime); summary.setRunTimeMin(runTime); @@ -168,12 +173,16 @@ public class AcidOeeServiceImpl implements IAcidOeeService { return rsp; } - // 2) 聚合停机,补齐 runTime - Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate); + // 2) 聚合停机,补齐 loadingTime / runTime + Map plannedDowntimeByDate2 = new HashMap<>(); + Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate, plannedDowntimeByDate2); for (AcidOeeDailySummaryVo d : daily) { + Long plannedDowntime = plannedDowntimeByDate2.getOrDefault(d.getStatDate(), 0L); + Long loading = Math.max(0, 1440 - plannedDowntime); + d.setPlannedDowntimeMin(plannedDowntime); + d.setLoadingTimeMin(loading); Long downtime = downtimeByDate.getOrDefault(d.getStatDate(), 0L); d.setDowntimeMin(downtime); - Long loading = d.getLoadingTimeMin() != null ? d.getLoadingTimeMin() : 0L; d.setRunTimeMin(Math.max(0, loading - downtime)); } @@ -294,11 +303,12 @@ public class AcidOeeServiceImpl implements IAcidOeeService { } /** - * 按日期聚合停机时间 - * 修复:如果停机事件跨天,需要按实际跨天的分钟数分配到对应的日期 + * 按日期聚合停机时间,同时将计划停机单独写入 plannedDowntimeOut。 + * - "计划停机" stopType 不计入 OEE 停机时间,也不计入负荷时间。 + * - 跨天事件按实际分钟数拆分到各天。 */ - private Map aggregateDowntimeByDate(String startDate, String endDate) { - // 性能稼动率/运转时间口径:停机时间需要包含短停机(<5min),否则 runTime 被高估 + private Map aggregateDowntimeByDate(String startDate, String endDate, + Map plannedDowntimeOut) { List events = getStoppageEvents(startDate, endDate, true); Map downtimeMap = new HashMap<>(); @@ -310,45 +320,40 @@ public class AcidOeeServiceImpl implements IAcidOeeService { continue; } + boolean isPlanned = "计划停机".equals(event.getStopType()); + Map targetMap = isPlanned ? plannedDowntimeOut : downtimeMap; + Date eventStart = event.getStartDate(); long durationSec = event.getDuration(); - long durationMin = (durationSec + 59) / 60; // 向上取整,避免丢失秒数 + long durationMin = (durationSec + 59) / 60; - // 计算停机结束时间 cal.setTime(eventStart); cal.add(Calendar.SECOND, (int) durationSec); Date eventEnd = cal.getTime(); - // 如果停机事件在同一天,直接累加 String startDateStr = dateFormat.format(eventStart); String endDateStr = dateFormat.format(eventEnd); if (startDateStr.equals(endDateStr)) { - // 同一天,直接累加 - downtimeMap.merge(startDateStr, durationMin, Long::sum); + targetMap.merge(startDateStr, durationMin, Long::sum); } else { - // 跨天:按实际跨天的分钟数分配到对应的日期 cal.setTime(eventStart); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); - Date dayStart = cal.getTime(); - - Date currentDayStart = dayStart; + Date currentDayStart = cal.getTime(); while (currentDayStart.before(eventEnd)) { cal.setTime(currentDayStart); cal.add(Calendar.DAY_OF_MONTH, 1); Date nextDayStart = cal.getTime(); - // 计算当前天的停机分钟数 Date dayEnd = nextDayStart.before(eventEnd) ? nextDayStart : eventEnd; long dayMinutes = Math.max(0, (dayEnd.getTime() - Math.max(currentDayStart.getTime(), eventStart.getTime())) / (1000 * 60)); if (dayMinutes > 0) { - String dateKey = dateFormat.format(currentDayStart); - downtimeMap.merge(dateKey, dayMinutes, Long::sum); + targetMap.merge(dateFormat.format(currentDayStart), dayMinutes, Long::sum); } currentDayStart = nextDayStart; diff --git a/klp-pocket/src/main/java/com/klp/pocket/galvanize1/service/impl/GalvanizeOeeServiceImpl.java b/klp-pocket/src/main/java/com/klp/pocket/galvanize1/service/impl/GalvanizeOeeServiceImpl.java index 7dd8700c..f66c1294 100644 --- a/klp-pocket/src/main/java/com/klp/pocket/galvanize1/service/impl/GalvanizeOeeServiceImpl.java +++ b/klp-pocket/src/main/java/com/klp/pocket/galvanize1/service/impl/GalvanizeOeeServiceImpl.java @@ -39,16 +39,20 @@ public class GalvanizeOeeServiceImpl implements IGalvanizeOeeService { List summaries = galvanizeOeeMasterMapper.selectDailySummary(startDate, endDate, galvanizeCreateBy); if (summaries == null || summaries.isEmpty()) return Collections.emptyList(); - Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate); + Map plannedDowntimeByDate = new HashMap<>(); + Map downtimeByDate = aggregateDowntimeByDate(startDate, endDate, plannedDowntimeByDate); Map> coilInfoByDate = getCoilNosByDate(startDate, endDate); List dailyCycles = new ArrayList<>(); for (AcidOeeDailySummaryVo s : summaries) { s.setLineId("DX1"); s.setLineName("镀锌一线"); + Long plannedDowntime = plannedDowntimeByDate.getOrDefault(s.getStatDate(), 0L); + Long loading = Math.max(0, 1440 - plannedDowntime); + s.setPlannedDowntimeMin(plannedDowntime); + s.setLoadingTimeMin(loading); Long downtime = downtimeByDate.getOrDefault(s.getStatDate(), 0L); s.setDowntimeMin(downtime); - Long loading = s.getLoadingTimeMin() == null ? 0L : s.getLoadingTimeMin(); Long run = Math.max(0, loading - downtime); s.setRunTimeMin(run); BigDecimal ton = s.getTotalOutputTon(); @@ -230,15 +234,62 @@ public class GalvanizeOeeServiceImpl implements IGalvanizeOeeService { } } - private Map aggregateDowntimeByDate(String startDate, String endDate) { + /** + * 按日期聚合停机时间,同时将计划停机写入 plannedDowntimeOut。 + * - "计划停机" stopType 不计入 OEE 停机时间,也不计入负荷时间。 + * - 跨天事件按实际分钟数拆分到各天。 + */ + private Map aggregateDowntimeByDate(String startDate, String endDate, + Map plannedDowntimeOut) { List events = getStoppageEvents(startDate, endDate); Map map = new HashMap<>(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + Calendar cal = Calendar.getInstance(); + for (Klptcm1ProStoppageVo e : events) { if (e.getStartDate() == null || e.getDuration() == null || e.getDuration() <= 0) continue; - long min = Math.max(1, (e.getDuration() + 59) / 60); - map.merge(df.format(e.getStartDate()), min, Long::sum); + + boolean isPlanned = "计划停机".equals(e.getStopType()); + Map targetMap = isPlanned ? plannedDowntimeOut : map; + + Date eventStart = e.getStartDate(); + long durationSec = e.getDuration(); + long durationMin = (durationSec + 59) / 60; + + cal.setTime(eventStart); + cal.add(Calendar.SECOND, (int) durationSec); + Date eventEnd = cal.getTime(); + + String startDateStr = df.format(eventStart); + String endDateStr = df.format(eventEnd); + + if (startDateStr.equals(endDateStr)) { + targetMap.merge(startDateStr, durationMin, Long::sum); + } else { + cal.setTime(eventStart); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + Date currentDayStart = cal.getTime(); + + while (currentDayStart.before(eventEnd)) { + cal.setTime(currentDayStart); + cal.add(Calendar.DAY_OF_MONTH, 1); + Date nextDayStart = cal.getTime(); + + Date dayEnd = nextDayStart.before(eventEnd) ? nextDayStart : eventEnd; + long dayMinutes = Math.max(0, (dayEnd.getTime() - Math.max(currentDayStart.getTime(), eventStart.getTime())) / (1000 * 60)); + + if (dayMinutes > 0) { + targetMap.merge(df.format(currentDayStart), dayMinutes, Long::sum); + } + + currentDayStart = nextDayStart; + } + } } + return map; }