增加json数据过滤能力
This commit is contained in:
		
							
								
								
									
										25
									
								
								define/filter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								define/filter.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| // Package define ... | ||||
| // | ||||
| // Description : define ... | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 2024-04-07 21:43 | ||||
| package define | ||||
|  | ||||
| import "git.zhangdeman.cn/zhangdeman/data_mask" | ||||
|  | ||||
| // FilterRule ... | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 21:43 2024/4/7 | ||||
| type FilterRule struct { | ||||
| 	SourceDataPath string              `json:"source_data_path"` // 原始数据路径 | ||||
| 	TargetDataPath string              `json:"target_data_path"` // 目标数据路径 | ||||
| 	IsRequired     bool                `json:"is_required"`      // 要求字段必须存在 | ||||
| 	AllowNil       bool                `json:"allow_nil"`        // 允许nil值 | ||||
| 	DefaultValue   string              `json:"default_value"`    // 不存在时的默认值 | ||||
| 	Type           string              `json:"type"`             // 数据类型 | ||||
| 	DataMask       data_mask.IDataMask `json:"-"`                // 数据脱敏策略 | ||||
| } | ||||
							
								
								
									
										158
									
								
								filter/filter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								filter/filter.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | ||||
| // Package filter ... | ||||
| // | ||||
| // Description : filter ... | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 2024-04-07 21:59 | ||||
| package filter | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"git.zhangdeman.cn/zhangdeman/data_mask/define" | ||||
| 	"github.com/tidwall/gjson" | ||||
| 	"github.com/tidwall/sjson" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // Execute 数据转换 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 12:39 2024/3/26 | ||||
| func Execute(sourceData string, convertRule []*define.FilterRule) *Transform { | ||||
| 	sourceData = strings.TrimSpace(sourceData) | ||||
| 	t := &Transform{ | ||||
| 		sourceData: sourceData, | ||||
| 		ruleList:   convertRule, | ||||
| 		result:     "{}", | ||||
| 	} | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| // Transform 转换 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:56 2024/3/27 | ||||
| type Transform struct { | ||||
| 	sourceData string | ||||
| 	ruleList   []*define.FilterRule | ||||
| 	result     string | ||||
| } | ||||
|  | ||||
| // Execute 执行 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:57 2024/3/27 | ||||
| func (t *Transform) Execute() error { | ||||
| 	sourceResult := gjson.Parse(t.sourceData) | ||||
| 	if !sourceResult.IsObject() { | ||||
| 		return errors.New("source data is not object") | ||||
| 	} | ||||
| 	if err := t.checkRule(); nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, itemRule := range t.ruleList { | ||||
| 		if err := t.rewrite(itemRule); nil != err { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetResult 获取处理结果 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 11:32 2024/3/27 | ||||
| func (t *Transform) GetResult() string { | ||||
| 	return t.result | ||||
| } | ||||
|  | ||||
| // checkRule 校验规则 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 11:18 2024/3/27 | ||||
| func (t *Transform) checkRule() error { | ||||
| 	for _, itemRule := range t.ruleList { | ||||
| 		itemRule.SourceDataPath = strings.TrimRight(itemRule.SourceDataPath, ".[]") | ||||
| 		itemRule.TargetDataPath = strings.TrimRight(itemRule.TargetDataPath, ".[]") | ||||
| 		fromPathArr := strings.Split(itemRule.SourceDataPath, "[]") | ||||
| 		targetPathArr := strings.Split(itemRule.TargetDataPath, "[]") | ||||
| 		if len(targetPathArr) > len(fromPathArr) { | ||||
| 			return errors.New("slice path config invalid : " + itemRule.SourceDataPath + " -> " + itemRule.TargetDataPath) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // rewrite 数据重写 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 11:25 2024/3/27 | ||||
| func (t *Transform) rewrite(rule *define.FilterRule) error { | ||||
| 	var ( | ||||
| 		err error | ||||
| 	) | ||||
|  | ||||
| 	sourceResult := gjson.Get(t.sourceData, rule.SourceDataPath) | ||||
| 	if !sourceResult.Exists() { | ||||
| 		if rule.IsRequired { | ||||
| 			return errors.New(rule.SourceDataPath + " is not exist, but required") | ||||
| 		} | ||||
| 		if strings.Contains(rule.SourceDataPath, "[]") { | ||||
| 			return t.rewriteForSlice(rule) | ||||
| 		} | ||||
| 		if t.result, err = sjson.Set(t.result, rule.TargetDataPath, rule.DefaultValue); nil != err { | ||||
| 			return err | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| 	t.result, err = sjson.Set(t.result, rule.TargetDataPath, sourceResult.Value()) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // rewriteForSlice 数组重写 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 15:22 2024/3/27 | ||||
| func (t *Transform) rewriteForSlice(rule *define.FilterRule) error { | ||||
| 	pathArr := strings.Split(rule.SourceDataPath, ".[].") | ||||
| 	sliceUnfoldResult := t.unfoldSourceSliceData(t.sourceData, pathArr[0:len(pathArr)-1], nil) | ||||
| 	targetArr := strings.Split(rule.TargetDataPath, ".[].") | ||||
| 	for idx, itemRes := range sliceUnfoldResult { | ||||
| 		t.result, _ = sjson.Set(t.result, fmt.Sprintf("%v.%v.%v", targetArr[0], idx, targetArr[1]), itemRes.Get(pathArr[len(pathArr)-1]).Value()) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // unfoldSourceSliceData 展开元数据的数组, 平铺 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 17:39 2024/3/27 | ||||
| func (t *Transform) unfoldSourceSliceData(sourceData string, pathList []string, res []gjson.Result) []gjson.Result { | ||||
| 	if nil == res { | ||||
| 		res = make([]gjson.Result, 0) | ||||
| 	} | ||||
|  | ||||
| 	arrRes := gjson.Get(sourceData, pathList[0]).Array() | ||||
| 	if len(pathList) == 1 { | ||||
| 		for _, itemRes := range arrRes { | ||||
| 			res = append(res, itemRes) | ||||
| 		} | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < len(arrRes)-1; i++ { | ||||
| 		res = t.unfoldSourceSliceData(arrRes[i].String(), pathList[1:], res) | ||||
| 	} | ||||
|  | ||||
| 	return t.unfoldSourceSliceData(arrRes[len(arrRes)-1].String(), pathList[1:], res) | ||||
| } | ||||
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,3 +1,10 @@ | ||||
| module git.zhangdeman.cn/zhangdeman/data_mask | ||||
|  | ||||
| go 1.21 | ||||
|  | ||||
| require ( | ||||
| 	github.com/tidwall/gjson v1.17.1 // indirect | ||||
| 	github.com/tidwall/match v1.1.1 // indirect | ||||
| 	github.com/tidwall/pretty v1.2.1 // indirect | ||||
| 	github.com/tidwall/sjson v1.2.5 // indirect | ||||
| ) | ||||
|  | ||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= | ||||
| github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= | ||||
| github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= | ||||
| github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= | ||||
| github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= | ||||
| github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= | ||||
| github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= | ||||
| github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= | ||||
| github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= | ||||
| github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= | ||||
| @ -1,4 +1,4 @@ | ||||
| // Package data_mask ... | ||||
| // Package strategy ... | ||||
| // | ||||
| // Description : data_mask ... | ||||
| // | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| // Package data_mask ... | ||||
| // Package strategy ... | ||||
| // | ||||
| // Description : data_mask ... | ||||
| // | ||||
|  | ||||
		Reference in New Issue
	
	Block a user