cauto 2 年之前
當前提交
14b18fca69

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+*.log
+.idea
+gin_scaffold

+ 186 - 0
README.md

@@ -0,0 +1,186 @@
+<!-- START doctoc generated TOC please keep comment here to allow auto update -->
+<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
+**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
+
+- [gin_scaffold](#gin_scaffold)
+    - [现在开始](#%E7%8E%B0%E5%9C%A8%E5%BC%80%E5%A7%8B)
+    - [文件分层](#%E6%96%87%E4%BB%B6%E5%88%86%E5%B1%82)
+    - [log / redis / mysql / http.client 常用方法](#log--redis--mysql--httpclient-%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95)
+    - [swagger文档生成](#swagger%E6%96%87%E6%A1%A3%E7%94%9F%E6%88%90)
+
+<!-- END doctoc generated TOC please keep comment here to allow auto update -->
+
+# gin_scaffold
+Gin best practices, gin development scaffolding, too late to explain, get on the bus.
+
+使用gin构建了企业级脚手架,代码简洁易读,可快速进行高效web开发。
+主要功能有:
+1. 请求链路日志打印,涵盖mysql/redis/request
+2. 支持多语言错误信息提示及自定义错误提示。
+3. 支持了多配置环境
+4. 封装了 log/redis/mysql/http.client 常用方法
+5. 支持swagger文档生成
+
+项目地址:https://github.com/go_gateway_admin
+### 现在开始
+- 安装软件依赖
+go mod使用请查阅:
+
+https://blog.csdn.net/e421083458/article/details/89762113
+```
+git clone git@github.com:e421083458/gin_scaffold.git
+cd gin_scaffold
+go mod tidy
+```
+- 确保正确配置了 conf/mysql_map.toml、conf/redis_map.toml:
+
+- 运行脚本
+
+```
+go run main.go
+
+➜  gin_scaffold git:(master) ✗ go run main.go
+------------------------------------------------------------------------
+[INFO]  config=./conf/dev/
+[INFO]  start loading resources.
+[INFO]  success loading resources.
+------------------------------------------------------------------------
+[GIN-debug] [WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
+
+[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
+
+[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
+ - using env:	export GIN_MODE=release
+ - using code:	gin.SetMode(gin.ReleaseMode)
+
+[GIN-debug] GET    /demo/index               --> github.com/go_gateway_admin/controller.(*Demo).Index-fm (6 handlers)
+[GIN-debug] GET    /demo/bind                --> github.com/go_gateway_admin/controller.(*Demo).Bind-fm (6 handlers)
+[GIN-debug] GET    /demo/dao                 --> github.com/go_gateway_admin/controller.(*Demo).Dao-fm (6 handlers)
+[GIN-debug] GET    /demo/redis               --> github.com/go_gateway_admin/controller.(*Demo).Redis-fm (6 handlers)
+ [INFO] HttpServerRun::8880
+```
+- 测试mysql与请求链路
+
+创建测试表:
+```
+CREATE TABLE `area` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `area_name` varchar(255) NOT NULL,
+ `city_id` int(11) NOT NULL,
+ `user_id` int(11) NOT NULL,
+ `update_at` datetime NOT NULL,
+ `create_at` datetime NOT NULL,
+ `delete_at` datetime NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='area';
+INSERT INTO `area` (`id`, `area_name`, `city_id`, `user_id`, `update_at`, `create_at`, `delete_at`) VALUES (NULL, 'area_name', '1', '2', '2019-06-15 00:00:00', '2019-06-15 00:00:00', '2019-06-15 00:00:00');
+```
+
+```
+curl 'http://127.0.0.1:8880/demo/dao?id=1'
+{
+    "errno": 0,
+    "errmsg": "",
+    "data": "[{\"id\":1,\"area_name\":\"area_name\",\"city_id\":1,\"user_id\":2,\"update_at\":\"2019-06-15T00:00:00+08:00\",\"create_at\":\"2019-06-15T00:00:00+08:00\",\"delete_at\":\"2019-06-15T00:00:00+08:00\"}]",
+    "trace_id": "c0a8fe445d05b9eeee780f9f5a8581b0"
+}
+
+查看链路日志(确认是不是一次请求查询,都带有相同trace_id):
+tail -f gin_scaffold.inf.log
+
+[INFO][2019-06-16T11:39:26.802][log.go:58] _com_request_in||method=GET||from=127.0.0.1||traceid=c0a8fe445d05b9eeee780f9f5a8581b0||cspanid=||uri=/demo/dao?id=1||args=map[]||body=||spanid=9dad47aa57e9d186
+[INFO][2019-06-16T11:39:26.802][log.go:58] _com_mysql_success||affected_row=1||traceid=c0a8fe445d05b9ee07b80f9f66cb39b0||spanid=9dad47aa1408d2ac||source=/Users/niuyufu/go/src/github.com/go_gateway_admin/dao/demo.go:24||proc_time=0.000000000||sql=SELECT * FROM `area`  WHERE (id = '1')||level=sql||current_time=2019-06-16 11:39:26||cspanid=
+[INFO][2019-06-16T11:39:26.802][log.go:58] _com_request_out||method=GET||args=map[]||proc_time=0.025019164||traceid=c0a8fe445d05b9eeee780f9f5a8581b0||spanid=9dad47aa57e9d186||uri=/demo/dao?id=1||from=127.0.0.1||response={\"errno\":0,\"errmsg\":\"\",\"data\":\"[{\\\"id\\\":1,\\\"area_name\\\":\\\"area_name\\\",\\\"city_id\\\":1,\\\"user_id\\\":2,\\\"update_at\\\":\\\"2019-06-15T00:00:00+08:00\\\",\\\"create_at\\\":\\\"2019-06-15T00:00:00+08:00\\\",\\\"delete_at\\\":\\\"2019-06-15T00:00:00+08:00\\\"}]\",\"trace_id\":\"c0a8fe445d05b9eeee780f9f5a8581b0\"}||cspanid=
+```
+- 测试参数绑定与多语言验证
+
+```
+curl 'http://127.0.0.1:8880/demo/bind?name=name&locale=zh'
+{
+    "errno": 500,
+    "errmsg": "年龄为必填字段,密码为必填字段",
+    "data": "",
+    "trace_id": "c0a8fe445d05badae8c00f9fb62158b0"
+}
+
+curl 'http://127.0.0.1:8880/demo/bind?name=name&locale=en'
+{
+    "errno": 500,
+    "errmsg": "Age is a required field,Passwd is a required field",
+    "data": "",
+    "trace_id": "c0a8fe445d05bb4cd3b00f9f3a768bb0"
+}
+```
+
+### 文件分层
+```
+├── README.md
+├── conf            配置文件夹
+│   └── dev
+│       ├── base.toml
+│       ├── mysql_map.toml
+│       └── redis_map.toml
+├── controller      控制器
+│   └── demo.go
+├── dao             DB数据层
+│   └── demo.go
+├── docs            swagger文件层
+├── dto             输入输出结构层
+│   └── demo.go
+├── go.mod
+├── go.sum
+├── main.go         入口文件
+├── middleware      中间件层
+│   ├── panic.go
+│   ├── response.go
+│   ├── token_auth.go
+│   └── translation.go
+├── public          公共文件
+│   ├── log.go
+│   ├── mysql.go
+│   └── validate.go
+└── router          路由层
+│   ├── httpserver.go
+│   └── route.go
+└── services        逻辑处理层
+```
+层次划分
+控制层 --> 逻辑处理层 --> DB数据层
+### log / redis / mysql / http.client 常用方法
+
+参考文档:https://github.com/e421083458/golang_common
+
+
+### swagger文档生成
+
+https://github.com/swaggo/swag/releases
+
+- 下载对应操作系统的执行文件到$GOPATH/bin下面
+
+如下:
+```
+➜  gin_scaffold git:(master) ✗ ll -r $GOPATH/bin
+total 434168
+-rwxr-xr-x  1 niuyufu  staff    13M  4  3 17:38 swag
+```
+
+- 设置接口文档参考: `controller/demo.go` 的 Bind方法的注释设置
+
+```
+// ListPage godoc
+// @Summary 测试数据绑定
+// @Description 测试数据绑定
+// @Tags 用户
+// @ID /demo/bind
+// @Accept  json
+// @Produce  json
+// @Param polygon body dto.DemoInput true "body"
+// @Success 200 {object} middleware.Response{data=dto.DemoInput} "success"
+// @Router /demo/bind [post]
+```
+
+- 生成接口文档:`swag init`
+- 然后启动服务器:`go run main.go`,浏览地址: http://127.0.0.1:8880/swagger/index.html
+
+
+- GOLANGD GOPROXY=https://goproxy.io,direct

+ 33 - 0
conf/dev/base.toml

@@ -0,0 +1,33 @@
+# This is base config
+
+[base]
+    debug_mode="debug"
+    time_location="Asia/Chongqing"
+
+[http]
+    addr =":8880"                       # 监听地址, default ":8700"
+    read_timeout = 10                   # 读取超时时长
+    write_timeout = 10                  # 写入超时时长
+    max_header_bytes = 20               # 最大的header大小,二进制位长度
+    allow_ip = [                        # 白名单ip列表
+        "127.0.0.1",
+        "192.168.1.1"
+    ]
+
+[log]
+    log_level = "trace"         #日志打印最低级别
+    [log.file_writer]           #文件写入配置
+        on = true
+        log_path = "./logs/gateway_admin.inf.log"
+        rotate_log_path = "./logs/gateway_admin.inf.log.%Y%M%D%H"
+        wf_log_path = "./logs/gateway_admin.wf.log"
+        rotate_wf_log_path = "./logs/gateway_admin.wf.log.%Y%M%D%H"
+    [log.console_writer]        #工作台输出
+        on = false
+        color = false
+
+[swagger]
+    title="gateway_admin swagger API"
+    desc="This is a sample server celler server."
+    host="127.0.0.1:8880"
+    base_path=""

+ 8 - 0
conf/dev/mysql_map.toml

@@ -0,0 +1,8 @@
+# this is mysql config
+[list]
+    [list.default]
+        driver_name = "mysql"
+        data_source_name = "root:123456@tcp(127.0.0.1:8889)/gateway?charset=utf8&parseTime=true&loc=Asia%2FChongqing"
+        max_open_conn = 20
+        max_idle_conn = 10
+        max_conn_life_time = 100

+ 7 - 0
conf/dev/redis_map.toml

@@ -0,0 +1,7 @@
+# this is redis config file
+[list]
+    [list.default]
+        proxy_list = ["127.0.0.1:6379"]
+        max_active = 100
+        max_idle = 100
+        down_grade = false

+ 40 - 0
controller/admin_login.go

@@ -0,0 +1,40 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go_gateway_admin/dto"
+	"github.com/go_gateway_admin/middleware"
+)
+
+type AdminLoginController struct {
+}
+
+func AdminLoginRegister(router *gin.RouterGroup) {
+	curd := AdminLoginController{}
+	router.POST("/login", curd.Login)
+	//router.GET("/loginout", curd.LoginOut)
+}
+
+// AdminLgoin godoc
+// @Summary 管理员登陆
+// @Description 管理员登陆
+// @Tags 管理员借口
+// @ID	/admin/login
+// @Accept  json
+// @Produce  json
+// @Param body body dto.AdminLoginInput true "body"
+// @Success 200 {object} middleware.Response{data=dto.AdminLoginOutput} "success"
+// @Router /admin/login [post]
+func (admin *AdminLoginController) Login(c *gin.Context) {
+
+	params := &dto.AdminLoginInput{}
+
+	if err := params.BindingValidParams(c); err != nil {
+		middleware.ResponseError(c, 1001, err)
+		return
+	}
+
+	out := &dto.AdminLoginOutput{Token: params.UserName}
+
+	middleware.ResponseSuccess(c, out)
+}

+ 125 - 0
docs/docs.go

@@ -0,0 +1,125 @@
+// Package docs GENERATED BY SWAG; DO NOT EDIT
+// This file was generated by swaggo/swag
+package docs
+
+import "github.com/swaggo/swag"
+
+const docTemplate = `{
+    "schemes": {{ marshal .Schemes }},
+    "swagger": "2.0",
+    "info": {
+        "description": "{{escape .Description}}",
+        "title": "{{.Title}}",
+        "contact": {},
+        "version": "{{.Version}}"
+    },
+    "host": "{{.Host}}",
+    "basePath": "{{.BasePath}}",
+    "paths": {
+        "/admin/login": {
+            "post": {
+                "description": "管理员登陆",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "管理员借口"
+                ],
+                "summary": "管理员登陆",
+                "operationId": "/admin/login",
+                "parameters": [
+                    {
+                        "description": "body",
+                        "name": "body",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/dto.AdminLoginInput"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "success",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/middleware.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/dto.AdminLoginOutput"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "dto.AdminLoginInput": {
+            "type": "object",
+            "required": [
+                "password",
+                "username"
+            ],
+            "properties": {
+                "password": {
+                    "type": "string",
+                    "example": ""
+                },
+                "username": {
+                    "type": "string",
+                    "example": ""
+                }
+            }
+        },
+        "dto.AdminLoginOutput": {
+            "type": "object",
+            "properties": {
+                "token": {
+                    "type": "string",
+                    "example": "token"
+                }
+            }
+        },
+        "middleware.Response": {
+            "type": "object",
+            "properties": {
+                "data": {},
+                "errmsg": {
+                    "type": "string"
+                },
+                "errno": {
+                    "type": "integer"
+                },
+                "stack": {},
+                "trace_id": {}
+            }
+        }
+    }
+}`
+
+// SwaggerInfo holds exported Swagger Info so clients can modify it
+var SwaggerInfo = &swag.Spec{
+	Version:          "",
+	Host:             "",
+	BasePath:         "",
+	Schemes:          []string{},
+	Title:            "",
+	Description:      "",
+	InfoInstanceName: "swagger",
+	SwaggerTemplate:  docTemplate,
+}
+
+func init() {
+	swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
+}

+ 97 - 0
docs/swagger.json

@@ -0,0 +1,97 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "contact": {}
+    },
+    "paths": {
+        "/admin/login": {
+            "post": {
+                "description": "管理员登陆",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "管理员借口"
+                ],
+                "summary": "管理员登陆",
+                "operationId": "/admin/login",
+                "parameters": [
+                    {
+                        "description": "body",
+                        "name": "body",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/dto.AdminLoginInput"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "success",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/middleware.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/dto.AdminLoginOutput"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "dto.AdminLoginInput": {
+            "type": "object",
+            "required": [
+                "password",
+                "username"
+            ],
+            "properties": {
+                "password": {
+                    "type": "string",
+                    "example": ""
+                },
+                "username": {
+                    "type": "string",
+                    "example": ""
+                }
+            }
+        },
+        "dto.AdminLoginOutput": {
+            "type": "object",
+            "properties": {
+                "token": {
+                    "type": "string",
+                    "example": "token"
+                }
+            }
+        },
+        "middleware.Response": {
+            "type": "object",
+            "properties": {
+                "data": {},
+                "errmsg": {
+                    "type": "string"
+                },
+                "errno": {
+                    "type": "integer"
+                },
+                "stack": {},
+                "trace_id": {}
+            }
+        }
+    }
+}

+ 61 - 0
docs/swagger.yaml

@@ -0,0 +1,61 @@
+definitions:
+  dto.AdminLoginInput:
+    properties:
+      password:
+        example: ""
+        type: string
+      username:
+        example: ""
+        type: string
+    required:
+    - password
+    - username
+    type: object
+  dto.AdminLoginOutput:
+    properties:
+      token:
+        example: token
+        type: string
+    type: object
+  middleware.Response:
+    properties:
+      data: {}
+      errmsg:
+        type: string
+      errno:
+        type: integer
+      stack: {}
+      trace_id: {}
+    type: object
+info:
+  contact: {}
+paths:
+  /admin/login:
+    post:
+      consumes:
+      - application/json
+      description: 管理员登陆
+      operationId: /admin/login
+      parameters:
+      - description: body
+        in: body
+        name: body
+        required: true
+        schema:
+          $ref: '#/definitions/dto.AdminLoginInput'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: success
+          schema:
+            allOf:
+            - $ref: '#/definitions/middleware.Response'
+            - properties:
+                data:
+                  $ref: '#/definitions/dto.AdminLoginOutput'
+              type: object
+      summary: 管理员登陆
+      tags:
+      - 管理员借口
+swagger: "2.0"

+ 19 - 0
dto/admin_login.go

@@ -0,0 +1,19 @@
+package dto
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go_gateway_admin/public"
+)
+
+type AdminLoginInput struct {
+	UserName string `form:"username" json:"username" comment:"用户名"  validate:"required,is_valid_username" example:""`
+	Password string `form:"password" json:"password" comment:"密码"  validate:"required" example:""`
+}
+
+type AdminLoginOutput struct {
+	Token string `form:"token" json:"token" comment:"token" validate:"" example:"token"`
+}
+
+func (params *AdminLoginInput) BindingValidParams(c *gin.Context) error {
+	return public.DefaultGetValidParams(c, params)
+}

+ 412 - 0
gateway.sql

@@ -0,0 +1,412 @@
+-- phpMyAdmin SQL Dump
+-- version 4.7.0
+-- https://www.phpmyadmin.net/
+--
+-- Host: 127.0.0.1
+-- Generation Time: 2020-04-27 13:59:47
+-- 服务器版本: 5.6.25-log
+-- PHP Version: 7.0.18
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET AUTOCOMMIT = 0;
+START TRANSACTION;
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Database: `go_gateway`
+--
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_admin`
+--
+
+CREATE TABLE `gateway_admin` (
+                                 `id` bigint(20) NOT NULL COMMENT '自增id',
+                                 `user_name` varchar(128) NOT NULL DEFAULT '' COMMENT '用户名',
+                                 `salt` varchar(50) NOT NULL DEFAULT '' COMMENT '盐',
+                                 `password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
+                                 `create_at` datetime NOT NULL DEFAULT '1971-01-01 00:00:00' COMMENT '新增时间',
+                                 `update_at` datetime NOT NULL DEFAULT '1971-01-01 00:00:00' COMMENT '更新时间',
+                                 `is_delete` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='管理员表';
+
+--
+-- 转存表中的数据 `gateway_admin`
+--
+
+INSERT INTO `gateway_admin` (`id`, `user_name`, `salt`, `password`, `create_at`, `update_at`, `is_delete`) VALUES
+    (1, 'admin', 'admin', '2823d896e9822c0833d41d4904f0c00756d718570fce49b9a379a62c804689d3', '2020-04-10 16:42:05', '2020-04-21 06:35:08', 0);
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_app`
+--
+
+CREATE TABLE `gateway_app` (
+                               `id` bigint(20) UNSIGNED NOT NULL COMMENT '自增id',
+                               `app_id` varchar(255) NOT NULL DEFAULT '' COMMENT '租户id',
+                               `name` varchar(128) NOT NULL DEFAULT '' COMMENT '租户名称',
+                               `secret` varchar(255) NOT NULL DEFAULT '' COMMENT '密钥',
+                               `white_ips` varchar(1000) NOT NULL DEFAULT '' COMMENT 'ip白名单,支持前缀匹配',
+                               `qpd` bigint(20) NOT NULL DEFAULT '0' COMMENT '日请求量限制',
+                               `qps` bigint(20) NOT NULL DEFAULT '0' COMMENT '每秒请求量限制',
+                               `create_at` datetime NOT NULL COMMENT '添加时间',
+                               `update_at` datetime NOT NULL COMMENT '更新时间',
+                               `is_delete` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 1=删除'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关租户表';
+
+--
+-- 转存表中的数据 `gateway_app`
+--
+
+INSERT INTO `gateway_app` (`id`, `app_id`, `name`, `secret`, `white_ips`, `qpd`, `qps`, `create_at`, `update_at`, `is_delete`) VALUES
+                                                                                                                                   (31, 'app_id_a', '租户A', '449441eb5e72dca9c42a12f3924ea3a2', 'white_ips', 100000, 100, '2020-04-15 20:55:02', '2020-04-21 07:23:34', 0),
+                                                                                                                                   (32, 'app_id_b', '租户B', '8d7b11ec9be0e59a36b52f32366c09cb', '', 20, 0, '2020-04-15 21:40:52', '2020-04-21 07:23:27', 0),
+                                                                                                                                   (33, 'app_id', '租户名称', '', '', 0, 0, '2020-04-15 22:02:23', '2020-04-15 22:06:51', 1),
+                                                                                                                                   (34, 'app_id45', '名称', '07d980f8a49347523ee1d5c1c41aec02', '', 0, 0, '2020-04-15 22:06:38', '2020-04-15 22:06:49', 1);
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_access_control`
+--
+
+CREATE TABLE `gateway_service_access_control` (
+                                                  `id` bigint(20) NOT NULL COMMENT '自增主键',
+                                                  `service_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '服务id',
+                                                  `open_auth` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否开启权限 1=开启',
+                                                  `black_list` varchar(1000) NOT NULL DEFAULT '' COMMENT '黑名单ip',
+                                                  `white_list` varchar(1000) NOT NULL DEFAULT '' COMMENT '白名单ip',
+                                                  `white_host_name` varchar(1000) NOT NULL DEFAULT '' COMMENT '白名单主机',
+                                                  `clientip_flow_limit` int(11) NOT NULL DEFAULT '0' COMMENT '客户端ip限流',
+                                                  `service_flow_limit` int(20) NOT NULL DEFAULT '0' COMMENT '服务端限流'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关权限控制表';
+
+--
+-- 转存表中的数据 `gateway_service_access_control`
+--
+
+INSERT INTO `gateway_service_access_control` (`id`, `service_id`, `open_auth`, `black_list`, `white_list`, `white_host_name`, `clientip_flow_limit`, `service_flow_limit`) VALUES
+                                                                                                                                                                               (162, 35, 1, '', '', '', 0, 0),
+                                                                                                                                                                               (165, 34, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (167, 36, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (168, 38, 1, '111.11', '22.33', '11.11', 12, 12),
+                                                                                                                                                                               (169, 41, 1, '111.11', '22.33', '11.11', 12, 12),
+                                                                                                                                                                               (170, 42, 1, '111.11', '22.33', '11.11', 12, 12),
+                                                                                                                                                                               (171, 43, 0, '111.11', '22.33', '11.11', 12, 12),
+                                                                                                                                                                               (172, 44, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (173, 45, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (174, 46, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (175, 47, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (176, 48, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (177, 49, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (178, 50, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (179, 51, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (180, 52, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (181, 53, 0, '', '', '', 0, 0),
+                                                                                                                                                                               (182, 54, 1, '127.0.0.3', '127.0.0.2', '', 11, 12),
+                                                                                                                                                                               (183, 55, 1, '127.0.0.2', '127.0.0.1', '', 45, 34),
+                                                                                                                                                                               (184, 56, 0, '192.168.1.0', '', '', 0, 0),
+                                                                                                                                                                               (185, 57, 0, '', '127.0.0.1,127.0.0.2', '', 0, 0),
+                                                                                                                                                                               (186, 58, 1, '', '', '', 0, 0),
+                                                                                                                                                                               (187, 59, 1, '127.0.0.1', '', '', 2, 3),
+                                                                                                                                                                               (188, 60, 1, '', '', '', 0, 0),
+                                                                                                                                                                               (189, 61, 0, '', '', '', 0, 0);
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_grpc_rule`
+--
+
+CREATE TABLE `gateway_service_grpc_rule` (
+                                             `id` bigint(20) NOT NULL COMMENT '自增主键',
+                                             `service_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '服务id',
+                                             `port` int(5) NOT NULL DEFAULT '0' COMMENT '端口',
+                                             `header_transfor` varchar(5000) NOT NULL DEFAULT '' COMMENT 'header转换支持增加(add)、删除(del)、修改(edit) 格式: add headname headvalue 多个逗号间隔'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关路由匹配表';
+
+--
+-- 转存表中的数据 `gateway_service_grpc_rule`
+--
+
+INSERT INTO `gateway_service_grpc_rule` (`id`, `service_id`, `port`, `header_transfor`) VALUES
+                                                                                            (171, 53, 8009, ''),
+                                                                                            (172, 54, 8002, 'add metadata1 datavalue,edit metadata2 datavalue2'),
+                                                                                            (173, 58, 8012, 'add meta_name meta_value');
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_http_rule`
+--
+
+CREATE TABLE `gateway_service_http_rule` (
+                                             `id` bigint(20) NOT NULL COMMENT '自增主键',
+                                             `service_id` bigint(20) NOT NULL COMMENT '服务id',
+                                             `rule_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '匹配类型 0=url前缀url_prefix 1=域名domain ',
+                                             `rule` varchar(255) NOT NULL DEFAULT '' COMMENT 'type=domain表示域名,type=url_prefix时表示url前缀',
+                                             `need_https` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支持https 1=支持',
+                                             `need_strip_uri` tinyint(4) NOT NULL DEFAULT '0' COMMENT '启用strip_uri 1=启用',
+                                             `need_websocket` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否支持websocket 1=支持',
+                                             `url_rewrite` varchar(5000) NOT NULL DEFAULT '' COMMENT 'url重写功能 格式:^/gatekeeper/test_service(.*) $1 多个逗号间隔',
+                                             `header_transfor` varchar(5000) NOT NULL DEFAULT '' COMMENT 'header转换支持增加(add)、删除(del)、修改(edit) 格式: add headname headvalue 多个逗号间隔'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关路由匹配表';
+
+--
+-- 转存表中的数据 `gateway_service_http_rule`
+--
+
+INSERT INTO `gateway_service_http_rule` (`id`, `service_id`, `rule_type`, `rule`, `need_https`, `need_strip_uri`, `need_websocket`, `url_rewrite`, `header_transfor`) VALUES
+                                                                                                                                                                          (165, 35, 1, '', 0, 0, 0, '', ''),
+                                                                                                                                                                          (168, 34, 0, '', 0, 0, 0, '', ''),
+                                                                                                                                                                          (170, 36, 0, '', 0, 0, 0, '', ''),
+                                                                                                                                                                          (171, 38, 0, '/abc', 1, 0, 1, '^/abc $1', 'add head1 value1'),
+                                                                                                                                                                          (172, 43, 0, '/usr', 1, 1, 0, '^/afsaasf $1,^/afsaasf $1', ''),
+                                                                                                                                                                          (173, 44, 1, 'www.test.com', 1, 1, 1, '', ''),
+                                                                                                                                                                          (174, 47, 1, 'www.test.com', 1, 1, 1, '', ''),
+                                                                                                                                                                          (175, 48, 1, 'www.test.com', 1, 1, 1, '', ''),
+                                                                                                                                                                          (176, 49, 1, 'www.test.com', 1, 1, 1, '', ''),
+                                                                                                                                                                          (177, 56, 0, '/test_http_service', 1, 1, 1, '^/test_http_service/abb/(.*) /test_http_service/bba/$1', 'add header_name header_value'),
+                                                                                                                                                                          (178, 59, 1, 'test.com', 0, 1, 1, '', 'add headername headervalue'),
+                                                                                                                                                                          (179, 60, 0, '/test_strip_uri', 0, 1, 0, '^/aaa/(.*) /bbb/$1', ''),
+                                                                                                                                                                          (180, 61, 0, '/test_https_server', 1, 1, 0, '', '');
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_info`
+--
+
+CREATE TABLE `gateway_service_info` (
+                                        `id` bigint(20) UNSIGNED NOT NULL COMMENT '自增主键',
+                                        `load_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '负载类型 0=http 1=tcp 2=grpc',
+                                        `service_name` varchar(255) NOT NULL DEFAULT '' COMMENT '服务名称 6-128 数字字母下划线',
+                                        `service_desc` varchar(255) NOT NULL DEFAULT '' COMMENT '服务描述',
+                                        `create_at` datetime NOT NULL DEFAULT '1971-01-01 00:00:00' COMMENT '添加时间',
+                                        `update_at` datetime NOT NULL DEFAULT '1971-01-01 00:00:00' COMMENT '更新时间',
+                                        `is_delete` tinyint(4) DEFAULT '0' COMMENT '是否删除 1=删除'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关基本信息表';
+
+--
+-- 转存表中的数据 `gateway_service_info`
+--
+
+INSERT INTO `gateway_service_info` (`id`, `load_type`, `service_name`, `service_desc`, `create_at`, `update_at`, `is_delete`) VALUES
+                                                                                                                                  (34, 0, 'websocket_test', 'websocket_test', '2020-04-13 01:31:47', '1971-01-01 00:00:00', 1),
+                                                                                                                                  (35, 1, 'test_grpc', 'test_grpc', '2020-04-13 01:34:32', '1971-01-01 00:00:00', 1),
+                                                                                                                                  (36, 2, 'test_httpe', 'test_httpe', '2020-04-11 21:12:48', '1971-01-01 00:00:00', 1),
+                                                                                                                                  (38, 0, 'service_name', '11111', '2020-04-15 07:49:45', '2020-04-11 23:59:39', 1),
+                                                                                                                                  (41, 0, 'service_name_tcp', '11111', '2020-04-13 01:38:01', '2020-04-12 01:06:09', 1),
+                                                                                                                                  (42, 0, 'service_name_tcp2', '11111', '2020-04-13 01:38:06', '2020-04-12 01:13:24', 1),
+                                                                                                                                  (43, 1, 'service_name_tcp4', 'service_name_tcp4', '2020-04-15 07:49:44', '2020-04-12 01:13:50', 1),
+                                                                                                                                  (44, 0, 'websocket_service', 'websocket_service', '2020-04-15 07:49:43', '2020-04-13 01:20:08', 1),
+                                                                                                                                  (45, 1, 'tcp_service', 'tcp_desc', '2020-04-15 07:49:41', '2020-04-13 01:46:27', 1),
+                                                                                                                                  (46, 1, 'grpc_service', 'grpc_desc', '2020-04-13 01:54:12', '2020-04-13 01:53:14', 1),
+                                                                                                                                  (47, 0, 'testsefsafs', 'werrqrr', '2020-04-13 01:59:14', '2020-04-13 01:57:49', 1),
+                                                                                                                                  (48, 0, 'testsefsafs1', 'werrqrr', '2020-04-13 01:59:11', '2020-04-13 01:58:14', 1),
+                                                                                                                                  (49, 0, 'testsefsafs1222', 'werrqrr', '2020-04-13 01:59:08', '2020-04-13 01:58:23', 1),
+                                                                                                                                  (50, 2, 'grpc_service_name', 'grpc_service_desc', '2020-04-15 07:49:40', '2020-04-13 02:01:00', 1),
+                                                                                                                                  (51, 2, 'gresafsf', 'wesfsf', '2020-04-15 07:49:39', '2020-04-13 02:01:57', 1),
+                                                                                                                                  (52, 2, 'gresafsf11', 'wesfsf', '2020-04-13 02:03:41', '2020-04-13 02:02:55', 1),
+                                                                                                                                  (53, 2, 'tewrqrw111', '123313', '2020-04-13 02:03:38', '2020-04-13 02:03:20', 1),
+                                                                                                                                  (54, 2, 'test_grpc_service1', 'test_grpc_service1', '2020-04-15 07:49:37', '2020-04-15 07:38:43', 1),
+                                                                                                                                  (55, 1, 'test_tcp_service1', 'redis服务代理', '2020-04-15 07:49:35', '2020-04-15 07:46:35', 1),
+                                                                                                                                  (56, 0, 'test_http_service', '测试HTTP代理', '2020-04-16 00:54:45', '2020-04-15 07:55:07', 0),
+                                                                                                                                  (57, 1, 'test_tcp_service', '测试TCP代理', '2020-04-19 14:03:09', '2020-04-15 07:58:39', 0),
+                                                                                                                                  (58, 2, 'test_grpc_service', '测试GRPC服务', '2020-04-21 07:20:16', '2020-04-15 07:59:46', 0),
+                                                                                                                                  (59, 0, 'test.com:8080', '测试域名接入', '2020-04-18 22:54:14', '2020-04-18 20:29:13', 0),
+                                                                                                                                  (60, 0, 'test_strip_uri', '测试路径接入', '2020-04-21 06:55:26', '2020-04-18 22:56:37', 0),
+                                                                                                                                  (61, 0, 'test_https_server', '测试https服务', '2020-04-19 12:22:33', '2020-04-19 12:17:04', 0);
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_load_balance`
+--
+
+CREATE TABLE `gateway_service_load_balance` (
+                                                `id` bigint(20) NOT NULL COMMENT '自增主键',
+                                                `service_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '服务id',
+                                                `check_method` tinyint(20) NOT NULL DEFAULT '0' COMMENT '检查方法 0=tcpchk,检测端口是否握手成功',
+                                                `check_timeout` int(10) NOT NULL DEFAULT '0' COMMENT 'check超时时间,单位s',
+                                                `check_interval` int(11) NOT NULL DEFAULT '0' COMMENT '检查间隔, 单位s',
+                                                `round_type` tinyint(4) NOT NULL DEFAULT '2' COMMENT '轮询方式 0=random 1=round-robin 2=weight_round-robin 3=ip_hash',
+                                                `ip_list` varchar(2000) NOT NULL DEFAULT '' COMMENT 'ip列表',
+                                                `weight_list` varchar(2000) NOT NULL DEFAULT '' COMMENT '权重列表',
+                                                `forbid_list` varchar(2000) NOT NULL DEFAULT '' COMMENT '禁用ip列表',
+                                                `upstream_connect_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '建立连接超时, 单位s',
+                                                `upstream_header_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '获取header超时, 单位s',
+                                                `upstream_idle_timeout` int(10) NOT NULL DEFAULT '0' COMMENT '链接最大空闲时间, 单位s',
+                                                `upstream_max_idle` int(11) NOT NULL DEFAULT '0' COMMENT '最大空闲链接数'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关负载表';
+
+--
+-- 转存表中的数据 `gateway_service_load_balance`
+--
+
+INSERT INTO `gateway_service_load_balance` (`id`, `service_id`, `check_method`, `check_timeout`, `check_interval`, `round_type`, `ip_list`, `weight_list`, `forbid_list`, `upstream_connect_timeout`, `upstream_header_timeout`, `upstream_idle_timeout`, `upstream_max_idle`) VALUES
+                                                                                                                                                                                                                                                                                   (162, 35, 0, 2000, 5000, 2, '127.0.0.1:50051', '100', '', 10000, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (165, 34, 0, 2000, 5000, 2, '100.90.164.31:8072,100.90.163.51:8072,100.90.163.52:8072,100.90.165.32:8072', '50,50,50,80', '', 20000, 20000, 10000, 100),
+                                                                                                                                                                                                                                                                                   (167, 36, 0, 2000, 5000, 2, '100.90.164.31:8072,100.90.163.51:8072,100.90.163.52:8072,100.90.165.32:8072', '50,50,50,80', '100.90.164.31:8072,100.90.163.51:8072', 10000, 10000, 10000, 100),
+                                                                                                                                                                                                                                                                                   (168, 38, 0, 0, 0, 1, '111:111,22:111', '11,11', '111', 1111, 111, 222, 333),
+                                                                                                                                                                                                                                                                                   (169, 41, 0, 0, 0, 1, '111:111,22:111', '11,11', '111', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (170, 42, 0, 0, 0, 1, '111:111,22:111', '11,11', '111', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (171, 43, 0, 2, 5, 1, '111:111,22:111', '11,11', '', 1111, 2222, 333, 444),
+                                                                                                                                                                                                                                                                                   (172, 44, 0, 2, 5, 2, '127.0.0.1:8076', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (173, 45, 0, 2, 5, 2, '127.0.0.1:88', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (174, 46, 0, 2, 5, 2, '127.0.0.1:8002', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (175, 47, 0, 2, 5, 2, '12777:11', '11', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (176, 48, 0, 2, 5, 2, '12777:11', '11', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (177, 49, 0, 2, 5, 2, '12777:11', '11', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (178, 50, 0, 2, 5, 2, '127.0.0.1:8001', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (179, 51, 0, 2, 5, 2, '1212:11', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (180, 52, 0, 2, 5, 2, '1212:11', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (181, 53, 0, 2, 5, 2, '1111:11', '111', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (182, 54, 0, 2, 5, 1, '127.0.0.1:80', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (183, 55, 0, 2, 5, 3, '127.0.0.1:81', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (184, 56, 0, 2, 5, 2, '127.0.0.1:2003,127.0.0.1:2004', '50,50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (185, 57, 0, 2, 5, 2, '127.0.0.1:6379', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (186, 58, 0, 2, 5, 2, '127.0.0.1:50055', '50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (187, 59, 0, 2, 5, 2, '127.0.0.1:2003,127.0.0.1:2004', '50,50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (188, 60, 0, 2, 5, 2, '127.0.0.1:2003,127.0.0.1:2004', '50,50', '', 0, 0, 0, 0),
+                                                                                                                                                                                                                                                                                   (189, 61, 0, 2, 5, 2, '127.0.0.1:3003,127.0.0.1:3004', '50,50', '', 0, 0, 0, 0);
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `gateway_service_tcp_rule`
+--
+
+CREATE TABLE `gateway_service_tcp_rule` (
+                                            `id` bigint(20) NOT NULL COMMENT '自增主键',
+                                            `service_id` bigint(20) NOT NULL COMMENT '服务id',
+                                            `port` int(5) NOT NULL DEFAULT '0' COMMENT '端口号'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网关路由匹配表';
+
+--
+-- 转存表中的数据 `gateway_service_tcp_rule`
+--
+
+INSERT INTO `gateway_service_tcp_rule` (`id`, `service_id`, `port`) VALUES
+                                                                        (171, 41, 8002),
+                                                                        (172, 42, 8003),
+                                                                        (173, 43, 8004),
+                                                                        (174, 38, 8004),
+                                                                        (175, 45, 8001),
+                                                                        (176, 46, 8005),
+                                                                        (177, 50, 8006),
+                                                                        (178, 51, 8007),
+                                                                        (179, 52, 8008),
+                                                                        (180, 55, 8010),
+                                                                        (181, 57, 8011);
+
+--
+-- Indexes for dumped tables
+--
+
+--
+-- Indexes for table `gateway_admin`
+--
+ALTER TABLE `gateway_admin`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_app`
+--
+ALTER TABLE `gateway_app`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_access_control`
+--
+ALTER TABLE `gateway_service_access_control`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_grpc_rule`
+--
+ALTER TABLE `gateway_service_grpc_rule`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_http_rule`
+--
+ALTER TABLE `gateway_service_http_rule`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_info`
+--
+ALTER TABLE `gateway_service_info`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_load_balance`
+--
+ALTER TABLE `gateway_service_load_balance`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- Indexes for table `gateway_service_tcp_rule`
+--
+ALTER TABLE `gateway_service_tcp_rule`
+    ADD PRIMARY KEY (`id`);
+
+--
+-- 在导出的表使用AUTO_INCREMENT
+--
+
+--
+-- 使用表AUTO_INCREMENT `gateway_admin`
+--
+ALTER TABLE `gateway_admin`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', AUTO_INCREMENT=2;
+--
+-- 使用表AUTO_INCREMENT `gateway_app`
+--
+ALTER TABLE `gateway_app`
+    MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增id', AUTO_INCREMENT=35;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_access_control`
+--
+ALTER TABLE `gateway_service_access_control`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=190;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_grpc_rule`
+--
+ALTER TABLE `gateway_service_grpc_rule`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=174;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_http_rule`
+--
+ALTER TABLE `gateway_service_http_rule`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=181;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_info`
+--
+ALTER TABLE `gateway_service_info`
+    MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=62;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_load_balance`
+--
+ALTER TABLE `gateway_service_load_balance`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=190;
+--
+-- 使用表AUTO_INCREMENT `gateway_service_tcp_rule`
+--
+ALTER TABLE `gateway_service_tcp_rule`
+    MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', AUTO_INCREMENT=182;COMMIT;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

+ 21 - 0
go.mod

@@ -0,0 +1,21 @@
+module github.com/go_gateway_admin
+
+go 1.14
+
+require (
+	github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
+	github.com/e421083458/golang_common v1.2.1
+	github.com/gin-gonic/contrib v0.0.0-20190526021735-7fb7810ed2a0
+	github.com/gin-gonic/gin v1.7.7
+	github.com/go-playground/locales v0.13.0
+	github.com/go-playground/universal-translator v0.17.0
+	github.com/gorilla/sessions v1.1.3 // indirect
+	github.com/pkg/errors v0.8.1
+	github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
+	github.com/swaggo/gin-swagger v1.2.0
+	github.com/swaggo/swag v1.8.1
+	golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
+	gopkg.in/go-playground/validator.v9 v9.29.0
+)
+
+replace github.com/gin-contrib/sse v0.1.0 => github.com/e421083458/sse v0.1.1

+ 21 - 0
main.go

@@ -0,0 +1,21 @@
+package main
+
+import (
+	"github.com/e421083458/golang_common/lib"
+	"github.com/go_gateway_admin/router"
+	"os"
+	"os/signal"
+	"syscall"
+)
+
+func main() {
+	lib.InitModule("./conf/dev/", []string{"base", "mysql", "redis"})
+	defer lib.Destroy()
+	router.HttpServerRun()
+
+	quit := make(chan os.Signal)
+	signal.Notify(quit, syscall.SIGKILL, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM)
+	<-quit
+
+	router.HttpServerStop()
+}

+ 25 - 0
middleware/ip_auth.go

@@ -0,0 +1,25 @@
+package middleware
+
+import (
+	"errors"
+	"fmt"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+)
+
+func IPAuthMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		isMatched := false
+		for _, host := range lib.GetStringSliceConf("base.http.allow_ip") {
+			if c.ClientIP() == host {
+				isMatched = true
+			}
+		}
+		if !isMatched {
+			ResponseError(c, InternalErrorCode, errors.New(fmt.Sprintf("%v, not in iplist", c.ClientIP())))
+			c.Abort()
+			return
+		}
+		c.Next()
+	}
+}

+ 35 - 0
middleware/recovery.go

@@ -0,0 +1,35 @@
+package middleware
+
+import (
+	"errors"
+	"fmt"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+	"github.com/go_gateway_admin/public"
+	"runtime/debug"
+)
+
+// RecoveryMiddleware捕获所有panic,并且返回错误信息
+func RecoveryMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		defer func() {
+			if err := recover(); err != nil {
+				//先做一下日志记录
+				fmt.Println(string(debug.Stack()))
+				public.ComLogNotice(c, "_com_panic", map[string]interface{}{
+					"error": fmt.Sprint(err),
+					"stack": string(debug.Stack()),
+				})
+
+				if lib.ConfBase.DebugMode != "debug" {
+					ResponseError(c, 500, errors.New("内部错误"))
+					return
+				} else {
+					ResponseError(c, 500, errors.New(fmt.Sprint(err)))
+					return
+				}
+			}
+		}()
+		c.Next()
+	}
+}

+ 61 - 0
middleware/request_log.go

@@ -0,0 +1,61 @@
+package middleware
+
+import (
+	"bytes"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+	"github.com/go_gateway_admin/public"
+	"io/ioutil"
+	"time"
+)
+
+// 请求进入日志
+func RequestInLog(c *gin.Context) {
+	traceContext := lib.NewTrace()
+	if traceId := c.Request.Header.Get("com-header-rid"); traceId != "" {
+		traceContext.TraceId = traceId
+	}
+	if spanId := c.Request.Header.Get("com-header-spanid"); spanId != "" {
+		traceContext.SpanId = spanId
+	}
+
+	c.Set("startExecTime", time.Now())
+	c.Set("trace", traceContext)
+
+	bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
+	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // Write body back
+
+	lib.Log.TagInfo(traceContext, "_com_request_in", map[string]interface{}{
+		"uri":    c.Request.RequestURI,
+		"method": c.Request.Method,
+		"args":   c.Request.PostForm,
+		"body":   string(bodyBytes),
+		"from":   c.ClientIP(),
+	})
+}
+
+// 请求输出日志
+func RequestOutLog(c *gin.Context) {
+	// after request
+	endExecTime := time.Now()
+	response, _ := c.Get("response")
+	st, _ := c.Get("startExecTime")
+
+	startExecTime, _ := st.(time.Time)
+	public.ComLogNotice(c, "_com_request_out", map[string]interface{}{
+		"uri":       c.Request.RequestURI,
+		"method":    c.Request.Method,
+		"args":      c.Request.PostForm,
+		"from":      c.ClientIP(),
+		"response":  response,
+		"proc_time": endExecTime.Sub(startExecTime).Seconds(),
+	})
+}
+
+func RequestLog() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		RequestInLog(c)
+		defer RequestOutLog(c)
+		c.Next()
+	}
+}

+ 66 - 0
middleware/response.go

@@ -0,0 +1,66 @@
+package middleware
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+	"strings"
+)
+
+type ResponseCode int
+
+//1000以下为通用码,1000以上为用户自定义码
+const (
+	SuccessCode ResponseCode = iota
+	UndefErrorCode
+	ValidErrorCode
+	InternalErrorCode
+
+	InvalidRequestErrorCode ResponseCode = 401
+	CustomizeCode           ResponseCode = 1000
+
+	GROUPALL_SAVE_FLOWERROR ResponseCode = 2001
+)
+
+type Response struct {
+	ErrorCode ResponseCode `json:"errno"`
+	ErrorMsg  string       `json:"errmsg"`
+	Data      interface{}  `json:"data"`
+	TraceId   interface{}  `json:"trace_id"`
+	Stack     interface{}  `json:"stack"`
+}
+
+func ResponseError(c *gin.Context, code ResponseCode, err error) {
+	trace, _ := c.Get("trace")
+	traceContext, _ := trace.(*lib.TraceContext)
+	traceId := ""
+	if traceContext != nil {
+		traceId = traceContext.TraceId
+	}
+
+	stack := ""
+	if c.Query("is_debug") == "1" || lib.GetConfEnv() == "dev" {
+		stack = strings.Replace(fmt.Sprintf("%+v", err), err.Error()+"\n", "", -1)
+	}
+
+	resp := &Response{ErrorCode: code, ErrorMsg: err.Error(), Data: "", TraceId: traceId, Stack: stack}
+	c.JSON(200, resp)
+	response, _ := json.Marshal(resp)
+	c.Set("response", string(response))
+	c.AbortWithError(200, err)
+}
+
+func ResponseSuccess(c *gin.Context, data interface{}) {
+	trace, _ := c.Get("trace")
+	traceContext, _ := trace.(*lib.TraceContext)
+	traceId := ""
+	if traceContext != nil {
+		traceId = traceContext.TraceId
+	}
+
+	resp := &Response{ErrorCode: SuccessCode, ErrorMsg: "", Data: data, TraceId: traceId}
+	c.JSON(200, resp)
+	response, _ := json.Marshal(resp)
+	c.Set("response", string(response))
+}

+ 19 - 0
middleware/session_auth.go

@@ -0,0 +1,19 @@
+package middleware
+
+import (
+	"errors"
+	"github.com/gin-gonic/contrib/sessions"
+	"github.com/gin-gonic/gin"
+)
+
+func SessionAuthMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		session := sessions.Default(c)
+		if name, ok := session.Get("user").(string); !ok || name == "" {
+			ResponseError(c, InternalErrorCode, errors.New("user not login"))
+			c.Abort()
+			return
+		}
+		c.Next()
+	}
+}

