Commit 000b6cf47fd8f14827a28b43c4f2c410b372163c

Authored by YunaiV
1 parent 22a170ee

【重构】V2 操作日志转正,基于注解的可使用变量、可以自定义函数的通用操作日志组件

Showing 30 changed files with 185 additions and 1188 deletions
sql/mysql/ruoyi-vue-pro.sql
... ... @@ -11,7 +11,7 @@
11 11 Target Server Version : 80200 (8.2.0)
12 12 File Encoding : 65001
13 13  
14   - Date: 03/04/2024 19:07:31
  14 + Date: 04/04/2024 01:17:25
15 15 */
16 16  
17 17 SET NAMES utf8mb4;
... ... @@ -347,7 +347,7 @@ CREATE TABLE `infra_api_access_log` (
347 347 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
348 348 PRIMARY KEY (`id`) USING BTREE,
349 349 INDEX `idx_create_time`(`create_time` ASC) USING BTREE
350   -) ENGINE = InnoDB AUTO_INCREMENT = 35920 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
  350 +) ENGINE = InnoDB AUTO_INCREMENT = 35925 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
351 351  
352 352 -- ----------------------------
353 353 -- Records of infra_api_access_log
... ... @@ -726,7 +726,7 @@ CREATE TABLE `infra_file_config` (
726 726 -- ----------------------------
727 727 BEGIN;
728 728 INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2024-02-28 22:54:07', b'0');
729   -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器', 20, '', b'1', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\"}', '1', '2024-01-13 22:11:12', '1', '2024-01-13 22:24:06', b'0');
  729 +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器', 20, '', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\"}', '1', '2024-01-13 22:11:12', '1', '2024-04-03 19:38:34', b'0');
730 730 COMMIT;
731 731  
732 732 -- ----------------------------
... ... @@ -1420,7 +1420,7 @@ CREATE TABLE `system_login_log` (
1420 1420 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1421 1421 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1422 1422 PRIMARY KEY (`id`) USING BTREE
1423   -) ENGINE = InnoDB AUTO_INCREMENT = 3066 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
  1423 +) ENGINE = InnoDB AUTO_INCREMENT = 3067 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1424 1424  
1425 1425 -- ----------------------------
1426 1426 -- Records of system_login_log
... ... @@ -2457,7 +2457,7 @@ CREATE TABLE `system_oauth2_access_token` (
2457 2457 PRIMARY KEY (`id`) USING BTREE,
2458 2458 INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
2459 2459 INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
2460   -) ENGINE = InnoDB AUTO_INCREMENT = 6366 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
  2460 +) ENGINE = InnoDB AUTO_INCREMENT = 6372 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
2461 2461  
2462 2462 -- ----------------------------
2463 2463 -- Records of system_oauth2_access_token
... ... @@ -2579,7 +2579,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
2579 2579 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2580 2580 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2581 2581 PRIMARY KEY (`id`) USING BTREE
2582   -) ENGINE = InnoDB AUTO_INCREMENT = 1441 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
  2582 +) ENGINE = InnoDB AUTO_INCREMENT = 1442 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
