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/test/java/jnpf/bizcommon/audit/service/AuditQuerySemanticsProbe.java | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 201 insertions(+), 0 deletions(-)
diff --git a/jnpf-biz-common/jnpf-biz-common-audit/src/test/java/jnpf/bizcommon/audit/service/AuditQuerySemanticsProbe.java b/jnpf-biz-common/jnpf-biz-common-audit/src/test/java/jnpf/bizcommon/audit/service/AuditQuerySemanticsProbe.java
new file mode 100644
index 0000000..3dca94e
--- /dev/null
+++ b/jnpf-biz-common/jnpf-biz-common-audit/src/test/java/jnpf/bizcommon/audit/service/AuditQuerySemanticsProbe.java
@@ -0,0 +1,201 @@
+package jnpf.bizcommon.audit.service;
+
+import jnpf.audit.diff.AuditFieldDiff;
+import jnpf.bizcommon.audit.entity.AuditEventEntity;
+import jnpf.bizcommon.audit.entity.model.AuditEventListVO;
+import jnpf.bizcommon.audit.entity.model.AuditOperationGroupRow;
+import jnpf.bizcommon.audit.service.impl.AuditQueryServiceImpl;
+import jnpf.bizcommon.audit.service.support.AuditEventCategories;
+import jnpf.bizcommon.audit.service.support.AuditQueryResponseSanitizer;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/** 鍙戝竷琛ㄥ崟/COMMENT fallback 涓庢煡璇㈣劚鏁忕函 JVM 鎺㈤拡銆� */
+public final class AuditQuerySemanticsProbe {
+
+ private static int passed;
+ private static int failed;
+
+ public static void main(String[] args) {
+ String fields = "[{\"vModel\":\"status\",\"config\":{\"label\":\"琛ㄥ崟鐘舵�乗","
+ + "\"jnpfKey\":\"select\",\"dataType\":\"dynamic\",\"children\":["
+ + "{\"vModel\":\"child_name\",\"config\":{\"label\":\"瀛愰」鍚嶇О\","
+ + "\"jnpfKey\":\"input\",\"dataType\":\"static\"}}]}},"
+ + "{\"vModel\":\"sampleCode\",\"config\":{\"label\":\"鏍峰搧缂栫爜\","
+ + "\"jnpfKey\":\"input\",\"dataType\":\"static\"}}]";
+ String formData = "{\"fields\":" + quote(fields) + "}";
+ Map<String, AuditFieldDiff.FieldMeta> published =
+ AuditFormRegistry.parsePublishedFieldMetadata(formData);
+ check("鍙戝竷琛ㄥ崟瑙f瀽 vModel -> label", "琛ㄥ崟鐘舵��".equals(published.get("status").label()),
+ String.valueOf(published));
+ check("鍙戝竷琛ㄥ崟閫掑綊瑙f瀽 children", "瀛愰」鍚嶇О".equals(published.get("child_name").label()),
+ String.valueOf(published));
+ check("鍔ㄦ�� select 鏍囪 nameModified", Boolean.TRUE.equals(published.get("status").nameModified()),
+ String.valueOf(published.get("status").nameModified()));
+ Map<String, Object> camelCaseRow = new LinkedHashMap<>();
+ camelCaseRow.put("sampleCode", "S-001");
+ String camelCaseDiff = AuditFieldDiff.diff(
+ Collections.emptyMap(), camelCaseRow, Collections.emptySet(), published);
+ check("camelCase vModel 鍙尮閰嶅皬鍐欏厓鏁版嵁閿�",
+ camelCaseDiff.contains("\"fieldName\":\"鏍峰搧缂栫爜\""), camelCaseDiff);
+
+ Map<String, AuditFieldDiff.FieldMeta> comments = new LinkedHashMap<>();
+ comments.put("status", new AuditFieldDiff.FieldMeta("COMMENT 鐘舵��", null, null));
+ comments.put("comment_only", new AuditFieldDiff.FieldMeta("COMMENT 涓撳睘瀛楁", null, null));
+ Map<String, AuditFieldDiff.FieldMeta> merged =
+ AuditFormRegistry.mergeFieldMetadata(comments, published);
+ check("鍙戝竷琛ㄥ崟鍚嶇О浼樺厛浜� COMMENT", "琛ㄥ崟鐘舵��".equals(merged.get("status").label()),
+ merged.get("status").label());
+ check("琛ㄥ崟缂哄け鏃朵娇鐢� COMMENT fallback",
+ "COMMENT 涓撳睘瀛楁".equals(merged.get("comment_only").label()),
+ merged.get("comment_only").label());
+
+ Map<String, AuditFieldDiff.FieldMeta> event = new LinkedHashMap<>();
+ event.put("status", new AuditFieldDiff.FieldMeta("浜嬩欢褰撴椂鐘舵��", "select", true));
+ Map<String, AuditFieldDiff.FieldMeta> finalMeta =
+ AuditFormRegistry.mergeFieldMetadata(merged, event);
+ check("浜嬩欢 listLog 浼樺厛浜庡綋鍓嶅彂甯冭〃鍗�",
+ "浜嬩欢褰撴椂鐘舵��".equals(finalMeta.get("status").label()), finalMeta.get("status").label());
+
+ String diffs = "[{\"field\":\"status\",\"fieldName\":\"status\",\"oldData\":\"a\",\"newData\":\"b\"},"
+ + "{\"field\":\"unknown_col\",\"fieldName\":\"unknown_col\",\"oldData\":\"a\",\"newData\":\"b\"},"
+ + "{\"field\":\"biz_sign\",\"fieldName\":\"biz_sign\",\"oldData\":\"secret-1\",\"newData\":\"secret-2\"}]";
+ String sanitized = AuditQueryResponseSanitizer.sanitizeFieldDiffs(diffs, finalMeta);
+ check("鍘嗗彶鎶�鏈悕鎸夊綋鍓嶅厓鏁版嵁瑁呴グ", sanitized.contains("\"fieldName\":\"浜嬩欢褰撴椂鐘舵�乗""), sanitized);
+ check("鍏冩暟鎹拰 COMMENT 閮界己澶辨椂鍥炶惤鏁版嵁搴撳瓧娈靛悕",
+ sanitized.contains("\"fieldName\":\"unknown_col\""), sanitized);
+ check("biz_sign 鍦ㄥ巻鍙� diff 涓笉鏆撮湶", !sanitized.contains("secret-1")
+ && !sanitized.contains("secret-2") && sanitized.contains("鐢靛瓙绛惧悕宸插叧鑱�"), sanitized);
+
+ String json = "{\"biz_sign\":\"credential\",\"nested\":{\"approveSignId\":\"credential-2\","
+ + "\"targetId\":\"business-id\"}}";
+ String safeJson = AuditQueryResponseSanitizer.sanitizeJson(json);
+ check("extra/snapshot 娣卞害鑴辨晱绛惧悕鍑瘉", !safeJson.contains("credential")
+ && safeJson.contains("business-id"), safeJson);
+ String childDiff = "[{\"field\":\"tableField1\",\"jnpfKey\":\"table\","
+ + "\"chidField\":[{\"prop\":\"item_name\",\"label\":\"椤圭洰\"},"
+ + "{\"prop\":\"review_sign\",\"label\":\"澶嶅绛惧悕\",\"jnpfKey\":\"sign\"}],"
+ + "\"chidData\":[{\"item_name\":\"鍚噺\",\"review_sign\":\"child-secret-new\","
+ + "\"jnpf_old_review_sign\":\"child-secret-old\",\"jnpf_type\":1}]}]";
+ String safeChildDiff = AuditQueryResponseSanitizer.sanitizeFieldDiffs(
+ childDiff, Collections.emptyMap());
+ check("瀛愯〃绛惧悕鍒楃殑鏂版棫鍑瘉鍧囪劚鏁忎笖鏅�氬垪淇濈暀",
+ safeChildDiff != null && !safeChildDiff.contains("child-secret")
+ && safeChildDiff.contains("鍚噺") && safeChildDiff.contains("\"masked\":true"),
+ safeChildDiff);
+ check("lims_sign targetId 涓嶈繑鍥炴櫘閫氭煡璇�",
+ AuditQueryResponseSanitizer.hidesTargetId("LIMS_SIGN"), "鏈懡涓�");
+
+ String missing = AuditQueryResponseSanitizer.sanitizeFieldDiffs(
+ "[{\"field\":\"x\",\"fieldName\":\"x\"}]", Collections.emptyMap());
+ check("绌哄厓鏁版嵁鍥炶惤鏁版嵁搴撳瓧娈靛悕", missing != null && missing.contains("\"fieldName\":\"x\""), missing);
+
+ Map<String, AuditFieldDiff.FieldMeta> databaseMeta = new LinkedHashMap<>();
+ databaseMeta.put("biz_status", new AuditFieldDiff.FieldMeta("涓氬姟鐘舵��", null, null));
+ databaseMeta.put("creator_time", new AuditFieldDiff.FieldMeta(null, null, null));
+ String historical = AuditQueryResponseSanitizer.sanitizeFieldDiffs(
+ "[{\"field\":\"bizStatus\",\"fieldName\":\"bizStatus\"},"
+ + "{\"field\":\"creatorTime\",\"fieldName\":\"creatorTime\"}]",
+ databaseMeta);
+ check("鍘嗗彶 Java 灞炴�у悕鍙槧灏勬暟鎹簱澶囨敞", historical.contains("\"fieldName\":\"涓氬姟鐘舵�乗""), historical);
+ check("鍘嗗彶 Java 灞炴�у悕鍦ㄥ娉ㄤ负绌烘椂鍥炶惤鏁版嵁搴撳垪鍚�",
+ historical.contains("\"fieldName\":\"creator_time\""), historical);
+
+ String repeatedFields = "[{\"field\":\"status\",\"oldData\":\"a\",\"newData\":\"b\"},"
+ + "{\"field\":\"status\",\"oldData\":\"b\",\"newData\":\"c\"},"
+ + "{\"field\":\"amount\",\"oldData\":1,\"newData\":2}]";
+ check("閲嶅瀛楁鎸夊瓧娈靛苟闆嗚鏁�",
+ AuditQueryResponseSanitizer.effectiveDiffCount(repeatedFields) == 2,
+ String.valueOf(AuditQueryResponseSanitizer.effectiveDiffFields(repeatedFields)));
+
+ String sameFieldAcrossTables = "[{\"targetTable\":\"main_table\",\"field\":\"status\","
+ + "\"oldData\":\"a\",\"newData\":\"b\"},"
+ + "{\"targetTable\":\"child_table\",\"field\":\"status\","
+ + "\"oldData\":\"x\",\"newData\":\"y\"},"
+ + "{\"targetTable\":\"child_table\",\"field\":\"status\","
+ + "\"oldData\":\"y\",\"newData\":\"z\"}]";
+ check("涓诲瓙琛ㄥ悓鍚嶅瓧娈垫寜鐗╃悊琛ㄥ垎鍒鏁�",
+ AuditQueryResponseSanitizer.effectiveDiffCount(sameFieldAcrossTables) == 2,
+ String.valueOf(AuditQueryResponseSanitizer.effectiveDiffFields(sameFieldAcrossTables)));
+
+ String batchSameField = "[{\"targetTable\":\"lims_task\",\"targetId\":\"row-1\","
+ + "\"field\":\"status\",\"oldData\":\"a\",\"newData\":\"b\"},"
+ + "{\"targetTable\":\"lims_task\",\"targetId\":\"row-2\","
+ + "\"field\":\"status\",\"oldData\":\"x\",\"newData\":\"b\"}]";
+ check("鎵归噺閫愯褰曞樊寮傜殑鎽樿浠嶆寜琛ㄥ拰瀛楁璁′负涓�涓�",
+ AuditQueryResponseSanitizer.effectiveDiffCount(batchSameField) == 1,
+ String.valueOf(AuditQueryResponseSanitizer.effectiveDiffFields(batchSameField)));
+
+ verifyOperationDisplayGrouping();
+
+ System.out.println("=== 鏌ヨ璇箟鏂█锛�" + passed + " 閫氳繃 / " + failed + " 澶辫触 ===");
+ System.exit(failed == 0 ? 0 : 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void verifyOperationDisplayGrouping() {
+ AuditEventEntity business = event(101L, AuditEventCategories.BUSINESS, "BIZ_ACTION",
+ "[{\"field\":\"status\",\"oldData\":\"a\",\"newData\":\"b\"}]");
+ AuditEventEntity primary = event(102L, AuditEventCategories.PRIMARY_SIGN, "E_SIGNATURE",
+ "[{\"field\":\"sign_a\"},{\"field\":\"sign_b\"}]");
+ AuditEventEntity review = event(103L, AuditEventCategories.REVIEW_SIGN, "E_SIGNATURE", null);
+ AuditOperationGroupRow group = new AuditOperationGroupRow();
+ group.setGid("op-display-1");
+
+ try {
+ Method method = AuditQueryServiceImpl.class.getDeclaredMethod(
+ "buildOperationRows", List.class, List.class);
+ method.setAccessible(true);
+ List<AuditEventListVO> rows = (List<AuditEventListVO>) method.invoke(
+ new AuditQueryServiceImpl(), Collections.singletonList(group),
+ Arrays.asList(primary, business, review));
+ AuditEventListVO main = rows.isEmpty() ? null : rows.get(0);
+ check("operationId 鍒楄〃鍙繑鍥� BUSINESS 涓昏",
+ rows.size() == 1 && main != null && Long.valueOf(101L).equals(main.getId()),
+ String.valueOf(rows));
+ check("涓荤鍚嶄笌澶嶅绛惧悕浣滀负涓ゆ潯鍏宠仈鏄庣粏",
+ main != null && main.getSubEvents() != null && main.getSubEvents().size() == 2
+ && "PRIMARY".equals(main.getSubEvents().get(0).getSignatureRole())
+ && "REVIEW".equals(main.getSubEvents().get(1).getSignatureRole()),
+ main == null ? "null" : String.valueOf(main.getSubEvents()));
+ check("鏌ヨ灞備笉绱姞绛惧悕宸紓鏁�",
+ main != null && Integer.valueOf(1).equals(main.getDiffCount()),
+ main == null ? "null" : String.valueOf(main.getDiffCount()));
+ } catch (ReflectiveOperationException ex) {
+ throw new AssertionError("鏃犳硶鎵ц operationId 灞曠ず缁勮鎺㈤拡", ex);
+ }
+ }
+
+ private static AuditEventEntity event(Long id, String category, String eventType, String fieldDiffs) {
+ AuditEventEntity event = new AuditEventEntity();
+ event.setId(id);
+ event.setOperationId("op-display-1");
+ event.setClientEventId("client-" + id);
+ event.setEventCategory(category);
+ event.setEventType(eventType);
+ event.setFieldDiffs(fieldDiffs);
+ return event;
+ }
+
+ private static String quote(String value) {
+ return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
+ }
+
+ private static void check(String name, boolean ok, String detail) {
+ if (ok) {
+ passed++;
+ System.out.println(" [PASS] " + name);
+ } else {
+ failed++;
+ System.out.println(" [FAIL] " + name + " -- " + detail);
+ }
+ }
+
+ private AuditQuerySemanticsProbe() {
+ }
+}
--
Gitblit v1.8.0