// 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 reflectFormValue reflect.Value reflectType reflect.Type ok bool ) 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 } } 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": reflectFormValue.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 := reflectFormValue.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 }