utils.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "reflect"
  6. "go-common/library/log"
  7. )
  8. // 每个ID单独查询 strict严格模式下一次错误,直接返回
  9. func (s *Service) singleIDtoName(c context.Context, list interface{}, singletrans func(context.Context, int64) ([]interface{}, error), strict bool, ID string, Names ...string) (err error) {
  10. var (
  11. lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
  12. id int64
  13. values []interface{}
  14. )
  15. if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
  16. return fmt.Errorf("invalid list")
  17. }
  18. count := lV.Len()
  19. for i := 0; i < count; i++ {
  20. if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
  21. return fmt.Errorf("invalid itemI")
  22. }
  23. if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
  24. return fmt.Errorf("invalid itemIE")
  25. }
  26. if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
  27. return fmt.Errorf("invalid idFiled")
  28. }
  29. for _, Name := range Names {
  30. if nameFiled = itemIE.FieldByName(Name); !nameFiled.IsValid() || !nameFiled.CanSet() {
  31. return fmt.Errorf("invalid nameFiled")
  32. }
  33. }
  34. if id = idFiled.Int(); id != 0 {
  35. if values, err = singletrans(c, id); err != nil || len(values) != len(Names) {
  36. log.Error("s.sigleIDtoName error(%v) len(values)=%d len(Names)=%d", err, len(values), len(Names))
  37. if strict {
  38. return
  39. }
  40. err = nil
  41. continue
  42. }
  43. for i, value := range values {
  44. nameFiled = itemIE.FieldByName(Names[i])
  45. valueField = reflect.ValueOf(value)
  46. if nameFiled.Kind() != valueField.Kind() {
  47. log.Error("singletrans return %s while need %s", valueField.Kind().String(), nameFiled.Kind().String())
  48. continue
  49. }
  50. nameFiled.Set(valueField)
  51. }
  52. }
  53. }
  54. return
  55. }
  56. /* 批量查询,批量转换
  57. * list []*struct{}
  58. * multrans 转化器,根据ID查出其他值
  59. * ID id字段名称,id字段类型必须是int64
  60. * Names 查出来的各个字段名称
  61. */
  62. func (s *Service) mulIDtoName(c context.Context, list interface{}, multrans func(context.Context, []int64) (map[int64][]interface{}, error), ID string, Names ...string) (err error) {
  63. var (
  64. lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
  65. id int64
  66. ids []int64
  67. hashIDName = make(map[int64][]interface{})
  68. )
  69. if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
  70. return fmt.Errorf("invalid list")
  71. }
  72. count := lV.Len()
  73. for i := 0; i < count; i++ {
  74. if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
  75. return fmt.Errorf("invalid itemI")
  76. }
  77. if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
  78. return fmt.Errorf("invalid itemIE")
  79. }
  80. if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
  81. return fmt.Errorf("invalid idFiled")
  82. }
  83. for _, name := range Names {
  84. if nameFiled = itemIE.FieldByName(name); !nameFiled.IsValid() || !nameFiled.CanSet() {
  85. return fmt.Errorf("invalid nameFiled")
  86. }
  87. }
  88. if id = idFiled.Int(); id != 0 {
  89. if _, ok := hashIDName[id]; !ok {
  90. hashIDName[id] = []interface{}{}
  91. ids = append(ids, id)
  92. }
  93. }
  94. }
  95. if hashIDName, err = multrans(c, ids); err != nil {
  96. return
  97. }
  98. for i := 0; i < count; i++ {
  99. itemIE = lV.Index(i).Elem()
  100. id = itemIE.FieldByName(ID).Int()
  101. if names, ok := hashIDName[id]; ok && len(names) == len(Names) {
  102. for i, name := range names {
  103. nameFiled = itemIE.FieldByName(Names[i])
  104. valueField = reflect.ValueOf(name)
  105. if nameFiled.Kind() != valueField.Kind() {
  106. log.Error("multrans return %v while need %v", ids)
  107. continue
  108. }
  109. itemIE.FieldByName(Names[i]).Set(reflect.ValueOf(name))
  110. }
  111. }
  112. }
  113. return
  114. }