struct.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package format
  2. import (
  3. "fmt"
  4. "gbase/glog"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. )
  9. // 解析gorm标签,返回键值对
  10. func ParseGormTag(tag string) map[string]string {
  11. result := make(map[string]string)
  12. pairs := strings.Split(tag, ";")
  13. for _, pair := range pairs {
  14. kv := strings.Split(pair, ":")
  15. if len(kv) == 2 {
  16. result[kv[0]] = kv[1]
  17. } else {
  18. result[kv[0]] = ""
  19. }
  20. }
  21. return result
  22. }
  23. // 将map的值赋给struct
  24. func MapToStruct(input map[string]interface{}, output interface{}) error {
  25. defer func() {
  26. if r := recover(); r != nil {
  27. glog.XWarning(fmt.Sprintf("MapToStruct %v panic: %v\n", input, r))
  28. }
  29. }()
  30. outputValue := reflect.ValueOf(output).Elem()
  31. outputType := outputValue.Type()
  32. for i := 0; i < outputType.NumField(); i++ {
  33. field := outputType.Field(i)
  34. column := field.Tag.Get("gorm")
  35. if column == "" {
  36. continue
  37. }
  38. tags := ParseGormTag(column)
  39. columnName := tags["column"]
  40. if value, ok := input[columnName]; ok {
  41. //println(columnName)
  42. fieldValue := outputValue.FieldByName(field.Name)
  43. if fieldValue.CanSet() {
  44. val := reflect.ValueOf(value)
  45. if val.Type().ConvertibleTo(fieldValue.Type()) {
  46. fieldValue.Set(val.Convert(fieldValue.Type()))
  47. } else {
  48. // 特别处理常见的类型转换
  49. switch fieldValue.Kind() {
  50. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  51. if intValue, err := strconv.Atoi(fmt.Sprintf("%v", value)); err == nil {
  52. fieldValue.SetInt(int64(intValue))
  53. }
  54. case reflect.String:
  55. fieldValue.SetString(fmt.Sprintf("%v", value))
  56. case reflect.Float32, reflect.Float64:
  57. if floatValue, err := strconv.ParseFloat(fmt.Sprintf("%v", value), 64); err == nil {
  58. fieldValue.SetFloat(floatValue)
  59. }
  60. default:
  61. fieldValue.SetString(fmt.Sprintf("%v", value))
  62. }
  63. }
  64. }
  65. }
  66. }
  67. return nil
  68. }
  69. func ConvertNilToEmptyString(data interface{}) interface{} {
  70. switch v := data.(type) {
  71. case nil:
  72. return ""
  73. case map[string]interface{}:
  74. for key, val := range v {
  75. v[key] = ConvertNilToEmptyString(val)
  76. }
  77. case []interface{}:
  78. for i, val := range v {
  79. v[i] = ConvertNilToEmptyString(val)
  80. }
  81. }
  82. //去除字符串左边和右边的空格
  83. if reflect.TypeOf(data).Kind() == reflect.String {
  84. data = strings.TrimLeft(data.(string), " ")
  85. data = strings.TrimRight(data.(string), " ")
  86. } else if reflect.TypeOf(data).Kind() == reflect.Float64 {
  87. if data.(float64) > 9000 {
  88. data = fmt.Sprintf("%v", int64(data.(float64)))
  89. } else {
  90. data = fmt.Sprintf("%v", data.(float64))
  91. }
  92. } else if reflect.TypeOf(data).Kind() == reflect.Float32 {
  93. if data.(float32) > 9000 {
  94. data = fmt.Sprintf("%v", int64(data.(float32)))
  95. } else {
  96. data = fmt.Sprintf("%v", data.(float32))
  97. }
  98. } else if reflect.TypeOf(data).Kind() == reflect.Int64 {
  99. data = fmt.Sprintf("%v", data)
  100. } else if reflect.TypeOf(data).Kind() == reflect.Int32 {
  101. data = fmt.Sprintf("%v", data)
  102. } else if reflect.TypeOf(data).Kind() == reflect.Int {
  103. data = fmt.Sprintf("%v", data)
  104. }
  105. return data
  106. }
  107. func StructToMapReflect(data interface{}) map[string]interface{} {
  108. val := reflect.ValueOf(data)
  109. typ := reflect.TypeOf(data)
  110. result := make(map[string]interface{})
  111. // 迭代结构体的字段
  112. for i := 0; i < val.NumField(); i++ {
  113. field := typ.Field(i)
  114. // 获取 JSON 标签
  115. jsonTag := field.Tag.Get("json")
  116. if jsonTag == "" {
  117. jsonTag = field.Name // 如果没有 JSON 标签,使用字段名
  118. } else {
  119. // 如果标签中有逗号,取第一个部分
  120. if commaIndex := strings.Index(jsonTag, ","); commaIndex != -1 {
  121. jsonTag = jsonTag[:commaIndex]
  122. }
  123. }
  124. fieldValue := val.Field(i).Interface()
  125. result[jsonTag] = fieldValue
  126. }
  127. return result
  128. }