package com.cyksj.aspect; import com.cyksj.web.util.StpAbroadUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import com.cyksj.common.annotation.Log; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.enums.BusinessStatus; import com.cyksj.mapper.manage.cms.SysLogMapper; import com.cyksj.model.entity.CmsUser; import com.cyksj.model.entity.SysLog; import com.cyksj.service.mange.cms.CmsUserManager; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; 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.springframework.http.HttpMethod; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Collection; import java.util.Enumeration; import java.util.Map; /* *项目名: yicang-admin *文件名: LogAspect *创建者: JavaZou *创建时间:2022/9/30 10:55 */ @Aspect @Component @Slf4j @RequiredArgsConstructor public class LogAspect { private final HttpServletRequest request; private final CmsUserManager cmsUserManager; private final SysLogMapper sysLogManager; /** * 处理后完成 * 切入点 */ @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { handleLog(joinPoint, controllerLog, null, jsonResult); } /** * 异常处理 * 切入 */ @AfterThrowing(pointcut = "@annotation(controllerLog)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) { handleLog(joinPoint, controllerLog, e, null); } private void handleLog(JoinPoint joinPoint, Log controllerLog, Exception e, Object jsonResult) { try { // 获取当前的用户 CmsUser cmsUser = cmsUserManager.getUser(StpAbroadUtil.getLoginIdAsLong()); SysLog sysLog = new SysLog(); sysLog.setOperateIp(ServletUtil.getClientIP(request)); sysLog.setOperateUrl(request.getRequestURI()); sysLog.setStatus(BusinessStatus.SUCCESS.ordinal()); sysLog.setOperateTime(DateTime.now().toString()); //操作人 if (cmsUser != null) { sysLog.setOperator(cmsUser.getNickname()); sysLog.setAccount(cmsUser.getPhone()); } if (e != null) { sysLog.setStatus(BusinessStatus.FAIL.ordinal()); sysLog.setErrMsg(StrUtil.subSufByLength(e.getMessage(), 2000)); } // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); sysLog.setMethod(String.format("%s.%s", className, methodName)); // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, controllerLog, sysLog, jsonResult); //请求方式 sysLog.setRequestMethod(request.getMethod()); sysLog.setOperateLocation(StringUtil.getRealAddressByIP(sysLog.getOperateIp())); sysLogManager.insert(sysLog); } catch (Exception exp) { // 记录本地异常日志 log.error("==前置通知异常=="); log.error("异常信息:{}", exp.getMessage()); } } private void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysLog sysLog, Object jsonResult) throws Exception { sysLog.setModule(log.module()); sysLog.setBusinessType(log.businessType().ordinal()); // 是否需要保存request,参数和值 if (log.isSaveRequestData()) { // 获取参数的信息,传入到数据库中。 setRequestValue(joinPoint, sysLog, log); } // 是否需要保存response,参数和值 if (log.isSaveResponseData() && jsonResult != null) { sysLog.setJsonResult(StrUtil.subSufByLength(Jsons.toJson(jsonResult), 2000)); } } /** * 请求入参 */ private void setRequestValue(JoinPoint joinPoint, SysLog sysLog, Log log) throws Exception { String requestMethod = log.businessType().name(); if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) { String params = argsArrayToString(joinPoint.getArgs()); sysLog.setOperateParams(StrUtil.subSufByLength(params, 2000)); } else { Map paramsMap = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); if (paramsMap.size() == 0) { Enumeration parameterNames = request.getParameterNames(); while (parameterNames.hasMoreElements()) { String key = parameterNames.nextElement(); String value = request.getParameter(key); paramsMap.put(key, value); } } sysLog.setOperateParams(StrUtil.subSufByLength(paramsMap.toString(), 2000)); } } /** * 参数拼装 */ private String argsArrayToString(Object[] paramsArray) { String params = ""; if (paramsArray != null && paramsArray.length > 0) { for (Object o : paramsArray) { if (o != null && !isFilterObject(o)) { try { Object jsonObj = Jsons.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; } }