123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- 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
- }
|