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-audit-sdk/src/main/java/jnpf/audit/sdk/AuditContextCollector.java |  131 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/jnpf-biz-common/jnpf-audit-sdk/src/main/java/jnpf/audit/sdk/AuditContextCollector.java b/jnpf-biz-common/jnpf-audit-sdk/src/main/java/jnpf/audit/sdk/AuditContextCollector.java
new file mode 100644
index 0000000..bec6c9b
--- /dev/null
+++ b/jnpf-biz-common/jnpf-audit-sdk/src/main/java/jnpf/audit/sdk/AuditContextCollector.java
@@ -0,0 +1,131 @@
+package jnpf.audit.sdk;
+
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import jnpf.audit.AuditApiConsts;
+import jnpf.audit.model.AuditEventDTO;
+import jnpf.base.UserInfo;
+import jnpf.util.IpUtil;
+import jnpf.util.RandomUtil;
+import jnpf.util.ServletUtil;
+import jnpf.util.UserProvider;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import java.util.Date;
+
+/**
+ * 瀹¤涓婁笅鏂囬噰闆嗗櫒锛圱ask 7 Step 1锛夛細鍙~ DTO 鐨勭┖缂哄瓧娈碉紝涓嶈鐩栬皟鐢ㄦ柟宸茬粰鍊笺��
+ *
+ * <p>鎿嶄綔浜�/绉熸埛鍙栬嚜 {@link UserProvider}锛圫a-Token 鐧诲綍涓婁笅鏂囷級锛汭P/娴忚鍣�/OS 鍙栬嚜璇锋眰涓婁笅鏂囷紝
+ * 宸ュ叿涓庡钩鍙� {@code jnpf.RequestLogAspect} 鍚屾锛坽@link IpUtil#getIpAddr()} / {@link IpUtil#getIpCity(String)} /
+ * {@link ServletUtil#getUserAgent()} + hutool {@link UserAgentUtil#parse(String)}锛夈��
+ *
+ * <p>鍏抽敭绾︽潫锛堢粓楠�#6锛夛細operationId **涓嶇敱鏈噰闆嗗櫒鐢熸垚銆佷篃涓嶅啓 MDC**鈥斺�旂敓鎴愪笌 MDC 鍐欏叆缁熶竴褰�
+ * {@link AuditTxHolder}锛涢噰闆嗗櫒鑻ュ厛鍐� MDC锛屼細璁� holder 璇诲埌鐨� previousMdc 鍙樻垚鏂板�兼湰韬紝鎭㈠绛変簬娌℃仮澶嶃��
+ */
+public class AuditContextCollector {
+
+    /** 鏃犵櫥褰曚笂涓嬫枃鏃剁殑鎿嶄綔浜哄崰浣嶏紙寮傛/绯荤粺瑙﹀彂閾捐矾锛� */
+    private static final String OPERATOR_SYSTEM = "SYSTEM";
+
+    private final String appName;
+
+    public AuditContextCollector(String appName) {
+        this.appName = appName;
+    }
+
+    /** 濉厖绌虹己瀛楁骞惰繑鍥炲悓涓� dto锛堜緵 AuditClient 鍐荤粨鍚庝氦 holder 缂撳啿锛夈�� */
+    public AuditEventDTO fill(AuditEventDTO dto) {
+        if (isBlank(dto.getClientEventId())) {
+            dto.setClientEventId(RandomUtil.uuId());   // 骞冲彴闆姳锛�= String.valueOf(YitIdHelper.nextId())锛�
+        }
+        if (dto.getEventTime() == null) {
+            dto.setEventTime(new Date());
+        }
+        if (isBlank(dto.getAppName())) {
+            dto.setAppName(appName);
+        }
+        fillOperator(dto);
+        fillRequest(dto);
+        return dto;
+    }
+
+    /**
+     * 鎿嶄綔浜�/绉熸埛锛氭湁鐧诲綍鐢ㄦ埛鍒欏~ userId/userName/organizeId/tenantId锛涙棤鍒� operator=SYSTEM銆�
+     *
+     * <p>绉熸埛鍥炶惤锛圡2 闃绘柇椤逛慨澶嶏級锛氬崟绉熸埛閮ㄧ讲涓� {@code user.getTenantId()} 杩斿洖**绌轰覆**锛�
+     * 鏃犱細璇濋摼璺洿鏄棤浠庡彇寰椻�斺�斾袱绉嶆儏鍐甸兘鍦ㄦ渶鍚庣粺涓�鍥炶惤鍒� {@link AuditApiConsts#DEFAULT_TENANT_ID}锛�
+     * 鍚﹀垯鏈嶅姟绔� validate 浼氫互銆宼enantId 涓嶈兘涓虹┖銆嶆嫆鏀讹紝浜嬩欢杩� %RETRY% 鐩磋嚦 DLQ銆�
+     * 鍥炶惤鍙湪绌虹櫧鏃跺彂鐢燂紝澶氱鎴烽儴缃蹭笅鐪熷疄绉熸埛鍙蜂笉鍙楀奖鍝嶃��
+     */
+    private void fillOperator(AuditEventDTO dto) {
+        UserInfo user = currentUser();
+        if (user != null && !isBlank(user.getUserId())) {
+            if (isBlank(dto.getOperatorId())) {
+                dto.setOperatorId(user.getUserId());
+            }
+            if (isBlank(dto.getOperatorName())) {
+                dto.setOperatorName(user.getUserName());
+            }
+            if (isBlank(dto.getOperatorOrgId())) {
+                dto.setOperatorOrgId(user.getOrganizeId());
+            }
+            if (isBlank(dto.getTenantId())) {
+                dto.setTenantId(user.getTenantId());
+            }
+        } else if (isBlank(dto.getOperatorId())) {
+            // 鏃犵櫥褰曚笂涓嬫枃锛歰perator=SYSTEM锛坱enantId 鐢变笅鏂瑰摠鍏靛洖钀藉厹搴曪級
+            dto.setOperatorId(OPERATOR_SYSTEM);
+        }
+        if (isBlank(dto.getTenantId())) {
+            dto.setTenantId(AuditApiConsts.DEFAULT_TENANT_ID);
+        }
+    }
+
+    /** IP/娴忚鍣�/OS锛氫粎鍦ㄦ湁璇锋眰涓婁笅鏂囨椂閲囬泦锛宐est-effort锛岄噰闆嗗け璐ラ潤榛橀檷绾т笉褰卞搷瀹¤涓绘祦绋嬨�� */
+    private void fillRequest(AuditEventDTO dto) {
+        if (RequestContextHolder.getRequestAttributes() == null) {
+            return;   // 鏃犺姹備笂涓嬫枃锛堝紓姝�/绯荤粺瑙﹀彂锛�
+        }
+        try {
+            if (isBlank(dto.getIp())) {
+                String ip = IpUtil.getIpAddr();
+                dto.setIp(ip);
+                if (isBlank(dto.getIpRegion())) {
+                    dto.setIpRegion(IpUtil.getIpCity(ip));
+                }
+            }
+            String ua = ServletUtil.getUserAgent();
+            if (!isBlank(ua)) {
+                UserAgent agent = UserAgentUtil.parse(ua);
+                if (isBlank(dto.getBrowser())) {
+                    dto.setBrowser(join(agent.getBrowser().getName(), agent.getVersion()));
+                }
+                if (isBlank(dto.getOs())) {
+                    dto.setOs(join(agent.getPlatform().getName(), agent.getOsVersion()));
+                }
+            }
+        } catch (Exception ignore) {
+            // 涓婁笅鏂囬噰闆嗗睘 best-effort锛屼换浣曞紓甯镐笉寰楀啋娉″奖鍝嶄笟鍔′笌瀹¤涓婚摼璺�
+        }
+    }
+
+    private static UserInfo currentUser() {
+        try {
+            return UserProvider.getUser();
+        } catch (Exception e) {
+            return null;   // 鏈櫥褰�/鏃� token锛圫a-Token 鍙兘鎶涘紓甯革級锛岃涓烘棤鐢ㄦ埛
+        }
+    }
+
+    private static String join(String a, String b) {
+        String x = a == null ? "" : a.trim();
+        String y = b == null ? "" : b.trim();
+        String r = (x + " " + y).trim();
+        return r.isEmpty() ? null : r;
+    }
+
+    private static boolean isBlank(String s) {
+        return s == null || s.trim().isEmpty();
+    }
+}

--
Gitblit v1.8.0