Commit 1fae341cae3ab3667757c2c766b3606fc78bf9e6
1 parent
55a215da
重构操作日志记录实现
Showing
22 changed files
with
491 additions
and
106 deletions
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogAutoConfiguration.java
| 1 | 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; | |
| 7 | 3 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 8 | -import org.springframework.context.annotation.Bean; | |
| 9 | 4 | |
| 10 | 5 | @AutoConfiguration |
| 11 | 6 | public class YudaoOperateLogAutoConfiguration { |
| 12 | 7 | |
| 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 | - } | |
| 8 | + //@Bean | |
| 9 | + //public OperateLogAspect operateLogAspect() { | |
| 10 | + // return new OperateLogAspect(); | |
| 11 | + //} | |
| 12 | + // | |
| 13 | + //@Bean | |
| 14 | + //public OperateLogFrameworkService operateLogFrameworkService(OperateLogApi operateLogApi) { | |
| 15 | + // return new OperateLogFrameworkServiceImpl(operateLogApi); | |
| 16 | + //} | |
| 22 | 17 | |
| 23 | 18 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/config/YudaoOperateLogV2Configuration.java
| 1 | 1 | package cn.iocoder.yudao.framework.operatelogv2.config; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.operatelogv2.core.aop.OperateLogV2Aspect; | |
| 3 | 4 | import cn.iocoder.yudao.framework.operatelogv2.core.service.ILogRecordServiceImpl; |
| 4 | -import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; | |
| 5 | 5 | import com.mzt.logapi.service.ILogRecordService; |
| 6 | 6 | import com.mzt.logapi.starter.annotation.EnableLogRecord; |
| 7 | 7 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -21,8 +21,13 @@ public class YudaoOperateLogV2Configuration { |
| 21 | 21 | |
| 22 | 22 | @Bean |
| 23 | 23 | @Primary |
| 24 | - public ILogRecordService iLogRecordServiceImpl(OperateLogApi operateLogApi) { | |
| 25 | - return new ILogRecordServiceImpl(operateLogApi); | |
| 24 | + public ILogRecordService iLogRecordServiceImpl() { | |
| 25 | + return new ILogRecordServiceImpl(); | |
| 26 | + } | |
| 27 | + | |
| 28 | + @Bean | |
| 29 | + public OperateLogV2Aspect operateLogV2Aspect() { | |
| 30 | + return new OperateLogV2Aspect(); | |
| 26 | 31 | } |
| 27 | 32 | |
| 28 | 33 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/aop/OperateLogV2Aspect.java
0 → 100644
| 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 io.swagger.v3.oas.annotations.tags.Tag; | |
| 20 | +import jakarta.annotation.Resource; | |
| 21 | +import jakarta.servlet.http.HttpServletRequest; | |
| 22 | +import jakarta.servlet.http.HttpServletResponse; | |
| 23 | +import lombok.extern.slf4j.Slf4j; | |
| 24 | +import org.aspectj.lang.ProceedingJoinPoint; | |
| 25 | +import org.aspectj.lang.annotation.Around; | |
| 26 | +import org.aspectj.lang.annotation.Aspect; | |
| 27 | +import org.aspectj.lang.reflect.MethodSignature; | |
| 28 | +import org.springframework.core.annotation.AnnotationUtils; | |
| 29 | +import org.springframework.validation.BindingResult; | |
| 30 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 31 | +import org.springframework.web.bind.annotation.RequestMethod; | |
| 32 | +import org.springframework.web.multipart.MultipartFile; | |
| 33 | + | |
| 34 | +import java.lang.annotation.Annotation; | |
| 35 | +import java.lang.reflect.Array; | |
| 36 | +import java.time.LocalDateTime; | |
| 37 | +import java.util.Arrays; | |
| 38 | +import java.util.Collection; | |
| 39 | +import java.util.HashMap; | |
| 40 | +import java.util.Map; | |
| 41 | +import java.util.function.Predicate; | |
| 42 | +import java.util.stream.IntStream; | |
| 43 | + | |
| 44 | +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR; | |
| 45 | +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS; | |
| 46 | +import static cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants.*; | |
| 47 | + | |
| 48 | +/** | |
| 49 | + * 拦截使用 @Operation 注解 | |
| 50 | + * | |
| 51 | + * @author HUIHUI | |
| 52 | + */ | |
| 53 | +@Aspect | |
| 54 | +@Slf4j | |
| 55 | +public class OperateLogV2Aspect { | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * 用于记录操作内容的上下文 | |
| 59 | + * | |
| 60 | + * @see OperateLogV2CreateReqDTO#getContent() | |
| 61 | + */ | |
| 62 | + private static final ThreadLocal<LogRecord> CONTENT = new ThreadLocal<>(); | |
| 63 | + /** | |
| 64 | + * 用于记录拓展字段的上下文 | |
| 65 | + * | |
| 66 | + * @see OperateLogV2CreateReqDTO#getExtra() | |
| 67 | + */ | |
| 68 | + private static final ThreadLocal<Map<String, Object>> EXTRA = new ThreadLocal<>(); | |
| 69 | + | |
| 70 | + @Resource | |
| 71 | + private OperateLogApi operateLogApi; | |
| 72 | + | |
| 73 | + @Around("@annotation(operation)") | |
| 74 | + public Object around(ProceedingJoinPoint joinPoint, Operation operation) throws Throwable { | |
| 75 | + RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint)); | |
| 76 | + if (requestMethod == RequestMethod.GET) { // 跳过 get 方法 | |
| 77 | + return joinPoint.proceed(); | |
| 78 | + } | |
| 79 | + | |
| 80 | + // 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录 | |
| 81 | + Integer userType = WebFrameworkUtils.getLoginUserType(); | |
| 82 | + if (ObjUtil.notEqual(userType, UserTypeEnum.ADMIN.getValue())) { | |
| 83 | + return joinPoint.proceed(); | |
| 84 | + } | |
| 85 | + | |
| 86 | + // 记录开始时间 | |
| 87 | + LocalDateTime startTime = LocalDateTime.now(); | |
| 88 | + try { | |
| 89 | + // 执行原有方法 | |
| 90 | + Object result = joinPoint.proceed(); | |
| 91 | + // 记录正常执行时的操作日志 | |
| 92 | + this.log(joinPoint, operation, startTime, result, null); | |
| 93 | + return result; | |
| 94 | + } catch (Throwable exception) { | |
| 95 | + this.log(joinPoint, operation, startTime, null, exception); | |
| 96 | + throw exception; | |
| 97 | + } finally { | |
| 98 | + clearThreadLocal(); | |
| 99 | + } | |
| 100 | + } | |
| 101 | + | |
| 102 | + public static void setContent(LogRecord content) { | |
| 103 | + CONTENT.set(content); | |
| 104 | + } | |
| 105 | + | |
| 106 | + public static void addExtra(String key, Object value) { | |
| 107 | + if (EXTRA.get() == null) { | |
| 108 | + EXTRA.set(new HashMap<>()); | |
| 109 | + } | |
| 110 | + EXTRA.get().put(key, value); | |
| 111 | + } | |
| 112 | + | |
| 113 | + public static void addExtra(Map<String, Object> extra) { | |
| 114 | + if (EXTRA.get() == null) { | |
| 115 | + EXTRA.set(new HashMap<>()); | |
| 116 | + } | |
| 117 | + EXTRA.get().putAll(extra); | |
| 118 | + } | |
| 119 | + | |
| 120 | + private static void clearThreadLocal() { | |
| 121 | + CONTENT.remove(); | |
| 122 | + EXTRA.remove(); | |
| 123 | + } | |
| 124 | + | |
| 125 | + private void log(ProceedingJoinPoint joinPoint, Operation operation, | |
| 126 | + LocalDateTime startTime, Object result, Throwable exception) { | |
| 127 | + try { | |
| 128 | + // 判断不记录的情况(默认没有值就是记录) | |
| 129 | + if (EXTRA.get() != null && EXTRA.get().get(ENABLE) != null) { | |
| 130 | + return; | |
| 131 | + } | |
| 132 | + // 真正记录操作日志 | |
| 133 | + this.log0(joinPoint, operation, startTime, result, exception); | |
| 134 | + } catch (Throwable ex) { | |
| 135 | + log.error("[log][记录操作日志时,发生异常,其中参数是 joinPoint({}) apiOperation({}) result({}) exception({}) ]", | |
| 136 | + joinPoint, operation, result, exception, ex); | |
| 137 | + } | |
| 138 | + } | |
| 139 | + | |
| 140 | + private void log0(ProceedingJoinPoint joinPoint, Operation operation, | |
| 141 | + LocalDateTime startTime, Object result, Throwable exception) { | |
| 142 | + OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO(); | |
| 143 | + // 补全通用字段 | |
| 144 | + reqDTO.setTraceId(TracerUtils.getTraceId()); | |
| 145 | + reqDTO.setStartTime(startTime); | |
| 146 | + // 补充用户信息 | |
| 147 | + fillUserFields(reqDTO); | |
| 148 | + // 补全模块信息 | |
| 149 | + fillModuleFields(reqDTO, joinPoint, operation); | |
| 150 | + // 补全请求信息 | |
| 151 | + fillRequestFields(reqDTO); | |
| 152 | + // 补全方法信息 | |
| 153 | + fillMethodFields(reqDTO, joinPoint, startTime, result, exception); | |
| 154 | + | |
| 155 | + // 异步记录日志 | |
| 156 | + operateLogApi.createOperateLogV2(reqDTO); | |
| 157 | + } | |
| 158 | + | |
| 159 | + private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) { | |
| 160 | + reqDTO.setUserId(WebFrameworkUtils.getLoginUserId()); | |
| 161 | + reqDTO.setUserType(WebFrameworkUtils.getLoginUserType()); | |
| 162 | + } | |
| 163 | + | |
| 164 | + private static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, ProceedingJoinPoint joinPoint, Operation operation) { | |
| 165 | + LogRecord logRecord = CONTENT.get(); | |
| 166 | + reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 | |
| 167 | + reqDTO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 | |
| 168 | + if (EXTRA.get() != null) { | |
| 169 | + reqDTO.setExtra((Map<String, Object>) EXTRA.get().get(EXTRA_KEY)); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} | |
| 170 | + } | |
| 171 | + | |
| 172 | + // type 属性 | |
| 173 | + if (logRecord.getType() != null) { | |
| 174 | + reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户 | |
| 175 | + } | |
| 176 | + if (StrUtil.isEmpty(reqDTO.getType())) { | |
| 177 | + Tag tag = getClassAnnotation(joinPoint, Tag.class); | |
| 178 | + if (tag != null) { | |
| 179 | + // 优先读取 @Tag 的 name 属性 | |
| 180 | + if (StrUtil.isNotEmpty(tag.name())) { | |
| 181 | + reqDTO.setType(tag.name()); | |
| 182 | + } | |
| 183 | + // 没有的话,读取 @API 的 description 属性 | |
| 184 | + if (StrUtil.isEmpty(reqDTO.getType()) && ArrayUtil.isNotEmpty(tag.description())) { | |
| 185 | + reqDTO.setType(tag.description()); | |
| 186 | + } | |
| 187 | + } | |
| 188 | + } | |
| 189 | + // subType 属性 | |
| 190 | + if (logRecord.getSubType() != null) { | |
| 191 | + reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户 | |
| 192 | + } | |
| 193 | + if (StrUtil.isEmpty(reqDTO.getSubType()) && operation != null) { | |
| 194 | + reqDTO.setSubType(operation.summary()); | |
| 195 | + } | |
| 196 | + | |
| 197 | + } | |
| 198 | + | |
| 199 | + private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) { | |
| 200 | + // 获得 Request 对象 | |
| 201 | + HttpServletRequest request = ServletUtils.getRequest(); | |
| 202 | + if (request == null) { | |
| 203 | + return; | |
| 204 | + } | |
| 205 | + // 补全请求信息 | |
| 206 | + reqDTO.setRequestMethod(request.getMethod()); | |
| 207 | + reqDTO.setRequestUrl(request.getRequestURI()); | |
| 208 | + reqDTO.setUserIp(ServletUtils.getClientIP(request)); | |
| 209 | + reqDTO.setUserAgent(ServletUtils.getUserAgent(request)); | |
| 210 | + } | |
| 211 | + | |
| 212 | + private static void fillMethodFields(OperateLogV2CreateReqDTO reqDTO, ProceedingJoinPoint joinPoint, LocalDateTime startTime, | |
| 213 | + Object result, Throwable exception) { | |
| 214 | + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); | |
| 215 | + reqDTO.setJavaMethod(methodSignature.toString()); | |
| 216 | + if (EXTRA.get().get(IS_LOG_ARGS) == null) { | |
| 217 | + reqDTO.setJavaMethodArgs(obtainMethodArgs(joinPoint)); | |
| 218 | + } | |
| 219 | + if (EXTRA.get().get(IS_LOG_RESULT_DATA) == null) { | |
| 220 | + reqDTO.setResultData(obtainResultData(result)); | |
| 221 | + } | |
| 222 | + reqDTO.setDuration((int) (LocalDateTimeUtil.between(startTime, LocalDateTime.now()).toMillis())); | |
| 223 | + // (正常)处理 resultCode 和 resultMsg 字段 | |
| 224 | + if (result instanceof CommonResult) { | |
| 225 | + CommonResult<?> commonResult = (CommonResult<?>) result; | |
| 226 | + reqDTO.setResultCode(commonResult.getCode()); | |
| 227 | + reqDTO.setResultMsg(commonResult.getMsg()); | |
| 228 | + } else { | |
| 229 | + reqDTO.setResultCode(SUCCESS.getCode()); | |
| 230 | + } | |
| 231 | + // (异常)处理 resultCode 和 resultMsg 字段 | |
| 232 | + if (exception != null) { | |
| 233 | + reqDTO.setResultCode(INTERNAL_SERVER_ERROR.getCode()); | |
| 234 | + reqDTO.setResultMsg(ExceptionUtil.getRootCauseMessage(exception)); | |
| 235 | + } | |
| 236 | + } | |
| 237 | + | |
| 238 | + @SuppressWarnings("SameParameterValue") | |
| 239 | + private static <T extends Annotation> T getClassAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationClass) { | |
| 240 | + return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass); | |
| 241 | + } | |
| 242 | + | |
| 243 | + private static String obtainMethodArgs(ProceedingJoinPoint joinPoint) { | |
| 244 | + // TODO 提升:参数脱敏和忽略 | |
| 245 | + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); | |
| 246 | + String[] argNames = methodSignature.getParameterNames(); | |
| 247 | + Object[] argValues = joinPoint.getArgs(); | |
| 248 | + // 拼接参数 | |
| 249 | + Map<String, Object> args = Maps.newHashMapWithExpectedSize(argValues.length); | |
| 250 | + for (int i = 0; i < argNames.length; i++) { | |
| 251 | + String argName = argNames[i]; | |
| 252 | + Object argValue = argValues[i]; | |
| 253 | + // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起 | |
| 254 | + args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]"); | |
| 255 | + } | |
| 256 | + return JsonUtils.toJsonString(args); | |
| 257 | + } | |
| 258 | + | |
| 259 | + private static String obtainResultData(Object result) { | |
| 260 | + // TODO 提升:结果脱敏和忽略 | |
| 261 | + if (result instanceof CommonResult) { | |
| 262 | + result = ((CommonResult<?>) result).getData(); | |
| 263 | + } | |
| 264 | + return JsonUtils.toJsonString(result); | |
| 265 | + } | |
| 266 | + | |
| 267 | + private static boolean isIgnoreArgs(Object object) { | |
| 268 | + Class<?> clazz = object.getClass(); | |
| 269 | + // 处理数组的情况 | |
| 270 | + if (clazz.isArray()) { | |
| 271 | + return IntStream.range(0, Array.getLength(object)) | |
| 272 | + .anyMatch(index -> isIgnoreArgs(Array.get(object, index))); | |
| 273 | + } | |
| 274 | + // 递归,处理数组、Collection、Map 的情况 | |
| 275 | + if (Collection.class.isAssignableFrom(clazz)) { | |
| 276 | + return ((Collection<?>) object).stream() | |
| 277 | + .anyMatch((Predicate<Object>) OperateLogV2Aspect::isIgnoreArgs); | |
| 278 | + } | |
| 279 | + if (Map.class.isAssignableFrom(clazz)) { | |
| 280 | + return isIgnoreArgs(((Map<?, ?>) object).values()); | |
| 281 | + } | |
| 282 | + // obj | |
| 283 | + return object instanceof MultipartFile | |
| 284 | + || object instanceof HttpServletRequest | |
| 285 | + || object instanceof HttpServletResponse | |
| 286 | + || object instanceof BindingResult; | |
| 287 | + } | |
| 288 | + | |
| 289 | + private static RequestMethod obtainFirstMatchRequestMethod(RequestMethod[] requestMethods) { | |
| 290 | + if (ArrayUtil.isEmpty(requestMethods)) { | |
| 291 | + return null; | |
| 292 | + } | |
| 293 | + // 优先,匹配最优的 POST、PUT、DELETE | |
| 294 | + RequestMethod result = obtainFirstLogRequestMethod(requestMethods); | |
| 295 | + if (result != null) { | |
| 296 | + return result; | |
| 297 | + } | |
| 298 | + // 然后,匹配次优的 GET | |
| 299 | + result = Arrays.stream(requestMethods).filter(requestMethod -> requestMethod == RequestMethod.GET) | |
| 300 | + .findFirst().orElse(null); | |
| 301 | + if (result != null) { | |
| 302 | + return result; | |
| 303 | + } | |
| 304 | + // 兜底,获得第一个 | |
| 305 | + return requestMethods[0]; | |
| 306 | + } | |
| 307 | + | |
| 308 | + private static RequestMethod[] obtainRequestMethod(ProceedingJoinPoint joinPoint) { | |
| 309 | + RequestMapping requestMapping = AnnotationUtils.getAnnotation( // 使用 Spring 的工具类,可以处理 @RequestMapping 别名注解 | |
| 310 | + ((MethodSignature) joinPoint.getSignature()).getMethod(), RequestMapping.class); | |
| 311 | + return requestMapping != null ? requestMapping.method() : new RequestMethod[]{}; | |
| 312 | + } | |
| 313 | + | |
| 314 | + private static RequestMethod obtainFirstLogRequestMethod(RequestMethod[] requestMethods) { | |
| 315 | + if (ArrayUtil.isEmpty(requestMethods)) { | |
| 316 | + return null; | |
| 317 | + } | |
| 318 | + return Arrays.stream(requestMethods).filter(requestMethod -> | |
| 319 | + requestMethod == RequestMethod.POST | |
| 320 | + || requestMethod == RequestMethod.PUT | |
| 321 | + || requestMethod == RequestMethod.DELETE) | |
| 322 | + .findFirst().orElse(null); | |
| 323 | + } | |
| 324 | + | |
| 325 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/enums/OperateLogV2Constants.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.operatelogv2.core.enums; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 操作日志常量接口 | |
| 5 | + * | |
| 6 | + * @author HUIHUI | |
| 7 | + */ | |
| 8 | +public interface OperateLogV2Constants { | |
| 9 | + | |
| 10 | + // ========== 开关字段-如果没有值默认就是记录 ========== | |
| 11 | + | |
| 12 | + /** | |
| 13 | + * 是否记录日志 | |
| 14 | + */ | |
| 15 | + String ENABLE = "enable"; | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * 是否记录方法参数 | |
| 19 | + */ | |
| 20 | + String IS_LOG_ARGS = "isLogArgs"; | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * 是否记录方法结果的数据 | |
| 24 | + */ | |
| 25 | + String IS_LOG_RESULT_DATA = "isLogResultData"; | |
| 26 | + | |
| 27 | + // ========== 扩展 ========== | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * 扩展信息 | |
| 31 | + */ | |
| 32 | + String EXTRA_KEY = "extra"; | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/service/ILogRecordServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.framework.operatelogv2.core.service; |
| 2 | 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; | |
| 3 | +import cn.iocoder.yudao.framework.operatelogv2.core.aop.OperateLogV2Aspect; | |
| 8 | 4 | import com.mzt.logapi.beans.LogRecord; |
| 5 | +import com.mzt.logapi.context.LogRecordContext; | |
| 9 | 6 | import com.mzt.logapi.service.ILogRecordService; |
| 10 | -import jakarta.servlet.http.HttpServletRequest; | |
| 11 | -import lombok.RequiredArgsConstructor; | |
| 12 | 7 | import lombok.extern.slf4j.Slf4j; |
| 13 | 8 | |
| 14 | 9 | import java.util.Collections; |
| ... | ... | @@ -17,56 +12,17 @@ import java.util.List; |
| 17 | 12 | /** |
| 18 | 13 | * 操作日志 ILogRecordService 实现类 |
| 19 | 14 | * |
| 20 | - * 基于 {@link OperateLogApi} 实现,记录操作日志 | |
| 15 | + * 基于 {@link OperateLogV2Aspect} 实现,记录操作日志 | |
| 21 | 16 | * |
| 22 | 17 | * @author HUIHUI |
| 23 | 18 | */ |
| 24 | 19 | @Slf4j |
| 25 | -@RequiredArgsConstructor | |
| 26 | 20 | public class ILogRecordServiceImpl implements ILogRecordService { |
| 27 | 21 | |
| 28 | - private final OperateLogApi operateLogApi; | |
| 29 | - | |
| 30 | 22 | @Override |
| 31 | 23 | public void record(LogRecord logRecord) { |
| 32 | - OperateLogV2CreateReqDTO reqBO = new OperateLogV2CreateReqDTO(); | |
| 33 | - // 补全通用字段 | |
| 34 | - reqBO.setTraceId(TracerUtils.getTraceId()); | |
| 35 | - // 补充用户信息 | |
| 36 | - fillUserFields(reqBO); | |
| 37 | - // 补全模块信息 | |
| 38 | - fillModuleFields(reqBO, logRecord); | |
| 39 | - // 补全请求信息 | |
| 40 | - fillRequestFields(reqBO); | |
| 41 | - // 异步记录日志 | |
| 42 | - operateLogApi.createOperateLogV2(reqBO); | |
| 43 | - log.info("操作日志 ===> {}", reqBO); | |
| 44 | - } | |
| 45 | - | |
| 46 | - private static void fillUserFields(OperateLogV2CreateReqDTO reqBO) { | |
| 47 | - reqBO.setUserId(WebFrameworkUtils.getLoginUserId()); | |
| 48 | - reqBO.setUserType(WebFrameworkUtils.getLoginUserType()); | |
| 49 | - } | |
| 50 | - | |
| 51 | - public static void fillModuleFields(OperateLogV2CreateReqDTO reqBO, LogRecord logRecord) { | |
| 52 | - reqBO.setType(logRecord.getType()); // 大模块类型如 crm-客户 | |
| 53 | - reqBO.setSubType(logRecord.getSubType());// 操作名称如 转移客户 | |
| 54 | - reqBO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 | |
| 55 | - reqBO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 | |
| 56 | - reqBO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} | |
| 57 | - } | |
| 58 | - | |
| 59 | - private static void fillRequestFields(OperateLogV2CreateReqDTO reqBO) { | |
| 60 | - // 获得 Request 对象 | |
| 61 | - HttpServletRequest request = ServletUtils.getRequest(); | |
| 62 | - if (request == null) { | |
| 63 | - return; | |
| 64 | - } | |
| 65 | - // 补全请求信息 | |
| 66 | - reqBO.setRequestMethod(request.getMethod()); | |
| 67 | - reqBO.setRequestUrl(request.getRequestURI()); | |
| 68 | - reqBO.setUserIp(ServletUtils.getClientIP(request)); | |
| 69 | - reqBO.setUserAgent(ServletUtils.getUserAgent(request)); | |
| 24 | + OperateLogV2Aspect.setContent(logRecord); // 操作日志 | |
| 25 | + OperateLogV2Aspect.addExtra(LogRecordContext.getVariables()); // 扩展信息 | |
| 70 | 26 | } |
| 71 | 27 | |
| 72 | 28 | @Override | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
| ... | ... | @@ -67,7 +67,7 @@ public class CrmCustomerController { |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | @PutMapping("/update") |
| 70 | - //@Operation(summary = "更新客户") | |
| 70 | + @Operation(summary = "更新客户") | |
| 71 | 71 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 72 | 72 | public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { |
| 73 | 73 | customerService.updateCustomer(updateReqVO); |
| ... | ... | @@ -131,7 +131,7 @@ public class CrmCustomerController { |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | 133 | @PutMapping("/transfer") |
| 134 | - //@Operation(summary = "客户转移") | |
| 134 | + @Operation(summary = "客户转移") | |
| 135 | 135 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 136 | 136 | public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { |
| 137 | 137 | customerService.transferCustomer(reqVO, getLoginUserId()); | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/package-info.java deleted
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmIndustryParseFunction.java
| 1 | -package cn.iocoder.yudao.module.crm.framework.bizlog.function; | |
| 1 | +package cn.iocoder.yudao.module.crm.framework.operatelog.function; | |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| ... | ... | @@ -8,7 +8,6 @@ import org.springframework.stereotype.Component; |
| 8 | 8 | |
| 9 | 9 | import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; |
| 10 | 10 | |
| 11 | -// TODO @puhui999:包名使用 operatelog 更合适哈; | |
| 12 | 11 | /** |
| 13 | 12 | * 自定义函数-通过行业编号获取行业信息 |
| 14 | 13 | * | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmLevelParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmLevelParseFunction.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmSourceParseFunction.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmSourceParseFunction.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java
0 → 100644
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2CreateReqDTO.java
| ... | ... | @@ -5,6 +5,9 @@ import jakarta.validation.constraints.NotEmpty; |
| 5 | 5 | import jakarta.validation.constraints.NotNull; |
| 6 | 6 | import lombok.Data; |
| 7 | 7 | |
| 8 | +import java.time.LocalDateTime; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 8 | 11 | /** |
| 9 | 12 | * 系统操作日志 Create Req BO |
| 10 | 13 | * |
| ... | ... | @@ -58,7 +61,7 @@ public class OperateLogV2CreateReqDTO { |
| 58 | 61 | * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) |
| 59 | 62 | * 例如说,记录订单编号,{ orderId: "1"} |
| 60 | 63 | */ |
| 61 | - private String extra; | |
| 64 | + private Map<String, Object> extra; | |
| 62 | 65 | |
| 63 | 66 | /** |
| 64 | 67 | * 请求方法名 |
| ... | ... | @@ -81,4 +84,38 @@ public class OperateLogV2CreateReqDTO { |
| 81 | 84 | @NotEmpty(message = "浏览器 UA 不能为空") |
| 82 | 85 | private String userAgent; |
| 83 | 86 | |
| 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 | + | |
| 84 | 121 | } | ... | ... |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java
| ... | ... | @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.api.logger.dto; |
| 2 | 2 | |
| 3 | 3 | import lombok.Data; |
| 4 | 4 | |
| 5 | +import java.time.LocalDateTime; | |
| 6 | + | |
| 5 | 7 | /** |
| 6 | 8 | * 系统操作日志 Resp DTO |
| 7 | 9 | * |
| ... | ... | @@ -65,8 +67,8 @@ public class OperateLogV2RespDTO { |
| 65 | 67 | private String userAgent; |
| 66 | 68 | |
| 67 | 69 | /** |
| 68 | - * 创建时间, 直接返回字符串 | |
| 70 | + * 创建时间 | |
| 69 | 71 | */ |
| 70 | - private String createTime; | |
| 72 | + private LocalDateTime createTime; | |
| 71 | 73 | |
| 72 | 74 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java
| ... | ... | @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; |
| 7 | 7 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO; |
| 8 | 8 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; |
| 9 | 9 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; |
| 10 | -import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert; | |
| 11 | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; |
| 12 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| 13 | 12 | import cn.iocoder.yudao.module.system.service.logger.OperateLogService; |
| ... | ... | @@ -63,7 +62,7 @@ public class OperateLogApiImpl implements OperateLogApi { |
| 63 | 62 | private static List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) { |
| 64 | 63 | Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId); |
| 65 | 64 | return convertList(logList, item -> { |
| 66 | - OperateLogV2RespDTO respDTO = OperateLogConvert.INSTANCE.convert(item); | |
| 65 | + OperateLogV2RespDTO respDTO = BeanUtils.toBean(item, OperateLogV2RespDTO.class); | |
| 67 | 66 | findAndThen(userMap, item.getUserId(), user -> { |
| 68 | 67 | respDTO.setUserName(user.getNickname()); |
| 69 | 68 | }); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/logger/OperateLogConvert.java
| ... | ... | @@ -3,20 +3,15 @@ package cn.iocoder.yudao.module.system.convert.logger; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; | |
| 7 | 6 | import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; |
| 8 | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; |
| 9 | -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; | |
| 10 | 8 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| 11 | 9 | import org.mapstruct.Mapper; |
| 12 | -import org.mapstruct.Mapping; | |
| 13 | 10 | import org.mapstruct.factory.Mappers; |
| 14 | 11 | |
| 15 | 12 | import java.util.List; |
| 16 | 13 | import java.util.Map; |
| 17 | 14 | |
| 18 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 19 | - | |
| 20 | 15 | @Mapper |
| 21 | 16 | public interface OperateLogConvert { |
| 22 | 17 | |
| ... | ... | @@ -30,7 +25,4 @@ public interface OperateLogConvert { |
| 30 | 25 | }); |
| 31 | 26 | } |
| 32 | 27 | |
| 33 | - @Mapping(target = "createTime", source = "logV2DO.createTime", dateFormat = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 34 | - OperateLogV2RespDTO convert(OperateLogV2DO logV2DO); | |
| 35 | - | |
| 36 | 28 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java
| 1 | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.logger; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | 6 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | +import com.baomidou.mybatisplus.annotation.TableField; | |
| 6 | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| 10 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 8 | 11 | import lombok.Data; |
| 9 | 12 | import lombok.EqualsAndHashCode; |
| 10 | 13 | |
| 14 | +import java.time.LocalDateTime; | |
| 15 | +import java.util.Map; | |
| 16 | + | |
| 11 | 17 | /** |
| 12 | 18 | * 操作日志表 V2 |
| 13 | 19 | * |
| ... | ... | @@ -20,6 +26,16 @@ import lombok.EqualsAndHashCode; |
| 20 | 26 | public class OperateLogV2DO extends BaseDO { |
| 21 | 27 | |
| 22 | 28 | /** |
| 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 | + /** | |
| 23 | 39 | * 日志主键 |
| 24 | 40 | */ |
| 25 | 41 | @TableId |
| ... | ... | @@ -65,8 +81,8 @@ public class OperateLogV2DO extends BaseDO { |
| 65 | 81 | * |
| 66 | 82 | * 例如说,记录订单编号,{ orderId: "1"} |
| 67 | 83 | */ |
| 68 | - // TODO @puhui999:看看能不能类似 exts 搞 json 格式; | |
| 69 | - private String extra; | |
| 84 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 85 | + private Map<String, Object> extra; | |
| 70 | 86 | /** |
| 71 | 87 | * 请求方法名 |
| 72 | 88 | */ |
| ... | ... | @@ -84,9 +100,43 @@ public class OperateLogV2DO extends BaseDO { |
| 84 | 100 | */ |
| 85 | 101 | private String userAgent; |
| 86 | 102 | |
| 87 | - // TODO @芋艿:requestUrl、requestMethod | |
| 88 | - // TODO @芋艿:javaMethod、javaMethodArgs | |
| 89 | - // TODO @芋艿:startTime、duration | |
| 90 | - // TODO @芋艿:resultMsg、resultData | |
| 103 | + /** | |
| 104 | + * Java 方法名 | |
| 105 | + */ | |
| 106 | + private String javaMethod; | |
| 107 | + /** | |
| 108 | + * Java 方法的参数 | |
| 109 | + * | |
| 110 | + * 实际格式为 Map<String, Object> | |
| 111 | + * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败 | |
| 112 | + * 其中,key 为参数名,value 为参数值 | |
| 113 | + */ | |
| 114 | + private String javaMethodArgs; | |
| 115 | + /** | |
| 116 | + * 开始时间 | |
| 117 | + */ | |
| 118 | + private LocalDateTime startTime; | |
| 119 | + /** | |
| 120 | + * 执行时长,单位:毫秒 | |
| 121 | + */ | |
| 122 | + private Integer duration; | |
| 123 | + /** | |
| 124 | + * 结果码 | |
| 125 | + * | |
| 126 | + * 目前使用的 {@link CommonResult#getCode()} 属性 | |
| 127 | + */ | |
| 128 | + private Integer resultCode; | |
| 129 | + /** | |
| 130 | + * 结果提示 | |
| 131 | + * | |
| 132 | + * 目前使用的 {@link CommonResult#getMsg()} 属性 | |
| 133 | + */ | |
| 134 | + private String resultMsg; | |
| 135 | + /** | |
| 136 | + * 结果数据 | |
| 137 | + * | |
| 138 | + * 如果是对象,则使用 JSON 格式化 | |
| 139 | + */ | |
| 140 | + private String resultData; | |
| 91 | 141 | |
| 92 | 142 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java
| ... | ... | @@ -4,23 +4,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 6 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; |
| 7 | -import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; | |
| 8 | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; |
| 9 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 9 | |
| 11 | -import java.util.Collection; | |
| 12 | - | |
| 13 | 10 | @Mapper |
| 14 | 11 | public interface OperateLogV2Mapper extends BaseMapperX<OperateLogV2DO> { |
| 15 | 12 | |
| 16 | - default PageResult<OperateLogV2DO> selectPage(OperateLogPageReqVO reqVO, Collection<Long> userIds) { | |
| 17 | - LambdaQueryWrapperX<OperateLogV2DO> query = new LambdaQueryWrapperX<OperateLogV2DO>() | |
| 18 | - .likeIfPresent(OperateLogV2DO::getType, reqVO.getModule()) | |
| 19 | - .inIfPresent(OperateLogV2DO::getUserId, userIds); | |
| 20 | - query.orderByDesc(OperateLogV2DO::getId); // 降序 | |
| 21 | - return selectPage(reqVO, query); | |
| 22 | - } | |
| 23 | - | |
| 24 | 13 | default PageResult<OperateLogV2DO> selectPage(OperateLogV2PageReqDTO pageReqVO) { |
| 25 | 14 | return selectPage(pageReqVO, new LambdaQueryWrapperX<OperateLogV2DO>() |
| 26 | 15 | .eqIfPresent(OperateLogV2DO::getType, pageReqVO.getBizType()) | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/package-info.java deleted
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/function/AdminUserParseFunction.java
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AreaParseFunction.java renamed to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/function/AreaParseFunction.java
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/package-info.java
0 → 100644
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java
| ... | ... | @@ -71,6 +71,8 @@ public class OperateLogServiceImpl implements OperateLogService { |
| 71 | 71 | @Override |
| 72 | 72 | public void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO) { |
| 73 | 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)); | |
| 74 | 76 | operateLogV2Mapper.insert(log); |
| 75 | 77 | } |
| 76 | 78 | ... | ... |