From c0396c87159c12c365f8b704858860f538d7c04f Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Thu, 18 Sep 2025 17:06:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E7=BB=84=E5=90=88=E9=80=89=E6=8B=A9=E6=B5=81=E6=B0=B4=E5=8F=B7?= =?UTF-8?q?=E7=94=9F=E6=88=90=E8=A7=84=E5=88=99=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Impl/LabelDataProcessorServiceImpl.java | 240 ++++++++++++++---- .../Impl/ReportLabelListServiceImpl.java | 2 + 2 files changed, 198 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java b/src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java index 789b9f9..0ffe8dc 100644 --- a/src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java +++ b/src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java @@ -22,6 +22,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; /** * 标签数据处理服务实现类 @@ -40,6 +41,9 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService @Autowired private com.gaotao.modules.base.service.FontService fontService; + @Autowired + private com.gaotao.modules.base.dao.ReportLabelListMapper reportLabelListMapper; + @Override public List processLabelData(List elements, Map dataMap,Boolean printFlag) { if (elements == null || elements.isEmpty()) { @@ -50,14 +54,22 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService // 第一轮处理:处理基本数据替换(不包含元素组合) List firstPassElements = new ArrayList<>(); + Map enhancedDataMap = new HashMap<>(dataMap != null ? dataMap : new HashMap<>()); + for (ReportLabelList element : elements) { - ReportLabelList processedElement = processElementData(element, dataMap,true, printFlag); + ReportLabelList processedElement = processElementData(element, enhancedDataMap,true, printFlag); firstPassElements.add(processedElement); + + // 如果是流水号元素,将其数据添加到数据映射中,供其他元素引用 + if ("serialNumber".equals(element.getType()) && processedElement.getData() != null && !processedElement.getData().isEmpty()) { + enhancedDataMap.put("SERIAL_NUMBER", processedElement.getData()); + log.debug("将流水号数据添加到数据映射: SERIAL_NUMBER={}", processedElement.getData()); + } } // 第二轮处理:处理元素组合引用 for (ReportLabelList element : firstPassElements) { - ReportLabelList finalElement = processElementCombinations(element, dataMap, firstPassElements, printFlag); + ReportLabelList finalElement = processElementCombinations(element, enhancedDataMap, firstPassElements, printFlag); // 如果元素被设置为不显示,则跳过该元素 if (("onecode".equals(element.getType()) || "qrcode".equals(element.getType()) @@ -73,6 +85,133 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService return processedElements; } + /** + * 处理二维码/一维码元素,特别处理流水号引用 + */ + private String processBarcodeElement(String originalData, Map dataMap, ReportLabelList element, Boolean printFlag) { + if (originalData == null || originalData.isEmpty()) { + return originalData; + } + + log.debug("处理条码元素: type={}, originalData={}", element.getType(), originalData); + + // 检查是否包含流水号引用(各种可能的格式) + if (containsSerialNumberReference(originalData)) { + log.debug("检测到流水号引用,开始处理"); + + // 获取流水号的真实数据 + String serialNumberData = getSerialNumberData(element.getReportId(), dataMap, printFlag); + + if (serialNumberData != null && !serialNumberData.isEmpty()) { + // 清理流水号数据,直接返回纯净的流水号 + String cleanSerialNumber = cleanSerialNumberData(serialNumberData); + log.debug("流水号处理完成: {} -> {}", originalData, cleanSerialNumber); + return cleanSerialNumber; + } else { + log.warn("未能获取到流水号数据,使用原始数据"); + } + } + + // 如果不包含流水号引用,使用常规的数据源字段替换 + return replaceDataSourceFields(originalData, dataMap); + } + + /** + * 检查数据中是否包含流水号引用 + */ + private boolean containsSerialNumberReference(String data) { + if (data == null || data.isEmpty()) { + return false; + } + + // 检查各种可能的流水号引用格式 + return data.contains("流水号") || + data.contains("#{SERIAL_NUMBER}") || + data.contains("serialNumber"); + } + + /** + * 获取流水号的真实数据(用于二维码引用,不递增流水号) + */ + private String getSerialNumberData(String reportId, Map dataMap, Boolean printFlag) { + try { + // 直接通过BaseService查询流水号元素,避免循环依赖 + List allElements = getElementsByReportId(reportId); + + for (ReportLabelList element : allElements) { + if ("serialNumber".equals(element.getType())) { + log.debug("找到流水号元素: itemNo={}, data={}", element.getItemNo(), element.getData()); + + // 获取流水号当前值,不递增(false参数) + String serialData = processSerialNumberElement(element, dataMap, false, printFlag); + log.debug("获取的流水号数据(不递增): {}", serialData); + + return serialData; + } + } + + log.warn("未找到流水号元素: reportId={}", reportId); + return null; + + } catch (Exception e) { + log.error("获取流水号数据失败: reportId={}, error={}", reportId, e.getMessage(), e); + return null; + } + } + + /** + * 通过Mapper直接查询元素,避免循环依赖 + */ + private List getElementsByReportId(String reportId) { + try { + // 使用Mapper直接查询,避免循环依赖 + return reportLabelListMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper() + .eq("report_id", reportId) + ); + } catch (Exception e) { + log.error("查询元素失败: reportId={}, error={}", reportId, e.getMessage(), e); + return new ArrayList<>(); + } + } + + /** + * 替换数据中的流水号引用为真实数据 + */ + private String replaceSerialNumberReferences(String originalData, String serialNumberData) { + String result = originalData; + + // 清理流水号数据,移除不需要的后缀 + String cleanSerialNumber = cleanSerialNumberData(serialNumberData); + + // 替换各种可能的流水号引用格式 + result = result.replaceAll("\\{流水号[^}]*\\}", cleanSerialNumber); + result = result.replaceAll("#\\{SERIAL_NUMBER\\}", cleanSerialNumber); + result = result.replaceAll("流水号", cleanSerialNumber); + + return result; + } + + /** + * 清理流水号数据,移除不需要的后缀 + * 例如:P120250918000003+#{CURRENT_DATE_YYYYMMDD}) -> P120250918000003 + */ + private String cleanSerialNumberData(String serialNumberData) { + if (serialNumberData == null || serialNumberData.isEmpty()) { + return serialNumberData; + } + + // 移除 +#{...} 格式的后缀 + String cleaned = serialNumberData.replaceAll("\\+#\\{[^}]*\\}[)]*", ""); + + // 移除其他可能的后缀模式 + cleaned = cleaned.replaceAll("\\+.*$", ""); // 移除+号及其后面的所有内容 + + log.debug("流水号数据清理: {} -> {}", serialNumberData, cleaned); + + return cleaned.trim(); + } + /** * 处理元素组合引用 */ @@ -141,14 +280,8 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService break; case "onecode": case "qrcode": - // 检查是否包含元素组合引用 - if (containsElementReferences(originalData)) { - // 需要传入所有元素列表来处理组合 - // 这里暂时使用基本的数据源替换,完整的组合处理在processLabelData中进行 - processedElement.setData(replaceDataSourceFields(originalData, dataMap)); - } else { - processedElement.setData(replaceDataSourceFields(originalData, dataMap)); - } + // 直接处理二维码/一维码的流水号引用 + processedElement.setData(processBarcodeElement(originalData, dataMap, element, printFlag)); break; case "serialNumber": // 处理流水号元素,生成真实的流水号 @@ -246,9 +379,15 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService // 检查是否是数据源字段引用 #{fieldName} if (reference.startsWith("#{") && reference.endsWith("}")) { String fieldName = reference.substring(2, reference.length() - 1); - + + // 特殊处理流水号引用 + if ("SERIAL_NUMBER".equals(fieldName)) { + Object serialValue = dataMap.get("SERIAL_NUMBER"); + replacement = serialValue != null ? serialValue.toString() : ""; + log.debug("元素组合中使用流水号引用: SERIAL_NUMBER={}", replacement); + } // 首先检查是否是系统变量 - if (isSystemVariable(fieldName)) { + else if (isSystemVariable(fieldName)) { replacement = getSystemVariableValue(fieldName); log.debug("元素组合中使用系统变量: {}={}", fieldName, replacement); } else { @@ -582,8 +721,21 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService String fieldName = matcher.group(1); String replacement; + // 特殊处理流水号引用 + if ("SERIAL_NUMBER".equals(fieldName)) { + // 对于流水号引用,需要从dataMap中获取已处理的流水号数据 + Object serialValue = dataMap.get("SERIAL_NUMBER"); + if (serialValue != null) { + replacement = serialValue.toString(); + log.debug("替换流水号引用: SERIAL_NUMBER={}", replacement); + } else { + // 如果没有找到流水号数据,保持原样,让后续处理 + replacement = "#{SERIAL_NUMBER}"; + log.debug("流水号数据未准备好,保持原样: #{SERIAL_NUMBER}"); + } + } // 首先检查是否是系统变量 - if (isSystemVariable(fieldName)) { + else if (isSystemVariable(fieldName)) { replacement = getSystemVariableValue(fieldName); log.debug("替换系统变量: {}={}", fieldName, replacement); } else if (dataMap != null && !dataMap.isEmpty()) { @@ -1083,7 +1235,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService if (objectName.startsWith("#{") && objectName.endsWith("}")) { String fieldName = objectName.substring(2, objectName.length() - 1); String value = ""; - + // 首先检查是否是系统变量 if (isSystemVariable(fieldName)) { value = getSystemVariableValue(fieldName); @@ -1092,7 +1244,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService Object fieldValue = dataMap.get(fieldName); value = fieldValue != null ? fieldValue.toString() : ""; } - + if (!value.isEmpty()) { keyInfoBuilder.append(value); keyInfoBuilder.append("_"); @@ -1235,7 +1387,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService else if (objectName.startsWith("#{") && objectName.endsWith("}")) { String fieldName = objectName.substring(2, objectName.length() - 1); String value = ""; - + // 首先检查是否是系统变量 if (isSystemVariable(fieldName)) { value = getSystemVariableValue(fieldName); @@ -1246,7 +1398,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService value = fieldValue != null ? fieldValue.toString() : ""; log.debug("使用真实数据字段: {}={}", fieldName, value); } - + serialNumberBuilder.append(value); } else { // 固定字符串,直接使用 @@ -1340,8 +1492,8 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService * @return 是否为系统变量 */ private boolean isSystemVariable(String fieldName) { - return fieldName.startsWith("CURRENT_DATE_") || - fieldName.startsWith("CURRENT_TIME_") || + return fieldName.startsWith("CURRENT_DATE_") || + fieldName.startsWith("CURRENT_TIME_") || fieldName.equals("CURRENT_DATETIME"); } @@ -1354,24 +1506,24 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService private String getSystemVariableValue(String fieldName) { java.time.LocalDateTime now = java.time.LocalDateTime.now(); java.time.format.DateTimeFormatter formatter; - + switch (fieldName) { case "CURRENT_DATE_YYYYMMDD": formatter = java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"); return now.format(formatter); - + case "CURRENT_DATE_YYYY-MM-DD": formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"); return now.format(formatter); - + case "CURRENT_TIME_HHMMSS": formatter = java.time.format.DateTimeFormatter.ofPattern("HHmmss"); return now.format(formatter); - + case "CURRENT_DATETIME": formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return now.format(formatter); - + default: log.warn("未知的系统变量: {}", fieldName); return ""; @@ -1384,93 +1536,93 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService */ public void testSystemVariables() { log.info("=== 系统变量功能测试开始 ==="); - + // 测试所有系统变量 String[] testVariables = { "CURRENT_DATE_YYYYMMDD", - "CURRENT_DATE_YYYY-MM-DD", + "CURRENT_DATE_YYYY-MM-DD", "CURRENT_TIME_HHMMSS", "CURRENT_DATETIME" }; - + for (String varName : testVariables) { boolean isSystemVar = isSystemVariable(varName); String value = getSystemVariableValue(varName); log.info("系统变量测试: {} -> 是否为系统变量: {}, 值: {}", varName, isSystemVar, value); } - + // 测试具体业务场景:P + site + YYYYMMDD + 8位流水号 log.info("=== 测试业务场景:P + site + YYYYMMDD + 流水号 ==="); - + java.util.List businessRules = new java.util.ArrayList<>(); - + // 规则1:固定前缀 "P" com.gaotao.modules.base.entity.LabelContentSerialRuleData rule1 = new com.gaotao.modules.base.entity.LabelContentSerialRuleData(); rule1.setObjectName("P"); businessRules.add(rule1); - + // 规则2:数据源字段 site com.gaotao.modules.base.entity.LabelContentSerialRuleData rule2 = new com.gaotao.modules.base.entity.LabelContentSerialRuleData(); rule2.setObjectName("#{site}"); businessRules.add(rule2); - + // 规则3:当前日期 YYYYMMDD com.gaotao.modules.base.entity.LabelContentSerialRuleData rule3 = new com.gaotao.modules.base.entity.LabelContentSerialRuleData(); rule3.setObjectName("#{CURRENT_DATE_YYYYMMDD}"); businessRules.add(rule3); - + // 规则4:8位流水号 com.gaotao.modules.base.entity.LabelContentSerialRuleData rule4 = new com.gaotao.modules.base.entity.LabelContentSerialRuleData(); rule4.setObjectName("流水号"); businessRules.add(rule4); - + // 模拟数据源数据 java.util.Map businessDataMap = new java.util.HashMap<>(); businessDataMap.put("site", "SH001"); // 模拟站点数据 - + // 测试组装流水号(8位流水号) String businessSerialNumber = assembleFullSerialNumber(businessRules, businessDataMap, "00000001"); log.info("业务场景流水号组装结果: {}", businessSerialNumber); - + // 测试KeyInfo生成(用于区分不同条件下的流水号序列) String businessKeyInfo = generateSerialKeyInfo(businessRules, businessDataMap); log.info("业务场景KeyInfo生成结果: {}", businessKeyInfo); - + // 测试不同站点的情况 businessDataMap.put("site", "BJ002"); String anotherSerialNumber = assembleFullSerialNumber(businessRules, businessDataMap, "00000001"); String anotherKeyInfo = generateSerialKeyInfo(businessRules, businessDataMap); log.info("不同站点流水号组装结果: {}", anotherSerialNumber); log.info("不同站点KeyInfo生成结果: {}", anotherKeyInfo); - + // 测试真实数据预览场景 log.info("=== 测试真实数据预览场景 ==="); - + // 模拟真实数据预览的数据映射(包含site字段) java.util.Map realDataMap = new java.util.HashMap<>(); realDataMap.put("site", "SH001"); realDataMap.put("product_code", "ABC123"); realDataMap.put("batch_no", "B20241218"); - + // 测试replaceDataSourceFields方法是否支持系统变量 String testText1 = "P#{site}#{CURRENT_DATE_YYYYMMDD}"; String replacedText1 = replaceDataSourceFields(testText1, realDataMap); log.info("真实数据预览测试1: {} -> {}", testText1, replacedText1); - + String testText2 = "#{product_code}-#{CURRENT_DATE_YYYYMMDD}-#{batch_no}"; String replacedText2 = replaceDataSourceFields(testText2, realDataMap); log.info("真实数据预览测试2: {} -> {}", testText2, replacedText2); - + // 测试混合场景:固定字符串 + 数据源字段 + 系统变量 String testText3 = "PREFIX_#{site}_#{CURRENT_DATE_YYYYMMDD}_SUFFIX"; String replacedText3 = replaceDataSourceFields(testText3, realDataMap); log.info("真实数据预览测试3: {} -> {}", testText3, replacedText3); - + // 测试仅系统变量的场景 String testText4 = "#{CURRENT_DATE_YYYYMMDD}"; String replacedText4 = replaceDataSourceFields(testText4, null); // 空数据源 log.info("真实数据预览测试4(空数据源): {} -> {}", testText4, replacedText4); - + log.info("=== 系统变量功能测试完成 ==="); } } diff --git a/src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java b/src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java index 1845e1a..25f5efe 100644 --- a/src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java +++ b/src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java @@ -13,6 +13,7 @@ import com.gaotao.modules.base.service.ReportLabelListService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,6 +38,7 @@ public class ReportLabelListServiceImpl extends ServiceImpl