Browse Source

界面设定的内容需要按特定格式组合到条码、二维码中

master
han\hanst 7 months ago
parent
commit
530bf69fa6
  1. 292
      src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java

292
src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java

@ -19,10 +19,12 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* 标签数据处理服务实现类 * 标签数据处理服务实现类
@ -45,22 +47,68 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
} }
List<ReportLabelList> processedElements = new ArrayList<>(); List<ReportLabelList> processedElements = new ArrayList<>();
// 第一轮处理处理基本数据替换不包含元素组合
List<ReportLabelList> firstPassElements = new ArrayList<>();
for (ReportLabelList element : elements) { for (ReportLabelList element : elements) {
ReportLabelList processedElement = processElementData(element, dataMap); ReportLabelList processedElement = processElementData(element, dataMap);
firstPassElements.add(processedElement);
}
// 第二轮处理处理元素组合引用
for (ReportLabelList element : firstPassElements) {
ReportLabelList finalElement = processElementCombinations(element, dataMap, firstPassElements);
// 如果元素被设置为不显示则跳过该元素 // 如果元素被设置为不显示则跳过该元素
if (("onecode".equals(element.getType()) || "qrcode".equals(element.getType()) if (("onecode".equals(element.getType()) || "qrcode".equals(element.getType())
|| "text".equals(element.getType()) || "pic".equals(element.getType())) || "text".equals(element.getType()) || "pic".equals(element.getType()))
&& processedElement.getData().isEmpty()
&& BigDecimal.ZERO.equals(processedElement.getWidth())) {
&& finalElement.getData().isEmpty()
&& BigDecimal.ZERO.equals(finalElement.getWidth())) {
log.debug("跳过不显示的元素: type={}, showElement={}", element.getType(), element.getShowElement()); log.debug("跳过不显示的元素: type={}, showElement={}", element.getType(), element.getShowElement());
continue; continue;
} }
processedElements.add(processedElement);
processedElements.add(finalElement);
} }
return processedElements; return processedElements;
} }
/**
* 处理元素组合引用
*/
private ReportLabelList processElementCombinations(ReportLabelList element, Map<String, Object> dataMap,
List<ReportLabelList> allElements) {
if (element == null || element.getData() == null || element.getData().isEmpty()) {
return element;
}
String originalData = element.getData();
// 检查是否包含元素引用
if (containsElementReferences(originalData)) {
ReportLabelList processedElement = copyElement(element);
String combinedData = processElementCombination(originalData, dataMap, allElements, element);
processedElement.setData(combinedData);
log.debug("处理元素组合: 原始数据={}, 组合后数据={}", originalData, combinedData);
return processedElement;
}
return element;
}
/**
* 检查数据中是否包含元素引用
*/
private boolean containsElementReferences(String data) {
if (data == null || data.isEmpty()) {
return false;
}
// 检查是否包含 {元素类型} 格式的引用排除 #{字段名} 格式
Pattern pattern = Pattern.compile("\\{(?!#)[^}]+\\}");
return pattern.matcher(data).find() || data.startsWith("CUSTOM:");
}
@Override @Override
public ReportLabelList processElementData(ReportLabelList element, Map<String, Object> dataMap) { public ReportLabelList processElementData(ReportLabelList element, Map<String, Object> dataMap) {
if (element == null || element.getData() == null || element.getData().isEmpty()) { if (element == null || element.getData() == null || element.getData().isEmpty()) {
@ -93,7 +141,14 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
break; break;
case "onecode": case "onecode":
case "qrcode": case "qrcode":
// 检查是否包含元素组合引用
if (containsElementReferences(originalData)) {
// 需要传入所有元素列表来处理组合
// 这里暂时使用基本的数据源替换完整的组合处理在processLabelData中进行
processedElement.setData(replaceDataSourceFields(originalData, dataMap));
} else {
processedElement.setData(replaceDataSourceFields(originalData, dataMap)); processedElement.setData(replaceDataSourceFields(originalData, dataMap));
}
break; break;
case "serialNumber": case "serialNumber":
// 处理流水号元素生成真实的流水号 // 处理流水号元素生成真实的流水号
@ -152,6 +207,237 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
return new CoordinateTransformer.CanvasSize(width, height, name, description); return new CoordinateTransformer.CanvasSize(width, height, name, description);
} }
/**
* 处理元素组合数据
* 支持将多个元素的内容按特定格式组合
*/
private String processElementCombination(String originalData, Map<String, Object> dataMap,
List<ReportLabelList> allElements, ReportLabelList currentElement) {
if (originalData == null || originalData.isEmpty()) {
return originalData;
}
// 检查是否是自定义表达式模式
if (originalData.startsWith("CUSTOM:")) {
return processCustomCombination(originalData.substring(7), dataMap, allElements);
}
// 处理模板模式的元素引用 {元素类型} {元素类型(内容)}
String processedData = originalData;
// 创建元素映射便于查找
Map<String, ReportLabelList> elementMap = new HashMap<>();
for (ReportLabelList element : allElements) {
if (element != currentElement) { // 排除自身
String elementKey = getElementDisplayName(element);
elementMap.put(elementKey, element);
}
}
// 替换元素引用
Pattern elementPattern = Pattern.compile("\\{([^}]+)\\}");
Matcher matcher = elementPattern.matcher(processedData);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String reference = matcher.group(1);
String replacement = "";
// 检查是否是数据源字段引用 #{fieldName}
if (reference.startsWith("#{") && reference.endsWith("}")) {
String fieldName = reference.substring(2, reference.length() - 1);
Object value = dataMap.get(fieldName);
replacement = value != null ? value.toString() : "";
} else {
// 查找匹配的元素
ReportLabelList referencedElement = findElementByReference(reference, elementMap);
if (referencedElement != null) {
// 递归处理引用的元素数据
replacement = processElementData(referencedElement, dataMap).getData();
if (replacement == null) {
replacement = "";
}
} else {
// 如果找不到匹配的元素保持原样
replacement = "{" + reference + "}";
}
}
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(result);
return result.toString();
}
/**
* 处理自定义组合表达式
*/
private String processCustomCombination(String expression, Map<String, Object> dataMap,
List<ReportLabelList> allElements) {
try {
// 这里可以实现简单的表达式处理
// 为了安全起见只支持有限的操作
// 示例支持简单的字符串拼接和条件判断
if (expression.contains("elements.filter")) {
return processElementsFilter(expression, allElements, dataMap);
} else if (expression.contains("dataMap.")) {
return processDataMapAccess(expression, dataMap);
}
// 默认返回表达式本身
return expression;
} catch (Exception e) {
log.error("处理自定义组合表达式失败: {}", expression, e);
return "ERROR: " + e.getMessage();
}
}
/**
* 处理元素过滤表达式
*/
private String processElementsFilter(String expression, List<ReportLabelList> allElements,
Map<String, Object> dataMap) {
// 简单实现elements.filter(e => e.type === 'text').map(e => e.data).join('-')
if (expression.contains("e.type === 'text'")) {
List<String> textData = allElements.stream()
.filter(e -> "text".equals(e.getType()))
.map(e -> e.getData() != null ? e.getData() : "")
.collect(Collectors.toList());
String separator = "-";
if (expression.contains(".join('")) {
int start = expression.indexOf(".join('") + 7;
int end = expression.indexOf("')", start);
if (end > start) {
separator = expression.substring(start, end);
}
}
return String.join(separator, textData);
}
return expression;
}
/**
* 处理数据映射访问表达式
*/
private String processDataMapAccess(String expression, Map<String, Object> dataMap) {
// 简单实现dataMap.fieldName
Pattern pattern = Pattern.compile("dataMap\\.([a-zA-Z_][a-zA-Z0-9_]*)");
Matcher matcher = pattern.matcher(expression);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String fieldName = matcher.group(1);
Object value = dataMap.get(fieldName);
String replacement = value != null ? value.toString() : "";
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(result);
return result.toString();
}
/**
* 根据引用查找元素
*/
private ReportLabelList findElementByReference(String reference, Map<String, ReportLabelList> elementMap) {
// 直接匹配
if (elementMap.containsKey(reference)) {
return elementMap.get(reference);
}
// 检查是否是带内容的引用格式文本(内容) 类型(内容)
Pattern contentPattern = Pattern.compile("^(文本|一维码|二维码|图片|流水号)\\((.+)\\)$");
Matcher contentMatcher = contentPattern.matcher(reference);
if (contentMatcher.matches()) {
String typeName = contentMatcher.group(1);
String expectedContent = contentMatcher.group(2);
// 根据类型名称获取对应的类型键
String targetType = getTypeKeyByName(typeName);
if (targetType != null) {
// 精确匹配同时匹配类型和内容
for (ReportLabelList element : elementMap.values()) {
if (targetType.equals(element.getType()) &&
expectedContent.equals(element.getData())) {
log.debug("精确匹配到元素: type={}, data={}", element.getType(), element.getData());
return element;
}
}
// 如果精确匹配失败尝试部分内容匹配
for (ReportLabelList element : elementMap.values()) {
if (targetType.equals(element.getType()) &&
element.getData() != null &&
element.getData().contains(expectedContent)) {
log.debug("部分匹配到元素: type={}, data={}, expected={}",
element.getType(), element.getData(), expectedContent);
return element;
}
}
}
}
// 模糊匹配按类型- 只有在没有内容指定时才使用
String[] typeNames = {"文本", "一维码", "二维码", "图片", "流水号"};
String[] typeKeys = {"text", "onecode", "qrcode", "pic", "serialNumber"};
for (int i = 0; i < typeNames.length; i++) {
if (reference.equals(typeNames[i])) { // 改为精确匹配类型名称
// 返回该类型的第一个元素保持向后兼容
for (ReportLabelList element : elementMap.values()) {
if (typeKeys[i].equals(element.getType())) {
log.debug("类型匹配到元素: type={}, data={}", element.getType(), element.getData());
return element;
}
}
}
}
log.warn("未找到匹配的元素引用: {}", reference);
return null;
}
/**
* 根据类型名称获取类型键
*/
private String getTypeKeyByName(String typeName) {
switch (typeName) {
case "文本": return "text";
case "一维码": return "onecode";
case "二维码": return "qrcode";
case "图片": return "pic";
case "流水号": return "serialNumber";
default: return null;
}
}
/**
* 获取元素显示名称
*/
private String getElementDisplayName(ReportLabelList element) {
Map<String, String> typeNames = new HashMap<>();
typeNames.put("text", "文本");
typeNames.put("onecode", "一维码");
typeNames.put("qrcode", "二维码");
typeNames.put("pic", "图片");
typeNames.put("serialNumber", "流水号");
String typeName = typeNames.getOrDefault(element.getType(), element.getType());
String content = element.getData() != null && !element.getData().isEmpty()
? "(" + (element.getData().length() > 10
? element.getData().substring(0, 10) + "..."
: element.getData()) + ")"
: "";
return typeName + content;
}
/** /**
* 处理文本元素支持数字日期字符串格式化 * 处理文本元素支持数字日期字符串格式化
*/ */

Loading…
Cancel
Save