产品需求
前几天,产品提了个需求,要记录下所有用户在管理平台的操作记录,这个简单通过AOP半天搞定,后来和产品聊了下,对于更新操作要记录操作前的值和操作后的值,比如用户修改某条数据要展示修改了哪些字段,并且要记录修改前的值和修改后的值,字段名称也要用中文,方便运营人员看
这就让人有点头大,会有个地方比较麻烦
因为前台的编辑保存操作都是将数据全量传给后端,如果需要知道哪些字段发生了变更就需要和数据库的旧值进行比较
思路
- 使用注解记录日志的元数据
- 使用AOP切面进行操作日志数据的组装插入
- 对dto字段增加注解别名
- 比较新老dto,将变更的内容存入http会话
- aop方法调用完毕获取字段变更内容
表设计
![e17d405d4b9822590a245dc3e8b2b6ef.png](https://i-blog.csdnimg.cn/blog_migrate/836f1da912b25026408aa37ec15b58fb.jpeg)
扩展字段(op_extend):记录数据的变更
主要实现代码
注解记录操作日志元数据
/**
* @author simplezero
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String category();
String subcategory();
String desc();
OperationLogTypeEnum type() default INSERT;
}
使用 AOP和 注解在接口层进行切面,无侵入
@PostMapping("/skill/editSkill")
@OperationLog(category = "技能管理", subcategory = "技能开发", desc = "编辑技能", type = OperationLogTypeEnum.UPDATE)
public BaseOutDto editSkill(@RequestBody EditSkillReqDTO req, HttpServletRequest request) throws IllegalAccessException {
bizSkillManagementService.editSkill(req, request);
return new BaseOutDto();
}
AOP实现,记录操作用户信息、请求返回等信息
/**
* @author simplezero
*/
@Aspect
@Component
@Slf4j
public class OperationLogAspect {
@Autowired
private OperationLogService operationLogService;
@Autowired
private SystemAccountManagementService accountManagementService;
@Around("@annotation(com.x.x.annotation.Oper