package format import ( "fmt" "gbase/glog" "reflect" "strconv" "strings" ) // 解析gorm标签,返回键值对 func ParseGormTag(tag string) map[string]string { result := make(map[string]string) pairs := strings.Split(tag, ";") for _, pair := range pairs { kv := strings.Split(pair, ":") if len(kv) == 2 { result[kv[0]] = kv[1] } else { result[kv[0]] = "" } } return result } // 将map的值赋给struct func MapToStruct(input map[string]interface{}, output interface{}) error { defer func() { if r := recover(); r != nil { glog.XWarning(fmt.Sprintf("MapToStruct %v panic: %v\n", input, r)) } }() outputValue := reflect.ValueOf(output).Elem() outputType := outputValue.Type() for i := 0; i < outputType.NumField(); i++ { field := outputType.Field(i) column := field.Tag.Get("gorm") if column == "" { continue } tags := ParseGormTag(column) columnName := tags["column"] if value, ok := input[columnName]; ok { //println(columnName) fieldValue := outputValue.FieldByName(field.Name) if fieldValue.CanSet() { val := reflect.ValueOf(value) if val.Type().ConvertibleTo(fieldValue.Type()) { fieldValue.Set(val.Convert(fieldValue.Type())) } else { // 特别处理常见的类型转换 switch fieldValue.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if intValue, err := strconv.Atoi(fmt.Sprintf("%v", value)); err == nil { fieldValue.SetInt(int64(intValue)) } case reflect.String: fieldValue.SetString(fmt.Sprintf("%v", value)) case reflect.Float32, reflect.Float64: if floatValue, err := strconv.ParseFloat(fmt.Sprintf("%v", value), 64); err == nil { fieldValue.SetFloat(floatValue) } default: fieldValue.SetString(fmt.Sprintf("%v", value)) } } } } } return nil } func ConvertNilToEmptyString(data interface{}) interface{} { switch v := data.(type) { case nil: return "" case map[string]interface{}: for key, val := range v { v[key] = ConvertNilToEmptyString(val) } case []interface{}: for i, val := range v { v[i] = ConvertNilToEmptyString(val) } } //去除字符串左边和右边的空格 if reflect.TypeOf(data).Kind() == reflect.String { data = strings.TrimLeft(data.(string), " ") data = strings.TrimRight(data.(string), " ") } else if reflect.TypeOf(data).Kind() == reflect.Float64 { if data.(float64) > 9000 { data = fmt.Sprintf("%v", int64(data.(float64))) } else { data = fmt.Sprintf("%v", data.(float64)) } } else if reflect.TypeOf(data).Kind() == reflect.Float32 { if data.(float32) > 9000 { data = fmt.Sprintf("%v", int64(data.(float32))) } else { data = fmt.Sprintf("%v", data.(float32)) } } else if reflect.TypeOf(data).Kind() == reflect.Int64 { data = fmt.Sprintf("%v", data) } else if reflect.TypeOf(data).Kind() == reflect.Int32 { data = fmt.Sprintf("%v", data) } else if reflect.TypeOf(data).Kind() == reflect.Int { data = fmt.Sprintf("%v", data) } return data } func StructToMapReflect(data interface{}) map[string]interface{} { val := reflect.ValueOf(data) typ := reflect.TypeOf(data) result := make(map[string]interface{}) // 迭代结构体的字段 for i := 0; i < val.NumField(); i++ { field := typ.Field(i) // 获取 JSON 标签 jsonTag := field.Tag.Get("json") if jsonTag == "" { jsonTag = field.Name // 如果没有 JSON 标签,使用字段名 } else { // 如果标签中有逗号,取第一个部分 if commaIndex := strings.Index(jsonTag, ","); commaIndex != -1 { jsonTag = jsonTag[:commaIndex] } } fieldValue := val.Field(i).Interface() result[jsonTag] = fieldValue } return result }