From 197a03ea2d5e38496d5495ee8bc0d4e127f233cf Mon Sep 17 00:00:00 2001
From: ludc
Date: 星期一, 08 四月 2024 11:31:43 +0800
Subject: [PATCH] 工具类添加

---
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java       |   57 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java                        | 2144 +++++++++++++++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java                  |   99 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java            |  705 +++++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java              |  161 +
 Source/platformProject/vci-platform-web/pom.xml                                                         |  401 +-
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java                    |   60 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java                  |   30 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java                    |  383 ++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java |    3 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java                  |  115 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java |   35 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java                  |   71 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java                  |  433 +++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java                  |   21 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java   |    1 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java                      |  109 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java                  |  195 +
 Source/platformProject/pom.xml                                                                          |    2 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java               |  501 +++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java                      |   22 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java        |   87 
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java                |  226 +
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java                  | 1560 +++++++++++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java                    |  634 ++++
 Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java                    |   58 
 26 files changed, 7,916 insertions(+), 197 deletions(-)

diff --git a/Source/platformProject/pom.xml b/Source/platformProject/pom.xml
index 8a37391..b5e7b23 100644
--- a/Source/platformProject/pom.xml
+++ b/Source/platformProject/pom.xml
@@ -20,6 +20,8 @@
         <old.spring.version>3.2.0.RELEASE</old.spring.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <java.version>1.8</java.version>
+        <lombok.version>1.18.22</lombok.version>
+        <jackson.version>2.13.3</jackson.version>
     </properties>
 
     <!-- <distributionManagement>
diff --git a/Source/platformProject/vci-platform-web/pom.xml b/Source/platformProject/vci-platform-web/pom.xml
index 2923196..7043531 100644
--- a/Source/platformProject/vci-platform-web/pom.xml
+++ b/Source/platformProject/vci-platform-web/pom.xml
@@ -12,183 +12,192 @@
     <artifactId>vci-platform-web</artifactId>
 
     <dependencies>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-starter-parent</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <type>pom</type>
-       </dependency>
-       <dependency>
-           <groupId>com.vci.corba</groupId>
-           <artifactId>plt-slice</artifactId>
-           <version>1.0.RELEASE</version>
-       </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-starter-parent</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>com.vci.corba</groupId>
+            <artifactId>plt-slice</artifactId>
+            <version>1.0.RELEASE</version>
+        </dependency>
 
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-starter-web</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-               <exclusion>
-                   <groupId>org.apache.logging.log4j</groupId>
-                   <artifactId>*</artifactId>
-               </exclusion>
-               <exclusion>
-                   <groupId>com.google.guava</groupId>
-                   <artifactId>guava</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-starter-corba</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency><!--鏂囦欢鐨勪俊鎭�-->
-           <groupId>com.vci</groupId>
-           <artifactId>vci-file-api</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-               <exclusion>
-                   <groupId>org.apache.logging.log4j</groupId>
-                   <artifactId>*</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-file-integration</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-starter-word</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-               <exclusion>
-                   <groupId>com.vci</groupId>
-                   <artifactId>vci-starter-web</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-starter-poi</artifactId>
-           <version>1.0-SNAPSHOT</version>
-           <exclusions>
-               <exclusion>
-                   <groupId>org.springframework.boot</groupId>
-                   <artifactId>spring-boot-starter-thymeleaf</artifactId>
-               </exclusion>
-               <exclusion>
-                   <groupId>com.vci</groupId>
-                   <artifactId>vci-starter-web</artifactId>
-               </exclusion>
-           </exclusions>
-       </dependency>
-       <dependency>
-           <groupId>eu.bitwalker</groupId>
-           <artifactId>UserAgentUtils</artifactId>
-           <version>1.20</version>
-       </dependency>
-       <!--寮�鍚� cache 缂撳瓨 -->
-       <dependency>
-           <groupId>org.springframework.boot</groupId>
-           <artifactId>spring-boot-starter-cache</artifactId>
-           <version>2.1.3.RELEASE</version>
-       </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-starter-web</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-starter-corba</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency><!--鏂囦欢鐨勪俊鎭�-->
+            <groupId>com.vci</groupId>
+            <artifactId>vci-file-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-file-integration</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-starter-word</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.vci</groupId>
+                    <artifactId>vci-starter-web</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-starter-poi</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.vci</groupId>
+                    <artifactId>vci-starter-web</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.20</version>
+        </dependency>
+        <!--寮�鍚� cache 缂撳瓨 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-cache</artifactId>
+            <version>2.1.3.RELEASE</version>
+        </dependency>
 
-       <!-- ehcache缂撳瓨 -->
-       <dependency>
-           <groupId>net.sf.ehcache</groupId>
-           <artifactId>ehcache</artifactId>
-           <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
-       </dependency>
+        <!-- ehcache缂撳瓨 -->
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache</artifactId>
+            <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
+        </dependency>
 
