Browse Source

重构udp服务器

pengshaojie 6 years ago
parent
commit
160a5eb2d2
67 changed files with 3500 additions and 1218 deletions
  1. 18 4
      .idea/artifacts/wsm_admin_web_war_exploded.xml
  2. 1 1
      .idea/artifacts/wsm_application_war.xml
  3. 9 2
      .idea/artifacts/wsm_application_war_exploded.xml
  4. 11 20
      .idea/compiler.xml
  5. 1 1
      .idea/encodings.xml
  6. 20 6
      .idea/misc.xml
  7. 0 12
      .idea/modules.xml
  8. 0 15
      .idea/vcs.xml
  9. 786 457
      .idea/workspace.xml
  10. 0 31
      jm-smart-city.iml
  11. 27 5
      pom.xml
  12. 2 2
      wsm-admin-dao/src/main/java/com/wsm/admin/dao/IDataDictionaryDao.java
  13. 7 0
      wsm-admin-dao/wsm-admin-dao.iml
  14. 2 2
      wsm-admin-service/src/main/java/com/wsm/admin/service/IDataDictionaryService.java
  15. 3 2
      wsm-admin-service/src/main/java/com/wsm/admin/service/impl/DataDictionaryServiceImpl.java
  16. 7 0
      wsm-admin-service/wsm-admin-service.iml
  17. 7 1
      wsm-admin-web/pom.xml
  18. 1 4
      wsm-admin-web/src/main/java/com/wsm/admin/api/DataDictionaryController.java
  19. 17 4
      wsm-admin-web/src/main/java/com/wsm/admin/api/FileController.java
  20. 10 9
      wsm-admin-web/src/main/java/com/wsm/admin/api/IndexController.java
  21. 9 9
      wsm-admin-web/src/main/java/com/wsm/admin/api/RoleController.java
  22. 7 3
      wsm-admin-web/src/main/java/com/wsm/admin/api/UserController.java
  23. 161 0
      wsm-admin-web/src/main/java/com/wsm/admin/handle/UdpServerHandler.java
  24. 34 0
      wsm-admin-web/src/main/java/com/wsm/admin/init/StartupUdpEvent.java
  25. 43 0
      wsm-admin-web/src/main/java/com/wsm/admin/init/UdpServer.java
  26. 2 0
      wsm-admin-web/src/main/java/com/wsm/admin/shiro/MyShiroRealm.java
  27. 24 2
      wsm-admin-web/src/main/java/com/wsm/admin/shiro/ShiroConfig.java
  28. 43 0
      wsm-admin-web/src/main/java/com/wsm/admin/thread/TaskExecutePool.java
  29. 0 143
      wsm-admin-web/src/main/java/com/wsm/admin/udp/Server.java
  30. 23 16
      wsm-admin-web/wsm-admin-web.iml
  31. 4 14
      wsm-application/pom.xml
  32. 6 1
      wsm-application/src/main/java/com/wsm/Application.java
  33. 12 5
      wsm-application/src/main/resources/application.properties
  34. 189 0
      wsm-application/src/main/resources/static/plugins/diyUpload/css/diyUpload.css
  35. 45 0
      wsm-application/src/main/resources/static/plugins/diyUpload/css/webuploader.css
  36. BIN
      wsm-application/src/main/resources/static/plugins/diyUpload/images/bgblack.png
  37. BIN
      wsm-application/src/main/resources/static/plugins/diyUpload/images/check_alt.png
  38. BIN
      wsm-application/src/main/resources/static/plugins/diyUpload/images/x_alt.png
  39. 236 0
      wsm-application/src/main/resources/static/plugins/diyUpload/js/diyUpload.js
  40. 2 0
      wsm-application/src/main/resources/static/plugins/diyUpload/js/webuploader.js
  41. 497 1
      wsm-application/src/main/resources/static/plugins/layui/lay/modules/form.js
  42. 17 0
      wsm-application/src/main/resources/static/plugins/ueditor/themes/default/css/umeditor.css
  43. 1 1
      wsm-application/src/main/resources/static/plugins/ueditor/themes/default/css/umeditor.min.css
  44. 2 77
      wsm-application/src/main/resources/static/plugins/ueditor/umeditor.config.js
  45. 26 93
      wsm-application/src/main/resources/static/plugins/ueditor/umeditor.js
  46. 243 252
      wsm-application/src/main/resources/static/plugins/ueditor/umeditor.min.js
  47. 2 2
      wsm-application/src/main/resources/templates/admin/role/form.html
  48. 5 7
      wsm-application/src/main/resources/templates/admin/role/list.html
  49. 5 7
      wsm-application/src/main/resources/templates/admin/user/list.html
  50. 56 0
      wsm-application/src/main/resources/templates/sock.html
  51. 7 0
      wsm-application/wsm-application.iml
  52. 19 0
      wsm-common/pom.xml
  53. 3 2
      wsm-common/src/main/java/com/wsm/common/config/WebMvcConfig.java
  54. 42 2
      wsm-common/src/main/java/com/wsm/common/interceptor/CommonInterceptor.java
  55. 22 1
      wsm-common/src/main/java/com/wsm/common/util/AjaxJson.java
  56. 2 2
      wsm-common/src/main/java/com/wsm/common/util/ConstantUtils.java
  57. 77 0
      wsm-common/src/main/java/com/wsm/common/util/DateTimeUtils.java
  58. 52 0
      wsm-common/src/main/java/com/wsm/common/util/FileUtils.java
  59. 317 0
      wsm-common/src/main/java/com/wsm/common/util/HttpClientUtils.java
  60. 21 0
      wsm-common/src/main/java/com/wsm/common/util/NumberUtils.java
  61. 88 0
      wsm-common/src/main/java/com/wsm/common/util/PatternUtils.java
  62. 63 0
      wsm-common/src/main/java/com/wsm/common/util/QrCodeUtil.java
  63. 35 0
      wsm-common/src/main/java/com/wsm/common/util/SpringContext.java
  64. 46 0
      wsm-common/src/main/java/com/wsm/common/util/StringUtil.java
  65. 40 0
      wsm-common/src/main/java/com/wsm/common/util/URLEncodeUtil.java
  66. 36 0
      wsm-common/src/main/java/com/wsm/common/util/ZipUtils.java
  67. 7 0
      wsm-common/wsm-common.iml

+ 18 - 4
.idea/artifacts/wsm_admin_web_war_exploded.xml

@@ -86,10 +86,24 @@
           <element id="archive" name="wsm-admin-service-1.0.0.jar">
             <element id="module-output" name="wsm-admin-service" />
           </element>
-          <element id="library" level="project" name="Maven: com.wsm:wsm-operation-web:unknown" />
-          <element id="library" level="project" name="Maven: com.wsm:wsm-member-web:unknown" />
-          <element id="library" level="project" name="Maven: com.wsm:wsm-goods-web:unknown" />
-          <element id="library" level="project" name="Maven: com.wsm:wsm-order-web:unknown" />
+          <element id="archive" name="wsm-operation-web-1.0.0.jar">
+            <element id="module-output" name="wsm-operation-web" />
+          </element>
+          <element id="archive" name="wsm-operation-dao-1.0.0.jar">
+            <element id="module-output" name="wsm-operation-dao" />
+          </element>
+          <element id="archive" name="wsm-operation-service-1.0.0.jar">
+            <element id="module-output" name="wsm-operation-service" />
+          </element>
+          <element id="archive" name="wsm-member-web-1.0.0.jar">
+            <element id="module-output" name="wsm-member-web" />
+          </element>
+          <element id="archive" name="wsm-member-dao-1.0.0.jar">
+            <element id="module-output" name="wsm-interaction-dao" />
+          </element>
+          <element id="archive" name="wsm-member-service-1.0.0.jar">
+            <element id="module-output" name="wsm-member-service" />
+          </element>
           <element id="library" level="project" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" />
           <element id="library" level="project" name="Maven: org.springframework.boot:spring-boot-starter:1.5.12.RELEASE" />
           <element id="library" level="project" name="Maven: org.springframework.boot:spring-boot:1.5.12.RELEASE" />

+ 1 - 1
.idea/artifacts/wsm_application_war.xml

@@ -1,7 +1,7 @@
 <component name="ArtifactManager">
   <artifact type="war" name="wsm-application:war">
     <output-path>$PROJECT_DIR$/wsm-application/target</output-path>
-    <root id="archive" name="mood-wall.war">
+    <root id="archive" name="smart.war">
       <element id="artifact" artifact-name="wsm-application:war exploded" />
     </root>
   </artifact>

+ 9 - 2
.idea/artifacts/wsm_application_war_exploded.xml

@@ -1,6 +1,6 @@
 <component name="ArtifactManager">
   <artifact type="exploded-war" name="wsm-application:war exploded">
-    <output-path>$PROJECT_DIR$/wsm-application/target/mood-wall</output-path>
+    <output-path>$PROJECT_DIR$/wsm-application/target/smart</output-path>
     <root id="root">
       <element id="directory" name="WEB-INF">
         <element id="directory" name="classes">
@@ -66,6 +66,13 @@
           <element id="library" level="project" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" />
           <element id="library" level="project" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" />
           <element id="library" level="project" name="Maven: joda-time:joda-time:2.9.9" />
+          <element id="library" level="project" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" />
+          <element id="library" level="project" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" />
+          <element id="library" level="project" name="Maven: commons-logging:commons-logging:1.2" />
+          <element id="library" level="project" name="Maven: commons-codec:commons-codec:1.10" />
+          <element id="library" level="project" name="Maven: commons-io:commons-io:2.5" />
+          <element id="library" level="project" name="Maven: commons-lang:commons-lang:2.6" />
+          <element id="library" level="project" name="Maven: com.google.zxing:core:2.1" />
           <element id="library" level="project" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" />
           <element id="library" level="project" name="Maven: org.springframework:spring-messaging:4.3.16.RELEASE" />
           <element id="library" level="project" name="Maven: org.springframework:spring-websocket:4.3.16.RELEASE" />
@@ -135,7 +142,7 @@
         </element>
       </element>
       <element id="directory" name="META-INF">
-        <element id="file-copy" path="$PROJECT_DIR$/wsm-application/target/mood-wall/META-INF/MANIFEST.MF" />
+        <element id="file-copy" path="$PROJECT_DIR$/wsm-application/target/smart/META-INF/MANIFEST.MF" />
       </element>
       <element id="javaee-facet-resources" facet="wsm-application/web/Web" />
     </root>

+ 11 - 20
.idea/compiler.xml

@@ -11,40 +11,31 @@
         <module name="wsm-admin-web" />
         <module name="wsm-application" />
         <module name="wsm-common" />
-        <module name="wsm-goods-dao" />
-        <module name="wsm-goods-service" />
-        <module name="wsm-goods-web" />
-        <module name="wsm-member-dao" />
-        <module name="wsm-member-service" />
-        <module name="wsm-member-web" />
-        <module name="wsm-operation-dao" />
-        <module name="wsm-operation-service" />
-        <module name="wsm-operation-web" />
-        <module name="wsm-order-dao" />
-        <module name="wsm-order-service" />
-        <module name="wsm-order-web" />
       </profile>
     </annotationProcessing>
     <bytecodeTargetLevel>
+      <module name="fdage-szggkfzlg" target="1.8" />
       <module name="wsm-admin-dao" target="1.8" />
       <module name="wsm-admin-service" target="1.8" />
       <module name="wsm-admin-web" target="1.8" />
       <module name="wsm-application" target="1.8" />
       <module name="wsm-base" target="1.8" />
+      <module name="wsm-collection-dao" target="1.8" />
+      <module name="wsm-collection-service" target="1.8" />
+      <module name="wsm-collection-web" target="1.8" />
       <module name="wsm-common" target="1.8" />
-      <module name="wsm-goods-dao" target="1.8" />
-      <module name="wsm-goods-service" target="1.8" />
-      <module name="wsm-goods-web" target="1.8" />
-      <module name="wsm-member-dao" target="1.8" />
+      <module name="wsm-exhibition-dao" target="1.8" />
+      <module name="wsm-exhibition-service" target="1.8" />
+      <module name="wsm-exhibition-web" target="1.8" />
+      <module name="wsm-interaction-dao" target="1.8" />
+      <module name="wsm-interaction-service" target="1.8" />
+      <module name="wsm-interaction-web" target="1.8" />
+      <module name="wsm-lucene" target="1.8" />
       <module name="wsm-member-service" target="1.8" />
       <module name="wsm-member-web" target="1.8" />
       <module name="wsm-operation-dao" target="1.8" />
       <module name="wsm-operation-service" target="1.8" />
       <module name="wsm-operation-web" target="1.8" />
-      <module name="wsm-order-dao" target="1.8" />
-      <module name="wsm-order-service" target="1.8" />
-      <module name="wsm-order-web" target="1.8" />
-      <module name="wsmmemberweb" target="1.8" />
     </bytecodeTargetLevel>
   </component>
 </project>

+ 1 - 1
.idea/encodings.xml

@@ -2,11 +2,11 @@
 <project version="4">
   <component name="Encoding">
     <file url="file://$PROJECT_DIR$" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/fdage-szggkfzlg" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/wsm-admin-dao" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/wsm-admin-service" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/wsm-admin-web" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/wsm-application" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/wsm-common" charset="UTF-8" />
-    <file url="file://$PROJECT_DIR$/wsm-root" charset="UTF-8" />
   </component>
 </project>

+ 20 - 6
.idea/misc.xml

@@ -1,19 +1,33 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="FrameworkDetectionExcludesConfiguration">
-    <file type="web" url="file://$PROJECT_DIR$" />
+    <file type="web" url="file://$PROJECT_DIR$/fdage-szggkfzlg" />
+    <file type="web" url="file://$PROJECT_DIR$/wsm-admin-web" />
+    <file type="web" url="file://$PROJECT_DIR$/wsm-application" />
   </component>
   <component name="MavenProjectsManager">
     <option name="originalFiles">
       <list>
         <option value="$PROJECT_DIR$/pom.xml" />
