185 lines
4.5 KiB
Plaintext
185 lines
4.5 KiB
Plaintext
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
|
|
}
|