| | |
| | | .failureList(new LinkedHashMap<>()).build(); |
| | | |
| | | // 1. 预热:分类编码 -> ID(MES 物料分类,与物料表单下拉数据源一致)、单位编码 -> ID |
| | | Map<String, Long> categoryCodeIdMap = new HashMap<>(); |
| | | for (String categoryCode : importList.stream() |
| | | .map(MdmItemImportExcelVO::getCategoryCode).filter(StrUtil::isNotBlank).distinct().toList()) { |
| | | CommonResult<MesMdItemTypeRespDTO> categoryResult = mesMdItemTypeApi.getItemTypeByCode(categoryCode); |
| | | if (categoryResult != null && categoryResult.getData() != null) { |
| | | categoryCodeIdMap.put(categoryCode, categoryResult.getData().getId()); |
| | | } |
| | | } |
| | | Map<String, Long> unitCodeIdMap = new HashMap<>(); |
| | | for (MdmUnitMeasureDO unit : unitMeasureMapper.selectList()) { |
| | | unitCodeIdMap.put(unit.getCode(), unit.getId()); |
| | | } |
| | | MdmItemImportContext context = buildImportContext(importList); |
| | | |
| | | // 2. 遍历导入(每行一个独立事务:单行失败只回滚该行,不影响其余行) |
| | | TransactionTemplate importTxTemplate = new TransactionTemplate(transactionManager); |
| | | for (MdmItemImportExcelVO importVO : importList) { |
| | | // 2.1 基础校验 |
| | | if (StrUtil.isBlank(importVO.getCode()) || StrUtil.isBlank(importVO.getName())) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), "物料编码和物料名称不能为空"); |
| | | // 2.1~2.6 校验必填项、解析分类与单位、组装 SaveReqVO |
| | | MdmItemRowResolution resolution = resolveImportRow(importVO, context); |
| | | if (!resolution.isSuccess()) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), resolution.failureMessage()); |
| | | continue; |
| | | } |
| | | // 2.2 解析分类 |
| | | Long categoryId = null; |
| | | if (StrUtil.isNotBlank(importVO.getCategoryCode())) { |
| | | categoryId = categoryCodeIdMap.get(importVO.getCategoryCode()); |
| | | if (categoryId == null) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), "物料分类编码不存在:" + importVO.getCategoryCode()); |
| | | continue; |
| | | } |
| | | } |
| | | // 2.3 解析主单位 |
| | | Long unitMeasureId = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode())) { |
| | | unitMeasureId = unitCodeIdMap.get(importVO.getUnitMeasureCode()); |
| | | if (unitMeasureId == null) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), "计量单位编码不存在:" + importVO.getUnitMeasureCode()); |
| | | continue; |
| | | } |
| | | } |
| | | // 2.4 解析辅单位1 |
| | | Long unitMeasureId2 = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode2())) { |
| | | unitMeasureId2 = unitCodeIdMap.get(importVO.getUnitMeasureCode2()); |
| | | if (unitMeasureId2 == null) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), "辅单位1编码不存在:" + importVO.getUnitMeasureCode2()); |
| | | continue; |
| | | } |
| | | } |
| | | // 2.5 解析辅单位2 |
| | | Long unitMeasureId3 = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode3())) { |
| | | unitMeasureId3 = unitCodeIdMap.get(importVO.getUnitMeasureCode3()); |
| | | if (unitMeasureId3 == null) { |
| | | respVO.getFailureList().put(buildFailKey(importVO), "辅单位2编码不存在:" + importVO.getUnitMeasureCode3()); |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | // 2.6 组装 SaveReqVO(复用 create/update 逻辑) |
| | | MdmItemSaveReqVO saveReqVO = new MdmItemSaveReqVO(); |
| | | saveReqVO.setCode(importVO.getCode()); |
| | | saveReqVO.setName(importVO.getName()); |
| | | saveReqVO.setBarCode(importVO.getBarCode()); |
| | | saveReqVO.setSpecification(importVO.getSpecification()); |
| | | saveReqVO.setCategoryId(categoryId); |
| | | saveReqVO.setUnitMeasureId(unitMeasureId); |
| | | saveReqVO.setUnitMeasureId2(unitMeasureId2); |
| | | saveReqVO.setUnitMeasureRate1(importVO.getUnitMeasureRate1()); |
| | | saveReqVO.setUnitMeasureId3(unitMeasureId3); |
| | | saveReqVO.setUnitMeasureRate2(importVO.getUnitMeasureRate2()); |
| | | saveReqVO.setPurchasePrice(importVO.getPurchasePrice()); |
| | | saveReqVO.setSalesPrice(importVO.getSalesPrice()); |
| | | saveReqVO.setCostPrice(importVO.getCostPrice()); |
| | | saveReqVO.setSafetyStock(importVO.getSafetyStock()); |
| | | saveReqVO.setMinStock(importVO.getMinStock()); |
| | | saveReqVO.setMaxStock(importVO.getMaxStock()); |
| | | saveReqVO.setIsBatchManaged(importVO.getIsBatchManaged()); |
| | | saveReqVO.setExpiryDay(importVO.getExpiryDay()); |
| | | saveReqVO.setStatus(importVO.getStatus() != null ? importVO.getStatus() : cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus()); |
| | | saveReqVO.setSyncMes(importVO.getSyncMes() != null ? importVO.getSyncMes() : false); |
| | | saveReqVO.setRemark(importVO.getRemark()); |
| | | saveReqVO.setItemType(1); // 默认物料类型:物料 |
| | | MdmItemSaveReqVO saveReqVO = resolution.saveReqVO(); |
| | | |
| | | // 2.7 已存在(按编码判断) |
| | | MdmItemDO existByCode = itemMapper.selectByCode(importVO.getCode()); |
| | |
| | | return respVO; |
| | | } |
| | | |
| | | @Override |
| | | public MdmItemImportContext buildImportContext(List<MdmItemImportExcelVO> importList) { |
| | | Map<String, Long> categoryCodeIdMap = new HashMap<>(); |
| | | Map<String, String> categoryCodeNameMap = new HashMap<>(); |
| | | for (String categoryCode : importList.stream() |
| | | .map(MdmItemImportExcelVO::getCategoryCode).filter(StrUtil::isNotBlank).distinct().toList()) { |
| | | CommonResult<MesMdItemTypeRespDTO> categoryResult = mesMdItemTypeApi.getItemTypeByCode(categoryCode); |
| | | if (categoryResult != null && categoryResult.getData() != null) { |
| | | categoryCodeIdMap.put(categoryCode, categoryResult.getData().getId()); |
| | | categoryCodeNameMap.put(categoryCode, categoryResult.getData().getName()); |
| | | } |
| | | } |
| | | Map<String, Long> unitCodeIdMap = new HashMap<>(); |
| | | Map<String, String> unitCodeNameMap = new HashMap<>(); |
| | | for (MdmUnitMeasureDO unit : unitMeasureMapper.selectList()) { |
| | | unitCodeIdMap.put(unit.getCode(), unit.getId()); |
| | | unitCodeNameMap.put(unit.getCode(), unit.getName()); |
| | | } |
| | | return new MdmItemImportContext(categoryCodeIdMap, categoryCodeNameMap, unitCodeIdMap, unitCodeNameMap); |
| | | } |
| | | |
| | | @Override |
| | | public MdmItemRowResolution resolveImportRow(MdmItemImportExcelVO importVO, MdmItemImportContext context) { |
| | | // 基础校验 |
| | | if (StrUtil.isBlank(importVO.getCode()) || StrUtil.isBlank(importVO.getName())) { |
| | | return MdmItemRowResolution.failure("物料编码和物料名称不能为空"); |
| | | } |
| | | // 解析分类 |
| | | Long categoryId = null; |
| | | if (StrUtil.isNotBlank(importVO.getCategoryCode())) { |
| | | categoryId = context.categoryCodeIdMap().get(importVO.getCategoryCode()); |
| | | if (categoryId == null) { |
| | | return MdmItemRowResolution.failure("物料分类编码不存在:" + importVO.getCategoryCode()); |
| | | } |
| | | } |
| | | // 解析主单位 |
| | | Long unitMeasureId = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode())) { |
| | | unitMeasureId = context.unitCodeIdMap().get(importVO.getUnitMeasureCode()); |
| | | if (unitMeasureId == null) { |
| | | return MdmItemRowResolution.failure("计量单位编码不存在:" + importVO.getUnitMeasureCode()); |
| | | } |
| | | } |
| | | // 解析辅单位1 |
| | | Long unitMeasureId2 = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode2())) { |
| | | unitMeasureId2 = context.unitCodeIdMap().get(importVO.getUnitMeasureCode2()); |
| | | if (unitMeasureId2 == null) { |
| | | return MdmItemRowResolution.failure("辅单位1编码不存在:" + importVO.getUnitMeasureCode2()); |
| | | } |
| | | } |
| | | // 解析辅单位2 |
| | | Long unitMeasureId3 = null; |
| | | if (StrUtil.isNotBlank(importVO.getUnitMeasureCode3())) { |
| | | unitMeasureId3 = context.unitCodeIdMap().get(importVO.getUnitMeasureCode3()); |
| | | if (unitMeasureId3 == null) { |
| | | return MdmItemRowResolution.failure("辅单位2编码不存在:" + importVO.getUnitMeasureCode3()); |
| | | } |
| | | } |
| | | |
| | | // 组装 SaveReqVO(复用 create/update 逻辑) |
| | | MdmItemSaveReqVO saveReqVO = new MdmItemSaveReqVO(); |
| | | saveReqVO.setCode(importVO.getCode()); |
| | | saveReqVO.setName(importVO.getName()); |
| | | saveReqVO.setBarCode(importVO.getBarCode()); |
| | | saveReqVO.setSpecification(importVO.getSpecification()); |
| | | saveReqVO.setCategoryId(categoryId); |
| | | saveReqVO.setUnitMeasureId(unitMeasureId); |
| | | saveReqVO.setUnitMeasureId2(unitMeasureId2); |
| | | saveReqVO.setUnitMeasureRate1(importVO.getUnitMeasureRate1()); |
| | | saveReqVO.setUnitMeasureId3(unitMeasureId3); |
| | | saveReqVO.setUnitMeasureRate2(importVO.getUnitMeasureRate2()); |
| | | saveReqVO.setPurchasePrice(importVO.getPurchasePrice()); |
| | | saveReqVO.setSalesPrice(importVO.getSalesPrice()); |
| | | saveReqVO.setCostPrice(importVO.getCostPrice()); |
| | | saveReqVO.setSafetyStock(importVO.getSafetyStock()); |
| | | saveReqVO.setMinStock(importVO.getMinStock()); |
| | | saveReqVO.setMaxStock(importVO.getMaxStock()); |
| | | saveReqVO.setIsBatchManaged(importVO.getIsBatchManaged()); |
| | | saveReqVO.setExpiryDay(importVO.getExpiryDay()); |
| | | saveReqVO.setStatus(importVO.getStatus() != null ? importVO.getStatus() : cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus()); |
| | | saveReqVO.setSyncMes(importVO.getSyncMes() != null ? importVO.getSyncMes() : false); |
| | | saveReqVO.setRemark(importVO.getRemark()); |
| | | saveReqVO.setItemType(1); // 默认物料类型:物料 |
| | | return MdmItemRowResolution.success(saveReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public List<MdmItemDO> getItemListByCode(String code) { |
| | | return itemMapper.selectListByCode(code); |
| | | } |
| | | |
| | | /** |
| | | * 失败清单的 key:用「编码 名称」,而不是单用名称。 |
| | | * 物料允许同名不同编码后,只按名称做 key 会让同名行互相覆盖、少报失败行; |