package com.ruoyi.framework.aspectj; 
 | 
  
 | 
import java.util.Collection; 
 | 
import java.util.Map; 
 | 
import javax.servlet.http.HttpServletRequest; 
 | 
import javax.servlet.http.HttpServletResponse; 
 | 
import org.aspectj.lang.JoinPoint; 
 | 
import org.aspectj.lang.annotation.AfterReturning; 
 | 
import org.aspectj.lang.annotation.AfterThrowing; 
 | 
import org.aspectj.lang.annotation.Aspect; 
 | 
import org.slf4j.Logger; 
 | 
import org.slf4j.LoggerFactory; 
 | 
import org.springframework.stereotype.Component; 
 | 
import org.springframework.validation.BindingResult; 
 | 
import org.springframework.web.multipart.MultipartFile; 
 | 
import org.springframework.web.servlet.HandlerMapping; 
 | 
import com.alibaba.fastjson.JSON; 
 | 
import com.ruoyi.common.annotation.Log; 
 | 
import com.ruoyi.common.core.domain.model.LoginUser; 
 | 
import com.ruoyi.common.enums.BusinessStatus; 
 | 
import com.ruoyi.common.enums.HttpMethod; 
 | 
import com.ruoyi.common.utils.ServletUtils; 
 | 
import com.ruoyi.common.utils.StringUtils; 
 | 
import com.ruoyi.common.utils.ip.IpUtils; 
 | 
import com.ruoyi.common.utils.SecurityUtils; 
 | 
import com.ruoyi.framework.manager.AsyncManager; 
 | 
import com.ruoyi.framework.manager.factory.AsyncFactory; 
 | 
import com.ruoyi.system.domain.SysOperLog; 
 | 
  
 | 
/** 
 | 
 * 操作日志记录处理 
 | 
 *  
 | 
 * @author ruoyi 
 | 
 */ 
 | 
@Aspect 
 | 
@Component 
 | 
