diff --git a/sql/mysql/youlai_admin.sql b/sql/mysql/youlai_admin.sql index af2e99a1..2bf42096 100644 --- a/sql/mysql/youlai_admin.sql +++ b/sql/mysql/youlai_admin.sql @@ -411,7 +411,7 @@ CREATE TABLE `sys_log` ( `action_type` TINYINT NOT NULL COMMENT '操作类型,数字枚举,参考 ActionType 枚举', `title` VARCHAR(100) NOT NULL COMMENT '前端显示标题', `content` TEXT COMMENT '自定义日志内容', - `operator_id` BIGINT NOT NULL COMMENT '操作人ID', + `operator_id` BIGINT COMMENT '操作人ID', `operator_name` VARCHAR(50) COMMENT '操作人名称', `request_uri` VARCHAR(255) COMMENT '请求路径', `request_method` VARCHAR(10) COMMENT '请求方法', diff --git a/sql/mysql/youlai_admin_template.sql b/sql/mysql/youlai_admin_template.sql index 9ed4db22..48db9455 100644 --- a/sql/mysql/youlai_admin_template.sql +++ b/sql/mysql/youlai_admin_template.sql @@ -371,7 +371,7 @@ CREATE TABLE `sys_log` ( `action_type` TINYINT NOT NULL COMMENT '操作类型,数字枚举,参考 ActionType 枚举', `title` VARCHAR(100) NOT NULL COMMENT '前端显示标题', `content` TEXT COMMENT '自定义日志内容', - `operator_id` BIGINT NOT NULL COMMENT '操作人ID', + `operator_id` BIGINT COMMENT '操作人ID', `operator_name` VARCHAR(50) COMMENT '操作人名称', `request_uri` VARCHAR(255) COMMENT '请求路径', `request_method` VARCHAR(10) COMMENT '请求方法', diff --git a/src/main/java/com/youlai/boot/common/aspect/LogAspect.java b/src/main/java/com/youlai/boot/common/aspect/LogAspect.java index c22552ea..145341c9 100644 --- a/src/main/java/com/youlai/boot/common/aspect/LogAspect.java +++ b/src/main/java/com/youlai/boot/common/aspect/LogAspect.java @@ -52,6 +52,9 @@ public class LogAspect { public Object around(ProceedingJoinPoint pjp, Log logAnnotation) throws Throwable { long startTime = System.currentTimeMillis(); + // 在方法执行前获取用户信息,避免 logout 等操作清除 SecurityContext 后无法获取 + Long userId = SecurityUtils.getUserId(); + String username = SecurityUtils.getUsername(); Object result = null; Exception exception = null; @@ -63,7 +66,16 @@ public class LogAspect { throw e; } finally { long executionTime = System.currentTimeMillis() - startTime; - saveLogAsync(logAnnotation, executionTime, exception); + // fallback:登录等场景在 proceed() 前未认证,需在 proceed() 后获取 + if (userId == null) { + userId = SecurityUtils.getUserId(); + username = SecurityUtils.getUsername(); + } + try { + saveLogAsync(logAnnotation, executionTime, exception, userId, username); + } catch (Exception ex) { + log.error("保存操作日志失败", ex); + } } } @@ -71,7 +83,7 @@ public class LogAspect { * 异步保存日志 */ @Async - public void saveLogAsync(Log logAnnotation, long executionTime, Exception exception) { + public void saveLogAsync(Log logAnnotation, long executionTime, Exception exception, Long userId, String username) { try { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { @@ -97,10 +109,6 @@ public class LogAspect { } } - // 获取当前用户信息 - Long userId = SecurityUtils.getUserId(); - String username = SecurityUtils.getUsername(); - // 构建日志实体 LogModuleEnum module = logAnnotation.module(); ActionTypeEnum actionType = logAnnotation.value(); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 94128c64..a8ddba0c 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -84,7 +84,7 @@ security: - /api/v1/auth/captcha # 验证码获取接口 - /api/v1/auth/sms/code # 发送登录短信验证码 - /api/v1/auth/refresh-token # 刷新令牌接口 - - /api/v1/wechat/miniapp/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) + - /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - /api/v1/logs/** # 日志接口(访问日志列表) # 非安全端点路径,完全绕过 Spring Security 的过滤器 unsecured-urls: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index a9ebf76a..d3d3fa06 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -81,8 +81,9 @@ security: ignore-urls: - /api/v1/auth/login/** # 登录接口(账号密码登录、手机验证码登录和微信登录) - /api/v1/auth/captcha # 验证码获取接口 + - /api/v1/auth/sms/code # 发送登录短信验证码 - /api/v1/auth/refresh-token # 刷新令牌接口 - - /api/v1/wechat/miniapp/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) + - /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - /api/v1/logs/** # 日志接口(访问日志列表) # 非安全端点路径,完全绕过 Spring Security 的过滤器 unsecured-urls: