120 lines
4.3 KiB
Go
120 lines
4.3 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
|
|
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
|
|
}
|
|
fieldValue := reflectFormValue.Elem().FieldByName(fieldName)
|
|
if !fieldValue.IsZero() {
|
|
// 表单次数不为空, 说明从参数中传递, 不做覆盖填充
|
|
logger.Instance.Debug("指定字段已赋值, 不做重新覆盖填充处理, 跳过", pkgLogger.NewLogData(innerCtx, logger.RecordType, logger.CodeInjectCommonParam, map[string]any{
|
|
"field_name": fieldName,
|
|
"struct": reflectFormValue.Elem().Type().String(),
|
|
"input_form_value": fieldValue.Interface(),
|
|
}).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
|
|
}
|
|
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
|
|
}
|