package cn.iocoder.yudao.module.mes.service.home; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.module.mes.controller.admin.home.vo.MesHomeProductionTrendRespVO; import cn.iocoder.yudao.module.mes.controller.admin.home.vo.MesHomeSummaryRespVO; import cn.iocoder.yudao.module.mes.controller.admin.home.vo.MesHomeWorkOrderStatusRespVO; import cn.iocoder.yudao.module.mes.dal.mysql.home.MesHomeStatisticsMapper; import cn.iocoder.yudao.module.mes.enums.dv.MesDvMachineryStatusEnum; import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; /** * MES 首页统计 Service 实现类 * * @author 芋道源码 */ @Service public class MesHomeStatisticsServiceImpl implements MesHomeStatisticsService { @Resource private MesHomeStatisticsMapper homeStatisticsMapper; @Override public MesHomeSummaryRespVO getHomeSummary() { MesHomeSummaryRespVO summary = new MesHomeSummaryRespVO(); // 1. 工单统计 List> workOrderStats = homeStatisticsMapper.selectWorkOrderCountGroupByStatus(); long activeCount = 0L; long prepareCount = 0L; long finishedCount = 0L; for (Map stat : workOrderStats) { int status = ((Number) stat.get("status")).intValue(); long count = ((Number) stat.get("count")).longValue(); if (status == MesProWorkOrderStatusEnum.CONFIRMED.getStatus()) { activeCount = count; } else if (status == MesProWorkOrderStatusEnum.PREPARE.getStatus()) { prepareCount = count; } else if (status == MesProWorkOrderStatusEnum.FINISHED.getStatus()) { finishedCount = count; } } summary.setWorkOrderActiveCount(activeCount); summary.setWorkOrderPrepareCount(prepareCount); summary.setWorkOrderFinishedCount(finishedCount); // 2. 今日产量 LocalDateTime today = LocalDateTimeUtils.getToday(); LocalDateTime yesterday = LocalDateTimeUtils.getYesterday(); Map todayFeedback = homeStatisticsMapper.selectFeedbackSummary(today, null); summary.setTodayOutput(getDecimal(todayFeedback, "feedbackQuantity")); summary.setTodayQualifiedQuantity(getDecimal(todayFeedback, "qualifiedQuantity")); summary.setTodayUnqualifiedQuantity(getDecimal(todayFeedback, "unqualifiedQuantity")); // 3. 昨日产量 Map yesterdayFeedback = homeStatisticsMapper.selectFeedbackSummary(yesterday, today); summary.setYesterdayOutput(getDecimal(yesterdayFeedback, "feedbackQuantity")); // 4. 设备统计 List> machineryStats = homeStatisticsMapper.selectMachineryCountGroupByStatus(); long total = 0L; long producing = 0L; long stop = 0L; long maintenance = 0L; for (Map stat : machineryStats) { int status = ((Number) stat.get("status")).intValue(); long count = ((Number) stat.get("count")).longValue(); total += count; if (status == MesDvMachineryStatusEnum.PRODUCING.getStatus()) { producing = count; } else if (status == MesDvMachineryStatusEnum.STOP.getStatus()) { stop = count; } else if (status == MesDvMachineryStatusEnum.MAINTENANCE.getStatus()) { maintenance = count; } } summary.setMachineryTotal(total); summary.setMachineryProducing(producing); summary.setMachineryStop(stop); summary.setMachineryMaintenance(maintenance); // 5. 异常/待办 summary.setAndonActiveCount(homeStatisticsMapper.selectAndonActiveCount()); summary.setRepairActiveCount(homeStatisticsMapper.selectRepairActiveCount()); return summary; } @Override public List getWorkOrderStatusDistribution() { List> stats = homeStatisticsMapper.selectWorkOrderCountGroupByStatus(); List result = new ArrayList<>(); for (MesProWorkOrderStatusEnum statusEnum : MesProWorkOrderStatusEnum.values()) { long count = 0L; for (Map stat : stats) { if (((Number) stat.get("status")).intValue() == statusEnum.getStatus()) { count = ((Number) stat.get("count")).longValue(); break; } } result.add(new MesHomeWorkOrderStatusRespVO(statusEnum.getStatus(), statusEnum.getName(), count)); } return result; } @Override public List getProductionTrend(Integer days) { LocalDate endDate = LocalDate.now().plusDays(1); LocalDate startDate = endDate.minusDays(days); LocalDateTime beginTime = startDate.atStartOfDay(); LocalDateTime endTime = endDate.atStartOfDay(); // 查询数据库 List> dbData = homeStatisticsMapper.selectDailyFeedbackTrend(beginTime, endTime); Map> dateMap = new LinkedHashMap<>(); for (Map row : dbData) { dateMap.put((String) row.get("date"), row); } // 补全所有日期(无数据的日期填 0) DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); List result = new ArrayList<>(); for (LocalDate d = startDate; d.isBefore(endDate); d = d.plusDays(1)) { String dateStr = d.format(fmt); Map row = dateMap.get(dateStr); MesHomeProductionTrendRespVO vo = new MesHomeProductionTrendRespVO(); vo.setDate(dateStr); if (row != null) { vo.setQuantity(getDecimalFromObj(row.get("quantity"))); vo.setQualifiedQuantity(getDecimalFromObj(row.get("qualifiedQuantity"))); vo.setUnqualifiedQuantity(getDecimalFromObj(row.get("unqualifiedQuantity"))); } else { vo.setQuantity(BigDecimal.ZERO); vo.setQualifiedQuantity(BigDecimal.ZERO); vo.setUnqualifiedQuantity(BigDecimal.ZERO); } result.add(vo); } return result; } // ========== 工具方法 ========== private BigDecimal getDecimal(Map map, String key) { if (map == null || map.get(key) == null) { return BigDecimal.ZERO; } return map.get(key); } private BigDecimal getDecimalFromObj(Object obj) { if (obj == null) { return BigDecimal.ZERO; } if (obj instanceof BigDecimal) { return (BigDecimal) obj; } return new BigDecimal(obj.toString()); } }