+ 66 - 0
middleware/translation.go

@@ -0,0 +1,66 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/locales/en"
+	"github.com/go-playground/locales/zh"
+	"github.com/go-playground/universal-translator"
+	"github.com/go_gateway_admin/public"
+	"gopkg.in/go-playground/validator.v9"
+	en_translations "gopkg.in/go-playground/validator.v9/translations/en"
+	zh_translations "gopkg.in/go-playground/validator.v9/translations/zh"
+	"reflect"
+)
+
+//设置Translation
+func TranslationMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		//参照:https://github.com/go-playground/validator/blob/v9/_examples/translations/main.go
+
+		//设置支持语言
+		en := en.New()
+		zh := zh.New()
+
+		//设置国际化翻译器
+		uni := ut.New(zh, zh, en)
+		val := validator.New()
+
+		//根据参数取翻译器实例
+		locale := c.DefaultQuery("locale", "zh")
+		trans, _ := uni.GetTranslator(locale)
+
+		//翻译器注册到validator
+		switch locale {
+		case "en":
+			en_translations.RegisterDefaultTranslations(val, trans)
+			val.RegisterTagNameFunc(func(fld reflect.StructField) string {
+				return fld.Tag.Get("en_comment")
+			})
+			break
+		default:
+			zh_translations.RegisterDefaultTranslations(val, trans)
+			val.RegisterTagNameFunc(func(fld reflect.StructField) string {
+				return fld.Tag.Get("comment")
+			})
+
+			//自定义验证方法
+			//https://github.com/go-playground/validator/blob/v9/_examples/custom-validation/main.go
+			val.RegisterValidation("is_valid_username", func(fl validator.FieldLevel) bool {
+				return fl.Field().String() == "admin"
+			})
+
+			//自定义验证器
+			//https://github.com/go-playground/validator/blob/v9/_examples/translations/main.go
+			val.RegisterTranslation("is_valid_username", trans, func(ut ut.Translator) error {
+				return ut.Add("is_valid_username", "{0} 填写不正确哦", true)
+			}, func(ut ut.Translator, fe validator.FieldError) string {
+				t, _ := ut.T("is_valid_username", fe.Field())
+				return t
+			})
+			break
+		}
+		c.Set(public.TranslatorKey, trans)
+		c.Set(public.ValidatorKey, val)
+		c.Next()
+	}
+}