2583 2583  
2584 2584 -- ----------------------------
2585 2585 -- Records of system_oauth2_refresh_token
... ... @@ -2596,46 +2596,6 @@ CREATE TABLE `system_operate_log` (
2596 2596 `trace_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '链路追踪编号',
2597 2597 `user_id` bigint NOT NULL COMMENT '用户编号',
2598 2598 `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型',
2599   - `module` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '模块标题',
2600   - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '操作名',
2601   - `type` bigint NOT NULL DEFAULT 0 COMMENT '操作分类',
2602   - `content` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '操作内容',
2603   - `exts` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '拓展字段',
2604   - `request_method` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '请求方法名',
2605   - `request_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '请求地址',
2606   - `user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户 IP',
2607   - `user_agent` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '浏览器 UA',
2608   - `java_method` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'Java 方法名',
2609   - `java_method_args` varchar(8000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT 'Java 方法的参数',
2610   - `start_time` datetime NOT NULL COMMENT '操作时间',
2611   - `duration` int NOT NULL COMMENT '执行时长',
2612   - `result_code` int NOT NULL DEFAULT 0 COMMENT '结果码',
2613   - `result_msg` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '结果提示',
2614   - `result_data` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '结果数据',
2615   - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
2616   - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
2617   - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
2618   - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
2619   - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2620   - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2621   - PRIMARY KEY (`id`) USING BTREE
2622   -) ENGINE = InnoDB AUTO_INCREMENT = 12000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
2623   -
2624   --- ----------------------------
2625   --- Records of system_operate_log
2626   --- ----------------------------
2627   -BEGIN;
2628   -COMMIT;
2629   -
2630   --- ----------------------------
2631   --- Table structure for system_operate_log_v2
2632   --- ----------------------------
2633   -DROP TABLE IF EXISTS `system_operate_log_v2`;
2634   -CREATE TABLE `system_operate_log_v2` (
2635   - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键',
2636   - `trace_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '链路追踪编号',
2637   - `user_id` bigint NOT NULL COMMENT '用户编号',
2638   - `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型',
2639 2599 `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '操作模块类型',
2640 2600 `sub_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '操作名',
2641 2601 `biz_id` bigint NOT NULL COMMENT '操作数据模块编号',
... ... @@ -2655,7 +2615,7 @@ CREATE TABLE `system_operate_log_v2` (
2655 2615 ) ENGINE = InnoDB AUTO_INCREMENT = 9019 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
2656 2616  
2657 2617 -- ----------------------------
2658   --- Records of system_operate_log_v2
  2618 +-- Records of system_operate_log
2659 2619 -- ----------------------------
2660 2620 BEGIN;
2661 2621 COMMIT;
... ... @@ -5623,7 +5583,7 @@ CREATE TABLE `system_users` (
5623 5583 -- Records of system_users
5624 5584 -- ----------------------------
5625 5585 BEGIN;
5626   -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/96c787a2ce88bf6d0ce3cd8b6cf5314e80e7703cd41bf4af8cd2e2909dbd6b6d.png', 0, '127.0.0.1', '2024-04-03 17:31:00', 'admin', '2021-01-05 17:03:47', NULL, '2024-04-03 17:31:00', b'0', 1);
  5586 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/96c787a2ce88bf6d0ce3cd8b6cf5314e80e7703cd41bf4af8cd2e2909dbd6b6d.png', 0, '127.0.0.1', '2024-04-03 20:01:18', 'admin', '2021-01-05 17:03:47', NULL, '2024-04-03 20:01:18', b'0', 1);
5627 5587 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
5628 5588 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-03-18 21:09:04', '', '2021-01-13 23:50:35', NULL, '2024-03-18 21:09:04', b'0', 1);
5629 5589 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$KhExCYl7lx6eWWZYKsibKOZ8IBJRyuNuCcEOLQ11RYhJKgHmlSwK.', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-26 07:11:35', '', '2021-01-21 02:13:53', NULL, '2024-03-26 07:11:35', b'0', 1);
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogAutoConfiguration.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.config;
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   -import org.springframework.boot.autoconfigure.AutoConfiguration;
8   -import org.springframework.context.annotation.Bean;
9   -
10   -@AutoConfiguration
11   -public class YudaoOperateLogAutoConfiguration {
12   -
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   - }
22   -
23   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.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.StrUtil;
7   -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
8   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
9   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
10   -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
11   -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
12   -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
13   -import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog;
14   -import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
15   -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
16   -import com.google.common.collect.Maps;
17   -import io.swagger.v3.oas.annotations.tags.Tag;
18   -import io.swagger.v3.oas.annotations.Operation;
19   -import lombok.extern.slf4j.Slf4j;
20   -import org.aspectj.lang.ProceedingJoinPoint;
21   -import org.aspectj.lang.annotation.Around;
22   -import org.aspectj.lang.annotation.Aspect;
23   -import org.aspectj.lang.reflect.MethodSignature;
24   -import org.springframework.core.annotation.AnnotationUtils;
25   -import org.springframework.validation.BindingResult;
26   -import org.springframework.web.bind.annotation.RequestMapping;
27   -import org.springframework.web.bind.annotation.RequestMethod;
28   -import org.springframework.web.multipart.MultipartFile;
29   -
30   -import jakarta.annotation.Resource;
31   -import jakarta.servlet.http.HttpServletRequest;
32   -import jakarta.servlet.http.HttpServletResponse;
33   -import java.lang.annotation.Annotation;
34   -import java.lang.reflect.Array;
35   -import java.time.LocalDateTime;
36   -import java.util.*;
37   -import java.util.function.Predicate;
38   -import java.util.stream.IntStream;
39   -
40   -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
41   -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS;
42   -
43   -/**
44   - * 拦截使用 @OperateLog 注解,如果满足条件,则生成操作日志。
45   - * 满足如下任一条件,则会进行记录:
46   - * 1. 使用 @ApiOperation + 非 @GetMapping
47   - * 2. 使用 @OperateLog 注解
48   - * <p>
49   - * 但是,如果声明 @OperateLog 注解时,将 enable 属性设置为 false 时,强制不记录。
50   - *
51   - * @author 芋道源码
52   - */
53   -@Aspect
54   -@Slf4j
55   -public class OperateLogAspect {
56   -
57   - /**
58   - * 用于记录操作内容的上下文
59   - *
60   - * @see OperateLog#getContent()
61   - */
62   - private static final ThreadLocal<String> CONTENT = new ThreadLocal<>();
63   - /**
64   - * 用于记录拓展字段的上下文
65   - *
66   - * @see OperateLog#getExts()
67   - */
68   - private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
69   -
70   - @Resource
71   - private OperateLogFrameworkService operateLogFrameworkService;
72   -
73   - @Around("@annotation(operation)")
74   - public Object around(ProceedingJoinPoint joinPoint, Operation operation) throws Throwable {
75   - // 可能也添加了 @ApiOperation 注解
76   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog = getMethodAnnotation(joinPoint,
77   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog.class);
78   - return around0(joinPoint, operateLog, operation);
79   - }
80   -
81   - @Around("!@annotation(io.swagger.v3.oas.annotations.Operation) && @annotation(operateLog)")
82   - // 兼容处理,只添加 @OperateLog 注解的情况
83   - public Object around(ProceedingJoinPoint joinPoint,
84   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog) throws Throwable {
85   - return around0(joinPoint, operateLog, null);
86   - }
87   -
88   - private Object around0(ProceedingJoinPoint joinPoint,
89   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
90   - Operation operation) throws Throwable {
91   - // 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录
92   - Integer userType = WebFrameworkUtils.getLoginUserType();
93   - if (!Objects.equals(userType, UserTypeEnum.ADMIN.getValue())) {
94   - return joinPoint.proceed();
95   - }
96   -
97   - // 记录开始时间
98   - LocalDateTime startTime = LocalDateTime.now();
99   - try {
100   - // 执行原有方法
101   - Object result = joinPoint.proceed();
102   - // 记录正常执行时的操作日志
103   - this.log(joinPoint, operateLog, operation, startTime, result, null);
104   - return result;
105   - } catch (Throwable exception) {
106   - this.log(joinPoint, operateLog, operation, startTime, null, exception);
107   - throw exception;
108   - } finally {
109   - clearThreadLocal();
110   - }
111   - }
112   -
113   - public static void setContent(String content) {
114   - CONTENT.set(content);
115   - }
116   -
117   - public static void addExt(String key, Object value) {
118   - if (EXTS.get() == null) {
119   - EXTS.set(new HashMap<>());
120   - }
121   - EXTS.get().put(key, value);
122   - }
123   -
124   - private static void clearThreadLocal() {
125   - CONTENT.remove();
126   - EXTS.remove();
127   - }
128   -
129   - private void log(ProceedingJoinPoint joinPoint,
130   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
131   - Operation operation,
132   - LocalDateTime startTime, Object result, Throwable exception) {
133   - try {
134   - // 判断不记录的情况
135   - if (!isLogEnable(joinPoint, operateLog)) {
136   - return;
137   - }
138   - // 真正记录操作日志
139   - this.log0(joinPoint, operateLog, operation, startTime, result, exception);
140   - } catch (Throwable ex) {
141   - log.error("[log][记录操作日志时,发生异常,其中参数是 joinPoint({}) operateLog({}) apiOperation({}) result({}) exception({}) ]",
142   - joinPoint, operateLog, operation, result, exception, ex);
143   - }
144   - }
145   -
146   - private void log0(ProceedingJoinPoint joinPoint,
147   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
148   - Operation operation,
149   - LocalDateTime startTime, Object result, Throwable exception) {
150   - OperateLog operateLogObj = new OperateLog();
151   - // 补全通用字段
152   - operateLogObj.setTraceId(TracerUtils.getTraceId());
153   - operateLogObj.setStartTime(startTime);
154   - // 补充用户信息
155   - fillUserFields(operateLogObj);
156   - // 补全模块信息
157   - fillModuleFields(operateLogObj, joinPoint, operateLog, operation);
158   - // 补全请求信息
159   - fillRequestFields(operateLogObj);
160   - // 补全方法信息
161   - fillMethodFields(operateLogObj, joinPoint, operateLog, startTime, result, exception);
162   -
163   - // 异步记录日志
164   - operateLogFrameworkService.createOperateLog(operateLogObj);
165   - }
166   -
167   - private static void fillUserFields(OperateLog operateLogObj) {
168   - operateLogObj.setUserId(WebFrameworkUtils.getLoginUserId());
169   - operateLogObj.setUserType(WebFrameworkUtils.getLoginUserType());
170   - }
171   -
172   - private static void fillModuleFields(OperateLog operateLogObj,
173   - ProceedingJoinPoint joinPoint,
174   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
175   - Operation operation) {
176   - // module 属性
177   - if (operateLog != null) {
178   - operateLogObj.setModule(operateLog.module());
179   - }
180   - if (StrUtil.isEmpty(operateLogObj.getModule())) {
181   - Tag tag = getClassAnnotation(joinPoint, Tag.class);
182   - if (tag != null) {
183   - // 优先读取 @Tag 的 name 属性
184   - if (StrUtil.isNotEmpty(tag.name())) {
185   - operateLogObj.setModule(tag.name());
186   - }
187   - // 没有的话,读取 @API 的 description 属性
188   - if (StrUtil.isEmpty(operateLogObj.getModule()) && ArrayUtil.isNotEmpty(tag.description())) {
189   - operateLogObj.setModule(tag.description());
190   - }
191   - }
192   - }
193   - // name 属性
194   - if (operateLog != null) {
195   - operateLogObj.setName(operateLog.name());
196   - }
197   - if (StrUtil.isEmpty(operateLogObj.getName()) && operation != null) {
198   - operateLogObj.setName(operation.summary());
199   - }
200   - // type 属性
201   - if (operateLog != null && ArrayUtil.isNotEmpty(operateLog.type())) {
202   - operateLogObj.setType(operateLog.type()[0].getType());
203   - }
204   - if (operateLogObj.getType() == null) {
205   - RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint));
206   - OperateTypeEnum operateLogType = convertOperateLogType(requestMethod);
207   - operateLogObj.setType(operateLogType != null ? operateLogType.getType() : null);
208   - }
209   - // content 和 exts 属性
210   - operateLogObj.setContent(CONTENT.get());
211   - operateLogObj.setExts(EXTS.get());
212   - }
213   -
214   - private static void fillRequestFields(OperateLog operateLogObj) {
215   - // 获得 Request 对象
216   - HttpServletRequest request = ServletUtils.getRequest();
217   - if (request == null) {
218   - return;
219   - }
220   - // 补全请求信息
221   - operateLogObj.setRequestMethod(request.getMethod());
222   - operateLogObj.setRequestUrl(request.getRequestURI());
223   - operateLogObj.setUserIp(ServletUtils.getClientIP(request));
224   - operateLogObj.setUserAgent(ServletUtils.getUserAgent(request));
225   - }
226   -
227   - private static void fillMethodFields(OperateLog operateLogObj,
228   - ProceedingJoinPoint joinPoint,
229   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
230   - LocalDateTime startTime, Object result, Throwable exception) {
231   - MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
232   - operateLogObj.setJavaMethod(methodSignature.toString());
233   - if (operateLog == null || operateLog.logArgs()) {
234   - operateLogObj.setJavaMethodArgs(obtainMethodArgs(joinPoint));
235   - }
236   - if (operateLog == null || operateLog.logResultData()) {
237   - operateLogObj.setResultData(obtainResultData(result));
238   - }
239   - operateLogObj.setDuration((int) (LocalDateTimeUtil.between(startTime, LocalDateTime.now()).toMillis()));
240   - // (正常)处理 resultCode 和 resultMsg 字段
241   - if (result instanceof CommonResult) {
242   - CommonResult<?> commonResult = (CommonResult<?>) result;
243   - operateLogObj.setResultCode(commonResult.getCode());
244   - operateLogObj.setResultMsg(commonResult.getMsg());
245   - } else {
246   - operateLogObj.setResultCode(SUCCESS.getCode());
247   - }
248   - // (异常)处理 resultCode 和 resultMsg 字段
249   - if (exception != null) {
250   - operateLogObj.setResultCode(INTERNAL_SERVER_ERROR.getCode());
251   - operateLogObj.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));
252   - }
253   - }
254   -
255   - private static boolean isLogEnable(ProceedingJoinPoint joinPoint,
256   - cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog) {
257   - // 有 @OperateLog 注解的情况下
258   - if (operateLog != null) {
259   - return operateLog.enable();
260   - }
261   - // 没有 @ApiOperation 注解的情况下,只记录 POST、PUT、DELETE 的情况
262   - return obtainFirstLogRequestMethod(obtainRequestMethod(joinPoint)) != null;
263   - }
264   -
265   - private static RequestMethod obtainFirstLogRequestMethod(RequestMethod[] requestMethods) {
266   - if (ArrayUtil.isEmpty(requestMethods)) {
267   - return null;
268   - }
269   - return Arrays.stream(requestMethods).filter(requestMethod ->
270   - requestMethod == RequestMethod.POST
271   - || requestMethod == RequestMethod.PUT
272   - || requestMethod == RequestMethod.DELETE)
273   - .findFirst().orElse(null);
274   - }
275   -
276   - private static RequestMethod obtainFirstMatchRequestMethod(RequestMethod[] requestMethods) {
277   - if (ArrayUtil.isEmpty(requestMethods)) {
278   - return null;
279   - }
280   - // 优先,匹配最优的 POST、PUT、DELETE
281   - RequestMethod result = obtainFirstLogRequestMethod(requestMethods);
282   - if (result != null) {
283   - return result;
284   - }
285   - // 然后,匹配次优的 GET
286   - result = Arrays.stream(requestMethods).filter(requestMethod -> requestMethod == RequestMethod.GET)
287   - .findFirst().orElse(null);
288   - if (result != null) {
289   - return result;
290   - }
291   - // 兜底,获得第一个
292   - return requestMethods[0];
293   - }
294   -
295   - private static OperateTypeEnum convertOperateLogType(RequestMethod requestMethod) {
296   - if (requestMethod == null) {
297   - return null;
298   - }
299   - switch (requestMethod) {
300   - case GET:
301   - return OperateTypeEnum.GET;
302   - case POST:
303   - return OperateTypeEnum.CREATE;
304   - case PUT:
305   - return OperateTypeEnum.UPDATE;
306   - case DELETE:
307   - return OperateTypeEnum.DELETE;
308   - default:
309   - return OperateTypeEnum.OTHER;
310   - }
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   - @SuppressWarnings("SameParameterValue")
320   - private static <T extends Annotation> T getMethodAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationClass) {
321   - return ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(annotationClass);
322   - }
323   -
324   - @SuppressWarnings("SameParameterValue")
325   - private static <T extends Annotation> T getClassAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationClass) {
326   - return ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaringClass().getAnnotation(annotationClass);
327   - }
328   -
329   - private static String obtainMethodArgs(ProceedingJoinPoint joinPoint) {
330   - // TODO 提升:参数脱敏和忽略
331   - MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
332   - String[] argNames = methodSignature.getParameterNames();
333   - Object[] argValues = joinPoint.getArgs();
334   - // 拼接参数
335   - Map<String, Object> args = Maps.newHashMapWithExpectedSize(argValues.length);
336   - for (int i = 0; i < argNames.length; i++) {
337   - String argName = argNames[i];
338   - Object argValue = argValues[i];
339   - // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
340   - args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
341   - }
342   - return JsonUtils.toJsonString(args);
343   - }
344   -
345   - private static String obtainResultData(Object result) {
346   - // TODO 提升:结果脱敏和忽略
347   - if (result instanceof CommonResult) {
348   - result = ((CommonResult<?>) result).getData();
349   - }
350   - return JsonUtils.toJsonString(result);
351   - }
352   -
353   - private static boolean isIgnoreArgs(Object object) {
354   - Class<?> clazz = object.getClass();
355   - // 处理数组的情况
356   - if (clazz.isArray()) {
357   - return IntStream.range(0, Array.getLength(object))
358   - .anyMatch(index -> isIgnoreArgs(Array.get(object, index)));
359   - }
360   - // 递归,处理数组、Collection、Map 的情况
361   - if (Collection.class.isAssignableFrom(clazz)) {
362   - return ((Collection<?>) object).stream()
363   - .anyMatch((Predicate<Object>) OperateLogAspect::isIgnoreArgs);
364   - }
365   - if (Map.class.isAssignableFrom(clazz)) {
366   - return isIgnoreArgs(((Map<?, ?>) object).values());
367   - }
368   - // obj
369   - return object instanceof MultipartFile
370   - || object instanceof HttpServletRequest
371   - || object instanceof HttpServletResponse
372   - || object instanceof BindingResult;
373   - }
374   -
375   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/package-info.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core;
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLog.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core.service;
2   -
3   -import lombok.Data;
4   -
5   -import java.time.LocalDateTime;
6   -import java.util.Map;
7   -
8   -/**
9   - * 操作日志
10   - *
11   - * @author 芋道源码
12   - */
13   -@Data
14   -public class OperateLog {
15   -
16   - /**
17   - * 链路追踪编号
18   - */
19   - private String traceId;
20   -
21   - /**
22   - * 用户编号
23   - */
24   - private Long userId;
25   - /**
26   - * 用户类型
27   - */
28   - private Integer userType;
29   -
30   - /**
31   - * 操作模块
32   - */
33   - private String module;
34   -
35   - /**
36   - * 操作名
37   - */
38   - private String name;
39   -
40   - /**
41   - * 操作分类
42   - */
43   - private Integer type;
44   -
45   - /**
46   - * 操作明细
47   - */
48   - private String content;
49   -
50   - /**
51   - * 拓展字段
52   - */
53   - private Map<String, Object> exts;
54   -
55   - /**
56   - * 请求方法名
57   - */
58   - private String requestMethod;
59   -
60   - /**
61   - * 请求地址
62   - */
63   - private String requestUrl;
64   -
65   - /**
66   - * 用户 IP
67   - */
68   - private String userIp;
69   -
70   - /**
71   - * 浏览器 UserAgent
72   - */
73   - private String userAgent;
74   -
75   - /**
76   - * Java 方法名
77   - */
78   - private String javaMethod;
79   -
80   - /**
81   - * Java 方法的参数
82   - */
83   - private String javaMethodArgs;
84   -
85   - /**
86   - * 开始时间
87   - */
88   - private LocalDateTime startTime;
89   -
90   - /**
91   - * 执行时长,单位:毫秒
92   - */
93   - private Integer duration;
94   -
95   - /**
96   - * 结果码
97   - */
98   - private Integer resultCode;
99   -
100   - /**
101   - * 结果提示
102   - */
103   - private String resultMsg;
104   -
105   - /**
106   - * 结果数据
107   - */
108   - private String resultData;
109   -
110   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkService.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core.service;
2   -
3   -/**
4   - * 操作日志 Framework Service 接口
5   - *
6   - * @author 芋道源码
7   - */
8   -public interface OperateLogFrameworkService {
9   -
10   - /**
11   - * 记录操作日志
12   - *
13   - * @param operateLog 操作日志请求
14   - */
15   - void createOperateLog(OperateLog operateLog);
16   -
17   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core.service;
2   -
3   -import cn.hutool.core.bean.BeanUtil;
4   -import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
5   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
6   -import lombok.RequiredArgsConstructor;
7   -import org.springframework.scheduling.annotation.Async;
8   -
9   -/**
10   - * 操作日志 Framework Service 实现类
11   - *
12   - * 基于 {@link OperateLogApi} 实现,记录操作日志
13   - *
14   - * @author 芋道源码
15   - */
16   -@RequiredArgsConstructor
17   -public class OperateLogFrameworkServiceImpl implements OperateLogFrameworkService {
18   -
19   - private final OperateLogApi operateLogApi;
20   -
21   - @Override
22   - @Async
23   - public void createOperateLog(OperateLog operateLog) {
24   - OperateLogCreateReqDTO reqDTO = BeanUtil.toBean(operateLog, OperateLogCreateReqDTO.class);
25   - operateLogApi.createOperateLog(reqDTO);
26   - }
27   -
28   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/util/OperateLogUtils.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core.util;
2   -
3   -import cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect;
4   -
5   -/**
6   - * 操作日志工具类
7   - * 目前主要的作用,是提供给业务代码,记录操作明细和拓展字段
8   - *
9   - * @author 芋道源码
10   - */
11   -public class OperateLogUtils {
12   -
13   - public static void setContent(String content) {
14   - OperateLogAspect.setContent(content);
15   - }
16   -
17   - public static void addExt(String key, Object value) {
18   - OperateLogAspect.addExt(key, value);
19   - }
20   -
21   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/package-info.java deleted
1   -/**
2   - * 用户操作日志:记录用户的操作,用于对用户的操作的审计与追溯,永久保存。
3   - *
4   - * @author 芋道源码
5   - */
6   -package cn.iocoder.yudao.framework.operatelog;
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted
1   -cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration
2 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java
... ... @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
5 5 import cn.iocoder.yudao.framework.security.core.LoginUser;
6 6 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
7 7 import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
8   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
  8 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
9 9 import com.mzt.logapi.beans.LogRecord;
10 10 import com.mzt.logapi.service.ILogRecordService;
11 11 import jakarta.annotation.Resource;
... ... @@ -30,7 +30,7 @@ public class LogRecordServiceImpl implements ILogRecordService {
30 30 @Override
31 31 public void record(LogRecord logRecord) {
32 32 // 1. 补全通用字段
33   - OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO();
  33 + OperateLogCreateReqDTO reqDTO = new OperateLogCreateReqDTO();
34 34 reqDTO.setTraceId(TracerUtils.getTraceId());
35 35 // 补充用户信息
36 36 fillUserFields(reqDTO);
... ... @@ -40,12 +40,10 @@ public class LogRecordServiceImpl implements ILogRecordService {
40 40 fillRequestFields(reqDTO);
41 41  
42 42 // 2. 异步记录日志
43   - operateLogApi.createOperateLogV2(reqDTO);
44   - // TODO 测试结束删除或搞个开关
45   - log.info("操作日志 ===> {}", reqDTO);
  43 + operateLogApi.createOperateLog(reqDTO);
46 44 }
47 45  
48   - private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) {
  46 + private static void fillUserFields(OperateLogCreateReqDTO reqDTO) {
49 47 // 使用 SecurityFrameworkUtils。因为要考虑,rpc、mq、job,它其实不是 web;
50 48 LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
51 49 if (loginUser == null) {
... ... @@ -55,7 +53,7 @@ public class LogRecordServiceImpl implements ILogRecordService {
55 53 reqDTO.setUserType(loginUser.getUserType());
56 54 }
57 55  
58   - public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) {
  56 + public static void fillModuleFields(OperateLogCreateReqDTO reqDTO, LogRecord logRecord) {
59 57 reqDTO.setType(logRecord.getType()); // 大模块类型,例如:CRM 客户
60 58 reqDTO.setSubType(logRecord.getSubType());// 操作名称,例如:转移客户
61 59 reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 业务编号,例如:客户编号
... ... @@ -63,7 +61,7 @@ public class LogRecordServiceImpl implements ILogRecordService {
63 61 reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
64 62 }
65 63  
66   - private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {
  64 + private static void fillRequestFields(OperateLogCreateReqDTO reqDTO) {
67 65 // 获得 Request 对象
68 66 HttpServletRequest request = ServletUtils.getRequest();
69 67 if (request == null) {
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java
... ... @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogR
8 8 import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
9 9 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
10 10 import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
11   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
  11 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
12 12 import io.swagger.v3.oas.annotations.Operation;
13 13 import io.swagger.v3.oas.annotations.tags.Tag;
14 14 import jakarta.annotation.Resource;
... ... @@ -55,9 +55,9 @@ public class CrmOperateLogController {
55 55 @Operation(summary = "获得操作日志")
56 56 @PreAuthorize("@ss.hasPermission('crm:operate-log:query')")
57 57 public CommonResult<PageResult<CrmOperateLogRespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
58   - OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
  58 + OperateLogPageReqDTO reqDTO = new OperateLogPageReqDTO();
59 59 reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
60   - reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
  60 + reqDTO.setType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
61 61 return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogRespVO.class));
62 62 }
63 63  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -8,6 +8,8 @@ import cn.hutool.extra.template.TemplateConfig;
8 8 import cn.hutool.extra.template.TemplateEngine;
9 9 import cn.hutool.extra.template.engine.velocity.VelocityEngine;
10 10 import cn.hutool.system.SystemUtil;
  11 +import cn.iocoder.yudao.framework.apilog.core.annotations.ApiAccessLog;
  12 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
11 13 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
12 14 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
13 15 import cn.iocoder.yudao.framework.common.pojo.PageParam;
... ... @@ -24,8 +26,6 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
24 26 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
25 27 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
26 28 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
27   -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
28   -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
29 29 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
30 30 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
31 31 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
... ... @@ -211,7 +211,7 @@ public class CodegenEngine {
211 211 globalBindingMap.put("LocalDateTimeUtilsClassName", LocalDateTimeUtils.class.getName());
212 212 globalBindingMap.put("ObjectUtilsClassName", ObjectUtils.class.getName());
213 213 globalBindingMap.put("DictConvertClassName", DictConvert.class.getName());
214   - globalBindingMap.put("OperateLogClassName", OperateLog.class.getName());
  214 + globalBindingMap.put("ApiAccessLogClassName", ApiAccessLog.class.getName());
215 215 globalBindingMap.put("OperateTypeEnumClassName", OperateTypeEnum.class.getName());
216 216 globalBindingMap.put("BeanUtils", BeanUtils.class.getName());
217 217 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
... ... @@ -23,7 +23,7 @@ import static ${CommonResultClassName}.success;
23 23  
24 24 import ${ExcelUtilsClassName};
25 25  
26   -import ${OperateLogClassName};
  26 +import ${ApiAccessLogClassName};
27 27 import static ${OperateTypeEnumClassName}.*;
28 28  
29 29 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
... ... @@ -114,7 +114,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
114 114 #if ($sceneEnum.scene == 1)
115 115 @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
116 116 #end
117   - @OperateLog(type = EXPORT)
  117 + @ApiAccessLog(operateType = EXPORT)
118 118 #if ( $table.templateType != 2 )
119 119 public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO,
120 120 HttpServletResponse response) throws IOException {
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java
... ... @@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.system.api.logger;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
5   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
6   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
7   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
  5 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
  6 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogRespDTO;
8 7 import jakarta.validation.Valid;
9 8  
10 9 /**
... ... @@ -22,18 +21,11 @@ public interface OperateLogApi {
22 21 void createOperateLog(@Valid OperateLogCreateReqDTO createReqDTO);
23 22  
24 23 /**
25   - * 创建操作日志
26   - *
27   - * @param createReqDTO 请求
28   - */
29   - void createOperateLogV2(@Valid OperateLogV2CreateReqDTO createReqDTO);
30   -
31   - /**
32 24 * 获取指定模块的指定数据的操作日志分页
33 25 *
34 26 * @param pageReqVO 请求
35 27 * @return 操作日志分页
36 28 */
37   - PageResult<OperateLogV2RespDTO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO);
  29 + PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqVO);
38 30  
39 31 }
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogCreateReqDTO.java
1 1 package cn.iocoder.yudao.module.system.api.logger.dto;
2 2  
3   -import lombok.Data;
4   -
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
5 4 import jakarta.validation.constraints.NotEmpty;
6 5 import jakarta.validation.constraints.NotNull;
7   -import java.time.LocalDateTime;
8   -import java.util.Map;
  6 +import lombok.Data;
9 7  
10 8 /**
11   - * 操作日志创建 Request DTO
  9 + * 系统操作日志 Create Request DTO
  10 + *
  11 + * @author HUIHUI
12 12 */
13 13 @Data
14 14 public class OperateLogCreateReqDTO {
15 15  
16 16 /**
17 17 * 链路追踪编号
  18 + *
  19 + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。
18 20 */
19 21 private String traceId;
20   -
21 22 /**
22 23 * 用户编号
  24 + *
  25 + * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性
23 26 */
24 27 @NotNull(message = "用户编号不能为空")
25 28 private Long userId;
26 29 /**
27 30 * 用户类型
  31 + *
  32 + * 关联 {@link UserTypeEnum}
28 33 */
29 34 @NotNull(message = "用户类型不能为空")
30 35 private Integer userType;
31   -
32 36 /**
33   - * 操作模块
  37 + * 操作模块类型
34 38 */
35   - @NotEmpty(message = "操作模块不能为空")
36   - private String module;
37   -
  39 + @NotEmpty(message = "操作模块类型不能为空")
  40 + private String type;
38 41 /**
39 42 * 操作名
40 43 */
41   - @NotEmpty(message = "操作名")
42   - private String name;
43   -
  44 + @NotEmpty(message = "操作名不能为空")
  45 + private String subType;
44 46 /**
45   - * 操作分类
  47 + * 操作模块业务编号
46 48 */
47   - @NotNull(message = "操作分类不能为空")
48   - private Integer type;
49   -
  49 + @NotNull(message = "操作模块业务编号不能为空")
  50 + private Long bizId;
50 51 /**
51   - * 操作明细
  52 + * 操作内容,记录整个操作的明细
  53 + * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
52 54 */
53   - private String content;
54   -
  55 + @NotEmpty(message = "操作内容不能为空")
  56 + private String action;
55 57 /**
56   - * 拓展字段
  58 + * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
  59 + * 例如说,记录订单编号,{ orderId: "1"}
57 60 */
58   - private Map<String, Object> exts;
  61 + private String extra;
59 62  
60 63 /**
61 64 * 请求方法名
62 65 */
63 66 @NotEmpty(message = "请求方法名不能为空")
64 67 private String requestMethod;
65   -
66 68 /**
67 69 * 请求地址
68 70 */
69 71 @NotEmpty(message = "请求地址不能为空")
70 72 private String requestUrl;
71   -
72 73 /**
73 74 * 用户 IP
74 75 */
75 76 @NotEmpty(message = "用户 IP 不能为空")
76 77 private String userIp;
77   -
78 78 /**
79   - * 浏览器 UserAgent
  79 + * 浏览器 UA
80 80 */
81   - @NotEmpty(message = "浏览器 UserAgent 不能为空")
  81 + @NotEmpty(message = "浏览器 UA 不能为空")
82 82 private String userAgent;
83 83  
84   - /**
85   - * Java 方法名
86   - */
87   - @NotEmpty(message = "Java 方法名不能为空")
88   - private String javaMethod;
89   -
90   - /**
91   - * Java 方法的参数
92   - */
93   - private String javaMethodArgs;
94   -
95   - /**
96   - * 开始时间
97   - */
98   - @NotNull(message = "开始时间不能为空")
99   - private LocalDateTime startTime;
100   -
101   - /**
102   - * 执行时长,单位:毫秒
103   - */
104   - @NotNull(message = "执行时长不能为空")
105   - private Integer duration;
106   -
107   - /**
108   - * 结果码
109   - */
110   - @NotNull(message = "结果码不能为空")
111   - private Integer resultCode;
112   -
113   - /**
114   - * 结果提示
115   - */
116   - private String resultMsg;
117   -
118   - /**
119   - * 结果数据
120   - */
121   - private String resultData;
122   -
123 84 }
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2PageReqDTO.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogPageReqDTO.java
... ... @@ -9,12 +9,12 @@ import lombok.Data;
9 9 * @author HUIHUI
10 10 */
11 11 @Data
12   -public class OperateLogV2PageReqDTO extends PageParam {
  12 +public class OperateLogPageReqDTO extends PageParam {
13 13  
14 14 /**
15 15 * 模块类型
16 16 */
17   - private String bizType;
  17 + private String type;
18 18 /**
19 19 * 模块数据编号
20 20 */
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogRespDTO.java
... ... @@ -13,7 +13,7 @@ import java.time.LocalDateTime;
13 13 * @author HUIHUI
14 14 */
15 15 @Data
16   -public class OperateLogV2RespDTO implements VO {
  16 +public class OperateLogRespDTO implements VO {
17 17  
18 18 /**
19 19 * 日志编号
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2CreateReqDTO.java deleted
1   -package cn.iocoder.yudao.module.system.api.logger.dto;
2   -
3   -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4   -import jakarta.validation.constraints.NotEmpty;
5   -import jakarta.validation.constraints.NotNull;
6   -import lombok.Data;
7   -
8   -/**
9   - * 系统操作日志 Create Request DTO
10   - *
11   - * @author HUIHUI
12   - */
13   -@Data
14   -public class OperateLogV2CreateReqDTO {
15   -
16   - /**
17   - * 链路追踪编号
18   - *
19   - * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。
20   - */
21   - private String traceId;
22   - /**
23   - * 用户编号
24   - *
25   - * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性
26   - */
27   - @NotNull(message = "用户编号不能为空")
28   - private Long userId;
29   - /**
30   - * 用户类型
31   - *
32   - * 关联 {@link UserTypeEnum}
33   - */
34   - @NotNull(message = "用户类型不能为空")
35   - private Integer userType;
36   - /**
37   - * 操作模块类型
38   - */
39   - @NotEmpty(message = "操作模块类型不能为空")
40   - private String type;
41   - /**
42   - * 操作名
43   - */
44   - @NotEmpty(message = "操作名不能为空")
45   - private String subType;
46   - /**
47   - * 操作模块业务编号
48   - */
49   - @NotNull(message = "操作模块业务编号不能为空")
50   - private Long bizId;
51   - /**
52   - * 操作内容,记录整个操作的明细
53   - * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
54   - */
55   - @NotEmpty(message = "操作内容不能为空")
56   - private String action;
57   - /**
58   - * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
59   - * 例如说,记录订单编号,{ orderId: "1"}
60   - */
61   - private String extra;
62   -
63   - /**
64   - * 请求方法名
65   - */
66   - @NotEmpty(message = "请求方法名不能为空")
67   - private String requestMethod;
68   - /**
69   - * 请求地址
70   - */
71   - @NotEmpty(message = "请求地址不能为空")
72   - private String requestUrl;
73   - /**
74   - * 用户 IP
75   - */
76   - @NotEmpty(message = "用户 IP 不能为空")
77   - private String userIp;
78   - /**
79   - * 浏览器 UA
80   - */
81   - @NotEmpty(message = "浏览器 UA 不能为空")
82   - private String userAgent;
83   -
84   -}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java
1 1 package cn.iocoder.yudao.module.system.api.logger;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 5 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
7   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
8   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
9   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
10   -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
  6 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
  7 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogRespDTO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
11 9 import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
12 10 import com.fhs.core.trans.anno.TransMethodResult;
13 11 import jakarta.annotation.Resource;
... ... @@ -28,24 +26,16 @@ public class OperateLogApiImpl implements OperateLogApi {
28 26 private OperateLogService operateLogService;
29 27  
30 28 @Override
  29 + @Async
31 30 public void createOperateLog(OperateLogCreateReqDTO createReqDTO) {
32 31 operateLogService.createOperateLog(createReqDTO);
33 32 }
34 33  
35 34 @Override
36   - @Async
37   - public void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO) {
38   - operateLogService.createOperateLogV2(createReqDTO);
39   - }
40   -
41   - @Override
42 35 @TransMethodResult
43   - public PageResult<OperateLogV2RespDTO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO) {
44   - PageResult<OperateLogV2DO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO);
45   - if (CollUtil.isEmpty(operateLogPage.getList())) {
46   - return PageResult.empty();
47   - }
48   - return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class);
  36 + public PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqVO) {
  37 + PageResult<OperateLogDO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO);
  38 + return BeanUtils.toBean(operateLogPage, OperateLogRespDTO.class);
49 39 }
50 40  
51 41 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java
... ... @@ -13,20 +13,23 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
13 13 @Data
14 14 public class OperateLogPageReqVO extends PageParam {
15 15  
16   - @Schema(description = "操作模块,模拟匹配", example = "订单")
17   - private String module;
  16 + @Schema(description = "用户编号", example = "芋道")
  17 + private Long userId;
  18 +
  19 + @Schema(description = "操作模块业务编号", example = "1")
  20 + private Long bizId;
18 21  
19   - @Schema(description = "用户昵称,模拟匹配", example = "芋道")
20   - private String userNickname;
  22 + @Schema(description = "操作模块,模拟匹配", example = "订单")
  23 + private String type;
21 24  
22   - @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1")
23   - private Integer type;
  25 + @Schema(description = "操作名,模拟匹配", example = "创建订单")
  26 + private String subType;
24 27  
25   - @Schema(description = "操作状态", example = "true")
26   - private Boolean success;
  28 + @Schema(description = "操作明细,模拟匹配", example = "修改编号为 1 的用户信息")
  29 + private String action;
27 30  
28 31 @Schema(description = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
29 32 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
30   - private LocalDateTime[] startTime;
  33 + private LocalDateTime[] createTime;
31 34  
32 35 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java
1 1 package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog;
2 2  
3   -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4   -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
5 3 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
6   -import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
7 4 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
8 5 import com.alibaba.excel.annotation.ExcelProperty;
9 6 import com.fhs.core.trans.anno.Trans;
... ... @@ -14,7 +11,6 @@ import jakarta.validation.constraints.NotEmpty;
14 11 import lombok.Data;
15 12  
16 13 import java.time.LocalDateTime;
17   -import java.util.Map;
18 14  
19 15 @Schema(description = "管理后台 - 操作日志 Response VO")
20 16 @Data
... ... @@ -29,31 +25,29 @@ public class OperateLogRespVO implements VO {
29 25 private String traceId;
30 26  
31 27 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
32   - @Trans(type = TransType.SIMPLE, target = AdminUserDO.class, fields = "nickname", ref = "userNickname")
  28 + @Trans(type = TransType.SIMPLE, target = AdminUserDO.class, fields = "nickname", ref = "userName")
33 29 private Long userId;
34   -
35 30 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
36 31 @ExcelProperty("操作人")
37   - private String userNickname;
  32 + private String userName;
38 33  
39   - @Schema(description = "操作模块", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单")
40   - @ExcelProperty("操作模块")
41   - private String module;
  34 + @Schema(description = "操作模块类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单")
  35 + @ExcelProperty("操作模块类型")
  36 + private String type;
42 37  
43 38 @Schema(description = "操作名", requiredMode = Schema.RequiredMode.REQUIRED, example = "创建订单")
44 39 @ExcelProperty("操作名")
45   - private String name;
  40 + private String subType;
46 41  
47   - @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
48   - @ExcelProperty(value = "操作类型", converter = DictConvert.class)
49   - @DictFormat(DictTypeConstants.OPERATE_TYPE)
50   - private Integer type;
  42 + @Schema(description = "操作模块业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  43 + @ExcelProperty("操作模块业务编号")
  44 + private Long bizId;
51 45  
52 46 @Schema(description = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。")
53   - private String content;
  47 + private String action;
54 48  
55 49 @Schema(description = "拓展字段", example = "{'orderId': 1}")
56   - private Map<String, Object> exts;
  50 + private String extra;
57 51  
58 52 @Schema(description = "请求方法名", requiredMode = Schema.RequiredMode.REQUIRED, example = "GET")
59 53 @NotEmpty(message = "请求方法名不能为空")
... ... @@ -68,28 +62,7 @@ public class OperateLogRespVO implements VO {
68 62 @Schema(description = "浏览器 UserAgent", requiredMode = Schema.RequiredMode.REQUIRED, example = "Mozilla/5.0")
69 63 private String userAgent;
70 64  
71   - @Schema(description = "Java 方法名", requiredMode = Schema.RequiredMode.REQUIRED, example = "cn.iocoder.yudao.adminserver.UserController.save(...)")
72   - private String javaMethod;
73   -
74   - @Schema(description = "Java 方法的参数")
75   - private String javaMethodArgs;
76   -
77   - @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
78   - @ExcelProperty("操作日志")
79   - private LocalDateTime startTime;
80   -
81   - @Schema(description = "执行时长,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED)
82   - @ExcelProperty("执行时长")
83   - private Integer duration;
84   -
85   - @Schema(description = "结果码", requiredMode = Schema.RequiredMode.REQUIRED)
86   - @ExcelProperty(value = "结果码")
87   - private Integer resultCode;
88   -
89   - @Schema(description = "结果提示")
90   - private String resultMsg;
91   -
92   - @Schema(description = "结果数据")
93   - private String resultData;
  65 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  66 + private LocalDateTime createTime;
94 67  
95 68 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogDO.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   -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
7 5 import com.baomidou.mybatisplus.annotation.KeySequence;
8   -import com.baomidou.mybatisplus.annotation.TableField;
9 6 import com.baomidou.mybatisplus.annotation.TableId;
10 7 import com.baomidou.mybatisplus.annotation.TableName;
11   -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
12 8 import lombok.Data;
13   -import lombok.EqualsAndHashCode;
14   -
15   -import java.time.LocalDateTime;
16   -import java.util.Map;
17 9  
18 10 /**
19 11 * 操作日志表
... ... @@ -23,20 +15,9 @@ import java.util.Map;
23 15 @TableName(value = "system_operate_log", autoResultMap = true)
24 16 @KeySequence("system_operate_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
25 17 @Data
26   -@EqualsAndHashCode(callSuper = true)
27 18 public class OperateLogDO extends BaseDO {
28 19  
29 20 /**
30   - * {@link #javaMethodArgs} 的最大长度
31   - */
32   - public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000;
33   -
34   - /**
35   - * {@link #resultData} 的最大长度
36   - */
37   - public static final Integer RESULT_MAX_LENGTH = 4000;
38   -
39   - /**
40 21 * 日志主键
41 22 */
42 23 @TableId
... ... @@ -60,30 +41,29 @@ public class OperateLogDO extends BaseDO {
60 41 */
61 42 private Integer userType;
62 43 /**
63   - * 操作模块
  44 + * 操作模块类型
64 45 */
65   - private String module;
  46 + private String type;
66 47 /**
67 48 * 操作名
68 49 */
69   - private String name;
  50 + private String subType;
70 51 /**
71   - * 操作分类
72   - *
73   - * 枚举 {@link OperateTypeEnum}
  52 + * 操作模块业务编号
74 53 */
75   - private Integer type;
  54 + private Long bizId;
76 55 /**
77   - * 操作内容,记录整个操作的明细
  56 + * 日志内容,记录整个操作的明细
  57 + *
78 58 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
79 59 */
80   - private String content;
  60 + private String action;
81 61 /**
82   - * 拓展字段,有些复杂的业务,需要记录一些字段
83   - * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号
  62 + * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
  63 + *
  64 + * 例如说,记录订单编号,{ orderId: "1"}
84 65 */
85   - @TableField(typeHandler = JacksonTypeHandler.class)
86   - private Map<String, Object> exts;
  66 + private String extra;
87 67  
88 68 /**
89 69 * 请求方法名
... ... @@ -102,43 +82,4 @@ public class OperateLogDO extends BaseDO {
102 82 */
103 83 private String userAgent;
104 84  
105   - /**
106   - * Java 方法名
107   - */
108   - private String javaMethod;
109   - /**
110   - * Java 方法的参数
111   - *
112   - * 实际格式为 Map<String, Object>
113   - * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败
114   - * 其中,key 为参数名,value 为参数值
115   - */
116   - private String javaMethodArgs;
117   - /**
118   - * 开始时间
119   - */
120   - private LocalDateTime startTime;
121   - /**
122   - * 执行时长,单位:毫秒
123   - */
124   - private Integer duration;
125   - /**
126   - * 结果码
127   - *
128   - * 目前使用的 {@link CommonResult#getCode()} 属性
129   - */
130   - private Integer resultCode;
131   - /**
132   - * 结果提示
133   - *
134   - * 目前使用的 {@link CommonResult#getMsg()} 属性
135   - */
136   - private String resultMsg;
137   - /**
138   - * 结果数据
139   - *
140   - * 如果是对象,则使用 JSON 格式化
141   - */
142   - private String resultData;
143   -
144 85 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java deleted
1   -package cn.iocoder.yudao.module.system.dal.dataobject.logger;
2   -
3   -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5   -import com.baomidou.mybatisplus.annotation.KeySequence;
6   -import com.baomidou.mybatisplus.annotation.TableId;
7   -import com.baomidou.mybatisplus.annotation.TableName;
8   -import lombok.Data;
9   -import lombok.EqualsAndHashCode;
10   -
11   -/**
12   - * 操作日志表 V2
13   - *
14   - * @author 芋道源码
15   - */
16   -@TableName(value = "system_operate_log_v2", autoResultMap = true)
17   -@KeySequence("system_operate_log_seq_v2") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
18   -@Data
19   -@EqualsAndHashCode(callSuper = true)
20   -public class OperateLogV2DO extends BaseDO {
21   -
22   - /**
23   - * 日志主键
24   - */
25   - @TableId
26   - private Long id;
27   - /**
28   - * 链路追踪编号
29   - *
30   - * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。
31   - */
32   - private String traceId;
33   - /**
34   - * 用户编号
35   - *
36   - * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性
37   - */
38   - private Long userId;
39   - /**
40   - * 用户类型
41   - *
42   - * 关联 {@link UserTypeEnum}
43   - */
44   - private Integer userType;
45   - /**
46   - * 操作模块类型
47   - */
48   - private String type;
49   - /**
50   - * 操作名
51   - */
52   - private String subType;
53   - /**
54   - * 操作模块业务编号
55   - */
56   - private Long bizId;
57   - /**
58   - * 日志内容,记录整个操作的明细
59   - *
60   - * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
61   - */
62   - private String action;
63   - /**
64   - * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
65   - *
66   - * 例如说,记录订单编号,{ orderId: "1"}
67   - */
68   - private String extra;
69   -
70   - /**
71   - * 请求方法名
72   - */
73   - private String requestMethod;
74   - /**
75   - * 请求地址
76   - */
77   - private String requestUrl;
78   - /**
79   - * 用户 IP
80   - */
81   - private String userIp;
82   - /**
83   - * 浏览器 UA
84   - */
85   - private String userAgent;
86   -
87   -}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogMapper.java
1 1 package cn.iocoder.yudao.module.system.dal.mysql.logger;
2 2  
3   -import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
4 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
7 7 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
8 8 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10 10  
11   -import java.util.Collection;
12   -
13 11 @Mapper
14 12 public interface OperateLogMapper extends BaseMapperX<OperateLogDO> {
15 13  
16   - default PageResult<OperateLogDO> selectPage(OperateLogPageReqVO reqVO, Collection<Long> userIds) {
17   - LambdaQueryWrapperX<OperateLogDO> query = new LambdaQueryWrapperX<OperateLogDO>()
18   - .likeIfPresent(OperateLogDO::getModule, reqVO.getModule())
19   - .inIfPresent(OperateLogDO::getUserId, userIds)
20   - .eqIfPresent(OperateLogDO::getType, reqVO.getType())
21   - .betweenIfPresent(OperateLogDO::getStartTime, reqVO.getStartTime());
22   - if (Boolean.TRUE.equals(reqVO.getSuccess())) {
23   - query.eq(OperateLogDO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode());
24   - } else if (Boolean.FALSE.equals(reqVO.getSuccess())) {
25   - query.gt(OperateLogDO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode());
26   - }
27   - query.orderByDesc(OperateLogDO::getId); // 降序
28   - return selectPage(reqVO, query);
  14 + default PageResult<OperateLogDO> selectPage(OperateLogPageReqVO pageReqDTO) {
  15 + return selectPage(pageReqDTO, new LambdaQueryWrapperX<OperateLogDO>()
  16 + .eqIfPresent(OperateLogDO::getUserId, pageReqDTO.getUserId())
  17 + .eqIfPresent(OperateLogDO::getBizId, pageReqDTO.getBizId())
  18 + .likeIfPresent(OperateLogDO::getType, pageReqDTO.getType())
  19 + .likeIfPresent(OperateLogDO::getSubType, pageReqDTO.getSubType())
  20 + .likeIfPresent(OperateLogDO::getAction, pageReqDTO.getAction())
  21 + .betweenIfPresent(OperateLogDO::getCreateTime, pageReqDTO.getCreateTime())
  22 + .orderByDesc(OperateLogDO::getId));
  23 + }
  24 +
  25 + default PageResult<OperateLogDO> selectPage(OperateLogPageReqDTO pageReqDTO) {
  26 + return selectPage(pageReqDTO, new LambdaQueryWrapperX<OperateLogDO>()
  27 + .eqIfPresent(OperateLogDO::getType, pageReqDTO.getType())
  28 + .eqIfPresent(OperateLogDO::getBizId, pageReqDTO.getBizId())
  29 + .eqIfPresent(OperateLogDO::getUserId, pageReqDTO.getUserId())
  30 + .orderByDesc(OperateLogDO::getId));
29 31 }
30 32  
31 33 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java deleted
1   -package cn.iocoder.yudao.module.system.dal.mysql.logger;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
7   -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
8   -import org.apache.ibatis.annotations.Mapper;
9   -
10   -@Mapper
11   -public interface OperateLogV2Mapper extends BaseMapperX<OperateLogV2DO> {
12   -
13   - default PageResult<OperateLogV2DO> selectPage(OperateLogV2PageReqDTO pageReqDTO) {
14   - return selectPage(pageReqDTO, new LambdaQueryWrapperX<OperateLogV2DO>()
15   - .eqIfPresent(OperateLogV2DO::getType, pageReqDTO.getBizType())
16   - .eqIfPresent(OperateLogV2DO::getBizId, pageReqDTO.getBizId())
17   - .eqIfPresent(OperateLogV2DO::getUserId, pageReqDTO.getUserId())
18   - .orderByDesc(OperateLogV2DO::getId));
19   - }
20   -
21   -}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java
... ... @@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.system.service.logger;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
5   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
6   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
  5 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
7 6 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
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  
11 9 /**
12 10 * 操作日志 Service 接口
... ... @@ -18,7 +16,7 @@ public interface OperateLogService {
18 16 /**
19 17 * 记录操作日志
20 18 *
21   - * @param createReqDTO 操作日志请求
  19 + * @param createReqDTO 创建请求
22 20 */
23 21 void createOperateLog(OperateLogCreateReqDTO createReqDTO);
24 22  
... ... @@ -30,21 +28,12 @@ public interface OperateLogService {
30 28 */
31 29 PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqVO pageReqVO);
32 30  
33   - // ======================= LOG V2 =======================
34   -
35   - /**
36   - * 记录操作日志 V2
37   - *
38   - * @param createReqDTO 创建请求
39   - */
40   - void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO);
41   -
42 31 /**
43 32 * 获得操作日志分页列表
44 33 *
45 34 * @param pageReqVO 分页条件
46 35 * @return 操作日志分页列表
47 36 */
48   - PageResult<OperateLogV2DO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO);
  37 + PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqDTO pageReqVO);
49 38  
50 39 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java
1 1 package cn.iocoder.yudao.module.system.service.logger;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.StrUtil;
5 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7   -import cn.iocoder.yudao.framework.common.util.string.StrUtils;
8 5 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
9   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
10   -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
  6 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
11 7 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
12 8 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
13   -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
14   -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
15 9 import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper;
16   -import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogV2Mapper;
17   -import cn.iocoder.yudao.module.system.service.user.AdminUserService;
18 10 import jakarta.annotation.Resource;
19 11 import lombok.extern.slf4j.Slf4j;
20 12 import org.springframework.stereotype.Service;
21 13 import org.springframework.validation.annotation.Validated;
22 14  
23   -import java.util.Collection;
24   -
25   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
26   -import static cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO.JAVA_METHOD_ARGS_MAX_LENGTH;
27   -import static cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO.RESULT_MAX_LENGTH;
28   -
29 15 /**
30 16 * 操作日志 Service 实现类
31 17 *
... ... @@ -38,45 +24,21 @@ public class OperateLogServiceImpl implements OperateLogService {
38 24  
39 25 @Resource
40 26 private OperateLogMapper operateLogMapper;
41   - @Resource
42   - private OperateLogV2Mapper operateLogV2Mapper;
43   -
44   - @Resource
45   - private AdminUserService userService;
46 27  
47 28 @Override
48 29 public void createOperateLog(OperateLogCreateReqDTO createReqDTO) {
49 30 OperateLogDO log = BeanUtils.toBean(createReqDTO, OperateLogDO.class);
50   - log.setJavaMethodArgs(StrUtils.maxLength(log.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
51   - log.setResultData(StrUtils.maxLength(log.getResultData(), RESULT_MAX_LENGTH));
52 31 operateLogMapper.insert(log);
53 32 }
54 33  
55 34 @Override
56 35 public PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqVO pageReqVO) {
57   - // 处理基于用户昵称的查询
58   - Collection<Long> userIds = null;
59   - if (StrUtil.isNotEmpty(pageReqVO.getUserNickname())) {
60   - userIds = convertSet(userService.getUserListByNickname(pageReqVO.getUserNickname()), AdminUserDO::getId);
61   - if (CollUtil.isEmpty(userIds)) {
62   - return PageResult.empty();
63   - }
64   - }
65   - // 查询分页
66   - return operateLogMapper.selectPage(pageReqVO, userIds);
67   - }
68   -
69   - // ======================= LOG V2 =======================
70   -
71   - @Override
72   - public void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO) {
73   - OperateLogV2DO log = BeanUtils.toBean(createReqDTO, OperateLogV2DO.class);
74   - operateLogV2Mapper.insert(log);
  36 + return operateLogMapper.selectPage(pageReqVO);
75 37 }
76 38  
77 39 @Override
78   - public PageResult<OperateLogV2DO> getOperateLogPage(OperateLogV2PageReqDTO pageReqDTO) {
79   - return operateLogV2Mapper.selectPage(pageReqDTO);
  40 + public PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqDTO pageReqDTO) {
  41 + return operateLogMapper.selectPage(pageReqDTO);
80 42 }
81 43  
82 44 }
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java
1 1 package cn.iocoder.yudao.module.system.service.logger;
2 2  
3   -import cn.hutool.core.map.MapUtil;
4   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5   -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6   -import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
7 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8   -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
9 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
10 5 import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
11 6 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
  7 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
12 8 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
13 9 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
14   -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
15 10 import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper;
16   -import cn.iocoder.yudao.module.system.service.user.AdminUserService;
  11 +import jakarta.annotation.Resource;
17 12 import org.junit.jupiter.api.Test;
18   -import org.springframework.boot.test.mock.mockito.MockBean;
19 13 import org.springframework.context.annotation.Import;
20 14  
21   -import jakarta.annotation.Resource;
22   -import java.util.Collections;
23   -
24   -import static cn.hutool.core.util.RandomUtil.randomEle;
25   -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
26 15 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
27 16 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
28 17 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
29 18 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
30   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
31 19 import static org.junit.jupiter.api.Assertions.assertEquals;
32   -import static org.mockito.Mockito.when;
33 20  
34 21 @Import({OperateLogServiceImpl.class})
35 22 public class OperateLogServiceImplTest extends BaseDbUnitTest {
... ... @@ -40,13 +27,9 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest {
40 27 @Resource
41 28 private OperateLogMapper operateLogMapper;
42 29  
43   - @MockBean
44   - private AdminUserService userService;
45   -
46 30 @Test
47 31 public void testCreateOperateLog() {
48   - OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class,
49   - o -> o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build()));
  32 + OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class);
50 33  
51 34 // 调研
52 35 operateLogServiceImpl.createOperateLog(reqVO);
... ... @@ -56,44 +39,38 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest {
56 39 }
57 40  
58 41 @Test
59   - public void testGetOperateLogPage() {
60   - // mock(用户信息)
61   - AdminUserDO user = RandomUtils.randomPojo(AdminUserDO.class, o -> {
62   - o.setNickname("wang");
63   - o.setStatus(CommonStatusEnum.ENABLE.getStatus());
64   - });
65   - when(userService.getUserListByNickname("wang")).thenReturn(Collections.singletonList(user));
66   - Long userId = user.getId();
67   -
  42 + public void testGetOperateLogPage_vo() {
68 43 // 构造操作日志
69 44 OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> {
70   - o.setUserId(userId);
71   - o.setUserType(randomEle(UserTypeEnum.values()).getValue());
72   - o.setModule("order");
73   - o.setType(OperateTypeEnum.CREATE.getType());
74   - o.setStartTime(buildTime(2021, 3, 6));
75   - o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
76   - o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
  45 + o.setUserId(2048L);
  46 + o.setBizId(999L);
  47 + o.setType("订单");
  48 + o.setSubType("创建订单");
  49 + o.setAction("修改编号为 1 的用户信息");
  50 + o.setCreateTime(buildTime(2021, 3, 6));
77 51 });
78 52 operateLogMapper.insert(operateLogDO);
79 53 // 测试 userId 不匹配
80   - operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(userId + 1)));
81   - // 测试 module 不匹配
82   - operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setModule("user")));
  54 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(1024L)));
  55 + // 测试 bizId 不匹配
  56 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setBizId(888L)));
83 57 // 测试 type 不匹配
84   - operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType(OperateTypeEnum.IMPORT.getType())));
  58 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType("退款")));
  59 + // 测试 subType 不匹配
  60 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setSubType("创建退款")));
  61 + // 测试 action 不匹配
  62 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setAction("修改编号为 1 退款信息")));
85 63 // 测试 createTime 不匹配
86   - operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setStartTime(buildTime(2021, 2, 6))));
87   - // 测试 resultCode 不匹配
88   - operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setResultCode(BAD_REQUEST.getCode())));
  64 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setCreateTime(buildTime(2021, 2, 6))));
89 65  
90 66 // 构造调用参数
91 67 OperateLogPageReqVO reqVO = new OperateLogPageReqVO();
92   - reqVO.setUserNickname("wang");
93   - reqVO.setModule("order");
94   - reqVO.setType(OperateTypeEnum.CREATE.getType());
95   - reqVO.setStartTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7));
96   - reqVO.setSuccess(true);
  68 + reqVO.setUserId(2048L);
  69 + reqVO.setBizId(999L);
  70 + reqVO.setType("订");
  71 + reqVO.setSubType("订单");
  72 + reqVO.setAction("用户信息");
  73 + reqVO.setCreateTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7));
97 74  
98 75 // 调用
99 76 PageResult<OperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqVO);
... ... @@ -103,4 +80,34 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest {
103 80 assertPojoEquals(operateLogDO, pageResult.getList().get(0));
104 81 }
105 82  
  83 + @Test
  84 + public void testGetOperateLogPage_dto() {
  85 + // 构造操作日志
  86 + OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> {
  87 + o.setUserId(2048L);
  88 + o.setBizId(999L);
  89 + o.setType("订单");
  90 + });
  91 + operateLogMapper.insert(operateLogDO);
  92 + // 测试 userId 不匹配
  93 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(1024L)));
  94 + // 测试 bizId 不匹配
  95 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setBizId(888L)));
  96 + // 测试 type 不匹配
  97 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType("退款")));
  98 +
  99 + // 构造调用参数
  100 + OperateLogPageReqDTO reqDTO = new OperateLogPageReqDTO();
  101 + reqDTO.setUserId(2048L);
  102 + reqDTO.setBizId(999L);
  103 + reqDTO.setType("订单");
  104 +
  105 + // 调用
  106 + PageResult<OperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqDTO);
  107 + // 断言,只查到了一条符合条件的
  108 + assertEquals(1, pageResult.getTotal());
  109 + assertEquals(1, pageResult.getList().size());
  110 + assertPojoEquals(operateLogDO, pageResult.getList().get(0));
  111 + }
  112 +
106 113 }
... ...
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
... ... @@ -202,22 +202,15 @@ CREATE TABLE IF NOT EXISTS `system_operate_log` (
202 202 `trace_id` varchar(64) NOT NULL DEFAULT '',
203 203 `user_id` bigint(20) NOT NULL,
204 204 "user_type" tinyint not null default '0',
205   - `module` varchar(50) NOT NULL,
206   - `name` varchar(50) NOT NULL,
207   - `type` bigint(4) NOT NULL DEFAULT '0',
208   - `content` varchar(2000) NOT NULL DEFAULT '',
209   - `exts` varchar(512) NOT NULL DEFAULT '',
  205 + `type` varchar(50) NOT NULL,
  206 + `sub_type` varchar(50) NOT NULL,
  207 + `biz_id` bigint(20) NOT NULL,
  208 + `action` varchar(2000) NOT NULL DEFAULT '',
  209 + `extra` varchar(512) NOT NULL DEFAULT '',
210 210 `request_method` varchar(16) DEFAULT '',
211 211 `request_url` varchar(255) DEFAULT '',
212 212 `user_ip` varchar(50) DEFAULT NULL,
213 213 `user_agent` varchar(200) DEFAULT NULL,
214   - `java_method` varchar(512) NOT NULL DEFAULT '',
215   - `java_method_args` varchar(8000) DEFAULT '',
216   - `start_time` datetime NOT NULL,
217   - `duration` int(11) NOT NULL,
218   - `result_code` int(11) NOT NULL DEFAULT '0',
219   - `result_msg` varchar(512) DEFAULT '',
220   - `result_data` varchar(4000) DEFAULT '',
221 214 `creator` varchar(64) DEFAULT '',
222 215 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
223 216 `updater` varchar(64) DEFAULT '',
... ...