Commit 69503689912abe6e565fd71895bc0245bd72fc2c

Authored by puhui999
1 parent 5de6a8bd

操作日志:完善 code review 提到的问题

Showing 27 changed files with 183 additions and 649 deletions
yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
@@ -47,13 +47,6 @@ @@ -47,13 +47,6 @@
47 <artifactId>guava</artifactId> 47 <artifactId>guava</artifactId>
48 </dependency> 48 </dependency>
49 49
50 - <dependency>  
51 - <!-- Spring Boot 通用操作日志组件,基于注解实现 -->  
52 - <!-- 此组件解决的问题是:「谁」在「什么时间」对「什么」做了「什么事」 -->  
53 - <groupId>io.github.mouzt</groupId>  
54 - <artifactId>bizlog-sdk</artifactId>  
55 - </dependency>  
56 -  
57 </dependencies> 50 </dependencies>
58 51
59 </project> 52 </project>
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogAutoConfiguration.java
1 package cn.iocoder.yudao.framework.operatelog.config; 1 package cn.iocoder.yudao.framework.operatelog.config;
2 2
  3 +import cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect;
  4 +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
  5 +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkServiceImpl;
  6 +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
3 import org.springframework.boot.autoconfigure.AutoConfiguration; 7 import org.springframework.boot.autoconfigure.AutoConfiguration;
  8 +import org.springframework.context.annotation.Bean;
