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