+ 6 - 0
public/const.go

@@ -0,0 +1,6 @@
+package public
+
+const (
+	ValidatorKey  = "ValidatorKey"
+	TranslatorKey = "TranslatorKey"
+)

+ 76 - 0
public/log.go

@@ -0,0 +1,76 @@
+package public
+
+import (
+	"context"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+)
+
+//错误日志
+func ContextWarning(c context.Context, dltag string, m map[string]interface{}) {
+	v := c.Value("trace")
+	traceContext, ok := v.(*lib.TraceContext)
+	if !ok {
+		traceContext = lib.NewTrace()
+	}
+	lib.Log.TagWarn(traceContext, dltag, m)
+}
+
+//错误日志
+func ContextError(c context.Context, dltag string, m map[string]interface{}) {
+	v := c.Value("trace")
+	traceContext, ok := v.(*lib.TraceContext)
+	if !ok {
+		traceContext = lib.NewTrace()
+	}
+	lib.Log.TagError(traceContext, dltag, m)
+}
+
+//普通日志
+func ContextNotice(c context.Context, dltag string, m map[string]interface{}) {
+	v := c.Value("trace")
+	traceContext, ok := v.(*lib.TraceContext)
+	if !ok {
+		traceContext = lib.NewTrace()
+	}
+	lib.Log.TagInfo(traceContext, dltag, m)
+}
+
+//错误日志
+func ComLogWarning(c *gin.Context, dltag string, m map[string]interface{}) {
+	traceContext := GetGinTraceContext(c)
+	lib.Log.TagError(traceContext, dltag, m)
+}
+
+//普通日志
+func ComLogNotice(c *gin.Context, dltag string, m map[string]interface{}) {
+	traceContext := GetGinTraceContext(c)
+	lib.Log.TagInfo(traceContext, dltag, m)
+}
+
+// 从gin的Context中获取数据
+func GetGinTraceContext(c *gin.Context) *lib.TraceContext {
+	// 防御
+	if c == nil {
+		return lib.NewTrace()
+	}
+	traceContext, exists := c.Get("trace")
+	if exists {
+		if tc, ok := traceContext.(*lib.TraceContext); ok {
+			return tc
+		}
+	}
+	return lib.NewTrace()
+}
+
+// 从Context中获取数据
+func GetTraceContext(c context.Context) *lib.TraceContext {
+	if c == nil {
+		return lib.NewTrace()
+	}
+	traceContext := c.Value("trace")
+	if tc, ok := traceContext.(*lib.TraceContext); ok {
+		return tc
+	}
+	return lib.NewTrace()
+}

