feat: 新增基于 zuul 的网关
diff --git a/zuul/src/main/resources/application-docker.yml b/zuul/src/main/resources/application-docker.yml
new file mode 100644
index 0000000..9c603b5
--- /dev/null
+++ b/zuul/src/main/resources/application-docker.yml
@@ -0,0 +1,129 @@
+server:
+  port: ${SERVER_PORT:8443}
+  ssl:
+    enabled: ${SSL_ENABLED:true}
+    clientAuth: NEED
+    key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore}
+    key-store-password: ${SSL_KEYSTORE_PASSWORD:}
+    trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore}
+    trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:}
+  tomcat: 
+    accept-count: ${SERVER_TOMCAT_ACCEPT_COUNT:100}
+    max-connections: ${SERVER_TOMCAT_MAX_CONNECTIONS:10000}
+    max-threads: ${SERVER_TOMCAT_MAX_THREADS:200}
+    min-spare-threads: ${SERVER_TOMCAT_MIN_SPARE_THREADS:10}
+    accesslog: 
+      enabled: ${TOMCAT_ACCESSLOG_ENABLED:false}
+      buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true}
+      directory: ${TOMCAT_ACCESSLOG_DIR:log}
+      prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog}
+      suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log}
+      file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd}
+      rotate: ${TOMCAT_ACCESSLOG_ROTATE:true}
+
+
+## logging
+logging:
+  level:
+    root: INFO
+
+
+spring:
+  jackson:
+    time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
+
+
+zuul:
+  routes:
+    bff-api:
+      url: ${SW_BACKEND_BFF_API_URL:https://sw-backend-admin-bff}
+    base-api:
+      url: ${SW_BACKEND_BASE_API_URL:https://sw-backend-admin-sa}
+    system-api:
+      url: ${SW_BACKEND_BASE_API_URL:https://sw-backend-admin-sa}
+    biz-api:
+      url: ${SW_BACKEND_BIZ_API_URL:https://sw-backend-biz-sa}
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false}
+infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/}
+infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/}
+
+
+##
+# security basic
+#
+infras.security.basic.enabled: ${INFRAS_SECURITY_BASIC_ENABLED:true}
+
+
+##
+# security jwt
+#
+infras.security.jwt.enabled: ${INFRAS_SECURITY_JWT_ENABLED:false}
+
+#token过期时长,86400 秒(1天)
+infras.security.jwt.expiration: ${INFRAS_SECURITY_JWT_EXPIRATION:86400}
+
+infras.security.jwt.public-key-pem: ${INFRAS_SECURITY_JWT_PUBLIC_KEY_PEM:}
+infras.security.jwt.private-key-pem-pkcs8: ${INFRAS_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8:}
+
+
+# 
+infras.security.jwt.token.generate.type: ${INFRAS_SECURITY_JWT_TOKEN_GENERATE_TYPE:jwt}
+infras.security.jwt.token.decrypt.key.private-key-pem-pkcs8: ${INFRAS_SECURITY_JWT_TOKEN_DECRYPT_KEY_PRIVATE_KEY_PEM_PKCS8:}
+infras.security.jwt.token.signing.key.url: ${INFRAS_SECURITY_JWT_TOKEN_SIGNING_KEY_URL:}
+
+
+##
+# security cas
+#
+infras.security.cas.enabled: ${INFRAS_SECURITY_CAS_ENABLED:false}
+
+#应用访问地址
+app.server.host.url: ${APP_SERVER_HOST_URL:https://localhost:8443}
+#应用登录地址
+app.login.url: ${APP_LOGIN_URL:/cas/login}
+#应用登出地址
+app.logout.url: ${APP_LOGOUT_URL:/cas/logout}
+
+#CAS服务地址
+cas.server.host.url: ${CAS_SERVER_HOST_URL:}
+
+##
+# 认证时,用户信息服务实现
+# memery 内存,用户名密码一致即可登录,测试用,默认;
+# base 后端base服务;
+# poa 开放平台服务,建议和cas一起使用)
+sw-backend-gateway.security.core.userdetails.service.impl: ${SW_BACKEND_GATEWAY_SECURITY_CORE_USERDETAILS_SERVICE_IMPL:memery}
+
+
+sw-backend-base-api: 
+  uri: ${SW_BACKEND_BASE_API_URI:https://sw-backend-admin-sa}
+  client-auth:
+    enabled: ${SW_BACKEND_BASE_API_CLIENT_AUTH_ENABLED:false}
+    key-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEY_PASSWORD:}
+    key-store: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+    key-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+    trust-store: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+    trust-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
+
+sw-backend-agent-poa: 
+  uri: ${SW_BACKEND_AGENT_POA_URI:https://sw-backend-agent}
+  client-auth:
+    enabled: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_ENABLED:false}
+    key-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEY_PASSWORD:}
+    key-store: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+    key-store-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+    trust-store: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+    trust-store-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
+
+
+zuul-httpclient:
+  client-auth:
+    enabled: ${ZUUL_HTTPCLIENT_CLIENT_AUTH_ENABLED:false}
+    key-password: ${ZUUL_HTTPCLIENT_CLIENT_AUTH_KEY_PASSWORD:}
+    key-store: ${ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+    key-store-password: ${ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_PASSWORD:}
diff --git a/zuul/src/main/resources/application.yml b/zuul/src/main/resources/application.yml
new file mode 100644
index 0000000..a11b7ed
--- /dev/null
+++ b/zuul/src/main/resources/application.yml
@@ -0,0 +1,135 @@
+server:
+  port: 8080
+
+
+## logging
+logging:
+  level:
+    root: INFO
+#    com.supwisdom.institute.base: DEBUG
+#    com.supwisdom.institute.admin.center: DEBUG
+#    org.springframework.web: INFO
+#    org.springframework.cloud.openfeign: DEBUG
+
+
+spring:
+  jackson:
+    time-zone: Asia/Shanghai
+
+
+zuul:
+  #sensitiveHeaders: Cookie,Set-Cookie
+  ignored-headers: Access-Control-Allow-Origin,Vary
+  host:
+    socket-timeout-millis: 30000
+    connect-timeout-millis: 2000
+  routes:
+    bff-api:
+      path: /api/bff/**
+      url: http://localhost:8081
+      stripPrefix: true
+    base-api:
+      path: /api/base/**
+      url: http://localhost:8082
+      stripPrefix: true
+    system-api:
+      path: /api/system/**
+      url: http://localhost:8082
+      stripPrefix: true
+    biz-api:
+      path: /api/biz/**
+      url: http://localhost:8083
+      stripPrefix: true
+
+
+infras:
+  mvc:
+    # 自定义error输出的例子
+    custom-error:
+      enabled: true
+      error-map:
+        org.springframework.validation.BindException: Customized Bind Error Reason
+      include-message: true
+      include-errors: true
+      include-error: true
+      include-exception: true
+      include-path: true
+      include-timestamp: true
+      include-status: true
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: true
+infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/admin-center/doc/
+infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/admin-center/doc/api-docs/
+
+
+##
+# security basic
+#
+infras.security.basic.enabled: false
+
+
+##
+# security jwt
+#
+infras.security.jwt.enabled: true
+
+infras.security.jwt.expiration: 2592000
+
+infras.security.jwt.public-key-pem: |-
+  -----BEGIN PUBLIC KEY-----
+  MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgzXhvHLKypr+G+gJgOJNt8Lu8ygFFCU0eO4qJ4j2vDzpGwTOWKmD/u7dwIWKyHR43hUSN+FN4SSy1AmHjEKxz0btm7Cki+0YFw0BE4/mB/0wPD251wOS3w0CLsRTfoov9OaGaXApjVSMM74aIX8D46CbwHioLHdAj0/jlVU6gZQIDAQAB
+  -----END PUBLIC KEY-----
+infras.security.jwt.private-key-pem-pkcs8: |-
+  -----BEGIN PRIVATE KEY-----
+  MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKDNeG8csrKmv4b6AmA4k23wu7zKAUUJTR47ioniPa8POkbBM5YqYP+7t3AhYrIdHjeFRI34U3hJLLUCYeMQrHPRu2bsKSL7RgXDQETj+YH/TA8PbnXA5LfDQIuxFN+ii/05oZpcCmNVIwzvhohfwPjoJvAeKgsd0CPT+OVVTqBlAgMBAAECgYAtNxlyROOKkJCyZ4JbhA0QkOx5PWP2AZOJuLxP4SnvG50LYDAdPXVg82u1P+38n2truTF5qiXuYMUNcMoNixayWEZ074kVTI+FluLO405wwMYHvGPKOJVFIUTsKz+xkg4r48R963D5DZ6ZjoPIjLWvxL1zdrsgi9AOz/skAl0yAQJBANO0yadz1fYinSmYa2O27lgE1DpTvYBXGkY2qG7D/QJv2FwP6pdBy9ejym45UXce4wR1Yrlvh9wsErI4p790XOECQQDCcjti2nbIuZP3Dy5Ej97Y6sIbIEu5MpJW8kBjUzUssxgdE9urA/yWVzT8lmj34he+uWJv6s+e/HBDV5tc0tAFAkBK+q2s4+a0jN/SuovWPhS+Eb/EhKIKEU9Z7MPMrxctxMUBHhX8yi3SyszIKv7CTKskihqUCH86qFVaz5wBv8mhAkBgnQea13ebxnGZmSZhFKciWoq1lbdqPpFtuBJ8B5TtL9N0ZzCHaYSwYoZGVqmzONiZgF1DxIUCtuVE4JumZGzNAkB5B1sUdZfLo4q3jOiX5UQ/a4u17ptemvFPR4OynHkuVkgyAfTIo9SAB8/KIntHMlrgcP03G41ciJrYeP5zv8xm
+  -----END PRIVATE KEY-----
+
+
+infras.security.jwt.token.generate.type: jwt
+#infras.security.jwt.token.signing.key.url: https://cas-dev.supwisdom.com/cas/jwt/publicKey
+infras.security.jwt.token.signing.key.url: ""
+#infras.security.jwt.token.decrypt.key.private-key-pem-pkcs8: MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDMubzaWCtdqk/38qaKd0fYCd+vfb9icw6kK2+GkDAw1Vgj9KpXLQSnAzgYz9SzuDibTo5GgR9vhrTSlJppDeA+Q1zeTkBvnkLBi1m5iCgCPoKgr7yqxJxuiazCyDVs3qx8Hf732LlHBcEv5+SHwPrVWkY2LWo5xb+8RvmFoaKo3Ksr6j5x87262n9KzplwFZET5ujvuWAM09o1cfrJWS0o2Cy4JSP7afndSMBIn6Qzi0dI3Ec3HlSk8E+3oQH01blBXnS6pPSb4bxYWdqYRG1cp394K60r42eWcep1amk+dTXxK/uRi7VB1HRKebcdZdDwdfE0LNTNqsIlMTn+HusrAgMBAAECggEBAI5slQatmhXCe3m6dMQVsYSJcfVrnO6HruLlWOQbgXsnoPb6qlqVdgwegDM6uvYArljVcMN55v22kCuDuFxni96lDIGXnNpKFpUBNf2NzI+rH0NcnvuKZm28F9U2ZXyE+Sgr0gpo2pSfW0PRproOtjIhaIEeXS0t9nKsScD+ruObyaZPAdJ1Ndb2Z6L1R/TFDsNUwIGQoc6zCidLxWVBd906CnkeFmVX4MCpPnrtGW2ozqDW4pB/aRxoUZZZ6bOjBmqiZ1YPtcHyAG/b1UgDYXSu6mUKrdhUVEkB6KHp92BKuU3DrMxroUtG8Rz2oY/7HBFXT6zZvmn7OneZRRSHKpkCgYEA9Xug3adh2xxtqHtZPb6u+H2SIdtXW7f/WDPKwV5tQc4X8H6uqh7KikLHbzgk5jgw6QHL4IT2+0W8EV5tieHWRY3bxyLAsR1uNQUnUNCr19vbw60fz/iSZb48e6F4wk5YPlHsbddsF3UdIWM1C5PSOJCrHB7uGexW9ZnOytTCHf8CgYEA1X8YsMoryEL1BPrJ/2OvVYPd0kSxU0ODvnXNq9UPi5JZpDviogXSyJ0MeEiRq96aeNDJ+4LQjPT8EnhJtZfy7MEzWdsS2fmh2uAc64kwN58l25t+TUpkhtkt06Zl7euGdOSupCWUOPqmdzoIg8Tu91YfD7OcYR86XGp7kXyQCtUCgYEAg/3TQxsKzKt+csbP9xkeL1IlTrsHP7OxQhWnAU3qZSWRTahv9dzUfn7liPGhNYAlHEPxAWm8+uJF+vjQ4QBjG8bo0yvme9UdOrjoqNVqcIgwpAfkQQigfsBI+RibO66wV+HoxC6+WeaIoTkcfnse33c56cbfs2SWZTwsKnc3YLUCgYEAt6c1Xh8LuqGelEIIMaFW2oEs+AwPXkjds6Ey43XMgYvLgPPi6O2JfPlcGLyUUvySdQtmNO066YZ0sI65GXU0i2VG/yzs8oVDLj1Lo3HIAJDuyBLieypbf4SjX0XsuNW6PCPb92g8MSesuzM4z+FAj5ON9LvU8dcjJQyUb3pvjmECgYEAlPvF5eA9zHGON8IKfMx9J+mDXWk6h3VyMGK9BCjLvR1CfLtXhTTOANX3LlERLV47D9+aCVah2sXUNUBB3cf8IHi9ExVmwmdgZu2ZkseeClgo6Sdyl26GkivvaNTfKZCt/Nkt5VKtU6BUuyp+kt5nWUkmrIIWSEiiQ+tVCB9Y+f8=
+
+
+##
+# security cas
+#
+infras.security.cas.enabled: true
+
+#应用访问地址
+app.server.host.url: http://localhost:8080
+#应用登录地址
+app.login.url: /cas/login
+#应用登出地址
+app.logout.url: /cas/logout
+
+#CAS服务地址
+cas.server.host.url: https://cas-dev.supwisdom.com/cas
+
+
+##
+# 认证时,用户信息服务实现
+# memery 内存,用户名密码一致即可登录,测试用,默认;
+# base 后端base服务;
+# poa 开放平台服务,建议和cas一起使用)
+sw-backend-gateway.security.core.userdetails.service.impl: memery
+
+
+sw-backend-base-api:
+  uri: http://localhost:8082
+
+sw-backend-agent-poa: 
+  uri: http://localhost:8090
+
+
+zuul-httpclient:
+  client-auth:
+    enabled: false
+    key-password: client
+    key-store: file:/Users/loie/c/work/git/institute/admin-center/certs/client/client.keystore
+    key-store-password: client
+
diff --git a/zuul/src/main/resources/bootstrap.yml b/zuul/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..10b3096
--- /dev/null
+++ b/zuul/src/main/resources/bootstrap.yml
@@ -0,0 +1,3 @@
+spring:
+  application:
+    name: sw-backend-zuul