diff --git a/klp-wms/src/main/java/com/klp/service/IWmsMaterialWarningService.java b/klp-wms/src/main/java/com/klp/service/IWmsMaterialWarningService.java index cce0f4b1..be80f90d 100644 --- a/klp-wms/src/main/java/com/klp/service/IWmsMaterialWarningService.java +++ b/klp-wms/src/main/java/com/klp/service/IWmsMaterialWarningService.java @@ -1,5 +1,6 @@ package com.klp.service; +import com.klp.domain.WmsMaterialCoil; import com.klp.domain.WmsMaterialWarning; import com.klp.domain.vo.WmsMaterialWarningVo; import com.klp.domain.bo.WmsMaterialWarningBo; @@ -46,4 +47,12 @@ public interface IWmsMaterialWarningService { * 校验并批量删除钢卷通用维度告警(长度/厚度/宽度)信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 检查钢卷长度/厚度偏差并批量插入告警记录 + * 在 calculateTheoretical 计算出理论长度和理论厚度后调用 + * + * @param coil 钢卷实体(需已填充 theoreticalLength/theoreticalThickness/actualLength/actualThickness/coilId) + */ + void checkAndInsertWarnings(WmsMaterialCoil coil); } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index f886c130..c4f7106d 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -78,6 +78,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { // private final WmsDeliveryPlanMapper deliveryPlanMapper; private final WmsProductMapper productMapper; private final WmsRawMaterialMapper rawMaterialMapper; + private final IWmsMaterialWarningService materialWarningService; private final WmsDeliveryWaybillDetailMapper deliveryWaybillDetailMapper; private final WmsCoilWarehouseOperationLogMapper wmsCoilWarehouseOperationLogMapper; private final IWmsCoilAbnormalService coilAbnormalService; @@ -1521,6 +1522,9 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { throw new RuntimeException("新增钢卷失败"); } + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(add); + // 设置返回用的ID并更新二维码内容中的coilId bo.setCoilId(add.getCoilId()); updateQrcodeCoilId(qrcodeRecordId, add.getCoilId()); @@ -1732,6 +1736,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { updateWrapper.set(WmsMaterialCoil::getSaleId, (Long)null); baseMapper.update(null, updateWrapper); } + + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(updateCoil); + // 如果实际库区id为-1或状态为1,则清空钢卷上的实际库区绑定 if ((bo.getActualWarehouseId() != null && bo.getActualWarehouseId().equals(-1L)) || (bo.getStatus() != null && bo.getStatus().equals(1))) { @@ -1839,6 +1847,9 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { throw new RuntimeException("创建新钢卷失败"); } + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(newCoil); + // 如果实际库区id为-1,则清空钢卷上的实际库区绑定 if (bo.getActualWarehouseId() != null && bo.getActualWarehouseId().equals(-1L)) { clearActualWarehouseBinding(newCoil.getActualWarehouseId(), newCoil.getCoilId()); @@ -2096,6 +2107,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { // 把老记录的coilId赋值给新纪录的parentCoilId newCoil.setParentCoilId(String.valueOf(oldCoil.getCoilId())); baseMapper.insert(newCoil); + + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(newCoil); + newCoils.add(newCoil); // 更新二维码内容中的coilId @@ -2234,6 +2249,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { newCoil.setParentCoilId(parentCoilIdsStr); baseMapper.insert(newCoil); + + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(newCoil); + newCoils.add(newCoil); // 更新二维码内容中的coilId @@ -5085,6 +5104,9 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { childCoil.setParentCoilId(String.valueOf(parentCoilId)); baseMapper.insert(childCoil); + // 检查长度/厚度偏差并插入告警 + materialWarningService.checkAndInsertWarnings(childCoil); + // 插入子钢卷的异常信息 if (childCoilBo.getAbnormals() != null && !childCoilBo.getAbnormals().isEmpty()) { for (WmsCoilAbnormalBo abnormalBo : childCoilBo.getAbnormals()) { diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialWarningServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialWarningServiceImpl.java index bd54d7a1..1278d7b0 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialWarningServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialWarningServiceImpl.java @@ -8,13 +8,18 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.klp.common.utils.StringUtils; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import com.klp.domain.bo.WmsMaterialWarningBo; import com.klp.domain.vo.WmsMaterialWarningVo; +import com.klp.domain.WmsMaterialCoil; import com.klp.domain.WmsMaterialWarning; import com.klp.mapper.WmsMaterialWarningMapper; import com.klp.service.IWmsMaterialWarningService; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Collection; @@ -25,6 +30,7 @@ import java.util.Collection; * @author klp * @date 2026-06-06 */ +@Slf4j @RequiredArgsConstructor @Service public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService { @@ -118,4 +124,143 @@ public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService } return baseMapper.deleteBatchIds(ids) > 0; } + + /** + * 检查钢卷长度/厚度偏差并批量插入告警记录 + * + * 长度规则:ABS((实测长度 - 理论长度) / 理论长度) > 0.1 → 告警 + * 厚度规则: + * 1. 实测厚度 < 理论厚度 → 偏薄告警(ERROR) + * 2. (实测厚度 - 理论厚度) / 理论厚度 > 0.1 → 偏厚告警(WARNING) + */ + @Override + public void checkAndInsertWarnings(WmsMaterialCoil coil) { + try { + doCheckAndInsertWarnings(coil); + } catch (Exception e) { + log.error("钢卷告警检查异常, coilId={}, 不影响原流程", coil != null ? coil.getCoilId() : null, e); + } + } + + private void doCheckAndInsertWarnings(WmsMaterialCoil coil) { + if (coil == null || coil.getCoilId() == null) { + return; + } + + List warnings = new ArrayList<>(); + + // ========== 长度检查 ========== + checkLength(coil, warnings); + + // ========== 厚度检查 ========== + checkThickness(coil, warnings); + + // 批量插入 + if (!warnings.isEmpty()) { + try { + baseMapper.insertBatch(warnings); + log.info("批量插入钢卷告警记录成功, coilId={}, 告警数={}", coil.getCoilId(), warnings.size()); + } catch (Exception e) { + log.error("批量插入钢卷告警记录失败, coilId={}", coil.getCoilId(), e); + } + } + } + + /** + * 长度偏差检查 + * ABS((actualLength - theoreticalLength) / theoreticalLength) > 0.1 → WARNING + */ + private void checkLength(WmsMaterialCoil coil, List warnings) { + Long actualLength = coil.getActualLength(); + BigDecimal theoreticalLength = coil.getTheoreticalLength(); + + if (actualLength == null || theoreticalLength == null + || theoreticalLength.compareTo(BigDecimal.ZERO) == 0) { + return; + } + + BigDecimal actual = new BigDecimal(actualLength); + BigDecimal diff = actual.subtract(theoreticalLength).abs(); + BigDecimal rate = diff.divide(theoreticalLength, 10, RoundingMode.HALF_UP); + + // 偏差率 > 0.1(即超过10%) + BigDecimal threshold = new BigDecimal("0.1"); + if (rate.compareTo(threshold) > 0) { + WmsMaterialWarning warning = new WmsMaterialWarning(); + warning.setCoilId(coil.getCoilId()); + warning.setWarningType("LENGTH"); + warning.setTheoreticalVal(theoreticalLength); + warning.setActualVal(actual); + warning.setAllowDeviation(threshold); + warning.setDeviationValue(actual.subtract(theoreticalLength)); + warning.setDeviationRate(rate.multiply(new BigDecimal("100")).setScale(4, RoundingMode.HALF_UP)); + warning.setWarningLevel("WARNING"); + warning.setWarningMsg("钢卷长度偏差超过10%,理论长度=" + theoreticalLength + "m,实测长度=" + actualLength + "mm"); + warning.setWarningStatus(0); + warnings.add(warning); + } + } + + /** + * 厚度偏差检查 + * 1. 实测厚度 < 理论厚度 → ERROR(不能比原来薄) + * 2. (实测厚度 - 理论厚度) / 理论厚度 > 0.1 → WARNING(不能厚太多) + */ + private void checkThickness(WmsMaterialCoil coil, List warnings) { + String actualThicknessStr = coil.getActualThickness(); + BigDecimal theoreticalThickness = coil.getTheoreticalThickness(); + + if (actualThicknessStr == null || theoreticalThickness == null + || theoreticalThickness.compareTo(BigDecimal.ZERO) == 0) { + return; + } + + BigDecimal actualThickness; + try { + actualThickness = new BigDecimal(actualThicknessStr.trim()); + } catch (NumberFormatException e) { + log.warn("实测厚度无法解析为数值, coilId={}, actualThickness={}", coil.getCoilId(), actualThicknessStr); + return; + } + + BigDecimal threshold = new BigDecimal("0.1"); + + // 规则1:实测厚度 < 理论厚度 → 偏薄 ERROR + if (actualThickness.compareTo(theoreticalThickness) < 0) { + WmsMaterialWarning warning = new WmsMaterialWarning(); + warning.setCoilId(coil.getCoilId()); + warning.setWarningType("THICKNESS"); + warning.setTheoreticalVal(theoreticalThickness); + warning.setActualVal(actualThickness); + warning.setAllowDeviation(BigDecimal.ZERO); + warning.setDeviationValue(actualThickness.subtract(theoreticalThickness)); + BigDecimal rate = theoreticalThickness.subtract(actualThickness) + .divide(theoreticalThickness, 10, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")).setScale(4, RoundingMode.HALF_UP); + warning.setDeviationRate(rate); + warning.setWarningLevel("ERROR"); + warning.setWarningMsg("钢卷实测厚度偏薄,理论厚度=" + theoreticalThickness + "mm,实测厚度=" + actualThickness + "mm"); + warning.setWarningStatus(0); + warnings.add(warning); + return; // 偏薄已经足够严重,不再重复判断偏厚 + } + + // 规则2:(实测厚度 - 理论厚度) / 理论厚度 > 0.1 → 偏厚超10% + BigDecimal diff = actualThickness.subtract(theoreticalThickness); + BigDecimal rate = diff.divide(theoreticalThickness, 10, RoundingMode.HALF_UP); + if (rate.compareTo(threshold) > 0) { + WmsMaterialWarning warning = new WmsMaterialWarning(); + warning.setCoilId(coil.getCoilId()); + warning.setWarningType("THICKNESS"); + warning.setTheoreticalVal(theoreticalThickness); + warning.setActualVal(actualThickness); + warning.setAllowDeviation(threshold); + warning.setDeviationValue(diff); + warning.setDeviationRate(rate.multiply(new BigDecimal("100")).setScale(4, RoundingMode.HALF_UP)); + warning.setWarningLevel("WARNING"); + warning.setWarningMsg("钢卷实测厚度偏厚超过10%,理论厚度=" + theoreticalThickness + "mm,实测厚度=" + actualThickness + "mm"); + warning.setWarningStatus(0); + warnings.add(warning); + } + } }