mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-28 16:58:43 +08:00 
			
		
		
		
	重构操作日志记录实现
This commit is contained in:
		| @@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO; | |||||||
| import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||||
| import com.mzt.logapi.beans.LogRecord; | import com.mzt.logapi.beans.LogRecord; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; |  | ||||||
| import jakarta.annotation.Resource; | import jakarta.annotation.Resource; | ||||||
| import jakarta.servlet.http.HttpServletRequest; | import jakarta.servlet.http.HttpServletRequest; | ||||||
| import jakarta.servlet.http.HttpServletResponse; | 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.*; | import static cn.iocoder.yudao.framework.operatelogv2.core.enums.OperateLogV2Constants.*; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 拦截使用 @Operation 注解 |  * 拦截使用 @Operation 注解, 获取操作类型、开始时间、持续时间、方法相关信息、执行结果等信息 | ||||||
|  |  * 对 mzt-biz-log 日志信息进行增强 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -165,27 +165,9 @@ public class OperateLogV2Aspect { | |||||||
|         LogRecord logRecord = CONTENT.get(); |         LogRecord logRecord = CONTENT.get(); | ||||||
|         reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 |         reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 | ||||||
|         reqDTO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 |         reqDTO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 | ||||||
|         if (EXTRA.get() != null) { |  | ||||||
|             reqDTO.setExtra((Map<String, Object>) EXTRA.get().get(EXTRA_KEY)); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // type 属性 |         // type 属性 | ||||||
|         if (logRecord.getType() != null) { |  | ||||||
|         reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户 |         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()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         // subType 属性 |         // subType 属性 | ||||||
|         if (logRecord.getSubType() != null) { |         if (logRecord.getSubType() != null) { | ||||||
|             reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户 |             reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户 | ||||||
| @@ -194,6 +176,24 @@ public class OperateLogV2Aspect { | |||||||
|             reqDTO.setSubType(operation.summary()); |             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) { |     private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) { | ||||||
|   | |||||||
| @@ -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.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| @@ -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.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| @@ -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.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.customer; | |||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 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.CrmCustomerCreateReqVO; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; | ||||||
| @@ -65,17 +66,21 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @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) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||||
|     public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { |     public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|         CrmCustomerDO oldCustomerDO = validateCustomerExists(updateReqVO.getId()); |         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); |         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); | ||||||
|         customerMapper.updateById(updateObj); |         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 |     @Override | ||||||
| @@ -125,27 +130,17 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|      */ |      */ | ||||||
|     @Override |     @Override | ||||||
|     public void validateCustomer(Long customerId) { |     public void validateCustomer(Long customerId) { | ||||||
|         // 校验客户是否存在 |         validateCustomerExists(customerId); | ||||||
|         if (customerId == null) { |  | ||||||
|             throw exception(CUSTOMER_NOT_EXISTS); |  | ||||||
|         } |  | ||||||
|         CrmCustomerDO customer = customerMapper.selectById(customerId); |  | ||||||
|         if (Objects.isNull(customer)) { |  | ||||||
|             throw exception(CUSTOMER_NOT_EXISTS); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     // TODO @puhui999:@LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) |     @LogRecord(type = CRM_CUSTOMER, bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) | ||||||
|     @LogRecord(success = TRANSFER_CUSTOMER_LOG_SUCCESS, type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}") |  | ||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) | ||||||
|     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { |     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { | ||||||
|         // 1. 校验客户是否存在 |         // 1. 校验客户是否存在 | ||||||
|         validateCustomer(reqVO.getId()); |         CrmCustomerDO customerDO = validateCustomerExists(reqVO.getId()); | ||||||
|         // 添加 crmCustomer 到日志上下文 TODO 日志记录放在 service 里是因为已经过了权限校验查询时不用走两次校验 |  | ||||||
|         // TODO @puhui999:customer 不用查询,从 1. 拿到哈;然后 put这个动作,可以放到 3.;这样逻辑结构就是,校验、逻辑、日志,更加清晰 |  | ||||||
|         LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId())); |  | ||||||
|         // 2.1 数据权限转移 |         // 2.1 数据权限转移 | ||||||
|         crmPermissionService.transferPermission( |         crmPermissionService.transferPermission( | ||||||
|                 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); |                 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()); |         customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); | ||||||
|  |  | ||||||
|         // 3. TODO 记录转移日志 |         // 3. TODO 记录转移日志 | ||||||
|  |         LogRecordContext.putVariable("crmCustomer", customerDO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -138,7 +138,6 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这里不用加的,就一个操作哈; |  | ||||||
|     public void deletePermission(Integer bizType, Long bizId) { |     public void deletePermission(Integer bizType, Long bizId) { | ||||||
|         int deletedCount = crmPermissionMapper.deletePermission(bizType, bizId); |         int deletedCount = crmPermissionMapper.deletePermission(bizType, bizId); | ||||||
|         if (deletedCount == 0) { |         if (deletedCount == 0) { | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.logger.dto; | |||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 系统操作日志 Resp DTO |  * 系统操作日志 Resp DTO | ||||||
| @@ -29,13 +30,13 @@ public class OperateLogV2RespDTO { | |||||||
|      */ |      */ | ||||||
|     private Integer userType; |     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; |     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,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.ObjUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| @@ -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.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999