package com.jilongda.applet.log; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.jilongda.applet.service.LoginLogService; import com.jilongda.common.log.OperLoginLog; import com.jilongda.common.log.ParamParser; import com.jilongda.common.model.LoginLog; import com.jilongda.common.utils.IPUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; /** * 切面处理类,登录日志记录处理 * * @author xiaochen * @date 2021/12/21 */ @Aspect @Component public class LoginLogAspect { @Autowired private LoginLogService loginLogService; /** * 设置操作日志切入点 记录登录日志 在注解的位置切入代码 */ @Pointcut("@annotation(com.jilongda.common.log.OperLoginLog)") public void operLoginLogPoinCut() { } /** * 正常返回通知,拦截用户登录日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 * * @param joinPoint 切入点 * @param keys 返回结果 */ @AfterReturning(value = "operLoginLogPoinCut()", returning = "keys") public void saveOperLog(JoinPoint joinPoint, Object keys) { // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); LoginLog operLoginLog = new LoginLog(); StringBuilder sb = new StringBuilder(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method = signature.getMethod(); // 获取操作 OperLoginLog opLog = method.getAnnotation(OperLoginLog.class); // 操作简述绑定参数 Object paramParserObj = null; String requestArgs; Parameter[] parameters = method.getParameters(); if (parameters != null && parameters.length > 0) { for (int i = 0; i < parameters.length; i++) { ParamParser an = parameters[i].getDeclaredAnnotation(ParamParser.class); if (an != null) { paramParserObj = an.value(); break; } } } // 不止一个参数 if (paramParserObj != null) { requestArgs = sb.append(":").append(paramParserObj).toString(); } else { requestArgs = JSONObject.toJSONString(joinPoint.getArgs()); } // 获取openid String openId = JSONObject.parseArray(requestArgs).getJSONObject(0).getString("openId"); operLoginLog.setOpenId(openId); // 获取当前登录用户信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String userName = null; // if (!(authentication instanceof AnonymousAuthenticationToken)) { // userName = authentication.getName(); // } // if (StringUtils.hasLength(userName)) { // 通过用户名查询该账号信息 // SecurityUserDetails userDetails = loadUserDetailsService.loadUserByUsername(userName); // operLoginLog.setUserName(userDetails.getShortName()); // 请求用户名称 // operLoginLog.setAccount(userDetails.getAccount()); // 请求账号 // } String ip = IPUtil.getIpAddress(request); operLoginLog.setLoginIp(ip); // 请求IP // operLoginLog.setLoginAddress(IPAddressUtil.getRealAddress(ip)); // 登录地址,目前服务器带不动 String address = IPUtil.getUserLocationByIp(); operLoginLog.setLoginAddress(address); operLoginLog.setWorkAddress(address); // 工作地 operLoginLog.setLoginTime(LocalDateTime.now()); // 登录时间 Long id = IdWorker.getId(); operLoginLog.setId(id); loginLogService.save(operLoginLog); } catch (Exception e) { e.printStackTrace(); } } /** * 转换request 请求参数 * * @param paramMap request获取的参数数组 */ public Map converMap(Map paramMap) { Map rtnMap = new HashMap(); for (String key : paramMap.keySet()) { rtnMap.put(key, paramMap.get(key)[0]); } return rtnMap; } }