// Package event ... // // Description : event ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2023-02-01 14:30 package event import ( "reflect" "strings" "sync" ) var ( // ReflectTypeInstance 反射实例 ReflectTypeInstance *ReflectType ) func init() { ReflectTypeInstance = &ReflectType{ lock: &sync.RWMutex{}, cacheTable: make(map[string]*StructInfo), } } // ReflectType 反射数据类型 // // Author : go_developer@163.com<白茶清欢> // // Date : 14:31 2023/2/1 type ReflectType struct { // 数据锁 lock *sync.RWMutex // 反射结果缓存 cacheTable map[string]*StructInfo } // Do 反射获取数据类型 // // Author : go_developer@163.com<白茶清欢> // // Date : 14:34 2023/2/1 // // 为特定结构体生成全局唯一的标识, 并进行缓存, 加速反射结果获取 func (rt *ReflectType) Do(dataFlag string, data interface{}) *StructInfo { rt.lock.Lock() defer rt.lock.Unlock() if cacheResult, exist := rt.cacheTable[dataFlag]; exist { // 缓存存在, 直接是有缓存结果 return cacheResult } // 缓存不存在, 解析 res := &StructInfo{ Flag: dataFlag, IsStruct: false, StructFieldList: make([]*StructField, 0), } reflectType := reflect.TypeOf(data) if reflectType.Kind() == reflect.Ptr { reflectType = reflectType.Elem() } if reflectType.Kind() != reflect.Struct { // 非结构体,无需反射 rt.cacheTable[dataFlag] = res return res } res.IsStruct = true for idx := 0; idx < reflectType.NumField(); idx++ { field := &StructField{ Idx: idx, Name: reflectType.Field(idx).Name, Type: reflectType.Field(idx).Type.Kind(), JsonTag: reflectType.Field(idx).Tag.Get(JsonTag), EventTag: reflectType.Field(idx).Tag.Get(OutEventTag), MappingRuleList: make([]MappingRuleItem, 0), } rt.fillMappingRule(field, reflectType.Field(idx).Tag.Get(MappingTag)) res.StructFieldList = append(res.StructFieldList, field) } rt.cacheTable[dataFlag] = res return res } // fillTagInfo 填充标签信息 // // Author : go_developer@163.com<白茶清欢> // // Date : 17:11 2023/2/1 func (rt *ReflectType) fillTagInfo(field *StructField) { if len(field.JsonTag) == 0 { field.JsonTag = field.Name } // jsonTag 去掉 omitempty jsonTagValArr := strings.Split(field.JsonTag, ",") for _, item := range jsonTagValArr { if len(item) > 0 && item != OmitemptyTag { field.JsonTag = item break } } // 没有设置event tag,则和 json tag保持一致 if len(field.EventTag) == 0 { field.EventTag = field.JsonTag } } // fillMappingRule 解析参数映射规则 // // Author : go_developer@163.com<白茶清欢> // // Date : 17:14 2023/2/1 // // mapping:"user_id:param#user_id|header#id" func (rt *ReflectType) fillMappingRule(field *StructField, inputMappingVal string) { if len(inputMappingVal) == 0 { // 没有指定规则, 有默认规则 for _, location := range mappingLocationList { field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: location, Field: field.JsonTag, }) } return } mappingArr := strings.Split(inputMappingVal, ",") for _, item := range mappingArr { item = strings.TrimSpace(item) // 要赋值的字段名 itemArr := strings.Split(item, ":") if len(itemArr) != 2 { // 配置格式错误, 跳过 continue } mapRuleArr := strings.Split(strings.TrimSpace(itemArr[1]), "|") for _, itemMapRule := range mapRuleArr { itemMapRule = strings.TrimLeft(itemMapRule, "#") itemMapRuleArr := strings.Split(itemMapRule, "#") // 注意 : # 为特殊分隔符, 如配置成 mapping:"project_id:#source_project_id#xxx_project_id" 实际等价于 mapping:"project_id:#source_project_id" 多余配置自动跳过 if len(itemMapRuleArr[0]) < 2 { // 没有指定位置,默认all, 即配置格式: mapping:"project_id:#source_project_id" itemMapRuleArr[0] = MappingLocationAll itemMapRuleArr = []string{MappingLocationAll, itemMapRuleArr[0]} } switch itemMapRuleArr[0] { // 从header读取 case MappingLocationHeader: field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: MappingLocationHeader, Field: itemMapRuleArr[1], }) // 从请求参数读取 case MappingLocationParam: field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: MappingLocationParam, Field: itemMapRuleArr[1], }) // 从响应数据读取 case MappingLocationResponse: field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: MappingLocationResponse, Field: itemMapRuleArr[1], }) // 从扩展数据读取 case MappingLocationExtension: field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: MappingLocationExtension, Field: itemMapRuleArr[1], }) // 全部读取一遍 case MappingLocationAll: fallthrough default: for _, itemLocation := range mappingLocationList { field.MappingRuleList = append(field.MappingRuleList, MappingRuleItem{ Location: itemLocation, Field: itemMapRuleArr[1], }) } } } } }