content: package org.jeecg.common.aspect;
  
  import com.alibaba.fastjson.JSONObject;
  import com.alibaba.fastjson.serializer.PropertyFilter;
  import org.apache.shiro.SecurityUtils;
  import org.aspectj.lang.JoinPoint;
  import org.aspectj.lang.ProceedingJoinPoint;
  import org.aspectj.lang.annotation.Around;
  import org.aspectj.lang.annotation.Aspect;
  import org.aspectj.lang.annotation.Pointcut;
  import org.aspectj.lang.reflect.MethodSignature;
  import org.jeecg.common.api.dto.LogDTO;
  import org.jeecg.common.api.vo.Result;
  import org.jeecg.common.aspect.annotation.AutoLog;
  import org.jeecg.common.constant.CommonConstant;
  import org.jeecg.common.constant.enums.ModuleType;
  import org.jeecg.common.system.vo.LoginUser;
  import org.jeecg.common.util.IPUtils;
  import org.jeecg.common.util.SpringContextUtils;
  import org.jeecg.common.util.oConvertUtils;
  import org.jeecg.modules.base.service.BaseCommonService;
  import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
  import org.springframework.stereotype.Component;
  import org.springframework.validation.BindingResult;
  import org.springframework.web.multipart.MultipartFile;
  
  import javax.annotation.Resource;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServletRequest;
  import java.lang.reflect.Method;
  import java.util.Date;
  
  
  /**
   * 系统日志，切面处理类
   *
   * @Author scott
   * @email jeecgos@163.com
   * @Date 2018年1月14日
   */
  @Aspect
  @Component
  public class AutoLogAspect {
  
      @Resource
      private BaseCommonService baseCommonService;
  
      @Pointcut("@annotation(org.jeecg.common.aspect.annotation.AutoLog)")
      public void logPointCut() {
  
      }
  
      @Around("logPointCut()")
      public Object around(ProceedingJoinPoint point) throws Throwable {
          long beginTime = System.currentTimeMillis();
          //执行方法
          Object result = point.proceed();
          //执行时长(毫秒)
          long time = System.currentTimeMillis() - beginTime;
  
          //保存日志
          saveSysLog(point, time, result);
  
          return result;
      }
  
      private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) {
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();
          Method method = signature.getMethod();
  
          LogDTO dto = new LogDTO();
          AutoLog syslog = method.getAnnotation(AutoLog.class);
          if(syslog != null){
              //update-begin-author:taoyan date:
              String content = syslog.value();
              if(syslog.module()== ModuleType.ONLINE){
                  content = getOnlineLogContent(obj, content);
              }
              //注解上的描述,操作日志内容
              dto.setLogType(syslog.logType());
              dto.setLogContent(content);
          }
  
          //请求的方法名
          String className = joinPoint.getTarget().getClass().getName();
          String methodName = signature.getName();
          dto.setMethod(className + "." + methodName + "()");
  
  
          //设置操作类型
          if (dto.getLogType() == CommonConstant.LOG_TYPE_2) {
              dto.setOperateType(getOperateType(methodName, syslog.operateType()));
          }
  
          //获取request
          HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
          //请求的参数
          dto.setRequestParam(getReqestParams(request,joinPoint));
          //设置IP地址
          dto.setIp(IPUtils.getIpAddr(request));
          //获取登录用户信息
          LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
          if(sysUser!=null){
              dto.setUserid(sysUser.getUsername());
              dto.setUsername(sysUser.getRealname());
  
          }
          //耗时
          dto.setCostTime(time);
          dto.setCreateTime(new Date());
          //保存系统日志
          baseCommonService.addLog(dto);
      }
  
  
      /**
       * 获取操作类型
       */
      private int getOperateType(String methodName,int operateType) {
          if (operateType > 0) {
              return operateType;
          }
          if (methodName.startsWith("list")) {
              return CommonConstant.OPERATE_TYPE_1;
          }
          if (methodName.startsWith("add")) {
              return CommonConstant.OPERATE_TYPE_2;
          }
          if (methodName.startsWith("edit")) {
              return CommonConstant.OPERATE_TYPE_3;
          }
          if (methodName.startsWith("delete")) {
              return CommonConstant.OPERATE_TYPE_4;
          }
          if (methodName.startsWith("import")) {
              return CommonConstant.OPERATE_TYPE_5;
          }
          if (methodName.startsWith("export")) {
              return CommonConstant.OPERATE_TYPE_6;
          }
          return CommonConstant.OPERATE_TYPE_1;
      }
  
      /**
       * @Description: 获取请求参数
       * @author: scott
       * @date: 2020/4/16 0:10
       * @param request:  request
       * @param joinPoint:  joinPoint
       * @Return: java.lang.String
       */
      private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) {
          String httpMethod = request.getMethod();
          String params = "";
          if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) || "PATCH".equals(httpMethod)) {
              Object[] paramsArray = joinPoint.getArgs();
              // java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
              //  https://my.oschina.net/mengzhang6/blog/2395893
              Object[] arguments  = new Object[paramsArray.length];
              for (int i = 0; i < paramsArray.length; i++) {
                  if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
                      //ServletRequest不能序列化，从入参里排除，否则报异常：java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
                      //ServletResponse不能序列化 从入参里排除，否则报异常：java.lang.IllegalStateException: getOutputStream() has already been called for this response
                      continue;
                  }
                  arguments[i] = paramsArray[i];
              }
              //update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
              PropertyFilter profilter = new PropertyFilter() {
                  @Override
                  public boolean apply(Object o, String name, Object value) {
                      if(value!=null && value.toString().length()>500){
                          return false;
                      }
                      return true;
                  }
              };
              params = JSONObject.toJSONString(arguments, profilter);
              //update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
          } else {
              MethodSignature signature = (MethodSignature) joinPoint.getSignature();
              Method method = signature.getMethod();
              // 请求的方法参数值
              Object[] args = joinPoint.getArgs();
              // 请求的方法参数名称
              LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
              String[] paramNames = u.getParameterNames(method);
              if (args != null && paramNames != null) {
                  for (int i = 0; i < args.length; i++) {
                      params += "  " + paramNames[i] + ": " + args[i];
                  }
              }
          }
          return params;
      }
  
      /**
       * online日志内容拼接
       * @param obj
       * @param content
       * @return
       */
      private String getOnlineLogContent(Object obj, String content){
          if (Result.class.isInstance(obj)){
              Result res = (Result)obj;
              String msg = res.getMessage();
              String tableName = res.getOnlTable();
              if(oConvertUtils.isNotEmpty(tableName)){
                  content+=",表名:"+tableName;
              }
              if(res.isSuccess()){
                  content+= ","+(oConvertUtils.isEmpty(msg)?"操作成功":msg);
              }else{
                  content+= ","+(oConvertUtils.isEmpty(msg)?"操作失败":msg);
              }
          }
          return content;
      }
  
  
      /*    private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) {
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();
          Method method = signature.getMethod();
  
          SysLog sysLog = new SysLog();
          AutoLog syslog = method.getAnnotation(AutoLog.class);
          if(syslog != null){
              //update-begin-author:taoyan date:
              String content = syslog.value();
              if(syslog.module()== ModuleType.ONLINE){
                  content = getOnlineLogContent(obj, content);
              }
              //注解上的描述,操作日志内容
              sysLog.setLogContent(content);
              sysLog.setLogType(syslog.logType());
          }
  
          //请求的方法名
          String className = joinPoint.getTarget().getClass().getName();
          String methodName = signature.getName();
          sysLog.setMethod(className + "." + methodName + "()");
  
  
          //设置操作类型
          if (sysLog.getLogType() == CommonConstant.LOG_TYPE_2) {
              sysLog.setOperateType(getOperateType(methodName, syslog.operateType()));
          }
  
          //获取request
          HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
          //请求的参数
          sysLog.setRequestParam(getReqestParams(request,joinPoint));
  
          //设置IP地址
          sysLog.setIp(IPUtils.getIpAddr(request));
  
          //获取登录用户信息
          LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
          if(sysUser!=null){
              sysLog.setUserid(sysUser.getUsername());
              sysLog.setUsername(sysUser.getRealname());
  
          }
          //耗时
          sysLog.setCostTime(time);
          sysLog.setCreateTime(new Date());
          //保存系统日志
          sysLogService.save(sysLog);
      }*/
  }
  