no message

main
HUOJIN\92525 2026-01-13 23:21:36 +08:00
parent f39de8e134
commit 3d5c48edf1
7 changed files with 89 additions and 72 deletions

View File

@ -116,8 +116,7 @@ public class BatchProcessor {
* *
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchAllocate(Map<Long, Inventory> inventoryUpdateMap, Map<Long, PickDetail> pickDetailUpdateMap, List<Task> createToTask) { public boolean batchAllocate(Map<Long, Inventory> inventoryUpdateMap, Map<Long, PickDetail> pickDetailUpdateMap, List<Task> createToTask) {
List<Inventory> updateToInventory = new ArrayList<>(inventoryUpdateMap.values()); List<Inventory> updateToInventory = new ArrayList<>(inventoryUpdateMap.values());
List<PickDetail> updateToPickDetail = new ArrayList<>(pickDetailUpdateMap.values()); List<PickDetail> updateToPickDetail = new ArrayList<>(pickDetailUpdateMap.values());
if (CollectionUtils.isNotEmpty(updateToInventory)) { if (CollectionUtils.isNotEmpty(updateToInventory)) {
@ -128,7 +127,9 @@ public class BatchProcessor {
} }
if (CollectionUtils.isNotEmpty(createToTask)) { if (CollectionUtils.isNotEmpty(createToTask)) {
batchUtil.saveBatchTask(createToTask); batchUtil.saveBatchTask(createToTask);
return true;
} }
return false;
} }
/** /**

View File

@ -154,9 +154,9 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
pointMapper.updateById(newPoint); pointMapper.updateById(newPoint);
} }
ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3()); ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3());
oldInventory.setItemKeyId(itemKey.getId()); inventory.setItemKeyId(itemKey.getId());
oldInventory.setItemId(inventory.getItemId()); inventory.setItemId(inventory.getItemId());
inventoryMapper.updateById(oldInventory); inventoryService.updateById(inventory);
return Result.OK("编辑成功!"); return Result.OK("编辑成功!");
} }

View File

@ -40,15 +40,6 @@ public class AllocatePickDetailJob implements Job {
@Autowired @Autowired
private IPickDetailService pickDetailService; private IPickDetailService pickDetailService;
@Autowired
private BaseCommonService baseCommonService;
// 使用 ConcurrentHashMap 缓存已处理的结果
private static final Map<String, Boolean> processedCache = new ConcurrentHashMap<>();
// 缓存最大大小,防止内存溢出
private static final int MAX_CACHE_SIZE = 1000;
@Override @Override
public void execute(JobExecutionContext jobExecutionContext) { public void execute(JobExecutionContext jobExecutionContext) {
//1.获取未拣货完成的出库明细 //1.获取未拣货完成的出库明细
@ -176,7 +167,10 @@ public class AllocatePickDetailJob implements Job {
// 检查是否需要分配 // 检查是否需要分配
if (shouldAllocatePickDetail(executingTaskKeys, currentKey)) { if (shouldAllocatePickDetail(executingTaskKeys, currentKey)) {
allocatePickDetail(detail); boolean allocated = allocatePickDetail(detail);
if (allocated) {
return true;
}
} }
} }
return false; // 未分配任何明细 return false; // 未分配任何明细
@ -221,7 +215,10 @@ public class AllocatePickDetailJob implements Job {
if (isAlreadyAssigned(detail.getStatus())) { if (isAlreadyAssigned(detail.getStatus())) {
continue; continue;
} }
allocatePickDetail(detail); boolean allocated = allocatePickDetail(detail);
if (allocated) {
return;
}
} }
} }
@ -235,45 +232,13 @@ public class AllocatePickDetailJob implements Job {
return PickStatusEnum.ASSIGNED.getValue().equals(status); return PickStatusEnum.ASSIGNED.getValue().equals(status);
} }
private void allocatePickDetail(PickDetail pickDetail) { private boolean allocatePickDetail(PickDetail pickDetail) {
// 分配单个出库明细
List<String> resultMsg;
try { try {
// 每次只分配一个出库单明细 return pickService.allocatePickDetail(pickDetail);
resultMsg = pickService.allocatePickDetail(pickDetail);
if (CollectionUtils.isNotEmpty(resultMsg)) {
// 生成缓存键
String cacheKey = generateCacheKey(resultMsg);
// 检查是否已经处理过相同的内容
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
baseCommonService.addLog("出库明细分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 添加到缓存
processedCache.put(cacheKey, true);
// 控制缓存大小
if (processedCache.size() > MAX_CACHE_SIZE) {
processedCache.clear();
}
}
}
} catch (Exception e) { } catch (Exception e) {
resultMsg = List.of(e.getMessage()); log.error("分配出库明细失败ID: {}, 错误: {}", pickDetail.getId(), e.getMessage());
log.error("分配出库明细失败ID: {}, 错误: {}", pickDetail.getId(), resultMsg); return false;
} }
} }
/**
* -
*/
private String generateCacheKey(List<String> resultMsg) {
// 对结果进行排序后拼接,确保相同内容生成相同键
return resultMsg.stream()
.filter(Objects::nonNull)
.sorted()
.collect(Collectors.joining("\n"));
}
} }

