会记录变更前/后的值,变更字段的属性名,变更字段中午名称
先看效果:
todo:纯为了实现需求效果,代码优化空间还很大
/**
* 对象比较工具类
*/
@Slf4j
public class ClassInstanceCompareUtil {
/**
* 对象比较
* @param source 源对象
* @param target 目标对象
* @return 比较结果对象
*/
public static CompareResultVo compareObject(Object source, Object target) {
CompareResultVo compareResultVo = new CompareResultVo();
if (source == null && target == null) {
return compareResultVo;
}
if (source == null || target == null) {
return compareResultVo;
}
Class<?> oldClazz = source.getClass();
Class<?> newClazz = target.getClass();
if (oldClazz != newClazz) {
return compareResultVo;
}
List<Field> fields = Arrays.stream(oldClazz.getDeclaredFields()).collect(Collectors.toList());
List<LabelValueResultVo> modifyInfoList = new ArrayList<>();
List<String> modifyFieldList = new ArrayList<>();
for (Field field : fields) {
try {
if (isSerialVersionUIDField(field.getName())) {
continue;
}
fieldCheck(field, source, target, modifyInfoList,modifyFieldList);
} catch (Exception e) {
log.info("field.error.fieldName:{},errorMsg:{}", field.getName(), e.getMessage(), e);
}
}
compareResultVo.setModifyInfoList(modifyInfoList);
compareResultVo.setModifyFieldList(modifyFieldList);
return compareResultVo;
}
/**
* 比较两个对象的指定字段是否相等
* @param field 字段
* @param source 源对象
* @param target 目标对象
* @param modifyInfoList 修改列表
* @throws Exception 异常
*/
public static void fieldCheck(Field field, Object source, Object target, List<LabelValueResultVo> modifyInfoList,List<String> modifyFieldList) throws Exception {
field.setAccessible(true);
NeedCompare needCompare = field.getAnnotation(NeedCompare.class);
if (needCompare == null) {
return;
}
Class<?> type = field.getType();
if (isBaseType(type)) {
Object o1 = field.get(source);
Object o2 = field.get(target);
if (Objects.isNull(o1) && Objects.isNull(o2)){
return;
}
if (Objects.isNull(o1)){
if (type == String.class){
if (StringUtils.isBlank(o2.toString())){
return;
}
}
if (type == Date.class){
String s = DateUtil.dateToStr((Date) o2);
o2 = DateUtil.strToDate(s);
}
}
if (Objects.isNull(o2)){
if (type == String.class){
if (StringUtils.isBlank(o1.toString())){
return;
}
}
if (type == Date.class){
String s = DateUtil.dateToStr((Date) o1);
o1 = DateUtil.strToDate(s);
}
}
if (!Objects.equals(o1, o2)) {
try {
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
if (apiModelProperty != null) {
LabelValueResultVo labelValueVo = new LabelValueResultVo();
labelValueVo.setLabel(apiModelProperty.value());
ChangeVO changeVO = new ChangeVO();
changeVO.setBefore(Objects.isNull(field.get(source)) ? "" : field.get(source));
changeVO.setAfter(Objects.isNull(field.get(target)) ? "" : field.get(target));
labelValueVo.setValue(changeVO);
modifyInfoList.add(labelValueVo);
modifyFieldList.add(field.getName());
}
} catch (Exception e) {
log.info("field.error.fieldName:{},errorMsg:{}", field.getName(), e.getMessage(), e);
}
}
} else if (isCollection(type)) {
//集合比较
List o1 = (List) field.get(source);
List o2 = (List) field.get(target);
if (CollectionUtils.isEmpty(o1) && CollectionUtils.isEmpty(o2)){
return;
}
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
LabelValueResultVo labelValueVo = new LabelValueResultVo();
labelValueVo.setLabel(apiModelProperty.value());
if (o1.size() == o2.size() || o1.size() > o2.size()) {
// 创建一个临时列表用于存放相同的元素
List<Object> newList = new ArrayList<>(o1);
newList.retainAll(o2); // 保留 o1 和 o2 中共有的元素
// 从 o1 和 o2 中删除相同的元素
o1.removeAll(newList);
o2.removeAll(newList);
if (CollectionUtils.isNotEmpty(o1) || CollectionUtils.isNotEmpty(o2)) {
ChangeVO changeVO = new ChangeVO();
List<LabelValueResultVo> labelValueResultVoList = getListField(o1,apiModelProperty.value());
List<LabelValueResultVo> labelValueResultVoList1 = getListField(o2,apiModelProperty.value());
changeVO.setBefore(labelValueResultVoList);
changeVO.setAfter(labelValueResultVoList1);
labelValueVo.setValue(changeVO);
modifyInfoList.add(labelValueVo);
modifyFieldList.add(field.getName());
}
}
if (o1.size() < o2.size()) {
// 创建一个临时列表用于存放相同的元素
List<Object> newList = new ArrayList<>(o2);
newList.retainAll(o1); // 保留 o1 和 o2 中共有的元素
// 从 o1 和 o2 中删除相同的元素
o1.removeAll(newList);
o2.removeAll(newList);
if (CollectionUtils.isNotEmpty(o1) || CollectionUtils.isNotEmpty(o2)) {
ChangeVO changeVO = new ChangeVO();
List<LabelValueResultVo> labelValueResultVoList = getListField(o1, apiModelProperty.value());
List<LabelValueResultVo> labelValueResultVoList1 = getListField(o2,apiModelProperty.value());
changeVO.setBefore(labelValueResultVoList);
changeVO.setAfter(labelValueResultVoList1);
labelValueVo.setValue(changeVO);
modifyInfoList.add(labelValueVo);
modifyFieldList.add(field.getName());
}
}
} else {
Object o1 = field.get(source);
Object o2 = field.get(target);
if (o1 == null && o2 == null) {
return;
}
List<Field> fields = Arrays.stream(field.get(source).getClass().getDeclaredFields()).collect(Collectors.toList());
for (Field field1 : fields) {
if (isSerialVersionUIDField(field1.getName())) {
continue;
}
fieldCheck(field1, o1, o2, modifyInfoList,modifyFieldList);
}
}
}
/**
* 判断给定的字段名是否为serialVersionUID字段
* @param fieldName 字段名
* @return 如果字段名为"serialVersionUID",则返回true,否则返回false
*/
public static boolean isSerialVersionUIDField(String fieldName){
return "serialVersionUID".equals(fieldName);
}
public static List<LabelValueResultVo> getListField(List list,String value) {
List<LabelValueResultVo> resultVos = new ArrayList<>();
try {
for (int i = 0; i < list.size(); i++) {
int x= i+1;
LabelValueResultVo resultVo = new LabelValueResultVo();
List<LabelValueResultVo> newFesultVos = new ArrayList<>();
resultVo.setLabel(value+x);
List<Field> oldFields = Arrays.stream(list.get(i).getClass().getDeclaredFields()).collect(Collectors.toList());
for (Field field1 : oldFields) {
field1.setAccessible(true);
if (isSerialVersionUIDField(field1.getName())) {
continue;
}
ApiModelProperty newApiModelProperty = field1.getAnnotation(ApiModelProperty.class);
if (newApiModelProperty == null) {
continue;
}
NeedCompare newNeedCompare = field1.getAnnotation(NeedCompare.class);
if (newNeedCompare == null) {
continue;
}
if (Objects.isNull(field1.get(list.get(i)))) {
continue;
}
LabelValueResultVo labelValueResultVo = new LabelValueResultVo();
labelValueResultVo.setLabel(newApiModelProperty.value());
labelValueResultVo.setValue(field1.get(list.get(i)));
newFesultVos.add(labelValueResultVo);
}
resultVo.setValue(newFesultVos);
resultVos.add(resultVo);
//resultVos.addAll(labelValueResultVoList);
}
} catch (Exception e) {
log.info("getListField.error,msg:{}", e.getMessage(), e);
}
return resultVos;
}
/**
* 是否是基本数据类型
*/
public static boolean isBaseType(Class<?> clazz) {
return clazz.isPrimitive() || clazz == String.class || clazz == Character.class || clazz == Boolean.class || clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == BigInteger.class || clazz == BigDecimal.class;
}
/**
* 标注在字段的注解,表示需要进行比较
*/
@Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedCompare {
}
@Data
public class CompareResultVo {
/**
* 变更内容
*/
private List<LabelValueResultVo> modifyInfoList;
/**
* 变更的字段属性名称
*/
private List<String> modifyFieldList;
}
@Data
public class LabelValueResultVo {
@ApiModelProperty("展示内容")
private Object label;
@ApiModelProperty("值")
private Object value;
}
@Data
public class ChangeVO {
private Object before;
private Object after;
}