Browse Source

优化FieldCompareUtil字段对比工具类:

泛型处理:使用 Number 类型来处理所有的数值类型(如 Integer, Long, Double, BigDecimal)。
枚举类型处理:增加对 Enum 类型的支持。
日期类型处理:增加对 Date 类型的支持,并格式化日期。
统一处理逻辑:通过 areEqual 和 formatValue 方法来减少冗余的条件判断。
异常处理:增加了对 PropertyDescriptor 和 Method 获取过程中可能出现的异常的处理。
dev
liuxiaoxu 1 month ago
parent
commit
9d22be2344
  1. 107
      ruoyi-common/src/main/java/com/ruoyi/common/utils/FieldCompareUtil.java

107
ruoyi-common/src/main/java/com/ruoyi/common/utils/FieldCompareUtil.java

@ -9,6 +9,7 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
@ -19,58 +20,84 @@ import java.util.*;
* */
public class FieldCompareUtil {
/**
* 比较两个对象的变化并记录
*
* @param type 对象的类型
* @param newObject 新对象
* @param oldObject 旧对象
* @return 变更记录列表
* @throws Exception 如果发生异常
*/
public static <T> List<SysFieldDifferent> compare(Class<T> type, T newObject, T oldObject) throws Exception {
// 变更的记录列表
List<SysFieldDifferent> changeLogFields = new ArrayList<>();
Class<?> newObj = newObject.getClass();
Field[] newFields = type.getDeclaredFields();
for (int i = 0; i < newFields.length; i++) {
FieldCompare newAnnotation = newFields[i].getAnnotation(FieldCompare.class);
if (null != newAnnotation) {
PropertyDescriptor newPd = new PropertyDescriptor(newFields[i].getName(), newObj);
Method getMethodNew = newPd.getReadMethod();
Object oldVal = getMethodNew.invoke(oldObject);
Object newVal = getMethodNew.invoke(newObject);
boolean eq = false;
Field[] fields = type.getDeclaredFields();
for (Field field : fields) {
FieldCompare annotation = field.getAnnotation(FieldCompare.class);
if (annotation != null) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), newObject.getClass());
Method getMethod = pd.getReadMethod();
Object oldVal = getMethod.invoke(oldObject);
Object newVal = getMethod.invoke(newObject);
if (!areEqual(oldVal, newVal)) {
String s1 = formatValue(oldVal);
String s2 = formatValue(newVal);
String chineseName = annotation.chineseName();
Map<String, String> codeToNameMap = codeToNameMap(annotation);
if (!codeToNameMap.isEmpty()) {
s1 = codeToNameMap.getOrDefault(s1, s1);
s2 = codeToNameMap.getOrDefault(s2, s2);
}
changeLogFields.add(new SysFieldDifferent(chineseName, s1, s2));
}
}
}
return changeLogFields;
}
//统一处理条件判断
private static boolean areEqual(Object oldVal, Object newVal) {
if (oldVal == null && newVal == null) {
return true;
}
if (oldVal == null || newVal == null) {
return false;
}
if (oldVal instanceof String) {
String s1 = String.valueOf(oldVal).trim();
String s2 = String.valueOf(newVal).trim();
eq = !s1.equals(s2);
} else if (oldVal instanceof Integer) {
int i1 = (Integer) oldVal;
int i2 = (Integer) newVal;
eq = i1 != i2;
} else if (oldVal instanceof Double) {
double d1 = (Double) oldVal;
double d2 = (Double) newVal;
eq = d1 != d2;
} else if (oldVal instanceof BigDecimal) {
BigDecimal b1 = (BigDecimal) oldVal;
BigDecimal b2 = (BigDecimal) newVal;
eq = b1.compareTo(b2) != 0;
} else if (oldVal instanceof Long) {
long l1 = (Long) oldVal;
long l2 = (Long) newVal;
eq = l1 != l2;
} else {
eq = !oldVal.equals(newVal);
}
String s1 = oldVal == null ? "" : oldVal.toString().trim();
String s2 = newVal == null ? "" : newVal.toString().trim();
if (eq) {
Map<String, String> map = codeToNameMap(newAnnotation);
if (map.size() > 0) {
changeLogFields.add(new SysFieldDifferent(newAnnotation.chineseName(), map.get(s1), map.get(s2)));
return oldVal.toString().trim().equals(newVal.toString().trim());
} else if (oldVal instanceof Number) {
return ((Number) oldVal).doubleValue() == ((Number) newVal).doubleValue();
} else if (oldVal instanceof Enum) {
return oldVal.equals(newVal);
} else if (oldVal instanceof Date) {
return oldVal.equals(newVal);
} else {
changeLogFields.add(new SysFieldDifferent(newAnnotation.chineseName(), s1, s2));
return oldVal.equals(newVal);
}
}
//统一处理格式化值
private static String formatValue(Object value) {
if (value == null) {
return "";
}
if (value instanceof String) {
return ((String) value).trim();
} else if (value instanceof Date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(value);
} else if (value instanceof Number) {
return value.toString();
} else if (value instanceof Enum) {
return value.toString();
} else {
return value.toString();
}
return changeLogFields;
}
/**
* 字典映射 使用方式:
* @param newAnnotation

Loading…
Cancel
Save