123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package rule
- import (
- "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
- "git.sxidc.com/go-tools/utils/reflectutils"
- "git.sxidc.com/go-tools/utils/strutils"
- "git.sxidc.com/go-tools/utils/template"
- "github.com/iancoleman/strcase"
- "github.com/pkg/errors"
- "reflect"
- "strings"
- )
- const (
- TypeString = "string"
- TypeTime = "time"
- TypeNumber = "number"
- TypeBool = "bool"
- )
- func IsSupportedType(typeStr string) bool {
- return typeStr == TypeString || typeStr == TypeTime || typeStr == TypeNumber || typeStr == TypeBool
- }
- const (
- tagPartSeparator = ";"
- tagPartKeyValueSeparator = ":"
- )
- const (
- tagKey = "rule"
- tagPartColumn = "column"
- tagPartType = "type"
- )
- type Tag struct {
- ColumnName string
- Type string
- }
- func parseTag(entityElemValue reflect.Value, onParsedFieldTagFunc OnParsedFieldTagFunc) error {
- for i := 0; i < entityElemValue.NumField(); i++ {
- entityField := entityElemValue.Type().Field(i)
- entityFieldValue := entityElemValue.Field(i)
- // 无效值,不进行映射
- if !entityFieldValue.IsValid() {
- continue
- }
- entityFieldElemValue := reflectutils.PointerValueElem(entityFieldValue)
- tagStr, ok := entityField.Tag.Lookup(tagKey)
- if !ok {
- continue
- }
- tag, err := parseFieldTag(entityField, tagStr)
- if err != nil {
- return err
- }
- if tag == nil {
- continue
- }
- // 结构类型的字段,解析结构内部
- if entityFieldElemValue.Kind() == reflect.Struct &&
- !reflectutils.IsValueTime(entityFieldElemValue) {
- err := parseTag(entityFieldElemValue, onParsedFieldTagFunc)
- if err != nil {
- return err
- }
- continue
- }
- err = onParsedFieldTagFunc(entityField.Name, entityFieldElemValue, tag)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
- fieldType := reflectutils.PointerTypeElem(field.Type)
- fieldKind := reflectutils.GroupTypeKind(fieldType)
- var fieldTypeStr string
- if fieldKind == reflect.Int64 || fieldKind == reflect.Uint64 || fieldKind == reflect.Float64 {
- fieldTypeStr = TypeNumber
- } else if fieldKind == reflect.String {
- fieldTypeStr = TypeString
- } else if fieldKind == reflect.Struct && fieldType.String() == "time.Time" {
- fieldTypeStr = TypeTime
- } else if fieldKind == reflect.Bool {
- fieldTypeStr = TypeBool
- } else {
- return nil, errors.New("type支持的类型包括: string, number, time")
- }
- tag := &Tag{
- ColumnName: strcase.ToSnake(template.Id(field.Name)),
- Type: fieldTypeStr,
- }
- if strutils.IsStringEmpty(tagStr) {
- return tag, nil
- }
- tagParts := strings.Split(tagStr, tagPartSeparator)
- if tagParts != nil || len(tagParts) != 0 {
- for _, tagPart := range tagParts {
- tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
- if tagPartKeyValue != nil && len(tagPartKeyValue) == 2 && strutils.IsStringNotEmpty(tagPartKeyValue[1]) {
- tagPartKeyValue[1] = strings.Trim(tagPartKeyValue[1], "'")
- }
- if strutils.IsStringEmpty(tagPartKeyValue[0]) {
- continue
- }
- switch tagPartKeyValue[0] {
- case tagPartColumn:
- if strutils.IsStringEmpty(tagPartKeyValue[1]) {
- return nil, errors.New("column没有赋值列名")
- }
- tag.ColumnName = tagPartKeyValue[1]
- case tagPartType:
- if strutils.IsStringEmpty(tagPartKeyValue[1]) {
- return nil, errors.New("type没有赋值字段类型")
- }
- if !IsSupportedType(tagPartKeyValue[1]) {
- return nil, errors.Errorf("类型为%v, type支持的类型包括: string, number, time", tagPartKeyValue[1])
- }
- tag.Type = tagPartKeyValue[1]
- default:
- err := errors.New(tagKey + "不支持的tag: " + tagPartKeyValue[0])
- logger.GetInstance().Error(err)
- continue
- }
- }
- }
- return tag, nil
- }
|