增加slice的公共逻辑处理
This commit is contained in:
parent
c4b8209839
commit
d9a775a799
@ -23,6 +23,7 @@ type FieldRule struct {
|
|||||||
AllowNil bool `json:"allow_nil"` // 必传时, nil值是否合法
|
AllowNil bool `json:"allow_nil"` // 必传时, nil值是否合法
|
||||||
RequiredConditionGroup [][]RequiredCondition `json:"required_condition_group"` // 满足何种条件,字段必传,不配置则为无差别必传, 组之间是或条件, 满足一组即命中, 组之内为与条件
|
RequiredConditionGroup [][]RequiredCondition `json:"required_condition_group"` // 满足何种条件,字段必传,不配置则为无差别必传, 组之间是或条件, 满足一组即命中, 组之内为与条件
|
||||||
ValueLimit *ValueLimit `json:"value_limit"` // 数据值的限制
|
ValueLimit *ValueLimit `json:"value_limit"` // 数据值的限制
|
||||||
|
SliceConfig *SliceConfig `json:"slice_config"` // 数组转化的配置
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequiredCondition 定义必传条件
|
// RequiredCondition 定义必传条件
|
||||||
@ -66,3 +67,14 @@ type StringValueLimit struct {
|
|||||||
type MapValueLimit struct {
|
type MapValueLimit struct {
|
||||||
IncludeFieldList []string `json:"include_field_list"` // 必须存在的字段列表
|
IncludeFieldList []string `json:"include_field_list"` // 必须存在的字段列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceConfig slice的配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:34 2024/4/30
|
||||||
|
type SliceConfig struct {
|
||||||
|
Mode string `json:"slice_mode"` // REAL - 输入直接是slice MARSHAL - json序列化之后的字符串 WITH_SPLIT_CHAR - 使用指定字符串分隔
|
||||||
|
DisableAutoConvert bool `json:"disable_auto_convert"` // 禁用自动格式转换, 不禁用情况下, ["1","2","3"] 可以转换成 [1,2,3]
|
||||||
|
SplitChar string `json:"split_char"` // 数组转换的分隔符, 当输入模式是 WITH_SPLIT_CHAR 时生效
|
||||||
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module git.zhangdeman.cn/gateway/validator
|
|||||||
go 1.22.2
|
go 1.22.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429082641-eeef7e967d00 // indirect
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240430135109-0be82b4a6434 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 // indirect
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 // indirect
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -4,6 +4,8 @@ git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429080251-9cd57471a8f5 h1:6JsrAD
|
|||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429080251-9cd57471a8f5/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429080251-9cd57471a8f5/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429082641-eeef7e967d00 h1:bOPZXYX9CfnZBPqkQnzgwnuC1uyXBivSY0nmV4HabXg=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429082641-eeef7e967d00 h1:bOPZXYX9CfnZBPqkQnzgwnuC1uyXBivSY0nmV4HabXg=
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429082641-eeef7e967d00/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240429082641-eeef7e967d00/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240430135109-0be82b4a6434 h1:BgpbeE3Vuy1iS4xrMzJP6bDGbrrhlv8uSDh8n/Sj+fg=
|
||||||
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240430135109-0be82b4a6434/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
||||||
|
108
run.go
108
run.go
@ -18,6 +18,7 @@ import (
|
|||||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -155,8 +156,12 @@ func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
|||||||
return handleFloat(inputVal, rule)
|
return handleFloat(inputVal, rule)
|
||||||
case consts.DataTypeInt: // int类型
|
case consts.DataTypeInt: // int类型
|
||||||
return handleInt(inputVal, rule)
|
return handleInt(inputVal, rule)
|
||||||
|
case consts.DataTypeUint:
|
||||||
|
return handleUint(inputVal, rule)
|
||||||
case consts.DataTypeString: // 字符串处理
|
case consts.DataTypeString: // 字符串处理
|
||||||
return handleString(inputVal, rule)
|
return handleString(inputVal, rule)
|
||||||
|
case consts.DataTypeBool:
|
||||||
|
return handleBool(inputVal, rule)
|
||||||
case consts.DataTypeMapStrFloat, consts.DataTypeMapStrBool,
|
case consts.DataTypeMapStrFloat, consts.DataTypeMapStrBool,
|
||||||
consts.DataTypeMapStrInt, consts.DataTypeMapStrUint:
|
consts.DataTypeMapStrInt, consts.DataTypeMapStrUint:
|
||||||
// 一律按照 map[string]float64处理
|
// 一律按照 map[string]float64处理
|
||||||
@ -167,6 +172,8 @@ func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
|||||||
return handleMapStringSlice(inputVal, rule)
|
return handleMapStringSlice(inputVal, rule)
|
||||||
case consts.DataTypeMapAnyAny: // 任意类型map
|
case consts.DataTypeMapAnyAny: // 任意类型map
|
||||||
return handleMapAnyAny(inputVal, rule)
|
return handleMapAnyAny(inputVal, rule)
|
||||||
|
case consts.DataTypeSliceUint, consts.DataTypeSliceUintWithChar: // uint数组处理
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -223,6 +230,44 @@ func handleInt(inputVal any, rule *define.FieldRule) (int64, error) {
|
|||||||
return formatData, nil
|
return formatData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleUint ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:28 2024/4/30
|
||||||
|
func handleUint(inputVal any, rule *define.FieldRule) (uint64, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData uint64
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err = handleFloat(formatData, rule); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleBool...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:26 2024/4/30
|
||||||
|
func handleBool(inputVal any, rule *define.FieldRule) (bool, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData bool
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err = handleFloat(formatData, rule); nil != err {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleString ...
|
// handleString ...
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
@ -419,3 +464,66 @@ func validateMap(dataFieldTable map[string]string, rule *define.FieldRule) error
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleSlice 数组处理
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:30 2024/4/30
|
||||||
|
func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error) {
|
||||||
|
inputValType := reflect.TypeOf(inputValue).Kind()
|
||||||
|
if inputValType != reflect.Slice && inputValType != reflect.String {
|
||||||
|
return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String())
|
||||||
|
}
|
||||||
|
if inputValType == reflect.Slice {
|
||||||
|
inputValue = serialize.JSON.MarshalForString(inputValue)
|
||||||
|
// 重置配置
|
||||||
|
if nil == rule.SliceConfig {
|
||||||
|
rule.SliceConfig = &define.SliceConfig{
|
||||||
|
Mode: consts.DataSliceModelMarshal,
|
||||||
|
DisableAutoConvert: false,
|
||||||
|
SplitChar: "",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rule.SliceConfig.Mode = consts.DataSliceModelMarshal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if inputStr, ok := inputValue.(string); ok {
|
||||||
|
return handleSliceString(inputStr, rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceString ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:06 2024/4/30
|
||||||
|
func handleSliceString(inputStr string, rule *define.FieldRule) ([]any, error) {
|
||||||
|
if nil == rule.SliceConfig {
|
||||||
|
return nil, fmt.Errorf("%v : data type is slice, but get string", rule.Path)
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelReal {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect real slice, but get string", rule.Path)
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelMarshal { // json序列化之后的
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res []any
|
||||||
|
)
|
||||||
|
if err = serialize.JSON.UnmarshalWithNumber([]byte(inputStr), &res); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect marshal slice, but can not convert", rule.Path)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelWithSplitChar { // 指定字符串切割
|
||||||
|
strArr := strings.Split(inputStr, rule.SliceConfig.SplitChar)
|
||||||
|
anyArr := make([]any, 0)
|
||||||
|
for _, item := range strArr {
|
||||||
|
anyArr = append(anyArr, item)
|
||||||
|
}
|
||||||
|
return anyArr, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("%v : data type is slice, but rule mode [%v] is not supported", rule.Path, rule.SliceConfig.Mode)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user