From bc68f4393cafe39c4fce614c8128936067ea25f7 Mon Sep 17 00:00:00 2001
From: 刘帅 <rr.iii@qq.com>
Date: 星期二, 22 九月 2026 17:18:17 +0800
Subject: [PATCH] bug:登录问题和操作日志

---
 cloud-server-management/src/main/java/com/dsh/guns/core/aop/LogAop.java |  130 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/cloud-server-management/src/main/java/com/dsh/guns/core/aop/LogAop.java b/cloud-server-management/src/main/java/com/dsh/guns/core/aop/LogAop.java
index 79fc41e..666d611 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/core/aop/LogAop.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/core/aop/LogAop.java
@@ -8,7 +8,10 @@
 import com.dsh.guns.core.log.factory.LogTaskFactory;
 import com.dsh.guns.core.support.HttpKit;
 import com.dsh.guns.core.util.Contrast;
+import com.dsh.guns.modular.system.audit.ManagementAuditWriter;
+import com.dsh.guns.modular.system.audit.AuditDataFormatter;
 import com.dsh.guns.modular.system.model.User;
+import com.dsh.guns.modular.system.service.IUserService;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.Signature;
 import org.aspectj.lang.annotation.Around;
@@ -19,8 +22,13 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+import java.util.HashMap;
 import java.lang.reflect.Method;
 import java.util.Map;
+import java.util.UUID;
 
 /**
  * 日志记录
@@ -33,6 +41,8 @@
 public class LogAop {
 
     private Logger log = LoggerFactory.getLogger(this.getClass());
+    @Resource private ManagementAuditWriter auditWriter;
+    @Resource private IUserService userService;
 
     @Pointcut(value = "@annotation(com.dsh.guns.core.common.annotion.BussinessLog)")
     public void cutService() {
@@ -40,17 +50,119 @@
 
     @Around("cutService()")
     public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
-
-        //先执行业务
-        Object result = point.proceed();
-
+        String beforeData = beforeData();
         try {
-            handle(point);
-        } catch (Exception e) {
-            log.error("日志记录出错!", e);
+            Object result = point.proceed();
+            appendUnifiedAudit(point, "SUCCESS", null, beforeData);
+            return result;
+        } catch (Throwable e) {
+            appendUnifiedAudit(point, "FAIL", e.getMessage(), beforeData);
+            throw e;
         }
+    }
 
-        return result;
+    /**
+     * @BussinessLog 是后台已有的“需要记录的用户操作”白名单。
+     * 在这里写统一审计,能够覆盖 /mgr/add 等直接访问管理端的请求,
+     * 并避免将其内部 Feign 调用和 POST 查询误记为操作。
+     */
+    private void appendUnifiedAudit(ProceedingJoinPoint point, String result, String errorMessage, String beforeData) {
+        try {
+            Method method = ((MethodSignature) point.getSignature()).getMethod();
+            BussinessLog annotation = method.getAnnotation(BussinessLog.class);
+            User user = UserExt.getUser();
+            if (annotation == null || user == null) return;
+
+            HttpServletRequest request = HttpKit.getRequest();
+            Map<String, Object> audit = new HashMap<String, Object>();
+            audit.put("traceId", UUID.randomUUID().toString().replace("-", ""));
+            audit.put("sourceService", "mb-cloud-management");
+            audit.put("sourceType", "HTTP");
+            audit.put("operationType", operationType(annotation.value()));
+            audit.put("riskLevel", "NORMAL");
+            audit.put("operationName", annotation.value());
+            audit.put("requestMethod", request.getMethod());
+            audit.put("requestUri", request.getRequestURI());
+            // 审计表字段为 varchar,必须在调用审计服务前序列化;直接传 Map 会导致
+            // Spring 无法绑定到 SysAccountAuditLog.requestParams(String),从而整条日志写入失败。
+            audit.put("requestParams", AuditDataFormatter.format(maskedParameters(HttpKit.getRequestParameters()), User.class));
+            audit.put("beforeData", beforeData);
+            audit.put("afterData", afterData(beforeData));
+            audit.put("userId", user.getId());
+            audit.put("userAccount", user.getAccount());
+            audit.put("clientIp", HttpKit.getIp());
+            audit.put("result", result);
+            audit.put("errorMessage", maskText(errorMessage));
+            audit.put("createdAt", new Date());
+            auditWriter.append(audit);
+        } catch (Exception auditException) {
+            // 审计失败不能影响原有业务。
+            log.error("统一操作审计记录出错", auditException);
+        }
+    }
+
+    private String operationType(String operationName) {
+        String value = operationName == null ? "" : operationName;
+        if (value.contains("删除")) return "DELETE";
+        if (value.contains("添加") || value.contains("新增")) return "CREATE";
+        if (value.contains("冻结") || value.contains("解冻") || value.contains("审核") || value.contains("状态")) return "STATUS_CHANGE";
+        return "UPDATE";
+    }
+
+    private Map<String, String> maskedParameters(Map<String, String> parameters) {
+        Map<String, String> masked = new HashMap<String, String>();
+        for (Map.Entry<String, String> entry : parameters.entrySet()) {
+            String key = entry.getKey();
+            masked.put(key, key != null && key.toLowerCase().matches(".*(password|token|secret|idcard|identity|bank|card|mobile|phone).*")
+                    ? "***" : entry.getValue());
+        }
+        return masked;
+    }
+
+    private String maskText(String text) {
+        return text == null ? null : text.replaceAll("(?i)(password|token|authorization|idcard|bankCard)\\s*[:=]\\s*[^,\\s&}]+", "$1=***");
+    }
+
+    /** 员工修改前后均从数据库读取真实记录,避免将前端提交值误当作旧值。 */
+    private String beforeData() {
+        try {
+            HttpServletRequest request = HttpKit.getRequest();
+            if (!"/mgr/edit".equals(request.getRequestURI())) return null;
+            Integer userId = Integer.valueOf(request.getParameter("id"));
+            return userSnapshot(userService.getById(userId));
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private String afterData(String beforeData) {
+        if (beforeData == null) return null;
+        try {
+            Integer userId = Integer.valueOf(HttpKit.getRequest().getParameter("id"));
+            return userSnapshot(userService.getById(userId));
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private String userSnapshot(User target) {
+        if (target == null) return null;
+        Map<String, Object> data = new HashMap<String, Object>();
+        data.put("id", target.getId());
+        data.put("account", target.getAccount());
+        data.put("name", target.getName());
+        data.put("phone", target.getPhone());
+        data.put("birthday", target.getBirthday());
+        data.put("sex", target.getSex());
+        data.put("email", target.getEmail());
+        data.put("roleid", target.getRoleid());
+        data.put("deptid", target.getDeptid());
+        data.put("status", target.getStatus());
+        data.put("objectType", target.getObjectType());
+        data.put("objectId", target.getObjectId());
+        data.put("idCard", target.getIdCard());
+        data.put("avatar", target.getAvatar());
+        return AuditDataFormatter.format(data, User.class);
     }
 
     private void handle(ProceedingJoinPoint point) throws Exception {
@@ -103,4 +215,4 @@
 //        LogManager.me().executeLog(LogTaskFactory.bussinessLog(1, bussinessName, className, methodName, msg));
 
     }
-}
\ No newline at end of file
+}

--
Gitblit v1.7.1