package com.attendance.aspect; import com.alibaba.fastjson2.JSON; import com.attendance.annotation.OperationLog; import com.attendance.common.UserContext; import com.attendance.entity.SysOperationLog; import com.attendance.service.SysOperationLogService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Objects; @Slf4j @Aspect @Component @RequiredArgsConstructor public class OperationLogAspect { private final SysOperationLogService sysOperationLogService; @Around("@annotation(operationLog)") public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable { long startTime = System.currentTimeMillis(); SysOperationLog logEntity = new SysOperationLog(); logEntity.setUserId(UserContext.getUserId()); logEntity.setUsername(UserContext.getUsername()); logEntity.setModule(operationLog.module()); logEntity.setAction(operationLog.action()); // 填充请求相关字段 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); logEntity.setMethod(request.getMethod()); logEntity.setRequestUrl(request.getRequestURI()); logEntity.setIpAddress(getClientIp(request)); logEntity.setUserAgent(request.getHeader("User-Agent")); // 记录请求参数(排除文件上传等二进制参数) Object[] args = joinPoint.getArgs(); try { logEntity.setRequestParams(JSON.toJSONString(args)); } catch (Exception e) { logEntity.setRequestParams("[无法序列化的参数]"); } } Object result; try { result = joinPoint.proceed(); logEntity.setStatus(1); try { logEntity.setResponseData(JSON.toJSONString(result)); } catch (Exception e) { logEntity.setResponseData("[无法序列化的响应]"); } } catch (Throwable e) { logEntity.setStatus(0); logEntity.setErrorMsg(e.getMessage()); throw e; } finally { logEntity.setDuration((int) (System.currentTimeMillis() - startTime)); try { sysOperationLogService.asyncSave(logEntity); } catch (Exception e) { log.error("保存操作日志失败", e); } } return result; } /** 获取客户端真实IP */ private String getClientIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } // 多级代理取第一个IP if (ip != null && ip.contains(",")) { ip = ip.split(",")[0].trim(); } return ip; } }