feat(wms): 添加钢卷ID映射下一步钢卷ID功能

- 在IWmsMaterialCoilService接口中新增getUpdatedCoilIdsByOldCoilIds方法
- 在WmsMaterialCoilController中添加/nexCoilIds接口端点
- 在WmsMaterialCoilServiceImpl中实现钢卷ID映射逻辑,支持分卷、合卷和普通更新场景
- 添加Jackson JSON处理依赖和日志记录功能
- 实现复杂的钢卷关系解析,包括步骤遍历和子卷ID处理
- 提供详细的异常处理和日志记录机制
This commit is contained in:
2026-01-10 11:34:01 +08:00
parent 915d1eb7ec
commit 2f11e6eaab
3 changed files with 187 additions and 4 deletions

View File

@@ -5,6 +5,7 @@ import java.util.Map;
import java.util.Arrays;
import java.util.stream.Collectors;
import com.klp.common.core.domain.AjaxResult;
import com.klp.domain.vo.WmsMaterialCoilExportVo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
@@ -211,5 +212,24 @@ public class WmsMaterialCoilController extends BaseController {
Boolean result = iWmsMaterialCoilService.batchUpdateDeliveryStatus(coilIdList, status);
return result ? R.ok() : R.fail("批量更新失败");
}
/**
* 根据更新前的钢卷ID列表获取更新后的钢卷ID映射关系
*/
@GetMapping("/nextCoilIds")
public R<Map<Long, String>> getUpdatedCoilIdsByOldCoilIds(@RequestParam List<Long> oldCoilIds)
{
if (oldCoilIds == null || oldCoilIds.isEmpty()) {
return R.fail("钢卷ID列表不能为空");
}
try {
Map<Long, String> result = iWmsMaterialCoilService.getUpdatedCoilIdsByOldCoilIds(oldCoilIds);
return R.ok(result);
} catch (Exception e) {
return R.fail("获取更新后的钢卷ID失败: " + e.getMessage());
}
}
}

View File

@@ -102,5 +102,14 @@ public interface IWmsMaterialCoilService {
Boolean batchUpdateDeliveryStatus(List<Long> coilIdList, Integer status);
/**
* 根据更新前的钢卷ID列表获取更新后的钢卷ID列表
*
* @param oldCoilIds 更新前的钢卷ID列表
* @return 更新后的钢卷ID列表
*/
Map<Long, String> getUpdatedCoilIdsByOldCoilIds(List<Long> oldCoilIds);
}

View File

