Browse Source

重构数据字典

zhou-hao 6 years ago
parent
commit
f7a2003188
23 changed files with 342 additions and 394 deletions
  1. 2 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java
  2. 1 1
      hsweb-core/src/main/java/org/hswebframework/web/dict/DictDefine.java
  3. 1 0
      hsweb-core/src/main/java/org/hswebframework/web/dict/DictDefineRepository.java
  4. 1 1
      hsweb-core/src/main/java/org/hswebframework/web/dict/DictParser.java
  5. 1 0
      hsweb-core/src/main/java/org/hswebframework/web/dict/DictSupportApi.java
  6. 45 19
      hsweb-core/src/main/java/org/hswebframework/web/dict/EnumDict.java
  7. 8 1
      hsweb-core/src/main/java/org/hswebframework/web/dict/ItemDefine.java
  8. 2 1
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultClassDictDefine.java
  9. 2 3
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictDefine.java
  10. 2 76
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictDefineRepository.java
  11. 9 7
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictParser.java
  12. 4 3
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultItemDefine.java
  13. 0 56
      hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java
  14. 12 11
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonGenericHttpMessageConverter.java
  15. 29 30
      hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-api/src/main/java/org/hswebframework/web/dictionary/api/entity/DictionaryItemEntity.java
  16. 7 159
      hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-api/src/main/java/org/hswebframework/web/dictionary/api/entity/SimpleDictionaryItemEntity.java
  17. 4 18
      hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-local/src/main/java/org/hswebframework/web/dictionary/simple/BoostDictDefineRepository.java
  18. 5 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/DefaultOptionalConvertBuilder.java
  19. 10 2
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/DictionaryOptionalConvertBuilderStrategy.java
  20. 75 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/EnumDictOptionConverter.java
  21. 119 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/EnumDictValueConverter.java
  22. 1 3
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/validator/GroovyVlidator.java
  23. 2 2
      hsweb-system/hsweb-system-workflow/hsweb-system-workflow-local/src/main/java/org/hswebframework/web/workflow/web/FlowableUtilsController.java

+ 2 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java

@@ -29,6 +29,7 @@ import org.hswebframework.web.validator.group.UpdateGroup;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
 
 import javax.annotation.PostConstruct;
 import java.util.ArrayList;
