Pārlūkot izejas kodu

优化代码结构

yjp 1 gadu atpakaļ
vecāks
revīzija
7a90408e44
2 mainītis faili ar 115 papildinājumiem un 77 dzēšanām
  1. 22 2
      examples/assign_tag/main.go
  2. 93 75
      tag/assign_struct.go

+ 22 - 2
examples/assign_tag/main.go

@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 	"git.sxidc.com/go-framework/baize/tag"
+	"reflect"
 	"time"
 )
 
@@ -28,6 +29,26 @@ type ClassDomain struct {
 }
 
 func main() {
+	class := new(ClassDomain)
+
+	err := tag.CustomAssignTo(&UpdateClassJsonBody{}, class,
+		func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *tag.AssignTag) error {
+			fmt.Println("Field Name:", fromFieldName)
+			fmt.Println("Type:", fromFieldElemValue.Type().String())
+			if fromFieldElemValue.Kind() == reflect.String {
+				fmt.Printf("\"%+v\"\n", fromFieldElemValue.Interface())
+			} else {
+				fmt.Printf("%+v\n", fromFieldElemValue.Interface())
+			}
+			fmt.Printf("%+v\n", tag)
+			fmt.Println()
+
+			return nil
+		})
+	if err != nil {
+		panic(err)
+	}
+
 	now := time.Now()
 
 	jsonBody := &UpdateClassJsonBody{
@@ -38,8 +59,7 @@ func main() {
 		CreatedTime: &now,
 	}
 
-	class := new(ClassDomain)
-	err := tag.AssignTo(jsonBody, class)
+	err = tag.AssignTo(jsonBody, class)
 	if err != nil {
 		panic(err)
 	}

+ 93 - 75
tag/assign_struct.go

@@ -10,7 +10,19 @@ import (
 	"time"
 )
 
+type OnAssignParsedFieldTagFunc func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error
+
 func AssignTo(from any, to any) error {
+	return CustomAssignTo(from, to, func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error {
+		if fromFieldElemValue.IsZero() {
+			return nil
+		}
+
+		return assignField(fromFieldElemValue, retFieldElementValue, tag)
+	})
+}
+
+func CustomAssignTo(from any, to any, onParsedFieldTagFunc OnAssignParsedFieldTagFunc) error {
 	if from == nil || to == nil {
 		return nil
 	}
@@ -42,7 +54,7 @@ func AssignTo(from any, to any) error {
 		}
 	}
 
-	err := assignTo(fromElemValue, &retElemValue)
+	err := parseStructAssignTag(fromElemValue, &retElemValue, onParsedFieldTagFunc)
 	if err != nil {
 		return err
 	}
@@ -50,75 +62,7 @@ func AssignTo(from any, to any) error {
 	return nil
 }
 
-func assignTo(fromElemValue reflect.Value, retElemValue *reflect.Value) error {
-	for i := 0; i < fromElemValue.NumField(); i++ {
-		fromField := fromElemValue.Type().Field(i)
-		fromFieldValue := fromElemValue.Field(i)
-
-		// 无效零值,不进行赋值
-		if !fromFieldValue.IsValid() || fromFieldValue.IsZero() {
-			continue
-		}
-
-		fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
-
-		tagStr := fromField.Tag.Get(assignTagKey)
-
-		// 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
-		if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
-			!reflectutils.IsValueTime(fromFieldElemValue) {
-			err := assignTo(fromFieldElemValue, retElemValue)
-			if err != nil {
-				return err
-			}
-
-			continue
-		}
-
-		tag, err := parseAssignTag(fromField, tagStr)
-		if err != nil {
-			return err
-		}
-
-		if tag == nil {
-			continue
-		}
-
-		retFieldValue := retElemValue.FieldByName(tag.ToField)
-
-		// 不存在对应的字段
-		if !retFieldValue.IsValid() {
-			continue
-		}
-
-		retFieldElemValue := retFieldValue
-		if retFieldValue.Kind() == reflect.Pointer {
-			if !retFieldValue.IsValid() {
-				continue
-			}
-
-			if !retFieldValue.CanSet() {
-				continue
-			}
-
-			// 空值针,初始化
-			if retFieldValue.IsNil() {
-				retFieldValue.Set(reflect.New(retFieldValue.Type().Elem()))
-			}
-
-			retFieldElemValue = retFieldValue.Elem()
-		}
-
-		err = assignField(fromFieldElemValue, retFieldElemValue, tag)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Value, tag *assignTag) error {
+func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Value, tag *AssignTag) error {
 	fromKind := reflectutils.GroupValueKind(fromFieldElemValue)
 	retKind := reflectutils.GroupValueKind(retFieldElemValue)
 
@@ -134,7 +78,9 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
 
 		// 不是time.Time类型的结构,接收字段是结构,执行结构到结构字段的赋值
 		if !reflectutils.IsValueTime(fromFieldElemValue) && retKind == reflect.Struct {
-			return assignTo(fromFieldElemValue, &retFieldElemValue)
+			return parseStructAssignTag(fromFieldElemValue, &retFieldElemValue, func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error {
+				return assignField(fromFieldElemValue, retFieldElementValue, tag)
+			})
 		}
 
 		// 直接将整个结构进行字段赋值
@@ -187,7 +133,7 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
 	}
 }
 
-func assignTrimFromString(fromString string, tag *assignTag) string {
+func assignTrimFromString(fromString string, tag *AssignTag) string {
 	if strutils.IsStringNotEmpty(tag.Trim) {
 		return strings.Trim(fromString, tag.Trim)
 	} else {
@@ -203,6 +149,78 @@ func assignTrimFromString(fromString string, tag *assignTag) string {
 	return fromString
 }
 
+func parseStructAssignTag(fromElemValue reflect.Value, retElemValue *reflect.Value, onParsedFieldTagFunc OnAssignParsedFieldTagFunc) error {
+	for i := 0; i < fromElemValue.NumField(); i++ {
+		fromField := fromElemValue.Type().Field(i)
+		fromFieldValue := fromElemValue.Field(i)
+
+		// 无效值
+		if !fromFieldValue.IsValid() {
+			continue
+		}
+
+		if fromFieldValue.Kind() == reflect.Pointer && fromFieldValue.IsNil() {
+			fromFieldValue.Set(reflect.New(fromField.Type.Elem()))
+		}
+
+		fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
+
+		tagStr := fromField.Tag.Get(assignTagKey)
+
+		// 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
+		if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
+			!reflectutils.IsValueTime(fromFieldElemValue) {
+			err := parseStructAssignTag(fromFieldElemValue, retElemValue, onParsedFieldTagFunc)
+			if err != nil {
+				return err
+			}
+
+			continue
+		}
+
+		tag, err := parseAssignTag(fromField, tagStr)
+		if err != nil {
+			return err
+		}
+
+		if tag == nil {
+			continue
+		}
+
+		retFieldValue := retElemValue.FieldByName(tag.ToField)
+
+		// 不存在对应的字段
+		if !retFieldValue.IsValid() {
+			continue
+		}
+
+		retFieldElemValue := retFieldValue
+		if retFieldValue.Kind() == reflect.Pointer {
+			if !retFieldValue.IsValid() {
+				continue
+			}
+
+			if !retFieldValue.CanSet() {
+				continue
+			}
+
+			// 空值针,初始化
+			if retFieldValue.IsNil() {
+				retFieldValue.Set(reflect.New(retFieldValue.Type().Elem()))
+			}
+
+			retFieldElemValue = retFieldValue.Elem()
+		}
+
+		err = onParsedFieldTagFunc(fromField.Name, fromFieldElemValue, retFieldElemValue, tag)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 const (
 	assignDefaultStringSliceSeparator = "::"
 	assignTagPartSeparator            = ";"
@@ -222,7 +240,7 @@ const (
 	assignTrimSuffix = "trimSuffix"
 )
 
-type assignTag struct {
+type AssignTag struct {
 	ToField    string
 	ParseTime  string
 	FormatTime string
@@ -233,12 +251,12 @@ type assignTag struct {
 	TrimSuffix string
 }
 
-func parseAssignTag(field reflect.StructField, tagStr string) (*assignTag, error) {
+func parseAssignTag(field reflect.StructField, tagStr string) (*AssignTag, error) {
 	if tagStr == assignIgnore {
 		return nil, nil
 	}
 
-	tag := &assignTag{
+	tag := &AssignTag{
 		ToField:    field.Name,
 		ParseTime:  time.DateTime,
 		FormatTime: time.DateTime,