feat: 升级hook处理逻辑
This commit is contained in:
@ -109,6 +109,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
||||
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
||||
// 解析第一个返回值, 要求必须是结构体或者是map
|
||||
outputStrictModel := metaField.Tag.Get(TagNameOutputStrict)
|
||||
hookSync := strings.ToLower(metaField.Tag.Get(TagNameHookSync))
|
||||
cfg.HookSync = hookSync == "1" || hookSync == "true" // 同步执行判断
|
||||
cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
||||
if cfg.OutputStrict {
|
||||
// 开启输出严格模式校验
|
||||
|
||||
@ -25,6 +25,7 @@ const (
|
||||
TagNameUriTag = "tag" // 接口的tag
|
||||
TagNameDesc = "desc" // 接口的描述
|
||||
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||
TagNameHookSync = "hook-sync" // hook同步执行
|
||||
TagNameBinding = "binding" // gin 内置的验证规则tag
|
||||
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
||||
TagNameErrMsg = "err" // 验证失败错误信息tag
|
||||
@ -41,6 +42,7 @@ type UriConfig struct {
|
||||
TagList []string `json:"tag_list"` // 接口分组
|
||||
Desc string `json:"desc"` // 接口描述
|
||||
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
|
||||
HookSync bool `json:"hook_sync"` // 接口主逻辑执行完成之后,hook是否同步执行, 默认异步执行
|
||||
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
|
||||
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
||||
@ -48,10 +50,6 @@ type UriConfig struct {
|
||||
}
|
||||
|
||||
// UriParam 接口参数配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:40 2025/1/27
|
||||
type UriParam struct {
|
||||
Field string `json:"field"` // 结构体字段
|
||||
Name string `json:"name"` // 参数名称
|
||||
|
||||
@ -78,7 +78,8 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
||||
// 非必传参数设置默认值
|
||||
defaults.SetDefaults(formValue)
|
||||
|
||||
isSuccess := false
|
||||
// 默认请求失败
|
||||
ctx.Set(consts.GinRequestSuccess, false)
|
||||
// 初始化响应之后logic
|
||||
logicAfterResponse := &define.LogicAfterResponse{
|
||||
SuccessHookFuncList: make([]func(), 0),
|
||||
@ -86,30 +87,8 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
||||
Lock: &sync.RWMutex{},
|
||||
}
|
||||
// 此处暴露出去,是为了使用方可以获取到对应数据
|
||||
ctx.Set(define.LogicAfterResponseKey, logicAfterResponse)
|
||||
defer func() {
|
||||
go func() {
|
||||
// 执行响应之后的相关逻辑
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
|
||||
}
|
||||
}()
|
||||
if isSuccess {
|
||||
for _, itemFunc := range logicAfterResponse.SuccessHookFuncList {
|
||||
if nil != itemFunc {
|
||||
itemFunc()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, itemFunc := range logicAfterResponse.FailureHookFuncList {
|
||||
if nil != itemFunc {
|
||||
itemFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}()
|
||||
ctx.Set(consts.GinLogicAfterResponseKey, logicAfterResponse)
|
||||
defer s.hook(ctx, uriCfg) // 执行Logic之后的相关逻辑
|
||||
// 执行逻辑
|
||||
if uriCfg.FormDataType.Kind() != reflect.Ptr {
|
||||
inputValue = inputValue.Elem()
|
||||
@ -118,8 +97,8 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
||||
firstParam = reflect.ValueOf(ctx)
|
||||
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, firstParam, inputValue})
|
||||
if resList[1].IsNil() {
|
||||
// 请求成功
|
||||
isSuccess = true
|
||||
// 请求成功, 更新标识
|
||||
ctx.Set(consts.GinRequestSuccess, true)
|
||||
response.SuccessWithExtension(ctx, resList[0].Interface(), &define.ResponseOption{ContentType: consts.MimeTypeJson})
|
||||
return
|
||||
}
|
||||
|
||||
74
router/hook.go
Normal file
74
router/hook.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Package router ...
|
||||
//
|
||||
// Description : router ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-11-01 12:34
|
||||
package router
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/define"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/logger"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/util"
|
||||
pkgLogger "git.zhangdeman.cn/zhangdeman/logger"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// hook 执行hook逻辑
|
||||
func (s *server) hook(ctx *gin.Context, uriCfg UriConfig) {
|
||||
responseAfter, exist := ctx.Get(consts.GinLogicAfterResponseKey)
|
||||
innerContext := util.GinCtxToContext(ctx)
|
||||
if !exist || nil != responseAfter {
|
||||
// 未配置
|
||||
logger.Instance.Debug("未配置Logic执行后的hook逻辑", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{
|
||||
"uri": uriCfg.Path,
|
||||
"logic_after_response_key": consts.GinLogicAfterResponseKey,
|
||||
}).ToFieldList()...)
|
||||
return
|
||||
}
|
||||
isSuccess, exist := ctx.Get(consts.GinRequestSuccess)
|
||||
success := false
|
||||
if nil != isSuccess && (isSuccess == "1" || isSuccess == "true" || isSuccess.(bool)) {
|
||||
success = true
|
||||
}
|
||||
hookInstance := responseAfter.(*define.LogicAfterResponse)
|
||||
if uriCfg.HookSync {
|
||||
// 同步执行
|
||||
s.hookAfter(ctx, uriCfg, hookInstance, success)
|
||||
} else {
|
||||
// 异步执行
|
||||
go s.hookAfter(ctx, uriCfg, hookInstance, success)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) hookAfter(ctx *gin.Context, uriCfg UriConfig, hookInstance *define.LogicAfterResponse, success bool) {
|
||||
innerContext := util.GinCtxToContext(ctx)
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Instance.Error("hook执行异常", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{
|
||||
"uri": uriCfg.Path,
|
||||
"logic_after_response_key": consts.GinLogicAfterResponseKey,
|
||||
"error": err.(error).Error(),
|
||||
"logic_success": success,
|
||||
}).ToFieldList()...)
|
||||
} else {
|
||||
|
||||
}
|
||||
}()
|
||||
if success {
|
||||
logger.Instance.Debug("接口Logic执行成功, 执行Hook逻辑")
|
||||
for _, itemFunc := range hookInstance.SuccessHookFuncList {
|
||||
if nil != itemFunc {
|
||||
itemFunc(ctx)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, itemFunc := range hookInstance.FailureHookFuncList {
|
||||
if nil != itemFunc {
|
||||
itemFunc(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user