소스 검색

first commit

wenxgdev 5 년 전
커밋
c04aaacb0e
100개의 변경된 파일6131개의 추가작업 그리고 0개의 파일을 삭제
  1. 35 0
      env_files/properties/dev.properties
  2. 36 0
      env_files/properties/prod.properties
  3. 35 0
      env_files/properties/test.properties
  4. 301 0
      pom.xml
  5. 293 0
      settings-cloud.xml
  6. 23 0
      sptg-common/pom.xml
  7. 148 0
      sptg-common/sptg-common-core/pom.xml
  8. 69 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ExcelResultEnum.java
  9. 31 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/PageBean.java
  10. 92 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ResultBean.java
  11. 69 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ResultEnum.java
  12. 22 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/StorePathChildren.java
  13. 35 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/UserBean.java
  14. 39 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/AopTypeDtxConfigBean.java
  15. 31 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/ConfigBean.java
  16. 26 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/GlobalConfigBean.java
  17. 36 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/RedisTemplateConfigBean.java
  18. 46 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/RestTemplateConfigBean.java
  19. 54 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/CommonConstant.java
  20. 22 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/DateFormatConstant.java
  21. 74 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/HttpConstant.java
  22. 57 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/OperationConstant.java
  23. 77 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/SymbolConstant.java
  24. 37 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/SysLogConstant.java
  25. 55 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/UserFlagConstant.java
  26. 46 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/BaseEntity.java
  27. 51 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/DispatchTask.java
  28. 75 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/PublishTask.java
  29. 86 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/PublishTaskResult.java
  30. 111 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/DeviceInstruct.java
  31. 118 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/Instruct.java
  32. 57 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/InstructDH.java
  33. 27 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/exception/ImportExcelException.java
  34. 64 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/CharlesRequestInterceptor.java
  35. 26 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/FeignAutoConfiguration.java
  36. 13 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/GatewayRequestInterceptor.java
  37. 274 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/filter/EncryptionFilter.java
  38. 80 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/handler/GlobalExceptionHandler.java
  39. 21 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/interfaces/VoidInterface.java
  40. 39 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/I18Config.java
  41. 15 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/I18n.java
  42. 137 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/MessageResourceExtension.java
  43. 53 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/MessageResourceInterceptor.java
  44. 35 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AccessCardExportModule.java
  45. 48 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AccessCardImportModule.java
  46. 41 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AdWatchExportModule.java
  47. 32 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AdWatchRankExportModule.java
  48. 52 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AgencyImportModule.java
  49. 41 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/DeviceInstallationExportModule.java
  50. 40 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/DeviceTestExportModule.java
  51. 43 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/PositionExportModule.java
  52. 83 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ProjectExportModule.java
  53. 64 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ResidentialExportModule.java
  54. 49 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ResidentialImportModule.java
  55. 54 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/RoomExportModule.java
  56. 67 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/RoomImportModule.java
  57. 47 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/StatisticsUserExportModule.java
  58. 52 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ThirdUserImportModule.java
  59. 52 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UnitExportModule.java
  60. 55 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UnitImportModule.java
  61. 47 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserAccessExportModule.java
  62. 50 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserAccessImportModule.java
  63. 50 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserExportModule.java
  64. 76 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserImportModule.java
  65. 94 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/AesEncryptionUtil.java
  66. 26 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/AssertUtil.java
  67. 109 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/Base64DecodeMultipartFileUtils.java
  68. 148 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/CommonUtil.java
  69. 221 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/CookieUtils.java
  70. 122 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/DateUtil.java
  71. 122 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/JsonUtils.java
  72. 97 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/TreeUtil.java
  73. 40 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/VersionUtil.java
  74. 133 0
      sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/WebUtils.java
  75. 7 0
      sptg-common/sptg-common-core/src/main/resources/META-INF/spring.factories
  76. 23 0
      sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/MessageApplication.java
  77. 14 0
      sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/MessageSourceTestCase.java
  78. 36 0
      sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/TestController.java
  79. 11 0
      sptg-common/sptg-common-core/src/test/resources/application.yml
  80. 1 0
      sptg-common/sptg-common-core/src/test/resources/i18n/messages_zh_CN.properties
  81. 8 0
      sptg-common/sptg-common-core/src/test/resources/templates/index.html
  82. 34 0
      sptg-common/sptg-common-security/pom.xml
  83. 30 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/annotation/Security.java
  84. 31 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/cfgbeans/SecurityConfigBean.java
  85. 49 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/cfgbeans/SecurityMvcConfigBean.java
  86. 23 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/enums/DataFormatEnum.java
  87. 12 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/BodyAuthenticationException.java
  88. 12 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/BodyAuthorizationException.java
  89. 12 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/ViewAuthenticationException.java
  90. 12 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/ViewAuthorizationException.java
  91. 94 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/interceptor/SecurityInterceptor.java
  92. 72 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/service/SecurityServiceInterface.java
  93. 150 0
      sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/service/impl/BaseRedisSecurityService.java
  94. 3 0
      sptg-common/sptg-common-security/src/main/resources/META-INF/spring.factories
  95. 33 0
      sptg-common/sptg-common-tag/pom.xml
  96. 56 0
      sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/cfgbeans/ThymeleafAutoConfigBean.java
  97. 41 0
      sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/dialect/CustomDialect.java
  98. 52 0
      sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/processor/CustomSessionIdTagProcessor.java
  99. 58 0
      sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/processor/SecurityTagProcessor.java
  100. 31 0
      sptg-common/sptg-common-tag/src/main/resources/META-INF/custom-dialect.xml

+ 35 - 0
env_files/properties/dev.properties

@@ -0,0 +1,35 @@
+#jdbc
+mvn.spring.datasource.host=smart-house-mysql
+mvn.spring.datasource.port=3306
+mvn.spring.datasource.username=root
+mvn.spring.datasource.password=root@123456
+
+#redis
+mvn.spring.redis.host=smart-house-redis
+mvn.spring.redis.port=6379
+mvn.spring.redis.password=
+
+# RabbitMq
+mvn.spring.rabbitmq.host=smart-house-rabbitmq
+mvn.spring.rabbitmq.port=5672
+mvn.spring.rabbitmq.username=guest
+mvn.spring.rabbitmq.password=guest
+mvn.spring.rabbitmq.virtual-host=smart-house-dev
+
+#亲邻接口
+mvn.qinlin.api.host=https://test-gateway.qinlinkeji.com
+mvn.qinlin.version=v1
+mvn.qinlin.appid=QCxTKDxQf4WH8Wmk
+mvn.qinlin.app.secret=DiReTxz4SWhmiKX3wrEiAmDaRb3sjsN0
+
+#数据库
+mysql.database.ad=cyzh_ad
+mysql.database.estate=cyzh_estate
+mysql.database.device=cyzh_device
+mysql.database.permissions=cyzh_permissions
+mysql.database.statistics=cyzh_statistics
+mysql.database.pay=cyzh_pay
+mysql.database.iot=cyzh_iot
+mysql.database.lcn=cyzh_lcn
+mysql.database.third=cyzh_third
+mysql.database.video-cloud=cyzh_video_cloud

+ 36 - 0
env_files/properties/prod.properties

@@ -0,0 +1,36 @@
+#jdbc
+mvn.spring.datasource.host=smart-house-mysql
+mvn.spring.datasource.port=3306
+mvn.spring.datasource.username=root
+mvn.spring.datasource.password=2e564ee5-d9ed-11e9-bab6-0242ac170005
+
+#redis
+mvn.spring.redis.host=smart-house-redis
+mvn.spring.redis.port=9736
+mvn.spring.redis.password=
+
+# RabbitMq
+mvn.spring.rabbitmq.host=smart-house-rabbitmq
+mvn.spring.rabbitmq.port=5672
+mvn.spring.rabbitmq.username=guest
+#本地
+mvn.spring.rabbitmq.password=2e564ee5-d9ed-11e9-bab6-0242ac170005
+mvn.spring.rabbitmq.virtual-host=smart-house
+
+#亲邻接口
+mvn.qinlin.api.host=https://gateway.qinlinkeji.com
+mvn.qinlin.version=v1
+mvn.qinlin.appid=QCxTKDxQf4WH8Wmk
+mvn.qinlin.app.secret=DiReTxz4SWhmiKX3wrEiAmDaRb3sjsN0
+
+#数据库
+mysql.database.ad=sptg_ad
+mysql.database.estate=sptg_estate
+mysql.database.device=sptg_device
+mysql.database.permissions=sptg_permissions
+mysql.database.statistics=sptg_statistics
+mysql.database.pay=sptg_pay
+mysql.database.iot=sptg_iot
+mysql.database.lcn=lcn_tx_manager
+mysql.database.third=sptg_third
+mysql.database.video-cloud=sptg_video_cloud

+ 35 - 0
env_files/properties/test.properties

@@ -0,0 +1,35 @@
+#jdbc
+mvn.spring.datasource.host=smart-house-mysql
+mvn.spring.datasource.port=3306
+mvn.spring.datasource.username=root
+mvn.spring.datasource.password=root@123456
+
+#redis
+mvn.spring.redis.host=smart-house-redis
+mvn.spring.redis.port=6379
+mvn.spring.redis.password=
+
+# RabbitMq
+mvn.spring.rabbitmq.host=smart-house-rabbitmq
+mvn.spring.rabbitmq.port=5672
+mvn.spring.rabbitmq.username=guest
+mvn.spring.rabbitmq.password=guest
+mvn.spring.rabbitmq.virtual-host=smart-house-dev
+
+#亲邻接口
+mvn.qinlin.api.host=https://test-gateway.qinlinkeji.com
+mvn.qinlin.version=v1
+mvn.qinlin.appid=QCxTKDxQf4WH8Wmk
+mvn.qinlin.app.secret=DiReTxz4SWhmiKX3wrEiAmDaRb3sjsN0
+
+#数据库
+mysql.database.ad=cyzh_ad
+mysql.database.estate=cyzh_estate
+mysql.database.device=cyzh_device
+mysql.database.permissions=cyzh_permissions
+mysql.database.statistics=cyzh_statistics
+mysql.database.pay=cyzh_pay
+mysql.database.iot=cyzh_iot
+mysql.database.lcn=cyzh_lcn
+mysql.database.third=cyzh_third
+mysql.database.video-cloud=cyzh_video_cloud

+ 301 - 0
pom.xml

