whyclxw
2 天以前 3e2f537e80f51948969de2a5b1b82292c0aac550
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package com.whyc.aop;/*
package com.com.whyc.com.whyc.aop;
 
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.com.whyc.dto.Response;
import com.com.whyc.service.UserLogService;
import com.com.whyc.util.JsonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.stereotype.Component;
 
import java.util.HashMap;
 
*/
/**
 * 定义aop,对特定的接口进行内容捕捉,生成操作日志
 * 切面为controller
 * 切点为Point表达式
 * 具体连接点为JoinPoint
 * 处理方式为doAfterReturning
 *
 *//*
 
 
@Component
@Aspect
public class OperationLogAspect {
 
    @Autowired
    private UserLogService service;
 
    */
/**定义切点*//*
 
    @Pointcut(value = "execution(public * com.com.whyc..controller.*.add*(..))" +
            "|| execution(public * com.com.whyc..controller.*.delete*(..))" +
            "|| execution(public * com.com.whyc..controller.*.update*(..))"
            //"|| execution(public * com.com.whyc..controller.LoginController.*(..))" LoginController模块有专门日志定义转化,不需要通用的拦截.
    )
    private void operationLogPointcut(){};
 
    */
/**
     * aop处理类,对捕捉到的切点接口,进行数据处理
     * 以 文档类型管理里面的新增为例:
     * 请求: POST
     * 请求地址: /pis/docType/add
     * 具体代码: com.com.whyc.controller.DocTypeController.add(DocType))
     * 参数: {"name":"显示屏类型"}
     *
     * 拦截得到的字段:
     * signature: com.com.whyc.controller.DocTypeController.add(DocType)
     * methodSignature: com.com.whyc.controller.DocTypeController.add(DocType)
     * methodName: add
     * fullClassName: com.com.whyc.controller.DocTypeController
     * classNameTrue: DocTypeController
     * parameterNames: 是数组,这个是代码里面传参的参数名,示例只有一个参数 docType
     * args: 是数组,示例只有一个参数,参数值为Oject -DocType(id=5, name=显示屏类型, updateTime=null, CreateTime=Mon Jul 07 10:39:11 CST 2025),通过toString来转化为字符串存储,需要对象有toString方法
     * map: 将parameterNames和args进行对应转换,并保存为map<String,String>,保存了最终的接口明细参数.docType -> {"id":5,"name":"显示屏类型","CreateTime":"Jul 7, 2025 10:39:11 AM"}
     *
     * TODO 这个输入模块需要迭代的具体工作量:
     * 1.将所有的Controller转化为具体操作日志模块
     * 2.特定模块定义及划分日志类型
     * 以上两个,在同一个Switch...Case...模块下,进行定义,并保存为枚举类,方便后续扩展,以及统一处理.
     * *//*
 
    @AfterReturning(pointcut = "operationLogPointcut()",returning = "resp")
    public void doAfterReturnOperation(JoinPoint point,Object resp){
        Response response = (Response) resp;
        Signature signature = point.getSignature();
        String methodSignature = signature.toString();
        //方法名
        // e.g:update
        String methodName = signature.getName();
        //执行的类全名
        // e.g: com.com.whyc.controller.CKPowerDevRtSetController
        String fullClassName = signature.getDeclaringTypeName();
        //获取类型
        String[] fullClassNameSplit = fullClassName.split("\\.");
        //类名
        // e.g: CKPowerDevRtSetController
        String classNameTrue = fullClassNameSplit[fullClassNameSplit.length - 1];
        Integer category = 0;
        Integer type = 0;
        String operationTypeName = "";
 
        //TODO 下面这段将优化,采用switch case 代替if else,提高代码可读性和优化性能
        //系统级
        */
