config.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package middleware
  2. import (
  3. "fmt"
  4. "reflect"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. "go-common/library/log"
  9. )
  10. const (
  11. //TypeMiddleAll 全部操作都允许
  12. TypeMiddleAll = int8(0)
  13. //TypeMiddleEncode 只允许编码,后端返回给前端的响应处理
  14. TypeMiddleEncode = int8(1)
  15. //TypeMiddleDecode 只允许解码,前端请求后端的请求参数处理
  16. TypeMiddleDecode = int8(2)
  17. )
  18. //Aggregate 前端映射结构,对应于前后端交互的字段
  19. type Aggregate struct {
  20. Hitn string `json:"hitn"` //name的多个结构体用.表示分级
  21. Hitv string `json:"hitv"` //枚举值
  22. Mapn string `json:"mapn"` //映射字段名,可以与hitname不同,也可以相同
  23. Mapv string `json:"mapv"` //映射字段值
  24. Delimiter string `json:"delimiter"` //映射字段值的分隔符号
  25. Order int64 `json:"order"` //顺序
  26. Type int8 `json:"type"`
  27. }
  28. func (f *Aggregate) Process(data interface{}, encode bool) {
  29. var (
  30. field, fieldm reflect.Value
  31. fieldExist, hited bool
  32. )
  33. defer func() {
  34. if errs := recover(); errs != nil {
  35. log.Error("Aggregate Process error(%+v)", errs)
  36. }
  37. }()
  38. hitn := f.Hitn
  39. hitv := strings.Split(f.Hitv, f.Delimiter)
  40. mapn := f.Mapn
  41. mapv := f.Mapv
  42. if !encode {
  43. hitn = f.Mapn
  44. hitv = strings.Split(f.Mapv, f.Delimiter)
  45. mapn = f.Hitn
  46. mapv = f.Hitv
  47. }
  48. //check fields exist
  49. fv := reflect.ValueOf(data)
  50. if field, fieldExist = getFieldByName(fv, hitn); !fieldExist {
  51. log.Warn("no field for hit(%s) data(%+v)", hitn, data)
  52. return
  53. }
  54. if mapn == hitn {
  55. fieldm = field
  56. } else if fieldm, fieldExist = getFieldByName(fv, mapn); !fieldExist || !fieldm.CanSet() {
  57. log.Warn("no field for map(%s) data(%+v)", mapn, data)
  58. return
  59. }
  60. fieldv := fmt.Sprintf("%v", field.Interface())
  61. for _, hit := range hitv {
  62. if fieldv == hit {
  63. hited = true
  64. break
  65. }
  66. }
  67. if !hited {
  68. return
  69. }
  70. log.Info("got hit field(%s) value(%s) config(%+v)", hitn, fieldv, f)
  71. switch fieldm.Kind() {
  72. case reflect.String:
  73. fieldm.SetString(mapv)
  74. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  75. vv, err := strconv.ParseInt(mapv, 10, 64)
  76. if err != nil {
  77. log.Error("strconv.ParseInt(%s) error(%v)", mapv, err)
  78. return
  79. }
  80. fieldm.SetInt(vv)
  81. default:
  82. log.Warn("not support field.kind(%s) for field(%s)", fieldm.Kind().String(), mapn)
  83. }
  84. }
  85. //getFieldByName 迭代遍历struct,获取指定名字的字段
  86. func getFieldByName(v reflect.Value, name string) (res reflect.Value, ok bool) {
  87. tp := v.Type()
  88. if tp.Kind() == reflect.Ptr {
  89. v = v.Elem()
  90. tp = tp.Elem()
  91. }
  92. if tp.Kind() != reflect.Struct || !v.IsValid() {
  93. return
  94. }
  95. for i := 0; i < tp.NumField(); i++ {
  96. fn := strings.ToLower(tp.Field(i).Name)
  97. if fn == name {
  98. res = v.Field(i)
  99. ok = true
  100. return
  101. }
  102. if vres, vok := getFieldByName(v.Field(i), name); vok {
  103. ok = vok
  104. res = vres
  105. return
  106. }
  107. }
  108. return
  109. }
  110. //MiddleAggregate 处理聚合逻辑
  111. type MiddleAggregate struct {
  112. Cfg []*Aggregate
  113. Encode bool
  114. }
  115. //Process handle multi aggregate logists
  116. func (m *MiddleAggregate) Process(data interface{}) {
  117. cfgs := []*Aggregate{}
  118. for _, item := range m.Cfg {
  119. if item.Type == TypeMiddleAll || (m.Encode && item.Type == TypeMiddleEncode) || (!m.Encode && item.Type == TypeMiddleDecode) {
  120. cfgs = append(cfgs, item)
  121. }
  122. }
  123. if len(cfgs) == 0 {
  124. return
  125. }
  126. sort.Sort(AggregateArr(cfgs))
  127. for _, item := range cfgs {
  128. item.Process(data, m.Encode)
  129. }
  130. }
  131. //AggregateArr arr
  132. type AggregateArr []*Aggregate
  133. //Len .
  134. func (f AggregateArr) Len() int {
  135. return len(f)
  136. }
  137. //Less .
  138. func (f AggregateArr) Less(i, j int) bool {
  139. return f[i].Order < f[j].Order
  140. }
  141. //Swap .
  142. func (f AggregateArr) Swap(i, j int) {
  143. f[i], f[j] = f[j], f[i]
  144. }