2021-09-09 14:31:40 +08:00
|
|
|
// Package json_tool ...
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Description : 将复杂数据结构转化为 JSONNode 树
|
|
|
|
//
|
2021-07-25 19:05:59 +08:00
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Date : 2021-03-14 10:40 下午
|
2021-09-09 14:31:40 +08:00
|
|
|
package json_tool
|
2021-03-14 23:31:08 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2021-04-13 22:11:52 +08:00
|
|
|
"fmt"
|
2021-03-14 23:31:08 +08:00
|
|
|
"reflect"
|
2021-04-13 21:53:36 +08:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/tidwall/gjson"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2021-03-14 23:31:08 +08:00
|
|
|
|
2021-07-25 18:50:56 +08:00
|
|
|
"git.zhangdeman.cn/zhangdeman/gopkg/util"
|
2021-03-14 23:31:08 +08:00
|
|
|
)
|
|
|
|
|
2022-01-17 18:09:50 +08:00
|
|
|
// MapDataRule 数据映射结果
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 5:09 PM 2022/1/17
|
|
|
|
type MapDataRule struct {
|
|
|
|
MapKey string
|
|
|
|
DefaultValue string
|
|
|
|
IsComplexType bool
|
|
|
|
}
|
|
|
|
|
2022-01-09 23:59:43 +08:00
|
|
|
// NewFilter 获取解析的实例
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
2021-07-25 19:05:59 +08:00
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Date : 10:43 下午 2021/3/14
|
2022-01-17 18:09:50 +08:00
|
|
|
func NewFilter(data interface{}, rule map[string]MapDataRule) *Filter {
|
2021-09-10 11:36:48 +08:00
|
|
|
return &Filter{
|
|
|
|
data: data,
|
|
|
|
rule: rule,
|
|
|
|
}
|
2021-03-14 23:31:08 +08:00
|
|
|
}
|
|
|
|
|
2022-01-09 23:59:43 +08:00
|
|
|
// Filter 解析json树
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
2021-07-25 19:05:59 +08:00
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Date : 10:41 下午 2021/3/14
|
2021-09-10 11:36:48 +08:00
|
|
|
type Filter struct {
|
2021-03-14 23:31:08 +08:00
|
|
|
data interface{}
|
2022-01-17 18:09:50 +08:00
|
|
|
rule map[string]MapDataRule
|
2021-03-14 23:31:08 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 11:36:48 +08:00
|
|
|
// Result 数据过滤结果
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
2021-07-25 19:05:59 +08:00
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Date : 10:44 下午 2021/3/14
|
2021-09-10 11:36:48 +08:00
|
|
|
func (f *Filter) Result() (*DynamicJSON, error) {
|
|
|
|
if !f.isLegalData() {
|
2021-04-13 21:53:36 +08:00
|
|
|
return nil, errors.New("非法的数据,无法转换成json")
|
|
|
|
}
|
|
|
|
result := NewDynamicJSON()
|
2021-09-10 11:36:48 +08:00
|
|
|
byteData, _ := json.Marshal(f.data)
|
2021-04-13 21:53:36 +08:00
|
|
|
source := string(byteData)
|
2022-01-17 18:09:50 +08:00
|
|
|
for extraDataPath, newDataRule := range f.rule {
|
2021-04-13 21:53:36 +08:00
|
|
|
// 为数组的处理
|
2021-09-10 11:36:48 +08:00
|
|
|
pathArr := strings.Split(extraDataPath, ".[].")
|
2021-04-13 23:43:04 +08:00
|
|
|
val := gjson.Get(source, pathArr[0])
|
|
|
|
if len(pathArr) == 1 {
|
2022-01-17 18:09:50 +08:00
|
|
|
f.SetValue(result, newDataRule.MapKey, val.Value(), false, 0)
|
2021-04-13 23:43:04 +08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
// 支持list再抽取一层,处于性能考虑,这么限制,不做递归无限深度处理
|
|
|
|
// 还能继续抽取,就认为是 []map[string]interface{}
|
2022-01-22 21:02:40 +08:00
|
|
|
keyList := strings.Split(pathArr[1], ".")
|
2021-04-13 23:43:04 +08:00
|
|
|
for idx, item := range val.Array() {
|
|
|
|
data := item.Map()
|
2022-01-22 21:02:40 +08:00
|
|
|
for _, key := range keyList {
|
|
|
|
if _, exist := data[key]; exist {
|
|
|
|
result.SetValue(strings.ReplaceAll(newDataRule.MapKey, "[]", fmt.Sprintf("[%d]", idx)), data[key].String(), newDataRule.IsComplexType)
|
2022-01-17 18:09:50 +08:00
|
|
|
} else {
|
|
|
|
// 结果集中不存在对应key,设置默认值
|
|
|
|
result.SetValue(strings.ReplaceAll(newDataRule.MapKey, "[]", fmt.Sprintf("[%d]", idx)), newDataRule.DefaultValue, newDataRule.IsComplexType)
|
2021-04-13 22:11:52 +08:00
|
|
|
}
|
2021-04-13 21:53:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result, nil
|
2021-03-14 23:31:08 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 18:05:49 +08:00
|
|
|
// SetValue 设置值
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 12:14 下午 2021/9/10
|
|
|
|
func (f *Filter) SetValue(result *DynamicJSON, path string, val interface{}, isSetSlice bool, sliceIndex int) {
|
|
|
|
if !isSetSlice {
|
|
|
|
result.SetValue(path, val, false)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-14 23:31:08 +08:00
|
|
|
// isLegalData 判断是否能转换成json结构, 只有slice/map/struct/能转换成slice或map的[]byte是合法的
|
|
|
|
//
|
2021-07-25 19:05:59 +08:00
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
2021-03-14 23:31:08 +08:00
|
|
|
//
|
|
|
|
// Date : 10:46 下午 2021/3/14
|
2021-09-10 11:36:48 +08:00
|
|
|
func (f *Filter) isLegalData() bool {
|
|
|
|
val := reflect.ValueOf(f.data)
|
2021-03-14 23:31:08 +08:00
|
|
|
|
|
|
|
switch val.Kind() {
|
|
|
|
case reflect.Slice:
|
|
|
|
// slice 情况下,对字节数组进行特殊判断
|
|
|
|
var (
|
|
|
|
byteData []byte
|
|
|
|
ok bool
|
|
|
|
err error
|
|
|
|
)
|
2021-09-10 11:36:48 +08:00
|
|
|
if byteData, ok = f.data.([]byte); ok {
|
2021-03-14 23:31:08 +08:00
|
|
|
// 字节数组转map或者slice
|
2021-09-10 11:36:48 +08:00
|
|
|
if err = json.Unmarshal(byteData, &f.data); nil != err {
|
2021-03-14 23:31:08 +08:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
case reflect.Map:
|
|
|
|
return true
|
|
|
|
case reflect.Struct:
|
|
|
|
// 结构体转为字符串处理
|
|
|
|
fallthrough
|
|
|
|
case reflect.Ptr:
|
|
|
|
// 指针
|
|
|
|
var err error
|
2021-09-10 11:36:48 +08:00
|
|
|
if f.data, err = util.StructToMap(f.data); nil != err {
|
2021-03-14 23:31:08 +08:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|