package structx import ( "fmt" "reflect" "strconv" "strings" "code.yun.ink/pkg/convx" ) type ChangeInfo struct { Old string `json:"old"` New string `json:"new"` Val interface{} `json:"val"` } // map[string]interface类型的值附加到结构体中 func AttactToStructAny(structxx interface{}, updateMap map[string]interface{}) (map[string]ChangeInfo, error) { m := map[string]string{} for k, v := range updateMap { str, err := convx.ToString(v) if err != nil { return nil, err } m[k] = str } // fmt.Println("bef", m, structxx) r, err := AttactToStruct(structxx, m) // fmt.Println("resp:", r, m, structxx) return r, err } // 这个方法将map的数据赋值到结构体中 func AttactToStruct(structxx interface{}, updateMap map[string]string) (map[string]ChangeInfo, error) { // 将结构体指针转换为reflect.Value类型 v := reflect.ValueOf(structxx) // 如果v不是指针或者v是零值,直接返回 if v.Kind() != reflect.Ptr || v.IsNil() { return nil, fmt.Errorf("structxx 需要是指针") } changeMap := make(map[string]ChangeInfo) // 获取v指向的元素,也就是结构体本身 v = v.Elem() // 遍历map的键和值 for k, val := range updateMap { // 根据json标签获取结构体中对应的字段 field := v.FieldByNameFunc(func(name string) bool { f, _ := v.Type().FieldByName(name) // fmt.Printf("FieldByNameFunc:%+v\n", f) js := f.Tag.Get("json") s := strings.Split(js, ",") if len(s) > 1 { return s[0] == k } return js == k }) // 如果字段存在且可写 if field.IsValid() && field.CanSet() { // 根据字段的类型进行类型转换和赋值 switch field.Kind() { case reflect.Bool: oldb := field.Bool() olds, _ := convx.ToString(oldb) b, _ := convx.ToBool(val) field.SetBool(b) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: b} case reflect.Int64: // 将字符串转换为int64 oldi := field.Int() olds, _ := convx.ToString(oldi) i, _ := strconv.ParseInt(val, 10, 64) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.String: olds := field.String() field.SetString(val) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: val} case reflect.Int: oldi := field.Int() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Int32: oldi := field.Int() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Int16: oldi := field.Int() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Int8: oldi := field.Int() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Uint: oldi := field.Uint() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Uint32: oldi := field.Uint() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Uint16: oldi := field.Uint() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Uint8: oldi := field.Uint() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Uint64: oldi := field.Uint() olds, _ := convx.ToString(oldi) i, _ := convx.ToInt64(val) field.SetInt(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Float32: oldi := field.Float() olds, _ := convx.ToString(oldi) i, _ := convx.ToFloat64(val) field.SetFloat(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} case reflect.Float64: oldi := field.Float() olds, _ := convx.ToString(oldi) i, _ := convx.ToFloat64(val) field.SetFloat(i) changeMap[k] = ChangeInfo{Old: olds, New: val, Val: i} default: fmt.Println("未知类型") return nil, fmt.Errorf("未知类型:" + k) } } } return changeMap, nil }