zc пре 2 месеци
родитељ
комит
791ee5f9a4

+ 121 - 1
alien-store-platform/src/main/java/shop/alien/storeplatform/aspect/PlatformOperationLogAspect.java

@@ -48,7 +48,10 @@ import java.util.List;
 import java.util.stream.Collectors;
 
 /**
- * 平台操作记录切面
+ * 平台操作记录切面。
+ * <p>
+ * 通过 {@link PlatformOperationLog} 注解拦截业务方法,记录操作内容、入参、操作者与请求信息。
+ * </p>
  *
  * @author system
  * @since 2025-01-XX
@@ -70,15 +73,26 @@ public class PlatformOperationLogAspect {
     private final DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
     private final TemplateParserContext templateParserContext = new TemplateParserContext("#{", "}");
 
+    /**
+     * 操作记录切点:拦截带 {@link PlatformOperationLog} 注解的方法。
+     */
     @Pointcut("@annotation(shop.alien.storeplatform.annotation.PlatformOperationLog)")
     public void operationLogPointcut() {
     }
 
+    /**
+     * 环绕通知:先执行业务逻辑,再生成并保存操作日志。
+     *
+     * @param joinPoint 连接点
+     * @return 业务方法返回值
+     * @throws Throwable 业务方法执行异常
+     */
     @Around("operationLogPointcut()")
     public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         Method method = signature.getMethod();
         PlatformOperationLog annotation = method.getAnnotation(PlatformOperationLog.class);
+        // 变更前快照:用于“修改子账号”差异日志
         SubAccountSnapshot beforeSnapshot = buildSubAccountSnapshot(annotation, joinPoint.getArgs());
 
         Object result;
@@ -100,6 +114,15 @@ public class PlatformOperationLogAspect {
         return result;
     }
 
