Browse Source

初始化

欧阳劲驰 3 months ago
parent
commit
7103d8370c
52 changed files with 3445 additions and 188 deletions
  1. 29 0
      custom-gateway-app/pom.xml
  2. 2 2
      src/main/java/com/shkpr/service/customgateway/CustomGateWayApplication.java
  3. 7 0
      custom-gateway-app/src/main/resources/application.yml
  4. 127 0
      custom-gateway-app/src/main/resources/logback.xml
  5. 20 0
      custom-gateway-app/src/test/java/com/shkpr/service/CustomGatewayApplicationTests.java
  6. BIN
      custom-gateway-core/libs/gbase.1.0.5.jar
  7. 47 0
      custom-gateway-core/pom.xml
  8. 9 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/ProjectRouter.java
  9. 10 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/AsyncTaskConfig.java
  10. 4 4
      src/main/java/com/shkpr/service/customgateway/config/GatewayConfig.java
  11. 10 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/TempFileConfig.java
  12. 121 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/WebMvcConfig.java
  13. 74 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/WebSecurityConfiguration.java
  14. 77 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/ApiURI.java
  15. 15 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/CommDefine.java
  16. 87 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/LogFlagBusiType.java
  17. 130 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/ResponseCode.java
  18. 69 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/CommonToken.java
  19. 19 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/LatLngBean.java
  20. 18 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/ResponseRes.java
  21. 14 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/exception/SelfAuthFilterException.java
  22. 40 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/ApiJWTBizFilterMgr.java
  23. 26 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/CustomAuthenticationProvider.java
  24. 138 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/JWTAuthenticationFilter.java
  25. 183 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/JWTControllerCheck.java
  26. 26 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/interfaces/URIInterceptorIntef.java
  27. 28 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/interfaces/sinks/LogPrintSink.java
  28. 27 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/manager/TraceLogMgr.java
  29. 59 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/AsyncTaskProperties.java
  30. 11 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/AuthenticationProperties.java
  31. 35 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/InfluxDbProperties.java
  32. 21 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/RouterProperties.java
  33. 32 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/TempFileProperties.java
  34. 207 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/storage/GlobalData.java
  35. 41 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/storage/UserStore.java
  36. 516 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/CommTool.java
  37. 208 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/HttpTool.java
  38. 1 1
      src/main/java/com/shkpr/service/customgateway/commtools/NameUtils.java
  39. 52 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/SpringContextUtil.java
  40. 513 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/TimeTool.java
  41. 263 0
      custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/TokenAuthenticationService.java
  42. 2 0
      custom-gateway-core/src/main/resources/application.yml
  43. 38 0
      custom-gateway-core/src/test/java/com/shkpr/service/customgateway/core/CustomGatewayCoreApplicationTests.java
  44. 24 0
      custom-gateway-zydma/pom.xml
  45. 4 0
      custom-gateway-zydma/src/main/java/com/shkpr/service/zydma/controller/TeatController.java
  46. 38 0
      custom-gateway-zydma/src/test/java/com/shkpr/service/zydma/ZydmApplicationTests.java
  47. 23 4
      pom.xml
  48. 0 63
      src/main/java/com/shkpr/service/customgateway/domain/PredicateDefinition.java
  49. 0 50
      src/main/java/com/shkpr/service/customgateway/domain/RouteDefinition.java
  50. 0 24
      src/main/java/com/shkpr/service/customgateway/properties/GatewayProperties.java
  51. 0 11
      src/main/resources/application.yml
  52. 0 29
      src/test/java/com/shkpr/service/customgateway/CustomGateWayApplicationTests.java

+ 29 - 0
custom-gateway-app/pom.xml

@@ -0,0 +1,29 @@
+<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>
+    <!--父工程信息-->
+    <parent>
+        <groupId>com.shkpr.service</groupId>
+        <artifactId>kpr-custom-gateway</artifactId>
+        <version>1.0.0-dev</version>
+    </parent>
+
+    <!--工件名-->
+    <artifactId>custom-gateway-app</artifactId>
+    <!--打包方式-->
+    <packaging>jar</packaging>
+    <!--项目名-->
+    <name>CustomGatewayApp</name>
+    <!--项目描述-->
+    <description>启动模块</description>
+
+    <!--依赖项-->
+    <dependencies>
+        <!--枣阳漏控-->
+        <dependency>
+            <groupId>com.shkpr.service</groupId>
+            <artifactId>custom-gateway-zydma</artifactId>
+            <version>1.0.0-dev</version>
+        </dependency>
+    </dependencies>
+</project>

+ 2 - 2
src/main/java/com/shkpr/service/customgateway/CustomGateWayApplication.java

@@ -10,8 +10,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
  * @since 1.0.0
  */
 @SpringBootApplication
-public class CustomGateWayApplication {
+public class CustomGatewayApplication {
     public static void main(String[] args) {
-        SpringApplication.run(CustomGateWayApplication.class, args);
+        SpringApplication.run(CustomGatewayApplication.class, args);
     }
 }

+ 7 - 0
custom-gateway-app/src/main/resources/application.yml

@@ -0,0 +1,7 @@
+#spring
+spring:
+  application:
+    name: KprCustomGateway
+#web
+server:
+  port: 9011

+ 127 - 0
custom-gateway-app/src/main/resources/logback.xml

@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--日志级别高低TRACE < DEBUG < INFO < WARN < ERROR < FATAL-->
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!--引用外部配置文件中的变量属性-->
+    <!--<property scope="context" resource="application.properties" />
+    <springProperty scope="context" name="log.dir" source="hgas.log.dir"/>
+    <springProperty scope="context" name="log.appname" source="hgas.log.appname"/>-->
+    <contextName>TriCP</contextName>
+    <!-- 自定义内部变量属性-->
+    <property name="log.dir" value="./trilog/log"/>
+    <property name="log.appname" value="tri"/>
+
+
+    <!--输出到控制台-->
+    <appender name="consoleOutput" class="ch.qos.logback.core.ConsoleAppender">
+        <!-- 如果要过滤掉ERROR级别以下的日志请启用该行
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>ERROR</level>
+        </filter>
+        -->
+
+        <!--对日志格式进行编码-->
+        <!--%d{HH: mm:ss.SSS}——日志输出时间-->
+        <!--%thread——输出日志的进程名字-->
+        <!--%-5level——日志级别,并且使用5个字符靠左对齐-->
+        <!--%logger{36}——日志输出者的名字-->
+        <!--%msg——日志消息-->
+        <!--%n——平台的换行符-->
+        <encoder>
+            <!--<pattern>%d{HH: mm:ss.SSS} %contextName {%thread} %-5level %logger{36} - %msg%n</pattern>-->
+            <pattern>%d{HH: mm:ss.SSS} %contextName %-5level %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!--输出到文件-->
+    <appender name="fileInfoOutput" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
+        如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
+        的日志改名为今天的日期。即,<File> 的日志都是当天的。
+        -->
+        <File>${log.dir}/info.${log.appname}.log</File>
+
+        <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Warn 日志,因为 Warn 的级别高,
+        所以我们使用下面的策略,可以避免输出 Warn 的日志-->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>Info</level>               <!--过滤Warn-->
+            <onMatch>ACCEPT</onMatch>         <!--匹配到就运行-->
+            <onMismatch>DENY</onMismatch>    <!--没有匹配到就拒绝-->
+        </filter>
+
+        <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
+            <FileNamePattern>${log.dir}/info.${log.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <!--只保留最近180天的日志-->
+            <maxHistory>180</maxHistory>
+            <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
+            <totalSizeCap>10GB</totalSizeCap>
+        </rollingPolicy>
+
+        <!--日志输出编码格式化-->
+        <encoder>
+            <charset>UTF-8</charset>
+            <!--<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>-->
+            <pattern>%d %-5level %msg%n</pattern>
+        </encoder>
+    </appender>
+
+
+    <appender name="fileWarnOutput" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${log.dir}/warn.${log.appname}.log</File>
+
+        <!--过滤出Warn以及以上的级别(Warn、Error)
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>Warn</level>
+        </filter>-->
+
+        <!--再对Error进行过滤-->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>Warn</level>              <!--过滤Error-->
+            <onMatch>ACCEPT</onMatch>       <!--匹配到就允许-->
+            <onMismatch>DENY</onMismatch>  <!--没有匹配到就拒绝-->
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${log.dir}/warn.${log.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <maxHistory>180</maxHistory>
+            <totalSizeCap>1GB</totalSizeCap>
+        </rollingPolicy>
+
+        <encoder>
+            <charset>UTF-8</charset>
+            <!--<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>-->
+            <pattern>%d %-5level %msg%n</pattern>
+        </encoder>
+    </appender>
+
+
+    <appender name="fileErrorOutput" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${log.dir}/error.${log.appname}.log</File>
+
+        <!--过滤出Error以及以上的级别-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>Error</level>
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${log.dir}/error.${log.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <maxHistory>180</maxHistory>
+            <totalSizeCap>1GB</totalSizeCap>
+        </rollingPolicy>
+
+        <encoder>
+            <charset>UTF-8</charset>
+            <!--<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>-->
+            <pattern>%d %-5level %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!--指定最基础的日志输出级别,低于Info级别的信息都不会输出-->
+    <root level="info">
+        <appender-ref ref="consoleOutput" />
+        <appender-ref ref="fileInfoOutput" />
+        <appender-ref ref="fileWarnOutput" />
+        <appender-ref ref="fileErrorOutput" />
+    </root>
+</configuration>

+ 20 - 0
custom-gateway-app/src/test/java/com/shkpr/service/CustomGatewayApplicationTests.java

@@ -0,0 +1,20 @@
+package com.shkpr.service;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * 测试启动类
+ */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class CustomGatewayApplicationTests {
+
+    @Test
+    public void test() {
+
+    }
+
+}

BIN
custom-gateway-core/libs/gbase.1.0.5.jar


+ 47 - 0
custom-gateway-core/pom.xml

@@ -0,0 +1,47 @@
+<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>
+    <!--父工程信息-->
+    <parent>
+        <groupId>com.shkpr.service</groupId>
+        <artifactId>kpr-custom-gateway</artifactId>
+        <version>1.0.0-dev</version>
+    </parent>
+
+    <!--工件名-->
+    <artifactId>custom-gateway-core</artifactId>
+    <!--打包方式-->
+    <packaging>jar</packaging>
+    <!--项目名-->
+    <name>CustomGatewayCore</name>
+    <!--项目描述-->
+    <description>核心模块</description>
+
+    <!--依赖项-->
+    <dependencies>
+        <!--base-->
+        <dependency>
+            <groupId>com.global</groupId>
+            <artifactId>gbase</artifactId>
+            <version>${gbase.version}</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/libs/gbase.${gbase.version}.jar</systemPath>
+        </dependency>
+        <!--spring-security-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <!--jts-->
+        <dependency>
+            <groupId>org.locationtech.jts</groupId>
+            <artifactId>jts-core</artifactId>
+            <version>${jts.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.locationtech.jts.io</groupId>
+            <artifactId>jts-io-common</artifactId>
+            <version>${jts.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 9 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/ProjectRouter.java

@@ -0,0 +1,9 @@
+package com.shkpr.service.customgateway.core;
+
+/**
+ * 项目路由
+ */
+public class ProjectRouter {
+
+
+}

+ 10 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/AsyncTaskConfig.java

@@ -0,0 +1,10 @@
+package com.shkpr.service.customgateway.core.config;
+
+import com.shkpr.service.customgateway.core.properties.AsyncTaskProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(AsyncTaskProperties.class)
+public class AsyncTaskConfig {
+}

+ 4 - 4
src/main/java/com/shkpr/service/customgateway/config/GatewayConfig.java

@@ -1,6 +1,6 @@
-package com.shkpr.service.customgateway.config;
+package com.shkpr.service.customgateway.core.config;
 
-import com.shkpr.service.customgateway.properties.GatewayProperties;
+import com.shkpr.service.customgateway.core.properties.RouterProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
@@ -11,7 +11,7 @@ import org.springframework.context.annotation.Configuration;
  * @since 1.0.0
  */
 @Configuration
-@EnableConfigurationProperties(GatewayProperties.class)
-public class GatewayConfig {
+@EnableConfigurationProperties(RouterProperties.class)
+public class RouterConfig {
 
 }

+ 10 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/TempFileConfig.java

@@ -0,0 +1,10 @@
+package com.shkpr.service.customgateway.core.config;
+
+import com.shkpr.service.customgateway.core.properties.TempFileProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(TempFileProperties.class)
+public class TempFileConfig {
+}

+ 121 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/WebMvcConfig.java

@@ -0,0 +1,121 @@
+package com.shkpr.service.customgateway.core.config;
+
+import com.shkpr.service.customgateway.core.utils.SpringContextUtil;
+import com.shkpr.service.customgateway.core.properties.AsyncTaskProperties;
+import com.shkpr.service.customgateway.core.properties.TempFileProperties;
+import com.shkpr.service.customgateway.core.constants.ApiURI;
+import com.shkpr.service.customgateway.core.interfaces.URIInterceptorIntef;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpMethod;
+import org.springframework.util.StringUtils;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.*;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 该类主要用来注册各种Controller拦截器
+ * WebSecurityConfig类中注册的过滤器JWTLoginFilter、JWTAuthenticationFilter优先于该类中注册的拦截器URIInterceptorIntef
+ * 过滤拦截顺序: JWTLoginFilter--->JWTAuthenticationFilter--->URIInterceptorIntef
+ */
+@Configuration
+@EnableWebMvc
+public class WebMvcConfig implements WebMvcConfigurer {
+    private  TempFileProperties tempFileProperties;
+    private  AsyncTaskProperties asyncTaskProperties;
+
+    public WebMvcConfig(TempFileProperties tempFileProperties , AsyncTaskProperties asyncTaskProperties) {
+        this.tempFileProperties = tempFileProperties;
+        this.asyncTaskProperties = asyncTaskProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        //临时文件映射
+        registry.addResourceHandler(ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_TEMP_FILES + "/**")
+                .addResourceLocations("file:" + tempFileProperties.getResourcePath() + "/");
+        //异步结果映射
+        registry.addResourceHandler(ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_ASYNC_RESULTS + "/**")
+                .addResourceLocations("file:" + asyncTaskProperties.getResultPath() + "/");
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        @SuppressWarnings("static-access")
+        Map<String, URIInterceptorIntef> mapURLInterceptorByOrder = new TreeMap<String, URIInterceptorIntef>(); //TreeMap默认按键值升序
+        Map<String, URIInterceptorIntef> mapURLInterceptor = SpringContextUtil.getApplicationContext().getBeansOfType(URIInterceptorIntef.class);  //获取URIInterceptorIntef类型的所有Component组件
+        if (!StringUtils.isEmpty(mapURLInterceptor)){
+            Iterator it = mapURLInterceptor.entrySet().iterator();
+            while (it.hasNext()){
+                Map.Entry entry = (Map.Entry)it.next();
+                URIInterceptorIntef urlInterceptor = (URIInterceptorIntef)entry.getValue();
+                if (urlInterceptor != null){
+                    mapURLInterceptorByOrder.put(String.valueOf(urlInterceptor.order()), urlInterceptor);
+                }
+            }
+        }
+
+        if (!StringUtils.isEmpty(mapURLInterceptorByOrder)){
+            Iterator it = mapURLInterceptorByOrder.entrySet().iterator();
+            while (it.hasNext()){
+                Map.Entry entry = (Map.Entry)it.next();
+                //System.out.println("WebMvcConfig::addInterceptors() key="+(String) entry.getKey());
+                URIInterceptorIntef urlInterceptor = (URIInterceptorIntef)entry.getValue();
+                if (urlInterceptor != null){
+                    String[] arrForbidUrls = urlInterceptor.forbidPathPatterns();
+                    if (arrForbidUrls == null)
+                        arrForbidUrls = new String[]{};
+                    String[] arrExcludeUrls = urlInterceptor.excludePathPatterns();
+                    if (arrExcludeUrls == null){
+                        //多个拦截器将按照链接的顺序依次匹配拦截(注:有可能多个拦截器都匹配成功,则多个拦截器依次执行)
+                        registry.addInterceptor(urlInterceptor).addPathPatterns(arrForbidUrls);
+                    }else{
+                        registry.addInterceptor(urlInterceptor).addPathPatterns(arrForbidUrls).excludePathPatterns(arrExcludeUrls);
+                    }
+                }
+            }
+        }
+        //super.addInterceptors(registry);
+    }
+
+    //解决跨域问题
+    private CorsConfiguration buildConfig() {
+        CorsConfiguration corsConfiguration = new CorsConfiguration();
+        corsConfiguration.addAllowedOrigin("*");
+        //corsConfiguration.addAllowedMethod("*");
+        corsConfiguration.addAllowedMethod(HttpMethod.POST);
+        corsConfiguration.addAllowedMethod(HttpMethod.GET);
+        corsConfiguration.addAllowedMethod(HttpMethod.PUT);
+        corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
+        corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
+        corsConfiguration.addAllowedMethod(HttpMethod.HEAD);
+        corsConfiguration.addAllowedHeader("x-requested-with,Content-Type,Authorization,user-agent,Timestamp,Sequence,Signature");
+        return corsConfiguration;
+    }
+
+    //解决跨域问题
+    @Bean
+    public CorsFilter corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", buildConfig());
+        return new CorsFilter(source);
+    }
+
+    //配置该服务的默认首页用于阿里云服务SLB的http head健康检查
+    @Override
+    public void addViewControllers(ViewControllerRegistry registry) {
+        registry.addViewController("/").setViewName("index");
+        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
+        //super.addViewControllers(registry);
+    }
+
+}

+ 74 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/config/WebSecurityConfiguration.java

@@ -0,0 +1,74 @@
+package com.shkpr.service.customgateway.core.config;
+
+import com.shkpr.service.customgateway.core.constants.ApiURI;
+import com.shkpr.service.customgateway.core.filter.ApiJWTBizFilterMgr;
+import com.shkpr.service.customgateway.core.filter.CustomAuthenticationProvider;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+/**
+ * 该类主要用来做权限控制的配置、以及注册各种过滤器
+ * 执行顺序
+ * (1) 注册验证组件 - configure(AuthenticationManagerBuilder auth)方法中注册自定义验证组件
+ * (2) 设置验证规则 - configure(HttpSecurity http)方法中设置了各种路由访问规则
+ * (3) 初始化过滤组件 - JWTLoginFilter 和 JWTAuthenticationFilter 类会初始化
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)                     //@PreAuthorize对权限的注解需要设置prePostEnabled = true
+public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
+    @Value("${global.test.pressure:false}")
+    private boolean mBForPressureTest;
+
+    @Value("${global.ops.lan.ip:127.0.0.1}")
+    private String mStrOpsServerLanIP;
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        //使用自定义身份验证组件
+        auth.authenticationProvider(new CustomAuthenticationProvider());
+    }
+
+    // 设置 HTTP 验证规则
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        String[] arrOpsServerLanIPs = mStrOpsServerLanIP.split(";");
+        String strAccessFilterForOps = "hasIpAddress('127.0.0.1')";
+        for (String strTmp : arrOpsServerLanIPs) {
+            strAccessFilterForOps += " or hasIpAddress('" + strTmp + "')";
+        }
+
+        http.csrf().disable()                                          // 关闭csrf验证
+                .authorizeRequests()                                   // 对请求进行认证
+                .antMatchers(ApiURI.URI_ACCESS_TOKEN_CHECK).permitAll()
+                .antMatchers(ApiURI.URI_FILE_BUSI_XXX).permitAll()
+                .antMatchers("/").permitAll()
+                //系统检查结果放行
+                .antMatchers(ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_SYS_CHECK_RESULTS + "/**").permitAll()
+                .anyRequest().permitAll()                                                                                          //所有其他请求需要身份认证
+                .and()
+                .addFilterBefore(new ApiJWTBizFilterMgr(ApiURI.URI_ALL_BUSI_XXX, authenticationManager()),
+                        UsernamePasswordAuthenticationFilter.class)
+                //禁用frame
+                .headers().frameOptions().disable();
+                /*.addFilterBefore(new ServerStatusMonitorFilter(ThirdApiURI.URI_HGAS_MONITOR_XXX, authenticationManager()),
+                        UsernamePasswordAuthenticationFilter.class);*/
+
+    }
+
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        /*web.ignoring()
+                .antMatchers("/error")
+                .antMatchers("/static")
+                .antMatchers("/static/**");                                                               // 所有/static下的静态资源请求时都忽略访问规则
+        */
+    }
+}

+ 77 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/ApiURI.java

@@ -0,0 +1,77 @@
+package com.shkpr.service.customgateway.core.constants;
+
+public class ApiURI {
+    public static final String HEADER_X_SOURCE_IP = "X-Source-IP";
+    public static final String HEADER_BIZ_TYPE = "Biz-Type";
+    public static final String HEADER_CLIENT_TYPE = "Client-Type";
+    public static final String HEADER_USER_AGENT = "user-agent";
+    public static final String HEADER_AUTH_VERIFY = "Auth-Verify";
+    public static final String HEADER_SIGN_KEY = "tri_coorperation_tech_task";
+    public static final String HEADER_TIMESTAMP = "Timestamp";
+    public static final String HEADER_SEQUENCE = "Sequence";
+    public static final String HEADER_SIGNATURE = "Signature";
+    public static final String HEADER_AUTHORIZATION = "Authorization";
+    public static final String EXCEPTION_FORMAT = "{%s:%s}:%s"; //{(ios/apk/pc):url}:error reason
+    public static final String WORKSPACE = "Workspace";
+
+    public static final String URI_XXX_NEW_INFO = "new-info";//新增
+    public static final String URI_XXX_LISTS = "lists"; //分页查询
+    public static final String URI_XXX_RESET = "reset"; //更新(插入或更新)
+    public static final String URI_XXX_SK = "sk";       //以key搜索查询
+    public static final String URI_XXX_SS = "ss";       //模糊搜索查询
+    public static final String URI_XXX_DEL = "del";     //删除
+    public static final String URI_XXX_UPLOAD = "upload";
+    public static final String URI_XXX_DOWNLOAD = "download";
+    public static final String URI_XXX_RESET_PWD = "pwd-reset";
+    public static final String URI_XXX_CHG_PWD = "pwd-chg";
+    public static final String URI_XXX_IMAGES = "images";
+    public static final String URI_XXX_SYS_CHECK = "sys-check";
+    public static final String URI_XXX_SYS_CHECK_CANCEL = "sys-check-cancel";
+    public static final String URI_XXX_SYS_CHECK_RESULTS = "sys-check-results";
+    public static final String URI_XXX_THIRD_IMPORT = "third-import";
+    public static final String URI_XXX_THIRD_IMPORT_GET = "third-import-get";
+    public static final String URI_XXX_THIRD_IMPORT_CANCEL = "third-import-cancel";
+    public static final String URI_XXX_THIRD_IMPORT_PREVIEW = "third-import-preview";
+    public static final String URI_XXX_THIRD_IMPORT_COMMIT = "third-import-commit";
+    public static final String URI_XXX_THIRD_IMPORT_COMMIT_GET = "third-import-commit-get";
+    public static final String URI_XXX_THIRD_EXPORT = "third-export";
+    public static final String URI_XXX_THIRD_EXPORT_GET = "third-export-get";
+    public static final String URI_XXX_CAD_CONVERT = "cad-convert";
+    public static final String URI_XXX_CAD_CONVERT_GET = "cad-convert-get";
+    public static final String URI_XXX_CRS_GET_LIST = "crs-get-list";
+    public static final String URI_XXX_CRS_GET_INFO = "crs-get-info";
+    public static final String URI_XXX_CRS_TRANSFORM = "crs-transform";
+
+    public static final String URI_XXX_DEVICE_STATUS_LIST = "device-status-list";
+    public static final String URI_XXX_WARING_INFO_LIST = "waring-info-list";
+    public static final String URI_XXX_WARING_INFO_REMOVE = "waring-info-remove";
+
+    public static final String URI_XXX_TEMP_FILES = "temp-files";
+    public static final String URI_XXX_ASYNC_RESULTS = "async-results";
+
+    public static final String URI_ACCESS_TOKEN_CHECK = "/kpr-plugin/apply/access-token-check";
+    public static final String URI_FILE_BUSI_XXX = "/files/**";
+    public static final String URI_IMAGE_SHOW_XXX = "/imageShow/**";
+
+    public static final String URI_ALL_BUSI_XXX = "/kpr-plugin/**";
+
+    public static final String URI_GIS_SURVEY_H = "/kpr-plugin/gis-survey";
+    public static final String URI_GIS_SURVEY_XXX = URI_GIS_SURVEY_H + "/**";
+
+    public static final String URI_PIPE_BURST_H = "/kpr-plugin/pipe_burst";
+    public static final String URI_PIPE_BURST_XXX = URI_PIPE_BURST_H + "/**";
+
+    public static final String URI_USERS_H = "/kpr-plugin/users";
+    public static final String URI_USERS_XXX = URI_USERS_H + "/**";
+
+    public static final String URI_COMMON_H = "/kpr-plugin/common";
+    public static final String URI_COMMON_XXX = URI_COMMON_H + "/**";
+
+    public static final String URI_FILES_H = "/kpr-plugin/files";
+    public static final String URI_FILES_XXX = URI_FILES_H + "/**";
+
+    public static final String URI_INTERNAL_H = "/kpr-plugin/internal";
+    public static final String URI_INTERNAL_XXX = URI_INTERNAL_H + "/**";
+
+    public static final String URI_INTERNAL_OPS_XXX = "/ops/**";
+}

+ 15 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/CommDefine.java

@@ -0,0 +1,15 @@
+package com.shkpr.service.customgateway.core.constants;
+
+public interface CommDefine {
+    String REQ_OUTER = "Outer";//外来请求者
+    String REQ_INNER = "Inner";
+    String INTERNAL_OPERATOR_ID = "FFFFFFFF";
+    String INTERNAL_OPERATOR_ROLE = "SelfOperator";
+    String INTERNAL_OPERATOR_ROLE_ID = "FFFFFFFF";
+    String ADMIN_USER_ID = "0";
+    String ADMIN_ROLE_ID = "0";
+    String ADMIN_ACCOUNT = "admin";
+    String INVALID_STR_ID = "-1";
+    String SUPER_USER_ID = "UUDA12395CB8B325F16";
+    int LIMIT_MAX = 2000;
+}

+ 87 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/LogFlagBusiType.java

@@ -0,0 +1,87 @@
+package com.shkpr.service.customgateway.core.constants;
+
+public enum LogFlagBusiType {
+    BUSI_INIT(0,"Init Busi"),
+    BUSI_CONN(1,"Conn Busi"),
+    BUSI_AUTH(2, "Auth Busi"),
+    BUSI_SUB(3, "Subscribe Busi"),
+    BUSI_NOTIFY(4, "Notify Busi"),
+    BUSI_CMD(5,"Command Busi"),
+    BUSI_USER(6,"User Busi"),
+    BUSI_DEV(7,"Dev Busi"),
+    BUSI_APP_APIS(8, "App Apis"),
+    BUSI_USER_APIS_CASE(9,"User Apis Case"),
+    BUSI_ROLE_POWER(10,"Role Power Info"),
+    BUSI_PARTITION(11,"Partition Info"),
+    BUSI_MAINT_RECORDS(12,"Maintenance Records"),
+    BUSI_CALL_BASE_AS(13, "Call Base As Busi"),
+    BUSI_CALL_GEO_SERVER(14, "Call GeoServer As Busi"),
+    BUSI_LINKED_PATH(15, "Linked Path Busi"),
+    BUSI_NNS_PATH(16, "NNS Path Busi"),
+    BUSI_WFS_FEATURE(17, "WFS Feature Busi"),
+    BUSI_CUSTOMER(18, "Customer Busi"),
+    BUSI_FILES(19, "Files Busi"),
+    BUSI_FEATURES(20, "Features Busi"),
+    BUSI_FEATURES_TOTALS(21, "Features Totals Busi"),
+    BUSI_CALL_TDT_MAP_SERVER(22, "Call TDTMap Server As Busi"),
+    BUSI_TDT_MAP_BUSI(23, "TDTMap Busi"),
+    BUSI_COMMON(24, "Common Busi"),
+    BUSI_EXTEND_DIRECT_TABLE(25,"Extend Power Direct Table"),
+    BUSI_CALL_TASK_AS(26, "Call Task As Busi"),
+    BUSI_PIPELINE(27, "PipeLine Busi"),
+    BUSI_GIS_TOTAL_TEMPLATE(28, "Gis Super Template Busi"),
+    BUSI_GIS_ELEMENT_ACTION(29, "Gis Element Action Busi"),
+    BUSI_FEATURES_LAYER_TEMPLATE(30, "Features Layer Template Biz"),
+    BUSI_GEO_PUBLISH(31, "Geo Publish Biz"),
+    BUSI_GIS_METADATA_LAYER_TT(32, "Gis Metadata Layer Template"),
+    BUSI_GIS_METADATA_PROPERTY_TT(33, "Gis Metadata Property Template"),
+    BUSI_NO_JWT_BIZ(34, "No JWT Biz"),
+    BUSI_GIS_ANALY_STATS_REPORT(35, "Gis Analy Stats Report Biz"),
+    BUSI_GIS_SURVEY_PROJECT_BIZ(36,"Gis Survey Project Biz"),
+    BUSI_GIS_SURVEY(37,"Gis Survey Biz"),
+    BUSI_PIPE_BURST(38,"Pipe Burst Biz"),
+
+    BUSI_INTERNAL(99,"Internal Busi"),
+
+    BUSI_DB_USER(100,"DB User Busi"),
+    BUSI_DB_DEV(101,"DB Dev Busi"),
+    BUSI_DB_DEV_TYPE(102, "DB Dev Type Busi"),
+    BUSI_DB_APP_APIS(103,"DB App Apis"),
+    BUSI_DB_USER_APIS_CASE(104,"DB User Apis Case"),
+    BUSI_DB_ROLE_POWER(105,"DB Role Power Info"),
+    BUSI_DB_PARTITION(106,"DB Partition Info"),
+    BUSI_DB_MT_RECORD(107,"DB Maintenance Records"),
+    BUSI_DB_ROLE_INFO(108,"DB Role Info"),
+    BUSI_DB_MEDIA_INFO(109,"DB Media Info"),
+    BUSI_DB_CUSTOMER_DEVICE_LINK(110,"DB Customer Device Link"),
+    BUSI_DB_TILE_MAP_INFO(111,"DB Tile Map Info"),
+    BUSI_DB_FILE_ATTACHMENT(112,"DB File Attachment Info"),
+    BUSI_DB_DEVICE_ATTACHMENT_LINK(113,"DB Device Attachment Link"),
+    BUSI_DB_DIRECT_READ_TABLE_INFO(114,"DB Direct Read Table Info"),
+    BUSI_DB_DEVICE_LABEL_INFO(115,"DB Device Label Info"),
+    BUSI_DB_GIS_TOTAL_TEMPLATE(116,"DB Gis Super Template"),
+    BUSI_DB_ELEMENT_CHANGE_APPLY(117,"DB Element Change Apply"),
+    BUSI_DB_PIPE_LAYER_TYPE_KIND_LINK(118,"DB Pipe Layer Type Kind Link"),
+    BUSI_DB_GIS_DYNAMIC_BIZ(119,"DB Gis Dynamic Biz"),
+    BUSI_DB_GIS_PUBLISH_APPLY(120,"DB Gis Publish Apply"),
+    BUSI_DB_GIS_METADATA_LAYER(121,"DB Gis Metadata Layer Template"),
+    BUSI_DB_GIS_METADATA_PROPERTY(122,"DB Gis Metadata Property Template"),
+    BUSI_DB_GIS_LAYER_DAILY_ANALYSIS(124,"DB Gis Layer Daily Analysis"),
+    BUSI_DB_SURVEY_PROJECT_BIZ(125,"DB Gis Survey Project"),
+    BUSI_DB_SURVEY_JOB_BIZ(126,"DB Gis Survey Job"),
+    BUSI_DB_SURVEY_JOB_FOCUS(127,"DB Gis Survey Job Focus"),
+    BUSI_DB_SURVEY_JOB_STATUS_TRACK(128,"DB Gis Survey Job Status Track"),
+
+    BUSI_ALL(999,"ALL Busi"),
+    BUSI_REDIS(1000,"Redis Busi");
+
+    private LogFlagBusiType(int index, String name){
+        this.name = name;
+        this.index = index;
+    }
+    private String name;
+    private int index;
+    public int toIntValue(){return index;}
+    public String toStrValue() {return name;}
+}
+

+ 130 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/constants/ResponseCode.java

@@ -0,0 +1,130 @@
+package com.shkpr.service.customgateway.core.constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.ToString;
+
+/**
+ * RESULT_开头的为响应体中的结果码rescode
+ * STATUS_开头的为HTTP Status响应码
+ */
+@AllArgsConstructor
+@Getter
+@ToString
+public enum ResponseCode {
+    RESULT_NORMAL(0, "Normal result."),
+    RESULT_BAD(1, "Bad result,see the message/data for reason."),
+
+    STATUS_SUCCESS(200, "Success"),
+    STATUS_BAD_REQUEST(600, "Bad Request,see the message/data for reason."),
+    STATUS_ACCESS_DENY(603, "Access denied."),
+    STATUS_NOT_FOUND_URI(604, "No mapping found for HTTP request with URI."),
+    STATUS_METHOD_NOT_ALLOWED(605, "Method Not Allowed."),
+    STATUS_HTTP_TYPE_NOT_ACCEPTABLE(606, "Http media type not acceptable."),
+    STATUS_HTTP_TYPE_NOT_SUPPORTED(615, "Http media type not supported."),
+    STATUS_INTERNAL_SERVER_ERROR(700, "Internal Server Error."),
+    STATUS_SERVER_RUN_ERROR(1000, "The server is abnormal."),
+    STATUS_NULL_POINT_EXCEPTION(1001, "Empty param or param is null."),
+    STATUS_ERROR_DATA_TYPE(1002, "The data type is wrong."),
+    STATUS_IO_EXCEPTION(1003, "IO exception."),
+    STATUS_NO_SUCH_METHOD(1004, "No such method."),
+    STATUS_INDEX_OUT_OF_BOUNDS(1005, "Index out of bounds."),
+    STATUS_ERROR_JSON_FORMAT(1006, "Error JSON data format."),
+    STATUS_NOT_POST_REQUEST(1007, "Not post request."),
+    STATUS_NOT_DELETE_REQUEST(1008, "Not delete request."),
+    STATUS_ERROR_PARAM_FORMAT(1009, "Error parameter format."),
+    STATUS_INVALID_CONTENT_TYPE(1010, "Error Content-Type."),
+    STATUS_NOT_MATCHED_URI(1011, "No mapping found for HTTP request with URI."),
+    STATUS_ERROR_REQUEST_METHOD(1012, "Error request method."),
+    STATUS_NO_USER_ACCOUNT(1013, "No such user or has not login."),
+    STATUS_SERVER_NET_DISCONN_OR_BUSY(1014, "The network of server is down or busy. Please try again later."),
+    STATUS_MAX_CONCURRENT_REQUEST_COUNT(1015, "Exceeded the maximum number of concurrent requests. Please try again later."),
+    STATUS_INVALID_HEADER(1016, "Invalid headers, please check the headers of request."),
+
+    STATUS_EMPTY_TOKEN(2000, "Empty token."),
+    STATUS_INVALID_TOKEN(2001, "Invalidate Token, please re-login."),
+    STATUS_EXPIRED_TOKEN(2002, "Expired Token, please re-login."),
+    STATUS_NOT_LOGGED_IN(2003, "Not logged in."),
+    STATUS_DENY_OPERATE_USER(2004, "No permission to operate."),
+    STATUS_TOO_OLD_TOKEN(2005, "The token is too old, please use your new token."),
+    STATUS_INVALID_OLD_PWD(2006, "The original password is wrong."),
+    STATUS_INVALID_KEY(2007, "Invalidate Key"),
+    STATUS_INVALID_NAME(2008, "Invalidate Name"),
+
+    RESULT_ERROR_SIGN(3000, "Illegal signature"),
+    RESULT_REPEAT_SEQUENCE(3001, "Repeat the request, please check the request sequence number."),
+    RESULT_REQUEST_TIMEOUT(3002, "Request timed out."),
+    RESULT_REQUEST_TOO_BUSY(3003, "Request too busy, please try again later."),
+    RESULT_REPEAT_RECORDS(3004, "Repeat the records, please check the request."),
+    RESULT_REFERENCE_RECORDS(3005, "Reference the records, please check the request."),
+    RESULT_REFERENCE_NOT_EXIST(3006, "Reference the not exist, please check the request."),
+    RESULT_INVALID_MULTI_TYPE_BIND(3007, "Multi type binding, please check the request."),
+    RESULT_ILLEGAL_LOGIN(3998, "Illegal login."),
+    RESULT_ACCOUNT_LOCKED(3999, "Account has been locked, please try again later."),
+
+    RESULT_INVALID_ORDER(4000, "The order number is inconsistent."),//错误或不合法的工单号
+    RESULT_DUPLICATE_ORDER(4001, "The order is already exists."), //指定工单已存在
+    RESULT_ORDER_ACCEPTED(4002, "The order is already accepted."),//指定工单已被接收
+    RESULT_ORDER_DEALED(4003, "The order is already deal."),//指定工单已被处理
+    RESULT_ORDER_ODD_STATUS(4004, "The order status is incorrect.No permission to operation."),//指定工单状态错误,暂无权限做次操作
+    RESULT_ORDER_OWN_CHANGED(4005, "The owner of order is changed.No permission to operation."),//指定工单归属已变更,暂无限操作
+
+    RESULT_USER_ALREADY_REG(8000, "This phone is already registered."),
+    RESULT_DENY_FOR_SAME_PASS(8001, "Two passwords cannot be the same."),
+    RESULT_REFRESH_TOKEN_FAILED(8002, "Refresh token failed, please login again."),
+    RESULT_TOKEN_INVALID_SIGN(8003, "Refresh token failed, invalid signature"),
+    RESULT_INVALID_USER_INFO(8004, "User information verification failed."),
+    RESULT_EXISTS_USER_NAME(8005, "Username already exists."),
+    RESULT_USER_NOT_REG(8006, "This phone is not registered."),
+    RESULT_INNER_JS_SERVER_AUTH_FAILED(8007, "Inner js bizservice verify failed."),
+
+    RESULT_SERVER_NET_DISCONN_OR_BUSY(9000, "The network of server is down or busy. Please try again later."),
+
+    RESULT_INVALID_PUSH_TASK(9100, "The push task is inconsistent."),
+    RESULT_PUSH_TASK_CLOSE(9101, "The push task will be closed."),
+    RESULT_PUSH_TASK_RETRY(9102, "The push task will be next push in the queue."),
+    RESULT_PUSH_FAILED_ERROR_RECEIVER(9103, "Push task failed because of error receiver."),
+    RESULT_PUSH_FAILED_ERROR_OTHERS(9104, "Push task failed because of other errors."),
+    RESULT_PUSH_FAILED_NO_WAY(9105, "Push task failed because of no support the push way."),
+
+    RESULT_FILE_INVALID_TYPE(10000, "Illegal file type."),
+    RESULT_FILE_RW_FILED(10001, "File read/write error."),
+    RESULT_FILE_SIZE_EXCEED(10002, "File size limit exceeded."),
+    RESULT_FILE_PARSE_FAILED(10003, "File parse failed."),
+    RESULT_FILE_EMPTY_ROWS(10004, "File is empty rows."),
+
+    RESULT_NOT_SUPPORT_GEO_WFS_TYPE(20000, "The operation for this geo wfs type is not supported."),
+    RESULT_NOT_SUPPORT_GEO_WFS_WS(20001, "The operation for this geo wfs workspace is not supported."),
+    RESULT_GEO_WFS_TYPE_EMPTY_DATA(20002, "The empty data for this geo wfs type."),
+    RESULT_LABEL_ALREADY_USED(20003, "The Label is already in use."),
+    RESULT_REQ_TO_GEO_SERVER_FAILED(20004, "The request to GeoServer Failed."),
+    RESULT_GEO_WFS_ELEMENT_IS_NOT_EXIST(20005, "The geo wfs element is not exist."),
+
+    RESULT_FAST_DFS_UPLOAD_FAILED(30000, "Upload File To FastDfs Failed."),
+
+    RESULT_SYSTEM_CHECK_FAILED(40000, "System check failed."),
+    RESULT_SYSTEM_CHECK_NOT_FOUND(40001, "System check not found."),
+    RESULT_SYSTEM_CHECK_CANCEL_FAILED(40002, "System check cancel failed."),
+    RESULT_SYSTEM_CHECK_RESULT_NOT_FOUND(40003, "System check result not found."),
+
+    RESULT_ASYNC_TASK_FAILED(40010, "Async task failed."),
+    RESULT_ASYNC_TASK_NOT_FOUND(40011, "Async task not found."),
+    RESULT_ASYNC_TASK_CANCEL_FAILED(40012, "Async task cancel failed."),
+
+    BUSINESS_SYNC_FUN_FAILED(65529, "The Synch operation failed."),
+    BUSINESS_DB_REQ_FAILED(65530, "The DB operation failed."),
+    BUSINESS_API_ABOLISH(65531, "The Api has been abolished."),
+    BUSINESS_BUSY(65532, "Business is busy, please try again."),
+    SERVICE_OFFLINE(65533, "Service offline, please turn off offline mode"),
+    STATUS_UNKNOWN(65534, "Unknown reason,see the message/data for reason."),
+    RESULT_UNKNOWN(65535, "Unknown reason,see the message/data for reason.");
+
+    /**
+     * 编码
+     */
+    private final int code;
+    /**
+     * 信息
+     */
+    private final String message;
+}

+ 69 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/CommonToken.java

@@ -0,0 +1,69 @@
+package com.shkpr.service.customgateway.core.domain;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * 通用token
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+public class CommonToken extends AbstractAuthenticationToken implements Serializable {
+    /**
+     * 认证信息
+     */
+    private final Object principal;
+    /**
+     * 密钥
+     */
+    private final Object credentials;
+
+    public CommonToken(Object principal, Object credentials) {
+        super(null);
+        this.principal = principal;
+        this.credentials = credentials;
+        setAuthenticated(false);
+    }
+
+    public CommonToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
+        super(authorities);
+        this.principal = principal;
+        this.credentials = credentials;
+        super.setAuthenticated(true); // must use super, as we override
+    }
+
+    /**
+     * 未认证
+     *
+     * @param principal   用户名
+     * @param credentials 密码
+     * @return 未认证的token
+     */
+    public static CommonToken unauthenticated(Object principal, Object credentials) {
+        return new CommonToken(principal, credentials);
+    }
+
+    /**
+     * 已认证
+     *
+     * @param principal   用户
+     * @param authorities 权限
+     * @return 已认证的token
+     */
+    public static CommonToken authenticated(Object principal, Collection<? extends GrantedAuthority> authorities) {
+        return new CommonToken(principal, null, authorities);
+    }
+
+    @Override
+    public Object getCredentials() {
+        return this.credentials;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return this.principal;
+    }
+}

+ 19 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/LatLngBean.java

@@ -0,0 +1,19 @@
+package com.shkpr.service.customgateway.core.domain;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class LatLngBean {
+    public double lat = 0.0; //对应Y
+    public double lng = 0.0; //对应X
+
+    public LatLngBean() {
+    }
+
+    public LatLngBean(double latitude, double longitude) {
+        this.lat = latitude;
+        this.lng = longitude;
+    }
+}

+ 18 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/domain/ResponseRes.java

@@ -0,0 +1,18 @@
+package com.shkpr.service.customgateway.core.domain;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class ResponseRes<T> {
+    private long timestamp;
+    private String rescode;
+    private String resmsg;//message;
+    private T resdata;//data;
+
+    public ResponseRes() {
+
+    }
+}
+

+ 14 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/exception/SelfAuthFilterException.java

@@ -0,0 +1,14 @@
+package com.shkpr.service.customgateway.core.exception;
+
+public class SelfAuthFilterException extends Exception {
+    private int nErrorCode;
+
+    public SelfAuthFilterException(int nErrorCode, String strErrorMsg) {
+        super(strErrorMsg);
+        this.nErrorCode = nErrorCode;
+    }
+
+    public int getErrorCode() {
+        return nErrorCode;
+    }
+}

+ 40 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/ApiJWTBizFilterMgr.java

@@ -0,0 +1,40 @@
+package com.shkpr.service.customgateway.core.filter;
+
+import com.shkpr.service.customgateway.core.constants.ApiURI;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ApiJWTBizFilterMgr extends JWTAuthenticationFilter {
+    private RequestMatcher mRequestMatcherForUser = null;
+    private RequestMatcher mRequestMatcherForCommon = null;
+    private RequestMatcher mRequestMatcherForGisSurvey = null;
+    private RequestMatcher mRequestMatcherForPipeBurst = null;
+
+
+    public ApiJWTBizFilterMgr(AuthenticationManager authenticationManager) {
+        this(null, authenticationManager);
+    }
+
+    public ApiJWTBizFilterMgr(String url, AuthenticationManager authenticationManager) {
+        super(url, authenticationManager);
+        this.mStrThisSampleName = this.getClass().getSimpleName();
+
+        mRequestMatcherForUser = new AntPathRequestMatcher(ApiURI.URI_USERS_XXX);
+        mRequestMatcherForCommon = new AntPathRequestMatcher(ApiURI.URI_COMMON_XXX);
+        mRequestMatcherForGisSurvey = new AntPathRequestMatcher(ApiURI.URI_GIS_SURVEY_XXX);
+        mRequestMatcherForPipeBurst = new AntPathRequestMatcher(ApiURI.URI_PIPE_BURST_XXX);
+
+    }
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+        chain.doFilter(request, response);
+    }
+}

+ 26 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/CustomAuthenticationProvider.java

@@ -0,0 +1,26 @@
+package com.shkpr.service.customgateway.core.filter;
+
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+public class CustomAuthenticationProvider implements AuthenticationProvider{
+    protected String mStrThisSampleName = null;
+    public CustomAuthenticationProvider() {
+        this.mStrThisSampleName = this.getClass().getSimpleName();
+        //innerJsService = SpringContextUtil.getBean(InnerJsService.class);
+    }
+
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        throw new UsernameNotFoundException(String.format("No account or password error."));
+    }
+
+    @Override
+    public boolean supports(Class<?> aClass) {
+        return aClass.equals(UsernamePasswordAuthenticationToken.class);
+    }
+}
+

+ 138 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/JWTAuthenticationFilter.java

@@ -0,0 +1,138 @@
+package com.shkpr.service.customgateway.core.filter;
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.shkpr.service.customgateway.core.utils.HttpTool;
+import com.shkpr.service.customgateway.core.utils.TokenAuthenticationService;
+import com.shkpr.service.customgateway.core.constants.ApiURI;
+import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
+import com.shkpr.service.customgateway.core.constants.ResponseCode;
+import com.shkpr.service.customgateway.core.exception.SelfAuthFilterException;
+import com.shkpr.service.customgateway.core.storage.GlobalData;
+import org.springframework.security.authentication.AccountExpiredException;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Token过滤器,检验所有请求的Token是否合法
+ * 从http头的Authorization 项读取token数据,然后校验token的合法性
+ * 如果校验通过,就认为这是一个取得授权的合法请求
+ */
+public class JWTAuthenticationFilter extends BasicAuthenticationFilter {
+    protected String mStrThisSampleName = null;
+    protected JWTControllerCheck mControllerCheck = null;
+    private RequestMatcher mRequestMatcher = null;
+    private PathMatcher mPathMatcher = null;
+
+    public JWTAuthenticationFilter(AuthenticationManager authenticationManager){
+        super(authenticationManager);
+        this.mStrThisSampleName = this.getClass().getSimpleName();
+        mPathMatcher = new AntPathMatcher();
+    }
+
+    public JWTAuthenticationFilter(String url, AuthenticationManager authenticationManager){
+        super(authenticationManager);
+        this.mStrThisSampleName = this.getClass().getSimpleName();
+        if (url != null && !url.isEmpty())
+            this.mRequestMatcher = new AntPathRequestMatcher(url);
+        mPathMatcher = new AntPathMatcher();
+    }
+
+    public void setControllerCheck(JWTControllerCheck mControllerCheck) {
+        this.mControllerCheck = mControllerCheck;
+    }
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+        if (this.mRequestMatcher != null && !this.mRequestMatcher.matches(request)){
+            chain.doFilter(request, response);
+            return;
+        }
+
+        //文件映射放行
+        if (this.mPathMatcher != null && (this.mPathMatcher.match(
+                String.format("%s%s", request.getContextPath(), ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_SYS_CHECK_RESULTS + "/**"),
+                request.getRequestURI())
+                || this.mPathMatcher.match(
+                String.format("%s%s", request.getContextPath(), ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_TEMP_FILES + "/**"),
+                request.getRequestURI())
+                || this.mPathMatcher.match(
+                String.format("%s%s", request.getContextPath(), ApiURI.URI_GIS_SURVEY_H + "/" + ApiURI.URI_XXX_ASYNC_RESULTS + "/**"),
+                request.getRequestURI())
+        )) {
+            chain.doFilter(request, response);
+            return;
+        }
+
+        if (mControllerCheck != null && !mControllerCheck.checkRequest(request, response))  //当前URI已匹配成功,但Request请求格式不对,不再向后传递
+            return;
+
+        int nStatusCode = HttpServletResponse.SC_OK;
+        Authentication authentication = null;
+        try {
+            authentication = TokenAuthenticationService.getAuthentication(request, mControllerCheck.skipCheckAuthToPermit(request, response));
+            if (authentication != null)
+                SecurityContextHolder.getContext().setAuthentication(authentication); //不设置setAuthentication(authentication)将默认返回403,得不到正确结果
+        }
+        /* !!! 注:SecurityContextHolder.getContext().getAuthentication() == null时response.setStatus(xxx)无效,response.status总为403 !!! */
+        catch (BadCredentialsException e){
+            //无Token或者非法的Token
+            nStatusCode = ResponseCode.STATUS_INVALID_TOKEN.getCode();
+            HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_INVALID_TOKEN);
+            //System.out.println(e.getMessage());
+        }catch (CredentialsExpiredException e){
+            //非法Token,或已过期
+            nStatusCode = ResponseCode.STATUS_EXPIRED_TOKEN.getCode();
+            HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_EXPIRED_TOKEN);
+            //System.out.println(e.getMessage());
+        }catch (AccountExpiredException e){
+            //还未注册过,需要注册
+            nStatusCode = ResponseCode.STATUS_NOT_LOGGED_IN.getCode();
+            HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_NOT_LOGGED_IN);
+            //System.out.println(e.getMessage());
+        }catch (SelfAuthFilterException e){
+            nStatusCode = e.getErrorCode();
+            HttpTool.handlerHttpErrorStatus(response, e.getErrorCode(), e.getMessage());
+            //System.out.println(e.getMessage());
+        }catch (Exception e){
+            //其他错误
+            nStatusCode = ResponseCode.STATUS_ACCESS_DENY.getCode();
+            HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_ACCESS_DENY);
+            //System.out.println(e.getMessage());
+        }
+
+        if (authentication == null){
+            //SecurityContextHolder.getContext().setAuthentication(null);           //Token不合法时需要设置setAuthentication(null),不然response仍然返回200并且携带数据结果
+                                                                                   //解决bug:最近一次验证成功过,如此次未验证成功且不设置setAuthentication(null)的话,response.status仍然为200且会携带数据结果
+            if (GlobalData.getInstance().isHttpStatusAlready200()){
+                if (nStatusCode == HttpServletResponse.SC_OK)
+                    HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_ACCESS_DENY);
+            }else{
+                if (response.getStatus() == HttpServletResponse.SC_OK)
+                    HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_ACCESS_DENY);
+            }
+
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_WARN, LogFlagBusiType.BUSI_AUTH.toStrValue(), "JWTAuthenticationFilter"
+                    , String.format("Auth Failed Uri{%s} Remote{%s:%d}"
+                            ,request.getRequestURI()
+                            ,request.getRemoteAddr()
+                            ,request.getRemotePort()));
+            return;
+        }
+        chain.doFilter(request, response);
+    }
+}

+ 183 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/filter/JWTControllerCheck.java

@@ -0,0 +1,183 @@
+package com.shkpr.service.customgateway.core.filter;
+
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.global.base.tools.FastJsonUtil;
+import com.shkpr.service.customgateway.core.utils.CommTool;
+import com.shkpr.service.customgateway.core.utils.HttpTool;
+import com.shkpr.service.customgateway.core.utils.TokenAuthenticationService;
+import com.shkpr.service.customgateway.core.constants.LogFlagBusiType;
+import com.shkpr.service.customgateway.core.constants.ResponseCode;
+import com.shkpr.service.customgateway.core.storage.GlobalData;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 该类主要用来校验Controller的request头和request参数
+ */
+public class JWTControllerCheck {
+    protected Validator mValidator = null;//由于该类不是@Component或@Bean,所以无法对Validator msValidator使用@Autowired
+    protected Map<String, String> mMapURI2Method;
+    protected String mStrThisSampleName = null;
+    private AtomicInteger mTmpIndex = new AtomicInteger(0);
+    public JWTControllerCheck(Map<String, String> mapURI2Method){
+        this.mMapURI2Method = mapURI2Method;
+        this.mValidator = GlobalData.getInstance().getValidForParam();
+        this.mStrThisSampleName = this.getClass().getSimpleName();
+    }
+
+    public boolean checkRequest(HttpServletRequest request, HttpServletResponse response){
+        //解决跨域请求问题
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT");
+        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Content-Type,Authorization");
+        response.setHeader("X-Content-Type-Options", "nosniff");
+        //response.setHeader("X-Frame-Options", "DENY");
+        response.setHeader("X-XSS-Protection", "1; mode=block");
+
+        if (!checkServerInternet(request, response))
+            return false;
+        if (!checkMaxConcurrentRequest(request, response))
+            return false;
+        if (!checkRequestHead(request, response))
+            return false;
+        if (!checkRequestParam(request, response))
+            return false;
+        if (!checkRequestBody(request, response))
+            return false;
+        return true;
+    }
+
+
+
+    protected boolean checkServerInternet(HttpServletRequest request, HttpServletResponse response){
+        /*if (!DataTransferMgr.getInstance().isConnected()){
+            response.setStatus(ResponseCode.STATUS_SERVER_NET_DISCONN_OR_BUSY.toInt());//服务器端网络异常
+            return false;
+        }*/
+        return true;
+    }
+
+    protected boolean checkMaxConcurrentRequest(HttpServletRequest request, HttpServletResponse response){
+        /*if (DataTransferMgr.getInstance().getLiveUnitClient() > GlobalData.getInstance().getMaxConcurrentRequest()){
+            response.setStatus(ResponseCode.STATUS_MAX_CONCURRENT_REQUEST_COUNT.toInt());//超过了最大并发请求数
+            return false;
+        }*/
+        return true;
+    }
+
+    protected boolean checkRequestHead(HttpServletRequest request, HttpServletResponse response){
+        boolean bResult = true;
+        if (mMapURI2Method == null)
+            return bResult;
+
+        String strOldMethod = mMapURI2Method.get(request.getRequestURI());
+        if (strOldMethod == null){
+            for (Map.Entry<String,String> entry:mMapURI2Method.entrySet()){
+                String uri = entry.getKey();
+                String method = entry.getValue();
+                if (CommTool.isTheThisFormatMatch(uri, request.getRequestURI())){
+                    strOldMethod = method;
+                    break;
+                }
+            }
+        }
+        if (strOldMethod != null){
+            String submitMehtod = request.getMethod();
+            submitMehtod = submitMehtod!=null ? submitMehtod.toLowerCase():"xxx";
+
+            if (submitMehtod.equalsIgnoreCase(strOldMethod)){
+                String strContentType = request.getHeader("Content-Type");
+                strContentType = strContentType!=null ? strContentType.toLowerCase():"xxx";
+                String strContent = request.getHeader("Content");                       //经测试发现ios只能设置Content
+                strContent = strContent!=null ? strContent.toLowerCase():"xxx";
+
+                String strAccept = request.getHeader("Accept");
+                strAccept = strAccept!=null ? strAccept.toLowerCase():"xxx";
+
+                String strCompare = TokenAuthenticationService.HEADER_CONTENT_TYPE;
+                strCompare = strCompare.toLowerCase();
+                String strShortCompare = TokenAuthenticationService.HEADER_SHORT_CONTENT_TYPE;
+                strShortCompare = strShortCompare.toLowerCase();
+
+                if (submitMehtod.equals("post")
+                        || submitMehtod.equals("delete")
+                        || submitMehtod.equals("put")){
+                    //boolean b = strAccept.contains(strCompare);
+                    if (!strContentType.contains(strCompare)
+                            && !strContentType.contains(strShortCompare)
+                            && !strContent.contains(strCompare)
+                            && !strContent.contains(strShortCompare)
+                            && !strAccept.contains(strCompare)
+                            && !strAccept.contains(strShortCompare)){
+                        HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_INVALID_CONTENT_TYPE);//POST/DELETE/PUT时Content-Type不对
+                        bResult = false;
+                    }
+                }else if (submitMehtod.equals("get")){
+                    /*String strAuthToken = request.getHeader("authortoken");
+                    String strUserAgent = request.getHeader(ApiURI.HEADER_USER_AGENT);
+                    if (!StringUtils.isEmpty(strAuthToken)
+                            || ("apk".equals(CommTool.getPlatformByAgent(strUserAgent)) && !strContentType.contains(strCompare))){
+                        HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_ACCESS_DENY);
+                        bResult = false;
+                    }*/
+                }
+
+                if (!bResult && mTmpIndex.incrementAndGet()%10==0){
+                    Map<String, String> mapHeads = new HashMap<String, String>();
+                    Enumeration<String> headerNames = request.getHeaderNames();
+                    while (headerNames.hasMoreElements()) {
+                        String key = (String)headerNames.nextElement();
+                        String value = "";
+                        Enumeration<String> headerValues = request.getHeaders(key);
+                        while (headerValues.hasMoreElements()){
+                            value = value + (String)headerValues.nextElement();
+                        }
+                        mapHeads.put(key, value);
+                    }
+
+                    String strAddress = HttpTool.getIpAddress(request);
+                    LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_WARN, LogFlagBusiType.BUSI_AUTH.toStrValue(), mStrThisSampleName, "Inner"
+                            , String.format("uri:{%s %s} remote_address:{%s} illegal request for printing... %s"
+                                    , submitMehtod
+                                    , request.getRequestURI()
+                                    , strAddress
+                                    , FastJsonUtil.toJSON(mapHeads)));
+                }
+            } else{
+                HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_ERROR_REQUEST_METHOD);//URI对应的Method不对
+                bResult = false;
+            }
+        } else{
+            HttpTool.handlerHttpErrorStatus(response, ResponseCode.STATUS_NOT_MATCHED_URI);//找不到对应的URI
+            bResult = false;
+        }
+        return bResult;
+    }
+
+    protected boolean checkRequestParam(HttpServletRequest request, HttpServletResponse response){ return true; }
+
+    protected boolean checkRequestBody(HttpServletRequest request, HttpServletResponse response){
+        return true;
+    }
+
+    public <T> boolean checkObjectByValidator(T object, Class<?>... classForObject){
+        if (mValidator != null){
+            Set<ConstraintViolation<T>> constraintViolations = mValidator.validate(object, classForObject);
+            if (!(constraintViolations == null || constraintViolations.size() <= 0))
+                return false;
+        }
+        return true;
+    }
+
+    public boolean skipCheckAuthToPermit(HttpServletRequest request, HttpServletResponse response){return false;}
+}

+ 26 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/interfaces/URIInterceptorIntef.java

@@ -0,0 +1,26 @@
+package com.shkpr.service.customgateway.core.interfaces;
+
+import org.springframework.web.servlet.HandlerInterceptor;
+
+/**
+ * URL拦截器接口,实现该接口并在实现类上添加注解@Component,将会自动注入spring拦截器
+ */
+public interface URIInterceptorIntef extends HandlerInterceptor {
+    /**
+     * 需拦截的地址
+     * @return
+     */
+    public String [] forbidPathPatterns();
+
+    /**
+     * 排除拦截的地址
+     * @return
+     */
+    public String [] excludePathPatterns();
+
+    /**
+     * 值越小优先级越高,值越大优先级越低;优先级越高越先得到执行
+     * @return
+     */
+    public int order();
+}

+ 28 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/interfaces/sinks/LogPrintSink.java

@@ -0,0 +1,28 @@
+package com.shkpr.service.customgateway.core.interfaces.sinks;
+
+import com.global.base.log.ILogPrintSink;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogPrintSink implements ILogPrintSink {
+    private final Logger mLogger = LoggerFactory.getLogger(this.getClass());
+    public LogPrintSink() {
+    }
+
+    @Override
+    public void printLogMsg(int nLevel, String strMsg) {
+        switch (nLevel){
+            case 0:{
+                mLogger.info(strMsg);
+            }break;
+            case 1:{
+                mLogger.warn(strMsg);
+            }break;
+            case 2:{
+                mLogger.error(strMsg);
+            }break;
+            default:
+                break;
+        }
+    }
+}

+ 27 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/manager/TraceLogMgr.java

@@ -0,0 +1,27 @@
+package com.shkpr.service.customgateway.core.manager;
+
+import com.global.base.tools.TraceIdUtil;
+import com.shkpr.service.customgateway.core.storage.GlobalData;
+
+public class TraceLogMgr {
+    public static void setTraceId(String traceId){
+        if (GlobalData.getInstance().isSwitchTraceLog())
+            TraceIdUtil.setTraceId(traceId);
+    }
+    public static void setTraceIdByBusinessType(String strBusinessType){
+        if (GlobalData.getInstance().isSwitchTraceLog())
+            TraceIdUtil.setTraceIdByBusinessType(strBusinessType);
+    }
+
+    public static String getTraceId(){
+        if (GlobalData.getInstance().isSwitchTraceLog())
+            return TraceIdUtil.getTraceId();
+        return "TID-0";
+    }
+
+    public static String removeTraceId(){
+        if (GlobalData.getInstance().isSwitchTraceLog())
+            return TraceIdUtil.removeTraceId();
+        return "TID-0";
+    }
+}

+ 59 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/AsyncTaskProperties.java

@@ -0,0 +1,59 @@
+package com.shkpr.service.customgateway.core.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.nio.file.Path;
+import java.time.Duration;
+
+/**
+ * 异步任务属性
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "async-task")
+public class AsyncTaskProperties {
+    /**
+     * 系统检查超时时间
+     */
+    private Duration systemCheckTimeout;
+
+    /**
+     * 系统检查结果落后时间
+     */
+    private Duration systemCheckResultLag;
+
+    /**
+     * 第三方导入超时时间
+     */
+    private Duration thirdImportTimeout;
+
+    /**
+     * 第三方导入超时时间
+     */
+    private Duration commitImportTimeout;
+
+    /**
+     * 第三方导出超时时间
+     */
+    private Duration thirdExportTimeout;
+
+    /**
+     * 第三方导出结果落后时间
+     */
+    private Duration thirdExportResultLag;
+
+    /**
+     * cad转换超时时间
+     */
+    private Duration cadConvertTimeout;
+
+    /**
+     * 结果路径
+     */
+    private Path resultPath;
+}

+ 11 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/AuthenticationProperties.java

@@ -0,0 +1,11 @@
+package com.shkpr.service.customgateway.core.properties;
+
+
+/**
+ * 认证属性
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+public class AuthenticationProperties {
+}

+ 35 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/InfluxDbProperties.java

@@ -0,0 +1,35 @@
+package com.shkpr.service.customgateway.core.properties;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * influxdb属性
+ * <p>spring自动装配有同名bean,务必不要写同名字段</p>
+ *
+ * @author 欧阳劲驰
+ * @since 0.0.1-dev
+ */
+@Getter
+@AllArgsConstructor
+public class InfluxDbProperties {
+    /**
+     * 连接地址
+     */
+    private String url;
+
+    /**
+     * 用户名
+     */
+    private String user;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 数据库
+     */
+    private String database;
+}

+ 21 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/RouterProperties.java

@@ -0,0 +1,21 @@
+package com.shkpr.service.customgateway.core.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 路由属性
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "router")
+public class RouterProperties {
+    /**
+     * 路由集合
+     */
+    String base;
+}

+ 32 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/properties/TempFileProperties.java

@@ -0,0 +1,32 @@
+package com.shkpr.service.customgateway.core.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.nio.file.Path;
+import java.time.Duration;
+
+/**
+ * 临时文件属性
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "temp-file")
+public class TempFileProperties {
+    /**
+     * 检查周期
+     */
+    private Duration checkCycle;
+    /**
+     * 资源路径
+     */
+    private Path resourcePath;
+    /**
+     * 文件生命周期
+     */
+    private Duration lifecycle;
+}

+ 207 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/storage/GlobalData.java

@@ -0,0 +1,207 @@
+package com.shkpr.service.customgateway.core.storage;
+
+import com.shkpr.service.customgateway.core.utils.CommTool;
+import com.shkpr.service.customgateway.core.utils.TimeTool;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.executable.ExecutableValidator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class GlobalData {
+    public final static String ORIGIN_KEY = "Y^c3b5d3z1";    //原始口令:阳春布德泽
+    private boolean mBHttpStatusAlready200 = true;          //HttpStatus返回码是不是总是返回200ok
+    private boolean  mBTokenIsUnique = false;
+    private boolean  mBSvrTestMode = false;
+
+    private Validator mValidForParam = null;
+    private ExecutableValidator mValidForFun = null;
+    private volatile boolean mBUseLocalCache = true;         //是否启用本地缓存
+    private String mStrServerId = "";                          //本服务的ID
+    private int mNOwnerMachineIndex = 0;                      //本服务所在的部署机器的索引编号
+    private int mNOwnerServiceIndex = 0;                      //本服务在部署机器上的服务索引编号
+    private int mNCpuCoresForEnableAsyncSubTask = 8;//启动异步子任务的最小cpu核心数
+    private volatile boolean mBSwitchTraceLog = true;//是否开启基于TraceId的日志记录
+
+    private String mStrOperatorAccount = "";
+    private String mStrOperatorPassword = "";
+
+    private long mTmUTCServiceOnline = 1580486400000L;        //服务上线的时间,默认为2020-02-01 00:00:00
+    private String mStrInternalCallPassword = "";            //本机的内部通信可信任口令
+    private Map<String, String> mGeoWfsTypeName2TypeKey = new ConcurrentHashMap<>();
+    private boolean mBPostGisValid = false;
+    private String mStrDesProxyFdfs = "";
+    private ConcurrentSkipListSet<String> mWhiteListWS = new ConcurrentSkipListSet<>();
+    private ConcurrentSkipListSet<String> mBlackListWS = new ConcurrentSkipListSet<>();
+    private volatile char[] mGeoServerWeakPBEKey = null;
+    private AtomicBoolean mGisAnalyzeDo = new AtomicBoolean(false);//GIS图层日分析动作状态
+    private volatile boolean switchManualHttpGiz = true;                    //启用人工http压缩解压机制
+    private static volatile GlobalData msInstance = null;
+    public static GlobalData getInstance(){
+        if (msInstance == null){
+            synchronized (GlobalData.class){
+                if (msInstance == null)
+                    msInstance = new GlobalData();
+            }
+        }
+        return msInstance;
+    }
+
+    private GlobalData() {
+    }
+
+    public void setCpuCoresForEnableAsyncSubTask(int nCpuCores){
+        this.mNCpuCoresForEnableAsyncSubTask = nCpuCores;
+    }
+
+    public boolean isEnableAsyncSubTask(){
+        //cpu核心数>=指定配置时才启用异步子任务(注:过多线程并发可增加线程间的切换开销,导致单个请求执行时间拉长)
+        return mNCpuCores >= mNCpuCoresForEnableAsyncSubTask;
+    }
+
+    private int mNCpuCores = 1;
+    public int getCpuCores() {
+        return mNCpuCores;
+    }
+
+    public void setCpuCores(int mNCpuCores) {
+        this.mNCpuCores = mNCpuCores;
+    }
+
+    public <T> boolean checkObjectByValidator(T object, Class<?>... classForObject){
+        if (mValidForParam != null){
+            Set<ConstraintViolation<T>> constraintViolations = mValidForParam.validate(object, classForObject);
+            if (!(constraintViolations == null || constraintViolations.size() <= 0))
+                return false;
+        }
+        return true;
+    }
+
+    public Validator getValidForParam() {
+        return mValidForParam;
+    }
+
+    public void setValidForParam(Validator mValidForParam) {
+        this.mValidForParam = mValidForParam;
+    }
+
+    public ExecutableValidator getValidForFun() {
+        return mValidForFun;
+    }
+
+    public void setValidForFun(ExecutableValidator mValidForFun) {
+        this.mValidForFun = mValidForFun;
+    }
+
+    public boolean isTokenMustUnique() {
+        return mBTokenIsUnique;
+    }
+
+    public void setTokenMustUnique(boolean mBTokenIsUnique) {
+        this.mBTokenIsUnique = mBTokenIsUnique;
+    }
+
+    public boolean isSvrTestMode() {
+        return mBSvrTestMode;
+    }
+
+    public void setSvrTestMode(boolean mBSvrTestMode) {
+        this.mBSvrTestMode = mBSvrTestMode;
+    }
+
+    public boolean isHttpStatusAlready200() {
+        return mBHttpStatusAlready200;
+    }
+
+    public void setHttpStatusAlready200(boolean mBHttpStatusAlready200) {
+        this.mBHttpStatusAlready200 = mBHttpStatusAlready200;
+    }
+
+    public boolean isUseLocalCache() { return mBUseLocalCache; }
+
+    public void setUseLocalCache(boolean mBUseLocalCache) { this.mBUseLocalCache = mBUseLocalCache; }
+
+    public String getServerId() { return mStrServerId; }
+
+    public void setServerId(String mStrServerId) { this.mStrServerId = mStrServerId; }
+
+    public int getNOwnerMachineIndex() { return mNOwnerMachineIndex; }
+
+    public void setNOwnerMachineIndex(int mNOwnerMachineIndex) { this.mNOwnerMachineIndex = mNOwnerMachineIndex; }
+
+    public int getNOwnerServiceIndex() { return mNOwnerServiceIndex; }
+
+    public void setNOwnerServiceIndex(int mNOwnerServiceIndex) { this.mNOwnerServiceIndex = mNOwnerServiceIndex; }
+
+    public boolean isSwitchTraceLog() { return mBSwitchTraceLog; }
+
+    public void setSwitchTraceLog(boolean mBSwitchTraceLog) { this.mBSwitchTraceLog = mBSwitchTraceLog; }
+
+    public String getStrOperatorAccount() { return mStrOperatorAccount; }
+
+    public void setStrOperatorAccount(String mStrOperatorAccount) { this.mStrOperatorAccount = mStrOperatorAccount; }
+
+    public String getStrOperatorPassword() { return mStrOperatorPassword; }
+
+    public void setStrOperatorPassword(String mStrOperatorPassword) { this.mStrOperatorPassword = mStrOperatorPassword; }
+
+    public long getTmUTCServiceOnline() {
+        return mTmUTCServiceOnline;
+    }
+
+    public void setTmUTCServiceOnline(long mTmUTCServiceOnline) {
+        if (!TimeTool.isMsUTC(mTmUTCServiceOnline))
+            mTmUTCServiceOnline = mTmUTCServiceOnline*1000;
+        this.mTmUTCServiceOnline = mTmUTCServiceOnline;
+    }
+
+    public String getInternalCallPassword() { return mStrInternalCallPassword; }
+
+    public void setInternalCallPassword(String mStrInternalCallPassword) { this.mStrInternalCallPassword = mStrInternalCallPassword; }
+
+    public void resetGeoWFSType(String typeKey, String typeName){
+        mGeoWfsTypeName2TypeKey.put(typeName, typeKey);
+    }
+
+    public String getGeoWFSTypeKey(String typeName){
+        return mGeoWfsTypeName2TypeKey.get(typeName);
+    }
+
+    public boolean isPostGisValid() { return mBPostGisValid; }
+
+    public void setPostGisValid(boolean mBPostGisValid) { this.mBPostGisValid = mBPostGisValid; }
+
+    public String getStrDesProxyFdfs() { return mStrDesProxyFdfs; }
+
+    public void setStrDesProxyFdfs(String mStrDesProxyFdfs) { this.mStrDesProxyFdfs = mStrDesProxyFdfs; }
+
+    public void initWhiteBlackWS(List<String> whiteList, List<String> blackList){
+        mWhiteListWS.clear();
+        mBlackListWS.clear();
+        if (CommTool.listSize(whiteList) > 0)
+            mWhiteListWS.addAll(whiteList);
+        if (CommTool.listSize(blackList) > 0)
+            mBlackListWS.addAll(blackList);
+    }
+
+    public boolean isWSFilerAndSkip(String wsKey){
+        if (mBlackListWS.size() > 0 && mBlackListWS.contains(wsKey))
+            return true;
+        if (mWhiteListWS.size() > 0 && !mWhiteListWS.contains(wsKey))
+            return true;
+        return false;
+    }
+
+    public boolean getSwitchManualHttpGiz() {
+        return switchManualHttpGiz;
+    }
+
+    public void setSwitchManualHttpGiz(boolean switchManualHttpGiz) {
+        this.switchManualHttpGiz = switchManualHttpGiz;
+    }
+}

+ 41 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/storage/UserStore.java

@@ -0,0 +1,41 @@
+package com.shkpr.service.customgateway.core.storage;
+
+/**
+ * 用户缓存
+ * <p>未实现</p>
+ *
+ * @author 欧阳劲驰
+ * @since 1.0.0
+ */
+public class UserStore {
+    /**
+     * 获取实例
+     *
+     * @return 实例
+     */
+    public static UserStore getInstance() {
+        return Holder.INSTANCE;
+    }
+
+    /**
+     * 初始化
+     *
+     * @param poolSize 线程大小
+     */
+    public void init(int poolSize) {
+
+    }
+
+    public long getLogoutAccountTime(String userId) {
+        return -1;
+    }
+
+
+    public String getUserInfoJson(String account) {
+        return "";
+    }
+
+    private static class Holder {
+        static final UserStore INSTANCE = new UserStore();
+    }
+}

+ 516 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/CommTool.java

