Browse Source

二维码元素组合选择流水号生成规则修改

master
han\hanst 4 months ago
parent
commit
c0396c8715
  1. 240
      src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java
  2. 2
      src/main/java/com/gaotao/modules/base/service/Impl/ReportLabelListServiceImpl.java

240
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<ReportLabelList> processLabelData(List<ReportLabelList> elements, Map<String, Object> dataMap,Boolean printFlag) {
if (elements == null || elements.isEmpty()) {
@ -50,14 +54,22 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
// 第一轮处理处理基本数据替换不包含元素组合
List<ReportLabelList> firstPassElements = new ArrayList<>();
Map<String, Object> 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<String, Object> 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<String, Object> dataMap, Boolean printFlag) {
try {
// 直接通过BaseService查询流水号元素避免循环依赖
List<ReportLabelList> 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<ReportLabelList> getElementsByReportId(String reportId) {
try {
// 使用Mapper直接查询避免循环依赖
return reportLabelListMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ReportLabelList>()
.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<com.gaotao.modules.base.entity.LabelContentSerialRuleData> 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);
// 规则48位流水号
com.gaotao.modules.base.entity.LabelContentSerialRuleData rule4 = new com.gaotao.modules.base.entity.LabelContentSerialRuleData();
rule4.setObjectName("流水号");
businessRules.add(rule4);
// 模拟数据源数据
java.util.Map<String, Object> 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<String, Object> 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("=== 系统变量功能测试完成 ===");
}
}

2
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<ReportLabelListMappe
private ProcedureMapper procedureMapper;
@Autowired
@Lazy
private LabelDataProcessorService labelDataProcessorService;
@Override

Loading…
Cancel
Save