/*if (classNameTrue.equals("UserInfController")) {
            if(methodName.contains("add")){ //用户新增
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_USER_ADD.getType();
                operationTypeName = OperationLogEnum.TYPE_2_USER_ADD.getName();
 
            }else if(methodName.contains("update")){ //用户修改
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_USER_UPDATE.getType();
                operationTypeName = OperationLogEnum.TYPE_2_USER_UPDATE.getName();
            }else if(methodName.contains("delete")){ //用户删除
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_USER_DELETE.getType();
                operationTypeName = OperationLogEnum.TYPE_2_USER_DELETE.getName();
            }else if(methodName.contains("resetSnId")){ //密码重置
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_USER_UPDATE_PASSWORD.getType();
                operationTypeName = OperationLogEnum.TYPE_2_USER_UPDATE_PASSWORD.getName();
            }
 
        }else if(classNameTrue.equals("LoginController")){
            if(methodName.equals("login")){
                if((boolean) response.getData()){ //用户登录
                    category = OperationLogEnum.TYPE_1_SYS.getType();
                    type = OperationLogEnum.TYPE_2_LOGIN.getType();
                    operationTypeName = OperationLogEnum.TYPE_2_LOGIN.getName();
                }else { //用户登录失败
                    category = OperationLogEnum.TYPE_1_SYS.getType();
                    type = OperationLogEnum.TYPE_2_LOGIN_FAIL.getType();
                    operationTypeName = OperationLogEnum.TYPE_2_LOGIN_FAIL.getName();
                }
            }
            else if(methodName.equals("logout")){ //用户退出
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_LOGOUT.getType();
                operationTypeName = OperationLogEnum.TYPE_2_LOGOUT.getName();
            }
            else if(methodName.equals("changeSnId")){ //用户密码重置
                category = OperationLogEnum.TYPE_1_SYS.getType();
                type = OperationLogEnum.TYPE_2_USER_UPDATE_PASSWORD.getType();
                operationTypeName = OperationLogEnum.TYPE_2_USER_UPDATE_PASSWORD.getName();
            }
        }else if(classNameTrue.contains("Alarm")
                ||classNameTrue.contains("Alm")){ //告警设置
            if(methodName.startsWith("update")){
                category = OperationLogEnum.TYPE_1_SERVICE.getType();
                type = OperationLogEnum.TYPE_2_ALARM.getType();
                operationTypeName = OperationLogEnum.TYPE_2_ALARM.getName();
            }
        }else if(classNameTrue.contains("plan")){
            if(methodName.startsWith("static")){//统计计划
                category = OperationLogEnum.TYPE_1_SERVICE.getType();
                type = OperationLogEnum.TYPE_2_PLAN_MON.getType();
                operationTypeName = OperationLogEnum.TYPE_2_PLAN_MON.getName();
            }
        }*//*
 
 
        String module = "模块";
        String className = classNameTrue.replace("Controller", module);
 
       */
/* //操作时间
        Date operationTime = new Date();
        //客户端ip
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String terminalIp = request.getRemoteAddr();*//*
 
 
        //操作信息
        //获取切点方法信息
        String[] parameterNames = ((MethodSignature) signature).getParameterNames();
        Object[] args = point.getArgs();
 
        HashMap<String, Object> map = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            if (args[i] != null) {
                StringBuilder paramBuilder = new StringBuilder();
                //String param = args[i].toString();
                try {
                    JsonObject paramJsonObject = JsonUtil.getGson().toJsonTree(args[i]).getAsJsonObject();
                    //TODO 如存在需要忽略的参数,这里进行处理
                    */
/*if(paramJsonObject.has("logList")){
                        paramJsonObject.remove("logList");
                        JsonElement jsonElement = new JsonPrimitive("logList字段忽略存储");
                        paramJsonObject.add("logList",jsonElement);
                    }*//*
 
                    paramBuilder.append(paramJsonObject.toString());
                }catch (Exception e){
                    paramBuilder.append(args[i].toString());
                }
                
                map.put(parameterNames[i], paramBuilder.toString());
            }
        }
        //登录接口的密码,不存储
        if (methodSignature.contains("LoginController.login")) {
            map.put("password","密码密文保密,忽略存储");
        }
        //TODO 修改密码接口的密码,也不存储
        */
/*else if(methodSignature.contains("LoginController.changeSnId")){
            map.put("oldSnId","旧密码密文保密,忽略存储");
            map.put("newSnId","新密码密文保密,忽略存储");
        }*//*
 
        //规范示例: 执行的文档类型管理的添加操作.
        String message = "执行了" + className + "的" + operationTypeName + "操作.";
        //规范示例:具体调用方法为: DocTypeController.add,具体参数为:{docType={"id":4,"name":"显示屏类型","CreateTime":"Jul 7, 2025 10:16:18 AM"}}
        String messageDetail = "具体调用方法为:" + classNameTrue+"."+methodName + ",具体参数为:" + map.toString();
 
        service.add(category, type, message, messageDetail);
 
    }
 
}
*/