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.Collections;
|
import java.util.List;
|
|
/**
|
* @author: LiuS
|
* @create: 2023-10-18 09:25
|
*/
|
@Service
|
public class MdcOverallEquipmentEfficiencyServiceImpl extends ServiceImpl<MdcOverallEquipmentEfficiencyMapper, MdcOverallEquipmentEfficiency> 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<MdcOverallEquipmentEfficiency> 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<MdcOverallEquipmentEfficiency>().
|
eq(MdcOverallEquipmentEfficiency::getValidDate, validDate));
|
}
|
} catch (Exception e) {
|
log.error("参数格式不对", e);
|
}
|
}
|
// 获取设备列表
|
// List<MdcEquipment> equipmentList = mdcEquipmentService.list(new LambdaQueryWrapper<MdcEquipment>().eq(MdcEquipment::getEquipmentId, "2140198"));
|
List<MdcEquipment> 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<String> 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<MdcStandardProcessDuration>().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<MdcOverallEquipmentEfficiency> pageList(String userId, Page<MdcOverallEquipmentEfficiency> page, MdcOverallEquipmentEfficiencyVo mdcOverallEquipmentEfficiencyVo, HttpServletRequest req) {
|
List<String> 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;
|
}
|
return this.baseMapper.pageList(page, mdcOverallEquipmentEfficiencyVo);
|
}
|
}
|