package td_builder import ( "fmt" "reflect" ) func scan(data interface{}) (*StructMate, error) { // 获取结构体的类型 t, v := getReflectTypeAndValue(data) // 确保是结构体类型 if t.Kind() != reflect.Struct { return nil, fmt.Errorf("input data is not a struct") } // 获取包路径和类型名称 uniqueTypeName := getUniqueTypeName(t) // 初始化结果结构体 sr := StructMate{ UniqueTypeName: uniqueTypeName, FieldIndexCache: make(map[string][]int, t.NumField()), FiledDBNameCache: make(map[string]string, t.NumField()), DBAnnotatedNames: make([]string, 0, t.NumField()), TaggedFieldNames: make([]string, 0, t.NumField()), SuperTableName: "", } //timeType := reflect.TypeOf(time.Time{}) // 遍历结构体的字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i) fieldValue := v.Field(i) if field.Anonymous { if field.Type.Kind() == reflect.Ptr { if fieldValue.IsNil() { // 如果指针是 nil,创建一个该类型的零值实例 zeroValue := reflect.Zero(field.Type.Elem()) fieldValue = zeroValue } else { fieldValue = fieldValue.Elem() } } if !fieldValue.CanInterface() { continue } subResult, err := scan(fieldValue.Interface()) if err != nil { return nil, err } for k, v := range subResult.FieldIndexCache { sr.FieldIndexCache[k] = append(sr.FieldIndexCache[k], i) sr.FieldIndexCache[k] = append(sr.FieldIndexCache[k], v...) } for k, v := range subResult.FiledDBNameCache { sr.FiledDBNameCache[k] = v } sr.DBAnnotatedNames = append(sr.DBAnnotatedNames, subResult.DBAnnotatedNames...) sr.TaggedFieldNames = append(sr.TaggedFieldNames, subResult.TaggedFieldNames...) continue } //// 如果字段是结构体或结构体指针,递归处理 //if (field.Type.Kind() == reflect.Struct || field.Type.Kind() == reflect.Ptr) && field.Type != timeType { // // if field.Type.Kind() == reflect.Ptr { // if fieldValue.IsNil() { // // 如果指针是 nil,创建一个该类型的零值实例 // zeroValue := reflect.Zero(field.Type.Elem()) // fieldValue = zeroValue // } else { // fieldValue = fieldValue.Elem() // } // } // // if !fieldValue.CanInterface() { // continue // } // // subResult, err := scan(fieldValue.Interface()) // if err != nil { // return nil, err // } // sr.merge(subResult) // continue //} // 检查字段是否有db注解 columnName := field.Tag.Get("db") if columnName == "-" || columnName == "" { continue } sr.FieldIndexCache[field.Name] = []int{i} sr.FiledDBNameCache[field.Name] = columnName // 检查字段是否有taos注解 if field.Tag.Get("taos") == "tag" { sr.TaggedFieldNames = append(sr.TaggedFieldNames, field.Name) } else { sr.DBAnnotatedNames = append(sr.DBAnnotatedNames, field.Name) } } sr.SuperTableName = callSuperTableName(data) return &sr, nil } // 获取包路径和类型名称 func getUniqueTypeName(t reflect.Type) string { pkgPath := t.PkgPath() typeName := t.Name() uniqueTypeName := fmt.Sprintf("%s.%s", pkgPath, typeName) return uniqueTypeName } func getReflectTypeAndValue(data interface{}) (reflect.Type, reflect.Value) { t := reflect.TypeOf(data) v := reflect.ValueOf(data) // 处理结构体和结构体指针 for t.Kind() == reflect.Ptr { t = t.Elem() v = v.Elem() } return t, v } func callSuperTableName(obj any) string { v := reflect.ValueOf(obj) if v.Kind() == reflect.Struct { return "" } // 检查是否可以调用 SuperTableName 方法 superTableNameMethod := v.MethodByName("SuperTableName") if !superTableNameMethod.IsValid() { return "" } // 调用 SuperTableName 方法 results := superTableNameMethod.Call(nil) if len(results) == 1 && results[0].Kind() == reflect.String { return results[0].String() } return "" }