Commit 69503689912abe6e565fd71895bc0245bd72fc2c
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 | 47 | <artifactId>guava</artifactId> |
| 48 | 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 | 50 | </dependencies> |
| 58 | 51 | |
| 59 | 52 | </project> | ... | ... |
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; | |
| 3 | 7 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 8 | +import org.springframework.context.annotation.Bean; | |
| 4 | 9 | |
| 5 | 10 | @AutoConfiguration |
| 6 | 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
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 | 1 | \ No newline at end of file |
| 2 | +cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration | |
| 4 | 3 | \ No newline at end of file | ... | ... |
yudao-framework/yudao-spring-boot-starter-security/pom.xml
| ... | ... | @@ -50,6 +50,13 @@ |
| 50 | 50 | <artifactId>guava</artifactId> |
| 51 | 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 | 61 | <dependency> |
| 55 | 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 | 4 | import com.mzt.logapi.service.ILogRecordService; |
| 6 | 5 | import com.mzt.logapi.starter.annotation.EnableLogRecord; |
| 7 | 6 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -9,7 +8,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 9 | 8 | import org.springframework.context.annotation.Bean; |
| 10 | 9 | import org.springframework.context.annotation.Primary; |
| 11 | 10 | |
| 12 | -// TODO @puhui999:思考了下,为了减少 starter 数量,在 security 组件里,增加一个 core/operatelog 包,然后 YudaoOperateLogV2Configuration 搞一个过去; | |
| 11 | + | |
| 13 | 12 | /** |
| 14 | 13 | * mzt-biz-log 配置类 |
| 15 | 14 | * |
| ... | ... | @@ -26,9 +25,4 @@ public class YudaoOperateLogV2Configuration { |
| 26 | 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
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 | 1 | cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration |
| 2 | -cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter | |
| 3 | 2 | \ No newline at end of file |
| 3 | +cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter | |
| 4 | +cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration | |
| 4 | 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 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 8 | 8 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 9 | -import cn.iocoder.yudao.framework.operatelogv2.core.vo.OperateLogV2PageReqVO; | |
| 10 | 9 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; |
| 11 | 10 | import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; |
| 12 | 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| ... | ... | @@ -61,6 +60,7 @@ public class CrmCustomerController { |
| 61 | 60 | |
| 62 | 61 | @PostMapping("/create") |
| 63 | 62 | @Operation(summary = "创建客户") |
| 63 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 64 | 64 | @PreAuthorize("@ss.hasPermission('crm:customer:create')") |
| 65 | 65 | public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerCreateReqVO createReqVO) { |
| 66 | 66 | return success(customerService.createCustomer(createReqVO, getLoginUserId())); |
| ... | ... | @@ -68,6 +68,7 @@ public class CrmCustomerController { |
| 68 | 68 | |
| 69 | 69 | @PutMapping("/update") |
| 70 | 70 | @Operation(summary = "更新客户") |
| 71 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 71 | 72 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 72 | 73 | public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { |
| 73 | 74 | customerService.updateCustomer(updateReqVO); |
| ... | ... | @@ -76,6 +77,7 @@ public class CrmCustomerController { |
| 76 | 77 | |
| 77 | 78 | @DeleteMapping("/delete") |
| 78 | 79 | @Operation(summary = "删除客户") |
| 80 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 79 | 81 | @Parameter(name = "id", description = "编号", required = true) |
| 80 | 82 | @PreAuthorize("@ss.hasPermission('crm:customer:delete')") |
| 81 | 83 | public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) { |
| ... | ... | @@ -132,6 +134,7 @@ public class CrmCustomerController { |
| 132 | 134 | |
| 133 | 135 | @PutMapping("/transfer") |
| 134 | 136 | @Operation(summary = "客户转移") |
| 137 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 135 | 138 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 136 | 139 | public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { |
| 137 | 140 | customerService.transferCustomer(reqVO, getLoginUserId()); |
| ... | ... | @@ -140,9 +143,8 @@ public class CrmCustomerController { |
| 140 | 143 | |
| 141 | 144 | @GetMapping("/operate-log-page") |
| 142 | 145 | @Operation(summary = "获得客户操作日志") |
| 143 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 144 | 146 | @PreAuthorize("@ss.hasPermission('crm:customer:query')") |
| 145 | - public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(OperateLogV2PageReqVO reqVO) { | |
| 147 | + public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(CrmCustomerOperateLogPageReqVO reqVO) { | |
| 146 | 148 | reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 |
| 147 | 149 | reqVO.setBizType(CRM_CUSTOMER); |
| 148 | 150 | return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class))); |
| ... | ... | @@ -151,6 +153,7 @@ public class CrmCustomerController { |
| 151 | 153 | // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了; |
| 152 | 154 | @PutMapping("/lock") |
| 153 | 155 | @Operation(summary = "锁定/解锁客户") |
| 156 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 154 | 157 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 155 | 158 | public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { |
| 156 | 159 | customerService.lockCustomer(updateReqVO); |
| ... | ... | @@ -161,6 +164,7 @@ public class CrmCustomerController { |
| 161 | 164 | |
| 162 | 165 | @PutMapping("/put-pool") |
| 163 | 166 | @Operation(summary = "数据放入公海") |
| 167 | + @OperateLog(enable = false) // TODO 关闭原有日志记录 | |
| 164 | 168 | @Parameter(name = "id", description = "客户编号", required = true, example = "1024") |
| 165 | 169 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 166 | 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 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | 5 | import lombok.Data; |
| 6 | 6 | |
| 7 | -// TODO @puhui999:这个最好每个模块自己弄哈,放这里有点怪可能 | |
| 8 | -@Schema(description = "管理后台 - 操作日志分页 Request VO") | |
| 7 | +@Schema(description = "管理后台 - crm 客户操作日志分页 Request VO") | |
| 9 | 8 | @Data |
| 10 | -public class OperateLogV2PageReqVO extends PageParam { | |
| 9 | +public class CrmCustomerOperateLogPageReqVO extends PageParam { | |
| 11 | 10 | |
| 12 | 11 | @Schema(description = "模块数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 13 | 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 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| 5 | 6 | import com.mzt.logapi.service.IParseFunction; |
| ... | ... | @@ -8,7 +9,6 @@ import org.springframework.stereotype.Component; |
| 8 | 9 | |
| 9 | 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 | 30 | |
| 31 | 31 | @Override |
| 32 | 32 | public String apply(Object value) { |
| 33 | -// if (ObjUtil.isEmpty(value)) TODO @puhui999 可以直接替代哈; | |
| 34 | - if (value == null) { | |
| 33 | + if (ObjUtil.isEmpty(value)) { | |
| 35 | 34 | return ""; |
| 36 | 35 | } |
| 37 | 36 | if (StrUtil.isEmpty(value.toString())) { |
| ... | ... | @@ -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 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| 5 | 6 | import com.mzt.logapi.service.IParseFunction; |
| ... | ... | @@ -29,7 +30,7 @@ public class CrmLevelParseFunction implements IParseFunction { |
| 29 | 30 | |
| 30 | 31 | @Override |
| 31 | 32 | public String apply(Object value) { |
| 32 | - if (value == null) { | |
| 33 | + if (ObjUtil.isEmpty(value)) { | |
| 33 | 34 | return ""; |
| 34 | 35 | } |
| 35 | 36 | if (StrUtil.isEmpty(value.toString())) { |
| ... | ... | @@ -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 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| 5 | 6 | import com.mzt.logapi.service.IParseFunction; |
| ... | ... | @@ -29,7 +30,7 @@ public class CrmSourceParseFunction implements IParseFunction { |
| 29 | 30 | |
| 30 | 31 | @Override |
| 31 | 32 | public String apply(Object value) { |
| 32 | - if (value == null) { | |
| 33 | + if (ObjUtil.isEmpty(value)) { | |
| 33 | 34 | return ""; |
| 34 | 35 | } |
| 35 | 36 | if (StrUtil.isEmpty(value.toString())) { |
| ... | ... | @@ -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 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | -import cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants; | |
| 7 | 6 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO; |
| 8 | 7 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; |
| 9 | 8 | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; |
| ... | ... | @@ -53,7 +52,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 53 | 52 | |
| 54 | 53 | @Override |
| 55 | 54 | @Transactional(rollbackFor = Exception.class) |
| 56 | - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#customerId}}", success = "创建了客户") | |
| 55 | + @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") | |
| 57 | 56 | public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) { |
| 58 | 57 | // 插入 |
| 59 | 58 | CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO); |
| ... | ... | @@ -71,7 +70,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 71 | 70 | // TODO @puhui999:测试下,能不能打出用户数据的变更。啊哈,可以打完微信发我下; |
| 72 | 71 | @Override |
| 73 | 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 | 74 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |
| 76 | 75 | public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { |
| 77 | 76 | // 校验存在 |
| ... | ... | @@ -83,14 +82,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 83 | 82 | |
| 84 | 83 | // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null |
| 85 | 84 | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class)); |
| 85 | + // TODO 扩展信息测试 | |
| 86 | 86 | HashMap<String, Object> extra = new HashMap<>(); |
| 87 | 87 | extra.put("tips", "随便记录一点啦"); |
| 88 | - LogRecordContext.putVariable(OperateLogV2Constants.EXTRA_KEY, extra); | |
| 88 | + LogRecordContext.putVariable("extra", extra); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | @Override |
| 92 | 92 | @Transactional(rollbackFor = Exception.class) |
| 93 | - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#id}}", success = "删除了客户") | |
| 93 | + @LogRecord(type = CRM_CUSTOMER, subType = "删除客户", bizNo = "{{#id}}", success = "删除了客户") | |
| 94 | 94 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) |
| 95 | 95 | public void deleteCustomer(Long id) { |
| 96 | 96 | // 校验存在 |
| ... | ... | @@ -141,7 +141,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 141 | 141 | |
| 142 | 142 | @Override |
| 143 | 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 | 145 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) |
| 146 | 146 | public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { |
| 147 | 147 | // 1. 校验客户是否存在 |
| ... | ... | @@ -158,7 +158,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | 160 | @Override |
| 161 | - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") | |
| 161 | + @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") | |
| 162 | 162 | public void lockCustomer(CrmCustomerUpdateReqVO updateReqVO) { |
| 163 | 163 | // 校验存在 |
| 164 | 164 | validateCustomerExists(updateReqVO.getId()); |
| ... | ... | @@ -172,7 +172,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 172 | 172 | |
| 173 | 173 | @Override |
| 174 | 174 | @Transactional(rollbackFor = Exception.class) |
| 175 | - @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#id}}", success = "将客户放入了公海") | |
| 175 | + @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") | |
| 176 | 176 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) |
| 177 | 177 | public void putCustomerPool(Long id) { |
| 178 | 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 | 5 | import jakarta.validation.constraints.NotNull; |
| 6 | 6 | import lombok.Data; |
| 7 | 7 | |
| 8 | -import java.time.LocalDateTime; | |
| 9 | -import java.util.Map; | |
| 10 | - | |
| 11 | 8 | /** |
| 12 | 9 | * 系统操作日志 Create Req BO |
| 13 | 10 | * |
| ... | ... | @@ -56,12 +53,12 @@ public class OperateLogV2CreateReqDTO { |
| 56 | 53 | * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 |
| 57 | 54 | */ |
| 58 | 55 | @NotEmpty(message = "操作内容不能为空") |
| 59 | - private String content; | |
| 56 | + private String action; | |
| 60 | 57 | /** |
| 61 | 58 | * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) |
| 62 | 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 | 81 | @NotEmpty(message = "浏览器 UA 不能为空") |
| 85 | 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 | 2 | |
| 3 | 3 | import lombok.Data; |
| 4 | 4 | |
| 5 | -import java.time.LocalDateTime; | |
| 6 | -import java.util.Map; | |
| 7 | - | |
| 8 | 5 | /** |
| 9 | 6 | * 系统操作日志 Resp DTO |
| 10 | 7 | * |
| ... | ... | @@ -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 | 64 | */ |
| 68 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 6 | 5 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; |
| 7 | 6 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO; |
| 8 | 7 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; |
| 9 | 8 | import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; |
| 9 | +import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert; | |
| 10 | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; |
| 11 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| 12 | 12 | import cn.iocoder.yudao.module.system.service.logger.OperateLogService; |
| ... | ... | @@ -17,10 +17,8 @@ import org.springframework.stereotype.Service; |
| 17 | 17 | import org.springframework.validation.annotation.Validated; |
| 18 | 18 | |
| 19 | 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 | 24 | * 操作日志 API 实现类 |
| ... | ... | @@ -56,17 +54,7 @@ public class OperateLogApiImpl implements OperateLogApi { |
| 56 | 54 | |
| 57 | 55 | // 获取用户 |
| 58 | 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 | 1 | package cn.iocoder.yudao.module.system.convert.logger; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; | |
| 6 | 8 | import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; |
| 7 | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; |
| 10 | +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; | |
| 8 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| 9 | 12 | import org.mapstruct.Mapper; |
| 10 | 13 | import org.mapstruct.factory.Mappers; |
| ... | ... | @@ -12,6 +15,9 @@ import org.mapstruct.factory.Mappers; |
| 12 | 15 | import java.util.List; |
| 13 | 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 | 21 | @Mapper |
| 16 | 22 | public interface OperateLogConvert { |
| 17 | 23 | |
| ... | ... | @@ -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 | 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; | |
| 5 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | 5 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | -import com.baomidou.mybatisplus.annotation.TableField; | |
| 8 | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 9 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 10 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 11 | 8 | import lombok.Data; |
| 12 | 9 | import lombok.EqualsAndHashCode; |
| 13 | 10 | |
| 14 | -import java.time.LocalDateTime; | |
| 15 | -import java.util.Map; | |
| 16 | - | |
| 17 | 11 | /** |
| 18 | 12 | * 操作日志表 V2 |
| 19 | 13 | * |
| ... | ... | @@ -26,16 +20,6 @@ import java.util.Map; |
| 26 | 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 | 25 | @TableId |
| ... | ... | @@ -70,20 +54,18 @@ public class OperateLogV2DO extends BaseDO { |
| 70 | 54 | * 操作模块业务编号 |
| 71 | 55 | */ |
| 72 | 56 | private Long bizId; |
| 73 | - // TODO @puhui999:content 改成 action,extra 换成 String。注释就直接用 mzt,和它完全对应好了。 | |
| 74 | 57 | /** |
| 75 | - * 操作内容,记录整个操作的明细 | |
| 58 | + * 日志内容,记录整个操作的明细 | |
| 76 | 59 | * |
| 77 | 60 | * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 |
| 78 | 61 | */ |
| 79 | - private String content; | |
| 62 | + private String action; | |
| 80 | 63 | /** |
| 81 | 64 | * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) |
| 82 | 65 | * |
| 83 | 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 | 84 | */ |
| 103 | 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 | 3 | import cn.hutool.core.util.ObjUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| ... | ... | @@ -9,7 +9,6 @@ import jakarta.annotation.Resource; |
| 9 | 9 | import lombok.extern.slf4j.Slf4j; |
| 10 | 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 | 26 | return "getAdminUserById"; |
| 28 | 27 | } |
| 29 | 28 | |
| 30 | - // TODO @puhui999:这个方法的实现优化下哈; | |
| 31 | 29 | @Override |
| 32 | 30 | public String apply(Object value) { |
| 33 | - if (value == null) { | |
| 34 | - //log.warn("(getAdminUserById) 解析异常参数为 null"); | |
| 31 | + if (ObjUtil.isEmpty(value)) { | |
| 35 | 32 | return ""; |
| 36 | 33 | } |
| 37 | 34 | if (StrUtil.isEmpty(value.toString())) { |
| 38 | - //log.warn("(getAdminUserById) 解析异常参数为空"); | |
| 39 | 35 | return ""; |
| 40 | 36 | } |
| 41 | 37 | |
| ... | ... | @@ -52,4 +48,5 @@ public class AdminUserParseFunction implements IParseFunction { |
| 52 | 48 | } |
| 53 | 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 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 5 | 6 | import com.mzt.logapi.service.IParseFunction; |
| 6 | 7 | import lombok.extern.slf4j.Slf4j; |
| 7 | 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 | 28 | |
| 29 | 29 | @Override |
| 30 | 30 | public String apply(Object value) { |
| 31 | - if (value == null) { | |
| 31 | + if (ObjUtil.isEmpty(value)) { | |
| 32 | 32 | return ""; |
| 33 | 33 | } |
| 34 | 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 | 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)); | |
| 76 | 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 | 21 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| 22 | 22 | import com.xingyuv.captcha.model.common.ResponseModel; |
| 23 | 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 | 24 | import jakarta.annotation.Resource; |
| 30 | 25 | import jakarta.validation.ConstraintViolationException; |
| 31 | 26 | import jakarta.validation.Validation; |
| 32 | 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 | 33 | import static cn.hutool.core.util.RandomUtil.randomEle; |
| 35 | 34 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| ... | ... | @@ -237,7 +236,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { |
| 237 | 236 | // mock 方法(绑定的用户编号) |
| 238 | 237 | Long userId = 1L; |
| 239 | 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 | 240 | // mock(用户) |
| 242 | 241 | AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); |
| 243 | 242 | when(userService.getUser(eq(userId))).thenReturn(user); | ... | ... |