日志操作记录工具类

1.创建一个日志记录表,这里就不细说了

2.需要封装一个注解

package com.kte.common.annotation;
import com.kte.common.enums.DictTypeEnum;
import java.lang.annotation.*;

/**
 * @className: FieldRecord
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FieldRecord {
	/**
	 * 字段名称
	 */
	String fieldName() default "";

	/**
	 * 时间格式
	 */
	String dateFormat() default "";

	/**
	 * 自定义字典
	 */
	String[] whether() default {};

	/**
	 * 字典枚举
	 */
	DictTypeEnum model() default DictTypeEnum.NULLDICT;

	/**
	 * 字典是否需要分隔记录
	 */
	boolean isDictSplit() default false;
}

3.引入日志记录工具类`

package com.kte.common.utils;

import com.google.common.collect.Maps;
import com.kte.common.annotation.FieldRecord;
import com.kte.core.tool.utils.DateUtil;
import com.kte.core.tool.utils.Func;
import com.kte.core.tool.utils.ObjectUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description: 日志记录工具类
 * @className: LogBeanUtils
 **/
public class LogBeanUtils {

	private static final String BIG_DECIMAL_NAME = "java.math.BigDecimal";

	/**
	 * 获取变更内容
	 *
	 * @param newBean
	 * @param oldBean
	 */
	public static <T> String getChangedFields(T newBean, T oldBean) {
		Field[] fields = newBean.getClass().getDeclaredFields();
		StringBuilder builder = new StringBuilder();
		for (Field field : fields) {
			field.setAccessible(true);
			if (field.isAnnotationPresent(FieldRecord.class)) {
				try {
					Object newValue = field.get(newBean);
					Object oldValue = field.get(oldBean);
					if (checkFields(builder, field, newValue, oldValue)) {
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println(e);
				}
			}
		}
		String context = StringUtils.replace(builder.toString(), "null", "");
		return context;
	}

	/**
	 * 获取变更内容不记录空值
	 *
	 * @param newBean
	 * @param oldBean
	 * @param isRecordNull
	 * @return java.lang.String
	 */
	public static <T> String getChangedFields(T newBean, T oldBean, String isRecordNull) {
		Field[] fields = newBean.getClass().getDeclaredFields();
		StringBuilder builder = new StringBuilder();
		boolean equals = "yes".equals(isRecordNull);
		for (Field field : fields) {
			field.setAccessible(true);
			if (field.isAnnotationPresent(FieldRecord.class)) {
				try {
					Object newValue = field.get(newBean);
					Object oldValue = field.get(oldBean);
					if (checkFields(builder, field, newValue, oldValue, equals)) {
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println(e);
				}
			}
		}
		String context = StringUtils.replace(builder.toString(), "null", "");
		return context;
	}

	public static <T> String getChangedFields(T newBean, T oldBean, Boolean isExcelChange) {
		Field[] fields = newBean.getClass().getDeclaredFields();
		StringBuilder builder = new StringBuilder();
		for (Field field : fields) {
			field.setAccessible(true);
			if (field.isAnnotationPresent(FieldRecord.class)) {
				try {
					Object newValue = field.get(newBean);
					Object oldValue = field.get(oldBean);
					if (isExcelChange) {
						if (ObjectUtil.isEmpty(newValue)) {
							continue;
						}
					}
					if (checkFields(builder, field, newValue, oldValue)) {
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println(e);
				}
			}
		}
		String context = StringUtils.replace(builder.toString(), "null", "");
		return context;
	}

	private static boolean checkFields(StringBuilder builder, Field field, Object newValue, Object oldValue) {
		if (ObjectUtil.isEmpty(newValue) && ObjectUtil.isEmpty(oldValue)) {
			return true;
		}
		if (ObjectUtil.isEmpty(newValue)) {
			newValue = null;
		}
		if (ObjectUtil.isEmpty(oldValue)) {
			oldValue = null;
		}
		//处理BigDecimal类型的数据
		String name = field.getType().getName();
		if (name.equals(BIG_DECIMAL_NAME)) {
			BigDecimal decimal = ObjectUtil.isEmpty(newValue) ? BigDecimal.ZERO : (BigDecimal) newValue;
			BigDecimal decimal1 = ObjectUtil.isEmpty(oldValue) ? BigDecimal.ZERO : (BigDecimal) oldValue;
			if (decimal.compareTo(decimal1) == 0) {
				return true;
			}
		}
		if (!Objects.equals(newValue, oldValue)) {
			FieldRecord fieldRecord = field.getAnnotation(FieldRecord.class);
			String[] whethers = fieldRecord.whether();
			if (ObjectUtil.isNotEmpty(whethers) && whethers.length > 0) {
				HashMap<String, String> dictMap = Maps.newHashMap();
				//解析字典
				if (ObjectUtil.isNotEmpty(fieldRecord.whether())) {
					for (String whether : whethers) {
						String[] s = whether.split("_");
						dictMap.put(s[0], s[1]);
					}
					//获取字段名称
					if (fieldRecord.isDictSplit()) {
						String[] oldSplit = oldValue.toString().split(",");
						String[] newSplit = newValue.toString().split(",");
						String oldCollect = Arrays.stream(oldSplit).map(dictMap::get).collect(Collectors.joining(","));
						String newCollect = Arrays.stream(newSplit).map(dictMap::get).collect(Collectors.joining(","));
						setValue(builder, fieldRecord, oldCollect, newCollect);
						dictMap.clear();
					} else {
						setValue(builder, fieldRecord, dictMap.get(oldValue.toString()), dictMap.get(newValue.toString()));
						dictMap.clear();
					}
					return true;
				}
			}
			Boolean x = getDate(builder, newValue, oldValue, fieldRecord);
			if (x != null) {
				return x;
			}
			//获取字段名称
			builder.append(fieldRecord.fieldName());
			builder.append(": 【更改前:");
			builder.append(oldValue);
			builder.append(", 更改后:");
			builder.append(newValue);
			builder.append("】;\n");
		}
		return false;
	}

	private static boolean checkFields(StringBuilder builder, Field field, Object newValue, Object oldValue, boolean isRecordNull) {
		if (ObjectUtil.isEmpty(newValue) && ObjectUtil.isEmpty(oldValue)) {
			return true;
		}
		if (ObjectUtil.isEmpty(newValue)) {
			if (isRecordNull) {
				return true;
			}
		}
		if (ObjectUtil.isEmpty(oldValue)) {
			oldValue = "";
		}
		//处理BigDecimal类型的数据
		String name = field.getType().getName();
		if (name.equals(BIG_DECIMAL_NAME)) {
			BigDecimal decimal = (BigDecimal) newValue;
			BigDecimal decimal1 = (BigDecimal) oldValue;
			if (decimal.compareTo(decimal1) == 0) {
				return true;
			}
		}
		if (!Objects.equals(newValue, oldValue)) {
			FieldRecord fieldRecord = field.getAnnotation(FieldRecord.class);
			String[] whethers = fieldRecord.whether();
			if (ObjectUtil.isNotEmpty(whethers) && whethers.length > 0) {
				HashMap<String, String> dictMap = Maps.newHashMap();
				//解析字典
				if (ObjectUtil.isNotEmpty(fieldRecord.whether())) {
					for (String whether : whethers) {
						String[] s = whether.split("_");
						dictMap.put(s[0], s[1]);
					}
					//获取字段名称
					if (fieldRecord.isDictSplit()) {
						String[] oldSplit = oldValue.toString().split(",");
						String[] newSplit = newValue.toString().split(",");
						String oldCollect = Arrays.stream(oldSplit).map(dictMap::get).collect(Collectors.joining(","));
						String newCollect = Arrays.stream(newSplit).map(dictMap::get).collect(Collectors.joining(","));
						setValue(builder, fieldRecord, oldCollect, newCollect);
						dictMap.clear();
					} else {
						setValue(builder, fieldRecord, dictMap.get(oldValue.toString()), dictMap.get(newValue.toString()));
						dictMap.clear();
					}
					return true;
				}
			}
			Boolean x = getDate(builder, newValue, oldValue, fieldRecord);
			if (x != null) {
				return x;
			}
			//获取字段名称
			builder.append(fieldRecord.fieldName());
			builder.append(": 【更改前:");
			builder.append(oldValue);
			builder.append(", 更改后:");
			builder.append(newValue);
			builder.append("】;\n");
		}
		return false;
	}

	private static Boolean getDate(StringBuilder builder, Object newValue, Object oldValue, FieldRecord fieldRecord) {
		String dateFormat = fieldRecord.dateFormat();
		if (Func.isNotBlank(dateFormat)) {
			if (oldValue instanceof Date) {
				Date oldValue1 = (Date) oldValue;
				Date newValue1 = (Date) newValue;
				switch (dateFormat) {
					case DateUtil.PATTERN_DATE:
						setValue(builder, fieldRecord, DateUtil.format(oldValue1, DateUtil.PATTERN_DATE), DateUtil.format(newValue1, DateUtil.PATTERN_DATE));
						break;
					case DateUtil.PATTERN_DATETIME:
						setValue(builder, fieldRecord, DateUtil.format(oldValue1, DateUtil.PATTERN_DATETIME), DateUtil.format(newValue1, DateUtil.PATTERN_DATETIME));
						break;
					default:
						break;
				}
			} else if (ObjectUtil.isEmpty(oldValue) && ObjectUtil.isNotEmpty(newValue)) {
				//处理老对象没有时间和新对象有时间问题
				Date newValue1 = (Date) newValue;
				switch (dateFormat) {
					case DateUtil.PATTERN_DATE:
						setValue(builder, fieldRecord, "", DateUtil.format(newValue1, DateUtil.PATTERN_DATE));
						break;
					case DateUtil.PATTERN_DATETIME:
						setValue(builder, fieldRecord, "", DateUtil.format(newValue1, DateUtil.PATTERN_DATETIME));
						break;
					default:
						break;
				}
			}
			if (oldValue instanceof LocalDateTime) {
				LocalDateTime oldValue1 = (LocalDateTime) oldValue;
				LocalDateTime newValue1 = (LocalDateTime) newValue;
				switch (dateFormat) {
					case DateUtil.PATTERN_DATE:
						setValue(builder, fieldRecord, DateUtil.format(oldValue1, DateUtil.PATTERN_DATE), DateUtil.format(newValue1, DateUtil.PATTERN_DATE));
						break;
					case DateUtil.PATTERN_DATETIME:
						setValue(builder, fieldRecord, DateUtil.format(oldValue1, DateUtil.PATTERN_DATETIME), DateUtil.format(newValue1, DateUtil.PATTERN_DATETIME));
						break;
					default:
						break;
				}
			} else if (ObjectUtil.isEmpty(oldValue) && ObjectUtil.isNotEmpty(newValue)) {
				//处理老对象没有时间和新对象有时间问题
				LocalDateTime newValue1 = (LocalDateTime) newValue;
				switch (dateFormat) {
					case DateUtil.PATTERN_DATE:
						setValue(builder, fieldRecord, "", DateUtil.format(newValue1, DateUtil.PATTERN_DATE));
						break;
					case DateUtil.PATTERN_DATETIME:
						setValue(builder, fieldRecord, "", DateUtil.format(newValue1, DateUtil.PATTERN_DATETIME));
						break;
					default:
						break;
				}
			}
			return true;
		}
		return null;
	}

	private static void setValue(StringBuilder builder, FieldRecord fieldRecord, String oldValue, String newValue) {
		builder.append(fieldRecord.fieldName());
		builder.append(": 【更改前:");
		builder.append(oldValue);
		builder.append(", 更改后:");
		builder.append(newValue);
		builder.append("】;\n");
	}
}

测试

package com.kte.system.user.vo;

import com.kte.common.annotation.FieldRecord;
import com.kte.product.annotation.FieldMeta;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 对象实体类
 */
@Data
public class UserLogVo {
	/**
	 * 用户姓名
	 */
	@ApiModelProperty(value = "用户姓名")
	@FieldRecord(fieldName = "用户姓名")
	private String realName;
	/**
	 * 电子邮箱
	 */
	@ApiModelProperty(value = "电子邮箱")
	@FieldRecord(fieldName = "电子邮箱")
	private String email;
	/**
	 * 手机号码
	 */
	@ApiModelProperty(value = "手机号码 ")
	@FieldRecord(fieldName = "手机号码")
	private String phone;
	/**
	 * 用户性别
	 */
	@ApiModelProperty(value = "用户性别")
	@FieldRecord(fieldName = "用户性别", whether = {"1_男", "2_女"})
	private String sex;
}

//调用工具类,获取变更的内容
String change=LogBeanUtils.getChangedFields(T newBean, T oldBean, String isRecordNull);

把变更的内容记录入库,此位置省略入库操作,自行编写

//注意细节:
1. @FieldRecord:需要记录变更得字段必须加上此注解
2. whether:枚举转换,如性别,我们入库记录的是“1和2”,记录日志时可自动装换为“男和女”
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值