疯狂的狮子li
2022-12-07 4c8137daf2f9c49dd1bf0d3f24372929016358f9
update 优化 使用spring事件发布机制 重构登录日志与操作日志
已添加1个文件
已修改6个文件
已重命名1个文件
已删除2个文件
179 ■■■■■ 文件已修改
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/LogininforEvent.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/OperLogEvent.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/LogininforEvent.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.common.core.domain.event;
import lombok.Data;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
/**
 * ç™»å½•事件
 *
 * @author Lion Li
 */
@Data
public class LogininforEvent implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ç”¨æˆ·è´¦å·
     */
    private String username;
    /**
     * ç™»å½•状态 0成功 1失败
     */
    private String status;
    /**
     * æç¤ºæ¶ˆæ¯
     */
    private String message;
    /**
     * è¯·æ±‚体
     */
    private HttpServletRequest request;
    /**
     * å…¶ä»–参数
     */
    private Object[] args;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/OperLogEvent.java
ÎļþÃû´Ó ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/OperLogDTO.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package com.ruoyi.common.core.domain.dto;
package com.ruoyi.common.core.domain.event;
import lombok.Data;
@@ -6,13 +6,13 @@
import java.util.Date;
/**
 * é€šç”¨æ“ä½œæ—¥å¿—实体
 * æ“ä½œæ—¥å¿—事件
 *
 * @author Lion Li
 */
