Commit ff9d771e by yubin

修bug

parent 88edf56f
package com.ruoyi.common.config;
/**
* 仓库配置类(存储默认仓库、常用仓库ID等)
*/
public class WarehouseConfig {
/**
* 默认出库仓库ID(核心默认值)
*/
public static final String DEFAULT_WAREHOUSE_ID = "572ba484-199c-45d9-9735-610928ed5c70";
}
\ No newline at end of file
......@@ -253,13 +253,13 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
@Transactional(rollbackFor = Exception.class)
@Override
public String importOutboundOrders(List<OutboundTemplateVO> inboundOrdersList, Boolean isUpdateSupport, String operName,Integer orderType) {
// 1. 基础空值校验(完全保留你的代码
public String importOutboundOrders(List<OutboundTemplateVO> inboundOrdersList, Boolean isUpdateSupport, String operName, Integer orderType) {
// 1. 基础空值校验(保留原有逻辑
if (CollectionUtils.isEmpty(inboundOrdersList)) {
throw new ServiceException("导入数据不能为空!");
}
// 2. 初始化变量(完全保留你的代码
// 2. 初始化变量(保留原有逻辑
int totalMainSuccess = 0;
int totalMainFailure = 0;
int totalItemSuccess = 0;
......@@ -274,12 +274,18 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
Map<String, List<OutboundOrderItems>> validItemMap = new HashMap<>();
boolean hasValidateError = false;
// 3. 按入库单号分组(完全保留你的代码)
// ========== 新增:预加载映射缓存(核心优化) ==========
Map<String, String> sapToMaterialIdMap = loadSapToMaterialIdMap(); // 物料SAP->ID
Map<String, String> locationNameToIdMap = loadLocationNameToIdMap(); // 库位名称->ID
Map<String, String> warehouseNameToIdMap = loadWarehouseNameToIdMap(); // 仓库名称->ID
Map<String, String> ownerNameToIdMap = loadOwnerNameToIdMap(); // 货主名称->ID
// 3. 按入库单号分组(保留原有逻辑)
Map<String, List<OutboundTemplateVO>> orderGroupMap = inboundOrdersList.stream()
.filter(vo -> StringUtils.isNotBlank(vo.getOrderId()))
.collect(Collectors.groupingBy(OutboundTemplateVO::getOrderId));
// 4. 第一步:仅验证所有数据(完全保留你的代码
// 4. 第一步:仅验证所有数据(替换为预加载映射校验
for (Map.Entry<String, List<OutboundTemplateVO>> entry : orderGroupMap.entrySet()) {
String orderId = entry.getKey();
List<OutboundTemplateVO> voList = entry.getValue();
......@@ -289,11 +295,12 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
try {
OutboundTemplateVO firstVO = voList.get(0);
// 检查出库单是否已存在(保留原有逻辑)
OutboundOrders outboundOrdersQuery = new OutboundOrders();
outboundOrdersQuery.setOrderId(orderId);
List<OutboundOrders> existMains = outboundOrdersMapper.selectOutboundOrdersList(outboundOrdersQuery);
if (CollectionUtils.isEmpty(existMains) && existMains.size() > 1) {
if (existMains != null && existMains.size() > 1) {
throw new ServiceException(String.format("入库单号【%s】存在多条重复主表数据", orderId));
}
......@@ -302,48 +309,49 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
if (!Boolean.TRUE.equals(isUpdateSupport)) {
throw new ServiceException(String.format("入库单号【%s】已存在,且不支持更新", orderId));
}
// 复用已有主表ID(保留原有逻辑)
mainDO = existMain;
BeanUtils.copyProperties(firstVO, mainDO, "id", "createBy", "createTime");
mainDO.setUpdateBy(operId);
mainDO.setWarehouseId("572ba484-199c-45d9-9735-610928ed5c70");
mainDO.setUpdateTime(now);
mainDO.setUpdateUserCode(operId);
} else {
// 新增主表(保留原有结构,替换货主校验为预加载映射)
mainDO = new OutboundOrders();
com.ruoyi.common.utils.bean.BeanUtils.copyProperties(firstVO, mainDO,
BeanUtils.copyProperties(firstVO, mainDO,
"sapNo", "materialName", "plannedQuantity", "actualQuantity",
"plannedPackages", "materialUnit", "materialRemark");
if (StringUtils.isNotBlank(firstVO.getOwnerName())) {
Owners ownerQuery = new Owners();
ownerQuery.setOwnerName(firstVO.getOwnerName());
List<Owners> owners = ownersService.selectOwnersList(ownerQuery);
if (CollectionUtils.isEmpty(owners)) {
// ========== 货主校验(替换为预加载映射) ==========
String ownerName = firstVO.getOwnerName();
String ownerId = firstVO.getOwnerId();
if (StringUtils.isNotBlank(ownerName)) {
// 从预加载映射获取货主ID,无需重复查询DB
String mappedOwnerId = ownerNameToIdMap.get(ownerName.trim());
if (StringUtils.isBlank(mappedOwnerId)) {
throw new ServiceException(String.format("业主【%s】不存在,无法新增入库单【%s】",
firstVO.getOwnerName(), orderId));
ownerName, orderId));
}
if (firstVO.getOwnerId() != null) {
boolean isMatch = owners.stream().anyMatch(o -> firstVO.getOwnerId().equals(o.getId()));
if (!isMatch) {
throw new ServiceException(String.format("入库单号【%s】的业主ID【%s】与业主名称【%s】不匹配",
orderId, firstVO.getOwnerId(), firstVO.getOwnerName()));
}
mainDO.setOwnerId(firstVO.getOwnerId());
} else {
mainDO.setOwnerId(owners.get(0).getId());
// 货主ID匹配校验
if (ownerId != null && !ownerId.equals(mappedOwnerId)) {
throw new ServiceException(String.format("入库单号【%s】的业主ID【%s】与业主名称【%s】不匹配",
orderId, ownerId, ownerName));
}
} else if (firstVO.getOwnerId() != null) {
Owners ownerById = ownersService.selectOwnersById(firstVO.getOwnerId());
mainDO.setOwnerId(mappedOwnerId);
} else if (ownerId != null) {
// 仅货主ID校验(保留原有逻辑)
Owners ownerById = ownersService.selectOwnersById(ownerId);
if (ownerById == null) {
throw new ServiceException(String.format("入库单号【%s】的业主ID【%s】不存在",
orderId, firstVO.getOwnerId()));
orderId, ownerId));
}
mainDO.setOwnerId(firstVO.getOwnerId());
mainDO.setOwnerId(ownerId);
} else {
throw new ServiceException(String.format("入库单号【%s】的业主名称/ID不能为空", orderId));
}
// 填充主表必填字段(保留原有逻辑)
mainDO.setId(UUID.randomUUID().toString());
mainDO.setOrderId(orderId);
mainDO.setOrderStatus(2L);
......@@ -357,14 +365,16 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
mainDO.setSortNo(Optional.ofNullable(mainDO.getSortNo()).orElse(0L));
}
// ========== 明细校验(替换为预加载映射) ==========
for (int i = 0; i < voList.size(); i++) {
OutboundTemplateVO vo = voList.get(i);
int lineNo = i + 1;
OutboundOrderItems itemDO = new OutboundOrderItems();
com.ruoyi.common.utils.bean.BeanUtils.copyProperties(vo, itemDO,
BeanUtils.copyProperties(vo, itemDO,
"orderId", "systemNo", "orderTypeId", "batchId");
// 填充明细必填字段(保留原有逻辑)
itemDO.setId(UUID.randomUUID().toString());
itemDO.setOrderId(orderId);
itemDO.setBatchCode(Optional.ofNullable(mainDO.getBatchCode()).orElse(""));
......@@ -374,41 +384,44 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
itemDO.setCreateUserCode(operId);
itemDO.setSortNo(0L);
if (StringUtils.isBlank(vo.getSapNo())) {
// ========== 物料SAP校验(替换为预加载映射) ==========
String sapNo = vo.getSapNo() != null ? vo.getSapNo().trim() : "";
if (StringUtils.isBlank(sapNo)) {
throw new ServiceException(String.format("入库单号【%s】第%d条明细的物料SAP号不能为空",
orderId, lineNo));
}
Materials materialsQuery = new Materials();
materialsQuery.setSapNo(vo.getSapNo());
List<Materials> materialsList = materialsService.selectMaterialsList(materialsQuery);
if (CollectionUtils.isEmpty(materialsList)) {
// 从预加载映射获取物料ID,无需重复查询DB
String materialId = sapToMaterialIdMap.get(sapNo);
if (StringUtils.isBlank(materialId)) {
throw new ServiceException(String.format("入库单号【%s】第%d条明细的SAP号【%s】对应的物料不存在",
orderId, lineNo, vo.getSapNo()));
orderId, lineNo, sapNo));
}
itemDO.setMaterialId(materialsList.get(0).getId());
itemDO.setMaterialId(materialId);
if (StringUtils.isBlank(vo.getLocationName())) {
// ========== 库位校验(替换为预加载映射) ==========
String locationName = vo.getLocationName() != null ? vo.getLocationName().trim() : "";
if (StringUtils.isBlank(locationName)) {
throw new ServiceException(String.format("入库单号【%s】第%d条明细的库位名称不能为空",
orderId, lineNo));
}
StorageLocations storageQuery = new StorageLocations();
storageQuery.setLocationCode(vo.getLocationName());
List<StorageLocations> storageList = storageLocationsService.selectStorageLocationsList(storageQuery);
if (CollectionUtils.isEmpty(storageList)) {
// 从预加载映射获取库位ID,无需重复查询DB
String locationId = locationNameToIdMap.get(locationName);
if (StringUtils.isBlank(locationId)) {
throw new ServiceException(String.format("入库单号【%s】第%d条明细的库位【%s】不存在",
orderId, lineNo, vo.getLocationName()));
orderId, lineNo, locationName));
}
itemDO.setLocationId(storageList.get(0).getId());
Warehouses warehouses = new Warehouses();
warehouses.setWarehousesName(vo.getWarehouseName());
List<Warehouses> warehousesList = warehousesService.selectWarehousesList(warehouses);
if (CollectionUtils.isEmpty(warehousesList)) {
throw new ServiceException(String.format("系统未配置仓库,无法导入入库单号【%s】的第%d条明细",
orderId, lineNo));
itemDO.setLocationId(locationId);
// ========== 仓库校验(替换为预加载映射) ==========
String warehouseName = vo.getWarehouseName() != null ? vo.getWarehouseName().trim() : "";
String warehouseId = warehouseNameToIdMap.get(warehouseName);
if (StringUtils.isBlank(warehouseId)) {
throw new ServiceException(String.format("系统未配置仓库【%s】,无法导入入库单号【%s】的第%d条明细",
warehouseName, orderId, lineNo));
}
itemDO.setWarehouseId(warehousesList.get(0).getId());
itemDO.setWarehouseId(warehouseId);
// ========== 库存校验(保留原有逻辑,使用预加载的ID) ==========
Inventory itemsList = new Inventory();
itemsList.setWarehousesId(itemDO.getWarehouseId());
itemsList.setMaterialId(itemDO.getMaterialId());
......@@ -418,11 +431,11 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
if (CollectionUtils.isEmpty(inventory)) {
throw new ServiceException(String.format(
"入库单号【%s】第%d条明细:仓库【%s】+物料【%s】+库位【%s】组合的库存记录不存在",
orderId, lineNo, itemDO.getWarehouseName(),firstVO.getMaterialName(), firstVO.getLocationName()));
orderId, lineNo, vo.getWarehouseName(), vo.getMaterialName(), vo.getLocationName()));
}
itemDO.setInventoryId(inventory.get(0).getId());
itemDO.setItemStatus(3l);
itemDO.setItemStatus(3L);
itemDOList.add(itemDO);
}
......@@ -437,12 +450,12 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
}
}
// 5. 有验证失败直接抛异常(完全保留你的代码
// 5. 有验证失败直接抛异常(保留原有逻辑
if (hasValidateError) {
throw new ServiceException(String.format("验证失败,导入终止!失败详情:%s", failureMsg.toString()));
}
// 6. 验证全通过:统一执行入库/更新操作(完全保留你的代码
// 6. 验证全通过:统一执行入库/更新操作(保留原有逻辑
for (Map.Entry<String, OutboundOrders> entry : validMainMap.entrySet()) {
String orderId = entry.getKey();
OutboundOrders mainDO = entry.getValue();
......@@ -471,9 +484,8 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
}
}
// ========== 仅新增这一段代码(核心:事务提交后执行自定义逻辑) ==========
// 事务提交后执行自定义逻辑(保留原有逻辑)
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// 保存当前需要的变量,用于事务提交后执行
Map<String, OutboundOrders> finalValidMainMap = new HashMap<>(validMainMap);
Map<String, List<OutboundOrderItems>> finalValidItemMap = new HashMap<>(validItemMap);
String finalOperId = operId;
......@@ -482,17 +494,14 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
// 事务提交后,调用你原来的executeCustomLogic方法
executeCustomLogic(finalValidMainMap, finalValidItemMap, finalOperId, finalNow);
}
});
} else {
// 无事务时,直接执行(和你原有逻辑一致)
executeCustomLogic(validMainMap, validItemMap, operId, now);
}
// ========== 新增代码结束 ==========
// 8. 结果汇总(完全保留你的代码
// 8. 结果汇总(保留原有逻辑
if (totalMainFailure > 0 || totalItemFailure > 0) {
String finalFailureMsg = String.format(
"导入结果:成功新增/更新%d个入库单,失败%d个;成功导入%d条明细,失败%d条。失败详情:%s",
......@@ -508,6 +517,108 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
}
}
// ========== 新增:预加载映射辅助方法(核心) ==========
/**
* 预加载物料SAP号 -> 物料ID映射
*/
private Map<String, String> loadSapToMaterialIdMap() {
List<Materials> materialsList = materialsService.selectMaterialsList(new Materials());
if (CollectionUtils.isEmpty(materialsList)) {
return Collections.emptyMap();
}
return materialsList.stream()
.filter(m -> StringUtils.isNotBlank(m.getSapNo()))
.collect(Collectors.toMap(
m -> m.getSapNo().trim(), // key:SAP号(去空格)
Materials::getId, // value:物料ID
(k1, k2) -> k1 // 重复SAP号保留第一个
));
}
/**
* 预加载库位名称(locationCode) -> 库位ID映射
*/
private Map<String, String> loadLocationNameToIdMap() {
StorageLocations query = new StorageLocations();
query.setIsUsed(1L); // 只查可用库位
List<StorageLocations> locationList = storageLocationsService.selectStorageLocationsList(query);
if (CollectionUtils.isEmpty(locationList)) {
return Collections.emptyMap();
}
return locationList.stream()
.filter(l -> StringUtils.isNotBlank(l.getLocationCode()))
.collect(Collectors.toMap(
l -> l.getLocationCode().trim(), // key:库位名称(去空格)
StorageLocations::getId, // value:库位ID
(k1, k2) -> k1 // 重复库位名称保留第一个
));
}
/**
* 预加载仓库名称 -> 仓库ID映射
*/
private Map<String, String> loadWarehouseNameToIdMap() {
Warehouses query = new Warehouses();
query.setIsUsed(1L); // 只查可用仓库
List<Warehouses> warehouseList = warehousesService.selectWarehousesList(query);
if (CollectionUtils.isEmpty(warehouseList)) {
return Collections.emptyMap();
}
return warehouseList.stream()
.filter(w -> StringUtils.isNotBlank(w.getWarehousesName()))
.collect(Collectors.toMap(
w -> w.getWarehousesName().trim(), // key:仓库名称(去空格)
Warehouses::getId, // value:仓库ID
(k1, k2) -> k1 // 重复仓库名称保留第一个
));
}
/**
* 预加载货主名称 -> 货主ID映射
*/
private Map<String, String> loadOwnerNameToIdMap() {
List<Owners> ownerList = ownersService.selectOwnersList(new Owners());
if (CollectionUtils.isEmpty(ownerList)) {
return Collections.emptyMap();
}
return ownerList.stream()
.filter(o -> StringUtils.isNotBlank(o.getOwnerName()))
.collect(Collectors.toMap(
o -> o.getOwnerName().trim(), // key:货主名称(去空格)
Owners::getId, // value:货主ID
(k1, k2) -> k1 // 重复货主名称保留第一个
));
}
private Map<String, String> loadInventoryTOIdMap() {
Inventory inventory = new Inventory();
inventory.setInventoryStatus(1l);
inventory.setIsUsed(1l);
List<Inventory> inventoryList = inventoryService.selectInventoryList(inventory);
if (CollectionUtils.isEmpty(inventoryList)) {
return Collections.emptyMap();
}
return inventoryList.stream()
.filter(inv -> {
// 过滤有效库存:仓库/物料/库位/库存ID都不能为空
return StringUtils.isNotBlank(inv.getWarehousesId());
})
.collect(Collectors.toMap(
// Key:仓库ID+物料ID+库位ID(拼接成唯一标识)
inv -> String.join("_",
inv.getWarehousesId().trim(),
inv.getMaterialId().trim(),
inv.getLocationId().trim()
),
// Value:库存ID(去空格)
inv -> inv.getId().trim(),
// 重复Key处理:保留第一个(避免主键冲突)
(k1, k2) -> k1,
// 指定Map类型(可选,默认HashMap)
HashMap::new
));
}
// 仅修改这个方法中【设置日志ID】的一行代码,其余完全保留
private void executeCustomLogic(Map<String, OutboundOrders> validMainMap,
Map<String, List<OutboundOrderItems>> validItemMap,
......@@ -533,6 +644,8 @@ public class OutboundOrdersServiceImpl implements IOutboundOrdersService
ship(itemList);
}
}
public int ship(List<OutboundOrderItems> outboundOrderItems)
{
if (!outboundOrderItems.isEmpty()) {
......
......@@ -5,6 +5,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.config.WarehouseConfig;
import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
......@@ -280,7 +281,7 @@ public class StorageLocationsServiceImpl implements IStorageLocationsService
storageLocations.setCreateTime(now);
storageLocations.setCreateUserCode(operId);
storageLocations.setWarehousesCode("固定仓库");
storageLocations.setWarehousesId("572ba484-199c-45d9-9735-610928ed5c70");
storageLocations.setWarehousesId(WarehouseConfig.DEFAULT_WAREHOUSE_ID);
// 设置默认值
if (storageLocations.getIsUsed() == null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论