json数据转换复用json_filter库

This commit is contained in:
白茶清欢 2025-03-29 16:03:13 +08:00
parent 164ea6b3ac
commit 9c3eceb0c8
3 changed files with 22 additions and 86 deletions

2
go.mod
View File

@ -3,7 +3,7 @@ module git.zhangdeman.cn/gateway/validate
go 1.24.1
require (
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250323125506-1b217c0e4fee
git.zhangdeman.cn/zhangdeman/json_filter v0.0.0-20250321103029-786c03293a28
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd

2
go.sum
View File

@ -4,6 +4,8 @@ git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321101544-734d9a9f7733 h1:j5tG00
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321101544-734d9a9f7733/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca h1:uxjzbY5fDozjyK6jkoQtuQouVTcVfXjbe3chARYSjRM=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c h1:cl3gQGXQpJ8ugDs0C/hQLfcvF4lGBm5BeABLvROFDoM=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250319072714-eab2a7abde63/go.mod h1:10CdqBLr/d7vDQ7HlZoPdJWV9PF7zNM9QmhKt9Iz0/8=
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250321154326-850866d6f568 h1:LKmmtWBhhw2ne8/mZ5qsgm9d4tX0ut2u1FFrM745N7g=
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250321154326-850866d6f568/go.mod h1:S5KcY8KjsOFC/jPaUz4ndxcD8Prqwwsa7Thp9VHBD0Y=

View File

@ -13,12 +13,11 @@ import (
"fmt"
"git.zhangdeman.cn/zhangdeman/consts"
dynamicStructGenerate "git.zhangdeman.cn/zhangdeman/dynamic-struct"
"git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack"
filter "git.zhangdeman.cn/zhangdeman/json_filter"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/creasty/defaults"
"github.com/go-playground/validator/v10"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"strings"
)
@ -35,10 +34,27 @@ func init() {
//
// Date : 15:12 2025/3/18
func Run(sourceData []byte, fieldList []StructField) ([]byte, error) {
filterRuleList := make([]filter.MapRule, 0)
for _, item := range fieldList {
filterRuleList = append(filterRuleList, filter.MapRule{
SourcePath: item.SourcePath,
TargetPath: item.TargetPath,
Required: item.Required,
DataType: item.Type,
DefaultValue: item.DefaultValue,
})
}
// source_path => target_path数据转换
filterInstance := filter.NewFilter(string(sourceData), filterRuleList)
if err := filterInstance.Deal(); nil != err {
return nil, err
}
// 格式化sourceData
handleInstance := &handle{
sourceData: sourceData,
sourceData: filterInstance.Byte(),
fieldList: fieldList,
parentFieldTable: map[string]bool{},
formatVal: filterInstance.String(),
}
tagTable := map[string]string{}
for _, item := range fieldList {
@ -92,10 +108,6 @@ func (h *handle) Run() ([]byte, error) {
Args: nil,
})
}
// 格式化数据
if _, err := h.formatDataValue(field); nil != err {
return nil, err
}
// 支持嵌套结构体
fieldTag := h.generateTag(field)
// 这里需要设置为对应类型的零值就行, 此处传入值的目的只是为了确认数据类型
@ -141,84 +153,6 @@ func (h *handle) checkRequired(field StructField) (bool, bool) {
return false, isHasRequiredRule
}
// getSourceDataValue 获取源数据值
func (h *handle) formatDataValue(field StructField) (any, error) {
sourceValue := gjson.GetBytes(h.sourceData, field.SourcePath)
if !sourceValue.Exists() {
if field.Required {
return nil, errors.New(field.SourcePath + " is required")
}
if len(field.DefaultValue) > 0 {
// 非必传, 且设置了默认值, 在数据源不存在时, 这只默认值
sourceValue = gjson.Result{
Type: gjson.String,
Raw: field.DefaultValue,
Str: field.DefaultValue,
Num: 0,
Index: 0,
Indexes: nil,
}
} else {
// 非必传, 且没有默认值, 就当做数据不存在
return nil, nil
}
}
var (
val any
err error
)
defer func() {
if nil == err && nil != val {
// 更新到格式化之后的数据结构中
h.formatVal, err = sjson.Set(h.formatVal, field.TargetPath, val)
}
}()
switch field.Type {
case consts.DataTypeInt: // Int类型
fallthrough
case consts.DataTypeIntPtr: // Uint类型
val, err = gjson_hack.Int(sourceValue)
return val, err
case consts.DataTypeUint:
fallthrough
case consts.DataTypeUintPtr: // Uint类型
val, err = gjson_hack.Uint(sourceValue)
return val, err
case consts.DataTypeFloat32:
fallthrough
case consts.DataTypeFloat32Ptr: // Float类型
val, err = gjson_hack.Float64(sourceValue)
return val, err
case consts.DataTypeString: // String类型
val = sourceValue.String()
return val, nil
case consts.DataTypeBool: // Bool类型
val = sourceValue.Bool()
return val, nil
case consts.DataTypeSliceFloat: // Float slice
val, err = gjson_hack.SliceFloat(sourceValue)
return val, err
case consts.DataTypeSliceInt: // Int slice
val, err = gjson_hack.SliceInt(sourceValue)
return val, err
case consts.DataTypeSliceUint: // Uint slice
val, err = gjson_hack.SliceUint(sourceValue)
return val, err
case consts.DataTypeSliceString: // String slice
val, err = gjson_hack.SliceString(sourceValue)
return val, err
case consts.DataTypeSliceBool: // Bool slice
val, err = gjson_hack.SliceBool(sourceValue)
return val, err
case consts.DataTypeMapStrAny: // Bool slice
val, err = gjson_hack.MapStrAny[any](sourceValue)
return val, err
}
val = sourceValue.Value()
return val, nil
}
// 生成结构体的tag标签
func (h *handle) generateTag(field StructField) string {
tagList := []string{