diff --git a/aucma-production/src/main/java/com/aucma/production/domain/ProductionReportQualityInspection.java b/aucma-production/src/main/java/com/aucma/production/domain/ProductionReportQualityInspection.java new file mode 100644 index 0000000..74a5a60 --- /dev/null +++ b/aucma-production/src/main/java/com/aucma/production/domain/ProductionReportQualityInspection.java @@ -0,0 +1,434 @@ +package com.aucma.production.domain; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.aucma.common.annotation.Excel; +import com.aucma.common.core.domain.BaseEntity; + +/** + * 质检记录管理对象 report_quality_inspection(生产模块专用) + * + * 注意:此类直接从aucma-report模块复制而来,用于解决循环依赖问题 + * 原始类路径:com.aucma.report.domain.ReportQualityInspection + * 已重命名以避免与aucma-report模块中的类产生MyBatis类型别名冲突 + * + * @author Yinq + * @date 2023-11-21 + */ +public class ProductionReportQualityInspection extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键标识 + */ + private Long objId; + + /** + * 产品条码 + */ + @Excel(name = "产品条码") + private String barCode; + + /** + * 物料名称 + */ + @Excel(name = "物料名称") + private String materialName; + + /** + * 工序编号 + */ + @Excel(name = "工序编号") + private String processCode; + + /** + * 工序名称 + */ + @Excel(name = "工序名称") + private String processName; + + /** + * 检测项编号 + */ + @Excel(name = "检测项编号") + private String testItemCode; + + /** + * 质量缺陷编码 + */ + @Excel(name = "质量缺陷编码") + private String qualityDefectCode; + + /** + * 质量缺陷名称 + */ + @Excel(name = "质量缺陷名称") + private String qualityDefectName; + + /** + * 处理措施(3=合格,1=返修) + */ + @Excel(name = "处理措施") + private String treatmentMeasure; + + /** + * 处理结果 + */ + @Excel(name = "处理结果") + private String processResult; + + /** + * 是否下静态线(1-是;2-否) + */ + @Excel(name = "是否下静态线", readConverterExp = "1=-是;2-否") + private String isLowerLine; + + /** + * 班组编号 + */ + @Excel(name = "班组编号") + private String groupCode; + + /** + * 班组名称 + */ + @Excel(name = "班组名称") + private String groupName; + + /** + * 检测人员编号 + */ + @Excel(name = "检测人员编号") + private String inspectorCode; + + /** + * 检测人员名称 + */ + @Excel(name = "检测人员名称") + private String inspectorName; + + /** + * 检测时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "检测时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inspectorTime; + + /** + * 返修次数 + */ + @Excel(name = "返修次数") + private Long reworkNumber; + + /** + * 完成时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date finishTime; + + /** + * 返修结果(1=正常,2=异常) + */ + @Excel(name = "返修结果") + private Long isFlag; + + /** + * 更新人 + */ + @Excel(name = "更新人") + private String updatedBy; + + /** + * 工位编码 + */ + private String stationCode; + + /** + * 提交质检ID + */ + private int submitQualtyId; + + /** + * PDA工位名称 + */ + private String productLineName; + + /** + * SAP计划编号 + */ + private String orderCode; + + /** + * MES工单编号 + */ + private String planCode; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date updatedTime; + + /** + * 开始时间 + */ + private String beginBeginTime; + + /** + * 结束时间 + */ + private String endBeginTime; + + public String getBeginBeginTime() { + return beginBeginTime; + } + + public void setBeginBeginTime(String beginBeginTime) { + this.beginBeginTime = beginBeginTime; + } + + public String getEndBeginTime() { + return endBeginTime; + } + + public void setEndBeginTime(String endBeginTime) { + this.endBeginTime = endBeginTime; + } + + public String getOrderCode() { + return orderCode; + } + + public void setOrderCode(String orderCode) { + this.orderCode = orderCode; + } + + public String getPlanCode() { + return planCode; + } + + public void setPlanCode(String planCode) { + this.planCode = planCode; + } + + public String getProcessName() { + return processName; + } + + public void setProcessName(String processName) { + this.processName = processName; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getInspectorName() { + return inspectorName; + } + + public void setInspectorName(String inspectorName) { + this.inspectorName = inspectorName; + } + + public void setObjId(Long objId) { + this.objId = objId; + } + + public Long getObjId() { + return objId; + } + + public void setBarCode(String barCode) { + this.barCode = barCode; + } + + public int getSubmitQualtyId() { + return submitQualtyId; + } + + public void setSubmitQualtyId(int submitQualtyId) { + this.submitQualtyId = submitQualtyId; + } + + public String getBarCode() { + return barCode; + } + + public void setMaterialName(String materialName) { + this.materialName = materialName; + } + + public String getStationCode() { + return stationCode; + } + + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } + + public String getMaterialName() { + return materialName; + } + + public void setProcessCode(String processCode) { + this.processCode = processCode; + } + + public String getProcessCode() { + return processCode; + } + + public void setTestItemCode(String testItemCode) { + this.testItemCode = testItemCode; + } + + public String getTestItemCode() { + return testItemCode; + } + + public void setQualityDefectCode(String qualityDefectCode) { + this.qualityDefectCode = qualityDefectCode; + } + + public String getQualityDefectCode() { + return qualityDefectCode; + } + + public void setQualityDefectName(String qualityDefectName) { + this.qualityDefectName = qualityDefectName; + } + + public String getQualityDefectName() { + return qualityDefectName; + } + + public void setTreatmentMeasure(String treatmentMeasure) { + this.treatmentMeasure = treatmentMeasure; + } + + public String getTreatmentMeasure() { + return treatmentMeasure; + } + + public void setProcessResult(String processResult) { + this.processResult = processResult; + } + + public String getProcessResult() { + return processResult; + } + + public void setIsLowerLine(String isLowerLine) { + this.isLowerLine = isLowerLine; + } + + public String getIsLowerLine() { + return isLowerLine; + } + + public String getProductLineName() { + return productLineName; + } + + public void setProductLineName(String productLineName) { + this.productLineName = productLineName; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getGroupCode() { + return groupCode; + } + + public void setInspectorCode(String inspectorCode) { + this.inspectorCode = inspectorCode; + } + + public String getInspectorCode() { + return inspectorCode; + } + + public void setInspectorTime(Date inspectorTime) { + this.inspectorTime = inspectorTime; + } + + public Date getInspectorTime() { + return inspectorTime; + } + + public void setReworkNumber(Long reworkNumber) { + this.reworkNumber = reworkNumber; + } + + public Long getReworkNumber() { + return reworkNumber; + } + + public void setFinishTime(Date finishTime) { + this.finishTime = finishTime; + } + + public Date getFinishTime() { + return finishTime; + } + + public void setIsFlag(Long isFlag) { + this.isFlag = isFlag; + } + + public Long getIsFlag() { + return isFlag; + } + + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + + public String getUpdatedBy() { + return updatedBy; + } + + public void setUpdatedTime(Date updatedTime) { + this.updatedTime = updatedTime; + } + + public Date getUpdatedTime() { + return updatedTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("objId", getObjId()) + .append("barCode", getBarCode()) + .append("materialName", getMaterialName()) + .append("processCode", getProcessCode()) + .append("testItemCode", getTestItemCode()) + .append("qualityDefectCode", getQualityDefectCode()) + .append("qualityDefectName", getQualityDefectName()) + .append("treatmentMeasure", getTreatmentMeasure()) + .append("processResult", getProcessResult()) + .append("isLowerLine", getIsLowerLine()) + .append("groupCode", getGroupCode()) + .append("inspectorCode", getInspectorCode()) + .append("inspectorTime", getInspectorTime()) + .append("reworkNumber", getReworkNumber()) + .append("finishTime", getFinishTime()) + .append("isFlag", getIsFlag()) + .append("updatedBy", getUpdatedBy()) + .append("updatedTime", getUpdatedTime()) + .toString(); + } +} diff --git a/aucma-production/src/main/java/com/aucma/production/mapper/ProductionReportQualityInspectionMapper.java b/aucma-production/src/main/java/com/aucma/production/mapper/ProductionReportQualityInspectionMapper.java new file mode 100644 index 0000000..e388423 --- /dev/null +++ b/aucma-production/src/main/java/com/aucma/production/mapper/ProductionReportQualityInspectionMapper.java @@ -0,0 +1,32 @@ +package com.aucma.production.mapper; + +import java.util.List; +import com.aucma.production.domain.ProductionReportQualityInspection; + +/** + * 质检记录管理Mapper接口(生产模块专用) + * + * 注意:此接口直接从aucma-report模块复制而来,用于解决循环依赖问题 + * 原始接口路径:com.aucma.report.mapper.ReportQualityInspectionMapper + * 已重命名以避免与aucma-report模块中的mapper产生bean名称冲突 + * + * @author Yinq + * @date 2023-11-21 + */ +public interface ProductionReportQualityInspectionMapper { + /** + * 查询质检记录管理 + * + * @param objId 质检记录管理主键 + * @return 质检记录管理 + */ + public ProductionReportQualityInspection selectReportQualityInspectionByObjId(Long objId); + + /** + * 查询质检记录管理列表 + * + * @param reportQualityInspection 质检记录管理 + * @return 质检记录管理集合 + */ + public List selectReportQualityInspectionList(ProductionReportQualityInspection reportQualityInspection); +} diff --git a/aucma-production/src/main/java/com/aucma/production/service/impl/AndonDashboardServiceImpl.java b/aucma-production/src/main/java/com/aucma/production/service/impl/AndonDashboardServiceImpl.java index f32fcd0..f40a0d9 100644 --- a/aucma-production/src/main/java/com/aucma/production/service/impl/AndonDashboardServiceImpl.java +++ b/aucma-production/src/main/java/com/aucma/production/service/impl/AndonDashboardServiceImpl.java @@ -1,15 +1,19 @@ package com.aucma.production.service.impl; import com.aucma.base.domain.BaseDeviceLedger; +import com.aucma.base.domain.BaseDeviceParamVal; import com.aucma.base.mapper.BaseDeviceLedgerMapper; +import com.aucma.base.mapper.BaseDeviceParamValMapper; import com.aucma.common.constant.AnDonConstants; import com.aucma.common.utils.DateUtils; import com.aucma.common.utils.StringUtils; import com.aucma.production.domain.AndonEvent; import com.aucma.production.domain.ProductPlanInfo; +import com.aucma.production.domain.ProductionReportQualityInspection; import com.aucma.production.domain.dto.AndonDashboardDTO; import com.aucma.production.mapper.AndonEventMapper; import com.aucma.production.mapper.ProductPlanInfoMapper; +import com.aucma.production.mapper.ProductionReportQualityInspectionMapper; import com.aucma.production.service.IAndonDashboardService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -31,12 +35,18 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { @Autowired private BaseDeviceLedgerMapper baseDeviceLedgerMapper; + @Autowired + private BaseDeviceParamValMapper baseDeviceParamValMapper; + @Autowired private ProductPlanInfoMapper productPlanInfoMapper; @Autowired private AndonEventMapper andonEventMapper; + @Autowired + private ProductionReportQualityInspectionMapper reportQualityInspectionMapper; + @Override public AndonDashboardDTO getDashboardData(String productLineCode) { AndonDashboardDTO dto = new AndonDashboardDTO(); @@ -53,15 +63,10 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { public AndonDashboardDTO.DeviceStatusSummary getDeviceStatusSummary(String productLineCode) { AndonDashboardDTO.DeviceStatusSummary summary = new AndonDashboardDTO.DeviceStatusSummary(); - // 查询设备列表 - BaseDeviceLedger query = new BaseDeviceLedger(); - query.setIsFlag(1L); // 有效设备 - if (StringUtils.isNotEmpty(productLineCode)) { - query.setProductLineCode(productLineCode); - } - List devices = baseDeviceLedgerMapper.selectBaseDeviceLedgerList(query); + // 直接调用BaseDeviceParamValMapper获取真实设备状态统计 + Map stats = baseDeviceParamValMapper.selectDeviceStatusStatistics(); - if (devices == null || devices.isEmpty()) { + if (stats == null || stats.isEmpty()) { summary.setTotalDevices(0); summary.setRunningDevices(0); summary.setStoppedDevices(0); @@ -70,35 +75,46 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { summary.setDeviceDetails(new ArrayList<>()); return summary; } + + // 设置统计数据 + Number totalCount = (Number) stats.get("totalCount"); + Number runningCount = (Number) stats.get("runningCount"); + Number stoppedCount = (Number) stats.get("stoppedCount"); + Number standbyCount = (Number) stats.get("standbyCount"); + + summary.setTotalDevices(totalCount != null ? totalCount.intValue() : 0); + summary.setRunningDevices(runningCount != null ? runningCount.intValue() : 0); + summary.setStoppedDevices(stoppedCount != null ? stoppedCount.intValue() : 0); + summary.setIdleDevices(standbyCount != null ? standbyCount.intValue() : 0); + summary.setFaultDevices(0); // 三色灯没有故障状态,使用报警代替 - int running = 0, stopped = 0, fault = 0, idle = 0; + // 获取设备状态详情 + List> deviceStatusList = baseDeviceParamValMapper.selectDeviceStatusList(); List details = new ArrayList<>(); - - for (BaseDeviceLedger device : devices) { - Long status = device.getDeviceStatus(); - // 状态:0-停机, 1-运行, 2-故障, 3-待机 - if (status == null) status = 3L; // 默认待机 - - if (status == 1L) running++; - else if (status == 0L) stopped++; - else if (status == 2L) fault++; - else idle++; - - AndonDashboardDTO.DeviceStatusDetail detail = new AndonDashboardDTO.DeviceStatusDetail(); - detail.setDeviceCode(device.getDeviceCode()); - detail.setDeviceName(device.getDeviceName()); - detail.setProductLineCode(device.getProductLineCode()); - detail.setProductLineName(device.getProductLineName()); - detail.setStatus(status.intValue()); - detail.setStatusName(getStatusName(status.intValue())); - details.add(detail); + + if (deviceStatusList != null) { + for (Map device : deviceStatusList) { + // 如果指定了产线编码,过滤设备 + if (StringUtils.isNotEmpty(productLineCode)) { + String lineCode = (String) device.get("productLineCode"); + if (!productLineCode.equals(lineCode)) { + continue; + } + } + + AndonDashboardDTO.DeviceStatusDetail detail = new AndonDashboardDTO.DeviceStatusDetail(); + detail.setDeviceCode((String) device.get("deviceCode")); + detail.setDeviceName((String) device.get("deviceName")); + detail.setProductLineCode((String) device.get("productLineCode")); + detail.setProductLineName((String) device.get("productLineName")); + + Number statusCode = (Number) device.get("statusCode"); + detail.setStatus(statusCode != null ? statusCode.intValue() : 0); + detail.setStatusName((String) device.get("deviceStatus")); + details.add(detail); + } } - - summary.setTotalDevices(devices.size()); - summary.setRunningDevices(running); - summary.setStoppedDevices(stopped); - summary.setFaultDevices(fault); - summary.setIdleDevices(idle); + summary.setDeviceDetails(details); return summary; @@ -216,70 +232,85 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { return summary; } - // 基于设备状态模拟计算OEE(实际应从设备运行数据表获取) - // OEE = 可用率 × 性能稼动率 × 良品率 - long totalPlannedMinutes = devices.size() * 480L; // 假设每台设备每天计划8小时 - long totalDowntimeMinutes = 0; - List details = new ArrayList<>(); double totalAvailability = 0, totalPerformance = 0, totalQuality = 0; + long totalPlannedTime = 0, totalDowntime = 0; for (BaseDeviceLedger device : devices) { - Long status = device.getDeviceStatus(); - if (status == null) status = 3L; - - // 根据设备状态模拟OEE指标 - double availability, performance, quality; - long downtime = 0; - - if (status == 1L) { // 运行中 - availability = 0.92 + Math.random() * 0.06; // 92%-98% - performance = 0.88 + Math.random() * 0.10; // 88%-98% - quality = 0.95 + Math.random() * 0.04; // 95%-99% - downtime = (long)(480 * (1 - availability)); - } else if (status == 0L) { // 停机 - availability = 0.0; - performance = 0.0; - quality = 0.0; - downtime = 480; - } else if (status == 2L) { // 故障 - availability = 0.3 + Math.random() * 0.2; // 30%-50% - performance = 0.5 + Math.random() * 0.2; // 50%-70% - quality = 0.8 + Math.random() * 0.1; // 80%-90% - downtime = (long)(480 * (1 - availability)); - } else { // 待机 - availability = 0.6 + Math.random() * 0.2; // 60%-80% - performance = 0.7 + Math.random() * 0.15; // 70%-85% - quality = 0.92 + Math.random() * 0.05; // 92%-97% - downtime = (long)(480 * (1 - availability)); + // 查询该设备的总计划生产时间 + BaseDeviceParamVal plannedQuery = new BaseDeviceParamVal(); + plannedQuery.setDeviceCode(device.getDeviceCode()); + plannedQuery.setParamName("机台状态-总计划生产时间"); + List plannedList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(plannedQuery); + double plannedTime = 0; + if (plannedList != null && !plannedList.isEmpty()) { + plannedTime = parseDouble(plannedList.get(0).getParamValue()); } - - totalDowntimeMinutes += downtime; + + // 查询该设备的实际生产时间 + BaseDeviceParamVal actualQuery = new BaseDeviceParamVal(); + actualQuery.setDeviceCode(device.getDeviceCode()); + actualQuery.setParamName("机台状态-实际生产时间"); + List actualList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(actualQuery); + double actualTime = 0; + if (actualList != null && !actualList.isEmpty()) { + actualTime = parseDouble(actualList.get(0).getParamValue()); + } + + // 查询该设备的设定产出数量 + BaseDeviceParamVal targetQuery = new BaseDeviceParamVal(); + targetQuery.setDeviceCode(device.getDeviceCode()); + targetQuery.setParamName("机台状态-设定产出数量"); + List targetList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(targetQuery); + long targetOutput = 0; + if (targetList != null && !targetList.isEmpty()) { + targetOutput = parseLong(targetList.get(0).getParamValue()); + } + + // 查询该设备的实际产出数量 + BaseDeviceParamVal actualOutputQuery = new BaseDeviceParamVal(); + actualOutputQuery.setDeviceCode(device.getDeviceCode()); + actualOutputQuery.setParamName("机台状态-实际产出数量"); + List actualOutputList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(actualOutputQuery); + long actualOutput = 0; + if (actualOutputList != null && !actualOutputList.isEmpty()) { + actualOutput = parseLong(actualOutputList.get(0).getParamValue()); + } + + // 计算OEE三个指标 + double availability = plannedTime > 0 ? (actualTime / plannedTime) : 0; + double performance = targetOutput > 0 ? (actualOutput / targetOutput) : 0; + double quality = 0.95; + + double oee = availability * performance * quality; + + totalPlannedTime += (long) plannedTime; + totalDowntime += (long)(plannedTime - actualTime); totalAvailability += availability; totalPerformance += performance; totalQuality += quality; - + AndonDashboardDTO.DeviceOeeDetail detail = new AndonDashboardDTO.DeviceOeeDetail(); detail.setDeviceCode(device.getDeviceCode()); detail.setDeviceName(device.getDeviceName()); detail.setAvailability(round(availability * 100, 2)); detail.setPerformance(round(performance * 100, 2)); detail.setQuality(round(quality * 100, 2)); - detail.setOee(round(availability * performance * quality * 100, 2)); + detail.setOee(round(oee * 100, 2)); details.add(detail); } - + int count = devices.size(); double avgAvailability = totalAvailability / count; double avgPerformance = totalPerformance / count; double avgQuality = totalQuality / count; - + summary.setAvailability(round(avgAvailability * 100, 2)); summary.setPerformance(round(avgPerformance * 100, 2)); summary.setQuality(round(avgQuality * 100, 2)); summary.setOverallOee(round(avgAvailability * avgPerformance * avgQuality * 100, 2)); - summary.setPlannedTimeMinutes(totalPlannedMinutes); - summary.setDowntimeMinutes(totalDowntimeMinutes); + summary.setPlannedTimeMinutes(totalPlannedTime); + summary.setDowntimeMinutes(totalDowntime); summary.setDeviceOeeDetails(details); return summary; @@ -303,7 +334,7 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { return summary; } - // 按产线分组计算利用率 + // 按产线分组 Map> lineDevices = devices.stream() .filter(d -> StringUtils.isNotEmpty(d.getProductLineCode())) .collect(Collectors.groupingBy(BaseDeviceLedger::getProductLineCode)); @@ -313,23 +344,31 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { for (Map.Entry> entry : lineDevices.entrySet()) { List lineDeviceList = entry.getValue(); - long linePlanned = lineDeviceList.size() * 480L; // 假设8小时 + long linePlanned = 0; long lineRunning = 0; - + for (BaseDeviceLedger device : lineDeviceList) { - Long status = device.getDeviceStatus(); - if (status == null) status = 3L; + // 查询该设备的总计划生产时间 + BaseDeviceParamVal plannedQuery = new BaseDeviceParamVal(); + plannedQuery.setDeviceCode(device.getDeviceCode()); + plannedQuery.setParamName("机台状态-总计划生产时间"); + List plannedList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(plannedQuery); + if (plannedList != null && !plannedList.isEmpty()) { + double plannedTime = parseDouble(plannedList.get(0).getParamValue()); + linePlanned += (long) plannedTime; + } - // 根据状态估算运行时间 - if (status == 1L) { - lineRunning += (long)(480 * (0.85 + Math.random() * 0.1)); - } else if (status == 2L) { - lineRunning += (long)(480 * (0.3 + Math.random() * 0.2)); - } else if (status == 3L) { - lineRunning += (long)(480 * (0.5 + Math.random() * 0.2)); + // 查询该设备的实际生产时间 + BaseDeviceParamVal actualQuery = new BaseDeviceParamVal(); + actualQuery.setDeviceCode(device.getDeviceCode()); + actualQuery.setParamName("机台状态-实际生产时间"); + List actualList = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(actualQuery); + if (actualList != null && !actualList.isEmpty()) { + double actualTime = parseDouble(actualList.get(0).getParamValue()); + lineRunning += (long) actualTime; } } - + totalRunning += lineRunning; totalPlanned += linePlanned; @@ -352,84 +391,75 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { public AndonDashboardDTO.QualitySummary getQualitySummary(String productLineCode) { AndonDashboardDTO.QualitySummary summary = new AndonDashboardDTO.QualitySummary(); - // 查询今日生产计划获取产量数据 - ProductPlanInfo query = new ProductPlanInfo(); - query.setIsFlag(1L); - if (StringUtils.isNotEmpty(productLineCode)) { - query.setProductLineCode(productLineCode); - } - List plans = productPlanInfoMapper.selectProductPlanInfoList(query); - - if (plans == null) plans = new ArrayList<>(); - // 获取今日日期范围 Date todayStart = DateUtils.parseDate(DateUtils.getDate()); Date todayEnd = DateUtils.addDays(todayStart, 1); - // 获取本月日期范围 - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.DAY_OF_MONTH, 1); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - Date monthStart = cal.getTime(); - cal.add(Calendar.MONTH, 1); - Date monthEnd = cal.getTime(); - - long todayOutput = 0, monthOutput = 0; - Map lineStats = new HashMap<>(); // [output, good, defect] - Map lineNames = new HashMap<>(); - - for (ProductPlanInfo plan : plans) { - Long compAmt = plan.getCompleteAmount() == null ? 0L : plan.getCompleteAmount(); - Date planDate = plan.getPlanBeginTime(); - - if (planDate != null && !planDate.before(todayStart) && planDate.before(todayEnd)) { - todayOutput += compAmt; - } - if (planDate != null && !planDate.before(monthStart) && planDate.before(monthEnd)) { - monthOutput += compAmt; - } - - String lineCode = plan.getProductLineCode(); + // 查询今日质检记录 + ProductionReportQualityInspection query = new ProductionReportQualityInspection(); + query.setBeginBeginTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", todayStart)); + query.setEndBeginTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", todayEnd)); + if (StringUtils.isNotEmpty(productLineCode)) { + query.setStationCode(productLineCode); + } + + List qualityList = reportQualityInspectionMapper.selectReportQualityInspectionList(query); + + if (qualityList == null) { + qualityList = new ArrayList<>(); + } + + // 按产线分组统计 + Map> lineQualityMap = new HashMap<>(); + for (ProductionReportQualityInspection inspection : qualityList) { + String lineCode = inspection.getStationCode(); if (StringUtils.isNotEmpty(lineCode)) { - lineStats.computeIfAbsent(lineCode, k -> new long[3]); - lineStats.get(lineCode)[0] += compAmt; - if (StringUtils.isNotEmpty(plan.getProductLineName())) { - lineNames.put(lineCode, plan.getProductLineName()); - } + lineQualityMap.computeIfAbsent(lineCode, k -> new ArrayList<>()).add(inspection); } } - - // 模拟良品率数据(实际应从质检数据获取) - double yieldRate = 0.95 + Math.random() * 0.04; // 95%-99% - long todayGood = (long)(todayOutput * yieldRate); - long todayDefect = todayOutput - todayGood; - + + long todayOutput = 0, todayGood = 0, todayDefect = 0; + List lineQualities = new ArrayList<>(); + + // 按产线统计良品和不良品 + for (Map.Entry> entry : lineQualityMap.entrySet()) { + List lineInspections = entry.getValue(); + long lineGood = 0; + long lineDefect = 0; + + for (ProductionReportQualityInspection inspection : lineInspections) { + // treatmentMeasure: 3=合格(良品), 1=返修(不良品) + if ("3".equals(inspection.getTreatmentMeasure())) { + lineGood++; + } else if ("1".equals(inspection.getTreatmentMeasure())) { + lineDefect++; + } + } + + long lineOutput = lineGood + lineDefect; + double lineYieldRate = lineOutput > 0 ? (lineGood * 100.0 / lineOutput) : 0; + + todayOutput += lineOutput; + todayGood += lineGood; + todayDefect += lineDefect; + + AndonDashboardDTO.LineQuality lq = new AndonDashboardDTO.LineQuality(); + lq.setProductLineCode(entry.getKey()); + lq.setProductLineName(lineInspections.get(0).getProductLineName()); + lq.setOutput(lineOutput); + lq.setGoodCount(lineGood); + lq.setDefectCount(lineDefect); + lq.setYieldRate(round(lineYieldRate, 2)); + lineQualities.add(lq); + } + + double todayYieldRate = todayOutput > 0 ? (todayGood * 100.0 / todayOutput) : 0; + summary.setTodayOutput(todayOutput); summary.setTodayGoodCount(todayGood); summary.setTodayDefectCount(todayDefect); - summary.setTodayYieldRate(round(yieldRate * 100, 2)); - summary.setMonthYieldRate(round((0.94 + Math.random() * 0.05) * 100, 2)); - - // 产线品质数据 - List lineQualities = new ArrayList<>(); - for (Map.Entry entry : lineStats.entrySet()) { - long output = entry.getValue()[0]; - double lineYield = 0.93 + Math.random() * 0.06; - long good = (long)(output * lineYield); - long defect = output - good; - - AndonDashboardDTO.LineQuality lq = new AndonDashboardDTO.LineQuality(); - lq.setProductLineCode(entry.getKey()); - lq.setProductLineName(lineNames.getOrDefault(entry.getKey(), entry.getKey())); - lq.setOutput(output); - lq.setGoodCount(good); - lq.setDefectCount(defect); - lq.setYieldRate(round(lineYield * 100, 2)); - lineQualities.add(lq); - } + summary.setTodayYieldRate(round(todayYieldRate, 2)); + summary.setMonthYieldRate(round(todayYieldRate, 2)); // 暂时使用今日良品率 summary.setLineQualities(lineQualities); return summary; @@ -523,21 +553,29 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService { return summary; } - private String getStatusName(int status) { - switch (status) { - case 0: return "停机"; - case 1: return "运行"; - case 2: return "故障"; - case 3: return "待机"; - default: return "未知"; - } - } - private double calcRate(long numerator, long denominator) { if (denominator == 0) return 0; return round((double) numerator / denominator * 100, 2); } + private double parseDouble(String value) { + if (StringUtils.isEmpty(value)) return 0; + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + return 0; + } + } + + private long parseLong(String value) { + if (StringUtils.isEmpty(value)) return 0; + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + return 0; + } + } + private double round(double value, int places) { return BigDecimal.valueOf(value) .setScale(places, RoundingMode.HALF_UP) diff --git a/aucma-production/src/main/resources/mapper/production/ProductionReportQualityInspectionMapper.xml b/aucma-production/src/main/resources/mapper/production/ProductionReportQualityInspectionMapper.xml new file mode 100644 index 0000000..dfb7648 --- /dev/null +++ b/aucma-production/src/main/resources/mapper/production/ProductionReportQualityInspectionMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select rqi.obj_id, + rqi.bar_code, + rqi.material_name, + rqi.process_code, + bps.PROCESS_NAME processName, + rqi.test_item_code, + pl.PRODUCT_LINE_NAME PRODUCT_LINE_NAME, + rqi.quality_defect_code, + rqi.quality_defect_name, + rqi.treatment_measure, + rqi.process_result, + rqi.is_lower_line, + rqi.group_code, + btm.TEAM_NAME groupName, + rqi.inspector_code, + su.NICK_NAME inspectorName, + rqi.inspector_time, + rqi.rework_number, + rqi.finish_time, + rqi.is_flag, + rqi.updated_by, + rqi.updated_time + from report_quality_inspection rqi + left join BASE_PROCESS_STATION bps on bps.PROCESS_CODE = rqi.PROCESS_CODE + left join BASE_TEAMMEMBERS btm on btm.TEAM_CODE = rqi.group_code + left join Z_SYS_USER su on su.USER_NAME = rqi.inspector_code + left join BASE_PRODUCTLINE pl on pl.PRODUCT_LINE_CODE = rqi.STATION_CODE + + + + + + + +