You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.8 KiB
Java

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;
}
}