@@ -3,6 +3,7 @@ package com.klp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.esotericsoftware.minlog.Log;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.klp.common.core.domain.entity.SysUser;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
@@ -13,18 +14,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.helper.LoginHelper;
import com.klp.common.utils.StringUtils;
import com.klp.common.utils.spring.SpringUtils;
import com.klp.domain.WmsDeliveryPlan;
import com.klp.domain.WmsProduct;
import com.klp.domain.WmsRawMaterial;
import com.klp.domain.*;
import com.klp.domain.bo.*;
import com.klp.domain.vo.*;
import com.klp.mapper.WmsDeliveryPlanMapper;
import com.klp.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.klp.domain.WmsMaterialCoil;
import com.klp.mapper.WmsMaterialCoilMapper;
import com.klp.mapper.WmsStockMapper;
import com.klp.mapper.WmsProductMapper;
@@ -50,6 +49,7 @@ import java.math.BigDecimal;
* @author Joshi
* @date 2025-07-18
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
@@ -1950,4 +1950,158 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
return baseMapper.update(null, updateWrapper) > 0;
}
/**
* 根据更新前的钢卷ID列表获取对应的直接下一步钢卷ID
* 分卷场景返回所有子卷ID逗号分隔合卷/普通更新返回单个ID
*
* @param oldCoilIds 更新前的钢卷ID列表
* @return Map<旧钢卷ID, 下一步钢卷ID字符串>
* - 普通更新/合卷value为单个ID字符串如"1002"
* - 分卷value为逗号分隔的子卷ID字符串如"1003,1004,1005"
* - 无下一步value为null
*/
public Map<Long, String> getUpdatedCoilIdsByOldCoilIds(List<Long> oldCoilIds) {
// 初始化返回的Mapkey=旧IDvalue=下一步ID字符串逗号分隔
Map<Long, String> old2NextCoilIdMap = new LinkedHashMap<>();
if (oldCoilIds == null || oldCoilIds.isEmpty()) {
return old2NextCoilIdMap;
}
// 先将所有旧ID放入Map默认value为null
for (Long oldCoilId : oldCoilIds) {
old2NextCoilIdMap.put(oldCoilId, null);
}
ObjectMapper objectMapper = new ObjectMapper();
// 遍历每个旧ID解析对应的下一步ID
for (Long oldCoilId : oldCoilIds) {
String nextCoilIdsStr = null; // 存储最终返回的ID字符串单个/逗号分隔)
try {
// 1. 查询旧钢卷记录
WmsMaterialCoil oldCoil = baseMapper.selectById(oldCoilId);
if (oldCoil == null || oldCoil.getQrcodeRecordId() == null) {
old2NextCoilIdMap.put(oldCoilId, null);
continue;
}
// 2. 查询关联的二维码记录
LambdaQueryWrapper<WmsGenerateRecord> qrWrapper = Wrappers.lambdaQuery();
qrWrapper.eq(WmsGenerateRecord::getSerialNumber, oldCoil.getEnterCoilNo())
.or()
.like(WmsGenerateRecord::getSerialNumber, oldCoil.getEnterCoilNo() + "-");
List<WmsGenerateRecordVo> qrRecords = generateRecordMapper.selectVoList(qrWrapper);
if (qrRecords.isEmpty()) {
old2NextCoilIdMap.put(oldCoilId, null);
continue;
}
// 3. 解析每个二维码的步骤
for (WmsGenerateRecordVo qrRecord : qrRecords) {
if (qrRecord.getContent() == null || qrRecord.getContent().trim().isEmpty()) {
continue;
}
Map<String, Object> contentMap;
try {
contentMap = objectMapper.readValue(qrRecord.getContent(), Map.class);
} catch (JsonProcessingException e) {
log.warn("解析二维码记录[{}]的content失败: {}", qrRecord.getRecordId(), e.getMessage());
continue;
}
List<Map<String, Object>> steps = (List<Map<String, Object>>) contentMap.get("steps");
if (steps == null || steps.isEmpty()) {
continue;
}
String oldCoilIdStr = oldCoilId.toString();
// 4. 遍历步骤找下一步ID
for (Map<String, Object> step : steps) {
String stepOldCoilIdStr = step.get("old_coil_id") != null ? step.get("old_coil_id").toString() : null;
String newCoilIdStr = step.get("new_coil_id") != null ? step.get("new_coil_id").toString() : null;
// 普通更新场景单个ID
if (stepOldCoilIdStr != null && stepOldCoilIdStr.equals(oldCoilIdStr)
&& newCoilIdStr != null && !"null".equals(newCoilIdStr)) {
nextCoilIdsStr = newCoilIdStr;
break;
}
// 合卷场景单个ID
String parentCoilIds = step.get("parent_coil_ids") != null ? step.get("parent_coil_ids").toString() : null;
if (parentCoilIds != null && parentCoilIds.contains(oldCoilIdStr)) {
String newCurrentCoilNo = step.get("new_current_coil_no") != null ? step.get("new_current_coil_no").toString() : null;
if (newCurrentCoilNo != null) {
LambdaQueryWrapper<WmsMaterialCoil> coilWrapper = Wrappers.lambdaQuery();
coilWrapper.eq(WmsMaterialCoil::getCurrentCoilNo, newCurrentCoilNo)
.eq(WmsMaterialCoil::getDataType, 1);
WmsMaterialCoil nextCoil = baseMapper.selectOne(coilWrapper);
if (nextCoil != null) {
nextCoilIdsStr = nextCoil.getCoilId().toString();
break;
}
}
}
// 分卷场景所有子卷ID逗号分隔
String operation = step.get("operation") != null ? step.get("operation").toString() : "";
if ("分卷".equals(operation) && oldCoilIdStr.equals(stepOldCoilIdStr)) {
String newCurrentCoilNos = step.get("new_current_coil_nos") != null ? step.get("new_current_coil_nos").toString() : null;
List<String> childCoilNos = null;
// 解析子卷号列表
if (newCurrentCoilNos != null && !newCurrentCoilNos.isEmpty()) {
childCoilNos = Arrays.asList(newCurrentCoilNos.split(","));
} else if (step.get("child_coils") instanceof List) {
childCoilNos = (List<String>) step.get("child_coils");
}
// 批量查询所有子卷ID并拼接为逗号分隔的字符串
if (childCoilNos != null && !childCoilNos.isEmpty()) {
// 去重+trim避免空字符串/重复卷号
List<String> validChildCoilNos = childCoilNos.stream()
.map(String::trim)
.filter(no -> !no.isEmpty())
.distinct()
.collect(Collectors.toList());
if (!validChildCoilNos.isEmpty()) {
// 批量查询(性能优化,避免循环查询)
LambdaQueryWrapper<WmsMaterialCoil> coilWrapper = Wrappers.lambdaQuery();
coilWrapper.in(WmsMaterialCoil::getCurrentCoilNo, validChildCoilNos)
.eq(WmsMaterialCoil::getDataType, 1);
List<WmsMaterialCoil> childCoils = baseMapper.selectList(coilWrapper);
// 拼接子卷ID为逗号分隔的字符串
if (!childCoils.isEmpty()) {
nextCoilIdsStr = childCoils.stream()
.map(coil -> coil.getCoilId().toString())
.collect(Collectors.joining(","));
break;
}
}
}
}
}
if (nextCoilIdsStr != null) {
break; // 找到结果,跳出二维码循环
}
}
// 5. 将结果放入Map
old2NextCoilIdMap.put(oldCoilId, nextCoilIdsStr);
} catch (Exception e) {
log.error("解析钢卷ID[{}]的下一步ID失败", oldCoilId, e);
old2NextCoilIdMap.put(oldCoilId, null);
}
}
return old2NextCoilIdMap;
}
}