// Package json_tool ... // // Description : json_tool ... // // Author : go_developer@163.com<张德满> // // Date : 2022/01/22 9:19 PM package json_tool import ( "reflect" "strings" "github.com/pkg/errors" "github.com/tidwall/gjson" "github.com/Jeffail/gabs" ) // FilterDataRule 参数过滤规则 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:44 PM type FilterDataRule struct { SourceKey string // 原始数据路径 MapKey string // 提取后映射到的数据路径 DefaultValue interface{} // 原始数据路径不存在时的默认值 WithDefault bool // 是否使用默认值 } // NewDataFilter 获取数据过滤方法实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:50 PM func NewDataFilter(source string, filterRule []FilterDataRule) *DataFilter { return &DataFilter{ source: source, filterRule: filterRule, } } // DataFilter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:20 PM type DataFilter struct { source string filterRule []FilterDataRule } // Filter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:36 PM func (df *DataFilter) Filter() (string, error) { var ( jsonObject *gabs.Container err error ) // 记录 obj => slice 的数据类型 obg2slice := make(map[string]string) // 创建数据的根结点 jsonObject = gabs.New() for _, item := range df.filterRule { if df.pathIsArrayValue(item.SourceKey) { // 数组, 特殊处理 // 0. 判断目标路径是否为数组 if !df.pathIsArrayValue(item.MapKey) { // 目标路径不是数组, 转换为支持list, 后续逻辑会自动提取为list数组 item.MapKey = item.MapKey + ".[]" } else { // 1. 判断数据源数组深度与目标数组深度是否一致 sourcePathArr := strings.Split(item.SourceKey, ".[].") mapPathArr := strings.Split(item.MapKey, ".[].") if len(sourcePathArr) != len(mapPathArr) { return "", errors.New("slice转化原始数据深度与目标数据深度不一致") } continue } } // 目标位置, 是一个数组 if df.pathIsArrayValue(item.MapKey) { realMapKey := strings.ReplaceAll(item.MapKey, ".[]", "") if exist := jsonObject.Exists(realMapKey); !exist { if _, err = jsonObject.ArrayP(realMapKey); nil != err { return "", err } } valueResult := gjson.Get(df.source, item.SourceKey) dataType := df.getValueType(valueResult) if _, exist := obg2slice[realMapKey]; !exist { obg2slice[realMapKey] = dataType } if dataType != obg2slice[realMapKey] { return "", errors.New(realMapKey + " 预期写入的字段数据类型不一致") } if err = jsonObject.ArrayAppend(valueResult.Value(), realMapKey); nil != err { return "", err } continue } sourceSearchResult := gjson.Get(df.source, item.SourceKey) if !sourceSearchResult.Exists() { if item.WithDefault { if _, err = jsonObject.SetP(item.DefaultValue, item.MapKey); nil != err { return "", err } } continue } if _, err = jsonObject.SetP(sourceSearchResult.Value(), item.MapKey); nil != err { return "", err } } return jsonObject.String(), nil } // getValueType 获取数据类型 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/23 12:45 AM func (df *DataFilter) getValueType(valueResult gjson.Result) string { dataType := reflect.TypeOf(valueResult.Value()).String() if strings.Contains(dataType, "int") { return "int64" } if strings.Contains(dataType, "float") { return "float64" } return dataType } // pathIsArrayValue 判断路径是否为数组值 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/23 12:56 AM func (df *DataFilter) pathIsArrayValue(path string) bool { return strings.Contains(path, "[]") }