Browse Source

优化实体对比工具类

zhou-hao 6 years ago
parent
commit
338f3cd9b2

+ 30 - 0
hsweb-core/src/main/java/org/hswebframework/web/audit/Audit.java

@@ -0,0 +1,30 @@
+package org.hswebframework.web.audit;
+
+import java.lang.annotation.*;
+
+/**
+ * 审计信息注解,用于在修改更新数据的时候记录被修改的内容.
+ * @since 3.0.7
+ *
+ */
+@Target({ElementType.FIELD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Audit {
+
+    //审计信息简介,如功能,字段.
+    String value();
+
+    //审计信息的说明
+    String comment() default "";
+
+    //是否忽略审计
+    boolean ignore() default false;
+
+    //字段生效策略,如果为MANUAL,修改数据时,字段将不会立即修改,而是需要手动审核通过后生效.
+    Strategy strategy() default Strategy.AUTO;
+
+    //如果设置了审核权限,当进行审核或者回退的时候将进行权限验证.
+    //如: permission:user:audit
+    String auditPermission() default "";
+}

+ 11 - 0
hsweb-core/src/main/java/org/hswebframework/web/audit/Strategy.java

@@ -0,0 +1,11 @@
+package org.hswebframework.web.audit;
+
+/**
+ * 生效策略
+ *
+ * @since 3.0.7
+ */
+public enum Strategy {
+    AUTO,
+    MANUAL;
+}

+ 75 - 9
hsweb-core/src/main/java/org/hswebframework/web/bean/CompareUtils.java

@@ -1,13 +1,12 @@
 package org.hswebframework.web.bean;
 
-import org.hswebframework.utils.StringUtils;
 import org.hswebframework.utils.time.DateFormatter;
 import org.hswebframework.web.dict.EnumDict;
-import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.util.*;
 
+@SuppressWarnings("all")
 public abstract class CompareUtils {
 
     public static boolean compare(Object source, Object target) {
@@ -77,19 +76,46 @@ public abstract class CompareUtils {
         }
 
 
-        return false;
+        return compare(FastBeanCopier.copy(source, HashMap.class), FastBeanCopier.copy(target, HashMap.class));
 
     }
 
-    public static boolean compare(Map collection, Object target) {
+    public static boolean compare(Map<?, ?> map, Object target) {
+        if (map == target) {
+            return true;
+        }
 
+        if (map == null || target == null) {
+            return false;
+        }
+        Map<?, ?> targetMap = null;
+        if (target instanceof Map) {
+            targetMap = ((Map) target);
+        } else {
+            targetMap = FastBeanCopier.copy(target, HashMap::new);
+        }
 
-        return false;
+        if (map.size() != targetMap.size()) {
+            return false;
+        }
+        for (Map.Entry entry : map.entrySet()) {
+            if (!compare(entry.getValue(), targetMap.get(entry.getKey()))) {
+                return false;
+            }
+        }
+
+        return true;
     }
 
-    @SuppressWarnings("all")
+
     public static boolean compare(Collection collection, Object target) {
+        if (collection == target) {
+            return true;
+        }
 
+        if (collection == null || target == null) {
+            return false;
+        }
         Collection targetCollection = null;
         if (target instanceof String) {
             target = ((String) target).split("[, ;]");
@@ -127,6 +153,14 @@ public abstract class CompareUtils {
     }
 
     public static boolean compare(Number number, Object target) {
+        if (number == target) {
+            return true;
+        }
+
+        if (number == null || target == null) {
+            return false;
+        }
+
         if (target.equals(number)) {
             return true;
         }
@@ -144,8 +178,10 @@ public abstract class CompareUtils {
                 DateFormatter dateFormatter = DateFormatter.getFormatter(stringValue);
                 return (dateFormatter.toString(new Date(number.longValue())).equals(stringValue));
             }
-            if (StringUtils.isNumber(target)) {
+            try{
                 return new BigDecimal(stringValue).doubleValue() == number.doubleValue();
+            }catch (NumberFormatException e){
+                return false;
             }
         }
 
@@ -153,6 +189,13 @@ public abstract class CompareUtils {
     }
 
     public static boolean compare(Enum e, Object target) {
+        if (e == target) {
+            return true;
+        }
+
+        if (e == null || target == null) {
+            return false;
+        }
         String stringValue = String.valueOf(target);
         if (e instanceof EnumDict) {
             EnumDict dict = ((EnumDict) e);
@@ -163,20 +206,43 @@ public abstract class CompareUtils {
     }
 
     public static boolean compare(String string, Object target) {
+        if (string == target) {
+            return true;
+        }
 
+        if (string == null || target == null) {
+            return false;
+        }
         if (string.equals(String.valueOf(target))) {
             return true;
         }
 
+        if (target instanceof Enum) {
+            return compare(((Enum) target), string);
+        }
+
         if (target instanceof Date) {
-            Date date = DateFormatter.fromString(string);
-            return (date != null && ((Date) target).getTime() == date.getTime());
+            return compare(((Date) target), string);
+        }
+
+        if (target instanceof Number) {
+            return compare(((Number) target), string);
+        }
+        if (target instanceof Collection) {
+            return compare(((Collection) target), string);
         }
 
         return false;
     }
 
     public static boolean compare(Date date, Object target) {
+        if (date == target) {
+            return true;
+        }
+
+        if (date == null || target == null) {
+            return false;
+        }
         if (target instanceof Date) {
             return date.getTime() == ((Date) target).getTime();
         }

+ 49 - 0
hsweb-core/src/main/java/org/hswebframework/web/bean/Diff.java

@@ -0,0 +1,49 @@
+package org.hswebframework.web.bean;
+
+import com.alibaba.fastjson.JSON;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class Diff {
+
+    private String property;
+
+    private Object before;
+
+    private Object after;
+
+    public static List<Diff> of(Object before, Object after) {
+        List<Diff> diffs = new ArrayList<>();
+
+        Map<String, Object> beforeMap = FastBeanCopier.copy(before, HashMap::new);
+        Map<String, Object> afterMap = FastBeanCopier.copy(after, HashMap::new);
+
+        for (Map.Entry<String, Object> entry : afterMap.entrySet()) {
+            Object afterValue = entry.getValue();
+            String key = entry.getKey();
+            Object beforeValue = beforeMap.get(key);
+            if (!CompareUtils.compare(beforeValue, afterValue)) {
+                diffs.add(new Diff(key, beforeValue, afterValue));
+            }
+        }
+        return diffs;
+
+    }
+
+    @Override
+    public String toString() {
+        return JSON.toJSONString(this);
+    }
+}

+ 0 - 21
hsweb-core/src/main/java/org/hswebframework/web/bean/diff/Diff.java

@@ -1,21 +0,0 @@
-package org.hswebframework.web.bean.diff;
-
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class Diff {
-
-    private String field;
-
-    private String comment;
-
-    private String type;
-
-    private Object before;
-
-    private Object after;
-
-
-}

+ 0 - 23
hsweb-core/src/main/java/org/hswebframework/web/bean/diff/DiffBean.java

@@ -1,23 +0,0 @@
-package org.hswebframework.web.bean.diff;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.List;
-
-public class DiffBean {
-
-    private Object before;
-
-    private Object after;
-
-    private List<Diff> diffs;
-
-
-
-
-
-    public List<Diff> getDiffs() {
-        return diffs;
-    }
-}

+ 107 - 12
hsweb-core/src/test/java/org/hswebframework/web/bean/CompareUtilsTest.java

@@ -2,26 +2,54 @@ package org.hswebframework.web.bean;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.Setter;
 import org.hswebframework.utils.time.DateFormatter;
 import org.hswebframework.web.dict.EnumDict;
 import org.junit.Assert;
 import org.junit.Test;
 
 import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Date;
+import java.util.*;
 
 import static org.junit.Assert.*;
 
 public class CompareUtilsTest {
 
+    @Test
+    public void nullTest() {
+
+        Assert.assertFalse(CompareUtils.compare(1, null));
+
+        Assert.assertFalse(CompareUtils.compare((Object) null, 1));
+        Assert.assertTrue(CompareUtils.compare((Object) null, null));
+        Assert.assertFalse(CompareUtils.compare((Number) null, 1));
+        Assert.assertTrue(CompareUtils.compare((Number) null, null));
+        Assert.assertFalse(CompareUtils.compare((Date) null, 1));
+        Assert.assertTrue(CompareUtils.compare((Date) null, null));
+        Assert.assertFalse(CompareUtils.compare((String) null, 1));
+        Assert.assertTrue(CompareUtils.compare((String) null, null));
+        Assert.assertFalse(CompareUtils.compare((Collection) null, 1));
+        Assert.assertTrue(CompareUtils.compare((Collection) null, null));
+        Assert.assertFalse(CompareUtils.compare((Map<?, ?>) null, 1));
+        Assert.assertTrue(CompareUtils.compare((Map<?, ?>) null, null));
+
+    }
 
     @Test
-    public void compareTest() {
-        Assert.assertTrue(CompareUtils.compare(1, "1"));
-        Assert.assertTrue(CompareUtils.compare("1", 1));
+    public void numberTest() {
+        Assert.assertTrue(CompareUtils.compare(1, 1));
+        Assert.assertTrue(CompareUtils.compare(1, 1D));
+        Assert.assertTrue(CompareUtils.compare(1, 1.0D));
+        Assert.assertTrue(CompareUtils.compare(1e3,"1e3"));
+        Assert.assertTrue(CompareUtils.compare(1e3,"1000"));
 
+        Assert.assertTrue(CompareUtils.compare(1, "1"));
+        Assert.assertTrue(CompareUtils.compare("1.0", 1));
         Assert.assertFalse(CompareUtils.compare(1, "1a"));
+    }
+
+    @Test
+    public void enumTest() {
 
         Assert.assertTrue(CompareUtils.compare(TestEnum.BLUE, "blue"));
 
@@ -38,7 +66,32 @@ public class CompareUtilsTest {
         Assert.assertFalse(CompareUtils.compare(TestEnumDic.RED, "蓝色"));
 
 
-        Assert.assertTrue(CompareUtils.compare(DateFormatter.fromString("20180101"), "20180101"));
+    }
+
+    @Test
+    public void stringTest() {
+
+        Assert.assertTrue(CompareUtils.compare("20180101", DateFormatter.fromString("20180101")));
+
+        Assert.assertTrue(CompareUtils.compare(1,"1"));
+
+        Assert.assertTrue(CompareUtils.compare("1", 1));
+
+        Assert.assertTrue(CompareUtils.compare("1.0", 1.0D));
+
+        Assert.assertTrue(CompareUtils.compare("1.01", 1.01D));
+
+        Assert.assertTrue(CompareUtils.compare("1,2,3", Arrays.asList(1, 2, 3)));
+
+        Assert.assertTrue(CompareUtils.compare("blue", TestEnumDic.BLUE));
+
+        Assert.assertTrue(CompareUtils.compare("BLUE", TestEnum.BLUE));
+
+
+    }
+
+    @Test
+    public void dateTest() {
 
         Date date = new Date();
 
@@ -50,20 +103,62 @@ public class CompareUtilsTest {
         Assert.assertTrue(CompareUtils.compare(date, date.getTime()));
         Assert.assertTrue(CompareUtils.compare(date.getTime(), date));
 
+    }
+
+    @Test
+    public void connectionTest() {
+        Date date = new Date();
+
+        Assert.assertTrue(CompareUtils.compare(100, new BigDecimal("100")));
+
+        Assert.assertTrue(CompareUtils.compare(new BigDecimal("100"), 100.0D));
+
+        Assert.assertTrue(CompareUtils.compare(Arrays.asList(1, 2, 3), Arrays.asList("3", "2", "1")));
+
+        Assert.assertFalse(CompareUtils.compare(Arrays.asList(1, 2, 3), Arrays.asList("3", "3", "1")));
+
+        Assert.assertFalse(CompareUtils.compare(Arrays.asList(1, 2, 3), Arrays.asList("3", "1")));
+
+        Assert.assertFalse(CompareUtils.compare(Arrays.asList(1, 2, 3), Collections.emptyList()));
+        Assert.assertFalse(CompareUtils.compare(Collections.emptyList(), Arrays.asList(1, 2, 3)));
+
+        Assert.assertTrue(CompareUtils.compare(Arrays.asList(date, 3), Arrays.asList("3", DateFormatter.toString(date, "yyyy-MM-dd"))));
+
+    }
 
-        Assert.assertTrue(CompareUtils.compare(100,new BigDecimal("100")));
+    @Test
+    public void mapTest() {
+        Date date = new Date();
 
-        Assert.assertTrue(CompareUtils.compare(new BigDecimal("100"),100.0D));
+        Assert.assertTrue(CompareUtils.compare(Collections.singletonMap("test", "123"), Collections.singletonMap("test", 123)));
 
-        Assert.assertTrue(CompareUtils.compare(Arrays.asList(1,2,3),Arrays.asList("3","2","1")));
 
-        Assert.assertFalse(CompareUtils.compare(Arrays.asList(1,2,3),Arrays.asList("3","3","1")));
+        Assert.assertFalse(CompareUtils.compare(Collections.singletonMap("test", "123"), Collections.emptyMap()));
 
-        Assert.assertFalse(CompareUtils.compare(Arrays.asList(1,2,3),Arrays.asList("3","1")));
+        Assert.assertTrue(CompareUtils.compare(Collections.singletonMap("test", "123"), new TestBean("123")));
 
-        Assert.assertTrue(CompareUtils.compare(Arrays.asList(date,3),Arrays.asList("3",DateFormatter.toString(date,"yyyy-MM-dd"))));
+        Assert.assertTrue(CompareUtils.compare(Collections.singletonMap("test", date), new TestBean(DateFormatter.toString(date, "yyyy-MM-dd"))));
+
+    }
+
+    @Test
+    public void beanTest() {
+        Date date = new Date();
 
+        Assert.assertTrue(CompareUtils.compare(new TestBean(date), new TestBean(DateFormatter.toString(date, "yyyy-MM-dd"))));
 
+        Assert.assertTrue(CompareUtils.compare(new TestBean(1), new TestBean("1")));
+
+        Assert.assertTrue(CompareUtils.compare(new TestBean(1), new TestBean("1.0")));
+        Assert.assertFalse(CompareUtils.compare(new TestBean(1), new TestBean("1.0000000001")));
+
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    public static class TestBean {
+        private Object test;
     }
 
 

+ 31 - 0
hsweb-core/src/test/java/org/hswebframework/web/bean/DiffTest.java

@@ -0,0 +1,31 @@
+package org.hswebframework.web.bean;
+
+import org.hswebframework.utils.time.DateFormatter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DiffTest {
+
+    @Test
+    public void mapTest() {
+        Map<String, Object> before = new HashMap<>();
+        before.put("name", "name");
+        before.put("age",21);
+        before.put("birthday", DateFormatter.fromString("19910101"));
+
+        Map<String, Object> after = new HashMap<>();
+        after.put("name", "name");
+        after.put("age", "21");
+        after.put("birthday", "1991-01-01");
+
+
+        List<Diff> diffs = Diff.of(before, after);
+        System.out.println(diffs);
+        Assert.assertTrue(diffs.isEmpty());
+
+    }
+}