Files
klp-oa/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialWarningServiceImpl.java
Joshi e00d1357b0 refactor(wms): 优化钢卷告警数据查询逻辑解决循环依赖
- 将钢卷信息批量查询逻辑从服务层迁移到控制器层
- 在控制器中实现钢卷ID收集和批量查询功能
- 通过Map映射方式关联钢卷信息到告警数据
- 移除服务层中的WmsMaterialCoilService依赖注入
- 提高数据查询效率和代码结构清晰度
2026-06-09 17:08:01 +08:00

281 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.klp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.core.service.ConfigService;
import com.klp.common.utils.StringUtils;
import com.klp.domain.vo.WmsMaterialCoilVo;
import com.klp.mapper.WmsMaterialCoilMapper;
import com.klp.service.IWmsMaterialCoilService;
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.domain.bo.WmsMaterialCoilBo;
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;
import java.util.stream.Collectors;
/**
* 钢卷通用维度告警(长度/厚度/宽度Service业务层处理
*
* @author klp
* @date 2026-06-06
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class WmsMaterialWarningServiceImpl implements IWmsMaterialWarningService {
private final WmsMaterialWarningMapper baseMapper;
private final ConfigService configService;
/**
* 查询钢卷通用维度告警(长度/厚度/宽度)
*/
@Override
public WmsMaterialWarningVo queryById(Long warningId){
return baseMapper.selectVoById(warningId);
}
/**
* 查询钢卷通用维度告警(长度/厚度/宽度)列表
*/
@Override
public TableDataInfo<WmsMaterialWarningVo> queryPageList(WmsMaterialWarningBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WmsMaterialWarning> lqw = buildQueryWrapper(bo);
Page<WmsMaterialWarningVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询钢卷通用维度告警(长度/厚度/宽度)列表
*/
@Override
public List<WmsMaterialWarningVo> queryList(WmsMaterialWarningBo bo) {
LambdaQueryWrapper<WmsMaterialWarning> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WmsMaterialWarning> buildQueryWrapper(WmsMaterialWarningBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsMaterialWarning> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getCoilId() != null, WmsMaterialWarning::getCoilId, bo.getCoilId());
// 批量钢卷ID过滤逗号分隔
if (StringUtils.isNotBlank(bo.getCoilIds())) {
String[] ids = bo.getCoilIds().split(",");
List<Long> idList = new ArrayList<>();
for (String id : ids) {
try {
idList.add(Long.parseLong(id.trim()));
} catch (NumberFormatException ignored) {
}
}
if (!idList.isEmpty()) {
lqw.in(WmsMaterialWarning::getCoilId, idList);
}
}
lqw.eq(StringUtils.isNotBlank(bo.getWarningType()), WmsMaterialWarning::getWarningType, bo.getWarningType());
lqw.eq(bo.getTheoreticalVal() != null, WmsMaterialWarning::getTheoreticalVal, bo.getTheoreticalVal());
lqw.eq(bo.getActualVal() != null, WmsMaterialWarning::getActualVal, bo.getActualVal());
lqw.eq(bo.getAllowDeviation() != null, WmsMaterialWarning::getAllowDeviation, bo.getAllowDeviation());
lqw.eq(bo.getDeviationValue() != null, WmsMaterialWarning::getDeviationValue, bo.getDeviationValue());
lqw.eq(bo.getDeviationRate() != null, WmsMaterialWarning::getDeviationRate, bo.getDeviationRate());
lqw.eq(StringUtils.isNotBlank(bo.getWarningLevel()), WmsMaterialWarning::getWarningLevel, bo.getWarningLevel());
lqw.eq(StringUtils.isNotBlank(bo.getWarningMsg()), WmsMaterialWarning::getWarningMsg, bo.getWarningMsg());
lqw.eq(bo.getWarningStatus() != null, WmsMaterialWarning::getWarningStatus, bo.getWarningStatus());
lqw.eq(StringUtils.isNotBlank(bo.getHandleBy()), WmsMaterialWarning::getHandleBy, bo.getHandleBy());
lqw.eq(bo.getHandleTime() != null, WmsMaterialWarning::getHandleTime, bo.getHandleTime());
lqw.eq(StringUtils.isNotBlank(bo.getHandleRemark()), WmsMaterialWarning::getHandleRemark, bo.getHandleRemark());
// 根据创建时间倒叙
lqw.orderByDesc(WmsMaterialWarning::getCreateTime);
return lqw;
}
/**
* 新增钢卷通用维度告警(长度/厚度/宽度)
*/
@Override
public Boolean insertByBo(WmsMaterialWarningBo bo) {
WmsMaterialWarning add = BeanUtil.toBean(bo, WmsMaterialWarning.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setWarningId(add.getWarningId());
}
return flag;
}
/**
* 修改钢卷通用维度告警(长度/厚度/宽度)
*/
@Override
public Boolean updateByBo(WmsMaterialWarningBo bo) {
WmsMaterialWarning update = BeanUtil.toBean(bo, WmsMaterialWarning.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(WmsMaterialWarning entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除钢卷通用维度告警(长度/厚度/宽度)
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 检查钢卷长度/厚度偏差并批量插入告警记录
*
* 长度规则ABS((实测长度 - 理论长度) / 理论长度) > 阈值 → WARNING
* 阈值从 sys_config(material.warning.length) 读取,默认 0.1
* 厚度规则:理论厚度 - 实测厚度 > 阈值 → ERROR
* 阈值从 sys_config(material.warning.thickness) 读取(绝对值差 mm默认 -0.01
*/
@Override
public void checkAndInsertWarnings(WmsMaterialCoil coil, WmsMaterialCoilBo bo) {
try {
doCheckAndInsertWarnings(coil, bo);
} catch (Exception e) {
log.error("钢卷告警检查异常, coilId={}, 不影响原流程", coil != null ? coil.getCoilId() : null, e);
}
}
private void doCheckAndInsertWarnings(WmsMaterialCoil coil, WmsMaterialCoilBo bo) {
if (coil == null || coil.getCoilId() == null) {
return;
}
List<WmsMaterialWarning> warnings = new ArrayList<>();
// ========== 长度检查 ==========
checkLength(coil, warnings);
// ========== 厚度检查 ==========
checkThickness(coil, bo, 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) > 阈值 → WARNING
* 阈值从 sys_config(material.warning.length) 读取,默认 0.1
*/
private void checkLength(WmsMaterialCoil coil, List<WmsMaterialWarning> warnings) {
Long actualLength = coil.getActualLength();
BigDecimal theoreticalLength = coil.getTheoreticalLength();
if (actualLength == null || theoreticalLength == null
|| theoreticalLength.compareTo(BigDecimal.ZERO) == 0) {
return;
}
// 读取配置阈值,默认 0.110%
BigDecimal threshold;
try {
String val = configService.getConfigValue("material.warning.length");
threshold = StringUtils.isNotBlank(val) ? new BigDecimal(val.trim()) : new BigDecimal("0.1");
} catch (Exception e) {
log.warn("读取长度告警阈值失败,使用默认值 0.1", e);
threshold = new BigDecimal("0.1");
}
BigDecimal actual = new BigDecimal(actualLength);
BigDecimal diff = actual.subtract(theoreticalLength).abs();
BigDecimal rate = diff.divide(theoreticalLength, 10, RoundingMode.HALF_UP);
if (rate.compareTo(threshold) > 0) {
WmsMaterialWarning warning = new WmsMaterialWarning();
warning.setCoilId(coil.getCoilId());
warning.setWarningType("LENGTH");
warning.setTheoreticalVal(theoreticalLength.setScale(3, RoundingMode.HALF_UP));
warning.setActualVal(actual.setScale(3, RoundingMode.HALF_UP));
warning.setAllowDeviation(threshold.setScale(3, RoundingMode.HALF_UP));
warning.setDeviationValue(actual.subtract(theoreticalLength).setScale(3, RoundingMode.HALF_UP));
warning.setDeviationRate(rate.multiply(new BigDecimal("100")).setScale(1, RoundingMode.HALF_UP));
warning.setWarningLevel("WARNING");
warning.setWarningMsg("钢卷长度偏差超过阈值,理论长度=" + theoreticalLength.setScale(3, RoundingMode.HALF_UP) + "m实测长度=" + actualLength + "mm");
warning.setWarningStatus(0);
warnings.add(warning);
}
}
/**
* 厚度偏差检查
* 规则:理论厚度 - 规格厚度 > 阈值 → WARNING
* 规格厚度从 BO 中取得calculateTheoretical 已解析)
* 阈值从 sys_config(material.warning.thickness) 读取,默认 -0.01
*/
private void checkThickness(WmsMaterialCoil coil, WmsMaterialCoilBo bo, List<WmsMaterialWarning> warnings) {
BigDecimal theoreticalThickness = coil.getTheoreticalThickness();
BigDecimal specThickness = bo != null ? bo.getSpecThickness() : null;
if (theoreticalThickness == null || specThickness == null
|| specThickness.compareTo(BigDecimal.ZERO) == 0) {
return;
}
// 读取配置阈值(单位 mm默认 -0.01
BigDecimal threshold;
try {
String val = configService.getConfigValue("material.warning.thickness");
threshold = StringUtils.isNotBlank(val) ? new BigDecimal(val.trim()) : new BigDecimal("-0.01");
} catch (Exception e) {
log.warn("读取厚度告警阈值失败,使用默认值 -0.01", e);
threshold = new BigDecimal("-0.01");
}
// 理论厚度 - 规格厚度 > 阈值 → 触发
BigDecimal diff = theoreticalThickness.subtract(specThickness);
if (diff.compareTo(threshold) > 0) {
WmsMaterialWarning warning = new WmsMaterialWarning();
warning.setCoilId(coil.getCoilId());
warning.setWarningType("THICKNESS");
warning.setTheoreticalVal(theoreticalThickness.setScale(3, RoundingMode.HALF_UP));
warning.setActualVal(specThickness.setScale(3, RoundingMode.HALF_UP));
warning.setAllowDeviation(threshold.setScale(3, RoundingMode.HALF_UP));
warning.setDeviationValue(theoreticalThickness.subtract(specThickness).setScale(3, RoundingMode.HALF_UP));
BigDecimal rate = diff.divide(specThickness, 10, RoundingMode.HALF_UP)
.multiply(new BigDecimal("100")).setScale(1, RoundingMode.HALF_UP);
warning.setDeviationRate(rate);
warning.setWarningLevel("WARNING");
warning.setWarningMsg("钢卷厚度偏差超出允许范围,理论厚度=" + theoreticalThickness.setScale(3, RoundingMode.HALF_UP) + "mm规格厚度=" + specThickness.setScale(3, RoundingMode.HALF_UP) + "mm");
warning.setWarningStatus(0);
warnings.add(warning);
}
}
}