4 9
5 @AutoConfiguration 10 @AutoConfiguration
6 public class YudaoOperateLogAutoConfiguration { 11 public class YudaoOperateLogAutoConfiguration {
7 12
8 - // TODO @puhui999:这个是不是留着哈?因为老版本还是会留着一段时间的  
9 - //@Bean  
10 - //public OperateLogAspect operateLogAspect() {  
11 - // return new OperateLogAspect();  
12 - //}  
13 - //  
14 - //@Bean  
15 - //public OperateLogFrameworkService operateLogFrameworkService(OperateLogApi operateLogApi) {  
16 - // return new OperateLogFrameworkServiceImpl(operateLogApi);  
17 - //} 13 + @Bean
  14 + public OperateLogAspect operateLogAspect() {
  15 + return new OperateLogAspect();
  16 + }
  17 +
  18 + @Bean
  19 + public OperateLogFrameworkService operateLogFrameworkService(OperateLogApi operateLogApi) {
  20 + return new OperateLogFrameworkServiceImpl(operateLogApi);
  21 + }
18 22
19 } 23 }
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/aop/OperateLogV2Aspect.java deleted
1 -package cn.iocoder.yudao.framework.operatelogv2.core.aop;  
2 -  
3 -import cn.hutool.core.date.LocalDateTimeUtil;  
4 -import cn.hutool.core.exceptions.ExceptionUtil;  
5 -import cn.hutool.core.util.ArrayUtil;  
6 -import cn.hutool.core.util.ObjUtil;  
7 -import cn.hutool.core.util.StrUtil;  
8 -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;  
9 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
10 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
11 -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;  
12 -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;  
13 -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;  
14 -import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;  
15 -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;  
16 -import com.google.common.collect.Maps;  
17 -import com.mzt.logapi.beans.LogRecord;  
18 -import io.swagger.v3.oas.annotations.Operation;  
19 -import jakarta.annotation.Resource;  
20 -import jakarta.servlet.http.HttpServletRequest;  
21 -import jakarta.servlet.http.HttpServletResponse;  
22 -import lombok.extern.slf4j.Slf4j;  
23 -import org.aspectj.lang.ProceedingJoinPoint;  
24 -import org.aspectj.lang.annotation.Around;  
25 -import org.aspectj.lang.annotation.Aspect;  
26 -import org.aspectj.lang.reflect.MethodSignature;  
27 -import org.springframework.core.annotation.AnnotationUtils;  
28 -import org.springframework.validation.BindingResult;  
29 -import org.springframework.web.bind.annotation.RequestMapping;  
30 -import org.springframework.web.bind.annotation.RequestMethod;  
31 -import org.springframework.web.multipart.MultipartFile;  
32 -  
33 -import java.lang.annotation.Annotation;  
34 -import java.lang.reflect.Array;  
35 -import java.time.LocalDateTime;  
36 -import java.util.Arrays;  
37 -import java.util.Collection;  
38 -import java.util.HashMap;  
39 -import java.util.Map;  
40 -import java.util.function.Predicate;  
41 -import java.util.stream.IntStream;  
42 -  
43 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;  
44 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS;  
45 -import static cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants.*;  
46 -  
47 -// TODO @puhui999:这个类,是不是可以删除哈;简化简化  
48 -/**  
49 - * 拦截使用 @Operation 注解, 获取操作类型、开始时间、持续时间、方法相关信息、执行结果等信息  
50 - * 对 mzt-biz-log 日志信息进行增强  
51 - *  
52 - * @author HUIHUI  
53 - */  
54 -@Aspect  
55 -@Slf4j  
56 -public class OperateLogV2Aspect {  
57 -  
58 - /**  
59 - * 用于记录操作内容的上下文  
60 - *  
61 - * @see OperateLogV2CreateReqDTO#getContent()  
62 - */  
63 - private static final ThreadLocal<LogRecord> CONTENT = new ThreadLocal<>();  
64 - /**  
65 - * 用于记录拓展字段的上下文  
66 - *  
67 - * @see OperateLogV2CreateReqDTO#getExtra()  
68 - */  
69 - private static final ThreadLocal<Map<String, Object>> EXTRA = new ThreadLocal<>();  
70 -  
71 - @Resource  
72 - private OperateLogApi operateLogApi;  
73 -  
74 - @Around("@annotation(operation)")  
75 - public Object around(ProceedingJoinPoint joinPoint, Operation operation) throws Throwable {  
76 - RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint));  
77 - if (requestMethod == RequestMethod.GET) { // 跳过 get 方法  
78 - return joinPoint.proceed();  
79 - }  
80 -  
81 - // 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录  
82 - Integer userType = WebFrameworkUtils.getLoginUserType();  
83 - if (ObjUtil.notEqual(userType, UserTypeEnum.ADMIN.getValue())) {  
84 - return joinPoint.proceed();  
85 - }  
86 -  
87 - // 记录开始时间  
88 - LocalDateTime startTime = LocalDateTime.now();  
89 - try {  
90 - // 执行原有方法  
91 - Object result = joinPoint.proceed();  
92 - // 记录正常执行时的操作日志  
93 - this.log(joinPoint, operation, startTime, result, null);  
94 - return result;  
95 - } catch (Throwable exception) {  
96 - this.log(joinPoint, operation, startTime, null, exception);  
97 - throw exception;  
98 - } finally {  
99 - clearThreadLocal();  
100 - }  
101 - }  
102 -  
103 - public static void setContent(LogRecord content) {  
104 - CONTENT.set(content);  
105 - }  
106 -  
107 - public static void addExtra(String key, Object value) {  
108 - if (EXTRA.get() == null) {  
109 - EXTRA.set(new HashMap<>());  
110 - }  
111 - EXTRA.get().put(key, value);  
112 - }  
113 -  
114 - public static void addExtra(Map<String, Object> extra) {  
115 - if (EXTRA.get() == null) {  
116 - EXTRA.set(new HashMap<>());  
117 - }  
118 - EXTRA.get().putAll(extra);  
119 - }  
120 -  
121 - private static void clearThreadLocal() {  
122 - CONTENT.remove();  
123 - EXTRA.remove();  
124 - }  
125 -  
126 - private void log(ProceedingJoinPoint joinPoint, Operation operation,  
127 - LocalDateTime startTime, Object result, Throwable exception) {  
128 - try {  
129 - // 判断不记录的情况(默认没有值就是记录)  
130 - if (EXTRA.get() != null && EXTRA.get().get(ENABLE) != null) {  
131 - return;  
132 - }  
133 - if (CONTENT.get() == null) { // 没有值说明没有日志需要记录  
134 - return;  
135 - }  
136 -  
137 - // 真正记录操作日志  
138 - this.log0(joinPoint, operation, startTime, result, exception);  
139 - } catch (Throwable ex) {  
140 - log.error("[log][记录操作日志时,发生异常,其中参数是 joinPoint({}) apiOperation({}) result({}) exception({}) ]",  
141 - joinPoint, operation, result, exception, ex);  
142 - }  
143 - }  
144 -  
145 - private void log0(ProceedingJoinPoint joinPoint, Operation operation,  
146 - LocalDateTime startTime, Object result, Throwable exception) {  
147 - OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO();  
148 - // 补全通用字段  
149 - reqDTO.setTraceId(TracerUtils.getTraceId());  
150 - reqDTO.setStartTime(startTime);  
151 - // 补充用户信息  
152 - fillUserFields(reqDTO);  
153 - // 补全模块信息  
154 - fillModuleFields(reqDTO, operation);  
155 - // 补全请求信息  
156 - fillRequestFields(reqDTO);  
157 - // 补全方法信息  
158 - fillMethodFields(reqDTO, joinPoint, startTime, result, exception);  
159 -  
160 - // 异步记录日志  
161 - operateLogApi.createOperateLogV2(reqDTO);  
162 - }  
163 -  
164 - private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) {  
165 - reqDTO.setUserId(WebFrameworkUtils.getLoginUserId());  
166 - reqDTO.setUserType(WebFrameworkUtils.getLoginUserType());  
167 - }  
168 -  
169 - private static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, Operation operation) {  
170 - LogRecord logRecord = CONTENT.get();  
171 - reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号  
172 - reqDTO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。  
173 -  
174 - // type 属性  
175 - reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户  
176 - // subType 属性  
177 - if (logRecord.getSubType() != null) {  
178 - reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户  
179 - }  
180 - if (StrUtil.isEmpty(reqDTO.getSubType()) && operation != null) {  
181 - reqDTO.setSubType(operation.summary());  
182 - }  
183 -  
184 - // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}  
185 - Map<String, Object> objectMap = EXTRA.get();  
186 - if (objectMap != null) {  
187 - Object object = objectMap.get(EXTRA_KEY);  
188 - if (object instanceof Map<?, ?> extraMap) {  
189 - if (extraMap.keySet().stream().allMatch(String.class::isInstance)) {  
190 - @SuppressWarnings("unchecked")  
191 - Map<String, Object> extra = (Map<String, Object>) extraMap;  
192 - reqDTO.setExtra(extra);  
193 - return;  
194 - }  
195 - }  
196 - // 激进一点不是 map 直接当 value 处理  
197 - Map<String, Object> extra = Maps.newHashMapWithExpectedSize(1);  
198 - extra.put(EXTRA_KEY, object);  
199 - reqDTO.setExtra(extra);  
200 - }  
201 -  
202 - }  
203 -  
204 - private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {  
205 - // 获得 Request 对象  
206 - HttpServletRequest request = ServletUtils.getRequest();  
207 - if (request == null) {  
208 - return;  
209 - }  
210 - // 补全请求信息  
211 - reqDTO.setRequestMethod(request.getMethod());  
212 - reqDTO.setRequestUrl(request.getRequestURI());  
213 - reqDTO.setUserIp(ServletUtils.getClientIP(request));  
214 - reqDTO.setUserAgent(ServletUtils.getUserAgent(request));  
215 - }  
216 -  
217 - private static void fillMethodFields(OperateLogV2CreateReqDTO reqDTO, ProceedingJoinPoint joinPoint, LocalDateTime startTime,  
218 - Object result, Throwable exception) {  
219 - MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();  
220 - reqDTO.setJavaMethod(methodSignature.toString());  
221 - if (EXTRA.get().get(IS_LOG_ARGS) == null) {  
222 - reqDTO.setJavaMethodArgs(obtainMethodArgs(joinPoint));  
223 - }  
224 - if (EXTRA.get().get(IS_LOG_RESULT_DATA) == null) {  
225 - reqDTO.setResultData(obtainResultData(result));  
226 - }  
227 - reqDTO.setDuration((int) (LocalDateTimeUtil.between(startTime, LocalDateTime.now()).toMillis()));  
228 - // (正常)处理 resultCode 和 resultMsg 字段  
229 - if (result instanceof CommonResult) {  
230 - CommonResult<?> commonResult = (CommonResult<?>) result;  
231 - reqDTO.setResultCode(commonResult.getCode());  
232 - reqDTO.setResultMsg(commonResult.getMsg());  
233 - } else {  
234 - reqDTO.setResultCode(SUCCESS.getCode());  
235 - }  
236 - // (异常)处理 resultCode 和 resultMsg 字段  
237 - if (exception != null) {  
238 - reqDTO.setResultCode(INTERNAL_SERVER_ERROR.getCode());  
239 - reqDTO.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));  
240 - }  
241 - }  
242 -  
243 - @SuppressWarnings("SameParameterValue")  
244 - private static <T extends Annotation> T getClassAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationClass) {  
245 - return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass);  
246 - }  
247 -  
248 - private static String obtainMethodArgs(ProceedingJoinPoint joinPoint) {  
249 - // TODO 提升:参数脱敏和忽略  
250 - MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();  
251 - String[] argNames = methodSignature.getParameterNames();  
252 - Object[] argValues = joinPoint.getArgs();  
253 - // 拼接参数  
254 - Map<String, Object> args = Maps.newHashMapWithExpectedSize(argValues.length);  
255 - for (int i = 0; i < argNames.length; i++) {  
256 - String argName = argNames[i];  
257 - Object argValue = argValues[i];  
258 - // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起  
259 - args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");  
260 - }  
261 - return JsonUtils.toJsonString(args);  
262 - }  
263 -  
264 - private static String obtainResultData(Object result) {  
265 - // TODO 提升:结果脱敏和忽略  
266 - if (result instanceof CommonResult) {  
267 - result = ((CommonResult<?>) result).getData();  
268 - }  
269 - return JsonUtils.toJsonString(result);  
270 - }  
271 -  
272 - private static boolean isIgnoreArgs(Object object) {  
273 - Class<?> clazz = object.getClass();  
274 - // 处理数组的情况  
275 - if (clazz.isArray()) {  
276 - return IntStream.range(0, Array.getLength(object))  
277 - .anyMatch(index -> isIgnoreArgs(Array.get(object, index)));  
278 - }  
279 - // 递归,处理数组、Collection、Map 的情况  
280 - if (Collection.class.isAssignableFrom(clazz)) {  
281 - return ((Collection<?>) object).stream()  
282 - .anyMatch((Predicate<Object>) OperateLogV2Aspect::isIgnoreArgs);  
283 - }  
284 - if (Map.class.isAssignableFrom(clazz)) {  
285 - return isIgnoreArgs(((Map<?, ?>) object).values());  
286 - }  
287 - // obj  
288 - return object instanceof MultipartFile  
289 - || object instanceof HttpServletRequest  
290 - || object instanceof HttpServletResponse  
291 - || object instanceof BindingResult;  
292 - }  
293 -  
294 - private static RequestMethod obtainFirstMatchRequestMethod(RequestMethod[] requestMethods) {  
295 - if (ArrayUtil.isEmpty(requestMethods)) {  
296 - return null;  
297 - }  
298 - // 优先,匹配最优的 POST、PUT、DELETE  
299 - RequestMethod result = obtainFirstLogRequestMethod(requestMethods);  
300 - if (result != null) {  
301 - return result;  
302 - }  
303 - // 然后,匹配次优的 GET  
304 - result = Arrays.stream(requestMethods).filter(requestMethod -> requestMethod == RequestMethod.GET)  
305 - .findFirst().orElse(null);  
306 - if (result != null) {  
307 - return result;  
308 - }  
309 - // 兜底,获得第一个  
310 - return requestMethods[0];  
311 - }  
312 -  
313 - private static RequestMethod[] obtainRequestMethod(ProceedingJoinPoint joinPoint) {  
314 - RequestMapping requestMapping = AnnotationUtils.getAnnotation( // 使用 Spring 的工具类,可以处理 @RequestMapping 别名注解  
315 - ((MethodSignature) joinPoint.getSignature()).getMethod(), RequestMapping.class);  
316 - return requestMapping != null ? requestMapping.method() : new RequestMethod[]{};  
317 - }  
318 -  
319 - private static RequestMethod obtainFirstLogRequestMethod(RequestMethod[] requestMethods) {  
320 - if (ArrayUtil.isEmpty(requestMethods)) {  
321 - return null;  
322 - }  
323 - return Arrays.stream(requestMethods).filter(requestMethod ->  
324 - requestMethod == RequestMethod.POST  
325 - || requestMethod == RequestMethod.PUT  
326 - || requestMethod == RequestMethod.DELETE)  
327 - .findFirst().orElse(null);  
328 - }  
329 -  
330 -}  
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/enums/OperateLogV2Constants.java deleted
1 -package cn.iocoder.yudao.framework.operatelogv2.core.enums;  
2 -  
3 -// TODO @puhui999:这个类,是不是可以删除哈;  
4 -/**  
5 - * 操作日志常量接口  
6 - *  
7 - * @author HUIHUI  
8 - */  
9 -public interface OperateLogV2Constants {  
10 -  
11 - // ========== 开关字段-如果没有值默认就是记录 ==========  
12 -  
13 - /**  
14 - * 是否记录日志  
15 - */  
16 - String ENABLE = "enable";  
17 -  
18 - /**  
19 - * 是否记录方法参数  
20 - */  
21 - String IS_LOG_ARGS = "isLogArgs";  
22 -  
23 - /**  
24 - * 是否记录方法结果的数据  
25 - */  
26 - String IS_LOG_RESULT_DATA = "isLogResultData";  
27 -  
28 - // ========== 扩展 ==========  
29 -  
30 - /**  
31 - * 扩展信息  
32 - */  
33 - String EXTRA_KEY = "extra";  
34 -  
35 -}  
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/service/ILogRecordServiceImpl.java deleted
1 -package cn.iocoder.yudao.framework.operatelogv2.core.service;  
2 -  
3 -import cn.iocoder.yudao.framework.operatelogv2.core.aop.OperateLogV2Aspect;  
4 -import com.mzt.logapi.beans.LogRecord;  
5 -import com.mzt.logapi.context.LogRecordContext;  
6 -import com.mzt.logapi.service.ILogRecordService;  
7 -import lombok.extern.slf4j.Slf4j;  
8 -  
9 -import java.util.Collections;  
10 -import java.util.List;  
11 -  
12 -/**  
13 - * 操作日志 ILogRecordService 实现类  
14 - *  
15 - * 基于 {@link OperateLogV2Aspect} 实现,记录操作日志  
16 - *  
17 - * @author HUIHUI  
18 - */  
19 -@Slf4j  
20 -public class ILogRecordServiceImpl implements ILogRecordService {  
21 -  
22 - @Override  
23 - public void record(LogRecord logRecord) {  
24 - OperateLogV2Aspect.setContent(logRecord); // 操作日志  
25 - OperateLogV2Aspect.addExtra(LogRecordContext.getVariables()); // 扩展信息  
26 - // TODO @puhui999:这里是不是调用 operateLogApi 进行记录哈  
27 - }  
28 -  
29 - @Override  
30 - public List<LogRecord> queryLog(String bizNo, String type) {  
31 - throw new UnsupportedOperationException("不支持该操作,请使用 OperateLogApi 查询!");  
32 - }  
33 -  
34 - @Override  
35 - public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) {  
36 - throw new UnsupportedOperationException("不支持该操作,请使用 OperateLogApi 查询!");  
37 - }  
38 -  
39 -}  
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/package-info.java deleted
1 -package cn.iocoder.yudao.framework.operatelogv2;  
2 \ No newline at end of file 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1 -cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration  
2 -cn.iocoder.yudao.framework.operatelogv2.config.YudaoOperateLogV2Configuration  
3 \ No newline at end of file 1 \ No newline at end of file
  2 +cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration
