Selaa lähdekoodia

Merge pull request #140 from hs-web/3.0.x

3.0.x
老周 5 vuotta sitten
vanhempi
commit
9eb96c4c7e
100 muutettua tiedostoa jossa 744 lisäystä ja 290 poistoa
  1. 1 1
      .travis.yml
  2. 1 1
      hsweb-authorization/hsweb-authorization-api/pom.xml
  3. 3 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationInitializeService.java
  4. 1 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationDecodeEvent.java
  5. 12 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationInitializeEvent.java
  6. 1 1
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  7. 8 2
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
  8. 1 1
      hsweb-authorization/hsweb-authorization-jwt/pom.xml
  9. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/pom.xml
  10. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/pom.xml
  11. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-core/pom.xml
  12. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/pom.xml
  13. 1 1
      hsweb-authorization/pom.xml
  14. 1 1
      hsweb-boost/hsweb-boost-aop/pom.xml
  15. 1 1
      hsweb-boost/hsweb-boost-excel/pom.xml
  16. 1 1
      hsweb-boost/hsweb-boost-ftp/pom.xml
  17. 1 1
      hsweb-boost/pom.xml
  18. 1 1
      hsweb-commons/hsweb-commons-bean/pom.xml
  19. 1 1
      hsweb-commons/hsweb-commons-controller/pom.xml
  20. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/pom.xml
  21. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml
  22. 121 60
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java
  23. 28 32
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParser.java
  24. 49 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/NumberBooleanTypeHandler.java
  25. 3 2
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/TreeStructureSqlTermCustomizer.java
  26. 2 3
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/Pager.java
  27. 8 2
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/PagerInterceptor.java
  28. 4 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/NestEntity.java
  29. 10 5
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestCrud.java
  30. 4 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestEntity.java
  31. 11 2
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/org/hswebframework/web/dao/test/TestDao.xml
  32. 1 1
      hsweb-commons/hsweb-commons-dao/pom.xml
  33. 1 1
      hsweb-commons/hsweb-commons-entity/pom.xml
  34. 87 51
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupportEntity.java
  35. 32 5
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/param/TermExpressionParser.java
  36. 8 3
      hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/TreeSupportEntityTests.java
  37. 24 0
      hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/param/TermExpressionParserTest.java
  38. 1 1
      hsweb-commons/hsweb-commons-model/pom.xml
  39. 1 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/pom.xml
  40. 1 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-oauth2/pom.xml
  41. 1 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/pom.xml
  42. 1 1
      hsweb-commons/hsweb-commons-service/pom.xml
  43. 1 1
      hsweb-commons/hsweb-commons-utils/pom.xml
  44. 1 1
      hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java
  45. 1 1
      hsweb-commons/pom.xml
  46. 1 1
      hsweb-concurrent/hsweb-concurrent-async-job/pom.xml
  47. 1 1
      hsweb-concurrent/hsweb-concurrent-cache/pom.xml
  48. 1 1
      hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/pom.xml
  49. 1 1
      hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-redis/pom.xml
  50. 1 1
      hsweb-concurrent/hsweb-concurrent-counter/pom.xml
  51. 1 1
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/pom.xml
  52. 1 1
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-redis/pom.xml
  53. 1 1
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/pom.xml
  54. 1 1
      hsweb-concurrent/hsweb-concurrent-lock/pom.xml
  55. 1 1
      hsweb-concurrent/hsweb-concurrent-rate-limiter/hsweb-concurrent-rate-limiter-api/pom.xml
  56. 1 1
      hsweb-concurrent/hsweb-concurrent-rate-limiter/hsweb-concurrent-rate-limiter-starter/pom.xml
  57. 1 1
      hsweb-concurrent/hsweb-concurrent-rate-limiter/pom.xml
  58. 1 1
      hsweb-concurrent/pom.xml
  59. 1 1
      hsweb-core/pom.xml
  60. 19 6
      hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
  61. 18 25
      hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java
  62. 5 0
      hsweb-core/src/test/java/org/hswebframework/web/bean/Source.java
  63. 2 0
      hsweb-core/src/test/java/org/hswebframework/web/bean/Target.java
  64. 1 1
      hsweb-datasource/hsweb-datasource-api/pom.xml
  65. 8 4
      hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DefaultDataSourceSwitcher.java
  66. 8 4
      hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DefaultDatabaseSwitcher.java
  67. 1 1
      hsweb-datasource/hsweb-datasource-jta/pom.xml
  68. 1 1
      hsweb-datasource/hsweb-datasource-web/pom.xml
  69. 1 1
      hsweb-datasource/pom.xml
  70. 1 1
      hsweb-logging/hsweb-access-logging-aop/pom.xml
  71. 1 1
      hsweb-logging/hsweb-access-logging-api/pom.xml
  72. 1 1
      hsweb-logging/pom.xml
  73. 7 5
      hsweb-starter/hsweb-spring-boot-starter/README.md
  74. 1 1
      hsweb-starter/hsweb-spring-boot-starter/pom.xml
  75. 11 0
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemInitializeAutoConfiguration.java
  76. 21 0
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/event/SystemInitializeEvent.java
  77. 1 1
      hsweb-starter/pom.xml
  78. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/pom.xml
  79. 3 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/ActionEntity.java
  80. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/AuthorizationSettingEntity.java
  81. 26 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingService.java
  82. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/pom.xml
  83. 102 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java
  84. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml
  85. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/pom.xml
  86. 31 9
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/AuthorizationSettingController.java
  87. 1 1
      hsweb-system/hsweb-system-authorization/pom.xml
  88. 1 1
      hsweb-system/hsweb-system-config/hsweb-system-config-api/pom.xml
  89. 1 1
      hsweb-system/hsweb-system-config/hsweb-system-config-local/pom.xml
  90. 1 1
      hsweb-system/hsweb-system-config/hsweb-system-config-starter/pom.xml
  91. 1 1
      hsweb-system/hsweb-system-config/hsweb-system-config-web/pom.xml
  92. 1 1
      hsweb-system/hsweb-system-config/pom.xml
  93. 1 1
      hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-api/pom.xml
  94. 1 1
      hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-local/pom.xml
  95. 1 1
      hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-starter/pom.xml
  96. 1 1
      hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-web/pom.xml
  97. 1 1
      hsweb-system/hsweb-system-dashboard/pom.xml
  98. 1 1
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/pom.xml
  99. 1 1
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-local/pom.xml
  100. 0 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-starter/pom.xml

+ 1 - 1
.travis.yml

@@ -1,7 +1,7 @@
 language: java
 sudo: false
 jdk:
-  - oraclejdk8
+  - openjdk8
 before_install:
   - chmod +x mvnw
 script:

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 3 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationInitializeService.java

@@ -18,6 +18,8 @@
 
 package org.hswebframework.web.authorization;
 
+import org.hswebframework.web.authorization.listener.event.AuthorizationInitializeEvent;
+
 /**
  * 授权信息初始化服务接口,使用该接口初始化用的权限信息
  *
@@ -30,6 +32,7 @@ public interface AuthenticationInitializeService {
      *
      * @param userId 用户ID
      * @return 权限信息
+     * @see AuthorizationInitializeEvent
      */
     Authentication initUserAuthorization(String userId);
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationDecodeEvent.java

@@ -39,7 +39,7 @@ public class AuthorizationDecodeEvent extends AbstractAuthorizationEvent {
     }
 
     public void setPassword(String password) {
-        super.username = password;
+        super.password = password;
     }
 
 }

+ 12 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationInitializeEvent.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.authorization.listener.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.authorization.Authentication;
+
+@Getter
+@AllArgsConstructor
+public class AuthorizationInitializeEvent {
+
+    private Authentication authentication;
+}

+ 1 - 1
hsweb-authorization/hsweb-authorization-basic/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 8 - 2
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -201,7 +201,10 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
             Function<Predicate<Role>, Boolean> func = logicalIsOr
                     ? authentication.getRoles().stream()::anyMatch
                     : authentication.getRoles().stream()::allMatch;
