fix(material): 解决入场钢卷号查询中的字符串排序问题
- 为WmsMaterialCoilBo的materialType字段添加@NotBlank验证注解 - 重构getMaxEnterCoilNoByPrefix方法,将字符串排序改为数值排序 - 添加边界校验和前缀长度验证(必须为4位) - 优化查询逻辑,先查询所有匹配记录再手动筛选数值最大值 - 增加详细的日志记录和异常处理机制 - 提升代码性能,使用固定容量HashMap和字段选择优化
This commit is contained in:
@@ -133,6 +133,7 @@ public class WmsMaterialCoilBo extends BaseEntity {
|
|||||||
private Long actualWarehouseId;
|
private Long actualWarehouseId;
|
||||||
|
|
||||||
//材料类型
|
//材料类型
|
||||||
|
@NotBlank(message = "物料类型不能为空")
|
||||||
private String materialType;
|
private String materialType;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2302,34 +2302,77 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据入场钢卷号前缀查询最大的入场钢卷号
|
* 根据入场钢卷号前缀查询最大的入场钢卷号
|
||||||
* 前端传入入场钢卷号的前四位,查询所有符合的入场钢卷号,返回最大值
|
* 前端传入入场钢卷号的前四位,查询所有符合的入场钢卷号,返回数值上的最大值
|
||||||
|
*
|
||||||
|
* @param enterCoilNoPrefix 入场钢卷号前缀(建议为4位)
|
||||||
|
* @return 包含最大钢卷号和前缀的Map,key分别为maxEnterCoilNo、prefix
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getMaxEnterCoilNoByPrefix(String enterCoilNoPrefix) {
|
public Map<String, Object> getMaxEnterCoilNoByPrefix(String enterCoilNoPrefix) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>(2); // 初始化固定容量,提升性能
|
||||||
|
result.put("prefix", enterCoilNoPrefix); // 先赋值前缀,避免重复代码
|
||||||
|
|
||||||
|
// 1. 边界校验:前缀为空/空白字符串,直接返回null
|
||||||
if (StringUtils.isBlank(enterCoilNoPrefix)) {
|
if (StringUtils.isBlank(enterCoilNoPrefix)) {
|
||||||
|
log.warn("查询最大入场钢卷号失败:前缀为空");
|
||||||
result.put("maxEnterCoilNo", null);
|
result.put("maxEnterCoilNo", null);
|
||||||
result.put("prefix", enterCoilNoPrefix);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询所有以该前缀开头的入场钢卷号
|
// 2. 前缀长度校验(可选,根据业务要求,比如强制4位)
|
||||||
|
if (enterCoilNoPrefix.length() != 4) {
|
||||||
|
log.warn("查询最大入场钢卷号失败:前缀长度不符合要求(需4位),当前前缀:{}", enterCoilNoPrefix);
|
||||||
|
result.put("maxEnterCoilNo", null);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 3. 构建查询条件:匹配前缀 + 未删除
|
||||||
LambdaQueryWrapper<WmsMaterialCoil> wrapper = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<WmsMaterialCoil> wrapper = Wrappers.lambdaQuery();
|
||||||
wrapper.likeRight(WmsMaterialCoil::getEnterCoilNo, enterCoilNoPrefix)
|
wrapper.likeRight(WmsMaterialCoil::getEnterCoilNo, enterCoilNoPrefix)
|
||||||
.eq(WmsMaterialCoil::getDelFlag, 0)
|
.eq(WmsMaterialCoil::getDelFlag, 0)
|
||||||
.orderByDesc(WmsMaterialCoil::getEnterCoilNo)
|
.select(WmsMaterialCoil::getEnterCoilNo); // 仅查询需要的字段,提升性能
|
||||||
.last("LIMIT 1");
|
|
||||||
|
|
||||||
WmsMaterialCoil maxCoil = baseMapper.selectOne(wrapper);
|
// 4. 查询所有匹配的钢卷记录
|
||||||
|
List<WmsMaterialCoil> coilList = baseMapper.selectList(wrapper);
|
||||||
|
log.info("根据前缀{}查询到匹配的钢卷记录数:{}", enterCoilNoPrefix, coilList.size());
|
||||||
|
|
||||||
|
// 5. 手动筛选数值最大的钢卷号(解决字符串排序问题)
|
||||||
String maxEnterCoilNo = null;
|
String maxEnterCoilNo = null;
|
||||||
if (maxCoil != null && StringUtils.isNotBlank(maxCoil.getEnterCoilNo())) {
|
long maxNum = -1;
|
||||||
maxEnterCoilNo = maxCoil.getEnterCoilNo();
|
for (WmsMaterialCoil coil : coilList) {
|
||||||
|
String coilNo = coil.getEnterCoilNo();
|
||||||
|
// 跳过空值、非纯数字的钢卷号
|
||||||
|
if (StringUtils.isBlank(coilNo) || !coilNo.matches("^\\d+$")) {
|
||||||
|
log.debug("跳过无效钢卷号:{}(空值或非纯数字)", coilNo);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理大数溢出风险(如果钢卷号超过Long范围,可改用BigDecimal)
|
||||||
|
long currentNum;
|
||||||
|
try {
|
||||||
|
currentNum = Long.parseLong(coilNo);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("钢卷号{}转换为数字失败:{}", coilNo, e.getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新最大值
|
||||||
|
if (currentNum > maxNum) {
|
||||||
|
maxNum = currentNum;
|
||||||
|
maxEnterCoilNo = coilNo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 结果赋值 + 日志记录
|
||||||
result.put("maxEnterCoilNo", maxEnterCoilNo);
|
result.put("maxEnterCoilNo", maxEnterCoilNo);
|
||||||
result.put("prefix", enterCoilNoPrefix);
|
log.info("前缀{}对应的最大入场钢卷号:{}", enterCoilNoPrefix, maxEnterCoilNo == null ? "无匹配记录" : maxEnterCoilNo);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 7. 全局异常捕获,避免接口报错
|
||||||
|
log.error("查询最大入场钢卷号失败,前缀:{}", enterCoilNoPrefix, e);
|
||||||
|
result.put("maxEnterCoilNo", null);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user