4 \ No newline at end of file 3 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-security/pom.xml
@@ -50,6 +50,13 @@ @@ -50,6 +50,13 @@
50 <artifactId>guava</artifactId> 50 <artifactId>guava</artifactId>
51 </dependency> 51 </dependency>
52 52
  53 + <dependency>
  54 + <!-- Spring Boot 通用操作日志组件,基于注解实现 -->
  55 + <!-- 此组件解决的问题是:「谁」在「什么时间」对「什么」做了「什么事」 -->
  56 + <groupId>io.github.mouzt</groupId>
  57 + <artifactId>bizlog-sdk</artifactId>
  58 + </dependency>
  59 +
53 <!-- 业务组件 --> 60 <!-- 业务组件 -->
54 <dependency> 61 <dependency>
55 <groupId>cn.iocoder.boot</groupId> 62 <groupId>cn.iocoder.boot</groupId>
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/config/YudaoOperateLogV2Configuration.java renamed to yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogV2Configuration.java
1 -package cn.iocoder.yudao.framework.operatelogv2.config; 1 +package cn.iocoder.yudao.framework.operatelog.config;
2 2
3 -import cn.iocoder.yudao.framework.operatelogv2.core.aop.OperateLogV2Aspect;  
4 -import cn.iocoder.yudao.framework.operatelogv2.core.service.ILogRecordServiceImpl; 3 +import cn.iocoder.yudao.framework.operatelog.core.service.ILogRecordServiceImpl;
5 import com.mzt.logapi.service.ILogRecordService; 4 import com.mzt.logapi.service.ILogRecordService;
6 import com.mzt.logapi.starter.annotation.EnableLogRecord; 5 import com.mzt.logapi.starter.annotation.EnableLogRecord;
7 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
@@ -9,7 +8,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -9,7 +8,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
9 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Primary; 9 import org.springframework.context.annotation.Primary;
11 10
12 -// TODO @puhui999:思考了下,为了减少 starter 数量,在 security 组件里,增加一个 core/operatelog 包,然后 YudaoOperateLogV2Configuration 搞一个过去; 11 +
13 /** 12 /**
14 * mzt-biz-log 配置类 13 * mzt-biz-log 配置类
15 * 14 *
@@ -26,9 +25,4 @@ public class YudaoOperateLogV2Configuration { @@ -26,9 +25,4 @@ public class YudaoOperateLogV2Configuration {
26 return new ILogRecordServiceImpl(); 25 return new ILogRecordServiceImpl();
27 } 26 }
28 27
29 - @Bean  
30 - public OperateLogV2Aspect operateLogV2Aspect() {  
31 - return new OperateLogV2Aspect();  
32 - }  
33 -  
34 } 28 }
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.operatelog.core;
0 \ No newline at end of file 2 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/ILogRecordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.operatelog.core.service;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
  4 +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
  5 +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
  6 +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
  7 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
  8 +import com.mzt.logapi.beans.LogRecord;
  9 +import com.mzt.logapi.service.ILogRecordService;
  10 +import jakarta.annotation.Resource;
  11 +import jakarta.servlet.http.HttpServletRequest;
  12 +import lombok.extern.slf4j.Slf4j;
  13 +
  14 +import java.util.Collections;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 操作日志 ILogRecordService 实现类
  19 + *
  20 + * 基于 {@link OperateLogApi} 实现,记录操作日志
  21 + *
  22 + * @author HUIHUI
  23 + */
  24 +@Slf4j
  25 +public class ILogRecordServiceImpl implements ILogRecordService {
  26 +
  27 + @Resource
  28 + private OperateLogApi operateLogApi;
  29 +
  30 + @Override
  31 + public void record(LogRecord logRecord) {
  32 + OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO();
  33 + // 补全通用字段
  34 + reqDTO.setTraceId(TracerUtils.getTraceId());
  35 + // 补充用户信息
  36 + fillUserFields(reqDTO);
  37 + // 补全模块信息
  38 + fillModuleFields(reqDTO, logRecord);
  39 + // 补全请求信息
  40 + fillRequestFields(reqDTO);
  41 + // 异步记录日志
  42 + operateLogApi.createOperateLogV2(reqDTO);
  43 + // TODO 测试结束删除或搞个开关
  44 + log.info("操作日志 ===> {}", reqDTO);
  45 + }
  46 +
  47 + private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) {
  48 + reqDTO.setUserId(WebFrameworkUtils.getLoginUserId());
  49 + reqDTO.setUserType(WebFrameworkUtils.getLoginUserType());
  50 + }
  51 +
  52 + public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) {
  53 + reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户
  54 + reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户
  55 + reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号
  56 + reqDTO.setAction(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
  57 + reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
  58 + }
  59 +
  60 + private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {
  61 + // 获得 Request 对象
  62 + HttpServletRequest request = ServletUtils.getRequest();
  63 + if (request == null) {
  64 + return;
  65 + }
  66 + // 补全请求信息
  67 + reqDTO.setRequestMethod(request.getMethod());
  68 + reqDTO.setRequestUrl(request.getRequestURI());
  69 + reqDTO.setUserIp(ServletUtils.getClientIP(request));
  70 + reqDTO.setUserAgent(ServletUtils.getUserAgent(request));
  71 + }
  72 +
  73 + @Override
  74 + public List<LogRecord> queryLog(String bizNo, String type) {
  75 + return Collections.emptyList();
  76 + }
  77 +
  78 + @Override
  79 + public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) {
  80 + return Collections.emptyList();
  81 + }
  82 +
  83 +}
