tag.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package assign
  2. import (
  3. "git.sxidc.com/go-framework/baize/infrastructure/logger"
  4. "git.sxidc.com/go-tools/utils/reflectutils"
  5. "git.sxidc.com/go-tools/utils/strutils"
  6. "git.sxidc.com/service-supports/fserr"
  7. "reflect"
  8. "strings"
  9. "time"
  10. )
  11. const (
  12. defaultStringSliceSeparator = "::"
  13. tagPartSeparator = ";"
  14. tagPartKeyValueSeparator = ":"
  15. )
  16. const (
  17. tagKey = "assign"
  18. tagPartIgnore = "-"
  19. tagPartToField = "toField"
  20. tagPartParseTime = "parseTime"
  21. tagPartFormatTime = "formatTime"
  22. tagPartJoinWith = "joinWith"
  23. tagPartSplitWith = "splitWith"
  24. tagPartTrim = "trim"
  25. tagPartTrimPrefix = "trimPrefix"
  26. tagPartTrimSuffix = "trimSuffix"
  27. )
  28. type Tag struct {
  29. ToField string
  30. ParseTime string
  31. FormatTime string
  32. JoinWith string
  33. SplitWith string
  34. Trim string
  35. TrimPrefix string
  36. TrimSuffix string
  37. }
  38. func parseTag(fromElemValue reflect.Value, toElemValue *reflect.Value, onParsedFieldTagFunc OnParsedFieldTagCallback) error {
  39. for i := 0; i < fromElemValue.NumField(); i++ {
  40. fromField := fromElemValue.Type().Field(i)
  41. fromFieldValue := fromElemValue.Field(i)
  42. // 无效值
  43. if !fromFieldValue.IsValid() {
  44. continue
  45. }
  46. if fromFieldValue.Kind() == reflect.Pointer && fromFieldValue.IsNil() {
  47. fromFieldValue.Set(reflect.New(fromField.Type.Elem()))
  48. }
  49. fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
  50. tagStr := fromField.Tag.Get(tagKey)
  51. // 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
  52. if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
  53. !reflectutils.IsValueTime(fromFieldElemValue) {
  54. err := parseTag(fromFieldElemValue, toElemValue, onParsedFieldTagFunc)
  55. if err != nil {
  56. return err
  57. }
  58. continue
  59. }
  60. tag, err := parseFieldTag(fromField, tagStr)
  61. if err != nil {
  62. return err
  63. }
  64. if tag == nil {
  65. continue
  66. }
  67. toFieldValue := toElemValue.FieldByName(tag.ToField)
  68. // 不存在对应的字段
  69. if !toFieldValue.IsValid() {
  70. continue
  71. }
  72. toFieldElemValue := toFieldValue
  73. if toFieldValue.Kind() == reflect.Pointer {
  74. if !toFieldValue.IsValid() {
  75. continue
  76. }
  77. if !toFieldValue.CanSet() {
  78. continue
  79. }
  80. // 空值针,初始化
  81. if toFieldValue.IsNil() {
  82. toFieldValue.Set(reflect.New(toFieldValue.Type().Elem()))
  83. }
  84. toFieldElemValue = toFieldValue.Elem()
  85. }
  86. err = onParsedFieldTagFunc(fromField.Name, fromFieldElemValue, toFieldElemValue, tag)
  87. if err != nil {
  88. return err
  89. }
  90. }
  91. return nil
  92. }
  93. func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
  94. if tagStr == tagPartIgnore {
  95. return nil, nil
  96. }
  97. tag := &Tag{
  98. ToField: field.Name,
  99. ParseTime: time.DateTime,
  100. FormatTime: time.DateTime,
  101. JoinWith: defaultStringSliceSeparator,
  102. SplitWith: defaultStringSliceSeparator,
  103. Trim: "",
  104. TrimPrefix: "",
  105. TrimSuffix: "",
  106. }
  107. if strutils.IsStringEmpty(tagStr) {
  108. return tag, nil
  109. }
  110. tagParts := strings.Split(tagStr, tagPartSeparator)
  111. if tagParts != nil || len(tagParts) != 0 {
  112. for _, tagPart := range tagParts {
  113. tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
  114. if tagPartKeyValue != nil && len(tagPartKeyValue) == 2 && strutils.IsStringNotEmpty(tagPartKeyValue[1]) {
  115. tagPartKeyValue[1] = strings.Trim(tagPartKeyValue[1], "'")
  116. }
  117. switch tagPartKeyValue[0] {
  118. case tagPartToField:
  119. tag.ToField = tagPartKeyValue[1]
  120. case tagPartParseTime:
  121. tag.ParseTime = tagPartKeyValue[1]
  122. case tagPartFormatTime:
  123. tag.FormatTime = tagPartKeyValue[1]
  124. case tagPartJoinWith:
  125. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  126. return nil, fserr.New(tagPartJoinWith + "没有赋值分隔符")
  127. }
  128. tag.JoinWith = tagPartKeyValue[1]
  129. case tagPartSplitWith:
  130. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  131. return nil, fserr.New(tagPartSplitWith + "没有赋值分隔符")
  132. }
  133. tag.SplitWith = tagPartKeyValue[1]
  134. case tagPartTrim:
  135. tag.Trim = tagPartKeyValue[1]
  136. case tagPartTrimPrefix:
  137. tag.TrimPrefix = tagPartKeyValue[1]
  138. case tagPartTrimSuffix:
  139. tag.TrimSuffix = tagPartKeyValue[1]
  140. default:
  141. err := fserr.New(tagKey + "不支持的tag: " + tagPartKeyValue[0])
  142. logger.GetInstance().Error(err)
  143. continue
  144. }
  145. }
  146. }
  147. return tag, nil
  148. }