gitee.com/quant1x/gox@v1.21.2/tags/tags.go (about)

     1  package tags
     2  
     3  import (
     4  	"fmt"
     5  	"gitee.com/quant1x/gox/api"
     6  	"reflect"
     7  	"strings"
     8  )
     9  
    10  const (
    11  	StructDefaultTagNameOfTableHeader = "name"
    12  )
    13  
    14  var (
    15  	// 结构体tag映射
    16  	__mapStructTags = map[reflect.Type]map[int]string{}
    17  	// 结构体作为TableView显示的表头
    18  	__mapTableHeaders = map[reflect.Type][]string{}
    19  )
    20  
    21  // GetFieldTags 缓存字段Tag
    22  func GetFieldTags(t reflect.Type, tag ...string) map[int]string {
    23  	ma, mok := __mapStructTags[t]
    24  	if mok {
    25  		return ma
    26  	}
    27  	tagName := StructDefaultTagNameOfTableHeader
    28  	if len(tag) > 0 {
    29  		tagName = tag[0]
    30  	}
    31  	ma = nil
    32  	fieldNum := t.NumField()
    33  	for i := 0; i < fieldNum; i++ {
    34  		field := t.Field(i)
    35  		tag := field.Tag
    36  		if len(tag) > 0 {
    37  			tv, ok := tag.Lookup(tagName)
    38  			tv, _, _ = strings.Cut(tv, ",")
    39  			if ok {
    40  				tv = strings.TrimSpace(tv)
    41  				if ma == nil {
    42  					ma = make(map[int]string)
    43  					__mapStructTags[t] = ma
    44  				}
    45  				ma[i] = tv
    46  			}
    47  		}
    48  	}
    49  	return ma
    50  }
    51  
    52  // GetStructHeaders 获取structs表头
    53  func GetStructHeaders(t reflect.Type, tag ...string) []string {
    54  	v, ok := __mapTableHeaders[t]
    55  	if ok {
    56  		return v
    57  	}
    58  	tagName := StructDefaultTagNameOfTableHeader
    59  	if len(tag) > 0 {
    60  		tagName = tag[0]
    61  	}
    62  	mapTags := GetFieldTags(t, tagName)
    63  	var headers []string
    64  	if len(mapTags) == 0 {
    65  		return headers
    66  	}
    67  	fieldNum := t.NumField()
    68  	for i := 0; i < fieldNum; i++ {
    69  		field, ok := mapTags[i]
    70  		if ok {
    71  			headers = append(headers, field)
    72  		}
    73  	}
    74  	__mapTableHeaders[t] = headers
    75  	return headers
    76  }
    77  
    78  func checkStructType(value any) (reflect.Type, reflect.Value) {
    79  	obj := reflect.ValueOf(value)
    80  	t := obj.Type()
    81  	if obj.Kind() == reflect.Ptr {
    82  		t = t.Elem()
    83  		obj = obj.Elem()
    84  	}
    85  	return t, obj
    86  }
    87  
    88  // GetHeadersByTags 获取字段表头
    89  func GetHeadersByTags(value any, tag ...string) []string {
    90  	t, _ := checkStructType(value)
    91  	return GetStructHeaders(t, tag...)
    92  
    93  }
    94  
    95  // GetValuesByTags Values 输出表格的行和列
    96  func GetValuesByTags(value any, tag ...string) []string {
    97  	t, obj := checkStructType(value)
    98  	mapTags := GetFieldTags(t, tag...)
    99  	var values []string
   100  	if len(mapTags) == 0 {
   101  		return values
   102  	}
   103  	fieldNum := t.NumField()
   104  	for i := 0; i < fieldNum; i++ {
   105  		_, ok := mapTags[i]
   106  		if ok {
   107  			ov := obj.Field(i).Interface()
   108  			var str string
   109  			switch v := ov.(type) {
   110  			case float32:
   111  				str = fmt.Sprintf("%.02f", api.Decimal(float64(v)))
   112  			case float64:
   113  				str = fmt.Sprintf("%.02f", api.Decimal(v))
   114  			default:
   115  				str = api.ToString(ov)
   116  			}
   117  			values = append(values, str)
   118  		}
   119  	}
   120  	return values
   121  }