diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java index 5f8bed0bd..b15f5244e 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java @@ -421,7 +421,8 @@ public class ShiftManageApplicationService { if (!isShiftParentCopy(parent, firstChild)) { continue; } - BeanUtils.copyProperties(firstChild, parent, "children", "parentUniqueId", "uniqueId", "shiftIoDetailId"); + // 排除 quantity:子项(parent_copy)通常无 quantity,避免覆盖父项的计划数量 + BeanUtils.copyProperties(firstChild, parent, "children", "parentUniqueId", "uniqueId", "shiftIoDetailId", "quantity"); List newChildren = new ArrayList<>(); for (int i = 1; i < children.size(); i++) { ShiftMaterialDetailDO c = children.get(i); @@ -521,15 +522,25 @@ public class ShiftManageApplicationService { BigDecimal totalShiftQuantity = BigDecimal.ZERO;//移位单当前作业收货数 int totalActualReceiptMaterialQuantity = 0;//移位单收货物料种数 List returnShiftMaterialDetailDOList = new ArrayList<>(); - for (ShiftMaterialDetailDO shiftMaterialDetailDO : shiftManageDO.getShiftMaterialDetailList()){ + List inputDetailList = shiftManageDO.getShiftMaterialDetailList(); + if (CollectionUtils.isEmpty(inputDetailList)) { + throw new ServiceException("物料明细不能为空,请确认已传入 shiftMaterialDetailList 或从 getInfoByApp 获取移位详情"); + } + for (ShiftMaterialDetailDO shiftMaterialDetailDO : inputDetailList){ //设置物料更多属性信息 ShiftMaterialDetailPO shiftMaterialDetailPO = shiftMaterialDetailPODbMap.get(shiftMaterialDetailDO.getShiftIoDetailId()); if (shiftMaterialDetailPO == null){ throw new ServiceException("物料明细不存在"); } //ShiftQuantity前端传过来是0 他那边不好赋值 和Quantity参数统一;有子项时父级已从 assignFirstChildToParentAndRemove 合并了 parent_copy,不再覆盖 + // 注意:assignFirstChildToParentAndRemove 复制时已排除 quantity,避免子项覆盖父项;此处 quantity 为 null 时保留已有 shiftQuantity if (CollectionUtils.isEmpty(shiftMaterialDetailDO.getChildren())) { - shiftMaterialDetailDO.setShiftQuantity(shiftMaterialDetailDO.getQuantity()); + BigDecimal qty = shiftMaterialDetailDO.getQuantity(); + if (qty != null) { + shiftMaterialDetailDO.setShiftQuantity(qty); + } else if (shiftMaterialDetailDO.getShiftQuantity() == null) { + shiftMaterialDetailDO.setShiftQuantity(BigDecimal.ZERO); + } } if (shiftMaterialDetailDO.getShiftQuantity() == null || shiftMaterialDetailDO.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0){ //未进行移位直接跳过(有子项时父级 shiftQuantity 可能为 0,由子项汇总) @@ -608,6 +619,9 @@ public class ShiftManageApplicationService { returnShiftMaterialDetailDO.setChildren(returnShiftMaterialDetailDOChildList); returnShiftMaterialDetailDOList.add(returnShiftMaterialDetailDO); } + if (CollectionUtils.isEmpty(returnShiftMaterialDetailDOList)) { + throw new ServiceException("无有效物料明细可移位,请确认 shiftQuantity>0 或子项有移位数量"); + } returnShiftManageDO.setShiftQuantity(totalShiftQuantity); returnShiftManageDO.setShiftMaterialDetailList(returnShiftMaterialDetailDOList); returnShiftManageDO.setShiftMaterialQuantity(totalActualReceiptMaterialQuantity); diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/service/ShiftManageDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/service/ShiftManageDomainService.java index 8aec71ccc..743e4ef77 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/service/ShiftManageDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/service/ShiftManageDomainService.java @@ -104,6 +104,10 @@ public class ShiftManageDomainService { Map> inMaterialDetailSerialNumberMap = outMaterialDetailSerialNumberPOList.stream() .collect(Collectors.groupingBy(OutMaterialDetailSerialNumberPO::getMaterialDetailUniqueId)); shiftMaterialDetailPOList.forEach(shiftMaterialDetailPO -> { + // 第一次移位显示:shiftQuantity 等于计划数量 quantity + if (shiftMaterialDetailPO.getShiftQuantity() == null || shiftMaterialDetailPO.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0) { + shiftMaterialDetailPO.setShiftQuantity(shiftMaterialDetailPO.getQuantity() != null ? shiftMaterialDetailPO.getQuantity() : BigDecimal.ZERO); + } // PDA移位页面:父级也填充批次属性、净重、毛重、面积、体积,保证顶层结构有值 fillMaterialMoreDetailForShiftDetail(shiftMaterialDetailPO); // 填充 totalNetWeight 等,供 PDA 表单区(移入数量、移入库位、容器旁)显示 @@ -113,6 +117,10 @@ public class ShiftManageDomainService { List shiftMaterialDetailPOChildrenNowList = new ArrayList<>(); ShiftMaterialDetailPO shiftMaterialDetailPOChildrenNow = new ShiftMaterialDetailPO(); BeanUtils.copyProperties(shiftMaterialDetailPO, shiftMaterialDetailPOChildrenNow, "children"); + // parent_copy 首次显示时 shiftQuantity 等于计划数量 + if (shiftMaterialDetailPOChildrenNow.getShiftQuantity() == null || shiftMaterialDetailPOChildrenNow.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0) { + shiftMaterialDetailPOChildrenNow.setShiftQuantity(shiftMaterialDetailPOChildrenNow.getQuantity() != null ? shiftMaterialDetailPOChildrenNow.getQuantity() : BigDecimal.ZERO); + } List materialDetailSerialNumberList = inMaterialDetailSerialNumberMap.get(shiftMaterialDetailPO.getUniqueId()); if (!CollectionUtils.isEmpty(materialDetailSerialNumberList)){ shiftMaterialDetailPOChildrenNow.setMaterialDetailSerialNumberList(materialDetailSerialNumberList); @@ -126,18 +134,24 @@ public class ShiftManageDomainService { shiftMaterialDetailPOChildrenNowList.add(shiftMaterialDetailPOChildrenNow); //子集 List shiftMaterialDetailPOChildrenList = shiftMaterialDetailPO.getChildren(); - shiftMaterialDetailPOChildrenList.forEach(receiptMaterialDetailPOChildren -> { - fillMaterialMoreDetailForShiftDetail(receiptMaterialDetailPOChildren); - fillTotalWeightVolumeArea(receiptMaterialDetailPOChildren); - fillNewStorageLocationName(receiptMaterialDetailPOChildren); - List materialDetailSerialNumberChildrenList = inMaterialDetailSerialNumberMap.get(shiftMaterialDetailPO.getUniqueId()); - if (!CollectionUtils.isEmpty(materialDetailSerialNumberChildrenList)){ - receiptMaterialDetailPOChildren.setMaterialDetailSerialNumberList(materialDetailSerialNumberChildrenList); - }else { - receiptMaterialDetailPOChildren.setMaterialDetailSerialNumberList(new ArrayList<>()); - } - }); - shiftMaterialDetailPOChildrenNowList.addAll(shiftMaterialDetailPOChildrenList); + if (shiftMaterialDetailPOChildrenList != null) { + shiftMaterialDetailPOChildrenList.forEach(receiptMaterialDetailPOChildren -> { + // 第一次移位显示:子项 shiftQuantity 等于计划数量 + if (receiptMaterialDetailPOChildren.getShiftQuantity() == null || receiptMaterialDetailPOChildren.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0) { + receiptMaterialDetailPOChildren.setShiftQuantity(receiptMaterialDetailPOChildren.getQuantity() != null ? receiptMaterialDetailPOChildren.getQuantity() : BigDecimal.ZERO); + } + fillMaterialMoreDetailForShiftDetail(receiptMaterialDetailPOChildren); + fillTotalWeightVolumeArea(receiptMaterialDetailPOChildren); + fillNewStorageLocationName(receiptMaterialDetailPOChildren); + List materialDetailSerialNumberChildrenList = inMaterialDetailSerialNumberMap.get(shiftMaterialDetailPO.getUniqueId()); + if (!CollectionUtils.isEmpty(materialDetailSerialNumberChildrenList)){ + receiptMaterialDetailPOChildren.setMaterialDetailSerialNumberList(materialDetailSerialNumberChildrenList); + }else { + receiptMaterialDetailPOChildren.setMaterialDetailSerialNumberList(new ArrayList<>()); + } + }); + shiftMaterialDetailPOChildrenNowList.addAll(shiftMaterialDetailPOChildrenList); + } shiftMaterialDetailPO.setChildren(shiftMaterialDetailPOChildrenNowList); }); shiftManagePO.setShiftMaterialDetailList(shiftMaterialDetailPOList); @@ -676,10 +690,14 @@ public class ShiftManageDomainService { ShiftMaterialDetailDO shiftMaterialDetailDO = new ShiftMaterialDetailDO(); shiftMaterialDetailDO.setShiftNumber(shiftNumber); List shiftMaterialDetailPOList = shiftMaterialDetailService.queryListChildren(shiftMaterialDetailDO); - Map> MaterialMoreDetailMap = shiftMaterialDetailList.stream().collect(Collectors.toMap( - ShiftMaterialDetailDO::getShiftNumber, - ShiftMaterialDetailDO::getMaterialMoreDetailList - )); + // 避免 NPE:getMaterialMoreDetailList 可能为 null;同一 shift 下 shiftNumber 重复需合并 + Map> MaterialMoreDetailMap = shiftMaterialDetailList.stream() + .filter(d -> d.getShiftNumber() != null) + .collect(Collectors.toMap( + ShiftMaterialDetailDO::getShiftNumber, + d -> d.getMaterialMoreDetailList() != null ? d.getMaterialMoreDetailList() : new ArrayList<>(), + (a, b) -> a + )); for (ShiftMaterialDetailPO shiftMaterialDetailPO : shiftMaterialDetailPOList){ MaterialInventory materialInventoryOldDb = materialInventoryService.getById(shiftMaterialDetailPO.getMaterialInventoryId()); BigDecimal shiftQuantity = shiftMaterialDetailPO.getShiftQuantity(); diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/shiftManage/ShiftManageAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/shiftManage/ShiftManageAssembler.java index e71d0ae6e..e2a21a850 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/shiftManage/ShiftManageAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/shiftManage/ShiftManageAssembler.java @@ -1,9 +1,17 @@ package com.mhd.wms.interfaces.assember.shiftManage; -import cn.hutool.json.JSONUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mhd.common.core.utils.bean.BeanUtils; import com.mhd.wms.domain.shiftManage.repository.todo.ShiftManageDO; +import com.mhd.wms.domain.shiftMaterialDetail.repository.todo.ShiftMaterialDetailDO; import com.mhd.wms.interfaces.dto.shiftManage.ShiftManageDTO; +import com.mhd.wms.interfaces.dto.shiftMaterialDetail.ShiftMaterialDetailDTO; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; /** * 移位管理Assembler @@ -14,11 +22,41 @@ import org.springframework.stereotype.Component; @Component public class ShiftManageAssembler { + @Autowired + private ObjectMapper objectMapper; + /** * 转换实体 + * ObjectMapper.convertValue 对嵌套 List 的泛型转换可能失败(空或 LinkedHashMap 等错误类型), + * 因此当 DTO 有物料明细时,始终使用 BeanUtils 手动递归转换,确保类型正确 */ public ShiftManageDO toDO(ShiftManageDTO shiftManageDTO) { - return JSONUtil.toBean(JSONUtil.toJsonStr(shiftManageDTO), ShiftManageDO.class); + ShiftManageDO shiftManageDO = objectMapper.convertValue(shiftManageDTO, ShiftManageDO.class); + // 修复:始终手动转换 shiftMaterialDetailList,避免 ObjectMapper 泛型擦除导致空列表或错误类型 + if (!CollectionUtils.isEmpty(shiftManageDTO.getShiftMaterialDetailList())) { + List doList = new ArrayList<>(); + for (ShiftMaterialDetailDTO dto : shiftManageDTO.getShiftMaterialDetailList()) { + doList.add(convertShiftMaterialDetailToDO(dto)); + } + shiftManageDO.setShiftMaterialDetailList(doList); + } + return shiftManageDO; + } + + /** + * 递归转换 ShiftMaterialDetailDTO 为 ShiftMaterialDetailDO(含 children) + */ + private ShiftMaterialDetailDO convertShiftMaterialDetailToDO(ShiftMaterialDetailDTO dto) { + ShiftMaterialDetailDO doObj = new ShiftMaterialDetailDO(); + BeanUtils.copyProperties(dto, doObj); + if (!CollectionUtils.isEmpty(dto.getChildren())) { + List childDoList = new ArrayList<>(); + for (ShiftMaterialDetailDTO childDto : dto.getChildren()) { + childDoList.add(convertShiftMaterialDetailToDO(childDto)); + } + doObj.setChildren(childDoList); + } + return doObj; } }