package com.oying.service.impl; import cn.hutool.core.lang.Dict; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.oying.annotation.Log; import com.oying.mapper.SysLogMapper; import com.oying.service.SysLogService; import lombok.RequiredArgsConstructor; import com.oying.utils.FileUtil; import com.oying.utils.PageResult; import com.oying.utils.PageUtil; import com.oying.utils.StringUtils; import com.oying.domain.SysLog; import com.oying.domain.dto.SysLogQueryCriteria; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.*; /** * @author Z * @date 2018-11-24 */ @Service @RequiredArgsConstructor public class SysLogServiceImpl extends ServiceImpl implements SysLogService { private final SysLogMapper sysLogMapper; @Override public PageResult queryAll(SysLogQueryCriteria criteria, Page page) { return PageUtil.toPage(sysLogMapper.queryAll(criteria, page)); } @Override public List queryAll(SysLogQueryCriteria criteria) { return sysLogMapper.queryAll(criteria); } @Override public PageResult queryAllByUser(SysLogQueryCriteria criteria, Page page) { return PageUtil.toPage(sysLogMapper.queryAllByUser(criteria, page)); } @Async @Override @Transactional(rollbackFor = Exception.class) public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, SysLog sysLog) { if (sysLog == null) { throw new IllegalArgumentException("Log 不能为 null!"); } // 获取方法签名 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Log aopLog = method.getAnnotation(Log.class); // 方法路径 String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; // 填充基本信息 sysLog.setRequestIp(ip); sysLog.setAddress(StringUtils.getCityInfo(sysLog.getRequestIp())); sysLog.setMethod(methodName); sysLog.setUsername(username); sysLog.setParams(getParameter(method, joinPoint.getArgs())); sysLog.setBrowser(browser); sysLog.setDescription(aopLog.value()); // 保存 save(sysLog); } /** * 根据方法和传入的参数获取请求参数 */ private String getParameter(Method method, Object[] args) { List argList = new ArrayList<>(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { // 过滤掉 MultiPartFile if (args[i] instanceof MultipartFile) { continue; } // 过滤掉 HttpServletResponse if (args[i] instanceof HttpServletResponse) { continue; } // 过滤掉 HttpServletRequest if (args[i] instanceof HttpServletRequest) { continue; } //将RequestBody注解修饰的参数作为请求参数 RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); if (requestBody != null) { argList.add(args[i]); } //将RequestParam注解修饰的参数作为请求参数 RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); if (requestParam != null) { Map map = new HashMap<>(); String key = parameters[i].getName(); if (!StringUtils.isEmpty(requestParam.value())) { key = requestParam.value(); } map.put(key, args[i]); argList.add(map); } } // 返回参数 if (argList.isEmpty()) { return ""; } return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); } @Override public Object findByErrDetail(Long id) { String details = sysLogMapper.getExceptionDetails(id); return Dict.create().set("exception", details); } @Override public void download(List sysLogs, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); for (SysLog sysLog : sysLogs) { Map map = new LinkedHashMap<>(); map.put("用户名", sysLog.getUsername()); map.put("IP", sysLog.getRequestIp()); map.put("IP来源", sysLog.getAddress()); map.put("描述", sysLog.getDescription()); map.put("浏览器", sysLog.getBrowser()); map.put("请求耗时/毫秒", sysLog.getTime()); map.put("异常详情", sysLog.getExceptionDetail()); map.put("创建日期", sysLog.getCreateTime()); list.add(map); } FileUtil.downloadExcel(list, response); } @Override @Transactional(rollbackFor = Exception.class) public void delAllByError() { // 删除 ERROR 级别的日志 sysLogMapper.deleteByLevel("ERROR"); } @Override @Transactional(rollbackFor = Exception.class) public void delAllByInfo() { // 删除 INFO 级别的日志 sysLogMapper.deleteByLevel("INFO"); } }