cloudroam
2024-12-12 db6da36b94e1e43096a818052ee65dbfcd5e6d98
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.mzl.flower.base.aspect;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mzl.flower.base.ReturnDataInfoDTO;
import com.mzl.flower.base.annotation.OperationLog;
import com.mzl.flower.entity.log.OperationRecord;
import com.mzl.flower.mapper.log.OperationRecordMapper;
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.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
 
import static com.mzl.flower.utils.IpUtil.getIpAddress;
 
 
@Aspect
@Component
public class OperationLogAspect {
 
 
    @Resource
    private OperationRecordMapper operationRecordMapper;
 
    //扫描使用这个注解的方法
    @Pointcut("@annotation(com.mzl.flower.base.annotation.OperationLog)")
    public void logPointCut() {
    }
 
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Date beginTime = new Date();
        String result = null;
        String status = null;
        //执行代码,都加try catch,即使出错也不能影响主进程
        OperationRecord operationRecord = null;
        try {
            Object obj = point.proceed();//放行请求的主进程并拿到返回值
            if (obj != null) {
                ResponseEntity<?> responseEntity = (ResponseEntity<?>) obj;
                Object body = responseEntity.getBody();
                // 将obj转换为String类型
                String jsonResponse = JSONObject.toJSONString(body);
                System.out.println(jsonResponse);
                // 创建ObjectMapper实例
                ObjectMapper objectMapper = new ObjectMapper();
                // 使用 TypeReference 指定泛型类型
                ReturnDataInfoDTO<Object> returnDataInfoDTO = JSON.parseObject(jsonResponse, new TypeReference<ReturnDataInfoDTO<Object>>() {});
                // 从 ReturnDataInfoDTO 对象中获取 OperationRecord 对象
                operationRecord = (OperationRecord) returnDataInfoDTO.getInfo();
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (attributes != null) {
                    HttpServletRequest request = attributes.getRequest();
                    // 获取请求的IP地址
                    String ip = getIpAddress(request);
                    operationRecord.setIpAddress(ip);
                    System.out.println("ip"+ip);
                }
//                if (attributes != null) {
//                    HttpServletRequest request = attributes.getRequest();
//                    System.out.println(request.getRemoteAddr()); // 或者使用上面提到的方法获取真实IP地址
//                }
            }
            status = "success";
            return obj;
        } catch (Exception e) {//请求执行出错
            result = e.getMessage();
            status = "error";
            throw e;
        } finally {//无论成功失败,都保存下日志
            saveLog(point, beginTime, new Date(), result, status, operationRecord);
        }
    }
 
    //保存日志
    private void saveLog(ProceedingJoinPoint joinPoint, Date beginTime, Date endTime, String result, String status, OperationRecord operationRecord) {
        if (!ObjectUtils.isEmpty(operationRecord)) {
            try {
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                OperationLog annotation = method.getAnnotation(OperationLog.class);
                operationRecord.setStatus(status);
                if (annotation != null) {
                    //注解上的描述
                    String type = annotation.type();
//                if (!StringUtils.isEmpty(type)) {
//                    String recordModule = operationRecordMapper.getCodeType("OPERATION_RECORD_MODULE", type);
//                    operationRecord.setModule(recordModule);
//                } else {
                    operationRecord.setModule(type);
//                }
                    operationRecord.setFunction(annotation.value());//注解类型
                }//记录入参
//            if (joinPoint.getArgs() != null) {
//                try {
//                    operationRecord.setContent(JSONObject.toJSONString(result));
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
                //如果注解类型是1(增删改)或者是2(查询)报错,记录返回值,如果是查询正常就不记录,有可能返回值太多
 
            } catch (Exception e) {
                e.printStackTrace();
            }
            //启动一个线程,执行报错日志,防止影响主请求
            new Thread(() -> {
                try {//保存数据到数据库
                    operationRecordMapper.insert(operationRecord);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}