refactor: 日志完善
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package com.youlai.system.controller;
|
||||
|
||||
import com.youlai.system.enums.LogTypeEnum;
|
||||
import com.youlai.system.enums.LogModuleEnum;
|
||||
import com.youlai.system.common.result.Result;
|
||||
import com.youlai.system.model.dto.CaptchaResult;
|
||||
import com.youlai.system.model.dto.LoginResult;
|
||||
@@ -30,7 +30,7 @@ public class AuthController {
|
||||
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
@LogAnnotation(value = "登录", logType = LogTypeEnum.LOGIN)
|
||||
@LogAnnotation(value = "登录", module = LogModuleEnum.LOGIN)
|
||||
public Result<LoginResult> login(
|
||||
@Parameter(description = "用户名", example = "admin") @RequestParam String username,
|
||||
@Parameter(description = "密码", example = "123456") @RequestParam String password
|
||||
@@ -41,7 +41,7 @@ public class AuthController {
|
||||
|
||||
@Operation(summary = "注销")
|
||||
@DeleteMapping("/logout")
|
||||
@LogAnnotation(value = "注销", logType = LogTypeEnum.LOGIN)
|
||||
@LogAnnotation(value = "注销", module = LogModuleEnum.LOGIN)
|
||||
public Result logout() {
|
||||
authService.logout();
|
||||
return Result.success();
|
||||
|
||||
51
src/main/java/com/youlai/system/enums/LogModuleEnum.java
Normal file
51
src/main/java/com/youlai/system/enums/LogModuleEnum.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.youlai.system.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 日志模块枚举
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2.10.0
|
||||
*/
|
||||
@Schema(enumAsRef = true)
|
||||
@Getter
|
||||
public enum LogModuleEnum {
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
LOGIN("登录"),
|
||||
/**
|
||||
* 用户模块
|
||||
*/
|
||||
USER("用户模块"),
|
||||
/**
|
||||
* 部门模块
|
||||
*/
|
||||
DEPT("部门模块"),
|
||||
/**
|
||||
* 角色模块
|
||||
*/
|
||||
ROLE("角色模块"),
|
||||
/**
|
||||
* 菜单模块
|
||||
*/
|
||||
MENU("菜单模块"),
|
||||
/**
|
||||
* 字典模块
|
||||
*/
|
||||
DICT("字典模块"),
|
||||
|
||||
OTHER("其他")
|
||||
;
|
||||
|
||||
@JsonValue
|
||||
private final String moduleName;
|
||||
|
||||
LogModuleEnum(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.youlai.system.enums;
|
||||
|
||||
import com.youlai.system.common.base.IBaseEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 日志类型枚举
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2.10.0
|
||||
*/
|
||||
@Schema(enumAsRef = true)
|
||||
@Getter
|
||||
public enum LogTypeEnum implements IBaseEnum<Integer> {
|
||||
|
||||
OPERATION(1, "操作日志"),
|
||||
LOGIN (2, "登录日志");
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private final String label;
|
||||
|
||||
LogTypeEnum(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import lombok.Getter;
|
||||
* @author haoxr
|
||||
* @since 2022/4/23 9:36
|
||||
*/
|
||||
|
||||
@Getter
|
||||
public enum MenuTypeEnum implements IBaseEnum<Integer> {
|
||||
|
||||
NULL(0, null),
|
||||
@@ -19,13 +19,12 @@ public enum MenuTypeEnum implements IBaseEnum<Integer> {
|
||||
EXTLINK(3, "外链"),
|
||||
BUTTON(4, "按钮");
|
||||
|
||||
@Getter
|
||||
@EnumValue // Mybatis-Plus 提供注解表示插入数据库时插入该值
|
||||
private Integer value;
|
||||
// Mybatis-Plus 提供注解表示插入数据库时插入该值
|
||||
@EnumValue
|
||||
private final Integer value;
|
||||
|
||||
@Getter
|
||||
// @JsonValue // 表示对枚举序列化时返回此字段
|
||||
private String label;
|
||||
private final String label;
|
||||
|
||||
MenuTypeEnum(Integer value, String label) {
|
||||
this.value = value;
|
||||
|
||||
@@ -2,11 +2,10 @@ package com.youlai.system.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.youlai.system.common.base.BaseEntity;
|
||||
import com.youlai.system.enums.LogModuleEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -24,33 +23,52 @@ public class SysLog implements Serializable {
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*
|
||||
* @see com.youlai.system.enums.LogTypeEnum
|
||||
* 日志模块
|
||||
*/
|
||||
private Integer type;
|
||||
private LogModuleEnum module;
|
||||
|
||||
|
||||
/**
|
||||
* 日志标题
|
||||
* 日志内容
|
||||
*/
|
||||
private String title;
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
private String requestUri;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* IP 地址
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 地区
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* 浏览器
|
||||
*/
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 终端系统
|
||||
*/
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* 执行时间(毫秒)
|
||||
*/
|
||||
private Long executionTime;
|
||||
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@@ -60,5 +78,7 @@ public class SysLog implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.youlai.system.plugin.syslog.annotation;
|
||||
|
||||
import com.youlai.system.enums.LogTypeEnum;
|
||||
import com.youlai.system.enums.LogModuleEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@@ -17,7 +17,7 @@ public @interface LogAnnotation {
|
||||
|
||||
String value() default "";
|
||||
|
||||
LogTypeEnum logType() default LogTypeEnum.OPERATION;
|
||||
LogModuleEnum module() ;
|
||||
|
||||
|
||||
}
|
||||
@@ -2,6 +2,12 @@ package com.youlai.system.plugin.syslog.aspect;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.useragent.Browser;
|
||||
import cn.hutool.http.useragent.OS;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import com.youlai.system.common.constant.SecurityConstants;
|
||||
import com.youlai.system.common.util.IPUtils;
|
||||
import com.youlai.system.model.entity.SysLog;
|
||||
import com.youlai.system.plugin.syslog.annotation.LogAnnotation;
|
||||
@@ -9,6 +15,7 @@ import com.youlai.system.security.util.SecurityUtils;
|
||||
import com.youlai.system.service.SysLogService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
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;
|
||||
@@ -24,6 +31,7 @@ import org.springframework.stereotype.Component;
|
||||
@Aspect
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class LogAspect {
|
||||
|
||||
private final SysLogService logService;
|
||||
@@ -35,19 +43,46 @@ public class LogAspect {
|
||||
|
||||
@Around("logPointcut() && @annotation(logAnnotation)")
|
||||
public Object logExecutionTime(ProceedingJoinPoint joinPoint, LogAnnotation logAnnotation) throws Throwable {
|
||||
String requestURI = request.getRequestURI();
|
||||
|
||||
Long userId = null;
|
||||
// 非登录请求获取用户ID,登录请求在登录成功后(joinPoint.proceed())获取用户ID
|
||||
if (!SecurityConstants.LOGIN_PATH.equals(requestURI)) {
|
||||
userId = SecurityUtils.getUserId();
|
||||
}
|
||||
|
||||
TimeInterval timer = DateUtil.timer();
|
||||
Object proceed = joinPoint.proceed();
|
||||
long executionTime =timer.interval();
|
||||
long executionTime = timer.interval();
|
||||
|
||||
// 创建日志对象
|
||||
SysLog log = new SysLog();
|
||||
log.setType(logAnnotation.logType().getValue());
|
||||
log.setTitle(logAnnotation.value());
|
||||
log.setRequestUri(request.getRequestURI());
|
||||
log.setIp(IPUtils.getIpAddr(request));
|
||||
log.setExecutionTime(executionTime);
|
||||
log.setCreateBy(SecurityUtils.getUserId());
|
||||
|
||||
log.setModule(logAnnotation.module());
|
||||
log.setContent(logAnnotation.value());
|
||||
log.setRequestUri(requestURI);
|
||||
// 登录方法需要在登录成功后获取用户ID
|
||||
if (userId == null) {
|
||||
userId = SecurityUtils.getUserId();
|
||||
}
|
||||
log.setCreateBy(userId);
|
||||
String ipAddr = IPUtils.getIpAddr(request);
|
||||
if (StrUtil.isNotBlank(ipAddr)) {
|
||||
log.setIp(ipAddr);
|
||||
String region = IPUtils.getRegion(ipAddr);
|
||||
log.setRegion(region);
|
||||
}
|
||||
log.setExecutionTime(executionTime);
|
||||
// 方法名
|
||||
log.setMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
|
||||
// 获取浏览器和终端系统信息
|
||||
String userAgentString = request.getHeader("User-Agent");
|
||||
UserAgent userAgent = UserAgentUtil.parse(userAgentString);
|
||||
// 系统信息
|
||||
log.setOs(userAgent.getOs().getName());
|
||||
// 浏览器信息
|
||||
String browserInfo = userAgent.getBrowser().getName() + " " + userAgent.getBrowser().getVersion(userAgentString);
|
||||
log.setBrowser(browserInfo);
|
||||
// 保存日志到数据库
|
||||
logService.save(log);
|
||||
|
||||
@@ -55,8 +90,4 @@ public class LogAspect {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -57,13 +57,16 @@ public class AuthServiceImpl implements AuthService {
|
||||
*/
|
||||
@Override
|
||||
public LoginResult login(String username, String password) {
|
||||
// 认证用户信息
|
||||
// 创建认证令牌对象
|
||||
UsernamePasswordAuthenticationToken authenticationToken =
|
||||
new UsernamePasswordAuthenticationToken(username.toLowerCase().trim(), password);
|
||||
// 认证
|
||||
// 执行用户认证
|
||||
Authentication authentication = authenticationManager.authenticate(authenticationToken);
|
||||
// 认证成功,生成Token
|
||||
// 认证成功后生成JWT令牌
|
||||
String accessToken = JwtUtils.createToken(authentication);
|
||||
// 将认证信息存入Security上下文,便于在AOP(如日志记录)中获取当前用户信息
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
// 返回包含JWT令牌的登录结果
|
||||
return LoginResult.builder()
|
||||
.tokenType("Bearer")
|
||||
.accessToken(accessToken)
|
||||
|
||||
Reference in New Issue
Block a user