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

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