|
|
@ -39,6 +39,91 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
|
|
|
|
|
|
// 数据源字段的正则表达式,匹配 #{field_name} 格式 |
|
|
// 数据源字段的正则表达式,匹配 #{field_name} 格式 |
|
|
private static final Pattern DATA_SOURCE_PATTERN = Pattern.compile("#\\{([^}]+)\\}"); |
|
|
private static final Pattern DATA_SOURCE_PATTERN = Pattern.compile("#\\{([^}]+)\\}"); |
|
|
|
|
|
private static final String CUSTOM_FIELDS_CONTEXT_KEY = "__CUSTOM_FIELDS_CONTEXT__"; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 从数据映射中取值:保持原有精确匹配逻辑,未命中时再从前端补充字段中按大小写不敏感匹配 |
|
|
|
|
|
*/ |
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
private Object getMapValueIgnoreCase(Map<String, Object> dataMap, String fieldName) { |
|
|
|
|
|
if (dataMap == null || dataMap.isEmpty() || fieldName == null) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
String normalizedFieldName = fieldName.trim(); |
|
|
|
|
|
if (normalizedFieldName.isEmpty()) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
// 1) 保持原有逻辑:精确匹配 |
|
|
|
|
|
if (dataMap.containsKey(fieldName)) { |
|
|
|
|
|
Object exactValue = dataMap.get(fieldName); |
|
|
|
|
|
if (hasUsableFieldValue(exactValue)) { |
|
|
|
|
|
return exactValue; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (!normalizedFieldName.equals(fieldName) && dataMap.containsKey(normalizedFieldName)) { |
|
|
|
|
|
Object normalizedValue = dataMap.get(normalizedFieldName); |
|
|
|
|
|
if (hasUsableFieldValue(normalizedValue)) { |
|
|
|
|
|
return normalizedValue; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 2) 仅对前端补充字段做大小写不敏感兜底,不改变视图/IFS原有匹配行为 |
|
|
|
|
|
Object customFieldsObj = dataMap.get(CUSTOM_FIELDS_CONTEXT_KEY); |
|
|
|
|
|
if (customFieldsObj instanceof Map<?, ?> customFieldsMap && !customFieldsMap.isEmpty()) { |
|
|
|
|
|
String normalizedLookupName = normalizeFieldNameForCustomLookup(normalizedFieldName); |
|
|
|
|
|
for (Map.Entry<?, ?> entry : customFieldsMap.entrySet()) { |
|
|
|
|
|
if (entry.getKey() == null) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
String customKey = entry.getKey().toString().trim(); |
|
|
|
|
|
if (customKey.equalsIgnoreCase(normalizedFieldName)) { |
|
|
|
|
|
return entry.getValue(); |
|
|
|
|
|
} |
|
|
|
|
|
// 对customFields做标准化匹配,兼容 #{ifs.QTY}、#{[QTY]} 等写法 |
|
|
|
|
|
String normalizedCustomKey = normalizeFieldNameForCustomLookup(customKey); |
|
|
|
|
|
if (normalizedCustomKey.equalsIgnoreCase(normalizedLookupName)) { |
|
|
|
|
|
return entry.getValue(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 判断字段值是否可用(null或空白字符串视为不可用) |
|
|
|
|
|
*/ |
|
|
|
|
|
private boolean hasUsableFieldValue(Object value) { |
|
|
|
|
|
if (value == null) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
if (value instanceof String stringValue) { |
|
|
|
|
|
return StringUtils.isNotBlank(stringValue); |
|
|
|
|
|
} |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 仅用于customFields兜底匹配的字段名标准化 |
|
|
|
|
|
*/ |
|
|
|
|
|
private String normalizeFieldNameForCustomLookup(String fieldName) { |
|
|
|
|
|
if (fieldName == null) { |
|
|
|
|
|
return ""; |
|
|
|
|
|
} |
|
|
|
|
|
String normalized = fieldName.trim(); |
|
|
|
|
|
if (normalized.isEmpty()) { |
|
|
|
|
|
return ""; |
|
|
|
|
|
} |
|
|
|
|
|
// 兼容 #[QTY]、[QTY] 这类字段写法 |
|
|
|
|
|
if (normalized.startsWith("[") && normalized.endsWith("]") && normalized.length() > 2) { |
|
|
|
|
|
normalized = normalized.substring(1, normalized.length() - 1).trim(); |
|
|
|
|
|
} |
|
|
|
|
|
// 兼容 ifs.QTY / main.qty |
|
|
|
|
|
int dotIndex = normalized.lastIndexOf('.'); |
|
|
|
|
|
if (dotIndex >= 0 && dotIndex < normalized.length() - 1) { |
|
|
|
|
|
normalized = normalized.substring(dotIndex + 1).trim(); |
|
|
|
|
|
} |
|
|
|
|
|
return normalized; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private com.gaotao.modules.base.service.BaseService baseService; |
|
|
private com.gaotao.modules.base.service.BaseService baseService; |
|
|
@ -390,7 +475,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
|
|
|
|
|
|
// 特殊处理流水号引用 |
|
|
// 特殊处理流水号引用 |
|
|
if ("SERIAL_NUMBER".equals(fieldName)) { |
|
|
if ("SERIAL_NUMBER".equals(fieldName)) { |
|
|
Object serialValue = dataMap.get("SERIAL_NUMBER"); |
|
|
|
|
|
|
|
|
Object serialValue = getMapValueIgnoreCase(dataMap, "SERIAL_NUMBER"); |
|
|
replacement = serialValue != null ? serialValue.toString() : ""; |
|
|
replacement = serialValue != null ? serialValue.toString() : ""; |
|
|
log.debug("元素组合中使用流水号引用: SERIAL_NUMBER={}", replacement); |
|
|
log.debug("元素组合中使用流水号引用: SERIAL_NUMBER={}", replacement); |
|
|
} |
|
|
} |
|
|
@ -400,7 +485,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
log.debug("元素组合中使用系统变量: {}={}", fieldName, replacement); |
|
|
log.debug("元素组合中使用系统变量: {}={}", fieldName, replacement); |
|
|
} else { |
|
|
} else { |
|
|
// 普通数据源字段 |
|
|
// 普通数据源字段 |
|
|
Object value = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object value = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
replacement = value != null ? value.toString() : ""; |
|
|
replacement = value != null ? value.toString() : ""; |
|
|
log.debug("元素组合中使用数据源字段: {}={}", fieldName, replacement); |
|
|
log.debug("元素组合中使用数据源字段: {}={}", fieldName, replacement); |
|
|
} |
|
|
} |
|
|
@ -488,7 +573,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
|
|
|
|
|
|
while (matcher.find()) { |
|
|
while (matcher.find()) { |
|
|
String fieldName = matcher.group(1); |
|
|
String fieldName = matcher.group(1); |
|
|
Object value = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object value = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
String replacement = value != null ? value.toString() : ""; |
|
|
String replacement = value != null ? value.toString() : ""; |
|
|
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement)); |
|
|
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement)); |
|
|
} |
|
|
} |
|
|
@ -760,7 +845,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
// 特殊处理流水号引用 |
|
|
// 特殊处理流水号引用 |
|
|
if ("SERIAL_NUMBER".equals(fieldName)) { |
|
|
if ("SERIAL_NUMBER".equals(fieldName)) { |
|
|
// 对于流水号引用,需要从dataMap中获取已处理的流水号数据 |
|
|
// 对于流水号引用,需要从dataMap中获取已处理的流水号数据 |
|
|
Object serialValue = dataMap.get("SERIAL_NUMBER"); |
|
|
|
|
|
|
|
|
Object serialValue = getMapValueIgnoreCase(dataMap, "SERIAL_NUMBER"); |
|
|
if (serialValue != null) { |
|
|
if (serialValue != null) { |
|
|
replacement = serialValue.toString(); |
|
|
replacement = serialValue.toString(); |
|
|
log.debug("替换流水号引用: SERIAL_NUMBER={}", replacement); |
|
|
log.debug("替换流水号引用: SERIAL_NUMBER={}", replacement); |
|
|
@ -776,7 +861,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
log.debug("替换系统变量: {}={}", fieldName, replacement); |
|
|
log.debug("替换系统变量: {}={}", fieldName, replacement); |
|
|
} else if (dataMap != null && !dataMap.isEmpty()) { |
|
|
} else if (dataMap != null && !dataMap.isEmpty()) { |
|
|
// 然后检查数据源字段 |
|
|
// 然后检查数据源字段 |
|
|
Object value = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object value = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
if (value != null) { |
|
|
if (value != null) { |
|
|
replacement = value.toString(); |
|
|
replacement = value.toString(); |
|
|
log.debug("替换数据源字段: {}={}", fieldName, replacement); |
|
|
log.debug("替换数据源字段: {}={}", fieldName, replacement); |
|
|
@ -1254,7 +1339,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
String expectedValue = parts[1].trim(); |
|
|
String expectedValue = parts[1].trim(); |
|
|
|
|
|
|
|
|
// 从数据源中获取字段值 |
|
|
// 从数据源中获取字段值 |
|
|
Object actualValue = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object actualValue = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
String actualValueStr = actualValue != null ? actualValue.toString().trim() : ""; |
|
|
String actualValueStr = actualValue != null ? actualValue.toString().trim() : ""; |
|
|
|
|
|
|
|
|
log.debug("检查图片显示条件: 字段名={}, 期望值={}, 实际值={}", fieldName, expectedValue, actualValueStr); |
|
|
log.debug("检查图片显示条件: 字段名={}, 期望值={}, 实际值={}", fieldName, expectedValue, actualValueStr); |
|
|
@ -1446,7 +1531,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
value = getSystemVariableValue(fieldName); |
|
|
value = getSystemVariableValue(fieldName); |
|
|
} else { |
|
|
} else { |
|
|
// 普通数据字段 |
|
|
// 普通数据字段 |
|
|
Object fieldValue = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object fieldValue = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
value = fieldValue != null ? fieldValue.toString() : ""; |
|
|
value = fieldValue != null ? fieldValue.toString() : ""; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1599,7 +1684,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
log.debug("使用系统变量: {}={}", fieldName, value); |
|
|
log.debug("使用系统变量: {}={}", fieldName, value); |
|
|
} else { |
|
|
} else { |
|
|
// 普通数据字段 |
|
|
// 普通数据字段 |
|
|
Object fieldValue = dataMap.get(fieldName); |
|
|
|
|
|
|
|
|
Object fieldValue = getMapValueIgnoreCase(dataMap, fieldName); |
|
|
value = fieldValue != null ? fieldValue.toString() : ""; |
|
|
value = fieldValue != null ? fieldValue.toString() : ""; |
|
|
log.debug("使用真实数据字段: {}={}", fieldName, value); |
|
|
log.debug("使用真实数据字段: {}={}", fieldName, value); |
|
|
} |
|
|
} |
|
|
@ -1670,6 +1755,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
|
|
|
|
|
|
// 3.3 确定数据记录数量(以主视图为准,如果没有主视图则以IFS视图为准) |
|
|
// 3.3 确定数据记录数量(以主视图为准,如果没有主视图则以IFS视图为准) |
|
|
int recordCount = Math.max(mainViewDataList.size(), ifsViewDataList.size()); |
|
|
int recordCount = Math.max(mainViewDataList.size(), ifsViewDataList.size()); |
|
|
|
|
|
Map<String, Object> customFields = getCustomFieldsFromQueryParams(queryParams); |
|
|
|
|
|
|
|
|
if (recordCount == 0) { |
|
|
if (recordCount == 0) { |
|
|
log.warn("两个视图查询都未返回数据,返回空列表"); |
|
|
log.warn("两个视图查询都未返回数据,返回空列表"); |
|
|
@ -1681,6 +1767,9 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
// 4. 为每条记录生成ZPL代码 |
|
|
// 4. 为每条记录生成ZPL代码 |
|
|
for (int i = 0; i < recordCount; i++) { |
|
|
for (int i = 0; i < recordCount; i++) { |
|
|
java.util.Map<String, Object> realDataMap = new java.util.HashMap<>(); |
|
|
java.util.Map<String, Object> realDataMap = new java.util.HashMap<>(); |
|
|
|
|
|
if (!customFields.isEmpty()) { |
|
|
|
|
|
realDataMap.put(CUSTOM_FIELDS_CONTEXT_KEY, customFields); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 4.1 添加主视图数据 |
|
|
// 4.1 添加主视图数据 |
|
|
if (i < mainViewDataList.size()) { |
|
|
if (i < mainViewDataList.size()) { |
|
|
@ -1702,7 +1791,17 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 4.3 使用当前记录的数据生成ZPL |
|
|
|
|
|
|
|
|
// 4.3 合并前端补充字段(仅在视图无该字段时才补位) |
|
|
|
|
|
if (!customFields.isEmpty()) { |
|
|
|
|
|
for (Map.Entry<String, Object> entry : customFields.entrySet()) { |
|
|
|
|
|
if (entry.getKey() == null || entry.getKey().trim().isEmpty()) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
realDataMap.putIfAbsent(entry.getKey(), entry.getValue()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4.4 使用当前记录的数据生成ZPL |
|
|
String zplCode = generateZplWithData(elements, realDataMap, labelSetting, printFlag); |
|
|
String zplCode = generateZplWithData(elements, realDataMap, labelSetting, printFlag); |
|
|
zplCodeList.add(zplCode); |
|
|
zplCodeList.add(zplCode); |
|
|
|
|
|
|
|
|
@ -1718,6 +1817,27 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 从查询参数中提取前端补充字段 |
|
|
|
|
|
*/ |
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
private Map<String, Object> getCustomFieldsFromQueryParams(Map<String, Object> queryParams) { |
|
|
|
|
|
if (queryParams == null) { |
|
|
|
|
|
return Collections.emptyMap(); |
|
|
|
|
|
} |
|
|
|
|
|
Object customFieldsObj = queryParams.get("customFields"); |
|
|
|
|
|
if (customFieldsObj instanceof Map<?, ?> customFieldsMap) { |
|
|
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
|
|
for (Map.Entry<?, ?> entry : customFieldsMap.entrySet()) { |
|
|
|
|
|
if (entry.getKey() != null) { |
|
|
|
|
|
result.put(entry.getKey().toString(), entry.getValue()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
return Collections.emptyMap(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 判断是否为系统变量 |
|
|
* 判断是否为系统变量 |
|
|
* |
|
|
* |
|
|
|