yudao-framework/yudao-spring-boot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1 cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration 1 cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration
2 -cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
  4 +cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration
4 \ No newline at end of file 5 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
9 -import cn.iocoder.yudao.framework.operatelogv2.core.vo.OperateLogV2PageReqVO;  
10 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; 9 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
11 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; 10 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -61,6 +60,7 @@ public class CrmCustomerController { @@ -61,6 +60,7 @@ public class CrmCustomerController {
61 60
62 @PostMapping("/create") 61 @PostMapping("/create")
63 @Operation(summary = "创建客户") 62 @Operation(summary = "创建客户")
  63 + @OperateLog(enable = false) // TODO 关闭原有日志记录
64 @PreAuthorize("@ss.hasPermission('crm:customer:create')") 64 @PreAuthorize("@ss.hasPermission('crm:customer:create')")
65 public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerCreateReqVO createReqVO) { 65 public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerCreateReqVO createReqVO) {
66 return success(customerService.createCustomer(createReqVO, getLoginUserId())); 66 return success(customerService.createCustomer(createReqVO, getLoginUserId()));
@@ -68,6 +68,7 @@ public class CrmCustomerController { @@ -68,6 +68,7 @@ public class CrmCustomerController {
68 68
69 @PutMapping("/update") 69 @PutMapping("/update")
70 @Operation(summary = "更新客户") 70 @Operation(summary = "更新客户")
  71 + @OperateLog(enable = false) // TODO 关闭原有日志记录
71 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 72 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
72 public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { 73 public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) {
73 customerService.updateCustomer(updateReqVO); 74 customerService.updateCustomer(updateReqVO);
@@ -76,6 +77,7 @@ public class CrmCustomerController { @@ -76,6 +77,7 @@ public class CrmCustomerController {
76 77
77 @DeleteMapping("/delete") 78 @DeleteMapping("/delete")
78 @Operation(summary = "删除客户") 79 @Operation(summary = "删除客户")
  80 + @OperateLog(enable = false) // TODO 关闭原有日志记录
79 @Parameter(name = "id", description = "编号", required = true) 81 @Parameter(name = "id", description = "编号", required = true)
80 @PreAuthorize("@ss.hasPermission('crm:customer:delete')") 82 @PreAuthorize("@ss.hasPermission('crm:customer:delete')")
81 public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) { 83 public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
@@ -132,6 +134,7 @@ public class CrmCustomerController { @@ -132,6 +134,7 @@ public class CrmCustomerController {
132 134
133 @PutMapping("/transfer") 135 @PutMapping("/transfer")
134 @Operation(summary = "客户转移") 136 @Operation(summary = "客户转移")
  137 + @OperateLog(enable = false) // TODO 关闭原有日志记录
135 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 138 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
136 public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { 139 public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) {
137 customerService.transferCustomer(reqVO, getLoginUserId()); 140 customerService.transferCustomer(reqVO, getLoginUserId());
@@ -140,9 +143,8 @@ public class CrmCustomerController { @@ -140,9 +143,8 @@ public class CrmCustomerController {
140 143
141 @GetMapping("/operate-log-page") 144 @GetMapping("/operate-log-page")
142 @Operation(summary = "获得客户操作日志") 145 @Operation(summary = "获得客户操作日志")
143 - @Parameter(name = "id", description = "编号", required = true, example = "1024")  
144 @PreAuthorize("@ss.hasPermission('crm:customer:query')") 146 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
145 - public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(OperateLogV2PageReqVO reqVO) { 147 + public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(CrmCustomerOperateLogPageReqVO reqVO) {
146 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 148 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
147 reqVO.setBizType(CRM_CUSTOMER); 149 reqVO.setBizType(CRM_CUSTOMER);
148 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class))); 150 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
@@ -151,6 +153,7 @@ public class CrmCustomerController { @@ -151,6 +153,7 @@ public class CrmCustomerController {
151 // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了; 153 // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了;
152 @PutMapping("/lock") 154 @PutMapping("/lock")
153 @Operation(summary = "锁定/解锁客户") 155 @Operation(summary = "锁定/解锁客户")
  156 + @OperateLog(enable = false) // TODO 关闭原有日志记录
154 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 157 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
155 public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { 158 public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) {
156 customerService.lockCustomer(updateReqVO); 159 customerService.lockCustomer(updateReqVO);
@@ -161,6 +164,7 @@ public class CrmCustomerController { @@ -161,6 +164,7 @@ public class CrmCustomerController {
161 164
162 @PutMapping("/put-pool") 165 @PutMapping("/put-pool")
163 @Operation(summary = "数据放入公海") 166 @Operation(summary = "数据放入公海")
  167 + @OperateLog(enable = false) // TODO 关闭原有日志记录
164 @Parameter(name = "id", description = "客户编号", required = true, example = "1024") 168 @Parameter(name = "id", description = "客户编号", required = true, example = "1024")
165 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 169 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
166 public CommonResult<Boolean> putCustomerPool(@RequestParam("id") Long id) { 170 public CommonResult<Boolean> putCustomerPool(@RequestParam("id") Long id) {
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/vo/OperateLogV2PageReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerOperateLogPageReqVO.java
1 -package cn.iocoder.yudao.framework.operatelogv2.core.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 6
7 -// TODO @puhui999:这个最好每个模块自己弄哈,放这里有点怪可能  
8 -@Schema(description = "管理后台 - 操作日志分页 Request VO") 7 +@Schema(description = "管理后台 - crm 客户操作日志分页 Request VO")
9 @Data 8 @Data
10 -public class OperateLogV2PageReqVO extends PageParam { 9 +public class CrmCustomerOperateLogPageReqVO extends PageParam {
11 10
12 @Schema(description = "模块数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 11 @Schema(description = "模块数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13 private Long bizId; 12 private Long bizId;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmIndustryParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmIndustryParseFunction.java
1 -package cn.iocoder.yudao.module.crm.framework.operatelog.parse; 1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; 5 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
5 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
@@ -8,7 +9,6 @@ import org.springframework.stereotype.Component; @@ -8,7 +9,6 @@ import org.springframework.stereotype.Component;
8 9
9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; 10 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
10 11
11 -// TODO @puhui999:还是放在 core 包下哈;  
12 /** 12 /**
13 * 自定义函数-通过行业编号获取行业信息 13 * 自定义函数-通过行业编号获取行业信息
14 * 14 *
@@ -30,8 +30,7 @@ public class CrmIndustryParseFunction implements IParseFunction { @@ -30,8 +30,7 @@ public class CrmIndustryParseFunction implements IParseFunction {
30 30
31 @Override 31 @Override
32 public String apply(Object value) { 32 public String apply(Object value) {
33 -// if (ObjUtil.isEmpty(value)) TODO @puhui999 可以直接替代哈;  
34 - if (value == null) { 33 + if (ObjUtil.isEmpty(value)) {
35 return ""; 34 return "";
36 } 35 }
37 if (StrUtil.isEmpty(value.toString())) { 36 if (StrUtil.isEmpty(value.toString())) {
@@ -39,12 +38,7 @@ public class CrmIndustryParseFunction implements IParseFunction { @@ -39,12 +38,7 @@ public class CrmIndustryParseFunction implements IParseFunction {
39 } 38 }
40 39
41 // 获取行业信息 40 // 获取行业信息
42 - // TODO @puhui999:这里可以不用 try catch 哇?  
43 - try {  
44 - return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString());  
45 - } catch (Exception ignored) {  
46 - }  
47 - return ""; 41 + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString());
48 } 42 }
49 43
50 } 44 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmLevelParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmLevelParseFunction.java
1 -package cn.iocoder.yudao.module.crm.framework.operatelog.parse; 1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; 5 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
5 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
@@ -29,7 +30,7 @@ public class CrmLevelParseFunction implements IParseFunction { @@ -29,7 +30,7 @@ public class CrmLevelParseFunction implements IParseFunction {
29 30
30 @Override 31 @Override
31 public String apply(Object value) { 32 public String apply(Object value) {
32 - if (value == null) { 33 + if (ObjUtil.isEmpty(value)) {
33 return ""; 34 return "";
34 } 35 }
35 if (StrUtil.isEmpty(value.toString())) { 36 if (StrUtil.isEmpty(value.toString())) {
@@ -37,10 +38,7 @@ public class CrmLevelParseFunction implements IParseFunction { @@ -37,10 +38,7 @@ public class CrmLevelParseFunction implements IParseFunction {
37 } 38 }
38 39
39 // 获取客户等级信息 40 // 获取客户等级信息
40 - try {  
41 - return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString());  
42 - } catch (Exception ignored) {  
43 - }  
44 - return ""; 41 + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString());
45 } 42 }
  43 +
46 } 44 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmSourceParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmSourceParseFunction.java
1 -package cn.iocoder.yudao.module.crm.framework.operatelog.parse; 1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; 5 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
5 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
@@ -29,7 +30,7 @@ public class CrmSourceParseFunction implements IParseFunction { @@ -29,7 +30,7 @@ public class CrmSourceParseFunction implements IParseFunction {
29 30
30 @Override 31 @Override
31 public String apply(Object value) { 32 public String apply(Object value) {
32 - if (value == null) { 33 + if (ObjUtil.isEmpty(value)) {
33 return ""; 34 return "";
34 } 35 }
35 if (StrUtil.isEmpty(value.toString())) { 36 if (StrUtil.isEmpty(value.toString())) {
@@ -37,10 +38,7 @@ public class CrmSourceParseFunction implements IParseFunction { @@ -37,10 +38,7 @@ public class CrmSourceParseFunction implements IParseFunction {
37 } 38 }
38 39
39 // 获取客户来源信息 40 // 获取客户来源信息
40 - try {  
41 - return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString());  
42 - } catch (Exception ignored) {  
43 - }  
44 - return ""; 41 + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString());
45 } 42 }
  43 +
46 } 44 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.customer; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.customer;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -import cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants;  
7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
@@ -53,7 +52,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -53,7 +52,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
53 52
54 @Override 53 @Override
55 @Transactional(rollbackFor = Exception.class) 54 @Transactional(rollbackFor = Exception.class)
56 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#customerId}}", success = "创建了客户") 55 + @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户")
57 public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) { 56 public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) {
58 // 插入 57 // 插入
59 CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO); 58 CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO);
@@ -71,7 +70,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -71,7 +70,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
71 // TODO @puhui999:测试下,能不能打出用户数据的变更。啊哈,可以打完微信发我下; 70 // TODO @puhui999:测试下,能不能打出用户数据的变更。啊哈,可以打完微信发我下;
72 @Override 71 @Override
73 @Transactional(rollbackFor = Exception.class) 72 @Transactional(rollbackFor = Exception.class)
74 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}") 73 + @LogRecord(type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}", extra = "{{#extra}}")
75 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 74 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
76 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { 75 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
77 // 校验存在 76 // 校验存在
@@ -83,14 +82,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -83,14 +82,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
83 82
84 // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null 83 // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null
85 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class)); 84 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class));
  85 + // TODO 扩展信息测试
86 HashMap<String, Object> extra = new HashMap<>(); 86 HashMap<String, Object> extra = new HashMap<>();
87 extra.put("tips", "随便记录一点啦"); 87 extra.put("tips", "随便记录一点啦");
88 - LogRecordContext.putVariable(OperateLogV2Constants.EXTRA_KEY, extra); 88 + LogRecordContext.putVariable("extra", extra);
89 } 89 }
90 90
91 @Override 91 @Override
92 @Transactional(rollbackFor = Exception.class) 92 @Transactional(rollbackFor = Exception.class)
93 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#id}}", success = "删除了客户") 93 + @LogRecord(type = CRM_CUSTOMER, subType = "删除客户", bizNo = "{{#id}}", success = "删除了客户")
94 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 94 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
95 public void deleteCustomer(Long id) { 95 public void deleteCustomer(Long id) {
96 // 校验存在 96 // 校验存在
@@ -141,7 +141,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -141,7 +141,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
141 141
142 @Override 142 @Override
143 @Transactional(rollbackFor = Exception.class) 143 @Transactional(rollbackFor = Exception.class)
144 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) 144 + @LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
145 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) 145 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
146 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { 146 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
147 // 1. 校验客户是否存在 147 // 1. 校验客户是否存在
@@ -158,7 +158,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -158,7 +158,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
158 } 158 }
159 159
160 @Override 160 @Override
161 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") 161 + @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户")
162 public void lockCustomer(CrmCustomerUpdateReqVO updateReqVO) { 162 public void lockCustomer(CrmCustomerUpdateReqVO updateReqVO) {
163 // 校验存在 163 // 校验存在
164 validateCustomerExists(updateReqVO.getId()); 164 validateCustomerExists(updateReqVO.getId());
@@ -172,7 +172,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -172,7 +172,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
172 172
173 @Override 173 @Override
174 @Transactional(rollbackFor = Exception.class) 174 @Transactional(rollbackFor = Exception.class)
175 - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#id}}", success = "将客户放入了公海") 175 + @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海")
176 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 176 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
177 public void putCustomerPool(Long id) { 177 public void putCustomerPool(Long id) {
178 // 1. 校验存在 178 // 1. 校验存在
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2CreateReqDTO.java
@@ -5,9 +5,6 @@ import jakarta.validation.constraints.NotEmpty; @@ -5,9 +5,6 @@ import jakarta.validation.constraints.NotEmpty;
5 import jakarta.validation.constraints.NotNull; 5 import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 -import java.time.LocalDateTime;  
9 -import java.util.Map;  
10 -  
11 /** 8 /**
12 * 系统操作日志 Create Req BO 9 * 系统操作日志 Create Req BO
13 * 10 *
@@ -56,12 +53,12 @@ public class OperateLogV2CreateReqDTO { @@ -56,12 +53,12 @@ public class OperateLogV2CreateReqDTO {
56 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 53 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
57 */ 54 */
58 @NotEmpty(message = "操作内容不能为空") 55 @NotEmpty(message = "操作内容不能为空")
59 - private String content; 56 + private String action;
60 /** 57 /**
61 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) 58 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
62 * 例如说,记录订单编号,{ orderId: "1"} 59 * 例如说,记录订单编号,{ orderId: "1"}
63 */ 60 */
64 - private Map<String, Object> extra; 61 + private String extra;
65 62
66 /** 63 /**
67 * 请求方法名 64 * 请求方法名
@@ -84,38 +81,4 @@ public class OperateLogV2CreateReqDTO { @@ -84,38 +81,4 @@ public class OperateLogV2CreateReqDTO {
84 @NotEmpty(message = "浏览器 UA 不能为空") 81 @NotEmpty(message = "浏览器 UA 不能为空")
85 private String userAgent; 82 private String userAgent;
86 83
87 - /**  
88 - * Java 方法名  
89 - */  
90 - private String javaMethod;  
91 - /**  
92 - * Java 方法的参数  
93 - */  
94 - private String javaMethodArgs;  
95 -  
96 - /**  
97 - * 开始时间  
98 - */  
99 - private LocalDateTime startTime;  
100 -  
101 - /**  
102 - * 执行时长,单位:毫秒  
103 - */  
104 - private Integer duration;  
105 -  
106 - /**  
107 - * 结果码  
108 - */  
109 - private Integer resultCode;  
110 -  
111 - /**  
112 - * 结果提示  
113 - */  
114 - private String resultMsg;  
115 -  
116 - /**  
117 - * 结果数据  
118 - */  
119 - private String resultData;  
120 -  
121 } 84 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java
@@ -2,9 +2,6 @@ package cn.iocoder.yudao.module.system.api.logger.dto; @@ -2,9 +2,6 @@ package cn.iocoder.yudao.module.system.api.logger.dto;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
5 -import java.time.LocalDateTime;  
6 -import java.util.Map;  
7 -  
8 /** 5 /**
9 * 系统操作日志 Resp DTO 6 * 系统操作日志 Resp DTO
10 * 7 *
@@ -44,11 +41,11 @@ public class OperateLogV2RespDTO { @@ -44,11 +41,11 @@ public class OperateLogV2RespDTO {
44 /** 41 /**
45 * 操作内容 42 * 操作内容
46 */ 43 */
47 - private String content; 44 + private String action;
48 /** 45 /**
49 * 拓展字段 46 * 拓展字段
50 */ 47 */
51 - private Map<String, Object> extra; 48 + private String extra;
52 49
53 /** 50 /**
54 * 请求方法名 51 * 请求方法名
@@ -67,43 +64,4 @@ public class OperateLogV2RespDTO { @@ -67,43 +64,4 @@ public class OperateLogV2RespDTO {
67 */ 64 */
68 private String userAgent; 65 private String userAgent;
69 66
70 - /**  
71 - * Java 方法名  
72 - */  
73 - private String javaMethod;  
74 - /**  
75 - * Java 方法的参数  
76 - */  
77 - private String javaMethodArgs;  
78 -  
79 - /**  
80 - * 开始时间  
81 - */  
82 - private LocalDateTime startTime;  
83 -  
84 - /**  
85 - * 执行时长,单位:毫秒  
86 - */  
87 - private Integer duration;  
88 -  
89 - /**  
90 - * 结果码  
91 - */  
92 - private Integer resultCode;  
93 -  
94 - /**  
95 - * 结果提示  
96 - */  
97 - private String resultMsg;  
98 -  
99 - /**  
100 - * 结果数据  
101 - */  
102 - private String resultData;  
103 -  
104 - /**  
105 - * 创建时间  
106 - */  
107 - private LocalDateTime createTime;  
108 -  
109 } 67 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java
@@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.system.api.logger; @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.system.api.logger;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
6 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; 5 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
7 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO; 6 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
8 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; 7 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
9 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; 8 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
  9 +import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert;
10 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
11 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
12 import cn.iocoder.yudao.module.system.service.logger.OperateLogService; 12 import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
@@ -17,10 +17,8 @@ import org.springframework.stereotype.Service; @@ -17,10 +17,8 @@ import org.springframework.stereotype.Service;
17 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
18 18
19 import java.util.List; 19 import java.util.List;
20 -import java.util.Map;  
21 20
22 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;  
23 -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; 21 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
24 22
25 /** 23 /**
26 * 操作日志 API 实现类 24 * 操作日志 API 实现类
@@ -56,17 +54,7 @@ public class OperateLogApiImpl implements OperateLogApi { @@ -56,17 +54,7 @@ public class OperateLogApiImpl implements OperateLogApi {
56 54
57 // 获取用户 55 // 获取用户
58 List<AdminUserDO> userList = adminUserService.getUserList(convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId)); 56 List<AdminUserDO> userList = adminUserService.getUserList(convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId));
59 - return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));  
60 - }  
61 -  
62 - // TODO @puhui999:这种 convert 还是放到 convert 类里,  
63 - private static List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {  
64 - Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);  
65 - return convertList(logList, item -> {  
66 - OperateLogV2RespDTO respDTO = BeanUtils.toBean(item, OperateLogV2RespDTO.class);  
67 - findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));  
68 - return respDTO;  
69 - }); 57 + return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList);
70 } 58 }
71 59
72 } 60 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/logger/OperateLogConvert.java
1 package cn.iocoder.yudao.module.system.convert.logger; 1 package cn.iocoder.yudao.module.system.convert.logger;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
6 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; 8 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;
7 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; 9 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
  10 +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
8 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
9 import org.mapstruct.Mapper; 12 import org.mapstruct.Mapper;
10 import org.mapstruct.factory.Mappers; 13 import org.mapstruct.factory.Mappers;
@@ -12,6 +15,9 @@ import org.mapstruct.factory.Mappers; @@ -12,6 +15,9 @@ import org.mapstruct.factory.Mappers;
12 import java.util.List; 15 import java.util.List;
13 import java.util.Map; 16 import java.util.Map;
14 17
  18 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  19 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  20 +
15 @Mapper 21 @Mapper
16 public interface OperateLogConvert { 22 public interface OperateLogConvert {
17 23
@@ -25,4 +31,17 @@ public interface OperateLogConvert { @@ -25,4 +31,17 @@ public interface OperateLogConvert {
25 }); 31 });
26 } 32 }
27 33
  34 + default PageResult<OperateLogV2RespDTO> convertPage(PageResult<OperateLogV2DO> operateLogPage, List<AdminUserDO> userList) {
  35 + return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));
  36 + }
  37 +
  38 + private static List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {
  39 + Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);
  40 + return CollectionUtils.convertList(logList, item -> {
  41 + OperateLogV2RespDTO respDTO = BeanUtils.toBean(item, OperateLogV2RespDTO.class);
  42 + findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));
  43 + return respDTO;
  44 + });
  45 + }
  46 +
28 } 47 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java
1 package cn.iocoder.yudao.module.system.dal.dataobject.logger; 1 package cn.iocoder.yudao.module.system.dal.dataobject.logger;
2 2
3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
5 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
6 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
7 -import com.baomidou.mybatisplus.annotation.TableField;  
8 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
10 -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;  
11 import lombok.Data; 8 import lombok.Data;
12 import lombok.EqualsAndHashCode; 9 import lombok.EqualsAndHashCode;
13 10
14 -import java.time.LocalDateTime;  
15 -import java.util.Map;  
16 -  
17 /** 11 /**
18 * 操作日志表 V2 12 * 操作日志表 V2
19 * 13 *
@@ -26,16 +20,6 @@ import java.util.Map; @@ -26,16 +20,6 @@ import java.util.Map;
26 public class OperateLogV2DO extends BaseDO { 20 public class OperateLogV2DO extends BaseDO {
27 21
28 /** 22 /**
29 - * {@link #javaMethodArgs} 的最大长度  
30 - */  
31 - public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000;  
32 -  
33 - /**  
34 - * {@link #resultData} 的最大长度  
35 - */  
36 - public static final Integer RESULT_MAX_LENGTH = 4000;  
37 -  
38 - /**  
39 * 日志主键 23 * 日志主键
40 */ 24 */
41 @TableId 25 @TableId
@@ -70,20 +54,18 @@ public class OperateLogV2DO extends BaseDO { @@ -70,20 +54,18 @@ public class OperateLogV2DO extends BaseDO {
70 * 操作模块业务编号 54 * 操作模块业务编号
71 */ 55 */
72 private Long bizId; 56 private Long bizId;
73 - // TODO @puhui999:content 改成 action,extra 换成 String。注释就直接用 mzt,和它完全对应好了。  
74 /** 57 /**
75 - * 操作内容,记录整个操作的明细 58 + * 日志内容,记录整个操作的明细
76 * 59 *
77 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 60 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
78 */ 61 */
79 - private String content; 62 + private String action;
80 /** 63 /**
81 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) 64 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
82 * 65 *
83 * 例如说,记录订单编号,{ orderId: "1"} 66 * 例如说,记录订单编号,{ orderId: "1"}
84 */ 67 */
85 - @TableField(typeHandler = JacksonTypeHandler.class)  
86 - private Map<String, Object> extra; 68 + private String extra;
87 69
88 /** 70 /**
89 * 请求方法名 71 * 请求方法名
@@ -102,44 +84,4 @@ public class OperateLogV2DO extends BaseDO { @@ -102,44 +84,4 @@ public class OperateLogV2DO extends BaseDO {
102 */ 84 */
103 private String userAgent; 85 private String userAgent;
104 86
105 - // TODO @puhui999:微信已经讨论,下面的字段都不要哈;  
106 - /**  
107 - * Java 方法名  
108 - */  
109 - private String javaMethod;  
110 - /**  
111 - * Java 方法的参数  
112 - *  
113 - * 实际格式为 Map<String, Object>  
114 - * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败  
115 - * 其中,key 为参数名,value 为参数值  
116 - */  
117 - private String javaMethodArgs;  
118 - /**  
119 - * 开始时间  
120 - */  
121 - private LocalDateTime startTime;  
122 - /**  
123 - * 执行时长,单位:毫秒  
124 - */  
125 - private Integer duration;  
126 - /**  
127 - * 结果码  
128 - *  
129 - * 目前使用的 {@link CommonResult#getCode()} 属性  
130 - */  
131 - private Integer resultCode;  
132 - /**  
133 - * 结果提示  
134 - *  
135 - * 目前使用的 {@link CommonResult#getMsg()} 属性  
136 - */  
137 - private String resultMsg;  
138 - /**  
139 - * 结果数据  
140 - *  
141 - * 如果是对象,则使用 JSON 格式化  
142 - */  
143 - private String resultData;  
144 -  
145 } 87 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/parse/AdminUserParseFunction.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/AdminUserParseFunction.java
1 -package cn.iocoder.yudao.module.system.framework.operatelog.parse; 1 +package cn.iocoder.yudao.module.system.framework.operatelog.core;
2 2
3 import cn.hutool.core.util.ObjUtil; 3 import cn.hutool.core.util.ObjUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
@@ -9,7 +9,6 @@ import jakarta.annotation.Resource; @@ -9,7 +9,6 @@ import jakarta.annotation.Resource;
9 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
10 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
11 11
12 -// TODO @puhui999:这个微信讨论下,function 叫啥好哈;  
13 /** 12 /**
14 * 自定义函数-通过用户编号获取用户信息 13 * 自定义函数-通过用户编号获取用户信息
15 * 14 *
@@ -27,15 +26,12 @@ public class AdminUserParseFunction implements IParseFunction { @@ -27,15 +26,12 @@ public class AdminUserParseFunction implements IParseFunction {
27 return "getAdminUserById"; 26 return "getAdminUserById";
28 } 27 }
29 28
30 - // TODO @puhui999:这个方法的实现优化下哈;  
31 @Override 29 @Override
32 public String apply(Object value) { 30 public String apply(Object value) {
33 - if (value == null) {  
34 - //log.warn("(getAdminUserById) 解析异常参数为 null"); 31 + if (ObjUtil.isEmpty(value)) {
35 return ""; 32 return "";
36 } 33 }
37 if (StrUtil.isEmpty(value.toString())) { 34 if (StrUtil.isEmpty(value.toString())) {
38 - //log.warn("(getAdminUserById) 解析异常参数为空");  
39 return ""; 35 return "";
40 } 36 }
41 37
@@ -52,4 +48,5 @@ public class AdminUserParseFunction implements IParseFunction { @@ -52,4 +48,5 @@ public class AdminUserParseFunction implements IParseFunction {
52 } 48 }
53 return nickname; 49 return nickname;
54 } 50 }
  51 +
55 } 52 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/parse/AreaParseFunction.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/AreaParseFunction.java
1 -package cn.iocoder.yudao.module.system.framework.operatelog.parse; 1 +package cn.iocoder.yudao.module.system.framework.operatelog.core;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 5 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
5 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
6 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
7 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
8 9
9 -// TODO @puhui999:还是放在 core 包下哈;  
10 /** 10 /**
11 * 自定义函数-通过区域编号获取区域信息 11 * 自定义函数-通过区域编号获取区域信息
12 * 12 *
@@ -28,7 +28,7 @@ public class AreaParseFunction implements IParseFunction { @@ -28,7 +28,7 @@ public class AreaParseFunction implements IParseFunction {
28 28
29 @Override 29 @Override
30 public String apply(Object value) { 30 public String apply(Object value) {
31 - if (value == null) { 31 + if (ObjUtil.isEmpty(value)) {
32 return ""; 32 return "";
33 } 33 }
34 if (StrUtil.isEmpty(value.toString())) { 34 if (StrUtil.isEmpty(value.toString())) {
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java
@@ -71,8 +71,6 @@ public class OperateLogServiceImpl implements OperateLogService { @@ -71,8 +71,6 @@ public class OperateLogServiceImpl implements OperateLogService {
71 @Override 71 @Override
72 public void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO) { 72 public void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO) {
73 OperateLogV2DO log = BeanUtils.toBean(createReqBO, OperateLogV2DO.class); 73 OperateLogV2DO log = BeanUtils.toBean(createReqBO, OperateLogV2DO.class);
74 - log.setJavaMethodArgs(StrUtils.maxLength(log.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));  
75 - log.setResultData(StrUtils.maxLength(log.getResultData(), RESULT_MAX_LENGTH));  
76 operateLogV2Mapper.insert(log); 74 operateLogV2Mapper.insert(log);
77 } 75 }
78 76
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
@@ -21,15 +21,14 @@ import cn.iocoder.yudao.module.system.service.social.SocialUserService; @@ -21,15 +21,14 @@ import cn.iocoder.yudao.module.system.service.social.SocialUserService;
21 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 21 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
22 import com.xingyuv.captcha.model.common.ResponseModel; 22 import com.xingyuv.captcha.model.common.ResponseModel;
23 import com.xingyuv.captcha.service.CaptchaService; 23 import com.xingyuv.captcha.service.CaptchaService;
24 -import org.junit.jupiter.api.BeforeEach;  
25 -import org.junit.jupiter.api.Test;  
26 -import org.springframework.boot.test.mock.mockito.MockBean;  
27 -import org.springframework.context.annotation.Import;  
28 -  
29 import jakarta.annotation.Resource; 24 import jakarta.annotation.Resource;
30 import jakarta.validation.ConstraintViolationException; 25 import jakarta.validation.ConstraintViolationException;
31 import jakarta.validation.Validation; 26 import jakarta.validation.Validation;
32 import jakarta.validation.Validator; 27 import jakarta.validation.Validator;
  28 +import org.junit.jupiter.api.BeforeEach;
  29 +import org.junit.jupiter.api.Test;
  30 +import org.springframework.boot.test.mock.mockito.MockBean;
  31 +import org.springframework.context.annotation.Import;
33 32
34 import static cn.hutool.core.util.RandomUtil.randomEle; 33 import static cn.hutool.core.util.RandomUtil.randomEle;
35 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 34 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@@ -237,7 +236,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { @@ -237,7 +236,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
237 // mock 方法(绑定的用户编号) 236 // mock 方法(绑定的用户编号)
238 Long userId = 1L; 237 Long userId = 1L;
239 when(socialUserService.getSocialUserByCode(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), 238 when(socialUserService.getSocialUserByCode(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()),
240 - eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId)); 239 + eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), randomString(), randomString(), userId));
241 // mock(用户) 240 // mock(用户)
242 AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); 241 AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId));
243 when(userService.getUser(eq(userId))).thenReturn(user); 242 when(userService.getUser(eq(userId))).thenReturn(user);