View File

@ -52,10 +52,10 @@ public class Asn implements Serializable {
@Schema(description = "系统单号") @Schema(description = "系统单号")
private java.lang.String orderNo; private java.lang.String orderNo;
/** /**
* *
*/ */
@Excel(name = "外部单号", width = 15) @Excel(name = "赛意单号", width = 15)
@Schema(description = "外部单号") @Schema(description = "赛意单号")
private java.lang.String thirdOrderNo; private java.lang.String thirdOrderNo;
/** /**
* *

View File

@ -59,7 +59,7 @@ public interface IPickService extends IService<Pick> {
* *
* @param pickDetail * @param pickDetail
*/ */
List<String> allocatePickDetail(PickDetail pickDetail); boolean allocatePickDetail(PickDetail pickDetail);
/** /**
* *

View File

@ -155,7 +155,7 @@ public class PickServiceImpl extends ServiceImpl<PickMapper, Pick> implements IP
} }
@Override @Override
public List<String> allocatePickDetail(PickDetail pickDetail) { public boolean allocatePickDetail(PickDetail pickDetail) {
return allocateProcessor.allocatePickDetail(pickDetail); return allocateProcessor.allocatePickDetail(pickDetail);
} }

View File

@ -31,11 +31,14 @@ import org.cpte.modules.shipping.vo.InventoryScore;
import org.cpte.modules.shipping.vo.ItemGroupKey; import org.cpte.modules.shipping.vo.ItemGroupKey;
import org.cpte.modules.utils.BigDecimalUtil; import org.cpte.modules.utils.BigDecimalUtil;
import org.cpte.modules.utils.RedisDistributedLockUtil; import org.cpte.modules.utils.RedisDistributedLockUtil;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.base.service.BaseCommonService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -81,6 +84,9 @@ public class AllocateProcessor {
@Autowired @Autowired
private IInventoryLogService inventoryLogService; private IInventoryLogService inventoryLogService;
@Autowired
private BaseCommonService baseCommonService;
@Autowired @Autowired
private ScanTrayProcessor scanTrayProcessor; private ScanTrayProcessor scanTrayProcessor;
@ -93,6 +99,12 @@ public class AllocateProcessor {
@Autowired @Autowired
private RedisDistributedLockUtil redissonLock; private RedisDistributedLockUtil redissonLock;
// 使用 ConcurrentHashMap 缓存已处理的结果
private static final Map<String, Boolean> processedCache = new ConcurrentHashMap<>();
// 缓存最大大小,防止内存溢出
private static final int MAX_CACHE_SIZE = 1000;
/** /**
* *
@ -108,7 +120,7 @@ public class AllocateProcessor {
AllocationData data = prepareAllocationData(pickIds); AllocationData data = prepareAllocationData(pickIds);
//2.验证库存 //2.验证库存
if (!validateInventory(data, errorMsgSet)) { if (validateInventory(data, errorMsgSet)) {
return new ArrayList<>(errorMsgSet); return new ArrayList<>(errorMsgSet);
} }
@ -139,7 +151,7 @@ public class AllocateProcessor {
* @param pickDetail * @param pickDetail
* @return * @return
*/ */
public List<String> allocatePickDetail(PickDetail pickDetail) { public boolean allocatePickDetail(PickDetail pickDetail) {
// 错误信息去重LinkedHashSet保证顺序和唯一 // 错误信息去重LinkedHashSet保证顺序和唯一
Set<String> errorMsgSet = new LinkedHashSet<>(); Set<String> errorMsgSet = new LinkedHashSet<>();
@ -147,8 +159,8 @@ public class AllocateProcessor {
AllocationData data = prepareAllocationDetailData(pickDetail); AllocationData data = prepareAllocationDetailData(pickDetail);
//2.验证库存 //2.验证库存
if (!validateInventory(data, errorMsgSet)) { if (validateInventory(data, errorMsgSet)) {
return new ArrayList<>(errorMsgSet); return false;
} }
//3.创建数据结构 //3.创建数据结构
@ -164,12 +176,12 @@ public class AllocateProcessor {
moveTask(createToTask, movePoints); moveTask(createToTask, movePoints);
//6.批量操作 //6.批量操作
batchProcessor.batchAllocate(inventoryUpdateMap, pickDetailUpdateMap, createToTask); boolean result = batchProcessor.batchAllocate(inventoryUpdateMap, pickDetailUpdateMap, createToTask);
//7.刷新出库单 //7.刷新出库单
refreshData(data); refreshData(data);
return new ArrayList<>(errorMsgSet); return result;
} }
@ -212,8 +224,8 @@ public class AllocateProcessor {
List<Long> itemKeyIds = list.stream().map(Inventory::getItemKeyId).distinct().toList(); List<Long> itemKeyIds = list.stream().map(Inventory::getItemKeyId).distinct().toList();
List<ItemKey> iks = itemKeyMapper.selectByIds(itemKeyIds); List<ItemKey> iks = itemKeyMapper.selectByIds(itemKeyIds);
if (CollectionUtils.isNotEmpty(itemKeys)) { if (CollectionUtils.isNotEmpty(itemKeys)) {
for (ItemKey ik : iks){ for (ItemKey ik : iks) {
if(!itemKeys.contains(ik)){ if (!itemKeys.contains(ik)) {
itemKeys.add(ik); itemKeys.add(ik);
} }
} }
@ -223,7 +235,7 @@ public class AllocateProcessor {
} }
} }
} }
if(CollectionUtils.isNotEmpty(itemKeys)){ if (CollectionUtils.isNotEmpty(itemKeys)) {
//根据物料属性分组 //根据物料属性分组
Map<ItemGroupKey, ItemKey> itemGroupKey = itemKeys.stream() Map<ItemGroupKey, ItemKey> itemGroupKey = itemKeys.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
@ -306,8 +318,8 @@ public class AllocateProcessor {
List<Long> itemKeyIds = list.stream().map(Inventory::getItemKeyId).distinct().toList(); List<Long> itemKeyIds = list.stream().map(Inventory::getItemKeyId).distinct().toList();
List<ItemKey> iks = itemKeyMapper.selectByIds(itemKeyIds); List<ItemKey> iks = itemKeyMapper.selectByIds(itemKeyIds);
if (CollectionUtils.isNotEmpty(itemKeys)) { if (CollectionUtils.isNotEmpty(itemKeys)) {
for (ItemKey ik : iks){ for (ItemKey ik : iks) {
if(!itemKeys.contains(ik)){ if (!itemKeys.contains(ik)) {
itemKeys.add(ik); itemKeys.add(ik);
} }
} }
@ -316,7 +328,7 @@ public class AllocateProcessor {
} }
} }
} }
if(CollectionUtils.isNotEmpty(itemKeys)){ if (CollectionUtils.isNotEmpty(itemKeys)) {
//根据物料属性分组 //根据物料属性分组
Map<ItemGroupKey, ItemKey> itemGroupKey = itemKeys.stream() Map<ItemGroupKey, ItemKey> itemGroupKey = itemKeys.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
@ -373,9 +385,11 @@ public class AllocateProcessor {
if (CollectionUtils.isEmpty(inventories)) { if (CollectionUtils.isEmpty(inventories)) {
String itemCodes = data.getItemMap().values().stream().map(Item::getItemCode).collect(Collectors.joining(",")); String itemCodes = data.getItemMap().values().stream().map(Item::getItemCode).collect(Collectors.joining(","));
errorMsgSet.add("【" + itemCodes + "】物料库存不足"); errorMsgSet.add("【" + itemCodes + "】物料库存不足");
return false; String cacheKey = generateCacheKey(errorMsgSet);
logAndCacheResult(cacheKey);
return true;
} }
return true; return false;
} }
/** /**
@ -465,6 +479,9 @@ public class AllocateProcessor {
); );
ItemKey itemKey = data.getItemGroupMap().get(groupKey); ItemKey itemKey = data.getItemGroupMap().get(groupKey);
if (itemKey == null) {
return new ArrayList<>();
}
return data.getInventoryMap().get(itemKey.getId()); return data.getInventoryMap().get(itemKey.getId());
} }
@ -482,6 +499,8 @@ public class AllocateProcessor {
errorMsgSet.add(String.format("物料【%s】无匹配库存物料ID:%s批次:%s库存状态:%s仓库:%s", errorMsgSet.add(String.format("物料【%s】无匹配库存物料ID:%s批次:%s库存状态:%s仓库:%s",
item.getItemCode(), item.getId(), item.getItemCode(), item.getId(),
pickDetail.getPropC1(), pickDetail.getPropC3(), pick.getWhCode())); pickDetail.getPropC1(), pickDetail.getPropC3(), pick.getWhCode()));
String cacheKey = generateCacheKey(errorMsgSet);
logAndCacheResult(cacheKey);
} }
/** /**
@ -516,7 +535,7 @@ public class AllocateProcessor {
Stock stock = stockService.getById(pickDetail.getStockId()); Stock stock = stockService.getById(pickDetail.getStockId());
String message = String.format("任务号【%s】,容器【%s】无库存", pick.getNo(), stock.getStockCode()); String message = String.format("任务号【%s】,容器【%s】无库存", pick.getNo(), stock.getStockCode());
errorMsgSet.add(message); errorMsgSet.add(message);
return; logAndCacheResult(message);
} }
//未分配数量 //未分配数量
@ -877,6 +896,7 @@ public class AllocateProcessor {
unallocateQty unallocateQty
); );
errorMsgSet.add(failInfo); errorMsgSet.add(failInfo);
logAndCacheResult(failInfo);
} }
/** /**
@ -992,4 +1012,35 @@ public class AllocateProcessor {
pickDetailService.refreshPick(entry.getValue(), pickDetailMapper.selectByMainId(entry.getKey())); pickDetailService.refreshPick(entry.getValue(), pickDetailMapper.selectByMainId(entry.getKey()));
} }
} }
/**
*
*
* @param cacheKey
*/
private void logAndCacheResult(String cacheKey) {
// 检查是否已经处理过相同的内容
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
// 注意这里需要注入baseCommonService
baseCommonService.addLog("出库明细分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 添加到缓存
processedCache.put(cacheKey, true);
// 控制缓存大小
if (processedCache.size() > MAX_CACHE_SIZE) {
processedCache.clear();
}
}
}
private String generateCacheKey(Collection<String> resultMsg) {
// 对结果进行排序后拼接,确保相同内容生成相同键
return resultMsg.stream()
.filter(Objects::nonNull)
.sorted()
.collect(Collectors.joining("\n"));
}
} }