+ 59 - 0
public/params.go

@@ -0,0 +1,59 @@
+package public
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/universal-translator"
+	"github.com/pkg/errors"
+	"gopkg.in/go-playground/validator.v9"
+	"strings"
+)
+
+func DefaultGetValidParams(c *gin.Context, params interface{}) error {
+	if err := c.ShouldBind(params); err != nil {
+		return err
+	}
+	//获取验证器
+	valid, err := GetValidator(c)
+	if err != nil {
+		return err
+	}
+	//获取翻译器
+	trans, err := GetTranslation(c)
+	if err != nil {
+		return err
+	}
+	err = valid.Struct(params)
+	if err != nil {
+		errs := err.(validator.ValidationErrors)
+		sliceErrs := []string{}
+		for _, e := range errs {
+			sliceErrs = append(sliceErrs, e.Translate(trans))
+		}
+		return errors.New(strings.Join(sliceErrs, ","))
+	}
+	return nil
+}
+
+func GetValidator(c *gin.Context) (*validator.Validate, error) {
+	val, ok := c.Get(ValidatorKey)
+	if !ok {
+		return nil, errors.New("未设置验证器")
+	}
+	validator, ok := val.(*validator.Validate)
+	if !ok {
+		return nil, errors.New("获取验证器失败")
+	}
+	return validator, nil
+}
+
+func GetTranslation(c *gin.Context) (ut.Translator, error) {
+	trans, ok := c.Get(TranslatorKey)
+	if !ok {
+		return nil, errors.New("未设置翻译器")
+	}
+	translator, ok := trans.(ut.Translator)
+	if !ok {
+		return nil, errors.New("获取翻译器失败")
+	}
+	return translator, nil
+}

