diff --git a/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java b/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java index 0875588..31af2c9 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java @@ -25,7 +25,7 @@ public class HwTagRecord extends BaseEntity { /** * 主键标识,RID */ - @Excel(name = "RID") + @Excel(name = "RID", type = Type.EXPORT) private Long rId; /** diff --git a/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportParams.java b/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportParams.java new file mode 100644 index 0000000..10147c2 --- /dev/null +++ b/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportParams.java @@ -0,0 +1,79 @@ +package hw.tagApi.service.domain; + +import lombok.Data; + +/** + * 导入参数类 + * 用于存储和管理数据导入过程中需要的各种参数 + * + * @author Yinq + * @date 2025-04-15 + */ +@Data +public class ImportParams { + /** + * 导入模式 + * 可选值:ADD(新增)、UPDATE(更新)、ADD_NO_CHECK(新增不校验)、UPDATE_NO_CHECK(更新不校验) + */ + private String importMode; + + /** + * 文件链接 + * 需要导入的Excel文件的URL地址 + */ + private String fileUrl; + + /** + * TID校验 + * 用于校验TID的前缀 + */ + private String TIDCheck; + + /** + * EPC校验 + * 用于校验EPC的前缀 + */ + private String EPCCheck; + + /** + * 文件名 + * 导入的Excel文件的名称 + */ + private String fileName; + + /** + * 型号 + * 标签的型号信息 + */ + private String model; + + /** + * 去向信息 + * 标签的去向信息 + */ + private String destinationInfo; + + /** + * 是否在库 + * 标识标签是否在库中 + */ + private String libraryFlag; + + /** + * 计划用途 + * 标签的计划用途信息 + */ + private String intendedUse; + + /** + * 备注 + * 标签的备注信息 + */ + private String remark; + + /** + * EPC位数校验长度 + * 用于校验EPC的长度,0表示不校验 + */ + private int EPCNumberCheckLength; +} \ No newline at end of file diff --git a/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportResult.java b/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportResult.java new file mode 100644 index 0000000..67fa232 --- /dev/null +++ b/tagApi-service/src/main/java/hw/tagApi/service/domain/ImportResult.java @@ -0,0 +1,68 @@ +package hw.tagApi.service.domain; + +import lombok.Data; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * 导入结果类 + * 用于存储和管理数据导入过程中的结果信息,包括成功数量、失败数量和错误信息 + * + * @author Yinq + * @date 2025-04-15 + */ +@Data +public class ImportResult { + /** + * 成功导入的记录数量 + */ + private int successCount; + + /** + * 导入失败的记录数量 + */ + private int failCount; + + /** + * 导入过程中的错误信息列表 + */ + private List errorMessages; + + /** + * 构造函数 + * 初始化导入结果对象,设置初始值为0 + */ + public ImportResult() { + this.successCount = 0; + this.failCount = 0; + this.errorMessages = new ArrayList<>(); + } + + /** + * 增加成功计数 + * 每成功导入一条记录时调用 + */ + public void incrementSuccessCount() { + this.successCount++; + } + + /** + * 增加失败计数 + * 每导入失败一条记录时调用 + */ + public void incrementFailCount() { + this.failCount++; + } + + /** + * 批量增加成功计数 + * 批量导入成功时调用 + * + * @param count 成功导入的记录数量 + */ + public void addSuccessCount(int count) { + this.successCount += count; + } +} \ No newline at end of file diff --git a/tagApi-service/src/main/java/hw/tagApi/service/service/impl/HwTagRecordServiceImpl.java b/tagApi-service/src/main/java/hw/tagApi/service/service/impl/HwTagRecordServiceImpl.java index e792a77..5e2ab8a 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/service/impl/HwTagRecordServiceImpl.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/service/impl/HwTagRecordServiceImpl.java @@ -7,9 +7,13 @@ import java.util.stream.Collectors; import hw.tagApi.common.exception.ServiceException; import hw.tagApi.common.utils.DateUtils; +import hw.tagApi.common.utils.StringUtils; +import hw.tagApi.common.utils.poi.ExcelUtil; import hw.tagApi.common.utils.uuid.IdGenerator; import hw.tagApi.service.constant.ApiConstants; import hw.tagApi.service.domain.ApiContent; +import hw.tagApi.service.domain.ImportParams; +import hw.tagApi.service.domain.ImportResult; import hw.tagApi.service.utils.TagExcelUtil; import hw.tagApi.service.utils.httpClientUtils; import org.slf4j.Logger; @@ -21,6 +25,7 @@ import hw.tagApi.service.domain.HwTagRecord; import hw.tagApi.service.service.IHwTagRecordService; import org.springframework.transaction.annotation.Transactional; +import static hw.tagApi.service.utils.TagExcelUtil.extractImportParams; import static hw.tagApi.service.utils.TagExcelUtil.startsWithCheck; /** @@ -124,8 +129,6 @@ public class HwTagRecordServiceImpl implements IHwTagRecordService { */ @Override public void updateHwTagRecordByTID(HwTagRecord record) { - - hwTagRecordMapper.updateHwTagRecordByTID(record); } @@ -194,6 +197,61 @@ public class HwTagRecordServiceImpl implements IHwTagRecordService { return hwTagRecordMapper.selectExistingEpcs(epcs); } + /** + * 将Excel数据转换为HwTagRecord列表 + * + * @param orderInfo 订单信息 + * @param tagList 标签列表 + * @param params 导入参数 + * @return HwTagRecord列表 + */ + private List convertExcelDataToTagRecords(Map orderInfo, List> tagList, ImportParams params) { + List records = new ArrayList<>(); + Date nowDate = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + for (Map tagData : tagList) { + HwTagRecord record = new HwTagRecord(); + + // 设置订单信息 + String lot = orderInfo.getOrDefault("orderNo", "").replace("Lot", ""); + record.setOrderCode(lot); + record.setBatchNumber(orderInfo.getOrDefault("batchNo", "")); + record.setOperatorId(orderInfo.getOrDefault("operatorId", "")); + Date processTime = orderInfo.containsKey("processTime") ? + sdf.parse(orderInfo.get("processTime")) : nowDate; + record.setProcessingTime(processTime); + record.setTotalQuantity(Long.valueOf(orderInfo.getOrDefault("totalCount", "0"))); + + // 设置标签数据 + record.setModelCode(params.getModel()); + record.setTagSequence(tagData.get("序号")); + record.setTId(tagData.get("TID").replace("-", "")); + record.setEpc(tagData.get("EPC").replace("-", "")); + record.setPassword(tagData.get("密码")); + record.setTestResult(tagData.get("测试结果")); + record.setTestValue(tagData.get("测试值")); + record.setReferenceValue(tagData.get("参考值")); + Date testingTime = tagData.containsKey("测试时间") ? + sdf.parse(tagData.get("测试时间")) : nowDate; + record.setTestingTime(testingTime); + record.setFileName(params.getFileName()); + record.setDestinationInfo(params.getDestinationInfo()); + record.setLibraryFlag(params.getLibraryFlag()); + record.setIntendedUse(params.getIntendedUse()); + record.setRemark(params.getRemark()); + + records.add(record); + } + } catch (Exception e) { + log.error("转换Excel数据失败: {}", e.getMessage(), e); + throw new ServiceException("转换Excel数据失败: " + e.getMessage()); + } + + return records; + } + /** * 导入数据 * @@ -203,35 +261,19 @@ public class HwTagRecordServiceImpl implements IHwTagRecordService { @Transactional(rollbackFor = Exception.class) public ApiContent importData(ApiContent apiContent) { Map fields = apiContent.getFields(); - String importMode = String.valueOf(fields.get("导入模式")); - String model = String.valueOf(fields.getOrDefault("型号", "")); - String fileUrl = String.valueOf(fields.get("文件链接")); - String fileName = String.valueOf(fields.getOrDefault("文件名", "")); - String TIDCheck = String.valueOf(fields.getOrDefault("TID校验", "")); - String EPCCheck = String.valueOf(fields.getOrDefault("EPC校验", "")); - String destinationInfo = String.valueOf(fields.getOrDefault("去向信息", "")); - String libraryFlag = String.valueOf(fields.getOrDefault("是否在库", "")); - String intendedUse = String.valueOf(fields.getOrDefault("计划用途", "")); - String remark = String.valueOf(fields.getOrDefault("备注", "")); - String EPCNumberCheck = String.valueOf(fields.getOrDefault("EPC位数校验", "0")); - int EPCNumberCheckLength = Integer.parseInt(EPCNumberCheck); - int tidCharCount = TIDCheck.length(); - int epcCharCount = EPCCheck.length(); - List batchList = new ArrayList<>(); Map resFields = new HashMap<>(); - List errorMessages = new ArrayList<>(); - Date nowDate = new Date(); int successCount = 0; int failCount = 0; apiContent.setFields(resFields); try { - log.info("开始处理文件,URL: {}", fileUrl); - // 获取文件字节数组 - byte[] fileData = httpClientUtils.getByteArrayFromUrl(fileUrl); + // 获取导入参数 + ImportParams params = extractImportParams(fields); + log.info("开始处理文件,URL: {}", params.getFileUrl()); + + // 获取文件数据 + byte[] fileData = httpClientUtils.getByteArrayFromUrl(params.getFileUrl()); if (fileData == null) { - log.error("获取文件失败"); - resFields.put(ApiConstants.IMPORT_STATUS, "系统错误"); - resFields.put(ApiConstants.DESCRIPTION, "获取文件失败"); + handleImportError(resFields, "获取文件失败"); return apiContent; } @@ -239,189 +281,293 @@ public class HwTagRecordServiceImpl implements IHwTagRecordService { try (ByteArrayInputStream bis = new ByteArrayInputStream(fileData)) { Map excelResult = TagExcelUtil.parseTagExcel(bis); if (!excelResult.containsKey("tagList")) { - log.error("解析Excel文件失败,未找到标签数据"); - resFields.put(ApiConstants.IMPORT_STATUS, "导入失败"); - resFields.put(ApiConstants.DESCRIPTION, "解析Excel文件失败,未找到标签数据"); + handleImportError(resFields, "解析Excel文件失败,未找到标签数据"); return apiContent; } - // 获取订单信息 - Map orderInfo = (Map) excelResult.get("orderInfo"); - // 获取标签数据列表 - List> tagList = (List>) excelResult.get("tagList"); - // 批量处理标签数据 - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String templateType = String.valueOf(excelResult.get("templateType")); - // 如果不是更新模式,先批量查询所有TID - Set existingTids = new HashSet<>(); - boolean tIdFlag = ApiConstants.MODE_ADD.equals(importMode) || ApiConstants.MODE_ADD_NO_CHECK.equals(importMode); - List allTids = tagList.stream() - .map(tag -> tag.get("TID").replace("-", "")) - .collect(Collectors.toList()); - existingTids = this.selectExistingTids(allTids); - - // 如果不是更新模式,批量查询所有EPC - List existingEpcs = new ArrayList<>(); - boolean epcCheckFlag = ApiConstants.MODE_ADD.equals(importMode) || ApiConstants.MODE_UPDATE.equals(importMode); - if (epcCheckFlag) { - List allEpcs = tagList.stream() - .map(tag -> tag.get("EPC").replace("-", "")) - .collect(Collectors.toList()); - existingEpcs = this.selectExistingEpcs(allEpcs); + List tagRecordList = new ArrayList<>(); + if (templateType.equals(ApiConstants.IMPORT_TEMPLATE_ONE)) { + ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData); + ExcelUtil utils = new ExcelUtil<>(HwTagRecord.class); + tagRecordList = utils.importExcel(inputStream); + convertExcelDataTemplateOne(tagRecordList, params); } - for (Map tagData : tagList) { - try { - String tid = tagData.get("TID").replace("-", ""); - String epc = tagData.get("EPC").replace("-", ""); - if (tid.length() != ApiConstants.TE_LENGTH || (EPCNumberCheckLength > 0 && epc.length() != EPCNumberCheckLength)) { - StringBuilder builder = new StringBuilder(); - if (tid.length() != ApiConstants.TE_LENGTH) { - String errorMsg = String.format("TID长度校验失败!预期长度:24,实际长度:%d,TID值:%s", tid.length(), tid); - builder.append(errorMsg); - log.error("异常 - {}", errorMsg); - } - if (EPCNumberCheckLength > 0 && epc.length() != EPCNumberCheckLength) { - String errorMsg = String.format("EPC长度校验失败!预期长度:24,实际长度:%d,EPC值:%s", epc.length(), epc); - builder.append(errorMsg); - log.error("EPC长度校验异常 - {}", errorMsg); - } - errorMessages.add(builder.toString()); - failCount++; - continue; - } - if (tidCharCount > 0 && !startsWithCheck(tid, TIDCheck)) { - String errorMsg = String.format("TID校验失败!TID校验:%s,实际TID:%s", TIDCheck, tid); - log.error("TID校验异常 - {}", errorMsg); - errorMessages.add(errorMsg); - failCount++; - continue; - } - if (epcCharCount > 0 && !startsWithCheck(epc, EPCCheck)) { - String errorMsg = String.format("EPC校验失败!EPC校验:%s,实际EPC:%s", EPCCheck, epc); - log.error("EPC校验异常 - {}", errorMsg); - errorMessages.add(errorMsg); - failCount++; - continue; - } - HwTagRecord record = new HwTagRecord(); - String lot = orderInfo.getOrDefault("orderNo", "").replace("Lot", ""); - record.setOrderCode(lot); - record.setBatchNumber(orderInfo.getOrDefault("batchNo", "")); - record.setOperatorId(orderInfo.getOrDefault("operatorId", "")); - Date processTime = orderInfo.containsKey("processTime") ? sdf.parse(orderInfo.get("processTime")) : nowDate; - record.setProcessingTime(processTime); - record.setTotalQuantity(Long.valueOf(orderInfo.getOrDefault("totalCount", "0"))); - // 设置标签数据 - record.setModelCode(model); - record.setTagSequence(tagData.get("序号")); - record.setTId(tid); - record.setEpc(epc); - record.setPassword(tagData.get("密码")); - record.setTestResult(tagData.get("测试结果")); - record.setTestValue(tagData.get("测试值")); - record.setReferenceValue(tagData.get("参考值")); - Date testingTime = tagData.containsKey("测试时间") ? sdf.parse(tagData.get("测试时间")) : nowDate; - record.setTestingTime(testingTime); - record.setFileName(fileName); - record.setDestinationInfo(destinationInfo); - record.setLibraryFlag(libraryFlag); - record.setIntendedUse(intendedUse); - record.setRemark(remark); - - //校验tId唯一 - if (tIdFlag && existingTids.contains(tid)) { - String errorMsg = String.format("TID已存在:%s", tid); - log.error(errorMsg); - errorMessages.add(errorMsg); - failCount++; - continue; - } - if ((ApiConstants.MODE_UPDATE.equals(importMode) || ApiConstants.MODE_UPDATE_NO_CHECK.equals(importMode)) && !existingTids.contains(tid)) { - String errorMsg = String.format("数据库未查询到TID:%s,无法%s", tid, importMode); - log.error(errorMsg); - errorMessages.add(errorMsg); - failCount++; - continue; - } - //校验EPC唯一 - if (epcCheckFlag) { - boolean isAddMode = ApiConstants.MODE_ADD.equals(importMode); - boolean isUpdateMode = ApiConstants.MODE_UPDATE.equals(importMode); - Set epcSet = isAddMode ? - existingEpcs.stream().map(HwTagRecord::getEpc).collect(Collectors.toSet()) : - Collections.emptySet(); - Map> epcMap = isUpdateMode ? - existingEpcs.stream().collect(Collectors.groupingBy(HwTagRecord::getEpc)) : - Collections.emptyMap(); - boolean conflict = false; - if (isAddMode && epcSet.contains(epc)) { - conflict = true; // ADD模式直接判断存在性 - } else if (isUpdateMode) { - // UPDATE模式:仅检查相同EPC但不同TID的情况 - List sameEpcs = epcMap.get(epc); - if (sameEpcs != null) { - conflict = sameEpcs.stream() - .anyMatch(r -> !r.getTId().equals(tid)); - } - } - if (conflict) { - String errorMsg = String.format("EPC已存在:%s", epc); - log.error(errorMsg); - errorMessages.add(errorMsg); - failCount++; - continue; - } - } - // 更新方法 - if ((ApiConstants.MODE_UPDATE.equals(importMode) || ApiConstants.MODE_UPDATE_NO_CHECK.equals(importMode)) && failCount == 0) { - - this.updateHwTagRecordByTID(record); - successCount++; - continue; - } - record.setRId(IdGenerator.nextId()); - // 添加到批处理列表 - batchList.add(record); - // 达到批量大小时执行插入 - if (batchList.size() >= BATCH_SIZE && failCount == 0) { - this.batchInsertHwTagRecord(batchList); - log.info("批量插入{}条数据成功", batchList.size()); - successCount += batchList.size(); - batchList.clear(); - } - } catch (Exception e) { - String errorMsg = String.format("处理数据失败:%s", e.getMessage()); - log.error(errorMsg); - errorMessages.add(errorMsg); - failCount++; - } + if (templateType.equals(ApiConstants.IMPORT_TEMPLATE_TWO) || templateType.equals(ApiConstants.IMPORT_TEMPLATE_THREE)) { + // 获取订单信息和标签数据 + Map orderInfo = (Map) excelResult.get("orderInfo"); + List> tagList = (List>) excelResult.get("tagList"); + // 转换Excel数据为HwTagRecord列表 + tagRecordList = convertExcelDataToTagRecords(orderInfo, tagList, params); } - - // 处理剩余的数据 - if (!batchList.isEmpty() && failCount == 0) { - this.batchInsertHwTagRecord(batchList); - log.info("批量插入剩余{}条数据成功", batchList.size()); - successCount += batchList.size(); - batchList.clear(); + // 检查TID是否存在 + if (tagRecordList.stream().anyMatch(tag -> !StringUtils.hasText(tag.getTId()))) { + throw new IllegalArgumentException("解析excel错误:存在缺少TID的数据!"); } + // 处理标签数据 + ImportResult result = processTagList(tagRecordList, params); + successCount = result.getSuccessCount(); + failCount = result.getFailCount(); + List errorMessages = new ArrayList<>(result.getErrorMessages()); // 设置导入结果 if (failCount > 0) { - throw new ServiceException(String.format(importMode + "失败:%d条。失败原因:%s", + throw new ServiceException(String.format(params.getImportMode() + "失败:%d条。失败原因:%s", failCount, String.join("; ", errorMessages))); } else { resFields.put(ApiConstants.IMPORT_STATUS, "导入成功"); - resFields.put(ApiConstants.DESCRIPTION, String.format(importMode + "成功导入%d条数据", successCount)); + resFields.put(ApiConstants.DESCRIPTION, String.format(params.getImportMode() + "成功导入%d条数据", successCount)); } } } catch (Exception e) { log.error("处理文件失败: {}", e.getMessage(), e); - resFields.put(ApiConstants.IMPORT_STATUS, "导入失败"); - resFields.put(ApiConstants.DESCRIPTION, e.getMessage()); + handleImportError(resFields, e.getMessage()); + return apiContent; } return apiContent; } + /** + * 处理模板一的Excel数据 + * 根据导入参数更新标签记录 + * + * @param tagRecordList 标签记录列表 + * @param params 导入参数 + */ + private void convertExcelDataTemplateOne(List tagRecordList, ImportParams params) { + for (HwTagRecord tagRecord : tagRecordList) { + // 设置型号 + if (StringUtils.hasText(params.getModel())) { + tagRecord.setModelCode(params.getModel()); + } + // 设置文件名 + if (StringUtils.hasText(params.getFileName())) { + tagRecord.setFileName(params.getFileName()); + } + // 设置去向信息 + if (StringUtils.hasText(params.getDestinationInfo())) { + tagRecord.setDestinationInfo(params.getDestinationInfo()); + } + // 设置是否在库 + if (StringUtils.hasText(params.getLibraryFlag())) { + tagRecord.setLibraryFlag(params.getLibraryFlag()); + } + // 设置计划用途 + if (StringUtils.hasText(params.getIntendedUse())) { + tagRecord.setIntendedUse(params.getIntendedUse()); + } + // 设置备注 + if (StringUtils.hasText(params.getRemark())) { + tagRecord.setRemark(params.getRemark()); + } + } + } + /** + * 处理导入错误 + */ + private void handleImportError(Map resFields, String errorMessage) { + log.error("导入错误: {}", errorMessage); + resFields.put(ApiConstants.IMPORT_STATUS, "导入失败"); + resFields.put(ApiConstants.DESCRIPTION, errorMessage); + } + + /** + * 处理标签列表 + */ + private ImportResult processTagList(List records, ImportParams params) { + ImportResult result = new ImportResult(); + List batchList = new ArrayList<>(); + + // 获取已存在的TID和EPC + Set existingTids = getExistingTids(records, params); + List existingEpcs = getExistingEpcs(records, params); + + for (HwTagRecord record : records) { + try { + // 校验标签数据 + if (!validateTagRecord(record, params, existingTids, existingEpcs, result)) { + continue; + } + + // 处理更新或插入 + if (handleRecordUpdateOrInsert(record, params, batchList, result)) { + continue; + } + + // 批量插入处理 + if (batchList.size() >= BATCH_SIZE && result.getFailCount() == 0) { + processBatchInsert(batchList, result); + } + } catch (Exception e) { + handleTagProcessingError(record, e, result); + return result; + } + } + + // 处理剩余的批量数据 + if (!batchList.isEmpty() && result.getFailCount() == 0) { + processBatchInsert(batchList, result); + } + + return result; + } + + /** + * 获取已存在的TID + */ + private Set getExistingTids(List records, ImportParams params) { + List allTids = records.stream() + .map(HwTagRecord::getTId) + .collect(Collectors.toList()); + return this.selectExistingTids(allTids); + } + + /** + * 获取已存在的EPC + */ + private List getExistingEpcs(List records, ImportParams params) { + List allEpcs = records.stream() + .map(HwTagRecord::getEpc) + .collect(Collectors.toList()); + return this.selectExistingEpcs(allEpcs); + } + + /** + * 校验标签数据 + */ + private boolean validateTagRecord(HwTagRecord record, ImportParams params, + Set existingTids, List existingEpcs, + ImportResult result) { + // 校验TID长度 + if (record.getTId().length() != ApiConstants.TE_LENGTH) { + String errorMsg = String.format("TID长度校验失败!预期长度:24,实际长度:%d,TID值:%s", + record.getTId().length(), record.getTId()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验EPC长度 + if (params.getEPCNumberCheckLength() > 0 && + record.getEpc().length() != params.getEPCNumberCheckLength()) { + String errorMsg = String.format("EPC长度校验失败!预期长度:%d,实际长度:%d,EPC值:%s", + params.getEPCNumberCheckLength(), record.getEpc().length(), record.getEpc()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验TID前缀 + if (!params.getTIDCheck().isEmpty() && + !startsWithCheck(record.getTId(), params.getTIDCheck())) { + String errorMsg = String.format("TID校验失败!TID校验:%s,实际TID:%s", + params.getTIDCheck(), record.getTId()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验EPC前缀 + if (!params.getEPCCheck().isEmpty() && + !startsWithCheck(record.getEpc(), params.getEPCCheck())) { + String errorMsg = String.format("EPC校验失败!EPC校验:%s,实际EPC:%s", + params.getEPCCheck(), record.getEpc()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验TID唯一性 + boolean tIdFlag = ApiConstants.MODE_ADD.equals(params.getImportMode()) || + ApiConstants.MODE_ADD_NO_CHECK.equals(params.getImportMode()); + if (tIdFlag && existingTids.contains(record.getTId())) { + String errorMsg = String.format("TID已存在:%s", record.getTId()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验更新模式下的TID存在性 + if ((ApiConstants.MODE_UPDATE.equals(params.getImportMode()) || + ApiConstants.MODE_UPDATE_NO_CHECK.equals(params.getImportMode())) && + !existingTids.contains(record.getTId())) { + String errorMsg = String.format("数据库未查询到TID:%s,无法%s", + record.getTId(), params.getImportMode()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + + // 校验EPC唯一性 + boolean epcCheckFlag = ApiConstants.MODE_ADD.equals(params.getImportMode()) || + ApiConstants.MODE_UPDATE.equals(params.getImportMode()); + if (epcCheckFlag) { + boolean isAddMode = ApiConstants.MODE_ADD.equals(params.getImportMode()); + boolean isUpdateMode = ApiConstants.MODE_UPDATE.equals(params.getImportMode()); + Set epcSet = isAddMode ? + existingEpcs.stream().map(HwTagRecord::getEpc).collect(Collectors.toSet()) : + Collections.emptySet(); + Map> epcMap = isUpdateMode ? + existingEpcs.stream().collect(Collectors.groupingBy(HwTagRecord::getEpc)) : + Collections.emptyMap(); + boolean conflict = false; + if (isAddMode && epcSet.contains(record.getEpc())) { + conflict = true; + } else if (isUpdateMode) { + List sameEpcs = epcMap.get(record.getEpc()); + if (sameEpcs != null) { + conflict = sameEpcs.stream() + .anyMatch(r -> !r.getTId().equals(record.getTId())); + } + } + if (conflict) { + String errorMsg = String.format("EPC已存在:%s", record.getEpc()); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + return false; + } + } + + return true; + } + + /** + * 处理记录更新或插入 + */ + private boolean handleRecordUpdateOrInsert(HwTagRecord record, ImportParams params, + List batchList, ImportResult result) { + if ((ApiConstants.MODE_UPDATE.equals(params.getImportMode()) || + ApiConstants.MODE_UPDATE_NO_CHECK.equals(params.getImportMode())) && + result.getFailCount() == 0) { + this.updateHwTagRecordByTID(record); + result.incrementSuccessCount(); + return true; + } + record.setRId(IdGenerator.nextId()); + batchList.add(record); + return false; + } + + /** + * 处理批量插入 + */ + private void processBatchInsert(List batchList, ImportResult result) { + this.batchInsertHwTagRecord(batchList); + log.info("批量插入{}条数据成功", batchList.size()); + result.addSuccessCount(batchList.size()); + batchList.clear(); + } + + /** + * 处理标签处理错误 + */ + private void handleTagProcessingError(HwTagRecord record, Exception e, ImportResult result) { + String errorMsg = String.format("处理数据失败 - TID: %s, 错误: %s", record.getTId(), e.getMessage()); + log.error(errorMsg); + result.getErrorMessages().add(errorMsg); + result.incrementFailCount(); + } } diff --git a/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java b/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java index 8a5a1c0..7842f5e 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java @@ -7,6 +7,7 @@ import hw.tagApi.common.utils.spring.SpringUtils; import hw.tagApi.common.utils.uuid.UUID; import hw.tagApi.service.constant.ApiConstants; import hw.tagApi.service.domain.HwTagRecord; +import hw.tagApi.service.domain.ImportParams; import hw.tagApi.system.domain.SysAttachInfo; import hw.tagApi.system.service.ISysAttachInfoService; import org.apache.poi.ss.usermodel.*; @@ -39,16 +40,18 @@ public class TagExcelUtil { Row row = sheet.getRow(0); String exportTemplate = getCellStringValue(row.getCell(0));//导出再导入模板 + boolean exportTemplateFlag = StringUtils.hasText(exportTemplate) && exportTemplate.equals("RID"); boolean isInventoryFlag = validateCells(row.getCell(8), row.getCell(9));//桌面读写器盘点模板 - if (StringUtils.hasText(exportTemplate) && exportTemplate.equals("RID")) { - List> tagList = parseTagList(sheet, 1); - result.put("tagList", tagList); + if (exportTemplateFlag) { + result.put("tagList", new ArrayList<>()); result.put("orderInfo", new HashMap<>()); + result.put("templateType", ApiConstants.IMPORT_TEMPLATE_ONE); } else if (isInventoryFlag) { List> tagList = parseTagList(sheet, 1); result.put("tagList", tagList); result.put("orderInfo", new HashMap<>()); + result.put("templateType", ApiConstants.IMPORT_TEMPLATE_TWO); } else { // 解析订单信息 Map orderInfo = parseOrderInfo(sheet); @@ -56,6 +59,7 @@ public class TagExcelUtil { // 解析标签数据 List> tagList = parseTagList(sheet, 7); result.put("tagList", tagList); + result.put("templateType", ApiConstants.IMPORT_TEMPLATE_THREE); } return result; @@ -319,7 +323,7 @@ public class TagExcelUtil { * @param input 字符串 * @return */ - public static List splitHorizontalBarString(String input) { + public static List splitHorizontalBarString(String input, Boolean zeroFlag) { List result = new ArrayList<>(); if (input == null || input.isEmpty()) { @@ -343,8 +347,12 @@ public class TagExcelUtil { // 生成连续数字序列 for (int i = start; i <= end; i++) { // 保持原始位数,前面补零 - String formatted = String.format("%0" + parts[0].length() + "d", i); - result.add(formatted); + if (zeroFlag) { + result.add(String.valueOf(i)); + } else { + String formatted = String.format("%0" + parts[0].length() + "d", i); + result.add(formatted); + } } } catch (NumberFormatException e) { // 如果无法解析为数字,则直接添加原始字符串 @@ -361,4 +369,23 @@ public class TagExcelUtil { return result; } + + /** + * 提取导入参数 + */ + public static ImportParams extractImportParams(Map fields) { + ImportParams params = new ImportParams(); + params.setImportMode(String.valueOf(fields.get("导入模式"))); + params.setFileUrl(String.valueOf(fields.get("文件链接"))); + params.setTIDCheck(String.valueOf(fields.getOrDefault("TID校验", ""))); + params.setEPCCheck(String.valueOf(fields.getOrDefault("EPC校验", ""))); + params.setEPCNumberCheckLength(Integer.parseInt(String.valueOf(fields.getOrDefault("EPC位数校验", "0")))); + params.setFileName(String.valueOf(fields.getOrDefault("文件名", ""))); + params.setModel(String.valueOf(fields.getOrDefault("型号", ""))); + params.setDestinationInfo(String.valueOf(fields.getOrDefault("去向信息", ""))); + params.setLibraryFlag(String.valueOf(fields.getOrDefault("是否在库", ""))); + params.setIntendedUse(String.valueOf(fields.getOrDefault("计划用途", ""))); + params.setRemark(String.valueOf(fields.getOrDefault("备注", ""))); + return params; + } } \ No newline at end of file