@@ -120,7 +121,7 @@ public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
     @Override
     public PK insert(E entity) {
         if (entity.getId() != null) {
-            if ((entity.getId() instanceof String)) {
+            if ((entity.getId() instanceof String) && !StringUtils.isEmpty(entity.getId())) {
                 tryValidateProperty(entity.getId().toString().matches("[a-zA-Z0-9_\\-]+"), "id", "只能由数字,字母,下划线,和-组成");
             }
             tryValidateProperty(selectByPk(entity.getId()) == null, "id", entity.getId() + "已存在");

+ 1 - 1
hsweb-core/src/main/java/org/hswebframework/web/dict/DictDefine.java

@@ -16,6 +16,6 @@ public interface DictDefine extends Serializable {
 
     String getParserId();
 
-    List<ItemDefine> getItems();
+    List<EnumDict<String>> getItems();
 
 }

+ 1 - 0
hsweb-core/src/main/java/org/hswebframework/web/dict/DictDefineRepository.java

@@ -9,6 +9,7 @@ import java.util.List;
 public interface DictDefineRepository {
     DictDefine getDefine(String id);
 
+    @Deprecated
     List<ClassDictDefine> getDefine(Class type);
 
     void addDefine(DictDefine dictDefine);

+ 1 - 1
hsweb-core/src/main/java/org/hswebframework/web/dict/DictParser.java

@@ -7,7 +7,7 @@ package org.hswebframework.web.dict;
 public interface DictParser {
     String getId();
 
-    String parseText(DictDefine dictDefine, String value);
+    String parseText(DictDefine dictDefine, Object value);
 
     String parseValue(DictDefine dictDefine, String text);
 }

+ 1 - 0
hsweb-core/src/main/java/org/hswebframework/web/dict/DictSupportApi.java

@@ -4,6 +4,7 @@ package org.hswebframework.web.dict;
  * @author zhouhao
  * @since 3.0
  */
+@Deprecated
 public interface DictSupportApi {
     DictParser getParser(String id, String defaultId);
 

+ 45 - 19
hsweb-core/src/main/java/org/hswebframework/web/dict/EnumDict.java

@@ -9,14 +9,13 @@ import com.alibaba.fastjson.parser.JSONToken;
 import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
 import com.alibaba.fastjson.serializer.JSONSerializable;
 import com.alibaba.fastjson.serializer.JSONSerializer;
+import lombok.extern.slf4j.Slf4j;
 
 import java.io.IOException;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 /**
  * 枚举字典,使用枚举来实现数据字典,可通过集成此接口来实现一些有趣的功能.
@@ -70,17 +69,30 @@ public interface EnumDict<V> extends JSONSerializable {
      * @param v value
      * @return 是否相等
      */
+    @SuppressWarnings("all")
     default boolean eq(Object v) {
+        if (v == null) {
+            return false;
+        }
+        if (v instanceof Object[]) {
+            v = Arrays.asList(v);
+        }
+        if (v instanceof Collection) {
+            return ((Collection) v).stream().anyMatch(this::eq);
+        }
+        v = ((Map) v).getOrDefault("value", ((Map) v).get("text"));
         return this == v
                 || getValue() == v
                 || getValue().equals(v)
-                || v.equals(getMask())
+                || (v instanceof Number ? in(((Number) v).longValue()) : false)
                 || String.valueOf(getValue()).equalsIgnoreCase(String.valueOf(v))
-                || getText().equalsIgnoreCase(String.valueOf(v));
+                || v.equals(getMask())
+                || getText().equalsIgnoreCase(String.valueOf(v)
+        );
     }
 
-    default boolean in(long bit) {
-        return (bit & getMask()) != 0;
+    default boolean in(long mask) {
+        return (mask & getMask()) != 0;
     }
 
     /**
@@ -100,7 +112,7 @@ public interface EnumDict<V> extends JSONSerializable {
      * @param <T>       枚举类型
      * @return 查找到的结果
      */
-    static <T extends EnumDict> Optional<T> find(Class<T> type, Predicate<T> predicate) {
+    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Predicate<T> predicate) {
         if (type.isEnum()) {
             for (T enumDict : type.getEnumConstants()) {
                 if (predicate.test(enumDict)) {
@@ -116,7 +128,7 @@ public interface EnumDict<V> extends JSONSerializable {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends EnumDict<?>> Optional<T> findByValue(Class<T> type, Object value) {
+    static <T extends Enum & EnumDict<?>> Optional<T> findByValue(Class<T> type, Object value) {
         return find(type, e -> e.getValue() == value || e.getValue().equals(value) || String.valueOf(e.getValue()).equalsIgnoreCase(String.valueOf(value)));
     }
 
@@ -125,7 +137,7 @@ public interface EnumDict<V> extends JSONSerializable {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends EnumDict> Optional<T> findByText(Class<T> type, String text) {
+    static <T extends Enum & EnumDict> Optional<T> findByText(Class<T> type, String text) {
         return find(type, e -> e.getText().equalsIgnoreCase(text));
     }
 
@@ -134,7 +146,7 @@ public interface EnumDict<V> extends JSONSerializable {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends EnumDict> Optional<T> find(Class<T> type, Object target) {
+    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Object target) {
         return find(type, v -> v.eq(target));
     }
 
@@ -151,27 +163,41 @@ public interface EnumDict<V> extends JSONSerializable {
     }
 
     @SafeVarargs
-    static <T extends EnumDict> boolean maskIn(long bit, T... t) {
+    static <T extends EnumDict> boolean maskIn(long mask, T... t) {
         long value = toMask(t);
-        return (bit & value) == value;
+        return (mask & value) == value;
     }
 
     @SafeVarargs
-    static <T extends EnumDict> boolean maskInAny(long bit, T... t) {
+    static <T extends EnumDict> boolean maskInAny(long mask, T... t) {
         long value = toMask(t);
-        return (bit & value) != 0;
+        return (mask & value) != 0;
     }
 
-    static <T extends EnumDict> List<T> getByMask(Class<T> tClass, long bit) {
+    static <T extends EnumDict> List<T> getByMask(List<T> allOptions, long mask) {
+        if (allOptions.size() >= 64) {
+            throw new UnsupportedOperationException("不支持选项超过64个数据字典!");
+        }
         List<T> arr = new ArrayList<>();
-        for (T t : tClass.getEnumConstants()) {
-            if (t.in(bit)) {
+        List<T> all = allOptions;
+        for (T t : all) {
+            if (t.in(mask)) {
                 arr.add(t);
             }
         }
         return arr;
     }
 
+    static <T extends EnumDict> List<T> getByMask(Supplier<List<T>> allOptionsSuppiler, long mask) {
+        return getByMask(allOptionsSuppiler.get(), mask);
+    }
+
+
+    static <T extends Enum & EnumDict> List<T> getByMask(Class<T> tClass, long mask) {
+
+        return getByMask(Arrays.asList(tClass.getEnumConstants()), mask);
+    }
+
     /**
      * 默认在序列化为json时,默认会以对象方式写出枚举,可通过系统环境变量 <code>hsweb.enum.dict.disableWriteJSONObject</code>关闭默认设置。
      * 比如: java -jar -Dhsweb.enum.dict.disableWriteJSONObject=true

+ 8 - 1
hsweb-core/src/main/java/org/hswebframework/web/dict/ItemDefine.java

@@ -6,13 +6,20 @@ import java.util.List;
  * @author zhouhao
  * @since 3.0
  */
-public interface ItemDefine {
+public interface ItemDefine extends EnumDict<String> {
     String getText();
 
     String getValue();
 
     String getComments();
 
+    int getOrdinal();
+
+    @Override
+    default int ordinal() {
+        return getOrdinal();
+    }
+
     List<ItemDefine> getChildren();
 
 }

+ 2 - 1
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultClassDictDefine.java

@@ -5,6 +5,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.hswebframework.web.dict.ClassDictDefine;
+import org.hswebframework.web.dict.EnumDict;
 import org.hswebframework.web.dict.ItemDefine;
 
 import java.util.List;
@@ -23,5 +24,5 @@ public class DefaultClassDictDefine implements ClassDictDefine {
     private String           alias;
     private String           comments;
     private String           parserId;
-    private List<ItemDefine> items;
+    private List<EnumDict> items;
 }

+ 2 - 3
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictDefine.java

@@ -4,9 +4,8 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import org.hswebframework.web.dict.ClassDictDefine;
 import org.hswebframework.web.dict.DictDefine;
-import org.hswebframework.web.dict.ItemDefine;
+import org.hswebframework.web.dict.EnumDict;
 
 import java.util.List;
 
@@ -24,5 +23,5 @@ public class DefaultDictDefine implements DictDefine {
     private String           alias;
     private String           comments;
     private String           parserId;
-    private List<ItemDefine> items;
+    private List<EnumDict<String>> items;
 }

+ 2 - 76
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictDefineRepository.java

@@ -43,17 +43,7 @@ public class DefaultDictDefineRepository implements DictDefineRepository {
             define.setComments(type.getSimpleName());
         }
 
-        List<ItemDefine> items = new ArrayList<>();
-
-        for (T t : type.getEnumConstants()) {
-            items.add(DefaultItemDefine.builder()
-                    .text(t.getText())
-                    .comments(t.getComments())
-                    .value(String.valueOf(t.getValue()))
-                    .build());
-
-        }
-        define.setItems(items);
+        define.setItems(Arrays.asList(type.getEnumConstants()));
 
         return define;
 
@@ -64,75 +54,11 @@ public class DefaultDictDefineRepository implements DictDefineRepository {
         return parsedDict.get(id);
     }
 
-    private List<Field> parseField(Class type) {
-        if (type == Object.class) {
-            return Collections.emptyList();
-        }
-        List<Field> fields = new ArrayList<>();
-        ReflectionUtils.doWithFields(type, fields::add);
-        return fields;
-    }
-
     @Override
     public List<ClassDictDefine> getDefine(Class type) {
-        return this.parseDefine(type);
+        return Collections.emptyList();
     }
 
-    protected List<ClassDictDefine> parseDefine(Class type) {
-        List<ClassDictDefine> defines = new ArrayList<>();
-
-        if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
-            return Arrays.asList(parseEnumDict(type));
-        }
-        for (Field field : parseField(type)) {
-            Dict dict = field.getAnnotation(Dict.class);
-            if (dict == null) {
-                continue;
-            }
-            String id = dict.id();
-            DictDefine dictDefine = getDefine(id);
-            if (dictDefine instanceof ClassDictDefine) {
-                defines.add(((ClassDictDefine) dictDefine));
-            } else {
-                DefaultClassDictDefine define;
-                if (dictDefine != null) {
-                    List<ItemDefine> items = dictDefine.getItems()
-                            .stream()
-                            .map(item -> DefaultItemDefine.builder()
-                                    .text(item.getText())
-                                    .value(item.getValue())
-                                    .comments(String.join(",", item.getComments()))
-                                    .build())
-                            .collect(Collectors.toList());
-                    define = DefaultClassDictDefine.builder()
-                            .id(id)
-                            .alias(dictDefine.getAlias())
-                            .comments(dictDefine.getComments())
-                            .field(field.getName())
-                            .items(items)
-                            .build();
-
-                } else {
-                    List<ItemDefine> items = Arrays
-                            .stream(dict.items())
-                            .map(item -> DefaultItemDefine.builder()
-                                    .text(item.text())
-                                    .value(item.value())
-                                    .comments(String.join(",", item.comments()))
-                                    .build()).collect(Collectors.toList());
-                    define = DefaultClassDictDefine.builder()
-                            .id(id)
-                            .alias(dict.alias())
-                            .comments(dict.comments())
-                            .field(field.getName())
-                            .items(items)
-                            .build();
-                }
-                defines.add(define);
-            }
-        }
-        return defines;
-    }
 
     @Override
     public void addDefine(DictDefine dictDefine) {

+ 9 - 7
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultDictParser.java

@@ -2,8 +2,11 @@ package org.hswebframework.web.dict.defaults;
 
 import org.hswebframework.web.dict.DictDefine;
 import org.hswebframework.web.dict.DictParser;
+import org.hswebframework.web.dict.EnumDict;
 import org.hswebframework.web.dict.ItemDefine;
 
+import java.util.stream.Collectors;
+
 /**
  * @author zhouhao
  * @since 3.0
@@ -15,21 +18,20 @@ public class DefaultDictParser implements DictParser {
     }
 
     @Override
-    public String parseText(DictDefine dictDefine, String value) {
+    public String parseText(DictDefine dictDefine, Object value) {
         return dictDefine.getItems()
                 .stream()
-                .filter(itemDefine -> itemDefine.getValue().equals(value))
-                .map(ItemDefine::getText)
-                .findFirst()
-                .orElse(value);
+                .filter(itemDefine -> itemDefine.eq(value))
+                .map(EnumDict::getText)
+                .collect(Collectors.joining(","));
     }
 
     @Override
     public String parseValue(DictDefine dictDefine, String text) {
         return dictDefine.getItems()
                 .stream()
-                .filter(itemDefine -> itemDefine.getText().equals(text))
-                .map(ItemDefine::getValue)
+                .filter(itemDefine -> itemDefine.eq(text))
+                .map(EnumDict::getValue)
                 .findFirst()
                 .orElse(text);
     }

+ 4 - 3
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/DefaultItemDefine.java

@@ -17,8 +17,9 @@ import java.util.List;
 @NoArgsConstructor
 @AllArgsConstructor
 public class DefaultItemDefine implements ItemDefine {
-    private String           text;
-    private String           value;
-    private String           comments;
+    private String text;
+    private String value;
+    private String comments;
+    private int ordinal;
     private List<ItemDefine> children;
 }

+ 0 - 56
hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java

@@ -61,60 +61,4 @@ public class DictDefineTest {
 
     }
 
-    @Test
-    public void testParse() {
-//        JSON.toJSONString("",SerializerFeature.PrettyFormat)
-        DefaultClassDictDefine define = DefaultClassDictDefine.builder()
-                .id("test-code")
-                .field("code")
-                .build();
-        repository.registerDefine(define);
-
-
-        List<ClassDictDefine> defines = repository.getDefine(UseDictEntity2.class);
-        assertFalse(defines.isEmpty());
-        assertEquals(defines.size(), 2);
-
-        defines = repository.getDefine(UserCode.class);
-        assertFalse(defines.isEmpty());
-        assertEquals(defines.size(), 1);
-
-        assertEquals(defines.get(0).getItems().size(), UserCode.values());
-
-
-    }
-
-    @Test
-    public void testWrap() {
-        assertNull(api.wrap(null));
-        assertNotNull(api.wrap(new HashMap<>()));
-        assertNull(api.unwrap(null));
-        assertNotNull(api.unwrap(new HashMap<>()));
-
-        UseDictEntity2 entity = new UseDictEntity2();
-        entity.setStatus(new Integer(1).byteValue());
-
-        entity = api.wrap(entity);
-
-        assertEquals(entity.getStatusText(), "正常");
-
-        entity.setStatus(null);
-        entity = api.unwrap(entity);
-        assertEquals(entity.getStatus(), Byte.valueOf((byte) 1));
-
-        entity.setStatus((byte) 2);
-        entity = api.unwrap(entity);
-        assertEquals(entity.getStatus(), Byte.valueOf((byte) 2));
-
-        entity.setStatus(null);
-        entity.setStatusText(null);
-        entity.setCode("1");
-        api.wrap(entity);
-
-        assertNull(entity.getStatusText());
-        assertEquals(entity.getCode(), "1");
-
-        api.unwrap(entity);
-        assertEquals(entity.getCode(), "1");
-    }
 }

+ 12 - 11
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonGenericHttpMessageConverter.java

@@ -39,8 +39,9 @@ import java.util.Set;
 public class FastJsonGenericHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> implements Ordered {
 
     public final static Charset UTF8 = Charset.forName("UTF-8");
-    @Autowired(required = false)
-    private DictSupportApi dictSupportApi;
+
+//    @Autowired(required = false)
+//    private DictSupportApi dictSupportApi;
 
     private Charset charset = UTF8;
 
@@ -116,9 +117,9 @@ public class FastJsonGenericHttpMessageConverter extends AbstractGenericHttpMess
             }
         }
         Object object = JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), type);
-        if (dictSupportApi != null) {
-            object = dictSupportApi.unwrap(object);
-        }
+//        if (dictSupportApi != null) {
+//            object = dictSupportApi.unwrap(object);
+//        }
         return object;
     }
 
@@ -149,14 +150,14 @@ public class FastJsonGenericHttpMessageConverter extends AbstractGenericHttpMess
         String callback = ThreadLocalUtils.getAndRemove("jsonp-callback");
         if (obj instanceof ResponseMessage) {
             ResponseMessage message = (ResponseMessage) obj;
-            if (dictSupportApi != null) {
-                message.setResult(dictSupportApi.wrap(message.getResult()));
-            }
+//            if (dictSupportApi != null) {
+//                message.setResult(dictSupportApi.wrap(message.getResult()));
+//            }
             text = JSON.toJSONString(obj, FastJsonHttpMessageConverter.parseFilter(message), features);
         } else {
-            if (dictSupportApi != null) {
-                obj = dictSupportApi.wrap(obj);
-            }
+//            if (dictSupportApi != null) {
+//                obj = dictSupportApi.wrap(obj);
+//            }
             text = JSON.toJSONString(obj, features);
         }
         if (!StringUtils.isNullOrEmpty(callback)) {

+ 29 - 30
hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-api/src/main/java/org/hswebframework/web/dictionary/api/entity/DictionaryItemEntity.java

@@ -17,6 +17,8 @@
 package org.hswebframework.web.dictionary.api.entity;
 
 import org.hswebframework.web.commons.entity.TreeSortSupportEntity;
+import org.hswebframework.web.dict.EnumDict;
+import org.hswebframework.web.dict.ItemDefine;
 
 import java.util.List;
 
@@ -25,75 +27,58 @@ import java.util.List;
  *
  * @author hsweb-generator-online
  */
-public interface DictionaryItemEntity extends TreeSortSupportEntity<String> {
+public interface DictionaryItemEntity extends TreeSortSupportEntity<String>, EnumDict<String> {
  /*-------------------------------------------
     |               属性名常量               |
     ===========================================*/
     /**
      * 字典id
      */
-    String dictId         = "dictId";
+    String dictId = "dictId";
     /**
      * 名称
      */
-    String name           = "name";
+    String name = "name";
     /**
      * 字典值
      */
-    String value          = "value";
+    String value = "value";
     /**
      * 字典文本
      */
-    String text           = "text";
+    String text = "text";
     /**
      * 字典值类型
      */
-    String valueType      = "valueType";
+    String valueType = "valueType";
     /**
      * 是否启用
      */
-    String status         = "status";
+    String status = "status";
     /**
      * 说明
      */
-    String describe       = "describe";
+    String describe = "describe";
     /**
      * 父级选项
      */
-    String parentId       = "parentId";
+    String parentId = "parentId";
     /**
      * 树编码
      */
-    String path           = "path";
+    String path = "path";
     /**
      * 快速搜索码
      */
-    String searchCode     = "searchCode";
+    String searchCode = "searchCode";
     /**
      * 排序索引
      */
-    String sortIndex      = "sortIndex";
+    String sortIndex = "sortIndex";
     /**
      * 树结构层级
      */
-    String level          = "level";
-    /**
-     * 文本提取表达式
-     */
-    String textExpression = "textExpression";
-
-    /**
-     * 文本提取表达式
-     */
-    String valueExpression = "valueExpression";
-
-    String getTextExpression();
-
-    void setTextExpression(String textExpression);
-
-    String getValueExpression();
-
-    void setValueExpression(String valueExpression);
+    String level = "level";
 
     /**
      * @return 字典id
@@ -176,4 +161,18 @@ public interface DictionaryItemEntity extends TreeSortSupportEntity<String> {
     void setSearchCode(String searchCode);
 
     void setChildren(List<DictionaryItemEntity> children);
+
+    Integer getOrdinal();
+
+    void setOrdinal(Integer ordinal);
+
+    @Override
+    default int ordinal() {
+        return getOrdinal() == null ? 0 : getOrdinal();
+    }
+
+    @Override
+    default String getComments() {
+        return getDescribe();
+    }
 }

+ 7 - 159
hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-api/src/main/java/org/hswebframework/web/dictionary/api/entity/SimpleDictionaryItemEntity.java

@@ -16,6 +16,8 @@
  */
 package org.hswebframework.web.dictionary.api.entity;
 
+import lombok.Getter;
+import lombok.Setter;
 import org.hswebframework.web.commons.entity.SimpleTreeSortSupportEntity;
 
 import java.util.List;
@@ -25,6 +27,8 @@ import java.util.List;
  *
  * @author hsweb-generator-online
  */
+@Getter
+@Setter
 public class SimpleDictionaryItemEntity extends SimpleTreeSortSupportEntity<String> implements DictionaryItemEntity {
     //字典id
     private String dictId;
@@ -37,7 +41,7 @@ public class SimpleDictionaryItemEntity extends SimpleTreeSortSupportEntity<Stri
     //字典值类型
     private String valueType;
     //是否启用
-    private Byte   status;
+    private Byte status;
     //说明
     private String describe;
     //快速搜索码
@@ -46,168 +50,12 @@ public class SimpleDictionaryItemEntity extends SimpleTreeSortSupportEntity<Stri
     // 使用表达式拼接text
     // #value+'('+#context.otherVal+')'
     private String textExpression;
+
     private String valueExpression;
 
+    private Integer ordinal;
 
     private List<DictionaryItemEntity> children;
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<DictionaryItemEntity> getChildren() {
-        return children;
-    }
-
-    @Override
-    public void setChildren(List<DictionaryItemEntity> children) {
-        this.children = children;
-    }
-
-    @Override
-    public String getTextExpression() {
-        return textExpression;
-    }
-
-    @Override
-    public void setTextExpression(String textExpression) {
-        this.textExpression = textExpression;
-    }
-
-    @Override
-    public String getValueExpression() {
-        return valueExpression;
-    }
-
-    @Override
-    public void setValueExpression(String valueExpression) {
-        this.valueExpression = valueExpression;
-    }
-
-    /**
-     * @return 字典id
-     */
-    @Override
-    public String getDictId() {
-        return this.dictId;
-    }
-
-    /**
-     * 设置 字典id
-     */
-    @Override
-    public void setDictId(String dictId) {
-        this.dictId = dictId;
-    }
-
-    /**
-     * @return 名称
-     */
-    @Override
-    public String getName() {
-        return this.name;
-    }
-
-    /**
-     * 设置 名称
-     */
-    @Override
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * @return 字典值
-     */
-    @Override
-    public String getValue() {
-        return this.value;
-    }
-
-    /**
-     * 设置 字典值
-     */
-    @Override
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    /**
-     * @return 字典文本
-     */
-    @Override
-    public String getText() {
-        return this.text;
-    }
-
-    /**
-     * 设置 字典文本
-     */
-    @Override
-    public void setText(String text) {
-        this.text = text;
-    }
-
-    /**
-     * @return 字典值类型
-     */
-    @Override
-    public String getValueType() {
-        return this.valueType;
-    }
-
-    /**
-     * 设置 字典值类型
-     */
-    @Override
-    public void setValueType(String valueType) {
-        this.valueType = valueType;
-    }
-
-    /**
-     * @return 是否启用
-     */
-    @Override
-    public Byte getStatus() {
-        return this.status;
-    }
-
-    /**
-     * 设置 是否启用
-     */
-    @Override
-    public void setStatus(Byte enabled) {
-        this.status = enabled;
-    }
-
-    /**
-     * @return 说明
-     */
-    @Override
-    public String getDescribe() {
-        return this.describe;
-    }
-
-    /**
-     * 设置 说明
-     */
-    @Override
-    public void setDescribe(String describe) {
-        this.describe = describe;
-    }
-
-    /**
-     * @return 快速搜索码
-     */
-    @Override
-    public String getSearchCode() {
-        return this.searchCode;
-    }
-
-    /**
-     * 设置 快速搜索码
-     */
-    @Override
-    public void setSearchCode(String searchCode) {
-        this.searchCode = searchCode;
-    }
 
 }

+ 4 - 18
hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-local/src/main/java/org/hswebframework/web/dictionary/simple/BoostDictDefineRepository.java

@@ -1,11 +1,9 @@
 package org.hswebframework.web.dictionary.simple;
 
-import org.hswebframework.web.dict.ClassDictDefine;
 import org.hswebframework.web.dict.DictDefine;
-import org.hswebframework.web.dict.ItemDefine;
+import org.hswebframework.web.dict.EnumDict;
 import org.hswebframework.web.dict.defaults.DefaultDictDefine;
 import org.hswebframework.web.dict.defaults.DefaultDictDefineRepository;
-import org.hswebframework.web.dict.defaults.DefaultItemDefine;
 import org.hswebframework.web.dictionary.api.DictionaryService;
 import org.hswebframework.web.dictionary.api.entity.DictionaryEntity;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,8 +11,8 @@ import org.springframework.cache.annotation.CacheConfig;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author zhouhao
@@ -34,15 +32,8 @@ public class BoostDictDefineRepository extends DefaultDictDefineRepository {
         if (entity == null) {
             return super.getDefine(id);
         }
-        List<ItemDefine> items = entity.getItems()
-                .stream()
-                .map(item -> DefaultItemDefine
-                        .builder()
-                        .value(item.getValue())
-                        .text(item.getText())
-                        .comments(item.getDescribe())
-                        .build())
-                .collect(Collectors.toList());
+        List<EnumDict<String>> items = new ArrayList<>(entity.getItems());
+
 
         return DefaultDictDefine.builder()
                 .id(id)
@@ -51,9 +42,4 @@ public class BoostDictDefineRepository extends DefaultDictDefineRepository {
                 .build();
     }
 
-    @Override
-    @Cacheable(key = "'DictDefineByClass:'+#type.name")
-    public List<ClassDictDefine> getDefine(Class type) {
-        return super.getDefine(type);
-    }
 }

+ 5 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/DefaultOptionalConvertBuilder.java

@@ -5,7 +5,9 @@ import org.hswebframework.web.entity.form.DictConfig;
 import org.hswebframework.web.service.form.OptionalConvertBuilder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -20,6 +22,9 @@ public class DefaultOptionalConvertBuilder implements OptionalConvertBuilder {
 
     @Override
     public OptionConverter build(DictConfig dictConfig) {
+        if(CollectionUtils.isEmpty(strategies)){
+            return null;
+        }
         return strategies.stream()
                 .filter(strategy -> strategy.support(dictConfig.getType()))
                 .findFirst()

+ 10 - 2
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/DictionaryOptionalConvertBuilderStrategy.java

@@ -3,7 +3,9 @@ package org.hswebframework.web.service.form.simple.dict;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import org.hswebframework.ezorm.core.OptionConverter;
+import org.hswebframework.web.dict.DictDefineRepository;
 import org.hswebframework.web.entity.form.DictConfig;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 
@@ -13,15 +15,21 @@ import org.springframework.stereotype.Component;
  */
 @Component
 public class DictionaryOptionalConvertBuilderStrategy implements OptionalConvertBuilderStrategy {
+    @Autowired(required = false)
+    private DictDefineRepository dictDefineRepository;
+
     @Override
     public boolean support(String type) {
-        return "dict".equals(type);
+        return "dict".equals(type) && dictDefineRepository != null;
     }
 
+
     @Override
     public OptionConverter build(DictConfig dictConfig) {
         JSONObject conf = JSON.parseObject(dictConfig.getConfig());
-        String dictType=conf.getString("dictType");
+        String dictType = conf.getString("dictType");
+
+
 
         return null;
     }

+ 75 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/EnumDictOptionConverter.java

@@ -0,0 +1,75 @@
+package org.hswebframework.web.service.form.simple.dict;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.ezorm.core.OptionConverter;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.util.*;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class EnumDictOptionConverter<T extends EnumDict> implements OptionConverter {
+
+    protected Supplier<List<T>> allOptionSupplier;
+
+    @Getter
+    @Setter
+    protected boolean multi;
+
+    @Getter
+    @Setter
+    protected boolean writeObject;
+
+    protected String fieldName;
+
+    public EnumDictOptionConverter(Supplier<List<T>> supplier, String fieldName) {
+        this.allOptionSupplier = supplier;
+        this.fieldName = fieldName;
+    }
+
+    @Override
+    public Object getOptions() {
+        return allOptionSupplier.get();
+    }
+
+    @Override
+    public String getFieldName() {
+        return fieldName;
+    }
+
+    @Override
+    public Object converterData(Object o) {
+        //什么也不做,EnumDictValueConverter会进行处理
+        return o;
+    }
+
+    @Override
+    @SuppressWarnings("all")
+    public Object converterValue(Object o) {
+        List<Object> values;
+        if (o instanceof String) {
+            values = Arrays.asList(((String) o).split("[, ; ;]"));
+        } else if (o instanceof Object[]) {
+            values = Arrays.asList(((Object[]) o));
+        } else if (o instanceof Collection) {
+            values = new ArrayList<>(((Collection) o));
+        } else {
+            values = Collections.singletonList(o);
+        }
+        if (writeObject) {
+            return allOptionSupplier.get()
+                    .stream()
+                    .filter(e -> e.eq(o))
+                    .collect(Collectors.toSet());
+        }
+        return allOptionSupplier.get()
+                .stream()
+                .filter(e -> e.eq(o))
+                .map(EnumDict::getText)
+                .map(String::valueOf)
+                .collect(Collectors.joining(","));
+    }
+}

+ 119 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/dict/EnumDictValueConverter.java

@@ -0,0 +1,119 @@
+package org.hswebframework.web.service.form.simple.dict;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.ezorm.core.ValueConverter;
+import org.hswebframework.web.dict.EnumDict;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class EnumDictValueConverter<T extends EnumDict> implements ValueConverter {
+
+    protected Supplier<List<T>> allOptionSupplier;
+
+    protected Function<Object, T> orElseGet = v -> {
+        log.warn("选项[{}]在字典中不存在.全部选项:[{}]", v, allOptionSupplier.get());
+        return null;
+    };
+
+    public EnumDictValueConverter(Supplier<List<T>> allOptionSupplier) {
+        this.allOptionSupplier = allOptionSupplier;
+    }
+
+    public EnumDictValueConverter(Supplier<List<T>> allOptionSupplier, Function<Object, T> orElseGet) {
+        this.allOptionSupplier = allOptionSupplier;
+        this.orElseGet = orElseGet;
+    }
+
+    @Setter
+    @Getter
+    private boolean multi = true;
+
+    @Setter
+    @Getter
+    private boolean dataToMask = true;
+
+    protected T find(Object value) {
+        return allOptionSupplier.get()
+                .stream()
+                .filter(e -> e.eq(value))
+                .findFirst()
+                .orElseGet(() -> orElseGet.apply(value));
+
+    }
+
+    @Override
+    @SuppressWarnings("all")
+    public Object getData(Object o) {
+        if (StringUtils.isEmpty(o)) {
+            return o;
+        }
+        //多选
+        if (multi) {
+            List<Object> values;
+            if (o instanceof String) {
+                values = Arrays.asList(((String) o).split("[, ; ;]"));
+            } else if (o instanceof Object[]) {
+                values = Arrays.asList(((Object[]) o));
+            } else if (o instanceof Collection) {
+                values = new ArrayList<>(((Collection) o));
+            } else {
+                values = Collections.singletonList(o);
+            }
+            //转为mask
+            if (dataToMask) {
+                if (o instanceof Number) {
+                    return ((Number) o).longValue();
+                }
+                return EnumDict.toMask(values.stream()
+                        .map(this::find)
+                        .filter(Objects::nonNull)
+                        .toArray(EnumDict[]::new));
+            }
+            //以逗号分隔
+            return values.stream()
+                    .map(this::find)
+                    .filter(Objects::nonNull)
+                    .map(EnumDict::getValue)
+                    .map(String::valueOf)
+                    .collect(Collectors.joining(","));
+        }
+
+        return Optional.ofNullable(this.find(o))
+                .map(EnumDict::getValue)
+                .orElse(o);
+    }
+
+    @Override
+    public Object getValue(Object o) {
+        if (multi) {
+            if (dataToMask) {
+                Long mask = null;
+                if (org.hswebframework.utils.StringUtils.isNumber(o)) {
+                    mask = org.hswebframework.utils.StringUtils.toLong(o);
+                }
+                if (mask != null) {
+                    return EnumDict.getByMask(allOptionSupplier, mask)
+                            .stream()
+                            .map(EnumDict::getValue)
+                            .map(String::valueOf)
+                            .collect(Collectors.joining(","));
+                }
+            }
+            return allOptionSupplier.get()
+                    .stream()
+                    .filter(e -> e.eq(o))
+                    .map(EnumDict::getValue)
+                    .map(String::valueOf)
+                    .collect(Collectors.joining(","));
+        }
+        return o;
+    }
+
+}

+ 1 - 3
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/validator/GroovyVlidator.java

@@ -1,7 +1,5 @@
 package org.hswebframework.web.service.form.simple.validator;
 
-/**
- * Created by zhouhao on 2017/7/12.
- */
 public class GroovyVlidator {
+
 }

+ 2 - 2
hsweb-system/hsweb-system-workflow/hsweb-system-workflow-local/src/main/java/org/hswebframework/web/workflow/web/FlowableUtilsController.java

@@ -39,11 +39,11 @@ public class FlowableUtilsController {
         List<ActivityImpl> activities = bpmActivityService.getActivitiesById(procDefId, null);
         for (ActivityImpl activity : activities) {
             Map<String, Object> map = new HashMap<>();
-            if ("startEvent".equals(activity.getProperty("dimension"))) {
+            if ("startEvent".equals(activity.getProperty("type"))) {
                 map.put("id", activity.getId());
                 map.put("name", "流程发起者");
 //                map.put("info", actDefService.selectSingle(single(ActDefEntity.actId, activity.getId())));
-            } else if ("userTask".equals(activity.getProperty("dimension"))) {
+            } else if ("userTask".equals(activity.getProperty("type"))) {
                 map.put("id", activity.getId());
                 map.put("name", activity.getProperty("name").toString());
 //                map.put("info", actDefService.selectSingle(single(ActDefEntity.actId, activity.getId())));