public class LogAspect 
 | 
{ 
 | 
    private static final Logger log = LoggerFactory.getLogger(LogAspect.class); 
 | 
  
 | 
    /** 
 | 
     * 处理完请求后执行 
 | 
     * 
 | 
     * @param joinPoint 切点 
 | 
     */ 
 | 
    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") 
 | 
    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) 
 | 
    { 
 | 
        handleLog(joinPoint, controllerLog, null, jsonResult); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 拦截异常操作 
 | 
     *  
 | 
     * @param joinPoint 切点 
 | 
     * @param e 异常 
 | 
     */ 
 | 
    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") 
 | 
    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) 
 | 
    { 
 | 
        handleLog(joinPoint, controllerLog, e, null); 
 | 
    } 
 | 
  
 | 
    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) 
 | 
    { 
 | 
        try 
 | 
        { 
 | 
  
 | 
            // 获取当前的用户 
 | 
            LoginUser loginUser = SecurityUtils.getLoginUser(); 
 | 
  
 | 
            // *========数据库日志=========*// 
 | 
            SysOperLog operLog = new SysOperLog(); 
 | 
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); 
 | 
            // 请求的地址 
 | 
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); 
 | 
            operLog.setOperIp(ip); 
 | 
            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); 
 | 
            if (loginUser != null) 
 | 
            { 
 | 
                operLog.setOperName(loginUser.getUsername()); 
 | 
            } 
 | 
  
 | 
            if (e != null) 
 | 
            { 
 | 
                operLog.setStatus(BusinessStatus.FAIL.ordinal()); 
 | 
                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); 
 | 
            } 
 | 
            // 设置方法名称 
 | 
            String className = joinPoint.getTarget().getClass().getName(); 
 | 
            String methodName = joinPoint.getSignature().getName(); 
 | 
            operLog.setMethod(className + "." + methodName + "()"); 
 | 
            // 设置请求方式 
 | 
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); 
 | 
            // 处理设置注解上的参数 
 | 
            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); 
 | 
            // 保存数据库 
 | 
            AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); 
 | 
        } 
 | 
        catch (Exception exp) 
 | 
        { 
 | 
            // 记录本地异常日志 
 | 
            log.error("==前置通知异常=="); 
 | 
            log.error("异常信息:{}", exp.getMessage()); 
 | 
            exp.printStackTrace(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取注解中对方法的描述信息 用于Controller层注解 
 | 
     *  
 | 
     * @param log 日志 
 | 
     * @param operLog 操作日志 
 | 
     * @throws Exception 
 | 
     */ 
 | 
    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception 
 | 
    { 
 | 
        // 设置action动作 
 | 
        operLog.setBusinessType(log.businessType().ordinal()); 
 | 
        // 设置标题 
 | 
        operLog.setTitle(log.title()); 
 | 
        // 设置操作人类别 
 | 
        operLog.setOperatorType(log.operatorType().ordinal()); 
 | 
        // 是否需要保存request,参数和值 
 | 
        if (log.isSaveRequestData()) 
 | 
        { 
 | 
            // 获取参数的信息,传入到数据库中。 
 | 
            setRequestValue(joinPoint, operLog); 
 | 
        } 
 | 
        // 是否需要保存response,参数和值 
 | 
        if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) 
 | 
        { 
 | 
            operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取请求的参数,放到log中 
 | 
     *  
 | 
     * @param operLog 操作日志 
 | 
     * @throws Exception 异常 
 | 
     */ 
 | 
    private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception 
 | 
    { 
 | 
        String requestMethod = operLog.getRequestMethod(); 
 | 
        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) 
 | 
        { 
 | 
            String params = argsArrayToString(joinPoint.getArgs()); 
 | 
            operLog.setOperParam(StringUtils.substring(params, 0, 2000)); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); 
 | 
            operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 参数拼装 
 | 
     */ 
 | 
    private String argsArrayToString(Object[] paramsArray) 
 | 
    { 
 | 
        String params = ""; 
 | 
        if (paramsArray != null && paramsArray.length > 0) 
 | 
        { 
 | 
            for (Object o : paramsArray) 
 | 
            { 
 | 
                if (StringUtils.isNotNull(o) && !isFilterObject(o)) 
 | 
                { 
 | 
                    try 
 | 
                    { 
 | 
                        Object jsonObj = JSON.toJSON(o); 
 | 
                        params += jsonObj.toString() + " "; 
 | 
                    } 
 | 
                    catch (Exception e) 
 | 
                    { 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return params.trim(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 判断是否需要过滤的对象。 
 | 
     *  
 | 
     * @param o 对象信息。 
 | 
     * @return 如果是需要过滤的对象,则返回true;否则返回false。 
 | 
     */ 
 | 
    @SuppressWarnings("rawtypes") 
 | 
    public boolean isFilterObject(final Object o) 
 | 
    { 
 | 
        Class<?> clazz = o.getClass(); 
 | 
        if (clazz.isArray()) 
 | 
        { 
 | 
            return clazz.getComponentType().isAssignableFrom(MultipartFile.class); 
 | 
        } 
 | 
        else if (Collection.class.isAssignableFrom(clazz)) 
 | 
        { 
 | 
            Collection collection = (Collection) o; 
 | 
            for (Object value : collection) 
 | 
            { 
 | 
                return value instanceof MultipartFile; 
 | 
            } 
 | 
        } 
 | 
        else if (Map.class.isAssignableFrom(clazz)) 
 | 
        { 
 | 
            Map map = (Map) o; 
 | 
            for (Object value : map.entrySet()) 
 | 
            { 
 | 
                Map.Entry entry = (Map.Entry) value; 
 | 
                return entry.getValue() instanceof MultipartFile; 
 | 
            } 
 | 
        } 
 | 
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse 
 | 
                || o instanceof BindingResult; 
 | 
    } 
 | 
} 
 |