From b14b1ef34557caeafd58bce5d313afcba662d277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 20 Jul 2024 23:39:25 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/api.go | 35 ---------- router/define.go | 13 ++++ router/meta.go | 15 ++++ router/register.go | 122 ++++++++++----------------------- router/register_router_test.go | 78 --------------------- router/register_test.go | 36 ++++++++++ router/util.go | 79 --------------------- 7 files changed, 102 insertions(+), 276 deletions(-) delete mode 100644 router/api.go create mode 100644 router/define.go create mode 100644 router/meta.go delete mode 100644 router/register_router_test.go create mode 100644 router/register_test.go delete mode 100644 router/util.go diff --git a/router/api.go b/router/api.go deleted file mode 100644 index 9ff2982..0000000 --- a/router/api.go +++ /dev/null @@ -1,35 +0,0 @@ -// Package router ... -// -// Description : 便捷的相关API处理 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2021-03-26 2:06 下午 -package router - -import ( - "github.com/gin-gonic/gin" -) - -// IApi 每一个接口的实现约束 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2:08 下午 2021/3/26 -type IApi interface { - // GetMethod 接口请求方法 - GetMethod() string - // GetURI 接口URI - GetURI() string - // GetMiddleWareList 使用的中间件列表 - GetMiddleWareList() []gin.HandlerFunc - // GetHandler 处理的handler - GetHandler() gin.HandlerFunc -} - -// RegisterFunc 注册路由的函数 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 3:09 下午 2021/3/26 -type RegisterFunc func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) diff --git a/router/define.go b/router/define.go new file mode 100644 index 0000000..3576bdc --- /dev/null +++ b/router/define.go @@ -0,0 +1,13 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-07-20 22:57 +package router + +const ( + PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 + MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 +) diff --git a/router/meta.go b/router/meta.go new file mode 100644 index 0000000..93d9204 --- /dev/null +++ b/router/meta.go @@ -0,0 +1,15 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-07-20 21:40 +package router + +// Meta 接口的元信息 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:40 2024/7/20 +type Meta struct{} diff --git a/router/register.go b/router/register.go index 16541a0..4861187 100644 --- a/router/register.go +++ b/router/register.go @@ -1,115 +1,69 @@ // Package router ... // -// Description : 注册路由 +// Description : router ... // // Author : go_developer@163.com<白茶清欢> // -// Date : 2021-03-26 2:13 下午 +// Date : 2024-07-20 21:39 package router import ( - "log" + "fmt" "reflect" - "github.com/pkg/errors" - "github.com/gin-gonic/gin" ) var ( - // DebugLogEnable 默认打开debug日志 - DebugLogEnable = true + ginRouter = gin.Default() ) -// DisableDebugLog 禁用debug日志 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2:17 下午 2021/3/26 -func DisableDebugLog() { - DebugLogEnable = false +func init() { + } -// RegisterRouter 注册一个路由 +// Register 注册路由 // // Author : go_developer@163.com<白茶清欢> // -// Date : 2:14 下午 2021/3/26 -func RegisterRouter(router *gin.Engine, apiInstanceList ...any) error { - for _, apiInstance := range apiInstanceList { - if nil == apiInstance { +// Date : 21:40 2024/7/20 +func Register(port int, controllerList ...any) { + for _, controller := range controllerList { + if nil == controller { + // 忽略空指针 continue } - val := reflect.ValueOf(apiInstance) - switch val.Kind() { - case reflect.Struct: - fallthrough - case reflect.Ptr: - api, ok := apiInstance.(IApi) - if ok { - if err := HandleRegisterRouter(router, api.GetMethod(), api.GetURI(), api.GetHandler(), api.GetMiddleWareList()); nil != err { - routerLog(err.Error()) - return err - } - continue - } - routerLog(val.String() + "结构体或者结构体指针, 自动识别函数是否包含RouterFunc") - // 不是IApi接口,自动识别函数列表 RouterFunc 函数自动注册 - methodCnt := val.NumMethod() - for i := 0; i < methodCnt; i++ { - // TODO : 识别函数本身是不是 RouterFunc - af, o := val.Method(i).Interface().(func() (string, string, gin.HandlerFunc, []gin.HandlerFunc)) - if o { - method, uri, handler, middlewareList := af() - if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err { - routerLog(err.Error()) - return err - } - continue - } - apiFuncList := val.Method(i).Call(nil) - for _, apiFuncVal := range apiFuncList { - apiFunc, ok := apiFuncVal.Interface().(RegisterFunc) - if !ok { - continue - } - method, uri, handler, middlewareList := apiFunc() - if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err { - routerLog(err.Error()) - return err - } - } - - } - case reflect.Func: - api, ok := apiInstance.(RegisterFunc) - if !ok { - err := errors.New("函数方式注册路由必须是 RouterFunc") - routerLog(err.Error()) - return err - } - method, uri, handler, middlewareList := api() - if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err { - routerLog(err.Error()) - return err - } - default: - err := errors.New("注册的路由必须是 IApi 或者 RouterFunc 或者 包含 RouterFunc 的结构体") - routerLog(err.Error()) - return err - } } - return nil } -// routerLog 记录日志 +// parseController 解析controller // // Author : go_developer@163.com<白茶清欢> // -// Date : 2:28 下午 2021/3/26 -func routerLog(msg string) { - if !DebugLogEnable || len(msg) == 0 { - return +// Date : 22:10 2024/7/20 +func parseController(controller any) { + controllerType := reflect.TypeOf(controller) + controllerValue := reflect.ValueOf(controller) + routerPrefix := "/" + // 解析路由前缀函数 + // routerPrefix 不能有任何入参, 并且只能有一个返回值, + // 返回值类型为字符串, 为具体路由前缀 + routerPrefixFunc, routerPrefixFuncExist := controllerType.MethodByName(PrefixFuncName) + if routerPrefixFuncExist { + routerPrefixFuncType := routerPrefixFunc.Type + if routerPrefixFuncType.NumIn() == 1 && // 无任何入参, 正在没有如何入参情况下, 第一个参数是结构体指针 + routerPrefixFuncType.NumOut() == 1 && // 只能有一个返回值 + routerPrefixFuncType.Out(0).Kind() == reflect.String { // 返回值必须是字符串 + routerPrefix = routerPrefixFunc.Func.Call([]reflect.Value{controllerValue})[0].String() + // .Call(nil)[0].String() + } + // 请求组的中间件 + /*routerMiddlewareFunc := controllerType.MethodByName(MiddlewareFuncName) + routerMiddlewareFuncType := routerMiddlewareFunc.Type() + if routerMiddlewareFuncType.NumIn() == 0 && // 无需任何参数 + routerMiddlewareFuncType.NumOut() == 1 && // 只能有一个返回值 + routerMiddlewareFuncType.Out(0).String() == "[]gin.HandlerFunc" { // 返回值必须是gin.HandlerFunc + }*/ } - log.Print(msg) + fmt.Println(routerPrefix) } diff --git a/router/register_router_test.go b/router/register_router_test.go deleted file mode 100644 index b7eae00..0000000 --- a/router/register_router_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Package router ... -// -// Description : 路由注册单元测试 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2021-03-26 3:49 下午 -package router - -import ( - "net/http" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/gin-gonic/gin" -) - -// TestRegisterRouter ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 3:50 下午 2021/3/26 -func TestRegisterRouter(t *testing.T) { - r := gin.Default() - err := RegisterRouter(r, demoApiFunc(), &demoApi{}, &otherApi{}, nil) - assert.Nil(t, err, "路由注册异常 : %v", err) -} - -func demoApiFunc() RouterFunc { - return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) { - return http.MethodGet, "/api/func/test", func(context *gin.Context) { - - }, nil - } -} - -type demoApi struct { -} - -func (d demoApi) GetMethod() string { - return http.MethodGet -} - -func (d demoApi) GetURI() string { - return "/api/struct/test" -} - -func (d demoApi) GetMiddleWareList() []gin.HandlerFunc { - return nil -} - -func (d demoApi) GetHandler() gin.HandlerFunc { - return func(context *gin.Context) { - - } -} - -type otherApi struct { -} - -func (oa *otherApi) DemoApiFunc() RouterFunc { - return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) { - return http.MethodGet, "/api/other/test", func(context *gin.Context) { - - }, nil - } -} - -func (oa *otherApi) Lala() { - -} - -func (oa *otherApi) SelfApi() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) { - return http.MethodGet, "/api/other/self/test", func(context *gin.Context) { - - }, nil -} diff --git a/router/register_test.go b/router/register_test.go new file mode 100644 index 0000000..bab42f0 --- /dev/null +++ b/router/register_test.go @@ -0,0 +1,36 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-07-20 23:24 +package router + +import ( + "testing" + + "github.com/gin-gonic/gin" +) + +type TestController struct{} + +func (t *TestController) RouterPrefix() string { + return "/uri/prefix" +} + +func (t *TestController) RouterMiddleware() []gin.HandlerFunc { + return []gin.HandlerFunc{ + func(ctx *gin.Context) { + + }, + } +} + +func Test_parseController(t *testing.T) { + type args struct { + controller any + } + parseController(TestController{}) + parseController(&TestController{}) +} diff --git a/router/util.go b/router/util.go deleted file mode 100644 index 7670113..0000000 --- a/router/util.go +++ /dev/null @@ -1,79 +0,0 @@ -// Package router ... -// -// Description : router ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2023-03-03 16:48 -package router - -import ( - "fmt" - "net/http" - "strings" - - "github.com/gin-gonic/gin" -) - -// HandleRegisterRouter 注册gin路由 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:36 下午 2021/3/9 -func HandleRegisterRouter(router *gin.Engine, method string, uri string, handler gin.HandlerFunc, middlewareList []gin.HandlerFunc) error { - if nil == middlewareList { - middlewareList = make([]gin.HandlerFunc, 0) - } - switch strings.ToUpper(method) { - case http.MethodGet: - router.GET(uri, handler).Use(middlewareList...) - case http.MethodPost: - router.POST(uri, handler).Use(middlewareList...) - case http.MethodDelete: - router.DELETE(uri, handler).Use(middlewareList...) - case http.MethodHead: - router.HEAD(uri, handler).Use(middlewareList...) - case http.MethodOptions: - router.OPTIONS(uri, handler).Use(middlewareList...) - case http.MethodPatch: - router.PATCH(uri, handler).Use(middlewareList...) - case http.MethodPut: - router.PUT(uri, handler).Use(middlewareList...) - case "ANY": // 一次性注册全部请求方法的路由 - router.Any(uri, handler).Use(middlewareList...) - default: - // 不是一个函数,数名method配置错误 - return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method) - } - return nil -} - -// RegisterRouterGroup 注册gin路由 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:36 下午 2021/3/9 -func RegisterRouterGroup(router *gin.RouterGroup, method string, uri string, handler gin.HandlerFunc) error { - switch strings.ToUpper(method) { - case http.MethodGet: - router.GET(uri, handler) - case http.MethodPost: - router.POST(uri, handler) - case http.MethodDelete: - router.DELETE(uri, handler) - case http.MethodHead: - router.HEAD(uri, handler) - case http.MethodOptions: - router.OPTIONS(uri, handler) - case http.MethodPatch: - router.PATCH(uri, handler) - case http.MethodPut: - router.PUT(uri, handler) - case "ANY": // 一次性注册全部请求方法的路由 - router.Any(uri, handler) - default: - // 不是一个函数,数名method配置错误 - return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method) - } - return nil -} -- 2.36.6 From f55dee577d016a3e9abfbfc2f667e9d746fac5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 21 Jul 2024 12:19:23 +0800 Subject: [PATCH 02/20] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/register.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/router/register.go b/router/register.go index 4861187..ea5ceea 100644 --- a/router/register.go +++ b/router/register.go @@ -55,15 +55,23 @@ func parseController(controller any) { routerPrefixFuncType.NumOut() == 1 && // 只能有一个返回值 routerPrefixFuncType.Out(0).Kind() == reflect.String { // 返回值必须是字符串 routerPrefix = routerPrefixFunc.Func.Call([]reflect.Value{controllerValue})[0].String() - // .Call(nil)[0].String() } - // 请求组的中间件 - /*routerMiddlewareFunc := controllerType.MethodByName(MiddlewareFuncName) - routerMiddlewareFuncType := routerMiddlewareFunc.Type() - if routerMiddlewareFuncType.NumIn() == 0 && // 无需任何参数 + } + // 请求组的中间件 + middlewareList := make([]gin.HandlerFunc, 0) + routerMiddlewareFunc, routerMiddlewareFuncExist := controllerType.MethodByName(MiddlewareFuncName) + if routerMiddlewareFuncExist { + routerMiddlewareFuncType := routerMiddlewareFunc.Type + if routerMiddlewareFuncType.NumIn() == 1 && // 无需任何参数 routerMiddlewareFuncType.NumOut() == 1 && // 只能有一个返回值 routerMiddlewareFuncType.Out(0).String() == "[]gin.HandlerFunc" { // 返回值必须是gin.HandlerFunc - }*/ + res := routerMiddlewareFunc.Func.Call([]reflect.Value{controllerValue}) + if !res[0].IsNil() { + middlewareList = res[0].Interface().([]gin.HandlerFunc) + } + } + fmt.Println(111, middlewareList) } + fmt.Println(routerPrefix) } -- 2.36.6 From 455f74ad89a6db770adb1d31544be67a5737cbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 21 Jul 2024 16:51:02 +0800 Subject: [PATCH 03/20] =?UTF-8?q?=E6=8E=A5=E5=8F=A3meta=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/define.go | 21 +++++++++++++ router/register.go | 70 +++++++++++++++++++++++++++++++++++++++-- router/register_test.go | 7 +++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/router/define.go b/router/define.go index 3576bdc..42aac9b 100644 --- a/router/define.go +++ b/router/define.go @@ -11,3 +11,24 @@ const ( PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 ) + +const ( + TagNamePath = "path" // 接口的请求路径 + TagNameMethod = "method" // 接口的请求方法 + TagNameUriTag = "tag" // 接口的tag + TagNameDesc = "desc" // 接口的描述 + TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY +) + +// UriConfig 接口配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:41 2024/7/21 +type UriConfig struct { + Path string `json:"path"` // 接口路由, 必须配置 + Method string `json:"method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY +} diff --git a/router/register.go b/router/register.go index ea5ceea..0d1432b 100644 --- a/router/register.go +++ b/router/register.go @@ -10,11 +10,15 @@ package router import ( "fmt" "reflect" + "strings" + + "git.zhangdeman.cn/zhangdeman/wrapper" "github.com/gin-gonic/gin" ) var ( + Debug = false // 是否开启DEBUG ginRouter = gin.Default() ) @@ -72,6 +76,68 @@ func parseController(controller any) { } fmt.Println(111, middlewareList) } - - fmt.Println(routerPrefix) + for funcIdx := 0; funcIdx < controllerType.NumMethod(); funcIdx++ { + method := controllerType.Method(funcIdx) + // methodValue := controllerValue.Method(funcIdx) + if method.Name == PrefixFuncName || method.Name == MiddlewareFuncName { + continue + } + methodType := method.Type + uriConfig, err := parseUriConfig(methodType, routerPrefix) + if nil != err { + debugLog("parseUriConfig error : %s -> %s", err.Error(), methodType.Kind().String()) + } + if nil == uriConfig { + continue + } + } +} + +// parseUriConfig 解析Uri配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 16:40 2024/7/21 +func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, error) { + if methodType.NumIn() != 3 || // 结构体指针 + 两个参数 + methodType.NumOut() != 2 { // 两个返回值 + return nil, nil + } + // 接口logic共计两个参数. 两个返回值, 格式 : func(ctx *gin.Context, formData any[组合Meta]) (any[response], error) + + // 解析第一个参数是 *gin.Context + if methodType.In(1).String() != "*gin.Context" { + return nil, nil + } + // 解析第二个参数是组合Meta的form表单 + formType := methodType.In(2) + if formType.Kind() == reflect.Ptr { + formType = methodType.In(2).Elem() + } + metaField, metaFieldExist := formType.FieldByName("Meta") + if !metaFieldExist { + return nil, nil + } + uriConfig := &UriConfig{ + Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), + Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), + TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), + Desc: metaField.Tag.Get(TagNameDesc), + Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, + } + // 解析第一个返回值 + // 解析第二个返回值 + return uriConfig, nil +} + +// debugLog ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:32 2024/7/21 +func debugLog(format string, valList ...any) { + if !Debug { + return + } + fmt.Printf("[DEBUG] "+format+"\n", valList...) } diff --git a/router/register_test.go b/router/register_test.go index bab42f0..08fddf1 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -26,6 +26,13 @@ func (t *TestController) RouterMiddleware() []gin.HandlerFunc { }, } } +func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) { + return nil, nil +} + +type TestForm struct { + Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` +} func Test_parseController(t *testing.T) { type args struct { -- 2.36.6 From f8f63691b7be40a20486d542ef614b2990eb1316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 21 Jul 2024 18:49:44 +0800 Subject: [PATCH 04/20] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=B3=A8=E5=86=8C,=20=E9=81=97=E7=95=99=20:?= =?UTF-8?q?=20form=E8=A1=A8=E5=8D=95,=20any=E6=95=B0=E6=8D=AE=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=A7=A3=E6=9E=90=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/define.go | 13 ++++--- router/register.go | 82 ++++++++++++++++++++++++++++++++++++----- router/register_test.go | 8 ++-- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/router/define.go b/router/define.go index 42aac9b..a761be7 100644 --- a/router/define.go +++ b/router/define.go @@ -7,6 +7,8 @@ // Date : 2024-07-20 22:57 package router +import "reflect" + const ( PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 @@ -26,9 +28,10 @@ const ( // // Date : 15:41 2024/7/21 type UriConfig struct { - Path string `json:"path"` // 接口路由, 必须配置 - Method string `json:"method"` // 接口请求方法, 必须配置 - TagList []string `json:"tag_list"` // 接口分组 - Desc string `json:"desc"` // 接口描述 - Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + Path string `json:"path"` // 接口路由, 必须配置 + Method string `json:"method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + FormDataType reflect.Type `json:"-"` // 表单数据类型 } diff --git a/router/register.go b/router/register.go index 0d1432b..bd433e1 100644 --- a/router/register.go +++ b/router/register.go @@ -9,9 +9,15 @@ package router import ( "fmt" + "net/http" "reflect" "strings" + "git.zhangdeman.cn/zhangdeman/exception" + "git.zhangdeman.cn/zhangdeman/gin/response" + + "git.zhangdeman.cn/zhangdeman/gin/request" + "git.zhangdeman.cn/zhangdeman/wrapper" "github.com/gin-gonic/gin" @@ -37,7 +43,9 @@ func Register(port int, controllerList ...any) { // 忽略空指针 continue } + parseController(controller) } + ginRouter.Run(fmt.Sprintf(":%d", port)) } // parseController 解析controller @@ -74,11 +82,9 @@ func parseController(controller any) { middlewareList = res[0].Interface().([]gin.HandlerFunc) } } - fmt.Println(111, middlewareList) } for funcIdx := 0; funcIdx < controllerType.NumMethod(); funcIdx++ { method := controllerType.Method(funcIdx) - // methodValue := controllerValue.Method(funcIdx) if method.Name == PrefixFuncName || method.Name == MiddlewareFuncName { continue } @@ -90,6 +96,7 @@ func parseController(controller any) { if nil == uriConfig { continue } + registerUri(uriConfig, controllerValue.Method(funcIdx), middlewareList) } } @@ -119,17 +126,74 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e return nil, nil } uriConfig := &UriConfig{ - Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), - Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), - TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), - Desc: metaField.Tag.Get(TagNameDesc), - Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, + Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), + Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), + TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), + Desc: metaField.Tag.Get(TagNameDesc), + Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, + FormDataType: methodType.In(2).Elem(), } - // 解析第一个返回值 - // 解析第二个返回值 return uriConfig, nil } +// registerUri 注册路由 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:00 2024/7/21 +func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList []gin.HandlerFunc) { + if nil == middlewareList { + middlewareList = make([]gin.HandlerFunc, 0) + } + handlerFunc := func(ctx *gin.Context) { + formDataReceiver := reflect.New(uriConfig.FormDataType) + if err := request.Form.Parse(ctx, formDataReceiver.Interface()); nil != err { + panic(err) + } + + returnValue := methodValue.Call([]reflect.Value{reflect.ValueOf(ctx), formDataReceiver}) + businessData := returnValue[0].Interface() + errData := returnValue[1] + if errData.IsNil() { + response.Success(ctx, businessData) + return + } + err := errData.Interface() + if e, ok := err.(exception.IException); ok { + response.SendWithException(ctx, e, businessData) + return + } else { + response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), businessData) + return + } + } + middlewareList = append(middlewareList, handlerFunc) + switch uriConfig.Method { + case http.MethodGet: + ginRouter.GET(uriConfig.Path, middlewareList...) + case http.MethodHead: + ginRouter.HEAD(uriConfig.Path, middlewareList...) + case http.MethodPost: + ginRouter.PUT(uriConfig.Path, middlewareList...) + case http.MethodPut: + ginRouter.PUT(uriConfig.Path, middlewareList...) + case http.MethodPatch: + ginRouter.PATCH(uriConfig.Path, middlewareList...) + case http.MethodDelete: + ginRouter.DELETE(uriConfig.Path, middlewareList...) + case http.MethodConnect: + ginRouter.Handle(http.MethodConnect, uriConfig.Path, middlewareList...) + case http.MethodOptions: + ginRouter.OPTIONS(uriConfig.Path, middlewareList...) + case http.MethodTrace: + ginRouter.Handle(http.MethodTrace, uriConfig.Path, middlewareList...) + case "ANY": + ginRouter.Any(uriConfig.Path, middlewareList...) + default: + panic(uriConfig.Path + " : " + uriConfig.Method + " is not support") + } +} + // debugLog ... // // Author : go_developer@163.com<白茶清欢> diff --git a/router/register_test.go b/router/register_test.go index 08fddf1..838898c 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -27,17 +27,19 @@ func (t *TestController) RouterMiddleware() []gin.HandlerFunc { } } func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) { - return nil, nil + return formData, nil } type TestForm struct { Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` + Age int `json:"age" form:"age"` + Name string `json:"name" form:"name"` + Test any `json:"test" form:"test"` } func Test_parseController(t *testing.T) { type args struct { controller any } - parseController(TestController{}) - parseController(&TestController{}) + Register(8080, &TestController{}) } -- 2.36.6 From deead87688ad33838b1d3619ddb4625f79b5caa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 21 Jul 2024 19:16:50 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/register.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/router/register.go b/router/register.go index bd433e1..36aaf67 100644 --- a/router/register.go +++ b/router/register.go @@ -37,7 +37,7 @@ func init() { // Author : go_developer@163.com<白茶清欢> // // Date : 21:40 2024/7/20 -func Register(port int, controllerList ...any) { +func Register(port int, controllerList ...any) error { for _, controller := range controllerList { if nil == controller { // 忽略空指针 @@ -45,7 +45,7 @@ func Register(port int, controllerList ...any) { } parseController(controller) } - ginRouter.Run(fmt.Sprintf(":%d", port)) + return ginRouter.Run(fmt.Sprintf(":%d", port)) } // parseController 解析controller -- 2.36.6 From 8a6182d0dee8c4e282711adaaa1456ac1a851020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 21 Jul 2024 22:03:59 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E8=AF=B7=E6=B1=82=E5=BC=80=E5=A7=8B=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/register.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/router/register.go b/router/register.go index 36aaf67..aaf2fc9 100644 --- a/router/register.go +++ b/router/register.go @@ -9,15 +9,14 @@ package router import ( "fmt" + "git.zhangdeman.cn/zhangdeman/exception" + "git.zhangdeman.cn/zhangdeman/gin/middleware" + "git.zhangdeman.cn/zhangdeman/gin/request" + "git.zhangdeman.cn/zhangdeman/gin/response" "net/http" "reflect" "strings" - "git.zhangdeman.cn/zhangdeman/exception" - "git.zhangdeman.cn/zhangdeman/gin/response" - - "git.zhangdeman.cn/zhangdeman/gin/request" - "git.zhangdeman.cn/zhangdeman/wrapper" "github.com/gin-gonic/gin" @@ -168,6 +167,9 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList } } middlewareList = append(middlewareList, handlerFunc) + middlewareList = append([]gin.HandlerFunc{ + middleware.InitRequest(), + }, middlewareList...) switch uriConfig.Method { case http.MethodGet: ginRouter.GET(uriConfig.Path, middlewareList...) -- 2.36.6 From 0b7df330f7c080762782a99ec68eac1ef57da289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 22 Jul 2024 10:30:18 +0800 Subject: [PATCH 07/20] =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=BC=83=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- request/form.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/request/form.go b/request/form.go index 7306c04..030d15e 100644 --- a/request/form.go +++ b/request/form.go @@ -10,7 +10,7 @@ package request import ( "bytes" "errors" - "io/ioutil" + "io" "net/http" "strings" @@ -37,11 +37,11 @@ type form struct { // Date : 00:34 2022/7/3 func (f *form) Parse(ctx *gin.Context, receiver interface{}) error { - requestBody, _ := ioutil.ReadAll(ctx.Request.Body) + requestBody, _ := io.ReadAll(ctx.Request.Body) // 请求信息写入上下文 ctx.Set(define.RecordRequestDataField, string(requestBody)) // 因为请求体被读一遍之后就没了,重新赋值 requestBody - ctx.Request.Body = ioutil.NopCloser(bytes.NewReader(requestBody)) + ctx.Request.Body = io.NopCloser(bytes.NewReader(requestBody)) method := strings.ToUpper(ctx.Request.Method) if method == http.MethodGet || method == http.MethodPatch || -- 2.36.6 From cc98043affbf5144f46886142addfa9227345bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 22 Jul 2024 11:19:41 +0800 Subject: [PATCH 08/20] update Test --- go.mod | 4 ---- go.sum | 2 -- router/register.go | 6 ++---- router/register_test.go | 4 +++- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 3f808f8..f62b322 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,6 @@ require ( git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 github.com/gin-gonic/gin v1.10.0 github.com/go-playground/validator/v10 v10.22.0 - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 ) @@ -27,7 +25,6 @@ require ( github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -45,7 +42,6 @@ require ( github.com/mozillazg/go-pinyin v0.20.0 // indirect github.com/mssola/user_agent v0.6.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/tidwall/gjson v1.17.1 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 0a7c671..6ca8741 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,6 @@ github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQw github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= diff --git a/router/register.go b/router/register.go index aaf2fc9..aec336c 100644 --- a/router/register.go +++ b/router/register.go @@ -13,13 +13,11 @@ import ( "git.zhangdeman.cn/zhangdeman/gin/middleware" "git.zhangdeman.cn/zhangdeman/gin/request" "git.zhangdeman.cn/zhangdeman/gin/response" + "git.zhangdeman.cn/zhangdeman/wrapper" + "github.com/gin-gonic/gin" "net/http" "reflect" "strings" - - "git.zhangdeman.cn/zhangdeman/wrapper" - - "github.com/gin-gonic/gin" ) var ( diff --git a/router/register_test.go b/router/register_test.go index 838898c..b021fe5 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -34,7 +34,9 @@ type TestForm struct { Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` Age int `json:"age" form:"age"` Name string `json:"name" form:"name"` - Test any `json:"test" form:"test"` + Test struct { + L string `json:"l"` + } `json:"test" form:"test"` } func Test_parseController(t *testing.T) { -- 2.36.6 From 89975771816ec68f033109425a21749a2a00a189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 22 Jul 2024 14:31:55 +0800 Subject: [PATCH 09/20] add readme --- router/README.md | 110 ++++++++++++++++++++++++++++++++++++++++ router/register.go | 6 +++ router/register_test.go | 8 +-- 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 router/README.md diff --git a/router/README.md b/router/README.md new file mode 100644 index 0000000..6b92c72 --- /dev/null +++ b/router/README.md @@ -0,0 +1,110 @@ +# 路由包使用说明 + +## 基础说明 + +- 基于 [web框架GIN](https://github.com/gin-gonic/gin) 的二次封装 + +## 为什么要二次封装 + +二次封装的想法来源于 [web框架GoFrame](https://github.com/gogf/gf)。gf框架本身内置集成了大量组件, 对于轻量应用开发, 相比较而言比较笨重, 但是启根据请求数据结构、响应数据结构自动生成表单的能力十分实用。 +在采用gin开发时,一般接口文档有两种选择 : +- 在内部文档平台手搓文档, 并人工维护, 此方案最终演变方式大概率为文档主键滞后,与接口实现并不一致 +- 利用golang的文档生成工具[swag]() 自动生成swagger文档, 此种方案需要在代码中引入大量swag工具解析时需要的注释, 且当输入/输出发生变化时需要维护相关注释 +基于以上问题, 对gin的路由注册进行二次封装 + +## 二次封装解决哪些问题 + +- 文档维护的繁琐性 : 会通过反射自动基于 **`请求的数据结构 + 返回的数据结构`** , 生成接口文档, 专注于数据结构设计即可, 无需关注文档相关内容, 程序接管, 自动生成 +- 做接口设计的统一性规范约束, 如 : + - 入参数据类型不能为 any + - 入参类型不能为 map , 但是特定字段特定场景, 可以强行禁用此规则等 + - 返回值必须为结构体等 + +## 设计方案 + +###【可选】路由组定义 + +路由组可以通过函数进行定义, 函数名必须需为 : **`RouterPrefix`** , 函数无任何参数, 返回路由组名称, 示例 : + +```go +type TestController struct{} + +func (t *TestController) RouterPrefix() string { + return "/uri/prefix" +} +``` + +###【可选】路由组中间件定义 + +路由组中间件可以通过函数进行定义, 函数名必须需为 : **`RouterMiddleware`** , 函数无任何参数, 返回路由组中间件列表 **`[]gin.HandlerFunc`**, 示例 : + +```go +type TestController struct{} + +func (t *TestController) RouterPrefix() string { + return "/uri/prefix" +} + +func (t *TestController) RouterMiddleware() []gin.HandlerFunc { + return []gin.HandlerFunc{ + func(ctx *gin.Context) { + + }, + } +} +``` + +### 接口逻辑处理定义 + +接口逻辑处理函数, 函数名称自定义, 必须是个 **`可导出函数`** , 函数接收两个参数, 分别是 : + +- *gin.Context : gin框架的上下文信息 +- any: 表单参数 **结构体指针** , 注意 : 类型必须为结构体指针 + +函数返回值有两个 : +- any : 返回的业务数据, 必须是个 **`结构体指针`** +- error : 可以是内置的 **error** , 也可以是 **exception.IException** , 建议使用 exception.IException , 可承载更多的异常信息 + +## 使用方式 + +```go +type TestController struct{} + +func (t *TestController) RouterPrefix() string { + return "/uri/prefix" +} + +func (t *TestController) RouterMiddleware() []gin.HandlerFunc { + return []gin.HandlerFunc{ + func(ctx *gin.Context) { + + }, + } +} +func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) { + return formData, nil +} + +type TestForm struct { + Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` + Age int `json:"age" form:"age"` + Name string `json:"name" form:"name"` + Test *Test `json:"test" form:"test"` + Num *int64 `json:"num" form:"num"` +} +type Test struct { + L string `json:"l"` +} + +func Test_parseController(t *testing.T) { + type args struct { + controller any + } + Register(8080, &TestController{}) +} +``` + +注意事项: + +- Register 方法第一个入参是监听的端口 +- 后面若干个controller实例, 朱一必须以指针的方式传入 \ No newline at end of file diff --git a/router/register.go b/router/register.go index aec336c..2f3ca60 100644 --- a/router/register.go +++ b/router/register.go @@ -130,6 +130,12 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, FormDataType: methodType.In(2).Elem(), } + // 校验 FormDataType + for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ { + if uriConfig.FormDataType.Field(fieldIdx).Type.Kind() == reflect.Interface { + panic("request param set type `interface` is not allowed") + } + } return uriConfig, nil } diff --git a/router/register_test.go b/router/register_test.go index b021fe5..4abc609 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -34,9 +34,11 @@ type TestForm struct { Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` Age int `json:"age" form:"age"` Name string `json:"name" form:"name"` - Test struct { - L string `json:"l"` - } `json:"test" form:"test"` + Test *Test `json:"test" form:"test"` + Num *int64 `json:"num" form:"num"` +} +type Test struct { + L string `json:"l"` } func Test_parseController(t *testing.T) { -- 2.36.6 From 60ef099fdf68c999a72058dbcc64547b7685d000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 22 Jul 2024 14:33:21 +0800 Subject: [PATCH 10/20] update readme --- router/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/router/README.md b/router/README.md index 6b92c72..6ef8a2b 100644 --- a/router/README.md +++ b/router/README.md @@ -22,7 +22,7 @@ ## 设计方案 -###【可选】路由组定义 +### 【可选】路由组定义 路由组可以通过函数进行定义, 函数名必须需为 : **`RouterPrefix`** , 函数无任何参数, 返回路由组名称, 示例 : @@ -34,7 +34,7 @@ func (t *TestController) RouterPrefix() string { } ``` -###【可选】路由组中间件定义 +### 【可选】路由组中间件定义 路由组中间件可以通过函数进行定义, 函数名必须需为 : **`RouterMiddleware`** , 函数无任何参数, 返回路由组中间件列表 **`[]gin.HandlerFunc`**, 示例 : -- 2.36.6 From fce6043dca200a963d8ae9ad1ee5638e81ef8771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 11 Aug 2024 17:39:03 +0800 Subject: [PATCH 11/20] update go mod --- go.mod | 20 ++++++++++---------- go.sum | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index ad25b7d..fe2bc5d 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8 git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 - git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 + git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd github.com/gin-gonic/gin v1.10.0 github.com/go-playground/validator/v10 v10.22.0 go.uber.org/zap v1.27.0 @@ -24,12 +24,12 @@ require ( git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect - github.com/bytedance/sonic v1.11.9 // indirect - github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/bytedance/sonic v1.12.1 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect - github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-playground/locales v0.14.1 // indirect @@ -50,17 +50,17 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/gjson v1.17.3 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/arch v0.9.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index e7cdf84..3b641f9 100644 --- a/go.sum +++ b/go.sum @@ -20,14 +20,20 @@ git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 h1:P2k git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2/go.mod h1:7KaMpQmWgiNLpEkaV7oDtep7geI1f/VoCoPVcyvMjAE= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 h1:olo34i2Gq5gX7bYPv5TR4X5l5CrYFtu9UCElkYlmL2c= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd h1:zcmfmp/1srHldFpa7BCH6Cpp9iVNFM/7W7DoxHp48UU= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/bytedance/sonic v1.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5zg= github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24= +github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= @@ -35,10 +41,13 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= @@ -111,6 +120,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= +github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -129,16 +140,26 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k= +golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -- 2.36.6 From c420abfed91b12c016beb38076095fbacfd984c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 14 Aug 2024 14:12:37 +0800 Subject: [PATCH 12/20] update go mod --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fe2bc5d..487f267 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8 git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 - git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd + git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b github.com/gin-gonic/gin v1.10.0 github.com/go-playground/validator/v10 v10.22.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index 3b641f9..c5d0dd1 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 h1:olo34 git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd h1:zcmfmp/1srHldFpa7BCH6Cpp9iVNFM/7W7DoxHp48UU= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b h1:CcO2t7ssBSZwE7BDTOkCSgOvTGATarOZ0tajZ00McEc= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= -- 2.36.6 From e40475cdb1b4632dba1215d7ab595ce55923e4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 26 Jan 2025 14:34:24 +0800 Subject: [PATCH 13/20] update go mod --- go.mod | 16 ++++++++-------- go.sum | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 840fffc..0a489ab 100644 --- a/go.mod +++ b/go.mod @@ -23,20 +23,20 @@ require ( git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect - git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 // indirect + git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect - github.com/bytedance/sonic v1.12.5 // indirect - github.com/bytedance/sonic/loader v0.2.1 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect + github.com/bytedance/sonic v1.12.7 // indirect + github.com/bytedance/sonic/loader v0.2.3 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/sse v1.0.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect @@ -58,12 +58,12 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.12.0 // indirect + golang.org/x/arch v0.13.0 // indirect golang.org/x/crypto v0.32.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - google.golang.org/protobuf v1.35.2 // indirect + google.golang.org/protobuf v1.36.4 // indirect gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0b25bc8..785a4d8 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6Cc git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI= git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 h1:P2kuhU2TFWk9mPbJlZCK6FMDVS7S3NGafWKD4eNqKiI= git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2/go.mod h1:7KaMpQmWgiNLpEkaV7oDtep7geI1f/VoCoPVcyvMjAE= +git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e h1:YE2Gi+M03UDImIpWa3I7jzSesyfu2RL8x/4ONs5v0oE= +git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e/go.mod h1:L/7JugxKZL3JP9JP/XDvPAPz0FQXG1u181Su1+u/d1c= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9 h1:yF770WIDNwyiKL0nwmBGmjZvNCLXtHQL4xJyffPjTMU= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9/go.mod h1:I76wxEsWq7KnMQ84elpwTjEqq4I49QFw60tp5h7iGBs= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= @@ -26,22 +28,31 @@ github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+I github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w= github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q= +github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0= +github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= @@ -56,6 +67,8 @@ github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -115,13 +128,17 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -141,6 +158,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg= golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA= +golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= @@ -154,6 +173,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -- 2.36.6 From 851de1b3ef8d726df3caccfb8f5df1bfe2b22aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 27 Jan 2025 15:07:58 +0800 Subject: [PATCH 14/20] save code --- router/meta.go | 6 +++++- router/register.go | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/router/meta.go b/router/meta.go index 93d9204..b821f86 100644 --- a/router/meta.go +++ b/router/meta.go @@ -7,7 +7,11 @@ // Date : 2024-07-20 21:40 package router -// Meta 接口的元信息 +// Meta 接口的元信息, 主要包含如下信息: +// +// uri: 接口路由(不包含group前缀) +// +// method: 请求方法: get/post 等 // // Author : go_developer@163.com<白茶清欢> // diff --git a/router/register.go b/router/register.go index 2f3ca60..5cce58f 100644 --- a/router/register.go +++ b/router/register.go @@ -163,10 +163,10 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList } err := errData.Interface() if e, ok := err.(exception.IException); ok { - response.SendWithException(ctx, e, businessData) + response.SendWithException(ctx, e, map[string]any{"business_data": businessData}) return } else { - response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), businessData) + response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), map[string]any{"business_data": businessData}) return } } -- 2.36.6 From b408076fa716a67820d588ac681de80b347b5776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 27 Jan 2025 19:46:34 +0800 Subject: [PATCH 15/20] =?UTF-8?q?=E4=BF=9D=E5=AD=98=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=B3=A8=E5=86=8C=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/controller.go | 125 +++++++++++++++++++++++++++++++++++++++++++ router/define.go | 29 +++++++--- router/group.go | 37 +++++++++++++ router/handler.go | 21 ++++++++ router/register.go | 2 +- 5 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 router/controller.go create mode 100644 router/group.go create mode 100644 router/handler.go diff --git a/router/controller.go b/router/controller.go new file mode 100644 index 0000000..fd3e558 --- /dev/null +++ b/router/controller.go @@ -0,0 +1,125 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2025-01-27 15:29 +package router + +import ( + "reflect" + "strings" +) + +// controller 解析controller有哪些方法要注册为接口 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:30 2025/1/27 +type controller struct { +} + +// Parse 执行解析 +// +// 符合注册为借口的方法具有如下特征: +// +// 1. 函数接受两个入参, 第一个参数为 gin.Context , 第二个参数为 任意结构体指针, 但是必须声明 Meta 相关信息, 否则会报错 +// +// 2. 函数有两个返回值, 第一个返回值为任意结构体/结构体指针(限制死不能为map/slice, 方便后续统一标准化) , 第二个返回值为 error , 代表处理的异常, 会自动适配 exception.IException 类型 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:31 2025/1/27 +func (c controller) Parse(inputController any) map[string]UriConfig { + parseRes := make(map[string]UriConfig) + if nil == inputController { + return parseRes + } + controllerType := reflect.TypeOf(inputController) + controllerValue := reflect.ValueOf(inputController) + if controllerType.Kind() == reflect.Func { + // 直接函数注册 + cfg, isNeedRegister := c.methodConfig(controllerType) + if isNeedRegister { + parseRes[cfg.Path] = cfg + } + return parseRes + } + if controllerType.Kind() == reflect.Ptr { + controllerValue = controllerValue.Elem() + } + if controllerValue.IsNil() { + return parseRes + } + for methodIdx := 0; methodIdx < controllerType.NumMethod(); methodIdx++ { + uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx).Type) + if !needRegister { + continue + } + parseRes[uriCfg.Path] = uriCfg + } + return parseRes +} + +// methodConfig 解析方法配置, 要求函数格式, 两个参数, 两个返回值, 格式 : func(ctx *gin.Context, formData anyStruct[组合Meta]) (anyStruct|map[response], error) +// +// 参数 : 方法反射结果 +// +// 返回值 : 第一个 -> 解析出的接口配置 第二个 -> 是否要注册为接口 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 16:05 2025/1/27 +func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRegister bool) { + // num0: 函数声明 + // num1: 第一个参数 + // num2: 第二个参数 + if methodType.NumIn() != 3 { + needRegister = false + return + } + // 第一个参数必须是 *gin.Context + if methodType.In(1).String() != "*gin.Context" { + needRegister = false + return + } + // 解析第二个参数是组合Meta的form表单 + formType := methodType.In(2) + if formType.Kind() == reflect.Ptr { + formType = methodType.In(2).Elem() + } + metaField, metaFieldExist := formType.FieldByName(FieldNameMeta) + if !metaFieldExist { + needRegister = false + return + } + // 解析第一个返回值, 要求必须是结构体或者是map + if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { + needRegister = false + return + } + if methodType.Out(1).Kind().String() != "error" { + // 判断是否是实现 error接口的方法 + outputErrParse := false + for j := 0; j < methodType.Out(1).NumMethod(); j++ { + if methodType.Out(1).Method(j).Name == "Error" && // 实现Error方法 + methodType.Out(1).Method(j).Type.NumIn() == 1 && // 没有任何参数 + methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值 + methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() { + outputErrParse = true + break + } + } + if !outputErrParse { + needRegister = false + } + return + } + // 解析meta信息 + cfg.Path = metaField.Tag.Get(TagNamePath) + cfg.Method = metaField.Tag.Get(TagNameMethod) + cfg.Desc = metaField.Tag.Get(TagNameDesc) + cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",") + return +} diff --git a/router/define.go b/router/define.go index a761be7..4e4b7bd 100644 --- a/router/define.go +++ b/router/define.go @@ -28,10 +28,27 @@ const ( // // Date : 15:41 2024/7/21 type UriConfig struct { - Path string `json:"path"` // 接口路由, 必须配置 - Method string `json:"method"` // 接口请求方法, 必须配置 - TagList []string `json:"tag_list"` // 接口分组 - Desc string `json:"desc"` // 接口描述 - Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY - FormDataType reflect.Type `json:"-"` // 表单数据类型 + Path string `json:"path"` // 接口路由, 必须配置 + Method string `json:"method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + ParamTable map[string]UriParam `json:"param_table"` // 参数信息表 + FormDataType reflect.Type `json:"-"` // 表单数据类型 } + +// UriParam 接口参数配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:40 2025/1/27 +type UriParam struct { + Name string `json:"name"` // 参数名称 + Type string `json:"type"` // 参数类型 + DisableAutoType bool `json:"disable_auto_type"` // 禁用自动类型转换 + Sort string `json:"sort"` // 参数读取顺序: 默认 POST : body > query > path GET : query > path > body +} + +const ( + FieldNameMeta = "Meta" // 元信息字段 +) diff --git a/router/group.go b/router/group.go new file mode 100644 index 0000000..1455f5f --- /dev/null +++ b/router/group.go @@ -0,0 +1,37 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2025-01-27 19:33 +package router + +import ( + "github.com/gin-gonic/gin" + "net/http" + "strings" +) + +// Group 注册接口路由 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 19:35 2025/1/27 +func Group(router *gin.Engine, routerPrefix string, middlewareList []gin.HandlerFunc, cList ...any) error { + g := router.Group(routerPrefix) + g.Use(middlewareList...) + cParser := controller{} + for _, c := range cList { + urlTable := cParser.Parse(c) + for _, itemUriCfg := range urlTable { + method := strings.ToUpper(itemUriCfg.Method) + switch method { + case http.MethodGet: + g.HEAD(itemUriCfg.Path) + + } + } + } + return nil +} diff --git a/router/handler.go b/router/handler.go new file mode 100644 index 0000000..6ac773d --- /dev/null +++ b/router/handler.go @@ -0,0 +1,21 @@ +// Package router ... +// +// Description : router ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2025-01-27 19:42 +package router + +import "github.com/gin-gonic/gin" + +// RequestHandler 获取请求处理方法 TODO : 待完成 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 19:44 2025/1/27 +func RequestHandler(uriCfg UriConfig) gin.HandlerFunc { + return func(ctx *gin.Context) { + + } +} diff --git a/router/register.go b/router/register.go index 5cce58f..1ac03d3 100644 --- a/router/register.go +++ b/router/register.go @@ -118,7 +118,7 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e if formType.Kind() == reflect.Ptr { formType = methodType.In(2).Elem() } - metaField, metaFieldExist := formType.FieldByName("Meta") + metaField, metaFieldExist := formType.FieldByName(FieldNameMeta) if !metaFieldExist { return nil, nil } -- 2.36.6 From 196c437cc50074c06ecafe71e1de912e59ffe43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 7 Feb 2025 10:33:39 +0800 Subject: [PATCH 16/20] update go mod --- go.mod | 12 ++++++------ go.sum | 12 ++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0a489ab..03dc904 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect - github.com/bytedance/sonic v1.12.7 // indirect + github.com/bytedance/sonic v1.12.8 // indirect github.com/bytedance/sonic/loader v0.2.3 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/iasm v0.2.0 // indirect @@ -36,7 +36,7 @@ require ( github.com/go-ini/ini v1.67.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/goccy/go-json v0.10.4 // indirect + github.com/goccy/go-json v0.10.5 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect @@ -58,12 +58,12 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.13.0 // indirect + golang.org/x/arch v0.14.0 // indirect golang.org/x/crypto v0.32.0 // indirect golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - google.golang.org/protobuf v1.36.4 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 785a4d8..7efb8b6 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/ github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q= github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I= +github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs= +github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -69,6 +71,8 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -160,6 +164,8 @@ golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg= golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA= golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= +golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= @@ -167,14 +173,20 @@ golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -- 2.36.6 From 77ea723e8661155f476e4f43a12043f680031fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 7 Feb 2025 16:10:33 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E5=AE=8C=E5=96=84=20RequestHandler=20?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/controller.go | 25 +++++++++++++++++++++++++ router/define.go | 31 +++++++++++++++++++------------ router/group.go | 18 ++++++++++++++++-- router/handler.go | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 15 deletions(-) diff --git a/router/controller.go b/router/controller.go index fd3e558..bb2cd5b 100644 --- a/router/controller.go +++ b/router/controller.go @@ -94,6 +94,7 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe needRegister = false return } + // 解析第一个返回值, 要求必须是结构体或者是map if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { needRegister = false @@ -121,5 +122,29 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe cfg.Method = metaField.Tag.Get(TagNameMethod) cfg.Desc = metaField.Tag.Get(TagNameDesc) cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",") + // 解析参数配置 + cfg.ParamList = c.parseParamConfig(formType) return } + +// parseParamConfig 解析参数配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:35 2025/2/7 +func (c controller) parseParamConfig(formDataType reflect.Type) []UriParam { + res := make([]UriParam, 0) + for i := 0; i < formDataType.NumField(); i++ { + structField := formDataType.Field(i) + if structField.Name == FieldNameMeta { + // Meta 字段, 忽略 + continue + } + jsonTag := structField.Tag.Get("json") + if jsonTag == "" { + jsonTag = structField.Name + } + + } + return res +} diff --git a/router/define.go b/router/define.go index 4e4b7bd..76e3aae 100644 --- a/router/define.go +++ b/router/define.go @@ -15,11 +15,14 @@ const ( ) const ( - TagNamePath = "path" // 接口的请求路径 - TagNameMethod = "method" // 接口的请求方法 - TagNameUriTag = "tag" // 接口的tag - TagNameDesc = "desc" // 接口的描述 - TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + TagNamePath = "path" // 接口的请求路径 + TagNameMethod = "method" // 接口的请求方法 + TagNameUriTag = "tag" // 接口的tag + TagNameDesc = "desc" // 接口的描述 + TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + TagNameBinding = "binding" // gin 内置的验证规则tag + TagNameValidate = "validate" // validator v10 默认的验证规则tag + TagNameErrMsg = "err" // 验证失败错误信息tag ) // UriConfig 接口配置 @@ -28,13 +31,14 @@ const ( // // Date : 15:41 2024/7/21 type UriConfig struct { - Path string `json:"path"` // 接口路由, 必须配置 - Method string `json:"method"` // 接口请求方法, 必须配置 - TagList []string `json:"tag_list"` // 接口分组 - Desc string `json:"desc"` // 接口描述 - Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY - ParamTable map[string]UriParam `json:"param_table"` // 参数信息表 - FormDataType reflect.Type `json:"-"` // 表单数据类型 + Path string `json:"path"` // 接口路由, 必须配置 + Method string `json:"method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + ParamList []UriParam `json:"param_list"` // 参数信息表 + FormDataType reflect.Type `json:"-"` // 表单数据类型 + ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑 } // UriParam 接口参数配置 @@ -43,8 +47,11 @@ type UriConfig struct { // // Date : 15:40 2025/1/27 type UriParam struct { + Field string `json:"field"` // 结构体字段 Name string `json:"name"` // 参数名称 Type string `json:"type"` // 参数类型 + Validate string `json:"validate"` // 验证规则: validator/v10 库 + ErrorMsg string `json:"error_msg"` // 验证失败的错误信息 DisableAutoType bool `json:"disable_auto_type"` // 禁用自动类型转换 Sort string `json:"sort"` // 参数读取顺序: 默认 POST : body > query > path GET : query > path > body } diff --git a/router/group.go b/router/group.go index 1455f5f..d968676 100644 --- a/router/group.go +++ b/router/group.go @@ -8,6 +8,7 @@ package router import ( + "errors" "github.com/gin-gonic/gin" "net/http" "strings" @@ -28,8 +29,21 @@ func Group(router *gin.Engine, routerPrefix string, middlewareList []gin.Handler method := strings.ToUpper(itemUriCfg.Method) switch method { case http.MethodGet: - g.HEAD(itemUriCfg.Path) - + g.GET(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodHead: + g.HEAD(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodPost: + g.POST(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodPut: + g.PUT(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodPatch: + g.PATCH(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodDelete: + g.DELETE(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodOptions: + g.OPTIONS(itemUriCfg.Path, RequestHandler(itemUriCfg)) + case http.MethodTrace: + return errors.New(`method Trace is not supported`) } } } diff --git a/router/handler.go b/router/handler.go index 6ac773d..b7aa2a1 100644 --- a/router/handler.go +++ b/router/handler.go @@ -7,7 +7,13 @@ // Date : 2025-01-27 19:42 package router -import "github.com/gin-gonic/gin" +import ( + "git.zhangdeman.cn/zhangdeman/exception" + "git.zhangdeman.cn/zhangdeman/gin/request" + "git.zhangdeman.cn/zhangdeman/gin/response" + "github.com/gin-gonic/gin" + "reflect" +) // RequestHandler 获取请求处理方法 TODO : 待完成 // @@ -16,6 +22,38 @@ import "github.com/gin-gonic/gin" // Date : 19:44 2025/1/27 func RequestHandler(uriCfg UriConfig) gin.HandlerFunc { return func(ctx *gin.Context) { + var ( + err error + ok bool + e exception.IException + ) + formData := reflect.New(uriCfg.FormDataType).Interface() + // 表单解析 + if err = request.Form.Parse(ctx, formData); nil != err { + return + } + // 执行逻辑 + resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(formData)}) + if resList[1].IsNil() { + // 请求成功 + response.Success(ctx, resList[0].Interface()) + return + } + // 请求失败 + if e, ok = resList[1].Interface().(exception.IException); ok { + response.SendWithException(ctx, e, nil) + return + } + if err, ok = resList[1].Interface().(error); ok { + e = exception.NewFromError(-1, err) + response.SendWithException(ctx, e, nil) + return + } + e = exception.NewWithCodeAndData(-1, map[string]any{ + "err": resList[1].Interface(), + }) + response.SendWithException(ctx, e, nil) + return } } -- 2.36.6 From e95061a1a8f36a47c93687887f94d45de3531f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 7 Feb 2025 16:57:15 +0800 Subject: [PATCH 18/20] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E5=8F=8D=E5=B0=84=E8=B0=83=E7=94=A8=E6=8E=A5=E5=8F=A3=20+=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/controller.go | 29 ++++++++++++++++++----------- router/define.go | 17 +++++++++-------- router/group.go | 2 +- router/handler.go | 4 +++- router/register.go | 16 ++++++++-------- router/register_test.go | 22 +++++----------------- 6 files changed, 44 insertions(+), 46 deletions(-) diff --git a/router/controller.go b/router/controller.go index bb2cd5b..ce96bbb 100644 --- a/router/controller.go +++ b/router/controller.go @@ -8,6 +8,7 @@ package router import ( + "fmt" "reflect" "strings" ) @@ -38,25 +39,26 @@ func (c controller) Parse(inputController any) map[string]UriConfig { } controllerType := reflect.TypeOf(inputController) controllerValue := reflect.ValueOf(inputController) - if controllerType.Kind() == reflect.Func { + /*if controllerType.Kind() == reflect.Func { // 直接函数注册 cfg, isNeedRegister := c.methodConfig(controllerType) if isNeedRegister { parseRes[cfg.Path] = cfg } return parseRes - } + }*/ if controllerType.Kind() == reflect.Ptr { controllerValue = controllerValue.Elem() } - if controllerValue.IsNil() { + /*if controllerValue.IsNil() { return parseRes - } + }*/ for methodIdx := 0; methodIdx < controllerType.NumMethod(); methodIdx++ { - uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx).Type) + uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx)) if !needRegister { continue } + uriCfg.ApiStructValue = controllerValue parseRes[uriCfg.Path] = uriCfg } return parseRes @@ -71,7 +73,8 @@ func (c controller) Parse(inputController any) map[string]UriConfig { // Author : go_developer@163.com<白茶清欢> // // Date : 16:05 2025/1/27 -func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRegister bool) { +func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, needRegister bool) { + methodType := reflectMethod.Type // num0: 函数声明 // num1: 第一个参数 // num2: 第二个参数 @@ -89,6 +92,7 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe if formType.Kind() == reflect.Ptr { formType = methodType.In(2).Elem() } + cfg.FormDataType = formType metaField, metaFieldExist := formType.FieldByName(FieldNameMeta) if !metaFieldExist { needRegister = false @@ -96,34 +100,37 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe } // 解析第一个返回值, 要求必须是结构体或者是map - if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { + /*if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { needRegister = false return - } + }*/ if methodType.Out(1).Kind().String() != "error" { // 判断是否是实现 error接口的方法 outputErrParse := false for j := 0; j < methodType.Out(1).NumMethod(); j++ { if methodType.Out(1).Method(j).Name == "Error" && // 实现Error方法 - methodType.Out(1).Method(j).Type.NumIn() == 1 && // 没有任何参数 + methodType.Out(1).Method(j).Type.NumIn() == 0 && // 没有任何参数 methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值 methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() { outputErrParse = true break } + fmt.Println(methodType.Out(1).Method(j).Name, methodType.Out(1).Method(j).Type.NumIn(), methodType.Out(1).Method(j).Type.NumOut(), methodType.Out(1).Method(j).Type.Out(0).Kind().String()) } if !outputErrParse { needRegister = false + return } - return } // 解析meta信息 cfg.Path = metaField.Tag.Get(TagNamePath) - cfg.Method = metaField.Tag.Get(TagNameMethod) + cfg.RequestMethod = metaField.Tag.Get(TagNameMethod) cfg.Desc = metaField.Tag.Get(TagNameDesc) cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",") // 解析参数配置 cfg.ParamList = c.parseParamConfig(formType) + cfg.ApiLogicFunc = reflectMethod + needRegister = true return } diff --git a/router/define.go b/router/define.go index 76e3aae..74f1add 100644 --- a/router/define.go +++ b/router/define.go @@ -31,14 +31,15 @@ const ( // // Date : 15:41 2024/7/21 type UriConfig struct { - Path string `json:"path"` // 接口路由, 必须配置 - Method string `json:"method"` // 接口请求方法, 必须配置 - TagList []string `json:"tag_list"` // 接口分组 - Desc string `json:"desc"` // 接口描述 - Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY - ParamList []UriParam `json:"param_list"` // 参数信息表 - FormDataType reflect.Type `json:"-"` // 表单数据类型 - ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑 + Path string `json:"path"` // 接口路由, 必须配置 + RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + ParamList []UriParam `json:"param_list"` // 参数信息表 + FormDataType reflect.Type `json:"-"` // 表单数据类型 + ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值 + ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑 } // UriParam 接口参数配置 diff --git a/router/group.go b/router/group.go index d968676..1b39b67 100644 --- a/router/group.go +++ b/router/group.go @@ -26,7 +26,7 @@ func Group(router *gin.Engine, routerPrefix string, middlewareList []gin.Handler for _, c := range cList { urlTable := cParser.Parse(c) for _, itemUriCfg := range urlTable { - method := strings.ToUpper(itemUriCfg.Method) + method := strings.ToUpper(itemUriCfg.RequestMethod) switch method { case http.MethodGet: g.GET(itemUriCfg.Path, RequestHandler(itemUriCfg)) diff --git a/router/handler.go b/router/handler.go index b7aa2a1..bfd2a0c 100644 --- a/router/handler.go +++ b/router/handler.go @@ -31,10 +31,12 @@ func RequestHandler(uriCfg UriConfig) gin.HandlerFunc { formData := reflect.New(uriCfg.FormDataType).Interface() // 表单解析 if err = request.Form.Parse(ctx, formData); nil != err { + e = exception.NewFromError(400, err) + response.SendWithException(ctx, e, nil) return } // 执行逻辑 - resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(formData)}) + resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, reflect.ValueOf(ctx), reflect.ValueOf(formData)}) if resList[1].IsNil() { // 请求成功 response.Success(ctx, resList[0].Interface()) diff --git a/router/register.go b/router/register.go index 1ac03d3..d49844e 100644 --- a/router/register.go +++ b/router/register.go @@ -123,12 +123,12 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e return nil, nil } uriConfig := &UriConfig{ - Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), - Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), - TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), - Desc: metaField.Tag.Get(TagNameDesc), - Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, - FormDataType: methodType.In(2).Elem(), + Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), + RequestMethod: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), + TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), + Desc: metaField.Tag.Get(TagNameDesc), + Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, + FormDataType: methodType.In(2).Elem(), } // 校验 FormDataType for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ { @@ -174,7 +174,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList middlewareList = append([]gin.HandlerFunc{ middleware.InitRequest(), }, middlewareList...) - switch uriConfig.Method { + switch uriConfig.RequestMethod { case http.MethodGet: ginRouter.GET(uriConfig.Path, middlewareList...) case http.MethodHead: @@ -196,7 +196,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList case "ANY": ginRouter.Any(uriConfig.Path, middlewareList...) default: - panic(uriConfig.Path + " : " + uriConfig.Method + " is not support") + panic(uriConfig.Path + " : " + uriConfig.RequestMethod + " is not support") } } diff --git a/router/register_test.go b/router/register_test.go index 4abc609..82a308f 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -15,24 +15,13 @@ import ( type TestController struct{} -func (t *TestController) RouterPrefix() string { - return "/uri/prefix" -} - -func (t *TestController) RouterMiddleware() []gin.HandlerFunc { - return []gin.HandlerFunc{ - func(ctx *gin.Context) { - - }, - } -} -func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) { +func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) { return formData, nil } type TestForm struct { Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` - Age int `json:"age" form:"age"` + Age int `json:"age" form:"age" binding:"min=20"` Name string `json:"name" form:"name"` Test *Test `json:"test" form:"test"` Num *int64 `json:"num" form:"num"` @@ -42,8 +31,7 @@ type Test struct { } func Test_parseController(t *testing.T) { - type args struct { - controller any - } - Register(8080, &TestController{}) + r := gin.Default() + Group(r, "test", nil, TestController{}) + r.Run(":8080") } -- 2.36.6 From 1b1964881fa38b0ebbe146093598e0bdbc5b2ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 7 Feb 2025 17:19:25 +0800 Subject: [PATCH 19/20] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=AF=E5=90=A6=E4=B8=A5=E6=A0=BC=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E6=A0=A1=E9=AA=8C,=20=E4=B8=A5=E6=A0=BC?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B,=20=E5=BF=85=E9=A1=BB=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=BB=93=E6=9E=84=E4=BD=93=E6=88=96=E8=80=85map?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- go.sum | 4 ++++ router/controller.go | 23 ++++++++++++++--------- router/define.go | 25 ++++++++++++++----------- router/handler.go | 2 +- router/register.go | 2 +- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 03dc904..978c27b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.1 require ( git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00 - git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465 + git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd diff --git a/go.sum b/go.sum index 7efb8b6..2c36799 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,10 @@ git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ= git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465 h1:j5EB0hamTMT5fY+xmjJ51oBvll+vS2inNPi+3/UBj60= git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091353-907c20662792 h1:BehqU7W+FF39xCcrbrlPBggbKVTIguDDXfABn8l5RB4= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091353-907c20662792/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 h1:XsjGMkBCi93h56oCg5Lrz5zVpUxify/CQVhQU9+qLWM= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw= git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad h1:6BI3QiDI64SlER1006UJbTJyOCXxB8KCmCK+Kr7FzQo= git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad/go.mod h1:+jPQTyCEQqMWhq4p1LowQWq15emisON+++87ArTgwNA= git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 h1:1eBf0C0gdpBQOqjTK3UCw/mwzQ/SCodx3iTQtidx9eE= diff --git a/router/controller.go b/router/controller.go index ce96bbb..b9d83c0 100644 --- a/router/controller.go +++ b/router/controller.go @@ -8,7 +8,6 @@ package router import ( - "fmt" "reflect" "strings" ) @@ -83,7 +82,7 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n return } // 第一个参数必须是 *gin.Context - if methodType.In(1).String() != "*gin.Context" { + if methodType.In(1).String() != GinContextType { needRegister = false return } @@ -100,22 +99,28 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n } // 解析第一个返回值, 要求必须是结构体或者是map - /*if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { - needRegister = false - return - }*/ - if methodType.Out(1).Kind().String() != "error" { + outputStrictModel := metaField.Tag.Get(TagNameOutputStrict) + // 输出是否严格模式 + cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true" + if cfg.OutputStrict { + // 开启输出严格模式校验 + if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { + needRegister = false + return + } + } + + if methodType.Out(1).Kind().String() != ErrorType { // 判断是否是实现 error接口的方法 outputErrParse := false for j := 0; j < methodType.Out(1).NumMethod(); j++ { - if methodType.Out(1).Method(j).Name == "Error" && // 实现Error方法 + if methodType.Out(1).Method(j).Name == ErrorInterfaceFuncName && // 实现Error方法 methodType.Out(1).Method(j).Type.NumIn() == 0 && // 没有任何参数 methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值 methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() { outputErrParse = true break } - fmt.Println(methodType.Out(1).Method(j).Name, methodType.Out(1).Method(j).Type.NumIn(), methodType.Out(1).Method(j).Type.NumOut(), methodType.Out(1).Method(j).Type.Out(0).Kind().String()) } if !outputErrParse { needRegister = false diff --git a/router/define.go b/router/define.go index 74f1add..4632d9d 100644 --- a/router/define.go +++ b/router/define.go @@ -10,19 +10,22 @@ package router import "reflect" const ( - PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 - MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 + PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 + MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 + GinContextType = "*gin.Context" // gin context 类型名称 + ErrorType = "error" // error类型 + ErrorInterfaceFuncName = "Error" // error接口需要实现的方法名称 ) const ( - TagNamePath = "path" // 接口的请求路径 - TagNameMethod = "method" // 接口的请求方法 - TagNameUriTag = "tag" // 接口的tag - TagNameDesc = "desc" // 接口的描述 - TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY - TagNameBinding = "binding" // gin 内置的验证规则tag - TagNameValidate = "validate" // validator v10 默认的验证规则tag - TagNameErrMsg = "err" // 验证失败错误信息tag + TagNamePath = "path" // 接口的请求路径 + TagNameMethod = "method" // 接口的请求方法 + TagNameUriTag = "tag" // 接口的tag + TagNameDesc = "desc" // 接口的描述 + TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值 + TagNameBinding = "binding" // gin 内置的验证规则tag + TagNameValidate = "validate" // validator v10 默认的验证规则tag + TagNameErrMsg = "err" // 验证失败错误信息tag ) // UriConfig 接口配置 @@ -35,7 +38,7 @@ type UriConfig struct { RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置 TagList []string `json:"tag_list"` // 接口分组 Desc string `json:"desc"` // 接口描述 - Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY + OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map ParamList []UriParam `json:"param_list"` // 参数信息表 FormDataType reflect.Type `json:"-"` // 表单数据类型 ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值 diff --git a/router/handler.go b/router/handler.go index bfd2a0c..e76a410 100644 --- a/router/handler.go +++ b/router/handler.go @@ -15,7 +15,7 @@ import ( "reflect" ) -// RequestHandler 获取请求处理方法 TODO : 待完成 +// RequestHandler 获取请求处理方法 // // Author : go_developer@163.com<白茶清欢> // diff --git a/router/register.go b/router/register.go index d49844e..d5bb1ba 100644 --- a/router/register.go +++ b/router/register.go @@ -127,7 +127,7 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e RequestMethod: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), Desc: metaField.Tag.Get(TagNameDesc), - Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, + OutputStrict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameOutputStrict))) >= 0, FormDataType: methodType.In(2).Elem(), } // 校验 FormDataType -- 2.36.6 From cb4718a2698ecb1f5790e69acdb9659bcfa3f672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 7 Feb 2025 17:25:25 +0800 Subject: [PATCH 20/20] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=E4=B8=A5=E6=A0=BC?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=97=B6,=20=E6=A0=A1=E9=AA=8C=E4=B8=8D?= =?UTF-8?q?=E9=80=9A=E8=BF=87,=20=E7=94=B1=E5=BF=BD=E7=95=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=B3=A8=E5=86=8C=E4=BF=AE=E6=94=B9=E4=B8=BApanic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/controller.go | 22 ++++++++++------------ router/register_test.go | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/router/controller.go b/router/controller.go index b9d83c0..8c6f5da 100644 --- a/router/controller.go +++ b/router/controller.go @@ -98,18 +98,6 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n return } - // 解析第一个返回值, 要求必须是结构体或者是map - outputStrictModel := metaField.Tag.Get(TagNameOutputStrict) - // 输出是否严格模式 - cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true" - if cfg.OutputStrict { - // 开启输出严格模式校验 - if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { - needRegister = false - return - } - } - if methodType.Out(1).Kind().String() != ErrorType { // 判断是否是实现 error接口的方法 outputErrParse := false @@ -132,6 +120,16 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n cfg.RequestMethod = metaField.Tag.Get(TagNameMethod) cfg.Desc = metaField.Tag.Get(TagNameDesc) cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",") + // 解析第一个返回值, 要求必须是结构体或者是map + outputStrictModel := metaField.Tag.Get(TagNameOutputStrict) + cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true" + if cfg.OutputStrict { + // 开启输出严格模式校验 + if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map { + panic(cfg.Path + " : 接口配置输出严格校验, 输出数据类型必须为 struct 或 *struct 或 map, 实际返回数据类型 : " + methodType.Out(0).Kind().String()) + return + } + } // 解析参数配置 cfg.ParamList = c.parseParamConfig(formType) cfg.ApiLogicFunc = reflectMethod diff --git a/router/register_test.go b/router/register_test.go index 82a308f..b19a439 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -20,7 +20,7 @@ func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) } type TestForm struct { - Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` + Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get"` Age int `json:"age" form:"age" binding:"min=20"` Name string `json:"name" form:"name"` Test *Test `json:"test" form:"test"` -- 2.36.6