-       <dependency><!--java bean 鍜寈ml杞崲-->
-           <groupId>com.thoughtworks.xstream</groupId>
-           <artifactId>xstream</artifactId>
-           <version>1.4.10</version>
-       </dependency>
-       <dependency><!--浠g爜鐢熸垚鍣ㄦ墍闇�妯℃澘-->
-           <artifactId>velocity</artifactId>
-           <groupId>org.apache.velocity</groupId>
-           <version>1.7</version>
-       </dependency>
-       <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
-           <groupId>com.vci.platform</groupId>
-           <artifactId>ddlTool-client</artifactId>
-           <version>${vciplt.version}</version>
-       </dependency>
-       <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
-           <groupId>com.vci.platform</groupId>
-           <artifactId>ddlTool-common</artifactId>
-           <version>${vciplt.version}</version>
-       </dependency>
-       <dependency>
-           <groupId>com.vci.client</groupId>
-           <artifactId>plt-clientbase</artifactId>
-           <version>1.0.RELEASE</version>
-       </dependency>
-       <dependency>
-           <groupId>com.zeroc</groupId>
-           <artifactId>icegridgui</artifactId>
-           <version>1.0.RELEASE</version>
-       </dependency>
+        <dependency><!--java bean 鍜寈ml杞崲-->
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>1.4.10</version>
+        </dependency>
+        <dependency><!--浠g爜鐢熸垚鍣ㄦ墍闇�妯℃澘-->
+            <artifactId>velocity</artifactId>
+            <groupId>org.apache.velocity</groupId>
+            <version>1.7</version>
+        </dependency>
+        <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
+            <groupId>com.vci.platform</groupId>
+            <artifactId>ddlTool-client</artifactId>
+            <version>${vciplt.version}</version>
+        </dependency>
+        <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
+            <groupId>com.vci.platform</groupId>
+            <artifactId>ddlTool-common</artifactId>
+            <version>${vciplt.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.vci.client</groupId>
+            <artifactId>plt-clientbase</artifactId>
+            <version>1.0.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zeroc</groupId>
+            <artifactId>icegridgui</artifactId>
+            <version>1.0.RELEASE</version>
+        </dependency>
         <dependency>
             <groupId>com.vci.common</groupId>
             <artifactId>plt-common</artifactId>
             <version>1.0.RELEASE</version>
         </dependency>
-       <dependency>
-           <groupId>com.vci</groupId>
-           <artifactId>vci-platform-starter</artifactId>
-           <version>2022.1-SNAPSHOT</version>
-       </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>vci-platform-starter</artifactId>
+            <version>2022.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <version>0.9.11</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
 
-       <dependency>
-           <groupId>org.reflections</groupId>
-           <artifactId>reflections</artifactId>
-           <version>0.9.11</version>
-       </dependency>
-
-       <!--redis start-->
-       <dependency>
-           <groupId>org.springframework.data</groupId>
-           <artifactId>spring-data-redis</artifactId>
-           <version>2.1.5.RELEASE</version>
-       </dependency>
-       <dependency>
-           <groupId>redis.clients</groupId>
-           <artifactId>jedis</artifactId>
-           <version>2.9.0</version>
-       </dependency>
-       <!--redis end-->
-   </dependencies>
+        <!--redis start-->
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-redis</artifactId>
+            <version>2.1.5.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>2.9.0</version>
+        </dependency>
+        <!--redis end-->
+    </dependencies>
 
     <build>
         <finalName>vci-platform-web</finalName>
@@ -211,34 +220,34 @@
                     </excludes>
                 </configuration>
             </plugin>
-<!--            <plugin>-->
-<!--                <groupId>org.springframework.boot</groupId>-->
-<!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
-<!--                <configuration>-->
-<!--                    &lt;!&ndash;閲嶅啓鍖呭惈渚濊禆锛屽寘鍚笉瀛樺湪鐨勪緷璧栵紝jar閲屾病鏈塸om閲岀殑渚濊禆&ndash;&gt;-->
-<!--                    <includes>-->
-<!--                        <include>-->
-<!--                            <groupId>null</groupId>-->
-<!--                            <artifactId>null</artifactId>-->
-<!--                        </include>-->
-<!--                    </includes>-->
-<!--                    <layout>ZIP</layout>-->
-<!--                    &lt;!&ndash;浣跨敤澶栭儴閰嶇疆鏂囦欢锛宩ar鍖呴噷娌℃湁璧勬簮鏂囦欢&ndash;&gt;-->
-<!--                    <addResources>true</addResources>-->
-<!--                </configuration>-->
-<!--                <executions>-->
-<!--                    <execution>-->
-<!--                        <goals>-->
-<!--                            <goal>repackage</goal>-->
-<!--                        </goals>-->
-<!--                        <configuration>-->
-<!--                            &lt;!&ndash;閰嶇疆jar鍖呯壒娈婃爣璇� 閰嶇疆鍚庯紝淇濈暀鍘熸枃浠讹紝鐢熸垚鏂版枃浠� *-run.jar &ndash;&gt;-->
-<!--                            &lt;!&ndash;閰嶇疆jar鍖呯壒娈婃爣璇� 涓嶉厤缃紝鍘熸枃浠跺懡鍚嶄负 *.jar.original锛岀敓鎴愭柊鏂囦欢 *.jar &ndash;&gt;-->
-<!--                            &lt;!&ndash;<classifier>run</classifier>&ndash;&gt;-->
-<!--                        </configuration>-->
-<!--                    </execution>-->
-<!--                </executions>-->
-<!--            </plugin>-->
+            <!--            <plugin>-->
+            <!--                <groupId>org.springframework.boot</groupId>-->
+            <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
+            <!--                <configuration>-->
+            <!--                    &lt;!&ndash;閲嶅啓鍖呭惈渚濊禆锛屽寘鍚笉瀛樺湪鐨勪緷璧栵紝jar閲屾病鏈塸om閲岀殑渚濊禆&ndash;&gt;-->
+            <!--                    <includes>-->
+            <!--                        <include>-->
+            <!--                            <groupId>null</groupId>-->
+            <!--                            <artifactId>null</artifactId>-->
+            <!--                        </include>-->
+            <!--                    </includes>-->
+            <!--                    <layout>ZIP</layout>-->
+            <!--                    &lt;!&ndash;浣跨敤澶栭儴閰嶇疆鏂囦欢锛宩ar鍖呴噷娌℃湁璧勬簮鏂囦欢&ndash;&gt;-->
+            <!--                    <addResources>true</addResources>-->
+            <!--                </configuration>-->
+            <!--                <executions>-->
+            <!--                    <execution>-->
+            <!--                        <goals>-->
+            <!--                            <goal>repackage</goal>-->
+            <!--                        </goals>-->
+            <!--                        <configuration>-->
+            <!--                            &lt;!&ndash;閰嶇疆jar鍖呯壒娈婃爣璇� 閰嶇疆鍚庯紝淇濈暀鍘熸枃浠讹紝鐢熸垚鏂版枃浠� *-run.jar &ndash;&gt;-->
+            <!--                            &lt;!&ndash;閰嶇疆jar鍖呯壒娈婃爣璇� 涓嶉厤缃紝鍘熸枃浠跺懡鍚嶄负 *.jar.original锛岀敓鎴愭柊鏂囦欢 *.jar &ndash;&gt;-->
+            <!--                            &lt;!&ndash;<classifier>run</classifier>&ndash;&gt;-->
+            <!--                        </configuration>-->
+            <!--                    </execution>-->
+            <!--                </executions>-->
+            <!--            </plugin>-->
 
         </plugins>
     </build>
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
index 7c79482..5e6e69a 100644
--- a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
@@ -5,7 +5,6 @@
 import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
 import com.vci.frameworkcore.lcstatuspck.ReleaseDataLCStatus;
 import com.vci.starter.revision.bo.TreeWrapperOptions;
-import com.vci.starter.revision.service.RevisionModelUtil;
 import com.vci.starter.web.annotation.bus.VciChangeDataAfter;
 import com.vci.starter.web.annotation.bus.VciChangeDataBefore;
 import com.vci.starter.web.annotation.bus.VciChangeDataPlugin;
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
index 47b838d..4a69509 100644
--- a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
@@ -507,7 +507,9 @@
 	@Override
 	@VciUnLog
 	public UITableDefineVO tableDO2VO(PortalVI portal, boolean queryDetail) {
+		if(){
 
+		}
 		UITableDefineVO tableDefineVO = new UITableDefineVO();
 		tableDefineVO.setOid(portal.id);
 		tableDefineVO.setId(portal.viName);
@@ -1275,6 +1277,7 @@
 						throw new VciBaseException("{0}閲岀殑琛ㄦ牸{1}涓嶅瓨鍦�", new String[]{btmType, componentDefineXO.getTemplateId()});
 					}
 					componentVO.setTableDefineVO(tableDefineVOMap.get(key));
+
 				}else{
 					try {
 						componentVO.setTableDefineVO(tableDO2VO(ServiceProvider.getUIService().getPortalVIByTypeNameAndVIName(btmType,componentDefineXO.getTemplateId()),true));
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java
new file mode 100644
index 0000000..86ba0db
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java
@@ -0,0 +1,501 @@
+package com.vci.web.support;
+
+import com.vci.web.util.StringUtil;
+import com.vci.web.util.Func;
+import com.vci.web.util.StringPool;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 瀛楃涓插垏鍒嗗櫒
+ *
+ * @author Looly
+ */
+public class StrSpliter {
+
+    //---------------------------------------------------------------------------------------------- Split by char
+
+    /**
+     * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+     *
+     * @param str 琚垏鍒嗙殑瀛楃涓�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> splitPath(String str) {
+        return splitPath(str, 0);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+     *
+     * @param str 琚垏鍒嗙殑瀛楃涓�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitPathToArray(String str) {
+        return toArray(splitPath(str));
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+     *
+     * @param str   琚垏鍒嗙殑瀛楃涓�
+     * @param limit 闄愬埗鍒嗙墖鏁�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> splitPath(String str, int limit) {
+        return split(str, StringPool.SLASH, limit, true, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+     *
+     * @param str   琚垏鍒嗙殑瀛楃涓�
+     * @param limit 闄愬埗鍒嗙墖鏁�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitPathToArray(String str, int limit) {
+        return toArray(splitPath(str, limit));
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitTrim(String str, char separator, boolean ignoreEmpty) {
+        return split(str, separator, 0, true, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, char separator, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, 0, isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝澶у皬鍐欐晱鎰燂紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌虹櫧绗�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> splitTrim(String str, char separator, int limit, boolean ignoreEmpty) {
+        return split(str, separator, limit, true, ignoreEmpty, false);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝澶у皬鍐欐晱鎰�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, limit, isTrim, ignoreEmpty, false);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝蹇界暐澶у皬鍐�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitIgnoreCase(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, limit, isTrim, ignoreEmpty, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @param ignoreCase  鏄惁蹇界暐澶у皬鍐�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
+        if (StringUtil.isEmpty(str)) {
+            return new ArrayList<String>(0);
+        }
+        if (limit == 1) {
+            return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+        }
+
+        final ArrayList<String> list = new ArrayList<>(limit > 0 ? limit : 16);
+        int len = str.length();
+        int start = 0;
+        for (int i = 0; i < len; i++) {
+            if (Func.equals(separator, str.charAt(i))) {
+                addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
+                start = i + 1;
+
+                //妫�鏌ユ槸鍚﹁秴鍑鸿寖鍥达紙鏈�澶у厑璁竘imit-1涓紝鍓╀笅涓�涓暀缁欐湯灏惧瓧绗︿覆锛�
+                if (limit > 0 && list.size() > limit - 2) {
+                    break;
+                }
+            }
+        }
+        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitToArray(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
+    }
+
+    //---------------------------------------------------------------------------------------------- Split by String
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝涓嶅拷鐣ュぇ灏忓啓
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, String separator, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, -1, isTrim, ignoreEmpty, false);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitTrim(String str, String separator, boolean ignoreEmpty) {
+        return split(str, separator, true, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝涓嶅拷鐣ュぇ灏忓啓
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, limit, isTrim, ignoreEmpty, false);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitTrim(String str, String separator, int limit, boolean ignoreEmpty) {
+        return split(str, separator, limit, true, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝蹇界暐澶у皬鍐�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitIgnoreCase(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, limit, isTrim, ignoreEmpty, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> splitTrimIgnoreCase(String str, String separator, int limit, boolean ignoreEmpty) {
+        return split(str, separator, limit, true, ignoreEmpty, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗︿覆
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @param ignoreCase  鏄惁蹇界暐澶у皬鍐�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.1
+     */
+    public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
+        if (StringUtil.isEmpty(str)) {
+            return new ArrayList<String>(0);
+        }
+        if (limit == 1) {
+            return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+        }
+
+        if (StringUtil.isEmpty(separator)) {
+            return split(str, limit);
+        } else if (separator.length() == 1) {
+            return split(str, separator.charAt(0), limit, isTrim, ignoreEmpty, ignoreCase);
+        }
+
+        final ArrayList<String> list = new ArrayList<>();
+        int len = str.length();
+        int separatorLen = separator.length();
+        int start = 0;
+        int i = 0;
+        while (i < len) {
+            i = StringUtil.indexOf(str, separator, start, ignoreCase);
+            if (i > -1) {
+                addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
+                start = i + separatorLen;
+
+                //妫�鏌ユ槸鍚﹁秴鍑鸿寖鍥达紙鏈�澶у厑璁竘imit-1涓紝鍓╀笅涓�涓暀缁欐湯灏惧瓧绗︿覆锛�
+                if (limit > 0 && list.size() > limit - 2) {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitToArray(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
+    }
+
+    //---------------------------------------------------------------------------------------------- Split by Whitespace
+
+    /**
+     * 浣跨敤绌虹櫧绗﹀垏鍒嗗瓧绗︿覆<br>
+     * 鍒囧垎鍚庣殑瀛楃涓蹭袱杈逛笉鍖呭惈绌虹櫧绗︼紝绌轰覆鎴栫┖鐧界涓插苟涓嶅仛涓哄厓绱犱箣涓�
+     *
+     * @param str   琚垏鍒嗙殑瀛楃涓�
+     * @param limit 闄愬埗鍒嗙墖鏁�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, int limit) {
+        if (StringUtil.isEmpty(str)) {
+            return new ArrayList<String>(0);
+        }
+        if (limit == 1) {
+            return addToList(new ArrayList<String>(1), str, true, true);
+        }
+
+        final ArrayList<String> list = new ArrayList<>();
+        int len = str.length();
+        int start = 0;
+        for (int i = 0; i < len; i++) {
+            if (Func.isEmpty(str.charAt(i))) {
+                addToList(list, str.substring(start, i), true, true);
+                start = i + 1;
+                if (limit > 0 && list.size() > limit - 2) {
+                    break;
+                }
+            }
+        }
+        return addToList(list, str.substring(start, len), true, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+     *
+     * @param str   琚垏鍒嗙殑瀛楃涓�
+     * @param limit 闄愬埗鍒嗙墖鏁�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitToArray(String str, int limit) {
+        return toArray(split(str, limit));
+    }
+
+    //---------------------------------------------------------------------------------------------- Split by regex
+
+    /**
+     * 閫氳繃姝e垯鍒囧垎瀛楃涓�
+     *
+     * @param str              瀛楃涓�
+     * @param separatorPattern 鍒嗛殧绗︽鍒檣@link Pattern}
+     * @param limit            闄愬埗鍒嗙墖鏁�
+     * @param isTrim           鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty      鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
+        if (StringUtil.isEmpty(str)) {
+            return new ArrayList<String>(0);
+        }
+        if (limit == 1) {
+            return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+        }
+
+        if (null == separatorPattern) {
+            return split(str, limit);
+        }
+
+        final Matcher matcher = separatorPattern.matcher(str);
+        final ArrayList<String> list = new ArrayList<>();
+        int len = str.length();
+        int start = 0;
+        while (matcher.find()) {
+            addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty);
+            start = matcher.end();
+
+            if (limit > 0 && list.size() > limit - 2) {
+                break;
+            }
+        }
+        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 閫氳繃姝e垯鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+     *
+     * @param str              琚垏鍒嗙殑瀛楃涓�
+     * @param separatorPattern 鍒嗛殧绗︽鍒檣@link Pattern}
+     * @param limit            闄愬埗鍒嗙墖鏁�
+     * @param isTrim           鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty      鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static String[] splitToArray(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
+        return toArray(split(str, separatorPattern, limit, isTrim, ignoreEmpty));
+    }
+
+    //---------------------------------------------------------------------------------------------- Split by length
+
+    /**
+     * 鏍规嵁缁欏畾闀垮害锛屽皢缁欏畾瀛楃涓叉埅鍙栦负澶氫釜閮ㄥ垎
+     *
+     * @param str 瀛楃涓�
+     * @param len 姣忎竴涓皬鑺傜殑闀垮害
+     * @return 鎴彇鍚庣殑瀛楃涓叉暟缁�
+     */
+    public static String[] splitByLength(String str, int len) {
+        int partCount = str.length() / len;
+        int lastPartCount = str.length() % len;
+        int fixPart = 0;
+        if (lastPartCount != 0) {
+            fixPart = 1;
+        }
+
+        final String[] strs = new String[partCount + fixPart];
+        for (int i = 0; i < partCount + fixPart; i++) {
+            if (i == partCount + fixPart - 1 && lastPartCount != 0) {
+                strs[i] = str.substring(i * len, i * len + lastPartCount);
+            } else {
+                strs[i] = str.substring(i * len, i * len + len);
+            }
+        }
+        return strs;
+    }
+
+    //---------------------------------------------------------------------------------------------------------- Private method start
+
+    /**
+     * 灏嗗瓧绗︿覆鍔犲叆List涓�
+     *
+     * @param list        鍒楄〃
+     * @param part        琚姞鍏ョ殑閮ㄥ垎
+     * @param isTrim      鏄惁鍘婚櫎涓ょ绌虹櫧绗�
+     * @param ignoreEmpty 鏄惁鐣ヨ繃绌哄瓧绗︿覆锛堢┖瀛楃涓蹭笉鍋氫负涓�涓厓绱狅級
+     * @return 鍒楄〃
+     */
+    private static List<String> addToList(List<String> list, String part, boolean isTrim, boolean ignoreEmpty) {
+        part = part.toString();
+        if (isTrim) {
+            part = part.trim();
+        }
+        if (false == ignoreEmpty || false == part.isEmpty()) {
+            list.add(part);
+        }
+        return list;
+    }
+
+    /**
+     * List杞珹rray
+     *
+     * @param list List
+     * @return Array
+     */
+    private static String[] toArray(List<String> list) {
+        return list.toArray(new String[list.size()]);
+    }
+    //---------------------------------------------------------------------------------------------------------- Private method end
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java
new file mode 100644
index 0000000..56a3003
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java
@@ -0,0 +1,115 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+/**
+ * Base64宸ュ叿
+ *
+ * @author L.cm
+ */
+public class Base64Util extends org.springframework.util.Base64Utils {
+
+	/**
+	 * 缂栫爜
+	 *
+	 * @param value 瀛楃涓�
+	 * @return {String}
+	 */
+	public static String encode(String value) {
+		return Base64Util.encode(value, Charsets.UTF_8);
+	}
+
+	/**
+	 * 缂栫爜
+	 *
+	 * @param value   瀛楃涓�
+	 * @param charset 瀛楃闆�
+	 * @return {String}
+	 */
+	public static String encode(String value, java.nio.charset.Charset charset) {
+		byte[] val = value.getBytes(charset);
+		return new String(Base64Util.encode(val), charset);
+	}
+
+	/**
+	 * 缂栫爜URL瀹夊叏
+	 *
+	 * @param value 瀛楃涓�
+	 * @return {String}
+	 */
+	public static String encodeUrlSafe(String value) {
+		return Base64Util.encodeUrlSafe(value, Charsets.UTF_8);
+	}
+
+	/**
+	 * 缂栫爜URL瀹夊叏
+	 *
+	 * @param value   瀛楃涓�
+	 * @param charset 瀛楃闆�
+	 * @return {String}
+	 */
+	public static String encodeUrlSafe(String value, java.nio.charset.Charset charset) {
+		byte[] val = value.getBytes(charset);
+		return new String(Base64Util.encodeUrlSafe(val), charset);
+	}
+
+	/**
+	 * 瑙g爜
+	 *
+	 * @param value 瀛楃涓�
+	 * @return {String}
+	 */
+	public static String decode(String value) {
+		return Base64Util.decode(value, Charsets.UTF_8);
+	}
+
+	/**
+	 * 瑙g爜
+	 *
+	 * @param value   瀛楃涓�
+	 * @param charset 瀛楃闆�
+	 * @return {String}
+	 */
+	public static String decode(String value, java.nio.charset.Charset charset) {
+		byte[] val = value.getBytes(charset);
+		byte[] decodedValue = Base64Util.decode(val);
+		return new String(decodedValue, charset);
+	}
+
+	/**
+	 * 瑙g爜URL瀹夊叏
+	 *
+	 * @param value 瀛楃涓�
+	 * @return {String}
+	 */
+	public static String decodeUrlSafe(String value) {
+		return Base64Util.decodeUrlSafe(value, Charsets.UTF_8);
+	}
+
+	/**
+	 * 瑙g爜URL瀹夊叏
+	 *
+	 * @param value   瀛楃涓�
+	 * @param charset 瀛楃闆�
+	 * @return {String}
+	 */
+	public static String decodeUrlSafe(String value, java.nio.charset.Charset charset) {
+		byte[] val = value.getBytes(charset);
+		byte[] decodedValue = Base64Util.decodeUrlSafe(val);
+		return new String(decodedValue, charset);
+	}
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java
new file mode 100644
index 0000000..dd99d9a
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java
@@ -0,0 +1,58 @@
+package com.vci.web.util;
+
+/**
+ * char 甯搁噺姹�
+ *
+ * @author L.cm
+ */
+public interface CharPool {
+
+    // @formatter:off
+    char UPPER_A          = 'A';
+    char LOWER_A          = 'a';
+    char UPPER_Z          = 'Z';
+    char LOWER_Z          = 'z';
+    char DOT              = '.';
+    char AT               = '@';
+    char LEFT_BRACE       = '{';
+    char RIGHT_BRACE      = '}';
+    char LEFT_BRACKET     = '(';
+    char RIGHT_BRACKET    = ')';
+    char DASH             = '-';
+    char PERCENT          = '%';
+    char PIPE             = '|';
+    char PLUS             = '+';
+    char QUESTION_MARK    = '?';
+    char EXCLAMATION_MARK = '!';
+    char EQUALS           = '=';
+    char AMPERSAND        = '&';
+    char ASTERISK         = '*';
+    char STAR             = ASTERISK;
+    char BACK_SLASH       = '\\';
+    char COLON            = ':';
+    char COMMA            = ',';
+    char DOLLAR           = '$';
+    char SLASH            = '/';
+    char HASH             = '#';
+    char HAT              = '^';
+    char LEFT_CHEV        = '<';
+    char NEWLINE          = '\n';
+    char N                = 'n';
+    char Y                = 'y';
+    char QUOTE            = '\"';
+    char RETURN           = '\r';
+    char TAB              = '\t';
+    char RIGHT_CHEV       = '>';
+    char SEMICOLON        = ';';
+    char SINGLE_QUOTE     = '\'';
+    char BACKTICK         = '`';
+    char SPACE            = ' ';
+    char TILDA            = '~';
+    char LEFT_SQ_BRACKET  = '[';
+    char RIGHT_SQ_BRACKET = ']';
+    char UNDERSCORE       = '_';
+    char ONE              = '1';
+    char ZERO             = '0';
+    // @formatter:on
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java
new file mode 100644
index 0000000..1a18b47
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java
@@ -0,0 +1,60 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+
+/**
+ * 瀛楃闆嗗伐鍏风被
+ *
+ * @author L.cm
+ */
+public class Charsets {
+
+	/**
+	 * 瀛楃闆咺SO-8859-1
+	 */
+	public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
+	public static final String ISO_8859_1_NAME = ISO_8859_1.name();
+
+	/**
+	 * 瀛楃闆咷BK
+	 */
+	public static final Charset GBK = Charset.forName(StringPool.GBK);
+	public static final String GBK_NAME = GBK.name();
+
+	/**
+	 * 瀛楃闆唘tf-8
+	 */
+	public static final Charset UTF_8 = StandardCharsets.UTF_8;
+	public static final String UTF_8_NAME = UTF_8.name();
+
+	/**
+	 * 杞崲涓篊harset瀵硅薄
+	 *
+	 * @param charsetName 瀛楃闆嗭紝涓虹┖鍒欒繑鍥為粯璁ゅ瓧绗﹂泦
+	 * @return Charsets
+	 * @throws UnsupportedCharsetException 缂栫爜涓嶆敮鎸�
+	 */
+	public static Charset charset(String charsetName) throws UnsupportedCharsetException {
+		return StringUtil.isBlank(charsetName) ? Charset.defaultCharset() : Charset.forName(charsetName);
+	}
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java
new file mode 100644
index 0000000..2b4aae9
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java
@@ -0,0 +1,161 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Array;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 闆嗗悎宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class CollectionUtil extends CollectionUtils {
+
+    /**
+     * Return {@code true} if the supplied Collection is not {@code null} or empty.
+     * Otherwise, return {@code false}.
+     *
+     * @param collection the Collection to check
+     * @return whether the given Collection is not empty
+     */
+    public static boolean isNotEmpty(@Nullable Collection<?> collection) {
+        return !CollectionUtil.isEmpty(collection);
+    }
+
+    /**
+     * Return {@code true} if the supplied Map is not {@code null} or empty.
+     * Otherwise, return {@code false}.
+     *
+     * @param map the Map to check
+     * @return whether the given Map is not empty
+     */
+    public static boolean isNotEmpty(@Nullable Map<?, ?> map) {
+        return !CollectionUtil.isEmpty(map);
+    }
+
+    /**
+     * Check whether the given Array contains the given element.
+     *
+     * @param array   the Array to check
+     * @param element the element to look for
+     * @param <T>     The generic tag
+     * @return {@code true} if found, {@code false} else
+     */
+    public static <T> boolean contains(@Nullable T[] array, final T element) {
+        if (array == null) {
+            return false;
+        }
+        return Arrays.stream(array).anyMatch(x -> ObjectUtil.nullSafeEquals(x, element));
+    }
+
+    /**
+     * Concatenates 2 arrays
+     *
+     * @param one   鏁扮粍1
+     * @param other 鏁扮粍2
+     * @return 鏂版暟缁�
+     */
+    public static String[] concat(String[] one, String[] other) {
+        return concat(one, other, String.class);
+    }
+
+    /**
+     * Concatenates 2 arrays
+     *
+     * @param one   鏁扮粍1
+     * @param other 鏁扮粍2
+     * @param clazz 鏁扮粍绫�
+     * @return 鏂版暟缁�
+     */
+    public static <T> T[] concat(T[] one, T[] other, Class<T> clazz) {
+        T[] target = (T[]) Array.newInstance(clazz, one.length + other.length);
+        System.arraycopy(one, 0, target, 0, one.length);
+        System.arraycopy(other, 0, target, one.length, other.length);
+        return target;
+    }
+
+    /**
+     * 瀵硅薄鏄惁涓烘暟缁勫璞�
+     *
+     * @param obj 瀵硅薄
+     * @return 鏄惁涓烘暟缁勫璞★紝濡傛灉涓簕@code null} 杩斿洖false
+     */
+    public static boolean isArray(Object obj) {
+        if (null == obj) {
+            return false;
+        }
+        return obj.getClass().isArray();
+    }
+
+    /**
+     * 涓嶅彲鍙� Set
+     *
+     * @param es  瀵硅薄
+     * @param <E> 娉涘瀷
+     * @return 闆嗗悎
+     */
+    @SafeVarargs
+    public static <E> Set<E> ofImmutableSet(E... es) {
+        Objects.requireNonNull(es, "args es is null.");
+        return Arrays.stream(es).collect(Collectors.toSet());
+    }
+
+    /**
+     * 涓嶅彲鍙� List
+     *
+     * @param es  瀵硅薄
+     * @param <E> 娉涘瀷
+     * @return 闆嗗悎
+     */
+    @SafeVarargs
+    public static <E> List<E> ofImmutableList(E... es) {
+        Objects.requireNonNull(es, "args es is null.");
+        return Arrays.stream(es).collect(Collectors.toList());
+    }
+
+    /**
+     * Iterable 杞崲涓篖ist闆嗗悎
+     *
+     * @param elements Iterable
+     * @param <E>      娉涘瀷
+     * @return 闆嗗悎
+     */
+    public static <E> List<E> toList(Iterable<E> elements) {
+        Objects.requireNonNull(elements, "elements es is null.");
+        if (elements instanceof Collection) {
+            return new ArrayList((Collection) elements);
+        }
+        Iterator<E> iterator = elements.iterator();
+        List<E> list = new ArrayList<>();
+        while (iterator.hasNext()) {
+            list.add(iterator.next());
+        }
+        return list;
+    }
+
+    /**
+     * 灏唊ey value 鏁扮粍杞负 map
+     *
+     * @param keysValues key value 鏁扮粍
+     * @param <K>        key
+     * @param <V>        value
+     * @return map 闆嗗悎
+     */
+    public static <K, V> Map<K, V> toMap(Object... keysValues) {
+        int kvLength = keysValues.length;
+        if (kvLength % 2 != 0) {
+            throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd");
+        }
+        Map<K, V> keyValueMap = new HashMap<>(kvLength);
+        for (int i = kvLength - 2; i >= 0; i -= 2) {
+            Object key = keysValues[i];
+            Object value = keysValues[i + 1];
+            keyValueMap.put((K) key, (V) value);
+        }
+        return keyValueMap;
+    }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java
new file mode 100644
index 0000000..722de89
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java
@@ -0,0 +1,87 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Queue;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * 鍙傝�僼omcat8涓殑骞跺彂DateFormat
+ * <p>
+ * {@link SimpleDateFormat}鐨勭嚎绋嬪畨鍏ㄥ寘瑁呭櫒銆�
+ * 涓嶄娇鐢═hreadLocal锛屽垱寤鸿冻澶熺殑SimpleDateFormat瀵硅薄鏉ユ弧瓒冲苟鍙戞�ц姹傘��
+ * </p>
+ *
+ * @author L.cm
+ */
+public class ConcurrentDateFormat {
+	private final String format;
+	private final Locale locale;
+	private final TimeZone timezone;
+	private final Queue<SimpleDateFormat> queue = new ConcurrentLinkedQueue<>();
+
+	private ConcurrentDateFormat(String format, Locale locale, TimeZone timezone) {
+		this.format = format;
+		this.locale = locale;
+		this.timezone = timezone;
+		SimpleDateFormat initial = createInstance();
+		queue.add(initial);
+	}
+
+	public static ConcurrentDateFormat of(String format) {
+		return new ConcurrentDateFormat(format, Locale.getDefault(), TimeZone.getDefault());
+	}
+
+	public static ConcurrentDateFormat of(String format, TimeZone timezone) {
+		return new ConcurrentDateFormat(format, Locale.getDefault(), timezone);
+	}
+
+	public static ConcurrentDateFormat of(String format, Locale locale, TimeZone timezone) {
+		return new ConcurrentDateFormat(format, locale, timezone);
+	}
+
+	public String format(Date date) {
+		SimpleDateFormat sdf = queue.poll();
+		if (sdf == null) {
+			sdf = createInstance();
+		}
+		String result = sdf.format(date);
+		queue.add(sdf);
+		return result;
+	}
+
+	public Date parse(String source) throws ParseException {
+		SimpleDateFormat sdf = queue.poll();
+		if (sdf == null) {
+			sdf = createInstance();
+		}
+		Date result = sdf.parse(source);
+		queue.add(sdf);
+		return result;
+	}
+
+	private SimpleDateFormat createInstance() {
+		SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+		sdf.setTimeZone(timezone);
+		return sdf;
+	}
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java
new file mode 100644
index 0000000..47d545c
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java
@@ -0,0 +1,57 @@
+package com.vci.web.util;
+
+/**
+ * 鏁版嵁绫诲瀷杞崲宸ュ叿绫�
+ *
+ * @author Chill
+ */
+public class DatatypeConverterUtil {
+
+	/**
+	 * hex鏂囨湰杞崲涓轰簩杩涘埗
+	 *
+	 * @param hexStr hex鏂囨湰
+	 * @return byte[]
+	 */
+	public static byte[] parseHexBinary(String hexStr) {
+		final int len = hexStr.length();
+
+		if (len % 2 != 0) {
+			throw new IllegalArgumentException("hexBinary needs to be even-length: " + hexStr);
+		}
+
+		byte[] out = new byte[len / 2];
+
+		for (int i = 0; i < len; i += 2) {
+			int h = hexToBin(hexStr.charAt(i));
+			int l = hexToBin(hexStr.charAt(i + 1));
+			if (h == -1 || l == -1) {
+				throw new IllegalArgumentException("contains illegal character for hexBinary: " + hexStr);
+			}
+
+			out[i / 2] = (byte) (h * 16 + l);
+		}
+
+		return out;
+	}
+
+	/**
+	 * hex鏂囨湰杞崲涓篿nt
+	 *
+	 * @param ch hex鏂囨湰
+	 * @return int
+	 */
+	private static int hexToBin(char ch) {
+		if ('0' <= ch && ch <= '9') {
+			return ch - '0';
+		}
+		if ('A' <= ch && ch <= 'F') {
+			return ch - 'A' + 10;
+		}
+		if ('a' <= ch && ch <= 'f') {
+			return ch - 'a' + 10;
+		}
+		return -1;
+	}
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java
new file mode 100644
index 0000000..09c62d5
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java
@@ -0,0 +1,226 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.Date;
+
+/**
+ * DateTime 宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class DateTimeUtil {
+	public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
+	public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
+	public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
+
+	/**
+	 * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDateTime(TemporalAccessor temporal) {
+		return DATETIME_FORMAT.format(temporal);
+	}
+
+	/**
+	 * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDate(TemporalAccessor temporal) {
+		return DATE_FORMAT.format(temporal);
+	}
+
+	/**
+	 * 鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatTime(TemporalAccessor temporal) {
+		return TIME_FORMAT.format(temporal);
+	}
+
+	/**
+	 * 鏃ユ湡鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @param pattern  琛ㄨ揪寮�
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String format(TemporalAccessor temporal, String pattern) {
+		return DateTimeFormatter.ofPattern(pattern).format(temporal);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param pattern 琛ㄨ揪寮�
+	 * @return 鏃堕棿
+	 */
+	public static LocalDateTime parseDateTime(String dateStr, String pattern) {
+		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+		return DateTimeUtil.parseDateTime(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr   鏃堕棿瀛楃涓�
+	 * @param formatter DateTimeFormatter
+	 * @return 鏃堕棿
+	 */
+	public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
+		return LocalDateTime.parse(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @return 鏃堕棿
+	 */
+	public static LocalDateTime parseDateTime(String dateStr) {
+		return DateTimeUtil.parseDateTime(dateStr, DateTimeUtil.DATETIME_FORMAT);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param pattern 琛ㄨ揪寮�
+	 * @return 鏃堕棿
+	 */
+	public static LocalDate parseDate(String dateStr, String pattern) {
+		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+		return DateTimeUtil.parseDate(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr   鏃堕棿瀛楃涓�
+	 * @param formatter DateTimeFormatter
+	 * @return 鏃堕棿
+	 */
+	public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
+		return LocalDate.parse(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘棩鏈�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @return 鏃堕棿
+	 */
+	public static LocalDate parseDate(String dateStr) {
+		return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param pattern 鏃堕棿姝e垯
+	 * @return 鏃堕棿
+	 */
+	public static LocalTime parseTime(String dateStr, String pattern) {
+		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+		return DateTimeUtil.parseTime(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr   鏃堕棿瀛楃涓�
+	 * @param formatter DateTimeFormatter
+	 * @return 鏃堕棿
+	 */
+	public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
+		return LocalTime.parse(dateStr, formatter);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @return 鏃堕棿
+	 */
+	public static LocalTime parseTime(String dateStr) {
+		return DateTimeUtil.parseTime(dateStr, DateTimeUtil.TIME_FORMAT);
+	}
+
+	/**
+	 * 鏃堕棿杞� Instant
+	 *
+	 * @param dateTime 鏃堕棿
+	 * @return Instant
+	 */
+	public static Instant toInstant(LocalDateTime dateTime) {
+		return dateTime.atZone(ZoneId.systemDefault()).toInstant();
+	}
+
+	/**
+	 * Instant 杞� 鏃堕棿
+	 *
+	 * @param instant Instant
+	 * @return Instant
+	 */
+	public static LocalDateTime toDateTime(Instant instant) {
+		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+	}
+
+	/**
+	 * 杞崲鎴� date
+	 *
+	 * @param dateTime LocalDateTime
+	 * @return Date
+	 */
+	public static Date toDate(LocalDateTime dateTime) {
+		return Date.from(DateTimeUtil.toInstant(dateTime));
+	}
+
+	/**
+	 * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨皬
+	 *
+	 * @param startInclusive 寮�濮嬫椂闂�
+	 * @param endExclusive   缁撴潫鏃堕棿
+	 * @return 鏃堕棿闂撮殧
+	 */
+	public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+		return Duration.between(startInclusive, endExclusive);
+	}
+
+	/**
+	 * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨ぇ锛屽勾鏈堟棩涓哄崟浣�
+	 *
+	 * @param startDate 寮�濮嬫椂闂�
+	 * @param endDate   缁撴潫鏃堕棿
+	 * @return 鏃堕棿闂撮殧
+	 */
+	public static Period between(LocalDate startDate, LocalDate endDate) {
+		return Period.between(startDate, endDate);
+	}
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java
new file mode 100644
index 0000000..6b86fbe
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java
@@ -0,0 +1,634 @@
+package com.vci.web.util;
+
+import org.springframework.util.Assert;
+
+import java.text.ParseException;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalQuery;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * 鏃ユ湡宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class DateUtil {
+
+	public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
+	public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
+	public static final String PATTERN_DATE = "yyyy-MM-dd";
+	public static final String PATTERN_TIME = "HH:mm:ss";
+	/**
+	 * 鑰� date 鏍煎紡鍖�
+	 */
+	public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
+	public static final ConcurrentDateFormat DATETIME_MINI_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME_MINI);
+	public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
+	public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
+	/**
+	 * java 8 鏃堕棿鏍煎紡鍖�
+	 */
+	public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
+	public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
+	public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
+	public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
+
+	/**
+	 * 鑾峰彇褰撳墠鏃ユ湡
+	 *
+	 * @return 褰撳墠鏃ユ湡
+	 */
+	public static Date now() {
+		return new Date();
+	}
+
+	/**
+	 * 娣诲姞骞�
+	 *
+	 * @param date       鏃堕棿
+	 * @param yearsToAdd 娣诲姞鐨勫勾鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusYears(Date date, int yearsToAdd) {
+		return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
+	}
+
+	/**
+	 * 娣诲姞鏈�
+	 *
+	 * @param date        鏃堕棿
+	 * @param monthsToAdd 娣诲姞鐨勬湀鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusMonths(Date date, int monthsToAdd) {
+		return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
+	}
+
+	/**
+	 * 娣诲姞鍛�
+	 *
+	 * @param date       鏃堕棿
+	 * @param weeksToAdd 娣诲姞鐨勫懆鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusWeeks(Date date, int weeksToAdd) {
+		return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
+	}
+
+	/**
+	 * 娣诲姞澶�
+	 *
+	 * @param date      鏃堕棿
+	 * @param daysToAdd 娣诲姞鐨勫ぉ鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusDays(Date date, long daysToAdd) {
+		return DateUtil.plus(date, Duration.ofDays(daysToAdd));
+	}
+
+	/**
+	 * 娣诲姞灏忔椂
+	 *
+	 * @param date       鏃堕棿
+	 * @param hoursToAdd 娣诲姞鐨勫皬鏃舵暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusHours(Date date, long hoursToAdd) {
+		return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
+	}
+
+	/**
+	 * 娣诲姞鍒嗛挓
+	 *
+	 * @param date         鏃堕棿
+	 * @param minutesToAdd 娣诲姞鐨勫垎閽熸暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusMinutes(Date date, long minutesToAdd) {
+		return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
+	}
+
+	/**
+	 * 娣诲姞绉�
+	 *
+	 * @param date         鏃堕棿
+	 * @param secondsToAdd 娣诲姞鐨勭鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusSeconds(Date date, long secondsToAdd) {
+		return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
+	}
+
+	/**
+	 * 娣诲姞姣
+	 *
+	 * @param date        鏃堕棿
+	 * @param millisToAdd 娣诲姞鐨勬绉掓暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusMillis(Date date, long millisToAdd) {
+		return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
+	}
+
+	/**
+	 * 娣诲姞绾崇
+	 *
+	 * @param date       鏃堕棿
+	 * @param nanosToAdd 娣诲姞鐨勭撼绉掓暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plusNanos(Date date, long nanosToAdd) {
+		return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
+	}
+
+	/**
+	 * 鏃ユ湡娣诲姞鏃堕棿閲�
+	 *
+	 * @param date   鏃堕棿
+	 * @param amount 鏃堕棿閲�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date plus(Date date, TemporalAmount amount) {
+		Instant instant = date.toInstant();
+		return Date.from(instant.plus(amount));
+	}
+
+	/**
+	 * 鍑忓皯骞�
+	 *
+	 * @param date  鏃堕棿
+	 * @param years 鍑忓皯鐨勫勾鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusYears(Date date, int years) {
+		return DateUtil.set(date, Calendar.YEAR, -years);
+	}
+
+	/**
+	 * 鍑忓皯鏈�
+	 *
+	 * @param date   鏃堕棿
+	 * @param months 鍑忓皯鐨勬湀鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusMonths(Date date, int months) {
+		return DateUtil.set(date, Calendar.MONTH, -months);
+	}
+
+	/**
+	 * 鍑忓皯鍛�
+	 *
+	 * @param date  鏃堕棿
+	 * @param weeks 鍑忓皯鐨勫懆鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusWeeks(Date date, int weeks) {
+		return DateUtil.minus(date, Period.ofWeeks(weeks));
+	}
+
+	/**
+	 * 鍑忓皯澶�
+	 *
+	 * @param date 鏃堕棿
+	 * @param days 鍑忓皯鐨勫ぉ鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusDays(Date date, long days) {
+		return DateUtil.minus(date, Duration.ofDays(days));
+	}
+
+	/**
+	 * 鍑忓皯灏忔椂
+	 *
+	 * @param date  鏃堕棿
+	 * @param hours 鍑忓皯鐨勫皬鏃舵暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusHours(Date date, long hours) {
+		return DateUtil.minus(date, Duration.ofHours(hours));
+	}
+
+	/**
+	 * 鍑忓皯鍒嗛挓
+	 *
+	 * @param date    鏃堕棿
+	 * @param minutes 鍑忓皯鐨勫垎閽熸暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusMinutes(Date date, long minutes) {
+		return DateUtil.minus(date, Duration.ofMinutes(minutes));
+	}
+
+	/**
+	 * 鍑忓皯绉�
+	 *
+	 * @param date    鏃堕棿
+	 * @param seconds 鍑忓皯鐨勭鏁�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusSeconds(Date date, long seconds) {
+		return DateUtil.minus(date, Duration.ofSeconds(seconds));
+	}
+
+	/**
+	 * 鍑忓皯姣
+	 *
+	 * @param date   鏃堕棿
+	 * @param millis 鍑忓皯鐨勬绉掓暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusMillis(Date date, long millis) {
+		return DateUtil.minus(date, Duration.ofMillis(millis));
+	}
+
+	/**
+	 * 鍑忓皯绾崇
+	 *
+	 * @param date  鏃堕棿
+	 * @param nanos 鍑忓皯鐨勭撼绉掓暟
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minusNanos(Date date, long nanos) {
+		return DateUtil.minus(date, Duration.ofNanos(nanos));
+	}
+
+	/**
+	 * 鏃ユ湡鍑忓皯鏃堕棿閲�
+	 *
+	 * @param date   鏃堕棿
+	 * @param amount 鏃堕棿閲�
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	public static Date minus(Date date, TemporalAmount amount) {
+		Instant instant = date.toInstant();
+		return Date.from(instant.minus(amount));
+	}
+
+	/**
+	 * 璁剧疆鏃ユ湡灞炴��
+	 *
+	 * @param date          鏃堕棿
+	 * @param calendarField 鏇存敼鐨勫睘鎬�
+	 * @param amount        鏇存敼鏁帮紝-1琛ㄧず鍑忓皯
+	 * @return 璁剧疆鍚庣殑鏃堕棿
+	 */
+	private static Date set(Date date, int calendarField, int amount) {
+		Assert.notNull(date, "The date must not be null");
+		Calendar c = Calendar.getInstance();
+		c.setLenient(false);
+		c.setTime(date);
+		c.add(calendarField, amount);
+		return c.getTime();
+	}
+
+	/**
+	 * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param date 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDateTime(Date date) {
+		return DATETIME_FORMAT.format(date);
+	}
+
+	/**
+	 * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param date 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDateTimeMini(Date date) {
+		return DATETIME_MINI_FORMAT.format(date);
+	}
+
+	/**
+	 * 鏃ユ湡鏍煎紡鍖�
+	 *
+	 * @param date 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDate(Date date) {
+		return DATE_FORMAT.format(date);
+	}
+
+	/**
+	 * 鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param date 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatTime(Date date) {
+		return TIME_FORMAT.format(date);
+	}
+
+	/**
+	 * 鏃ユ湡鏍煎紡鍖�
+	 *
+	 * @param date    鏃堕棿
+	 * @param pattern 琛ㄨ揪寮�
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String format(Date date, String pattern) {
+		return ConcurrentDateFormat.of(pattern).format(date);
+	}
+
+	/**
+	 * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDateTime(TemporalAccessor temporal) {
+		return DATETIME_FORMATTER.format(temporal);
+	}
+
+	/**
+	 * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDateTimeMini(TemporalAccessor temporal) {
+		return DATETIME_MINI_FORMATTER.format(temporal);
+	}
+
+	/**
+	 * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatDate(TemporalAccessor temporal) {
+		return DATE_FORMATTER.format(temporal);
+	}
+
+	/**
+	 * java8 鏃堕棿鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String formatTime(TemporalAccessor temporal) {
+		return TIME_FORMATTER.format(temporal);
+	}
+
+	/**
+	 * java8 鏃ユ湡鏍煎紡鍖�
+	 *
+	 * @param temporal 鏃堕棿
+	 * @param pattern  琛ㄨ揪寮�
+	 * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+	 */
+	public static String format(TemporalAccessor temporal, String pattern) {
+		return DateTimeFormatter.ofPattern(pattern).format(temporal);
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param pattern 琛ㄨ揪寮�
+	 * @return 鏃堕棿
+	 */
+	public static Date parse(String dateStr, String pattern) {
+		ConcurrentDateFormat format = ConcurrentDateFormat.of(pattern);
+		try {
+			return format.parse(dateStr);
+		} catch (ParseException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param format  ConcurrentDateFormat
+	 * @return 鏃堕棿
+	 */
+	public static Date parse(String dateStr, ConcurrentDateFormat format) {
+		try {
+			return format.parse(dateStr);
+		} catch (ParseException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+	 *
+	 * @param dateStr 鏃堕棿瀛楃涓�
+	 * @param pattern 琛ㄨ揪寮�
+	 * @return 鏃堕棿
+	 */
+	public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
+		return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
+	}
+
+	/**
+	 * 鏃堕棿杞� Instant
+	 *
+	 * @param dateTime 鏃堕棿
+	 * @return Instant
+	 */
+	public static Instant toInstant(LocalDateTime dateTime) {
+		return dateTime.atZone(ZoneId.systemDefault()).toInstant();
+	}
+
+	/**
+	 * Instant 杞� 鏃堕棿
+	 *
+	 * @param instant Instant
+	 * @return Instant
+	 */
+	public static LocalDateTime toDateTime(Instant instant) {
+		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+	}
+
+	/**
+	 * 杞崲鎴� date
+	 *
+	 * @param dateTime LocalDateTime
+	 * @return Date
+	 */
+	public static Date toDate(LocalDateTime dateTime) {
+		return Date.from(DateUtil.toInstant(dateTime));
+	}
+
+	/**
+	 * 杞崲鎴� date
+	 *
+	 * @param localDate LocalDate
+	 * @return Date
+	 */
+	public static Date toDate(final LocalDate localDate) {
+		return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+	}
+
+	/**
+	 * Converts local date time to Calendar.
+	 */
+	public static Calendar toCalendar(final LocalDateTime localDateTime) {
+		return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
+	}
+
+	/**
+	 * localDateTime 杞崲鎴愭绉掓暟
+	 *
+	 * @param localDateTime LocalDateTime
+	 * @return long
+	 */
+	public static long toMilliseconds(final LocalDateTime localDateTime) {
+		return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+	}
+
+	/**
+	 * localDate 杞崲鎴愭绉掓暟
+	 *
+	 * @param localDate LocalDate
+	 * @return long
+	 */
+	public static long toMilliseconds(LocalDate localDate) {
+		return toMilliseconds(localDate.atStartOfDay());
+	}
+
+	/**
+	 * 杞崲鎴恓ava8 鏃堕棿
+	 *
+	 * @param calendar 鏃ュ巻
+	 * @return LocalDateTime
+	 */
+	public static LocalDateTime fromCalendar(final Calendar calendar) {
+		TimeZone tz = calendar.getTimeZone();
+		ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
+		return LocalDateTime.ofInstant(calendar.toInstant(), zid);
+	}
+
+	/**
+	 * 杞崲鎴恓ava8 鏃堕棿
+	 *
+	 * @param instant Instant
+	 * @return LocalDateTime
+	 */
+	public static LocalDateTime fromInstant(final Instant instant) {
+		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+	}
+
+	/**
+	 * 杞崲鎴恓ava8 鏃堕棿
+	 *
+	 * @param date Date
+	 * @return LocalDateTime
+	 */
+	public static LocalDateTime fromDate(final Date date) {
+		return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+	}
+
+	/**
+	 * 杞崲鎴恓ava8 鏃堕棿
+	 *
+	 * @param milliseconds 姣鏁�
+	 * @return LocalDateTime
+	 */
+	public static LocalDateTime fromMilliseconds(final long milliseconds) {
+		return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
+	}
+
+	/**
+	 * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨皬
+	 *
+	 * @param startInclusive 寮�濮嬫椂闂�
+	 * @param endExclusive   缁撴潫鏃堕棿
+	 * @return 鏃堕棿闂撮殧
+	 */
+	public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+		return Duration.between(startInclusive, endExclusive);
+	}
+
+	/**
+	 * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨ぇ锛屽勾鏈堟棩涓哄崟浣�
+	 *
+	 * @param startDate 寮�濮嬫椂闂�
+	 * @param endDate   缁撴潫鏃堕棿
+	 * @return 鏃堕棿闂撮殧
+	 */
+	public static Period between(LocalDate startDate, LocalDate endDate) {
+		return Period.between(startDate, endDate);
+	}
+
+	/**
+	 * 姣旇緝2涓� 鏃堕棿宸�
+	 *
+	 * @param startDate 寮�濮嬫椂闂�
+	 * @param endDate   缁撴潫鏃堕棿
+	 * @return 鏃堕棿闂撮殧
+	 */
+	public static Duration between(Date startDate, Date endDate) {
+		return Duration.between(startDate.toInstant(), endDate.toInstant());
+	}
+
+	/**
+	 * 灏嗙鏁拌浆鎹负鏃ユ椂鍒嗙
+	 *
+	 * @param second 绉掓暟
+	 * @return 鏃堕棿
+	 */
+	public static String secondToTime(Long second) {
+		// 鍒ゆ柇鏄惁涓虹┖
+		if (second == null || second == 0L) {
+			return StringPool.EMPTY;
+		}
+		//杞崲澶╂暟
+		long days = second / 86400;
+		//鍓╀綑绉掓暟
+		second = second % 86400;
+		//杞崲灏忔椂
+		long hours = second / 3600;
+		//鍓╀綑绉掓暟
+		second = second % 3600;
+		//杞崲鍒嗛挓
+		long minutes = second / 60;
+		//鍓╀綑绉掓暟
+		second = second % 60;
+		if (days > 0) {
+			return StringUtil.format("{}澶﹞}灏忔椂{}鍒唟}绉�", days, hours, minutes, second);
+		} else {
+			return StringUtil.format("{}灏忔椂{}鍒唟}绉�", hours, minutes, second);
+		}
+	}
+
+	/**
+	 * 鑾峰彇浠婂ぉ鐨勬棩鏈�
+	 *
+	 * @return 鏃堕棿
+	 */
+	public static String today() {
+		return format(new Date(), "yyyyMMdd");
+	}
+
+	/**
+	 * 鑾峰彇浠婂ぉ鐨勬椂闂�
+	 *
+	 * @return 鏃堕棿
+	 */
+	public static String time() {
+		return format(new Date(), PATTERN_DATETIME_MINI);
+	}
+
+	/**
+	 * 鑾峰彇浠婂ぉ鐨勫皬鏃舵暟
+	 *
+	 * @return 鏃堕棿
+	 */
+	public static Integer hour() {
+		return NumberUtil.toInt(format(new Date(), "HH"));
+	}
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java
new file mode 100644
index 0000000..5daa93e
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java
@@ -0,0 +1,433 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.DigestUtils;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 鍔犲瘑鐩稿叧宸ュ叿绫荤洿鎺ヤ娇鐢⊿pring util灏佽锛屽噺灏慾ar渚濊禆
+ *
+ * @author L.cm
+ */
+public class DigestUtil extends org.springframework.util.DigestUtils {
+    private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    /**
+     * Calculates the MD5 digest and returns the value as a 32 character hex string.
+     *
+     * @param data Data to digest
+     * @return MD5 digest as a hex string
+     */
+    public static String md5Hex(final String data) {
+        return DigestUtils.md5DigestAsHex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * Return a hexadecimal string representation of the MD5 digest of the given bytes.
+     *
+     * @param bytes the bytes to calculate the digest over
+     * @return a hexadecimal digest string
+     */
+    public static String md5Hex(final byte[] bytes) {
+        return DigestUtils.md5DigestAsHex(bytes);
+    }
+
+    /**
+     * sha1Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha1Hex(String data) {
+        return DigestUtil.sha1Hex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * sha1Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha1Hex(final byte[] bytes) {
+        return DigestUtil.digestHex("SHA-1", bytes);
+    }
+
+    /**
+     * SHA224Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha224Hex(String data) {
+        return DigestUtil.sha224Hex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * SHA224Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha224Hex(final byte[] bytes) {
+        return DigestUtil.digestHex("SHA-224", bytes);
+    }
+
+    /**
+     * sha256Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha256Hex(String data) {
+        return DigestUtil.sha256Hex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * sha256Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha256Hex(final byte[] bytes) {
+        return DigestUtil.digestHex("SHA-256", bytes);
+    }
+
+    /**
+     * sha384Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha384Hex(String data) {
+        return DigestUtil.sha384Hex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * sha384Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha384Hex(final byte[] bytes) {
+        return DigestUtil.digestHex("SHA-384", bytes);
+    }
+
+    /**
+     * sha512Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha512Hex(String data) {
+        return DigestUtil.sha512Hex(data.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * sha512Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha512Hex(final byte[] bytes) {
+        return DigestUtil.digestHex("SHA-512", bytes);
+    }
+
+    /**
+     * digest Hex
+     *
+     * @param algorithm 绠楁硶
+     * @param bytes     Data to digest
+     * @return digest as a hex string
+     */
+    public static String digestHex(String algorithm, byte[] bytes) {
+        try {
+            MessageDigest md = MessageDigest.getInstance(algorithm);
+            return encodeHex(md.digest(bytes));
+        } catch (NoSuchAlgorithmException e) {
+            throw Exceptions.unchecked(e);
+        }
+    }
+
+    /**
+     * hmacMd5 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacMd5Hex(String data, String key) {
+        return DigestUtil.hmacMd5Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacMd5 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacMd5Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacMD5", bytes, key);
+    }
+
+    /**
+     * hmacSha1 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha1Hex(String data, String key) {
+        return DigestUtil.hmacSha1Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha1 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha1Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacSHA1", bytes, key);
+    }
+
+    /**
+     * hmacSha224 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha224Hex(String data, String key) {
+        return DigestUtil.hmacSha224Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha224 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha224Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacSHA224", bytes, key);
+    }
+
+    /**
+     * hmacSha256
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static byte[] hmacSha256(String data, String key) {
+        return DigestUtil.hmacSha256(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha256
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a byte array
+     */
+    public static byte[] hmacSha256(final byte[] bytes, String key) {
+        return DigestUtil.digestHMac("HmacSHA256", bytes, key);
+    }
+
+    /**
+     * hmacSha256 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha256Hex(String data, String key) {
+        return DigestUtil.hmacSha256Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha256 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha256Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacSHA256", bytes, key);
+    }
+
+    /**
+     * hmacSha384 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha384Hex(String data, String key) {
+        return DigestUtil.hmacSha384Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha384 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha384Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacSHA384", bytes, key);
+    }
+
+    /**
+     * hmacSha512 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha512Hex(String data, String key) {
+        return DigestUtil.hmacSha512Hex(data.getBytes(Charsets.UTF_8), key);
+    }
+
+    /**
+     * hmacSha512 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha512Hex(final byte[] bytes, String key) {
+        return DigestUtil.digestHMacHex("HmacSHA512", bytes, key);
+    }
+
+    /**
+     * digest HMac Hex
+     *
+     * @param algorithm 绠楁硶
+     * @param bytes     Data to digest
+     * @return digest as a hex string
+     */
+    public static String digestHMacHex(String algorithm, final byte[] bytes, String key) {
+        SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
+        try {
+            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
+            mac.init(secretKey);
+            return DigestUtil.encodeHex(mac.doFinal(bytes));
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            throw Exceptions.unchecked(e);
+        }
+    }
+
+    /**
+     * digest HMac
+     *
+     * @param algorithm 绠楁硶
+     * @param bytes     Data to digest
+     * @return digest as a byte array
+     */
+    public static byte[] digestHMac(String algorithm, final byte[] bytes, String key) {
+        SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
+        try {
+            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
+            mac.init(secretKey);
+            return mac.doFinal(bytes);
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            throw Exceptions.unchecked(e);
+        }
+    }
+
+    /**
+     * encode Hex
+     *
+     * @param bytes Data to Hex
+     * @return bytes as a hex string
+     */
+    public static String encodeHex(byte[] bytes) {
+        StringBuilder r = new StringBuilder(bytes.length * 2);
+        for (byte b : bytes) {
+            r.append(HEX_CODE[(b >> 4) & 0xF]);
+            r.append(HEX_CODE[(b & 0xF)]);
+        }
+        return r.toString();
+    }
+
+    /**
+     * decode Hex
+     *
+     * @param hexStr Hex string
+     * @return decode hex to bytes
+     */
+    public static byte[] decodeHex(final String hexStr) {
+        return DatatypeConverterUtil.parseHexBinary(hexStr);
+    }
+
+    /**
+     * 姣旇緝瀛楃涓诧紝閬垮厤瀛楃涓插洜涓鸿繃闀匡紝浜х敓鑰楁椂
+     *
+     * @param a String
+     * @param b String
+     * @return 鏄惁鐩稿悓
+     */
+    public static boolean slowEquals(@Nullable String a, @Nullable String b) {
+        if (a == null || b == null) {
+            return false;
+        }
+        return DigestUtil.slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8));
+    }
+
+    /**
+     * 姣旇緝 byte 鏁扮粍锛岄伩鍏嶅瓧绗︿覆鍥犱负杩囬暱锛屼骇鐢熻�楁椂
+     *
+     * @param a byte array
+     * @param b byte array
+     * @return 鏄惁鐩稿悓
+     */
+    public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) {
+        if (a == null || b == null) {
+            return false;
+        }
+        if (a.length != b.length) {
+            return false;
+        }
+        int diff = a.length ^ b.length;
+        for (int i = 0; i < a.length; i++) {
+            diff |= a[i] ^ b[i];
+        }
+        return diff == 0;
+    }
+
+    /**
+     * 鑷畾涔夊姞瀵� 灏嗗墠绔紶閫掔殑瀵嗙爜鍐嶆鍔犲瘑
+     *
+     * @param data 鏁版嵁
+     * @return {String}
+     */
+    public static String hex(String data) {
+        if (StringUtil.isBlank(data)) {
+            return StringPool.EMPTY;
+        }
+        return sha1Hex(data);
+    }
+
+    /**
+     * 鐢ㄦ埛瀵嗙爜鍔犲瘑瑙勫垯 鍏圡D5鍐峉HA1
+     *
+     * @param data 鏁版嵁
+     * @return {String}
+     */
+    public static String encrypt(String data) {
+        if (StringUtil.isBlank(data)) {
+            return StringPool.EMPTY;
+        }
+        return sha1Hex(md5Hex(data));
+    }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java
new file mode 100644
index 0000000..b43a584
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java
@@ -0,0 +1,99 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import cn.hutool.core.io.FastStringWriter;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+
+/**
+ * 寮傚父澶勭悊宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class Exceptions {
+
+	/**
+	 * 灏咰heckedException杞崲涓篣ncheckedException.
+	 *
+	 * @param e Throwable
+	 * @return {RuntimeException}
+	 */
+	public static RuntimeException unchecked(Throwable e) {
+		if (e instanceof Error) {
+			throw (Error) e;
+		} else if (e instanceof IllegalAccessException ||
+			e instanceof IllegalArgumentException ||
+			e instanceof NoSuchMethodException) {
+			return new IllegalArgumentException(e);
+		} else if (e instanceof InvocationTargetException) {
+			return new RuntimeException(((InvocationTargetException) e).getTargetException());
+		} else if (e instanceof RuntimeException) {
+			return (RuntimeException) e;
+		} else if (e instanceof InterruptedException) {
+			Thread.currentThread().interrupt();
+		}
+		return Exceptions.runtime(e);
+	}
+
+	/**
+	 * 涓嶉噰鐢� RuntimeException 鍖呰锛岀洿鎺ユ姏鍑猴紝浣垮紓甯告洿鍔犵簿鍑�
+	 *
+	 * @param throwable Throwable
+	 * @param <T>       娉涘瀷鏍囪
+	 * @return Throwable
+	 * @throws T 娉涘瀷
+	 */
+	@SuppressWarnings("unchecked")
+	private static <T extends Throwable> T runtime(Throwable throwable) throws T {
+		throw (T) throwable;
+	}
+
+	/**
+	 * 浠g悊寮傚父瑙e寘
+	 *
+	 * @param wrapped 鍖呰杩囧緱寮傚父
+	 * @return 瑙e寘鍚庣殑寮傚父
+	 */
+	public static Throwable unwrap(Throwable wrapped) {
+		Throwable unwrapped = wrapped;
+		while (true) {
+			if (unwrapped instanceof InvocationTargetException) {
+				unwrapped = ((InvocationTargetException) unwrapped).getTargetException();
+			} else if (unwrapped instanceof UndeclaredThrowableException) {
+				unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable();
+			} else {
+				return unwrapped;
+			}
+		}
+	}
+
+	/**
+	 * 灏咵rrorStack杞寲涓篠tring.
+	 *
+	 * @param ex Throwable
+	 * @return {String}
+	 */
+	public static String getStackTraceAsString(Throwable ex) {
+		FastStringWriter stringWriter = new FastStringWriter();
+		ex.printStackTrace(new PrintWriter(stringWriter));
+		return stringWriter.toString();
+	}
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java
new file mode 100644
index 0000000..be66a55
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java
@@ -0,0 +1,383 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.FileSystemUtils;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鏂囦欢宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class FileUtil extends org.springframework.util.FileCopyUtils {
+
+	/**
+	 * 榛樿涓簍rue
+	 *
+	 * @author L.cm
+	 */
+	public static class TrueFilter implements FileFilter, Serializable {
+		private static final long serialVersionUID = -6420452043795072619L;
+
+		public final static TrueFilter TRUE = new TrueFilter();
+
+		@Override
+		public boolean accept(File pathname) {
+			return true;
+		}
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param path 璺緞
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(String path) {
+		File file = new File(path);
+		return list(file, TrueFilter.TRUE);
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param path   璺緞
+	 * @param fileNamePattern 鏂囦欢鍚� * 鍙�
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(String path, final String fileNamePattern) {
+		File file = new File(path);
+		return list(file, pathname -> {
+			String fileName = pathname.getName();
+			return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
+		});
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param path   璺緞
+	 * @param filter 鏂囦欢杩囨护
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(String path, FileFilter filter) {
+		File file = new File(path);
+		return list(file, filter);
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param file 鏂囦欢
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(File file) {
+		List<File> fileList = new ArrayList<>();
+		return list(file, fileList, TrueFilter.TRUE);
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param file   鏂囦欢
+	 * @param fileNamePattern Spring AntPathMatcher 瑙勫垯
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(File file, final String fileNamePattern) {
+		List<File> fileList = new ArrayList<>();
+		return list(file, fileList, pathname -> {
+			String fileName = pathname.getName();
+			return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
+		});
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param file   鏂囦欢
+	 * @param filter 鏂囦欢杩囨护
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	public static List<File> list(File file, FileFilter filter) {
+		List<File> fileList = new ArrayList<>();
+		return list(file, fileList, filter);
+	}
+
+	/**
+	 * 鎵弿鐩綍涓嬬殑鏂囦欢
+	 *
+	 * @param file   鏂囦欢
+	 * @param filter 鏂囦欢杩囨护
+	 * @return 鏂囦欢闆嗗悎
+	 */
+	private static List<File> list(File file, List<File> fileList, FileFilter filter) {
+		if (file.isDirectory()) {
+			File[] files = file.listFiles();
+			if (files != null) {
+				for (File f : files) {
+					list(f, fileList, filter);
+				}
+			}
+		} else {
+			// 杩囨护鏂囦欢
+			boolean accept = filter.accept(file);
+			if (file.exists() && accept) {
+				fileList.add(file);
+			}
+		}
+		return fileList;
+	}
+
+	/**
+	 * 鑾峰彇鏂囦欢鍚庣紑鍚�
+	 * @param fullName 鏂囦欢鍏ㄥ悕
+	 * @return {String}
+	 */
+	public static String getFileExtension(String fullName) {
+		if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
+		String fileName = new File(fullName).getName();
+		int dotIndex = fileName.lastIndexOf(CharPool.DOT);
+		return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
+	}
+
+	/**
+	 * 鑾峰彇鏂囦欢鍚嶏紝鍘婚櫎鍚庣紑鍚�
+	 * @param fullName 鏂囦欢鍏ㄥ悕
+	 * @return {String}
+	 */
+	public static String getNameWithoutExtension(String fullName) {
+		if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
+		String fileName = new File(fullName).getName();
+		int dotIndex = fileName.lastIndexOf(CharPool.DOT);
+		return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
+	}
+
+	/**
+	 * Returns the path to the system temporary directory.
+	 *
+	 * @return the path to the system temporary directory.
+	 */
+	public static String getTempDirPath() {
+		return System.getProperty("java.io.tmpdir");
+	}
+
+	/**
+	 * Returns a {@link File} representing the system temporary directory.
+	 *
+	 * @return the system temporary directory.
+	 */
+	public static File getTempDir() {
+		return new File(getTempDirPath());
+	}
+
+	/**
+	 * Reads the contents of a file into a String.
+	 * The file is always closed.
+	 *
+	 * @param file the file to read, must not be {@code null}
+	 * @return the file contents, never {@code null}
+	 */
+	public static String readToString(final File file) {
+		return readToString(file, Charsets.UTF_8);
+	}
+
+	/**
+	 * Reads the contents of a file into a String.
+	 * The file is always closed.
+	 *
+	 * @param file     the file to read, must not be {@code null}
+	 * @param encoding the encoding to use, {@code null} means platform default
+	 * @return the file contents, never {@code null}
+	 */
+	public static String readToString(final File file, final Charset encoding) {
+		try (InputStream in = Files.newInputStream(file.toPath())) {
+			return IoUtil.readToString(in, encoding);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * Reads the contents of a file into a String.
+	 * The file is always closed.
+	 *
+	 * @param file     the file to read, must not be {@code null}
+	 * @return the file contents, never {@code null}
+	 */
+	public static byte[] readToByteArray(final File file) {
+		try (InputStream in = Files.newInputStream(file.toPath())) {
+			return IoUtil.readToByteArray(in);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * Writes a String to a file creating the file if it does not exist.
+	 *
+	 * @param file the file to write
+	 * @param data the content to write to the file
+	 */
+	public static void writeToFile(final File file, final String data) {
+		writeToFile(file, data, Charsets.UTF_8, false);
+	}
+
+	/**
+	 * Writes a String to a file creating the file if it does not exist.
+	 *
+	 * @param file   the file to write
+	 * @param data   the content to write to the file
+	 * @param append if {@code true}, then the String will be added to the
+	 *               end of the file rather than overwriting
+	 */
+	public static void writeToFile(final File file, final String data, final boolean append){
+		writeToFile(file, data, Charsets.UTF_8, append);
+	}
+
+	/**
+	 * Writes a String to a file creating the file if it does not exist.
+	 *
+	 * @param file     the file to write
+	 * @param data     the content to write to the file
+	 * @param encoding the encoding to use, {@code null} means platform default
+	 */
+	public static void writeToFile(final File file, final String data, final Charset encoding) {
+		writeToFile(file, data, encoding, false);
+	}
+
+	/**
+	 * Writes a String to a file creating the file if it does not exist.
+	 *
+	 * @param file     the file to write
+	 * @param data     the content to write to the file
+	 * @param encoding the encoding to use, {@code null} means platform default
+	 * @param append   if {@code true}, then the String will be added to the
+	 *                 end of the file rather than overwriting
+	 */
+	public static void writeToFile(final File file, final String data, final Charset encoding, final boolean append) {
+		try (OutputStream out = new FileOutputStream(file, append)) {
+			IoUtil.write(data, out, encoding);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 杞垚file
+	 * @param multipartFile MultipartFile
+	 * @param file File
+	 */
+	public static void toFile(MultipartFile multipartFile, final File file) {
+		try {
+			FileUtil.toFile(multipartFile.getInputStream(), file);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 杞垚file
+	 * @param in InputStream
+	 * @param file File
+	 */
+	public static void toFile(InputStream in, final File file) {
+		try (OutputStream out = new FileOutputStream(file)) {
+			FileUtil.copy(in, out);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * Moves a file.
+	 * <p>
+	 * When the destination file is on another file system, do a "copy and delete".
+	 *
+	 * @param srcFile  the file to be moved
+	 * @param destFile the destination file
+	 * @throws NullPointerException if source or destination is {@code null}
+	 * @throws IOException          if source or destination is invalid
+	 * @throws IOException          if an IO error occurs moving the file
+	 */
+	public static void moveFile(final File srcFile, final File destFile) throws IOException {
+		Assert.notNull(srcFile, "Source must not be null");
+		Assert.notNull(destFile, "Destination must not be null");
+		if (!srcFile.exists()) {
+			throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
+		}
+		if (srcFile.isDirectory()) {
+			throw new IOException("Source '" + srcFile + "' is a directory");
+		}
+		if (destFile.exists()) {
+			throw new IOException("Destination '" + destFile + "' already exists");
+		}
+		if (destFile.isDirectory()) {
+			throw new IOException("Destination '" + destFile + "' is a directory");
+		}
+		final boolean rename = srcFile.renameTo(destFile);
+		if (!rename) {
+			FileUtil.copy(srcFile, destFile);
+			if (!srcFile.delete()) {
+				FileUtil.deleteQuietly(destFile);
+				throw new IOException("Failed to delete original file '" + srcFile + "' after copy to '" + destFile + "'");
+			}
+		}
+	}
+
+	/**
+	 * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
+	 * <p>
+	 * The difference between File.delete() and this method are:
+	 * <ul>
+	 * <li>A directory to be deleted does not have to be empty.</li>
+	 * <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
+	 * </ul>
+	 *
+	 * @param file file or directory to delete, can be {@code null}
+	 * @return {@code true} if the file or directory was deleted, otherwise
+	 * {@code false}
+	 */
+	public static boolean deleteQuietly(@Nullable final File file) {
+		if (file == null) {
+			return false;
+		}
+		try {
+			if (file.isDirectory()) {
+				FileSystemUtils.deleteRecursively(file);
+			}
+		} catch (final Exception ignored) {
+		}
+
+		try {
+			return file.delete();
+		} catch (final Exception ignored) {
+			return false;
+		}
+	}
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java
new file mode 100644
index 0000000..4d14c13
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java
@@ -0,0 +1,2144 @@
+package com.vci.web.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import com.aspose.words.ConvertUtil;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jndi.toolkit.url.UrlUtil;
+import com.vci.web.util.jackson.JsonUtil;
+import org.springframework.util.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.lang.Nullable;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.method.HandlerMethod;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.text.DecimalFormat;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.*;
+import java.util.function.Supplier;
+
+/**
+ * 宸ュ叿鍖呴泦鍚堬紝宸ュ叿绫诲揩鎹锋柟寮�
+ *
+ * @author L.cm
+ */
+public class Func {
+
+    /**
+     * 鏂█锛屽繀椤讳笉鑳戒负 null
+     * <blockquote><pre>
+     * public Foo(Bar bar) {
+     *     this.bar = $.requireNotNull(bar);
+     * }
+     * </pre></blockquote>
+     *
+     * @param obj the object reference to check for nullity
+     * @param <T> the type of the reference
+     * @return {@code obj} if not {@code null}
+     * @throws NullPointerException if {@code obj} is {@code null}
+     */
+    public static <T> T requireNotNull(T obj) {
+        return Objects.requireNonNull(obj);
+    }
+
+    /**
+     * 鏂█锛屽繀椤讳笉鑳戒负 null
+     * <blockquote><pre>
+     * public Foo(Bar bar, Baz baz) {
+     *     this.bar = $.requireNotNull(bar, "bar must not be null");
+     *     this.baz = $.requireNotNull(baz, "baz must not be null");
+     * }
+     * </pre></blockquote>
+     *
+     * @param obj     the object reference to check for nullity
+     * @param message detail message to be used in the event that a {@code
+     *                NullPointerException} is thrown
+     * @param <T>     the type of the reference
+     * @return {@code obj} if not {@code null}
+     * @throws NullPointerException if {@code obj} is {@code null}
+     */
+    public static <T> T requireNotNull(T obj, String message) {
+        return Objects.requireNonNull(obj, message);
+    }
+
+    /**
+     * 鏂█锛屽繀椤讳笉鑳戒负 null
+     * <blockquote><pre>
+     * public Foo(Bar bar, Baz baz) {
+     *     this.bar = $.requireNotNull(bar, () -> "bar must not be null");
+     * }
+     * </pre></blockquote>
+     *
+     * @param obj             the object reference to check for nullity
+     * @param messageSupplier supplier of the detail message to be
+     *                        used in the event that a {@code NullPointerException} is thrown
+     * @param <T>             the type of the reference
+     * @return {@code obj} if not {@code null}
+     * @throws NullPointerException if {@code obj} is {@code null}
+     */
+    public static <T> T requireNotNull(T obj, Supplier<String> messageSupplier) {
+        return Objects.requireNonNull(obj, messageSupplier);
+    }
+
+    /**
+     * 鍒ゆ柇瀵硅薄鏄惁涓簄ull
+     * <p>
+     * This method exists to be used as a
+     * {@link java.util.function.Predicate}, {@code filter($::isNull)}
+     * </p>
+     *
+     * @param obj a reference to be checked against {@code null}
+     * @return {@code true} if the provided reference is {@code null} otherwise
+     * {@code false}
+     * @see java.util.function.Predicate
+     */
+    public static boolean isNull(@Nullable Object obj) {
+        return Objects.isNull(obj);
+    }
+
+    /**
+     * 鍒ゆ柇瀵硅薄鏄惁 not null
+     * <p>
+     * This method exists to be used as a
+     * {@link java.util.function.Predicate}, {@code filter($::notNull)}
+     * </p>
+     *
+     * @param obj a reference to be checked against {@code null}
+     * @return {@code true} if the provided reference is non-{@code null}
+     * otherwise {@code false}
+     * @see java.util.function.Predicate
+     */
+    public static boolean notNull(@Nullable Object obj) {
+        return Objects.nonNull(obj);
+    }
+
+    /**
+     * 棣栧瓧姣嶅彉灏忓啓
+     *
+     * @param str 瀛楃涓�
+     * @return {String}
+     */
+    public static String firstCharToLower(String str) {
+        return StringUtil.firstCharToLower(str);
+    }
+
+    /**
+     * 棣栧瓧姣嶅彉澶у啓
+     *
+     * @param str 瀛楃涓�
+     * @return {String}
+     */
+    public static String firstCharToUpper(String str) {
+        return StringUtil.firstCharToUpper(str);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁涓虹┖瀛楃涓�
+     * <pre class="code">
+     * $.isBlank(null)		= true
+     * $.isBlank("")		= true
+     * $.isBlank(" ")		= true
+     * $.isBlank("12345")	= false
+     * $.isBlank(" 12345 ")	= false
+     * </pre>
+     *
+     * @param cs the {@code CharSequence} to check (may be {@code null})
+     * @return {@code true} if the {@code CharSequence} is not {@code null},
+     * its length is greater than 0, and it does not contain whitespace only
+     * @see Character#isWhitespace
+     */
+    public static boolean isBlank(@Nullable final CharSequence cs) {
+        return StringUtil.isBlank(cs);
+    }
+
+    /**
+     * 鍒ゆ柇涓嶄负绌哄瓧绗︿覆
+     * <pre>
+     * $.isNotBlank(null)	= false
+     * $.isNotBlank("")		= false
+     * $.isNotBlank(" ")	= false
+     * $.isNotBlank("bob")	= true
+     * $.isNotBlank("  bob  ") = true
+     * </pre>
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is
+     * not empty and not null and not whitespace
+     * @see Character#isWhitespace
+     */
+    public static boolean isNotBlank(@Nullable final CharSequence cs) {
+        return StringUtil.isNotBlank(cs);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁鏈変换鎰忎竴涓� 绌哄瓧绗︿覆
+     *
+     * @param css CharSequence
+     * @return boolean
+     */
+    public static boolean isAnyBlank(final CharSequence... css) {
+        return StringUtil.isAnyBlank(css);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁鍏ㄤ负闈炵┖瀛楃涓�
+     *
+     * @param css CharSequence
+     * @return boolean
+     */
+    public static boolean isNoneBlank(final CharSequence... css) {
+        return StringUtil.isNoneBlank(css);
+    }
+
+    /**
+     * 鍒ゆ柇瀵硅薄鏄暟缁�
+     *
+     * @param obj the object to check
+     * @return 鏄惁鏁扮粍
+     */
+    public static boolean isArray(@Nullable Object obj) {
+        return ObjectUtil.isArray(obj);
+    }
+
+    /**
+     * 鍒ゆ柇绌哄璞� object銆乵ap銆乴ist銆乻et銆佸瓧绗︿覆銆佹暟缁�
+     *
+     * @param obj the object to check
+     * @return 鏁扮粍鏄惁涓虹┖
+     */
+    public static boolean isEmpty(@Nullable Object obj) {
+        return ObjectUtil.isEmpty(obj);
+    }
+
+    /**
+     * 瀵硅薄涓嶄负绌� object銆乵ap銆乴ist銆乻et銆佸瓧绗︿覆銆佹暟缁�
+     *
+     * @param obj the object to check
+     * @return 鏄惁涓嶄负绌�
+     */
+    public static boolean isNotEmpty(@Nullable Object obj) {
+        return !ObjectUtil.isEmpty(obj);
+    }
+
+    /**
+     * 鍒ゆ柇鏁扮粍涓虹┖
+     *
+     * @param array the array to check
+     * @return 鏁扮粍鏄惁涓虹┖
+     */
+    public static boolean isEmpty(@Nullable Object[] array) {
+        return ObjectUtil.isEmpty(array);
+    }
+
+    /**
+     * 鍒ゆ柇鏁扮粍涓嶄负绌�
+     *
+     * @param array 鏁扮粍
+     * @return 鏁扮粍鏄惁涓嶄负绌�
+     */
+    public static boolean isNotEmpty(@Nullable Object[] array) {
+        return ObjectUtil.isNotEmpty(array);
+    }
+
+    /**
+     * 瀵硅薄缁勪腑鏄惁瀛樺湪 Empty Object
+     *
+     * @param os 瀵硅薄缁�
+     * @return boolean
+     */
+    public static boolean hasEmpty(Object... os) {
+        for (Object o : os) {
+            if (isEmpty(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 瀵硅薄缁勪腑鏄惁鍏ㄩ儴涓� Empty Object
+     *
+     * @param os 瀵硅薄缁�
+     * @return boolean
+     */
+    public static boolean isAllEmpty(Object... os) {
+        for (Object o : os) {
+            if (isNotEmpty(o)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆涓壒瀹氭ā寮忕殑瀛楃杞崲鎴恗ap涓搴旂殑鍊�
+     * <p>
+     * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
+     *
+     * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+     * @param params  杞崲鎵�闇�鐨勯敭鍊煎闆嗗悎
+     * @return 杞崲鍚庣殑瀛楃涓�
+     */
+    public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
+        return StringUtil.format(message, params);
+    }
+
+    /**
+     * 鍚� log 鏍煎紡鐨� format 瑙勫垯
+     * <p>
+     * use: format("my name is {}, and i like {}!", "L.cm", "Java")
+     *
+     * @param message   闇�瑕佽浆鎹㈢殑瀛楃涓�
+     * @param arguments 闇�瑕佹浛鎹㈢殑鍙橀噺
+     * @return 杞崲鍚庣殑瀛楃涓�
+     */
+    public static String format(@Nullable String message, @Nullable Object... arguments) {
+        return StringUtil.format(message, arguments);
+    }
+
+    /**
+     * 鏍煎紡鍖栨墽琛屾椂闂达紝鍗曚綅涓� ms 鍜� s锛屼繚鐣欎笁浣嶅皬鏁�
+     *
+     * @param nanos 绾崇
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String format(long nanos) {
+        return StringUtil.format(nanos);
+    }
+
+    /**
+     * 姣旇緝涓や釜瀵硅薄鏄惁鐩哥瓑銆�<br>
+     * 鐩稿悓鐨勬潯浠舵湁涓や釜锛屾弧瓒冲叾涓�鍗冲彲锛�<br>
+     *
+     * @param obj1 瀵硅薄1
+     * @param obj2 瀵硅薄2
+     * @return 鏄惁鐩哥瓑
+     */
+    public static boolean equals(Object obj1, Object obj2) {
+        return Objects.equals(obj1, obj2);
+    }
+
+    /**
+     * 瀹夊叏鐨� equals
+     *
+     * @param o1 first Object to compare
+     * @param o2 second Object to compare
+     * @return whether the given objects are equal
+     * @see Object#equals(Object)
+     * @see java.util.Arrays#equals
+     */
+    public static boolean equalsSafe(@Nullable Object o1, @Nullable Object o2) {
+        return ObjectUtil.nullSafeEquals(o1, o2);
+    }
+
+    /**
+     * 鍒ゆ柇鏁扮粍涓槸鍚﹀寘鍚厓绱�
+     *
+     * @param array   the Array to check
+     * @param element the element to look for
+     * @param <T>     The generic tag
+     * @return {@code true} if found, {@code false} else
+     */
+    public static <T> boolean contains(@Nullable T[] array, final T element) {
+        return CollectionUtil.contains(array, element);
+    }
+
+    /**
+     * 鍒ゆ柇杩唬鍣ㄤ腑鏄惁鍖呭惈鍏冪礌
+     *
+     * @param iterator the Iterator to check
+     * @param element  the element to look for
+     * @return {@code true} if found, {@code false} otherwise
+     */
+    public static boolean contains(@Nullable Iterator<?> iterator, Object element) {
+        return CollectionUtil.contains(iterator, element);
+    }
+
+    /**
+     * 鍒ゆ柇鏋氫妇鏄惁鍖呭惈璇ュ厓绱�
+     *
+     * @param enumeration the Enumeration to check
+     * @param element     the element to look for
+     * @return {@code true} if found, {@code false} otherwise
+     */
+    public static boolean contains(@Nullable Enumeration<?> enumeration, Object element) {
+        return CollectionUtil.contains(enumeration, element);
+    }
+
+    /**
+     * 涓嶅彲鍙� Set
+     *
+     * @param es  瀵硅薄
+     * @param <E> 娉涘瀷
+     * @return 闆嗗悎
+     */
+    @SafeVarargs
+    public static <E> Set<E> ofImmutableSet(E... es) {
+        return CollectionUtil.ofImmutableSet(es);
+    }
+
+    /**
+     * 涓嶅彲鍙� List
+     *
+     * @param es  瀵硅薄
+     * @param <E> 娉涘瀷
+     * @return 闆嗗悎
+     */
+    @SafeVarargs
+    public static <E> List<E> ofImmutableList(E... es) {
+        return CollectionUtil.ofImmutableList(es);
+    }
+
+    /**
+     * 寮鸿浆string,骞跺幓鎺夊浣欑┖鏍�
+     *
+     * @param str 瀛楃涓�
+     * @return {String}
+     */
+    public static String toStr(Object str) {
+        return toStr(str, "");
+    }
+
+    /**
+     * 寮鸿浆string,骞跺幓鎺夊浣欑┖鏍�
+     *
+     * @param str          瀛楃涓�
+     * @param defaultValue 榛樿鍊�
+     * @return {String}
+     */
+    public static String toStr(Object str, String defaultValue) {
+        if (null == str || str.equals(StringPool.NULL)) {
+            return defaultValue;
+        }
+        return String.valueOf(str);
+    }
+
+    /**
+     * 寮鸿浆string(鍖呭惈绌哄瓧绗︿覆),骞跺幓鎺夊浣欑┖鏍�
+     *
+     * @param str          瀛楃涓�
+     * @param defaultValue 榛樿鍊�
+     * @return {String}
+     */
+    public static String toStrWithEmpty(Object str, String defaultValue) {
+        if (null == str || str.equals(StringPool.NULL) || str.equals(StringPool.EMPTY)) {
+            return defaultValue;
+        }
+        return String.valueOf(str);
+    }
+
+
+    /**
+     * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁鏄暟瀛�
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {boolean}
+     */
+    public static boolean isNumeric(final CharSequence cs) {
+        return StringUtil.isNumeric(cs);
+    }
+
+    /**
+     * 瀛楃涓茶浆 int锛屼负绌哄垯杩斿洖0
+     *
+     * <pre>
+     *   $.toInt(null) = 0
+     *   $.toInt("")   = 0
+     *   $.toInt("1")  = 1
+     * </pre>
+     *
+     * @param str the string to convert, may be null
+     * @return the int represented by the string, or <code>zero</code> if
+     * conversion fails
+     */
+    public static int toInt(final Object str) {
+        return NumberUtil.toInt(String.valueOf(str));
+    }
+
+    /**
+     * 瀛楃涓茶浆 int锛屼负绌哄垯杩斿洖榛樿鍊�
+     *
+     * <pre>
+     *   $.toInt(null, 1) = 1
+     *   $.toInt("", 1)   = 1
+     *   $.toInt("1", 0)  = 1
+     * </pre>
+     *
+     * @param str          the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static int toInt(@Nullable final Object str, final int defaultValue) {
+        return NumberUtil.toInt(String.valueOf(str), defaultValue);
+    }
+
+    /**
+     * 瀛楃涓茶浆 long锛屼负绌哄垯杩斿洖0
+     *
+     * <pre>
+     *   $.toLong(null) = 0L
+     *   $.toLong("")   = 0L
+     *   $.toLong("1")  = 1L
+     * </pre>
+     *
+     * @param str the string to convert, may be null
+     * @return the long represented by the string, or <code>0</code> if
+     * conversion fails
+     */
+    public static long toLong(final Object str) {
+        return NumberUtil.toLong(String.valueOf(str));
+    }
+
+    /**
+     * 瀛楃涓茶浆 long锛屼负绌哄垯杩斿洖榛樿鍊�
+     *
+     * <pre>
+     *   $.toLong(null, 1L) = 1L
+     *   $.toLong("", 1L)   = 1L
+     *   $.toLong("1", 0L)  = 1L
+     * </pre>
+     *
+     * @param str          the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the long represented by the string, or the default if conversion fails
+     */
+    public static long toLong(@Nullable final Object str, final long defaultValue) {
+        return NumberUtil.toLong(String.valueOf(str), defaultValue);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toDouble(null, 1) = 1.0
+     *   $.toDouble("", 1)   = 1.0
+     *   $.toDouble("1", 0)  = 1.0
+     * </pre>
+     *
+     * @param value the string to convert, may be null
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Double toDouble(Object value) {
+        return toDouble(String.valueOf(value), -1.00);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toDouble(null, 1) = 1.0
+     *   $.toDouble("", 1)   = 1.0
+     *   $.toDouble("1", 0)  = 1.0
+     * </pre>
+     *
+     * @param value        the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Double toDouble(Object value, Double defaultValue) {
+        return NumberUtil.toDouble(String.valueOf(value), defaultValue);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toFloat(null, 1) = 1.00f
+     *   $.toFloat("", 1)   = 1.00f
+     *   $.toFloat("1", 0)  = 1.00f
+     * </pre>
+     *
+     * @param value the string to convert, may be null
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Float toFloat(Object value) {
+        return toFloat(String.valueOf(value), -1.0f);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toFloat(null, 1) = 1.00f
+     *   $.toFloat("", 1)   = 1.00f
+     *   $.toFloat("1", 0)  = 1.00f
+     * </pre>
+     *
+     * @param value        the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Float toFloat(Object value, Float defaultValue) {
+        return NumberUtil.toFloat(String.valueOf(value), defaultValue);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toBoolean("true", true)  = true
+     *   $.toBoolean("false")   	= false
+     *   $.toBoolean("", false)  	= false
+     * </pre>
+     *
+     * @param value the string to convert, may be null
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Boolean toBoolean(Object value) {
+        return toBoolean(value, null);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   $.toBoolean("true", true)  = true
+     *   $.toBoolean("false")   	= false
+     *   $.toBoolean("", false)  	= false
+     * </pre>
+     *
+     * @param value        the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static Boolean toBoolean(Object value, Boolean defaultValue) {
+        if (value != null) {
+            String val = String.valueOf(value);
+            val = val.toLowerCase().trim();
+            return Boolean.parseBoolean(val);
+        }
+        return defaultValue;
+    }
+
+    /**
+     * 杞崲涓篒nteger鏁扮粍<br>
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Integer[] toIntArray(String str) {
+        return toIntArray(",", str);
+    }
+
+    /**
+     * 杞崲涓篒nteger鏁扮粍<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Integer[] toIntArray(String split, String str) {
+        if (StringUtil.isEmpty(str)) {
+            return new Integer[]{};
+        }
+        String[] arr = str.split(split);
+        final Integer[] ints = new Integer[arr.length];
+        for (int i = 0; i < arr.length; i++) {
+            final Integer v = toInt(arr[i], 0);
+            ints[i] = v;
+        }
+        return ints;
+    }
+
+    /**
+     * 杞崲涓篒nteger闆嗗悎<br>
+     *
+     * @param str 缁撴灉琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<Integer> toIntList(String str) {
+        return Arrays.asList(toIntArray(str));
+    }
+
+    /**
+     * 杞崲涓篒nteger闆嗗悎<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<Integer> toIntList(String split, String str) {
+        return Arrays.asList(toIntArray(split, str));
+    }
+
+    /**
+     * 鑾峰彇绗竴浣岻nteger鏁板��
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Integer firstInt(String str) {
+        return firstInt(",", str);
+    }
+
+    /**
+     * 鑾峰彇绗竴浣岻nteger鏁板��
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Integer firstInt(String split, String str) {
+        List<Integer> ints = toIntList(split, str);
+        if (isEmpty(ints)) {
+            return null;
+        } else {
+            return ints.get(0);
+        }
+    }
+
+    /**
+     * 杞崲涓篖ong鏁扮粍<br>
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Long[] toLongArray(String str) {
+        return toLongArray(",", str);
+    }
+
+    /**
+     * 杞崲涓篖ong鏁扮粍<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Long[] toLongArray(String split, String str) {
+        if (StringUtil.isEmpty(str)) {
+            return new Long[]{};
+        }
+        String[] arr = str.split(split);
+        final Long[] longs = new Long[arr.length];
+        for (int i = 0; i < arr.length; i++) {
+            final Long v = toLong(arr[i], 0);
+            longs[i] = v;
+        }
+        return longs;
+    }
+
+    /**
+     * 杞崲涓篖ong闆嗗悎<br>
+     *
+     * @param str 缁撴灉琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<Long> toLongList(String str) {
+        return Arrays.asList(toLongArray(str));
+    }
+
+    /**
+     * 杞崲涓篖ong闆嗗悎<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<Long> toLongList(String split, String str) {
+        return Arrays.asList(toLongArray(split, str));
+    }
+
+    /**
+     * 鑾峰彇绗竴浣峀ong鏁板��
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Long firstLong(String str) {
+        return firstLong(",", str);
+    }
+
+    /**
+     * 鑾峰彇绗竴浣峀ong鏁板��
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static Long firstLong(String split, String str) {
+        List<Long> longs = toLongList(split, str);
+        if (isEmpty(longs)) {
+            return null;
+        } else {
+            return longs.get(0);
+        }
+    }
+
+    /**
+     * 杞崲涓篠tring鏁扮粍<br>
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static String[] toStrArray(String str) {
+        return toStrArray(",", str);
+    }
+
+    /**
+     * 杞崲涓篠tring鏁扮粍<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static String[] toStrArray(String split, String str) {
+        if (isBlank(str)) {
+            return new String[]{};
+        }
+        return str.split(split);
+    }
+
+    /**
+     * 杞崲涓篠tring闆嗗悎<br>
+     *
+     * @param str 缁撴灉琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<String> toStrList(String str) {
+        return Arrays.asList(toStrArray(str));
+    }
+
+    /**
+     * 杞崲涓篠tring闆嗗悎<br>
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static List<String> toStrList(String split, String str) {
+        return Arrays.asList(toStrArray(split, str));
+    }
+
+    /**
+     * 鑾峰彇绗竴浣峉tring鏁板��
+     *
+     * @param str 琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static String firstStr(String str) {
+        return firstStr(",", str);
+    }
+
+    /**
+     * 鑾峰彇绗竴浣峉tring鏁板��
+     *
+     * @param split 鍒嗛殧绗�
+     * @param str   琚浆鎹㈢殑鍊�
+     * @return 缁撴灉
+     */
+    public static String firstStr(String split, String str) {
+        List<String> strs = toStrList(split, str);
+        if (isEmpty(strs)) {
+            return null;
+        } else {
+            return strs.get(0);
+        }
+    }
+
+    /**
+     * 灏� long 杞煭瀛楃涓� 涓� 62 杩涘埗
+     *
+     * @param num 鏁板瓧
+     * @return 鐭瓧绗︿覆
+     */
+    public static String to62String(long num) {
+        return NumberUtil.to62String(num);
+    }
+
+    /**
+     * 灏嗛泦鍚堟嫾鎺ユ垚瀛楃涓诧紝榛樿浣跨敤`,`鎷兼帴
+     *
+     * @param coll the {@code Collection} to convert
+     * @return the delimited {@code String}
+     */
+    public static String join(Collection<?> coll) {
+        return StringUtil.join(coll);
+    }
+
+    /**
+     * 灏嗛泦鍚堟嫾鎺ユ垚瀛楃涓诧紝榛樿鎸囧畾鍒嗛殧绗�
+     *
+     * @param coll  the {@code Collection} to convert
+     * @param delim the delimiter to use (typically a ",")
+     * @return the delimited {@code String}
+     */
+    public static String join(Collection<?> coll, String delim) {
+        return StringUtil.join(coll, delim);
+    }
+
+    /**
+     * 灏嗘暟缁勬嫾鎺ユ垚瀛楃涓诧紝榛樿浣跨敤`,`鎷兼帴
+     *
+     * @param arr the array to display
+     * @return the delimited {@code String}
+     */
+    public static String join(Object[] arr) {
+        return StringUtil.join(arr);
+    }
+
+    /**
+     * 灏嗘暟缁勬嫾鎺ユ垚瀛楃涓诧紝榛樿鎸囧畾鍒嗛殧绗�
+     *
+     * @param arr   the array to display
+     * @param delim the delimiter to use (typically a ",")
+     * @return the delimited {@code String}
+     */
+    public static String join(Object[] arr, String delim) {
+        return StringUtil.join(arr, delim);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝涓嶅幓闄ゅ垏鍒嗗悗姣忎釜鍏冪礌涓よ竟鐨勭┖鐧界锛屼笉鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     */
+    public static List<String> split(CharSequence str, char separator) {
+        return StringUtil.split(str, separator, -1);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     */
+    public static List<String> splitTrim(CharSequence str, char separator) {
+        return StringUtil.splitTrim(str, separator);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     */
+    public static List<String> splitTrim(CharSequence str, CharSequence separator) {
+        return StringUtil.splitTrim(str, separator);
+    }
+
+    /**
+     * 鍒嗗壊 瀛楃涓�
+     *
+     * @param str       瀛楃涓�
+     * @param delimiter 鍒嗗壊绗�
+     * @return 瀛楃涓叉暟缁�
+     */
+    public static String[] split(@Nullable String str, @Nullable String delimiter) {
+        return StringUtil.delimitedListToStringArray(str, delimiter);
+    }
+
+    /**
+     * 鍒嗗壊 瀛楃涓� 鍒犻櫎甯歌 绌虹櫧绗�
+     *
+     * @param str       瀛楃涓�
+     * @param delimiter 鍒嗗壊绗�
+     * @return 瀛楃涓叉暟缁�
+     */
+    public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
+        return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
+    }
+
+    /**
+     * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+     *
+     * <p>
+     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+     * </p>
+     *
+     * @param pattern 琛ㄨ揪寮�
+     * @param str     瀛楃涓�
+     * @return 鏄惁鍖归厤
+     */
+    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
+        return PatternMatchUtils.simpleMatch(pattern, str);
+    }
+
+    /**
+     * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+     *
+     * <p>
+     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+     * </p>
+     *
+     * @param patterns 琛ㄨ揪寮� 鏁扮粍
+     * @param str      瀛楃涓�
+     * @return 鏄惁鍖归厤
+     */
+    public static boolean simpleMatch(@Nullable String[] patterns, String str) {
+        return PatternMatchUtils.simpleMatch(patterns, str);
+    }
+
+    /**
+     * 鐢熸垚uuid
+     *
+     * @return UUID
+     */
+    public static String randomUUID() {
+        return StringUtil.randomUUID();
+    }
+
+    /**
+     * 杞箟HTML鐢ㄤ簬瀹夊叏杩囨护
+     *
+     * @param html html
+     * @return {String}
+     */
+    public static String escapeHtml(String html) {
+        return StringUtil.escapeHtml(html);
+    }
+
+    /**
+     * 闅忔満鏁扮敓鎴�
+     *
+     * @param count 瀛楃闀垮害
+     * @return 闅忔満鏁�
+     */
+    public static String random(int count) {
+        return StringUtil.random(count);
+    }
+
+    /**
+     * 闅忔満鏁扮敓鎴�
+     *
+     * @param count      瀛楃闀垮害
+     * @param randomType 闅忔満鏁扮被鍒�
+     * @return 闅忔満鏁�
+     */
+    public static String random(int count, RandomType randomType) {
+        return StringUtil.random(count, randomType);
+    }
+
+    /**
+     * 瀛楃涓插簭鍒楀寲鎴� md5
+     *
+     * @param data Data to digest
+     * @return MD5 digest as a hex string
+     */
+    public static String md5Hex(final String data) {
+        return DigestUtil.md5Hex(data);
+    }
+
+    /**
+     * 鏁扮粍搴忓垪鍖栨垚 md5
+     *
+     * @param bytes the bytes to calculate the digest over
+     * @return md5 digest string
+     */
+    public static String md5Hex(final byte[] bytes) {
+        return DigestUtil.md5Hex(bytes);
+    }
+
+
+    /**
+     * sha1Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha1Hex(String data) {
+        return DigestUtil.sha1Hex(data);
+    }
+
+    /**
+     * sha1Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha1Hex(final byte[] bytes) {
+        return DigestUtil.sha1Hex(bytes);
+    }
+
+    /**
+     * SHA224Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha224Hex(String data) {
+        return DigestUtil.sha224Hex(data);
+    }
+
+    /**
+     * SHA224Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha224Hex(final byte[] bytes) {
+        return DigestUtil.sha224Hex(bytes);
+    }
+
+    /**
+     * sha256Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha256Hex(String data) {
+        return DigestUtil.sha256Hex(data);
+    }
+
+    /**
+     * sha256Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha256Hex(final byte[] bytes) {
+        return DigestUtil.sha256Hex(bytes);
+    }
+
+    /**
+     * sha384Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha384Hex(String data) {
+        return DigestUtil.sha384Hex(data);
+    }
+
+    /**
+     * sha384Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha384Hex(final byte[] bytes) {
+        return DigestUtil.sha384Hex(bytes);
+    }
+
+    /**
+     * sha512Hex
+     *
+     * @param data Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha512Hex(String data) {
+        return DigestUtil.sha512Hex(data);
+    }
+
+    /**
+     * sha512Hex
+     *
+     * @param bytes Data to digest
+     * @return digest as a hex string
+     */
+    public static String sha512Hex(final byte[] bytes) {
+        return DigestUtil.sha512Hex(bytes);
+    }
+
+    /**
+     * hmacMd5 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacMd5Hex(String data, String key) {
+        return DigestUtil.hmacMd5Hex(data, key);
+    }
+
+    /**
+     * hmacMd5 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacMd5Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacMd5Hex(bytes, key);
+    }
+
+    /**
+     * hmacSha1 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha1Hex(String data, String key) {
+        return DigestUtil.hmacSha1Hex(data, key);
+    }
+
+    /**
+     * hmacSha1 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha1Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacSha1Hex(bytes, key);
+    }
+
+    /**
+     * hmacSha224 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha224Hex(String data, String key) {
+        return DigestUtil.hmacSha224Hex(data, key);
+    }
+
+    /**
+     * hmacSha224 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha224Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacSha224Hex(bytes, key);
+    }
+
+    /**
+     * hmacSha256 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha256Hex(String data, String key) {
+        return DigestUtil.hmacSha256Hex(data, key);
+    }
+
+    /**
+     * hmacSha256 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha256Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacSha256Hex(bytes, key);
+    }
+
+    /**
+     * hmacSha384 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha384Hex(String data, String key) {
+        return DigestUtil.hmacSha384Hex(data, key);
+    }
+
+    /**
+     * hmacSha384 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha384Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacSha384Hex(bytes, key);
+    }
+
+    /**
+     * hmacSha512 Hex
+     *
+     * @param data Data to digest
+     * @param key  key
+     * @return digest as a hex string
+     */
+    public static String hmacSha512Hex(String data, String key) {
+        return DigestUtil.hmacSha512Hex(data, key);
+    }
+
+    /**
+     * hmacSha512 Hex
+     *
+     * @param bytes Data to digest
+     * @param key   key
+     * @return digest as a hex string
+     */
+    public static String hmacSha512Hex(final byte[] bytes, String key) {
+        return DigestUtil.hmacSha512Hex(bytes, key);
+    }
+
+    /**
+     * byte 鏁扮粍搴忓垪鍖栨垚 hex
+     *
+     * @param bytes bytes to encode
+     * @return MD5 digest as a hex string
+     */
+    public static String encodeHex(byte[] bytes) {
+        return DigestUtil.encodeHex(bytes);
+    }
+
+    /**
+     * 瀛楃涓插弽搴忓垪鍖栨垚 hex
+     *
+     * @param hexString String to decode
+     * @return MD5 digest as a hex string
+     */
+    public static byte[] decodeHex(final String hexString) {
+        return DigestUtil.decodeHex(hexString);
+    }
+
+    /**
+     * Base64缂栫爜
+     *
+     * @param value 瀛楃涓�
+     * @return {String}
+     */
+    public static String encodeBase64(String value) {
+        return Base64Util.encode(value);
+    }
+
+    /**
+     * Base64缂栫爜
+     *
+     * @param value   瀛楃涓�
+     * @param charset 瀛楃闆�
+     * @return {String}
+     */
+    public static String encodeBase64(String value, Charset charset) {
+        return Base64Util.encode(value, charset);
+    }
+
+    /**
+     * Base64缂栫爜涓篣RL瀹夊叏
+     *
+     * @param value 瀛楃涓�
+     * @return {String}
+     */
+    public static String encodeBase64UrlSafe(String value) {
+        return Base64Util.encodeUrlSafe(value);
+    }
+
+    /**
+     * Base64缂栫爜涓篣RL瀹夊叏
+     *
+     * @param value   瀛楃涓�
+     * @param charset 瀛楃闆�
+     * @return {String}
+     */
+    public static String encodeBase64UrlSafe(String value, Charset charset) {
+        return Base64Util.encodeUrlSafe(value, charset);
+    }
+
+    /**
+     * Base64瑙g爜
+     *
+     * @param value 瀛楃涓�
+     * @return {String}
+     */
+    public static String decodeBase64(String value) {
+        return Base64Util.decode(value);
+    }
+
+    /**
+     * Base64瑙g爜
+     *
+     * @param value   瀛楃涓�
+     * @param charset 瀛楃闆�
+     * @return {String}
+     */
+    public static String decodeBase64(String value, Charset charset) {
+        return Base64Util.decode(value, charset);
+    }
+
+    /**
+     * Base64URL瀹夊叏瑙g爜
+     *
+     * @param value 瀛楃涓�
+     * @return {String}
+     */
+    public static String decodeBase64UrlSafe(String value) {
+        return Base64Util.decodeUrlSafe(value);
+    }
+
+    /**
+     * Base64URL瀹夊叏瑙g爜
+     *
+     * @param value   瀛楃涓�
+     * @param charset 瀛楃闆�
+     * @return {String}
+     */
+    public static String decodeBase64UrlSafe(String value, Charset charset) {
+        return Base64Util.decodeUrlSafe(value, charset);
+    }
+
+    /**
+     * 鍏抽棴 Closeable
+     *
+     * @param closeable 鑷姩鍏抽棴
+     */
+    public static void closeQuietly(@Nullable Closeable closeable) {
+        IoUtil.closeQuietly(closeable);
+    }
+
+    /**
+     * InputStream to String utf-8
+     *
+     * @param input the <code>InputStream</code> to read from
+     * @return the requested String
+     * @throws NullPointerException if the input is null
+     */
+    public static String readToString(InputStream input) {
+        return IoUtil.readToString(input);
+    }
+
+    /**
+     * InputStream to String
+     *
+     * @param input   the <code>InputStream</code> to read from
+     * @param charset the <code>Charset</code>
+     * @return the requested String
+     * @throws NullPointerException if the input is null
+     */
+    public static String readToString(@Nullable InputStream input, Charset charset) {
+        return IoUtil.readToString(input, charset);
+    }
+
+    /**
+     * InputStream to bytes 鏁扮粍
+     *
+     * @param input InputStream
+     * @return the requested byte array
+     */
+    public static byte[] readToByteArray(@Nullable InputStream input) {
+        return IoUtil.readToByteArray(input);
+    }
+
+    /**
+     * 璇诲彇鏂囦欢涓哄瓧绗︿覆
+     *
+     * @param file the file to read, must not be {@code null}
+     * @return the file contents, never {@code null}
+     */
+    public static String readToString(final File file) {
+        return FileUtil.readToString(file);
+    }
+
+    /**
+     * 璇诲彇鏂囦欢涓哄瓧绗︿覆
+     *
+     * @param file     the file to read, must not be {@code null}
+     * @param encoding the encoding to use, {@code null} means platform default
+     * @return the file contents, never {@code null}
+     */
+    public static String readToString(File file, Charset encoding) {
+        return FileUtil.readToString(file, encoding);
+    }
+
+    /**
+     * 璇诲彇鏂囦欢涓� byte 鏁扮粍
+     *
+     * @param file the file to read, must not be {@code null}
+     * @return the file contents, never {@code null}
+     */
+    public static byte[] readToByteArray(File file) {
+        return FileUtil.readToByteArray(file);
+    }
+
+    /**
+     * 灏嗗璞″簭鍒楀寲鎴恓son瀛楃涓�
+     *
+     * @param object javaBean
+     * @return jsonString json瀛楃涓�
+     */
+    public static String toJson(Object object) {
+        return JsonUtil.toJson(object);
+    }
+
+    /**
+     * 灏嗗璞″簭鍒楀寲鎴� json byte 鏁扮粍
+     *
+     * @param object javaBean
+     * @return jsonString json瀛楃涓�
+     */
+    public static byte[] toJsonAsBytes(Object object) {
+        return JsonUtil.toJsonAsBytes(object);
+    }
+
+    /**
+     * 灏唈son瀛楃涓茶浆鎴� JsonNode
+     *
+     * @param jsonString jsonString
+     * @return jsonString json瀛楃涓�
+     */
+    public static JsonNode readTree(String jsonString) {
+        return JsonUtil.readTree(jsonString);
+    }
+
+    /**
+     * 灏唈son瀛楃涓茶浆鎴� JsonNode
+     *
+     * @param in InputStream
+     * @return jsonString json瀛楃涓�
+     */
+    public static JsonNode readTree(InputStream in) {
+        return JsonUtil.readTree(in);
+    }
+
+    /**
+     * 灏唈son瀛楃涓茶浆鎴� JsonNode
+     *
+     * @param content content
+     * @return jsonString json瀛楃涓�
+     */
+    public static JsonNode readTree(byte[] content) {
+        return JsonUtil.readTree(content);
+    }
+
+    /**
+     * 灏唈son瀛楃涓茶浆鎴� JsonNode
+     *
+     * @param jsonParser JsonParser
+     * @return jsonString json瀛楃涓�
+     */
+    public static JsonNode readTree(JsonParser jsonParser) {
+        return JsonUtil.readTree(jsonParser);
+    }
+
+    /**
+     * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param bytes     json bytes
+     * @param valueType class
+     * @param <T>       T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(byte[] bytes, Class<T> valueType) {
+        return JsonUtil.parse(bytes, valueType);
+    }
+
+    /**
+     * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param jsonString jsonString
+     * @param valueType  class
+     * @param <T>        T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(String jsonString, Class<T> valueType) {
+        return JsonUtil.parse(jsonString, valueType);
+    }
+
+    /**
+     * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param in        InputStream
+     * @param valueType class
+     * @param <T>       T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(InputStream in, Class<T> valueType) {
+        return JsonUtil.parse(in, valueType);
+    }
+
+    /**
+     * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param bytes         bytes
+     * @param typeReference 娉涘瀷绫诲瀷
+     * @param <T>           T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(byte[] bytes, TypeReference<T> typeReference) {
+        return JsonUtil.parse(bytes, typeReference);
+    }
+
+    /**
+     * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param jsonString    jsonString
+     * @param typeReference 娉涘瀷绫诲瀷
+     * @param <T>           T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(String jsonString, TypeReference<T> typeReference) {
+        return JsonUtil.parse(jsonString, typeReference);
+    }
+
+    /**
+     * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+     *
+     * @param in            InputStream
+     * @param typeReference 娉涘瀷绫诲瀷
+     * @param <T>           T 娉涘瀷鏍囪
+     * @return Bean
+     */
+    public static <T> T readJson(InputStream in, TypeReference<T> typeReference) {
+        return JsonUtil.parse(in, typeReference);
+    }
+
+    /**
+     * url 缂栫爜
+     *
+     * @param source the String to be encoded
+     * @return the encoded String
+     */
+    public static String urlEncode(String source) {
+        return UrlUtil.encode(source, Charsets.UTF_8);
+    }
+
+    /**
+     * url 缂栫爜
+     *
+     * @param source  the String to be encoded
+     * @param charset the character encoding to encode to
+     * @return the encoded String
+     */
+    public static String urlEncode(String source, Charset charset) {
+        return UrlUtil.encode(source, charset);
+    }
+
+    /**
+     * url 瑙g爜
+     *
+     * @param source the encoded String
+     * @return the decoded value
+     * @throws IllegalArgumentException when the given source contains invalid encoded sequences
+     * @see StringUtils#uriDecode(String, Charset)
+     * @see java.net.URLDecoder#decode(String, String)
+     */
+    public static String urlDecode(String source) {
+        return StringUtils.uriDecode(source, Charsets.UTF_8);
+    }
+
+    /**
+     * url 瑙g爜
+     *
+     * @param source  the encoded String
+     * @param charset the character encoding to use
+     * @return the decoded value
+     * @throws IllegalArgumentException when the given source contains invalid encoded sequences
+     * @see StringUtils#uriDecode(String, Charset)
+     * @see java.net.URLDecoder#decode(String, String)
+     */
+    public static String urlDecode(String source, Charset charset) {
+        return StringUtils.uriDecode(source, charset);
+    }
+
+    /**
+     * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+     *
+     * @param date 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatDateTime(Date date) {
+        return DateUtil.formatDateTime(date);
+    }
+
+    /**
+     * 鏃ユ湡鏍煎紡鍖�
+     *
+     * @param date 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatDate(Date date) {
+        return DateUtil.formatDate(date);
+    }
+
+    /**
+     * 鏃堕棿鏍煎紡鍖�
+     *
+     * @param date 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatTime(Date date) {
+        return DateUtil.formatTime(date);
+    }
+
+    /**
+     * 瀵硅薄鏍煎紡鍖� 鏀寔鏁板瓧锛宒ate锛宩ava8鏃堕棿
+     *
+     * @param object  鏍煎紡鍖栧璞�
+     * @param pattern 琛ㄨ揪寮�
+     * @return 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+     */
+    public static String format(Object object, String pattern) {
+        if (object instanceof Number) {
+            DecimalFormat decimalFormat = new DecimalFormat(pattern);
+            return decimalFormat.format(object);
+        } else if (object instanceof Date) {
+            return DateUtil.format((Date) object, pattern);
+        } else if (object instanceof TemporalAccessor) {
+            return DateTimeUtil.format((TemporalAccessor) object, pattern);
+        }
+        throw new IllegalArgumentException("鏈敮鎸佺殑瀵硅薄:" + object + ",鏍煎紡:" + object);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr 鏃堕棿瀛楃涓�
+     * @param pattern 琛ㄨ揪寮�
+     * @return 鏃堕棿
+     */
+    public static Date parseDate(String dateStr, String pattern) {
+        return DateUtil.parse(dateStr, pattern);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr 鏃堕棿瀛楃涓�
+     * @param format  ConcurrentDateFormat
+     * @return 鏃堕棿
+     */
+    public static Date parse(String dateStr, ConcurrentDateFormat format) {
+        return DateUtil.parse(dateStr, format);
+    }
+
+    /**
+     * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+     *
+     * @param temporal 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatDateTime(TemporalAccessor temporal) {
+        return DateTimeUtil.formatDateTime(temporal);
+    }
+
+    /**
+     * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+     *
+     * @param temporal 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatDate(TemporalAccessor temporal) {
+        return DateTimeUtil.formatDate(temporal);
+    }
+
+    /**
+     * 鏃堕棿鏍煎紡鍖�
+     *
+     * @param temporal 鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String formatTime(TemporalAccessor temporal) {
+        return DateTimeUtil.formatTime(temporal);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr   鏃堕棿瀛楃涓�
+     * @param formatter DateTimeFormatter
+     * @return 鏃堕棿
+     */
+    public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
+        return DateTimeUtil.parseDateTime(dateStr, formatter);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr 鏃堕棿瀛楃涓�
+     * @return 鏃堕棿
+     */
+    public static LocalDateTime parseDateTime(String dateStr) {
+        return DateTimeUtil.parseDateTime(dateStr);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr   鏃堕棿瀛楃涓�
+     * @param formatter DateTimeFormatter
+     * @return 鏃堕棿
+     */
+    public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
+        return DateTimeUtil.parseDate(dateStr, formatter);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘棩鏈�
+     *
+     * @param dateStr 鏃堕棿瀛楃涓�
+     * @return 鏃堕棿
+     */
+    public static LocalDate parseDate(String dateStr) {
+        return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr   鏃堕棿瀛楃涓�
+     * @param formatter DateTimeFormatter
+     * @return 鏃堕棿
+     */
+    public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
+        return DateTimeUtil.parseTime(dateStr, formatter);
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+     *
+     * @param dateStr 鏃堕棿瀛楃涓�
+     * @return 鏃堕棿
+     */
+    public static LocalTime parseTime(String dateStr) {
+        return DateTimeUtil.parseTime(dateStr);
+    }
+
+    /**
+     * 鏃堕棿姣旇緝
+     *
+     * @param startInclusive the start instant, inclusive, not null
+     * @param endExclusive   the end instant, exclusive, not null
+     * @return a {@code Duration}, not null
+     */
+    public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+        return Duration.between(startInclusive, endExclusive);
+    }
+
+    /**
+     * 姣旇緝2涓� 鏃堕棿宸�
+     *
+     * @param startDate 寮�濮嬫椂闂�
+     * @param endDate   缁撴潫鏃堕棿
+     * @return 鏃堕棿闂撮殧
+     */
+    public static Duration between(Date startDate, Date endDate) {
+        return DateUtil.between(startDate, endDate);
+    }
+
+    /**
+     * 瀵硅薄绫诲瀷杞崲
+     *
+     * @param source     the source object
+     * @param targetType the target type
+     * @param <T>        娉涘瀷鏍囪
+     * @return the converted value
+     * @throws IllegalArgumentException if targetType is {@code null},
+     *                                  or sourceType is {@code null} but source is not {@code null}
+     */
+    @Nullable
+    public static <T> T convert(@Nullable Object source, Class<T> targetType) {
+        return ConvertUtil.convert(source, targetType);
+    }
+
+    /**
+     * 瀵硅薄绫诲瀷杞崲
+     *
+     * @param source     the source object
+     * @param sourceType the source type
+     * @param targetType the target type
+     * @param <T>        娉涘瀷鏍囪
+     * @return the converted value
+     * @throws IllegalArgumentException if targetType is {@code null},
+     *                                  or sourceType is {@code null} but source is not {@code null}
+     */
+    @Nullable
+    public static <T> T convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
+        return ConvertUtil.convert(source, sourceType, targetType);
+    }
+
+    /**
+     * 瀵硅薄绫诲瀷杞崲
+     *
+     * @param source     the source object
+     * @param targetType the target type
+     * @param <T>        娉涘瀷鏍囪
+     * @return the converted value
+     * @throws IllegalArgumentException if targetType is {@code null},
+     *                                  or sourceType is {@code null} but source is not {@code null}
+     */
+    @Nullable
+    public static <T> T convert(@Nullable Object source, TypeDescriptor targetType) {
+        return ConvertUtil.convert(source, targetType);
+    }
+
+    /**
+     * 鑾峰彇鏂规硶鍙傛暟淇℃伅
+     *
+     * @param constructor    鏋勯�犲櫒
+     * @param parameterIndex 鍙傛暟搴忓彿
+     * @return {MethodParameter}
+     */
+    public static MethodParameter getMethodParameter(Constructor<?> constructor, int parameterIndex) {
+        return ClassUtil.getMethodParameter(constructor, parameterIndex);
+    }
+
+    /**
+     * 鑾峰彇鏂规硶鍙傛暟淇℃伅
+     *
+     * @param method         鏂规硶
+     * @param parameterIndex 鍙傛暟搴忓彿
+     * @return {MethodParameter}
+     */
+    public static MethodParameter getMethodParameter(Method method, int parameterIndex) {
+        return ClassUtil.getMethodParameter(method, parameterIndex);
+    }
+
+    /**
+     * 鑾峰彇Annotation娉ㄨВ
+     *
+     * @param annotatedElement AnnotatedElement
+     * @param annotationType   娉ㄨВ绫�
+     * @param <A>              娉涘瀷鏍囪
+     * @return {Annotation}
+     */
+    @Nullable
+    public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
+        return AnnotatedElementUtils.findMergedAnnotation(annotatedElement, annotationType);
+    }
+
+    /**
+     * 鑾峰彇Annotation锛屽厛鎵炬柟娉曪紝娌℃湁鍒欏啀鎵炬柟娉曚笂鐨勭被
+     *
+     * @param method         Method
+     * @param annotationType 娉ㄨВ绫�
+     * @param <A>            娉涘瀷鏍囪
+     * @return {Annotation}
+     */
+    @Nullable
+    public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
+        return ClassUtil.getAnnotation(method, annotationType);
+    }
+
+    /**
+     * 鑾峰彇Annotation锛屽厛鎵綡andlerMethod锛屾病鏈夊垯鍐嶆壘瀵瑰簲鐨勭被
+     *
+     * @param handlerMethod  HandlerMethod
+     * @param annotationType 娉ㄨВ绫�
+     * @param <A>            娉涘瀷鏍囪
+     * @return {Annotation}
+     */
+    @Nullable
+    public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
+        return ClassUtil.getAnnotation(handlerMethod, annotationType);
+    }
+
+    /**
+     * 瀹炰緥鍖栧璞�
+     *
+     * @param clazz 绫�
+     * @param <T>   娉涘瀷鏍囪
+     * @return 瀵硅薄
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T newInstance(Class<?> clazz) {
+        return (T) BeanUtil.instantiateClass(clazz);
+    }
+
+    /**
+     * 瀹炰緥鍖栧璞�
+     *
+     * @param clazzStr 绫诲悕
+     * @param <T>      娉涘瀷鏍囪
+     * @return 瀵硅薄
+     */
+    public static <T> T newInstance(String clazzStr) {
+        return BeanUtil.newInstance(clazzStr);
+    }
+
+    /**
+     * 鑾峰彇Bean鐨勫睘鎬�
+     *
+     * @param bean         bean
+     * @param propertyName 灞炴�у悕
+     * @return 灞炴�у��
+     */
+    @Nullable
+    public static Object getProperty(@Nullable Object bean, String propertyName) {
+        return BeanUtil.getProperty(bean, propertyName);
+    }
+
+    /**
+     * 璁剧疆Bean灞炴��
+     *
+     * @param bean         bean
+     * @param propertyName 灞炴�у悕
+     * @param value        灞炴�у��
+     */
+    public static void setProperty(Object bean, String propertyName, Object value) {
+        BeanUtil.setProperty(bean, propertyName, value);
+    }
+
+    /**
+     * 娴呭鍒�
+     *
+     * @param source 婧愬璞�
+     * @param <T>    娉涘瀷鏍囪
+     * @return T
+     */
+    @Nullable
+    public static <T> T clone(@Nullable T source) {
+        return BeanUtil.clone(source);
+    }
+
+    /**
+     * 鎷疯礉瀵硅薄锛屾敮鎸� Map 鍜� Bean
+     *
+     * @param source 婧愬璞�
+     * @param clazz  绫诲悕
+     * @param <T>    娉涘瀷鏍囪
+     * @return T
+     */
+    @Nullable
+    public static <T> T copy(@Nullable Object source, Class<T> clazz) {
+        return BeanUtil.copy(source, clazz);
+    }
+
+    /**
+     * 鎷疯礉瀵硅薄锛屾敮鎸� Map 鍜� Bean
+     *
+     * @param source     婧愬璞�
+     * @param targetBean 闇�瑕佽祴鍊肩殑瀵硅薄
+     */
+    public static void copy(@Nullable Object source, @Nullable Object targetBean) {
+        BeanUtil.copy(source, targetBean);
+    }
+
+    /**
+     * 鎷疯礉瀵硅薄锛宻ource 瀵硅薄灞炴�у仛闈� null 鍒ゆ柇
+     *
+     * <p>
+     * 鏀寔 map bean copy
+     * </p>
+     *
+     * @param source     婧愬璞�
+     * @param targetBean 闇�瑕佽祴鍊肩殑瀵硅薄
+     */
+    public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) {
+        BeanUtil.copyNonNull(source, targetBean);
+    }
+
+    /**
+     * 鎷疯礉瀵硅薄锛屽苟瀵逛笉鍚岀被鍨嬪睘鎬ц繘琛岃浆鎹�
+     *
+     * @param source 婧愬璞�
+     * @param clazz  绫诲悕
+     * @param <T>    娉涘瀷鏍囪
+     * @return T
+     */
+    @Nullable
+    public static <T> T copyWithConvert(@Nullable Object source, Class<T> clazz) {
+        return BeanUtil.copyWithConvert(source, clazz);
+    }
+
+    /**
+     * 鎷疯礉鍒楄〃瀵硅薄
+     *
+     * <p>
+     * 鏀寔 map bean copy
+     * </p>
+     *
+     * @param sourceList  婧愬垪琛�
+     * @param targetClazz 杞崲鎴愮殑绫诲瀷
+     * @param <T>         娉涘瀷鏍囪
+     * @return T
+     */
+    public static <T> List<T> copy(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
+        return BeanUtil.copy(sourceList, targetClazz);
+    }
+
+    /**
+     * 鎷疯礉鍒楄〃瀵硅薄锛屽苟瀵逛笉鍚岀被鍨嬪睘鎬ц繘琛岃浆鎹�
+     *
+     * <p>
+     * 鏀寔 map bean copy
+     * </p>
+     *
+     * @param sourceList  婧愬璞″垪琛�
+     * @param targetClazz 杞崲鎴愮殑绫�
+     * @param <T>         娉涘瀷鏍囪
+     * @return List
+     */
+    public static <T> List<T> copyWithConvert(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
+        return BeanUtil.copyWithConvert(sourceList, targetClazz);
+    }
+
+    /**
+     * 鎷疯礉瀵硅薄锛屾墿灞� Spring 鐨勬嫹璐濇柟娉�
+     *
+     * @param source the source bean
+     * @param clazz  the target bean class
+     * @param <T>    娉涘瀷鏍囪
+     * @return T
+     * @throws BeansException if the copying failed
+     */
+    @Nullable
+    public static <T> T copyProperties(@Nullable Object source, Class<T> clazz) throws BeansException {
+        return BeanUtil.copyProperties(source, clazz);
+    }
+
+    /**
+     * 鎷疯礉鍒楄〃瀵硅薄锛屾墿灞� Spring 鐨勬嫹璐濇柟娉�
+     *
+     * @param sourceList  the source list bean
+     * @param targetClazz the target bean class
+     * @param <T>         娉涘瀷鏍囪
+     * @return List
+     * @throws BeansException if the copying failed
+     */
+    public static <T> List<T> copyProperties(@Nullable Collection<?> sourceList, Class<T> targetClazz) throws BeansException {
+        return BeanUtil.copyProperties(sourceList, targetClazz);
+    }
+
+    /**
+     * 灏嗗璞¤鎴恗ap褰㈠紡
+     *
+     * @param bean 婧愬璞�
+     * @return {Map}
+     */
+    public static Map<String, Object> toMap(@Nullable Object bean) {
+        return BeanUtil.toMap(bean);
+    }
+
+    /**
+     * 灏唌ap 杞负 bean
+     *
+     * @param beanMap   map
+     * @param valueType 瀵硅薄绫诲瀷
+     * @param <T>       娉涘瀷鏍囪
+     * @return {T}
+     */
+    public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) {
+        return BeanUtil.toBean(beanMap, valueType);
+    }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java
new file mode 100644
index 0000000..ec11d04
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java
@@ -0,0 +1,22 @@
+package com.vci.web.util;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+/**
+ * 涓�浜涘父鐢ㄧ殑鍗曚緥瀵硅薄
+ *
+ * @author L.cm
+ */
+public class Holder {
+
+    /**
+     * RANDOM
+     */
+    public final static Random RANDOM = new Random();
+
+    /**
+     * SECURE_RANDOM
+     */
+    public final static SecureRandom SECURE_RANDOM = new SecureRandom();
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java
new file mode 100644
index 0000000..836380e
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java
@@ -0,0 +1,109 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+/**
+ * 娴佸伐鍏风被
+ *
+ * @author L.cm
+ */
+public class IoUtil extends org.springframework.util.StreamUtils {
+
+	/**
+	 * closeQuietly
+	 *
+	 * @param closeable 鑷姩鍏抽棴
+	 */
+	public static void closeQuietly(@Nullable Closeable closeable) {
+		if (closeable == null) {
+			return;
+		}
+		if (closeable instanceof Flushable) {
+			try {
+				((Flushable) closeable).flush();
+			} catch (IOException ignored) {
+				// ignore
+			}
+		}
+		try {
+			closeable.close();
+		} catch (IOException ignored) {
+			// ignore
+		}
+	}
+
+	/**
+	 * InputStream to String utf-8
+	 *
+	 * @param input the <code>InputStream</code> to read from
+	 * @return the requested String
+	 */
+	public static String readToString(InputStream input) {
+		return readToString(input, Charsets.UTF_8);
+	}
+
+	/**
+	 * InputStream to String
+	 *
+	 * @param input   the <code>InputStream</code> to read from
+	 * @param charset the <code>Charset</code>
+	 * @return the requested String
+	 */
+	public static String readToString(@Nullable InputStream input, Charset charset) {
+		try {
+			return IoUtil.copyToString(input, charset);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		} finally {
+			IoUtil.closeQuietly(input);
+		}
+	}
+
+	public static byte[] readToByteArray(@Nullable InputStream input) {
+		try {
+			return IoUtil.copyToByteArray(input);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		} finally {
+			IoUtil.closeQuietly(input);
+		}
+	}
+
+	/**
+	 * Writes chars from a <code>String</code> to bytes on an
+	 * <code>OutputStream</code> using the specified character encoding.
+	 * <p>
+	 * This method uses {@link String#getBytes(String)}.
+	 * </p>
+	 * @param data     the <code>String</code> to write, null ignored
+	 * @param output   the <code>OutputStream</code> to write to
+	 * @param encoding the encoding to use, null means platform default
+	 * @throws NullPointerException if output is null
+	 * @throws IOException          if an I/O error occurs
+	 */
+	public static void write(@Nullable final String data, final OutputStream output, final Charset encoding) throws IOException {
+		if (data != null) {
+			output.write(data.getBytes(encoding));
+		}
+	}
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java
new file mode 100644
index 0000000..c493791
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java
@@ -0,0 +1,195 @@
+package com.vci.web.util;
+
+
+import org.springframework.lang.Nullable;
+
+/**
+ * 鏁板瓧绫诲瀷宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class NumberUtil extends org.springframework.util.NumberUtils {
+
+    //-----------------------------------------------------------------------
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>int</code>, returning
+     * <code>zero</code> if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
+     *
+     * <pre>
+     *   NumberUtil.toInt(null) = 0
+     *   NumberUtil.toInt("")   = 0
+     *   NumberUtil.toInt("1")  = 1
+     * </pre>
+     *
+     * @param str the string to convert, may be null
+     * @return the int represented by the string, or <code>zero</code> if
+     * conversion fails
+     */
+    public static int toInt(final String str) {
+        return toInt(str, -1);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to an <code>int</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   NumberUtil.toInt(null, 1) = 1
+     *   NumberUtil.toInt("", 1)   = 1
+     *   NumberUtil.toInt("1", 0)  = 1
+     * </pre>
+     *
+     * @param str          the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the int represented by the string, or the default if conversion fails
+     */
+    public static int toInt(@Nullable final String str, final int defaultValue) {
+        if (str == null) {
+            return defaultValue;
+        }
+        try {
+            return Integer.valueOf(str);
+        } catch (final NumberFormatException nfe) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>long</code>, returning
+     * <code>zero</code> if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
+     *
+     * <pre>
+     *   NumberUtil.toLong(null) = 0L
+     *   NumberUtil.toLong("")   = 0L
+     *   NumberUtil.toLong("1")  = 1L
+     * </pre>
+     *
+     * @param str the string to convert, may be null
+     * @return the long represented by the string, or <code>0</code> if
+     * conversion fails
+     */
+    public static long toLong(final String str) {
+        return toLong(str, 0L);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>long</code>, returning a
+     * default value if the conversion fails.</p>
+     *
+     * <p>If the string is <code>null</code>, the default value is returned.</p>
+     *
+     * <pre>
+     *   NumberUtil.toLong(null, 1L) = 1L
+     *   NumberUtil.toLong("", 1L)   = 1L
+     *   NumberUtil.toLong("1", 0L)  = 1L
+     * </pre>
+     *
+     * @param str          the string to convert, may be null
+     * @param defaultValue the default value
+     * @return the long represented by the string, or the default if conversion fails
+     */
+    public static long toLong(@Nullable final String str, final long defaultValue) {
+        if (str == null) {
+            return defaultValue;
+        }
+        try {
+            return Long.valueOf(str);
+        } catch (final NumberFormatException nfe) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>Double</code>
+     *
+     * @param value value
+     * @return double value
+     */
+    public static Double toDouble(String value) {
+        return toDouble(value, null);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>Double</code>
+     *
+     * @param value value
+     * @param defaultValue 榛樿鍊�
+     * @return double value
+     */
+    public static Double toDouble(@Nullable String value, Double defaultValue) {
+        if (value != null) {
+            return Double.valueOf(value.trim());
+        }
+        return defaultValue;
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>Double</code>
+     *
+     * @param value value
+     * @return double value
+     */
+    public static Float toFloat(String value) {
+        return toFloat(value, null);
+    }
+
+    /**
+     * <p>Convert a <code>String</code> to a <code>Double</code>
+     *
+     * @param value value
+     * @param defaultValue 榛樿鍊�
+     * @return double value
+     */
+    public static Float toFloat(@Nullable String value, Float defaultValue) {
+        if (value != null) {
+            return Float.valueOf(value.trim());
+        }
+        return defaultValue;
+    }
+
+    /**
+     * All possible chars for representing a number as a String
+     */
+    private final static char[] DIGITS = {
+            '0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', 'a', 'b',
+            'c', 'd', 'e', 'f', 'g', 'h',
+            'i', 'j', 'k', 'l', 'm', 'n',
+            'o', 'p', 'q', 'r', 's', 't',
+            'u', 'v', 'w', 'x', 'y', 'z',
+            'A', 'B', 'C', 'D', 'E', 'F',
+            'G', 'H', 'I', 'J', 'K', 'L',
+            'M', 'N', 'O', 'P', 'Q', 'R',
+            'S', 'T', 'U', 'V', 'W', 'X',
+            'Y', 'Z'
+    };
+
+    /**
+     * 灏� long 杞煭瀛楃涓� 涓� 62 杩涘埗
+     *
+     * @param i 鏁板瓧
+     * @return 鐭瓧绗︿覆
+     */
+    public static String to62String(long i) {
+        int radix = DIGITS.length;
+        char[] buf = new char[65];
+        int charPos = 64;
+        i = -i;
+        while (i <= -radix) {
+            buf[charPos--] = DIGITS[(int) (-(i % radix))];
+            i = i / radix;
+        }
+        buf[charPos] = DIGITS[(int) (-i)];
+
+        return new String(buf, charPos, (65 - charPos));
+    }
+
+}
+
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java
new file mode 100644
index 0000000..da05460
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java
@@ -0,0 +1,21 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+
+/**
+ * 瀵硅薄宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class ObjectUtil extends org.springframework.util.ObjectUtils {
+
+    /**
+     * 鍒ゆ柇鍏冪礌涓嶄负绌�
+     * @param obj object
+     * @return boolean
+     */
+    public static boolean isNotEmpty(@Nullable Object obj) {
+        return !ObjectUtil.isEmpty(obj);
+    }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java
new file mode 100644
index 0000000..98da4bc
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java
@@ -0,0 +1,30 @@
+package com.vci.web.util;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 鐢熸垚鐨勯殢鏈烘暟绫诲瀷
+ *
+ * @author L.cm
+ */
+@Getter
+@RequiredArgsConstructor
+public enum RandomType {
+    /**
+     * INT STRING ALL
+     */
+    INT(RandomType.INT_STR),
+    STRING(RandomType.STR_STR),
+    ALL(RandomType.ALL_STR);
+
+    private final String factor;
+
+    /**
+     * 闅忔満瀛楃涓插洜瀛�
+     */
+    private static final String INT_STR = "0123456789";
+    private static final String STR_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    private static final String ALL_STR = INT_STR + STR_STR;
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java
new file mode 100644
index 0000000..5dd92d7
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java
@@ -0,0 +1,71 @@
+package com.vci.web.util;
+
+/**
+ * 闈欐�� String 姹�
+ *
+ * @author L.cm
+ */
+public interface StringPool {
+
+    String AMPERSAND		= "&";
+    String AND				= "and";
+    String AT				= "@";
+    String ASTERISK			= "*";
+    String STAR				= ASTERISK;
+    String SLASH			= "/";
+    String BACK_SLASH		= "\\";
+    String DOUBLE_SLASH		= "#//";
+    String COLON			= ":";
+    String COMMA			= ",";
+    String DASH				= "-";
+    String DOLLAR			= "$";
+    String DOT				= ".";
+    String EMPTY			= "";
+    String EMPTY_JSON 		= "{}";
+    String EQUALS			= "=";
+    String FALSE			= "false";
+    String HASH				= "#";
+    String HAT				= "^";
+    String LEFT_BRACE		= "{";
+    String LEFT_BRACKET		= "(";
+    String LEFT_CHEV		= "<";
+    String NEWLINE			= "\n";
+    String N				= "n";
+    String NO				= "no";
+    String NULL				= "null";
+    String OFF				= "off";
+    String ON				= "on";
+    String PERCENT			= "%";
+    String PIPE				= "|";
+    String PLUS				= "+";
+    String QUESTION_MARK	= "?";
+    String EXCLAMATION_MARK	= "!";
+    String QUOTE			= "\"";
+    String RETURN			= "\r";
+    String TAB				= "\t";
+    String RIGHT_BRACE		= "}";
+    String RIGHT_BRACKET	= ")";
+    String RIGHT_CHEV		= ">";
+    String SEMICOLON		= ";";
+    String SINGLE_QUOTE		= "'";
+    String BACKTICK			= "`";
+    String SPACE			= " ";
+    String TILDA			= "~";
+    String LEFT_SQ_BRACKET	= "[";
+    String RIGHT_SQ_BRACKET	= "]";
+    String TRUE				= "true";
+    String UNDERSCORE		= "_";
+    String UTF_8			= "UTF-8";
+    String GBK				= "GBK";
+    String ISO_8859_1 		= "ISO-8859-1";
+    String Y				= "y";
+    String YES				= "yes";
+    String ONE				= "1";
+    String ZERO				= "0";
+    String MINUS_ONE		= "-1";
+    String DOLLAR_LEFT_BRACE= "${";
+    String UNKNOWN			= "unknown";
+    String GET				= "GET";
+    String POST				= "POST";
+
+}
\ No newline at end of file
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java
new file mode 100644
index 0000000..c062a75
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java
@@ -0,0 +1,1560 @@
+package com.vci.web.util;
+
+import cn.hutool.core.util.ObjectUtil;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.util.HtmlUtils;
+import com.vci.web.support.StrSpliter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+/**
+ * 缁ф壙鑷猄pring util鐨勫伐鍏风被锛屽噺灏慾ar渚濊禆
+ *
+ * @author L.cm
+ */
+public class StringUtil extends org.springframework.util.StringUtils {
+
+    public static final int INDEX_NOT_FOUND = -1;
+    // public static final int INDEX_NOT_FOUND = 0;
+
+    /**
+     * Check whether the given {@code CharSequence} contains actual <em>text</em>.
+     * <p>More specifically, this method returns {@code true} if the
+     * {@code CharSequence} is not {@code null}, its length is greater than
+     * 0, and it contains at least one non-whitespace character.
+     * <pre class="code">
+     * StringUtil.isBlank(null) = true
+     * StringUtil.isBlank("") = true
+     * StringUtil.isBlank(" ") = true
+     * StringUtil.isBlank("12345") = false
+     * StringUtil.isBlank(" 12345 ") = false
+     * </pre>
+     *
+     * @param cs the {@code CharSequence} to check (may be {@code null})
+     * @return {@code true} if the {@code CharSequence} is not {@code null},
+     * its length is greater than 0, and it does not contain whitespace only
+     * @see Character#isWhitespace
+     */
+    public static boolean isBlank(final CharSequence cs) {
+        return !StringUtil.hasText(cs);
+    }
+
+    /**
+     * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
+     * <pre>
+     * StringUtil.isNotBlank(null)	  = false
+     * StringUtil.isNotBlank("")		= false
+     * StringUtil.isNotBlank(" ")	   = false
+     * StringUtil.isNotBlank("bob")	 = true
+     * StringUtil.isNotBlank("  bob  ") = true
+     * </pre>
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is
+     * not empty and not null and not whitespace
+     * @see Character#isWhitespace
+     */
+    public static boolean isNotBlank(final CharSequence cs) {
+        return StringUtil.hasText(cs);
+    }
+
+    /**
+     * 鏈� 浠绘剰 涓�涓� Blank
+     *
+     * @param css CharSequence
+     * @return boolean
+     */
+    public static boolean isAnyBlank(final CharSequence... css) {
+        if (ObjectUtil.isEmpty(css)) {
+            return true;
+        }
+        return Stream.of(css).anyMatch(StringUtil::isBlank);
+    }
+
+    /**
+     * 鏄惁鍏ㄩ潪 Blank
+     *
+     * @param css CharSequence
+     * @return boolean
+     */
+    public static boolean isNoneBlank(final CharSequence... css) {
+        if (ObjectUtil.isEmpty(css)) {
+            return false;
+        }
+        return Stream.of(css).allMatch(StringUtil::isNotBlank);
+    }
+
+    /**
+     * 鏄惁鍏ㄤ负 Blank
+     *
+     * @param css CharSequence
+     * @return boolean
+     */
+    public static boolean isAllBlank(final CharSequence... css) {
+        return Stream.of(css).allMatch(StringUtil::isBlank);
+    }
+
+    /**
+     * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁鏄暟瀛�
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {boolean}
+     */
+    public static boolean isNumeric(final CharSequence cs) {
+        if (isBlank(cs)) {
+            return false;
+        }
+        for (int i = cs.length(); --i >= 0; ) {
+            int chr = cs.charAt(i);
+            if (chr < 48 || chr > 57) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆涓壒瀹氭ā寮忕殑瀛楃杞崲鎴恗ap涓搴旂殑鍊�
+     * <p>
+     * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
+     *
+     * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+     * @param params  杞崲鎵�闇�鐨勯敭鍊煎闆嗗悎
+     * @return 杞崲鍚庣殑瀛楃涓�
+     */
+    public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
+        // message 涓� null 杩斿洖绌哄瓧绗︿覆
+        if (message == null) {
+            return StringPool.EMPTY;
+        }
+        // 鍙傛暟涓� null 鎴栬�呬负绌�
+        if (params == null || params.isEmpty()) {
+            return message;
+        }
+        // 鏇挎崲鍙橀噺
+        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
+        int cursor = 0;
+        for (int start, end; (start = message.indexOf(StringPool.DOLLAR_LEFT_BRACE, cursor)) != -1 && (end = message.indexOf(StringPool.RIGHT_BRACE, start)) != -1; ) {
+            sb.append(message, cursor, start);
+            String key = message.substring(start + 2, end);
+            Object value = params.get(StringUtil.trimWhitespace(key));
+            sb.append(value == null ? StringPool.EMPTY : value);
+            cursor = end + 1;
+        }
+        sb.append(message.substring(cursor));
+        return sb.toString();
+    }
+
+    /**
+     * 鍚� log 鏍煎紡鐨� format 瑙勫垯
+     * <p>
+     * use: format("my name is {}, and i like {}!", "L.cm", "Java")
+     *
+     * @param message   闇�瑕佽浆鎹㈢殑瀛楃涓�
+     * @param arguments 闇�瑕佹浛鎹㈢殑鍙橀噺
+     * @return 杞崲鍚庣殑瀛楃涓�
+     */
+    public static String format(@Nullable String message, @Nullable Object... arguments) {
+        // message 涓� null 杩斿洖绌哄瓧绗︿覆
+        if (message == null) {
+            return StringPool.EMPTY;
+        }
+        // 鍙傛暟涓� null 鎴栬�呬负绌�
+        if (arguments == null || arguments.length == 0) {
+            return message;
+        }
+        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
+        int cursor = 0;
+        int index = 0;
+        int argsLength = arguments.length;
+        for (int start, end; (start = message.indexOf('{', cursor)) != -1 && (end = message.indexOf('}', start)) != -1 && index < argsLength; ) {
+            sb.append(message, cursor, start);
+            sb.append(arguments[index]);
+            cursor = end + 1;
+            index++;
+        }
+        sb.append(message.substring(cursor));
+        return sb.toString();
+    }
+
+    /**
+     * 鏍煎紡鍖栨墽琛屾椂闂达紝鍗曚綅涓� ms 鍜� s锛屼繚鐣欎笁浣嶅皬鏁�
+     *
+     * @param nanos 绾崇
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+     */
+    public static String format(long nanos) {
+        if (nanos < 1) {
+            return "0ms";
+        }
+        double millis = (double) nanos / (1000 * 1000);
+        // 涓嶅 1 ms锛屾渶灏忓崟浣嶄负 ms
+        if (millis > 1000) {
+            return String.format("%.3fs", millis / 1000);
+        } else {
+            return String.format("%.3fms", millis);
+        }
+    }
+
+    /**
+     * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV).
+     * <p>Useful for {@code toString()} implementations.
+     *
+     * @param coll the {@code Collection} to convert
+     * @return the delimited {@code String}
+     */
+    public static String join(Collection<?> coll) {
+        return StringUtil.collectionToCommaDelimitedString(coll);
+    }
+
+    /**
+     * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV).
+     * <p>Useful for {@code toString()} implementations.
+     *
+     * @param coll  the {@code Collection} to convert
+     * @param delim the delimiter to use (typically a ",")
+     * @return the delimited {@code String}
+     */
+    public static String join(Collection<?> coll, String delim) {
+        return StringUtil.collectionToDelimitedString(coll, delim);
+    }
+
+    /**
+     * Convert a {@code String} array into a comma delimited {@code String}
+     * (i.e., CSV).
+     * <p>Useful for {@code toString()} implementations.
+     *
+     * @param arr the array to display
+     * @return the delimited {@code String}
+     */
+    public static String join(Object[] arr) {
+        return StringUtil.arrayToCommaDelimitedString(arr);
+    }
+
+    /**
+     * Convert a {@code String} array into a delimited {@code String} (e.g. CSV).
+     * <p>Useful for {@code toString()} implementations.
+     *
+     * @param arr   the array to display
+     * @param delim the delimiter to use (typically a ",")
+     * @return the delimited {@code String}
+     */
+    public static String join(Object[] arr, String delim) {
+        return StringUtil.arrayToDelimitedString(arr, delim);
+    }
+
+    /**
+     * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+     *
+     * <p>
+     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+     * </p>
+     *
+     * @param pattern 琛ㄨ揪寮�
+     * @param str     瀛楃涓�
+     * @return 鏄惁鍖归厤
+     */
+    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
+        return PatternMatchUtils.simpleMatch(pattern, str);
+    }
+
+    /**
+     * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+     *
+     * <p>
+     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+     * </p>
+     *
+     * @param patterns 琛ㄨ揪寮� 鏁扮粍
+     * @param str      瀛楃涓�
+     * @return 鏄惁鍖归厤
+     */
+    public static boolean simpleMatch(@Nullable String[] patterns, String str) {
+        return PatternMatchUtils.simpleMatch(patterns, str);
+    }
+
+    /**
+     * 鐢熸垚uuid
+     *
+     * @return UUID
+     */
+    public static String randomUUID() {
+        ThreadLocalRandom random = ThreadLocalRandom.current();
+        return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
+    }
+
+    /**
+     * 杞箟HTML鐢ㄤ簬瀹夊叏杩囨护
+     *
+     * @param html html
+     * @return {String}
+     */
+    public static String escapeHtml(String html) {
+        return StringUtil.isBlank(html) ? StringPool.EMPTY : HtmlUtils.htmlEscape(html);
+    }
+
+    /**
+     * 娓呯悊瀛楃涓诧紝娓呯悊鍑烘煇浜涗笉鍙瀛楃
+     *
+     * @param txt 瀛楃涓�
+     * @return {String}
+     */
+    public static String cleanChars(String txt) {
+        return txt.replaceAll("[ 銆�`路鈥拷\\f\\t\\v\\s]", "");
+    }
+
+    /**
+     * 鐗规畩瀛楃姝e垯锛宻ql鐗规畩瀛楃鍜岀┖鐧界
+     */
+    private final static Pattern SPECIAL_CHARS_REGEX = Pattern.compile("[`'\"|/,;()-+*%#路鈥拷銆�\\s]");
+
+    /**
+     * 娓呯悊瀛楃涓诧紝娓呯悊鍑烘煇浜涗笉鍙瀛楃鍜屼竴浜泂ql鐗规畩瀛楃
+     *
+     * @param txt 鏂囨湰
+     * @return {String}
+     */
+    @Nullable
+    public static String cleanText(@Nullable String txt) {
+        if (txt == null) {
+            return null;
+        }
+        return SPECIAL_CHARS_REGEX.matcher(txt).replaceAll(StringPool.EMPTY);
+    }
+
+    /**
+     * 鑾峰彇鏍囪瘑绗︼紝鐢ㄤ簬鍙傛暟娓呯悊
+     *
+     * @param param 鍙傛暟
+     * @return 娓呯悊鍚庣殑鏍囪瘑绗�
+     */
+    @Nullable
+    public static String cleanIdentifier(@Nullable String param) {
+        if (param == null) {
+            return null;
+        }
+        StringBuilder paramBuilder = new StringBuilder();
+        for (int i = 0; i < param.length(); i++) {
+            char c = param.charAt(i);
+            if (Character.isJavaIdentifierPart(c)) {
+                paramBuilder.append(c);
+            }
+        }
+        return paramBuilder.toString();
+    }
+
+    /**
+     * 闅忔満鏁扮敓鎴�
+     *
+     * @param count 瀛楃闀垮害
+     * @return 闅忔満鏁�
+     */
+    public static String random(int count) {
+        return StringUtil.random(count, RandomType.ALL);
+    }
+
+    /**
+     * 闅忔満鏁扮敓鎴�
+     *
+     * @param count      瀛楃闀垮害
+     * @param randomType 闅忔満鏁扮被鍒�
+     * @return 闅忔満鏁�
+     */
+    public static String random(int count, RandomType randomType) {
+        if (count == 0) {
+            return StringPool.EMPTY;
+        }
+        Assert.isTrue(count > 0, "Requested random string length " + count + " is less than 0.");
+        final Random random = Holder.SECURE_RANDOM;
+        char[] buffer = new char[count];
+        for (int i = 0; i < count; i++) {
+            String factor = randomType.getFactor();
+            buffer[i] = factor.charAt(random.nextInt(factor.length()));
+        }
+        return new String(buffer);
+    }
+
+    /**
+     * 鏈夊簭鐨勬牸寮忓寲鏂囨湰锛屼娇鐢▄number}鍋氫负鍗犱綅绗�<br>
+     * 渚嬶細<br>
+     * 閫氬父浣跨敤锛歠ormat("this is {0} for {1}", "a", "b") =銆� this is a for b<br>
+     *
+     * @param pattern   鏂囨湰鏍煎紡
+     * @param arguments 鍙傛暟
+     * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
+     */
+    public static String indexedFormat(CharSequence pattern, Object... arguments) {
+        return MessageFormat.format(pattern.toString(), arguments);
+    }
+
+    /**
+     * 鏍煎紡鍖栨枃鏈紝浣跨敤 {varName} 鍗犱綅<br>
+     * map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=銆� aValue and bValue
+     *
+     * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {key} 琛ㄧず
+     * @param map      鍙傛暟鍊煎
+     * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
+     */
+    public static String format(CharSequence template, Map<?, ?> map) {
+        if (null == template) {
+            return null;
+        }
+        if (null == map || map.isEmpty()) {
+            return template.toString();
+        }
+
+        String template2 = template.toString();
+        for (Map.Entry<?, ?> entry : map.entrySet()) {
+            template2 = template2.replace("{" + entry.getKey() + "}", Func.toStr(entry.getValue()));
+        }
+        return template2;
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝涓嶅幓闄ゅ垏鍒嗗悗姣忎釜鍏冪礌涓よ竟鐨勭┖鐧界锛屼笉鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @param limit     闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     */
+    public static List<String> split(CharSequence str, char separator, int limit) {
+        return split(str, separator, limit, false, false);
+    }
+
+    /**
+     * 鍒嗗壊 瀛楃涓� 鍒犻櫎甯歌 绌虹櫧绗�
+     *
+     * @param str       瀛楃涓�
+     * @param delimiter 鍒嗗壊绗�
+     * @return 瀛楃涓叉暟缁�
+     */
+    public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
+        return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.1.2
+     */
+    public static List<String> splitTrim(CharSequence str, char separator) {
+        return splitTrim(str, separator, -1);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.0
+     */
+    public static List<String> splitTrim(CharSequence str, CharSequence separator) {
+        return splitTrim(str, separator, -1);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @param limit     闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.1.0
+     */
+    public static List<String> splitTrim(CharSequence str, char separator, int limit) {
+        return split(str, separator, limit, true, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗﹀瓧绗�
+     * @param limit     闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.0
+     */
+    public static List<String> splitTrim(CharSequence str, CharSequence separator, int limit) {
+        return split(str, separator, limit, true, true);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓诧紝涓嶉檺鍒跺垎鐗囨暟閲�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(CharSequence str, char separator, boolean isTrim, boolean ignoreEmpty) {
+        return split(str, separator, 0, isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.0.8
+     */
+    public static List<String> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        if (null == str) {
+            return new ArrayList<>(0);
+        }
+        return StrSpliter.split(str.toString(), separator, limit, isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str         琚垏鍒嗙殑瀛楃涓�
+     * @param separator   鍒嗛殧绗﹀瓧绗�
+     * @param limit       闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+     * @param isTrim      鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+     * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+     * @return 鍒囧垎鍚庣殑闆嗗悎
+     * @since 3.2.0
+     */
+    public static List<String> split(CharSequence str, CharSequence separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+        if (null == str) {
+            return new ArrayList<>(0);
+        }
+        final String separatorStr = (null == separator) ? null : separator.toString();
+        return StrSpliter.split(str.toString(), separatorStr, limit, isTrim, ignoreEmpty);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楃涓�
+     */
+    public static String[] split(CharSequence str, CharSequence separator) {
+        if (str == null) {
+            return new String[]{};
+        }
+
+        final String separatorStr = (null == separator) ? null : separator.toString();
+        return StrSpliter.splitToArray(str.toString(), separatorStr, 0, false, false);
+    }
+
+    /**
+     * 鏍规嵁缁欏畾闀垮害锛屽皢缁欏畾瀛楃涓叉埅鍙栦负澶氫釜閮ㄥ垎
+     *
+     * @param str 瀛楃涓�
+     * @param len 姣忎竴涓皬鑺傜殑闀垮害
+     * @return 鎴彇鍚庣殑瀛楃涓叉暟缁�
+     * @see StrSpliter#splitByLength(String, int)
+     */
+    public static String[] split(CharSequence str, int len) {
+        if (null == str) {
+            return new String[]{};
+        }
+        return StrSpliter.splitByLength(str.toString(), len);
+    }
+
+    /**
+     * 鎸囧畾瀛楃鏄惁鍦ㄥ瓧绗︿覆涓嚭鐜拌繃
+     *
+     * @param str        瀛楃涓�
+     * @param searchChar 琚煡鎵剧殑瀛楃
+     * @return 鏄惁鍖呭惈
+     * @since 3.1.2
+     */
+    public static boolean contains(CharSequence str, char searchChar) {
+        return indexOf(str, searchChar) > -1;
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆
+     *
+     * @param str      鎸囧畾瀛楃涓�
+     * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
+     * @since 3.2.0
+     */
+    public static boolean containsAny(CharSequence str, CharSequence... testStrs) {
+        return null != getContainsStr(str, testStrs);
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆锛屽鏋滃寘鍚繑鍥炴壘鍒扮殑绗竴涓瓧绗︿覆
+     *
+     * @param str      鎸囧畾瀛楃涓�
+     * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 琚寘鍚殑绗竴涓瓧绗︿覆
+     * @since 3.2.0
+     */
+    public static String getContainsStr(CharSequence str, CharSequence... testStrs) {
+        if (isEmpty(str) || Func.isEmpty(testStrs)) {
+            return null;
+        }
+        for (CharSequence checkStr : testStrs) {
+            if (str.toString().contains(checkStr)) {
+                return checkStr.toString();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鏄惁鍖呭惈鐗瑰畾瀛楃锛屽拷鐣ュぇ灏忓啓锛屽鏋滅粰瀹氫袱涓弬鏁伴兘涓�<code>null</code>锛岃繑鍥瀟rue
+     *
+     * @param str     琚娴嬪瓧绗︿覆
+     * @param testStr 琚祴璇曟槸鍚﹀寘鍚殑瀛楃涓�
+     * @return 鏄惁鍖呭惈
+     */
+    public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr) {
+        if (null == str) {
+            // 濡傛灉琚洃娴嬪瓧绗︿覆鍜�
+            return null == testStr;
+        }
+        return str.toString().toLowerCase().contains(testStr.toString().toLowerCase());
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆<br>
+     * 蹇界暐澶у皬鍐�
+     *
+     * @param str      鎸囧畾瀛楃涓�
+     * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
+     * @since 3.2.0
+     */
+    public static boolean containsAnyIgnoreCase(CharSequence str, CharSequence... testStrs) {
+        return null != getContainsStrIgnoreCase(str, testStrs);
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆锛屽鏋滃寘鍚繑鍥炴壘鍒扮殑绗竴涓瓧绗︿覆<br>
+     * 蹇界暐澶у皬鍐�
+     *
+     * @param str      鎸囧畾瀛楃涓�
+     * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 琚寘鍚殑绗竴涓瓧绗︿覆
+     * @since 3.2.0
+     */
+    public static String getContainsStrIgnoreCase(CharSequence str, CharSequence... testStrs) {
+        if (isEmpty(str) || Func.isEmpty(testStrs)) {
+            return null;
+        }
+        for (CharSequence testStr : testStrs) {
+            if (containsIgnoreCase(str, testStr)) {
+                return testStr.toString();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鏀硅繘JDK subString<br>
+     * index浠�0寮�濮嬭绠楋紝鏈�鍚庝竴涓瓧绗︿负-1<br>
+     * 濡傛灉from鍜宼o浣嶇疆涓�鏍凤紝杩斿洖 "" <br>
+     * 濡傛灉from鎴杢o涓鸿礋鏁帮紝鍒欐寜鐓ength浠庡悗鍚戝墠鏁颁綅缃紝濡傛灉缁濆鍊煎ぇ浜庡瓧绗︿覆闀垮害锛屽垯from褰掑埌0锛宼o褰掑埌length<br>
+     * 濡傛灉缁忚繃淇鐨刬ndex涓璮rom澶т簬to锛屽垯浜掓崲from鍜宼o example: <br>
+     * abcdefgh 2 3 =銆� c <br>
+     * abcdefgh 2 -3 =銆� cde <br>
+     *
+     * @param str       String
+     * @param fromIndex 寮�濮嬬殑index锛堝寘鎷級
+     * @param toIndex   缁撴潫鐨刬ndex锛堜笉鍖呮嫭锛�
+     * @return 瀛椾覆
+     */
+    public static String sub(CharSequence str, int fromIndex, int toIndex) {
+        if (isEmpty(str)) {
+            return StringPool.EMPTY;
+        }
+        int len = str.length();
+
+        if (fromIndex < 0) {
+            fromIndex = len + fromIndex;
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+        } else if (fromIndex > len) {
+            fromIndex = len;
+        }
+
+        if (toIndex < 0) {
+            toIndex = len + toIndex;
+            if (toIndex < 0) {
+                toIndex = len;
+            }
+        } else if (toIndex > len) {
+            toIndex = len;
+        }
+
+        if (toIndex < fromIndex) {
+            int tmp = fromIndex;
+            fromIndex = toIndex;
+            toIndex = tmp;
+        }
+
+        if (fromIndex == toIndex) {
+            return StringPool.EMPTY;
+        }
+
+        return str.toString().substring(fromIndex, toIndex);
+    }
+
+
+    /**
+     * 鎴彇鍒嗛殧瀛楃涓蹭箣鍓嶇殑瀛楃涓诧紝涓嶅寘鎷垎闅斿瓧绗︿覆<br>
+     * 濡傛灉缁欏畾鐨勫瓧绗︿覆涓虹┖涓诧紙null鎴�""锛夋垨鑰呭垎闅斿瓧绗︿覆涓簄ull锛岃繑鍥炲師瀛楃涓�<br>
+     * 濡傛灉鍒嗛殧瀛楃涓蹭负绌轰覆""锛屽垯杩斿洖绌轰覆锛屽鏋滃垎闅斿瓧绗︿覆鏈壘鍒帮紝杩斿洖鍘熷瓧绗︿覆
+     * <p>
+     * 鏍楀瓙锛�
+     *
+     * <pre>
+     * StringUtil.subBefore(null, *)      = null
+     * StringUtil.subBefore("", *)        = ""
+     * StringUtil.subBefore("abc", "a")   = ""
+     * StringUtil.subBefore("abcba", "b") = "a"
+     * StringUtil.subBefore("abc", "c")   = "ab"
+     * StringUtil.subBefore("abc", "d")   = "abc"
+     * StringUtil.subBefore("abc", "")    = ""
+     * StringUtil.subBefore("abc", null)  = "abc"
+     * </pre>
+     *
+     * @param string          琚煡鎵剧殑瀛楃涓�
+     * @param separator       鍒嗛殧瀛楃涓诧紙涓嶅寘鎷級
+     * @param isLastSeparator 鏄惁鏌ユ壘鏈�鍚庝竴涓垎闅斿瓧绗︿覆锛堝娆″嚭鐜板垎闅斿瓧绗︿覆鏃堕�夊彇鏈�鍚庝竴涓級锛宼rue涓洪�夊彇鏈�鍚庝竴涓�
+     * @return 鍒囧壊鍚庣殑瀛楃涓�
+     * @since 3.1.1
+     */
+    public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+        if (isEmpty(string) || separator == null) {
+            return null == string ? null : string.toString();
+        }
+
+        final String str = string.toString();
+        final String sep = separator.toString();
+        if (sep.isEmpty()) {
+            return StringPool.EMPTY;
+        }
+        final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+        if (pos == INDEX_NOT_FOUND) {
+            return str;
+        }
+        return str.substring(0, pos);
+    }
+
+    /**
+     * 鎴彇鍒嗛殧瀛楃涓蹭箣鍚庣殑瀛楃涓诧紝涓嶅寘鎷垎闅斿瓧绗︿覆<br>
+     * 濡傛灉缁欏畾鐨勫瓧绗︿覆涓虹┖涓诧紙null鎴�""锛夛紝杩斿洖鍘熷瓧绗︿覆<br>
+     * 濡傛灉鍒嗛殧瀛楃涓蹭负绌轰覆锛坣ull鎴�""锛夛紝鍒欒繑鍥炵┖涓诧紝濡傛灉鍒嗛殧瀛楃涓叉湭鎵惧埌锛岃繑鍥炵┖涓�
+     * <p>
+     * 鏍楀瓙锛�
+     *
+     * <pre>
+     * StringUtil.subAfter(null, *)      = null
+     * StringUtil.subAfter("", *)        = ""
+     * StringUtil.subAfter(*, null)      = ""
+     * StringUtil.subAfter("abc", "a")   = "bc"
+     * StringUtil.subAfter("abcba", "b") = "cba"
+     * StringUtil.subAfter("abc", "c")   = ""
+     * StringUtil.subAfter("abc", "d")   = ""
+     * StringUtil.subAfter("abc", "")    = "abc"
+     * </pre>
+     *
+     * @param string          琚煡鎵剧殑瀛楃涓�
+     * @param separator       鍒嗛殧瀛楃涓诧紙涓嶅寘鎷級
+     * @param isLastSeparator 鏄惁鏌ユ壘鏈�鍚庝竴涓垎闅斿瓧绗︿覆锛堝娆″嚭鐜板垎闅斿瓧绗︿覆鏃堕�夊彇鏈�鍚庝竴涓級锛宼rue涓洪�夊彇鏈�鍚庝竴涓�
+     * @return 鍒囧壊鍚庣殑瀛楃涓�
+     * @since 3.1.1
+     */
+    public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+        if (isEmpty(string)) {
+            return null == string ? null : string.toString();
+        }
+        if (separator == null) {
+            return StringPool.EMPTY;
+        }
+        final String str = string.toString();
+        final String sep = separator.toString();
+        final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+        if (pos == INDEX_NOT_FOUND) {
+            return StringPool.EMPTY;
+        }
+        return str.substring(pos + separator.length());
+    }
+
+    /**
+     * 鎴彇鎸囧畾瀛楃涓蹭腑闂撮儴鍒嗭紝涓嶅寘鎷爣璇嗗瓧绗︿覆<br>
+     * <p>
+     * 鏍楀瓙锛�
+     *
+     * <pre>
+     * StringUtil.subBetween("wx[b]yz", "[", "]") = "b"
+     * StringUtil.subBetween(null, *, *)          = null
+     * StringUtil.subBetween(*, null, *)          = null
+     * StringUtil.subBetween(*, *, null)          = null
+     * StringUtil.subBetween("", "", "")          = ""
+     * StringUtil.subBetween("", "", "]")         = null
+     * StringUtil.subBetween("", "[", "]")        = null
+     * StringUtil.subBetween("yabcz", "", "")     = ""
+     * StringUtil.subBetween("yabcz", "y", "z")   = "abc"
+     * StringUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
+     * </pre>
+     *
+     * @param str    琚垏鍓茬殑瀛楃涓�
+     * @param before 鎴彇寮�濮嬬殑瀛楃涓叉爣璇�
+     * @param after  鎴彇鍒扮殑瀛楃涓叉爣璇�
+     * @return 鎴彇鍚庣殑瀛楃涓�
+     * @since 3.1.1
+     */
+    public static String subBetween(CharSequence str, CharSequence before, CharSequence after) {
+        if (str == null || before == null || after == null) {
+            return null;
+        }
+
+        final String str2 = str.toString();
+        final String before2 = before.toString();
+        final String after2 = after.toString();
+
+        final int start = str2.indexOf(before2);
+        if (start != INDEX_NOT_FOUND) {
+            final int end = str2.indexOf(after2, start + before2.length());
+            if (end != INDEX_NOT_FOUND) {
+                return str2.substring(start + before2.length(), end);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鎴彇鎸囧畾瀛楃涓蹭腑闂撮儴鍒嗭紝涓嶅寘鎷爣璇嗗瓧绗︿覆<br>
+     * <p>
+     * 鏍楀瓙锛�
+     *
+     * <pre>
+     * StringUtil.subBetween(null, *)            = null
+     * StringUtil.subBetween("", "")             = ""
+     * StringUtil.subBetween("", "tag")          = null
+     * StringUtil.subBetween("tagabctag", null)  = null
+     * StringUtil.subBetween("tagabctag", "")    = ""
+     * StringUtil.subBetween("tagabctag", "tag") = "abc"
+     * </pre>
+     *
+     * @param str            琚垏鍓茬殑瀛楃涓�
+     * @param beforeAndAfter 鎴彇寮�濮嬪拰缁撴潫鐨勫瓧绗︿覆鏍囪瘑
+     * @return 鎴彇鍚庣殑瀛楃涓�
+     * @since 3.1.1
+     */
+    public static String subBetween(CharSequence str, CharSequence beforeAndAfter) {
+        return subBetween(str, beforeAndAfter, beforeAndAfter);
+    }
+
+    /**
+     * 鍘绘帀鎸囧畾鍓嶇紑
+     *
+     * @param str    瀛楃涓�
+     * @param prefix 鍓嶇紑
+     * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ墠缂�涓嶆槸 preffix锛� 杩斿洖鍘熷瓧绗︿覆
+     */
+    public static String removePrefix(CharSequence str, CharSequence prefix) {
+        if (isEmpty(str) || isEmpty(prefix)) {
+            return StringPool.EMPTY;
+        }
+
+        final String str2 = str.toString();
+        if (str2.startsWith(prefix.toString())) {
+            return subSuf(str2, prefix.length());
+        }
+        return str2;
+    }
+
+    /**
+     * 蹇界暐澶у皬鍐欏幓鎺夋寚瀹氬墠缂�
+     *
+     * @param str    瀛楃涓�
+     * @param prefix 鍓嶇紑
+     * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ墠缂�涓嶆槸 prefix锛� 杩斿洖鍘熷瓧绗︿覆
+     */
+    public static String removePrefixIgnoreCase(CharSequence str, CharSequence prefix) {
+        if (isEmpty(str) || isEmpty(prefix)) {
+            return StringPool.EMPTY;
+        }
+
+        final String str2 = str.toString();
+        if (str2.toLowerCase().startsWith(prefix.toString().toLowerCase())) {
+            return subSuf(str2, prefix.length());
+        }
+        return str2;
+    }
+
+    /**
+     * 鍘绘帀鎸囧畾鍚庣紑
+     *
+     * @param str    瀛楃涓�
+     * @param suffix 鍚庣紑
+     * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+     */
+    public static String removeSuffix(CharSequence str, CharSequence suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return StringPool.EMPTY;
+        }
+
+        final String str2 = str.toString();
+        if (str2.endsWith(suffix.toString())) {
+            return subPre(str2, str2.length() - suffix.length());
+        }
+        return str2;
+    }
+
+    /**
+     * 鍘绘帀鎸囧畾鍚庣紑锛屽苟灏忓啓棣栧瓧姣�
+     *
+     * @param str    瀛楃涓�
+     * @param suffix 鍚庣紑
+     * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+     */
+    public static String removeSufAndLowerFirst(CharSequence str, CharSequence suffix) {
+        return firstCharToLower(removeSuffix(str, suffix));
+    }
+
+    /**
+     * 蹇界暐澶у皬鍐欏幓鎺夋寚瀹氬悗缂�
+     *
+     * @param str    瀛楃涓�
+     * @param suffix 鍚庣紑
+     * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+     */
+    public static String removeSuffixIgnoreCase(CharSequence str, CharSequence suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return StringPool.EMPTY;
+        }
+
+        final String str2 = str.toString();
+        if (str2.toLowerCase().endsWith(suffix.toString().toLowerCase())) {
+            return subPre(str2, str2.length() - suffix.length());
+        }
+        return str2;
+    }
+
+    /**
+     * 棣栧瓧姣嶅彉灏忓啓
+     *
+     * @param str 瀛楃涓�
+     * @return {String}
+     */
+    public static String firstCharToLower(String str) {
+        char firstChar = str.charAt(0);
+        if (firstChar >= CharPool.UPPER_A && firstChar <= CharPool.UPPER_Z) {
+            char[] arr = str.toCharArray();
+            arr[0] += (CharPool.LOWER_A - CharPool.UPPER_A);
+            return new String(arr);
+        }
+        return str;
+    }
+
+    /**
+     * 棣栧瓧姣嶅彉澶у啓
+     *
+     * @param str 瀛楃涓�
+     * @return {String}
+     */
+    public static String firstCharToUpper(String str) {
+        char firstChar = str.charAt(0);
+        if (firstChar >= CharPool.LOWER_A && firstChar <= CharPool.LOWER_Z) {
+            char[] arr = str.toCharArray();
+            arr[0] -= (CharPool.LOWER_A - CharPool.UPPER_A);
+            return new String(arr);
+        }
+        return str;
+    }
+
+    /**
+     * 鍒囧壊鎸囧畾浣嶇疆涔嬪墠閮ㄥ垎鐨勫瓧绗︿覆
+     *
+     * @param string  瀛楃涓�
+     * @param toIndex 鍒囧壊鍒扮殑浣嶇疆锛堜笉鍖呮嫭锛�
+     * @return 鍒囧壊鍚庣殑鍓╀綑鐨勫墠鍗婇儴鍒嗗瓧绗︿覆
+     */
+    public static String subPre(CharSequence string, int toIndex) {
+        return sub(string, 0, toIndex);
+    }
+
+    /**
+     * 鍒囧壊鎸囧畾浣嶇疆涔嬪悗閮ㄥ垎鐨勫瓧绗︿覆
+     *
+     * @param string    瀛楃涓�
+     * @param fromIndex 鍒囧壊寮�濮嬬殑浣嶇疆锛堝寘鎷級
+     * @return 鍒囧壊鍚庡悗鍓╀綑鐨勫悗鍗婇儴鍒嗗瓧绗︿覆
+     */
+    public static String subSuf(CharSequence string, int fromIndex) {
+        if (isEmpty(string)) {
+            return null;
+        }
+        return sub(string, fromIndex, string.length());
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+     *
+     * @param str        瀛楃涓�
+     * @param searchChar 琚煡鎵剧殑瀛楃
+     * @return 浣嶇疆
+     */
+    public static int indexOf(final CharSequence str, char searchChar) {
+        return indexOf(str, searchChar, 0);
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+     *
+     * @param str        瀛楃涓�
+     * @param searchChar 琚煡鎵剧殑瀛楃
+     * @param start      璧峰浣嶇疆锛屽鏋滃皬浜�0锛屼粠0寮�濮嬫煡鎵�
+     * @return 浣嶇疆
+     */
+    public static int indexOf(final CharSequence str, char searchChar, int start) {
+        if (str instanceof String) {
+            return ((String) str).indexOf(searchChar, start);
+        } else {
+            return indexOf(str, searchChar, start, -1);
+        }
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+     *
+     * @param str        瀛楃涓�
+     * @param searchChar 琚煡鎵剧殑瀛楃
+     * @param start      璧峰浣嶇疆锛屽鏋滃皬浜�0锛屼粠0寮�濮嬫煡鎵�
+     * @param end        缁堟浣嶇疆锛屽鏋滆秴杩噑tr.length()鍒欓粯璁ゆ煡鎵惧埌瀛楃涓叉湯灏�
+     * @return 浣嶇疆
+     */
+    public static int indexOf(final CharSequence str, char searchChar, int start, int end) {
+        final int len = str.length();
+        if (start < 0 || start > len) {
+            start = 0;
+        }
+        if (end > len || end < 0) {
+            end = len;
+        }
+        for (int i = start; i < end; i++) {
+            if (str.charAt(i) == searchChar) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+     *
+     * <pre>
+     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+     * </pre>
+     *
+     * @param str       瀛楃涓�
+     * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+        return indexOfIgnoreCase(str, searchStr, 0);
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆
+     *
+     * <pre>
+     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+     * </pre>
+     *
+     * @param str       瀛楃涓�
+     * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @param fromIndex 璧峰浣嶇疆
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
+        return indexOf(str, searchStr, fromIndex, true);
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呭弽鍚戞煡鎵惧瓧绗︿覆
+     *
+     * @param str        瀛楃涓�
+     * @param searchStr  闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @param fromIndex  璧峰浣嶇疆
+     * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) {
+        if (str == null || searchStr == null) {
+            return INDEX_NOT_FOUND;
+        }
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        }
+
+        final int endLimit = str.length() - searchStr.length() + 1;
+        if (fromIndex > endLimit) {
+            return INDEX_NOT_FOUND;
+        }
+        if (searchStr.length() == 0) {
+            return fromIndex;
+        }
+
+        if (false == ignoreCase) {
+            // 涓嶅拷鐣ュぇ灏忓啓璋冪敤JDK鏂规硶
+            return str.toString().indexOf(searchStr.toString(), fromIndex);
+        }
+
+        for (int i = fromIndex; i < endLimit; i++) {
+            if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
+                return i;
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+     *
+     * @param str       瀛楃涓�
+     * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+        return lastIndexOfIgnoreCase(str, searchStr, str.length());
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+     *
+     * @param str       瀛楃涓�
+     * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @param fromIndex 璧峰浣嶇疆锛屼粠鍚庡線鍓嶈鏁�
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
+        return lastIndexOf(str, searchStr, fromIndex, true);
+    }
+
+    /**
+     * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆<br>
+     *
+     * @param str        瀛楃涓�
+     * @param searchStr  闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+     * @param fromIndex  璧峰浣嶇疆锛屼粠鍚庡線鍓嶈鏁�
+     * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+     * @return 浣嶇疆
+     * @since 3.2.1
+     */
+    public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase) {
+        if (str == null || searchStr == null) {
+            return INDEX_NOT_FOUND;
+        }
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        }
+        fromIndex = Math.min(fromIndex, str.length());
+
+        if (searchStr.length() == 0) {
+            return fromIndex;
+        }
+
+        if (false == ignoreCase) {
+            // 涓嶅拷鐣ュぇ灏忓啓璋冪敤JDK鏂规硶
+            return str.toString().lastIndexOf(searchStr.toString(), fromIndex);
+        }
+
+        for (int i = fromIndex; i > 0; i--) {
+            if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
+                return i;
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    /**
+     * 杩斿洖瀛楃涓� searchStr 鍦ㄥ瓧绗︿覆 str 涓 ordinal 娆″嚭鐜扮殑浣嶇疆銆�<br>
+     * 姝ゆ柟娉曟潵鑷細Apache-Commons-Lang
+     * <p>
+     * 鏍楀瓙锛�*浠h〃浠绘剰瀛楃锛夛細
+     *
+     * <pre>
+     * StringUtil.ordinalIndexOf(null, *, *)          = -1
+     * StringUtil.ordinalIndexOf(*, null, *)          = -1
+     * StringUtil.ordinalIndexOf("", "", *)           = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "a", 1)  = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "a", 2)  = 1
+     * StringUtil.ordinalIndexOf("aabaabaa", "b", 1)  = 2
+     * StringUtil.ordinalIndexOf("aabaabaa", "b", 2)  = 5
+     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+     * StringUtil.ordinalIndexOf("aabaabaa", "", 1)   = 0
+     * StringUtil.ordinalIndexOf("aabaabaa", "", 2)   = 0
+     * </pre>
+     *
+     * @param str       琚鏌ョ殑瀛楃涓诧紝鍙互涓簄ull
+     * @param searchStr 琚煡鎵剧殑瀛楃涓诧紝鍙互涓簄ull
+     * @param ordinal   绗嚑娆″嚭鐜扮殑浣嶇疆
+     * @return 鏌ユ壘鍒扮殑浣嶇疆
+     * @since 3.2.3
+     */
+    public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
+        if (str == null || searchStr == null || ordinal <= 0) {
+            return INDEX_NOT_FOUND;
+        }
+        if (searchStr.length() == 0) {
+            return 0;
+        }
+        int found = 0;
+        int index = INDEX_NOT_FOUND;
+        do {
+            index = str.indexOf(searchStr, index + 1);
+            if (index < 0) {
+                return index;
+            }
+            found++;
+        } while (found < ordinal);
+        return index;
+    }
+
+    /**
+     * 鎴彇涓や釜瀛楃涓茬殑涓嶅悓閮ㄥ垎锛堥暱搴︿竴鑷达級锛屽垽鏂埅鍙栫殑瀛愪覆鏄惁鐩稿悓<br>
+     * 浠绘剰涓�涓瓧绗︿覆涓簄ull杩斿洖false
+     *
+     * @param str1       绗竴涓瓧绗︿覆
+     * @param start1     绗竴涓瓧绗︿覆寮�濮嬬殑浣嶇疆
+     * @param str2       绗簩涓瓧绗︿覆
+     * @param start2     绗簩涓瓧绗︿覆寮�濮嬬殑浣嶇疆
+     * @param length     鎴彇闀垮害
+     * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+     * @return 瀛愪覆鏄惁鐩稿悓
+     * @since 3.2.1
+     */
+    public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase) {
+        if (null == str1 || null == str2) {
+            return false;
+        }
+
+        return str1.toString().regionMatches(ignoreCase, start1, str2.toString(), start2, length);
+    }
+
+    /**
+     * 姣旇緝涓や釜瀛楃涓诧紙澶у皬鍐欐晱鎰燂級銆�
+     *
+     * <pre>
+     * equalsIgnoreCase(null, null)   = true
+     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
+     * </pre>
+     *
+     * @param str1 瑕佹瘮杈冪殑瀛楃涓�1
+     * @param str2 瑕佹瘮杈冪殑瀛楃涓�2
+     * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+     */
+    public static boolean equals(CharSequence str1, CharSequence str2) {
+        return equals(str1, str2, false);
+    }
+
+    /**
+     * 姣旇緝涓や釜瀛楃涓诧紙澶у皬鍐欎笉鏁忔劅锛夈��
+     *
+     * <pre>
+     * equalsIgnoreCase(null, null)   = true
+     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
+     * </pre>
+     *
+     * @param str1 瑕佹瘮杈冪殑瀛楃涓�1
+     * @param str2 瑕佹瘮杈冪殑瀛楃涓�2
+     * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+     */
+    public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
+        return equals(str1, str2, true);
+    }
+
+    /**
+     * 姣旇緝涓や釜瀛楃涓叉槸鍚︾浉绛夈��
+     *
+     * @param str1       瑕佹瘮杈冪殑瀛楃涓�1
+     * @param str2       瑕佹瘮杈冪殑瀛楃涓�2
+     * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+     * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+     * @since 3.2.0
+     */
+    public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
+        if (null == str1) {
+            // 鍙湁涓や釜閮戒负null鎵嶅垽鏂浉绛�
+            return str2 == null;
+        }
+        if (null == str2) {
+            // 瀛楃涓�2绌猴紝瀛楃涓�1闈炵┖锛岀洿鎺alse
+            return false;
+        }
+
+        if (ignoreCase) {
+            return str1.toString().equalsIgnoreCase(str2.toString());
+        } else {
+            return str1.equals(str2);
+        }
+    }
+
+    /**
+     * 鍒涘缓StringBuilder瀵硅薄
+     *
+     * @return {String}Builder瀵硅薄
+     */
+    public static StringBuilder builder() {
+        return new StringBuilder();
+    }
+
+    /**
+     * 鍒涘缓StringBuilder瀵硅薄
+     *
+     * @param capacity 鍒濆澶у皬
+     * @return {String}Builder瀵硅薄
+     */
+    public static StringBuilder builder(int capacity) {
+        return new StringBuilder(capacity);
+    }
+
+    /**
+     * 鍒涘缓StringBuilder瀵硅薄
+     *
+     * @param strs 鍒濆瀛楃涓插垪琛�
+     * @return {String}Builder瀵硅薄
+     */
+    public static StringBuilder builder(CharSequence... strs) {
+        final StringBuilder sb = new StringBuilder();
+        for (CharSequence str : strs) {
+            sb.append(str);
+        }
+        return sb;
+    }
+
+    /**
+     * 鍒涘缓StringBuilder瀵硅薄
+     *
+     * @param sb   鍒濆StringBuilder
+     * @param strs 鍒濆瀛楃涓插垪琛�
+     * @return {String}Builder瀵硅薄
+     */
+    public static StringBuilder appendBuilder(StringBuilder sb, CharSequence... strs) {
+        for (CharSequence str : strs) {
+            sb.append(str);
+        }
+        return sb;
+    }
+
+    /**
+     * 鑾峰緱StringReader
+     *
+     * @param str 瀛楃涓�
+     * @return {String}Reader
+     */
+    public static StringReader getReader(CharSequence str) {
+        if (null == str) {
+            return null;
+        }
+        return new StringReader(str.toString());
+    }
+
+    /**
+     * 鑾峰緱StringWriter
+     *
+     * @return {String}Writer
+     */
+    public static StringWriter getWriter() {
+        return new StringWriter();
+    }
+
+    /**
+     * 缁熻鎸囧畾鍐呭涓寘鍚寚瀹氬瓧绗︿覆鐨勬暟閲�<br>
+     * 鍙傛暟涓� {@code null} 鎴栬�� "" 杩斿洖 {@code 0}.
+     *
+     * <pre>
+     * StringUtil.count(null, *)       = 0
+     * StringUtil.count("", *)         = 0
+     * StringUtil.count("abba", null)  = 0
+     * StringUtil.count("abba", "")    = 0
+     * StringUtil.count("abba", "a")   = 2
+     * StringUtil.count("abba", "ab")  = 1
+     * StringUtil.count("abba", "xxx") = 0
+     * </pre>
+     *
+     * @param content      琚煡鎵剧殑瀛楃涓�
+     * @param strForSearch 闇�瑕佹煡鎵剧殑瀛楃涓�
+     * @return 鏌ユ壘鍒扮殑涓暟
+     */
+    public static int count(CharSequence content, CharSequence strForSearch) {
+        if (Func.hasEmpty(content, strForSearch) || strForSearch.length() > content.length()) {
+            return 0;
+        }
+
+        int count = 0;
+        int idx = 0;
+        final String content2 = content.toString();
+        final String strForSearch2 = strForSearch.toString();
+        while ((idx = content2.indexOf(strForSearch2, idx)) > -1) {
+            count++;
+            idx += strForSearch.length();
+        }
+        return count;
+    }
+
+    /**
+     * 缁熻鎸囧畾鍐呭涓寘鍚寚瀹氬瓧绗︾殑鏁伴噺
+     *
+     * @param content       鍐呭
+     * @param charForSearch 琚粺璁$殑瀛楃
+     * @return 鍖呭惈鏁伴噺
+     */
+    public static int count(CharSequence content, char charForSearch) {
+        int count = 0;
+        if (isEmpty(content)) {
+            return 0;
+        }
+        int contentLength = content.length();
+        for (int i = 0; i < contentLength; i++) {
+            if (charForSearch == content.charAt(i)) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 涓嬪垝绾胯浆椹煎嘲
+     *
+     * @param para 瀛楃涓�
+     * @return {String}
+     */
+    public static String underlineToHump(String para) {
+        if (isBlank(para)) {
+            return StringPool.EMPTY;
+        }
+        StringBuilder result = new StringBuilder();
+        String[] a = para.split("_");
+        for (String s : a) {
+            if (result.length() == 0) {
+                result.append(s.toLowerCase());
+            } else {
+                result.append(s.substring(0, 1).toUpperCase());
+                result.append(s.substring(1).toLowerCase());
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * 椹煎嘲杞笅鍒掔嚎
+     *
+     * @param para 瀛楃涓�
+     * @return {String}
+     */
+    public static String humpToUnderline(String para) {
+        if (isBlank(para)) {
+            return StringPool.EMPTY;
+        }
+        para = firstCharToLower(para);
+        StringBuilder sb = new StringBuilder(para);
+        int temp = 0;
+        for (int i = 0; i < para.length(); i++) {
+            if (Character.isUpperCase(para.charAt(i))) {
+                sb.insert(i + temp, "_");
+                temp += 1;
+            }
+        }
+        return sb.toString().toLowerCase();
+    }
+
+    /**
+     * 妯嚎杞┘宄�
+     *
+     * @param para 瀛楃涓�
+     * @return {String}
+     */
+    public static String lineToHump(String para) {
+        if (isBlank(para)) {
+            return StringPool.EMPTY;
+        }
+        StringBuilder result = new StringBuilder();
+        String[] a = para.split("-");
+        for (String s : a) {
+            if (result.length() == 0) {
+                result.append(s.toLowerCase());
+            } else {
+                result.append(s.substring(0, 1).toUpperCase());
+                result.append(s.substring(1).toLowerCase());
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * 椹煎嘲杞í绾�
+     *
+     * @param para 瀛楃涓�
+     * @return {String}
+     */
+    public static String humpToLine(String para) {
+        if (isBlank(para)) {
+            return StringPool.EMPTY;
+        }
+        para = firstCharToLower(para);
+        StringBuilder sb = new StringBuilder(para);
+        int temp = 0;
+        for (int i = 0; i < para.length(); i++) {
+            if (Character.isUpperCase(para.charAt(i))) {
+                sb.insert(i + temp, "-");
+                temp += 1;
+            }
+        }
+        return sb.toString().toLowerCase();
+    }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java
new file mode 100644
index 0000000..e3ee236
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java
@@ -0,0 +1,35 @@
+package com.vci.web.util.jackson;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.vci.web.util.DateTimeUtil;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+ * java 8 鏃堕棿榛樿搴忓垪鍖�
+ *
+ * @author L.cm
+ */
+public class BladeJavaTimeModule extends SimpleModule {
+	public static final BladeJavaTimeModule INSTANCE = new BladeJavaTimeModule();
+
+	public BladeJavaTimeModule() {
+		super(PackageVersion.VERSION);
+		this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeUtil.DATETIME_FORMAT));
+		this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeUtil.DATE_FORMAT));
+		this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeUtil.TIME_FORMAT));
+		this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeUtil.DATETIME_FORMAT));
+		this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeUtil.DATE_FORMAT));
+		this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeUtil.TIME_FORMAT));
+	}
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java
new file mode 100644
index 0000000..dd459c3
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java
@@ -0,0 +1,705 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.web.util.jackson;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.TreeNode;
+import com.fasterxml.jackson.core.json.JsonReadFeature;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.type.CollectionLikeType;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.vci.web.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.lang.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+import java.util.*;
+
+/**
+ * Jackson宸ュ叿绫�
+ *
+ * @author Chill
+ */
+@Slf4j
+public class JsonUtil {
+
+	/**
+	 * 灏嗗璞″簭鍒楀寲鎴恓son瀛楃涓�
+	 *
+	 * @param value javaBean
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static <T> String toJson(T value) {
+		try {
+			return getInstance().writeValueAsString(value);
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		}
+		return null;
+	}
+
+	/**
+	 * 灏嗗璞″簭鍒楀寲鎴� json byte 鏁扮粍
+	 *
+	 * @param object javaBean
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static byte[] toJsonAsBytes(Object object) {
+		try {
+			return getInstance().writeValueAsBytes(object);
+		} catch (JsonProcessingException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param content   content
+	 * @param valueType class
+	 * @param <T>       T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(String content, Class<T> valueType) {
+		try {
+			return getInstance().readValue(content, valueType);
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		}
+		return null;
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param content       content
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(String content, TypeReference<T> typeReference) {
+		try {
+			return getInstance().readValue(content, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param bytes     json bytes
+	 * @param valueType class
+	 * @param <T>       T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(byte[] bytes, Class<T> valueType) {
+		try {
+			return getInstance().readValue(bytes, valueType);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param bytes         bytes
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
+		try {
+			return getInstance().readValue(bytes, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param in        InputStream
+	 * @param valueType class
+	 * @param <T>       T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(InputStream in, Class<T> valueType) {
+		try {
+			return getInstance().readValue(in, valueType);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param in            InputStream
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
+		try {
+			return getInstance().readValue(in, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴怢ist瀵硅薄
+	 *
+	 * @param content      content
+	 * @param valueTypeRef class
+	 * @param <T>          T 娉涘瀷鏍囪
+	 * @return List<T>
+	 */
+	public static <T> List<T> parseArray(String content, Class<T> valueTypeRef) {
+		try {
+
+			if (!StringUtil.startsWithIgnoreCase(content, StringPool.LEFT_SQ_BRACKET)) {
+				content = StringPool.LEFT_SQ_BRACKET + content + StringPool.RIGHT_SQ_BRACKET;
+			}
+
+			List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
+			});
+
+			List<T> result = new ArrayList<>();
+			for (Map<String, Object> map : list) {
+				result.add(toPojo(map, valueTypeRef));
+			}
+			return result;
+		} catch (IOException e) {
+			log.error(e.getMessage(), e);
+		}
+		return null;
+	}
+
+	/**
+	 * 灏唈son瀛楃涓茶浆鎴� JsonNode
+	 *
+	 * @param jsonString jsonString
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static JsonNode readTree(String jsonString) {
+		Objects.requireNonNull(jsonString, "jsonString is null");
+		try {
+			return getInstance().readTree(jsonString);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son瀛楃涓茶浆鎴� JsonNode
+	 *
+	 * @param in InputStream
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static JsonNode readTree(InputStream in) {
+		Objects.requireNonNull(in, "InputStream in is null");
+		try {
+			return getInstance().readTree(in);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son瀛楃涓茶浆鎴� JsonNode
+	 *
+	 * @param content content
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static JsonNode readTree(byte[] content) {
+		Objects.requireNonNull(content, "byte[] content is null");
+		try {
+			return getInstance().readTree(content);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son瀛楃涓茶浆鎴� JsonNode
+	 *
+	 * @param jsonParser JsonParser
+	 * @return jsonString json瀛楃涓�
+	 */
+	public static JsonNode readTree(JsonParser jsonParser) {
+		Objects.requireNonNull(jsonParser, "jsonParser is null");
+		try {
+			return getInstance().readTree(jsonParser);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+
+	/**
+	 * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param content   json bytes
+	 * @param valueType class
+	 * @param <T>       T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable byte[] content, Class<T> valueType) {
+		if (ObjectUtil.isEmpty(content)) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(content, valueType);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param jsonString jsonString
+	 * @param valueType  class
+	 * @param <T>        T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable String jsonString, Class<T> valueType) {
+		if (StringUtil.isBlank(jsonString)) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(jsonString, valueType);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param in        InputStream
+	 * @param valueType class
+	 * @param <T>       T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable InputStream in, Class<T> valueType) {
+		if (in == null) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(in, valueType);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param content       bytes
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable byte[] content, TypeReference<T> typeReference) {
+		if (ObjectUtil.isEmpty(content)) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(content, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param jsonString    jsonString
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable String jsonString, TypeReference<T> typeReference) {
+		if (StringUtil.isBlank(jsonString)) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(jsonString, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+	 *
+	 * @param in            InputStream
+	 * @param typeReference 娉涘瀷绫诲瀷
+	 * @param <T>           T 娉涘瀷鏍囪
+	 * @return Bean
+	 */
+	@Nullable
+	public static <T> T readValue(@Nullable InputStream in, TypeReference<T> typeReference) {
+		if (in == null) {
+			return null;
+		}
+		try {
+			return getInstance().readValue(in, typeReference);
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 灏佽 map type
+	 *
+	 * @param keyClass   key 绫诲瀷
+	 * @param valueClass value 绫诲瀷
+	 * @return MapType
+	 */
+	public static MapType getMapType(Class<?> keyClass, Class<?> valueClass) {
+		return getInstance().getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
+	}
+
+	/**
+	 * 灏佽 map type
+	 *
+	 * @param elementClass 闆嗗悎鍊肩被鍨�
+	 * @return CollectionLikeType
+	 */
+	public static CollectionLikeType getListType(Class<?> elementClass) {
+		return getInstance().getTypeFactory().constructCollectionLikeType(List.class, elementClass);
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content      bytes
+	 * @param elementClass elementClass
+	 * @param <T>          娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <T> List<T> readList(@Nullable byte[] content, Class<T> elementClass) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyList();
+		}
+		try {
+			return getInstance().readValue(content, getListType(elementClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content      InputStream
+	 * @param elementClass elementClass
+	 * @param <T>          娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <T> List<T> readList(@Nullable InputStream content, Class<T> elementClass) {
+		if (content == null) {
+			return Collections.emptyList();
+		}
+		try {
+			return getInstance().readValue(content, getListType(elementClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content      bytes
+	 * @param elementClass elementClass
+	 * @param <T>          娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <T> List<T> readList(@Nullable String content, Class<T> elementClass) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyList();
+		}
+		try {
+			return getInstance().readValue(content, getListType(elementClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content    bytes
+	 * @param keyClass   key绫诲瀷
+	 * @param valueClass 鍊肩被鍨�
+	 * @param <K>        娉涘瀷
+	 * @param <V>        娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <K, V> Map<K, V> readMap(@Nullable byte[] content, Class<?> keyClass, Class<?> valueClass) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyMap();
+		}
+		try {
+			return getInstance().readValue(content, getMapType(keyClass, valueClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content    InputStream
+	 * @param keyClass   key绫诲瀷
+	 * @param valueClass 鍊肩被鍨�
+	 * @param <K>        娉涘瀷
+	 * @param <V>        娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <K, V> Map<K, V> readMap(@Nullable InputStream content, Class<?> keyClass, Class<?> valueClass) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyMap();
+		}
+		try {
+			return getInstance().readValue(content, getMapType(keyClass, valueClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content    bytes
+	 * @param keyClass   key绫诲瀷
+	 * @param valueClass 鍊肩被鍨�
+	 * @param <K>        娉涘瀷
+	 * @param <V>        娉涘瀷
+	 * @return 闆嗗悎
+	 */
+	public static <K, V> Map<K, V> readMap(@Nullable String content, Class<?> keyClass, Class<?> valueClass) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyMap();
+		}
+		try {
+			return getInstance().readValue(content, getMapType(keyClass, valueClass));
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content bytes
+	 * @return 闆嗗悎
+	 */
+	public static Map<String, Object> readMap(@Nullable String content) {
+		return readMap(content, String.class, Object.class);
+	}
+
+	/**
+	 * 璇诲彇闆嗗悎
+	 *
+	 * @param content bytes
+	 * @return 闆嗗悎
+	 */
+	public static List<Map<String, Object>> readListMap(@Nullable String content) {
+		if (ObjectUtil.isEmpty(content)) {
+			return Collections.emptyList();
+		}
+		try {
+			return getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
+			});
+		} catch (IOException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * jackson 鐨勭被鍨嬭浆鎹�
+	 *
+	 * @param fromValue   鏉ユ簮瀵硅薄
+	 * @param toValueType 杞崲鐨勭被鍨�
+	 * @param <T>         娉涘瀷鏍囪
+	 * @return 杞崲缁撴灉
+	 */
+	public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
+		return getInstance().convertValue(fromValue, toValueType);
+	}
+
+	/**
+	 * jackson 鐨勭被鍨嬭浆鎹�
+	 *
+	 * @param fromValue   鏉ユ簮瀵硅薄
+	 * @param toValueType 杞崲鐨勭被鍨�
+	 * @param <T>         娉涘瀷鏍囪
+	 * @return 杞崲缁撴灉
+	 */
+	public static <T> T convertValue(Object fromValue, JavaType toValueType) {
+		return getInstance().convertValue(fromValue, toValueType);
+	}
+
+	/**
+	 * jackson 鐨勭被鍨嬭浆鎹�
+	 *
+	 * @param fromValue      鏉ユ簮瀵硅薄
+	 * @param toValueTypeRef 娉涘瀷绫诲瀷
+	 * @param <T>            娉涘瀷鏍囪
+	 * @return 杞崲缁撴灉
+	 */
+	public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
+		return getInstance().convertValue(fromValue, toValueTypeRef);
+	}
+
+	/**
+	 * tree 杞璞�
+	 *
+	 * @param treeNode  TreeNode
+	 * @param valueType valueType
+	 * @param <T>       娉涘瀷鏍囪
+	 * @return 杞崲缁撴灉
+	 */
+	public static <T> T treeToValue(TreeNode treeNode, Class<T> valueType) {
+		try {
+			return getInstance().treeToValue(treeNode, valueType);
+		} catch (JsonProcessingException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 瀵硅薄杞负 json node
+	 *
+	 * @param value 瀵硅薄
+	 * @return JsonNode
+	 */
+	public static JsonNode valueToTree(@Nullable Object value) {
+		return getInstance().valueToTree(value);
+	}
+
+	/**
+	 * 鍒ゆ柇鏄惁鍙互搴忓垪鍖�
+	 *
+	 * @param value 瀵硅薄
+	 * @return 鏄惁鍙互搴忓垪鍖�
+	 */
+	public static boolean canSerialize(@Nullable Object value) {
+		if (value == null) {
+			return true;
+		}
+		return getInstance().canSerialize(value.getClass());
+	}
+
+	public static Map<String, Object> toMap(String content) {
+		try {
+			return getInstance().readValue(content, Map.class);
+		} catch (IOException e) {
+			log.error(e.getMessage(), e);
+		}
+		return null;
+	}
+
+	public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
+		try {
+			Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
+			});
+			Map<String, T> result = new HashMap<>(16);
+			for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
+				result.put(entry.getKey(), toPojo(entry.getValue(), valueTypeRef));
+			}
+			return result;
+		} catch (IOException e) {
+			log.error(e.getMessage(), e);
+		}
+		return null;
+	}
+
+	public static <T> T toPojo(Map fromValue, Class<T> toValueType) {
+		return getInstance().convertValue(fromValue, toValueType);
+	}
+
+	public static ObjectMapper getInstance() {
+		return JacksonHolder.INSTANCE;
+	}
+
+	private static class JacksonHolder {
+		private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
+	}
+
+	private static class JacksonObjectMapper extends ObjectMapper {
+		private static final long serialVersionUID = 4288193147502386170L;
+
+		private static final Locale CHINA = Locale.CHINA;
+
+		public JacksonObjectMapper(ObjectMapper src) {
+			super(src);
+		}
+
+		public JacksonObjectMapper() {
+			super();
+			//璁剧疆鍦扮偣涓轰腑鍥�
+			super.setLocale(CHINA);
+			//鍘绘帀榛樿鐨勬椂闂存埑鏍煎紡
+			super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+			//璁剧疆涓轰腑鍥戒笂娴锋椂鍖�
+			super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
+			//搴忓垪鍖栨椂锛屾棩鏈熺殑缁熶竴鏍煎紡
+			super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
+			// 鍗曞紩鍙�
+			super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+			// 鍏佽JSON瀛楃涓插寘鍚潪寮曞彿鎺у埗瀛楃锛堝�煎皬浜�32鐨凙SCII瀛楃锛屽寘鍚埗琛ㄧ鍜屾崲琛岀锛�
+			super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
+			super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
+			super.findAndRegisterModules();
+			//澶辫触澶勭悊
+			super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+			super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			//鍗曞紩鍙峰鐞�
+			super.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
+			//鍙嶅簭鍒楀寲鏃讹紝灞炴�т笉瀛樺湪鐨勫吋瀹瑰鐞唖
+			super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+			//鏃ユ湡鏍煎紡鍖�
+			super.registerModule(new BladeJavaTimeModule());
+			super.findAndRegisterModules();
+		}
+
+		@Override
+		public ObjectMapper copy() {
+			return new JacksonObjectMapper(this);
+		}
+	}
+
+}

--
Gitblit v1.9.3