|  | @@ -1,7 +1,9 @@
 | 
	
		
			
				|  |  |  package gio
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import (
 | 
	
		
			
				|  |  | +	"fmt"
 | 
	
		
			
				|  |  |  	"io"
 | 
	
		
			
				|  |  | +	"reflect"
 | 
	
		
			
				|  |  |  	"runtime"
 | 
	
		
			
				|  |  |  	"strings"
 | 
	
		
			
				|  |  |  )
 | 
	
	
		
			
				|  | @@ -18,3 +20,66 @@ func CallFuncName(skip int) string {
 | 
	
		
			
				|  |  |  	funcName := runtime.FuncForPC(pc).Name()
 | 
	
		
			
				|  |  |  	return funcName[strings.LastIndex(funcName, ".")+1:]
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func StructToMap(obj any) (map[string]any, error) {
 | 
	
		
			
				|  |  | +	// 获取反射值
 | 
	
		
			
				|  |  | +	val := reflect.ValueOf(obj)
 | 
	
		
			
				|  |  | +	if val.Kind() == reflect.Ptr {
 | 
	
		
			
				|  |  | +		val = val.Elem()
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 确保输入是结构体
 | 
	
		
			
				|  |  | +	if val.Kind() != reflect.Struct {
 | 
	
		
			
				|  |  | +		return nil, fmt.Errorf("input must be a struct or struct pointer")
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 创建结果 map
 | 
	
		
			
				|  |  | +	result := make(map[string]any)
 | 
	
		
			
				|  |  | +	typ := val.Type()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 遍历结构体的字段
 | 
	
		
			
				|  |  | +	for i := 0; i < val.NumField(); i++ {
 | 
	
		
			
				|  |  | +		field := typ.Field(i)
 | 
	
		
			
				|  |  | +		fieldVal := val.Field(i)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// 获取 json 标签
 | 
	
		
			
				|  |  | +		jsonTag := field.Tag.Get("json")
 | 
	
		
			
				|  |  | +		if jsonTag == "" {
 | 
	
		
			
				|  |  | +			jsonTag = field.Name
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			if idx := strings.Index(jsonTag, ","); idx != -1 {
 | 
	
		
			
				|  |  | +				jsonTag = jsonTag[:idx]
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// 跳过忽略字段或无效字段
 | 
	
		
			
				|  |  | +		if jsonTag == "-" || !fieldVal.IsValid() {
 | 
	
		
			
				|  |  | +			continue
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// 检查字段是否为结构体或结构体指针,且是否有 json 标签
 | 
	
		
			
				|  |  | +		hasJsonTag := field.Tag.Get("json") != ""
 | 
	
		
			
				|  |  | +		if (fieldVal.Kind() == reflect.Struct || (fieldVal.Kind() == reflect.Ptr && !fieldVal.IsNil() && fieldVal.Elem().Kind() == reflect.Struct)) && !hasJsonTag {
 | 
	
		
			
				|  |  | +			// 如果是结构体且无 json 标签,递归展开
 | 
	
		
			
				|  |  | +			var nestedVal interface{}
 | 
	
		
			
				|  |  | +			if fieldVal.Kind() == reflect.Ptr {
 | 
	
		
			
				|  |  | +				nestedVal = fieldVal.Interface()
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				nestedVal = fieldVal.Interface()
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			nestedMap, err := StructToMap(nestedVal)
 | 
	
		
			
				|  |  | +			if err != nil {
 | 
	
		
			
				|  |  | +				return nil, err
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			for k, v := range nestedMap {
 | 
	
		
			
				|  |  | +				result[k] = v
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			// 其他情况(包括有 json 标签的嵌套结构体),直接存储字段值
 | 
	
		
			
				|  |  | +			result[jsonTag] = fieldVal.Interface()
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return result, nil
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 |