From ab78127317994c6ddfc8f1d97fe490383c5e1d11 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, 10 Mar 2025 14:44:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5=20GinWrapperContext,=20gatew?= =?UTF-8?q?ay=E5=BE=85=E5=8D=87=E7=BA=A7=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/request.go | 12 ++++++++++++ request/context.go | 2 +- request/wrapper.go | 18 ++++++++++++++++++ router/controller.go | 5 ++++- router/define.go | 20 +++++++++++--------- router/handler.go | 9 ++++++++- router/register.go | 5 +++-- router/register_test.go | 5 ++--- 8 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 define/request.go diff --git a/define/request.go b/define/request.go new file mode 100644 index 0000000..a1a7c06 --- /dev/null +++ b/define/request.go @@ -0,0 +1,12 @@ +// Package define ... +// +// Description : define ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2025-03-10 14:38 +package define + +const ( + GinWrapperContextKey = "GIN_WRAPPER_CONTEXT" +) diff --git a/request/context.go b/request/context.go index 018b83b..bbab282 100644 --- a/request/context.go +++ b/request/context.go @@ -67,7 +67,7 @@ func NewContext(ginContext *gin.Context) *Context { return &Context{ Context: ginContext, StartRequestTime: time.Now(), - FinishRequestTime: time.Time(int64(0)), + FinishRequestTime: time.Unix(0, 0), HandlerAfterResponse: make([]gin.HandlerFunc, 0), customData: make(map[string]any), Hostname: hostname, diff --git a/request/wrapper.go b/request/wrapper.go index 0e1d09d..7c6f18d 100644 --- a/request/wrapper.go +++ b/request/wrapper.go @@ -326,3 +326,21 @@ func (wh *wrapperHandle) GetLogicAfterResponse(ctx *gin.Context) *define.LogicAf // 就这么写, key值如果被其他人覆盖成非法值, 此处会直接panic return l.(*define.LogicAfterResponse) } + +// GetGinWrapperContext 获取包装之后context +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:41 2025/3/10 +func (wh *wrapperHandle) GetGinWrapperContext(ctx *gin.Context) *Context { + if nil == ctx { + return nil + } + if val, exist := ctx.Get(define.GinWrapperContextKey); !exist || nil == val { + newCtx := NewContext(ctx) + newCtx.SetCustom(define.GinWrapperContextKey, newCtx) + return newCtx + } else { + return val.(*Context) + } +} diff --git a/router/controller.go b/router/controller.go index c352744..9b3249d 100644 --- a/router/controller.go +++ b/router/controller.go @@ -70,7 +70,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n return } // 第一个参数必须是 *gin.Context - if methodType.In(1).String() != GinContextType { + firstParamStr := methodType.In(1).String() + if firstParamStr != GinContextType && firstParamStr != GinWrapperContextType { needRegister = false return } @@ -105,6 +106,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n return } } + // 是否gin包装后的context + cfg.IsGinWrapperContext = firstParamStr == GinWrapperContextType // 解析meta信息 cfg.Path = metaField.Tag.Get(TagNamePath) cfg.RequestMethod = metaField.Tag.Get(TagNameMethod) diff --git a/router/define.go b/router/define.go index bc49eb7..ca125f4 100644 --- a/router/define.go +++ b/router/define.go @@ -15,6 +15,7 @@ const ( PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 GinContextType = "*gin.Context" // gin context 类型名称 + GinWrapperContextType = "*request.Context" // gin context 类型名称 ErrorType = "error" // error类型 ErrorInterfaceFuncName = "Error" // error接口需要实现的方法名称 ) @@ -36,15 +37,16 @@ const ( // // Date : 15:41 2024/7/21 type UriConfig struct { - Path string `json:"path"` // 接口路由, 必须配置 - RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置 - TagList []string `json:"tag_list"` // 接口分组 - Desc string `json:"desc"` // 接口描述 - OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map - FormDataType reflect.Type `json:"-"` // 表单数据类型 - ResultDataType reflect.Type `json:"-"` // 返回值数据类型 - ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值 - ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑 + Path string `json:"path"` // 接口路由, 必须配置 + RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置 + TagList []string `json:"tag_list"` // 接口分组 + Desc string `json:"desc"` // 接口描述 + OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map + FormDataType reflect.Type `json:"-"` // 表单数据类型 + ResultDataType reflect.Type `json:"-"` // 返回值数据类型 + ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值 + ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑 + IsGinWrapperContext bool `json:"is_gin_wrapper_context"` // 是否gin包装后的context } // UriParam 接口参数配置 diff --git a/router/handler.go b/router/handler.go index f0a28dc..09a528a 100644 --- a/router/handler.go +++ b/router/handler.go @@ -79,7 +79,14 @@ func RequestHandler(uriCfg UriConfig) gin.HandlerFunc { if uriCfg.FormDataType.Kind() != reflect.Ptr { inputValue = inputValue.Elem() } - resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, reflect.ValueOf(ctx), inputValue}) + ginWrapperContext := request.NewContext(ctx) + // wrapper context 设置到 gin context + ginWrapperContext.Set(define.GinWrapperContextKey, ginWrapperContext) + ctxReflect := reflect.ValueOf(ctx) + if uriCfg.IsGinWrapperContext { + ctxReflect = reflect.ValueOf(ginWrapperContext) + } + resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, ctxReflect, inputValue}) if resList[1].IsNil() { // 请求成功 isSuccess = true diff --git a/router/register.go b/router/register.go index 515d63a..69e7cf2 100644 --- a/router/register.go +++ b/router/register.go @@ -109,8 +109,9 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e } // 接口logic共计两个参数. 两个返回值, 格式 : func(ctx *gin.Context, formData any[组合Meta]) (any[response], error) - // 解析第一个参数是 *gin.Context - if methodType.In(1).String() != "*gin.Context" { + // 解析第一个参数是 *gin.Context / 或者包装后的 request.Context + firstParamStr := methodType.In(1).String() + if firstParamStr != "*gin.Context" && firstParamStr != "*request.Context" { return nil, nil } // 解析第二个参数是组合Meta的form表单 diff --git a/router/register_test.go b/router/register_test.go index ca43da2..3aa9f74 100644 --- a/router/register_test.go +++ b/router/register_test.go @@ -8,14 +8,13 @@ package router import ( + "git.zhangdeman.cn/zhangdeman/gin/request" "testing" - - "github.com/gin-gonic/gin" ) type TestController struct{} -func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (TestOut, error) { +func (t TestController) Logic(ctx *request.Context, formData *TestForm) (TestOut, error) { return TestOut{ FormData: formData, }, nil