操作日志:完善 code review 提到的问题

This commit is contained in:
puhui999
2023-12-26 00:04:20 +08:00
parent 5de6a8bd23
commit 6950368991
27 changed files with 183 additions and 649 deletions

View File

@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.system.api.logger;
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.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
@ -17,10 +17,8 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
/**
* 操作日志 API 实现类
@ -56,17 +54,7 @@ public class OperateLogApiImpl implements OperateLogApi {
// 获取用户
List<AdminUserDO> userList = adminUserService.getUserList(convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId));
return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));
}
// TODO @puhui999这种 convert 还是放到 convert 类里,
private static List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {
Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);
return convertList(logList, item -> {
OperateLogV2RespDTO respDTO = BeanUtils.toBean(item, OperateLogV2RespDTO.class);
findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));
return respDTO;
});
return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList);
}
}

View File

@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.system.convert.logger;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@ -12,6 +15,9 @@ import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@Mapper
public interface OperateLogConvert {
@ -25,4 +31,17 @@ public interface OperateLogConvert {
});
}
default PageResult<OperateLogV2RespDTO> convertPage(PageResult<OperateLogV2DO> operateLogPage, List<AdminUserDO> userList) {
return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));
}
private static List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {
Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);
return CollectionUtils.convertList(logList, item -> {
OperateLogV2RespDTO respDTO = BeanUtils.toBean(item, OperateLogV2RespDTO.class);
findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));
return respDTO;
});
}
}

View File

@ -1,19 +1,13 @@
package cn.iocoder.yudao.module.system.dal.dataobject.logger;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
import java.util.Map;
/**
* 操作日志表 V2
*
@ -25,16 +19,6 @@ import java.util.Map;
@EqualsAndHashCode(callSuper = true)
public class OperateLogV2DO extends BaseDO {
/**
* {@link #javaMethodArgs} 的最大长度
*/
public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000;
/**
* {@link #resultData} 的最大长度
*/
public static final Integer RESULT_MAX_LENGTH = 4000;
/**
* 日志主键
*/
@ -70,20 +54,18 @@ public class OperateLogV2DO extends BaseDO {
* 操作模块业务编号
*/
private Long bizId;
// TODO @puhui999content 改成 actionextra 换成 String。注释就直接用 mzt和它完全对应好了。
/**
* 操作内容,记录整个操作的明细
* 日志内容,记录整个操作的明细
*
* 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
*/
private String content;
private String action;
/**
* 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
*
* 例如说,记录订单编号,{ orderId: "1"}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> extra;
private String extra;
/**
* 请求方法名
@ -102,44 +84,4 @@ public class OperateLogV2DO extends BaseDO {
*/
private String userAgent;
// TODO @puhui999微信已经讨论下面的字段都不要哈
/**
* Java 方法名
*/
private String javaMethod;
/**
* Java 方法的参数
*
* 实际格式为 Map<String, Object>
* 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败
* 其中key 为参数名value 为参数值
*/
private String javaMethodArgs;
/**
* 开始时间
*/
private LocalDateTime startTime;
/**
* 执行时长,单位:毫秒
*/
private Integer duration;
/**
* 结果码
*
* 目前使用的 {@link CommonResult#getCode()} 属性
*/
private Integer resultCode;
/**
* 结果提示
*
* 目前使用的 {@link CommonResult#getMsg()} 属性
*/
private String resultMsg;
/**
* 结果数据
*
* 如果是对象,则使用 JSON 格式化
*/
private String resultData;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.system.framework.operatelog.parse;
package cn.iocoder.yudao.module.system.framework.operatelog.core;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
@ -9,7 +9,6 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
// TODO @puhui999这个微信讨论下function 叫啥好哈
/**
* 自定义函数-通过用户编号获取用户信息
*
@ -27,15 +26,12 @@ public class AdminUserParseFunction implements IParseFunction {
return "getAdminUserById";
}
// TODO @puhui999这个方法的实现优化下哈
@Override
public String apply(Object value) {
if (value == null) {
//log.warn("(getAdminUserById) 解析异常参数为 null");
if (ObjUtil.isEmpty(value)) {
return "";
}
if (StrUtil.isEmpty(value.toString())) {
//log.warn("(getAdminUserById) 解析异常参数为空");
return "";
}
@ -52,4 +48,5 @@ public class AdminUserParseFunction implements IParseFunction {
}
return nickname;
}
}

View File

@ -1,12 +1,12 @@
package cn.iocoder.yudao.module.system.framework.operatelog.parse;
package cn.iocoder.yudao.module.system.framework.operatelog.core;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import com.mzt.logapi.service.IParseFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
// TODO @puhui999还是放在 core 包下哈
/**
* 自定义函数-通过区域编号获取区域信息
*
@ -28,7 +28,7 @@ public class AreaParseFunction implements IParseFunction {
@Override
public String apply(Object value) {
if (value == null) {
if (ObjUtil.isEmpty(value)) {
return "";
}
if (StrUtil.isEmpty(value.toString())) {

View File

@ -71,8 +71,6 @@ public class OperateLogServiceImpl implements OperateLogService {
@Override
public void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO) {
OperateLogV2DO log = BeanUtils.toBean(createReqBO, OperateLogV2DO.class);
log.setJavaMethodArgs(StrUtils.maxLength(log.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
log.setResultData(StrUtils.maxLength(log.getResultData(), RESULT_MAX_LENGTH));
operateLogV2Mapper.insert(log);
}

View File

@ -21,15 +21,14 @@ import cn.iocoder.yudao.module.system.service.social.SocialUserService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.xingyuv.captcha.model.common.ResponseModel;
import com.xingyuv.captcha.service.CaptchaService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@ -237,7 +236,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
// mock 方法(绑定的用户编号)
Long userId = 1L;
when(socialUserService.getSocialUserByCode(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()),
eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId));
eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), randomString(), randomString(), userId));
// mock用户
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId));
when(userService.getUser(eq(userId))).thenReturn(user);