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/title/AuditTitleSpecParser.java |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)

diff --git a/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/title/AuditTitleSpecParser.java b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/title/AuditTitleSpecParser.java
new file mode 100644
index 0000000..6e004ac
--- /dev/null
+++ b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/title/AuditTitleSpecParser.java
@@ -0,0 +1,163 @@
+package jnpf.bizcommon.audit.service.title;
+
+import jnpf.util.JsonUtil;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * 浠庡凡鍙戝竷琛ㄥ崟 JSON锛坽@code base_visual_release.F_FORM_DATA}锛夎В鏋�
+ * {@code __config__.biz_log_enabled} 鍕鹃�夈��
+ *
+ * <p><b>绾潤鎬併�佹棤渚濊禆銆佹案涓嶆姏寮傚父</b>锛氳В鏋愬け璐ヤ竴寰嬭繑鍥� {@link AuditTitleSpec#EMPTY}銆�
+ * 灞� 0 鐨� handler 澶栧眰铏芥湁 {@code catch(Throwable)} 鍏滃簳锛圠002锛夛紝浣嗛偅浼氫涪鎺�**鏁存潯浜嬩欢**鈥斺��
+ * 鏍囬瑙f瀽澶辫触鍙璁╂爣棰樼己甯紝涓嶈璁�"杩欐鏀硅繃"缂哄腑銆�
+ *
+ * <p><b>閫掑綊瑙勫垯</b>锛氬竷灞�瀹瑰櫒锛堟爡鏍� row / 鏍囩椤� tab / 鍗$墖 card / 琛ㄦ牸甯冨眬 tableGridTr鈥︼級鐨�
+ * children 鏄富琛ㄥ瓧娈碉紝蹇呴』缁х画寰�涓嬫敹锛涘彧鏈� {@code jnpfKey=table}锛堝瓙琛ㄦ帶浠讹級鐨� children
+ * 鎵嶆槸鍙︿竴寮犺〃鐨勫瓧娈碉紝鐙珛鎴愮粍涓�**涓嶅啀寰�涓昏〃鏀�**銆�
+ */
+public final class AuditTitleSpecParser {
+
+    /** 瀛愯〃鎺т欢鐨� jnpfKey锛屼笌 {@code AuditFieldDiff.JNPF_KEY_TABLE} 鍚屽�笺�� */
+    private static final String JNPF_KEY_TABLE = "table";
+
+    private AuditTitleSpecParser() {
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static AuditTitleSpec parse(String formDataJson) {
+        if (formDataJson == null || formDataJson.trim().isEmpty()) {
+            return AuditTitleSpec.EMPTY;
+        }
+        try {
+            Map<String, Object> root = JsonUtil.stringToMap(formDataJson);
+            if (root == null) {
+                return AuditTitleSpec.EMPTY;
+            }
+            List<?> fields = asList(root.get("fields"));
+            if (fields.isEmpty()) {
+                return AuditTitleSpec.EMPTY;
+            }
+            List<String> main = new ArrayList<String>();
+            List<AuditTitleSpec.SubTableSpec> subs = new ArrayList<AuditTitleSpec.SubTableSpec>();
+            collect(fields, main, subs);
+            if (main.isEmpty() && subs.isEmpty()) {
+                return AuditTitleSpec.EMPTY;
+            }
+            return new AuditTitleSpec(main, subs);
+        } catch (Throwable t) {
+            // 杩欐鏂囨湰瑙f瀽涓嶄簡灏辨槸瑙f瀽涓嶄簡锛岃繑鍥� EMPTY = 涓嶄骇鍑烘爣棰樸�備笉璁版棩蹇楋細
+            // 鍚屼竴涓〃鍗曟瘡娆′繚瀛橀兘浼氳蛋鍒拌繖閲岋紝鎶ラ敊浼氭妸鏃ュ織鍒风垎锛涜皟鐢ㄦ柟鎸� EMPTY 鍐� extra 鐣欑棔銆�
+            return AuditTitleSpec.EMPTY;
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static void collect(List<?> fields, List<String> main,
+                                List<AuditTitleSpec.SubTableSpec> subs) {
+        for (Object raw : fields) {
+            if (!(raw instanceof Map)) {
+                continue;
+            }
+            Map item = (Map) raw;
+            Map config = config(item);
+            if (config == null) {
+                continue;
+            }
+            // 瀛愯〃 vModel 淇濈暀鍘熷澶у皬鍐欙紙濡� tableField6da682锛夛細Task 4 瑕佹嬁瀹冨幓 newData 閲�
+            // 鎸夐敭鍙栧瓙琛ㄦ槑缁嗭紝newData 鐨勯敭灏辨槸琛ㄥ崟璁捐鍣ㄥ啓鐨勫師鏍凤紝lower() 杩囧氨姘歌繙鏌ヤ笉鍒般��
+            // 涓昏〃瀛楁鍒欒灏忓啓鈥斺�旇 AuditTitleSpec.mainFields() 鐨勫彛寰勩��
+            String rawVModel = str(item.containsKey("vModel")
+                    ? item.get("vModel") : item.get("__vModel__"));
+            String vModel = lower(rawVModel);
+            String jnpfKey = str(config.get("jnpfKey"));
+            List<?> children = asList(config.get("children"));
+
+            if (JNPF_KEY_TABLE.equals(jnpfKey)) {
+                List<String> subFields = new ArrayList<String>();
+                collectEnabledFlat(children, subFields);
+                if (rawVModel != null && !subFields.isEmpty()) {
+                    subs.add(new AuditTitleSpec.SubTableSpec(
+                            rawVModel, lower(str(config.get("tableName"))), subFields));
+                }
+                continue;   // 瀛愯〃 children 宸插崟鐙鐞嗭紝缁濅笉鑳藉啀寰�涓昏〃鏀�
+            }
+
+            if (vModel != null && enabled(config)) {
+                main.add(vModel);
+            }
+            if (!children.isEmpty()) {
+                collect(children, main, subs);   // 甯冨眬瀹瑰櫒锛歝hildren 浠嶆槸涓昏〃瀛楁
+            }
+        }
+    }
+
+    /** 瀛愯〃鍐呴儴涓嶅啀宓屽瀛愯〃锛堝钩鍙颁笉鏀寔锛夛紝鏁呭彧鏀朵竴灞傚嬀閫夊瓧娈点�� */
+    @SuppressWarnings("rawtypes")
+    private static void collectEnabledFlat(List<?> fields, List<String> out) {
+        for (Object raw : fields) {
+            if (!(raw instanceof Map)) {
+                continue;
+            }
+            Map item = (Map) raw;
+            Map config = config(item);
+            if (config == null) {
+                continue;
+            }
+            String vModel = lower(str(item.containsKey("vModel")
+                    ? item.get("vModel") : item.get("__vModel__")));
+            if (vModel != null && enabled(config)) {
+                out.add(vModel);
+            }
+            List<?> children = asList(config.get("children"));
+            if (!children.isEmpty()) {
+                collectEnabledFlat(children, out);   // 瀛愯〃閲岀殑甯冨眬瀹瑰櫒
+            }
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static Map config(Map item) {
+        Object raw = item.containsKey("config") ? item.get("config") : item.get("__config__");
+        return raw instanceof Map ? (Map) raw : null;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static boolean enabled(Map config) {
+        Object raw = config.get("biz_log_enabled");
+        if (raw instanceof Boolean) {
+            return (Boolean) raw;
+        }
+        // 璺� JVM / 瀛橀噺琛ㄥ崟閲屽彲鑳芥槸瀛楃涓� "true"锛涜涓嶅嚭灏卞綋娌″嬀鈥斺��**涓嶇寽**锛�
+        // 鐚滈敊鐨勬柟鍚戞槸鎶婃病鍕剧殑瀛楁鍐欒繘鏄庢枃鏍囬鍒椼��
+        return raw != null && "true".equalsIgnoreCase(String.valueOf(raw).trim());
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static List<?> asList(Object raw) {
+        if (raw instanceof List) {
+            return (List<?>) raw;
+        }
+        if (raw == null || String.valueOf(raw).trim().isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<Map> parsed = JsonUtil.getJsonToList(String.valueOf(raw), Map.class);
+        return parsed == null ? Collections.emptyList() : parsed;
+    }
+
+    private static String str(Object value) {
+        if (value == null) {
+            return null;
+        }
+        String s = value.toString().trim();
+        return s.isEmpty() ? null : s;
+    }
+
+    private static String lower(String value) {
+        return value == null ? null : value.toLowerCase(Locale.ROOT);
+    }
+}

--
Gitblit v1.8.0