Przeglądaj źródła

重构操作日志记录实现

puhui999 1 rok temu
rodzic
commit
f56d8a2751

+ 21 - 21
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelogv2/core/aop/OperateLogV2Aspect.java

@@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
 import com.google.common.collect.Maps;
 import com.mzt.logapi.beans.LogRecord;
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -46,7 +45,8 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
 import static cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants.*;
 
 /**
- * 拦截使用 @Operation 注解
+ * 拦截使用 @Operation 注解, 获取操作类型、开始时间、持续时间、方法相关信息、执行结果等信息
+ * 对 mzt-biz-log 日志信息进行增强
  *
  * @author HUIHUI
  */
@@ -165,27 +165,9 @@ public class OperateLogV2Aspect {
         LogRecord logRecord = CONTENT.get();
         reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号
         reqDTO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
-        if (EXTRA.get() != null) {
-            reqDTO.setExtra((Map<String, Object>) EXTRA.get().get(EXTRA_KEY)); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
-        }
 
         // type 属性
-        if (logRecord.getType() != null) {
-            reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户
-        }
-        if (StrUtil.isEmpty(reqDTO.getType())) {
-            Tag tag = getClassAnnotation(joinPoint, Tag.class);
-            if (tag != null) {
-                // 优先读取 @Tag 的 name 属性
-                if (StrUtil.isNotEmpty(tag.name())) {
-                    reqDTO.setType(tag.name());
-                }
-                // 没有的话,读取 @API 的 description 属性
-                if (StrUtil.isEmpty(reqDTO.getType()) && ArrayUtil.isNotEmpty(tag.description())) {
-                    reqDTO.setType(tag.description());
-                }
-            }
-        }
+        reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户
         // subType 属性
         if (logRecord.getSubType() != null) {
             reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户
@@ -194,6 +176,24 @@ public class OperateLogV2Aspect {
             reqDTO.setSubType(operation.summary());
         }
 
+        // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
+        Map<String, Object> objectMap = EXTRA.get();
+        if (objectMap != null) {
+            Object object = objectMap.get(EXTRA_KEY);
+            if (object instanceof Map<?, ?> extraMap) {
+                if (extraMap.keySet().stream().allMatch(String.class::isInstance)) {
+                    @SuppressWarnings("unchecked")
+                    Map<String, Object> extra = (Map<String, Object>) extraMap;
+                    reqDTO.setExtra(extra);
+                    return;
+                }
+            }
+            // 激进一点不是 map 直接当 value 处理
+            Map<String, Object> extra = Maps.newHashMapWithExpectedSize(1);
+            extra.put(EXTRA_KEY, object);
+            reqDTO.setExtra(extra);
+        }
+
     }
 
     private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {

+ 1 - 1
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmIndustryParseFunction.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmIndustryParseFunction.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.crm.framework.operatelog.function;
+package cn.iocoder.yudao.module.crm.framework.operatelog.parse;
 
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;

+ 1 - 1
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmLevelParseFunction.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmLevelParseFunction.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.crm.framework.operatelog.function;
+package cn.iocoder.yudao.module.crm.framework.operatelog.parse;
 
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;

+ 1 - 1
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/function/CrmSourceParseFunction.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/parse/CrmSourceParseFunction.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.crm.framework.operatelog.function;
+package cn.iocoder.yudao.module.crm.framework.operatelog.parse;
 
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;

+ 13 - 17
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.customer;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants;
 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
@@ -65,17 +66,21 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    @LogRecord(success = "更新了客户{_DIFF{#updateReqVO}}", type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}")
+    @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}")
     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
     public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
         // 校验存在
         CrmCustomerDO oldCustomerDO = validateCustomerExists(updateReqVO.getId());
 
-        // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null
-        LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class));
         // 更新
         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);
         customerMapper.updateById(updateObj);
+
+        // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null
+        LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class));
+        HashMap<String, Object> extra = new HashMap<>();
+        extra.put("tips", "随便记录一点啦");
+        LogRecordContext.putVariable(OperateLogV2Constants.EXTRA_KEY, extra);
     }
 
     @Override
@@ -125,27 +130,17 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
      */
     @Override
     public void validateCustomer(Long customerId) {
-        // 校验客户是否存在
-        if (customerId == null) {
-            throw exception(CUSTOMER_NOT_EXISTS);
-        }
-        CrmCustomerDO customer = customerMapper.selectById(customerId);
-        if (Objects.isNull(customer)) {
-            throw exception(CUSTOMER_NOT_EXISTS);
-        }
+        validateCustomerExists(customerId);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    // TODO @puhui999:@LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
-    @LogRecord(success = TRANSFER_CUSTOMER_LOG_SUCCESS, type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}")
+    @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
         // 1. 校验客户是否存在
-        validateCustomer(reqVO.getId());
-        // 添加 crmCustomer 到日志上下文 TODO 日志记录放在 service 里是因为已经过了权限校验查询时不用走两次校验
-        // TODO @puhui999:customer 不用查询,从 1. 拿到哈;然后 put这个动作,可以放到 3.;这样逻辑结构就是,校验、逻辑、日志,更加清晰
-        LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId()));
+        CrmCustomerDO customerDO = validateCustomerExists(reqVO.getId());
+
         // 2.1 数据权限转移
         crmPermissionService.transferPermission(
                 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()));
@@ -153,6 +148,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
         customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
 
         // 3. TODO 记录转移日志
+        LogRecordContext.putVariable("crmCustomer", customerDO);
     }
 
     @Override

+ 0 - 1
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java

@@ -138,7 +138,6 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这里不用加的,就一个操作哈;
     public void deletePermission(Integer bizType, Long bizId) {
         int deletedCount = crmPermissionMapper.deletePermission(bizType, bizId);
         if (deletedCount == 0) {

+ 39 - 4
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.logger.dto;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.Map;
 
 /**
  * 系统操作日志 Resp DTO
@@ -29,13 +30,13 @@ public class OperateLogV2RespDTO {
      */
     private Integer userType;
     /**
-     * 操作模块
+     * 操作模块类型
      */
-    private String module;
+    private String type;
     /**
      * 操作名
      */
-    private String name;
+    private String subType;
     /**
      * 操作模块业务编号
      */
@@ -47,7 +48,7 @@ public class OperateLogV2RespDTO {
     /**
      * 拓展字段
      */
-    private String extra;
+    private Map<String, Object> extra;
 
     /**
      * 请求方法名
@@ -66,6 +67,40 @@ public class OperateLogV2RespDTO {
      */
     private String userAgent;
 
+    /**
+     * Java 方法名
+     */
+    private String javaMethod;
+    /**
+     * Java 方法的参数
+     */
+    private String javaMethodArgs;
+
+    /**
+     * 开始时间
+     */
+    private LocalDateTime startTime;
+
+    /**
+     * 执行时长,单位:毫秒
+     */
+    private Integer duration;
+
+    /**
+     * 结果码
+     */
+    private Integer resultCode;
+
+    /**
+     * 结果提示
+     */
+    private String resultMsg;
+
+    /**
+     * 结果数据
+     */
+    private String resultData;
+
     /**
      * 创建时间
      */

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/function/AdminUserParseFunction.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/parse/AdminUserParseFunction.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.framework.operatelog.function;
+package cn.iocoder.yudao.module.system.framework.operatelog.parse;
 
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/function/AreaParseFunction.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/parse/AreaParseFunction.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.framework.operatelog.function;
+package cn.iocoder.yudao.module.system.framework.operatelog.parse;
 
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;