From 2190fcf6235ee172f7095d1238e8e88f9767bc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Mon, 2 Feb 2026 13:31:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=93=E5=86=85=EF=BC=88=E7=A7=BB=E4=BD=8D?= =?UTF-8?q?=E3=80=81=E7=9B=98=E7=82=B9=EF=BC=89=E6=89=B9=E6=AC=A1=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E4=BF=AE=E6=94=B9=20=E5=87=BA=E5=BA=93=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E8=B0=83=E6=95=B4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...InvestigationManageApplicationService.java | 281 +++++++++++++- ...ShiftMaterialDetailApplicationService.java | 286 ++++++++++++++- .../StockOutOrderApplicationService.java | 343 +++++++++++++++++- .../po/InvestigetionManageDetailPO.java | 6 + .../mapper/MaterialInventoryMapper.java | 7 + .../entity/OutMaterialDetail.java | 2 +- .../repository/po/OutMaterialDetailPO.java | 8 +- .../repository/todo/OutMaterialDetailDO.java | 2 +- .../repository/po/ShiftMaterialDetailPO.java | 4 + .../listener/ExcelParseService.java | 4 +- .../repository/listener/ItemListener.java | 2 +- .../OutMaterialDetailDTO.java | 2 +- .../ShiftMaterialDetailApi.java | 3 +- .../OutMaterialDetailMapper.xml | 4 +- .../MaterialInventoryMapper.xml | 34 ++ 15 files changed, 967 insertions(+), 21 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java index 16c4b9847..e753bf178 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java @@ -5,11 +5,13 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; import com.mhd.common.core.utils.bean.BeanUtils; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.domain.WarehouseFeignPO; import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO; import com.mhd.system.api.domain.cache.SystemServiceCacheUtil; @@ -20,14 +22,18 @@ import com.mhd.wms.domain.investigationManage.service.InvestigationManageDomainS import com.mhd.wms.domain.investigetionManageDetail.repository.po.InvestigetionManageDetailPO; import com.mhd.wms.domain.investigetionManageDetail.repository.todo.InvestigetionManageDetailDO; import com.mhd.wms.domain.investigetionManageDetail.service.InvestigetionManageDetailDomainService; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -48,6 +54,8 @@ public class InvestigationManageApplicationService { private UserServiceFeign userServiceFeign; @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; /** @@ -94,10 +102,273 @@ public class InvestigationManageApplicationService { } /** - * 获取盘点管理详细信息 + * 获取盘点管理详细信息(带批次属性) */ public InvestigationManagePO getInfo(Long investigationManageId) { - return investigationManageDomainService.getInfo(investigationManageId); + InvestigationManagePO investigationManagePO = investigationManageDomainService.getInfo(investigationManageId); + + if (investigationManagePO == null || CollectionUtils.isEmpty(investigationManagePO.getInvestigetionManageDetailList())) { + return investigationManagePO; + } + + List detailList = investigationManagePO.getInvestigetionManageDetailList(); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = detailList.stream() + .map(InvestigetionManageDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(detailList, batchDetailMap); + + return investigationManagePO; + } + + /** + * 为盘点物料明细设置更多属性(从库存表中获取值) + * @param investigetionManageDetailPOList 盘点物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List investigetionManageDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(investigetionManageDetailPOList)) { + return; + } + + investigetionManageDetailPOList.forEach(investigetionManageDetailPO -> { + Long materialBaseInfoId = investigetionManageDetailPO.getMaterialBaseInfoId(); + Long materialInventoryId = investigetionManageDetailPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO materialInventoryPO = null; + if (materialInventoryId != null) { + materialInventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (materialInventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + investigetionManageDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("盘点物料明细 investigationManageDetailId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}", + investigetionManageDetailPO.getInvestigationManageDetailId(), investigetionManageDetailPO.getMaterialBaseInfoId(), + investigetionManageDetailPO.getMaterialInventoryId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java index b5184043f..256f592ea 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java @@ -1,16 +1,29 @@ package com.mhd.wms.application.service.shiftMaterialDetail; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.shiftMaterialDetail.repository.po.ShiftMaterialDetailPO; import com.mhd.wms.domain.shiftMaterialDetail.repository.todo.ShiftMaterialDetailDO; import com.mhd.wms.domain.shiftMaterialDetail.service.ShiftMaterialDetailDomainService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.List; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; /** * 移位物料明细ApplicationService @@ -25,6 +38,8 @@ public class ShiftMaterialDetailApplicationService { private ShiftMaterialDetailDomainService shiftMaterialDetailDomainService; @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; /** * 分页查询移位物料明细列表 @@ -92,4 +107,273 @@ public class ShiftMaterialDetailApplicationService { return shiftMaterialDetailDomainService.getShiftMaterialDetail(shiftMaterialDetailDO); } + /** + * 查询移位物料明细列表(带批次属性) + * 批次属性值从库存表中获取 + */ + public List queryListWithBatchAttributes(ShiftMaterialDetailDO shiftMaterialDetailDO) { + List list = queryList(shiftMaterialDetailDO); + + if (CollectionUtils.isEmpty(list)) { + return list; + } + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = list.stream() + .map(ShiftMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(list, batchDetailMap); + + return list; + } + + /** + * 为移位物料明细设置更多属性(从库存表中获取值) + * @param shiftMaterialDetailPOList 移位物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List shiftMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(shiftMaterialDetailPOList)) { + return; + } + + shiftMaterialDetailPOList.forEach(shiftMaterialDetailPO -> { + Long materialBaseInfoId = shiftMaterialDetailPO.getMaterialBaseInfoId(); + Long materialInventoryId = shiftMaterialDetailPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO materialInventoryPO = null; + if (materialInventoryId != null) { + materialInventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (materialInventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + shiftMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("移位物料明细 uniqueId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}", + shiftMaterialDetailPO.getUniqueId(), shiftMaterialDetailPO.getMaterialBaseInfoId(), + shiftMaterialDetailPO.getMaterialInventoryId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java index f07436fb1..6fbf1c4ca 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java @@ -16,6 +16,7 @@ import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.domain.StorageLocationFeignPO; import com.mhd.system.api.domain.SysDictData; import com.mhd.system.api.domain.WarehouseFeignPO; @@ -24,6 +25,7 @@ import com.mhd.system.api.domain.cache.SystemServiceCacheUtil; import com.mhd.system.api.model.LoginUser; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.outMaterialDetail.repository.po.OutMaterialCheckPO; import com.mhd.wms.domain.outMaterialDetail.repository.po.OutMaterialDetailPO; import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; @@ -36,10 +38,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -121,11 +123,342 @@ public class StockOutOrderApplicationService { } /** - * 获取出库单详细信息 + * 获取出库单详细信息(带批次属性) */ public StockOutOrderPO getInfoChildren(Long outOrderId) { - return stockOutOrderDomainService.getInfoChildren(outOrderId); + StockOutOrderPO stockOutOrderPO = stockOutOrderDomainService.getInfoChildren(outOrderId); + + if (stockOutOrderPO == null || CollectionUtils.isEmpty(stockOutOrderPO.getMaterialDetailList())) { + return stockOutOrderPO; + } + + List detailList = stockOutOrderPO.getMaterialDetailList(); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = detailList.stream() + .map(OutMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从物料明细表中获取值),递归处理所有层级 + setMaterialMoreDetailListRecursively(detailList, batchDetailMap); + + return stockOutOrderPO; + } + + /** + * 递归为出库物料明细设置更多属性(从物料明细表中获取值) + * @param outMaterialDetailPOList 出库物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListRecursively(List outMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(outMaterialDetailPOList)) { + return; + } + + outMaterialDetailPOList.forEach(outMaterialDetailPO -> { + Long materialBaseInfoId = outMaterialDetailPO.getMaterialBaseInfoId(); + + // 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了) + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 创建batchDetailId到MaterialMoreDetailPO的映射,用于快速查找已有的属性值 + Map batchDetailIdToMaterialMoreDetailMap = new HashMap<>(); + List existingList = outMaterialDetailPO.getMaterialMoreDetailList(); + if (!CollectionUtils.isEmpty(existingList)) { + for (MaterialMoreDetailPO existing : existingList) { + if (existing.getBatchDetailId() != null) { + batchDetailIdToMaterialMoreDetailMap.put(existing.getBatchDetailId(), existing); + } + } + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = batchDetailIdToMaterialMoreDetailMap.get(batchDetailFeignPO.getBatchDetailId()); + + // 如果不存在,创建新的 + if (materialMoreDetailPO == null) { + materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } else { + // 如果已存在,更新属性(保留已有的attributeValue) + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从物料明细中获取对应的字段值 + if (outMaterialDetailPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(outMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(outMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue(避免覆盖已有的值) + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + outMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("出库物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + outMaterialDetailPO.getUniqueId(), outMaterialDetailPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + + // 递归处理子集 + if (!CollectionUtils.isEmpty(outMaterialDetailPO.getChildren())) { + setMaterialMoreDetailListRecursively(outMaterialDetailPO.getChildren(), batchDetailMap); + } + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("申报数量", "declareQuantity"); + labelToFieldNameMap.put("申报单位", "declareUnit"); + labelToFieldNameMap.put("原产国", "countryOfOrigin"); + labelToFieldNameMap.put("币制", "currency"); + labelToFieldNameMap.put("单位", "unit"); + labelToFieldNameMap.put("升", "liter"); + labelToFieldNameMap.put("尺寸", "size"); + labelToFieldNameMap.put("箱数", "caseCount"); + labelToFieldNameMap.put("件数", "pieceCount"); + labelToFieldNameMap.put("出库数量", "outboundQuantity"); + labelToFieldNameMap.put("总净重", "totalNetWeight"); + labelToFieldNameMap.put("总毛重", "totalGrossWeight"); + labelToFieldNameMap.put("总体积", "totalVolume"); + labelToFieldNameMap.put("总面积", "totalArea"); + labelToFieldNameMap.put("总价", "totalAmount"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + // 如果找不到映射,尝试将批次标签转换为驼峰命名(简单处理) + return convertLabelToFieldName(batchLabel); + } + + /** + * 将批次标签转换为字段名(驼峰命名) + * @param label 批次标签 + * @return 字段名 + */ + private String convertLabelToFieldName(String label) { + if (StringUtils.isBlank(label)) { + return null; + } + + // 移除特殊字符,转换为小写,用空格或特殊字符分割 + String cleaned = label.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s]", " ") + .trim() + .toLowerCase(); + + // 如果是中文,无法自动转换,返回null + if (cleaned.matches(".*[\\u4e00-\\u9fa5].*")) { + return null; + } + + // 将空格分割的单词转换为驼峰命名 + String[] words = cleaned.split("\\s+"); + if (words.length == 0) { + return null; + } + + StringBuilder fieldName = new StringBuilder(words[0]); + for (int i = 1; i < words.length; i++) { + if (words[i].length() > 0) { + fieldName.append(words[i].substring(0, 1).toUpperCase()) + .append(words[i].substring(1)); + } + } + + return fieldName.toString(); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java index ccae1e974..c3252dfac 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java @@ -1,12 +1,15 @@ package com.mhd.wms.domain.investigetionManageDetail.repository.po; +import com.baomidou.mybatisplus.annotation.TableField; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** @@ -204,5 +207,8 @@ public class InvestigetionManageDetailPO extends BaseVOEntity { @Excel(name = "物料状态名称") private String materialStatusName; + @ApiModelProperty("更多属性明细列表") + @TableField(exist = false) + private List materialMoreDetailList; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java index 767f16126..36919cd3c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java @@ -88,4 +88,11 @@ public interface MaterialInventoryMapper extends BaseMapper MaterialInventoryPO selectOneByWhere(MaterialInventoryDO materialInventoryDO); List selectListByWhere(MaterialInventory materialInventory); + + /** + * 根据库存ID查询库存信息(包含批次属性字段) + * @param materialInventoryId 库存ID + * @return 库存信息 + */ + MaterialInventoryPO selectByIdWithBatchAttributes(@Param("materialInventoryId") Long materialInventoryId); } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java index ad979aaa3..632a2512a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java @@ -308,7 +308,7 @@ public class OutMaterialDetail extends BaseVOEntity { */ @ApiModelProperty("箱号/卡板号") @Excel(name = "箱号/卡板号") - private String casePalletNo; + private String boxPalletNo; /** * 币制 diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/po/OutMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/po/OutMaterialDetailPO.java index 69d050dff..79b432ffb 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/po/OutMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/po/OutMaterialDetailPO.java @@ -1,8 +1,10 @@ package com.mhd.wms.domain.outMaterialDetail.repository.po; +import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderBaseDO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -315,7 +317,7 @@ public class OutMaterialDetailPO extends StockOutOrderBaseDO { */ @ApiModelProperty("箱号/卡板号") @Excel(name = "箱号/卡板号") - private String casePalletNo; + private String boxPalletNo; /** * 币制 @@ -392,4 +394,8 @@ public class OutMaterialDetailPO extends StockOutOrderBaseDO { @ApiModelProperty("单位") @Excel(name = "单位") private String unit; + + @ApiModelProperty("更多属性明细列表") + @TableField(exist = false) + private List materialMoreDetailList; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java index dccff4064..1e362dcc5 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java @@ -323,7 +323,7 @@ public class OutMaterialDetailDO extends BaseVOEntity { */ @ApiModelProperty("箱号/卡板号") @Excel(name = "箱号/卡板号") - private String casePalletNo; + private String boxPalletNo; /** * 币制 diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java index 6bd63cb60..1e71768f1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.outMaterialDetailSerialNumber.repository.po.OutMaterialDetailSerialNumberPO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -250,5 +251,8 @@ public class ShiftMaterialDetailPO extends BaseVOEntity { @ApiModelProperty("序列号") private List materialDetailSerialNumberList; + @ApiModelProperty("更多属性明细列表") + @TableField(exist = false) + private List materialMoreDetailList; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java index da34f09f0..5c333dadd 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java @@ -196,10 +196,10 @@ public class ExcelParseService { if (StringUtils.isEmpty(stockOutOrder.getCarrier())) errorMsg.append("承运商不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getTransportModeCode())) errorMsg.append("运输方式不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getSupervisionModeCode())) errorMsg.append("监督方式不能为空; "); - if (StringUtils.isEmpty(stockOutOrder.getContainerNo())) errorMsg.append("柜号不能为空; "); +// if (StringUtils.isEmpty(stockOutOrder.getContainerNo())) errorMsg.append("柜号不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getDepartureArrivalCountry())) errorMsg.append("出发/到达国家不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getManufacturer())) errorMsg.append("制造商不能为空; "); - if (ObjectUtil.isEmpty(stockOutOrder.getOutboundDate())) errorMsg.append("出仓日期不能为空; "); +// if (ObjectUtil.isEmpty(stockOutOrder.getOutboundDate())) errorMsg.append("出仓日期不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getContactPerson())) errorMsg.append("联系人不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getTel())) errorMsg.append("Tel不能为空; "); if (StringUtils.isEmpty(stockOutOrder.getFax())) errorMsg.append("Fax不能为空; "); diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java index 705772c2b..c39d3bac0 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java @@ -71,7 +71,7 @@ public class ItemListener extends AnalysisEventListener> { item.setSheetRefNo(getStringValue(rowData[18])); item.setCountryOfOrigin(getStringValue(rowData[19])); - item.setCasePalletNo(getStringValue(rowData[20])); + item.setBoxPalletNo(getStringValue(rowData[20])); item.setTotalAmount(parseBigDecimal(rowData[21])); item.setCurrency(getStringValue(rowData[22])); item.setRemark(getStringValue(rowData[23])); diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java index a6765f61e..aba09239d 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java @@ -325,7 +325,7 @@ public class OutMaterialDetailDTO extends BaseVOEntity { */ @ApiModelProperty("箱号/卡板号") @Excel(name = "箱号/卡板号") - private String casePalletNo; + private String boxPalletNo; /** * 币制 diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java index a582d40da..1e83eaeed 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java @@ -92,7 +92,8 @@ public class ShiftMaterialDetailApi extends BaseController { throw new ServiceException("请输入移位单号"); } startPage(); - List list = shiftMaterialDetailApplicationService.queryList(shiftMaterialDetailDO); + // 使用带批次属性的查询方法,批次属性值从库存表中获取 + List list = shiftMaterialDetailApplicationService.queryListWithBatchAttributes(shiftMaterialDetailDO); return getDataTable(list); } diff --git a/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml index 83890d3a0..472daba29 100644 --- a/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml @@ -63,7 +63,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + @@ -98,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.BATCH_REF_NO, a.SHEET_REF_NO, a.COUNTRY_OF_ORIGIN, - a.CASE_PALLET_NO, + a.BOX_PALLET_NO, a.CURRENCY, a.DECLARE_QUANTITY, a.CASE_COUNT, diff --git a/mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml b/mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml index d47258ded..e1f020cf7 100644 --- a/mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml +++ b/mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml @@ -44,6 +44,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + @@ -718,4 +733,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND a.BATCH_REF_NO = #{batchRefNo} + + + \ No newline at end of file