|
|
@ -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 |
|
|
|