完成操作记录的大部分功能开发。
This commit is contained in:
parent
40ce933356
commit
961bfb2baa
|
|
@ -1,11 +1,13 @@
|
||||||
package com.electromagnetic.industry.software.manage.aop;
|
package com.electromagnetic.industry.software.manage.aop;
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
|
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.catalina.connector.ResponseFacade;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
|
|
@ -13,8 +15,8 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
@Component
|
||||||
|
|
@ -29,30 +31,34 @@ public class ServiceAspect {
|
||||||
String methodInfo = jp.getTarget().getClass().getSimpleName() + "."
|
String methodInfo = jp.getTarget().getClass().getSimpleName() + "."
|
||||||
+ jp.getSignature().getName();
|
+ jp.getSignature().getName();
|
||||||
Object[] args = jp.getArgs();
|
Object[] args = jp.getArgs();
|
||||||
|
String[] argNames = ((MethodSignature)jp.getSignature()).getParameterNames();
|
||||||
String paramInfo = "";
|
String paramInfo = "";
|
||||||
if (args != null && args.length > 0) {
|
if (args != null && args.length > 0) {
|
||||||
if (args[0] != null && args[0].getClass() != ResponseFacade.class) {
|
Map<String, Object> map = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
List<Object> list = new ArrayList<>();
|
for (int i = 0; i < args.length; i++) {
|
||||||
for (Object obj : jp.getArgs()) {
|
String name = argNames[i];
|
||||||
|
Object value = args[i];
|
||||||
if (obj instanceof ServletResponse) {
|
if (value instanceof ServletRequest) {
|
||||||
log.info("参数中有response");
|
|
||||||
} else if (obj instanceof ServletRequest) {
|
|
||||||
log.info("参数中有request");
|
log.info("参数中有request");
|
||||||
} else if (obj instanceof MultipartFile) {
|
map.put(name, "request");
|
||||||
//文件不输出
|
} else if (value instanceof ServletResponse) {
|
||||||
MultipartFile obj1 = (MultipartFile) obj;
|
log.info("参数中有response");
|
||||||
log.info("参数中文件;文件名:{},文件大小:{}", obj1.getName(), obj1.getSize());
|
map.put(name, "response");
|
||||||
break;
|
} else if (value instanceof MultipartFile) {
|
||||||
|
MultipartFile file = (MultipartFile) value;
|
||||||
|
Map<String, Object> pars = new HashMap<>();
|
||||||
|
pars.put("fileName", file.getOriginalFilename());
|
||||||
|
pars.put("fileSize", file.getSize());
|
||||||
|
map.put("file", pars);
|
||||||
} else {
|
} else {
|
||||||
list.add(obj);
|
map.put(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
paramInfo = JSONUtil.toJsonStr(list);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("切面异常--->{}", e.getMessage());
|
log.warn("切面异常--->{}", e.getMessage(), e);
|
||||||
}
|
} finally {
|
||||||
|
paramInfo = JSONUtil.toJsonStr(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("请求接口开始:{},参数:{}", methodInfo, paramInfo);
|
log.info("请求接口开始:{},参数:{}", methodInfo, paramInfo);
|
||||||
|
|
@ -63,6 +69,8 @@ public class ServiceAspect {
|
||||||
if (rvt instanceof ResponseEntity) {
|
if (rvt instanceof ResponseEntity) {
|
||||||
return rvt;
|
return rvt;
|
||||||
}
|
}
|
||||||
|
UserThreadLocal.setRes((ElectromagneticResult)rvt);
|
||||||
|
UserThreadLocal.setReqArgs(paramInfo);
|
||||||
String returnInfo = JSONUtil.toJsonStr(rvt);
|
String returnInfo = JSONUtil.toJsonStr(rvt);
|
||||||
log.info("请求接口结束:{},返回参数:{},接口耗时:{}", methodInfo, returnInfo, (System.currentTimeMillis() - startTime) + "毫秒");
|
log.info("请求接口结束:{},返回参数:{},接口耗时:{}", methodInfo, returnInfo, (System.currentTimeMillis() - startTime) + "毫秒");
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,24 @@
|
||||||
package com.electromagnetic.industry.software.manage.config;
|
package com.electromagnetic.industry.software.manage.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.date.SystemClock;
|
import cn.hutool.core.date.SystemClock;
|
||||||
|
import com.electromagnetic.industry.software.common.annotations.UserOperation;
|
||||||
import com.electromagnetic.industry.software.common.cons.UserConstants;
|
import com.electromagnetic.industry.software.common.cons.UserConstants;
|
||||||
import com.electromagnetic.industry.software.common.enums.AdminTypeEnum;
|
import com.electromagnetic.industry.software.common.enums.AdminTypeEnum;
|
||||||
import com.electromagnetic.industry.software.common.pojo.UserLoginInfo;
|
import com.electromagnetic.industry.software.common.pojo.UserLoginInfo;
|
||||||
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
|
import com.electromagnetic.industry.software.common.util.IdWorker;
|
||||||
import com.electromagnetic.industry.software.common.util.TokenUtil;
|
import com.electromagnetic.industry.software.common.util.TokenUtil;
|
||||||
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
|
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
|
||||||
import com.electromagnetic.industry.software.manage.mapper.TokenMapper;
|
import com.electromagnetic.industry.software.manage.mapper.TokenMapper;
|
||||||
|
import com.electromagnetic.industry.software.manage.mapper.UserAccessLogMapper;
|
||||||
|
import com.electromagnetic.industry.software.manage.mapper.UserMapper;
|
||||||
import com.electromagnetic.industry.software.manage.pojo.models.Token;
|
import com.electromagnetic.industry.software.manage.pojo.models.Token;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.models.UserAccessLog;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
|
@ -26,8 +34,12 @@ public class LoginInterceptor implements HandlerInterceptor {
|
||||||
@Resource
|
@Resource
|
||||||
private TokenMapper tokenMapper;
|
private TokenMapper tokenMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserAccessLogMapper userAccessLogMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
request.getSession().setAttribute("accessStartTime", System.currentTimeMillis());
|
||||||
// 首先校验token
|
// 首先校验token
|
||||||
boolean isTokenValid = checkToken(request, response);
|
boolean isTokenValid = checkToken(request, response);
|
||||||
if (!isTokenValid) {
|
if (!isTokenValid) {
|
||||||
|
|
@ -86,6 +98,31 @@ public class LoginInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
|
|
||||||
|
long accessStartTime = (long)request.getSession().getAttribute("accessStartTime");
|
||||||
|
ElectromagneticResult<?> result = UserThreadLocal.getResult();
|
||||||
|
String reqArgs = UserThreadLocal.getReqArgs();
|
||||||
|
long accessEndTime = System.currentTimeMillis();
|
||||||
|
UserOperation userOperation = ((HandlerMethod) handler).getMethod().getAnnotation(UserOperation.class);
|
||||||
|
UserAccessLog userAccessLog = UserAccessLog.builder()
|
||||||
|
.id(IdWorker.getSnowFlakeIdString())
|
||||||
|
.userId(UserThreadLocal.getUserId())
|
||||||
|
.accessStartTime(DateUtil.date(accessStartTime))
|
||||||
|
.accessEndTime(DateUtil.date(accessEndTime))
|
||||||
|
.accessDuration(accessEndTime - accessStartTime)
|
||||||
|
.action(userOperation.value())
|
||||||
|
.requestUrl(request.getRequestURL().toString())
|
||||||
|
.reqArgs(reqArgs)
|
||||||
|
.remoteAddr(request.getRemoteAddr())
|
||||||
|
.accessSuccess(true)
|
||||||
|
.createTime(new Date())
|
||||||
|
.build();
|
||||||
|
if (!result.getSuccess()) {
|
||||||
|
userAccessLog.setAccessSuccess(false);
|
||||||
|
userAccessLog.setFailureReason(result.getErrorMessage());
|
||||||
|
}
|
||||||
|
// TODO 如果是下载的文件,那么返回的是ResponseEntity而不是ElectromagneticResult
|
||||||
|
userAccessLogMapper.insert(userAccessLog);
|
||||||
UserThreadLocal.remove();
|
UserThreadLocal.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.electromagnetic.industry.software.manage.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.electromagnetic.industry.software.manage.pojo.models.UserAccessLog;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserAccessLogMapper extends BaseMapper<UserAccessLog> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.electromagnetic.industry.software.manage.pojo.models;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@TableName("user_access_log")
|
||||||
|
public class UserAccessLog {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
private Date accessStartTime;
|
||||||
|
|
||||||
|
private Date accessEndTime;
|
||||||
|
|
||||||
|
private Long accessDuration;
|
||||||
|
|
||||||
|
private String action;
|
||||||
|
|
||||||
|
private String requestUrl;
|
||||||
|
|
||||||
|
private String reqArgs;
|
||||||
|
|
||||||
|
private String remoteAddr;
|
||||||
|
|
||||||
|
private Boolean accessSuccess;
|
||||||
|
|
||||||
|
private String failureReason;
|
||||||
|
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.electromagnetic.industry.software.common.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
|
public @interface UserOperation {
|
||||||
|
|
||||||
|
String value() default "";
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.electromagnetic.industry.software.common.pojo;
|
package com.electromagnetic.industry.software.common.pojo;
|
||||||
|
|
||||||
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -34,4 +35,14 @@ public class UserLoginInfo {
|
||||||
* 管理员类型
|
* 管理员类型
|
||||||
*/
|
*/
|
||||||
private String adminType;
|
private String adminType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回值
|
||||||
|
*/
|
||||||
|
private ElectromagneticResult result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问请求的参数
|
||||||
|
*/
|
||||||
|
private String reqArgs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@ package com.electromagnetic.industry.software.common.util;
|
||||||
|
|
||||||
|
|
||||||
import com.electromagnetic.industry.software.common.pojo.UserLoginInfo;
|
import com.electromagnetic.industry.software.common.pojo.UserLoginInfo;
|
||||||
|
import com.electromagnetic.industry.software.common.resp.ElectromagneticResult;
|
||||||
|
|
||||||
public class UserThreadLocal {
|
public class UserThreadLocal {
|
||||||
/**
|
/**
|
||||||
* 存储用户信息
|
* 存储用户信息
|
||||||
*/
|
*/
|
||||||
private static ThreadLocal<UserLoginInfo> userThread = new ThreadLocal<>();
|
private static final ThreadLocal<UserLoginInfo> userThread = new ThreadLocal<>();
|
||||||
|
|
||||||
public static void set(UserLoginInfo userLoginInfo) {
|
public static void set(UserLoginInfo userLoginInfo) {
|
||||||
userThread.set(userLoginInfo);
|
userThread.set(userLoginInfo);
|
||||||
|
|
@ -32,4 +33,21 @@ public class UserThreadLocal {
|
||||||
public static void remove() {
|
public static void remove() {
|
||||||
userThread.remove();
|
userThread.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setRes(ElectromagneticResult result) {
|
||||||
|
userThread.get().setResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ElectromagneticResult getResult() {
|
||||||
|
return userThread.get().getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setReqArgs(String args) {
|
||||||
|
userThread.get().setReqArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getReqArgs() {
|
||||||
|
return userThread.get().getReqArgs();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue