Selaa lähdekoodia

初始化代码
from: http://192.168.0.115:3000/4dkankan_back/4dkankanOpenGateWay.git
branch:1.0.3
version:e9d29fb9

tianboguang 3 vuotta sitten
commit
11f52c5b40
46 muutettua tiedostoa jossa 3560 lisäystä ja 0 poistoa
  1. 53 0
      4dkankan-open-gateway-base/pom.xml
  2. 28 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/config/MyBatisPlusConfig.java
  3. 15 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/config/RateLimiterConfiguration.java
  4. 36 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/config/RedisConfiguration.java
  5. 51 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/config/SwaggerApp.java
  6. 16 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/dao/TmDeveloperDao.java
  7. 16 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/dao/TmDomainListDao.java
  8. 82 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/entity/TmDeveloper.java
  9. 67 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/entity/TmDomainList.java
  10. 40 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/enums/DeveloperTerminalType.java
  11. 36 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/enums/DomainRegisterType.java
  12. 34 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/enums/IdStarterEnum.java
  13. 47 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/enums/ResultCodeEnum.java
  14. 98 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/generator/MysqlGenerator.java
  15. 103 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/module/Result.java
  16. 16 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/service/ITmDeveloperService.java
  17. 16 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/service/ITmDomainListService.java
  18. 20 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/service/impl/TmDeveloperServiceImpl.java
  19. 20 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/service/impl/TmDomainListServiceImpl.java
  20. 137 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/utils/DataUtils.java
  21. 839 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/utils/FileUtils.java
  22. 253 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/utils/HttpClientUtil.java
  23. 57 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/utils/SHAUtils.java
  24. 26 0
      4dkankan-open-gateway-base/src/main/java/api/gateway/utils/UUidGenerator.java
  25. 59 0
      4dkankan-open-gateway-main/pom.xml
  26. 35 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/GateWayApiApplication.java
  27. 180 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/controller/developer/AdminDeveloperController.java
  28. 57 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/controller/fdage/DomainController.java
  29. 19 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/controller/gateway/GatewayErrorDefaultController.java
  30. 48 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/exception/CommonBaseException.java
  31. 39 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/exception/ControllerHanderException.java
  32. 65 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/exception/ExceptionHandlerConfiguration.java
  33. 97 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/exception/JsonExceptionHandler.java
  34. 79 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/filters/CachePostBodyFilter.java
  35. 114 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/filters/CommonAuthFilter.java
  36. 64 0
      4dkankan-open-gateway-main/src/main/java/api/gateway/filters/FilterConfigration.java
  37. 75 0
      4dkankan-open-gateway-main/src/main/resources/application-dev.properties
  38. 76 0
      4dkankan-open-gateway-main/src/main/resources/application-prod.properties
  39. 71 0
      4dkankan-open-gateway-main/src/main/resources/application-test.properties
  40. 3 0
      4dkankan-open-gateway-main/src/main/resources/application.properties
  41. 57 0
      4dkankan-open-gateway-main/src/main/resources/bootstrap.yml
  42. BIN
      4dkankan-open-gateway-main/src/main/resources/favicon.ico
  43. 65 0
      4dkankan-open-gateway-main/src/main/resources/log4j2.xml
  44. 250 0
      pom.xml
  45. BIN
      readmeDoc/四维看房4Dkankan开放api说明文档_v1.1.docx
  46. 1 0
      remark.md

+ 53 - 0
4dkankan-open-gateway-base/pom.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.4dage</groupId>
+    <artifactId>4dkankan-open-gateway-base</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <description>四维看房开放api网关基础模块</description>
+
+    <parent>
+        <groupId>org.4dage</groupId>
+        <artifactId>4dkankan-open-gateway-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../</relativePath> <!-- lookup parent from repository -->
+    </parent>
+
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+           <!-- <version>4.5</version>-->
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <!-- 打包成可依赖的jar, 并且没有主类,不可运行 -->
+                    <layout>NONE</layout>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                        <configuration>
+                            <classifier>exec</classifier>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+
+    </build>
+</project>

+ 28 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/config/MyBatisPlusConfig.java

@@ -0,0 +1,28 @@
+package api.gateway.config;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/3 14:53
+ * @desciption
+ */
+@Configuration
+public class MyBatisPlusConfig {
+
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        //mybatis-plus分页配置
+        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
+        // paginationInterceptor.setOverflow(false);
+        // 设置最大单页限制数量,默认 500 条,-1 不受限制
+        // paginationInterceptor.setLimit(500);
+        // 开启 count 的 join 优化,只针对部分 left join
+        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
+        return paginationInterceptor;
+    }
+}

+ 15 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/config/RateLimiterConfiguration.java

@@ -0,0 +1,15 @@
+package api.gateway.config;
+
+import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import reactor.core.publisher.Mono;
+
+@Configuration
+public class RateLimiterConfiguration {
+
+    @Bean(value = "ipKeyResolver")
+    public KeyResolver ipKeyResolver() {
+        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
+    }
+}

+ 36 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/config/RedisConfiguration.java

@@ -0,0 +1,36 @@
+package api.gateway.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfiguration {
+
+    @Bean("redisTemplate")
+    public RedisTemplate redisTemplate(@Value("${spring.redis.host}") String host,
+                                       @Value("${spring.redis.port}") int port) {
+        RedisTemplate redisTemplate = new RedisTemplate();
+        RedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+        redisTemplate.setHashKeySerializer(stringRedisSerializer);
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.setConnectionFactory(standaloneConnectionFactory(host, port));
+        return redisTemplate;
+    }
+
+    protected JedisConnectionFactory standaloneConnectionFactory(String host, int port) {
+        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
+        redisStandaloneConfiguration.setHostName(host);
+        redisStandaloneConfiguration.setPort(port);
+        return new JedisConnectionFactory(redisStandaloneConfiguration);
+    }
+}

+ 51 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/config/SwaggerApp.java

@@ -0,0 +1,51 @@
+/*
+package api.gateway.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+*/
+/**
+ * @author abnerhou
+ * @date 2020/5/15 18:27
+ * @desciption
+ *//*
+
+@Configuration
+@EnableSwagger2
+public class SwaggerApp {
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                //为当前包路径
+                .apis(RequestHandlerSelectors.basePackage("api.gateway"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    //构建 api文档的详细信息函数,注意这里的注解引用的是哪个
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                //页面标题
+                .title("开放API网关后端 API")
+                //创建人
+                .contact(new Contact("Abner", "", "houweiyu@cgaii.com"))
+                //版本号
+                .version("1.0")
+                //描述
+                .description("包括用户API以及管理后台的所有接口")
+                .build();
+    }
+}
+*/

+ 16 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/dao/TmDeveloperDao.java

@@ -0,0 +1,16 @@
+package api.gateway.dao;
+
+import api.gateway.entity.TmDeveloper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 开发者信息表 Mapper 接口
+ * </p>
+ *
+ * @author abner
+ * @since 2020-06-18
+ */
+public interface TmDeveloperDao extends BaseMapper<TmDeveloper> {
+
+}

+ 16 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/dao/TmDomainListDao.java

@@ -0,0 +1,16 @@
+package api.gateway.dao;
+
+import api.gateway.entity.TmDomainList;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author abner
+ * @since 2020-10-15
+ */
+public interface TmDomainListDao extends BaseMapper<TmDomainList> {
+
+}

+ 82 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/entity/TmDeveloper.java

@@ -0,0 +1,82 @@
+package api.gateway.entity;
+
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 开发者信息表
+ * </p>
+ *
+ * @author abner
+ * @since 2020-06-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="TmDeveloper对象", description="开发者信息表")
+public class TmDeveloper implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "开发者id")
+    private String developerId;
+
+    @ApiModelProperty(value = "开发者应用id")
+    private String appId;
+
+    @ApiModelProperty(value = "开发者所属公司统一社会信用代码")
+    private String companyCreditCode;
+
+    @ApiModelProperty(value = "开发者应用密钥")
+    private String appSecret;
+
+    @ApiModelProperty(value = "模式")
+    private String state;
+
+    @ApiModelProperty(value = "使用的微信小程序的app id")
+    private String wxAppId;
+
+    @ApiModelProperty(value = "开发者所属公司")
+    private String company;
+
+    @ApiModelProperty(value = "开发者所属公司固话号码")
+    private String tel;
+
+    @ApiModelProperty(value = "开发者所属公司法人名字")
+    private String legalPersonName;
+
+    @ApiModelProperty(value = "开发者所属公司法人手机号码")
+    private String legalPersonPhone;
+
+    @ApiModelProperty(value = "是否可用: 2审批通过 1 待审批 0 不可用")
+    private Integer enable;
+
+    @ApiModelProperty(value = "创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "最新修改时间")
+    private LocalDateTime lastModifyDatetime;
+
+    @ApiModelProperty(value = "openApi回调开发者接口的url")
+    private String callBackUrl;
+
+    @ApiModelProperty(value = "管理者手机号")
+    private String adminPhone;
+
+    @ApiModelProperty(value = "管理者邮箱")
+    private String adminEmail;
+
+    @ApiModelProperty(value = "微信小程序校验文件链接")
+    private String wxMiniProgramFile;
+
+    @ApiModelProperty(value = "所属领域")
+    private String domainType;
+
+
+}

+ 67 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/entity/TmDomainList.java

@@ -0,0 +1,67 @@
+package api.gateway.entity;
+
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author abner
+ * @since 2020-10-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="TmDomainList对象", description="")
+public class TmDomainList implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "主键id")
+    private Integer domainId;
+
+    @ApiModelProperty(value = "领域名称")
+    private String domainName;
+
+    @ApiModelProperty(value = "领域部署机器IP")
+    private String domainIp;
+
+    @ApiModelProperty(value = "领域部署机器端口")
+    private String domainIpPort;
+
+    @ApiModelProperty(value = "领域所属的组")
+    private String domainGroup;
+
+    @ApiModelProperty(value = "领域所属二级组")
+    private String domainSubGroup;
+
+    @ApiModelProperty(value = "领域实例绑定域名")
+    private String domainLink;
+
+    @ApiModelProperty(value = "领域编号")
+    private Integer domainSeqNum;
+
+    @ApiModelProperty(value = "创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "最后修改时间")
+    private LocalDateTime lastModifyDatetime;
+
+    @ApiModelProperty(value = "是否可以用:1 可用,0 不可用")
+    private Integer enable;
+
+    @ApiModelProperty(value = "登记类型: 1->热点")
+    private Integer registerType;
+
+    @ApiModelProperty(value = "请求路径标识")
+    private String domainPath;
+
+
+}

+ 40 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/enums/DeveloperTerminalType.java

@@ -0,0 +1,40 @@
+package api.gateway.enums;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/5 18:16
+ * @desciption
+ */
+public enum DeveloperTerminalType {
+    CUSTOMER("customer" , "用户端"),
+    AGENT("agent" , "经纪人端"),
+    ;
+    private String type;
+    private String desc;
+
+    DeveloperTerminalType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public  static DeveloperTerminalType getByType(String type){
+        if(StringUtils.isNoneBlank(type)){
+            for (DeveloperTerminalType terminalType : DeveloperTerminalType.values()){
+                if(StringUtils.equals(terminalType.getType() , type)){
+                    return terminalType;
+                }
+            }
+        }
+        return null;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 36 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/enums/DomainRegisterType.java

@@ -0,0 +1,36 @@
+package api.gateway.enums;
+
+/**
+ * @author abnerhou
+ * @date 2020/10/15 12:20
+ * @desciption
+ */
+public enum DomainRegisterType {
+
+    HOT_TYPE(1 , "热点"),
+    ;
+
+    private int type;
+    private String desc;
+
+    DomainRegisterType(int type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 34 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/enums/IdStarterEnum.java

@@ -0,0 +1,34 @@
+package api.gateway.enums;
+
+/**
+ * @author abnerhou
+ * @date 2020/4/22 17:19
+ * @desciption
+ */
+public enum IdStarterEnum {
+
+    DEFAULT("1001" ,"默认表id初始值"),
+    RELATION("1010" ,"关联关系Id的初始值"),
+    DEVELOPER("1020" ,"开发者id的初始值"),
+    APP_ID("1030" ,"开发者应用id的初始值"),
+    APP_SECRET("1040" ,"开发者应用密钥的初始值"),
+
+    ;
+
+    private String starter;
+
+    private String desc;
+
+    IdStarterEnum(String starter, String desc) {
+        this.starter = starter;
+        this.desc = desc;
+    }
+
+    public String getStarter() {
+        return starter;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 47 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/enums/ResultCodeEnum.java

@@ -0,0 +1,47 @@
+package api.gateway.enums;
+
+/**
+ * @author abnerhou
+ * @date 2020/5/6 8:23
+ * @desciption
+ */
+public enum ResultCodeEnum {
+
+    D3001(3001 , "缺少必要参数" , true),
+    D3002(3002 , "token非法" , false),
+    D3003(3003 , "APP ID 缺失" ,false),
+    D3004(3004 , "入参数据缺失" , true),
+    D3005(3005 , "权限不足", true),
+    D3006(3006 , "非法的APP ID" , false),
+    D3007(3007 , "时间超时" , true),
+    D3008(3008 , "解析数据签名失败" , true),
+    D3009(3009 , "数据已经被篡改" , true),
+    D3010(3010 , "终端用户类型非法" , true),
+    D3011(3011 , "非法的用户类型" , true),
+
+    D100(3100 , "系统异常" , true),
+    D101(3101 , "数据异常" , true),
+    ;
+
+    ResultCodeEnum(Integer code, String desc , Boolean canBeReplace) {
+        this.code = code;
+        this.desc = desc;
+        this.canBeReplace = canBeReplace;
+    }
+
+    private Integer code;
+    private String desc;
+    private Boolean canBeReplace;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public Boolean getCanBeReplace() {
+        return canBeReplace;
+    }
+}

+ 98 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/generator/MysqlGenerator.java

@@ -0,0 +1,98 @@
+package api.gateway.generator;
+
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/3 14:54
+ * @desciption
+ */
+public class MysqlGenerator {
+
+    public static void main(String[] args) {
+        AutoGenerator mpg = new AutoGenerator();
+
+        GlobalConfig gc = new GlobalConfig();
+        String projectPath = System.getProperty("user.dir");
+        gc.setOutputDir(projectPath + "/4dkankan-open-gateway-base/src/main/java");
+        gc.setAuthor("abner");   // 作者
+        gc.setOpen(false);      //生成代码后是否打开文件夹
+        gc.setSwagger2(true);
+        gc.setMapperName("%sDao");
+//        gc.setXmlName("%sMapper");
+//        gc.setControllerName("%sController");
+        gc.setFileOverride(true);//是否覆盖
+        mpg.setGlobalConfig(gc);
+
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://120.25.146.52:3306/4dage-api-gateway?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("4dkk2020test%");
+        mpg.setDataSource(dsc);
+
+        // 包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setModuleName("gateway"); // 模块名称, 这里可以根据不同模块来写
+        pc.setParent("api"); // 父包名
+        pc.setMapper("dao");
+        pc.setController("controller");
+
+        mpg.setPackageInfo(pc);
+
+        // 配置模板
+        TemplateConfig templateConfig = new TemplateConfig();
+
+        //控制 不生成 controller
+        templateConfig.setController("");
+
+        templateConfig.setXml(null);
+        mpg.setTemplate(templateConfig);
+
+
+        // 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                Map<String, Object> map = new HashMap<String, Object>();
+                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
+                this.setMap(map);
+            }
+        };
+
+        // 调整 xml 生成目录演示
+        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
+        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                return  "E:\\code\\projects\\4dkankanOpenGateWay\\4dkankan-open-gateway-base\\src\\main\\resources\\mybatis\\mappers\\" + tableInfo.getEntityName() + "Mapper.xml";
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+
+
+        // 策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+//        strategy.setSuperEntityClass("house.api.base.model");
+
+        strategy.setEntityLombokModel(true);
+//        strategy.setInclude("tm_developer","tm_domain_list");  // 如果要生成多个,这里可以传入String[]
+        strategy.setInclude("tm_domain_list");  // 如果要生成多个,这里可以传入String[]
+        mpg.setStrategy(strategy);
+        //TODO:使用的时候,释放出来就可以了
+        mpg.execute();
+        System.out.println("代码自动生成执行完成");
+    }
+}

+ 103 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/module/Result.java

@@ -0,0 +1,103 @@
+package api.gateway.module;
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 通用返回类
+ *
+ * @author
+ */
+@Data
+public class Result<T> implements Serializable {
+    private static final long serialVersionUID = -1491499610244557029L;
+    public static final String SUCCESS_MSG = "操作成功";
+    public static Integer CODE_SUCCESS = 0;
+    public static Integer CODE_FAILURE = -1;
+    public static String[] NOOP = new String[]{};
+
+    /**
+     * 处理状态:0: 成功, 1: 失败
+     */
+    private Integer code;
+    /**
+     * 消息
+     */
+    private String msg;
+    /**
+     * 返回数据
+     */
+
+    private T data;
+
+
+    public Result(Integer code, String msg, T data) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static  Result success(Object data) {
+        return new  Result(CODE_SUCCESS, SUCCESS_MSG, data);
+    }
+    /**
+     * 处理成功
+     *
+     * @return data
+     */
+    public static  Result success() {
+        return new  Result(CODE_SUCCESS, SUCCESS_MSG, NOOP);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static  Result success(String msg) {
+        return new  Result(CODE_SUCCESS, msg, NOOP);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg  消息
+     * @param data 数据对象
+     * @return data
+     */
+    public static  Result success(String msg, Object data) {
+        return new  Result(CODE_SUCCESS, msg, data);
+    }
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static  Result failure(Integer code, String msg) {
+        return new  Result(code, msg, NOOP);
+    }
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static  Result failure(String msg) {
+        return failure(CODE_FAILURE, msg);
+    }
+
+    @Override
+    public String toString() {
+        return "JsonResult [code=" + code + ", msg=" + msg + ", data="
+                + data + "]";
+    }
+}

+ 16 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/service/ITmDeveloperService.java

@@ -0,0 +1,16 @@
+package api.gateway.service;
+
+import api.gateway.entity.TmDeveloper;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 开发者信息表 服务类
+ * </p>
+ *
+ * @author abner
+ * @since 2020-06-18
+ */
+public interface ITmDeveloperService extends IService<TmDeveloper> {
+
+}

+ 16 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/service/ITmDomainListService.java

@@ -0,0 +1,16 @@
+package api.gateway.service;
+
+import api.gateway.entity.TmDomainList;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author abner
+ * @since 2020-10-15
+ */
+public interface ITmDomainListService extends IService<TmDomainList> {
+
+}

+ 20 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/service/impl/TmDeveloperServiceImpl.java

@@ -0,0 +1,20 @@
+package api.gateway.service.impl;
+
+import api.gateway.entity.TmDeveloper;
+import api.gateway.dao.TmDeveloperDao;
+import api.gateway.service.ITmDeveloperService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 开发者信息表 服务实现类
+ * </p>
+ *
+ * @author abner
+ * @since 2020-06-18
+ */
+@Service
+public class TmDeveloperServiceImpl extends ServiceImpl<TmDeveloperDao, TmDeveloper> implements ITmDeveloperService {
+
+}

+ 20 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/service/impl/TmDomainListServiceImpl.java

@@ -0,0 +1,20 @@
+package api.gateway.service.impl;
+
+import api.gateway.entity.TmDomainList;
+import api.gateway.dao.TmDomainListDao;
+import api.gateway.service.ITmDomainListService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author abner
+ * @since 2020-10-15
+ */
+@Service
+public class TmDomainListServiceImpl extends ServiceImpl<TmDomainListDao, TmDomainList> implements ITmDomainListService {
+
+}

+ 137 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/utils/DataUtils.java

@@ -0,0 +1,137 @@
+package api.gateway.utils;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author abnerhou
+ * @date 2020/4/23 17:35
+ * @desciption
+ */
+@Component
+public class DataUtils {
+
+    public static BigDecimal getBigDecimalObj(Object data) {
+
+        if (null == data) {
+            return null;
+        } else if (data instanceof String) {
+            String dataStr = (String) data;
+            if (!StringUtils.isEmpty(dataStr.trim())) {
+                return new BigDecimal(dataStr.trim());
+            }
+        } else if (data instanceof Long) {
+            Long dataLong = (Long) data;
+            return BigDecimal.valueOf(dataLong);
+        } else if (data instanceof Integer) {
+            Integer dataInt = (Integer) data;
+            return BigDecimal.valueOf(dataInt);
+
+        } else if (data instanceof Double) {
+            Double dataDouble = (Double) data;
+            return BigDecimal.valueOf(dataDouble);
+        }
+
+        return null;
+
+    }
+
+    public static Integer getInteger(Object object) {
+        if (null == object) {
+            return new Integer(0);
+        }
+        if (object instanceof String) {
+            String ojStr = (String) object;
+            if (StringUtils.isEmpty(ojStr)) {
+                //TODO:在斟酌这里的处理方式
+                return new Integer(0);
+            } else {
+                return new Integer(Integer.parseInt(ojStr.trim()));
+            }
+        } else if (object instanceof Integer) {
+            return (Integer) object;
+        } else if (object instanceof Long) {
+            return (Integer) object;
+        } else if (object instanceof Double) {
+            return (Integer) object;
+        } else {
+            return new Integer(0);
+        }
+    }
+
+    public static Long getLongReturnNullIfNotExit(Object num){
+        if(null == num){
+            return null;
+        }else if(num instanceof String){
+            if(org.apache.commons.lang3.StringUtils.isNotBlank((String) num)){
+                String numStr = (String) num;
+                return Long.parseLong(numStr.trim());
+            }
+        }else if(num instanceof Integer){
+            return (Long) num;
+        }else if(num instanceof  Long){
+            return (Long) num;
+        }
+        return null;
+    }
+
+    public static Integer getIntegerWithDefault(Object object, boolean withDefault) {
+        if (null == object) {
+
+            return withDefault ? new Integer(0) : null;
+        }
+        if (object instanceof String) {
+            String ojStr = (String) object;
+            if (StringUtils.isEmpty(ojStr)) {
+
+                return withDefault ? new Integer(0) : null;
+            } else {
+                return new Integer(Integer.parseInt(ojStr.trim()));
+            }
+        } else if (object instanceof Integer) {
+            return (Integer) object;
+        } else if (object instanceof Long) {
+            return (Integer) object;
+        } else if (object instanceof Double) {
+            return (Integer) object;
+        } else {
+            return withDefault ? new Integer(0) : null;
+        }
+    }
+
+    public static Map<String, Object> assembleResult(long totalNum, long totalPageNum, long currPageNum, Object list) {
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("totalNum", totalNum);
+        resultMap.put("totalPageNum", totalPageNum);
+        resultMap.put("curPage", currPageNum);
+        resultMap.put("list", list);
+        return resultMap;
+    }
+
+    public static <T> void assembleTimeQueryWrapper(Map<String, Object> constantQuery, String dynamicQuery,
+                                                    QueryWrapper<T> queryWrapper, String idQuery,
+                                                    String secondQuery, String thirdQuery) {
+        assembleConstantQuery(queryWrapper, constantQuery);
+        if (org.apache.commons.lang3.StringUtils.isNotBlank(dynamicQuery)) {
+            queryWrapper.and(wrapper -> wrapper
+                    .or().like(org.apache.commons.lang3.StringUtils.isNotBlank(secondQuery), secondQuery, dynamicQuery)
+                    .or().like(org.apache.commons.lang3.StringUtils.isNotBlank(thirdQuery), thirdQuery, dynamicQuery)
+                    .or().like(dynamicQuery.length() <= 32 && org.apache.commons.lang3.StringUtils.isNotBlank(idQuery), idQuery, dynamicQuery));
+        }
+
+    }
+
+    public static <T> void assembleConstantQuery(QueryWrapper<T> queryWrapper, Map<String, Object> constantQuery) {
+        if (null != queryWrapper && !CollectionUtils.isEmpty(constantQuery)) {
+            for (Map.Entry<String, Object> entry : constantQuery.entrySet()) {
+                queryWrapper.eq(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+}

+ 839 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/utils/FileUtils.java

@@ -0,0 +1,839 @@
+package api.gateway.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Decoder;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.*;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipFile;
+import org.apache.tools.zip.ZipOutputStream;
+
+@Slf4j
+public class FileUtils {
+
+    //文件路径+名称
+    private static String fileNameTemp;
+
+    public static void uploadImg(String path, String base64Data)
+            throws Exception {
+        byte[] bt = null;
+        try {
+            BASE64Decoder decoder = new BASE64Decoder();
+            if (base64Data.startsWith("data:image/png;base64,")) {
+                bt = decoder.decodeBuffer(base64Data.replace("data:image/png;base64,", ""));
+            } else if (base64Data.startsWith("data:image/jpeg;base64,")) {
+                bt = decoder.decodeBuffer(base64Data.replace("data:image/jpeg;base64,", ""));
+            } else if (base64Data.startsWith("data:image/bmp;base64,")) {
+                bt = decoder.decodeBuffer(base64Data.replace("data:image/bmp;base64,", ""));
+            } else {
+                return;
+            }
+            writeBinary(bt, path);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static void writeBinary(byte[] buf, String filePath) throws Exception {
+        File fout = new File(filePath);
+        if (!fout.getParentFile().exists()) {
+            fout.getParentFile().mkdirs();
+        }
+        FileOutputStream fos = new FileOutputStream(fout);
+        ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+        BufferedOutputStream bos = new BufferedOutputStream(fos);//设置输出路径
+        BufferedInputStream bis = new BufferedInputStream(stream);
+        int b = -1;
+        while ((b = bis.read()) != -1) {
+            bos.write(b);
+        }
+        bis.close();
+        bos.close();
+    }
+
+    public static boolean createDir(String destDirName) {
+        File dir = new File(destDirName);
+        if (dir.exists()) {
+            System.out.println("创建目录" + destDirName + "失败,目标目录已经存在");
+            return false;
+        }
+        if (!destDirName.endsWith(File.separator)) {
+            destDirName = destDirName + File.separator;
+        }
+        //创建目录  
+        if (dir.mkdirs()) {
+            System.out.println("创建目录" + destDirName + "成功!");
+            return true;
+        } else {
+            System.out.println("创建目录" + destDirName + "失败!");
+            return false;
+        }
+    }
+
+
+    /**
+     * 创建文件
+     *
+     * @param fileName    文件名称
+     * @param fileContent 文件内容
+     * @return 是否创建成功,成功则返回true
+     */
+    public static boolean createFile(String path, String fileName, String fileContent) {
+        Boolean bool = false;
+        fileNameTemp = path + fileName + ".json";//文件路径+名称+文件类型
+        File file = new File(fileNameTemp);
+        try {
+            File folder = new File(path);
+            if (!folder.exists()) {
+                folder.mkdirs();
+            }
+            //如果文件不存在,则创建新的文件
+            if (!file.exists()) {
+                file.createNewFile();
+                bool = true;
+                System.out.println("success create file,the file is " + fileNameTemp);
+                //创建文件成功后,写入内容到文件里
+                writeFileContent(fileNameTemp, fileContent);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return bool;
+    }
+
+    /**
+     * 向文件中写入内容
+     *
+     * @param filePath 文件路径与名称
+     * @param newstr   写入的内容
+     * @return
+     * @throws IOException
+     */
+    public static boolean writeFileContent(String filePath, String newstr) throws IOException {
+        Boolean bool = false;
+        String filein = newstr + "\r\n";//新写入的行,换行
+        String temp = "";
+
+        FileInputStream fis = null;
+        InputStreamReader isr = null;
+        BufferedReader br = null;
+        FileOutputStream fos = null;
+        PrintWriter pw = null;
+        try {
+            File file = new File(filePath);//文件路径(包括文件名称)
+            //将文件读入输入流
+            fis = new FileInputStream(file);
+            isr = new InputStreamReader(fis);
+            br = new BufferedReader(isr);
+            StringBuffer buffer = new StringBuffer();
+
+            //文件原有内容
+            for (int i = 0; (temp = br.readLine()) != null; i++) {
+                buffer.append(temp);
+                // 行与行之间的分隔符 相当于“\n”
+                buffer = buffer.append(System.getProperty("line.separator"));
+            }
+            buffer.append(filein);
+
+            fos = new FileOutputStream(file);
+            pw = new PrintWriter(fos);
+            pw.write(buffer.toString().toCharArray());
+            pw.flush();
+            bool = true;
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        } finally {
+            //不要忘记关闭
+            if (pw != null) {
+                pw.close();
+            }
+            if (fos != null) {
+                fos.close();
+            }
+            if (br != null) {
+                br.close();
+            }
+            if (isr != null) {
+                isr.close();
+            }
+            if (fis != null) {
+                fis.close();
+            }
+        }
+        return bool;
+    }
+
+
+    public static String parseFile(MultipartFile multipartFile , String fileBackupPath) {
+        File directory = new File(fileBackupPath);
+        if (!directory.exists()) {
+            directory.mkdirs();
+        }
+        String fileName = fileBackupPath.concat(multipartFile.getOriginalFilename());
+        log.info("上传的文件名:{}", fileName);
+        File file = new File(fileName);
+        if(file.exists()){
+            deleteFile(fileName);
+            file = new File(fileName);
+        }
+        try {
+            InputStream is = multipartFile.getInputStream();
+            FileOutputStream os = new FileOutputStream(file);
+            byte[] b = new byte[2048];
+            int length;
+            while ((length = is.read(b)) > 0) {
+                os.write(b, 0, length);
+            }
+            is.close();
+            os.close();
+        } catch (IOException e) {
+            log.info("文件存储本地出现异常:{}", e);
+        }
+        return fileName;
+    }
+
+
+
+
+
+    /**
+     * 删除单个文件
+     *
+     * @param fileName 要删除的文件的文件名
+     * @return 单个文件删除成功返回true,否则返回false
+     */
+    public static boolean deleteFile(String fileName) {
+        File file = new File(fileName);
+        if (file.exists() && file.isFile()) {
+            if (file.delete()) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 根据路径删除指定的目录,无论存在与否
+     *
+     * @param sPath 要删除的目录path
+     * @return 删除成功返回 true,否则返回 false。
+     */
+    public static boolean deleteFolder(String sPath) {
+        boolean flag = false;
+        File file = new File(sPath);
+        // 判断目录或文件是否存在
+        if (!file.exists()) {  // 不存在返回 false
+            return flag;
+        } else {
+            // 判断是否为文件
+            if (file.isFile()) {  // 为文件时调用删除文件方法
+                return deleteFile(sPath);
+            } else {  // 为目录时调用删除目录方法
+                return deleteDirectory(sPath);
+            }
+        }
+    }
+
+    /**
+     * 删除目录以及目录下的文件
+     *
+     * @param sPath 被删除目录的路径
+     * @return 目录删除成功返回true,否则返回false
+     */
+    public static boolean deleteDirectory(String sPath) {
+        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
+        if (!sPath.endsWith(File.separator)) {
+            sPath = sPath + File.separator;
+        }
+        File dirFile = new File(sPath);
+        //如果dir对应的文件不存在,或者不是一个目录,则退出
+        if (!dirFile.exists() || !dirFile.isDirectory()) {
+            return false;
+        }
+        boolean flag = true;
+        //删除文件夹下的所有文件(包括子目录)
+        File[] files = dirFile.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            //删除子文件
+            if (files[i].isFile()) {
+                flag = deleteFile(files[i].getAbsolutePath());
+                if (!flag) {
+                    break;
+                }
+            } //删除子目录
+            else {
+                flag = deleteDirectory(files[i].getAbsolutePath());
+                if (!flag) {
+                    break;
+                }
+            }
+        }
+        if (!flag) {
+            return false;
+        }
+        //删除当前目录
+        if (dirFile.delete()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //按行读文件
+    public static String readFile(String path) throws Exception {
+        File f = new File(path);
+        if (!f.exists()) {
+            return null;
+        }
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
+        BufferedInputStream in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(f));
+            int buf_size = 1024;
+            byte[] buffer = new byte[buf_size];
+            int len = 0;
+            while (-1 != (len = in.read(buffer, 0, buf_size))) {
+                bos.write(buffer, 0, len);
+            }
+            return bos.toString();
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        } finally {
+            try {
+                in.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            bos.close();
+        }
+    }
+
+    public static boolean copyFile(String srcFileName, String destFileName, boolean overlay) {
+        File srcFile = new File(srcFileName);
+        // 判断源文件是否存在
+        if (!srcFile.exists()) {
+            return false;
+        } else if (!srcFile.isFile()) {
+            return false;
+        }
+        // 判断目标文件是否存在
+        File destFile = new File(destFileName);
+        if (destFile.exists()) {
+            // 如果目标文件存在并允许覆盖
+            if (overlay) {
+                // 删除已经存在的目标文件,无论目标文件是目录还是单个文件
+                new File(destFileName).delete();
+            }
+        } else {
+            // 如果目标文件所在目录不存在,则创建目录
+            if (!destFile.getParentFile().exists()) {
+                // 目标文件所在目录不存在
+                if (!destFile.getParentFile().mkdirs()) {
+                    // 复制文件失败:创建目标文件所在目录失败
+                    return false;
+                }
+            }
+        }
+        // 复制文件
+        int byteread = 0; // 读取的字节数
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = new FileInputStream(srcFile);
+            out = new FileOutputStream(destFile);
+            byte[] buffer = new byte[1024];
+
+            while ((byteread = in.read(buffer)) != -1) {
+                out.write(buffer, 0, byteread);
+            }
+            return true;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 从网络Url中下载文件
+     *
+     * @param urlStr
+     * @param fileName
+     * @param savePath
+     * @return
+     * @throws IOException
+     */
+    public static boolean downLoadFromUrl(String urlStr, String fileName, String savePath) {
+        FileOutputStream fos = null;
+        InputStream inputStream = null;
+        try {
+            URL url = new URL(urlStr);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            // 设置超时间为3秒
+            conn.setConnectTimeout(3 * 1000);
+            // 防止屏蔽程序抓取而返回403错误
+            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+
+            // 得到输入流
+            inputStream = conn.getInputStream();
+            // 获取自己数组
+            byte[] getData = readInputStream(inputStream);
+
+            // 文件保存位置
+            File saveDir = new File(savePath);
+            if (!saveDir.exists()) {
+                saveDir.mkdirs();
+            }
+            String filePath = saveDir + File.separator + fileName;
+            String filePathFolder = filePath.substring(0, filePath.lastIndexOf("/") + 1);
+            createDir(filePathFolder);
+
+            File file = new File(filePath);
+            fos = new FileOutputStream(file);
+            fos.write(getData);
+            if (fos != null) {
+                fos.close();
+            }
+            if (inputStream != null) {
+                inputStream.close();
+            }
+            System.out.println("info:" + url + " download success");
+        } catch (FileNotFoundException e) {
+            return false;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 从输入流中获取字节数组
+     *
+     * @param inputStream
+     * @return
+     * @throws IOException
+     */
+    private static byte[] readInputStream(InputStream inputStream) throws IOException {
+        byte[] buffer = new byte[1024];
+        int len = 0;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        while ((len = inputStream.read(buffer)) != -1) {
+            bos.write(buffer, 0, len);
+        }
+        bos.close();
+        return bos.toByteArray();
+    }
+
+
+    public static void writeFile(String filePath, String str) throws IOException {
+        File fout = new File(filePath);
+        if (!fout.getParentFile().exists()) {
+            fout.getParentFile().mkdirs();
+        }
+        if (!fout.exists()) {
+            fout.createNewFile();
+        }
+        FileOutputStream fos = new FileOutputStream(fout);
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
+        bw.write(str);
+        bw.close();
+    }
+
+    /**
+     * 将byte数组写入文件
+     *
+     * @param path
+     * @param fileName
+     * @param content
+     * @throws IOException
+     */
+    public static void writeFile(String path, String fileName, byte[] content)
+            throws IOException {
+        try {
+            File f = new File(path);
+            if (!f.exists()) {
+                f.mkdirs();
+            }
+            FileOutputStream fos = new FileOutputStream(path + fileName);
+            fos.write(content);
+            fos.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 向json文件写入参数,重复的覆盖,多的新增
+     *
+     * @return
+     */
+    public static void writeJsonFile(String path, Map<String, Object> map) throws Exception {
+        String str = readFile(path);
+        JSONObject json = new JSONObject();
+        if (str != null) {
+            json = JSONObject.parseObject(str);
+        } else {
+            File file = new File(path);
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+            if (!file.exists()) {
+                file.createNewFile();
+            }
+        }
+        Iterator entries = map.entrySet().iterator();
+        while (entries.hasNext()) {
+            Map.Entry entry = (Map.Entry) entries.next();
+            json.put(String.valueOf(entry.getKey()), entry.getValue());
+        }
+
+        writeFile(path, json.toString());
+    }
+
+    public static void decompress(String srcPath, String dest) throws Exception {
+
+        File file = new File(srcPath);
+
+        if (!file.exists()) {
+
+            throw new RuntimeException(srcPath + "所指文件不存在");
+
+        }
+
+        ZipFile zf = new ZipFile(file);
+
+        Enumeration entries = zf.getEntries();
+
+        ZipEntry entry = null;
+
+        while (entries.hasMoreElements()) {
+
+            entry = (ZipEntry) entries.nextElement();
+
+            log.info("解压" + entry.getName());
+
+            if (entry.isDirectory()) {
+
+                String dirPath = dest + File.separator + entry.getName();
+
+                File dir = new File(dirPath);
+
+                dir.mkdirs();
+
+            } else {
+
+                // 表示文件
+
+                File f = new File(dest + File.separator + entry.getName());
+
+                if (!f.exists()) {
+
+                    //String dirs = FileUtils.getParentPath(f);
+                    String dirs = f.getParent();
+
+                    File parentDir = new File(dirs);
+
+                    parentDir.mkdirs();
+
+
+                }
+
+                f.createNewFile();
+
+                // 将压缩文件内容写入到这个文件中
+
+                InputStream is = zf.getInputStream(entry);
+
+                FileOutputStream fos = new FileOutputStream(f);
+
+
+                int count;
+
+                byte[] buf = new byte[8192];
+
+                while ((count = is.read(buf)) != -1) {
+
+                    fos.write(buf, 0, count);
+
+                }
+
+                is.close();
+
+                fos.close();
+
+            }
+
+        }
+
+    }
+
+    public static void zipFile(String zipFileName, String inputFileName)
+            throws Exception {
+        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
+        out.setEncoding("UTF-8");
+        File inputFile = new File(inputFileName);
+        zipIt(out, inputFile, "", true);
+        out.close();
+    }
+
+    /*
+     * 能支持中文的压缩 参数base 开始为"" first 开始为true
+     */
+    public static void zipIt(ZipOutputStream out, File f,
+                             String base, boolean first) throws Exception {
+        if (f.isDirectory()) {
+            File[] fl = f.listFiles();
+            if (first) {
+                first = false;
+            } else {
+                base = base + "/";
+            }
+            for (int i = 0; i < fl.length; i++) {
+                zipIt(out, fl[i], base + fl[i].getName(), first);
+            }
+        } else {
+            if (first) {
+                base = f.getName();
+            }
+            out.putNextEntry(new org.apache.tools.zip.ZipEntry(base));
+            FileInputStream in = new FileInputStream(f);
+            int b;
+            while ((b = in.read()) != -1) {
+                out.write(b);
+            }
+            in.close();
+        }
+    }
+
+    //删除文件夹
+    public static void delFolder(String folderPath) {
+        try {
+            delAllFile(folderPath); //删除完里面所有内容
+            String filePath = folderPath;
+            filePath = filePath.toString();
+            File myFilePath = new File(filePath);
+            myFilePath.delete(); //删除空文件夹
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    //删除指定文件夹下的所有文件
+    public static boolean delAllFile(String path) {
+        boolean flag = false;
+        File file = new File(path);
+        if (!file.exists()) {
+            return flag;
+        }
+        if (!file.isDirectory()) {
+            return flag;
+        }
+        String[] tempList = file.list();
+        File temp = null;
+        if (tempList != null) {
+            for (int i = 0; i < tempList.length; i++) {
+                if (path.endsWith(File.separator)) {
+                    temp = new File(path + tempList[i]);
+                } else {
+                    temp = new File(path + File.separator + tempList[i]);
+                }
+                if (temp.isFile()) {
+                    temp.delete();
+                }
+                if (temp.isDirectory()) {
+                    delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
+                    delFolder(path + "/" + tempList[i]);//再删除空文件夹
+                    flag = true;
+                }
+            }
+        }
+
+        //再删除当前空文件夹
+        file.delete();
+        return flag;
+    }
+
+    public static List<String> readfileNamesForDirectory(String path, String except) {
+        try {
+            File file = new File(path);
+            if (file.isDirectory()) {
+                String[] fileNames = file.list();
+                List<String> list = new ArrayList<String>();
+                if (fileNames != null) {
+                    for (int i = 0; i < fileNames.length; ++i) {
+                        if (fileNames[i].toLowerCase().endsWith(except)) {
+                            list.add(fileNames[i]);
+                        }
+                    }
+                }
+
+                return list;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    //递归获取文件中所有文件的路径
+    public static List<String> readfilePath(String path, List<String> urlList) {
+        try {
+            File file = new File(path);
+            if (file != null && file.isDirectory()) {
+                File[] files = file.listFiles();
+
+                if (files != null) {
+                    for (int i = 0; i < files.length; ++i) {
+                        if (files[i].isDirectory()) {
+                            readfilePath(files[i].getAbsolutePath(), urlList);
+                        } else {
+                            urlList.add(files[i].getAbsolutePath());
+                        }
+                    }
+                }
+                return urlList;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return urlList;
+    }
+
+    public static void saveImageToDisk(String accessToken, String mediaId, String picName, String picPath, InputStream inputStream)
+            throws Exception {
+        byte[] data = new byte[10240];
+        int len = 0;
+        FileOutputStream fileOutputStream = null;
+        try {
+            fileOutputStream = new FileOutputStream(picPath + picName + ".amr");
+            while ((len = inputStream.read(data)) != -1) {
+                fileOutputStream.write(data, 0, len);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (fileOutputStream != null) {
+                try {
+                    fileOutputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * @param content base64内容
+     * @param path    输出文件路径,需要后缀名
+     * @return
+     */
+    public static boolean base64ToFileWriter(String content, String path) {
+        if (content == null) {
+            return false;
+        }
+        BASE64Decoder decoder = new BASE64Decoder();
+        try {
+            // decoder
+            byte[] b = decoder.decodeBuffer(content);
+            // processing data
+            for (int i = 0; i < b.length; ++i) {
+                if (b[i] < 0) {
+                    b[i] += 256;
+                }
+            }
+            OutputStream out = new FileOutputStream(path);
+            out.write(b);
+            out.flush();
+            out.close();
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * 获取类路径(classes路径)
+     */
+    public static String getResource() {
+        String path = "";
+        try {
+            path = ResourceUtils.getURL("classpath:").getPath();
+            path = URLDecoder.decode(path, "utf-8");
+        } catch (Exception e) {
+        }
+        return path;
+    }
+
+    /**
+     * 判断文件大小处于限制内
+     *
+     * @param fileLen  文件长度
+     * @param fileSize 限制大小
+     * @param fileUnit 限制的单位(B,K,M,G)
+     * @return
+     */
+    public static boolean checkFileSizeIsLimit(Long fileLen, double fileSize, String fileUnit) {
+//        long len = file.length();
+        double fileSizeCom = 0;
+        if ("B".equals(fileUnit.toUpperCase())) {
+            fileSizeCom = (double) fileLen;
+        } else if ("K".equals(fileUnit.toUpperCase())) {
+            fileSizeCom = (double) fileLen / 1024;
+        } else if ("M".equals(fileUnit.toUpperCase())) {
+            fileSizeCom = (double) fileLen / (1024 * 1024);
+        } else if ("G".equals(fileUnit.toUpperCase())) {
+            fileSizeCom = (double) fileLen / (1024 * 1024 * 1024);
+        }
+        if (fileSizeCom > fileSize) {
+            return false;
+        }
+        return true;
+
+    }
+
+}

+ 253 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/utils/HttpClientUtil.java

@@ -0,0 +1,253 @@
+package api.gateway.utils;
+
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * @author abnerhou
+ * @date 2020/5/11 17:48
+ * @desciption
+ */
+@Log4j2
+public class HttpClientUtil {
+
+    public static String doGetWithParam(String url, Map<String, String> param) {
+
+        // 创建Httpclient对象
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+
+        String resultString = "";
+        CloseableHttpResponse response = null;
+        try {
+            // 创建uri
+            URIBuilder builder = new URIBuilder(url);
+            if (param != null) {
+                for (String key : param.keySet()) {
+                    builder.addParameter(key, param.get(key));
+                }
+            }
+            URI uri = builder.build();
+
+            // 创建http GET请求
+            HttpGet httpGet = new HttpGet(uri);
+
+            // 执行请求
+            response = httpclient.execute(httpGet);
+            // 判断返回状态是否为200
+            if (response.getStatusLine().getStatusCode() == 200) {
+                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+            }
+        } catch (Exception e) {
+            log.error("http调用执行get出错:{}" , e);
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                httpclient.close();
+            } catch (IOException e) {
+               log.error("http调用执行get关闭资源出错:{}" , e);
+            }
+        }
+        return resultString;
+    }
+    public static String doGet(String url, Map<String, String[]>  param) {
+
+        // 创建Httpclient对象
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+
+        String resultString = "";
+        CloseableHttpResponse response = null;
+        try {
+            // 创建uri
+            URIBuilder builder = new URIBuilder(url);
+            if (param != null) {
+                for (String key : param.keySet()) {
+                    //TODO:是否有必要
+                    builder.addParameter(key, param.get(key)[0]);
+                }
+            }
+            URI uri = builder.build();
+            // 创建http GET请求
+            HttpGet httpGet = new HttpGet(uri);
+            // 执行请求
+            response = httpclient.execute(httpGet);
+            // 判断返回状态是否为200
+            if (response.getStatusLine().getStatusCode() == 200) {
+                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+            }
+        } catch (Exception e) {
+            log.error("http调用执行get出错:{}" , e);
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                httpclient.close();
+            } catch (IOException e) {
+               log.error("http调用执行get关闭资源出错:{}" , e);
+            }
+        }
+        return resultString;
+    }
+
+    public static String doGet(String url) {
+        return doGet(url, null);
+    }
+
+    public static String doPost(String url, Map<String, String> param) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            // 创建参数列表
+            if (param != null) {
+                List<NameValuePair> paramList = new ArrayList<>();
+                for (String key : param.keySet()) {
+                    paramList.add(new BasicNameValuePair(key, param.get(key)));
+                }
+                // 模拟表单
+                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
+                httpPost.setEntity(entity);
+            }
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            log.error("http执行post调用出错:{}" , e);
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                log.error("http执行post调用关闭资源出错:{}" , e);
+            }
+        }
+
+        return resultString;
+    }
+
+    public static String doPost(String url) {
+        return doPost(url, null);
+    }
+
+    public static String doPostJson(String url, String json) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            // 创建请求内容
+            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
+            httpPost.setEntity(entity);
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            log.error("http执行post调用出错:{}" , e);
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                log.error("http执行post调用关闭资源出错:{}" , e);
+            }
+        }
+
+        return resultString;
+    }
+
+    public static String doPostJsonWithHeader(String url, String json ,Map<String, Object> headers) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            // 创建请求内容
+            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
+            httpPost.setEntity(entity);
+
+            if(!CollectionUtils.isEmpty(headers)){
+                for (Map.Entry<String,Object> entry : headers.entrySet()){
+                    httpPost.addHeader(entry.getKey() , (String) entry.getValue());
+                }
+            }
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            log.error("http执行post调用出错:{}" , e);
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                log.error("http执行post调用关闭资源出错:{}" , e);
+            }
+        }
+
+        return resultString;
+    }
+
+    public static String doPostStreamWithHeader(String url, InputStream  inputStream , Map<String, Object> headers) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            String body = IOUtils.toString(inputStream , "utf-8");
+
+            // 创建请求内容
+            StringEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
+            httpPost.setEntity(entity);
+
+            if(!CollectionUtils.isEmpty(headers)){
+                for (Map.Entry<String,Object> entry : headers.entrySet()){
+                    httpPost.addHeader(entry.getKey() , (String) entry.getValue());
+                }
+            }
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            log.error("http执行post调用出错:{}" , e);
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                log.error("http执行post调用关闭资源出错:{}" , e);
+            }
+        }
+
+        return resultString;
+    }
+
+
+}

+ 57 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/utils/SHAUtils.java

@@ -0,0 +1,57 @@
+package api.gateway.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/5 11:33
+ * @desciption
+ */
+public class SHAUtils {
+
+    /**
+     * 利用java原生的类实现SHA256加密
+     *
+     * @param str
+     * @return
+     */
+    public static String getSHA256(String str) {
+        MessageDigest messageDigest;
+        String encodestr = "";
+        try {
+            messageDigest = MessageDigest.getInstance("SHA-256");
+            messageDigest.update(str.getBytes("UTF-8"));
+            encodestr = byte2Hex(messageDigest.digest());
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return encodestr;
+    }
+
+
+    //15 转16进制
+
+    /**
+     * 将byte转为16进制
+     *
+     * @param bytes
+     * @return
+     */
+    public static String byte2Hex(byte[] bytes) {
+        StringBuffer stringBuffer = new StringBuffer();
+        String temp = null;
+        for (int i = 0; i < bytes.length; i++) {
+            temp = Integer.toHexString(bytes[i] & 0xFF);
+            if (temp.length() == 1) {
+                //1得到一位的进行补0操作
+                stringBuffer.append("0");
+            }
+            stringBuffer.append(temp);
+        }
+        return stringBuffer.toString();
+    }
+}

+ 26 - 0
4dkankan-open-gateway-base/src/main/java/api/gateway/utils/UUidGenerator.java

@@ -0,0 +1,26 @@
+package api.gateway.utils;
+
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * @author abnerhou
+ * @date 2020/4/22 16:39
+ * @desciption
+ */
+@Component
+@Log4j2
+public class UUidGenerator {
+
+    public static String generatorUuid(String starter) {
+        StringBuilder stringBuilder = new StringBuilder();
+        String tmp = UUID.randomUUID().toString().replace("-", "");
+        tmp = tmp.substring(tmp.length() - 15);
+        stringBuilder.append(starter).append(tmp).append((new Date()).getTime());
+        return stringBuilder.toString();
+    }
+
+}

+ 59 - 0
4dkankan-open-gateway-main/pom.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+<!--    <groupId>org.4dage</groupId>-->
+    <artifactId>4dkankan-open-gateway-main</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <description>四维看房开放api网关核心模块</description>
+
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>org.4dage</groupId>
+        <artifactId>4dkankan-open-gateway-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../</relativePath> <!-- lookup parent from repository -->
+    </parent>
+
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.4dage</groupId>
+            <artifactId>4dkankan-open-gateway-base</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.75</version>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <finalName>open_gateway_01</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+
+</project>

+ 35 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/GateWayApiApplication.java

@@ -0,0 +1,35 @@
+package api.gateway;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/4 12:25
+ * @desciption
+ */
+@EnableCaching
+@EnableScheduling
+@EnableAsync
+@RestController
+@SpringBootApplication
+@EnableDiscoveryClient
+@MapperScan(basePackages = {"api.gateway.**"})
+public class GateWayApiApplication {
+
+
+
+
+    public static void main(String[] args) {
+        SpringApplication.run(GateWayApiApplication.class, args);
+    }
+}

+ 180 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/controller/developer/AdminDeveloperController.java

@@ -0,0 +1,180 @@
+package api.gateway.controller.developer;
+
+import api.gateway.dao.TmDeveloperDao;
+import api.gateway.entity.TmDeveloper;
+import api.gateway.enums.IdStarterEnum;
+import api.gateway.enums.ResultCodeEnum;
+import api.gateway.exception.CommonBaseException;
+import api.gateway.module.Result;
+import api.gateway.utils.DataUtils;
+import api.gateway.utils.FileUtils;
+import api.gateway.utils.UUidGenerator;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.*;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.bouncycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/18 9:48
+ * @desciption
+ */
+@Api(description = "开放api网关开发者管理相关接口")
+@Controller
+@RequestMapping("/admin/developer")
+@Log4j2
+public class AdminDeveloperController {
+
+    @Autowired
+    private TmDeveloperDao tmDeveloperDao;
+
+
+    @Value("${file-path}")
+    private String localFilePath;
+
+    @ApiOperation(value = "开发者信息添加")
+    @ResponseBody
+    @PostMapping(value = "/insert")
+    @Transactional(rollbackFor = Exception.class)
+    public Result insertDeveloper(@RequestBody @ApiParam(name = "登录请求实体", value = "传入json格式", required = true) TmDeveloper tmDeveloper) {
+
+        if (null != tmDeveloper) {
+            if (!StringUtils.isNoneBlank(tmDeveloper.getCallBackUrl(), tmDeveloper.getCompanyCreditCode())) {
+                throw new CommonBaseException(ResultCodeEnum.D3001, "回调url或者统一社会信用代码缺失");
+            }
+
+            if (!StringUtils.isNoneBlank(tmDeveloper.getAdminPhone(), tmDeveloper.getAdminEmail())) {
+                throw new CommonBaseException(ResultCodeEnum.D3001, "管理员的手机号或者邮箱缺失");
+            }
+            tmDeveloper.setDeveloperId(UUidGenerator.generatorUuid(IdStarterEnum.DEVELOPER.getStarter()));
+            tmDeveloper.setEnable(1);
+            tmDeveloper.setCreateTime(LocalDateTime.now());
+            tmDeveloper.setLastModifyDatetime(LocalDateTime.now());
+            int insert = tmDeveloperDao.insert(tmDeveloper);
+            if (insert != 1) {
+                throw new CommonBaseException(ResultCodeEnum.D101, "新增记录失败");
+            }
+
+        } else {
+            return Result.failure("新增失败,入参为空");
+        }
+        return Result.success("新增成功", tmDeveloper);
+    }
+
+    @ApiOperation(value = "获取开发者信息详情")
+    @ResponseBody
+    @GetMapping(value = "/detailByAppId")
+    @Transactional(rollbackFor = Exception.class)
+    public Result getDeveloperByAppId(@RequestParam(value = "appId") String appId) {
+        if (StringUtils.isBlank(appId)) {
+            throw new CommonBaseException(ResultCodeEnum.D3001, "开发者appId不能为空");
+        }
+        QueryWrapper<TmDeveloper> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("app_id", appId);
+        queryWrapper.eq("enable", 1);
+        queryWrapper.last("limit 1");
+        TmDeveloper tmDeveloper = tmDeveloperDao.selectOne(queryWrapper);
+        if (null == tmDeveloper) {
+            throw new CommonBaseException(ResultCodeEnum.D101, "开发者不存在");
+        }
+        return Result.success("获取成功", tmDeveloper);
+    }
+
+        @ApiOperation(value = "获取开发者信息详情")
+    @ResponseBody
+    @GetMapping(value = "/detail")
+    @Transactional(rollbackFor = Exception.class)
+    public Result getDeveloperDetail(@RequestParam(value = "id") String id) {
+
+        if (StringUtils.isBlank(id)) {
+            throw new CommonBaseException(ResultCodeEnum.D3001, "开发者id不能为空");
+        }
+        QueryWrapper<TmDeveloper> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("developer_id", id);
+        //剔除已经删除了的
+        queryWrapper.ne("enable", 0);
+        queryWrapper.last("limit 1");
+        TmDeveloper tmDeveloper = tmDeveloperDao.selectOne(queryWrapper);
+        if (null == tmDeveloper) {
+            throw new CommonBaseException(ResultCodeEnum.D101, "开放着不存在");
+        }
+        return Result.success("新增成功", tmDeveloper);
+    }
+
+    @ApiOperation(value = "获取开发者信息详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "当前页码", paramType = "query", required = true, dataType = "Integer"),
+            @ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "query", required = true, dataType = "Integer"),
+
+    })
+    @ResponseBody
+    @GetMapping(value = "/unAcceptList")
+    @Transactional(rollbackFor = Exception.class)
+    public Result getDeveloperList(@RequestParam(name = "pageNum") Long pageNum,
+                                   @RequestParam(name = "pageSize") Long pageSize) {
+
+        IPage<TmDeveloper> page = new Page<>(pageNum, pageSize);
+        QueryWrapper<TmDeveloper> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("enable", 1);
+        IPage<TmDeveloper> resultPage = new Page<>();
+        resultPage = tmDeveloperDao.selectPage(page, queryWrapper);
+        if (null == resultPage) {
+            throw new CommonBaseException(ResultCodeEnum.D101, "获取不到数据");
+        }
+        return Result.success(DataUtils.assembleResult(resultPage.getTotal(), resultPage.getPages(),
+                resultPage.getCurrent(), resultPage.getRecords()));
+    }
+
+
+    @ApiOperation(value = "开发者审批")
+    @ResponseBody
+    @PostMapping(value = "/accept")
+    @Transactional(rollbackFor = Exception.class)
+    public Result acceptDeveloper(@RequestBody @ApiParam(name = "登录请求实体", value = "传入json格式", required = true) TmDeveloper tmDeveloper) {
+
+        if (null == tmDeveloper) {
+            throw new CommonBaseException(ResultCodeEnum.D3001);
+        }
+        QueryWrapper<TmDeveloper> developerQueryWrapper = new QueryWrapper<>();
+        developerQueryWrapper.eq("developer_id", tmDeveloper.getDeveloperId());
+        developerQueryWrapper.last("limit 1");
+        TmDeveloper dbDeveloper = tmDeveloperDao.selectOne(developerQueryWrapper);
+        if (null == dbDeveloper) {
+            throw new CommonBaseException(ResultCodeEnum.D101, "开发者不存在,无需审批");
+        }
+        if (null != dbDeveloper.getEnable() && dbDeveloper.getEnable() == 2) {
+            throw new CommonBaseException(ResultCodeEnum.D101, "开发者已经审批通过,无需重复审批");
+        }
+        if (null != tmDeveloper.getEnable()
+                && tmDeveloper.getEnable() == 2) {
+            //审批通过
+            tmDeveloper.setEnable(tmDeveloper.getEnable());
+            tmDeveloper.setAppId(UUidGenerator.generatorUuid(IdStarterEnum.APP_ID.getStarter()));
+            tmDeveloper.setAppSecret(UUidGenerator.generatorUuid(IdStarterEnum.APP_SECRET.getStarter()));
+            int update = tmDeveloperDao.update(tmDeveloper, developerQueryWrapper);
+            if (update != 1) {
+                throw new CommonBaseException(ResultCodeEnum.D101, "更新开发者信息失败");
+            }
+        } else if (null != tmDeveloper.getEnable()
+                && tmDeveloper.getEnable() == 1) {
+            throw new CommonBaseException(ResultCodeEnum.D100, "开发者当前为待审批,上送状态也为待审批");
+        } else {
+            throw new CommonBaseException(ResultCodeEnum.D100, "开发者状态异常");
+        }
+        return Result.success("审批成功", tmDeveloper);
+    }
+
+}

+ 57 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/controller/fdage/DomainController.java

@@ -0,0 +1,57 @@
+package api.gateway.controller.fdage;
+
+import api.gateway.entity.TmDeveloper;
+import api.gateway.entity.TmDomainList;
+import api.gateway.enums.DomainRegisterType;
+import api.gateway.module.Result;
+import api.gateway.service.impl.TmDomainListServiceImpl;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author abnerhou
+ * @date 2020/10/15 12:11
+ * @desciption
+ */
+
+@Api(tags = "获取相关领域的应用列表")
+@Controller
+@RequestMapping("/domainList")
+@Log4j2
+public class DomainController {
+
+    @Autowired
+    private TmDomainListServiceImpl tmDomainListService;
+
+    @ApiOperation(value = "开发者信息添加")
+    @ResponseBody
+    @GetMapping(value = "/hot")
+    @Transactional(rollbackFor = Exception.class)
+    public Result getDomainListByType() {
+
+        QueryWrapper<TmDomainList> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("enable" , 1);
+        queryWrapper.eq("register_type" , DomainRegisterType.HOT_TYPE.getType());
+        List<TmDomainList> domainListList = tmDomainListService.getBaseMapper().selectList(queryWrapper);
+        List<String> result = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(domainListList)){
+            for(TmDomainList domainList : domainListList){
+               String path = domainList.getDomainLink() + domainList.getDomainPath();
+               result.add(path);
+            }
+        }
+        return Result.success(result);
+    }
+
+}

+ 19 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/controller/gateway/GatewayErrorDefaultController.java

@@ -0,0 +1,19 @@
+package api.gateway.controller.gateway;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/23 10:23
+ * @desciption
+ */
+@RestController
+public class GatewayErrorDefaultController {
+
+    @GetMapping(value = "/fallback")
+    public String fallback(){
+        return "fallback nothing";
+    }
+
+}

+ 48 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/exception/CommonBaseException.java

@@ -0,0 +1,48 @@
+package api.gateway.exception;
+
+import api.gateway.enums.ResultCodeEnum;
+import lombok.Data;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ * @author abnerhou
+ * @date 2020/5/25 11:39
+ * @desciption
+ */
+@ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR,reason="server error")
+@Data
+public class CommonBaseException extends RuntimeException{
+    private static final long serialVersionUID = 2899335020273674737L;
+
+    private Integer code;
+
+    private String msg;
+
+    public CommonBaseException(Integer code, String msg){
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+
+    public CommonBaseException(ResultCodeEnum resultCodeEnum){
+        super(resultCodeEnum.getDesc());
+        this.code = resultCodeEnum.getCode();
+        this.msg = resultCodeEnum.getDesc();
+    }
+
+    public CommonBaseException(ResultCodeEnum resultCodeEnum , String replaceMsg){
+        super(resultCodeEnum.getDesc());
+        this.code = resultCodeEnum.getCode();
+        if(resultCodeEnum.getCanBeReplace()){
+            this.msg = replaceMsg;
+        }else{
+            this.msg = resultCodeEnum.getDesc();
+        }
+    }
+
+
+
+
+}

+ 39 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/exception/ControllerHanderException.java

@@ -0,0 +1,39 @@
+/*
+package api.gateway.exception;
+
+import api.gateway.module.Result;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import java.util.HashMap;
+import java.util.Map;
+
+*/
+/**
+ * @author abnerhou
+ * @date 2020/9/27 19:09
+ * @desciption
+ *//*
+
+@ControllerAdvice
+public class ControllerHanderException {
+
+    @ExceptionHandler(CommonBaseException.class)
+    @ResponseBody
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    //在这个方法里定义我们需要返回的格式
+//    public Map<String, Object> handleUserNotExistException(CommonBaseException ex){
+    public Result handleUserNotExistException(CommonBaseException e){
+       */
+/* Map<String, Object> result = new HashMap<>();
+        result.put("code", ex.getCode());
+        result.put("msg", ex.getMsg());
+        return result;*//*
+
+        return api.gateway.module.Result.failure(null == e.getCode() ? Result.CODE_FAILURE : e.getCode(), e.getMsg());
+    }
+
+}
+*/

+ 65 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/exception/ExceptionHandlerConfiguration.java

@@ -0,0 +1,65 @@
+package api.gateway.exception;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.codec.ServerCodecConfigurer;
+import org.springframework.web.reactive.result.view.ViewResolver;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author abnerhou
+ * @date 2020/9/29 15:30
+ * @desciption
+ */
+@Configuration
+@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
+public class ExceptionHandlerConfiguration {
+
+    private final ServerProperties serverProperties;
+
+    private final ApplicationContext applicationContext;
+
+    private final ResourceProperties resourceProperties;
+
+    private final List<ViewResolver> viewResolvers;
+
+    private final ServerCodecConfigurer serverCodecConfigurer;
+
+    public ExceptionHandlerConfiguration(ServerProperties serverProperties,
+                                         ResourceProperties resourceProperties,
+                                         ObjectProvider<List<ViewResolver>> viewResolversProvider,
+                                         ServerCodecConfigurer serverCodecConfigurer,
+                                         ApplicationContext applicationContext) {
+        this.serverProperties = serverProperties;
+        this.applicationContext = applicationContext;
+        this.resourceProperties = resourceProperties;
+        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
+        this.serverCodecConfigurer = serverCodecConfigurer;
+    }
+
+    @Bean
+    @Order(Ordered.HIGHEST_PRECEDENCE)
+    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
+        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
+                errorAttributes,
+                this.resourceProperties,
+                this.serverProperties.getError(),
+                this.applicationContext);
+        exceptionHandler.setViewResolvers(this.viewResolvers);
+        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
+        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
+        return exceptionHandler;
+    }
+
+}

+ 97 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/exception/JsonExceptionHandler.java

@@ -0,0 +1,97 @@
+package api.gateway.exception;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.web.ErrorProperties;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.reactive.function.server.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author abnerhou
+ * @date 2020/9/29 15:32
+ * @desciption
+ */
+public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
+
+    private static Logger logger = LoggerFactory.getLogger(JsonExceptionHandler.class);
+
+    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
+                                ErrorProperties errorProperties, ApplicationContext applicationContext) {
+        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
+    }
+
+    /**
+     * 获取异常属性
+     */
+    @Override
+    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
+        int code = HttpStatus.INTERNAL_SERVER_ERROR.value();
+        Throwable error = super.getError(request);
+        if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
+            code = HttpStatus.NOT_FOUND.value();
+        }
+//        return response(code, this.buildMessage(request, error));
+        return response(code, error.getMessage());
+    }
+
+    /**
+     * 指定响应处理方法为JSON处理的方法
+     * @param errorAttributes
+     */
+    @Override
+    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
+        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
+    }
+
+
+    /**
+     * 根据code获取对应的HttpStatus
+     * @param errorAttributes
+     */
+    @Override
+    protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
+        int statusCode = (int) errorAttributes.get("code");
+        return HttpStatus.valueOf(statusCode);
+    }
+
+    /**
+     * 构建异常信息
+     * @param request
+     * @param ex
+     * @return
+     */
+    private String buildMessage(ServerRequest request, Throwable ex) {
+        StringBuilder message = new StringBuilder("Failed to handle request [");
+        message.append(request.methodName());
+        message.append(" ");
+        message.append(request.uri());
+        message.append("]");
+        if (ex != null) {
+            message.append(": ");
+            message.append(ex.getMessage());
+        }
+        return message.toString();
+    }
+
+    /**
+     * 构建返回的JSON数据格式
+     * @param status        状态码
+     * @param errorMessage  异常信息
+     * @return
+     */
+    public static Map<String, Object> response(int status, String errorMessage) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("code", status);
+        map.put("message", errorMessage);
+        map.put("data", null);
+        logger.error(map.toString());
+        return map;
+    }
+}

+ 79 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/filters/CachePostBodyFilter.java

@@ -0,0 +1,79 @@
+package api.gateway.filters;
+
+import api.gateway.dao.TmDeveloperDao;
+import api.gateway.entity.TmDeveloper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.netty.buffer.UnpooledByteBufAllocator;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.support.DefaultServerRequest;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.NettyDataBufferFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Component
+public class CachePostBodyFilter implements GlobalFilter, Ordered {
+    @Autowired
+    TmDeveloperDao tmDeveloperDao;
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        ServerHttpRequest serverHttpRequest = exchange.getRequest();
+        String method = serverHttpRequest.getMethodValue();
+        //TODO:如果GET请求呢?
+        if("POST".equalsIgnoreCase(method)) {
+            ServerRequest serverRequest = new DefaultServerRequest(exchange);
+            Mono<String> bodyToMono = serverRequest.bodyToMono(String.class);
+            return bodyToMono.flatMap(body -> {
+                exchange.getAttributes().put("cachedRequestBody", body);
+                ServerHttpRequest newRequest = new ServerHttpRequestDecorator(serverHttpRequest) {
+                    @Override
+                    public HttpHeaders getHeaders() {
+                        HttpHeaders httpHeaders = new HttpHeaders();
+                        httpHeaders.putAll(super.getHeaders());
+                        httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
+                        QueryWrapper<TmDeveloper> developerQueryWrapper = new QueryWrapper<>();
+                        if(super.getQueryParams().containsKey("appId")){
+                            String appId = super.getQueryParams().get("appId").get(0);
+                            if(!StringUtils.isBlank(appId)){
+                                developerQueryWrapper.eq("app_id" ,appId);
+                                developerQueryWrapper.last("limit 1");
+                                TmDeveloper tmDeveloper = tmDeveloperDao.selectOne(developerQueryWrapper);
+                                if(null != tmDeveloper){
+                                    httpHeaders.set("keyWord", tmDeveloper.getAppSecret());
+                                }
+                            }
+                        }
+
+
+                        return httpHeaders;
+                    }
+
+                    @Override
+                    public Flux<DataBuffer> getBody() {
+                        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
+                        DataBuffer bodyDataBuffer = nettyDataBufferFactory.wrap(body.getBytes());
+                        return Flux.just(bodyDataBuffer);
+                    }
+                };
+                return chain.filter(exchange.mutate().request(newRequest).build());
+            });
+        }
+        return chain.filter(exchange);
+    }
+
+    @Override
+    public int getOrder() {
+        return -21;
+    }
+}

+ 114 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/filters/CommonAuthFilter.java

@@ -0,0 +1,114 @@
+package api.gateway.filters;
+
+import api.gateway.dao.TmDeveloperDao;
+import api.gateway.entity.TmDeveloper;
+import api.gateway.enums.ResultCodeEnum;
+import api.gateway.exception.CommonBaseException;
+import api.gateway.utils.DataUtils;
+import api.gateway.utils.SHAUtils;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.cloud.gateway.filter.GatewayFilter;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+@Log4j2
+public class CommonAuthFilter implements GatewayFilter, Ordered {
+
+
+    private TmDeveloperDao tmDeveloperDao;
+
+    public CommonAuthFilter(TmDeveloperDao tmDeveloperDao) {
+        this.tmDeveloperDao = tmDeveloperDao;
+    }
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+
+
+        StringBuilder logBuilder = new StringBuilder();
+        Map<String, String> params = parseRequest(exchange, logBuilder);
+
+        if (!CollectionUtils.isEmpty(params)) {
+            String token = params.get("token");
+            String appId = params.get("appId");
+            Long timeStamp = DataUtils.getLongReturnNullIfNotExit(params.get("timeStamp"));
+            log.info("鉴权流程获取到的appid={},请求路径:{}" , appId , exchange.getRequest().getURI());
+            //先获取校验app id的合法性
+            QueryWrapper<TmDeveloper> developerQueryWrapper = new QueryWrapper<>();
+            developerQueryWrapper.eq("app_id" ,appId);
+            developerQueryWrapper.last("limit 1");
+            TmDeveloper tmDeveloper = tmDeveloperDao.selectOne(developerQueryWrapper);
+            if(null == tmDeveloper){
+                throw new CommonBaseException(ResultCodeEnum.D3006);
+            }
+            //校验时间戳是否超过时间
+            long diff = System.currentTimeMillis() - timeStamp;
+            log.info("时间差值为:{}" , diff);
+            //时间不能超过 5mine
+            if(diff/1000 > 300){
+                throw new CommonBaseException(ResultCodeEnum.D3007);
+            }
+            //校验token的有效性
+            String tmpToken = tmDeveloper.getAppId() + tmDeveloper.getAppSecret() + timeStamp.toString();
+            String enCodeToken = SHAUtils.getSHA256(tmpToken);
+            if(!StringUtils.equals(enCodeToken , token)){
+                throw new CommonBaseException(ResultCodeEnum.D3002);
+            }
+            //校验数据是否已经被串改放到controller里面校验
+            log.info("网关基础校验通过");
+        }else{
+            throw new CommonBaseException(ResultCodeEnum.D3001);
+        }
+        return chain.filter(exchange);
+    }
+
+    private Map<String, String> parseRequest(ServerWebExchange exchange, StringBuilder logBuilder) {
+        ServerHttpRequest serverHttpRequest = exchange.getRequest();
+        String method = serverHttpRequest.getMethodValue().toUpperCase();
+        logBuilder.append(method).append(",").append(serverHttpRequest.getURI());
+        MultiValueMap<String, String> query = serverHttpRequest.getQueryParams();
+        Map<String, String> params = new HashMap<>();
+        query.forEach((k, v) -> {
+            params.put(k, v.get(0));
+        });
+        if ("POST".equals(method)) {
+            String body = exchange.getAttributeOrDefault("cachedRequestBody", "");
+            if (StringUtils.isNotBlank(body)) {
+                logBuilder.append(",body=").append(body);
+                String[] kvArray = body.split("&");
+                for (String kv : kvArray) {
+                    if (kv.indexOf("=") >= 0) {
+                        String k = kv.split("=")[0];
+                        String v = kv.split("=")[1];
+                        if (!params.containsKey(k)) {
+                            try {
+                                params.put(k, URLDecoder.decode(v, "UTF-8"));
+                            } catch (UnsupportedEncodingException e) {
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return params;
+    }
+
+    @Override
+    public int getOrder() {
+        return -20;
+    }
+}

+ 64 - 0
4dkankan-open-gateway-main/src/main/java/api/gateway/filters/FilterConfigration.java

@@ -0,0 +1,64 @@
+package api.gateway.filters;
+
+import api.gateway.dao.TmDeveloperDao;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author abnerhou
+ * @date 2020/6/24 17:09
+ * @desciption
+ */
+@Configuration
+@Log4j2
+public class FilterConfigration {
+
+    @Autowired
+    private TmDeveloperDao tmDeveloperDao;
+
+    @Bean
+    public RouteLocator vrhouseOutSideRoute(RouteLocatorBuilder builder) {
+        log.info("开始启用看房网关外部调用过滤器");
+        return builder.routes()
+                .route(r ->
+                        r.path("/api/vrhouse/**")
+                                .filters(
+                                        f -> f.filters(new CommonAuthFilter(tmDeveloperDao))
+                                )
+                                .uri("lb://vrhouse-api-service")
+                )
+                .build();
+    }
+
+    @Bean
+    public RouteLocator shopOutSideRoute(RouteLocatorBuilder builder) {
+        log.info("开始启用看店网关外部调用过滤器");
+        return builder.routes()
+                .route(r ->
+                        r.path("/api/shop/**")
+                                .filters(
+                                        f -> f.filters(new CommonAuthFilter(tmDeveloperDao))
+                                )
+                                .uri("lb://shop-api-service")
+                )
+                .build();
+    }
+
+    @Bean
+    public RouteLocator showOutSideRoute(RouteLocatorBuilder builder) {
+        log.info("开始启用看展网关外部调用过滤器");
+        return builder.routes()
+                .route(r ->
+                        r.path("/api/show/**")
+                                .filters(
+                                        f -> f.filters(new CommonAuthFilter(tmDeveloperDao))
+                                )
+                                .uri("lb://show-api-service")
+                )
+                .build();
+    }
+}

+ 75 - 0
4dkankan-open-gateway-main/src/main/resources/application-dev.properties

@@ -0,0 +1,75 @@
+server.port=8091
+
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.max-file-size=500MB
+spring.servlet.multipart.max-request-size=500MB
+
+
+spring.datasource.url=jdbc:mysql://120.25.146.52:3306/4dage-api-gateway?serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+spring.datasource.username=root
+spring.datasource.password=4dkk2020test%
+spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
+
+
+# 初始化大小,最小,最大
+spring.datasource.initialSize=5
+spring.datasource.minIdle=5
+spring.datasource.maxActive=30
+# 配置获取连接等待超时的时间
+spring.datasource.maxWait=60000
+# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+spring.datasource.timeBetweenEvictionRunsMillis=60000
+# 配置一个连接在池中最小生存的时间,单位是毫秒
+spring.datasource.minEvictableIdleTimeMillis=300000
+spring.datasource.validationQuery=SELECT 1 FROM DUAL
+spring.datasource.testWhileIdle=true
+spring.datasource.testOnBorrow=false
+spring.datasource.testOnReturn=false
+# 打开PSCache,并且指定每个连接上PSCache的大小
+spring.datasource.poolPreparedStatements=true
+spring.datasource.maxPoolPreparedSta;tementPerConnectionSize=20
+# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+# 合并多个DruidDataSource的监控数据
+#spring.datasource.useGlobalDataSourceStat=true
+
+# 排除一些静态资源,以提高效率
+spring.datasource.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
+
+
+#redis
+spring.redis.database=0
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+spring.redis.password=
+# 连接超时时间 单位 ms(毫秒)
+spring.redis.timeout=3000ms
+# 连接池中的最大空闲连接,默认值也是8。
+spring.redis.jedis.pool.max-idle=50
+# 连接池中的最小空闲连接,默认值也是0。
+spring.redis.jedis.pool.min-idle=8
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
+spring.redis.jedis.pool.max-active=8
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
+spring.redis.jedis.pool.max-wait=-1ms
+
+
+#四维看看的登录域名
+4dkankan.host=https://test.4dkankan.com/
+
+#四维看房的ip和端口
+4dkankan.vrhouse.host=http://127.0.0.1:8095/
+path.separator=?/
+
+#oss配置
+oss.point=http://oss-cn-shenzhen.aliyuncs.com
+oss.key=LTAIUrvuHqj8pvry
+oss.secrey=JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+oss.bucket=4d-tjw
+#本地文件临时存放路径
+file-path: D:/api-gateway/developer/temp_file/
+file-downloan-host:192.168.0.83
+
+
+
+

+ 76 - 0
4dkankan-open-gateway-main/src/main/resources/application-prod.properties

@@ -0,0 +1,76 @@
+server.port=8091
+
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.max-file-size=500MB
+spring.servlet.multipart.max-request-size=500MB
+
+spring.datasource.url=jdbc:mysql://127.0.0.1:3306/4dage-api-gateway?serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+spring.datasource.username=root
+spring.datasource.password=4dkankancuikuan%
+spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
+
+
+# 初始化大小,最小,最大
+spring.datasource.initialSize=5
+spring.datasource.minIdle=5
+spring.datasource.maxActive=30
+# 配置获取连接等待超时的时间
+spring.datasource.maxWait=60000
+# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+spring.datasource.timeBetweenEvictionRunsMillis=60000
+# 配置一个连接在池中最小生存的时间,单位是毫秒
+spring.datasource.minEvictableIdleTimeMillis=300000
+spring.datasource.validationQuery=SELECT 1 FROM DUAL
+spring.datasource.testWhileIdle=true
+spring.datasource.testOnBorrow=false
+spring.datasource.testOnReturn=false
+# 打开PSCache,并且指定每个连接上PSCache的大小
+spring.datasource.poolPreparedStatements=true
+spring.datasource.maxPoolPreparedSta;tementPerConnectionSize=20
+
+# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+# 合并多个DruidDataSource的监控数据
+#spring.datasource.useGlobalDataSourceStat=true
+# druid连接池监控
+spring.datasource.stat-view-servlet.login-username=admin
+spring.datasource.stat-view-servlet.login-password=admin
+# 排除一些静态资源,以提高效率
+spring.datasource.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
+
+
+
+
+#redis
+spring.redis.database=0
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+spring.redis.password=
+# 连接超时时间 单位 ms(毫秒)
+spring.redis.timeout=3000ms
+# 连接池中的最大空闲连接,默认值也是8。
+spring.redis.jedis.pool.max-idle=50
+# 连接池中的最小空闲连接,默认值也是0。
+spring.redis.jedis.pool.min-idle=8
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
+spring.redis.jedis.pool.max-active=8
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
+spring.redis.jedis.pool.max-wait=-1ms
+
+#四维看看的登录域名
+4dkankan.host=https://4dkankan.com/
+
+#四维看房的ip和端口
+4dkankan.vrhouse.host=http://127.0.0.1:8095/
+path.separator=
+
+#oss配置
+oss.point=http://oss-cn-shenzhen.aliyuncs.com
+oss.key=LTAIUrvuHqj8pvry
+oss.secrey=JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+oss.bucket=4d-tjw
+#本地文件临时存放路径
+#本地文件临时存放路径
+file-path: /api-gateway/developer/temp_file/
+file-downloan-host:127.0.0.1
+

+ 71 - 0
4dkankan-open-gateway-main/src/main/resources/application-test.properties

@@ -0,0 +1,71 @@
+server.port=8091
+
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.max-file-size=500MB
+spring.servlet.multipart.max-request-size=500MB
+
+
+spring.datasource.url=jdbc:mysql://localhost:3306/4dage-api-gateway?serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+spring.datasource.username=root
+spring.datasource.password=4dkk2020test%
+spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
+
+
+# 初始化大小,最小,最大
+spring.datasource.initialSize=5
+spring.datasource.minIdle=5
+spring.datasource.maxActive=30
+# 配置获取连接等待超时的时间
+spring.datasource.maxWait=60000
+# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+spring.datasource.timeBetweenEvictionRunsMillis=60000
+# 配置一个连接在池中最小生存的时间,单位是毫秒
+spring.datasource.minEvictableIdleTimeMillis=300000
+spring.datasource.validationQuery=SELECT 1 FROM DUAL
+spring.datasource.testWhileIdle=true
+spring.datasource.testOnBorrow=false
+spring.datasource.testOnReturn=false
+# 打开PSCache,并且指定每个连接上PSCache的大小
+spring.datasource.poolPreparedStatements=true
+spring.datasource.maxPoolPreparedSta;tementPerConnectionSize=20
+# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+# 合并多个DruidDataSource的监控数据
+#spring.datasource.useGlobalDataSourceStat=true
+
+# 排除一些静态资源,以提高效率
+spring.datasource.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
+
+
+#redis
+spring.redis.database=0
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+spring.redis.password=
+# 连接超时时间 单位 ms(毫秒)
+spring.redis.timeout=3000ms
+# 连接池中的最大空闲连接,默认值也是8。
+spring.redis.jedis.pool.max-idle=50
+# 连接池中的最小空闲连接,默认值也是0。
+spring.redis.jedis.pool.min-idle=8
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
+spring.redis.jedis.pool.max-active=8
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
+spring.redis.jedis.pool.max-wait=-1ms
+
+
+#四维看看的登录域名
+4dkankan.host=https://test.4dkankan.com/
+
+#四维看房的ip和端口
+4dkankan.vrhouse.host=http://127.0.0.1:8095/
+path.separator=?/
+
+#oss配置
+oss.point=http://oss-cn-shenzhen.aliyuncs.com
+oss.key=LTAIUrvuHqj8pvry
+oss.secrey=JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+oss.bucket=4d-tjw
+#本地文件临时存放路径
+file-path: /api-gateway/developer/temp_file/
+file-downloan-host:127.0.0.1

+ 3 - 0
4dkankan-open-gateway-main/src/main/resources/application.properties

@@ -0,0 +1,3 @@
+spring.profiles.active=prod
+#spring.profiles.active=dev
+#spring.profiles.active=test

+ 57 - 0
4dkankan-open-gateway-main/src/main/resources/bootstrap.yml

@@ -0,0 +1,57 @@
+spring:
+  application:
+    name: 4dkankan-open-gateway-service
+  cloud:
+    nacos:
+      config:
+        server-addr: 127.0.0.1:8848
+      discovery:
+        server-addr: 127.0.0.1:8848
+    gateway:
+      discovery:
+        locator:
+          enabled: true
+      default-filters:
+        - name: Hystrix
+          args:
+            name : default
+            fallbackUri: 'forward:/defaultFallback'
+      routes:
+        #        - id: common-outside-router
+        # uri: lb://vrhouse-api-service
+        # predicates:
+        #   - Path=/api/**
+        # filters:
+        #   - name: RequestRateLimiter
+        #     args:
+        #       redis-rate-limiter.replenishRate: 1
+        #       redis-rate-limiter.burstCapacity: 5
+        #       key-resolver: '#{@ipKeyResolver}'
+        #- name: CommonAuthFilter
+        - id: 4dage-vrhouse-inside-router
+          uri: lb://vrhouse-api-service
+          predicates:
+            - Path=/vrhouse/**
+          filters:
+            - StripPrefix=1
+        - id: 4dage-shop-inside-router
+          uri: lb://shop-api-service
+          predicates:
+            - Path=/4dage/shop/**
+          filters:
+        - id: 4dage-show-inside-router
+          uri: lb://show-api-service
+          predicates:
+            - Path=/4dage/kanzhan/**
+          filters:
+
+
+
+hystrix:
+  command:
+    default:
+      execution:
+        isolation:
+          strategy: SEMAPHORE
+          thread:
+            timeoutInMilliseconds: 4000

BIN
4dkankan-open-gateway-main/src/main/resources/favicon.ico


+ 65 - 0
4dkankan-open-gateway-main/src/main/resources/log4j2.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration status="INFO">
+    <!--全局参数-->
+    <Properties>
+        <Property name="pattern">%d{yyyy-MM-dd HH:mm:ss,SSS} [%thread]  |-%-5level   %c{1}:%L - %m%n</Property>
+        <property name="LOG_HOME">log/api/gateway/</property>
+        <property name="REQUEST_FILE_NAME">request</property>
+        <property name="INFO_FILE_NAME">gateway_info</property>
+    </Properties>
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout>
+                <pattern>
+                    ${pattern}
+                </pattern>
+            </PatternLayout>
+        </Console>
+
+        <RollingFile  name="info-log"
+                      fileName="${LOG_HOME}/${INFO_FILE_NAME}.log"
+                      filePattern="${LOG_HOME}/$${date:yyyy-MM}/${INFO_FILE_NAME}-%d{yyyy-MM-dd}-%i.log">
+            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
+            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout>
+                <pattern>
+                    ${pattern}
+                </pattern>
+            </PatternLayout>
+            <Policies>
+                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
+                <SizeBasedTriggeringPolicy size="200 MB"/>
+            </Policies>
+            <DefaultRolloverStrategy max="200"/>
+        </RollingFile >
+
+        <RollingRandomAccessFile name="request-log"
+                                 fileName="${LOG_HOME}/${REQUEST_FILE_NAME}.log"
+                                 filePattern="${LOG_HOME}/$${date:yyyy-MM}/${REQUEST_FILE_NAME}-%d{yyyy-MM-dd}-%i.log">
+            <PatternLayout
+                    pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+                <SizeBasedTriggeringPolicy size="200 MB"/>
+            </Policies>
+            <DefaultRolloverStrategy max="200"/>
+        </RollingRandomAccessFile>
+    </Appenders>
+
+    <Loggers>
+        <Root level="INFO">
+            <AppenderRef ref="info-log" />
+            <AppenderRef ref="Console" />
+        </Root>
+        <Logger name="request" level="INFO"
+                additivity="false">
+            <AppenderRef ref="request-log"/>
+        </Logger>
+        <Logger name="org.springframework">
+            <AppenderRef ref="Console" />
+        </Logger>
+        <Logger name="org.mybatis">
+            <AppenderRef ref="Console" />
+        </Logger>
+    </Loggers>
+</configuration>

+ 250 - 0
pom.xml

@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <packaging>pom</packaging>
+
+
+    <modules>
+        <module>4dkankan-open-gateway-base</module>
+        <module>4dkankan-open-gateway-main</module>
+        <module>4dkankan-open-gateway-auth</module>
+    </modules>
+
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.4.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <groupId>org.4dage</groupId>
+    <artifactId>4dkankan-open-gateway-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <description>四维看房开放api网关</description>
+
+
+    <properties>
+        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
+        <alibaba.version>0.9.0.RELEASE</alibaba.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-gateway</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+
+<!--        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>-->
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+            <version>${alibaba.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+            <version>${alibaba.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+
+                <exclusion>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-core</artifactId>
+                </exclusion>
+
+            </exclusions>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.1.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.3.1.tmp</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis-spring</artifactId>
+                </exclusion>
+
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.3.1.tmp</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- swagger-ui -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.8.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>1.8.2</version>
+        </dependency>
+
+
+
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${spring-cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

BIN
readmeDoc/四维看房4Dkankan开放api说明文档_v1.1.docx


+ 1 - 0
remark.md

@@ -0,0 +1 @@
+测试22 333