+ 41 - 0
router/httpserver.go

@@ -0,0 +1,41 @@
+package router
+
+import (
+	"context"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/gin"
+	"log"
+	"net/http"
+	"time"
+)
+
+var (
+	HttpSrvHandler *http.Server
+)
+
+func HttpServerRun() {
+	gin.SetMode(lib.ConfBase.DebugMode)
+	r := InitRouter()
+	HttpSrvHandler = &http.Server{
+		Addr:           lib.GetStringConf("base.http.addr"),
+		Handler:        r,
+		ReadTimeout:    time.Duration(lib.GetIntConf("base.http.read_timeout")) * time.Second,
+		WriteTimeout:   time.Duration(lib.GetIntConf("base.http.write_timeout")) * time.Second,
+		MaxHeaderBytes: 1 << uint(lib.GetIntConf("base.http.max_header_bytes")),
+	}
+	go func() {
+		log.Printf(" [INFO] HttpServerRun:%s\n", lib.GetStringConf("base.http.addr"))
+		if err := HttpSrvHandler.ListenAndServe(); err != nil {
+			log.Fatalf(" [ERROR] HttpServerRun:%s err:%v\n", lib.GetStringConf("base.http.addr"), err)
+		}
+	}()
+}
+
+func HttpServerStop() {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	if err := HttpSrvHandler.Shutdown(ctx); err != nil {
+		log.Fatalf(" [ERROR] HttpServerStop err:%v\n", err)
+	}
+	log.Printf(" [INFO] HttpServerStop stopped\n")
+}

