tag.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package rule
  2. import (
  3. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
  4. "git.sxidc.com/go-tools/utils/reflectutils"
  5. "git.sxidc.com/go-tools/utils/strutils"
  6. "git.sxidc.com/go-tools/utils/template"
  7. "github.com/iancoleman/strcase"
  8. "github.com/pkg/errors"
  9. "reflect"
  10. "strings"
  11. )
  12. const (
  13. TypeString = "string"
  14. TypeTime = "time"
  15. TypeNumber = "number"
  16. TypeBool = "bool"
  17. )
  18. func IsSupportedType(typeStr string) bool {
  19. return typeStr == TypeString || typeStr == TypeTime || typeStr == TypeNumber || typeStr == TypeBool
  20. }
  21. const (
  22. tagPartSeparator = ";"
  23. tagPartKeyValueSeparator = ":"
  24. )
  25. const (
  26. tagKey = "rule"
  27. tagPartColumn = "column"
  28. tagPartType = "type"
  29. )
  30. type Tag struct {
  31. ColumnName string
  32. Type string
  33. }
  34. func parseTag(entityElemValue reflect.Value, onParsedFieldTagFunc OnParsedFieldTagFunc) error {
  35. for i := 0; i < entityElemValue.NumField(); i++ {
  36. entityField := entityElemValue.Type().Field(i)
  37. entityFieldValue := entityElemValue.Field(i)
  38. // 无效值,不进行映射
  39. if !entityFieldValue.IsValid() {
  40. continue
  41. }
  42. entityFieldElemValue := reflectutils.PointerValueElem(entityFieldValue)
  43. tagStr, ok := entityField.Tag.Lookup(tagKey)
  44. if !ok {
  45. continue
  46. }
  47. tag, err := parseFieldTag(entityField, tagStr)
  48. if err != nil {
  49. return err
  50. }
  51. if tag == nil {
  52. continue
  53. }
  54. // 结构类型的字段,解析结构内部
  55. if entityFieldElemValue.Kind() == reflect.Struct &&
  56. !reflectutils.IsValueTime(entityFieldElemValue) {
  57. err := parseTag(entityFieldElemValue, onParsedFieldTagFunc)
  58. if err != nil {
  59. return err
  60. }
  61. continue
  62. }
  63. err = onParsedFieldTagFunc(entityField.Name, entityFieldElemValue, tag)
  64. if err != nil {
  65. return err
  66. }
  67. }
  68. return nil
  69. }
  70. func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
  71. fieldType := reflectutils.PointerTypeElem(field.Type)
  72. fieldKind := reflectutils.GroupTypeKind(fieldType)
  73. var fieldTypeStr string
  74. if fieldKind == reflect.Int64 || fieldKind == reflect.Uint64 || fieldKind == reflect.Float64 {
  75. fieldTypeStr = TypeNumber
  76. } else if fieldKind == reflect.String {
  77. fieldTypeStr = TypeString
  78. } else if fieldKind == reflect.Struct && fieldType.String() == "time.Time" {
  79. fieldTypeStr = TypeTime
  80. } else if fieldKind == reflect.Bool {
  81. fieldTypeStr = TypeBool
  82. } else {
  83. return nil, errors.New("type支持的类型包括: string, number, time")
  84. }
  85. tag := &Tag{
  86. ColumnName: strcase.ToSnake(template.Id(field.Name)),
  87. Type: fieldTypeStr,
  88. }
  89. if strutils.IsStringEmpty(tagStr) {
  90. return tag, nil
  91. }
  92. tagParts := strings.Split(tagStr, tagPartSeparator)
  93. if tagParts != nil || len(tagParts) != 0 {
  94. for _, tagPart := range tagParts {
  95. tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
  96. if tagPartKeyValue != nil && len(tagPartKeyValue) == 2 && strutils.IsStringNotEmpty(tagPartKeyValue[1]) {
  97. tagPartKeyValue[1] = strings.Trim(tagPartKeyValue[1], "'")
  98. }
  99. if strutils.IsStringEmpty(tagPartKeyValue[0]) {
  100. continue
  101. }
  102. switch tagPartKeyValue[0] {
  103. case tagPartColumn:
  104. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  105. return nil, errors.New("column没有赋值列名")
  106. }
  107. tag.ColumnName = tagPartKeyValue[1]
  108. case tagPartType:
  109. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  110. return nil, errors.New("type没有赋值字段类型")
  111. }
  112. if !IsSupportedType(tagPartKeyValue[1]) {
  113. return nil, errors.Errorf("类型为%v, type支持的类型包括: string, number, time", tagPartKeyValue[1])
  114. }
  115. tag.Type = tagPartKeyValue[1]
  116. default:
  117. err := errors.New(tagKey + "不支持的tag: " + tagPartKeyValue[0])
  118. logger.GetInstance().Error(err)
  119. continue
  120. }
  121. }
  122. }
  123. return tag, nil
  124. }