package sql_result import ( "fmt" "git.sxidc.com/go-tools/utils/encoding" "git.sxidc.com/go-tools/utils/reflectutils" "git.sxidc.com/go-tools/utils/strutils" "github.com/pkg/errors" "reflect" "strings" "time" ) const ( timeMicroFormat = "2006-01-02T15:04:05.000000" timeMilliFormat = "2006-01-02T15:04:05.000" timeSecFormat = "2006-01-02T15:04:05" ) func DefaultUsage(result map[string]any, e any, columnName string) error { if result == nil || len(result) == 0 { return nil } err := UseTag(e, defaultCallback(result, columnName)) if err != nil { return err } return nil } func defaultCallback(result map[string]any, columnName string) OnParsedFieldTagFunc { return func(fieldName string, entityFieldElemValue reflect.Value, tag *Tag) error { if strutils.IsStringNotEmpty(columnName) && columnName != tag.Name { return nil } resultValue, ok := result[tag.Name] if !ok { return nil } if resultValue == nil { return nil } entityFieldKind := reflectutils.GroupValueKind(entityFieldElemValue) switch entityFieldKind { case reflect.Bool: return reflectutils.AssignBoolValue(resultValue, entityFieldElemValue) case reflect.String: strValue, ok := resultValue.(string) if ok { // 实体字段是字符串类型,接收到的是数据库时间格式 parsedTime, err := parseTimeStringResult(strValue) if err == nil { // 转换成功说明是时间字符串 strValue = parsedTime.Format(tag.TimeLayout) } parsedValue, err := dealStringResultValue(strValue, tag) if err != nil { return err } return reflectutils.AssignStringValue(parsedValue, entityFieldElemValue) } timeResult, ok := resultValue.(time.Time) if ok { return reflectutils.AssignStringValue(timeResult.Format(tag.TimeLayout), entityFieldElemValue) } return errors.New("查询到的值无法赋值为string类型") case reflect.Int64: return reflectutils.AssignInt64Value(resultValue, entityFieldElemValue) case reflect.Uint64: return reflectutils.AssignUint64Value(resultValue, entityFieldElemValue) case reflect.Float64: return reflectutils.AssignFloat64Value(resultValue, entityFieldElemValue) case reflect.Struct: // 实体字段是time.Time,接收到的是数据库时间格式 if reflectutils.IsValueTime(entityFieldElemValue) { timeStr, ok := resultValue.(string) if ok { parsedTime, err := parseTimeStringResult(timeStr) if err != nil { return err } entityFieldElemValue.Set(reflect.ValueOf(parsedTime)) return nil } timeResult, ok := resultValue.(time.Time) if ok { entityFieldElemValue.Set(reflect.ValueOf(timeResult)) return nil } return errors.New("查询到的值无法赋值为time.Time类型") } return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s", fieldName, tag.Name, entityFieldElemValue.Type().String()) case reflect.Slice: if !reflectutils.IsSliceValueOf(entityFieldElemValue, reflect.String) { return errors.New(fieldName + " Error: slice仅支持[]string") } strValue, ok := resultValue.(string) if !ok { return errors.New("Result Type Error: slice仅支持[]string") } strParts := strings.Split(strValue, tag.SplitWith) if strParts == nil || len(strParts) == 0 { return nil } valSlice := entityFieldElemValue if valSlice.IsNil() { valSlice = reflect.MakeSlice(entityFieldElemValue.Type(), 0, 0) } for _, strPart := range strParts { valSlice = reflect.Append(valSlice, reflect.ValueOf(strPart)) } entityFieldElemValue.Set(valSlice) return nil default: return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s", fieldName, tag.Name, entityFieldElemValue.Type().String()) } } } func parseTimeStringResult(timeStr string) (time.Time, error) { layout := timeSecFormat timeZoneIndex := strings.LastIndex(timeStr, "+08:") if timeZoneIndex != -1 { timeStr = timeStr[:timeZoneIndex] afterSecondIndex := strings.LastIndex(timeStr, ".") if afterSecondIndex != -1 { if len(timeStr)-afterSecondIndex-1 == 6 { layout = timeMicroFormat } else if len(timeStr)-afterSecondIndex-1 == 3 { layout = timeMilliFormat } } } parsedTime, err := time.ParseInLocation(layout, timeStr, time.Local) if err != nil { return time.Time{}, errors.New(err.Error()) } return parsedTime, nil } func dealStringResultValue(value string, tag *Tag) (string, error) { retValue := value if strutils.IsStringNotEmpty(tag.AESKey) { decryptedValue, err := encoding.AESDecrypt(retValue, tag.AESKey) if err != nil { return "", err } retValue = decryptedValue } if strutils.IsStringNotEmpty(tag.Trim) { retValue = strings.Trim(retValue, tag.Trim) } else { if strutils.IsStringNotEmpty(tag.TrimPrefix) { retValue = strings.TrimPrefix(retValue, tag.TrimPrefix) } if strutils.IsStringNotEmpty(tag.TrimSuffix) { retValue = strings.TrimSuffix(retValue, tag.TrimSuffix) } } return retValue, nil }