@@ -0,0 +1,516 @@
+package com.shkpr.service.customgateway.core.utils;
+
+import com.global.base.component.SnowFlakeEx;
+import com.global.base.tools.*;
+import com.shkpr.service.customgateway.core.constants.CommDefine;
+import com.shkpr.service.customgateway.core.domain.LatLngBean;
+import org.springframework.util.StringUtils;
+
+import java.awt.geom.Path2D;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CommTool {
+    public static final char[] HEX_DIGITS;
+    static {
+        HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+    }
+
+    public static String getPlatformByAgent(String strClientType, String strUserAgent){
+        return getPlatformByAgent(!StringUtils.isEmpty(strClientType)?strClientType:strUserAgent);
+    }
+
+    public static String getPlatformByAgent(String strUserAgent){
+        String type = "pc";
+        if (StringUtils.isEmpty(strUserAgent))
+            return type;
+
+        String lowerAgent = strUserAgent.toLowerCase();
+        if(lowerAgent.contains("android") || lowerAgent.contains("linux")) {
+            type = "apk";
+        } else if (lowerAgent.contains("iphone") || lowerAgent.contains("ios") || lowerAgent.contains("ipad")){
+            type = "ios";
+        } else if (lowerAgent.indexOf("micromessenger") > -1){
+            type = "wx";
+        } else if (lowerAgent.indexOf("cs") > -1){
+            type = "cs";
+        } else if (lowerAgent.indexOf("windows") > -1){
+            type = "pc";
+        } else if (lowerAgent.contains("tri.")){
+            type = strUserAgent;
+        }
+        return type;
+    }
+
+    public static boolean isMobilePlatform(String platform){
+        return ("apk".equals(platform) || "ios".equals(platform) || "wx".equals(platform));
+    }
+
+    public static boolean isTheThisFormatMatch(final String strFormatFilter, String strDesData){
+        if (!StringUtils.isEmpty(strFormatFilter) && !StringUtils.isEmpty(strDesData)) {
+            //正则表达式的模式
+            Pattern p = Pattern.compile(strFormatFilter);
+            //正则表达式的匹配器
+            Matcher m = p.matcher(strDesData);
+            //进行正则匹配
+            return m.matches();
+        }
+        return false;
+    }
+
+    public static int listSize(List<? extends Object> listSrc){
+        return (listSrc==null)?0:listSrc.size();
+    }
+
+    public static int collectionSize(Collection<? extends Object> cc){
+        return (cc==null)?0:cc.size();
+    }
+
+    public static int mapSize(Map<? extends Object, ? extends Object> mapSrc){
+        return (mapSrc==null)?0:mapSrc.size();
+    }
+
+    public static int lenString(String strSrc) {
+        if (StringUtils.isEmpty(strSrc))
+            return 0;
+        return strSrc.length();
+    }
+
+    public static boolean strBetweenLen(String strSrc, int nMinLen, int nMaxLen){
+        if (strSrc == null || nMinLen > nMaxLen)
+            return false;
+        return strSrc.length() >= nMinLen && strSrc.length() <= nMaxLen;
+    }
+
+    public static String genAppApisID(){
+        return (new StringBuilder("AA")).append(SnowFlakeEx.getInstance().nextHexStrId(2)).toString();
+    }
+
+    public static String genApisCaseID(){
+        return (new StringBuilder("AC")).append(SnowFlakeEx.getInstance().nextHexStrId(2)).toString();
+    }
+
+    public static String genNotifyEventID(){
+        return (new StringBuilder("PNE")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genGisTotalTempID(){
+        return (new StringBuilder("PGT")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genElementApplyID(){
+        return (new StringBuilder("EPY")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genPublishBatchNo(){
+        return (new StringBuilder("PN")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genDeviceSN(){
+        StringBuilder tmp = new StringBuilder("GSM");
+        tmp.append(TimeTool.convertUTC2DateStr(System.currentTimeMillis(), TimeTool.TIMESTAMP_FORMAT_EX2).substring(2));
+        tmp.append(EncryptionUtil.MD5Hash(UUID.randomUUID().toString()).toUpperCase().substring(10, 21));
+        return tmp.toString();
+    }
+
+    public static String list2QueryIn(List<? extends Object> listSrc){
+        StringBuilder str = new StringBuilder("");
+        if (listSrc != null && listSrc.size() > 0){
+            str.append("(");
+            int nStart = 0;
+            for (Object item:listSrc){
+                if (nStart++ > 0)
+                    str.append(",");
+                if (item instanceof String){
+                    str.append("'"+item+"'");
+                }else{
+                    str.append(item);
+                }
+            }
+            str.append(")");
+        }
+        return str.toString();
+    }
+
+    public static int totalCharCountsInStr(String srcStr, char chDes){
+        int nums = 0;
+        if (StringUtils.isEmpty(srcStr))
+            return nums;
+
+        char[] arr = srcStr.toCharArray();
+        for (char ch:arr){
+            if (ch == chDes)
+                nums++;
+        }
+        return nums;
+    }
+
+    public static int forceConvertToInt(Object oldObj, int defaultV){
+        if (oldObj != null){
+            if (oldObj.getClass().getSimpleName().equals("Double"))
+                return Double.valueOf((double)oldObj).intValue();
+            else if (oldObj.getClass().getSimpleName().equals("Float"))
+                return Float.valueOf((float)oldObj).intValue();
+            else
+                return CastUtil.castInt(oldObj, defaultV);
+        }
+        return defaultV;
+    }
+
+    public static String escapeInHex(final String src) {
+        StringBuilder tmp = new StringBuilder("");
+        if (StringUtils.isEmpty(src))
+            return tmp.toString();
+
+        int i;
+        char j;
+        tmp.ensureCapacity(src.length() * 6);
+        for (i = 0; i < src.length(); i++) {
+            j = src.charAt(i);
+            if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j))
+                tmp.append(j);
+            else if (j < 256) {
+                tmp.append(j);
+                /*tmp.append("%");
+                if (j < 16)
+                    tmp.append("0");
+                tmp.append(Integer.toString(j, 16));
+                */
+            } else {
+                //tmp.append("%u");
+                //tmp.append(Integer.toString(j, 16));
+                tmp.append("&#x");
+                tmp.append(Integer.toString(j, 16));
+                tmp.append(";");
+            }
+        }
+        return tmp.toString();
+    }
+
+    private static final String PHONE_MATCH_FILTER = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
+    public static String adjustMobilePhone(String phone){
+        if (!StringUtils.isEmpty(phone)
+                && phone.length() == 11
+                && isTheThisFormatMatch(PHONE_MATCH_FILTER, phone)){
+            return phone;
+        }
+        return "";
+    }
+
+    private static String exchangeMD5(String md5){
+        StringBuilder res = new StringBuilder("");
+        int len = md5.length()/2;
+        for (int i=0; i<len; i++){
+            int index = i*2;
+            res.append(Integer.toHexString((Integer.parseInt(String.valueOf(md5.charAt(index+1)), 16)<<4 | Integer.parseInt(String.valueOf(md5.charAt(index)), 16)) % 16).toUpperCase());
+        }
+        //for (int i = 0,j = md5.length()-1; i<=j; i++,j--){
+        //    res.append(Integer.toHexString(((0x0F & md5.charAt(i)) ^ (0x0F & md5.charAt(j)))).toUpperCase());
+        //}
+        return res.toString();
+    }
+
+    public static String genUserUid(String account, String extend){
+        return "UUD" + exchangeMD5(EncryptionUtil.MD5Hash(account+extend));
+    }
+
+    public static String likeMap2LikeStr(Map<String, String> mapLikes, Set<String> filterKey){
+        StringBuilder strLikes = new StringBuilder("");
+        if (mapLikes != null && mapLikes.size() > 0){
+            int nStart = 0;
+            for(Map.Entry<String, String> entry:mapLikes.entrySet()){
+                String key = entry.getKey();
+                String data = entry.getValue();
+
+                if (StringUtils.isEmpty(data) || !filterKey.contains(key))  //likes条件暂时只支持有限字段
+                    continue;
+
+                if (nStart++ > 0)
+                    strLikes.append(" or ");
+                strLikes.append(StringUtil.lower2UnLine(key)+" like '%"+data+"%' ");
+            }
+        }
+        return strLikes.toString();
+    }
+
+    /**
+     * 获取不规则多边形重心点
+     * @param mPoints
+     * @return
+     */
+    public static LatLngBean getCenterOfGravityPoint(List<LatLngBean> mPoints) {
+        double area = 0.0;        //多边形面积
+        double Gx = 0.0, Gy = 0.0;// 重心的x、y
+        int pointSize = CommTool.listSize(mPoints);
+        if (pointSize >= 2){
+            for (int i = 1; i <= mPoints.size(); i++) {
+                double iLat = mPoints.get(i % pointSize).lat;
+                double iLng = mPoints.get(i % pointSize).lng;
+                double nextLat = mPoints.get(i - 1).lat;
+                double nextLng = mPoints.get(i - 1).lng;
+                double temp = (iLat * nextLng - iLng * nextLat) / 2.0;
+                area += temp;
+                Gx += temp * (iLat + nextLat) / 3.0;
+                Gy += temp * (iLng + nextLng) / 3.0;
+            }
+            Gx = Gx / area;
+            Gy = Gy / area;
+        }else if (pointSize == 1)
+            return mPoints.get(0);
+        return new LatLngBean(Gx, Gy);
+    }
+
+    /**
+     * 指定gis点是否在指定区域内
+     * @param areaGis
+     * @param lng
+     * @param lat
+     * @return
+     */
+    public static boolean isGisPointInArea(List<LatLngBean> areaGis, double lng, double lat){
+        if (listSize(areaGis) <= 2)
+            return false;
+
+        Path2D.Double generalPath = new Path2D.Double();
+        LatLngBean firstPoint = areaGis.get(0);
+        if (firstPoint == null)
+            return false;
+
+        generalPath.moveTo(firstPoint.getLng(), firstPoint.getLat());
+        for (int i=1;i<areaGis.size();i++){
+            LatLngBean nextPoint = areaGis.get(i);
+            if (nextPoint == null)
+                return false;
+
+            generalPath.lineTo(nextPoint.getLng(), nextPoint.getLat());
+        }
+        generalPath.lineTo(firstPoint.getLng(), firstPoint.getLat());
+        generalPath.closePath();
+        return generalPath.contains(lng, lat);
+    }
+
+    /**
+     * 指定的点是否在线所属的bbox区域内
+     * @param lineBegin
+     * @param lineEnd
+     * @param lng
+     * @param lat
+     * @return
+     */
+    public static boolean isGisPointInLineArea(LatLngBean lineBegin, LatLngBean lineEnd, double lng, double lat){
+        List<LatLngBean> areaGis = new ArrayList<>();
+        double mixBoxLng = Double.min(lineBegin.getLng(), lineEnd.getLng());
+        double mixBoxLat = Double.min(lineBegin.getLat(), lineEnd.getLat());
+        double maxBoxLng = Double.max(lineBegin.getLng(), lineEnd.getLng());
+        double maxBoxLat = Double.max(lineBegin.getLat(), lineEnd.getLat());
+
+        if ((new BigDecimal(mixBoxLng).compareTo(new BigDecimal(lineBegin.getLng())) == 0
+                && new BigDecimal(mixBoxLat).compareTo(new BigDecimal(lineBegin.getLat())) == 0)
+                || (new BigDecimal(mixBoxLng).compareTo(new BigDecimal(lineEnd.getLng())) == 0
+                    && new BigDecimal(mixBoxLat).compareTo(new BigDecimal(lineEnd.getLat())) == 0)){
+            areaGis.add(new LatLngBean(mixBoxLat, mixBoxLng));
+            areaGis.add(new LatLngBean(maxBoxLat, mixBoxLng));
+            areaGis.add(new LatLngBean(maxBoxLat, maxBoxLng));
+            areaGis.add(new LatLngBean(mixBoxLat, maxBoxLng));
+        }else {
+            areaGis.add(new LatLngBean(mixBoxLat, mixBoxLng));
+            areaGis.add(new LatLngBean(lineBegin.getLat(), lineBegin.getLng()));
+            areaGis.add(new LatLngBean(maxBoxLat, maxBoxLng));
+            areaGis.add(new LatLngBean(lineEnd.getLat(), lineEnd.getLng()));
+        }
+        return isGisPointInArea(areaGis, lng, lat);
+    }
+
+    //WGS84标准参考椭球中的地球长半径(单位:米)
+    private static final double EARTH_RADIUS = 6378137; //地球半径:米
+    /**
+     * 根据经纬度,计算两点间的距离
+     *
+     * @param lng1 第一个点的经度
+     * @param lat1  第一个点的纬度
+     * @param lng2 第二个点的经度
+     * @param lat2  第二个点的纬度
+     * @return 返回距离 单位:米
+     */
+    public static long getGisDistance(double lng1, double lat1, double lng2, double lat2) {
+        lat1 = Math.toRadians(lat1);
+        lat2 = Math.toRadians(lat2);
+        lng1 = Math.toRadians(lng1);
+        lng2 = Math.toRadians(lng2);
+
+        double a = lat1 - lat2;    // 纬度之差
+        double b = lng1 - lng2;     // 经度之差
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));// 计算两点距离的公式
+        s =  s * EARTH_RADIUS;
+        return Math.round(s * 10000) / 10000;
+    }
+
+    public static double getGisDistanceEx(double lng1, double lat1, double lng2, double lat2) {
+        lat1 = Math.toRadians(lat1);
+        lat2 = Math.toRadians(lat2);
+        lng1 = Math.toRadians(lng1);
+        lng2 = Math.toRadians(lng2);
+
+        double a = lat1 - lat2;    // 纬度之差
+        double b = lng1 - lng2;     // 经度之差
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));// 计算两点距离的公式
+        s =  s * EARTH_RADIUS;
+        return s;
+    }
+
+    /**
+     * 指定两个gis点是否在指定的距离内
+     * @param from 起始点
+     * @param to 终止点
+     * @param maxDistance 指定的最大距离(单位:米)
+     * @return
+     */
+    public static boolean isGisPointNearPoint(LatLngBean from, LatLngBean to, long maxDistance){
+        return getGisDistance(from.getLng(), from.getLat(), to.getLng(), to.getLat()) <= maxDistance;
+    }
+
+    /**
+     * gis点到gis线是否在指定的距离内
+     * @param fromPoint 起始gis点
+     * @param toLineGis 终止gis线
+     * @param maxDistance 指定的最大距离(单位:米)
+     * @return
+     */
+    public static boolean isGisPointNearLine(LatLngBean fromPoint, List<LatLngBean> toLineGis, long maxDistance){
+        int nPointSize = CommTool.listSize(toLineGis);
+        if (nPointSize <= 0)
+            return false;
+        if (nPointSize <= 1)
+            return isGisPointNearPoint(fromPoint, toLineGis.get(0), maxDistance);
+        else {//直线或折线,注:是折线时需将其拆分成多条直线
+            for (int i=0;i<=toLineGis.size()-2;i++){
+                LatLngBean pointA = fromPoint;
+                LatLngBean pointB = toLineGis.get(i);
+                LatLngBean pointC = toLineGis.get(i+1);
+
+                long b = getGisDistance(pointA.getLng(), pointA.getLat(), pointC.getLng(), pointC.getLat());
+                if (b <= 0 || b <= maxDistance)
+                    return true;
+
+                long c = getGisDistance(pointA.getLng(), pointA.getLat(), pointB.getLng(), pointB.getLat());
+                if (c <= 0 || c <= maxDistance)
+                    return true;
+
+                long a = getGisDistance(pointB.getLng(), pointB.getLat(), pointC.getLng(), pointC.getLat());
+                if (a <= 0)
+                    continue;
+
+                long cosABC = (a*a + c*c - b*b)/(2*a*c);
+                if (cosABC <= 0){//直角或钝角
+                    if (c <= maxDistance)
+                        return true;
+                    continue;
+                }
+
+                long cosACB = (a*a + b*b - c*c)/(2*a*b);
+                if (cosACB <= 0){//直角或钝角
+                    if (b <= maxDistance)
+                        return true;
+                    continue;
+                }
+
+                long pp = (a+b+c)/2;
+                long ss = Math.round(10000*Math.sqrt(pp*(pp-a)*(pp-b)*(pp-c)))/10000;
+                long shortA2BC = 2*ss/a;
+                if (shortA2BC <= maxDistance)
+                    return true;
+            }
+            return false;
+        }/*else if (nPointSize == 2){
+            if (isGisPointNearPoint(fromPoint, toLineGis.get(0), maxDistance))//指定点到直线一端的距离
+                return true;
+            if (isGisPointNearPoint(fromPoint, toLineGis.get(1), maxDistance))//指定点到直线另一端的距离
+                return true;
+            return getGisDistance(fromPoint.getLng()//指定点到直线中心点的距离
+                    , fromPoint.getLat()
+                    , (toLineGis.get(0).getLng()+toLineGis.get(1).getLng())/2
+                    , (toLineGis.get(0).getLat()+toLineGis.get(1).getLat())/2) <= maxDistance;
+        }else {//折线
+            if (isGisPointInArea(toLineGis, fromPoint.getLng(), fromPoint.getLat()))//是否在折线的封闭区域内
+                return true;
+            return isGisPointNearPoint(fromPoint, getCenterOfGravityPoint(toLineGis), maxDistance);//指定点到折线封闭区域的重心距离
+        }*/
+    }
+
+    public static String genFileAttachmentId(String fileName, int type, String strExtend){
+        String time = TimeTool.convertUTC2DateStr(System.currentTimeMillis(), TimeTool.TIMESTAMP_FORMAT_EX2);
+        String fileNameHash = (StringUtils.isEmpty(fileName))? RandomUtil.getDigitalRandomStr(4):EncryptionUtil.MD5Hash(fileName).substring(0,4);
+        String extend = (StringUtils.isEmpty(strExtend))?RandomUtil.getDigitalRandomStr(4):strExtend;
+        return (new StringBuilder("FT"))
+                .append(time==null?"":time)
+                .append(String.format("%02d",type%100))
+                .append(fileNameHash==null?"":fileNameHash)
+                .append(extend==null?"":extend).toString();
+    }
+
+    public static List safeList(List<? extends Object> listSrc){
+        if (listSrc == null)
+            return new ArrayList();
+        else
+            return listSrc;
+    }
+
+    public static boolean isRootAdminID(String userId){
+        return CommDefine.ADMIN_USER_ID.equals(userId)
+                || CommDefine.INTERNAL_OPERATOR_ID.equals(userId);
+    }
+
+    //84坐标系转2000坐标系
+    public static double[] convert84To2000(double latitude, double longitude) {
+        double x = 0.0, y = 0.0, z = 0.0;
+        double a = EARTH_RADIUS;
+        double f = 1.0 / 298.257223563;
+        double b = (1 - f) * a;
+        double e = Math.sqrt((a * a - b * b) / (a * a));
+        double E = Math.atan2(z, Math.sqrt(x * x + y * y));
+        double r = Math.sqrt(x * x + y * y + z * z);
+        double latitude1 = Math.atan2(z + e * e * b * Math.pow(Math.sin(E), 3), r - a * Math.pow(e, 2) * Math.pow(Math.cos(E), 3));
+        double longitude1 = Math.atan2(y, x);
+        double N = a / Math.sqrt(1 - Math.pow(e * Math.sin(latitude1), 2));
+        double h = r / Math.cos(latitude1) - N;
+        double X = (N + h) * Math.cos(latitude1) * Math.cos(longitude1);
+        double Y = (N + h) * Math.cos(latitude1) * Math.sin(longitude1);
+        double Z = (N * (1 - Math.pow(e, 2)) + h) * Math.sin(latitude1);
+        double k = 1.0000648438897;
+        double dx = -24.9;
+        double dy = 140.8;
+        double dz = 76.3;
+        double X1 = k * (X + dx);
+        double Y1 = k * (Y + dy);
+        double Z1 = k * (Z + dz);
+        return new double[]{X1, Y1, Z1};
+    }
+
+    //已知点A、B、C,求夹角<ABC
+    public static double angleBFromGis(LatLngBean pointA, LatLngBean pointB, LatLngBean pointC){
+        double side_c = getGisDistanceEx(pointA.getLng(), pointA.getLat(), pointB.getLng(), pointB.getLat());
+        double side_a = getGisDistanceEx(pointB.getLng(), pointB.getLat(), pointC.getLng(), pointC.getLat());
+        double side_b = getGisDistanceEx(pointA.getLng(), pointA.getLat(), pointC.getLng(), pointC.getLat());
+        return angleBFromSide(side_a, side_b, side_c);
+    }
+
+    public static double angleBFromSide(double a, double b, double c){
+        if (c + a < b)
+            return -1.0;
+        if (c + a == b)
+            return 180.0;
+        return Math.toDegrees(Math.acos((a*a + c*c - b*b) / (2*a*c)));
+    }
+
+    public static String genSurveyProjID(){
+        return (new StringBuilder("GSP")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genSurveyJobID(){
+        return (new StringBuilder("GJB")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+}

File diff suppressed because it is too large
+ 208 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/HttpTool.java


+ 1 - 1
src/main/java/com/shkpr/service/customgateway/commtools/NameUtils.java

@@ -1,4 +1,4 @@
-package com.shkpr.service.customgateway.commtools;
+package com.shkpr.service.customgateway.core.utils;
 
 /**
  * 名称工具

+ 52 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/SpringContextUtil.java

@@ -0,0 +1,52 @@
+package com.shkpr.service.customgateway.core.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+//@Lazy(false) //true为懒加载,在第一次被引用的时候才会创建;false为Spring容器在启动时会立即创建
+//若要明确指定为懒加载,则必须使用@Lazy(true),否则bean对象默认取值lazy-init="false"即@Lazy(false)
+public class SpringContextUtil implements ApplicationContextAware {
+    //Spring应用上下文环境
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextUtil.applicationContext = applicationContext;
+    }
+
+    public static ApplicationContext getApplicationContext(){
+        return applicationContext;
+    }
+
+    public static boolean containsBean(String beanName){
+        return applicationContext.containsBean(beanName);
+    }
+
+    public static boolean isSingleton(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.isSingleton(beanName);
+    }
+
+    public static Class getType(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.getType(beanName);
+    }
+
+    public static String[] getAliases(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.getAliases(beanName);
+    }
+
+    public static Object getBean(String beanName) throws BeansException {
+        return applicationContext.getBean(beanName);
+    }
+
+    public static <T> T getBean(Class<T> className) throws BeansException {
+        return applicationContext.getBean(className);
+    }
+
+    public static <T> T getBean(String beanName, Class<T> className) throws BeansException{
+        return applicationContext.getBean(beanName, className);
+    }
+}

+ 513 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/TimeTool.java

@@ -0,0 +1,513 @@
+package com.shkpr.service.customgateway.core.utils;
+
+import org.springframework.util.StringUtils;
+
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.format.ResolverStyle;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+public class TimeTool {
+    public static final long MS_HTTP_REQ_TIMEOUT = 120*1000;  //两分钟的毫秒数
+    public static final long MS_ONE_HALF_MIN = 90*1000;  //一分半钟的毫秒数
+    public static final long MS_ONE_MIN = 60*1000;       //一分钟的毫秒数
+    public static final long MIN_ONE_DAY = 24*60;        //一天中的分
+    public static final long SEC_ONE_DAY = 24*60*60;     //一天中的秒
+    public static final long MS_ONE_DAY = 24*60*60*1000; //一天中的毫秒
+    public static final long MS_ONE_YEAR = 365*MS_ONE_DAY;//一年中的毫秒
+    public static final long MS_ONE_HOUR = 60*60*1000;   //一小时的毫秒
+    public static final String YEAR_FORMAT = "yyyy";
+    public static final String YEAR_MONTH_FORMAT_EX = "yyyyMM";
+    public static final String YEAR_MONTH_FORMAT = "yyyy-MM";
+    public static final String YEAR_MONTH_FORMAT_SLASH = "yyyy/MM";
+    public static final String YEAR_MONTH_DAY_FORMAT = "yyyy-MM-dd";
+    public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    public static final String TIMESTAMP_FORMAT_EX = "yyyy-MM-dd HH:mm:ss.SSS";
+    public static final String TIMESTAMP_FORMAT_EX2 = "yyyyMMddHHmmss";
+    public static final long UTC_MS_START_ONLINE = 1538323200000L;//2018-10-01 00:00:00
+    public static volatile long UTC_MS_TODAY_BEGIN = 0L;
+    public static volatile long UTC_MS_TODAY_END = 0L;
+    public static volatile long UTC_MS_THIS_MONTH_BEGIN = 0L;
+    public static volatile long UTC_MS_THIS_MONTH_END = 0L;
+
+    private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);
+    private static final DateTimeFormatter TIMESTAMP_EX_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX);
+    private static final DateTimeFormatter TIMESTAMP_EX2_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX2);
+    private static final DateTimeFormatter YEAR_MONTH_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_FORMAT);
+    private static final DateTimeFormatter YEAR_MONTH_DAY_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_DAY_FORMAT);
+
+    public static void refreshUTCTimeRes(){
+        UTC_MS_TODAY_BEGIN = getTodayBeginUTC();
+        UTC_MS_TODAY_END = getTodayEndUTC();
+        UTC_MS_THIS_MONTH_BEGIN = getMonthBeginUTC(System.currentTimeMillis());
+        UTC_MS_THIS_MONTH_END = getMonthEndUTC(System.currentTimeMillis());
+    }
+
+    private static LocalDateTime strTime2LocalDateTime(String time, String format) {
+        switch (format){
+            case YEAR_MONTH_FORMAT:
+                return LocalDateTime.parse(time, YEAR_MONTH_FORMATTER);
+            case YEAR_MONTH_DAY_FORMAT:
+                return LocalDateTime.parse(time, YEAR_MONTH_DAY_FORMATTER);
+            case TIMESTAMP_FORMAT:
+                return LocalDateTime.parse(time, TIMESTAMP_FORMATTER);
+            case TIMESTAMP_FORMAT_EX:
+                return LocalDateTime.parse(time, TIMESTAMP_EX_FORMATTER);
+            case TIMESTAMP_FORMAT_EX2:
+                return LocalDateTime.parse(time, TIMESTAMP_EX2_FORMATTER);
+            default:
+                return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(format));
+        }
+    }
+
+    private static String localDateTime2StrTime(LocalDateTime localDateTime, String format) {
+        switch (format){
+            case YEAR_MONTH_FORMAT:
+                return localDateTime.format(YEAR_MONTH_FORMATTER);
+            case YEAR_MONTH_DAY_FORMAT:
+                return localDateTime.format(YEAR_MONTH_DAY_FORMATTER);
+            case TIMESTAMP_FORMAT:
+                return localDateTime.format(TIMESTAMP_FORMATTER);
+            case TIMESTAMP_FORMAT_EX:
+                return localDateTime.format(TIMESTAMP_EX_FORMATTER);
+            case TIMESTAMP_FORMAT_EX2:
+                return localDateTime.format(TIMESTAMP_EX2_FORMATTER);
+            default:
+                return localDateTime.format(DateTimeFormatter.ofPattern(format));
+        }
+    }
+
+    private static LocalDateTime utcMsTime2LocalDateTime(long lUTC) {
+        if (!isMsUTC(lUTC)){
+            lUTC = lUTC*1000;
+        }
+        Instant instant = Instant.ofEpochMilli(lUTC);
+        ZoneId zone = ZoneId.systemDefault();
+        return LocalDateTime.ofInstant(instant, zone);
+    }
+
+    private static long localDateTime2UtcMsTime(LocalDateTime localDateTime) {
+        ZoneId zone = ZoneId.systemDefault();
+        Instant instant = localDateTime.atZone(zone).toInstant();
+        return instant.toEpochMilli();
+    }
+
+    private static long strTime2UtcMsTime(String dateStr, String format){
+        return localDateTime2UtcMsTime(strTime2LocalDateTime(dateStr, format));
+    }
+
+    private static String utcMsTime2StrTime(long lUTC, String format){
+        return localDateTime2StrTime(utcMsTime2LocalDateTime(lUTC), format);
+    }
+
+    public static long convertDateStr2UTC(String dateStr){
+        try {
+            dateStr = dateStr.trim();
+            int len = dateStr.length();
+            if (len >= 23)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX);
+            else if (len >= 19)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT);
+            else if (len >= 14)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX2);
+            else if (len >= 10)//即dataStr为yyyy-MM-dd
+                return strTime2UtcMsTime(String.format("%s 00:00:00", dateStr), TIMESTAMP_FORMAT);
+            else if (len >= 7)//即dataStr为yyyy-MM
+                return strTime2UtcMsTime(String.format("%s-01 00:00:00", dateStr), TIMESTAMP_FORMAT);
+            else if (len >= 6)//即dataStr为yyyyMM
+                return strTime2UtcMsTime(String.format("%s01000000", dateStr), TIMESTAMP_FORMAT_EX2);
+            else if (len >= 4)//即dataStr为yyyy
+                return strTime2UtcMsTime(String.format("%s-01-01 00:00:00", dateStr), TIMESTAMP_FORMAT);
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 指定UTC是否为精确到毫秒的UTC时间
+     * @param lUTC
+     * @return
+     */
+    public static boolean isMsUTC(long lUTC){
+        return lUTC > 10000000000L;
+    }
+
+    public static long getCurSecUTC(){
+        return (System.currentTimeMillis()/1000)*1000;
+    }
+
+    public static long getCurMsUTC(){
+        return System.currentTimeMillis();
+    }
+
+    /**
+     *
+     * @param lUTC  UTC时间格式(单位:毫秒)
+     * @param strDateFormat 日期格式模板:如:yyyy-MM-dd HH:mm:ss
+     * @return
+     */
+    public static String convertUTC2DateStr(long lUTC, String strDateFormat){
+        try {
+            return utcMsTime2StrTime(lUTC<=0?System.currentTimeMillis():lUTC
+                    , StringUtils.isEmpty(strDateFormat)?TIMESTAMP_FORMAT:strDateFormat);
+        }catch (Exception e){}
+        return "";
+    }
+
+    /**
+     * 从当前时间算起,还有多少毫秒今天将结束
+     * @return 所剩的毫秒数
+     */
+    public static long hasMsWhenTodayEnd(){
+        long lR = UTC_MS_TODAY_END+1-System.currentTimeMillis();
+        if (lR <= 0)
+            lR = 1;
+        return lR;
+    }
+
+    /**
+     * 获取过期时间
+     * @param nSeconds 从当前时间算起,nSeconds秒后过期
+     * @return UTC时间格式(单位:毫秒)
+     */
+    public static long createExpiredTime(long nSeconds){
+        nSeconds = nSeconds<0?0:nSeconds;
+        long nowMillis = System.currentTimeMillis();
+        return nowMillis+(nSeconds*1000);
+    }
+
+    /**
+     * 获取当天的开始时间
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:00:00:00.000所对应的时间戳
+     */
+    public static long getTodayBeginUTC(){
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+        /*Calendar todayStart = Calendar.getInstance();
+        todayStart.set(Calendar.HOUR_OF_DAY, 0);
+        todayStart.set(Calendar.MINUTE, 0);
+        todayStart.set(Calendar.SECOND, 0);
+        todayStart.set(Calendar.MILLISECOND, 0);
+        return todayStart.getTime().getTime();*/
+    }
+
+    /**
+     * 获取当天距离最近的整点时刻
+     * @return UTC时间格式(单位:毫秒)
+     * @return
+     */
+    public static long getTodayLastHourUTC(){
+        return LocalDateTime.now().withMinute(0).withSecond(0).withNano(0)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+    }
+
+    /**
+     * 获取指定时间当日的起始时刻(即00:00:00.000)
+     * @param tmMS
+     * @return
+     */
+    public static long getBeginUTCOfTime(long tmMS){
+        if (!isMsUTC(tmMS)){
+            tmMS = tmMS*1000;
+        }
+        LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MIN);
+        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+    }
+
+    /**
+     * 获取指定时间当日的结束时刻(即23:59:59.999)
+     * @param tmMS
+     * @return
+     */
+    public static long getEndUTCOfTime(long tmMS){
+        if (!isMsUTC(tmMS)){
+            tmMS = tmMS*1000;
+        }
+        LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MAX);
+        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+    }
+    /**
+     * 获取当天的结束时间
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:23:59:59.999所对应的时间戳
+     */
+    public static long getTodayEndUTC(){
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+        /*Calendar todayStart = Calendar.getInstance();
+        todayStart.set(Calendar.HOUR_OF_DAY, 23);
+        todayStart.set(Calendar.MINUTE, 59);
+        todayStart.set(Calendar.SECOND, 59);
+        todayStart.set(Calendar.MILLISECOND, 999);
+        return todayStart.getTime().getTime();*/
+    }
+
+    /**
+     * 获取当前时间所在月份的开始时间戳
+     * @param curTime
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:xxxx-xx-01 00:00:00.000所对应的时间戳
+     */
+    public static long getMonthBeginUTC(long curTime){
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.set(Calendar.DAY_OF_MONTH, 1);
+            c.set(Calendar.HOUR_OF_DAY, 0);
+            c.set(Calendar.MINUTE, 0);
+            c.set(Calendar.SECOND,0);
+            c.set(Calendar.MILLISECOND, 0);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 获取当前时间所在月份的结束时间戳
+     * @param curTime
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:xxxx-xx-31 23:59:59.999所对应的时间戳
+     */
+    public static long getMonthEndUTC(long curTime){
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
+            c.set(Calendar.HOUR_OF_DAY, 23);
+            c.set(Calendar.MINUTE, 59);
+            c.set(Calendar.SECOND,59);
+            c.set(Calendar.MILLISECOND, 999);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份字符串列表
+     * ["2018-01", "2018-02"]
+     */
+    public static List<String> getMonthListBetween(long startTime, long endTime){
+        ArrayList<String> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(dPos.getTime()));
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(strEnd);
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份字符串列表
+     * ["201801", "201802"]
+     */
+    public static List<String> getMonthListBetweenEx(long startTime, long endTime){
+        ArrayList<String> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(dPos.getTime()));
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(strEnd);
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表UTC
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份UTC时间戳列表(精确到毫秒)
+     * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC]
+     */
+    public static List<Long> getMonthUTCListBetween(long startTime, long endTime){
+        ArrayList<Long> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add(dPos.getTimeInMillis());
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(dtEnd.getTime());
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份字符串列表
+     * ["2018-01", "2018-02"]
+     */
+    public static List<String> getMonthListBetween(String startTime, String endTime){
+        try {
+            //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime);
+            //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime);
+            return getMonthListBetween(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份字符串列表
+     * ["201801", "201802"]
+     */
+    public static List<String> getMonthListBetweenEx(String startTime, String endTime){
+        try {
+            //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(startTime);
+            //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(endTime);
+            return getMonthListBetweenEx(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表UTC
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份UTC时间戳列表(精确到秒)
+     * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC]
+     */
+    public static List<Long> getMonthUTCListBetween(String startTime, String endTime){
+        try {
+            Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime);
+            Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime);
+            return getMonthUTCListBetween(d1.getTime(), d2.getTime());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * yyyyMMddhhmmss时间字符串转yyyy-MM-dd HH:mm:ss时间字符串
+     * @param strDateStr
+     * @return
+     */
+    public static String addSplitForDateStr(String strDateStr){
+        if (!StringUtils.isEmpty(strDateStr)){
+            try {
+                return localDateTime2StrTime(strTime2LocalDateTime(strDateStr, TIMESTAMP_FORMAT_EX2), TIMESTAMP_FORMAT);
+            }catch (Exception e){}
+        }
+        return "";
+    }
+
+    /**
+     * 修改指定时间的月份
+     * @param curTime
+     * @param month  > 0 在指定时间上加数个月;< 0 在指定时间上减数个月;
+     * @return
+     */
+    public static long getTimeChgMonth(long curTime, int month){
+        if (month == 0)
+            return curTime;
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.add(Calendar.MONTH, month);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    public static String convertDateObj2DateStr(Date dateObj, String strDateFormat){
+        try {
+            int len = strDateFormat.length();
+            if (len >= 21)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT_EX).format(dateObj);
+            else if (len >= 17)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT).format(dateObj);
+            else if (len >= 12)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT_EX2).format(dateObj);
+            else {
+                int splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '-');
+                if (splitCounts <= 0)
+                    splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '/');
+                if (splitCounts >= 2)
+                    return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj);
+                else if (splitCounts >= 1)
+                    return new SimpleDateFormat(YEAR_MONTH_FORMAT).format(dateObj);
+                else
+                    return new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).format(dateObj);
+            }
+        }catch (Exception e){}
+        return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj);
+    }
+
+    public static boolean checkValidDate(String dateStr) {
+        try {
+            DateTimeFormatter formatter = DateTimeFormatter
+                    .ofPattern("uuuu-MM-dd")//使用 "uuuu" 避免年份解析歧义
+                    .withResolverStyle(ResolverStyle.STRICT);
+            LocalDate.parse(dateStr, formatter);
+            return true;
+        } catch (DateTimeParseException e) {
+            return false;
+        }
+    }
+}

+ 263 - 0
custom-gateway-core/src/main/java/com/shkpr/service/customgateway/core/utils/TokenAuthenticationService.java

@@ -0,0 +1,263 @@
+package com.shkpr.service.customgateway.core.utils;
+
+import com.shkpr.service.customgateway.core.constants.ApiURI;
+import com.shkpr.service.customgateway.core.constants.CommDefine;
+import com.shkpr.service.customgateway.core.constants.ResponseCode;
+import com.shkpr.service.customgateway.core.dto.AuthTokenData;
+import com.shkpr.service.customgateway.core.exception.SelfAuthFilterException;
+import com.shkpr.service.customgateway.core.globalcache.GlobalData;
+import com.shkpr.service.customgateway.core.globalcache.UserCacheProxy;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.util.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Map;
+
+public class TokenAuthenticationService {
+    public static final int MIN_EXPIRATIONTIME = 7*60*24;                              // 默认Token过期时间为7天(单位:分钟)
+    public static final long MS_EXPIRATIONTIME = MIN_EXPIRATIONTIME*60*1000;         // 默认Token过期时间为7天(单位:毫秒)
+    public static final String SECRET = "TRICP_ALAM_DMA";                              // JWT密码
+    public static final String HEADER_STRING = "Authorization";                       // 存放Token的Header Key
+    public static final String HEADER_CONTENT_TYPE = "application/json;charset=UTF-8";
+    public static final String HEADER_SHORT_CONTENT_TYPE = "application/json";
+    public static final String SIGNATURE_KEY = "tri_coorperation_tech";              //签名秘钥
+    public static final String HEADER_SEQUENCE = "Sequence";
+    public static final String HEADER_USERID = "UUID";
+    public static final String HEADER_ROLEID = "RLID";
+
+    private static AuthTokenData generateToken(Map<String, Object> claims){
+        return generateToken(claims, MIN_EXPIRATIONTIME);
+    }
+
+    private static AuthTokenData generateToken(Map<String, Object> claims, int expired){
+        String strFlagKey = "";
+        String strAccount = "";
+        String roleId = "";
+        try {
+            strFlagKey = (String)claims.get("flagkey");
+        } catch (Exception e){}
+        try {
+            strAccount = (String)claims.get("account");
+        } catch (Exception e){}
+        try {
+            roleId = (String)claims.get("roleid");
+        } catch (Exception e){}
+        return generateToken(strFlagKey, strAccount, roleId, expired);
+    }
+
+    public static AuthTokenData generateToken(String strFlagKey, String strAccount, String roleId, int expired){
+        /*Map<String, Object> claims = new HashMap<>(16);
+        //claims.put("sub", strUsername);
+        claims.put("flagkey", strFlagKey);
+        claims.put("account", strAccount);
+        claims.put("roleid", roleId);
+        return generateToken(claims, expired);*/
+        long nowMillis = System.currentTimeMillis();
+        Date dateExpired  = null;
+        String strToken = null;
+        try {
+            strToken = Jwts.builder()
+                    .setHeaderParam("typ", "JWT")
+                    .setHeaderParam("alg", "HS256")
+                    //.setAudience("APP")
+                    //.setIssuer("SERVICE")
+                    //.setId(UUID.randomUUID().toString())
+                    .setIssuedAt(new Date(nowMillis))
+                    .setExpiration(dateExpired = new Date(nowMillis + expired*60*1000))
+                    .signWith(SignatureAlgorithm.HS256, SECRET.getBytes("UTF-8"))
+                    .claim("flagkey", strFlagKey)
+                    .claim("account", strAccount)
+                    .claim("roleid", roleId)
+                    .compact();
+        } catch (Exception e){
+            strToken = null;
+            e.printStackTrace();
+        }
+
+        return  StringUtils.isEmpty(strToken) ? null:new AuthTokenData(strToken
+                , dateExpired!=null ? dateExpired.getTime():System.currentTimeMillis()
+                , nowMillis
+                , strFlagKey);
+    }
+
+    private static Claims getClaimsFromToken(String token) throws ExpiredJwtException, Exception{
+        Claims claims = null;
+        try {
+            claims = Jwts.parser().setSigningKey(SECRET.getBytes("UTF-8")).parseClaimsJws(token).getBody();
+        }catch (ExpiredJwtException e){
+            claims = null;
+            throw e;
+        }catch (Exception e) {
+            claims = null;
+            throw e;
+        }
+        return claims;
+    }
+
+    public static String getFlagKeyFromToken(String token) throws ExpiredJwtException, Exception{
+        String strKey = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null)
+                strKey = (String)claims.get("flagkey");
+        }catch (ExpiredJwtException e){
+            strKey = null;
+            throw e;
+        }catch (Exception e) {
+            strKey = null;
+            throw e;
+        }
+        return strKey;
+    }
+
+    public static AuthTokenData getAuthDataFromToken(String token) throws ExpiredJwtException, Exception{
+        AuthTokenData data = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                String strKey = (String)claims.get("flagkey");
+                String strRoleId = (String)claims.get("roleid");
+                data = new AuthTokenData(token, claims.getExpiration().getTime(), claims.getIssuedAt().getTime(), strKey, strRoleId);
+            }
+        }catch (ExpiredJwtException e){
+            data = null;
+            throw e;
+        }catch (Exception e) {
+            data = null;
+            throw e;
+        }
+        return data;
+    }
+
+    public static String getUserIDFromToken(String token) throws ExpiredJwtException, Exception{
+        String strKey = null;
+        try {
+            strKey = getFlagKeyFromToken(token);
+        }catch (Exception e) {
+            strKey = null;
+            throw e;
+        }
+        int nIndex = (strKey != null) ? strKey.indexOf(":"):-1;
+        if (nIndex >= 0)
+            strKey = strKey.substring(nIndex+1);
+        return strKey;
+    }
+
+    public static Boolean isTokenExpired(String token){
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                Date expiration = claims.getExpiration();
+                return expiration.before(new Date());
+            }
+        } catch (ExpiredJwtException e){
+            return true;
+        } catch (Exception e) {
+            return true;
+        }
+        return true;
+    }
+
+    public static Boolean isTokenExpired(long lExpired){
+        return lExpired <= new Date().getTime();
+    }
+
+    public static AuthTokenData refreshToken(String token, int nExpired) throws ExpiredJwtException, Exception{
+        AuthTokenData tokenData = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                tokenData = generateToken(claims, nExpired);
+            }
+        } catch (ExpiredJwtException e){
+            tokenData = null;
+            throw e;
+        } catch (Exception e) {
+            tokenData = null;
+            throw e;
+        }
+        return tokenData;
+    }
+
+    public static Boolean validateToken(String token) {
+        return !isTokenExpired(token);
+    }
+
+    public static Authentication getAuthentication(HttpServletRequest request, boolean isSkipAuthToPermit) throws Exception{
+        final String strAuthVerify = request.getHeader(ApiURI.HEADER_AUTH_VERIFY);
+        if (GlobalData.getInstance().getInternalCallPassword().equalsIgnoreCase(strAuthVerify)
+                || isSkipAuthToPermit){
+            try {
+                request.setAttribute(HEADER_USERID, CommDefine.INTERNAL_OPERATOR_ID);
+                request.setAttribute(HEADER_ROLEID, CommDefine.INTERNAL_OPERATOR_ROLE_ID);
+            }catch (Exception e){}
+
+            return new UsernamePasswordAuthenticationToken(CommDefine.INTERNAL_OPERATOR_ID,
+                    null,
+                    new ArrayList<GrantedAuthorityImpl>());
+        }
+
+        String strUri = request.getRequestURI();
+        String authHeader = request.getHeader(HEADER_STRING);
+        if (authHeader != null && authHeader.length() > 0 /*&& authHeader.startsWith(TOKEN_PREFIX)*/){
+            String authToken = authHeader/*authHeader.substring(TOKEN_PREFIX.length())*/;
+            AuthTokenData authData = null;
+            try {
+                authData = getAuthDataFromToken(authToken);
+            } catch (ExpiredJwtException e){
+                throw new CredentialsExpiredException("Invalidate token, token is expired.");
+            } catch (Exception e){
+                throw new BadCredentialsException("Invalidate Token, has no user.");
+            }
+
+            boolean bEasy = true;
+            if (bEasy && authData != null){
+                long lTimeLogout = UserCacheProxy.getInstance().getLogoutAccountTime(authData.getStrFlagKey());
+                if (lTimeLogout == -1){
+                    if (isTokenExpired(authData.getExpired()))
+                        throw new CredentialsExpiredException("Invalidate token, token is expired.");
+                }else {
+                    if (authData.getIssueAt() <= lTimeLogout)        //签发时间早于注销时间
+                        throw new BadCredentialsException("Invalidate Token, has no user.");
+                    else if (isTokenExpired(authData.getExpired())) //签发时间晚于注销时间,但已过期
+                        throw new CredentialsExpiredException("Invalidate token, token is expired.");
+                }
+
+                try {
+                    request.setAttribute(HEADER_USERID, authData.getStrFlagKey());
+                    request.setAttribute(HEADER_ROLEID, authData.getRoleid());
+                }catch (Exception e){}
+
+                return new UsernamePasswordAuthenticationToken(authData.getStrFlagKey(),
+                        null,
+                        new ArrayList<GrantedAuthorityImpl>());
+            }else{
+                throw new BadCredentialsException("Invalidate Token, has no user.");
+            }
+        }else {
+            throw new SelfAuthFilterException(ResponseCode.STATUS_EMPTY_TOKEN.toInt(), ResponseCode.STATUS_EMPTY_TOKEN.toStrMsg());
+        }
+    }
+
+    public static boolean isTheSelfUser(String strAuthToken, String strUserId){
+        if (StringUtils.isEmpty(strUserId))
+            return false;
+
+        String strFlagKey = null;
+        try {
+            strFlagKey = TokenAuthenticationService.getFlagKeyFromToken(strAuthToken);
+        }catch (Exception e){
+            return false;
+        }
+        return strUserId.equals(strFlagKey);
+    }
+}

+ 2 - 0
custom-gateway-core/src/main/resources/application.yml

@@ -0,0 +1,2 @@
+router:
+  base: custom-gw

+ 38 - 0
custom-gateway-core/src/test/java/com/shkpr/service/customgateway/core/CustomGatewayCoreApplicationTests.java

@@ -0,0 +1,38 @@
+package com.shkpr.service.customgateway.core;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class CustomGatewayCoreApplicationTests
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public CustomGatewayCoreApplicationTests(String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( CustomGatewayCoreApplicationTests.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}

+ 24 - 0
custom-gateway-zydma/pom.xml

@@ -0,0 +1,24 @@
+<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>
+    <!--父工程信息-->
+    <parent>
+        <groupId>com.shkpr.service</groupId>
+        <artifactId>kpr-custom-gateway</artifactId>
+        <version>1.0.0-dev</version>
+    </parent>
+
+    <!--工件名-->
+    <artifactId>custom-gateway-zydma</artifactId>
+    <!--打包方式-->
+    <packaging>jar</packaging>
+    <!--项目名-->
+    <name>CustomGatewayZydma</name>
+    <!--项目描述-->
+    <description>枣阳漏控</description>
+
+    <!--依赖项-->
+    <dependencies>
+
+    </dependencies>
+</project>

+ 4 - 0
custom-gateway-zydma/src/main/java/com/shkpr/service/zydma/controller/TeatController.java

@@ -0,0 +1,4 @@
+package com.shkpr.service.zydma.controller;
+
+public class TeatController {
+}

+ 38 - 0
custom-gateway-zydma/src/test/java/com/shkpr/service/zydma/ZydmApplicationTests.java

@@ -0,0 +1,38 @@
+package com.shkpr.service.zydma;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class ZydmApplicationTests
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public ZydmApplicationTests(String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( ZydmApplicationTests.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}

+ 23 - 4
pom.xml

@@ -1,13 +1,14 @@
 <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.shkpr.service</groupId>
     <!--工件名-->
-    <artifactId>KprCustomGateway</artifactId>
+    <artifactId>kpr-custom-gateway</artifactId>
     <!--版本号-->
     <version>1.0.0-dev</version>
+    <!--打包方式-->
+    <packaging>pom</packaging>
     <!--项目名-->
     <name>KprCustomGateway</name>
 
@@ -18,16 +19,29 @@
         如:/custom-gw/zy-dma/xxx
     </description>
 
+    <!--子模块-->
+    <modules>
+        <!--核心模块-->
+        <module>custom-gateway-core</module>
+        <!--启动模块-->
+        <module>custom-gateway-app</module>
+
+        <!--枣阳漏控-->
+        <module>custom-gateway-zydma</module>
+    </modules>
+
 
     <!--属性配置+统一版本管理-->
     <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <java.version>1.8</java.version>
-        <maven.compiler.source>1.8</maven.compiler.source>
-        <maven.compiler.target>1.8</maven.compiler.target>
 
         <spring.boot.version>2.1.3.RELEASE</spring.boot.version>
+        <gbase.version>1.0.5</gbase.version>
+        <jts.version>1.19.0</jts.version>
     </properties>
 
     <!--依赖项-->
@@ -42,6 +56,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
         </dependency>
+        <!--commons-->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
         <!--lombok-->
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 0 - 63
src/main/java/com/shkpr/service/customgateway/domain/PredicateDefinition.java

@@ -1,63 +0,0 @@
-package com.shkpr.service.customgateway.domain;
-
-
-import com.shkpr.service.customgateway.commtools.NameUtils;
-import lombok.*;
-import org.springframework.util.StringUtils;
-import org.springframework.validation.annotation.Validated;
-
-import javax.validation.ValidationException;
-import javax.validation.constraints.NotNull;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * 谓词定义
- *
- * @author 欧阳劲驰
- * @since 1.0.0
- */
-@Setter
-@Getter
-@NoArgsConstructor
-@EqualsAndHashCode
-@ToString
-@Validated
-public class PredicateDefinition {
-    /**
-     * 名称
-     */
-    @NotNull
-    private String name;
-    /**
-     * 参数
-     */
-    private Map<String, String> args = new LinkedHashMap<>();
-
-    /**
-     * 文本构造
-     *
-     * @param text 文本
-     */
-    public PredicateDefinition(String text) {
-        //等号分割
-        int eqIdx = text.indexOf('=');
-        if (eqIdx <= 0)
-            throw new ValidationException("无法解析Predicate定义文本'" + text + "'" + ",必须符合name=value的格式");
-        //设置名称
-        setName(text.substring(0, eqIdx));
-        //设置参数
-        String[] args = StringUtils.tokenizeToStringArray(text.substring(eqIdx + 1), ",");
-        for (int i = 0; i < args.length; i++) this.args.put(NameUtils.generateName(i), args[i]);
-    }
-
-    /**
-     * 添加参数
-     *
-     * @param key   k
-     * @param value v
-     */
-    public void addArg(String key, String value) {
-        this.args.put(key, value);
-    }
-}

+ 0 - 50
src/main/java/com/shkpr/service/customgateway/domain/RouteDefinition.java

@@ -1,50 +0,0 @@
-package com.shkpr.service.customgateway.domain;
-
-import lombok.*;
-import org.springframework.validation.annotation.Validated;
-
-import javax.validation.constraints.NotNull;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 路由定义
- *
- * @author 欧阳劲驰
- * @since 1.0.0
- */
-@Setter
-@Getter
-@NoArgsConstructor
-@EqualsAndHashCode
-@ToString
-@Validated
-public class RouteDefinition {
-    /**
-     * ID
-     */
-    private String id;
-    /**
-     * 谓词集合
-     */
-    private List<PredicateDefinition> predicates = new ArrayList<>();
-    /**
-     * 过滤器集合
-     */
-    private List<FilterDefinition> filters = new ArrayList<>();
-    /**
-     * 目标URI
-     */
-    private @NotNull URI uri;
-    /**
-     * 元数据
-     */
-    private Map<String, Object> metadata = new HashMap<>();
-    /**
-     * 权重
-     */
-    private int order = 0;
-}

+ 0 - 24
src/main/java/com/shkpr/service/customgateway/properties/GatewayProperties.java

@@ -1,24 +0,0 @@
-package com.shkpr.service.customgateway.properties;
-
-import com.shkpr.service.customgateway.domain.RouteDefinition;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import java.util.List;
-
-/**
- * 网关属性
- *
- * @author 欧阳劲驰
- * @since 1.0.0
- */
-@Getter
-@Setter
-@ConfigurationProperties(prefix = "spring.gateway")
-public class GatewayProperties {
-    /**
-     * 路由集合
-     */
-    List<RouteDefinition> routes;
-}

+ 0 - 11
src/main/resources/application.yml

@@ -1,11 +0,0 @@
-#spring
-spring:
-  application:
-    name: KprCustomGateway
-  gateway:
-    routes:
-      - id: zy-dma
-        uri: http://locaohost:8000/
-#web
-server:
-  port: 9011

+ 0 - 29
src/test/java/com/shkpr/service/customgateway/CustomGateWayApplicationTests.java

@@ -1,29 +0,0 @@
-package com.shkpr.service.customgateway;
-
-import com.shkpr.service.customgateway.domain.RouteDefinition;
-import com.shkpr.service.customgateway.properties.GatewayProperties;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.List;
-
-/**
- * 测试启动类
- */
-@SpringBootTest
-@RunWith(SpringRunner.class)
-public class CustomGateWayApplicationTests {
-    @Autowired
-    GatewayProperties properties;
-
-    @Test
-    public void test() {
-        List<RouteDefinition> routes = properties.getRoutes();
-
-        routes.forEach(System.out::println);
-    }
-
-}