-        <option value="$PROJECT_DIR$/wsm-member-dao/pom.xml" />
-        <option value="$PROJECT_DIR$/wsm-member-web/pom.xml" />
       </list>
     </option>
-  </component>
-  <component name="ProjectPlainTextFileTypeManager">
-    <file url="file://$PROJECT_DIR$/wsm-common/src/main/resources/application.properties" />
+    <option name="ignoredFiles">
+      <set>
+        <option value="$PROJECT_DIR$/wsm-collection-dao/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-collection-service/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-collection-web/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-exhibition-dao/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-exhibition-service/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-exhibition-web/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-interaction-dao/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-interaction-service/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-interaction-web/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-lucene/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-operation-dao/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-operation-service/pom.xml" />
+        <option value="$PROJECT_DIR$/wsm-operation-web/pom.xml" />
+      </set>
+    </option>
   </component>
   <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/classes" />

+ 0 - 12
.idea/modules.xml

@@ -8,18 +8,6 @@
       <module fileurl="file://$PROJECT_DIR$/wsm-application/wsm-application.iml" filepath="$PROJECT_DIR$/wsm-application/wsm-application.iml" />
       <module fileurl="file://$PROJECT_DIR$/wsm-base.iml" filepath="$PROJECT_DIR$/wsm-base.iml" />
       <module fileurl="file://$PROJECT_DIR$/wsm-common/wsm-common.iml" filepath="$PROJECT_DIR$/wsm-common/wsm-common.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-goods-dao/wsm-goods-dao.iml" filepath="$PROJECT_DIR$/wsm-goods-dao/wsm-goods-dao.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-goods-service/wsm-goods-service.iml" filepath="$PROJECT_DIR$/wsm-goods-service/wsm-goods-service.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-goods-web/wsm-goods-web.iml" filepath="$PROJECT_DIR$/wsm-goods-web/wsm-goods-web.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-member-dao/wsm-member-dao.iml" filepath="$PROJECT_DIR$/wsm-member-dao/wsm-member-dao.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-member-service/wsm-member-service.iml" filepath="$PROJECT_DIR$/wsm-member-service/wsm-member-service.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-member-web/wsm-member-web.iml" filepath="$PROJECT_DIR$/wsm-member-web/wsm-member-web.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-operation-dao/wsm-operation-dao.iml" filepath="$PROJECT_DIR$/wsm-operation-dao/wsm-operation-dao.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-operation-service/wsm-operation-service.iml" filepath="$PROJECT_DIR$/wsm-operation-service/wsm-operation-service.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-operation-web/wsm-operation-web.iml" filepath="$PROJECT_DIR$/wsm-operation-web/wsm-operation-web.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-order-dao/wsm-order-dao.iml" filepath="$PROJECT_DIR$/wsm-order-dao/wsm-order-dao.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-order-service/wsm-order-service.iml" filepath="$PROJECT_DIR$/wsm-order-service/wsm-order-service.iml" />
-      <module fileurl="file://$PROJECT_DIR$/wsm-order-web/wsm-order-web.iml" filepath="$PROJECT_DIR$/wsm-order-web/wsm-order-web.iml" />
     </modules>
   </component>
 </project>

+ 0 - 15
.idea/vcs.xml

@@ -2,21 +2,6 @@
 <project version="4">
   <component name="VcsDirectoryMappings">
     <mapping directory="$PROJECT_DIR$" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-admin-dao" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-admin-service" vcs="svn" />
     <mapping directory="$PROJECT_DIR$/wsm-admin-web" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-common" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-goods-dao" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-goods-service" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-goods-web" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-member-dao" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-member-service" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-member-web" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-operation-dao" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-operation-service" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-operation-web" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-order-dao" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-order-service" vcs="svn" />
-    <mapping directory="$PROJECT_DIR$/wsm-order-web" vcs="svn" />
   </component>
 </project>

File diff suppressed because it is too large
+ 786 - 457
.idea/workspace.xml


+ 0 - 31
jm-smart-city.iml

@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-    <facet type="web" name="Web">
-      <configuration>
-        <webroots>
-          <root url="file://$MODULE_DIR$/src/main/webapp" relative="/" />
-        </webroots>
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
-      </configuration>
-    </facet>
-  </component>
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 27 - 5
pom.xml

@@ -58,8 +58,9 @@
         <feign-httpclient.version>8.18.0</feign-httpclient.version>
         <feign-jackson.version>8.18.0</feign-jackson.version>
         <joda-time.version>2.9.9</joda-time.version>
-        <java-mail.version>1.4.7</java-mail.version>
+        <zxing.version>2.1</zxing.version>
         <spring-boot-starter-websocket.version>2.1.3.RELEASE</spring-boot-starter-websocket.version>
+        <poi.version>3.17</poi.version>
     </properties>
 
     <!--dependencyManagement用于管理依赖版本号-->
@@ -90,7 +91,6 @@
                 <artifactId>wsm-admin-dao</artifactId>
                 <version>${wsm.version}</version>
             </dependency>
-
             <!--spring boot -->
             <dependency>
                 <groupId>org.springframework.boot</groupId>
@@ -296,9 +296,30 @@
             </dependency>
 
             <dependency>
-                <groupId>javax.mail</groupId>
-                <artifactId>mail</artifactId>
-                <version>${java-mail.version}</version>
+                <groupId>com.google.zxing</groupId>
+                <artifactId>core</artifactId>
+                <version>${zxing.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.zxing</groupId>
+                <artifactId>javase</artifactId>
+                <version>${zxing.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml-schemas</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi</artifactId>
+                <version>${poi.version}</version>
             </dependency>
 
             <dependency>
@@ -306,6 +327,7 @@
                 <artifactId>spring-boot-starter-websocket</artifactId>
                 <version>${spring-boot-starter-websocket.version}</version>
             </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 2 - 2
wsm-admin-dao/src/main/java/com/wsm/admin/dao/IDataDictionaryDao.java

@@ -1,11 +1,11 @@
 package com.wsm.admin.dao;
 
+import java.util.List;
+
 import com.wsm.admin.model.DataDictionary;
 import com.wsm.common.dao.IBaseDao;
 import org.springframework.stereotype.Repository;
 
-import java.util.List;
-
 @Repository
 public interface IDataDictionaryDao extends IBaseDao<DataDictionary, Long> {
 

+ 7 - 0
wsm-admin-dao/wsm-admin-dao.iml

@@ -65,6 +65,13 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" level="project" />
     <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.google.zxing:core:2.1" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" level="project" />
     <orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.12.RELEASE" level="project" />

+ 2 - 2
wsm-admin-service/src/main/java/com/wsm/admin/service/IDataDictionaryService.java

@@ -1,10 +1,10 @@
 package com.wsm.admin.service;
 
+import java.util.List;
+
 import com.wsm.admin.model.DataDictionary;
 import com.wsm.common.service.IBaseService;
 
-import java.util.List;
-
 /**
  * <p>
  * 数据字典服务类

+ 3 - 2
wsm-admin-service/src/main/java/com/wsm/admin/service/impl/DataDictionaryServiceImpl.java

@@ -1,5 +1,8 @@
 package com.wsm.admin.service.impl;
 
+import java.util.Date;
+import java.util.List;
+
 import com.wsm.admin.dao.IDataDictionaryDao;
 import com.wsm.admin.model.DataDictionary;
 import com.wsm.admin.service.IDataDictionaryService;
@@ -8,8 +11,6 @@ import com.wsm.common.service.impl.BaseServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
 /**
  * <p>
  *  数据字典 服务实现类

+ 7 - 0
wsm-admin-service/wsm-admin-service.iml

@@ -101,6 +101,13 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" level="project" />
     <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.google.zxing:core:2.1" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" level="project" />
     <orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.12.RELEASE" level="project" />

+ 7 - 1
wsm-admin-web/pom.xml

@@ -43,11 +43,17 @@
             <groupId>com.wsm</groupId>
             <artifactId>wsm-admin-service</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.github.theborakompanioni</groupId>
             <artifactId>thymeleaf-extras-shiro</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
     </dependencies>
 
+
+
 </project>

+ 1 - 4
wsm-admin-web/src/main/java/com/wsm/admin/api/DataDictionaryController.java

@@ -13,10 +13,7 @@ import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.util.StringUtils;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
 
 @Controller
 @RequestMapping("/admin/dataDictionary")

+ 17 - 4
wsm-admin-web/src/main/java/com/wsm/admin/api/FileController.java

@@ -14,20 +14,19 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.UUID;
 
 @Controller
 public class FileController extends BaseController {
 
     @Value("${web.upload.file.path}")
     private String path;
-    @Value("server.host.address")
-    private String server;
 
     private Logger logger = LoggerFactory.getLogger(getClass());
 
     @RequestMapping(value = "/upload/file", method = RequestMethod.POST)
     @ResponseBody
-    public AjaxJson upload(HttpServletRequest req, MultipartFile file) {
+    public AjaxJson uploadFile(HttpServletRequest req, MultipartFile file) {
         String newFileName = null;
         try {
             newFileName = FileUtils.uploadFile(req, file, path);
@@ -38,9 +37,23 @@ public class FileController extends BaseController {
         return AjaxJson.success("SUCCESS", newFileName);
     }
 
+    @RequestMapping(value = "/upload/audio", method = RequestMethod.POST)
+    @ResponseBody
+    public AjaxJson uploadAudio(HttpServletRequest req, MultipartFile file) {
+        String fileName= null;
+        try {
+            fileName = FileUtils.uploadFile(req, file, path + "audio/");
+            fileName = "/audio" + fileName;
+        } catch (Exception e) {
+            logger.error("系统异常:", e);
+            return AjaxJson.failure("系统异常:" + e);
+        }
+        return AjaxJson.success("SUCCESS", fileName);
+    }
+
     @RequestMapping(value = "/upload/image", method = RequestMethod.POST)
     @ResponseBody
-    public JSONObject imageUpload(HttpServletRequest req, MultipartFile upfile) {
+    public JSONObject uploadImage(HttpServletRequest req, MultipartFile upfile) {
         String newFileName = null;
         try {
             newFileName = FileUtils.uploadFile(req, upfile, path);

+ 10 - 9
wsm-admin-web/src/main/java/com/wsm/admin/api/IndexController.java

@@ -4,6 +4,7 @@ import com.wsm.admin.model.User;
 import com.wsm.admin.service.IResourceService;
 import com.wsm.admin.service.IUserService;
 import com.wsm.common.api.BaseController;
+import com.wsm.common.util.AjaxJson;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.UsernamePasswordToken;
@@ -11,8 +12,10 @@ import org.apache.shiro.subject.Subject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -20,11 +23,7 @@ import javax.servlet.http.HttpServletRequest;
 public class IndexController extends BaseController {
 
     @Autowired
-    private HttpServletRequest request;
-
-    @Autowired
     private IUserService userService;
-
     @Autowired
     private IResourceService resourceService;
 
@@ -53,8 +52,10 @@ public class IndexController extends BaseController {
         return "home";
     }
 
+    @ResponseBody
     @RequestMapping(value = {"/admin/login"}, method = RequestMethod.POST)
-    public String login(User user, String randomcode, boolean rememberMe, Model model) {
+    public AjaxJson login(User user, String randomcode, boolean rememberMe, Model model) {
+        AjaxJson ajaxJson = null;
         try {
         	String validateCode = (String) request.getSession().getAttribute("validateCode");
 			if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) {
@@ -63,13 +64,13 @@ public class IndexController extends BaseController {
             Subject subject = SecurityUtils.getSubject();
             UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword(), rememberMe);
             subject.login(token);
-            return redirect("/admin/index");
+            ajaxJson = AjaxJson.success();
         } catch (Exception e) {
-            model.addAttribute("message", e.getMessage());
+            ajaxJson = AjaxJson.failure(e.getMessage());
         }
-        return "login";
+        return ajaxJson;
     }
-
+    
     @RequestMapping(value = {"/admin/logout"}, method = RequestMethod.POST)
     public String logout() {
         Subject subject = SecurityUtils.getSubject();

+ 9 - 9
wsm-admin-web/src/main/java/com/wsm/admin/api/RoleController.java

@@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.Model;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -33,12 +34,15 @@ public class RoleController extends BaseController {
     private IRoleService roleService;
 
     @RequestMapping("/list")
+    @Transactional(readOnly = true)
     public String list(Model model) {
         Page<Role> roleList = roleService.findAll(getPageRequest(new Sort(Sort.Direction.DESC, "createTime")));
+        /*if (roleList != null){
+            for (Role role : roleList){
+                role.setResources(null);
+            }
+        }*/
         model.addAttribute("roles", roleList);
-        model.addAttribute("size", roleList.getSize());
-        model.addAttribute("totalElements", roleList.getTotalElements());
-        model.addAttribute("number", roleList.getNumber());
         return "/admin/role/list";
     }
 
@@ -49,15 +53,11 @@ public class RoleController extends BaseController {
             role = roleService.find(Long.valueOf(roleId));
             Set<Resource> resources = role.getResources();
             StringBuffer sb = new StringBuffer();
-            StringBuffer sbIds = new StringBuffer();
             int i = 1;
-            for (Resource r : resources){
-                sb.append(r.getName()).append(i == resources.size() ? "" : ",");
-                sbIds.append(r.getId().toString()).append(i == resources.size() ? "" : ",");
-                i++;
+            for (Iterator<Resource> it = resources.iterator(); it.hasNext(); ++i) {
+                sb.append(it.next().getName()).append(i == resources.size() ? "" : ",");
             }
             model.addAttribute("checkNodesName", sb.toString());
-            model.addAttribute("resourceIds", sbIds.toString());
         }
         model.addAttribute("role", role);
         return "/admin/role/form";

+ 7 - 3
wsm-admin-web/src/main/java/com/wsm/admin/api/UserController.java

@@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.Model;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -41,12 +42,15 @@ public class UserController extends BaseController {
     private IRoleService roleService;
 
     @RequestMapping("/list")
+    @Transactional(readOnly = true)
     public String list(Model model) {
         Page<User> userList = userService.findAll(getPageRequest(new Sort(Sort.Direction.DESC, "createTime")));
+        /*if (userList.getContent() != null){
+            for (User user : userList){
+                user.setRoles(null);
+            }
+        }*/
         model.addAttribute("users", userList);
-        model.addAttribute("size", userList.getSize());
-        model.addAttribute("totalElements", userList.getTotalElements());
-        model.addAttribute("number", userList.getNumber());
         return "/admin/user/list";
     }
 

+ 161 - 0
wsm-admin-web/src/main/java/com/wsm/admin/handle/UdpServerHandler.java

@@ -0,0 +1,161 @@
+package com.wsm.admin.handle;
+
+import com.wsm.admin.model.Device;
+import com.wsm.admin.model.DeviceStatus;
+import com.wsm.admin.service.IDeviceService;
+import com.wsm.admin.service.IDeviceStatusService;
+import com.wsm.admin.service.impl.DeviceServiceImpl;
+import com.wsm.admin.service.impl.DeviceStatusServiceImpl;
+import com.wsm.common.util.ASCIIUtil;
+import com.wsm.common.util.SpringContext;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.socket.DatagramPacket;
+import io.netty.util.CharsetUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 接受UDP消息并且处理
+ *
+ */
+public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
+
+    private static final Logger log= LoggerFactory.getLogger(UdpServerHandler.class);
+
+    private IDeviceStatusService deviceStatusService;
+    private IDeviceService deviceService;
+    private SimpMessagingTemplate messagingTemplate;
+
+    public UdpServerHandler(){
+        if (deviceService == null){
+            deviceService = SpringContext.getBean(DeviceServiceImpl.class);
+        }
+        if (deviceStatusService == null){
+            deviceStatusService = SpringContext.getBean(DeviceStatusServiceImpl.class);
+        }
+        if (messagingTemplate == null){
+            messagingTemplate = SpringContext.getBean(SimpMessagingTemplate.class);
+        }
+    }
+
+    private static final Map<String, String> deviceStatusMap = new HashMap<>();
+
+    static {
+        deviceStatusMap.put("08", "硬件版本号");
+        deviceStatusMap.put("15", "SIM 卡CCID 号码");
+        deviceStatusMap.put("05", "NB/GPRS 信号强度");
+        deviceStatusMap.put("2A00", "电池:低压");
+        deviceStatusMap.put("3500", "NB底座的电池:低压");
+        deviceStatusMap.put("3600", "烟感底座上的烟感电池:低压");
+        deviceStatusMap.put("3701", "消防门状态:打开");
+        deviceStatusMap.put("3801", "消防手报状态:弹起");
+        deviceStatusMap.put("3E01", "喷淋状态:打开");
+
+        deviceStatusMap.put("111", "烟雾报警");
+        deviceStatusMap.put("384", "低压报警");
+        deviceStatusMap.put("993", "底座上的烟感低压");
+        deviceStatusMap.put("992", "NB 底座低压报警 ");
+        deviceStatusMap.put("991", "燃气报警");
+        deviceStatusMap.put("990", "消防手报按钮报警");
+        deviceStatusMap.put("989", "消防门打开");
+        deviceStatusMap.put("988", "消防门关闭");
+        deviceStatusMap.put("987", "消防门长时间未关闭");
+        deviceStatusMap.put("986", "高温报警");
+        deviceStatusMap.put("985", "漏电报警");
+        deviceStatusMap.put("984", "温感低压");
+        deviceStatusMap.put("966", "喷淋打开");
+        deviceStatusMap.put("965", "喷淋关闭");
+    }
+
+    @Override
+    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
+        String receiveMsg = packet.content().toString(CharsetUtil.UTF_8);
+        log.warn("Received UDP Msg:" + receiveMsg);
+
+        if (StringUtils.isNotEmpty(receiveMsg)){
+
+            String[] str = ASCIIUtil.turnToArray(receiveMsg);
+            Device device = deviceService.findByDeviceId16Hex(ASCIIUtil.getDevice(str));
+
+            String type = str[6];
+            switch (type){
+                // 心跳
+                case "02":
+                    break;
+                // 状态
+                case "04":
+                    int total = Integer.valueOf(str[16]);
+                    for (int i = 0, length = 3; i < total; i++){
+                        String a = str[17 + i * length];
+                        //String b = str[18 + i * length];
+                        String c = str[19 + i * length];
+                        // 状态异常
+                        if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(a+c)) && device != null){
+                            DeviceStatus status =  new DeviceStatus();
+                            status.setContent(deviceStatusMap.get(a+c));
+                            status.setDevice(device);
+                            status.setStatus((byte)0);
+                            deviceStatusService.save(status);
+                            log.warn(device.getDeviceId() + ":"+ status.getContent());
+
+                            messagingTemplate.convertAndSend("/topic/device", status);
+                        }
+                    }
+                    break;
+                // 报警
+                case "09":
+                    // 报警
+                    String hex = ASCIIUtil.hexStringToString(str[24]+str[25]+str[26]);
+                    if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(hex)) && device != null){
+                        DeviceStatus status =  new DeviceStatus();
+                        status.setContent(deviceStatusMap.get(hex));
+                        status.setDevice(device);
+                        status.setStatus((byte)1);
+                        deviceStatusService.save(status);
+                        log.warn(device.getDeviceId() + ":"+ status.getContent());
+
+                        messagingTemplate.convertAndSend("/topic/device", status);
+                    }
+                    break;
+            }
+
+            String feedback = ASCIIUtil.getOKFeedback(str);
+            //byte[] data = feedback.getBytes("ASCII");
+
+            //在这里可以返回一个UDP消息给对方,告知已接收到UDP消息,但考虑到这是UDP消息,此处可以注释掉
+            ctx.write(new DatagramPacket(
+                    Unpooled.copiedBuffer(feedback , CharsetUtil.UTF_8), packet.sender()));
+
+        }else{
+            log.error("Received Error UDP Messsage:" + receiveMsg);
+        }
+    }
+
+    @Override
+    public void channelReadComplete(ChannelHandlerContext ctx) {
+        ctx.flush();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+        cause.printStackTrace();
+        // We don't close the channel because we can keep serving requests.
+    }
+
+    public Timestamp getTime(){
+        Date date = new Date();
+        Timestamp time = new Timestamp(date.getTime());
+        return time;
+    }
+
+}

