124 lines
4.0 KiB
Go
124 lines
4.0 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"reflect"
|
||
|
||
"go-common/library/log"
|
||
)
|
||
|
||
// 每个ID单独查询 strict严格模式下一次错误,直接返回
|
||
func (s *Service) singleIDtoName(c context.Context, list interface{}, singletrans func(context.Context, int64) ([]interface{}, error), strict bool, ID string, Names ...string) (err error) {
|
||
var (
|
||
lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
|
||
id int64
|
||
values []interface{}
|
||
)
|
||
|
||
if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
|
||
return fmt.Errorf("invalid list")
|
||
}
|
||
|
||
count := lV.Len()
|
||
for i := 0; i < count; i++ {
|
||
if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
|
||
return fmt.Errorf("invalid itemI")
|
||
}
|
||
if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
|
||
return fmt.Errorf("invalid itemIE")
|
||
}
|
||
if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
|
||
return fmt.Errorf("invalid idFiled")
|
||
}
|
||
for _, Name := range Names {
|
||
if nameFiled = itemIE.FieldByName(Name); !nameFiled.IsValid() || !nameFiled.CanSet() {
|
||
return fmt.Errorf("invalid nameFiled")
|
||
}
|
||
}
|
||
|
||
if id = idFiled.Int(); id != 0 {
|
||
if values, err = singletrans(c, id); err != nil || len(values) != len(Names) {
|
||
log.Error("s.sigleIDtoName error(%v) len(values)=%d len(Names)=%d", err, len(values), len(Names))
|
||
if strict {
|
||
return
|
||
}
|
||
err = nil
|
||
continue
|
||
}
|
||
for i, value := range values {
|
||
nameFiled = itemIE.FieldByName(Names[i])
|
||
valueField = reflect.ValueOf(value)
|
||
if nameFiled.Kind() != valueField.Kind() {
|
||
log.Error("singletrans return %s while need %s", valueField.Kind().String(), nameFiled.Kind().String())
|
||
continue
|
||
}
|
||
nameFiled.Set(valueField)
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
/* 批量查询,批量转换
|
||
* list []*struct{}
|
||
* multrans 转化器,根据ID查出其他值
|
||
* ID id字段名称,id字段类型必须是int64
|
||
* Names 查出来的各个字段名称
|
||
*/
|
||
func (s *Service) mulIDtoName(c context.Context, list interface{}, multrans func(context.Context, []int64) (map[int64][]interface{}, error), ID string, Names ...string) (err error) {
|
||
var (
|
||
lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
|
||
id int64
|
||
ids []int64
|
||
hashIDName = make(map[int64][]interface{})
|
||
)
|
||
|
||
if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
|
||
return fmt.Errorf("invalid list")
|
||
}
|
||
|
||
count := lV.Len()
|
||
for i := 0; i < count; i++ {
|
||
if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
|
||
return fmt.Errorf("invalid itemI")
|
||
}
|
||
if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
|
||
return fmt.Errorf("invalid itemIE")
|
||
}
|
||
if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
|
||
return fmt.Errorf("invalid idFiled")
|
||
}
|
||
for _, name := range Names {
|
||
if nameFiled = itemIE.FieldByName(name); !nameFiled.IsValid() || !nameFiled.CanSet() {
|
||
return fmt.Errorf("invalid nameFiled")
|
||
}
|
||
}
|
||
if id = idFiled.Int(); id != 0 {
|
||
if _, ok := hashIDName[id]; !ok {
|
||
hashIDName[id] = []interface{}{}
|
||
ids = append(ids, id)
|
||
}
|
||
}
|
||
}
|
||
if hashIDName, err = multrans(c, ids); err != nil {
|
||
return
|
||
}
|
||
for i := 0; i < count; i++ {
|
||
itemIE = lV.Index(i).Elem()
|
||
id = itemIE.FieldByName(ID).Int()
|
||
if names, ok := hashIDName[id]; ok && len(names) == len(Names) {
|
||
for i, name := range names {
|
||
nameFiled = itemIE.FieldByName(Names[i])
|
||
valueField = reflect.ValueOf(name)
|
||
if nameFiled.Kind() != valueField.Kind() {
|
||
log.Error("multrans return %v while need %v", ids)
|
||
continue
|
||
}
|
||
itemIE.FieldByName(Names[i]).Set(reflect.ValueOf(name))
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|