公共参数自动注入, 增加参数是否已赋值检测 #18
@ -38,22 +38,40 @@ func (s *server) injectCommonParam(ctx *gin.Context, formValue any) error {
 | 
			
		||||
	var (
 | 
			
		||||
		val              any
 | 
			
		||||
		err              error
 | 
			
		||||
		reflectFormValue reflect.Value
 | 
			
		||||
		reflectType      reflect.Type
 | 
			
		||||
		ok               bool
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	reflectType := reflect.TypeOf(formValue)
 | 
			
		||||
	if reflectFormValue, ok = formValue.(reflect.Value); !ok {
 | 
			
		||||
		reflectFormValue = reflect.ValueOf(formValue)
 | 
			
		||||
		reflectType = reflect.TypeOf(formValue)
 | 
			
		||||
	} else {
 | 
			
		||||
		reflectType = reflectFormValue.Type()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fieldTable := map[string]bool{}
 | 
			
		||||
	fieldNum := reflectType.Elem().NumField()
 | 
			
		||||
	for i := 0; i < fieldNum; i++ {
 | 
			
		||||
		if reflectType.Elem().Field(i).Anonymous && ((reflectType.Elem().Field(i).Type.Kind() == reflect.Ptr && reflectType.Elem().Field(i).Type.Kind() == reflect.Struct) || reflectType.Elem().Field(i).Type.Kind() == reflect.Struct) {
 | 
			
		||||
			anonymousFieldType := reflectType.Elem().Field(i).Type
 | 
			
		||||
			if anonymousFieldType.Kind() == reflect.Ptr {
 | 
			
		||||
				anonymousFieldType = anonymousFieldType.Elem()
 | 
			
		||||
			}
 | 
			
		||||
			for j := 0; j < anonymousFieldType.NumField(); j++ {
 | 
			
		||||
				fieldTable[anonymousFieldType.Field(j).Name] = true
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// 提取全部结构体字段
 | 
			
		||||
			fieldTable[reflectType.Elem().Field(i).Name] = true
 | 
			
		||||
		}
 | 
			
		||||
	reflectValue := reflect.ValueOf(formValue)
 | 
			
		||||
	}
 | 
			
		||||
	for fieldName, getParamFunc := range s.commonParam {
 | 
			
		||||
		if _, ok := fieldTable[fieldName]; !ok {
 | 
			
		||||
		if _, ok = fieldTable[fieldName]; !ok {
 | 
			
		||||
			// 结构体字段未配置自动注入
 | 
			
		||||
			logger.Instance.Debug("当前结构体不包含指定字段, 忽略执行", pkgLogger.NewLogData(innerCtx, logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
 | 
			
		||||
				"field_name": fieldName,
 | 
			
		||||
				"struct":     reflectValue.Elem().Type().String(),
 | 
			
		||||
				"struct":     reflectFormValue.Elem().Type().String(),
 | 
			
		||||
			}).ToFieldList()...)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
@ -64,7 +82,7 @@ func (s *server) injectCommonParam(ctx *gin.Context, formValue any) error {
 | 
			
		||||
			}).ToFieldList()...)
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		fieldValue := reflectValue.Elem().FieldByName(fieldName)
 | 
			
		||||
		fieldValue := reflectFormValue.Elem().FieldByName(fieldName)
 | 
			
		||||
		if !fieldValue.CanSet() {
 | 
			
		||||
			logDataList := pkgLogger.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
 | 
			
		||||
				"field_name": fieldName,
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,7 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
 | 
			
		||||
			ok         bool
 | 
			
		||||
			e          exception.IException
 | 
			
		||||
			formValue  any
 | 
			
		||||
			firstParam reflect.Value
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		if formValue, err = s.getFormInitValue(ctx, uriCfg); nil != err {
 | 
			
		||||
@ -60,6 +61,17 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
 | 
			
		||||
			ctx.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// 表单数据
 | 
			
		||||
		inputValue := reflect.ValueOf(formValue)
 | 
			
		||||
		// 注入公共参数
 | 
			
		||||
		if err = s.injectCommonParam(ctx, inputValue); nil != err {
 | 
			
		||||
			e = exception.NewFromError(500, err)
 | 
			
		||||
			response.SendWithException(ctx, e, &define.ResponseOption{
 | 
			
		||||
				ContentType: consts.MimeTypeJson,
 | 
			
		||||
			})
 | 
			
		||||
			ctx.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		isSuccess := false
 | 
			
		||||
		// 初始化响应之后logic
 | 
			
		||||
@ -94,11 +106,9 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
 | 
			
		||||
			}()
 | 
			
		||||
		}()
 | 
			
		||||
		// 执行逻辑
 | 
			
		||||
		inputValue := reflect.ValueOf(formValue)
 | 
			
		||||
		if uriCfg.FormDataType.Kind() != reflect.Ptr {
 | 
			
		||||
			inputValue = inputValue.Elem()
 | 
			
		||||
		}
 | 
			
		||||
		var firstParam reflect.Value
 | 
			
		||||
		if uriCfg.CtxType == CustomContextType {
 | 
			
		||||
			customCtx := ctx.MustGet(define.CustomContextKey)
 | 
			
		||||
			firstParam = reflect.ValueOf(customCtx)
 | 
			
		||||
@ -109,7 +119,7 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
 | 
			
		||||
		if resList[1].IsNil() {
 | 
			
		||||
			// 请求成功
 | 
			
		||||
			isSuccess = true
 | 
			
		||||
			response.SuccessWithExtension(ctx, resList[0].Interface(), &define.ResponseOption{ContentType: "application/json;charset=utf-8"})
 | 
			
		||||
			response.SuccessWithExtension(ctx, resList[0].Interface(), &define.ResponseOption{ContentType: consts.MimeTypeJson})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// 请求失败
 | 
			
		||||
@ -123,7 +133,7 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
		response.SendWithException(ctx, e, &define.ResponseOption{
 | 
			
		||||
			ContentType: "application/json;charset=utf-8",
 | 
			
		||||
			ContentType: consts.MimeTypeJson,
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -131,6 +131,7 @@ func NewServer(port int, optionList ...SetServerOptionFunc) *server {
 | 
			
		||||
		port:        port,
 | 
			
		||||
		option:      option,
 | 
			
		||||
		lock:        &sync.RWMutex{},
 | 
			
		||||
		commonParam: map[string]GetCommonParam{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,28 @@ import (
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type testCommon struct {
 | 
			
		||||
	UserID uint `json:"user_id"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type testForm struct {
 | 
			
		||||
	Meta `json:"-" method:"get" path:"test"`
 | 
			
		||||
	testCommon
 | 
			
		||||
	Name string `json:"name"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewServer(t *testing.T) {
 | 
			
		||||
	s := NewServer(9087)
 | 
			
		||||
	s.Router().GET("/ping", func(c *gin.Context) {})
 | 
			
		||||
	s.AddCommonParamRule("UserID", func(ctx *gin.Context) (any, error) {
 | 
			
		||||
		return uint(123456), nil
 | 
			
		||||
	})
 | 
			
		||||
	s.Group("", nil, testController{})
 | 
			
		||||
	s.Start()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type testController struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tc testController) Test(ctx *gin.Context, requestData *testForm) (*testCommon, error) {
 | 
			
		||||
	return &testCommon{UserID: requestData.UserID}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user