From 13d8d84ea2c66a89db2d6e2165247bdd9b88134a Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Tue, 28 Jul 2026 09:15:20 +0800 Subject: [PATCH] =?UTF-8?q?0=E6=89=98=20=E4=BD=93=E7=A7=AF=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/CoDelExcelTXServiceImpl.java | 143 ++++++++++++++---- 1 file changed, 111 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java index 6deda579..0875df44 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java @@ -614,6 +614,46 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { // 解析数据行 int lastRowNum = sheet.getLastRowNum(); + // 预扫描:判断是否存在有效托数(>0) + boolean hasPositivePalletQty = false; + for (int r = 1; r <= lastRowNum; r++) { + Row row = sheet.getRow(r); + if (row == null) continue; + String invoiceSeqStr = getMergedCellValue(sheet, r, headerMap.get("发票序号")); + if (StringUtils.isBlank(invoiceSeqStr)) continue; + String palletQtyStr = headerMap.containsKey("托数") ? getMergedCellValue(sheet, r, headerMap.get("托数")) : null; + BigDecimal palletQty = parseBigDecimal(palletQtyStr); + if (palletQty != null && palletQty.compareTo(BigDecimal.ZERO) > 0) { + hasPositivePalletQty = true; + break; + } + } + // 无有效托数时,先按明细累计总体积(合并单元格只计一次),用于托盘体积落库 + BigDecimal totalVolumeWithoutPalletQty = BigDecimal.ZERO; + if (!hasPositivePalletQty && headerMap.containsKey("总体积")) { + int volumeCol = headerMap.get("总体积"); + Set noPalletVolumeRegionKeys = new HashSet<>(); + for (int r = 1; r <= lastRowNum; r++) { + Row row = sheet.getRow(r); + if (row == null) continue; + String invoiceSeqStr = getMergedCellValue(sheet, r, headerMap.get("发票序号")); + if (StringUtils.isBlank(invoiceSeqStr)) continue; + String volumeRegionKey = getMergedRegionKey(sheet, r, volumeCol); + BigDecimal currentVolume; + if (volumeRegionKey != null) { + if (noPalletVolumeRegionKeys.contains(volumeRegionKey)) { + continue; + } + currentVolume = parseBigDecimal(getMergedCellValue(sheet, r, volumeCol)); + noPalletVolumeRegionKeys.add(volumeRegionKey); + } else { + currentVolume = parseBigDecimal(getMergedCellValue(sheet, r, volumeCol)); + } + if (currentVolume != null) { + totalVolumeWithoutPalletQty = totalVolumeWithoutPalletQty.add(currentVolume); + } + } + } Map detailMap = new HashMap<>(); int palletSeqNo = 1; @@ -626,6 +666,7 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { // 记录已处理的合并区域,保证“总体积/毛重”只落在该合并区域的第一个托/箱 Set handledVolumeMergedRegions = new HashSet<>(); Set handledGrossWeightMergedRegions = new HashSet<>(); + boolean defaultPalletCreated = false; for (int r = 1; r <= lastRowNum; r++) { Row row = sheet.getRow(r); @@ -706,41 +747,71 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { volume = parseBigDecimal(getMergedCellValue(sheet, r, volumeCol)); } } - if (palletQtyStr != null && !palletQtyStr.isEmpty()) { - // 判断是否是托盘的第一行 - if (isFirstRowOfMergedRegion(sheet, r, headerMap.get("托数")) || !isMerged(sheet, r, headerMap.get("托数"))) { - int palletCount = (int) Double.parseDouble(palletQtyStr); - String outerSizeStr = headerMap.containsKey("外包尺寸") ? getMergedCellValue(sheet, r, headerMap.get("外包尺寸")) : null; - String palletNo = palletSeqNo + "~" + (palletSeqNo + palletCount - 1); - EcssCoDelPalletHeader palletHeader = new EcssCoDelPalletHeader(); - palletHeader.setSite(site); - palletHeader.setBuNo(data.getBuNo()); - palletHeader.setDelNo(delNo); - palletHeader.setSeqNo(palletSeqNo); - palletHeader.setPalletNo(palletNo); - palletHeader.setPalletQty(palletCount); - palletHeader.setVolume(volume!= null ? volume : BigDecimal.ZERO); - - if (outerSizeStr != null && !outerSizeStr.isEmpty()) { - String[] sizes = outerSizeStr.split("\\*"); - if (sizes.length == 3) { - palletHeader.setLength(parseBigDecimal(sizes[0])); - palletHeader.setWidth(parseBigDecimal(sizes[1])); - palletHeader.setHeight(parseBigDecimal(sizes[2])); + BigDecimal palletQty = parseBigDecimal(palletQtyStr); + if (hasPositivePalletQty) { + if (palletQty != null && palletQty.compareTo(BigDecimal.ZERO) > 0) { + // 判断是否是托盘的第一行 + if (isFirstRowOfMergedRegion(sheet, r, headerMap.get("托数")) || !isMerged(sheet, r, headerMap.get("托数"))) { + int palletCount = palletQty.setScale(0, RoundingMode.HALF_UP).intValue(); + String outerSizeStr = headerMap.containsKey("外包尺寸") ? getMergedCellValue(sheet, r, headerMap.get("外包尺寸")) : null; + String palletNo = palletSeqNo + "~" + (palletSeqNo + palletCount - 1); + EcssCoDelPalletHeader palletHeader = new EcssCoDelPalletHeader(); + palletHeader.setSite(site); + palletHeader.setBuNo(data.getBuNo()); + palletHeader.setDelNo(delNo); + palletHeader.setSeqNo(palletSeqNo); + palletHeader.setPalletNo(palletNo); + palletHeader.setPalletQty(palletCount); + palletHeader.setVolume(volume != null ? volume : BigDecimal.ZERO); + + if (outerSizeStr != null && !outerSizeStr.isEmpty()) { + String[] sizes = outerSizeStr.split("\\*"); + if (sizes.length == 3) { + palletHeader.setLength(parseBigDecimal(sizes[0])); + palletHeader.setWidth(parseBigDecimal(sizes[1])); + palletHeader.setHeight(parseBigDecimal(sizes[2])); + } } - } - palletHeader.setCreateBy(data.getUsername()); - palletHeader.setCreateDate(new Date()); - coDelMapper.saveCodelPalletHeader(palletHeader); + palletHeader.setCreateBy(data.getUsername()); + palletHeader.setCreateDate(new Date()); + coDelMapper.saveCodelPalletHeader(palletHeader); - currentPalletSeqNo = palletSeqNo; - palletSeqNo += palletCount; + currentPalletSeqNo = palletSeqNo; + palletSeqNo += palletCount; + } } - } else { - // 托数为空时,需要更新总体积到发货通知单头表 - header.setTotalVolume(volume); - coDelMapper.updateEcssDelHeaderVolume(header); + } else if (!defaultPalletCreated) { + // 托数全部为空或0时,仍需创建托信息;体积按整票总体积累计值落库 + String outerSizeStr = headerMap.containsKey("外包尺寸") ? getMergedCellValue(sheet, r, headerMap.get("外包尺寸")) : null; + int effectivePalletCount = 1; + int palletQtyValue = palletQty != null ? palletQty.setScale(0, RoundingMode.HALF_UP).intValue() : 0; + String palletNo = palletSeqNo + "~" + palletSeqNo; + EcssCoDelPalletHeader palletHeader = new EcssCoDelPalletHeader(); + palletHeader.setSite(site); + palletHeader.setBuNo(data.getBuNo()); + palletHeader.setDelNo(delNo); + palletHeader.setSeqNo(palletSeqNo); + palletHeader.setPalletNo(palletNo); + palletHeader.setPalletQty(palletQtyValue); + palletHeader.setVolume(totalVolumeWithoutPalletQty); + + if (outerSizeStr != null && !outerSizeStr.isEmpty()) { + String[] sizes = outerSizeStr.split("\\*"); + if (sizes.length == 3) { + palletHeader.setLength(parseBigDecimal(sizes[0])); + palletHeader.setWidth(parseBigDecimal(sizes[1])); + palletHeader.setHeight(parseBigDecimal(sizes[2])); + } + } + + palletHeader.setCreateBy(data.getUsername()); + palletHeader.setCreateDate(new Date()); + coDelMapper.saveCodelPalletHeader(palletHeader); + + currentPalletSeqNo = palletSeqNo; + palletSeqNo += effectivePalletCount; + defaultPalletCreated = true; } // 4. 箱信息 EcssCoDelBoxList @@ -835,6 +906,12 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { coDelMapper.saveCodelBoxList(boxList); } + // 兼容历史依赖:无有效托数场景同步回写通知单头总体积 + if (!hasPositivePalletQty) { + header.setTotalVolume(totalVolumeWithoutPalletQty); + coDelMapper.updateEcssDelHeaderVolume(header); + } + // 保存所有发货通知单明细 for (EcssCoDelNotifyDetail detail : detailMap.values()) { coDelMapper.insertEcssDelDetail(detail); @@ -3096,7 +3173,9 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { boolean isCurrentPalletEnd = (m == list.size() - 1) || !Objects.equals(palletSeqNo, nextPalletSeqNo); if (isCurrentPalletEnd && palletStartIndex >= 0 && boxEndIndex >= palletStartIndex) { // 第一列托号按托盘合并(一个托可能有多个箱) - template.addMergeRegion(palletStartIndex, boxEndIndex, 0); + if (hasPalletData) { + template.addMergeRegion(palletStartIndex, boxEndIndex, 0); + } // 托盘列(倒数第3列,索引6)按托盘合并 template.addMergeRegion(palletStartIndex, boxEndIndex, 8); }