@Data
public class OperLogDTO implements Serializable {
public class OperLogEvent implements Serializable {
    private static final long serialVersionUID = 1L;
ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java
ÎļþÒÑɾ³ý
ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java
ÎļþÒÑɾ³ý
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
@@ -4,8 +4,7 @@
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.dto.OperLogDTO;
import com.ruoyi.common.core.service.OperLogService;
import com.ruoyi.common.core.domain.event.OperLogEvent;
import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.helper.LoginHelper;
@@ -67,7 +66,7 @@
        try {
            // *========数据库日志=========*//
            OperLogDTO operLog = new OperLogDTO();
            OperLogEvent operLog = new OperLogEvent();
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
            // è¯·æ±‚的地址
            String ip = ServletUtils.getClientIP();
@@ -87,8 +86,8 @@
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // å¤„理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
            // ä¿å­˜æ•°æ®åº“
            SpringUtils.getBean(OperLogService.class).recordOper(operLog);
            // å‘布事件保存数据库
            SpringUtils.context().publishEvent(operLog);
        } catch (Exception exp) {
            // è®°å½•本地异常日志
            log.error("异常信息:{}", exp.getMessage());
@@ -103,7 +102,7 @@
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception
     */
    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogDTO operLog, Object jsonResult) throws Exception {
    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception {
        // è®¾ç½®action动作
        operLog.setBusinessType(log.businessType().ordinal());
        // è®¾ç½®æ ‡é¢˜
@@ -127,7 +126,7 @@
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception å¼‚常
     */
    private void setRequestValue(JoinPoint joinPoint, OperLogDTO operLog) throws Exception {
    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog) throws Exception {
        String requestMethod = operLog.getRequestMethod();
        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
            String params = argsArrayToString(joinPoint.getArgs());
ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java
@@ -18,7 +18,7 @@
 *
 * @author Lion Li
 */
@EnableAsync
@EnableAsync(proxyTargetClass = true)
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {
ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
@@ -7,11 +7,11 @@
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.domain.dto.RoleDTO;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.XcxLoginUser;
import com.ruoyi.common.core.service.LogininforService;
import com.ruoyi.common.enums.DeviceType;
import com.ruoyi.common.enums.LoginType;
import com.ruoyi.common.enums.UserStatus;
@@ -24,6 +24,7 @@
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -46,7 +47,6 @@
    private final ISysUserService userService;
    private final ISysConfigService configService;
    private final LogininforService asyncService;
    private final SysPermissionService permissionService;
    @Value("${user.password.maxRetryCount}")
@@ -141,7 +141,12 @@
     * @return
     */
    private void recordLogininfor(String username, String status, String message) {
        asyncService.recordLogininfor(username, status, message, ServletUtils.getRequest());
        LogininforEvent logininforDTO = new LogininforEvent();
        logininforDTO.setUsername(username);
        logininforDTO.setStatus(status);
        logininforDTO.setMessage(message);
        logininforDTO.setRequest(ServletUtils.getRequest());
        SpringUtils.context().publishEvent(logininforDTO);
    }
    /**
ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java
@@ -4,9 +4,9 @@
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.service.LogininforService;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
@@ -15,6 +15,7 @@
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -31,7 +32,6 @@
    private final ISysUserService userService;
    private final ISysConfigService configService;
    private final LogininforService asyncService;
    /**
     * æ³¨å†Œ
@@ -61,7 +61,7 @@
        if (!regFlag) {
            throw new UserException("user.register.error");
        }
        asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"), request);
        recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"));
    }
    /**
@@ -77,12 +77,30 @@
        String captcha = RedisUtils.getCacheObject(verifyKey);
        RedisUtils.deleteObject(verifyKey);
        if (captcha == null) {
            asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"), request);
            recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"), request);
            recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
            throw new CaptchaException();
        }
    }
    /**
     * è®°å½•登录信息
     *
     * @param username ç”¨æˆ·å
     * @param status   çŠ¶æ€
     * @param message  æ¶ˆæ¯å†…容
     * @return
     */
    private void recordLogininfor(String username, String status, String message) {
        LogininforEvent logininforDTO = new LogininforEvent();
        logininforDTO.setUsername(username);
        logininforDTO.setStatus(status);
        logininforDTO.setMessage(message);
        logininforDTO.setRequest(ServletUtils.getRequest());
        SpringUtils.context().publishEvent(logininforDTO);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
@@ -6,8 +6,8 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.event.LogininforEvent;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.LogininforService;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
@@ -16,6 +16,7 @@
import com.ruoyi.system.service.ISysLogininforService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@@ -33,22 +34,19 @@
@RequiredArgsConstructor
@Slf4j
@Service
public class SysLogininforServiceImpl implements ISysLogininforService, LogininforService {
public class SysLogininforServiceImpl implements ISysLogininforService {
    private final SysLogininforMapper baseMapper;
    /**
     * è®°å½•登录信息
     *
     * @param username ç”¨æˆ·å
     * @param status   çŠ¶æ€
     * @param message  æ¶ˆæ¯
     * @param args     åˆ—表
     * @param logininforEvent ç™»å½•事件
     */
    @Async
    @Override
    public void recordLogininfor(final String username, final String status, final String message,
                                 HttpServletRequest request, final Object... args) {
    @EventListener
    public void recordLogininfor(LogininforEvent logininforEvent) {
        HttpServletRequest request = logininforEvent.getRequest();
        final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        final String ip = ServletUtils.getClientIP(request);
@@ -56,27 +54,27 @@
        StringBuilder s = new StringBuilder();
        s.append(getBlock(ip));
        s.append(address);
        s.append(getBlock(username));
        s.append(getBlock(status));
        s.append(getBlock(message));
        s.append(getBlock(logininforEvent.getUsername()));
        s.append(getBlock(logininforEvent.getStatus()));
        s.append(getBlock(logininforEvent.getMessage()));
        // æ‰“印信息到日志
        log.info(s.toString(), args);
        log.info(s.toString(), logininforEvent.getArgs());
        // èŽ·å–å®¢æˆ·ç«¯æ“ä½œç³»ç»Ÿ
        String os = userAgent.getOs().getName();
        // èŽ·å–å®¢æˆ·ç«¯æµè§ˆå™¨
        String browser = userAgent.getBrowser().getName();
        // å°è£…对象
        SysLogininfor logininfor = new SysLogininfor();
        logininfor.setUserName(username);
        logininfor.setUserName(logininforEvent.getUsername());
        logininfor.setIpaddr(ip);
        logininfor.setLoginLocation(address);
        logininfor.setBrowser(browser);
        logininfor.setOs(os);
        logininfor.setMsg(message);
        logininfor.setMsg(logininforEvent.getMessage());
        // æ—¥å¿—状态
        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
        if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
            logininfor.setStatus(Constants.SUCCESS);
        } else if (Constants.LOGIN_FAIL.equals(status)) {
        } else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
            logininfor.setStatus(Constants.FAIL);
        }
        // æ’入数据
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
@@ -5,15 +5,15 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.dto.OperLogDTO;
import com.ruoyi.common.core.domain.event.OperLogEvent;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.OperLogService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.mapper.SysOperLogMapper;
import com.ruoyi.system.service.ISysOperLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@@ -29,19 +29,19 @@
 */
@RequiredArgsConstructor
@Service
public class SysOperLogServiceImpl implements ISysOperLogService, OperLogService {
public class SysOperLogServiceImpl implements ISysOperLogService {
    private final SysOperLogMapper baseMapper;
    /**
     * æ“ä½œæ—¥å¿—记录
     *
     * @param operLogDTO æ“ä½œæ—¥å¿—信息
     * @param operLogEvent æ“ä½œæ—¥å¿—事件
     */
    @Async
    @Override
    public void recordOper(final OperLogDTO operLogDTO) {
        SysOperLog operLog = BeanUtil.toBean(operLogDTO, SysOperLog.class);
    @EventListener
    public void recordOper(OperLogEvent operLogEvent) {
        SysOperLog operLog = BeanUtil.toBean(operLogEvent, SysOperLog.class);
        // è¿œç¨‹æŸ¥è¯¢æ“ä½œåœ°ç‚¹
        operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
        insertOperlog(operLog);