@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.sptg</groupId>
+    <artifactId>smart-house</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0</version>
+    <modules>
+        <module>sptg-eureka</module>
+        <module>sptg-api-gateway</module>
+        <module>sptg-config</module>
+        <module>sptg-common</module>
+        <module>sptg-gateway</module>
+        <module>sptg-pay</module>
+        <module>sptg-permissions</module>
+        <module>sptg-device</module>
+        <module>sptg-estate</module>
+        <module>sptg-ad</module>
+        <module>sptg-statistics</module>
+        <module>sptg-tx-manager</module>
+        <module>sptg-iot</module>
+        <module>sptg-video-cloud</module>
+        <module>sptg-third</module>
+        <module>sptg-repeater</module>
+    </modules>
+
+    <properties>
+        <!-- 编码 -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <!-- Maven 编译版本 -->
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
+
+        <!-- Mysql -->
+        <mysql.version>8.0.11</mysql.version>
+        <!-- Spring Boot -->
+        <spring-boot-dependencies.version>2.0.7.RELEASE</spring-boot-dependencies.version>
+        <!-- Spring Cloud -->
+        <spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
+
+        <!-- lombok -->
+        <lombok.version>1.18.2</lombok.version>
+        <!-- mybatis-plus -->
+        <mbp.boot.version>2.3</mbp.boot.version>
+        <!-- druid 数据源 -->
+        <druid.version>1.1.9</druid.version>
+        <!-- Apache工具组件  -->
+        <commons-io.version>2.6</commons-io.version>
+        <commons-fileupload.version>1.3.1</commons-fileupload.version>
+        <commons-codec.version>1.11</commons-codec.version>
+        <poi.version>3.17</poi.version>
+        <poi-ooxml.version>3.17</poi-ooxml.version>
+        <easyexcel.version>1.1.2-beta5</easyexcel.version>
+        <!-- FastDfs 客户端 -->
+        <fastdfs-client.version>1.26.3</fastdfs-client.version>
+        <!-- Lcn 分布式事务框架 -->
+        <lcn-tx.version>5.0.2.RELEASE</lcn-tx.version>
+    </properties>
+	<distributionManagement>
+        <repository>
+            <id>nexus-releases</id>
+            <name>ReleasesProxy</name>
+            <url>http://800pharm.7766.org:9081/repository/maven-releases/</url>
+        </repository>
+        <snapshotRepository>
+	        <id>nexus-snapshots</id>
+	        <url>http://800pharm.7766.org:9081/repository/maven-snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+    <!-- 依赖管理 -->
+    <dependencyManagement>
+        <dependencies>
+            <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
+            <dependency>
+                <groupId>net.sf.json-lib</groupId>
+                <artifactId>json-lib</artifactId>
+                <version>2.4</version>
+            </dependency>
+
+            <!-- LCN 分布式事务服务端 -->
+            <dependency>
+                <groupId>com.codingapi.txlcn</groupId>
+                <artifactId>txlcn-tm</artifactId>
+                <version>${lcn-tx.version}</version>
+            </dependency>
+            <!-- LCN 分布式事务客户端 -->
+            <dependency>
+                <groupId>com.codingapi.txlcn</groupId>
+                <artifactId>txlcn-tc</artifactId>
+                <version>${lcn-tx.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.codingapi.txlcn</groupId>
+                <artifactId>txlcn-txmsg-netty</artifactId>
+                <version>${lcn-tx.version}</version>
+            </dependency>
+            <!-- FastDfs 客户端 -->
+            <dependency>
+                <groupId>com.github.tobato</groupId>
+                <artifactId>fastdfs-client</artifactId>
+                <version>${fastdfs-client.version}</version>
+            </dependency>
+            <!-- Mysql -->
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql.version}</version>
+            </dependency>
+            <!-- Spring Boot -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot-dependencies.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <!-- Spring Cloud -->
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${spring-cloud-dependencies.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- Lombok -->
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>${lombok.version}</version>
+                <scope>provided</scope>
+            </dependency>
+
+            <!-- mybatis-plus -->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-core</artifactId>
+                <version>${mbp.boot.version}</version>
+                <scope>compile</scope>
+            </dependency>
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>${mbp.boot.version}</version>
+            </dependency>
+
+            <!-- 连接池druid 数据源 -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>druid</artifactId>
+                <version>${druid.version}</version>
+            </dependency>
+
+            <!-- Apache工具组件  -->
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${commons-codec.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>${commons-io.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-fileupload</groupId>
+                <artifactId>commons-fileupload</artifactId>
+                <version>${commons-fileupload.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>easyexcel</artifactId>
+                <version>${easyexcel.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <dependencies>
+        <!-- 模板引擎 -->
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.0</version>
+        </dependency>
+    </dependencies>
+    <repositories>
+        <!-- 使用阿里云镜像 -->
+        <repository>
+            <id>aliyun</id>
+            <name>aliyun</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+        </repository>
+        <repository>
+            <id>spring-milestones</id>
+            <name>Spring Milestones</name>
+            <url>https://repo.spring.io/milestone</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+    <profiles>
+	    <!-- 开发环境,默认激活 -->
+	    <profile>
+	        <id>dev</id>
+	        <properties>
+	            <env>dev</env>
+                <config-url>http://smart-house-config:4001</config-url>
+	        </properties>
+	        <activation>
+	            <activeByDefault>true</activeByDefault>
+	        </activation>
+	    </profile>
+        <profile>
+            <id>test</id>
+            <properties>
+                <env>test</env>
+                <config-url>http://smart-house-config:4001</config-url>
+            </properties>
+        </profile>
+        <profile>
+            <id>prod</id>
+            <properties>
+                <env>prod</env>
+                <config-url>http://smart-house-config:4001</config-url>
+            </properties>
+        </profile>
+    </profiles>
+    <build>
+        <finalName>${project.artifactId}</finalName>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+			</resource>
+			<resource>
+			   <directory>src/main/resources</directory>
+			   <filtering>true</filtering>
+			   <includes>
+				 <include>conf/*.yml</include>
+				 <include>*.yml</include>
+				 <include>*.properties</include>
+			   </includes>
+		   </resource>
+		</resources>
+        <pluginManagement>
+            <plugins>
+                <!-- Spring Boot 打包插件( 非“Web模块”请勿引入) -->
+                <plugin>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-maven-plugin</artifactId>
+                    <version>${spring-boot-dependencies.version}</version>
+                    <configuration>
+                        <!-- 没有该配置,devtools 不生效 -->
+                        <fork>true</fork>
+                        <addResources>true</addResources>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>repackage</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <!-- 公共插件 -->
+        <plugins>
+            <!-- Maven 打包时跳过测试用例 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M3</version>
+                <configuration>
+                    <!-- <skip>true</skip> -->
+                    <skipTests>true</skipTests>
+                    <systemProperties>
+                        <property>
+                            <name>env</name>
+                            <value>${env}</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 293 - 0
settings-cloud.xml

@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+ | This is the configuration file for Maven. It can be specified at two levels:
+ |
+ |  1. User Level. This settings.xml file provides configuration for a single user, 
+ |                 and is normally provided in ${user.home}/.m2/settings.xml.
+ |
+ |                 NOTE: This location can be overridden with the CLI option:
+ |
+ |                 -s /path/to/user/settings.xml
+ |
+ |  2. Global Level. This settings.xml file provides configuration for all Maven
+ |                 users on a machine (assuming they're all using the same Maven
+ |                 installation). It's normally provided in 
+ |                 ${maven.home}/conf/settings.xml.
+ |
+ |                 NOTE: This location can be overridden with the CLI option:
+ |
+ |                 -gs /path/to/global/settings.xml
+ |
+ | The sections in this sample file are intended to give you a running start at
+ | getting the most out of your Maven installation. Where appropriate, the default
+ | values (values used when the setting is not specified) are provided.
+ |
+ |-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+  <!-- localRepository
+   | The path to the local repository maven will use to store artifacts.
+   |
+   | Default: ~/.m2/repository
+  -->
+  
+  <localRepository>D:\Maven\m2\repository</localRepository>
+
+  <!-- interactiveMode
+   | This will determine whether maven prompts you when it needs input. If set to false,
+   | maven will use a sensible default value, perhaps based on some other setting, for
+   | the parameter in question.
+   |
+   | Default: true
+  <interactiveMode>true</interactiveMode>
+  -->
+
+  <!-- offline
+   | Determines whether maven should attempt to connect to the network when executing a build.
+   | This will have an effect on artifact downloads, artifact deployment, and others.
+   |
+   | Default: false
+  <offline>false</offline>
+  -->
+  <offline>false</offline>
+  <!-- pluginGroups
+   | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
+   | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
+   | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
+   |-->
+  <pluginGroups>
+    <!-- pluginGroup
+     | Specifies a further group identifier to use for plugin lookup.
+    <pluginGroup>com.your.plugins</pluginGroup>
+    -->
+    <pluginGroup>org.codehaus.cargo</pluginGroup>
+  </pluginGroups>
+
+  <!-- proxies
+   | This is a list of proxies which can be used on this machine to connect to the network.
+   | Unless otherwise specified (by system property or command-line switch), the first proxy
+   | specification in this list marked as active will be used.
+   |-->
+  <proxies>
+    <!-- proxy
+     | Specification for one proxy, to be used in connecting to the network.
+     |
+    <proxy>
+      <id>optional</id>
+      <active>true</active>
+      <protocol>http</protocol>
+      <username>proxyuser</username>
+      <password>proxypass</password>
+      <host>proxy.host.net</host>
+      <port>80</port>
+      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
+    </proxy>
+    -->
+  </proxies>
+
+  <!-- servers
+   | This is a list of authentication profiles, keyed by the server-id used within the system.
+   | Authentication profiles can be used whenever maven must make a connection to a remote server.
+   |-->
+  <servers>
+  	<server>
+      <id>myLocalServer</id>
+      <privateKey>E:\maven\repository2</privateKey>
+    </server>
+    <!-- server
+     | Specifies the authentication information to use when connecting to a particular server, identified by
+     | a unique name within the system (referred to by the 'id' attribute below).
+     | 
+     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are 
+     |       used together.
+     |
+    <server>
+      <id>deploymentRepo</id>
+      <username>repouser</username>
+      <password>repopwd</password>
+    </server>
+    -->
+    
+    <server>
+      <id>nexus-releases</id>
+      <username>admin</username>
+      <password>admin123</password>
+    </server>
+    <server>
+      <id>nexus-snapshots</id>
+      <username>admin</username>
+      <password>admin123</password>
+    </server>
+    <server>
+       <id>3rd_party</id>
+       <username>admin</username>
+       <password>admin123</password>
+    </server>
+  </servers>
+
+  <!-- mirrors
+   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
+   | 
+   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
+   | However, this repository may have problems with heavy traffic at times, so people have mirrored
+   | it to several places.
+   |
+   | That repository definition will have a unique id, so we can create a mirror reference for that
+   | repository, to be used as an alternate download site. The mirror site will be the preferred 
+   | server for that repository.
+   |-->
+  <mirrors>
+  	<!--
+    <mirror>
+		  <id>nexus</id>
+		  <mirrorOf>*,!sonar</mirrorOf>
+		  <url>http://800pharm.7766.org:9081/repository/maven-public/</url>
+    </mirror>
+     -->
+	 <mirror>
+		<id>nexus</id>
+		<mirrorOf>*,!sonar</mirrorOf>
+		<url>http://800pharm.7766.org:9081/repository/maven-public/</url>
+    </mirror>
+    <mirror>
+            <id>nexus-aliyun</id>
+            <mirrorOf>central</mirrorOf>
+            <name>mirror</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+    </mirror>
+  </mirrors>
+  
+  <!-- profiles
+   | This is a list of profiles which can be activated in a variety of ways, and which can modify
+   | the build process. Profiles provided in the settings.xml are intended to provide local machine-
+   | specific paths and repository locations which allow the build to work in the local environment.
+   |
+   | For example, if you have an integration testing plugin - like cactus - that needs to know where
+   | your Tomcat instance is installed, you can provide a variable here such that the variable is 
+   | dereferenced during the build process to configure the cactus plugin.
+   |
+   | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
+   | section of this document (settings.xml) - will be discussed later. Another way essentially
+   | relies on the detection of a system property, either matching a particular value for the property,
+   | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a 
+   | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
+   | Finally, the list of active profiles can be specified directly from the command line.
+   |
+   | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
+   |       repositories, plugin repositories, and free-form properties to be used as configuration
+   |       variables for plugins in the POM.
+   |
+   |-->
+  <profiles>
+  
+    <!-- profile
+     | Specifies a set of introductions to the build process, to be activated using one or more of the
+     | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
+     | or the command line, profiles have to have an ID that is unique.
+     |
+     | An encouraged best practice for profile identification is to use a consistent naming convention
+     | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
+     | This will make it more intuitive to understand what the set of introduced profiles is attempting
+     | to accomplish, particularly when you only have a list of profile id's for debug.
+     |
+     | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
+    <profile>
+      <id>jdk-1.4</id>
+
+      <activation>
+        <jdk>1.4</jdk>
+      </activation>
+
+      <repositories>
+        <repository>
+          <id>jdk14</id>
+          <name>Repository for JDK 1.4 builds</name>
+          <url>http://www.myhost.com/maven/jdk14</url>
+          <layout>default</layout>
+          <snapshotPolicy>always</snapshotPolicy>
+        </repository>
+      </repositories>
+    </profile>
+    -->
+
+    <!--
+     | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
+     | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
+     | might hypothetically look like:
+     |
+     | ...
+     | <plugin>
+     |   <groupId>org.myco.myplugins</groupId>
+     |   <artifactId>myplugin</artifactId>
+     |   
+     |   <configuration>
+     |     <tomcatLocation>${tomcatPath}</tomcatLocation>
+     |   </configuration>
+     | </plugin>
+     | ...
+     |
+     | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
+     |       anything, you could just leave off the <value/> inside the activation-property.
+     |
+    <profile>
+      <id>env-dev</id>
+
+      <activation>
+        <property>
+          <name>target-env</name>
+          <value>dev</value>
+        </property>
+      </activation>
+
+      <properties>
+        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
+      </properties>
+    </profile>
+    -->
+    <!--
+    <profile>  
+       <id>sonar</id>  
+       <activation>  
+           <activeByDefault>true</activeByDefault>  
+       </activation> 
+       <properties>
+            <sonar.jdbc.url>jdbc:oracle:thin:@localhost:1521:ORCL</sonar.jdbc.url> 
+            <sonar.jdbc.driver>oracle.jdbc.driver.OracleDriver</sonar.jdbc.driver>
+            <sonar.jdbc.username>sonar</sonar.jdbc.username>  
+            <sonar.jdbc.password>sonar</sonar.jdbc.password>
+            <sonar.host.url>http://localhost:9000</sonar.host.url> 
+       </properties>  
+    </profile>  
+    -->
+  </profiles>
+
+  <!-- activeProfiles
+   | List of profiles that are active for all builds.
+   |
+  <activeProfiles>
+    <activeProfile>alwaysActiveProfile</activeProfile>
+    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
+  </activeProfiles>
+  -->
+</settings>

+ 23 - 0
sptg-common/pom.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-house</artifactId>
+        <groupId>com.sptg</groupId>
+        <version>1.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sptg-common</artifactId>
+    <packaging>pom</packaging>
+    <description>公共聚合模块</description>
+    <modules>
+        <module>sptg-common-core</module>
+        <module>sptg-common-tag</module>
+        <module>sptg-common-security</module>
+    </modules>
+
+
+</project>

+ 148 - 0
sptg-common/sptg-common-core/pom.xml

@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sptg-common</artifactId>
+        <groupId>com.sptg</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sptg-common-core</artifactId>
+    <description>常用工具包</description>
+
+    <dependencies>
+
+        <!-- ===================================== Or JAR ===================================== -->
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <!--server-api-->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- mybatis-plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-core</artifactId>
+        </dependency>
+        <!-- 常用工具包  -->
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <!-- POI组件  -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
+        <!-- easyExcel组件  -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+        </dependency>
+        <!-- ===================================== Spring Boot JAR ===================================== -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- 配置文件处理器 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!-- redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- aop -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
+        <!-- ===================================== Spring Cloud JAR ===================================== -->
+        <!-- eureka-client -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <!-- conf -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <!-- feign -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <!-- hystrix -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
+        </dependency>
+        <!-- stream -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
+        </dependency>
+        <!-- fastdfs -->
+        <dependency>
+            <groupId>com.github.tobato</groupId>
+            <artifactId>fastdfs-client</artifactId>
+        </dependency>
+
+        <!-- LCN 分布式事务客户端 -->
+        <dependency>
+            <groupId>com.codingapi.txlcn</groupId>
+            <artifactId>txlcn-tc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.codingapi.txlcn</groupId>
+            <artifactId>txlcn-txmsg-netty</artifactId>
+        </dependency>
+        <!-- 测试用例 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+            <scope>test</scope>
+        </dependency>
+         -->
+        <!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+
+    </dependencies>
+
+
+
+</project>

+ 69 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ExcelResultEnum.java

@@ -0,0 +1,69 @@
+package com.sptg.common.core.beans;
+
+import lombok.Getter;
+
+/**
+ * title: ExcelResultEnum
+ * package: com.sptg.common.core.beans
+ * description: excel 导入枚举
+ *
+ *
+ *
+ */
+@Getter
+public enum ExcelResultEnum implements ResultBean.BaseResultEnum{
+    /**
+     * 部分数据导入成功
+     */
+    SUCCESS_ERROR("200","部分数据导入成功,错误数据请查看生成的错误表格"),
+
+    /**
+     * 导入成功
+     */
+    SUCCESS("200","导入成功"),
+
+    /**
+     * 导入失败
+     */
+    ERROR("200","导入失败"),
+
+    /**
+     * 参数异常
+     */
+    PARAMETER_ANOMALY("200","参数类型错误,请核实后再操作"),
+
+    /**
+     * 文件类型错误
+     */
+    FILE_TYPE_ERROR("200","文件类型错误,请重新选择"),
+
+    /**
+     * 文件内容错误
+     */
+    FILE_CONTENT_ERROR("200","文件内容错误,请核实后再操作"),
+
+    /**
+     * 文件太大
+     */
+    FILE_IS_BIG_1000("200","文件太大(不超过1000条),请分批操作"),
+    /**
+     * 文件太大
+     */
+    FILE_IS_BIG_2000("200","文件太大(不超过2000条),请分批操作"),
+    ;
+
+    /**
+     * 状态吗
+     */
+    private String code;
+
+    /**
+     * 消息
+     */
+    private String msg;
+
+    ExcelResultEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 31 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/PageBean.java

@@ -0,0 +1,31 @@
+package com.sptg.common.core.beans;
+
+import com.baomidou.mybatisplus.plugins.Page;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * title: PageBean
+ * package: com.sptg.common.core.beans
+ * description: 分页查询条件
+ *
+ *                  
+ *                 
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class PageBean<T,Dto> extends Page<T> {
+
+    /**
+     * 查询条件
+     */
+    private Dto dto;
+
+    public PageBean(int current, int size) {
+        super(current, size);
+    }
+}

+ 92 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ResultBean.java

@@ -0,0 +1,92 @@
+package com.sptg.common.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * title: ResultBean
+ * package: com.sptg.common.core.beans
+ * description: 所有接口的返回值类型
+ *                  
+ *               
+ */
+@Getter
+public class ResultBean<Entity> implements java.io.Serializable {
+
+    /**
+     * 状态代码
+     */
+    private String code;
+
+    /**
+     * 消息
+     */
+    private String msg;
+
+    /**
+     * 返回值
+     */
+    @Setter
+    private Entity data;
+
+    /**
+     * 返回值列表,有序
+     */
+    @Setter
+    private List<Entity> list;
+
+    /**
+     * 全部返回值状态枚举的父类接口
+     */
+    public interface BaseResultEnum {
+
+        /**
+         * 错误代码
+         * @return String
+         */
+        String getCode();
+
+        /**
+         * 错误消息
+         * @return String
+         */
+        String getMsg();
+
+    }
+
+    /* ================================================== 构造函数 ================================================== */
+
+    public ResultBean(){
+
+    }
+
+    public ResultBean(String code,String msg){
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public ResultBean(BaseResultEnum result){
+        this(result.getCode(),result.getMsg());
+    }
+
+    public ResultBean(BaseResultEnum result, Entity data) {
+        this(result);
+        this.data = data;
+    }
+
+    public ResultBean(BaseResultEnum result, List<Entity> list) {
+        this(result);
+        this.list = list;
+    }
+
+    public static ResultBean ok(){
+        return new ResultBean(ResultEnum.SUCCESS);
+    }
+
+    public static <T> ResultBean<T> ok(T data){
+        return new ResultBean<>(ResultEnum.SUCCESS,data);
+    }
+
+}

+ 69 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/ResultEnum.java

@@ -0,0 +1,69 @@
+package com.sptg.common.core.beans;
+
+import lombok.Getter;
+
+/**
+ * title: ResultEnum
+ * package: com.sptg.common.core.beans
+ * description: 返回值枚举
+ *
+ *
+ */
+@Getter
+public enum ResultEnum implements ResultBean.BaseResultEnum {
+
+    /**
+     * 请求成功
+     */
+    SUCCESS("200","success"),
+
+    /**
+     * 参数异常
+     */
+    PARAMETER_ANOMALY("400","请求参数有误"),
+
+    /**
+     * 禁止访问
+     */
+    FORBIDDEN("403","没权限"),
+
+    /**
+     * 认证失败
+     */
+    UNAUTHORIZED("401","未登陆或登录超时"),
+
+    /**
+     * 找不到处理程序
+     */
+    NOT_FIND("404","资源不存在"),
+
+    /**
+     * 请求超时
+     */
+    REQUEST_TIME_OUT("408","请求超时"),
+
+    /**
+     * 服务器异常
+     */
+    ERROR("500","服务器异常"),
+
+    /**
+     * 请求失败
+     */
+    FAILURE("402", "失败");
+
+    /**
+     * 状态吗
+     */
+    private String code;
+
+    /**
+     * 消息
+     */
+    private String msg;
+
+    ResultEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 22 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/StorePathChildren.java

@@ -0,0 +1,22 @@
+package com.sptg.common.core.beans;
+
+import com.github.tobato.fastdfs.domain.StorePath;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: StorePathChildren
+ * package: com.sptg.common.core.beans
+ * description: 存储文件的路径信息--扩展类
+ *
+ *               
+ *                
+ */
+@Getter
+@Setter
+public class StorePathChildren extends StorePath {
+    /**
+     * 文件的md5值
+     */
+    private String md5;
+}

+ 35 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/beans/UserBean.java

@@ -0,0 +1,35 @@
+package com.sptg.common.core.beans;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * title: UserBean
+ * package: com.sptg.common.core.beans
+ * description: 所有用户的父类
+ *
+ *                  
+ *                 
+ */
+@Getter
+@Setter
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class UserBean implements java.io.Serializable {
+
+    /**
+     * 登陆标识
+     */
+    @TableField(exist = false)
+    private String loginToken;
+
+    /**
+     * 拥有的权限列表
+     */
+    @TableField(exist = false)
+    private List<String> tokenList;
+
+}

+ 39 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/AopTypeDtxConfigBean.java

@@ -0,0 +1,39 @@
+package com.sptg.common.core.cfgbeans;
+
+import com.codingapi.txlcn.common.util.Transactions;
+import com.codingapi.txlcn.tc.aspect.interceptor.TxLcnInterceptor;
+import com.codingapi.txlcn.tc.aspect.weave.DTXLogicWeaver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+/**
+ * title: AopTypeDTXConfiguration
+ * package: com.cjlgb.tx.clent.cfgbeans
+ * description:
+ *
+ *                  
+ *                
+ */
+@Configuration
+public class AopTypeDtxConfigBean {
+
+
+    /**
+     * 分布式事务配置 设置为LCN模式
+     */
+    @Bean
+    @ConditionalOnBean(DTXLogicWeaver.class)
+    public TxLcnInterceptor txLcnInterceptor(@Autowired DTXLogicWeaver dtxLogicWeaver) {
+        TxLcnInterceptor txLcnInterceptor = new TxLcnInterceptor(dtxLogicWeaver);
+        Properties properties = new Properties();
+        properties.setProperty(Transactions.DTX_TYPE, Transactions.LCN);
+        properties.setProperty(Transactions.DTX_PROPAGATION, "REQUIRED");
+        txLcnInterceptor.setTransactionAttributes(properties);
+        return txLcnInterceptor;
+    }
+
+}

+ 31 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/ConfigBean.java

@@ -0,0 +1,31 @@
+package com.sptg.common.core.cfgbeans;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * title: ConfigBean
+ * package: com.sptg.common.core.cfgbeans
+ * description: 基本配置类
+ *      EnableAsync :   开启异步注解
+ *                  
+ *            
+ */
+@Configuration
+@EnableAsync
+public class ConfigBean {
+
+    /**
+     * 参数绑定工具
+     *      使用 @ConfigurationProperties(prefix = "") 初始化参数
+     * @return PropertySourcesPlaceholderConfigurer
+     */
+    @Bean
+    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
+        return new PropertySourcesPlaceholderConfigurer();
+    }
+
+
+}

+ 26 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/GlobalConfigBean.java

@@ -0,0 +1,26 @@
+package com.sptg.common.core.cfgbeans;
+
+import com.sptg.common.core.handler.GlobalExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * title: GlobalConfigBean
+ * package: com.sptg.common.core.cfgbeans
+ * description: 全局配置
+ *                  
+ *                
+ */
+@Configuration
+public class GlobalConfigBean {
+
+    /**
+     * 全局异常处理器
+     * @return GlobalExceptionHandler
+     */
+    @Bean
+    public GlobalExceptionHandler globalExceptionHandler(){
+        return new GlobalExceptionHandler();
+    }
+
+}

+ 36 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/RedisTemplateConfigBean.java

@@ -0,0 +1,36 @@
+package com.sptg.common.core.cfgbeans;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.jedis.JedisConnection;
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+
+
+/**
+ * title: RedisTemplateConfigBean
+ * package: com.sptg.common.core.cfgbeans
+ * description: Redis配置类
+ *                  
+ *               
+ */
+@EnableCaching
+@Configuration
+@ConditionalOnClass({JedisConnection.class, RedisOperations.class, RedisProperties.Jedis.class})
+public class RedisTemplateConfigBean {
+
+    @Bean(name = "redisTemplate")
+    @ConditionalOnMissingBean(value = RedisTemplate.class)
+    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(redisConnectionFactory);
+        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
+        return template;
+    }
+}

+ 46 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/cfgbeans/RestTemplateConfigBean.java

@@ -0,0 +1,46 @@
+package com.sptg.common.core.cfgbeans;
+
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * title: RestTemplateConfigBean
+ * package: com.sptg.common.core.cfgbeans
+ * description: RestTemplate配置类
+ *                  
+ *               
+ */
+@Configuration
+public class RestTemplateConfigBean {
+
+    /**
+     * 功能描述:    开启负载均衡,仅限调用内部接口使用
+     *      提供了多种便捷访问远程 Http 服务的方法
+     *      是一种简单便捷的访问 RestFull 服务模板类
+     *      是 Spring 提供的用于访问 Rest 服务的客户端模板工具集
+     * @return RestTemplate
+     *                  
+     *                       
+     */
+    @Bean(name = "lbRestTemplate")
+    @LoadBalanced
+    public RestTemplate lbRestTemplate(){
+        return new RestTemplate();
+    }
+
+    /**
+     * 功能描述:    可调用外部接口
+     *      提供了多种便捷访问远程 Http 服务的方法
+     *      是一种简单便捷的访问 RestFull 服务模板类
+     *      是 Spring 提供的用于访问 Rest 服务的客户端模板工具集
+     * @return RestTemplate
+     *                  
+     *                       
+     */
+    @Bean(name = "restTemplate")
+    public RestTemplate restTemplate(){
+        return new RestTemplate();
+    }
+}

+ 54 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/CommonConstant.java

@@ -0,0 +1,54 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: CommonConstant
+ * package: com.sptg.common.core.constant
+ * description: 常用常量
+ *                  
+ *                
+ */
+public interface CommonConstant {
+
+    /**
+     * 空字符串
+     */
+    String EMPTY = "";
+
+    /**
+     * 隐藏
+     */
+    String HIDE = "******";
+
+    /**
+     * utf-8
+     */
+    String UTF_8 = "UTF-8";
+
+    /**
+     * localhost
+     */
+    String LOCALHOST = "localhost";
+
+    /**
+     * 重定向到退出页面
+     */
+    String REDIRECT_LOGOUT = "redirect:/permissions/authentication/logout";
+
+    /**
+     * 字符串 1
+     *
+     */
+    String ONE = "1";
+
+    /**
+     * 字符串 2
+     *
+     */
+    String TWO = "2";
+
+    /**
+     * 字符串 3
+     *
+     */
+    String THREE = "3";
+}

+ 22 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/DateFormatConstant.java

@@ -0,0 +1,22 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: DateFormatConstant
+ * package: com.sptg.common.core.constant
+ * description: 常用日期格式常量
+ *
+ *                  
+ *                 
+ */
+public interface DateFormatConstant {
+
+    /**
+     * 年月日 时分秒
+     */
+    String DEFAULT = "yyyy-MM-dd hh:mm:ss";
+
+    /**
+     * 年月日 数字
+     */
+    String YYYY_MM_DD_NUMBER = "yyyyMMdd";
+}

+ 74 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/HttpConstant.java

@@ -0,0 +1,74 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: HttpConstant
+ * package: com.sptg.common.core.constant
+ * description: Http常量
+ *                  
+ *                
+ */
+public interface HttpConstant {
+
+    /**
+     * 未知
+     */
+    String UNKNOWN = "unknown";
+
+    /**
+     * 请求头:可获取到Ip信息
+     */
+    String[] IP_HEADER_ARRAY = {
+            "X-Requested-For",
+            "X-Forwarded-For",
+            "Proxy-Client-IP",
+            "WL-Proxy-Client-IP",
+            "HTTP_CLIENT_IP",
+            "HTTP_X_FORWARDED_FOR"
+    };
+
+    /**
+     * 请求头:可获取到用户代理相关信息
+     */
+    String USER_AGENT_HEADER = "user-agent";
+
+    /**
+     * 请求头:访问令牌
+     */
+    String ACCESS_TOKEN = "access-token";
+
+    /**
+     * Cookie:记住我
+     */
+    String REMEMBER_ME = "rememberMe";
+
+    /**
+     * 请求头:数据签名
+     */
+    String DATA_SIGN = "data-sign";
+
+    /**
+     * 请求头:时间戳
+     */
+    String TIME_STAMP = "time-stamp";
+
+    /**
+     * logo 图标
+     */
+    String LOGO_ICON = "favicon.ico";
+
+    /**
+     * content-type
+     */
+    String APPLICATION_JSON = "application/json";
+
+    /**
+     * content-type
+     */
+    String APPLICATION_JSON_UTF8 = "application/json;charset=utf-8";
+
+    /**
+     * content-type
+     */
+    String TEXT_PLAIN = "text/plain;charset=utf-8";
+
+}

+ 57 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/OperationConstant.java

@@ -0,0 +1,57 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: OperationConstant
+ * package: com.sptg.common.core.constant
+ * description: 操作常量
+ *                  
+ *                
+ */
+public interface OperationConstant {
+
+    /**
+     * 表示放入垃圾箱
+     */
+    int MINUS_TWO = -2;
+
+    /**
+     * 通常表示删除或已结束
+     */
+    int MINUS_ONE = -1;
+
+    /**
+     * 通常表示默认的意思
+     */
+    int ZERO = 0;
+
+    /**
+     * 通常表示是的意思
+     */
+    int ONE = 1;
+
+    /**
+     * 通常表示非的意思
+     */
+    int TWO = 2;
+
+    /**
+     * 选项3
+     */
+    int THREE = 3;
+
+    /**
+     * 选项4
+     */
+    int FOUR = 4;
+
+    /**
+     * 选项5
+     */
+    int FIVE = 5;
+
+    /**
+     * 选项6
+     */
+    int SIX = 6;
+
+}

+ 77 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/SymbolConstant.java

@@ -0,0 +1,77 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: SymbolConstant
+ * package: com.sptg.common.core.constant
+ * description: 标点符号常量
+ *
+ *
+ */
+public interface SymbolConstant {
+
+    /**
+     * 逗号
+     */
+    String COMMA = ",";
+
+    /**
+     * 等于号
+     */
+    String BE_EQUAL_TO = "=";
+
+    /**
+     * And
+     */
+    String AND = "&";
+
+    /**
+     * 冒号
+     */
+    String COLON = ":";
+
+    /**
+     * 反斜杠
+     */
+    String BACK_SLASH = "/";
+
+    /**
+     * 双斜线
+     */
+    String DOUBLE_SLASH = "//";
+
+    /**
+     * 百分号
+     */
+    String PER_CENT = "%";
+
+    /**
+     * 星号
+     */
+    String ASTERISK = "*";
+
+    /**
+     * 英文字母
+     */
+    String A_NO = "A";
+
+    /**
+     * 英文字母
+     */
+    String B_NO = "B";
+
+    /**
+     * 英文字母
+     */
+    String SC_NO = "SC";
+
+    /**
+     * 英文字母
+     */
+    String GGW_NO = "LO";
+
+    /**
+     * 下划线
+     */
+    String UNDERLINE = "_";
+
+}

+ 37 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/SysLogConstant.java

@@ -0,0 +1,37 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: SysLogConstant
+ * package: com.sptg.common.core.constant
+ * description: 系统日志常量
+ *
+ *                
+ *                 
+ */
+public interface SysLogConstant {
+    /**
+     * 新增事件
+     */
+    int ADD_EVENT=0;
+    /**
+     * 删除事件
+     */
+    int DELETE_EVENT=1;
+    /**
+     * 修改事件
+     */
+    int ALTER_EVENT=2;
+    /**
+     * 登录事件
+     */
+    int LOGIN_EVENT=3;
+    /**
+     * 退出登录事件
+     */
+    int OUT_LOGIN_EVENT=4;
+    /**
+     * 关联事件
+     */
+    int RELATE_EVENT=5;
+
+}

+ 55 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/constant/UserFlagConstant.java

@@ -0,0 +1,55 @@
+package com.sptg.common.core.constant;
+
+/**
+ * title: UserFlagConstant
+ * package: com.sptg.estate.api.constant
+ * description:
+ *
+ *
+ *
+ */
+public interface UserFlagConstant {
+
+    /**
+     * 服务人员标识
+     */
+    String SERVER_USER_FLAG = "s_";
+
+    /**
+     * 住户标识
+     */
+    String USER_FLAG = "u_";
+
+    /**
+     * 管理员标记
+     */
+    String ADMIN_USER_FLAG = "a_";
+
+    /**
+     * 设备管理机账号
+     */
+    String DEVICE_MANAGE_FLAG = "d_";
+
+    /**
+     * 测试账号表示
+     */
+    String TEST_USER_FLAG = "t_";
+
+    /**
+     * 管理员数字标记
+     */
+    String ADMIN_USER_NUMBER_FLAG = "101";
+
+    /**
+     * 住户数字标记
+     */
+    String USER_NUMBER_FLAG = "102";
+
+    /**
+     * 服务员数字标记
+     */
+    String SERVER_USER_NUMBER_FLAG = "103";
+
+    String GUEST_FLAG = "104";
+
+}

+ 46 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/BaseEntity.java

@@ -0,0 +1,46 @@
+package com.sptg.common.core.entity;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.enums.IdType;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * title: BaseEntity
+ * package: com.sptg.common.core.entity
+ * description: 实体类公共父类
+ *
+ *                  
+ *                
+ */
+@Getter
+@Setter
+@JsonIgnoreProperties(ignoreUnknown = true)
+public abstract class BaseEntity implements java.io.Serializable {
+
+    /**
+     * 主键
+     */
+    @TableId(value = "l_id",type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 删除标记:{ -1:已删除,0:正常 }
+     */
+    @TableField(value = "i_status")
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "t_create_date")
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date createDate;
+
+
+}

+ 51 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/DispatchTask.java

@@ -0,0 +1,51 @@
+package com.sptg.common.core.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * title: DispatchTask
+ * package: com.sptg.common.core.entity
+ * description: 下发任务
+ *
+ *
+ *
+ */
+@Setter
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class DispatchTask {
+
+    /**
+     * 小区Id
+     */
+    private Long xqId;
+
+    /**
+     * 单元Id
+     */
+    private Long unitId;
+
+    /**
+     * 设备序列号
+     */
+    private String serialNumber;
+
+    /**
+     * 设备厂商
+     */
+    private String factory;
+
+    /**
+     * 数据
+     */
+    private Object data;
+
+    public DispatchTask(String serialNumber, Object data) {
+        this.serialNumber = serialNumber;
+        this.data = data;
+    }
+}

+ 75 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/PublishTask.java

@@ -0,0 +1,75 @@
+package com.sptg.common.core.entity;
+
+import com.sptg.common.core.enums.Instruct;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ *            
+ *                
+ * description: 推送任务
+ */
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class PublishTask {
+
+    /**
+     * 任务Id
+     */
+    private Long taskId;
+
+    /**
+     * 推送指令
+     */
+    private Instruct instruct;
+
+    /**
+     * 推送内容
+     */
+    private Object body;
+
+    /**
+     * 设备Id列表
+     */
+    private List<Long> deviceIdList;
+
+    /**
+     * 回调地址
+     */
+    @Setter
+    private String callBackUrl;
+
+    /**
+     * 任务类型:{ 1:广告,2:策略,3:公告 }
+     */
+    @Setter
+    private Integer taskType;
+
+    /**
+     * 是否过滤阈值:{ 1:启用阈值配置,2:禁用阈值配置 }
+     */
+    @Setter
+    private Integer enableThreshold;
+
+    @Setter
+    private Long orgId;
+
+    /**
+     *
+     * @param taskId 任务Id
+     * @param instruct 推送指令
+     * @param body 推送内容
+     * @param deviceIdList 设备Id列表
+     */
+    public PublishTask(Long taskId, Instruct instruct, Object body, List<Long> deviceIdList) {
+        this.taskId = taskId;
+        this.instruct = instruct;
+        this.body = body;
+        this.deviceIdList = deviceIdList;
+    }
+}

+ 86 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/entity/PublishTaskResult.java

@@ -0,0 +1,86 @@
+package com.sptg.common.core.entity;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.enums.IdType;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: PublishTaskResult
+ * package: com.sptg.common.core.entity
+ * description: 推送结果
+ *
+ *
+ */
+@Getter
+@Setter
+public class PublishTaskResult implements java.io.Serializable {
+
+    /**
+     * 主键
+     */
+    @TableId(value = "l_id",type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 任务Id
+     */
+    @TableField(value = "l_task_id")
+    private Long taskId;
+
+    /**
+     * 设备Id
+     */
+    @TableField(value = "l_device_id")
+    private Long deviceId;
+
+    /**
+     * 设备名称
+     */
+    @TableField(value = "s_device_name")
+    private String deviceName;
+
+    /**
+     * 设备序列号
+     */
+    @TableField(value = "s_serial_number")
+    private String serialNumber;
+
+    /**
+     * 设备安装路径
+     */
+    @TableField(value = "s_install_path")
+    private String installPath;
+
+    /**
+     * 小区名称
+     */
+    @TableField(value = "s_xq_name")
+    private String xqName;
+
+    /**
+     * 单元名称
+     */
+    @TableField(value = "s_dy_name")
+    private String dyName;
+
+    /**
+     * 推送状态:{ 0:未推送, 1:推送成功,2:推送失败,3:推送中 }
+     */
+    @TableField(value = "i_push_status")
+    private Integer pushStatus;
+
+    /**
+     * 备注,推送失败时,此字段有值
+     */
+    @TableField(value = "s_remark")
+    private String remark;
+
+    /**
+     * 删除标记:{ -1:已删除,0:正常 }
+     */
+    @TableField(value = "i_status")
+    private Integer status;
+
+}

+ 111 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/DeviceInstruct.java

@@ -0,0 +1,111 @@
+package com.sptg.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * title: DeviceInstruct
+ * package: com.sptg.common.core.enums
+ * description: 设备指令
+ *
+ *                  
+ *                
+ */
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public enum  DeviceInstruct {
+
+    /**
+     * 开门指令
+     */
+    open_door("open_door","开门"),
+
+    /**
+     * 重启
+     */
+    restart("restart","重启"),
+
+    /**
+     * 获取数据
+     */
+    pull_data("pull_data","获取数据"),
+
+    /**
+     * 添加开门密码
+     */
+    add_open_door_pwd("add_open_door_pwd","添加开门密码"),
+
+    /**
+     * 删除开门密码
+     */
+    del_open_door_pwd("del_open_door_pwd","删除开门密码"),
+
+    /**
+     * 添加人脸
+     */
+    add_user_face("add_user_face","添加人脸"),
+
+    /**
+     * 添加门禁卡
+     */
+    add_open_door_card("add_open_door_card","添加门禁卡"),
+
+    /**
+     * 删除门禁卡
+     */
+    del_open_door_card("del_open_door_card","删除门禁卡"),
+
+    /**
+     * 修改设备信息
+     */
+    update_device_info("update_device_info","修改设备信息"),
+
+    /**
+     * 添加视频对讲账号
+     */
+    add_video_call_account("add_video_call_account","添加视频对讲账号"),
+
+    /**
+     * 紧急疏散
+     */
+    evacuate("evacuate","紧急疏散"),
+
+    /**
+     * 紧急疏散
+     */
+    cancel_evacuate("cancel_evacuate","取消紧急疏散"),
+
+    /**
+     * 更新app包指令
+     */
+    update_app_package("update_app_package","在线升级"),
+
+    /**
+     * 格式化数据
+     */
+    format_data("format_data","格式化数据"),
+
+    /**
+     * 同步广告数据
+     */
+    sync_ad("sync_ad_data","格式化数据"),
+
+    /**
+     * 同步屏保数据
+     */
+    sync_pb("sync_pb_data","格式化数据"),
+
+    /**
+     * 同步公告数据
+     */
+    sync_notice("sync_notice_data","格式化数据");
+
+    private String code;
+
+    @Setter
+    private Object data;
+
+}

+ 118 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/Instruct.java

@@ -0,0 +1,118 @@
+package com.sptg.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.apache.commons.lang3.EnumUtils;
+
+import java.util.List;
+
+/**
+ *
+ *
+ * description: 指令
+ */
+@Getter
+@AllArgsConstructor
+public enum Instruct {
+
+    //  临时指令:消息在指定时间内没有被消费,将自动清除
+    /* ############################################################################################################## */
+
+    open_door("open_door",Instruct.TRANSIENT_EXCHANGE,"远程开门"),
+    restart("restart",Instruct.TRANSIENT_EXCHANGE,"重启设备"),
+    check_online("check_online",Instruct.TRANSIENT_EXCHANGE,"检测设备在线"),
+
+    //  持久指令:消息在队列中存储,等待客户端消费后清除
+    /* ############################################################################################################## */
+
+    pull_data("pull_data",Instruct.PERSISTENT_EXCHANGE,"重新拉取数据"),
+    add_open_door_pwd("add_open_door_pwd",Instruct.PERSISTENT_EXCHANGE,"添加开门密码"),
+    del_open_door_pwd("del_open_door_pwd",Instruct.PERSISTENT_EXCHANGE,"删除开门密码"),
+    add_user_face("add_user_face",Instruct.PERSISTENT_EXCHANGE,"设置用户人脸"),
+    update_user_face("update_user_face",Instruct.PERSISTENT_EXCHANGE,"更新用户人脸"),
+    delete_user_face("delete_user_face",Instruct.PERSISTENT_EXCHANGE,"删除用户人脸"),
+    delete_user("delete_user",Instruct.PERSISTENT_EXCHANGE,"删除用户"),
+    add_user_face_batch("add_user_face_batch",Instruct.PERSISTENT_EXCHANGE,"批量设置人脸"),
+    delete_user_face_batch("delete_user_face_batch",Instruct.PERSISTENT_EXCHANGE,"批量删除人脸"),
+    add_open_door_card("add_open_door_card",Instruct.PERSISTENT_EXCHANGE,"添加门禁卡"),
+    del_open_door_card("del_open_door_card",Instruct.PERSISTENT_EXCHANGE,"删除门禁卡"),
+    add_open_door_card_batch("add_open_door_card_batch",Instruct.PERSISTENT_EXCHANGE,"批量添加门禁卡"),
+    delete_open_door_card_batch("del_open_door_card_batch",Instruct.PERSISTENT_EXCHANGE,"批量删除门禁卡"),
+    update_device_info("update_device_info",Instruct.PERSISTENT_EXCHANGE,"更新设备信息"),
+    add_video_call_account("add_video_call_account",Instruct.PERSISTENT_EXCHANGE,"添加视频对讲账号"),
+    evacuate("evacuate",Instruct.PERSISTENT_EXCHANGE,"开启紧急疏散模式"),
+    cancel_evacuate("cancel_evacuate",Instruct.PERSISTENT_EXCHANGE,"解除紧急疏散模式"),
+    update_app_package("update_app_package",Instruct.PERSISTENT_EXCHANGE,"更新app包"),
+    update_restore_app_package("update_restore_app_package",Instruct.PERSISTENT_EXCHANGE,"更新设备恢复版app包"),
+    format_data("format_data",Instruct.PERSISTENT_EXCHANGE,"格式化数据"),
+    format_user_face("format_user_face",Instruct.PERSISTENT_EXCHANGE,"格式化住户人脸数据"),
+    format_server_face("format_server_face",Instruct.PERSISTENT_EXCHANGE,"格式化服务人员人脸数据"),
+    format_card_data("format_card_data",Instruct.PERSISTENT_EXCHANGE,"格式化门禁卡数据"),
+    format_face_advert("format_face_advert",Instruct.PERSISTENT_EXCHANGE,"格式化人脸广告数据"),
+    format_leisure_advert("format_leisure_advert",Instruct.PERSISTENT_EXCHANGE,"格式化轮播广告数据"),
+    format_notice_data("format_notice_data",Instruct.PERSISTENT_EXCHANGE,"格式化公告数据"),
+    format_open_pwd("format_open_pwd",Instruct.PERSISTENT_EXCHANGE,"格式化访客密码数据"),
+    sync_face_advert("sync_face_advert",Instruct.PERSISTENT_EXCHANGE,"同步人脸广告数据"),
+    sync_leisure_advert("sync_leisure_advert",Instruct.PERSISTENT_EXCHANGE,"同步轮播广告数据"),
+    sync_notice_data("sync_notice_data",Instruct.PERSISTENT_EXCHANGE,"同步公告数据"),
+    sync_user_face("sync_user_face",Instruct.PERSISTENT_EXCHANGE,"同步住户人脸数据"),
+    sync_server_face("sync_server_face",Instruct.PERSISTENT_EXCHANGE,"同步服务人员人脸数据"),
+    sync_card_data("sync_card_data",Instruct.PERSISTENT_EXCHANGE,"同步门禁卡数据"),
+    sync_open_pwd("sync_open_pwd",Instruct.PERSISTENT_EXCHANGE,"同步访客密码数据"),
+    add_face_advert_task("add_face_advert_task",Instruct.PERSISTENT_EXCHANGE,"添加人脸广告任务"),
+    add_leisure_advert_task("add_leisure_advert_task",Instruct.PERSISTENT_EXCHANGE,"添加轮播广告任务"),
+    add_notice("add_notice",Instruct.PERSISTENT_EXCHANGE,"添加设备公告"),
+    delete_notice("delete_notice",Instruct.PERSISTENT_EXCHANGE,"删除设备公告"),
+    add_strategy_task("add_strategy_task",Instruct.PERSISTENT_EXCHANGE,"添加策略任务"),
+    delete_advert("delete_advert",Instruct.PERSISTENT_EXCHANGE,"删除设备广告"),
+    restore("restore",Instruct.PERSISTENT_EXCHANGE,"远程恢复版本"),
+//    disable_device("disable_device",Instruct.PERSISTENT_EXCHANGE,"禁用设备"),
+//    disable_keyboard("disable_keyboard",Instruct.PERSISTENT_EXCHANGE,"禁用设备按键"),
+//    disable_face_open_door("disable_face_open_door",Instruct.PERSISTENT_EXCHANGE,"禁用刷脸开门功能"),
+//    disable_card_open_door("disable_card_open_door",Instruct.PERSISTENT_EXCHANGE,"禁用刷卡开门功能"),
+//    disable_pwd_open_door("disable_pwd_open_door",Instruct.PERSISTENT_EXCHANGE,"禁用密码开门功能"),
+//    disable_remote_open_door("disable_remote_open_door",Instruct.PERSISTENT_EXCHANGE,"禁用远程开门功能"),
+//    disable_ad_play("disable_ad_play",Instruct.PERSISTENT_EXCHANGE,"禁用广告播放功能"),
+    remote_update_device_setting("remote_update_device_setting",Instruct.PERSISTENT_EXCHANGE,"远程更新配置"),
+    remote_info_obtain("remote_info_obtain",Instruct.PERSISTENT_EXCHANGE,"远程信息获取"),
+    ;
+
+    /**
+     * 临时交换机
+     */
+    private static final String TRANSIENT_EXCHANGE = "TRANSIENT_EXCHANGE";
+
+    /**
+     * 持久交换机
+     */
+    private static final String PERSISTENT_EXCHANGE = "PERSISTENT_EXCHANGE";
+
+    /**
+     * 指令
+     */
+    private String code;
+
+    /**
+     * 交换机
+     */
+    private String exchangeName;
+
+    /**
+     * 描述
+     */
+    private String describe;
+
+    public static Instruct getByCode(String code){
+        List<Instruct> enumList = EnumUtils.getEnumList(Instruct.class);
+        if(enumList != null){
+            for (Instruct instruct : enumList){
+                if(instruct.getCode().equals(code)){
+                    return instruct;
+                }
+            }
+            return null;
+        }else{
+            return null;
+        }
+    }
+}

+ 57 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/enums/InstructDH.java

@@ -0,0 +1,57 @@
+package com.sptg.common.core.enums;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ *
+ *
+ * description: 指令
+ */
+@Getter
+@Setter
+public class InstructDH {
+
+    /**
+     * 临时交换机
+     */
+    private static final String TRANSIENT_EXCHANGE_DH = "TRANSIENT_EXCHANGE_DH";
+
+    /**
+     * 持久交换机
+     */
+    private static final String PERSISTENT_EXCHANGE_DH = "PERSISTENT_EXCHANGE_DH";
+
+    /**
+     * 指令
+     */
+    private String code;
+
+    /**
+     * 指令
+     */
+    private String batchCode;
+
+    /**
+     * 交换机
+     */
+    private String exchangeName;
+
+    /**
+     * 描述
+     */
+    private String describe;
+
+    public String getDHExchange(String exchangeName) {
+        if (StringUtils.isNotBlank(exchangeName)) {
+            if (exchangeName.equals("TRANSIENT_EXCHANGE")) {
+                return TRANSIENT_EXCHANGE_DH;
+            } else if (exchangeName.equals("PERSISTENT_EXCHANGE")) {
+                return PERSISTENT_EXCHANGE_DH;
+            }
+        }
+        return exchangeName;
+    }
+
+}

+ 27 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/exception/ImportExcelException.java

@@ -0,0 +1,27 @@
+package com.sptg.common.core.exception;
+
+import com.sptg.common.core.util.JsonUtils;
+import lombok.Getter;
+
+/**
+ * @author WFT
+ * @date 2020/5/29
+ * description:导入表格异常
+ */
+@Getter
+public class ImportExcelException extends Exception {
+
+    /**
+     * 错误数据
+     */
+    private String data;
+
+    public ImportExcelException(String message, Object data) {
+        super(message);
+        this.data = JsonUtils.objectToJson(data);
+    }
+
+    public ImportExcelException(String message) {
+        super(message);
+    }
+}

+ 64 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/CharlesRequestInterceptor.java

@@ -0,0 +1,64 @@
+package com.sptg.common.core.feign;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.util.*;
+
+public class CharlesRequestInterceptor implements RequestInterceptor {
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Override
+    public void apply(RequestTemplate template) {
+        // feign 不支持 GET 方法传 POJO, json body转query
+        if (template.method().equals("GET") && template.body() != null) {
+            try {
+                JsonNode jsonNode = objectMapper.readTree(template.body());
+                template.body(null);
+
+                Map<String, Collection<String>> queries = new HashMap<>();
+                buildQuery(jsonNode, "", queries);
+                template.queries(queries);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
+        if (!jsonNode.isContainerNode()) {   // 叶子节点
+            if (jsonNode.isNull()) {
+                return;
+            }
+            Collection<String> values = queries.get(path);
+            if (null == values) {
+                values = new ArrayList<>();
+                queries.put(path, values);
+            }
+            values.add(jsonNode.asText());
+            return;
+        }
+        if (jsonNode.isArray()) {   // 数组节点
+            Iterator<JsonNode> it = jsonNode.elements();
+            while (it.hasNext()) {
+                buildQuery(it.next(), path, queries);
+            }
+        } else {
+            Iterator<Map.Entry<String, JsonNode>> it = jsonNode.fields();
+            while (it.hasNext()) {
+                Map.Entry<String, JsonNode> entry = it.next();
+                if (StringUtils.hasText(path)) {
+                    buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
+                } else {  // 根节点
+                    buildQuery(entry.getValue(), entry.getKey(), queries);
+                }
+            }
+        }
+    }
+}

+ 26 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/FeignAutoConfiguration.java

@@ -0,0 +1,26 @@
+package com.sptg.common.core.feign;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import feign.Logger;
+import feign.RequestInterceptor;
+
+@ConditionalOnClass(FeignClient.class)
+@Configuration
+public class FeignAutoConfiguration {
+	@Bean
+    public RequestInterceptor gatewayRequestInterceptor() {
+        return new GatewayRequestInterceptor();
+    }
+	@Bean
+	public RequestInterceptor charlesRequestInterceptor() {
+	    return new CharlesRequestInterceptor();
+	}
+	@Bean
+	public Logger.Level feignLevel() {
+        return Logger.Level.FULL;
+    }
+}

+ 13 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/feign/GatewayRequestInterceptor.java

@@ -0,0 +1,13 @@
+package com.sptg.common.core.feign;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+
+public class GatewayRequestInterceptor implements RequestInterceptor{
+
+	@Override
+	public void apply(RequestTemplate template) {
+		String url=template.url();
+		System.out.println(url);
+	}
+}

+ 274 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/filter/EncryptionFilter.java

@@ -0,0 +1,274 @@
+package com.sptg.common.core.filter;
+
+import com.sptg.common.core.constant.HttpConstant;
+import com.sptg.common.core.util.AesEncryptionUtil;
+import com.sptg.common.core.util.WebUtils;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * title: EncryptionFilter
+ * package: com.sptg.gateway.filter
+ * description: 加解密过滤器
+ *
+ *                  
+ *               
+ */
+@Slf4j
+public class EncryptionFilter implements Filter {
+
+    /**
+     * 不需要拦截的请求列表
+     */
+    @Setter
+    private List<String> excludeList;
+
+    @Override
+    public void init(FilterConfig filterConfig){
+
+    }
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        String uri = request.getRequestURI();
+        //  过滤浏览器自动请求logo
+        if (uri.endsWith(HttpConstant.LOGO_ICON)) {
+            return;
+        }
+        //  过滤不需要拦截的请求
+        if (excludeList.contains(uri)){
+            chain.doFilter(servletRequest,servletResponse);
+            return;
+        }
+        //  判断请求体是否为json
+        if (!HttpConstant.APPLICATION_JSON.equals(request.getContentType()) &&
+                !HttpConstant.APPLICATION_JSON_UTF8.equals(request.getContentType())){
+            OutputStream out = servletResponse.getOutputStream();
+            out.write("请求头ContentType需为json".getBytes());
+            return;
+        }
+//        log.info("当前毫秒值:" + System.currentTimeMillis());
+//        //  获取时间戳(密钥)
+//        String secretKey = request.getHeader(HttpConstant.TIME_STAMP);
+//        if (StringUtils.isEmpty(secretKey)){
+//            return;
+//        }
+        //  获取签名
+        String sign = request.getHeader(HttpConstant.DATA_SIGN);
+        if (StringUtils.isEmpty(sign)){
+            return;
+        }
+        //  获取请求报文
+        String requestBody = WebUtils.getRequestBody(request);
+//        log.info("密文:" + requestBody);
+//        try{
+//            //  对报文进行解密
+//            requestBody = AesEncryptionUtil.aesDecrypt(secretKey, requestBody);
+//        }catch (Exception e){
+//            log.debug("解密失败");
+//            return;
+//        }
+        //  将解密后的报文进行Md5,校验签名
+        String md5Body = DigestUtils.md5Hex(requestBody);
+        if (!sign.equals(md5Body)){
+            OutputStream out = servletResponse.getOutputStream();
+            out.write("请求头缺少签名参数".getBytes());
+            return;
+        }
+//        log.info("明文:" + requestBody);
+//        log.info("当前毫秒值:" + System.currentTimeMillis());
+        //  调用接口
+        HttpServletResponse response = (HttpServletResponse)servletResponse;
+        WrapperResponse wrapperResponse = new WrapperResponse(response);
+        chain.doFilter(new WrapperRequest(request,requestBody),wrapperResponse);
+        //  获取响应体
+        String responseBody = new String(wrapperResponse.getResponseBody(), StandardCharsets.UTF_8);
+        try {
+//            加密密钥
+//            secretKey =  String.valueOf(System.currentTimeMillis());
+//            response.setHeader(HttpConstant.TIME_STAMP,secretKey);
+            //  数据签名
+            response.setHeader(HttpConstant.DATA_SIGN,DigestUtils.md5Hex(responseBody));
+//            //  数据加密
+//            String data = AesEncryptionUtil.aesEncryption(secretKey, responseBody);
+            WebUtils.writeResponse(response,responseBody,HttpConstant.TEXT_PLAIN);
+        }catch (Exception e){
+            log.error("数据加密异常",e.getMessage());
+        }
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+
+    /**
+     * 功能描述: Response 封装类
+     *                  
+     *                     
+     */
+    public class WrapperResponse extends HttpServletResponseWrapper {
+
+        /**
+         * 真正存储数据的流
+         */
+        private final ByteArrayOutputStream buffer;
+        private final ServletOutputStream outputStream;
+        private final PrintWriter printWriter;
+
+        /**
+         * Constructs a response adaptor wrapping the given response.
+         * @throws IllegalArgumentException if the response is null
+         */
+        private WrapperResponse(HttpServletResponse response) {
+            super(response);
+            buffer = new ByteArrayOutputStream();
+            printWriter = new PrintWriter(new OutputStreamWriter(buffer,StandardCharsets.UTF_8));
+            outputStream = new ServletOutputStream(){
+
+                @Override
+                public void write(int b) {
+                    buffer.write(b);
+                }
+
+                @Override
+                public void write(byte[] b, int off, int len){
+                    buffer.write(b, off, len);
+                }
+
+                @Override
+                public boolean isReady() {
+                    return false;
+                }
+
+                @Override
+                public void setWriteListener(WriteListener writeListener) {
+
+                }
+            };
+        }
+
+        @Override
+        public ServletOutputStream getOutputStream(){
+            return this.outputStream;
+        }
+
+        @Override
+        public PrintWriter getWriter(){
+            return this.printWriter;
+        }
+
+        @Override
+        public void flushBuffer() throws IOException {
+            if (null != this.outputStream){
+                this.outputStream.flush();
+            }
+            if (null != this.printWriter){
+                this.printWriter.flush();
+            }
+        }
+
+        @Override
+        public void reset() {
+            this.buffer.reset();
+        }
+
+        /**
+         * 功能描述: 获取响应体的字节数组
+         *                  
+         *                     
+         */
+        private byte[] getResponseBody()throws IOException{
+            this.flushBuffer();
+            return this.buffer.toByteArray();
+        }
+    }
+
+    /**
+     * 功能描述: Request 封装类
+     *                  
+     *                     
+     */
+    public class WrapperRequest extends HttpServletRequestWrapper {
+
+        /**
+         * 请求报文
+         */
+        private final String requestBody;
+        private final HttpServletRequest request;
+
+        /**
+         * Constructs a request object wrapping the given request.
+         * @param request The request to wrap
+         * @param requestBody 请求报文
+         * @throws IllegalArgumentException if the request is null
+         */
+        private WrapperRequest(HttpServletRequest request,String requestBody) {
+            super(request);
+            this.request = request;
+            this.requestBody = requestBody;
+        }
+
+        @Override
+        public int getContentLength() {
+            return this.requestBody.length();
+        }
+
+        @Override
+        public BufferedReader getReader(){
+            return new BufferedReader(new StringReader(this.requestBody));
+        }
+
+        @Override
+        public ServletInputStream getInputStream() throws IOException {
+            return new ServletInputStream() {
+
+                private InputStream inputStream = new ByteArrayInputStream(requestBody.getBytes(request.getCharacterEncoding()));
+
+                @Override
+                public boolean isFinished() {
+                    return false;
+                }
+
+                @Override
+                public boolean isReady() {
+                    return false;
+                }
+
+                @Override
+                public void setReadListener(ReadListener listener) {
+
+                }
+
+                @Override
+                public int read() throws IOException {
+                    return this.inputStream.read();
+                }
+
+                @Override
+                public int read(byte[] buffer, int off, int len) throws IOException {
+                    if (null == buffer) {
+                        throw new NullPointerException();
+                    } else if (off < 0 || len < 0 || len > buffer.length - off) {
+                        throw new IndexOutOfBoundsException();
+                    } else if (len == 0) {
+                        return 0;
+                    }
+                    return this.inputStream.read(buffer, off, len);
+                }
+            };
+        }
+    }
+}

+ 80 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/handler/GlobalExceptionHandler.java

@@ -0,0 +1,80 @@
+package com.sptg.common.core.handler;
+
+import com.netflix.hystrix.exception.HystrixTimeoutException;
+import com.sptg.common.core.beans.ResultBean;
+import com.sptg.common.core.beans.ResultEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+/**
+ * title: GlobalExceptionHandler
+ * package: com.sptg.common.core.handler
+ * description: 全局异常处理器
+ *                  
+ *                
+ */
+@Slf4j
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    /**
+     * 捕获404异常
+     * @param e NoHandlerFoundException
+     * @return ResultBean
+     *                  
+     *                       
+     */
+    @ResponseBody
+    @ExceptionHandler(value = NoHandlerFoundException.class)
+    public ResultBean noHandlerFoundException(NoHandlerFoundException e){
+        return new ResultBean<>(ResultEnum.NOT_FIND,e.getMessage());
+    }
+
+    /**
+     * 捕获运行时异常
+     * @param e RuntimeException
+     * @return ResultBean
+     *                  
+     *                       
+     */
+    @ResponseBody
+    @ExceptionHandler(value = Exception.class)
+    public ResultBean runtimeException(Exception e){
+        log.error(e.getMessage(),e);
+        return new ResultBean<>(ResultEnum.ERROR,e.getMessage());
+    }
+
+    /**
+     * 功能描述: 捕获超时异常
+     * @param e HystrixTimeoutException
+     * @return ResultBean
+     *                  
+     * date:  2018/10/31 0:08
+     */
+    @ResponseBody
+    @ExceptionHandler(value = HystrixTimeoutException.class)
+    public ResultBean hystrixTimeoutException(HystrixTimeoutException e){
+        log.error(e.getMessage(),e);
+        return new ResultBean<>(ResultEnum.REQUEST_TIME_OUT);
+    }
+
+    /**
+     * 非法数据异常状态码
+     */
+    private final static String ILLEGAL_ARGUMENT_CODE = "400";
+
+    /**
+     * 捕获非法参数异常
+     * @param e 异常信息
+     * @return ResultBean
+     */
+    @ResponseBody
+    @ExceptionHandler(value = IllegalArgumentException.class)
+    public ResultBean illegalArgumentException(IllegalArgumentException e){
+        return new ResultBean(ILLEGAL_ARGUMENT_CODE,e.getMessage());
+    }
+
+}

+ 21 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/interfaces/VoidInterface.java

@@ -0,0 +1,21 @@
+package com.sptg.common.core.interfaces;
+
+/**
+ * title: VoidInterface
+ * package: com.sptg.common.core.interfaces
+ * description: 无返回值接口
+ *
+ *                  
+ *                 
+ */
+public interface VoidInterface<T> {
+
+    /**
+     * 功能描述:
+     * @param t 泛型对象
+     *                  
+     *                       
+     */
+    void run(T t);
+
+}

+ 39 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/I18Config.java

@@ -0,0 +1,39 @@
+package com.sptg.common.core.locale;
+
+import java.util.Locale;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+import org.springframework.web.servlet.i18n.SessionLocaleResolver;
+
+@Configuration
+@ComponentScan
+public class I18Config implements WebMvcConfigurer{
+    @Bean
+    public LocaleResolver localeResolver() {
+        SessionLocaleResolver slr = new SessionLocaleResolver();
+        slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
+        return slr;
+    }
+
+    @Bean
+    public LocaleChangeInterceptor localeChangeInterceptor() {
+        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
+        lci.setParamName("lang");
+        return lci;
+    }
+    @Bean
+    public MessageResourceInterceptor messageResourceInterceptor() {
+        return new MessageResourceInterceptor();
+    }
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(messageResourceInterceptor()).addPathPatterns("/**");
+        registry.addInterceptor(localeChangeInterceptor());
+    }
+}

+ 15 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/I18n.java

@@ -0,0 +1,15 @@
+package com.sptg.common.core.locale;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface I18n {
+	/**
+      * 国际化文件名
+     */
+    String value();
+}

+ 137 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/MessageResourceExtension.java

@@ -0,0 +1,137 @@
+package com.sptg.common.core.locale;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+/**
+ * @Autowired
+ * private MessageSource messageSource;
+ * #{hello}
+ * Locale locale = LocaleContextHolder.getLocale();
+ * messageSource.getMessage("world", null, locale)
+ *
+ */
+@Component("messageSource")
+public class MessageResourceExtension extends ResourceBundleMessageSource {
+	public final static String I18N_ATTRIBUTE = "i18n_attribute";
+	private final static String[] EMPTY_STRING=new String[0];
+	private ResourcePatternResolver resourcePatternResolver=new PathMatchingResourcePatternResolver();
+    /**
+     * 指定的国际化文件目录
+     */
+    @Value(value = "${spring.messages.dir:i18n}")
+    private String baseFolder;
+
+    /**
+     * 父MessageSource指定的国际化文件
+     */
+    @Value(value = "${spring.messages.basename:message}")
+    private String basename;
+
+    @PostConstruct
+    public void init() {
+        logger.info("init MessageResourceExtension...");
+        if (!StringUtils.isEmpty(baseFolder)) {
+            try {
+                this.setBasenames(getAllBaseNames(baseFolder));
+            } catch (IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+        ResourceBundleMessageSource parent = new ResourceBundleMessageSource();
+        parent.setBasename(basename);
+        this.setParentMessageSource(parent);
+    }
+
+    /**
+     * 获取文件夹下所有的国际化文件名
+     *
+     * @param folderName 文件名
+     * @return
+     * @throws IOException
+     */
+    private String[] getAllBaseNames(final String folderName) throws IOException {
+        URL url = Thread.currentThread().getContextClassLoader().getResource(folderName);
+        if (null == url) {
+           return EMPTY_STRING;
+        }
+        Set<String> baseNames=Collections.emptySet();
+        if (url.getProtocol().equalsIgnoreCase("file")) {
+            // 文件夹形式,用File获取资源路径
+            File file = new File(url.getFile());
+            if (file.exists() && file.isDirectory()) {
+                baseNames = Files.walk(file.toPath())
+                        .filter(path -> path.toFile().isFile())
+                        .map(Path::toString)
+                        .map(path -> path.substring(path.indexOf(folderName)))
+                        .map(this::getI18FileName)
+                        .distinct()
+                        .collect(Collectors.toSet());
+            } else {
+                logger.error("指定的baseFile不存在或者不是文件夹");
+            }
+        } else if (url.getProtocol().equalsIgnoreCase("jar")) {
+        	baseNames = new LinkedHashSet<String>();
+        	Resource[] metaInfResources = resourcePatternResolver.getResources("classpath*:"+folderName+"/*.properties");
+        	for(Resource r : metaInfResources){
+            	baseNames.add(folderName+"/"+getI18FileName(r.getFilename()));
+            }
+        }
+        return baseNames.toArray(EMPTY_STRING);
+    }
+    /**
+       * 把普通文件名转换成国际化文件名
+     */
+    private String getI18FileName(String filename) {
+        filename = filename.replace(".properties", "");
+        for (int i = 0; i < 2; i++) {
+            int index = filename.lastIndexOf("_");
+            if (index != -1) {
+                filename = filename.substring(0, index);
+            }
+        }
+        return filename.replace("\\", "/");
+    }
+    @Override
+    protected String resolveCodeWithoutArguments(String code, Locale locale) {
+        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+        if(attr==null) {
+        	return super.resolveCodeWithoutArguments(code,locale);
+        }
+        final String i18File = (String) attr.getAttribute(I18N_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
+        if (!StringUtils.isEmpty(i18File)) {
+            String basename = getBasenameSet().stream()
+                    .filter(name -> StringUtils.endsWithIgnoreCase(name, i18File))
+                    .findFirst().orElse(null);
+            if (!StringUtils.isEmpty(basename)) {
+                //得到指定的国际化文件资源
+                ResourceBundle bundle = getResourceBundle(basename, locale);
+                if (bundle != null) {
+                    return getStringOrNull(bundle, code);
+                }
+            }
+        }
+        return super.resolveCodeWithoutArguments(code,locale);
+    }
+}

+ 53 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/locale/MessageResourceInterceptor.java

@@ -0,0 +1,53 @@
+package com.sptg.common.core.locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.ModelAndView;
+ 
+public class MessageResourceInterceptor implements HandlerInterceptor{
+    @Override
+    public void postHandle(HttpServletRequest req, HttpServletResponse rep, Object handler, ModelAndView modelAndView) {
+        // 在方法中设置i18路径
+        if (null != req.getAttribute(MessageResourceExtension.I18N_ATTRIBUTE)) {
+            return;
+        }
+        if(!HandlerMethod.class.isInstance(handler)){
+        	return;
+        }
+        HandlerMethod method = (HandlerMethod) handler;
+        // 在method上注解了i18
+        I18n i18nMethod = method.getMethodAnnotation(I18n.class);
+        if (null != i18nMethod) {
+            req.setAttribute(MessageResourceExtension.I18N_ATTRIBUTE, i18nMethod.value());
+            return;
+        }
+        // 在Controller上注解了i18
+        I18n i18nController = method.getBeanType().getAnnotation(I18n.class);
+        if (null != i18nController) {
+            req.setAttribute(MessageResourceExtension.I18N_ATTRIBUTE, i18nController.value());
+            return;
+        }
+        req.setAttribute(MessageResourceExtension.I18N_ATTRIBUTE,"messages");
+        // 根据Controller名字设置i18
+        /*String controller = method.getBeanType().getName();
+        int index = controller.lastIndexOf(".");
+        if (index != -1) {
+            controller = controller.substring(index + 1, controller.length());
+        }
+        index = controller.toUpperCase().indexOf("CONTROLLER");
+        if (index != -1) {
+            controller = controller.substring(0, index);
+        }
+        req.setAttribute(MessageResourceExtension.I18N_ATTRIBUTE, controller);*/
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest req, HttpServletResponse rep, Object handler) {
+        // 在跳转到该方法先清除request中的国际化信息
+        req.removeAttribute(MessageResourceExtension.I18N_ATTRIBUTE);
+        return true;
+    }
+
+}

+ 35 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AccessCardExportModule.java

@@ -0,0 +1,35 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: AccessCardExportModule
+ * package: com.sptg.common.core.module
+ * description: 卡管理导出
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class AccessCardExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "卡号",index = 0)
+    private String cardNo;
+
+    @ExcelProperty(value = "所属房间",index = 1)
+    private String roomName;
+
+    @ExcelProperty(value = "所属单元",index = 2)
+    private String unitName;
+
+    @ExcelProperty(value = "所属小区",index = 3)
+    private String residentialName;
+
+    @ExcelProperty(value = "卡号有效期",index = 4)
+    private String cardDate;
+
+}

+ 48 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AccessCardImportModule.java

@@ -0,0 +1,48 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: AccessCardImportModule
+ * package: com.sptg.common.core.module
+ * description: 卡管理导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class AccessCardImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "卡号(必填)",index = 0)
+    private String cardNo;
+
+    @ExcelProperty(value = "卡号开始有效期(必填,例如 2000-01-01 00:00:00)",index = 1)
+    private String beginDate;
+
+    @ExcelProperty(value = "卡号结束有效期(必填,例如 2000-01-01 00:00:00)",index = 2)
+    private String endDate;
+
+    @ExcelProperty(value = "小区编号(必填)",index = 3)
+    private String residentialNumber;
+
+    @ExcelProperty(value = "单元编号",index = 4)
+    private String unitNumber;
+
+//    @ExcelProperty(value = "门牌号",index = 5)
+//    private String houseNumber;
+
+    @ExcelProperty(value = "房间编号",index = 5)
+    private String houseNumber;
+
+    /**
+     * 导入住户时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 6)
+    private String importErrorMsg;
+
+
+}

+ 41 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AdWatchExportModule.java

@@ -0,0 +1,41 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: AdWatchExportModule
+ * package: com.sptg.common.core.module
+ * description: 广告观看导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class AdWatchExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "广告名称" ,index = 0)
+    private String adName;
+
+    @ExcelProperty(value = "广告编号",index = 1)
+    private String adCode;
+
+    @ExcelProperty(value = "广告类别",index = 2)
+    private String adTypeName;
+
+    @ExcelProperty(value = "所属小区",index = 3)
+    private String residentialName;
+
+    @ExcelProperty(value = "设备位置" ,index = 4)
+    private String installPath;
+
+    @ExcelProperty(value = "观看用户",index = 5)
+    private String userName;
+
+    @ExcelProperty(value = "观看时间",index = 6)
+    private String createDate;
+
+}

+ 32 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AdWatchRankExportModule.java

@@ -0,0 +1,32 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: AdWatchRankExportModule
+ * package: com.sptg.common.core.module
+ * description: 广告观看排行导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class AdWatchRankExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "广告名称" ,index = 0)
+    private String adName;
+
+    @ExcelProperty(value = "广告编号",index = 1)
+    private String adCode;
+
+    @ExcelProperty(value = "广告类别",index = 2)
+    private String adTypeName;
+
+    @ExcelProperty(value = "观看次数",index = 3)
+    private Long watchCount;
+
+}

+ 52 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/AgencyImportModule.java

@@ -0,0 +1,52 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: ResidentialImportModule
+ * package: com.sptg.common.core.module
+ * description: 小区导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class AgencyImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "所属省(必填)" ,index = 0)
+    private String regionProvince;
+
+    @ExcelProperty(value = "所属市(必填)" ,index = 1)
+    private String regionCity;
+
+    @ExcelProperty(value = "所属区/县(必填)" ,index = 2)
+    private String regionArea;
+
+    @ExcelProperty(value = "所属街道(必填)",index = 3)
+    private String regionPStreet;
+
+    @ExcelProperty(value = "社区名称(必填,全称)",index = 4)
+    private String agengcyName;
+
+    @ExcelProperty(value = "详细地址",index = 5)
+    private String address;
+
+    @ExcelProperty(value = "负责人姓名",index = 6)
+    private String personName;
+
+    @ExcelProperty(value = "负责人电话",index = 7)
+    private String personTel;
+
+    @ExcelProperty(value = "备注",index = 8)
+    private String remark;
+
+    /**
+     * 导入小区时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 10)
+    private String importErrorMsg;
+}

+ 41 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/DeviceInstallationExportModule.java

@@ -0,0 +1,41 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: DeviceInstallationExportModule
+ * package: com.sptg.common.core.module
+ * description: 设备安装导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class DeviceInstallationExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "设备安装时间" ,index = 0)
+    private String createDate;
+
+    @ExcelProperty(value = "设备编号",index = 1)
+    private String serialNumber;
+
+    @ExcelProperty(value = "设备类型",index = 2)
+    private String deviceTypeName;
+
+    @ExcelProperty(value = "安装人",index = 3)
+    private String createName;
+
+    @ExcelProperty(value = "安装楼盘" ,index = 4)
+    private String residentialName;
+
+    @ExcelProperty(value = "具体位置",index = 5)
+    private String specificLocation;
+
+    @ExcelProperty(value = "审核状态",index = 6)
+    private String checkStateName;
+
+}

+ 40 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/DeviceTestExportModule.java

@@ -0,0 +1,40 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: DeviceTestExportModule
+ * package: com.sptg.common.core.module
+ * description: 设备检测导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class DeviceTestExportModule extends BaseRowModel {
+    @ExcelProperty(value = "检测时间" ,index = 0)
+    private String createDate;
+
+    @ExcelProperty(value = "设备编号",index = 1)
+    private String serialNumber;
+
+    @ExcelProperty(value = "设备类型",index = 2)
+    private String deviceTypeName;
+
+    @ExcelProperty(value = "检测人",index = 3)
+    private String createName;
+
+    @ExcelProperty(value = "安装楼盘" ,index = 4)
+    private String residentialName;
+
+    @ExcelProperty(value = "具体位置",index = 5)
+    private String specificLocation;
+
+    @ExcelProperty(value = "审核状态",index = 6)
+    private String checkStateName;
+
+}

+ 43 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/PositionExportModule.java

@@ -0,0 +1,43 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: PositionExportModule
+ * package: com.sptg.common.core.module
+ * description: 定位导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class PositionExportModule extends BaseRowModel{
+
+    @ExcelProperty(value = "设备定位时间" ,index = 0)
+    private String createDate;
+
+    @ExcelProperty(value = "安装楼盘",index = 1)
+    private String residentialName;
+
+    @ExcelProperty(value = "定位人",index = 2)
+    private String createName;
+
+    @ExcelProperty(value = "立柱机",index = 3)
+    private Integer pillar;
+
+    @ExcelProperty(value = "挂壁机" ,index = 4)
+    private Integer wallHung;
+
+    @ExcelProperty(value = "总台数",index = 5)
+    private Integer total;
+
+    @ExcelProperty(value = "雨罩",index = 6)
+    private Integer rainCover;
+
+    @ExcelProperty(value = "审核状态",index = 7)
+    private String checkStateName;
+}

+ 83 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ProjectExportModule.java

@@ -0,0 +1,83 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: ProjectExportModule
+ * package: com.sptg.common.core.module
+ * description: 111
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class ProjectExportModule extends BaseRowModel{
+
+    @ExcelProperty(value = {"序号","序号","序号","序号"} ,index = 0)
+    private String number;
+
+    @ExcelProperty(value = {"实    施   项   目","项目名称","项目名称","项目名称"} ,index = 1)
+    private String residentialName;
+
+    @ExcelProperty(value = {"实    施   项   目","区域","区域","区域"} ,index = 2)
+    private String region;
+
+    @ExcelProperty(value = {"实    施   项   目","项目实施派工单","签署日期","签署日期"} ,index = 3)
+    private String positionCreateDate;
+
+    @ExcelProperty(value = {"实    施   项   目","项目实施派工单","报备设备台数","立柱机"} ,index = 4)
+    private Integer positionPillar;
+
+    @ExcelProperty(value = {"实    施   项   目","项目实施派工单","报备设备台数","壁挂机"} ,index = 5)
+    private Integer positionWallHung;
+
+    @ExcelProperty(value = {"实    施   项   目","项目实施派工单","报备设备台数","总台数"} ,index = 6)
+    private Integer positionTotalCount;
+
+    @ExcelProperty(value = {"实    施   项   目","项目实施派工单","报备设备台数","雨罩"} ,index = 7)
+    private Integer positionRainCover;
+
+    @ExcelProperty(value = {"实    施   项   目","立项书项目时间简表","环境整改时间","环境整改时间"} ,index = 8)
+    private String projectBookRectificationDate;
+
+    @ExcelProperty(value = {"实    施   项   目","立项书项目时间简表","设备整改时间","设备整改时间"} ,index = 9)
+    private String projectBookProductionDate;
+
+    @ExcelProperty(value = {"实    施   项   目","立项书项目时间简表","设备出入库测试及物流发货时间","设备出入库测试及物流发货时间"} ,index = 10)
+    private String projectBookDeliveryDate;
+
+    @ExcelProperty(value = {"实    施   项   目","立项书项目时间简表","进场施工时间","进场施工时间"} ,index = 11)
+    private String projectBookConstructionDate;
+
+    @ExcelProperty(value = {"实    施   项   目","立项书项目时间简表","项目验收和交接时间","项目验收和交接时间"} ,index = 12)
+    private String projectBookAcceptanceDate;
+
+    @ExcelProperty(value = {"实    施   项   目","项目竣工验收单","签署日期","签署日期"} ,index = 13)
+    private String projectCompletionDate;
+
+    @ExcelProperty(value = {"实    施   项   目","项目竣工验收单","确认设备台数","立柱机"} ,index = 14)
+    private Integer projectCompletionPillar;
+
+    @ExcelProperty(value = {"实    施   项   目","项目竣工验收单","确认设备台数","壁挂机"} ,index = 15)
+    private Integer projectCompletionWallHung;
+
+    @ExcelProperty(value = {"实    施   项   目","项目竣工验收单","确认设备台数","总台数"} ,index = 16)
+    private Integer projectCompletionTotalCount;
+
+    @ExcelProperty(value = {"合  同  合  作  方  名  称","合同编号","合同编号","合同编号"} ,index = 17)
+    private String contractNo;
+
+    @ExcelProperty(value = {"合  同  合  作  方  名  称","合同签约日期","合同签约日期","合同签约日期"} ,index = 18)
+    private String signingDate;
+
+    @ExcelProperty(value = {"合  同  合  作  方  名  称","物业管理方(乙方)","物业管理方(乙方)","物业管理方(乙方)"} ,index = 19)
+    private String propertyName;
+
+    @ExcelProperty(value = {"合  同  合  作  方  名  称","综合服务方(丙方)","综合服务方(丙方)","综合服务方(丙方)"} ,index = 20)
+    private String integratedServiceName;
+
+}

+ 64 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ResidentialExportModule.java

@@ -0,0 +1,64 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: ResidentialExportModule
+ * package: com.sptg.estate.api.module
+ * description: 小区导出模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class ResidentialExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "小区名称" ,index = 0)
+    private String name;
+
+    /*@ExcelProperty(value = "小区编号",index = 1)
+    private String residentialNumber;*/
+
+    @ExcelProperty(value = "所属物业",index = 2)
+    private String orgPidName;
+
+    @ExcelProperty(value = "小区地址",index = 3)
+    private String region;
+
+    @ExcelProperty(value = "详细地址" ,index = 4)
+    private String address;
+
+    @ExcelProperty(value = "单元总数",index = 5)
+    private Integer totalUnitNumber;
+
+    @ExcelProperty(value = "房间总数",index = 6)
+    private Integer totalRoomNumber;
+
+    @ExcelProperty(value = "住户总数",index = 7)
+    private Integer totalUserNumber;
+
+    @ExcelProperty(value = "已录单元总数",index = 8)
+    private Integer unitNumber;
+
+    @ExcelProperty(value = "已录房间总数",index = 9)
+    private Integer roomNumber;
+
+    @ExcelProperty(value = "已录住户总数",index = 10)
+    private Integer userNumber;
+
+    @ExcelProperty(value = "入住率",index = 11)
+    private String rate;
+
+    @ExcelProperty(value = "负责人",index = 12)
+    private String personName;
+
+    @ExcelProperty(value = "联系电话",index = 13)
+    private String personTel;
+
+    @ExcelProperty(value = "备注",index = 14)
+    private String remark;
+}

+ 49 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ResidentialImportModule.java

@@ -0,0 +1,49 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: ResidentialImportModule
+ * package: com.sptg.common.core.module
+ * description: 小区导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class ResidentialImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "小区名称(必填)" ,index = 0)
+    private String name;
+
+    @ExcelProperty(value = "所属社区全称(必填)" ,index = 1)
+    private String agencyName;
+
+    @ExcelProperty(value = "详细地址" ,index = 2)
+    private String address;
+
+    @ExcelProperty(value = "物业名称",index = 3)
+    private String estateName;
+
+    @ExcelProperty(value = "物业电话",index = 4)
+    private String estateTel;
+
+    @ExcelProperty(value = "负责人姓名",index = 5)
+    private String personName;
+
+    @ExcelProperty(value = "负责人电话",index = 6)
+    private String personTel;
+
+    @ExcelProperty(value = "备注",index = 7)
+    private String remark;
+
+    /**
+     * 导入小区时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 8)
+    private String importErrorMsg;
+}

+ 54 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/RoomExportModule.java

@@ -0,0 +1,54 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: RoomExportModule
+ * package: com.sptg.common.core.module
+ * description: 房间导出模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class RoomExportModule extends BaseRowModel {
+    @ExcelProperty(value = "房间名称" ,index = 0)
+    private String name;
+
+//    @ExcelProperty(value = "门牌号",index = 1)
+//    private String houseNumber;
+
+    @ExcelProperty(value = "房间编号",index = 1)
+    private String houseNumber;
+
+    @ExcelProperty(value = "所属单元",index = 2)
+    private String unitName;
+
+    @ExcelProperty(value = "所属小区",index = 3)
+    private String residentialName;
+
+    @ExcelProperty(value = "住户总数" ,index = 4)
+    private Integer userNumber;
+
+    @ExcelProperty(value = "户型",index = 5)
+    private String houseType;
+
+    @ExcelProperty(value = "楼层",index = 6)
+    private String floor;
+
+    @ExcelProperty(value = "朝向",index = 7)
+    private String orientation;
+
+    @ExcelProperty(value = "装修",index = 8)
+    private String ornament;
+
+    @ExcelProperty(value = "面积(m²)",index = 9)
+    private Double area;
+
+    @ExcelProperty(value = "备注",index = 10)
+    private String remark;
+}

+ 67 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/RoomImportModule.java

@@ -0,0 +1,67 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: RoomImportModule
+ * package: com.sptg.common.core.module
+ * description: 房间导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class RoomImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "所属小区编码(必填)",index = 0)
+    private String residentialNumber;
+
+    /*@ExcelProperty(value = "所属单元名称(必填)",index = 1)
+    private String unitName;*/
+
+    /*@ExcelProperty(value = "所属单元名称(选填)",index = 1)
+    private String unitName;*/
+
+    @ExcelProperty(value = "所属单元编号(必填)",index = 1)
+    private String unitNumber;
+
+    @ExcelProperty(value = "房间名称(必填)" ,index = 2)
+    private String name;
+
+    /*@ExcelProperty(value = "门牌号(必填)",index = 3)
+    private String houseNumber;*/
+
+//    @ExcelProperty(value = "房间编号(选填且为数字)",index = 4)
+//    private String houseNumber;
+
+    @ExcelProperty(value = "户型",index = 3)
+    private String houseType;
+
+    @ExcelProperty(value = "楼层",index = 4)
+    private String floor;
+
+    @ExcelProperty(value = "朝向",index = 5)
+    private String orientation;
+
+    @ExcelProperty(value = "装修",index = 6)
+    private String ornament;
+
+    @ExcelProperty(value = "面积(m²)",index = 7)
+    private Double area;
+
+    @ExcelProperty(value = "备注",index = 8)
+    private String remark;
+
+    @ExcelProperty(value = "排序",index = 9)
+    private String serial;
+
+    /**
+     * 导入单元时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 10)
+    private String importErrorMsg;
+}

+ 47 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/StatisticsUserExportModule.java

@@ -0,0 +1,47 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: StatisticsUserExportModule
+ * package: com.sptg.common.core.module
+ * description: 住户统计导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class StatisticsUserExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "小区名称" ,index = 0)
+    private String name;
+
+    @ExcelProperty(value = "所属物业",index = 1)
+    private String orgPidName;
+
+    @ExcelProperty(value = "小区地址",index = 2)
+    private String region;
+
+    @ExcelProperty(value = "总住户数" ,index = 3)
+    private Integer userCount;
+
+    @ExcelProperty(value = "未知性别住户数",index = 4)
+    private Integer unknownSexUserCount;
+
+    @ExcelProperty(value = "男性住户数",index = 5)
+    private Integer manSexUserCount;
+
+    @ExcelProperty(value = "女性住户数",index = 6)
+    private Integer omanSexUserCount;
+
+    @ExcelProperty(value = "租客数",index = 7)
+    private Integer tenantUserCount;
+
+    @ExcelProperty(value = "上月新增住户数",index = 8)
+    private Integer lastMonthAddUserCount;
+
+}

+ 52 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/ThirdUserImportModule.java

@@ -0,0 +1,52 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UserImportModule
+ * package: com.sptg.common.core.module
+ * description: 住户导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class ThirdUserImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "姓名",index = 0)
+    private String name;
+
+    @ExcelProperty(value = "性别" ,index = 1)
+    private String sex;
+
+    @ExcelProperty(value = "主键",index = 2)
+    private String key;
+
+    @ExcelProperty(value = "社区",index = 3)
+    private String agencyName;
+
+    @ExcelProperty(value = "小区",index = 4)
+    private String residentialName;
+
+    @ExcelProperty(value = "楼栋-单元-房",index = 5)
+    private String houseInfo;
+
+    @ExcelProperty(value = "照片地址",index = 6)
+    private String imageName;
+
+    @ExcelProperty(value = "证件",index = 7)
+    private String idcard;
+
+    @ExcelProperty(value = "手机", index = 8)
+    private String tel;
+
+    /**
+     * 导入住户时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 10)
+    private String importErrorMsg;
+}

+ 52 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UnitExportModule.java

@@ -0,0 +1,52 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UnitExportModule
+ * package: com.sptg.common.core.module
+ * description: 单元导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class UnitExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "单元名称" ,index = 0)
+    private String name;
+
+    @ExcelProperty(value = "单元编号",index = 1)
+    private String unitNumber;
+
+    @ExcelProperty(value = "所属小区",index = 2)
+    private String residentialName;
+
+    @ExcelProperty(value = "负责人",index = 3)
+    private String personName;
+
+    @ExcelProperty(value = "联系方式" ,index = 4)
+    private String personTel;
+
+    @ExcelProperty(value = "建筑年代",index = 5)
+    private String builtYear;
+
+    @ExcelProperty(value = "产权性质",index = 6)
+    private String propertyNature;
+
+    @ExcelProperty(value = "有无电梯",index = 7)
+    private String includingElevator;
+
+    @ExcelProperty(value = "房间总数",index = 8)
+    private Integer roomNumber;
+
+    @ExcelProperty(value = "住户总数",index = 9)
+    private Integer userNumber;
+
+    @ExcelProperty(value = "备注",index = 10)
+    private String remark;
+}

+ 55 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UnitImportModule.java

@@ -0,0 +1,55 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UnitImportModule
+ * package: com.sptg.common.core.module
+ * description: 单元导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class UnitImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "所属小区编码(必填)" ,index = 0)
+    private String residentialNumber;
+
+    @ExcelProperty(value = "单元名称(必填)",index = 1)
+    private String name;
+
+    /*@ExcelProperty(value = "单元编号(必填且为数字)",index = 2)
+    private String unitNumber;*/
+
+    @ExcelProperty(value = "负责人",index = 2)
+    private String personName;
+
+    @ExcelProperty(value = "联系方式" ,index = 3)
+    private String personTel;
+
+    @ExcelProperty(value = "建筑年代",index = 4)
+    private String builtYear;
+
+    @ExcelProperty(value = "产权性质",index = 5)
+    private String propertyNature;
+
+    @ExcelProperty(value = "有无电梯",index = 6)
+    private String includingElevator;
+
+    @ExcelProperty(value = "备注",index = 7)
+    private String remark;
+
+    @ExcelProperty(value = "排序",index = 8)
+    private String serial;
+
+    /**
+     * 导入单元时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 9)
+    private String importErrorMsg;
+}

+ 47 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserAccessExportModule.java

@@ -0,0 +1,47 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UserAccessExportModule
+ * package: com.sptg.common.core.module
+ * description: 住户卡导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class UserAccessExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "姓名" ,index = 0)
+    private String name;
+
+    @ExcelProperty(value = "联系方式",index = 1)
+    private String tel;
+
+    @ExcelProperty(value = "身份证" ,index = 2)
+    private String idCard;
+
+    @ExcelProperty(value = "所属房间",index = 3)
+    private String roomName;
+
+    @ExcelProperty(value = "所属单元",index = 4)
+    private String unitName;
+
+    @ExcelProperty(value = "所属小区",index = 5)
+    private String residentialName;
+
+    @ExcelProperty(value = "性别",index = 6)
+    private String sexName;
+
+    @ExcelProperty(value = "人脸审核状态",index = 7)
+    private String checkStateName;
+
+    @ExcelProperty(value = "门禁卡号",index = 8)
+    private String cardNo;
+
+}

+ 50 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserAccessImportModule.java

@@ -0,0 +1,50 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UserAccessImportModule
+ * package: com.sptg.common.core.module
+ * description: 住户卡导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class UserAccessImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "小区编号(必填)" ,index = 0)
+    private String residentialNumber;
+
+    @ExcelProperty(value = "单元编号(必填)",index = 1)
+    private String unitNumber;
+
+//    @ExcelProperty(value = "门牌号(必填)" ,index = 2)
+//    private String houseNumber;
+
+    @ExcelProperty(value = "房间编号(必填)" ,index = 2)
+    private String houseNumber;
+
+    @ExcelProperty(value = "住户姓名(必填)",index = 3)
+    private String userName;
+
+    @ExcelProperty(value = "卡号(必填)",index = 4)
+    private String cardNo;
+
+    @ExcelProperty(value = "卡号开始有效期(必填,例如 2000-01-01 00:00:00)",index = 5)
+    private String beginDate;
+
+    @ExcelProperty(value = "卡号结束有效期(必填,例如 2000-01-01 00:00:00)",index = 6)
+    private String endDate;
+
+    /**
+     * 导入住户时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 7)
+    private String importErrorMsg;
+
+}

+ 50 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserExportModule.java

@@ -0,0 +1,50 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UserExportModule
+ * package: com.sptg.common.core.module
+ * description: 住户导出模板
+ *
+ *             
+ *                
+ */
+@Getter
+@Setter
+public class UserExportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "姓名" ,index = 0)
+    private String name;
+
+    @ExcelProperty(value = "性别",index = 1)
+    private String sexName;
+
+    @ExcelProperty(value = "所属房间",index = 2)
+    private String roomName;
+
+    @ExcelProperty(value = "住户类型",index = 3)
+    private String typeName;
+
+    @ExcelProperty(value = "身份证" ,index = 4)
+    private String idCard;
+
+    @ExcelProperty(value = "籍贯",index = 5)
+    private String birthPlace;
+
+    @ExcelProperty(value = "联系方式",index = 6)
+    private String tel;
+
+    @ExcelProperty(value = "住户来源",index = 7)
+    private String createTypeName;
+
+    @ExcelProperty(value = "审核状态",index = 8)
+    private String checkStateName;
+
+    @ExcelProperty(value = "备注",index = 9)
+    private String remark;
+
+}

+ 76 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/module/UserImportModule.java

@@ -0,0 +1,76 @@
+package com.sptg.common.core.module;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * title: UserImportModule
+ * package: com.sptg.common.core.module
+ * description: 住户导入模板
+ *
+ *
+ *
+ */
+@Getter
+@Setter
+public class UserImportModule extends BaseRowModel {
+
+    @ExcelProperty(value = "小区所属省(必填)",index = 0)
+    private String regionProvince;
+
+    @ExcelProperty(value = "小区所属市(必填)" ,index = 1)
+    private String regionCity;
+
+    @ExcelProperty(value = "小区所属区/县(必填)",index = 2)
+    private String regionArea;
+
+//    @ExcelProperty(value = "小区所属街道(必填)",index = 3)
+//    private String streetName;
+//
+//    @ExcelProperty(value = "所属社区全称(必填)",index = 4)
+//    private String agencyName;
+
+    @ExcelProperty(value = "所属小区全称(必填)",index = 3)
+    private String residentialName;
+
+    @ExcelProperty(value = "所属楼栋全称(必填)",index = 4)
+    private String buildinglName;
+
+    @ExcelProperty(value = "所属单元名称(必填)",index = 5)
+    private String unitName;
+
+    @ExcelProperty(value = "所属楼层名称(必填)",index = 6)
+    private String floorName;
+
+    @ExcelProperty(value = "所属房屋名称(必填)",index = 7)
+    private String roomName;
+
+    @ExcelProperty(value = "姓名(必填)", index = 8)
+    private String name;
+
+    @ExcelProperty(value = "联系方式(业主必填)", index = 9)
+    private String tel;
+
+    @ExcelProperty(value = "性别(必填,男/女)", index = 10)
+    private String sex;
+
+    @ExcelProperty(value = "住户类型(必填,业主/家属/租户})", index = 11)
+    private String type;
+
+    @ExcelProperty(value = "身份证号(业主必填)", index = 12)
+    private String idCard;
+
+    @ExcelProperty(value = "籍贯", index = 13)
+    private String birthPlace;
+
+    @ExcelProperty(value = "备注", index = 14)
+    private String remark;
+
+    /**
+     * 导入住户时导致错误的错误信息
+     */
+    @ExcelProperty(value = "",index = 15)
+    private String importErrorMsg;
+}

+ 94 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/AesEncryptionUtil.java

@@ -0,0 +1,94 @@
+package com.sptg.common.core.util;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+
+/**
+ * title: AesEncryptionUtil
+ * package: com.sptg.common.core.util
+ * description: Aes对称加密工具类
+ *
+ *                  
+ *               
+ */
+public final class AesEncryptionUtil {
+
+    private static final BASE64Encoder BASE_64_ENCODER = new BASE64Encoder();
+
+    /**
+     * 功能描述: Aes对称加密
+     * @param secretKey 密钥
+     * @param content 加密内容,明文
+     * @return 密文
+     *                  
+     *                     
+     */
+    public static String aesEncryption(String secretKey,String content)throws Exception{
+        Cipher cipher = AesEncryptionUtil.generateCipher(secretKey,Cipher.ENCRYPT_MODE);
+        //  获取加密内容的字节数组
+        byte [] byteEncode = content.getBytes(StandardCharsets.UTF_8);
+        //  将数据进行加密
+        byte [] byteAES = cipher.doFinal(byteEncode);
+        //  将加密内容进行base64编码
+        return BASE_64_ENCODER.encode(byteAES);
+    }
+
+    private static final BASE64Decoder BASE_64_DECODER = new BASE64Decoder();
+
+    /**
+     * 功能描述: Aes解密
+     * @param secretKey 密钥
+     * @param content 揭秘内容,密文
+     * @return 明文
+     *                  
+     *                     
+     */
+    public static String aesDecrypt(String secretKey,String content)throws Exception{
+        //  构建密码器
+        Cipher cipher = AesEncryptionUtil.generateCipher(secretKey,Cipher.DECRYPT_MODE);
+        //  将编码后的数据解码为字节数组
+        byte [] byteAES = BASE_64_DECODER.decodeBuffer(content);
+        //  解密
+        byte[] byteEncode = cipher.doFinal(byteAES);
+        return new String(byteEncode, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * Aes 算法
+     */
+    private static final String AES = "AES";
+
+    /**
+     * 功能描述: 构建密码器,指定为AES算法
+     * @param encodeRule 密钥
+     * @param isEncryption 1:加密,2:解密
+     * @return Cipher
+     *                  
+     *                     
+     */
+    private static Cipher generateCipher(String encodeRule,int isEncryption)throws Exception{
+        //  构造密钥生成器,指定为AES算法
+        KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
+        //  根据加密规则初始化密钥生成器
+        keyGenerator.init(128,new SecureRandom(encodeRule.getBytes()));
+        //  产生原始对称密钥
+        SecretKey secretKey = keyGenerator.generateKey();
+        //  获取密钥的字节数组
+        byte[] encoded = secretKey.getEncoded();
+        //  根据字节数组生成AES密钥
+        SecretKey key = new SecretKeySpec(encoded, AES);
+        //  构建密码器,指定为AES算法
+        Cipher cipher = Cipher.getInstance(AES);
+        //  初始化密码器
+        cipher.init(isEncryption, key);
+        return cipher;
+    }
+
+}

+ 26 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/AssertUtil.java

@@ -0,0 +1,26 @@
+package com.sptg.common.core.util;
+
+import org.springframework.util.Assert;
+
+/**
+ * title: AssertUtil
+ * package: com.sptg.common.core.util
+ * description: 断言工具类
+ *
+ *                  
+ *                
+ */
+public class AssertUtil extends Assert {
+
+    /**
+     * 表达式为False时,抛出异常
+     * @param expression 表达式
+     * @param message 异常消息
+     */
+    public static void isFalse(boolean expression, String message) {
+        if (expression) {
+            throw new IllegalArgumentException(message);
+        }
+    }
+
+}

+ 109 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/Base64DecodeMultipartFileUtils.java

@@ -0,0 +1,109 @@
+package com.sptg.common.core.util;
+
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Decoder;
+
+import java.io.*;
+
+/**
+ * title: Base64DecodeMultipartFileUtils
+ * package: com.sptg.common.core.util
+ * description: aaa
+ *
+ *             
+ *                 
+ */
+public class Base64DecodeMultipartFileUtils implements MultipartFile {
+    private final byte[] imgContent;
+    private final String header;
+
+    public Base64DecodeMultipartFileUtils(byte[] imgContent, String header) {
+        this.imgContent = imgContent;
+        this.header = header.split(";")[0];
+    }
+
+    @Override
+    public String getName() {
+        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return System.nanoTime() +  "." + header.split("/")[1];
+    }
+
+    @Override
+    public String getContentType() {
+        return header.split(":")[1];
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return imgContent == null || imgContent.length == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return imgContent.length;
+    }
+
+    @Override
+    public byte[] getBytes(){
+        return imgContent;
+    }
+
+    @Override
+    public InputStream getInputStream() {
+        return new ByteArrayInputStream(imgContent);
+    }
+
+    @Override
+    public void transferTo(File dest) {
+        FileOutputStream stream = null;
+        try {
+            stream = new FileOutputStream(dest);
+            stream.write(imgContent);
+            stream.close();
+        }catch (IOException e){
+            if (null != stream){
+                try {
+                    stream.close();
+                }catch (IOException err){
+                    stream = null;
+                }
+            }
+            stream = null;
+        }
+    }
+
+    public static MultipartFile base64ToMultipart(String base64) {
+        try {
+            String[] baseStrs = base64.split(",");
+            BASE64Decoder decoder = new BASE64Decoder();
+            byte[] b =decoder.decodeBuffer(baseStrs[1]);
+            for(int i = 0; i < b.length; ++i) {
+                if (b[i] < 0) {
+                    b[i] += 256;
+                }
+            }
+            return new Base64DecodeMultipartFileUtils(b, baseStrs[0]);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 功能描述: 把图片的格式转成png格式
+     * @param base64  图片的base64字符串
+     * @return base64
+     *               
+     *                      
+     */
+    public static String imageFormatToPng(String base64){
+        String png = "data:image/png;";
+        String[] strs = base64.split(";");
+        base64 = png + strs[1];
+        return base64;
+    }
+}

+ 148 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/CommonUtil.java

@@ -0,0 +1,148 @@
+package com.sptg.common.core.util;
+
+import com.sptg.common.core.constant.SymbolConstant;
+import net.sourceforge.pinyin4j.PinyinHelper;
+import org.springframework.util.StringUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * title: CommonUtil
+ * package: com.sptg.common.core.util
+ * description: 常用工具栏
+ *
+ *
+ *
+ */
+public final class CommonUtil {
+
+    /**
+     * 功能描述: 自动填充零
+     * @param length 指定长度
+     * @param number 数字
+     * @return String
+     *
+     *
+     */
+    public static String autoZeroFilling(int length,long number){
+        String result = Long.toString(number);
+        //  长度不足自动补0
+        if (result.length() < length){
+            StringBuilder sb = new StringBuilder();
+            for (int i = result.length(); i < length; i++){
+                sb.append("0");
+            }
+            result = sb.toString() + result;
+        }
+        return result;
+    }
+
+    /**
+     * 功能描述: String字符串转Long类型数组
+     * @param text 字符串,每个数字间通过“,”分割
+     * @return List<Long>
+     *
+     *
+     */
+    public static List<Long> stringToLongList(String text) throws NumberFormatException{
+        List<Long> resultList = new ArrayList<>();
+        if (!StringUtils.isEmpty(text)) {
+            String[] array = text.split(SymbolConstant.COMMA);
+            for (String item : array) {
+                if (StringUtils.hasText(item)) {
+                    resultList.add(Long.parseLong(item));
+                }
+            }
+        }
+        return resultList;
+    }
+
+    /**
+     * 功能描述: 生成随机数
+     * @param length 随机数长度
+     * @return int
+     *
+     *
+     */
+    public static int generateNumber(int length){
+        double min = Math.pow(10,length - 1);
+        double max = Math.pow(10, length);
+        return (int)(new Random().nextInt((int) (max - min)) + min);
+    }
+
+    /**
+     * 功能描述:判断当前时间是否在7:00-22:00之间
+     * @return
+     * @throws ParseException
+     */
+    public static boolean isTimeRange(String beginStr, String endStr)throws ParseException {
+        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
+        Date now = df.parse(df.format(new Date()));
+        Date begin = df.parse(beginStr);
+        Date end = df.parse(endStr);
+        Calendar nowTime = Calendar.getInstance();
+        nowTime.setTime(now);
+        Calendar beginTime = Calendar.getInstance();
+        beginTime.setTime(begin);
+        Calendar endTime = Calendar.getInstance();
+        endTime.setTime(end);
+        if (nowTime.before(endTime) && nowTime.after(beginTime)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 随机生成8位密码 工具类
+     *
+     */
+    public static String getRandomPassword(Integer length) {
+        if (length == null || length <= 0){
+            length = 8;
+        }
+        Random rd = new Random(); // 创建随机对象
+        String n = ""; // 保存随机数
+        int rdGet; // 取得随机数
+        do {
+            if (rd.nextInt() % 2 == 1) {
+                rdGet = Math.abs(rd.nextInt()) % 10 + 48; // 产生48到57的随机数(0-9的键位值)
+            } else {
+                Random rdm = new Random();
+                if (rdm.nextInt() % 2 == 1) {
+                    rdGet = Math.abs(rd.nextInt()) % 26 + 65; // 产生65到90的随机数(A-Z的键位值)
+                }else{
+                    rdGet = Math.abs(rd.nextInt()) % 26 + 97; // 产生97到122的随机数(a-z的键位值)
+                }
+
+            }
+            char num1 = (char) rdGet; // int转换char
+            String dd = Character.toString(num1);
+            n += dd;
+        } while (n.length() < length);// 设定长度,此处假定长度小于8
+        return n;
+
+    }
+
+    /**
+     * 得到中文首字母(中国 -> ZG)
+     * @param str 需要转化的中文字符串
+     * @return 大写首字母缩写的字符串
+     */
+    public static String getPinYinHeadChar(String str) {
+        StringBuilder convert = new StringBuilder();
+        for (int j = 0; j < str.length(); j++) {
+            char word = str.charAt(j);
+            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
+            if (pinyinArray != null) {
+                convert.append(pinyinArray[0].charAt(0));
+            } else {
+                convert.append(word);
+            }
+        }
+        return convert.toString().toLowerCase();
+    }
+
+}

+ 221 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/CookieUtils.java

@@ -0,0 +1,221 @@
+package com.sptg.common.core.util;
+
+import com.sptg.common.core.constant.CommonConstant;
+import com.sptg.common.core.constant.OperationConstant;
+import com.sptg.common.core.constant.SymbolConstant;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+/**
+ * title: CookieUtils
+ * package: com.sptg.common.core.util
+ * description: Cookie工具类
+ *                  
+ *                
+ */
+public final class CookieUtils {
+
+
+    /**
+     * 得到Cookie的值, 不编码
+     * @param cookieName Cookie名称
+     * @return String
+     *                  
+     *                       
+     */
+    public static String getCookieValue(String cookieName) {
+        return getCookieValue(cookieName, false);
+    }
+
+    /**
+     * 得到Cookie的值
+     * @param cookieName Cookie名称
+     * @return String
+     *                  
+     *                       
+     */
+    public static String getCookieValue(String cookieName, boolean isDecoder) {
+        HttpServletRequest request = WebUtils.getHttpServletRequest();
+        Cookie[] cookieList = request.getCookies();
+        if (cookieList == null || cookieName == null) {
+            return null;
+        }
+        String retValue = null;
+        try {
+            for(Cookie cookie : cookieList){
+                if (cookie.getName().equals(cookieName)){
+                    if (isDecoder){
+                        retValue = URLDecoder.decode(cookie.getValue(), CommonConstant.UTF_8);
+                    }else {
+                        retValue = cookie.getValue();
+                    }
+                    break;
+                }
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return retValue;
+    }
+
+    /**
+     * 得到Cookie的值
+     * @param cookieName Cookie名称
+     * @return String
+     *                  
+     *                       
+     */
+    public static String getCookieValue(String cookieName, String encodeString) {
+        HttpServletRequest request = WebUtils.getHttpServletRequest();
+        Cookie[] cookieList = request.getCookies();
+        if (cookieList == null || cookieName == null) {
+            return null;
+        }
+        String retValue = null;
+        try {
+            for (Cookie cookie:cookieList){
+                if (cookie.getName().equals(cookieName)){
+                    retValue = URLDecoder.decode(cookie.getValue(), encodeString);
+                    break;
+                }
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return retValue;
+    }
+
+    /**
+     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
+     */
+    public static void setCookie(String cookieName, String cookieValue) {
+        setCookie(cookieName, cookieValue, OperationConstant.MINUS_ONE);
+    }
+
+    /**
+     * 设置Cookie的值 在指定时间内生效,但不编码
+     */
+    public static void setCookie(String cookieName, String cookieValue, int cookieMaxAge) {
+        setCookie(cookieName, cookieValue, cookieMaxAge, false);
+    }
+
+    /**
+     * 设置Cookie的值 不设置生效时间,但编码
+     */
+    public static void setCookie(String cookieName,String cookieValue, boolean isEncode) {
+        setCookie(cookieName, cookieValue, OperationConstant.MINUS_ONE, isEncode);
+    }
+
+    /**
+     * 设置Cookie的值 在指定时间内生效, 编码参数
+     */
+    public static void setCookie(String cookieName,String cookieValue, int cookieMaxAge, boolean isEncode) {
+        doSetCookie(cookieName, cookieValue, cookieMaxAge, isEncode);
+    }
+
+    /**
+     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
+     */
+    public static void setCookie(String cookieName,String cookieValue, int cookieMaxAge, String encodeString) {
+        doSetCookie(cookieName, cookieValue, cookieMaxAge, encodeString);
+    }
+
+    /**
+     * 删除Cookie带cookie域名
+     */
+    public static void deleteCookie(String cookieName) {
+        doSetCookie(cookieName, CommonConstant.EMPTY, OperationConstant.MINUS_ONE, false);
+    }
+
+    /**
+     * 设置Cookie的值,并使其在指定时间内生效
+     * @param cookieMaxAge cookie生效的最大秒数
+     *                  
+     *                       
+     */
+    private static void doSetCookie(String cookieName, String cookieValue, int cookieMaxAge, boolean isEncode) {
+        HttpServletRequest request = WebUtils.getHttpServletRequest();
+        HttpServletResponse response = WebUtils.getHttpServletResponse();
+        try {
+            if (cookieValue == null) {
+                cookieValue = CommonConstant.EMPTY;
+            } else if (isEncode) {
+                cookieValue = URLEncoder.encode(cookieValue, CommonConstant.UTF_8);
+            }
+            Cookie cookie = new Cookie(cookieName, cookieValue);
+            if (cookieMaxAge > OperationConstant.ZERO) {
+                cookie.setMaxAge(cookieMaxAge);
+            }
+            // 设置域名的cookie
+            if (null != request) {
+                String domainName = getDomainName(request);
+                if (!CommonConstant.LOCALHOST.equals(domainName)) {
+                    cookie.setDomain(domainName);
+                }
+            }
+            cookie.setPath(SymbolConstant.BACK_SLASH);
+            response.addCookie(cookie);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 设置Cookie的值,并使其在指定时间内生效
+     * @param cookieMaxAge cookie生效的最大秒数
+     *                  
+     *                       
+     */
+    private static void doSetCookie(String cookieName, String cookieValue, int cookieMaxAge, String encodeString) {
+        HttpServletRequest request = WebUtils.getHttpServletRequest();
+        try {
+            if (cookieValue == null) {
+                cookieValue = CommonConstant.EMPTY;
+            } else {
+                cookieValue = URLEncoder.encode(cookieValue, encodeString);
+            }
+            Cookie cookie = new Cookie(cookieName, cookieValue);
+            if (cookieMaxAge > OperationConstant.ZERO) {
+                cookie.setMaxAge(cookieMaxAge);
+            }
+            if (null != request) {
+                // 设置域名的cookie
+                String domainName = getDomainName(request);
+                if (!CommonConstant.LOCALHOST.equals(domainName)) {
+                    cookie.setDomain(domainName);
+                }
+            }
+            cookie.setPath(SymbolConstant.BACK_SLASH);
+            HttpServletResponse response = WebUtils.getHttpServletResponse();
+            response.addCookie(cookie);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 得到cookie的域名
+     */
+    private static String getDomainName(HttpServletRequest request) {
+        StringBuffer url = request.getRequestURL();
+        //  删除 http://
+        url.delete(OperationConstant.ZERO,url.indexOf(SymbolConstant.DOUBLE_SLASH) + OperationConstant.TWO);
+        int index = url.indexOf(SymbolConstant.COLON);
+        if(index > OperationConstant.MINUS_ONE){
+            //  删除端口及后面的路径
+            url.delete(index, url.length());
+        }else {
+            //  删除多余的路径
+            url.delete(url.length() - request.getRequestURI().length(), url.length());
+        }
+        return url.toString();
+    }
+
+
+
+}

+ 122 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/DateUtil.java

@@ -0,0 +1,122 @@
+package com.sptg.common.core.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * title: DateUtil
+ * package: com.sptg.common.core.util
+ * description:Date工具类
+ *
+ *                
+ *               
+ */
+public class DateUtil {
+
+    /**
+     * 功能描述:上周周一
+     * @return Date
+     *                
+     *                      
+     */
+    public static Date getBeginDayOfLastWeek(){
+        Date date = new Date();
+
+        // 取上周一 00:00:00
+        Calendar cal1 = Calendar.getInstance();
+        cal1.setTime(date);
+        //-7上周
+        cal1.add(Calendar.DATE, -7);
+        cal1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        cal1.set(Calendar.HOUR_OF_DAY, 0);
+        cal1.set(Calendar.MINUTE, 0);
+        cal1.set(Calendar.SECOND, 0);
+        return  cal1.getTime();
+    }
+
+
+    /**
+     * 功能描述:本周周一
+     * @return Date
+     *                
+     *                      
+     */
+    public static  Date getBeginDayOfWeek() {
+        Date date = new Date();
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        return  cal.getTime();
+    }
+
+    /**
+     * 由过去的某一时间,计算距离当前的时间
+     */
+    public static String calculateTime(Date date) {
+        String msg="";
+        // 获取当前时间的毫秒数
+        long nowTime = System.currentTimeMillis();
+        // 指定时间
+        Date setTime = date;
+        // 获取指定时间的毫秒数
+        long reset = setTime.getTime();
+        long dateDiff = nowTime - reset;
+        if (dateDiff < 0) {
+            msg = "输入的时间不对";
+        } else {
+            // 秒
+            long dateTemp1 = dateDiff / 1000;
+            // 分钟
+            long dateTemp2 = dateTemp1 / 60;
+            // 小时
+            long dateTemp3 = dateTemp2 / 60;
+            // 天数
+            long dateTemp4 = dateTemp3 / 24;
+            // 月数
+            long dateTemp5 = dateTemp4 / 30;
+            // 年数
+            long dateTemp6 = dateTemp5 / 12;
+            if (dateTemp6 > 0) {
+                msg = dateTemp6 + "年前";
+            } else if (dateTemp5 > 0) {
+                msg = dateTemp5 + "个月前";
+            } else if (dateTemp4 > 0) {
+                msg = dateTemp4 + "天前";
+            } else if (dateTemp3 > 0) {
+                msg = dateTemp3 + "小时前";
+            } else if (dateTemp2 > 0) {
+                msg = dateTemp2 + "分钟前";
+            } else if (dateTemp1 > 0) {
+                msg = "刚刚";
+            }
+        }
+        return msg;
+    }
+
+    /**
+     * 功能描述:获取某年第几周,跟mysql计算YEARWEEK匹配
+     * @param date
+     * @param firstDayOfWeek //设置为一周的第一天  如:Calendar.MONDAY
+     * @return int
+     *                
+     *                      
+     */
+    public static  int getYearWeek(Date date,int firstDayOfWeek){
+        Calendar calendar= Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.setFirstDayOfWeek(firstDayOfWeek);
+        int year=calendar.get(Calendar.YEAR);
+        int yearWeek=calendar.get(Calendar.WEEK_OF_YEAR);
+        int month=calendar.get(Calendar.MONTH)+1;
+        //特殊处理12月份第一周是下一年 采用mysql YEARWEEK函数处理方法
+        if(month==12&&yearWeek==1){
+            year=year+1;
+        }
+        String yearWeekStr=String.format("%02d",yearWeek);
+        return Integer.parseInt(year+yearWeekStr);
+    }
+}

+ 122 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/JsonUtils.java

@@ -0,0 +1,122 @@
+package com.sptg.common.core.util;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * title: JsonUtils
+ * package: com.sptg.common.core.util
+ * description: Json工具类
+ *                  
+ *               
+ */
+@Slf4j
+public class JsonUtils {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    static {
+        //  忽略value为null时,key的输出
+        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
+        MAPPER.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        //  配置反序列化时,禁用对日期以时间戳方式输出的特性
+        MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        MAPPER.registerModule(new JavaTimeModule());
+
+        SimpleModule module = new SimpleModule();
+        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
+        module.addSerializer(Long.class, ToStringSerializer.instance);
+        MAPPER.registerModule(module);
+    }
+
+    /**
+     * 将对象转为 Json 字符串
+     * @param data 对象
+     * @return json 字符串
+     *                  
+     *                       
+     */
+    public static String objectToJson(Object data){
+        try{
+            return MAPPER.writeValueAsString(data);
+        }catch (JsonProcessingException e){
+            log.error("将对象转为 Json 字符串时出现了异常");
+            log.error(e.getMessage());
+            return "";
+        }
+    }
+
+    /**
+     * 将 json 字符串转换为对象
+     * @param jsonData json 字符串
+     * @param beanType 对象类型
+     * @return T
+     *                  
+     *                       
+     */
+    public static <T> T jsonToPojo(String jsonData,Class<T> beanType){
+        try{
+            return MAPPER.readValue(jsonData,beanType);
+        }catch (Exception e){
+            log.error("将 json 字符串转换为对象时出现了异常");
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 将 Json 字符串转换成对象集合
+     * @param jsonData json 字符串
+     * @param beanType 集合类型
+     * @return List<T>
+     *                  
+     *                       
+     */
+    public static <T> List<T> jsonToList(String jsonData,Class<T> beanType){
+        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
+        try {
+            return MAPPER.readValue(jsonData, javaType);
+        } catch (Exception e) {
+            log.error("将 Json 字符串转换成对象集合时出现了异常");
+            log.error(e.getMessage());
+            return new ArrayList<>(0);
+        }
+    }
+
+    /**
+     * list转成string类型,中间用逗号隔开
+     * @param list
+     * @return
+     */
+    public static String listToString(List list){
+        String[] strArrStrings = new String[list.size()];
+        String resultString = "";
+
+        for(int i=0;i<=list.size()-1;i++){
+            strArrStrings[i] = (String) list.get(i);
+        }
+
+        for(int j=0;j<=strArrStrings.length-1;j++){
+            if(j < strArrStrings.length-1){
+                resultString += strArrStrings[j] + ",";
+            }else{
+                resultString += strArrStrings[j];
+            }
+        }
+        return resultString;
+    }
+}

+ 97 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/TreeUtil.java

@@ -0,0 +1,97 @@
+package com.sptg.common.core.util;
+
+import java.util.*;
+
+/**
+ * title: TreeUtil
+ * package: com.sptg.common.core.util
+ * description: 树形工具类
+ *
+ *                  
+ *                 
+ */
+public class TreeUtil {
+
+    public interface TreeEntity<Entity>{
+        /**
+         * 获取主键
+         * @return Long
+         */
+        Long getId();
+
+        /**
+         * 父级Id
+         * @return Long
+         */
+        Long getPid();
+
+        /**
+         * 排序值
+         * @return Integer
+         */
+        Integer getSort();
+
+        /**
+         * 设置子节点
+         * @param entityList 子节点列表
+         */
+        void setSubList(List<Entity> entityList);
+
+        /**
+         * 获取子节点
+         * @return List<Entity>
+         */
+        List<Entity> getSubList();
+    }
+
+    public static <Entity extends TreeEntity<Entity>> List<Entity> tree(List<Entity> entityList){
+        if (entityList.size() == 0){
+            return entityList;
+        }
+        entityList.sort(Comparator.comparing(Entity :: getSort));
+        Map<Long, List<Entity>> groupMap = new HashMap<>(16);
+        entityList.forEach(entity -> {
+            List<Entity> list = groupMap.get(entity.getPid());
+            if (null == list){
+                list = new ArrayList<>();
+                list.add(entity);
+                groupMap.put(entity.getPid(),list);
+            }else {
+                list.add(entity);
+            }
+        });
+        //  得到Pid列表
+        List<Long> pidList = new ArrayList<>(groupMap.keySet());
+        pidList.sort(Comparator.comparing(Long::longValue));
+        for (int i = pidList.size() - 1; i > 0; i--){
+            //  数值最大的Pid
+            long thisKey = pidList.get(i);
+            //  寻找父节点
+            for (int j = i - 1; j >= 0; j--){
+                //  距离最近Pid
+                long lastKey = pidList.get(j);
+                List<Entity> list = groupMap.get(lastKey);
+                //  递归
+                if (recursion(list,thisKey,groupMap)){
+                    break;
+                }
+            }
+        }
+        return groupMap.get(pidList.get(0));
+    }
+
+    private static <Entity extends TreeEntity<Entity>> boolean recursion(List<Entity> list,long thisKey,Map<Long, List<Entity>> groupMap){
+        for (Entity entity : list){
+            if (entity.getId().equals(thisKey)){
+                List<Entity> children = groupMap.get(thisKey);
+                entity.setSubList(children);
+                groupMap.remove(thisKey);
+                return true;
+            }else if (null != entity.getSubList()){
+                return recursion(entity.getSubList(),thisKey,groupMap);
+            }
+        }
+        return false;
+    }
+
+}

+ 40 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/VersionUtil.java

@@ -0,0 +1,40 @@
+package com.sptg.common.core.util;
+
+/**
+ * @author WFT
+ * @date 2020/6/20
+ * description:
+ */
+public class VersionUtil {
+
+    /**
+     * 版本号比较
+     * @param version1 旧的版本号
+     * @param version2 新的版本号
+     * @return true:新版本大于旧版本,false:新版本小于或等于旧版本
+     */
+    public static boolean compareTo(String version1,String version2){
+        String[] arr1 = version1.split("\\.");
+        String[] arr2 = version2.split("\\.");
+
+        int len;
+        if (arr1.length == arr2.length){
+            len = arr1.length;
+        } else {
+            len = arr1.length > arr2.length ? arr2.length : arr1.length;
+        }
+
+        for (int i = 0; i < len; i++){
+            int flag = arr1[i].length() - arr2[i].length();
+            if (flag == 0){
+                flag = arr1[i].compareTo(arr2[i]);
+                if (flag == 0){
+                    continue;
+                }
+            }
+            return flag < 0;
+        }
+        return false;
+    }
+
+}

+ 133 - 0
sptg-common/sptg-common-core/src/main/java/com/sptg/common/core/util/WebUtils.java

@@ -0,0 +1,133 @@
+package com.sptg.common.core.util;
+
+import com.sptg.common.core.constant.CommonConstant;
+import com.sptg.common.core.constant.HttpConstant;
+import com.sptg.common.core.constant.SymbolConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * title: WebUtils
+ * package: com.sptg.common.core.util
+ * description: Web工具类
+ *                  
+ *                
+ */
+@Slf4j
+public class WebUtils {
+
+//    /**
+//     * 获取 ServletRequestAttributes
+//     * @return ServletRequestAttributes
+//     */
+//    public static ServletRequestAttributes getRequestAttributes(){
+//        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+//        return null == attributes ? null : (ServletRequestAttributes) attributes;
+//    }
+
+    /**
+     * 获取 HttpServletRequest
+     * @return HttpServletRequest
+     */
+    public static HttpServletRequest getHttpServletRequest(){
+        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+    }
+
+    /**
+     * 获取 HttpServletResponse
+     * @return HttpServletResponse
+     */
+    public static HttpServletResponse getHttpServletResponse(){
+        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+    }
+
+    /**
+     * 获取Ip
+     * @return Ip
+     */
+    public static String getIp(){
+        HttpServletRequest request = WebUtils.getHttpServletRequest();
+        //  获取远程地址
+        String ip = request.getRemoteAddr();
+        for (String ipHeader : HttpConstant.IP_HEADER_ARRAY) {
+            String value = request.getHeader(ipHeader);
+            if (!StringUtils.isEmpty(value) && !value.equalsIgnoreCase(HttpConstant.UNKNOWN)){
+                ip = value;
+                break;
+            }
+        }
+        return StringUtils.isEmpty(ip) ? null : ip.split(SymbolConstant.COMMA)[0];
+    }
+
+    /**
+     * 功能描述: 获取请求体数据
+     * @param request 请求信息
+     * @return String
+     *                  
+     *                     
+     */
+    public static String getRequestBody(HttpServletRequest request)throws IOException{
+        byte[] buffer = getRequestBodys(request);
+        String encoding = request.getCharacterEncoding();
+        if (null == encoding){
+            encoding = CommonConstant.UTF_8;
+        }
+        return new String(buffer, encoding);
+    }
+
+    /**
+     * 功能描述: 获取请求体二进制数据
+     * @param request 请求信息
+     * @return byte[]
+     *                  
+     *                     
+     */
+    private static byte[] getRequestBodys(HttpServletRequest request)throws IOException {
+        int contentLength = request.getContentLength();
+        byte[] buffer = new byte[contentLength];
+        ServletInputStream inputStream = request.getInputStream();
+        for (int i = 0; i < contentLength;){
+            int readLen = inputStream.read(buffer, i, contentLength - i);
+            if (readLen == -1){
+                break;
+            }
+            i += readLen;
+        }
+        return buffer;
+    }
+
+    /**
+     * 功能描述: 写入数据到输出流
+     * @param response 相应体
+     * @param data 数据
+     * @param contentType 数据类型
+     *                  
+     *                     
+     */
+    public static void writeResponse(HttpServletResponse response, String data, String contentType){
+        PrintWriter printWriter = null;
+        response.setContentLength(-1);
+        response.setCharacterEncoding(CommonConstant.UTF_8);
+        response.setContentType(contentType);
+        try{
+            printWriter = response.getWriter();
+            printWriter.write(data);
+            printWriter.flush();
+        }catch (IOException e){
+            log.error(e.getMessage(),e);
+        }
+        if (null != printWriter){
+            printWriter.close();
+        }
+    }
+
+
+}

+ 7 - 0
sptg-common/sptg-common-core/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,7 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.sptg.common.core.cfgbeans.ConfigBean,\
+  com.sptg.common.core.cfgbeans.GlobalConfigBean,\
+  com.sptg.common.core.cfgbeans.RestTemplateConfigBean,\
+  com.sptg.common.core.cfgbeans.RedisTemplateConfigBean,\
+  com.sptg.common.core.cfgbeans.AopTypeDtxConfigBean,\
+  com.sptg.common.core.feign.FeignAutoConfiguration

+ 23 - 0
sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/MessageApplication.java

@@ -0,0 +1,23 @@
+package com.sptg.common.core.test;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import com.sptg.common.core.locale.I18Config;
+
+@Configuration
+@EnableAutoConfiguration
+@ComponentScan(value = {
+ "com.sptg.common"
+})
+@Import({
+	I18Config.class
+})
+public class MessageApplication {
+	public static void main(String[] args) {
+        SpringApplication.run(MessageApplication.class, args);
+    }
+}

+ 14 - 0
sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/MessageSourceTestCase.java

@@ -0,0 +1,14 @@
+package com.sptg.common.core.test;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import lombok.extern.slf4j.Slf4j;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = MessageApplication.class)
+@Slf4j
+public class MessageSourceTestCase {
+
+}

+ 36 - 0
sptg-common/sptg-common-core/src/test/java/com/sptg/common/core/test/TestController.java

@@ -0,0 +1,36 @@
+package com.sptg.common.core.test;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.sptg.common.core.locale.I18n;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@RestController
+@RequestMapping(value = "/test")
+@RequiredArgsConstructor
+@Slf4j
+public class TestController {
+	@Autowired
+	private MessageSource messageSource;
+	@I18n("messages")
+	@GetMapping("/index")
+    public ModelAndView index(HttpServletRequest request){
+		 ModelAndView modelAndView=new ModelAndView("index");
+		 Locale locale = LocaleContextHolder.getLocale();
+		 String hello= messageSource.getMessage("hello", null, locale);
+		 log.info("----------------"+hello);
+		 return modelAndView;
+	}
+}

+ 11 - 0
sptg-common/sptg-common-core/src/test/resources/application.yml

@@ -0,0 +1,11 @@
+server:
+  port: 1000
+spring:
+  thymeleaf:
+    mode: HTML5
+    encoding: UTF-8
+    cache: false
+    prefix: classpath:/templates/
+    suffix:  .html
+    servlet:
+      content-type: text/html

+ 1 - 0
sptg-common/sptg-common-core/src/test/resources/i18n/messages_zh_CN.properties

@@ -0,0 +1 @@
+hello=\u6d4b\u8bd5222dd

+ 8 - 0
sptg-common/sptg-common-core/src/test/resources/templates/index.html

@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
+    <head>
+    </head>
+    <body class="layui-layout-body">
+    <span th:text="|#{hello}设备序列号登记表|"></span> 
+    </body>
+</html>

+ 34 - 0
sptg-common/sptg-common-security/pom.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sptg-common</artifactId>
+        <groupId>com.sptg</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sptg-common-security</artifactId>
+    <description>权限校验组件</description>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+        <!-- ===================================== Or JAR ===================================== -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- ===================================== Modular JAR ===================================== -->
+        <dependency>
+            <groupId>com.sptg</groupId>
+            <artifactId>sptg-common-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+
+    </dependencies>
+
+</project>

+ 30 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/annotation/Security.java

@@ -0,0 +1,30 @@
+package com.sptg.common.security.annotation;
+
+import com.sptg.common.security.enums.DataFormatEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * title: Security
+ * package: com.sptg.common.security.annotation
+ * description: 安全注解
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Security {
+
+    /**
+     * 功能描述:访问令牌
+     */
+    String[] token() default {};
+
+    /**
+     * 功能描述: 返回的数据格式
+     * @return 默认值为视图
+     */
+    DataFormatEnum format() default DataFormatEnum.VIEW;
+
+}

+ 31 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/cfgbeans/SecurityConfigBean.java

@@ -0,0 +1,31 @@
+package com.sptg.common.security.cfgbeans;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+
+/**
+ * title: SecurityConfigBean
+ * package: com.sptg.common.security.cfgbeans
+ * description: 安全配置
+ *
+ *                  
+ *                 
+ */
+@Configuration
+public class SecurityConfigBean {
+
+    @Bean(name = "redisTemplate")
+    @ConditionalOnMissingBean(value = RedisTemplate.class)
+    public RedisTemplate<Object, Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory){
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(redisConnectionFactory);
+        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
+        return template;
+    }
+
+}

+ 49 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/cfgbeans/SecurityMvcConfigBean.java

@@ -0,0 +1,49 @@
+package com.sptg.common.security.cfgbeans;
+
+import com.sptg.common.security.interceptor.SecurityInterceptor;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * title: SecurityMvcConfigBean
+ * package: com.sptg.common.security.cfgbeans
+ * description: WEB相关配置
+ *
+ *                  
+ *                 
+ */
+@Configuration
+public class SecurityMvcConfigBean implements ApplicationContextAware, WebMvcConfigurer {
+
+    private ApplicationContext applicationContext;
+
+    /**
+     * 添加拦截器
+     * @param registry 拦截器注册表
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        //  添加权限拦截器
+        registry.addInterceptor(this.getSecurityInterceptor()).addPathPatterns("/**");
+    }
+
+    /**
+     * 功能描述: 从Spring容器中获取Bean
+     * @return 权限拦截器
+     *                  
+     *                       
+     */
+    private SecurityInterceptor getSecurityInterceptor(){
+        return this.applicationContext.getBean(SecurityInterceptor.class);
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+}

+ 23 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/enums/DataFormatEnum.java

@@ -0,0 +1,23 @@
+package com.sptg.common.security.enums;
+
+/**
+ * title: DataFormatEnum
+ * package: com.sptg.common.security.enums
+ * description: 数据格式枚举
+ *                  
+ *                 
+ */
+public enum DataFormatEnum {
+
+    /**
+     * Json
+     */
+    JSON,
+
+    /**
+     * 页面
+     */
+    VIEW,
+    ;
+
+}

+ 12 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/BodyAuthenticationException.java

@@ -0,0 +1,12 @@
+package com.sptg.common.security.exception;
+
+/**
+ * title: BodyAuthenticationException
+ * package: com.sptg.common.security.exception
+ * description: 响应体认证失败
+ *
+ *                  
+ *                 
+ */
+public class BodyAuthenticationException extends RuntimeException {
+}

+ 12 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/BodyAuthorizationException.java

@@ -0,0 +1,12 @@
+package com.sptg.common.security.exception;
+
+/**
+ * title: BodyAuthorizationException
+ * package: com.sptg.common.security.exception
+ * description: 响应体授权失败
+ *
+ *                  
+ *                 
+ */
+public class BodyAuthorizationException extends RuntimeException {
+}

+ 12 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/ViewAuthenticationException.java

@@ -0,0 +1,12 @@
+package com.sptg.common.security.exception;
+
+/**
+ * title: ViewAuthenticationException
+ * package: com.sptg.common.security.exception
+ * description: 页面认证失败
+ *
+ *                  
+ *                 
+ */
+public class ViewAuthenticationException extends RuntimeException {
+}

+ 12 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/exception/ViewAuthorizationException.java

@@ -0,0 +1,12 @@
+package com.sptg.common.security.exception;
+
+/**
+ * title: ViewAuthorizationException
+ * package: com.sptg.common.security.exception
+ * description: 页面授权失败
+ *
+ *                  
+ *                 
+ */
+public class ViewAuthorizationException extends RuntimeException {
+}

+ 94 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/interceptor/SecurityInterceptor.java

@@ -0,0 +1,94 @@
+package com.sptg.common.security.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.sptg.common.core.beans.UserBean;
+import com.sptg.common.security.annotation.Security;
+import com.sptg.common.security.enums.DataFormatEnum;
+import com.sptg.common.security.exception.BodyAuthenticationException;
+import com.sptg.common.security.exception.BodyAuthorizationException;
+import com.sptg.common.security.exception.ViewAuthenticationException;
+import com.sptg.common.security.exception.ViewAuthorizationException;
+import com.sptg.common.security.service.SecurityServiceInterface;
+
+/**
+ * title: SecurityInterceptor
+ * package: com.sptg.common.security.interceptor
+ * description: 权限拦截器
+ */
+public class SecurityInterceptor<Account extends UserBean> extends HandlerInterceptorAdapter {
+
+    private final SecurityServiceInterface<Account> securityServiceInterface;
+
+
+    public SecurityInterceptor(SecurityServiceInterface<Account> securityServiceInterface){
+        this.securityServiceInterface = securityServiceInterface;
+    }
+
+    /**
+     * 功能描述: 预处理方法
+     * @param request 请求信息
+     * @param response 响应信息
+     * @param handler 响应方法
+     * @return boolean 是否拦截
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
+        if (handler instanceof HandlerMethod){
+            // 将handler强转为HandlerMethod
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            // 从方法处理器中获取出要调用的方法
+            Method method = handlerMethod.getMethod();
+            //  获取方法上的权限注解
+            Security security = method.getAnnotation(Security.class);
+            //  获取用户
+            Account onLineUser = this.securityServiceInterface.getOnLineUser();
+            //  判断是否需要校验登陆
+            if (null != security){
+                if (null == onLineUser){
+                    //  认证失败
+                    throw this.throwsErrorByIsBody(security, BodyAuthenticationException.class, ViewAuthenticationException.class);
+                }
+                //  判断是否需要校验权限
+                if (security.token().length > 0){
+                    //  获取用户的权限列表
+                    List<String> tokenList = onLineUser.getTokenList();
+                    //  权限校验
+                    boolean result = tokenList.stream().anyMatch(x -> PatternMatchUtils.simpleMatch(security.token(), x));
+                    if (!result){
+                        //  授权失败
+                        throw this.throwsErrorByIsBody(security,BodyAuthorizationException.class, ViewAuthorizationException.class);
+                    }
+                }
+            }
+            request.setAttribute("onLineUser",onLineUser);
+        }
+        return true;
+    }
+
+    /**
+     * 功能描述: 根据接口返回值的类型抛出对应的异常
+     * @param security 权限注解
+     * @param bodyError 响应体(认证/授权)异常
+     * @param viewError 页面(认证/授权)异常
+     */
+    private RuntimeException throwsErrorByIsBody(Security security,
+                                     Class bodyError,
+                                     Class viewError) throws Exception{
+        //  判断接口返回值的类型是否为Json
+        if (DataFormatEnum.JSON.equals(security.format())){
+            return (RuntimeException) bodyError.newInstance();
+        }else {
+            return (RuntimeException) viewError.newInstance();
+        }
+    }
+
+}

+ 72 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/service/SecurityServiceInterface.java

@@ -0,0 +1,72 @@
+package com.sptg.common.security.service;
+
+import com.sptg.common.core.beans.UserBean;
+
+import java.util.List;
+
+/**
+ * title: SecurityServiceInterface
+ * package: com.sptg.common.security.security
+ * description: 安全接口
+ *
+ *                  
+ *                 
+ */
+public interface SecurityServiceInterface<Account extends UserBean> {
+
+    /**
+     * 功能描述: 创建用户令牌
+     * @param account 用户信息
+     *                  
+     * @return String 用户令牌
+     *                       
+     */
+    String createUserToken(Account account);
+
+    /**
+     * 功能描述: 获取登陆用户信息
+     *                  
+     *                       
+     * @return UserBean
+     */
+    Account getOnLineUser();
+
+    /**
+     * 功能描述:删除用户令牌
+     *                  
+     *                       
+     */
+    void removeUserToken();
+
+    /**
+     * 功能描述: 是否已登陆
+     * @return true 已登陆,false 未登陆
+     *                  
+     *                       
+     */
+    boolean isLogin();
+
+    /**
+     * 功能描述: 获取所有的登陆用户
+     * @return List<Account>
+     *                  
+     *                       
+     */
+    List<Account> getOnLineUserList();
+
+    /**
+     * 功能描述: 强制退出
+     * @param token 用户令牌
+     *                  
+     *                       
+     */
+    void removeUserToken(String token);
+
+    /**
+     * 功能描述: 更新账号
+     * @param account 账号
+     *                  
+     *                       
+     */
+    void updateAccount(Account account);
+}

+ 150 - 0
sptg-common/sptg-common-security/src/main/java/com/sptg/common/security/service/impl/BaseRedisSecurityService.java

@@ -0,0 +1,150 @@
+package com.sptg.common.security.service.impl;
+
+import com.sptg.common.core.beans.UserBean;
+import com.sptg.common.core.constant.HttpConstant;
+import com.sptg.common.core.constant.SymbolConstant;
+import com.sptg.common.core.util.CookieUtils;
+import com.sptg.common.core.util.JsonUtils;
+import com.sptg.common.security.service.SecurityServiceInterface;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * title: BaseRedisSecurityService
+ * package: com.sptg.common.security.security.impl
+ * description: Redis安全接口抽象类
+ *
+ *                  
+ *                 
+ */
+@RequiredArgsConstructor
+public abstract class BaseRedisSecurityService<Account extends UserBean> implements SecurityServiceInterface<Account> {
+
+    private final RedisTemplate<String,String> redisTemplate;
+
+    /* -------------------------------------------------------------------------------------------------------------- */
+
+    @Override
+    public String createUserToken(Account account) {
+        //  生成Token 用户类型:UUID
+        String token = UUID.randomUUID().toString();
+        account.setLoginToken(token);
+        this.updateAccount(account);
+        return token;
+    }
+
+    @Override
+    public void removeUserToken() {
+        //  获得用户访问令牌
+        String token = this.getTokenByRequest();
+        if (!StringUtils.isEmpty(token)){
+            this.removeUserToken(token);
+            //  删除Cookie
+            CookieUtils.deleteCookie(HttpConstant.ACCESS_TOKEN);
+        }
+    }
+
+    @Override
+    public boolean isLogin() {
+        String token = this.getTokenByRequest();
+        if (!StringUtils.isEmpty(token)){
+            String key = this.generateKey(token);
+            //  判断key是否存在
+            return this.redisTemplate.hasKey(key);
+        }
+        return false;
+    }
+
+    /**
+     * 功能描述: 生成Key
+     * @param token 登陆令牌
+     * @return String
+     *                  
+     *                       
+     */
+    private String generateKey(String token){
+        return this.getCacheName() + token;
+    }
+
+    @Override
+    public Account getOnLineUser() {
+        String token = this.getTokenByRequest();
+        if (!StringUtils.isEmpty(token)) {
+            String key = this.generateKey(token);
+            //  从缓存中获取用户信息
+            String json = this.redisTemplate.opsForValue().get(key);
+            if (!StringUtils.isEmpty(json)) {
+                //  更新缓存有效期
+                this.redisTemplate.expire(key, this.getTimeOut(), TimeUnit.SECONDS);
+                return jsonToPojo(json);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 从请求中获取用户令牌
+     * @return String
+     */
+    protected abstract String getTokenByRequest();
+
+    /**
+     * 获取缓存名称
+     * @return String
+     */
+    protected abstract String getCacheName();
+
+    /**
+     * 获取登陆超时时间
+     * @return 秒
+     */
+    protected abstract long getTimeOut();
+    
+    /**
+     * 功能描述: json转账号类型
+     * @param json 账号json
+     * @return Account 账号类型
+     *                  
+     *                       
+     */
+    protected abstract Account jsonToPojo(String json);
+
+    @Override
+    public List<Account> getOnLineUserList() {
+        //  获取缓存中的所有key
+        Set<String> keys = this.redisTemplate.keys(this.getCacheName() + SymbolConstant.ASTERISK);
+        if (null == keys){
+            return new ArrayList<>(0);
+        }
+        List<Account> onLineUserList = new ArrayList<>(keys.size());
+        keys.forEach(key -> {
+            String json = this.redisTemplate.opsForValue().get(key);
+            Account account = this.jsonToPojo(json);
+            onLineUserList.add(account);
+        });
+        return onLineUserList;
+    }
+
+    @Override
+    public void removeUserToken(String token) {
+        //  创建Key
+        String key = this.generateKey(token);
+        //  将缓存中的用户信息删除
+        this.redisTemplate.delete(key);
+    }
+
+    @Override
+    public void updateAccount(Account account) {
+        String key = this.generateKey(account.getLoginToken());
+        String json = JsonUtils.objectToJson(account);
+        this.redisTemplate.opsForValue().set(key,json);
+        this.redisTemplate.expire(key, this.getTimeOut(), TimeUnit.SECONDS);
+    }
+}

+ 3 - 0
sptg-common/sptg-common-security/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,3 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.sptg.common.security.cfgbeans.SecurityConfigBean,\
+  com.sptg.common.security.cfgbeans.SecurityMvcConfigBean

+ 33 - 0
sptg-common/sptg-common-tag/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sptg-common</artifactId>
+        <groupId>com.sptg</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sptg-common-tag</artifactId>
+    <packaging>jar</packaging>
+    <description>自定义标签组件</description>
+
+    <dependencies>
+        <!-- ===================================== Spring Boot JAR ===================================== -->
+        <!-- thymeleaf -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sptg</groupId>
+            <artifactId>sptg-common-core</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+
+    </dependencies>
+
+</project>

+ 56 - 0
sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/cfgbeans/ThymeleafAutoConfigBean.java

@@ -0,0 +1,56 @@
+package com.sptg.common.tag.cfgbeans;
+
+import com.sptg.common.tag.dialect.CustomDialect;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.CollectionUtils;
+import org.thymeleaf.dialect.IDialect;
+import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.templateresolver.ITemplateResolver;
+
+import java.util.Collection;
+
+/**
+ * title: ThymeleafAutoConfigBean
+ * package: com.sptg.common.tag.cfgbeans
+ * description:
+ *
+ *                  
+ *                 
+ */
+@Configuration
+public class ThymeleafAutoConfigBean {
+
+
+    @Configuration
+    @ConditionalOnMissingBean(SpringTemplateEngine.class)
+    protected static class ThymeleafDefaultConfiguration {
+
+        private final Collection<ITemplateResolver> templateResolvers;
+
+        private final Collection<IDialect> dialects;
+
+        public ThymeleafDefaultConfiguration(
+                Collection<ITemplateResolver> templateResolvers,
+                ObjectProvider<Collection<IDialect>> dialectsProvider) {
+            this.templateResolvers = templateResolvers;
+            this.dialects = dialectsProvider.getIfAvailable();
+        }
+
+        @Bean
+        public SpringTemplateEngine templateEngine() {
+            SpringTemplateEngine engine = new SpringTemplateEngine();
+            this.templateResolvers.forEach(engine::addTemplateResolver);
+            if (!CollectionUtils.isEmpty(this.dialects)) {
+                this.dialects.forEach(engine::addDialect);
+            }
+            //  加入自定义方言
+            engine.addDialect(new CustomDialect());
+            return engine;
+        }
+
+    }
+
+}

+ 41 - 0
sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/dialect/CustomDialect.java

@@ -0,0 +1,41 @@
+package com.sptg.common.tag.dialect;
+
+import com.sptg.common.tag.processor.CustomSessionIdTagProcessor;
+import com.sptg.common.tag.processor.SecurityTagProcessor;
+import org.thymeleaf.dialect.AbstractProcessorDialect;
+import org.thymeleaf.processor.IProcessor;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * title: CustomDialect
+ * package: com.sptg.common.tag.dialect
+ * description: 自定义方言
+ *
+ *                  
+ *                 
+ */
+public class CustomDialect extends AbstractProcessorDialect {
+
+    private static final String NAME = "Standard";
+    private static final String PREFIX = "sptg";
+    private static final int PROCESSOR_PRECEDENCE = 1000;
+
+    public CustomDialect(){
+        super(NAME,PREFIX,PROCESSOR_PRECEDENCE);
+    }
+
+    @Override
+    public Set<IProcessor> getProcessors(String dialectPrefix) {
+        return CustomDialect.createStandardProcessorsSet(dialectPrefix);
+    }
+
+    private static Set<IProcessor> createStandardProcessorsSet(final String dialectPrefix){
+        final Set<IProcessor> processors = new LinkedHashSet<>();
+        processors.add(new CustomSessionIdTagProcessor(dialectPrefix));
+        processors.add(new SecurityTagProcessor(dialectPrefix));
+        return processors;
+    }
+
+}

+ 52 - 0
sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/processor/CustomSessionIdTagProcessor.java

@@ -0,0 +1,52 @@
+package com.sptg.common.tag.processor;
+
+import org.thymeleaf.context.ITemplateContext;
+import org.thymeleaf.context.WebEngineContext;
+import org.thymeleaf.engine.AttributeName;
+import org.thymeleaf.model.IProcessableElementTag;
+import org.thymeleaf.processor.element.IElementTagStructureHandler;
+import org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor;
+import org.thymeleaf.templatemode.TemplateMode;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * title: CustomSessionIdTagProcessor
+ * package: com.sptg.common.tag.processor
+ * description: 自定义测试标签
+ *
+ *                  
+ *                 
+ */
+public class CustomSessionIdTagProcessor extends AbstractStandardExpressionAttributeTagProcessor {
+
+    private static final int PRECEDENCE = 1000;
+    private static final String ATTR_NAME = "sessionId";
+
+
+    public CustomSessionIdTagProcessor(final String dialectPrefix) {
+        super(TemplateMode.HTML, dialectPrefix, ATTR_NAME, PRECEDENCE, false, false);
+    }
+
+    @Override
+    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, Object expressionResult, IElementTagStructureHandler structureHandler) {
+        if (context instanceof WebEngineContext){
+            WebEngineContext webEngineContext = (WebEngineContext)context;
+            //  获取request对象
+            HttpServletRequest request = webEngineContext.getRequest();
+            String sessionId = request.getRequestedSessionId();
+
+            structureHandler.setBody(ATTR_NAME + ":" + sessionId, false);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+}

+ 58 - 0
sptg-common/sptg-common-tag/src/main/java/com/sptg/common/tag/processor/SecurityTagProcessor.java

@@ -0,0 +1,58 @@
+package com.sptg.common.tag.processor;
+
+import com.sptg.common.core.beans.UserBean;
+import org.thymeleaf.context.ITemplateContext;
+import org.thymeleaf.context.WebEngineContext;
+import org.thymeleaf.engine.AttributeName;
+import org.thymeleaf.model.IProcessableElementTag;
+import org.thymeleaf.standard.processor.AbstractStandardConditionalVisibilityTagProcessor;
+import org.thymeleaf.templatemode.TemplateMode;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * title: SecurityTagProcessor
+ * package: com.sptg.common.tag.processor
+ * description: 权限标签
+ *
+ *                  
+ *                
+ */
+public class SecurityTagProcessor extends AbstractStandardConditionalVisibilityTagProcessor {
+
+    private static final String ATTR_NAME = "security";
+
+    public SecurityTagProcessor( final String dialectPrefix) {
+        super(TemplateMode.HTML, dialectPrefix, ATTR_NAME, 300);
+    }
+
+
+    @Override
+    protected boolean isVisible(
+            final ITemplateContext context,
+            final IProcessableElementTag tag,
+            final AttributeName attributeName, final String attributeValue) {
+
+        if (context instanceof WebEngineContext){
+            WebEngineContext webEngineContext = (WebEngineContext)context;
+            //  获取request对象
+            HttpServletRequest request = webEngineContext.getRequest();
+            UserBean onLineUser = (UserBean)request.getAttribute("onLineUser");
+            if (null != onLineUser.getTokenList()){
+                //  判断是否显示
+                return onLineUser.getTokenList().contains(attributeValue);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+}

+ 31 - 0
sptg-common/sptg-common-tag/src/main/resources/META-INF/custom-dialect.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   Copyright 2013, The Thymeleaf Project (http://www.thymeleaf.org/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<dialect xmlns="http://www.thymeleaf.org/extras/dialect"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://www.thymeleaf.org/extras/dialect http://www.thymeleaf.org/xsd/thymeleaf-extras-dialect-3.0.xsd"
+         prefix="sptg"
+         namespace-uri="http://www.thymeleaf.org/sptg"
+         namespace-strict="false"
+         class="com.sptg.common.tag.dialect.CustomDialect">
+
+    <!-- 注册自定义标签 -->
+    <attribute-processor name="sessionId" class="com.sptg.common.tag.processor.CustomSessionIdTagProcessor"/>
+    <attribute-processor name="security" class="com.sptg.common.tag.processor.SecurityTagProcessor"/>
+
+</dialect>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.