Files
gin/router/common_param.go

91 lines
3.1 KiB
Go

// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-10-30 15:39
package router
import (
"errors"
"reflect"
"git.zhangdeman.cn/zhangdeman/gin/logger"
"git.zhangdeman.cn/zhangdeman/gin/util"
pkgLogger "git.zhangdeman.cn/zhangdeman/logger"
"github.com/gin-gonic/gin"
)
// GetCommonParam 获取公共参数
type GetCommonParam func(ctx *gin.Context) (any, error)
// AddCommonParamRule 添加公共参数注入规则
func (s *server) AddCommonParamRule(fieldName string, getParamFunc GetCommonParam) {
s.commonParam[fieldName] = getParamFunc
}
// AddCommonParamRules 批量添加公共参数注入规则
func (s *server) AddCommonParamRules(rules map[string]GetCommonParam) {
for fieldName, rule := range rules {
s.AddCommonParamRule(fieldName, rule)
}
}
// injectCommonParam 注入公共参数
func (s *server) injectCommonParam(ctx *gin.Context, formValue any) error {
innerCtx := util.GinCtxToContext(ctx)
var (
val any
err error
)
reflectType := reflect.TypeOf(formValue)
fieldTable := map[string]bool{}
fieldNum := reflectType.Elem().NumField()
for i := 0; i < fieldNum; i++ {
// 提取全部结构体字段
fieldTable[reflectType.Elem().Field(i).Name] = true
}
reflectValue := reflect.ValueOf(formValue)
for fieldName, getParamFunc := range s.commonParam {
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(),
}).ToFieldList()...)
continue
}
if val, err = getParamFunc(ctx); nil != err {
logger.Instance.Error("获取公共结构体字段参数值失败", pkgLogger.NewLogData(innerCtx, logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
"field_name": fieldName,
"err_msg": err.Error(),
}).ToFieldList()...)
return err
}
fieldValue := reflectValue.Elem().FieldByName(fieldName)
if !fieldValue.CanSet() {
logDataList := pkgLogger.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
"field_name": fieldName,
"field_type": fieldValue.Type().String(),
})
logger.Instance.Error("结构体字段不可设置值", logDataList.ToFieldList()...)
return errors.New(fieldName + ": 结构体字段不可设置值")
}
reflectVal := reflect.ValueOf(val)
if reflectVal.Type() != fieldValue.Type() {
logDataList := pkgLogger.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
"field_name": fieldName,
"field_type": fieldValue.Type().String(),
"value_type": reflectVal.Type().String(),
})
logger.Instance.Error("返回数据类型与字段类型不一致", logDataList.ToFieldList()...)
return errors.New(fieldName + ": 字段自动注入, 返回数据类型与字段类型不一致")
}
// 设置值
fieldValue.Set(reflectVal)
}
return nil
}