+ 34 - 0
wsm-admin-web/src/main/java/com/wsm/admin/init/StartupUdpEvent.java

@@ -0,0 +1,34 @@
+package com.wsm.admin.init;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+public class StartupUdpEvent implements ApplicationListener<ContextRefreshedEvent> {
+
+    private static final Logger log = LoggerFactory.getLogger(StartupUdpEvent.class);
+
+    private static ApplicationContext context;
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
+        try {
+            context = contextRefreshedEvent.getApplicationContext();
+
+            log.warn("启动UDP线程,接收UDP消息");
+            //接收UDP消息并保存至redis中
+            UdpServer udpServer = (UdpServer)StartupUdpEvent.getBean(UdpServer.class);
+            udpServer.run(2000);
+
+
+        } catch (Exception e) {
+            log.error("Exception", e);
+        }
+    }
+
+    public static Object getBean(Class beanName) {
+        return context != null ? context.getBean(beanName) : null;
+    }
+}

+ 43 - 0
wsm-admin-web/src/main/java/com/wsm/admin/init/UdpServer.java

@@ -0,0 +1,43 @@
+package com.wsm.admin.init;
+
+import com.wsm.admin.handle.UdpServerHandler;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioDatagramChannel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * server服务器
+ */
+@Component
+public class UdpServer {
+
+    private static final Logger log= LoggerFactory.getLogger(UdpServer.class);
+
+    @Async("updAsyncPool")
+    public void run(int udpReceivePort) {
+
+        EventLoopGroup group = new NioEventLoopGroup();
+        log.info("Server start!  Udp Receive msg Port:" + udpReceivePort );
+
+        try {
+            Bootstrap b = new Bootstrap();
+            b.group(group)
+                    .channel(NioDatagramChannel.class)
+                    .option(ChannelOption.SO_BROADCAST, true)
+                    .handler(new UdpServerHandler());
+
+            b.bind(udpReceivePort).sync().channel().closeFuture().await();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            group.shutdownGracefully();
+        }
+    }
+
+}

+ 2 - 0
wsm-admin-web/src/main/java/com/wsm/admin/shiro/MyShiroRealm.java

@@ -61,6 +61,8 @@ public class MyShiroRealm extends AuthorizingRealm {
     @Override
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         String username = (String) token.getPrincipal();
+
+
         User user = userService.findByUserName(username);
         // 账号不存在
         if (user == null) {

+ 24 - 2
wsm-admin-web/src/main/java/com/wsm/admin/shiro/ShiroConfig.java

@@ -18,6 +18,7 @@ import org.springframework.context.annotation.DependsOn;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
+import javax.servlet.Filter;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -101,22 +102,45 @@ public class ShiroConfig {
         //配置不会被拦截的链接 顺序判断
         //静态资源不拦截
         filterChainDefinitionMap.put("/", "anon");
+        filterChainDefinitionMap.put("/webSocketServer/**", "anon");
         filterChainDefinitionMap.put("/static/**", "anon");
         filterChainDefinitionMap.put("/index.html", "anon");
+        filterChainDefinitionMap.put("/mobile.html", "anon");
         filterChainDefinitionMap.put("/css/**", "anon");
         filterChainDefinitionMap.put("/img/**", "anon");
         filterChainDefinitionMap.put("/js/**", "anon");
+        filterChainDefinitionMap.put("/language/**", "anon");
         filterChainDefinitionMap.put("/plugins/**", "anon");
         filterChainDefinitionMap.put("/member_head_image/**", "anon");
+        filterChainDefinitionMap.put("/audio/**", "anon");
+        filterChainDefinitionMap.put("/*.js", "anon");
         filterChainDefinitionMap.put("/*.png", "anon");
         filterChainDefinitionMap.put("/*.jpg", "anon");
         filterChainDefinitionMap.put("/*.jpeg", "anon");
+        filterChainDefinitionMap.put("/*.JPG", "anon");
+        filterChainDefinitionMap.put("/*.JPEG", "anon");
+        filterChainDefinitionMap.put("/*.PNG", "anon");
+        filterChainDefinitionMap.put("/*.mp3", "anon");
+        filterChainDefinitionMap.put("/*.wav", "anon");
+        filterChainDefinitionMap.put("/*.wma", "anon");
+        filterChainDefinitionMap.put("/*.asf", "anon");
+        filterChainDefinitionMap.put("/*.aac", "anon");
+        filterChainDefinitionMap.put("/*.vqf", "anon");
+        filterChainDefinitionMap.put("/*.flac", "anon");
+        filterChainDefinitionMap.put("/*.ape", "anon");
+        filterChainDefinitionMap.put("/*.mid", "anon");
+        filterChainDefinitionMap.put("/*.ogg", "anon");
+        filterChainDefinitionMap.put("/*.m4a", "anon");
+        filterChainDefinitionMap.put("/*.mod", "anon");
+
         //登录链接不拦截
         filterChainDefinitionMap.put("/admin/login", "anon");
         filterChainDefinitionMap.put("/admin", "anon");
         filterChainDefinitionMap.put("/kaptcha", "anon");
         filterChainDefinitionMap.put("/api/**", "anon");
 
+        filterChainDefinitionMap.put("/**", "authc");
+
         /*Map<String, Filter> filters = shiroFilter.getFilters();
         filters.put("authc", new CustomFormAuthenticationFilter());*/
 
@@ -124,8 +148,6 @@ public class ShiroConfig {
         for (com.wsm.admin.model.Resource resource : list) {
             filterChainDefinitionMap.put(resource.getUrl(), "perms[" + resource.getResourceKey() + "]");
         }
-
-        filterChainDefinitionMap.put("/**", "authc");
         shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
         return shiroFilter;
     }

+ 43 - 0
wsm-admin-web/src/main/java/com/wsm/admin/thread/TaskExecutePool.java

@@ -0,0 +1,43 @@
+package com.wsm.admin.thread;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * Created by wangjian on 2017/8/29.
+ */
+@Configuration
+@EnableAsync
+public class TaskExecutePool {
+
+    @Value("${spring.task.pool.corePoolSize}")
+    private int corePoolSize;
+    @Value("${spring.task.pool.corePoolSize}")
+    private int maxPoolSize;
+    @Value("${spring.task.pool.keepAliveSeconds}")
+    private int keepAliveSeconds;
+    @Value("${spring.task.pool.queueCapacity}")
+    private int queueCapacity;
+
+    @Bean
+    public Executor updAsyncPool() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(keepAliveSeconds);
+        executor.setKeepAliveSeconds(queueCapacity);
+        executor.setThreadNamePrefix("MyExecutor-");
+        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
+        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.initialize();
+        return executor;
+    }
+}

+ 0 - 143
wsm-admin-web/src/main/java/com/wsm/admin/udp/Server.java

@@ -1,143 +0,0 @@
-package com.wsm.admin.udp;
-
-import com.wsm.admin.model.Device;
-import com.wsm.admin.model.DeviceStatus;
-import com.wsm.admin.service.IDeviceService;
-import com.wsm.admin.service.IDeviceStatusService;
-import com.wsm.common.util.ASCIIUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class Server implements ApplicationRunner {
-
-    private static Logger logger = LoggerFactory.getLogger(Server.class);
-
-    private final static int PORT = 2000;
-
-    private static final Map<String, String> deviceStatusMap = new HashMap<>();
-
-    static {
-        deviceStatusMap.put("08", "硬件版本号");
-        deviceStatusMap.put("15", "SIM 卡CCID 号码");
-        deviceStatusMap.put("05", "NB/GPRS 信号强度");
-        deviceStatusMap.put("2A00", "电池:低压");
-        deviceStatusMap.put("3500", "NB底座的电池:低压");
-        deviceStatusMap.put("3600", "烟感底座上的烟感电池:低压");
-        deviceStatusMap.put("3701", "消防门状态:打开");
-        deviceStatusMap.put("3801", "消防手报状态:弹起");
-        deviceStatusMap.put("3E01", "喷淋状态:打开");
-
-        deviceStatusMap.put("111", "烟雾报警");
-        deviceStatusMap.put("384", "低压报警");
-        deviceStatusMap.put("993", "底座上的烟感低压");
-        deviceStatusMap.put("992", "NB 底座低压报警 ");
-        deviceStatusMap.put("991", "燃气报警");
-        deviceStatusMap.put("990", "消防手报按钮报警");
-        deviceStatusMap.put("989", "消防门打开");
-        deviceStatusMap.put("988", "消防门关闭");
-        deviceStatusMap.put("987", "消防门长时间未关闭");
-        deviceStatusMap.put("986", "高温报警");
-        deviceStatusMap.put("985", "漏电报警");
-        deviceStatusMap.put("984", "温感低压");
-        deviceStatusMap.put("966", "喷淋打开");
-        deviceStatusMap.put("965", "喷淋关闭");
-    }
-
-    @Autowired
-    private IDeviceStatusService deviceStatusService;
-    @Autowired
-    private IDeviceService deviceService;
-    @Autowired
-    private SimpMessagingTemplate messagingTemplate;
-
-    @Override
-    public void run(ApplicationArguments args) throws Exception {
-
-        try (DatagramSocket socket = new DatagramSocket(PORT)) {
-            while (true) {
-                try {
-                    DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
-                    socket.receive(dp);
-                    String message = new String(dp.getData(), 0, dp.getLength());
-                    String[] str = ASCIIUtil.turnToArray(message);
-                    Device device = deviceService.findByDeviceId16Hex(ASCIIUtil.getDevice(str));
-                    String type = str[6];
-                    switch (type){
-                        // 心跳
-                        case "02":
-                            break;
-                        // 状态
-                        case "04":
-                            int total = Integer.valueOf(str[16]);
-                            for (int i = 0, length = 3; i < total; i++){
-                                String a = str[17 + i * length];
-//                                String b = str[18 + i * length];
-                                String c = str[19 + i * length];
-                                // 状态异常
-                                if (!StringUtils.isEmpty(deviceStatusMap.get(a+c)) && device != null){
-                                    DeviceStatus status =  new DeviceStatus();
-                                    status.setContent(deviceStatusMap.get(a+c));
-                                    status.setDevice(device);
-                                    status.setDeviceType((byte)0);
-                                    deviceStatusService.save(status);
-                                    logger.warn(device.getDeviceId() + ":"+ status.getContent());
-
-                                    messagingTemplate.convertAndSend("/topic/device", status);
-                                }
-                            }
-                            break;
-                        // 报警
-                        case "09":
-                            // 报警
-                            String hex = ASCIIUtil.hexStringToString(str[24]+str[25]+str[26]);
-                            if (!StringUtils.isEmpty(deviceStatusMap.get(hex)) && device != null){
-                                DeviceStatus status =  new DeviceStatus();
-                                status.setContent(deviceStatusMap.get(hex));
-                                status.setDevice(device);
-                                status.setDeviceType((byte)1);
-                                deviceStatusService.save(status);
-                                logger.warn(device.getDeviceId() + ":"+ status.getContent());
-
-                                messagingTemplate.convertAndSend("/topic/device", status);
-                            }
-                            break;
-                    }
-
-                    String feedback = ASCIIUtil.getOKFeedback(str);
-                    byte[] data = feedback.getBytes("ASCII");
-                    DatagramPacket response = new DatagramPacket(data, data.length, dp.getAddress(), dp.getPort());
-                    socket.send(response);
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-    }
-
-
-
-    public static void main(String[] args) {
-        String a = "2b633273000b04004f4b";
-        System.out.println("结果:"+ASCIIUtil.makeChecksum(a));
-        System.out.println("结果:"+ASCIIUtil.hexStringToString("313131"));
-
-    }
-
-
-}

+ 23 - 16
wsm-admin-web/wsm-admin-web.iml

@@ -37,9 +37,6 @@
     <orderEntry type="library" name="Maven: io.projectreactor:reactor-bus:2.0.8.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: com.goldmansachs:gs-collections:5.1.0" level="project" />
     <orderEntry type="library" name="Maven: com.goldmansachs:gs-collections-api:5.1.0" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.16.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.16.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.16.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.16.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
     <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.16.RELEASE" level="project" />
@@ -81,7 +78,6 @@
     <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:2.0.8.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.0" level="project" />
     <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.16.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.16.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: com.github.penggle:kaptcha:2.3.2" level="project" />
     <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
     <orderEntry type="library" name="Maven: com.jhlabs:filters:2.0.235-1" level="project" />
@@ -109,18 +105,13 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" level="project" />
     <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.9" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" level="project" />
-    <orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.12.RELEASE" level="project" />
-    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.29" level="project" />
-    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.29" level="project" />
-    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:8.5.29" level="project" />
-    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:8.5.29" level="project" />
-    <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.6.Final" level="project" />
-    <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-messaging:4.3.16.RELEASE" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-websocket:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.google.zxing:core:2.1" level="project" />
     <orderEntry type="module" module-name="wsm-admin-dao" />
     <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2" level="project" />
     <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.3.2" level="project" />
@@ -156,5 +147,21 @@
     </orderEntry>
     <orderEntry type="module" module-name="wsm-admin-service" />
     <orderEntry type="library" name="Maven: com.github.theborakompanioni:thymeleaf-extras-shiro:1.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.12.RELEASE" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:8.5.29" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:8.5.29" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.6.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-messaging:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.16.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-websocket:4.3.16.RELEASE" level="project" />
   </component>
 </module>

+ 4 - 14
wsm-application/pom.xml

@@ -40,7 +40,6 @@
             <groupId>com.wsm</groupId>
             <artifactId>wsm-admin-web</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
@@ -51,26 +50,17 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <!-- 打war包需要把以下注释掉 -->
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-tomcat</artifactId>
-            <scope>provided</scope>
+            <artifactId>spring-boot-starter-test</artifactId>
         </dependency>
-
-        <!--<dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <version>3.1.0</version>
-            <scope>provided</scope>
-        </dependency>-->
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+            <scope>provided</scope>
         </dependency>
 
-
         <dependency>
             <groupId>com.github.theborakompanioni</groupId>
             <artifactId>thymeleaf-extras-shiro</artifactId>

+ 6 - 1
wsm-application/src/main/java/com/wsm/Application.java

@@ -3,15 +3,19 @@ package com.wsm;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.ServletComponentScan;
 import org.springframework.boot.web.support.SpringBootServletInitializer;
 import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
-@SpringBootApplication
+@ComponentScan(basePackages = {"com.wsm", "com.wsm.admin"})
+@SpringBootApplication(scanBasePackages = {"com.wsm", "com.wsm.admin"})
 @EnableCaching
 @EnableScheduling
 @EnableAsync
+@ServletComponentScan(basePackages = {"com.wsm.admin.filter"})
 public class Application extends SpringBootServletInitializer {
 
     @Override
@@ -22,4 +26,5 @@ public class Application extends SpringBootServletInitializer {
     public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
     }
+
 }

+ 12 - 5
wsm-application/src/main/resources/application.properties

@@ -1,5 +1,4 @@
-server.port=80
-server.host.address=127.0.0.1
+server.port=8080
 #DB
 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
 spring.datasource.url=jdbc:mysql://localhost:3306/jm-smart-city?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
@@ -22,12 +21,13 @@ spring.thymeleaf.content-type=text/html
 logging.config=classpath:logback.xml
 spring.http.multipart.maxFileSize=10Mb
 spring.http.multipart.maxRequestSize=1000Mb
-
-web.upload.file.path=/usr/local/jm-smart-city/upload/
+#windows path
+web.upload.file.path=/usr/local/smart/
 
 spring.mvc.static-path-pattern=/**
 spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/appointment/,file:${web.upload.file.path}
 
+# redis
 spring.redis.database=0
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
@@ -45,4 +45,11 @@ spring.redis.pool.max-wait=-1
 #Redis服务器master的名字
 #spring.redis.sentinel.master=master8026
 #redis-sentinel的配置地址和端口
-#spring.redis.sentinel.nodes=10.189.80.25:26379,10.189.80.26:26379,10.189.80.27:26378
+#spring.redis.sentinel.nodes=10.189.80.25:26379,10.189.80.26:26379,10.189.80.27:26378
+
+context.listener.classes=com.wsm.admin.init.StartupUdpEvent
+#线程池
+spring.task.pool.corePoolSize=5
+spring.task.pool.maxPoolSize=100
+spring.task.pool.keepAliveSeconds=100
+spring.task.pool.queueCapacity=100

+ 189 - 0
wsm-application/src/main/resources/static/plugins/diyUpload/css/diyUpload.css

@@ -0,0 +1,189 @@
+@charset "utf-8";
+.parentFileBox {
+    width: auto;
+    height: auto;
+    overflow: hidden;
+    position: relative
+}
+
+.parentFileBox > .fileBoxUl {
+    position: relative;
+    width: 100%;
+    height: auto;
+    overflow: hidden;
+    padding-bottom: 5px
+}
+
+.parentFileBox > .fileBoxUl > li {
+    float: left;
+    border: 1px solid #09f;
+    border-radius: 5px;
+    width: 170px;
+    height: 150px;
+    margin-top: 5px;
+    margin-left: 5px;
+    overflow: hidden;
+    position: relative;
+    background-color: #099
+}
+
+.parentFileBox > .fileBoxUl > li > .viewThumb {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 170px;
+    height: 150px;
+    overflow: hidden
+}
+
+.parentFileBox > .fileBoxUl > li > .viewThumb > img {
+    width: 100%;
+    height: 100%
+}
+
+.parentFileBox > .fileBoxUl > li > .diyCancel, .parentFileBox > .fileBoxUl > li > .diySuccess {
+    position: absolute;
+    width: 32px;
+    height: 32px;
+    top: 2px;
+    right: 2px;
+    cursor: pointer;
+    display: none
+}
+
+.parentFileBox > .fileBoxUl > li > .diyCancel {
+    background: url(../images/x_alt.png) no-repeat
+}
+
+.parentFileBox > .fileBoxUl > li > .diySuccess {
+    background: url(../images/check_alt.png) no-repeat;
+    cursor: default
+}
+
+.parentFileBox > .fileBoxUl > li > .diyFileName {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 20px;
+    line-height: 20px;
+    text-align: center;
+    color: #fff;
+    font-size: 12px;
+    display: none;
+    background: url(../images/bgblack.png)
+}
+
+.parentFileBox > .fileBoxUl > li > .diyBar {
+    top: 0;
+    left: 0;
+    position: absolute;
+    width: 170px;
+    height: 150px;
+    line-height: 150px;
+    background: url(../images/bgblack.png);
+    display: none
+}
+
+.parentFileBox > .fileBoxUl > li > .diyBar > .diyProgressText {
+    font-size: 14px;
+    text-align: center;
+    color: #fff;
+    position: relative;
+    z-index: 99
+}
+
+.parentFileBox > .fileBoxUl > li > .diyBar > .diyProgress {
+    position: absolute;
+    left: 0;
+    top: 42%;
+    height: 24px;
+    width: 100%;
+    background-color: #09f;
+    filter: alpha(opacity=70);
+    -moz-opacity: .7;
+    opacity: .7;
+    z-index: 97
+}
+
+.parentFileBox > .diyButton {
+    width: 100%;
+    margin-top: 5px;
+    margin-bottom: 5px;
+    height: 20px;
+    line-height: 20px;
+    text-align: center
+}
+
+.parentFileBox > .diyButton > a {
+    padding: 5px 10px;
+    /*background-color: #09c;*/
+    background-color: #009688;
+    color: #fff;
+    font-size: 12px;
+    text-decoration: none;
+    border-radius: 3px
+}
+
+.parentFileBox > .diyButton > a:hover {
+    /*background-color: #0cc;
+    color: #f30;*/
+    opacity: .8;
+    filter: alpha(opacity=80);
+    color: #fff;
+}
+
+.parentFileBox > .fileBoxUl > li:hover {
+    -moz-box-shadow: 3px 3px 4px #ff0;
+    -webkit-box-shadow: 3px 3px 4px #ff0;
+    box-shadow: 3px 3px 4px #ff0
+}
+
+.parentFileBox > .fileBoxUl > .diyUploadHover:hover .diyCancel {
+    display: block
+}
+
+.parentFileBox > .fileBoxUl > li:hover .diyFileName {
+    display: block
+}
+
+.avi_diy_bg, .txt_diy_bg, .doc_diy_bg, .zip_diy_bg, .csv_diy_bg, .xls_diy_bg, .mp3_diy_bg, .pdf_diy_bg, .rar_diy_bg {
+    background-position: center;
+    background-repeat: no-repeat
+}
+
+.avi_diy_bg {
+    background-image: url(../images/filebg/avi.png)
+}
+
+.txt_diy_bg {
+    background-image: url(../images/filebg/txt.png)
+}
+
+.doc_diy_bg {
+    background-image: url(../images/filebg/doc.png)
+}
+
+.zip_diy_bg {
+    background-image: url(../images/filebg/zip.png)
+}
+
+.csv_diy_bg {
+    background-image: url(../images/filebg/csv.png)
+}
+
+.xls_diy_bg {
+    background-image: url(../images/filebg/xls.png)
+}
+
+.mp3_diy_bg {
+    background-image: url(../images/filebg/mp3.png)
+}
+
+.pdf_diy_bg {
+    background-image: url(../images/filebg/pdf.png)
+}
+
+.rar_diy_bg {
+    background-image: url(../images/filebg/rar.png)
+}

+ 45 - 0
wsm-application/src/main/resources/static/plugins/diyUpload/css/webuploader.css

@@ -0,0 +1,45 @@
+.webuploader-container {
+    position: relative
+}
+
+.webuploader-element-invisible {
+    position: absolute !important;
+    clip: rect(1px 1px 1px 1px);
+    clip: rect(1px, 1px, 1px, 1px)
+}
+
+.webuploader-pick {
+    position: relative;
+    display: inline-block;
+    cursor: pointer;
+    background: #00b7ee;
+    padding: 10px 15px;
+    color: #fff;
+    text-align: center;
+    border-radius: 3px;
+    overflow: hidden;
+    display: inline-block;
+    height: 38px;
+    line-height: 38px;
+    padding: 0 18px;
+    background-color: #009688;
+    color: #fff;
+    white-space: nowrap;
+    text-align: center;
+    font-size: 14px;
+    border: none;
+    border-radius: 2px;
+    cursor: pointer;
+}
+
+.webuploader-pick-hover {
+    /*background: #00a2d4*/
+    opacity: .8;
+    filter: alpha(opacity=80);
+    color: #fff;
+}
+
+.webuploader-pick-disable {
+    opacity: .6;
+    pointer-events: none
+}

BIN
wsm-application/src/main/resources/static/plugins/diyUpload/images/bgblack.png


BIN
wsm-application/src/main/resources/static/plugins/diyUpload/images/check_alt.png


BIN
wsm-application/src/main/resources/static/plugins/diyUpload/images/x_alt.png


+ 236 - 0
wsm-application/src/main/resources/static/plugins/diyUpload/js/diyUpload.js

@@ -0,0 +1,236 @@
+(function ($) {
+    var startupload;
+    var endupload;
+    $.fn.extend({
+        diyUpload: function (opt, serverCallBack) {
+            if (typeof opt != "object") {
+                alert('参数错误!');
+                return;
+            }
+            var $fileInput = $(this);
+            var $fileInputId = $fileInput.attr('id');
+            if (opt.url) {
+                opt.server = opt.url;
+                delete opt.url;
+            }
+            if (opt.success) {
+                var successCallBack = opt.success;
+                delete opt.success;
+            }
+            if (opt.error) {
+                var errorCallBack = opt.error;
+                delete opt.error;
+            }
+            if (opt.startupload){
+                startupload = opt.startupload;
+                delete opt.startupload;
+            }
+            if (opt.endupload){
+                endupload = opt.endupload;
+                delete opt.endupload;
+            }
+            $.each(getOption('#' + $fileInputId), function (key, value) {
+                opt[key] = opt[key] || value;
+            });
+            if (opt.buttonText) {
+                opt['pick']['label'] = opt.buttonText;
+                delete opt.buttonText;
+            }
+            var webUploader = getUploader(opt);
+            if (!WebUploader.Uploader.support()) {
+                alert(' 上传组件不支持您的浏览器!');
+                return false;
+            }
+            webUploader.on('fileQueued', function (file) {
+                createBox($fileInput, file, webUploader);
+            });
+            webUploader.on('uploadProgress', function (file, percentage) {
+                var $fileBox = $('#fileBox_' + file.id);
+                var $diyBar = $fileBox.find('.diyBar');
+                $diyBar.show();
+                percentage = percentage * 100;
+                showDiyProgress(percentage.toFixed(2), $diyBar);
+            });
+            webUploader.on('uploadFinished', function () {
+                $fileInput.next('.parentFileBox').children('.diyButton').remove();
+                if (endupload) {
+                    endupload();
+                }
+            });
+            webUploader.on('uploadAccept', function (object, data) {
+                if (serverCallBack) serverCallBack(data);
+            });
+            webUploader.on('uploadSuccess', function (file, response) {
+                var $fileBox = $('#fileBox_' + file.id);
+                var $diyBar = $fileBox.find('.diyBar');
+                $fileBox.removeClass('diyUploadHover');
+                $diyBar.fadeOut(1000, function () {
+                    $fileBox.children('.diySuccess').show();
+                });
+                if (successCallBack) {
+                    successCallBack(response);
+                }
+            });
+            webUploader.on('uploadError', function (file, reason) {
+                var $fileBox = $('#fileBox_' + file.id);
+                var $diyBar = $fileBox.find('.diyBar');
+                showDiyProgress(0, $diyBar, '上传失败!');
+                var err = '上传失败! 文件:' + file.name + ' 错误码:' + reason;
+                if (errorCallBack) {
+                    errorCallBack(err);
+                }
+            });
+            webUploader.on('error', function (code) {
+                var text = '';
+                switch (code) {
+                    case 'F_DUPLICATE':
+                        text = '该文件已经被选择了!';
+                        break;
+                    case 'Q_EXCEED_NUM_LIMIT':
+                        text = '上传文件数量超过限制!';
+                        break;
+                    case 'F_EXCEED_SIZE':
+                        text = '文件大小超过限制!';
+                        break;
+                    case 'Q_EXCEED_SIZE_LIMIT':
+                        text = '所有文件总大小超过限制!';
+                        break;
+                    case 'Q_TYPE_DENIED':
+                        text = '文件类型不正确或者是空文件!';
+                        break;
+                    default:
+                        text = '未知错误!';
+                        break;
+                }
+                alert(text);
+            });
+        }
+    });
+
+    function getOption(objId) {
+        return {
+            pick: {id: objId, label: "点击选择图片"},
+            accept: {title: "Images", extensions: "gif,jpg,jpeg,bmp,png", mimeTypes: "image/*"},
+            thumb: {width: 170, height: 150, quality: 70, allowMagnify: false, crop: true, type: "image/jpeg"},
+            method: "POST",
+            server: "",
+            sendAsBinary: false,
+            threads:1,
+            chunked: true,
+            fileNumLimit: 20,
+            fileSizeLimit: 100 * 1024 * 1024,
+            fileSingleSizeLimit: 5 * 1024 * 1024
+        };
+    }
+
+    function getUploader(opt) {
+        return new WebUploader.Uploader(opt);
+    }
+
+    function showDiyProgress(progress, $diyBar, text) {
+        if (progress >= 100) {
+            progress = progress + '%';
+            text = text || '上传完成';
+        } else {
+            progress = progress + '%';
+            text = text || progress;
+        }
+        var $diyProgress = $diyBar.find('.diyProgress');
+        var $diyProgressText = $diyBar.find('.diyProgressText');
+        $diyProgress.width(progress);
+        $diyProgressText.text(text);
+    }
+
+    function removeLi($li, file_id, webUploader) {
+        webUploader.removeFile(file_id);
+        if ($li.siblings('li').length <= 0) {
+            $li.parents('.parentFileBox').remove();
+        } else {
+            $li.remove();
+        }
+    }
+
+    function createBox($fileInput, file, webUploader) {
+        var file_id = file.id;
+        var $parentFileBox = $fileInput.next('.parentFileBox');
+        if ($parentFileBox.length <= 0) {
+            var div = '<div class="parentFileBox"> \
+						<ul class="fileBoxUl"></ul>\
+					</div>';
+            $fileInput.after(div);
+            $parentFileBox = $fileInput.next('.parentFileBox');
+        }
+        if ($parentFileBox.find('.diyButton').length <= 0) {
+            var div = '<div class="diyButton"> \
+						<a class="diyStart" href="javascript:void(0)">开始上传</a> \
+						<a class="diyCancelAll" href="javascript:void(0)">全部取消</a> \
+					</div>';
+            $parentFileBox.append(div);
+            var $startButton = $parentFileBox.find('.diyStart');
+            var $cancelButton = $parentFileBox.find('.diyCancelAll');
+            var uploadStart = function () {
+                if (startupload) {
+                    startupload();
+                }
+                webUploader.upload();
+                $startButton.text('暂停上传').one('click', function () {
+                    webUploader.stop();
+                    $(this).text('继续上传').one('click', function () {
+                        uploadStart();
+                    });
+                });
+            }
+            $startButton.one('click', uploadStart);
+            $cancelButton.bind('click', function () {
+                var fileArr = webUploader.getFiles('queued');
+                $.each(fileArr, function (i, v) {
+                    removeLi($('#fileBox_' + v.id), v.id, webUploader);
+                });
+            });
+        }
+        var li = '<li id="fileBox_' + file_id + '" class="diyUploadHover"> \
+					<div class="viewThumb"></div> \
+					<div class="diyCancel"></div> \
+					<div class="diySuccess"></div> \
+					<div class="diyFileName">' + file.name + '</div>\
+					<div class="diyBar"> \
+							<div class="diyProgress"></div> \
+							<div class="diyProgressText">0%</div> \
+					</div> \
+				</li>';
+        $parentFileBox.children('.fileBoxUl').append(li);
+        var $width = $('.fileBoxUl>li').length * 180;
+        var $maxWidth = $fileInput.parent().width();
+        $width = $maxWidth > $width ? $width : $maxWidth;
+        $parentFileBox.width($width);
+        var $fileBox = $parentFileBox.find('#fileBox_' + file_id);
+        var $diyCancel = $fileBox.children('.diyCancel').one('click', function () {
+            removeLi($(this).parent('li'), file_id, webUploader);
+        });
+        if (file.type.split("/")[0] != 'image') {
+            var liClassName = getFileTypeClassName(file.name.split(".").pop());
+            $fileBox.addClass(liClassName);
+            return;
+        }
+        webUploader.makeThumb(file, function (error, dataSrc) {
+            if (!error) {
+                $fileBox.find('.viewThumb').append('<img src="' + dataSrc + '" >');
+            }
+        });
+    }
+
+    function getFileTypeClassName(type) {
+        var fileType = {};
+        var suffix = '_diy_bg';
+        fileType['pdf'] = 'pdf';
+        fileType['zip'] = 'zip';
+        fileType['rar'] = 'rar';
+        fileType['csv'] = 'csv';
+        fileType['doc'] = 'doc';
+        fileType['xls'] = 'xls';
+        fileType['xlsx'] = 'xls';
+        fileType['txt'] = 'txt';
+        fileType = fileType[type] || 'txt';
+        return fileType + suffix;
+    }
+})(jQuery);

File diff suppressed because it is too large
+ 2 - 0
wsm-application/src/main/resources/static/plugins/diyUpload/js/webuploader.js


File diff suppressed because it is too large
+ 497 - 1
wsm-application/src/main/resources/static/plugins/layui/lay/modules/form.js


+ 17 - 0
wsm-application/src/main/resources/static/plugins/ueditor/themes/default/css/umeditor.css

@@ -770,4 +770,21 @@
     *zoom:1;
     border:none;
 
+}
+
+#edui-link-Jtarget {
+    display: inline !important;
+}
+.edui-map-dynamic {
+    display: inline !important;
+}
+.edui-body-container ol, ul  {
+    margin: 16px 0;
+    padding-left: 40px !important;
+}
+.edui-body-container ol li  {
+    list-style: decimal !important;
+}
+.edui-body-container ul li  {
+    list-style: initial !important;
 }

+ 1 - 1
wsm-application/src/main/resources/static/plugins/ueditor/themes/default/css/umeditor.min.css

@@ -1,7 +1,7 @@
 /*!
  * UEditor Mini版本
  * version: 1.2.2
- * build: Thu Dec 22 2016 16:36:28 GMT+0800 (CST)
+ * build: Wed Mar 19 2014 17:14:25 GMT+0800 (中国标准时间)
  */
 
 

+ 2 - 77
wsm-application/src/main/resources/static/plugins/ueditor/umeditor.config.js

@@ -147,7 +147,7 @@
             'insertorderedlist insertunorderedlist | selectall cleardoc paragraph | fontfamily fontsize' ,
             '| justifyleft justifycenter justifyright justifyjustify |',
             'link unlink | emotion image ',
-            '| horizontal preview fullscreen', 'drafts', 'formula'
+            '| horizontal print preview fullscreen', 'drafts', 'formula'
         ]
 
         //语言配置项,默认是zh-cn。有需要的话也可以使用如下这样的方式来自动多语言切换,当然,前提条件是lang文件夹下存在对应的语言文件:
@@ -244,81 +244,6 @@
         //,topOffset:30
 
         //填写过滤规则
-        ,filterRules: {}
-        // xss 过滤是否开启,inserthtml等操作
- 		,xssFilterRules: true
- 		//input xss过滤
- 		,inputXssFilter: true
- 		//output xss过滤
- 		,outputXssFilter: true
- 		// xss过滤白名单 名单来源: https://raw.githubusercontent.com/leizongmin/js-xss/master/lib/default.js
-        ,whiteList: {
-            a:      ['target', 'href', 'title', 'style', 'class', 'id'],
-			abbr:   ['title', 'style', 'class', 'id'],
-			address: ['style', 'class', 'id'],
-			area:   ['shape', 'coords', 'href', 'alt', 'style', 'class', 'id'],
-			article: ['style', 'class', 'id'],
-			aside:  ['style', 'class', 'id'],
-			audio:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'style', 'class', 'id'],
-			b:      ['style', 'class', 'id'],
-			bdi:    ['dir'],
-			bdo:    ['dir'],
-			big:    [],
-			blockquote: ['cite', 'style', 'class', 'id'],
-			br:     [],
-			caption: ['style', 'class', 'id'],
-			center: [],
-			cite:   [],
-			code:   ['style', 'class', 'id'],
-			col:    ['align', 'valign', 'span', 'width', 'style', 'class', 'id'],
-			colgroup: ['align', 'valign', 'span', 'width', 'style', 'class', 'id'],
-			dd:     ['style', 'class', 'id'],
-			del:    ['datetime', 'style', 'class', 'id'],
-			details: ['open', 'style', 'class', 'id'],
-			div:    ['style', 'class', 'id'],
-			dl:     ['style', 'class', 'id'],
-			dt:     ['style', 'class', 'id'],
-			em:     ['style', 'class', 'id'],
-            embed:  ['style', 'class', 'id', '_url', 'type', 'pluginspage', 'src', 'width', 'height', 'wmode', 'play', 'loop', 'menu', 'allowscriptaccess', 'allowfullscreen'],
-			font:   ['color', 'size', 'face', 'style', 'class', 'id'],
-			footer: ['style', 'class', 'id'],
-			h1:     ['style', 'class', 'id'],
-			h2:     ['style', 'class', 'id'],
-			h3:     ['style', 'class', 'id'],
-			h4:     ['style', 'class', 'id'],
-			h5:     ['style', 'class', 'id'],
-			h6:     ['style', 'class', 'id'],
-			header: ['style', 'class', 'id'],
-			hr:     ['style', 'class', 'id'],
-			i:      ['style', 'class', 'id'],
-            iframe: ['style', 'class', 'id', 'src', 'frameborder', 'data-latex'],
-			img:    ['src', 'alt', 'title', 'width', 'height', 'style', 'class', 'id', '_url'],
-			ins:    ['datetime', 'style', 'class', 'id'],
-			li:     ['style', 'class', 'id'],
-			mark:   [],
-			nav:    [],
-			ol:     ['style', 'class', 'id'],
-			p:      ['style', 'class', 'id'],
-			pre:    ['style', 'class', 'id'],
-			s:      [],
-			section:[],
-			small:  ['style', 'class', 'id'],
-			span:   ['style', 'class', 'id'],
-			sub:    ['style', 'class', 'id'],
-			sup:    ['style', 'class', 'id'],
-			strong: ['style', 'class', 'id'],
-			table:  ['width', 'border', 'align', 'valign', 'style', 'class', 'id'],
-			tbody:  ['align', 'valign', 'style', 'class', 'id'],
-			td:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'style', 'class', 'id'],
-			tfoot:  ['align', 'valign', 'style', 'class', 'id'],
-			th:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'style', 'class', 'id'],
-			thead:  ['align', 'valign', 'style', 'class', 'id'],
-			tr:     ['rowspan', 'align', 'valign', 'style', 'class', 'id'],
-			tt:     ['style', 'class', 'id'],
-			u:      [],
-			ul:     ['style', 'class', 'id'],
-            svg:    ['style', 'class', 'id', 'width', 'height', 'xmlns', 'fill', 'viewBox'],
-			video:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'style', 'class', 'id']
-        }
+        //,filterRules: {}
     };
 })();

+ 26 - 93
wsm-application/src/main/resources/static/plugins/ueditor/umeditor.js

@@ -1,7 +1,7 @@
 /*!
  * UEditor Mini版本
  * version: 1.2.2
- * build: Thu Dec 22 2016 16:36:28 GMT+0800 (CST)
+ * build: Wed Mar 19 2014 17:14:25 GMT+0800 (中国标准时间)
  */
 
 (function($){
@@ -1864,7 +1864,10 @@ var domUtils = dom.domUtils = {
     isBr: function (node) {
         return node.nodeType == 1 && node.tagName == 'BR';
     },
-    
+    isFillChar: function (node, isInStart) {
+        return node.nodeType == 3 && !node.nodeValue.replace(new RegExp((isInStart ? '^' : '' ) + domUtils.fillChar), '').length
+    },
+
     isEmptyBlock: function (node, reg) {
         if (node.nodeType != 1)
             return 0;
@@ -6047,7 +6050,7 @@ UM.plugins['link'] = function(){
 
     this.addOutputRule(function(root){
         $.each(root.getNodesByTagName('a'),function(i,a){
-            var _href = a.getAttr('_href');
+            var _href = utils.html(a.getAttr('_href'));
             if(!/^(ftp|https?|\/|file)/.test(_href)){
                 _href = 'http://' + _href;
             }
@@ -6060,7 +6063,7 @@ UM.plugins['link'] = function(){
     });
     this.addInputRule(function(root){
         $.each(root.getNodesByTagName('a'),function(i,a){
-            a.setAttr('_href', a.getAttr('href'));
+            a.setAttr('_href', utils.html(a.getAttr('href')));
         })
     });
     me.commands['link'] = {
@@ -6068,15 +6071,13 @@ UM.plugins['link'] = function(){
 
             var me = this;
             var rng = me.selection.getRange();
-            opt._href && (opt._href = utils.unhtml(opt._href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
-            opt.href && (opt.href = utils.unhtml(opt.href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
             if(rng.collapsed){
                 var start = rng.startContainer;
                 if(start = domUtils.findParentByTagName(start,'a',true)){
                     $(start).attr(opt);
                     rng.selectNode(start).select()
                 }else{
-                    rng.insertNode($('<a>' + opt.href +'</a>').attr(opt)[0]).select()
+                    rng.insertNode($('<a>' +opt.href+'</a>').attr(opt)[0]).select()
 
                 }
 
@@ -7334,7 +7335,6 @@ UM.plugins['video'] = function (){
             var html = [],id = 'tmpVedio';
             for(var i=0,vi,len = videoObjs.length;i<len;i++){
                  vi = videoObjs[i];
-                 vi.url = utils.unhtml(vi.url, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g);
                  html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i,vi.align,false));
             }
             me.execCommand("inserthtml",html.join(""),true);
@@ -8171,90 +8171,11 @@ UM.plugins['formula'] = function () {
 
 };
 
-/**
- * @file xssFilter.js
- * @desc xss过滤器
- * @author robbenmu
- */
-
-UM.plugins.xssFilter = function() {
-
-	var config = UMEDITOR_CONFIG;
-	var whiteList = config.whiteList;
-
-	function filter(node) {
-
-		var tagName = node.tagName;
-		var attrs = node.attrs;
-
-		if (!whiteList.hasOwnProperty(tagName)) {
-			node.parentNode.removeChild(node);
-			return false;
-		}
-
-		UM.utils.each(attrs, function (val, key) {
-
-			if (whiteList[tagName].indexOf(key) === -1) {
-				node.setAttr(key);
-			}
-		});
-	}
-
-	// 添加inserthtml\paste等操作用的过滤规则
-	if (whiteList && config.xssFilterRules) {
-		this.options.filterRules = function () {
-
-			var result = {};
-
-			UM.utils.each(whiteList, function(val, key) {
-				result[key] = function (node) {
-					return filter(node);
-				};
-			});
-
-			return result;
-		}();
-	}
-
-	var tagList = [];
-
-	UM.utils.each(whiteList, function (val, key) {
-		tagList.push(key);
-	});
-
-	// 添加input过滤规则
-	//
-	if (whiteList && config.inputXssFilter) {
-		this.addInputRule(function (root) {
-
-			root.traversal(function(node) {
-				if (node.type !== 'element') {
-					return false;
-				}
-				filter(node);
-			});
-		});
-	}
-	// 添加output过滤规则
-	//
-	if (whiteList && config.outputXssFilter) {
-		this.addOutputRule(function (root) {
-
-			root.traversal(function(node) {
-				if (node.type !== 'element') {
-					return false;
-				}
-				filter(node);
-			});
-		});
-	}
-
-};
 (function ($) {
     //对jquery的扩展
     $.parseTmpl = function parse(str, data) {
         var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + 'with(obj||{}){__p.push(\'' + str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/<%=([\s\S]+?)%>/g,function (match, code) {
-            return "',obj." + code.replace(/\\'/g, "'") + ",'";
+            return "'," + code.replace(/\\'/g, "'") + ",'";
         }).replace(/<%([\s\S]+?)%>/g,function (match, code) {
                 return "');" + code.replace(/\\'/g, "'").replace(/[\r\n\t]/g, ' ') + "__p.push('";
             }).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/\t/g, '\\t') + "');}return __p.join('');";
@@ -10048,9 +9969,20 @@ UM.registerUI('bold italic redo undo underline strikethrough superscript subscri
 
             //还原CSS表达式
             var options = this.editor.options,
-                height = /%$/.test(options.initialFrameHeight) ?  '100%' : (options.initialFrameHeight - this.getStyleValue("padding-top")- this.getStyleValue("padding-bottom") - this.getStyleValue('border-width'));
+                height = /%$/.test(options.initialFrameHeight) ?  '100%' : (options.initialFrameHeight - this.getStyleValue("padding-top")- this.getStyleValue("padding-bottom"));
 
-            $.IE6 && this.getEditorHolder().style.setExpression('height', 'this.scrollHeight <= ' + height + ' ? "' + height + 'px" : "auto"');
+            /*if(options.autoHeightEnabled){
+                container.style.minHeight = height +'px';
+                container.style.height = '';
+                if(browser.ie && browser.version <= 6){
+                    container.style.height = height ;
+                    container.style.setExpression('height', 'this.scrollHeight <= ' + height + ' ? "' + height + 'px" : "auto"');
+                }
+            }else{
+                $(container).height(height)
+            }*/
+            
+            $.IE6 && this.getEditorHolder().style.setExpression('height',  height + 'px');
 
             //还原容器状态
             this.revertContainerStatus();
@@ -10114,9 +10046,10 @@ UM.registerUI('bold italic redo undo underline strikethrough superscript subscri
                 overflowY: 'hidden'
             } );
 
+            var h = window.innerHeight - 2*borderWidth - ( editor.options.withoutToolbar ? 0 : $( '.edui-toolbar', editor.container ).outerHeight() ) + 'px';
             $( editorBody ).css({
                 width: width - 2*borderWidth - paddingWidth + 'px',
-                height: height - 2*borderWidth - ( editor.options.withoutToolbar ? 0 : $( '.edui-toolbar', editor.container ).outerHeight() ) - $( '.edui-bottombar', editor.container).outerHeight() + 'px',
+                height: h,
                 overflowX: 'hidden',
                 overflowY: 'auto'
             });
@@ -10186,10 +10119,10 @@ UM.registerUI('bold italic redo undo underline strikethrough superscript subscri
             var holder = this.getEditorHolder(),
                 state = this.getContentAreaStatus();
 
-            if ( this.supportMin() ) {
+            /*if ( this.supportMin() ) {
                 delete state.height;
                 holder.style.height = null;
-            }
+            }*/
 
             $( holder ).css( state );
         },

File diff suppressed because it is too large
+ 243 - 252
wsm-application/src/main/resources/static/plugins/ueditor/umeditor.min.js


+ 2 - 2
wsm-application/src/main/resources/templates/admin/role/form.html

@@ -24,7 +24,7 @@
         <div class="layui-card-body">
             <form class="layui-form" action="/admin/role/save" method="post">
                 <input type="hidden" id="roleId" name="id" th:value="${role.id}">
-                <input type="hidden" id="resourceIds" name="resourceIds" th:value="${resourceIds}">
+                <input type="hidden" id="resourceIds" name="resourceIds">
                 <div class="layui-form-item">
                     <label class="layui-form-label">角色名</label>
                     <div class="layui-input-inline">
@@ -146,7 +146,7 @@
                         checkNodesName.push(nodes[i].name);
                     }
                     $('#resourceIds').val(checkNodes.join(","));
-                    $('#resourceGrant').val(checkNodesName.join(","));
+                    $('#resourceGrant').val(checkNodesName.join(","))
                     layer.close(treeOpen);
                 },
                 btn2: function (index) {

+ 5 - 7
wsm-application/src/main/resources/templates/admin/role/list.html

@@ -69,22 +69,20 @@
 <script th:inline="javascript">
     layui.use(['element', 'laypage', 'layer', 'table', 'laydate'], function () {
         /*<![CDATA[*/
-        var size = [[${size}]];
-        var totalElements = [[${totalElements}]];
-        var number = [[${number}]];
+        var pageable = [[${roles}]];
         /*]]>*/
 
         var $ = layui.jquery;
         var table = layui.table, laypage = layui.laypage;
 
-        table.init('rolePage', {limit: size});
+        table.init('rolePage', {limit: pageable.size});
 
         laypage.render({
             elem: 'pag',
-            count: totalElements,
+            count: pageable.totalElements,
             groups: 10,
-            limit: size,
-            curr: number + 1,
+            limit: pageable.size,
+            curr: pageable.number + 1,
             layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'],
             jump: function (obj, first) {
                 if (!first) {

+ 5 - 7
wsm-application/src/main/resources/templates/admin/user/list.html

@@ -70,23 +70,21 @@
 <script src="/plugins/layui/layui.js"></script>
 <script th:inline="javascript">
     /*<![CDATA[*/
-    var size = [[${size}]];
-    var totalElements = [[${totalElements}]];
-    var number = [[${number}]];
+    var pageable = [[${users}]];
     /*]]>*/
 
     layui.use(['element', 'laypage', 'layer', 'table', 'laydate'], function () {
         var $ = layui.jquery;
         var table = layui.table, laypage = layui.laypage;
 
-        table.init('userPage', {limit: size});
+        table.init('userPage', {limit: pageable.size});
 
         laypage.render({
             elem: 'pag',
-            count: totalElements,
+            count: pageable.totalElements,
             groups: 10,
-            limit: size,
-            curr: number + 1,
+            limit: pageable.size,
+            curr: pageable.number + 1,
             layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'],
             jump: function (obj, first) {
                 if (!first) {

+ 56 - 0
wsm-application/src/main/resources/templates/sock.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>stomp</title>
+</head>
+
+<body>
+    Welcome<br/><input id="text" type="text" />
+    <button onclick="send()">发送消息</button>
+    <button onclick="subscribe1()">订阅消息/topic/device</button>
+    <hr/>
+    <button onclick="closeWebSocket()">关闭WebSocket连接</button>
+    <hr/>
+    <div id="message"></div>
+</body>
+
+<script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
+<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
+<script type="text/javascript">
+    // 建立连接对象(还未发起连接)
+    var socket = new SockJS("http://192.168.0.100:8080/webSocketServer");
+
+    // 获取 STOMP 子协议的客户端对象
+    var stompClient = Stomp.over(socket);
+
+    // 向服务器发起websocket连接并发送CONNECT帧
+    stompClient.connect(
+        {},
+        function connectCallback(frame) {
+            // 连接成功时(服务器响应 CONNECTED 帧)的回调方法
+            setMessageInnerHTML("连接成功");
+        },
+        function errorCallBack(error) {
+            // 连接失败时(服务器响应 ERROR 帧)的回调方法
+            setMessageInnerHTML("连接失败");
+        }
+    );
+
+    //订阅消息
+    function subscribe1() {
+        stompClient.subscribe('/topic/device', function (response) {
+            setMessageInnerHTML("已成功订阅/topic/device");
+            var returnData = JSON.parse(response.body);
+            setMessageInnerHTML("/topic/device 你接收到的消息为:" + returnData.responseMessage);
+        });
+    }
+
+    //将消息显示在网页上
+    function setMessageInnerHTML(innerHTML) {
+        document.getElementById('message').innerHTML += innerHTML + '<br/>';
+    }
+
+</script>
+
+</html>

+ 7 - 0
wsm-application/wsm-application.iml

@@ -84,6 +84,13 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" level="project" />
     <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.google.zxing:core:2.1" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework:spring-messaging:4.3.16.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework:spring-websocket:4.3.16.RELEASE" level="project" />

+ 19 - 0
wsm-common/pom.xml

@@ -92,6 +92,25 @@
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.5</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 3 - 2
wsm-common/src/main/java/com/wsm/common/config/WebMvcConfig.java

@@ -11,6 +11,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.http.MediaType;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
@@ -85,12 +86,12 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter {
         return registration;
     }
 
-    /*@Override
+    @Override
     public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**")
                 .allowedOrigins("*")
                 .allowCredentials(true)
                 .allowedMethods("GET", "POST", "DELETE", "PUT")
                 .maxAge(3600);
-    }*/
+    }
 }

+ 42 - 2
wsm-common/src/main/java/com/wsm/common/interceptor/CommonInterceptor.java

@@ -1,18 +1,53 @@
 package com.wsm.common.interceptor;
 
+import com.alibaba.fastjson.JSONObject;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
 
 @Component
 public class CommonInterceptor implements HandlerInterceptor {
 
+    // \\b表示限定单词边界,比如 select不通过,1select则是可以的
+    private static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"
+            + "(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)";
+
+    private static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
+
     @Override
     public boolean preHandle(HttpServletRequest request,
-                             HttpServletResponse response, Object handler) throws Exception {
+                             HttpServletResponse resp, Object handler) throws Exception {
+        //获得所有请求参数名
+        /*Enumeration params = request.getParameterNames();
+        String sql = "";
+        while (params.hasMoreElements()) {
+            //得到参数名
+            String name = params.nextElement().toString();
+            //得到参数对应值
+            String[] value = request.getParameterValues(name);
+            for (int i = 0; i < value.length; i++) {
+                sql = sql + value[i];
+            }
+        }
+        if (!isSQLValid(sql)){
+            resp.setCharacterEncoding("UTF-8");
+            resp.setContentType("application/json; charset=utf-8");
+
+            JSONObject res = new JSONObject();
+            res.put("code", -1);
+            res.put("msg", "您发送请求中的参数中含有非法字符");
+            PrintWriter out = resp.getWriter();
+            out.append(res.toString());
+            out.flush();
+            out.close();
+            return false;
+        }*/
         return true;
     }
 
@@ -30,5 +65,10 @@ public class CommonInterceptor implements HandlerInterceptor {
 
     }
 
-
+    private static boolean isSQLValid(String str) {
+        if (sqlPattern.matcher(str.toLowerCase()).find()) {
+            return false;
+        }
+        return true;
+    }
 }

+ 22 - 1
wsm-common/src/main/java/com/wsm/common/util/AjaxJson.java

@@ -16,7 +16,7 @@ public class AjaxJson implements Serializable {
     public static String[] NOOP = new String[]{};
 
     /**
-     * 处理状态:0: 成功, 1: 失败
+     * 处理状态:0: 成功, -1: 失败
      */
     private int code;
     /**
@@ -112,6 +112,17 @@ public class AjaxJson implements Serializable {
     }
 
     /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static final AjaxJson failure(int code, String msg, Object data) {
+        return new AjaxJson(code, msg, data, 0);
+    }
+
+    /**
      * 处理失败
      *
      * @param msg 消息
@@ -121,6 +132,16 @@ public class AjaxJson implements Serializable {
         return failure(CODE_FAILURED, msg);
     }
 
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static final AjaxJson failure(String msg, Object data) {
+        return failure(CODE_FAILURED, msg, data);
+    }
+
     public int getCode() {
         return code;
     }

+ 2 - 2
wsm-common/src/main/java/com/wsm/common/util/ConstantUtils.java

@@ -7,10 +7,10 @@ public class ConstantUtils {
     public static final String SUCCESS_MSG = "操作成功。";
 
     public static final int FAILURE_CODE_01 = 11;
-    public static final String FAILURE_MSG_01 = "参数值不能为空。";
+    public static final String FAILURE_MSG_01 = "token不能为空。";
 
     public static final int FAILURE_CODE_102 = 102;
-    public static final String FAILURE_MSG_102 = "登录超时,请重新登录。";
+    public static final String FAILURE_MSG_102 = "token失效,请重新登录。";
 
 
 }

+ 77 - 0
wsm-common/src/main/java/com/wsm/common/util/DateTimeUtils.java

@@ -0,0 +1,77 @@
+package com.wsm.common.util;
+
+import java.util.Date;
+
+import org.joda.time.DateTime;
+import org.joda.time.Duration;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+public class DateTimeUtils {
+	
+	public static String getStatusByTime(String openTime) {
+		try {
+			
+			String[] times = openTime.split(" - ");
+			DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");  
+			
+			DateTime start = new DateTime(times[0]);    
+			DateTime end = DateTime.parse(times[1] + " 23:59:59", format);
+			if(start.isAfterNow()){
+				return "待展出";
+			}else if(start.isEqualNow() || (start.isBeforeNow() && end.isAfterNow()) || end.isEqualNow()){
+				return "展出中";
+			}else if (end.isBeforeNow()){
+				return "已结束";
+			}
+		}catch(Exception e){
+			return "";
+		}
+		return "";
+	}
+	
+	public static String getStatusByDate(Date startTime, Date endTime) {
+		try {
+			
+			DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");  
+			
+			DateTime start = new DateTime(startTime);    
+			DateTime end = DateTime.parse(endTime + " 23:59:59", format);
+			if(start.isAfterNow()){
+				return "待展出";
+			}else if(start.isEqualNow() || (start.isBeforeNow() && end.isAfterNow()) || end.isEqualNow()){
+				return "展出中";
+			}else if (end.isBeforeNow()){
+				return "已结束";
+			}
+		}catch(Exception e){
+			return "";
+		}
+		return "";
+	}
+	
+	public static String getStatusTextByDate(Date startTime, Date endTime) {
+		try {
+			if (startTime == null && endTime == null){
+				return "常设展";
+			}
+			DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");  
+			
+			DateTime start = new DateTime(startTime);    
+			DateTime end = DateTime.parse(endTime + " 23:59:59", format);
+			if(start.isAfterNow()){
+				Duration duration = new Duration(DateTime.now(), start);
+				return duration.getStandardDays() + 1 + "天后开幕";
+			}else if(start.isEqualNow() || (start.isBeforeNow() && end.isAfterNow()) || end.isEqualNow()){
+				Duration duration = new Duration(DateTime.now(), end);
+				return duration.getStandardDays() + "天后闭幕";
+			}else if (end.isBeforeNow()){
+				return "已结束";
+			}
+		}catch(Exception e){
+			return "";
+		}
+		return "常设展";
+	}
+
+}

+ 52 - 0
wsm-common/src/main/java/com/wsm/common/util/FileUtils.java

@@ -3,7 +3,9 @@ package com.wsm.common.util;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.*;
+import java.net.URLEncoder;
 import java.util.UUID;
 
 public class FileUtils {
@@ -247,4 +249,54 @@ public class FileUtils {
         }
     }
 
+    public static void downloadExcel(String fname, String fPath, HttpServletResponse resp) throws IOException {
+        File file = new File(fPath);
+
+        resp.reset();// 清空输出流
+        resp.setHeader("Content-disposition", "attachment; filename="+ new String(fname.getBytes(), "iso-8859-1") + ".xls");
+        resp.setContentType("application/msexcel");
+        resp.setContentLength((int) file.length());
+        output(resp, file);
+    }
+
+    public static void downloadFile(String agent, String fileName, String filePath, String contentType, HttpServletResponse resp) throws IOException {
+        if (agent != null && (agent.contains("MSIE")||agent.contains("Trident"))) {
+            fileName = URLEncoder.encode(fileName, "UTF-8");
+        } else {
+            //非IE浏览器的处理:
+            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
+        }
+
+        File file = new File(filePath);
+        resp.reset();
+        resp.setHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");
+        resp.setContentType(contentType);
+        resp.setContentLength((int) file.length());
+        output(resp, file);
+    }
+
+    public static void output(HttpServletResponse resp, File file) {
+        OutputStream os = null;
+        BufferedInputStream bis = null;
+        byte[] buff = new byte[1024];
+        try {
+            os = resp.getOutputStream();
+            bis = new BufferedInputStream(new FileInputStream(file));
+            int i = 0;
+            while ((i = bis.read(buff)) != -1) {
+                os.write(buff, 0, i);
+                os.flush();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                bis.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
 }

+ 317 - 0
wsm-common/src/main/java/com/wsm/common/util/HttpClientUtils.java

@@ -0,0 +1,317 @@
+package com.wsm.common.util;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.config.RequestConfig.Builder;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContextBuilder;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class HttpClientUtils {
+
+    public static final int connTimeout=10000;
+    public static final int readTimeout=10000;
+    public static final String charset="UTF-8";
+    private static HttpClient client = null;
+
+    static {
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+        cm.setMaxTotal(128);
+        cm.setDefaultMaxPerRoute(128);
+        client = HttpClients.custom().setConnectionManager(cm).build();
+    }
+
+    public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception{
+        return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
+    }
+
+    public static String postParameters(String url, String parameterStr,String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception{
+        return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
+    }
+
+    public static String postParameters(String url, Map<String, String> params) throws ConnectTimeoutException,
+            SocketTimeoutException, Exception {
+        return postForm(url, params, null, connTimeout, readTimeout);
+    }
+
+    public static String postParameters(String url, Map<String, String> params, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
+            SocketTimeoutException, Exception {
+        return postForm(url, params, null, connTimeout, readTimeout);
+    }
+
+    public static String get(String url) throws Exception {
+        return get(url, charset, null, null);
+    }
+
+    public static String get(String url, String charset) throws Exception {
+        return get(url, charset, connTimeout, readTimeout);
+    }
+
+    /**
+     * 发送一个 Post 请求, 使用指定的字符集编码.
+     *
+     * @param url
+     * @param body RequestBody
+     * @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
+     * @param charset 编码
+     * @param connTimeout 建立链接超时时间,毫秒.
+     * @param readTimeout 响应超时时间,毫秒.
+     * @return ResponseBody, 使用指定的字符集编码.
+     * @throws ConnectTimeoutException 建立链接超时异常
+     * @throws SocketTimeoutException  响应超时
+     * @throws Exception
+     */
+    public static String post(String url, String body, String mimeType,String charset, Integer connTimeout, Integer readTimeout)
+            throws ConnectTimeoutException, SocketTimeoutException, Exception {
+        HttpClient client = null;
+        HttpPost post = new HttpPost(url);
+        String result = "";
+        try {
+            if (StringUtils.isNotBlank(body)) {
+                HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
+                post.setEntity(entity);
+            }
+            // 设置参数
+            Builder customReqConf = RequestConfig.custom();
+            if (connTimeout != null) {
+                customReqConf.setConnectTimeout(connTimeout);
+            }
+            if (readTimeout != null) {
+                customReqConf.setSocketTimeout(readTimeout);
+            }
+            post.setConfig(customReqConf.build());
+
+            HttpResponse res;
+            if (url.startsWith("https")) {
+                // 执行 Https 请求.
+                client = createSSLInsecureClient();
+                res = client.execute(post);
+            } else {
+                // 执行 Http 请求.
+                client = HttpClientUtils.client;
+                res = client.execute(post);
+            }
+            result = IOUtils.toString(res.getEntity().getContent(), charset);
+        } finally {
+            post.releaseConnection();
+            if (url.startsWith("https") && client != null&& client instanceof CloseableHttpClient) {
+                ((CloseableHttpClient) client).close();
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * 提交form表单
+     *
+     * @param url
+     * @param params
+     * @param connTimeout
+     * @param readTimeout
+     * @return
+     * @throws ConnectTimeoutException
+     * @throws SocketTimeoutException
+     * @throws Exception
+     */
+    public static String postForm(String url, Map<String, String> params, Map<String, String> headers, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
+            SocketTimeoutException, Exception {
+
+        HttpClient client = null;
+        HttpPost post = new HttpPost(url);
+        try {
+            if (params != null && !params.isEmpty()) {
+                List<NameValuePair> formParams = new ArrayList<NameValuePair>();
+                Set<Map.Entry<String, String>> entrySet = params.entrySet();
+                for (Map.Entry<String, String> entry : entrySet) {
+                    formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+                }
+                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+                post.setEntity(entity);
+            }
+
+            if (headers != null && !headers.isEmpty()) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    post.addHeader(entry.getKey(), entry.getValue());
+                }
+            }
+            // 设置参数
+            Builder customReqConf = RequestConfig.custom();
+            if (connTimeout != null) {
+                customReqConf.setConnectTimeout(connTimeout);
+            }
+            if (readTimeout != null) {
+                customReqConf.setSocketTimeout(readTimeout);
+            }
+            post.setConfig(customReqConf.build());
+            HttpResponse res = null;
+            if (url.startsWith("https")) {
+                // 执行 Https 请求.
+                client = createSSLInsecureClient();
+                res = client.execute(post);
+            } else {
+                // 执行 Http 请求.
+                client = HttpClientUtils.client;
+                res = client.execute(post);
+            }
+            return IOUtils.toString(res.getEntity().getContent(), "UTF-8");
+        } finally {
+            post.releaseConnection();
+            if (url.startsWith("https") && client != null
+                    && client instanceof CloseableHttpClient) {
+                ((CloseableHttpClient) client).close();
+            }
+        }
+    }
+
+
+
+
+    /**
+     * 发送一个 GET 请求
+     *
+     * @param url
+     * @param charset
+     * @param connTimeout  建立链接超时时间,毫秒.
+     * @param readTimeout  响应超时时间,毫秒.
+     * @return
+     * @throws ConnectTimeoutException   建立链接超时
+     * @throws SocketTimeoutException   响应超时
+     * @throws Exception
+     */
+    public static String get(String url, String charset, Integer connTimeout,Integer readTimeout)
+            throws ConnectTimeoutException,SocketTimeoutException, Exception {
+
+        HttpClient client = null;
+        HttpGet get = new HttpGet(url);
+        String result = "";
+        try {
+            // 设置参数
+            Builder customReqConf = RequestConfig.custom();
+            if (connTimeout != null) {
+                customReqConf.setConnectTimeout(connTimeout);
+            }
+            if (readTimeout != null) {
+                customReqConf.setSocketTimeout(readTimeout);
+            }
+            get.setConfig(customReqConf.build());
+
+            HttpResponse res = null;
+
+            if (url.startsWith("https")) {
+                // 执行 Https 请求.
+                client = createSSLInsecureClient();
+                res = client.execute(get);
+            } else {
+                // 执行 Http 请求.
+                client = HttpClientUtils.client;
+                res = client.execute(get);
+            }
+
+            result = IOUtils.toString(res.getEntity().getContent(), charset);
+        } finally {
+            get.releaseConnection();
+            if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
+                ((CloseableHttpClient) client).close();
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * 从 response 里获取 charset
+     *
+     * @param ressponse
+     * @return
+     */
+    @SuppressWarnings("unused")
+    private static String getCharsetFromResponse(HttpResponse ressponse) {
+        // Content-Type:text/html; charset=GBK
+        if (ressponse.getEntity() != null  && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
+            String contentType = ressponse.getEntity().getContentType().getValue();
+            if (contentType.contains("charset=")) {
+                return contentType.substring(contentType.indexOf("charset=") + 8);
+            }
+        }
+        return null;
+    }
+
+
+
+    /**
+     * 创建 SSL连接
+     * @return
+     * @throws GeneralSecurityException
+     */
+    private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
+        try {
+            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                    return true;
+                }
+            }).build();
+
+            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
+
+                @Override
+                public boolean verify(String arg0, SSLSession arg1) {
+                    return true;
+                }
+
+                @Override
+                public void verify(String host, SSLSocket ssl)
+                        throws IOException {
+                }
+
+                @Override
+                public void verify(String host, X509Certificate cert)
+                        throws SSLException {
+                }
+
+                @Override
+                public void verify(String host, String[] cns,
+                                   String[] subjectAlts) throws SSLException {
+                }
+
+            });
+
+            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+
+        } catch (GeneralSecurityException e) {
+            throw e;
+        }
+    }
+}

+ 21 - 0
wsm-common/src/main/java/com/wsm/common/util/NumberUtils.java

@@ -3,6 +3,8 @@ package com.wsm.common.util;
 import org.joda.time.DateTime;
 
 import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class NumberUtils {
 	
@@ -59,4 +61,23 @@ public class NumberUtils {
         return result;
     }
 
+    //验证手机号码
+    public static boolean isPhoneNumber(String number) {
+        String rgx = "^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$";
+        return isCorrect(rgx, number);
+    }
+
+    //验证身份证号码
+    public static boolean isIdCardNumber(String number) {
+        String rgx = "^\\d{15}|^\\d{17}([0-9]|X|x)$";
+        return isCorrect(rgx, number);
+    }
+
+    //正则验证
+    public static boolean isCorrect(String rgx, String res) {
+        Pattern p = Pattern.compile(rgx);
+        Matcher m = p.matcher(res);
+        return m.matches();
+    }
+
 }

+ 88 - 0
wsm-common/src/main/java/com/wsm/common/util/PatternUtils.java

@@ -0,0 +1,88 @@
+package com.wsm.common.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PatternUtils {
+
+    public static boolean isEmail(String email) {
+        // 1、\\w+表示@之前至少要输入一个匹配字母或数字或下划线
+        // \\w 单词字符:[a-zA-Z_0-9] // 2、(\\w+\\.)表示域名. 如新浪邮箱域名是sina.com.cn
+        // {1,3}表示可以出现一次或两次或者三次.
+        String reg = "\\w+@(\\w+\\.){1,3}\\w+";
+        Pattern pattern = Pattern.compile(reg);
+        boolean flag = false;
+        if (email != null) {
+            Matcher matcher = pattern.matcher(email);
+            flag = matcher.matches();
+        }
+        return flag;
+    }
+
+    /**
+     * 判断身份证格式
+     *
+     * @param idNum
+     * @return
+     */
+    public static boolean isIdNum(String idNum) {
+        if (idNum == null || "".equals(idNum)) {
+            return false;
+        }
+        // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母)
+        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
+                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
+        //假设18位身份证号码:41000119910101123X  410001 19910101 123X
+        //^开头
+        //[1-9] 第一位1-9中的一个      4
+        //\\d{5} 五位数字           10001(前六位省市县地区)
+        //(18|19|20)                19(现阶段可能取值范围18xx-20xx年)
+        //\\d{2}                    91(年份)
+        //((0[1-9])|(10|11|12))     01(月份)
+        //(([0-2][1-9])|10|20|30|31)01(日期)
+        //\\d{3} 三位数字            123(第十七位奇数代表男,偶数代表女)
+        //[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值)
+        //$结尾
+
+        //假设15位身份证号码:410001910101123  410001 910101 123
+        //^开头
+        //[1-9] 第一位1-9中的一个      4
+        //\\d{5} 五位数字           10001(前六位省市县地区)
+        //\\d{2}                    91(年份)
+        //((0[1-9])|(10|11|12))     01(月份)
+        //(([0-2][1-9])|10|20|30|31)01(日期)
+        //\\d{3} 三位数字            123(第十五位奇数代表男,偶数代表女),15位身份证不含X
+        //$结尾
+        boolean matches = idNum.matches(regularExpression);
+        //判断第18位校验值
+        if (matches) {
+            if (idNum.length() == 18) {
+                try {
+                    char[] charArray = idNum.toCharArray();
+                    //前十七位加权因子
+                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
+                    //这是除以11后,可能产生的11位余数对应的验证码
+                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
+                    int sum = 0;
+                    for (int i = 0; i < idCardWi.length; i++) {
+                        int current = Integer.parseInt(String.valueOf(charArray[i]));
+                        int count = current * idCardWi[i];
+                        sum += count;
+                    }
+                    char idCardLast = charArray[17];
+                    int idCardMod = sum % 11;
+                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+
+        }
+        return matches;
+    }
+}

+ 63 - 0
wsm-common/src/main/java/com/wsm/common/util/QrCodeUtil.java

@@ -0,0 +1,63 @@
+package com.wsm.common.util;
+
+import com.google.zxing.*;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.Hashtable;
+
+/**
+ * 二维码生成和读的工具类
+ *
+ */
+public class QrCodeUtil {
+    /**
+     * 生成包含字符串信息的二维码图片
+     * @param filePath 文件输出流路径
+     * @param content 二维码携带信息
+     * @param qrCodeSize 二维码图片大小
+     * @param imageFormat 二维码的格式
+     * @throws WriterException
+     * @throws IOException
+     */
+    public static boolean createQrCode(String  filePath, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
+        //设置二维码纠错级别MAP
+        Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
+        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  // 矫错级别
+        QRCodeWriter qrCodeWriter = new QRCodeWriter();
+        //创建比特矩阵(位矩阵)的QR码编码的字符串
+        BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
+        // 使BufferedImage勾画QRCode  (matrixWidth 是行二维码像素点)
+        int matrixWidth = byteMatrix.getWidth();
+        BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
+        image.createGraphics();
+        Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setColor(Color.WHITE);
+        graphics.fillRect(0, 0, matrixWidth, matrixWidth);
+        // 使用比特矩阵画并保存图像
+        graphics.setColor(Color.BLACK);
+        for (int i = 0; i < matrixWidth; i++){
+            for (int j = 0; j < matrixWidth; j++){
+                if (byteMatrix.get(i, j)){
+                    graphics.fillRect(i-100, j-100, 1, 1);
+                }
+            }
+        }
+        OutputStream outputStream=new FileOutputStream(new File(filePath));
+        return ImageIO.write(image, imageFormat, outputStream);
+    }
+
+    /**
+     * 测试代码
+     * @throws WriterException
+     */
+    public static void main(String[] args) throws IOException, WriterException {
+        createQrCode("d:\\qrcode.jpg","china is good",900,"JPEG");
+//        createQrCode("src\\main\\webapp\\qrcode\\qrcode.jpg","china is good",900,"JPEG");
+    }
+}

+ 35 - 0
wsm-common/src/main/java/com/wsm/common/util/SpringContext.java

@@ -0,0 +1,35 @@
+package com.wsm.common.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+@Component
+@Lazy(false)
+public class SpringContext implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    public static Object getBean(String name) {
+        return getApplicationContext().getBean(name);
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+
+    public static <T> T getBean(String name, Class<T> clazz) {
+        return getApplicationContext().getBean(name, clazz);
+    }
+}

+ 46 - 0
wsm-common/src/main/java/com/wsm/common/util/StringUtil.java

@@ -0,0 +1,46 @@
+package com.wsm.common.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+public class StringUtil {
+
+    /**
+     * 过滤掉超过3个字节的UTF8字符
+     * @param text
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+    public static String filterOffUtf8Mb4(String text) throws UnsupportedEncodingException {
+        byte[] bytes = text.getBytes("utf-8");
+        ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
+        int i = 0;
+        while (i < bytes.length) {
+            short b = bytes[i];
+            if (b > 0) {
+                buffer.put(bytes[i++]);
+                continue;
+            }
+
+            b += 256; // 去掉符号位
+
+            if (((b >> 5) ^ 0x6) == 0) {
+                buffer.put(bytes, i, 2);
+                i += 2;
+            } else if (((b >> 4) ^ 0xE) == 0) {
+                buffer.put(bytes, i, 3);
+                i += 3;
+            } else if (((b >> 3) ^ 0x1E) == 0) {
+                i += 4;
+            } else if (((b >> 2) ^ 0x3E) == 0) {
+                i += 5;
+            } else if (((b >> 1) ^ 0x7E) == 0) {
+                i += 6;
+            } else {
+                buffer.put(bytes[i++]);
+            }
+        }
+        buffer.flip();
+        return new String(buffer.array(), "utf-8");
+    }
+}

+ 40 - 0
wsm-common/src/main/java/com/wsm/common/util/URLEncodeUtil.java

@@ -0,0 +1,40 @@
+package com.wsm.common.util;
+
+import java.io.UnsupportedEncodingException;
+
+public class URLEncodeUtil {
+
+    private final static String ENCODE = "UTF-8";
+    /**
+     * URL 解码
+     */
+    public static String getURLDecoderString(String str) {
+        String result = "";
+        if (null == str) {
+            return "";
+        }
+        try {
+            result = java.net.URLDecoder.decode(str, ENCODE);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+    /**
+     * URL 转码
+     */
+    public static String getURLEncoderString(String str) {
+        String result = "";
+        if (null == str) {
+            return "";
+        }
+        try {
+            result = java.net.URLEncoder.encode(str, ENCODE);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+
+}

+ 36 - 0
wsm-common/src/main/java/com/wsm/common/util/ZipUtils.java

@@ -0,0 +1,36 @@
+package com.wsm.common.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ZipUtils {
+
+    public static void generateZip(OutputStream os, List<File> files) throws Exception {
+        ZipOutputStream out = null;
+        try {
+            byte[] buffer = new byte[1024]; //生成的ZIP文件名为Demo.zip
+            out = new ZipOutputStream(os); //需要同时下载的两个文件result.txt ,source.txt
+            for (File file : files) {
+                FileInputStream fis = new FileInputStream(file);
+                out.putNextEntry(new ZipEntry(file.getName()));
+                int len; //读入需要下载的文件的内容,打包到zip文件
+                while ((len = fis.read(buffer)) != -1) {
+                    out.write(buffer, 0, len);
+                }
+                out.flush();
+                out.closeEntry();
+                fis.close();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+}

+ 7 - 0
wsm-common/wsm-common.iml

@@ -106,6 +106,13 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.2" level="project" />
     <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.9" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: com.google.zxing:core:2.1" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-websocket:2.1.3.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.12.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.6.Final" level="project" />