-            access = func.apply(role -> rolesDef.contains(role.getId()));
+
+            access = logicalIsOr
+                    ? access || func.apply(role -> rolesDef.contains(role.getId()))
+                    : access && func.apply(role -> rolesDef.contains(role.getId()));
         }
         //控制用户
         if (!usersDef.isEmpty()) {
@@ -211,7 +214,10 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
             Function<Predicate<String>, Boolean> func = logicalIsOr
                     ? usersDef.stream()::anyMatch
                     : usersDef.stream()::allMatch;
-            access = func.apply(authentication.getUser().getUsername()::equals);
+            access = logicalIsOr
+                    ? access || func.apply(authentication.getUser().getUsername()::equals)
+                    : access && func.apply(authentication.getUser().getUsername()::equals);
+
         }
         if (!access) {
             throw new AccessDenyException(definition.getMessage());

+ 1 - 1
hsweb-authorization/hsweb-authorization-jwt/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-authorization-oauth2</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-authorization-oauth2</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-core/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-authorization-oauth2</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <!--<relativePath>../../pom.xml</relativePath>-->
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-authorization/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-boost/hsweb-boost-aop/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-boost</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-boost/hsweb-boost-excel/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-boost</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-boost/hsweb-boost-ftp/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-boost</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-boost/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-commons/hsweb-commons-bean/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-controller/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons-dao</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons-dao</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 121 - 60
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -38,9 +38,11 @@ import org.hswebframework.ezorm.rdb.render.dialect.*;
 import org.hswebframework.ezorm.rdb.render.support.simple.CommonSqlRender;
 import org.hswebframework.ezorm.rdb.render.support.simple.SimpleWhereSqlBuilder;
 import org.hswebframework.web.BusinessException;
+import org.hswebframework.web.bean.FastBeanCopier;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.dao.mybatis.builder.jpa.JpaAnnotationParser;
+import org.hswebframework.web.dao.mybatis.handler.NumberBooleanTypeHandler;
 import org.hswebframework.web.dao.mybatis.plgins.pager.Pager;
 import org.hswebframework.web.dao.mybatis.MybatisUtils;
 import org.hswebframework.utils.StringUtils;
@@ -106,11 +108,11 @@ public class EasyOrmSqlBuilder {
         return javaType;
     }
 
-    private final RDBDatabaseMetaData mysql = new MysqlMeta();
-    private final RDBDatabaseMetaData oracle = new OracleMeta();
-    private final RDBDatabaseMetaData h2 = new H2Meta();
-    private final RDBDatabaseMetaData postgresql = new PGMeta();
-    private final RDBDatabaseMetaData mssql = new MSSQLMeta();
+    public static final RDBDatabaseMetaData mysql = new MysqlMeta();
+    public static final RDBDatabaseMetaData oracle = new OracleMeta();
+    public static final RDBDatabaseMetaData h2 = new H2Meta();
+    public static final RDBDatabaseMetaData postgresql = new PGMeta();
+    public static final RDBDatabaseMetaData mssql = new MSSQLMeta();
 
     private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<>();
 
@@ -145,6 +147,50 @@ public class EasyOrmSqlBuilder {
 
     }
 
+    private List<RDBColumnMetaData> createColumn(String prefix, String columnName, ResultMapping resultMapping) {
+        List<RDBColumnMetaData> metaData = new ArrayList<>();
+        if (resultMapping.getNestedQueryId() == null) {
+
+            if (resultMapping.getNestedResultMapId() != null) {
+                ResultMap nests = MybatisUtils.getResultMap(resultMapping.getNestedResultMapId());
+                Set<ResultMapping> resultMappings = new HashSet<>(nests.getResultMappings());
+                resultMappings.addAll(nests.getIdResultMappings());
+                for (ResultMapping mapping : resultMappings) {
+                    metaData.addAll(createColumn(resultMapping.getProperty(),
+                            org.springframework.util.StringUtils.hasText(resultMapping.getColumn())
+                                    ? resultMapping.getColumn()
+                                    : resultMapping.getProperty(),
+                            mapping));
+                }
+                return metaData;
+            }
+
+            JDBCType jdbcType = JDBCType.VARCHAR;
+            try {
+                jdbcType = JDBCType.valueOf(resultMapping.getJdbcType().name());
+            } catch (Exception e) {
+                log.warn("can not parse jdbcType:{}", resultMapping.getJdbcType());
+            }
+            RDBColumnMetaData column = new RDBColumnMetaData();
+            column.setJdbcType(jdbcType);
+            column.setName(org.springframework.util.StringUtils.hasText(columnName)
+                    ? columnName.concat(".").concat(resultMapping.getColumn()) : resultMapping.getColumn());
+
+            if (resultMapping.getTypeHandler() != null) {
+                column.setProperty("typeHandler", resultMapping.getTypeHandler().getClass().getName());
+            }
+            if (!StringUtils.isNullOrEmpty(resultMapping.getProperty())) {
+                column.setAlias(org.springframework.util.StringUtils.hasText(prefix)
+                        ? prefix.concat(".").concat(resultMapping.getProperty()) : resultMapping.getProperty());
+
+            }
+            column.setJavaType(resultMapping.getJavaType());
+            column.setProperty("resultMapping", resultMapping);
+            metaData.add(column);
+        }
+        return metaData;
+    }
+
     protected RDBTableMetaData createMeta(String tableName, String resultMapId) {
 //        tableName = getRealTableName(tableName);
         RDBDatabaseMetaData active = getActiveDatabase();
@@ -169,40 +215,11 @@ public class EasyOrmSqlBuilder {
 
         List<ResultMapping> resultMappings = new ArrayList<>(resultMaps.getResultMappings());
         resultMappings.addAll(resultMaps.getIdResultMappings());
-        for (ResultMapping resultMapping : resultMappings) {
-            if (resultMapping.getNestedQueryId() == null) {
-                RDBColumnMetaData column = new RDBColumnMetaData();
-                column.setJdbcType(JDBCType.valueOf(resultMapping.getJdbcType().name()));
-                column.setName(resultMapping.getColumn());
-                if (resultMapping.getTypeHandler() != null) {
-                    column.setProperty("typeHandler", resultMapping.getTypeHandler().getClass().getName());
-                }
-                if (!StringUtils.isNullOrEmpty(resultMapping.getProperty())) {
-                    column.setAlias(resultMapping.getProperty());
-                }
-                column.setJavaType(resultMapping.getJavaType());
-                column.setProperty("resultMapping", resultMapping);
-                //时间
-                if (column.getJdbcType() == JDBCType.DATE || column.getJdbcType() == JDBCType.TIMESTAMP) {
-                    ValueConverter dateConvert = new DateTimeConverter("yyyy-MM-dd HH:mm:ss", column.getJavaType()) {
-                        @Override
-                        public Object getData(Object value) {
-                            if (value instanceof Number) {
-                                return new Date(((Number) value).longValue());
-                            }
-                            return super.getData(value);
-                        }
-                    };
-                    column.setValueConverter(dateConvert);
-                } else if (column.getJavaType() == boolean.class || column.getJavaType() == Boolean.class) {
-                    column.setValueConverter(new BooleanValueConverter(column.getJdbcType()));
-                } else if (TypeUtils.isNumberType(column)) { //数字
-                    //数字
-                    column.setValueConverter(new NumberValueConverter(column.getJavaType()));
-                }
-                rdbTableMetaData.addColumn(column);
-            }
-        }
+
+        resultMappings.stream()
+                .map(mapping -> this.createColumn(null, null, mapping))
+                .flatMap(Collection::stream)
+                .forEach(rdbTableMetaData::addColumn);
 
         if (useJpa) {
             Class type = entityFactory == null ? resultMaps.getType() : entityFactory.getInstanceType(resultMaps.getType());
@@ -217,6 +234,27 @@ public class EasyOrmSqlBuilder {
                 }
             }
         }
+        for (RDBColumnMetaData column : rdbTableMetaData.getColumns()) {
+            //时间
+            if (column.getJdbcType() == JDBCType.DATE || column.getJdbcType() == JDBCType.TIMESTAMP) {
+                ValueConverter dateConvert = new DateTimeConverter("yyyy-MM-dd HH:mm:ss", column.getJavaType()) {
+                    @Override
+                    public Object getData(Object value) {
+                        if (value instanceof Number) {
+                            return new Date(((Number) value).longValue());
+                        }
+                        return super.getData(value);
+                    }
+                };
+                column.setValueConverter(dateConvert);
+            } else if (column.getJavaType() == boolean.class || column.getJavaType() == Boolean.class) {
+                column.setValueConverter(new BooleanValueConverter(column.getJdbcType()));
+                column.setProperty("typeHandler", NumberBooleanTypeHandler.class.getName());
+            } else if (TypeUtils.isNumberType(column)) { //数字
+                //数字
+                column.setValueConverter(new NumberValueConverter(column.getJavaType()));
+            }
+        }
         cache.put(cacheKey, rdbTableMetaData);
         return rdbTableMetaData;
     }
@@ -230,7 +268,11 @@ public class EasyOrmSqlBuilder {
         CommonSqlRender render = (CommonSqlRender) databaseMetaDate.getRenderer(SqlRender.TYPE.SELECT);
         List<CommonSqlRender.OperationColumn> columns = render.parseOperationField(tableMetaData, param);
         SqlAppender appender = new SqlAppender();
+        Object data = param.getData();
+        Map<String, Object> mapData = FastBeanCopier.copy(data, HashMap::new);
+
         columns.forEach(column -> {
+
             RDBColumnMetaData columnMetaData = column.getRDBColumnMetaData();
             if (columnMetaData == null) {
                 return;
@@ -238,21 +280,27 @@ public class EasyOrmSqlBuilder {
             if (columnMetaData.getName().contains(".")) {
                 return;
             }
-            Object value;
-            try {
-                value = propertyUtils.getProperty(param.getData(), columnMetaData.getAlias());
-                if (value == null) {
-                    return;
-                }
-            } catch (Exception e) {
+            if (columnMetaData.getProperty("read-only").isTrue()) {
+                return;
+            }
+            Object value = mapData.get(columnMetaData.getAlias());
+
+            if (value == null) {
                 return;
             }
+
             if (value instanceof Sql) {
-                appender.add(",", encodeColumn(dialect, columnMetaData.getName())
-                        , "=", ((Sql) value).getSql());
+                appender.add(",", encodeColumn(dialect, columnMetaData.getName()), "=", ((Sql) value).getSql());
             } else {
-                String typeHandler = columnMetaData.getProperty("typeHandler")
-                        .getValue();
+                value = columnMetaData.getValueConverter().getData(value);
+
+                if (columnMetaData.getOptionConverter() != null) {
+                    value = columnMetaData.getOptionConverter().converterData(value);
+                }
+
+                mapData.put(columnMetaData.getAlias(), value);
+
+                String typeHandler = columnMetaData.getProperty("typeHandler").getValue();
 
                 appender.add(",", encodeColumn(dialect, columnMetaData.getName())
                         , "=", "#{data.", columnMetaData.getAlias(),
@@ -303,15 +351,18 @@ public class EasyOrmSqlBuilder {
         QueryParam param = null;
         if (arg instanceof QueryParam) {
             param = ((QueryParam) arg);
+            if (param.isPaging()) {
+                if (Pager.get() == null) {
+                    Pager.doPaging(param.getPageIndex(), param.getPageSize());
+                }
+            } else {
+                Pager.reset();
+            }
         }
         if (param == null) {
             return "*";
         }
-        if (param.isPaging() && Pager.get() == null) {
-            Pager.doPaging(param.getPageIndex(), param.getPageSize());
-        } else {
-            Pager.reset();
-        }
+
         RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
         RDBDatabaseMetaData databaseMetaDate = getActiveDatabase();
         Dialect dialect = databaseMetaDate.getDialect();
@@ -401,6 +452,16 @@ public class EasyOrmSqlBuilder {
         } else {
             terms = new ArrayList<>();
         }
+        if (param instanceof QueryParam) {
+            QueryParam queryParam = ((QueryParam) param);
+            if (queryParam.isPaging()) {
+                if (Pager.get() == null) {
+                    Pager.doPaging(queryParam.getPageIndex(), queryParam.getPageSize());
+                }
+            } else {
+                Pager.reset();
+            }
+        }
         return buildWhere(resultMapId, tableName, terms);
     }
 
@@ -418,7 +479,7 @@ public class EasyOrmSqlBuilder {
         return appender.toString();
     }
 
-    class MysqlMeta extends MysqlRDBDatabaseMetaData {
+    static class MysqlMeta extends MysqlRDBDatabaseMetaData {
         MysqlMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -431,7 +492,7 @@ public class EasyOrmSqlBuilder {
         }
     }
 
-    class OracleMeta extends OracleRDBDatabaseMetaData {
+    static class OracleMeta extends OracleRDBDatabaseMetaData {
         OracleMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -444,7 +505,7 @@ public class EasyOrmSqlBuilder {
         }
     }
 
-    class H2Meta extends H2RDBDatabaseMetaData {
+    static class H2Meta extends H2RDBDatabaseMetaData {
         H2Meta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -457,7 +518,7 @@ public class EasyOrmSqlBuilder {
         }
     }
 
-    class PGMeta extends PGRDBDatabaseMetaData {
+    static class PGMeta extends PGRDBDatabaseMetaData {
         PGMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -470,7 +531,7 @@ public class EasyOrmSqlBuilder {
         }
     }
 
-    class MSSQLMeta extends MSSQLRDBDatabaseMetaData {
+    static class MSSQLMeta extends MSSQLRDBDatabaseMetaData {
         MSSQLMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());

+ 28 - 32
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParser.java

@@ -15,10 +15,7 @@ import org.hswebframework.web.dict.EnumDict;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.util.StringUtils;
 
-import javax.persistence.Column;
-import javax.persistence.Enumerated;
-import javax.persistence.Lob;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.beans.PropertyDescriptor;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
@@ -109,25 +106,31 @@ public class JpaAnnotationParser {
     }
 
 
-    public static RDBTableMetaData parseMetaDataFromEntity(Class entityClass) {
-        Table table = AnnotationUtils.findAnnotation(entityClass, Table.class);
-        if (table == null) {
-            return null;
-        }
-        RDBTableMetaData tableMetaData = new RDBTableMetaData();
-        tableMetaData.setName(table.name());
+    private static List<RDBColumnMetaData> parseColumnMeta(String prefix, String columnName, Class entityClass) {
 
         PropertyDescriptor[] descriptors = BeanUtilsBean.getInstance()
                 .getPropertyUtils()
                 .getPropertyDescriptors(entityClass);
+        List<RDBColumnMetaData> columnMetaDataList = new ArrayList<>();
+
         for (PropertyDescriptor descriptor : descriptors) {
             Column columnAnn = getAnnotation(entityClass, descriptor, Column.class);
+            CollectionTable collectionTable = getAnnotation(entityClass, descriptor, CollectionTable.class);
+
             if (columnAnn == null) {
+                if (collectionTable != null) {
+                    columnMetaDataList.addAll(parseColumnMeta(descriptor.getName(), collectionTable.name(), descriptor.getPropertyType()));
+                    continue;
+                }
                 continue;
             }
+
+            String realName = StringUtils.hasText(columnAnn.name()) ? columnAnn.name() : descriptor.getName();
+            String realAlias = StringUtils.hasText(prefix) ? prefix.concat(".").concat(descriptor.getName()) : descriptor.getName();
+
             RDBColumnMetaData column = new RDBColumnMetaData();
-            column.setName(columnAnn.name());
-            column.setAlias(descriptor.getName());
+            column.setName(StringUtils.hasText(columnName) ? columnName.concat(".").concat(realName) : realName);
+            column.setAlias(realAlias);
             column.setLength(columnAnn.length());
             column.setPrecision(columnAnn.precision());
             column.setJavaType(descriptor.getPropertyType());
@@ -151,26 +154,19 @@ public class JpaAnnotationParser {
                         .orElse(JDBCType.OTHER);
             }
             column.setJdbcType(type);
-            ValueConverter dateConvert = new DateTimeConverter("yyyy-MM-dd HH:mm:ss", column.getJavaType()) {
-                @Override
-                public Object getData(Object value) {
-                    if (value instanceof Number) {
-                        return new Date(((Number) value).longValue());
-                    }
-                    return super.getData(value);
-                }
-            };
-
-            if (column.getJdbcType() == JDBCType.DATE
-                    || column.getJdbcType() == JDBCType.TIMESTAMP) {
-                column.setValueConverter(dateConvert);
-            } else if (column.getJavaType() == boolean.class || column.getJavaType() == Boolean.class) {
-                column.setValueConverter(new BooleanValueConverter(column.getJdbcType()));
-            } else if (TypeUtils.isNumberType(column)) {
-                column.setValueConverter(new NumberValueConverter(column.getJavaType()));
-            }
-            tableMetaData.addColumn(column);
+            columnMetaDataList.add(column);
         }
+        return columnMetaDataList;
+    }
+
+    public static RDBTableMetaData parseMetaDataFromEntity(Class entityClass) {
+        Table table = AnnotationUtils.findAnnotation(entityClass, Table.class);
+        if (table == null) {
+            return null;
+        }
+        RDBTableMetaData tableMetaData = new RDBTableMetaData();
+        tableMetaData.setName(table.name());
+        parseColumnMeta(null, null, entityClass).forEach(tableMetaData::addColumn);
         return tableMetaData;
     }
 

+ 49 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/NumberBooleanTypeHandler.java

@@ -0,0 +1,49 @@
+package org.hswebframework.web.dao.mybatis.handler;
+
+import org.apache.ibatis.type.*;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@Alias("numberBooleanTypeHandler")
+@MappedTypes({Boolean.class})
+@MappedJdbcTypes({JdbcType.NUMERIC, JdbcType.BOOLEAN})
+public class NumberBooleanTypeHandler implements TypeHandler<Object> {
+    @Override
+    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
+        if (parameter == null) {
+            ps.setNull(i, jdbcType.TYPE_CODE);
+            return;
+        }
+        if(parameter instanceof Number){
+            if (jdbcType == JdbcType.BOOLEAN) {
+                ps.setBoolean(i, ((Number) parameter).intValue()==1);
+            }else{
+                ps.setInt(i,((Number) parameter).intValue());
+            }
+        }else{
+            if (jdbcType == JdbcType.BOOLEAN) {
+                ps.setBoolean(i, Boolean.TRUE.equals(parameter));
+            } else {
+                ps.setInt(i, Boolean.TRUE.equals(parameter) ? 1 : 0);
+            }
+        }
+    }
+
+    @Override
+    public Object getResult(ResultSet rs, String columnName) throws SQLException {
+        return rs.getBoolean(columnName);
+    }
+
+    @Override
+    public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.getBoolean(columnIndex);
+    }
+
+    @Override
+    public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.getBoolean(columnIndex);
+    }
+}

+ 3 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/TreeStructureSqlTermCustomizer.java

@@ -19,13 +19,14 @@ import java.util.stream.Collectors;
  */
 @Slf4j
 public abstract class TreeStructureSqlTermCustomizer extends AbstractSqlTermCustomizer {
-    boolean not = false;
+    protected boolean not;
 
-    boolean parent = false;
+    protected boolean parent;
 
     public TreeStructureSqlTermCustomizer(String termType, boolean not, boolean parent) {
         super(termType);
         this.not = not;
+        this.parent = parent;
     }
 
     protected abstract String getTableName();

+ 2 - 3
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/Pager.java

@@ -71,14 +71,13 @@ public interface Pager {
 
     static void rePaging(int total) {
         Pager pager = get();
-        int pageIndex = 0;
         if (pager != null) {
             // 当前页没有数据后跳转到最后一页
             if (pager.pageIndex() != 0 && (pager.pageIndex() * pager.pageSize()) >= total) {
                 int tmp = total / pager.pageSize();
-                pageIndex = total % pager.pageSize() == 0 ? tmp - 1 : tmp;
+                int pageIndex = total % pager.pageSize() == 0 ? tmp - 1 : tmp;
+                doPaging(pageIndex, pager.pageSize());
             }
-            doPaging(pageIndex, pager.pageSize());
         }
     }
 }

+ 8 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/PagerInterceptor.java

@@ -49,8 +49,14 @@ public class PagerInterceptor implements Interceptor {
             MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
             String sql = statementHandler.getBoundSql().getSql();
             Pager pager = Pager.getAndReset();
-            String newSql = sql;
-            if (sql.trim().toLowerCase().startsWith("select")) {
+
+            String lower = sql.trim();
+
+            if (lower.startsWith("select")) {
+                if (lower.contains("count(")) {
+                    return Plugin.wrap(target, this);
+                }
+                String newSql = sql;
                 if (pager != null) {
                     newSql = EasyOrmSqlBuilder.getInstance()
                             .getActiveDatabase().getDialect()

+ 4 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/NestEntity.java

@@ -2,6 +2,8 @@ package org.hswebframework.web.dao.crud;
 
 import lombok.Data;
 
+import javax.persistence.Column;
+
 /**
  *
  * @author zhouhao
@@ -9,5 +11,7 @@ import lombok.Data;
  */
 @Data
 public class NestEntity {
+
+    @Column
     private String name;
 }

+ 10 - 5
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestCrud.java

@@ -1,5 +1,6 @@
 package org.hswebframework.web.dao.crud;
 
+import lombok.SneakyThrows;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.hswebframework.ezorm.core.param.QueryParam;
 import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
@@ -53,12 +54,13 @@ public class TestCrud extends AbstractTransactionalJUnit4SpringContextTests {
                 ")");
         sqlExecutor.exec("\n" +
                 "create table h_nest_table(\n" +
-                "  id BIGINT AUTO_INCREMENT PRIMARY KEY,\n" +
+                "  id BIGINT PRIMARY KEY,\n" +
                 "  name VARCHAR(32)\n" +
                 ")");
     }
 
     @Test
+    @SneakyThrows
     public void testCRUD() {
 
         DataSourceHolder.databaseSwitcher().use("PUBLIC");
@@ -69,22 +71,25 @@ public class TestCrud extends AbstractTransactionalJUnit4SpringContextTests {
         entity.setDataTypes(new DataType[]{DataType.TYPE1, DataType.TYPE3});
         testDao.insert(entity);
         Assert.assertNotNull(entity.getId());
+        sqlExecutor.insert("insert into h_nest_table (id,name) values(#{id},'1234')",entity);
 
         QueryParamEntity query = new QueryParamEntity();
         //any in
         query.where("dataTypes$in$any", Arrays.asList(DataType.TYPE1, DataType.TYPE2));
 
         //#102
-        query.where("createTime", "2017-11-10");
+        //query.where("createTime", "2017-11-10");
 
-//        query.includes("nest.name", "*");
 
 //        DataSourceHolder.tableSwitcher().use("h_test", "h_test2");
         List<TestEntity> entities = testDao.queryNest(query);
-
+        query.includes("name");
+        testDao.count(query);
         testDao.query(query);
+
+        query.includes("nest.name", "*");
         testDao.countNest(query);
-        testDao.count(query);
+
         UpdateParamEntity.newUpdate()
                 .set("name","测试")
                 .set(entity::getDataType)

+ 4 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestEntity.java

@@ -44,6 +44,10 @@ public class TestEntity implements org.hswebframework.web.commons.entity.Entity
     )
     private DataType[] dataTypes;
 
+    @CollectionTable(name = "nest_table")
     private NestEntity nest;
 
+    @CollectionTable(name = "nest_table2")
+    private NestEntity nest2;
+
 }

+ 11 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/org/hswebframework/web/dao/test/TestDao.xml

@@ -10,7 +10,13 @@
 
     <resultMap id="TestNestResultMap" type="org.hswebframework.web.dao.crud.TestEntity">
         <id property="id" column="id" javaType="Long" jdbcType="INTEGER"/>
-        <result property="nest.name" column="nest_table.name" javaType="String" jdbcType="VARCHAR"/>
+<!--                <result property="nest2.name" column="nest_table2.name" javaType="String" jdbcType="VARCHAR"/>-->
+<!--        <association property="nest" javaType="org.hswebframework.web.dao.crud.NestEntity" columnPrefix="nest_table." column="nest_table">-->
+<!--            <result property="name" column="name" jdbcType="VARCHAR" javaType="String"/>-->
+<!--        </association>-->
+<!--        <association property="nest2" javaType="org.hswebframework.web.dao.crud.NestEntity" columnPrefix="nest_table2." column="nest_table2">-->
+<!--            <result property="name" column="name" jdbcType="VARCHAR" javaType="String"/>-->
+<!--        </association>-->
     </resultMap>
 
     <!--用于动态生成sql所需的配置-->
@@ -19,7 +25,8 @@
         <bind name="tableName" value="'h_test'"/>
     </sql>
 
-    <insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true" parameterType="org.hswebframework.web.dao.crud.TestEntity">
+    <insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true"
+            parameterType="org.hswebframework.web.dao.crud.TestEntity">
         <include refid="config"/>
         <include refid="BasicMapper.buildInsertSql"/>
     </insert>
@@ -52,6 +59,7 @@
         <include refid="BasicMapper.buildSelectField"/>
         from ${_fullTableName} h_test
         left join ${_databasePrefix}h_nest_table nest_table on nest_table.id=h_test.id
+        left join ${_databasePrefix}h_nest_table nest_table2 on nest_table2.id=h_test.id
         <where>
             <include refid="BasicMapper.buildWhere"/>
         </where>
@@ -65,6 +73,7 @@
         count(1)
         from ${_fullTableName} h_test
         left join ${_databasePrefix}h_nest_table nest_table on nest_table.id=h_test.id
+        left join ${_databasePrefix}h_nest_table nest_table2 on nest_table2.id=h_test.id
         <where>
             <include refid="BasicMapper.buildWhere"/>
         </where>

+ 1 - 1
hsweb-commons/hsweb-commons-dao/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-entity/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 87 - 51
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupportEntity.java

@@ -19,15 +19,16 @@
 package org.hswebframework.web.commons.entity;
 
 
-import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.utils.RandomUtil;
+import org.hswebframework.web.id.IDGenerator;
+import org.springframework.util.CollectionUtils;
 
-import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+@SuppressWarnings("all")
 public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
 
     String id = "id";
@@ -64,68 +65,103 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
     }
 
     static <T extends TreeSupportEntity> void forEach(Collection<T> list, Consumer<T> consumer) {
-        list.forEach(node -> {
+        Queue<T> queue = new LinkedList<>(list);
+        Set<Long> all = new HashSet<>();
+        for (T node = queue.poll(); node != null; node = queue.poll()) {
+            long hash = System.identityHashCode(node);
+            if (all.contains(hash)) {
+                continue;
+            }
+            all.add(hash);
             consumer.accept(node);
-            if (node.getChildren() != null) {
-                forEach(node.getChildren(), consumer);
+            if (!CollectionUtils.isEmpty(node.getChildren())) {
+                queue.addAll(node.getChildren());
             }
-        });
+        }
     }
 
     static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T parent, List<T> target, IDGenerator<PK> idGenerator) {
-        expandTree2List(parent,target,idGenerator,null);
+        expandTree2List(parent, target, idGenerator, null);
     }
-        /**
-         * 将树形结构转为列表结构,并填充对应的数据。<br>
-         * 如树结构数据: {name:'父节点',children:[{name:'子节点1'},{name:'子节点2'}]}<br>
-         * 解析后:[{id:'id1',name:'父节点',path:'<b>aoSt</b>'},{id:'id2',name:'子节点1',path:'<b>aoSt</b>-oS5a'},{id:'id3',name:'子节点2',path:'<b>aoSt</b>-uGpM'}]
-         *
-         * @param parent      树结构的根节点
-         * @param target      目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
-         * @param <T>         继承{@link TreeSupportEntity}的类型
-         * @param idGenerator ID生成策略
-         * @param <PK>        主键类型
-         */
-    static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T parent, List<T> target, IDGenerator<PK> idGenerator, BiConsumer<T, List<T>> childConsumer) {
 
-        List<T> children = parent.getChildren();
-        if(childConsumer!=null){
-            childConsumer.accept(parent,new ArrayList<>());
+
+    /**
+     * 将树形结构转为列表结构,并填充对应的数据。<br>
+     * 如树结构数据: {name:'父节点',children:[{name:'子节点1'},{name:'子节点2'}]}<br>
+     * 解析后:[{id:'id1',name:'父节点',path:'<b>aoSt</b>'},{id:'id2',name:'子节点1',path:'<b>aoSt</b>-oS5a'},{id:'id3',name:'子节点2',path:'<b>aoSt</b>-uGpM'}]
+     *
+     * @param root        树结构的根节点
+     * @param target      目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
+     * @param <T>         继承{@link TreeSupportEntity}的类型
+     * @param idGenerator ID生成策略
+     * @param <PK>        主键类型
+     */
+    static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T root, List<T> target, IDGenerator<PK> idGenerator, BiConsumer<T, List<T>> childConsumer) {
+
+        if (CollectionUtils.isEmpty(root.getChildren())) {
+            target.add(root);
+            return;
         }
-        target.add(parent);
-        if (parent.getPath() == null) {
-            parent.setPath(RandomUtil.randomChar(4));
-            if (parent.getPath() != null) {
-                parent.setLevel(parent.getPath().split("-").length);
-            }
-            if (parent instanceof SortSupportEntity) {
-                Long index = ((SortSupportEntity) parent).getSortIndex();
-                if (null == index) {
-                    ((SortSupportEntity) parent).setSortIndex(1L);
-                }
+
+        //尝试设置id
+        PK parentId = root.getId();
+        if (parentId == null) {
+            parentId = idGenerator.generate();
+            root.setId(parentId);
+        }
+        //尝试设置树路径path
+        if (root.getPath() == null) {
+            root.setPath(RandomUtil.randomChar(4));
+        }
+        if (root.getPath() != null) {
+            root.setLevel(root.getPath().split("[-]").length);
+        }
+        //尝试设置排序
+        if (root instanceof SortSupportEntity) {
+            SortSupportEntity sortableRoot = ((SortSupportEntity) root);
+            Long index = sortableRoot.getSortIndex();
+            if (null == index) {
+                sortableRoot.setSortIndex(1L);
             }
         }
-        if (children != null) {
-            PK pid = parent.getId();
-            if (pid == null) {
-                pid = idGenerator.generate();
-                parent.setId(pid);
+
+        //所有节点处理队列
+        Queue<T> queue = new LinkedList<>();
+        queue.add(root);
+        //已经处理过的节点过滤器
+        Set<Long> filter = new HashSet<>();
+
+        for (T parent = queue.poll(); parent != null; parent = queue.poll()) {
+            long hash = System.identityHashCode(parent);
+            if (filter.contains(hash)) {
+                continue;
             }
-            for (int i = 0; i < children.size(); i++) {
-                T child = children.get(i);
-                if (child instanceof SortSupportEntity && parent instanceof SortSupportEntity) {
-                    Long index = ((SortSupportEntity) parent).getSortIndex();
-                    if (null == index) {
-                        ((SortSupportEntity) parent).setSortIndex(index = 1L);
+            filter.add(hash);
+
+            //处理子节点
+            if (!CollectionUtils.isEmpty(parent.getChildren())) {
+                long index = 1;
+                for (TreeSupportEntity<PK> child : parent.getChildren()) {
+                    if (child.getId() == null) {
+                        child.setId(idGenerator.generate());
                     }
-                    ((SortSupportEntity) child).setSortIndex(new BigDecimal(index + "0" + (i + 1)).longValue());
+                    child.setParentId(parent.getId());
+                    child.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
+                    child.setLevel(child.getPath().split("[-]").length);
+
+                    //子节点排序
+                    if (child instanceof SortSupportEntity && parent instanceof SortSupportEntity) {
+                        SortSupportEntity sortableParent = ((SortSupportEntity) parent);
+                        SortSupportEntity sortableChild = ((SortSupportEntity) child);
+                        sortableChild.setSortIndex(sortableParent.getSortIndex() * 100 + index++);
+                    }
+                    queue.add((T) child);
                 }
-                child.setParentId(pid);
-                child.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
-                child.setLevel(child.getPath().split("-").length);
-
-                expandTree2List(child, target, idGenerator,childConsumer);
             }
+            if (childConsumer != null) {
+                childConsumer.accept(parent, new ArrayList<>());
+            }
+            target.add(parent);
         }
     }
 
@@ -165,7 +201,7 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
         Objects.requireNonNull(childConsumer, "child consumer can not be null");
         Objects.requireNonNull(predicateFunction, "root predicate function can not be null");
 
-        Supplier<Stream<N>> streamSupplier = () -> dataList.size() < 1000 ? dataList.stream() : dataList.parallelStream();
+        Supplier<Stream<N>> streamSupplier = () -> dataList.size() < 50000 ? dataList.stream() : dataList.parallelStream();
         // id,node
         Map<PK, N> cache = new HashMap<>();
         // parentId,children

+ 32 - 5
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/param/TermExpressionParser.java

@@ -19,19 +19,37 @@ public class TermExpressionParser {
 
         NestConditional<?> nest = null;
 
+        // 字符容器
         char[] buf = new char[128];
+        // 记录词项的长度, Arrays.copyOf使用
         byte len = 0;
+        // 空格数量?
         byte spaceLen = 0;
-
+        // 当前列
         char[] currentColumn = null;
-
-        String currentTermType = null;
+        // 当前列对应的值
         char[] currentValue = null;
-        char[] all = expression.toCharArray();
+        // 当前条件类型 eq btw in ...
+        String currentTermType = null;
+        // 当前链接类型 and / or
         String currentType = "and";
+        // 是否是引号, 单引号 / 双引号
+        byte quotationMarks = 0;
+        // 表达式字符数组
+        char[] all = expression.toCharArray();
+
         for (char c : all) {
 
-            if (c == '(') {
+            if (c == '\'' || c == '"') {
+                if (quotationMarks != 0) {
+                    // 碰到(结束的)单/双引号, 标志归零, 跳过
+                    quotationMarks = 0;
+                    continue;
+                }
+                // 碰到(开始的)单/双引号, 做记录, 跳过
+                quotationMarks++;
+                continue;
+            } else if (c == '(') {
                 nest = (nest == null ?
                         (currentType.equals("or") ? conditional.orNest() : conditional.nest()) :
                         (currentType.equals("or") ? nest.orNest() : nest.nest()));
@@ -70,6 +88,11 @@ public class TermExpressionParser {
                 if (len == 0) {
                     continue;
                 }
+                if (quotationMarks != 0) {
+                    // 如果当前字符是空格,并且前面迭代时碰到过单/双引号, 不处理并且添加到buf中
+                    buf[len++] = c;
+                    continue;
+                }
                 spaceLen++;
                 if (currentColumn == null && (spaceLen == 1 || spaceLen % 5 == 0)) {
                     currentColumn = Arrays.copyOf(buf, len);
@@ -117,6 +140,10 @@ public class TermExpressionParser {
                         len = 0;
                         spaceLen++;
                     }
+                } else {
+                    currentColumn = Arrays.copyOf(buf, len);
+                    len = 0;
+                    spaceLen++;
                 }
                 continue;
             }

+ 8 - 3
hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/TreeSupportEntityTests.java

@@ -2,19 +2,18 @@ package org.hswebframework.web.commons.entity;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import org.hswebframework.web.id.IDGenerator;
 import org.junit.Assert;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Predicate;
 
-import static org.junit.Assert.*;
-
 public class TreeSupportEntityTests {
 
+
     @Test
     public void test() {
         MenuEntity parent = MenuEntity.builder().build();
@@ -48,6 +47,12 @@ public class TreeSupportEntityTests {
 
         System.out.println(JSON.toJSONString(tree, SerializerFeature.PrettyFormat));
 
+        LongAdder adder=new LongAdder();
+        TreeSupportEntity.forEach(tree,menu->{
+            adder.increment();
+        });
+        Assert.assertEquals(adder.intValue(),4);
+
         List<MenuEntity> list = new ArrayList<>();
 
         //将树形结构展平为list

+ 24 - 0
hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/param/TermExpressionParserTest.java

@@ -51,7 +51,31 @@ public class TermExpressionParserTest {
         Assert.assertEquals(terms.get(2).getValue(), "test2");
         Assert.assertEquals(terms.get(2).getTermType(), "like");
 
+    }
+
+    /**
+     * 测试日期字符串空格解析,'2019-07-26 12:00:00'
+     */
+    @Test
+    public void testDateSpace() {
+        String expression = "(name=测试 or age=10) and (birth btw \"2019-07-26 12:00:00, 2019-08-04 12:00:00\" or startTime <= '2019-08-04 12:00:00') and finishTime >= '2019-08-01 00:00:00'";
+        List<Term> terms = TermExpressionParser.parse(expression);
+        System.out.println(JSON.toJSONString(terms, SerializerFeature.PrettyFormat));
+
+        Assert.assertEquals(terms.size(), 3);
+        Assert.assertEquals(terms.get(0).getTerms().size(), 2);
+
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getColumn(), "birth");
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getTermType(), "btw");
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getValue(), "2019-07-26 12:00:00, 2019-08-04 12:00:00");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getColumn(), "startTime");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getTermType(), "lte");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getValue(), "2019-08-04 12:00:00");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getType(), Term.Type.or);
 
+        Assert.assertEquals(terms.get(2).getColumn(), "finishTime");
+        Assert.assertEquals(terms.get(2).getValue(), "2019-08-01 00:00:00");
+        Assert.assertEquals(terms.get(2).getTermType(), "gte");
     }
 
 }

+ 1 - 1
hsweb-commons/hsweb-commons-model/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons-service</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-oauth2/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-commons-service</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 1 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons-service</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
 
     </parent>

+ 1 - 1
hsweb-commons/hsweb-commons-service/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 1 - 1
hsweb-commons/hsweb-commons-utils/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-commons</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java

@@ -48,7 +48,7 @@ public final class ThreadLocalUtils {
      * @return threadLocal中的全部值
      */
     public static Map<String, Object> getAll() {
-        return local.get();
+        return new HashMap<>(local.get());
     }
 
     /**

+ 1 - 1
hsweb-commons/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-async-job/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-cache/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-concurrent</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-concurrent-counter</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-redis/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-counter</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-counter/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-concurrent</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-lock</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-redis/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-lock</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-lock</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-lock/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-concurrent</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-rate-limiter/hsweb-concurrent-rate-limiter-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-rate-limiter</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-rate-limiter/hsweb-concurrent-rate-limiter-starter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent-rate-limiter</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/hsweb-concurrent-rate-limiter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-concurrent</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-concurrent/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-core/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 19 - 6
hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java

@@ -14,6 +14,7 @@ import org.springframework.util.ClassUtils;
 import org.springframework.util.ReflectionUtils;
 
 import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.util.*;
 import java.util.function.BiFunction;
@@ -141,8 +142,8 @@ public final class FastBeanCopier {
         String method = "public void copy(Object s, Object t, java.util.Set ignore, " +
                 "org.hswebframework.web.bean.Converter converter){\n" +
                 "try{\n\t" +
-                sourceName + " source=(" + sourceName + ")s;\n\t" +
-                tartName + " target=(" + tartName + ")t;\n\t" +
+                sourceName + " $$__source=(" + sourceName + ")s;\n\t" +
+                tartName + " $$__target=(" + tartName + ")t;\n\t" +
                 createCopierCode(source, target) +
                 "}catch(Exception e){\n" +
                 "\tthrow new RuntimeException(e.getMessage(),e);" +
@@ -211,7 +212,7 @@ public final class FastBeanCopier {
             }
             code.append("if(!ignore.contains(\"").append(sourceProperty.getName()).append("\")){\n\t");
             if (!sourceProperty.isPrimitive()) {
-                code.append("if(source.").append(sourceProperty.getReadMethod()).append("!=null){\n");
+                code.append("if($$__source.").append(sourceProperty.getReadMethod()).append("!=null){\n");
             }
             code.append(targetProperty.generateVar(targetProperty.getName())).append("=")
                     .append(sourceProperty.generateGetter(target, targetProperty.getType()))
@@ -220,7 +221,7 @@ public final class FastBeanCopier {
             if (!targetProperty.isPrimitive()) {
                 code.append("\tif(").append(sourceProperty.getName()).append("!=null){\n");
             }
-            code.append("\ttarget.").append(targetProperty.generateSetter(targetProperty.getType(), sourceProperty.getName())).append(";\n");
+            code.append("\t$$__target.").append(targetProperty.generateSetter(targetProperty.getType(), sourceProperty.getName())).append(";\n");
             if (!targetProperty.isPrimitive()) {
                 code.append("\t}\n");
             }
@@ -310,7 +311,7 @@ public final class FastBeanCopier {
         public BiFunction<Class, Class, String> createGetterFunction() {
 
             return (targetBeanType, targetType) -> {
-                String getterCode = "source." + getReadMethod();
+                String getterCode = "$$__source." + getReadMethod();
 
                 String generic = "org.hswebframework.web.bean.FastBeanCopier.EMPTY_CLASS_ARRAY";
                 Field field = ReflectionUtils.findField(targetBeanType, name);
@@ -540,7 +541,11 @@ public final class FastBeanCopier {
 
             if (targetClass.isEnum()) {
                 if (EnumDict.class.isAssignableFrom(targetClass)) {
-                    Object val = EnumDict.find((Class) targetClass, String.valueOf(source)).orElse(null);
+                    String strVal=String.valueOf(source);
+
+                    Object val = EnumDict.find((Class) targetClass, e -> {
+                        return e.eq(source) || e.name().equalsIgnoreCase(strVal);
+                    }).orElse(null);
                     if (targetClass.isInstance(val)) {
                         return ((T) val);
                     }
@@ -551,9 +556,17 @@ public final class FastBeanCopier {
                         return t;
                     }
                 }
+
                 log.warn("无法将:{}转为枚举:{}", source, targetClass);
                 return null;
             }
+            //转换为数组
+            if (targetClass.isArray()) {
+                Class<?> componentType = targetClass.getComponentType();
+                List<?> val = convert(source, List.class, new Class[]{componentType});
+                return (T) val.toArray((Object[])Array.newInstance(componentType,val.size()));
+            }
+
             try {
                 org.apache.commons.beanutils.Converter converter = BeanUtilsBean
                         .getInstance()

+ 18 - 25
hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java

@@ -1,9 +1,11 @@
 package org.hswebframework.web.bean;
 
 import org.apache.commons.beanutils.BeanUtils;
+import org.junit.Assert;
 import org.junit.Test;
 
 import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -35,35 +37,26 @@ public class FastBeanCopierTest {
         FastBeanCopier.copy(source, target);
 
 
-        long t = System.currentTimeMillis();
-//        for (int i = 10_0000; i > 0; i--) {
-//            FastBeanCopier.copy(source, target);
-//        }
-        System.out.println(System.currentTimeMillis() - t);
-
         System.out.println(source);
         System.out.println(target);
         System.out.println(target.getNestObject() == source.getNestObject());
-//        Source source1=new Source();
-
-//        FastBeanCopier.copy(source,source1);
-
-//        System.out.println(source1);
-//
-//        t = System.currentTimeMillis();
-//
-//        for (int i = 100_0000; i > 0; i--) {
-//            try {
-//                BeanUtils.copyProperties(source, target);
-//            } catch (Exception e) {
-//                e.printStackTrace();
-//            }
-//        }
-//        System.out.println(System.currentTimeMillis() - t);
-//        System.out.println(target);
-//        System.out.println(target.getNestObject() == source.getNestObject());
     }
 
+    @Test
+    public void testMapArray() {
+       Map<String,Object> data =new HashMap<>();
+       data.put("colors", Arrays.asList("RED"));
+
+
+        Target target = new Target();
+        FastBeanCopier.copy(data, target);
+
+
+        System.out.println(target);
+        Assert.assertNotNull(target.getColors());
+        Assert.assertSame(target.getColors()[0], Color.RED);
+
+    }
 
     @Test
     public void testCopyMap() {
@@ -85,7 +78,7 @@ public class FastBeanCopierTest {
         System.out.println(FastBeanCopier.copy(source, target, FastBeanCopier.include("age")));
 
         System.out.println(target);
-        System.out.println(FastBeanCopier.copy(target, new Source()));
+        System.out.println(FastBeanCopier.copy(target, new Target()));
     }
 
 

+ 5 - 0
hsweb-core/src/test/java/org/hswebframework/web/bean/Source.java

@@ -55,6 +55,11 @@ public class Source {
 
     private String[] arr6 = {"1", "2"};
 
+    private Color[] colors ={Color.BLUE,Color.RED};
+
+    private String source;
+
+    private String target;
 
 }
 

+ 2 - 0
hsweb-core/src/test/java/org/hswebframework/web/bean/Target.java

@@ -64,6 +64,8 @@ public class Target {
 
     private Integer[] arr4;
 
+    private Color[] colors;
+
 
     @Override
     public String toString() {

+ 1 - 1
hsweb-datasource/hsweb-datasource-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-datasource</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 8 - 4
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DefaultDataSourceSwitcher.java

@@ -18,9 +18,13 @@ public class DefaultDataSourceSwitcher implements DataSourceSwitcher {
     //默认数据源标识
     private static final String DEFAULT_DATASOURCE_ID = DataSourceSwitcher.class.getName() + "_default_";
 
-    private Logger logger = LoggerFactory.getLogger(this.getClass());
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    private Deque<String> getUsedHistoryQueue() {
+    protected String getDefaultDataSourceIdKey(){
+        return DEFAULT_DATASOURCE_ID;
+    }
+
+    protected Deque<String> getUsedHistoryQueue() {
         // 从ThreadLocal中获取一个使用记录
         return ThreadLocalUtils.get(DefaultDataSourceSwitcher.class.getName() + "_queue", LinkedList::new);
     }
@@ -54,7 +58,7 @@ public class DefaultDataSourceSwitcher implements DataSourceSwitcher {
 
     @Override
     public void useDefault() {
-        getUsedHistoryQueue().addLast(DEFAULT_DATASOURCE_ID);
+        getUsedHistoryQueue().addLast(getDefaultDataSourceIdKey());
         if (logger.isDebugEnabled()) {
             logger.debug("try use default datasource");
         }
@@ -67,7 +71,7 @@ public class DefaultDataSourceSwitcher implements DataSourceSwitcher {
         }
 
         String activeId = getUsedHistoryQueue().getLast();
-        if (DEFAULT_DATASOURCE_ID.equals(activeId)) {
+        if (getDefaultDataSourceIdKey().equals(activeId)) {
             return null;
         }
         return activeId;

+ 8 - 4
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DefaultDatabaseSwitcher.java

@@ -18,9 +18,13 @@ public class DefaultDatabaseSwitcher implements DatabaseSwitcher {
     //默认数据源标识
     private static final String DEFAULT_DATASOURCE_ID = DatabaseSwitcher.class.getName() + "_default_";
 
-    private Logger logger = LoggerFactory.getLogger(this.getClass());
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    private Deque<String> getUsedHistoryQueue() {
+    protected String getDefaultDataSourceIdKey(){
+        return DEFAULT_DATASOURCE_ID;
+    }
+
+    protected Deque<String> getUsedHistoryQueue() {
         // 从ThreadLocal中获取一个使用记录
         return ThreadLocalUtils.get(DefaultDatabaseSwitcher.class.getName() + "_queue", LinkedList::new);
     }
@@ -54,7 +58,7 @@ public class DefaultDatabaseSwitcher implements DatabaseSwitcher {
 
     @Override
     public void useDefault() {
-        getUsedHistoryQueue().addLast(DEFAULT_DATASOURCE_ID);
+        getUsedHistoryQueue().addLast(getDefaultDataSourceIdKey());
         if (logger.isDebugEnabled()) {
             logger.debug("try use default database");
         }
@@ -67,7 +71,7 @@ public class DefaultDatabaseSwitcher implements DatabaseSwitcher {
         }
 
         String activeId = getUsedHistoryQueue().getLast();
-        if (DEFAULT_DATASOURCE_ID.equals(activeId)) {
+        if (getDefaultDataSourceIdKey().equals(activeId)) {
             return null;
         }
         return activeId;

+ 1 - 1
hsweb-datasource/hsweb-datasource-jta/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-datasource</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
 
     </parent>

+ 1 - 1
hsweb-datasource/hsweb-datasource-web/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-datasource</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 1 - 1
hsweb-datasource/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 1 - 1
hsweb-logging/hsweb-access-logging-aop/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-logging</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-logging/hsweb-access-logging-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-logging</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-logging/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 7 - 5
hsweb-starter/hsweb-spring-boot-starter/README.md

@@ -15,11 +15,13 @@ hsweb:
 hsweb: 
     cors:
       enable: true
-      allowed-headers: "*"
-      allowed-methods: "*"
-      allowed-origins: "*"
-      allow-credentials: true
-      max-age: 14400
+      configs:
+        - /**:
+            allowed-headers: "*"
+            allowed-methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
+            allowed-origins: ["http://xxx.example.com"]
+            allow-credentials: true
+            maxAge: 1800
 ```
 
 # json序列化配置

+ 1 - 1
hsweb-starter/hsweb-spring-boot-starter/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-starter</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 11 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemInitializeAutoConfiguration.java

@@ -30,6 +30,7 @@ import org.hswebframework.web.ScriptScope;
 import org.hswebframework.web.datasource.DataSourceHolder;
 import org.hswebframework.web.datasource.DatabaseType;
 import org.hswebframework.web.service.Service;
+import org.hswebframework.web.starter.event.SystemInitializeEvent;
 import org.hswebframework.web.starter.init.SystemInitialize;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,6 +38,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.AnnotationUtils;
@@ -75,6 +77,9 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
     @Autowired
     private ApplicationContext applicationContext;
 
+    @Autowired
+    private ApplicationEventPublisher eventPublisher;
+
     private List<DynamicScriptEngine> engines;
 
     @Autowired
@@ -158,6 +163,12 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
 
         SimpleDatabase database = new SimpleDatabase(metaData, sqlExecutor);
         database.setAutoParse(true);
+
+        SystemInitializeEvent event = new SystemInitializeEvent(database);
+        eventPublisher.publishEvent(event);
+        if (event.isIgnore()) {
+            return;
+        }
         SystemInitialize initialize = new SystemInitialize(sqlExecutor, database, version);
 
         initialize.addScriptContext("db", jdbcUserName);

+ 21 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/event/SystemInitializeEvent.java

@@ -0,0 +1,21 @@
+package org.hswebframework.web.starter.event;
+
+import lombok.Getter;
+import org.hswebframework.ezorm.rdb.RDBDatabase;
+
+@Getter
+public class SystemInitializeEvent {
+
+    public SystemInitializeEvent(RDBDatabase database){
+        this.database=database;
+    }
+
+    private RDBDatabase database;
+
+    private boolean ignore;
+
+    public void setIgnore(boolean ignore) {
+        this.ignore = ignore;
+    }
+
+}

+ 1 - 1
hsweb-starter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-framework</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 3 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/ActionEntity.java

@@ -6,6 +6,7 @@ import org.springframework.util.StringUtils;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 @Getter
@@ -22,6 +23,8 @@ public class ActionEntity implements CloneableEntity {
 
     private boolean defaultCheck;
 
+    private Map<String,Object> properties;
+
     public ActionEntity(String action) {
         this.action = action;
     }

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/AuthorizationSettingEntity.java

@@ -32,7 +32,7 @@ public interface AuthorizationSettingEntity extends GenericEntity<String> {
     |                属性名常量                |
     ===========================================*/
     /**
-     * 设置类型,如: role
+     * 设置类型(维度),如: role
      *
      * @see org.hswebframework.web.service.authorization.AuthorizationSettingTypeSupplier
      */

+ 26 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingService.java

@@ -41,6 +41,32 @@ public interface AuthorizationSettingService extends CrudService<AuthorizationSe
      */
     AuthorizationSettingEntity select(String type, String settingFor);
 
+    /**
+     * 根据权限ID获取所有维度的权限设置,{@link AuthorizationSettingEntity#getDetails()}中只包含对应权限的信息,不会包含全部信息
+     *
+     * @param permissionId 权限ID
+     * @return 配置了权限的全部权限设置信息
+     * @since 3.0.9
+     */
+    List<AuthorizationSettingEntity> selectByPermissionId(String permissionId);
+
+    /**
+     * 合并保存权限信息,如果权限信息不存在则新增,如果已存在,则合并,而不是覆盖
+     *
+     * @param settings 权限信息集合
+     * @since 3.0.9
+     */
+    void mergeSetting(List<AuthorizationSettingEntity> settings);
+
+    /**
+     * 删除权限设置的单个权限
+     *
+     * @param settingId    权限设置ID
+     * @param permissionId 权限ID
+     * @since 3.0.9
+     */
+    void deleteDetail(String settingId, String permissionId);
+
     /**
      * 根据类型和被设置者初始化对应的权限信息
      *

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 102 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java

@@ -22,18 +22,24 @@ import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationInitializeService;
 import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
+import org.hswebframework.web.authorization.listener.event.AuthorizationInitializeEvent;
 import org.hswebframework.web.authorization.simple.SimpleAuthentication;
 import org.hswebframework.web.authorization.simple.SimplePermission;
 import org.hswebframework.web.authorization.simple.SimpleRole;
 import org.hswebframework.web.authorization.simple.SimpleUser;
+import org.hswebframework.web.bean.FastBeanCopier;
 import org.hswebframework.web.commons.entity.DataStatus;
+import org.hswebframework.web.commons.entity.QueryEntity;
 import org.hswebframework.web.commons.entity.TreeSupportEntity;
+import org.hswebframework.web.commons.entity.factory.EntityFactory;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.dao.authorization.AuthorizationSettingDao;
 import org.hswebframework.web.dao.authorization.AuthorizationSettingDetailDao;
 import org.hswebframework.web.entity.authorization.*;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.DefaultDSLDeleteService;
 import org.hswebframework.web.service.DefaultDSLQueryService;
+import org.hswebframework.web.service.DefaultDSLUpdateService;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.authorization.*;
 import org.hswebframework.web.service.authorization.AuthorizationSettingTypeSupplier.SettingInfo;
@@ -44,6 +50,7 @@ import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.cache.annotation.Caching;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.event.TransactionalEventListener;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
@@ -54,12 +61,14 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import static java.util.Optional.*;
 import static org.apache.commons.collections.CollectionUtils.isEmpty;
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
 import static org.hswebframework.web.commons.entity.DataStatus.STATUS_ENABLED;
 import static org.hswebframework.web.entity.authorization.AuthorizationSettingDetailEntity.*;
 import static org.hswebframework.web.entity.authorization.AuthorizationSettingEntity.settingFor;
 import static org.hswebframework.web.entity.authorization.AuthorizationSettingEntity.type;
+import static org.hswebframework.web.service.DefaultDSLDeleteService.*;
 import static org.hswebframework.web.service.authorization.simple.CacheConstants.USER_AUTH_CACHE_NAME;
 import static org.hswebframework.web.service.authorization.simple.CacheConstants.USER_MENU_CACHE_NAME;
 
@@ -181,6 +190,98 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
         return super.deleteByPk(id);
     }
 
+    @Override
+    @CacheEvict(cacheNames = {CacheConstants.USER_AUTH_CACHE_NAME, CacheConstants.USER_MENU_CACHE_NAME}, allEntries = true)
+    public void deleteDetail(String settingId, String permissionId) {
+
+        DefaultDSLDeleteService.createDelete(authorizationSettingDetailDao)
+                .where(AuthorizationSettingDetailEntity.settingId, settingId)
+                .and(AuthorizationSettingDetailEntity.permissionId, permissionId)
+                .exec();
+    }
+
+    @Override
+    @CacheEvict(cacheNames = {CacheConstants.USER_AUTH_CACHE_NAME, CacheConstants.USER_MENU_CACHE_NAME}, allEntries = true)
+    public void mergeSetting(List<AuthorizationSettingEntity> settings) {
+        for (AuthorizationSettingEntity setting : settings) {
+            AuthorizationSettingEntity old = select(setting.getType(), setting.getSettingFor());
+            if (old == null) {
+                setting.setStatus(STATUS_ENABLED);
+                insert(setting);
+                continue;
+            }
+            setting.setId(old.getId());
+            if (!CollectionUtils.isEmpty(setting.getDetails())) {
+                for (AuthorizationSettingDetailEntity detail : setting.getDetails()) {
+                    detail.setSettingId(setting.getId());
+                    //删除权限信息
+                    if (Byte.valueOf((byte) -100).equals(detail.getStatus())) {
+                        DefaultDSLDeleteService.createDelete(authorizationSettingDetailDao)
+                                .where(detail::getSettingId)
+                                .and(detail::getPermissionId)
+                                .exec();
+                        continue;
+                    }
+                    int i = DefaultDSLUpdateService
+                            .createUpdate(authorizationSettingDetailDao, detail)
+                            .where(detail::getSettingId)
+                            .and(detail::getPermissionId)
+                            .exec();
+                    if (i == 0) {
+                        detail.setStatus(STATUS_ENABLED);
+                        detail.setId(IDGenerator.MD5.generate());
+                        authorizationSettingDetailDao.insert(detail);
+                    }
+                }
+            }
+            if (!CollectionUtils.isEmpty(setting.getMenus())) {
+                Set<String> menus = old.getMenus().stream()
+                        .map(AuthorizationSettingMenuEntity::getMenuId)
+                        .collect(Collectors.toSet());
+                for (AuthorizationSettingMenuEntity menu : setting.getMenus()) {
+                    menu.setSettingId(setting.getId());
+                    if (menus.contains(menu.getMenuId())) {
+                        continue;
+                    }
+                    menu.setStatus(STATUS_ENABLED);
+                    menus.add(menu.getMenuId());
+                    authorizationSettingMenuService.saveOrUpdate(menu);
+                }
+            }
+        }
+    }
+
+    @Transactional(readOnly = true)
+    public List<AuthorizationSettingEntity> selectByPermissionId(String permissionId) {
+        List<AuthorizationSettingDetailEntity> detailEntities = DefaultDSLQueryService
+                .createQuery(authorizationSettingDetailDao)
+                .where(AuthorizationSettingDetailEntity::getPermissionId, permissionId)
+                .listNoPaging();
+
+        if (CollectionUtils.isEmpty(detailEntities)) {
+            return new ArrayList<>();
+        }
+
+        List<String> settingIdList = detailEntities
+                .stream()
+                .map(AuthorizationSettingDetailEntity::getSettingId)
+                .collect(Collectors.toList());
+
+        List<AuthorizationSettingEntity> allSettings = selectByPk(settingIdList)
+                .stream()
+                //复制为新对象,防止加载一些没用的信息
+                .map(entity -> FastBeanCopier.copy(entity, entityFactory.newInstance(AuthorizationSettingEntity.class), "details", "menus"))
+                .collect(Collectors.toList());
+
+        Map<String, List<AuthorizationSettingDetailEntity>> details = detailEntities.stream()
+                .collect(Collectors.groupingBy(AuthorizationSettingDetailEntity::getSettingId));
+
+        for (AuthorizationSettingEntity allSetting : allSettings) {
+            ofNullable(details.get(allSetting.getId())).ifPresent(allSetting::setDetails);
+        }
+
+        return allSettings;
+    }
 
     private List<AuthorizationSettingEntity> getUserSetting(String userId) {
         Map<String, List<SettingInfo>> settingInfo =
@@ -340,7 +441,7 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
                 .listNoPaging();
 
         authentication.setPermissions(initPermission(detailList));
-
+        eventPublisher.publishEvent(new AuthorizationInitializeEvent(authentication));
         return authentication;
     }
 

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml

@@ -22,7 +22,7 @@
     <parent>
         <artifactId>hsweb-system-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-authorization</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 31 - 9
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/AuthorizationSettingController.java

@@ -1,18 +1,18 @@
 /*
  *  Copyright 2019 http://www.hswebframework.org
- *  
+ *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  You may obtain a copy of the License at
  *
  *        http://www.apache.org/licenses/LICENSE-2.0
- *  
+ *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
- *  
+ *
  */
 
 package org.hswebframework.web.authorization.controller;
@@ -27,10 +27,9 @@ import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.entity.authorization.AuthorizationSettingEntity;
 import org.hswebframework.web.service.authorization.AuthorizationSettingService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 权限设置
@@ -39,8 +38,8 @@ import org.springframework.web.bind.annotation.RestController;
  */
 @RestController
 @RequestMapping("${hsweb.web.mappings.autz-setting:autz-setting}")
-@Authorize(permission = "autz-setting",description = "权限设置")
-@Api(tags = "权限-权限设置",value = "权限设置")
+@Authorize(permission = "autz-setting", description = "权限设置")
+@Api(tags = "权限-权限设置", value = "权限设置")
 public class AuthorizationSettingController implements SimpleGenericEntityController<AuthorizationSettingEntity, String, QueryParamEntity> {
 
     private AuthorizationSettingService authorizationSettingService;
@@ -61,4 +60,27 @@ public class AuthorizationSettingController implements SimpleGenericEntityContro
     public ResponseMessage<AuthorizationSettingEntity> select(@PathVariable String type, @PathVariable String settingFor) {
         return ResponseMessage.ok(authorizationSettingService.select(type, settingFor));
     }
+
+    @GetMapping("/permission/{permissionId}")
+    @Authorize(action = Permission.ACTION_GET)
+    @ApiOperation("根据权限ID获取对应的权限配置信息")
+    public ResponseMessage<List<AuthorizationSettingEntity>> selectByPermissionId(@PathVariable String permissionId) {
+        return ResponseMessage.ok(authorizationSettingService.selectByPermissionId(permissionId));
+    }
+
+    @PutMapping("/merge")
+    @Authorize(action = Permission.ACTION_UPDATE)
+    @ApiOperation("合并权限信息")
+    public ResponseMessage<Void> mergeSetting(@RequestBody List<AuthorizationSettingEntity> list) {
+        authorizationSettingService.mergeSetting(list);
+        return ResponseMessage.ok();
+    }
+
+    @DeleteMapping("/{settingId}/{permissionId}")
+    @Authorize(action = Permission.ACTION_UPDATE)
+    @ApiOperation("删除单个权限配置详情")
+    public ResponseMessage<Void> deleteDetail(@PathVariable String settingId, @PathVariable String permissionId) {
+        authorizationSettingService.deleteDetail(settingId, permissionId);
+        return ResponseMessage.ok();
+    }
 }

+ 1 - 1
hsweb-system/hsweb-system-authorization/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-config/hsweb-system-config-api/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-system-config</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
 
         <relativePath>../pom.xml</relativePath>
     </parent>

+ 1 - 1
hsweb-system/hsweb-system-config/hsweb-system-config-local/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-system-config</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-system/hsweb-system-config/hsweb-system-config-starter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-config</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-system/hsweb-system-config/hsweb-system-config-web/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-system-config</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

+ 1 - 1
hsweb-system/hsweb-system-config/pom.xml

@@ -23,7 +23,7 @@
     <parent>
         <artifactId>hsweb-system</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-dashboard</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-local/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-dashboard</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-starter/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-dashboard</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-dashboard/hsweb-system-dashboard-web/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-dashboard</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-dashboard/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-database-manager</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-local/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>hsweb-system-database-manager</artifactId>
         <groupId>org.hswebframework.web</groupId>
-        <version>3.0.8</version>
+        <version>3.0.9</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 0 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-starter/pom.xml


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä