feat, docs: 完善框架代码,示例代码,使用文档
diff --git a/bff/admin/pom.xml b/bff/admin/pom.xml
index 5bc267a..ecd5261 100644
--- a/bff/admin/pom.xml
+++ b/bff/admin/pom.xml
@@ -50,6 +50,12 @@
 
 
     <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-starter-openfeign</artifactId>
+    </dependency>
+
+
+    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-webflux</artifactId>
     </dependency>
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
index 364ed0b..942b082 100644
--- a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
@@ -2,22 +2,27 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 //import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.annotation.Bean;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.springframework.web.filter.CorsFilter;
 
+
+
 //import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc;
 import com.supwisdom.infras.security.configure.basic.EnableInfrasBasicApi;
 import com.supwisdom.infras.security.configure.cas.EnableInfrasCasSecurity;
 import com.supwisdom.infras.security.configure.jwt.EnableInfrasJWTApi;
 import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
+import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
 
 @SpringBootApplication
-//@EnableFeignClients
+@EnableFeignClients
 
 @EnableSimpleUserTransmit
+@EnableCustomExceptionHandler
 
 //@EnableInfrasOnlineDoc
 
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/model/biz/Biz.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/model/biz/Biz.java
new file mode 100644
index 0000000..f1d904e
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/model/biz/Biz.java
@@ -0,0 +1,37 @@
+package com.supwisdom.institute.backend.admin.bff.apis.model.biz;
+
+import java.util.Date;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+public class Biz extends ABaseModel {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 8755876583168251137L;
+  
+  @Getter
+  @Setter
+  private String id;
+
+  @Getter
+  @Setter
+  private String name;
+  
+  @Getter
+  @Setter
+  private Boolean bool;
+  
+  @Getter
+  @Setter
+  private Date date;
+
+  @Getter
+  @Setter
+  private Integer num;
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFallbackFactory.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFallbackFactory.java
new file mode 100644
index 0000000..30d312d
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFallbackFactory.java
@@ -0,0 +1,61 @@
+package com.supwisdom.institute.backend.admin.bff.apis.remote.biz;
+
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.apis.model.biz.Biz;
+import com.supwisdom.institute.backend.admin.bff.remote.FallbackError;
+
+import feign.hystrix.FallbackFactory;
+
+@Component
+public class BizRemoteFallbackFactory implements FallbackFactory<BizRemoteFeignClient> {
+
+  @Override
+  public BizRemoteFeignClient create(Throwable cause) {
+    return new BizRemoteFeignClient() {
+
+      @Override
+      public JSONObject query(boolean loadAll, int pageIndex, int pageSize) {
+        if (cause != null) {
+          cause.printStackTrace();
+        }
+        return FallbackError.defaultErrorJson(cause);
+      }
+
+      @Override
+      public JSONObject load(String id) {
+        if (cause != null) {
+          cause.printStackTrace();
+        }
+        return FallbackError.defaultErrorJson(cause);
+      }
+
+      @Override
+      public JSONObject create(Biz biz) {
+        if (cause != null) {
+          cause.printStackTrace();
+        }
+        return FallbackError.defaultErrorJson(cause);
+      }
+
+      @Override
+      public JSONObject update(String id, Biz biz) {
+        if (cause != null) {
+          cause.printStackTrace();
+        }
+        return FallbackError.defaultErrorJson(cause);
+      }
+
+      @Override
+      public JSONObject delete(String id) {
+        if (cause != null) {
+          cause.printStackTrace();
+        }
+        return FallbackError.defaultErrorJson(cause);
+      }
+      
+    };
+  }
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFeignClient.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFeignClient.java
new file mode 100644
index 0000000..cccdd8a
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/remote/biz/BizRemoteFeignClient.java
@@ -0,0 +1,49 @@
+package com.supwisdom.institute.backend.admin.bff.apis.remote.biz;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.apis.model.biz.Biz;
+
+@FeignClient(
+    name = "biz-biz-remote-feign-client",
+    url = "${sw-backend-biz-api.uri}/v1/admin/biz",
+    fallbackFactory = BizRemoteFallbackFactory.class
+)
+public interface BizRemoteFeignClient {
+  
+  @RequestMapping(method = RequestMethod.GET)
+  JSONObject query(
+      @RequestParam(name = "loadAll") boolean loadAll,
+      @RequestParam(name = "pageIndex") int pageIndex,
+      @RequestParam(name = "pageSize") int pageSize
+      
+  );
+  
+  @RequestMapping(method = RequestMethod.GET, path = "/{id}")
+  JSONObject load(
+      @PathVariable(name = "id") String id
+  );
+
+  @RequestMapping(method = RequestMethod.POST)
+  JSONObject create(
+      @RequestBody Biz biz
+  );
+
+  @RequestMapping(method = RequestMethod.PUT, path = "/{id}")
+  JSONObject update(
+      @PathVariable(name = "id") String id,
+      @RequestBody Biz biz
+  );
+  
+  @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
+  JSONObject delete(
+      @PathVariable(name = "id") String id
+  );
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/biz/BizService.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/biz/BizService.java
new file mode 100644
index 0000000..7c6b8a7
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/service/biz/BizService.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.admin.bff.apis.service.biz;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.apis.remote.biz.BizRemoteFeignClient;
+import com.supwisdom.institute.backend.admin.bff.apis.vo.response.biz.data.BizQueryResponseData;
+
+public class BizService {
+  
+  @Autowired
+  private BizRemoteFeignClient bizRemote;
+  
+  public BizQueryResponseData query(boolean loadAll, int pageIndex, int pageSize) {
+    
+    JSONObject jsonObject = bizRemote.query(loadAll, pageIndex, pageSize);
+    if (jsonObject == null) {
+      return null;
+    }
+    
+    if (jsonObject.getIntValue("code") == 0) {
+      JSONObject data = jsonObject.getJSONObject("data");
+      
+      return data.toJavaObject(BizQueryResponseData.class);
+    }
+    
+    return null;
+  }
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/response/biz/data/BizQueryResponseData.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/response/biz/data/BizQueryResponseData.java
new file mode 100644
index 0000000..3699ff7
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/apis/vo/response/biz/data/BizQueryResponseData.java
@@ -0,0 +1,45 @@
+package com.supwisdom.institute.backend.admin.bff.apis.vo.response.biz.data;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.admin.bff.apis.model.biz.Biz;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+public class BizQueryResponseData implements IApiQueryResponseData<Biz> {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -380945463584664943L;
+
+  @Getter
+  private boolean loadAll;
+  @Getter
+  private int pageIndex;
+  @Getter
+  private int pageSize;
+  @Getter
+  private Map<String, Object> mapBean;
+  @Getter
+  private Map<String, String> orderBy;
+  
+  @Getter
+  @Setter
+  private int pageCount;
+  @Getter
+  @Setter
+  private long recordCount;
+  
+  @Getter
+  @Setter
+  private int currentItemCount;
+  
+  @Getter
+  @Setter
+  private List<Biz> items;
+  
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java
new file mode 100644
index 0000000..9559532
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java
@@ -0,0 +1,114 @@
+package com.supwisdom.institute.backend.admin.bff.configuration;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.AuthorizationScopeBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.BasicAuth;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+import static com.google.common.collect.Lists.*;
+
+
+//@Configuration
+//@EnableSwagger2
+public class Swagger2Config {
+
+  @Value("${swagger2.apis.basePackage:com.supwisdom.institute}")
+  private String basePackage;
+
+  @Bean
+  public Docket createRestApi() {
+    return new Docket(DocumentationType.SWAGGER_2)
+        .securitySchemes(securitySchemes())
+        .securityContexts(securityContexts())
+        .apiInfo(apiInfo())
+        .select()
+        .apis(RequestHandlerSelectors.basePackage(basePackage))
+        .paths(PathSelectors.any())
+        .build()
+        ;
+  }
+
+  private ApiInfo apiInfo() {
+    Contact contact = new Contact("Backend Admin BFF", "https://sw-backend-api.supwisdom.com/swagger-ui.html", ""); // name, url, email
+    return new ApiInfoBuilder()
+        .title("Backend Admin BFF APIs")
+        .description("管理后台 - 后端接口")
+        .termsOfServiceUrl("http://www.supwisdom.com/")
+        .contact(contact)
+        .version("1.0")
+        .build();
+  }
+  
+  private List<SecurityScheme> securitySchemes() {
+    return newArrayList(new BasicAuth("sample"));
+  }
+  
+  private List<SecurityContext> securityContexts() {
+    AuthorizationScope[] authScopes = new AuthorizationScope[1];
+    authScopes[0] = new AuthorizationScopeBuilder()
+            .scope("read")
+            .description("read access")
+            .build();
+    SecurityReference securityReference = SecurityReference.builder()
+            .reference("sample")
+            .scopes(authScopes)
+            .build();
+    
+    return newArrayList(SecurityContext.builder().securityReferences(newArrayList(securityReference)).build());
+  }
+
+  @Bean
+  public UiConfiguration uiConfig() {
+    
+    return UiConfigurationBuilder.builder().build();
+    
+//    return new UiConfiguration(null, // url
+//        "none", // docExpansion => none | list
+//        "alpha", // apiSorter => alpha
+//        "schema", // defaultModelRendering => schema
+//        UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
+//        false, // enableJsonEditor => true || false
+//        true, // showRequestHeaders => true | false
+//        60000L); // requestTimeout => in milliseconds, defaults to null
+//    // (uses jquery xh timeout)
+  }
+  
+  
+//  @Bean
+//  public SecurityConfiguration oauth2() {
+//      return SecurityConfigurationBuilder.builder()
+//          .clientId("common")
+//          .clientSecret("secret")
+//          .scopeSeparator(" ")
+//          .useBasicAuthenticationWithAccessCodeGrant(true)
+//          .build();
+//  }
+//  
+//  @Bean
+//  public SecurityConfiguration basic() {
+//      return SecurityConfigurationBuilder.builder()
+//          .clientId("common")
+//          .clientSecret("secret")
+//          .scopeSeparator(" ")
+//          .useBasicAuthenticationWithAccessCodeGrant(true)
+//          .build();
+//  }
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/remote/FallbackError.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/remote/FallbackError.java
new file mode 100644
index 0000000..d46aa8d
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/remote/FallbackError.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.admin.bff.remote;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class FallbackError {
+  
+  private FallbackError() {
+    
+  }
+  
+  public static JSONObject defaultErrorJson(Throwable cause) {
+    JSONObject error = new JSONObject();
+    
+    error.put("code", -1);
+    error.put("message", cause.getMessage());
+    error.put("error", cause.getMessage());
+    
+    return error;
+  }
+
+}
diff --git a/bff/admin/src/main/resources/application.yml b/bff/admin/src/main/resources/application.yml
index d93888b..815040b 100644
--- a/bff/admin/src/main/resources/application.yml
+++ b/bff/admin/src/main/resources/application.yml
@@ -111,4 +111,5 @@
 ##
 # server url for feign
 #
-sw-backend-api-admin.server.url: http://localhost:8081
+sw-backend-system-api.uri: http://localhost:8081
+sw-backend-biz-api.uri: http://localhost:8081