+ 102 - 0
router/route.go

@@ -0,0 +1,102 @@
+package router
+
+import (
+	"errors"
+	"github.com/e421083458/golang_common/lib"
+	"github.com/gin-gonic/contrib/sessions"
+	"github.com/gin-gonic/gin"
+	"github.com/go_gateway_admin/controller"
+	"github.com/go_gateway_admin/docs"
+	"github.com/go_gateway_admin/middleware"
+	"github.com/swaggo/files"
+	"github.com/swaggo/gin-swagger"
+	"log"
+)
+
+// @title Swagger Example API
+// @version 1.0
+// @description This is a sample server celler server.
+// @termsOfService http://swagger.io/terms/
+
+// @contact.name API Support
+// @contact.url http://www.swagger.io/support
+// @contact.email support@swagger.io
+
+// @license.name Apache 2.0
+// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
+
+// @host localhost:8080
+// @BasePath /api/v1
+// @query.collection.format multi
+
+// @securityDefinitions.basic BasicAuth
+
+// @securityDefinitions.apikey ApiKeyAuth
+// @in header
+// @name Authorization
+
+// @securitydefinitions.oauth2.application OAuth2Application
+// @tokenUrl https://example.com/oauth/token
+// @scope.write Grants write access
+// @scope.admin Grants read and write access to administrative information
+
+// @securitydefinitions.oauth2.implicit OAuth2Implicit
+// @authorizationurl https://example.com/oauth/authorize
+// @scope.write Grants write access
+// @scope.admin Grants read and write access to administrative information
+
+// @securitydefinitions.oauth2.password OAuth2Password
+// @tokenUrl https://example.com/oauth/token
+// @scope.read Grants read access
+// @scope.write Grants write access
+// @scope.admin Grants read and write access to administrative information
+
+// @securitydefinitions.oauth2.accessCode OAuth2AccessCode
+// @tokenUrl https://example.com/oauth/token
+// @authorizationurl https://example.com/oauth/authorize
+// @scope.admin Grants read and write access to administrative information
+
+// @x-extension-openapi {"example": "value on a json format"}
+
+func InitRouter(middlewares ...gin.HandlerFunc) *gin.Engine {
+	// programatically set swagger info
+	docs.SwaggerInfo.Title = lib.GetStringConf("base.swagger.title")
+	docs.SwaggerInfo.Description = lib.GetStringConf("base.swagger.desc")
+	docs.SwaggerInfo.Version = "1.0"
+	docs.SwaggerInfo.Host = lib.GetStringConf("base.swagger.host")
+	docs.SwaggerInfo.BasePath = lib.GetStringConf("base.swagger.base_path")
+	docs.SwaggerInfo.Schemes = []string{"http", "https"}
+
+	router := gin.Default()
+	router.Use(middlewares...)
+	router.GET("/ping", func(c *gin.Context) {
+		c.JSON(200, gin.H{
+			"message": "pong",
+		})
+	})
+	router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+
+	//middleware.ResponseError(c, 2002, errors.New("账号或密码错误"))
+	router.NoRoute(func(c *gin.Context) {
+		middleware.ResponseError(c, middleware.InvalidRequestErrorCode, errors.New("未找到路由"))
+	})
+
+	adminLoginRoute := router.Group("/admin/")
+
+	store, err := sessions.NewRedisStore(10, "tcp", "127.0.0.1:6379", "", []byte("secret"))
+	if err != nil {
+		log.Fatalf("session.NewRedisStore err : %v", err)
+	}
+
+	adminLoginRoute.Use(sessions.Sessions("mysession", store),
+		middleware.RecoveryMiddleware(),
+		middleware.RequestLog(),
+		middleware.TranslationMiddleware())
+	{
+		controller.AdminLoginRegister(adminLoginRoute)
+	}
+	//store := sessions.NewCookieStore([]byte("secret"))
+	//apiNormalGroup := router.Group("/api")
+
+	return router
+}