package org.jeecg.modules.mdc.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.StringUtils; import org.jeecg.modules.mdc.constant.MdcConstant; import org.jeecg.modules.mdc.entity.MdcEquipment; import org.jeecg.modules.mdc.entity.MdcOverallEquipmentEfficiency; import org.jeecg.modules.mdc.entity.MdcStandardProcessDuration; import org.jeecg.modules.mdc.mapper.MdcOverallEquipmentEfficiencyMapper; import org.jeecg.modules.mdc.service.*; import org.jeecg.modules.mdc.util.DateUtils; import org.jeecg.modules.mdc.vo.MdcOverallEquipmentEfficiencyVo; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.YearMonth; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author: LiuS * @create: 2023-10-18 09:25 */ @Service public class MdcOverallEquipmentEfficiencyServiceImpl extends ServiceImpl implements IMdcOverallEquipmentEfficiencyService { @Resource private IMdcEquipmentService mdcEquipmentService; @Resource private IMdcEquipmentOvertimeService mdcEquipmentOvertimeService; @Resource private IMdcDeviceCalendarService mdcDeviceCalendarService; @Resource private IMdcNoplanCloseService mdcNoplanCloseService; @Resource private IMdcPlanCloseService mdcPlanCloseService; @Resource private IMdcPassRateService mdcPassRateService; @Resource private IMdcStandardProcessDurationService mdcStandardProcessDurationService; @Resource private IMdcEquipmentStatisticalShiftInfoService mdcEquipmentStatisticalShiftInfoService; @Resource private IProcessCountService processCountService; /** * 计算设备综合效率OEE */ @Override public void runningOverallEquipmentEfficiency(String dateTime) { /* OEE = 时间开动率 × 性能开动率 × 合格品率 时间开动率 = (负荷时间 - 非计划停机时间) / 负荷时间 × 100% 性能开动率 = 净开动时间 / 开动时间 × 100% 合格品率 = 加工数量 - 不合格数量 / 加工数量 负荷时间 = 日历工作时间 - 计划停机时间 非计划停机时间 = 负荷时间 - 主轴运转时间 工作日历时间 = 日历时间 - 法定假日 - 双休日 + 加班时间 净开动时间 = 标准加工时间 × 加工数量 */ List result = new ArrayList<>(); // 获取有效日期 格式 yyyy-MM String validDate = YearMonth.now().minusMonths(1).toString(); if (StringUtils.isNotBlank(dateTime)) { validDate = DateUtils.format(DateUtils.toDate(dateTime, "yyyyMM"), DateUtils.STR_YEAR_MONTH); try { if (validDate != null) { this.remove(new LambdaQueryWrapper(). eq(MdcOverallEquipmentEfficiency::getValidDate, validDate)); } } catch (Exception e) { log.error("参数格式不对", e); } } // 获取设备列表 // List equipmentList = mdcEquipmentService.list(new LambdaQueryWrapper().eq(MdcEquipment::getEquipmentId, "2140198")); List equipmentList = mdcEquipmentService.list(); for (MdcEquipment mdcEquipment : equipmentList) { String equipmentId = mdcEquipment.getEquipmentId(); MdcOverallEquipmentEfficiency mdcOverallEquipmentEfficiency = new MdcOverallEquipmentEfficiency(); // 时间开动率计算 mdcOverallEquipmentEfficiency.setEquipmentId(equipmentId); mdcOverallEquipmentEfficiency.setEquipmentName(mdcEquipment.getEquipmentName()); mdcOverallEquipmentEfficiency.setEquipmentModel(mdcEquipment.getEquipmentModel()); mdcOverallEquipmentEfficiency.setValidDate(validDate); // 查询班制分类 List shiftSubIdList = mdcDeviceCalendarService.findShiftSort(equipmentId, validDate); if (shiftSubIdList != null && !shiftSubIdList.isEmpty()) { String shift = String.join(",", shiftSubIdList); mdcOverallEquipmentEfficiency.setShift(shift); } else { mdcOverallEquipmentEfficiency.setShift("无"); } if (StringUtils.isEmpty(mdcOverallEquipmentEfficiency.getShift())) { mdcOverallEquipmentEfficiency.setShiftTimeCount(BigDecimal.ZERO); } else { mdcOverallEquipmentEfficiency.setShiftTimeCount(new BigDecimal("8")); } // TODO 计算加班时间 BigDecimal overtime = mdcEquipmentOvertimeService.computeOvertime(equipmentId, validDate); mdcOverallEquipmentEfficiency.setOvertime(overtime); // 计算实际班产天数 BigDecimal actualWorkDayCount = mdcDeviceCalendarService.computeActualWorkDayCount(equipmentId, validDate); mdcOverallEquipmentEfficiency.setActualWorkDayCount(actualWorkDayCount); // 月度实际班产总时间(分钟) mdcOverallEquipmentEfficiency.setMonthActualWorkDayTimeCount(mdcOverallEquipmentEfficiency.getShiftTimeCount().multiply(actualWorkDayCount).multiply(new BigDecimal("60")).add(overtime)); // // 故障停机时长统计(分钟) // BigDecimal breakdownDownDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.BREAKDOWN_DOWN); // mdcOverallEquipmentEfficiency.setBreakdownDownDuration(breakdownDownDuration); // // 换型调试时长统计(分钟) // BigDecimal conversionDebugDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.CONVERSION_DEBUG); // mdcOverallEquipmentEfficiency.setConversionDebugDuration(conversionDebugDuration); // // 物料短缺时长统计(分钟) // BigDecimal materialShortageDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.MATERIAL_SHORTAGE); // mdcOverallEquipmentEfficiency.setMaterialShortageDuration(materialShortageDuration); // // 计划等任务时长统计(分钟) // BigDecimal plannedTaskDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.PLANNED_TASK); // mdcOverallEquipmentEfficiency.setPlannedTaskDuration(plannedTaskDuration); // // 检验时长统计(分钟) // BigDecimal inspectDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.INSPECT); // mdcOverallEquipmentEfficiency.setInspectDuration(inspectDuration); // // 其他时长统计(分钟) // BigDecimal otherDuration = mdcNoplanCloseService.findNoplanTimeDuration(equipmentId, validDate, MdcConstant.OTHER); // mdcOverallEquipmentEfficiency.setOtherDuration(otherDuration); // // 计划保养时长统计(分钟) // BigDecimal plannedMaintenanceDuration = mdcPlanCloseService.findPlanTimeDuration(actualWorkDayCount, MdcConstant.PLANNED_MAINTENANCE); // mdcOverallEquipmentEfficiency.setPlannedMaintenanceDuration(plannedMaintenanceDuration); // // 会议/培训时长统计(分钟) // BigDecimal conferenceTrainingDuration = mdcPlanCloseService.findPlanTimeDuration(actualWorkDayCount, MdcConstant.CONFERENCE_TRAINING); // mdcOverallEquipmentEfficiency.setConferenceTrainingDuration(conferenceTrainingDuration); // // 其它休息时长统计(分钟) // BigDecimal otherRestDuration = mdcPlanCloseService.findPlanTimeDuration(actualWorkDayCount, MdcConstant.OTHER_REST); // mdcOverallEquipmentEfficiency.setOtherRestDuration(otherRestDuration); /* 负荷时间(小时) = 工作日历时间 - 计划停机时间 工作日历时间 = 日历时间 - 法定假日 - 双休日 + 加班时间 计划停机时间 = 计划保养时长 + 会议/培训时长 + 会议/培训时长 */ // mdcOverallEquipmentEfficiency.getShiftTimeCount() - plannedMaintenanceDuration - conferenceTrainingDuration - otherRestDuration // 负荷时间(分钟) // BigDecimal loadTime = mdcOverallEquipmentEfficiency.getMonthActualWorkDayTimeCount().subtract(plannedMaintenanceDuration).subtract(conferenceTrainingDuration).subtract(otherRestDuration); // if (loadTime.compareTo(BigDecimal.ZERO) < 0) { // loadTime = BigDecimal.ZERO; // } // mdcOverallEquipmentEfficiency.setLoadTime(loadTime.divide(new BigDecimal("60"), 1, RoundingMode.HALF_UP)); // 时间开动率 = 主轴运行时间/负荷时间 // 查询主轴运行时间(分钟) // BigDecimal spindleRunDuration = mdcEquipmentStatisticalShiftInfoService.findSpindleRunDuration(equipmentId, validDate); // BigDecimal timeActuationRate = BigDecimal.ZERO; // if (loadTime.compareTo(BigDecimal.ZERO) == 0) { // mdcOverallEquipmentEfficiency.setTimeActuationRate(BigDecimal.ZERO); // } else { // timeActuationRate = spindleRunDuration.divide(loadTime, 4, RoundingMode.HALF_UP); // mdcOverallEquipmentEfficiency.setTimeActuationRate(timeActuationRate); // } // BigDecimal processQuantity; // // 加工零件数(件) processQuantity // if ("FANUC".equals(mdcEquipment.getDriveType())) { // processQuantity = processCountService.findCount(equipmentId, validDate); // } else { // processQuantity = mdcPassRateService.findProcessQuantity(equipmentId, validDate); // } // mdcOverallEquipmentEfficiency.setProcessQuantity(processQuantity); // // // 标准加工时间(分钟) // MdcStandardProcessDuration mdcStandardProcessDuration = mdcStandardProcessDurationService.getOne(new LambdaQueryWrapper().eq(MdcStandardProcessDuration::getEquipmentId, equipmentId)); // if (mdcStandardProcessDuration != null) { // mdcOverallEquipmentEfficiency.setStandardProcessDuration(new BigDecimal(mdcStandardProcessDuration.getDuration()).multiply(processQuantity)); // } else { // mdcOverallEquipmentEfficiency.setStandardProcessDuration(BigDecimal.ZERO); // } // if ("FANUC".equals(mdcEquipment.getDriveType())) { // // (新)性能开动率 = 理论标准加工时长 * 件数 /(主轴运行时间) // // 查询法兰克设备标准加工时长(秒) // BigDecimal duration = processCountService.findDuration(mdcEquipment.getEquipmentId(), validDate); // if (spindleRunDuration.compareTo(BigDecimal.ZERO) != 0 && duration.compareTo(BigDecimal.ZERO) != 0) { // mdcOverallEquipmentEfficiency.setStandardProcessDuration(duration.divide(new BigDecimal("60"), 0, RoundingMode.HALF_UP)); // BigDecimal performanceRate = duration.divide(new BigDecimal("60"), 0, RoundingMode.HALF_UP).divide(spindleRunDuration, 4, RoundingMode.HALF_UP); // if (performanceRate.compareTo(BigDecimal.ONE) == 1) { // performanceRate = new BigDecimal("0.95").add(BigDecimal.valueOf(Math.random() * 5).divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP)); // } // mdcOverallEquipmentEfficiency.setPerformanceRate(performanceRate); // } else { // mdcOverallEquipmentEfficiency.setPerformanceRate(BigDecimal.ZERO); // } // } else { // // (旧)性能开动率 = 主轴运行时间/负荷时间 // if (loadTime.compareTo(BigDecimal.ZERO) != 0) { // mdcOverallEquipmentEfficiency.setPerformanceRate(spindleRunDuration.divide(loadTime, 4, RoundingMode.HALF_UP)); // } else { // mdcOverallEquipmentEfficiency.setPerformanceRate(BigDecimal.ZERO); // } // } // 废品数 unqualifiedQuantity // BigDecimal unqualifiedQuantity = mdcPassRateService.findUnqualifiedQuantity(equipmentId, validDate); // mdcOverallEquipmentEfficiency.setUnqualifiedQuantity(unqualifiedQuantity); // // 合格率 // if (processQuantity.compareTo(BigDecimal.ZERO) == 0) { // mdcOverallEquipmentEfficiency.setPassRate(BigDecimal.ONE); // } else { // mdcOverallEquipmentEfficiency.setPassRate((processQuantity.subtract(unqualifiedQuantity)).divide(processQuantity, 4, RoundingMode.HALF_UP)); // } // // // 设备综合效率 = 时间开动率 × 性能开动率 × 合格品率 // mdcOverallEquipmentEfficiency.setOverallEquipmentEfficiency(timeActuationRate.multiply(mdcOverallEquipmentEfficiency.getPerformanceRate()).multiply(mdcOverallEquipmentEfficiency.getPassRate()).setScale(4, RoundingMode.HALF_UP)); // if (mdcOverallEquipmentEfficiency.getOverallEquipmentEfficiency().compareTo(BigDecimal.ZERO) == 0) { // mdcOverallEquipmentEfficiency.setOverallEquipmentEfficiency(BigDecimal.ZERO); // } result.add(mdcOverallEquipmentEfficiency); } super.saveBatch(result); } /** * 分页列表查询 * * @param userId * @param page * @param mdcOverallEquipmentEfficiencyVo * @param req * @return */ @Override public IPage pageList(String userId, Page page, MdcOverallEquipmentEfficiencyVo mdcOverallEquipmentEfficiencyVo, HttpServletRequest req) { List equipmentIds = new ArrayList<>(); if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getParentId()) && StringUtils.isEmpty(mdcOverallEquipmentEfficiencyVo.getEquipmentId())) { if ("2".equals(mdcOverallEquipmentEfficiencyVo.getTypeTree())) { // 部门层级 equipmentIds = mdcEquipmentService.getEquipmentIdsByDepart(userId, mdcOverallEquipmentEfficiencyVo.getParentId()); } else { // 产线层级 equipmentIds = mdcEquipmentService.getEquipmentIdsProduction(userId, mdcOverallEquipmentEfficiencyVo.getParentId()); } } else if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getEquipmentId())) { // 单台设备信息 mdcOverallEquipmentEfficiencyVo.setEquipmentIdList(Collections.singletonList(mdcOverallEquipmentEfficiencyVo.getEquipmentId())); } else { // 查询用户拥有的所有设备信息 if ("2".equals(mdcOverallEquipmentEfficiencyVo.getTypeTree())) { // 部门层级 equipmentIds = mdcEquipmentService.getEquipmentIdsByDepart(userId, null); } else { // 产线层级 equipmentIds = mdcEquipmentService.getEquipmentIdsProduction(userId, null); } } if (mdcOverallEquipmentEfficiencyVo.getEquipmentIdList() == null || mdcOverallEquipmentEfficiencyVo.getEquipmentIdList().isEmpty()) { mdcOverallEquipmentEfficiencyVo.setEquipmentIdList(equipmentIds); } if (mdcOverallEquipmentEfficiencyVo.getEquipmentIdList() == null || mdcOverallEquipmentEfficiencyVo.getEquipmentIdList().isEmpty()) { return null; } if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getEquipmentType())) { mdcOverallEquipmentEfficiencyVo.setEquipmentTypeList(Arrays.asList(mdcOverallEquipmentEfficiencyVo.getEquipmentType().split(","))); } if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getDeviceCategory())) { mdcOverallEquipmentEfficiencyVo.setDeviceCategoryList(Arrays.asList(mdcOverallEquipmentEfficiencyVo.getDeviceCategory().split(","))); } if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getDeviceLevel())) { mdcOverallEquipmentEfficiencyVo.setDeviceLevelList(Arrays.asList(mdcOverallEquipmentEfficiencyVo.getDeviceLevel().split(","))); } if (StringUtils.isNotEmpty(mdcOverallEquipmentEfficiencyVo.getDriveType())) { mdcOverallEquipmentEfficiencyVo.setDriveTypeList(Arrays.asList(mdcOverallEquipmentEfficiencyVo.getDriveType().split(","))); } return this.baseMapper.pageList(page, mdcOverallEquipmentEfficiencyVo); } }