diff --git a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanDeliveryImportVo.java b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanDeliveryImportVo.java index ad89b660d..26807181a 100644 --- a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanDeliveryImportVo.java +++ b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanDeliveryImportVo.java @@ -10,7 +10,9 @@ import java.math.BigDecimal; * 采购计划到货导入模板(对应到货 Excel,一行一卷) * * 列:日期 牌号 规格 卷号 单卷重量 车号 数量 件数 销售 钢厂到站 - * 注:车号/数量/件数 为合并单元格,仅首行有值,导入时向下填充。 + * 注:车号/数量/件数 为合并单元格,仅首行有值; + * 数量/件数 使用 String 类型读取以避开 EasyExcel 对合并空白格的数值转换异常, + * 在 Service 层统一 parse 并校验。 * * @author klp * @date 2026-06-22 @@ -37,11 +39,13 @@ public class ErpPurchasePlanDeliveryImportVo { @ExcelProperty("车号") private String truckNo; + /** 整车总重(合并单元格,仅首行有值;读为 String 以兼容空白/点号等占位符) */ @ExcelProperty("数量") - private BigDecimal truckWeight; + private String truckWeight; + /** 整车件数(合并单元格,仅首行有值;读为 String 以兼容空白/点号等占位符) */ @ExcelProperty("件数") - private Integer pieceCount; + private String pieceCount; @ExcelProperty("销售") private String salesCode; diff --git a/klp-erp/src/main/java/com/klp/erp/listener/ErpDeliveryExcelListener.java b/klp-erp/src/main/java/com/klp/erp/listener/ErpDeliveryExcelListener.java index f7c9121d4..5b26b33c9 100644 --- a/klp-erp/src/main/java/com/klp/erp/listener/ErpDeliveryExcelListener.java +++ b/klp-erp/src/main/java/com/klp/erp/listener/ErpDeliveryExcelListener.java @@ -5,6 +5,7 @@ import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelDataConvertException; import com.klp.common.exception.ServiceException; import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryImportVo; +import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Arrays; @@ -58,6 +59,11 @@ public class ErpDeliveryExcelListener extends AnalysisEventListener cd = e.getCellData(); + if (cd == null) { + return true; + } + if (cd.getType() == com.alibaba.excel.enums.CellDataTypeEnum.EMPTY) { + return true; + } + String s = cd.getStringValue(); + // StringUtils.isBlank 覆盖全角空格、不间断空格等 Unicode 空白 + // 额外忽略 "." 等 Excel 合并单元格常见占位符 + if (StringUtils.isBlank(s)) { + return true; + } + if (s != null) { + String t = s.trim(); + if (t.isEmpty() || ".".equals(t) || ".".equals(t) || "/".equals(t) || "-".equals(t)) { + return true; + } + } + return false; + } catch (Throwable t) { + return false; + } + } + @Override public void doAfterAllAnalysed(AnalysisContext context) { // no-op diff --git a/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java b/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java index 6e9417dca..483f4162a 100644 --- a/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java +++ b/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java @@ -389,23 +389,21 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { batch.setFileName(StringUtils.isNotBlank(fileName) ? fileName : "到货表"); deliveryBatchMapper.insert(batch); - // 6) 合并单元格向下填充 + 单位换算 + 落库 + WMS到货标记 + // 6) 落库 + 单位换算 + WMS到货标记 + // 合并单元格:车号(F)几卷共用一车 → 向下填充让每卷都带车号; + // 数量(G=整车总重)/件数(H=整车件数) 是「整车合计」,只记在该车首行(其余行留空), + // 避免按行重复计数(用户:一共3件,不是每行3件)。 String lastTruckNo = null; - BigDecimal lastTruckWeight = null; - Integer lastPieceCount = null; int count = 0; int matched = 0; for (ErpPurchasePlanDeliveryImportVo row : rows) { if (StringUtils.isNotBlank(row.getTruckNo())) { lastTruckNo = row.getTruckNo(); - lastTruckWeight = row.getTruckWeight(); - lastPieceCount = row.getPieceCount(); } if (StringUtils.isBlank(row.getCoilNo()) && row.getCoilWeight() == null) { continue; } boolean arrived = StringUtils.isNotBlank(row.getCoilNo()) && wmsArrivedSet.contains(normCoil(row.getCoilNo())); - BigDecimal truckWeight = row.getTruckWeight() != null ? row.getTruckWeight() : lastTruckWeight; ErpPurchasePlanDelivery d = new ErpPurchasePlanDelivery(); d.setPlanId(planId); d.setBatchId(batch.getBatchId()); @@ -415,9 +413,12 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { d.setSpec(row.getSpec()); d.setCoilNo(row.getCoilNo()); d.setCoilWeight(convertWeight(row.getCoilWeight(), kgConverted)); + // 车号:每卷归属的车(向下填充) d.setTruckNo(StringUtils.isNotBlank(row.getTruckNo()) ? row.getTruckNo() : lastTruckNo); - d.setTruckWeight(convertWeight(truckWeight, kgConverted)); - d.setPieceCount(row.getPieceCount() != null ? row.getPieceCount() : lastPieceCount); + // 整车总重 / 件数:整车合计,仅该车首行有值,不向下填充 + // 数量/件数 作为 String 读取以兼容合并单元格的空白/点号等占位符,在此 parse + d.setTruckWeight(convertWeight(parseDecimal(row.getTruckWeight()), kgConverted)); + d.setPieceCount(parseInteger(row.getPieceCount())); d.setSalesCode(row.getSalesCode()); d.setArrivalStation(row.getArrivalStation()); deliveryMapper.insert(d); @@ -458,6 +459,47 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { return kgConverted ? v.divide(KG_TO_T, 3, RoundingMode.HALF_UP) : v; } + /** + * 将数量列 String 转为 BigDecimal,兼容合并单元格中的空白、点号、横线等占位符。 + * 无法解析时返回 null,由 Service 按合并单元格语义(仅首行有值)处理。 + */ + private static BigDecimal parseDecimal(String s) { + if (StringUtils.isBlank(s)) { + return null; + } + String t = s.trim(); + // 合并单元格常见占位符:半角/全角点、横线、斜线 + if (".".equals(t) || ".".equals(t) || "-".equals(t) || "--".equals(t) + || "/".equals(t) || "\\".equals(t) || "、".equals(t)) { + return null; + } + try { + return new BigDecimal(t); + } catch (NumberFormatException e) { + return null; + } + } + + /** + * 将件数列 String 转为 Integer,兼容合并单元格中的空白、点号、横线等占位符。 + * 无法解析时返回 null。 + */ + private static Integer parseInteger(String s) { + if (StringUtils.isBlank(s)) { + return null; + } + String t = s.trim(); + if (".".equals(t) || ".".equals(t) || "-".equals(t) || "--".equals(t) + || "/".equals(t) || "\\".equals(t) || "、".equals(t)) { + return null; + } + try { + return new BigDecimal(t).intValue(); + } catch (NumberFormatException e) { + return null; + } + } + @Override public List queryDeliveryList(Long planId) { return deliveryMapper.selectVoList(Wrappers.lambdaQuery(ErpPurchasePlanDelivery.class) diff --git a/klp-ui/src/views/erp/purchaseDelivery/index.vue b/klp-ui/src/views/erp/purchaseDelivery/index.vue index cdc5dac57..56ed9cf9f 100644 --- a/klp-ui/src/views/erp/purchaseDelivery/index.vue +++ b/klp-ui/src/views/erp/purchaseDelivery/index.vue @@ -148,7 +148,6 @@ -