From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfDictionaryFieldValueResolver.java | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 233 insertions(+), 0 deletions(-)
diff --git a/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfDictionaryFieldValueResolver.java b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfDictionaryFieldValueResolver.java
new file mode 100644
index 0000000..02fa248
--- /dev/null
+++ b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfDictionaryFieldValueResolver.java
@@ -0,0 +1,233 @@
+package jnpf.bizcommon.audit.service.value;
+
+import com.alibaba.fastjson.JSON;
+import jnpf.bizcommon.audit.entity.model.AuditFieldDiffViewVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 鎸� JNPF dictionaryType 鎵归噺瑙f瀽瀛楀吀椤癸紱涓�娆¤鎯呰嚦澶氭墽琛屼竴鏉″瓧鍏告煡璇€��
+ *
+ * <p>{@code @Order} 鐨勫惈涔夎 {@link LimsQingyandanFieldValueResolver} 鐨勭被娉ㄩ噴銆�
+ */
+@Slf4j
+@Component
+@Order(JnpfDictionaryFieldValueResolver.ORDER)
+public class JnpfDictionaryFieldValueResolver implements AuditFieldValueResolver {
+
+ /** 骞冲彴閫氱敤瑙f瀽鍣紝鎺掑湪琛ㄤ笓鐢紙100锛変箣鍚庛�佺敤鎴峰厹搴曪紙300锛変箣鍓嶃�� */
+ public static final int ORDER = 200;
+
+ private static final String UNAVAILABLE = "鍚嶇О鏆備笉鍙敤";
+
+ private final DictionaryLookup lookup;
+
+ @Autowired
+ public JnpfDictionaryFieldValueResolver(JdbcTemplate jdbcTemplate) {
+ this(new JdbcDictionaryLookup(jdbcTemplate));
+ }
+
+ JnpfDictionaryFieldValueResolver(DictionaryLookup lookup) {
+ this.lookup = lookup;
+ }
+
+ @Override
+ public boolean supports(String targetTable) {
+ return true;
+ }
+
+ @Override
+ public void resolve(AuditFieldValueContext context, List<AuditFieldDiffViewVO> fields) {
+ if (context == null || blank(context.getTenantId()) || fields == null || fields.isEmpty()
+ || context.getDictionaryTypes().isEmpty()) {
+ return;
+ }
+ Set<String> dictionaryTypes = new LinkedHashSet<>();
+ Set<String> values = new LinkedHashSet<>();
+ for (AuditFieldDiffViewVO field : fields) {
+ String dictionaryType = dictionaryType(context, field);
+ if (dictionaryType == null || displaysResolved(field)) {
+ continue;
+ }
+ dictionaryTypes.add(dictionaryType);
+ values.addAll(parseValues(field.getOldData()));
+ values.addAll(parseValues(field.getNewData()));
+ }
+ if (dictionaryTypes.isEmpty() || values.isEmpty()) {
+ return;
+ }
+
+ Map<String, Map<String, String>> labels = lookup.labels(
+ context.getTenantId().trim(), dictionaryTypes, values);
+ for (AuditFieldDiffViewVO field : fields) {
+ String dictionaryType = dictionaryType(context, field);
+ Map<String, String> dictionary = dictionaryType == null
+ ? null : labels.get(dictionaryType);
+ if (dictionary == null) {
+ continue;
+ }
+ boolean multiple = "multiEnum".equals(field.getValueType())
+ || startsWithArray(field.getOldData()) || startsWithArray(field.getNewData());
+ if (blank(field.getValueType())) {
+ field.setValueType(multiple ? "multiEnum" : "enum");
+ }
+ if (field.getOldDisplay() == null) {
+ field.setOldDisplay(display(field.getOldData(), dictionary));
+ }
+ if (field.getNewDisplay() == null) {
+ field.setNewDisplay(display(field.getNewData(), dictionary));
+ }
+ }
+ }
+
+ private static String dictionaryType(AuditFieldValueContext context, AuditFieldDiffViewVO field) {
+ if (field == null || blank(field.getField())) {
+ return null;
+ }
+ return context.getDictionaryTypes().get(field.getField().trim().toLowerCase(Locale.ROOT));
+ }
+
+ private static boolean displaysResolved(AuditFieldDiffViewVO field) {
+ return (blank(field.getOldData()) || field.getOldDisplay() != null)
+ && (blank(field.getNewData()) || field.getNewDisplay() != null);
+ }
+
+ private static String display(String raw, Map<String, String> labels) {
+ if (blank(raw)) {
+ return "";
+ }
+ List<String> values = parseValues(raw);
+ if (values.isEmpty()) {
+ return UNAVAILABLE;
+ }
+ List<String> result = new ArrayList<>(values.size());
+ for (String value : values) {
+ String label = labels.get(value);
+ result.add(blank(label) ? UNAVAILABLE : label);
+ }
+ return String.join("銆�", result);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<String> parseValues(String raw) {
+ if (blank(raw)) {
+ return Collections.emptyList();
+ }
+ String trimmed = raw.trim();
+ if (!trimmed.startsWith("[")) {
+ return Collections.singletonList(trimmed);
+ }
+ try {
+ Object parsed = JSON.parse(trimmed);
+ if (!(parsed instanceof Collection)) {
+ return Collections.emptyList();
+ }
+ List<String> result = new ArrayList<>();
+ for (Object value : (Collection<Object>) parsed) {
+ if (value != null && !String.valueOf(value).trim().isEmpty()) {
+ result.add(String.valueOf(value).trim());
+ }
+ }
+ return result;
+ } catch (RuntimeException ignored) {
+ return Collections.emptyList();
+ }
+ }
+
+ private static boolean startsWithArray(String raw) {
+ return raw != null && raw.trim().startsWith("[");
+ }
+
+ private static boolean blank(String value) {
+ return value == null || value.trim().isEmpty();
+ }
+
+ interface DictionaryLookup {
+ Map<String, Map<String, String>> labels(String tenantId, Set<String> dictionaryTypes,
+ Set<String> values);
+ }
+
+ /** 琛ㄥ悕鍜屽垪鍚嶅浐瀹氾紱dictionaryType銆佸�煎拰绉熸埛鍏ㄩ儴鍙傛暟鍖栥�� */
+ private static final class JdbcDictionaryLookup implements DictionaryLookup {
+ private final NamedParameterJdbcTemplate jdbc;
+
+ private JdbcDictionaryLookup(JdbcTemplate jdbcTemplate) {
+ this.jdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
+ }
+
+ @Override
+ public Map<String, Map<String, String>> labels(
+ String tenantId, Set<String> dictionaryTypes, Set<String> values) {
+ try {
+ MapSqlParameterSource params = new MapSqlParameterSource()
+ .addValue("dictionaryTypes", dictionaryTypes)
+ .addValue("values", values)
+ .addValue("tenantId", tenantId);
+ List<Map<String, Object>> rows = jdbc.queryForList(
+ "SELECT t.f_id AS type_id, t.f_en_code AS type_code, "
+ + "d.f_id AS data_id, d.f_en_code AS data_code, d.f_full_name AS data_name "
+ + "FROM base_dictionary_data d "
+ + "JOIN base_dictionary_type t ON t.f_id = d.f_dictionary_type_id "
+ + "WHERE (t.f_id IN (:dictionaryTypes) OR t.f_en_code IN (:dictionaryTypes)) "
+ + "AND (d.f_id IN (:values) OR d.f_en_code IN (:values)) "
+ + "AND COALESCE(NULLIF(t.f_tenant_id, ''), '0') = :tenantId "
+ + "AND COALESCE(NULLIF(d.f_tenant_id, ''), '0') = :tenantId "
+ + "AND COALESCE(t.f_delete_mark, 0) = 0 "
+ + "AND COALESCE(d.f_delete_mark, 0) = 0",
+ params);
+ Map<String, Map<String, String>> result = new LinkedHashMap<>();
+ for (Map<String, Object> row : rows) {
+ String typeId = text(row.get("type_id"));
+ String typeCode = text(row.get("type_code"));
+ String dataId = text(row.get("data_id"));
+ String dataCode = text(row.get("data_code"));
+ String label = text(row.get("data_name"));
+ put(result, typeId, dataId, dataCode, label);
+ put(result, typeCode, dataId, dataCode, label);
+ }
+ return result;
+ } catch (RuntimeException ex) {
+ log.warn("[AUDIT-QUERY] JNPF 瀛楀吀鎵归噺瑙f瀽澶辫触 typeCount={} valueCount={} err={}",
+ dictionaryTypes.size(), values.size(), ex.getClass().getSimpleName());
+ return Collections.emptyMap();
+ }
+ }
+
+ private static void put(Map<String, Map<String, String>> result, String type,
+ String dataId, String dataCode, String label) {
+ if (type == null || label == null) {
+ return;
+ }
+ Map<String, String> values = result.computeIfAbsent(type, key -> new LinkedHashMap<>());
+ if (dataId != null) {
+ values.put(dataId, label);
+ }
+ if (dataCode != null) {
+ values.put(dataCode, label);
+ }
+ }
+
+ private static String text(Object value) {
+ if (value == null) {
+ return null;
+ }
+ String result = String.valueOf(value).trim();
+ return result.isEmpty() ? null : result;
+ }
+ }
+}
--
Gitblit v1.8.0