mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-29 18:51:53 +08:00
重构操作日志记录实现
This commit is contained in:
parent
1fae341cae
commit
f56d8a2751
@ -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;
|
Loading…
Reference in New Issue
Block a user