+    /**
+     * 判断是否需要记录操作日志。
+     * <p>
+     * 返回值为 {@link R} 时,只有成功结果才记录。
+     * </p>
+     *
+     * @param result 业务方法返回值
+     * @return 是否记录日志
+     */
     private boolean shouldRecord(Object result) {
         if (result instanceof R) {
             return R.isSuccess((R<?>) result);
@@ -107,6 +130,15 @@ public class PlatformOperationLogAspect {
         return true;
     }
 
+    /**
+     * 构建操作日志实体。
+     *
+     * @param joinPoint     连接点
+     * @param annotation    注解信息
+     * @param result        业务方法返回值
+     * @param beforeSnapshot 子账号变更前快照
+     * @return 操作日志实体
+     */
     private StorePlatformOperationLog buildLogRecord(ProceedingJoinPoint joinPoint, PlatformOperationLog annotation, Object result,
                                                      SubAccountSnapshot beforeSnapshot) {
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
@@ -114,6 +146,7 @@ public class PlatformOperationLogAspect {
         Object[] args = joinPoint.getArgs();
         String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
 
+        // SpEL 上下文:支持 #p0/#arg0/参数名/返回值
         EvaluationContext context = new StandardEvaluationContext();
         if (args != null) {
             for (int i = 0; i < args.length; i++) {
@@ -140,6 +173,11 @@ public class PlatformOperationLogAspect {
         return logRecord;
     }
 
+    /**
+     * 填充操作者信息。
+     *
+     * @param logRecord 操作日志实体
+     */
     private void fillOperatorInfo(StorePlatformOperationLog logRecord) {
         try {
             JSONObject userInfo = LoginUserUtil.getCurrentUserInfo();
@@ -167,6 +205,11 @@ public class PlatformOperationLogAspect {
         }
     }
 
+    /**
+     * 填充请求信息。
+     *
+     * @param logRecord 操作日志实体
+     */
     private void fillRequestInfo(StorePlatformOperationLog logRecord) {
         try {
             ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
@@ -174,6 +217,7 @@ public class PlatformOperationLogAspect {
                 return;
             }
             HttpServletRequest request = attributes.getRequest();
+            // 记录请求方法/路径/IP
             logRecord.setRequestMethod(request.getMethod());
             logRecord.setRequestPath(request.getRequestURI());
             logRecord.setIpAddress(getIpAddress(request));
@@ -182,6 +226,12 @@ public class PlatformOperationLogAspect {
         }
     }
 
+    /**
+     * 获取请求 IP 地址,优先从代理头读取。
+     *
+     * @param request HttpServletRequest
+     * @return IP 地址
+     */
     private String getIpAddress(HttpServletRequest request) {
         String ip = request.getHeader("X-Forwarded-For");
         if (!StringUtils.hasText(ip) || "unknown".equalsIgnoreCase(ip)) {
@@ -202,8 +252,21 @@ public class PlatformOperationLogAspect {
         return ip;
     }
 
+    /**
+     * 解析日志内容。
+     * <p>
+     * 优先处理账号相关自定义内容,其次为角色统一模板,最后回退到注解 SpEL。
+     * </p>
+     *
+     * @param annotation    注解信息
+     * @param context       SpEL 上下文
+     * @param args          方法参数
+     * @param beforeSnapshot 子账号变更前快照
+     * @return 日志内容
+     */
     private String resolveContent(PlatformOperationLog annotation, EvaluationContext context, Object[] args,
                                   SubAccountSnapshot beforeSnapshot) {
+        // 先处理自定义的账号相关日志模板
         if ("账号操作记录".equals(annotation.module()) && annotation.type().contains("移除角色")) {
             String content = buildAccountRoleRemoveContent(args);
             if (StringUtils.hasText(content)) {
@@ -222,6 +285,7 @@ public class PlatformOperationLogAspect {
                 return content;
             }
         }
+        // 角色相关日志的统一格式
         if ("角色操作记录".equals(annotation.module())) {
             return buildRoleOperationContent(annotation.type(), args);
         }
@@ -234,6 +298,13 @@ public class PlatformOperationLogAspect {
         return annotation.type();
     }
 
+    /**
+     * 构建子账号变更前快照,仅用于“修改子账号”日志差异对比。
+     *
+     * @param annotation 注解信息
+     * @param args       方法参数
+     * @return 变更前快照
+     */
     private SubAccountSnapshot buildSubAccountSnapshot(PlatformOperationLog annotation, Object[] args) {
         if (annotation == null || args == null || args.length == 0) {
             return null;
@@ -272,6 +343,13 @@ public class PlatformOperationLogAspect {
         return new SubAccountSnapshot(phone, accountName, roleId);
     }
 
+    /**
+     * 构建“修改子账号”日志内容,仅记录变更字段。
+     *
+     * @param args           方法参数
+     * @param beforeSnapshot 变更前快照
+     * @return 日志内容
+     */
     private String buildUpdateSubAccountContent(Object[] args, SubAccountSnapshot beforeSnapshot) {
         if (beforeSnapshot == null || args == null || args.length == 0) {
             return null;
@@ -300,6 +378,12 @@ public class PlatformOperationLogAspect {
         return "修改子账号," + changed;
     }
 
+    /**
+     * 构建“新增子账号”日志内容。
+     *
+     * @param args 方法参数
+     * @return 日志内容
+     */
     private String buildCreateSubAccountContent(Object[] args) {
         if (args == null || args.length == 0) {
             return null;
@@ -323,6 +407,14 @@ public class PlatformOperationLogAspect {
         return content.toString();
     }
 
+    /**
+     * 追加字段变更描述。
+     *
+     * @param builder  内容构建器
+     * @param label    字段中文名
+     * @param oldValue 旧值
+     * @param newValue 新值
+     */
     private void appendChange(StringBuilder builder, String label, String oldValue, String newValue) {
         if (builder.length() > 0) {
             builder.append(";");
@@ -334,6 +426,9 @@ public class PlatformOperationLogAspect {
                 .append(StringUtils.hasText(newValue) ? newValue : "空");
     }
 
+    /**
+     * 子账号变更前快照。
+     */
     private static class SubAccountSnapshot {
         private final String phone;
         private final String accountName;
@@ -346,6 +441,12 @@ public class PlatformOperationLogAspect {
         }
     }
 
+    /**
+     * 构建“移除角色”日志内容。
+     *
+     * @param args 方法参数
+     * @return 日志内容
+     */
     private String buildAccountRoleRemoveContent(Object[] args) {
         if (args == null || args.length < 2) {
             return null;
@@ -367,6 +468,12 @@ public class PlatformOperationLogAspect {
         return String.format("移除用户%s的%s角色", accountName, roleName);
     }
 
+    /**
+     * 解析账号名称,允许读取已删除用户。
+     *
+     * @param userId 用户ID
+     * @return 账号名称
+     */
     private String resolveAccountName(Integer userId) {
         StoreUser storeUser = storeUserMapper.getUserIncludeDeleted(userId);
         if (storeUser == null) {
@@ -382,6 +489,12 @@ public class PlatformOperationLogAspect {
         return StringUtils.hasText(name) ? name : "未知";
     }
 
+    /**
+     * 解析角色名称。
+     *
+     * @param roleId 角色ID
+     * @return 角色名称
+     */
     private String resolveRoleName(Long roleId) {
         String roleName = storePlatformRoleQueryService.getRoleNameById(roleId);
         if (!StringUtils.hasText(roleName)) {
@@ -390,6 +503,13 @@ public class PlatformOperationLogAspect {
         return roleName;
     }
 
+    /**
+     * 构建操作入参 JSON 字符串。
+     *
+     * @param parameterNames 参数名列表
+     * @param args           参数值列表
+     * @return JSON 字符串
+     */
     private String buildParamsJson(String[] parameterNames, Object[] args) {
         try {
             if (args == null || args.length == 0) {