Compare commits
24 Commits
d87fb61db5
...
feature/wr
Author | SHA1 | Date | |
---|---|---|---|
4b94376e7c | |||
50440cc8f9 | |||
5fe0557d90 | |||
44e6c5cdcf | |||
a69f3a1e01 | |||
a2a3a2f653 | |||
cdbf5376a7 | |||
55502d1c28 | |||
fcad833e88 | |||
064f5e2c5b | |||
978e52089c | |||
ae7bbe8584 | |||
3618568122 | |||
da9aa14f0e | |||
bc555966fa | |||
0ece3237d7 | |||
4367435ab7 | |||
0e090ee488 | |||
09c09a9621 | |||
d3be2ddb2d | |||
4c70ca6f84 | |||
974063eb26 | |||
c35d379a26 | |||
e5b2e1a377 |
@ -7,6 +7,10 @@
|
|||||||
// Date : 2024-04-29 10:51
|
// Date : 2024-04-29 10:51
|
||||||
package define
|
package define
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
)
|
||||||
|
|
||||||
// FieldRule 字段验证规则
|
// FieldRule 字段验证规则
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
@ -14,7 +18,7 @@ package define
|
|||||||
// Date : 10:52 2024/4/29
|
// Date : 10:52 2024/4/29
|
||||||
type FieldRule struct {
|
type FieldRule struct {
|
||||||
Path string `json:"path"` // 字段路径
|
Path string `json:"path"` // 字段路径
|
||||||
Type string `json:"type"` // 数据类型, 具体枚举值参见 git.zhangdeman.cn/zhangdeman/consts
|
Type consts.DataType `json:"type"` // 数据类型, 具体枚举值参见 git.zhangdeman.cn/zhangdeman/consts
|
||||||
DisableRewrite bool `json:"disable_rewrite"` // 验证完相关数据类型之后, 不要重新给字段赋值
|
DisableRewrite bool `json:"disable_rewrite"` // 验证完相关数据类型之后, 不要重新给字段赋值
|
||||||
DefaultValue any `json:"default_value"` // 默认值, 统一以字符串传入, 会转为最终设置的类型
|
DefaultValue any `json:"default_value"` // 默认值, 统一以字符串传入, 会转为最终设置的类型
|
||||||
IsRequired bool `json:"is_required"` // 是否必传
|
IsRequired bool `json:"is_required"` // 是否必传
|
||||||
@ -35,9 +39,9 @@ type FieldRule struct {
|
|||||||
//
|
//
|
||||||
// Date : 10:58 2024/4/29
|
// Date : 10:58 2024/4/29
|
||||||
type RequiredCondition struct {
|
type RequiredCondition struct {
|
||||||
DependOnField string `json:"depend_on_field"` // 依赖数据源中的那一个字段
|
DependOnField string `json:"depend_on_field"` // 依赖数据源中的那一个字段
|
||||||
DependOnFieldType string `json:"depend_on_field_type"` // 依赖数据源数据类型
|
DependOnFieldType consts.DataType `json:"depend_on_field_type"` // 依赖数据源数据类型
|
||||||
DependOnFieldStatus []string `json:"depend_on_field_status"` // 依赖数据状态 : NOT_FOUND / IS_NIL / IS_ZERO / IS_EMPTY / IS_FALSE
|
DependOnFieldStatus []string `json:"depend_on_field_status"` // 依赖数据状态 : NOT_FOUND / IS_NIL / IS_ZERO / IS_EMPTY / IS_FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValueLimit 取值的限制
|
// ValueLimit 取值的限制
|
||||||
|
26
go.mod
26
go.mod
@ -3,27 +3,43 @@ module git.zhangdeman.cn/gateway/validator
|
|||||||
go 1.22.2
|
go 1.22.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9
|
||||||
|
github.com/go-playground/validator/v10 v10.24.0
|
||||||
|
github.com/smartystreets/goconvey v1.8.1
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/tidwall/gjson v1.17.3
|
github.com/tidwall/gjson v1.18.0
|
||||||
github.com/tidwall/sjson v1.2.5
|
github.com/tidwall/sjson v1.2.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
|
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/smarty/assertions v1.15.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
|
golang.org/x/crypto v0.32.0 // indirect
|
||||||
|
golang.org/x/net v0.34.0 // indirect
|
||||||
|
golang.org/x/sys v0.29.0 // indirect
|
||||||
|
golang.org/x/text v0.21.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace git.zhangdeman.cn/zhangdeman/consts => ../consts
|
||||||
|
|
||||||
|
replace git.zhangdeman.cn/zhangdeman/wrapper => ../wrapper
|
||||||
|
76
go.sum
76
go.sum
@ -1,68 +1,52 @@
|
|||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240501142503-e31a270e50cc h1:kPz9xiUVruM8kwbUUVpxyCTX8pGgyKt60K5zX77oyC4=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240501142503-e31a270e50cc/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec h1:ENemx9RGAU9nqpPYC4S6C/Dnw9gwcx96+sTISG/6rsY=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240608104035-feddc6a70f9d h1:qKou2RVGqRd7ojAHq2H8xTxfwayjYvfn35Rk+Fz0+zU=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240608104035-feddc6a70f9d/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240623031247-2fea122027a7 h1:f04tDgg1+cWuoH+vkMeKtJ+glq2WhLG20MKFjogz8gQ=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240623031247-2fea122027a7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240709134122-e1e2a2e421de h1:ksjcMHupU0Bw0BJxJp3dajmWqGdqV7k2eVohN5O3S9Q=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240709134122-e1e2a2e421de/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5 h1:pmIHln0gWW+5xAB762h3WDsRkZuYLUDndvJDsGMKoOY=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7 h1:tyCPCMK+68PZ0axZylQHitMVp1d5mzNr9/YqMHXqo+A=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7/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/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd h1:2Y37waOVCmVvx0Rp8VGEptE2/2JVMImtxB4dKKDk/3w=
|
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd/go.mod h1:6+7whkCmb4sJDIfH3HxNuXRveaM0gCCNWd2uXZqNtIE=
|
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4=
|
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95 h1:3lO4ap9p7kEA+4yL5ojG9mAWsz5sY28Nu2tSzAZEehw=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95/go.mod h1:Fo4XOiZPua4E4/Qzy3ZYS5zyd15bS/lsb3t6S6PQFGY=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306 h1:Iy36ouA7TecVwBY1QTJfWIYNU2d39+APEfOhBC4gvic=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306/go.mod h1:7vFN7QrHLLI/iN7ZrJSU0bw/7TyaYjVQ4+clYuIoRrY=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240520124754-3faebb9145e3 h1:fDDWQV3Xu/ntjrtKjwK30URPHr4kJJpqZocw52x+DKw=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240520124754-3faebb9145e3/go.mod h1:7vFN7QrHLLI/iN7ZrJSU0bw/7TyaYjVQ4+clYuIoRrY=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e h1:+PeWa2QdYBWnL32CfAAgy0dlaRCVNmYZDH4q+9w7Gfg=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 h1:olo34i2Gq5gX7bYPv5TR4X5l5CrYFtu9UCElkYlmL2c=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3 h1:RcWNxrHmhZksZWrP/HLEwAM8uIIHYlPLQ20HnLzC+j0=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3/go.mod h1:KcojKP22mv9/IZrQWlIBfa1EuBxtEOqfWMgN3SYK2N8=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1 h1:LYw8NJeWcOiyrGjH9weyxnaMit94MlIngL+uskbLjtw=
|
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1/go.mod h1:+2qNxuRsfyfOvXk9HNwn+CmyPmmhhrQm/eIi1FDU1jw=
|
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
|
||||||
|
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||||
|
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||||
|
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
|
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
|
||||||
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||||
|
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||||
|
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||||
|
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
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.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
|
||||||
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
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.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
@ -70,6 +54,14 @@ 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/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 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"git.zhangdeman.cn/gateway/validator/define"
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
"git.zhangdeman.cn/zhangdeman/util"
|
"git.zhangdeman.cn/zhangdeman/util"
|
||||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -112,9 +113,24 @@ func handleString(inputVal any, rule *define.FieldRule) (string, error) {
|
|||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
formatData string
|
formatData string
|
||||||
|
ok bool
|
||||||
)
|
)
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return "", err
|
if formatData, ok = inputVal.(string); !ok {
|
||||||
|
// 传入的不是string类型
|
||||||
|
if rule.DisableAutoConvert {
|
||||||
|
// 禁用类型转换
|
||||||
|
return "", fmt.Errorf("%v : filed type is %v, data value auto convert is disabled, input value type is %v", rule.Path, rule.Type, reflect.TypeOf(inputVal).Kind().String())
|
||||||
|
}
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断空字符串
|
||||||
|
if !rule.AllowEmpty && formatData == "" && rule.IsRequired {
|
||||||
|
// 必传且不允许空字符串
|
||||||
|
return "", fmt.Errorf("%v : data type is string empty, field is required and empty value is not allowed", rule.Path)
|
||||||
}
|
}
|
||||||
if nil == rule.ValueLimit {
|
if nil == rule.ValueLimit {
|
||||||
return formatData, nil
|
return formatData, nil
|
||||||
|
@ -141,7 +141,7 @@ func handleMapAnyAny(inputVal any, rule *define.FieldRule) (map[any]any, error)
|
|||||||
if inputValStr, ok := inputVal.(string); ok {
|
if inputValStr, ok := inputVal.(string); ok {
|
||||||
jsonRes = gjson.Parse(inputValStr)
|
jsonRes = gjson.Parse(inputValStr)
|
||||||
} else {
|
} else {
|
||||||
jsonRes = gjson.Parse(serialize.JSON.MarshalForString(inputVal))
|
jsonRes = gjson.Parse(serialize.JSON.MarshalForStringIgnoreError(inputVal))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !jsonRes.IsObject() {
|
if !jsonRes.IsObject() {
|
||||||
@ -176,7 +176,7 @@ func strOrMapConvert(inputVal any, mapConfig *define.MapConfig, receiver any) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byteData := serialize.JSON.MarshalForByte(inputVal)
|
byteData := serialize.JSON.MarshalForByteIgnoreError(inputVal)
|
||||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ func strOrMapConvert(inputVal any, mapConfig *define.MapConfig, receiver any) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mapConfig.Mode == consts.DataMapModelReal {
|
if mapConfig.Mode == consts.DataMapModelReal {
|
||||||
byteData := serialize.JSON.MarshalForByte(inputVal)
|
byteData := serialize.JSON.MarshalForByteIgnoreError(inputVal)
|
||||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ func handleSliceSlice(inputValue interface{}, rule *define.FieldRule) ([][]any,
|
|||||||
}
|
}
|
||||||
sliceSlice := make([][]any, 0)
|
sliceSlice := make([][]any, 0)
|
||||||
for _, item := range anySlice {
|
for _, item := range anySlice {
|
||||||
byteData := serialize.JSON.MarshalForByte(item)
|
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||||
res := make([]any, 0)
|
res := make([]any, 0)
|
||||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, &res); nil != err {
|
if err = serialize.JSON.UnmarshalWithNumber(byteData, &res); nil != err {
|
||||||
return nil, fmt.Errorf("%v : data type is expect [][]any, but convert fail : %v", rule.Path, err.Error())
|
return nil, fmt.Errorf("%v : data type is expect [][]any, but convert fail : %v", rule.Path, err.Error())
|
||||||
@ -154,7 +154,7 @@ func handleSliceMapAny(inputValue interface{}, rule *define.FieldRule) ([]map[an
|
|||||||
}
|
}
|
||||||
mapSlice := make([]map[any]any, 0)
|
mapSlice := make([]map[any]any, 0)
|
||||||
for _, item := range anySlice {
|
for _, item := range anySlice {
|
||||||
byteData := serialize.JSON.MarshalForByte(item)
|
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||||
jsonRes := gjson.ParseBytes(byteData)
|
jsonRes := gjson.ParseBytes(byteData)
|
||||||
res := make(map[any]any)
|
res := make(map[any]any)
|
||||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||||
@ -181,7 +181,7 @@ func handleSliceMapString(inputValue interface{}, rule *define.FieldRule) ([]map
|
|||||||
}
|
}
|
||||||
mapSlice := make([]map[string]any, 0)
|
mapSlice := make([]map[string]any, 0)
|
||||||
for _, item := range anySlice {
|
for _, item := range anySlice {
|
||||||
byteData := serialize.JSON.MarshalForByte(item)
|
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||||
jsonRes := gjson.ParseBytes(byteData)
|
jsonRes := gjson.ParseBytes(byteData)
|
||||||
res := make(map[string]any)
|
res := make(map[string]any)
|
||||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||||
@ -204,7 +204,7 @@ func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error)
|
|||||||
return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String())
|
return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String())
|
||||||
}
|
}
|
||||||
if inputValType == reflect.Slice {
|
if inputValType == reflect.Slice {
|
||||||
inputValue = serialize.JSON.MarshalForString(inputValue)
|
inputValue = serialize.JSON.MarshalForStringIgnoreError(inputValue)
|
||||||
// 重置配置
|
// 重置配置
|
||||||
if nil == rule.SliceConfig {
|
if nil == rule.SliceConfig {
|
||||||
rule.SliceConfig = &define.SliceConfig{
|
rule.SliceConfig = &define.SliceConfig{
|
||||||
|
@ -7,14 +7,17 @@
|
|||||||
// Date : 2024-04-29 12:18
|
// Date : 2024-04-29 12:18
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import "git.zhangdeman.cn/gateway/validator/define"
|
import (
|
||||||
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
)
|
||||||
|
|
||||||
// NewDefaultFieldRule ...
|
// NewDefaultFieldRule ...
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 14:01 2024/4/29
|
// Date : 14:01 2024/4/29
|
||||||
func NewDefaultFieldRule(path string, dataType string, isRequired bool, defaultValue string) *define.FieldRule {
|
func NewDefaultFieldRule(path string, dataType consts.DataType, isRequired bool, defaultValue string) *define.FieldRule {
|
||||||
r := &define.FieldRule{
|
r := &define.FieldRule{
|
||||||
Path: path,
|
Path: path,
|
||||||
Type: dataType,
|
Type: dataType,
|
||||||
|
19
run.go
19
run.go
@ -126,7 +126,7 @@ func checkRuleConditionRequiredRule(sourceData []byte, rule *define.FieldRule) {
|
|||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 15:59 2024/4/29
|
// Date : 15:59 2024/4/29
|
||||||
func getDataStatus(val gjson.Result, dataType string) string {
|
func getDataStatus(val gjson.Result, dataType consts.DataType) string {
|
||||||
if !val.Exists() {
|
if !val.Exists() {
|
||||||
return consts.DataStatusNotFound
|
return consts.DataStatusNotFound
|
||||||
}
|
}
|
||||||
@ -142,17 +142,17 @@ func getDataStatus(val gjson.Result, dataType string) string {
|
|||||||
return consts.DataStatusIsZero
|
return consts.DataStatusIsZero
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(dataType, "[]") {
|
if strings.HasPrefix(dataType.String(), "[]") {
|
||||||
// 数组
|
// 数组
|
||||||
if len(val.Array()) == 0 {
|
if len(val.Array()) == 0 {
|
||||||
return consts.DataStatusIsEmpty
|
return consts.DataStatusIsEmpty
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(dataType, "map") {
|
} else if strings.HasPrefix(dataType.String(), "map") {
|
||||||
// 对象
|
// 对象
|
||||||
if len(val.Map()) == 0 {
|
if len(val.Map()) == 0 {
|
||||||
return consts.DataStatusIsEmpty
|
return consts.DataStatusIsEmpty
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(dataType, "*") {
|
} else if strings.HasPrefix(dataType.String(), "*") {
|
||||||
// 指针类型
|
// 指针类型
|
||||||
if nil == val.Value() {
|
if nil == val.Value() {
|
||||||
return consts.DataStatusIsNil
|
return consts.DataStatusIsNil
|
||||||
@ -227,7 +227,7 @@ func validate(sourceData []byte, val gjson.Result, rule *define.FieldRule) (any,
|
|||||||
if rule.IsRequired {
|
if rule.IsRequired {
|
||||||
return nil, fmt.Errorf("%v : field is required, but not found", rule.Path)
|
return nil, fmt.Errorf("%v : field is required, but not found", rule.Path)
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(rule.Type, "_ptr") {
|
if strings.HasSuffix(rule.Type.String(), "_ptr") {
|
||||||
// 指针类型数据, 无需验证
|
// 指针类型数据, 无需验证
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -246,10 +246,13 @@ func validate(sourceData []byte, val gjson.Result, rule *define.FieldRule) (any,
|
|||||||
//
|
//
|
||||||
// Date : 14:43 2024/4/29
|
// Date : 14:43 2024/4/29
|
||||||
func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
||||||
rule.Type = strings.ToLower(rule.Type)
|
rule.Type = consts.DataType(strings.ToLower(rule.Type.String()))
|
||||||
|
if !rule.Type.IsValid() {
|
||||||
|
return nil, fmt.Errorf("%v : data type %v is invalid", rule.Path, rule.Type.String())
|
||||||
|
}
|
||||||
// 处理真实的map和序列化之后的map
|
// 处理真实的map和序列化之后的map
|
||||||
if strings.HasPrefix(rule.Type, "map") {
|
if strings.HasPrefix(rule.Type.String(), "map") {
|
||||||
if strings.HasSuffix(rule.Type, "_marshal") {
|
if strings.HasSuffix(rule.Type.String(), "_marshal") {
|
||||||
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelMarshal}
|
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelMarshal}
|
||||||
} else {
|
} else {
|
||||||
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelReal}
|
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelReal}
|
||||||
|
180
run_test.go
180
run_test.go
@ -8,37 +8,177 @@
|
|||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
// TestRunString 测试字符串类型
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:48 2024/11/1
|
||||||
|
func TestRunString(t *testing.T) {
|
||||||
sourceData := map[string]interface{}{
|
sourceData := map[string]interface{}{
|
||||||
"name": "白茶清欢",
|
"name": "白茶清欢",
|
||||||
}
|
}
|
||||||
_ = Run(sourceData, nil)
|
ruleListForNotFound := []*define.FieldRule{
|
||||||
byteData, _ := json.Marshal(sourceData)
|
&define.FieldRule{
|
||||||
fmt.Println(string(byteData))
|
Path: "name1",
|
||||||
|
Type: "string",
|
||||||
|
DisableRewrite: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
IsRequired: true,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: false,
|
||||||
|
DisableAutoConvert: false,
|
||||||
|
RequiredConditionGroup: nil,
|
||||||
|
ValueLimit: nil,
|
||||||
|
SliceConfig: nil,
|
||||||
|
MapConfig: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := Run(sourceData, ruleListForNotFound, nil)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
sourceData = map[string]interface{}{
|
||||||
|
"name": "",
|
||||||
|
}
|
||||||
|
ruleListForEmpty := []*define.FieldRule{
|
||||||
|
&define.FieldRule{
|
||||||
|
Path: "name",
|
||||||
|
Type: "string",
|
||||||
|
DisableRewrite: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
IsRequired: true,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: false,
|
||||||
|
DisableAutoConvert: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = Run(sourceData, ruleListForEmpty, nil)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
sourceData = map[string]interface{}{
|
||||||
|
"name": 18,
|
||||||
|
}
|
||||||
|
ruleListForDisableAutoConvert := []*define.FieldRule{
|
||||||
|
&define.FieldRule{
|
||||||
|
Path: "name",
|
||||||
|
Type: "string",
|
||||||
|
DisableRewrite: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
IsRequired: true,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: false,
|
||||||
|
DisableAutoConvert: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = Run(sourceData, ruleListForDisableAutoConvert, nil)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
sourceData = map[string]interface{}{
|
||||||
|
"name": " ",
|
||||||
|
}
|
||||||
|
ruleListForAllowTrim := []*define.FieldRule{
|
||||||
|
&define.FieldRule{
|
||||||
|
Path: "name",
|
||||||
|
Type: "string",
|
||||||
|
DisableRewrite: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
IsRequired: true,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: false,
|
||||||
|
DisableAutoConvert: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = Run(sourceData, ruleListForAllowTrim, nil)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
sourceData = map[string]interface{}{
|
||||||
|
"name": " ",
|
||||||
|
}
|
||||||
|
ruleListForDisableTrim := []*define.FieldRule{
|
||||||
|
&define.FieldRule{
|
||||||
|
Path: "name",
|
||||||
|
Type: "string",
|
||||||
|
DisableRewrite: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
IsRequired: true,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: true,
|
||||||
|
DisableAutoConvert: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = Run(sourceData, ruleListForDisableTrim, nil)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_getDataStatus(t *testing.T) {
|
// TestRunFieldDepend 测试字段依赖关系
|
||||||
type args struct {
|
//
|
||||||
val gjson.Result
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
dataType string
|
//
|
||||||
|
// Date : 18:40 2024/11/1
|
||||||
|
func TestRunFieldDepend(t *testing.T) {
|
||||||
|
sourceData := map[string]interface{}{
|
||||||
|
"name": "",
|
||||||
}
|
}
|
||||||
tests := []struct {
|
ruleListForDepend := []*define.FieldRule{
|
||||||
name string
|
&define.FieldRule{
|
||||||
args args
|
Path: "name",
|
||||||
want string
|
Type: "string",
|
||||||
}{
|
DisableRewrite: false,
|
||||||
// TODO: Add test cases.
|
DefaultValue: nil,
|
||||||
|
IsRequired: false,
|
||||||
|
AllowEmpty: false,
|
||||||
|
AllowZero: false,
|
||||||
|
AllowNil: false,
|
||||||
|
DisableAutoTrimSpace: false,
|
||||||
|
DisableAutoConvert: false,
|
||||||
|
RequiredConditionGroup: [][]define.RequiredCondition{
|
||||||
|
[]define.RequiredCondition{
|
||||||
|
define.RequiredCondition{
|
||||||
|
DependOnField: "age",
|
||||||
|
DependOnFieldType: "int",
|
||||||
|
DependOnFieldStatus: []string{consts.DataStatusIsEmpty, consts.DataStatusIsNil, consts.DataStatusNotFound},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ValueLimit: nil,
|
||||||
|
SliceConfig: nil,
|
||||||
|
MapConfig: nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
err := Run(sourceData, ruleListForDepend, nil)
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
if nil != err {
|
||||||
assert.Equalf(t, tt.want, getDataStatus(tt.args.val, tt.args.dataType), "getDataStatus(%v, %v)", tt.args.val, tt.args.dataType)
|
fmt.Println(err.Error())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
35
v10/abstract/validate_rule.go
Normal file
35
v10/abstract/validate_rule.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Package abstract ...
|
||||||
|
//
|
||||||
|
// Description : abstract ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-23 18:44
|
||||||
|
package abstract
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/define"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IValidateRuleGenerateFunc 生成校验规则的方法约束
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:46 2025/1/23
|
||||||
|
//
|
||||||
|
// 参数说明
|
||||||
|
//
|
||||||
|
// - validateRule: 参数验证规则, 具体参见静态库声明
|
||||||
|
// - paramList: 验证规则需要的参数列表, 可以为空
|
||||||
|
//
|
||||||
|
// 返回值说明
|
||||||
|
// - express: 生成的表达式
|
||||||
|
// - err: 表达式生成过程中出现的异常
|
||||||
|
type IValidateRuleGenerateFunc func(ruleConfig define.GenerateRuleExpressConfig) (express string, err error)
|
||||||
|
|
||||||
|
// IFieldValidateRuleGenerateFunc 字段验证规则生成方法
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:16 2025/1/24
|
||||||
|
type IFieldValidateRuleGenerateFunc func(fieldValidateRule define.FieldValidateGenerateConfig) (express string, err error)
|
82
v10/default.go
Normal file
82
v10/default.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Package v10 ...
|
||||||
|
//
|
||||||
|
// Description : v10 ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 10:32
|
||||||
|
package v10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/define"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultValidateRuleGenerateFunc 验证规则生成的默认方法
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 10:33 2025/1/24
|
||||||
|
func DefaultValidateRuleGenerateFunc(validateRule define.GenerateRuleExpressConfig) (express string, err error) {
|
||||||
|
ruleConfig := validateRule.Rule.Config()
|
||||||
|
if len(ruleConfig.ValidatorRule.String()) == 0 {
|
||||||
|
return "", define.ErrValidatorRuleIsEmpty
|
||||||
|
}
|
||||||
|
if ruleConfig.WithoutParam {
|
||||||
|
// 验证规则不需要任何参数, 舍弃参数
|
||||||
|
return ruleConfig.ValidatorRule.String(), nil
|
||||||
|
}
|
||||||
|
// 验证参数数量
|
||||||
|
if ruleConfig.MinParamCnt > 0 && len(validateRule.ParamList) < ruleConfig.MinParamCnt {
|
||||||
|
return "", errors.New(ruleConfig.ValidatorRule.String() + " : " + define.ErrValidatorRuleParamCntIsTooLess.Error() + "-> " + fmt.Sprintf("%v", ruleConfig.MinParamCnt))
|
||||||
|
}
|
||||||
|
if ruleConfig.MaxParamCnt > 0 && len(validateRule.ParamList) > ruleConfig.MaxParamCnt {
|
||||||
|
return "", errors.New(ruleConfig.ValidatorRule.String() + " :" + define.ErrValidatorRuleParamCntIsTooMore.Error() + " -> " + fmt.Sprintf("%v", ruleConfig.MaxParamCnt))
|
||||||
|
}
|
||||||
|
if ruleConfig.ParamCntMustEven && len(validateRule.ParamList)%2 != 0 {
|
||||||
|
return "", errors.New(ruleConfig.ValidatorRule.String() + " : " + define.ErrValidatorRuleParamCntIsNotEven.Error())
|
||||||
|
}
|
||||||
|
paramStrList := make([]string, 0)
|
||||||
|
for _, param := range validateRule.ParamList {
|
||||||
|
paramStrList = append(paramStrList, fmt.Sprintf("%v", param))
|
||||||
|
}
|
||||||
|
return ruleConfig.ValidatorRule.String() + "=" + strings.Join(paramStrList, " "), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultFieldValidateRuleGenerateFunc 字段验证表达式生成
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:44 2025/1/24
|
||||||
|
func DefaultFieldValidateRuleGenerateFunc(fieldValidateRule define.FieldValidateGenerateConfig) (string, error) {
|
||||||
|
fieldValidateRule.Field = strings.TrimSpace(fieldValidateRule.Field)
|
||||||
|
if len(fieldValidateRule.Field) == 0 {
|
||||||
|
return "", define.ErrValidatorRuleFieldIsEmpty
|
||||||
|
}
|
||||||
|
if len(fieldValidateRule.RuleGroup) == 0 && len(fieldValidateRule.RuleSimple.Rule.String()) == 0 {
|
||||||
|
return "", define.ErrValidatorRuleGroupOrSimpleRuleAllEmpty
|
||||||
|
}
|
||||||
|
if len(fieldValidateRule.RuleGroup) == 0 {
|
||||||
|
// note: 当 fieldValidateRule.RuleGroup 不为空时, 会忽略 fieldValidateRule.RuleSimple 配置
|
||||||
|
fieldValidateRule.RuleGroup = [][]define.GenerateRuleExpressConfig{
|
||||||
|
[]define.GenerateRuleExpressConfig{
|
||||||
|
fieldValidateRule.RuleSimple,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalExpressList := make([]string, 0)
|
||||||
|
for _, itemGroupList := range fieldValidateRule.RuleGroup {
|
||||||
|
expressList := make([]string, 0)
|
||||||
|
for _, itemRule := range itemGroupList {
|
||||||
|
if fieldExpress, err := validatorRuleExpressGenerateFunc(itemRule); nil != err {
|
||||||
|
return "", err
|
||||||
|
} else {
|
||||||
|
expressList = append(expressList, fieldExpress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalExpressList = append(finalExpressList, strings.Join(expressList, ","))
|
||||||
|
}
|
||||||
|
return strings.Join(finalExpressList, "|"), nil
|
||||||
|
}
|
132
v10/default_test.go
Normal file
132
v10/default_test.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Package v10 ...
|
||||||
|
//
|
||||||
|
// Description : v10 ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 12:01
|
||||||
|
package v10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestDefaultValidateRuleGenerateFunc 表达式生成函数测试
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 12:02 2025/1/24
|
||||||
|
func TestDefaultValidateRuleGenerateFunc(t *testing.T) {
|
||||||
|
Convey("传入的验证规则未注册", t, func() {
|
||||||
|
testRule := consts.ValidatorRule("invalid_rule")
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: testRule,
|
||||||
|
ParamList: nil,
|
||||||
|
})
|
||||||
|
So(err, ShouldBeError)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleIsEmpty.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("传入规则无参数", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequired,
|
||||||
|
ParamList: nil,
|
||||||
|
})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldEqual, consts.ValidatorRuleCommonRequired.String())
|
||||||
|
})
|
||||||
|
Convey("传入oneof枚举值缺少枚举值列表", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonOneOf,
|
||||||
|
ParamList: nil,
|
||||||
|
})
|
||||||
|
So(err, ShouldBeError)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsTooLess.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldEqual, "")
|
||||||
|
})
|
||||||
|
Convey("传入oneof枚举值构建成功", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonOneOf,
|
||||||
|
ParamList: []any{"name", "1", 2, 3},
|
||||||
|
})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldNotBeEmpty)
|
||||||
|
So(res, ShouldEqual, consts.ValidatorRuleCommonOneOf.String()+"=name 1 2 3")
|
||||||
|
})
|
||||||
|
Convey("传入RequiredIf枚举值 -> 参数少于2", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequiredIf,
|
||||||
|
ParamList: []any{},
|
||||||
|
})
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsTooLess.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("传入RequiredIf枚举值 -> 参数奇数个", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequiredIf,
|
||||||
|
ParamList: []any{1, 2, 3},
|
||||||
|
})
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsNotEven.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("传入RequiredIf枚举值 -> 构建成功", t, func() {
|
||||||
|
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequiredIf,
|
||||||
|
ParamList: []any{1, 2, 3, 4},
|
||||||
|
})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldNotBeEmpty)
|
||||||
|
So(res, ShouldEqual, consts.ValidatorRuleCommonRequiredIf.String()+"=1 2 3 4")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDefaultFieldValidateRuleGenerateFunc 测试字段验证规则生成逻辑
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:53 2025/1/24
|
||||||
|
func TestDefaultFieldValidateRuleGenerateFunc(t *testing.T) {
|
||||||
|
Convey("未传入待验证字段", t, func() {
|
||||||
|
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
|
||||||
|
Field: "",
|
||||||
|
})
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleFieldIsEmpty.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("传入待验证字段有空格组成", t, func() {
|
||||||
|
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
|
||||||
|
Field: "",
|
||||||
|
})
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleFieldIsEmpty.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("未传入任何字段验证规则", t, func() {
|
||||||
|
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
|
||||||
|
Field: "test",
|
||||||
|
})
|
||||||
|
So(err, ShouldBeError)
|
||||||
|
So(define.IsErr(err, define.ErrValidatorRuleGroupOrSimpleRuleAllEmpty.Error()), ShouldBeTrue)
|
||||||
|
So(res, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
Convey("传入SimpleRule", t, func() {
|
||||||
|
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
|
||||||
|
Field: "test",
|
||||||
|
RuleGroup: nil,
|
||||||
|
RuleSimple: define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequired,
|
||||||
|
ParamList: nil,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldNotBeEmpty)
|
||||||
|
So(strings.HasPrefix(res, consts.ValidatorRuleCommonRequired.String()), ShouldBeTrue)
|
||||||
|
})
|
||||||
|
}
|
35
v10/define/err.go
Normal file
35
v10/define/err.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Package define ...
|
||||||
|
//
|
||||||
|
// Description : define ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 15:38
|
||||||
|
package define
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrValidatorRuleIsEmpty = errors.New("validator rule is empty")
|
||||||
|
ErrValidatorRuleParamCntIsTooLess = errors.New("validate rule param count is less than min param cnt")
|
||||||
|
ErrValidatorRuleParamCntIsTooMore = errors.New("validate rule param count is more than min param cnt")
|
||||||
|
ErrValidatorRuleParamCntIsNotEven = errors.New("validate rule param count is not even")
|
||||||
|
|
||||||
|
ErrValidatorRuleGroupOrSimpleRuleAllEmpty = errors.New("validator rule group or simple rule all empty")
|
||||||
|
ErrValidatorRuleFieldIsEmpty = errors.New("field is empty")
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsErr 是否指定类型Err
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:45 2025/1/24
|
||||||
|
func IsErr(err error, subMsg string) bool {
|
||||||
|
if nil == err {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains(err.Error(), subMsg)
|
||||||
|
}
|
29
v10/define/err_test.go
Normal file
29
v10/define/err_test.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Package define ...
|
||||||
|
//
|
||||||
|
// Description : define ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 15:46
|
||||||
|
package define
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsErr(t *testing.T) {
|
||||||
|
Convey("传入error为nil", t, func() {
|
||||||
|
isErrRes := IsErr(nil, "")
|
||||||
|
So(isErrRes, ShouldBeFalse)
|
||||||
|
})
|
||||||
|
Convey("传入error为test类型", t, func() {
|
||||||
|
isErrRes := IsErr(errors.New("aaatestbbb"), "test")
|
||||||
|
So(isErrRes, ShouldBeTrue)
|
||||||
|
})
|
||||||
|
Convey("传入error非test类型", t, func() {
|
||||||
|
isErrRes := IsErr(errors.New("aaatecccstbbb"), "test")
|
||||||
|
So(isErrRes, ShouldBeFalse)
|
||||||
|
})
|
||||||
|
}
|
31
v10/define/field_validate.go
Normal file
31
v10/define/field_validate.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Package define ...
|
||||||
|
//
|
||||||
|
// Description : define ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 11:21
|
||||||
|
package define
|
||||||
|
|
||||||
|
import "git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
|
||||||
|
// FieldValidateGenerateConfig 字段验证规则生成的配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:23 2025/1/24
|
||||||
|
type FieldValidateGenerateConfig struct {
|
||||||
|
Field string `json:"field,omitempty"` // 字段
|
||||||
|
RuleGroup [][]GenerateRuleExpressConfig `json:"rule_group,omitempty"` // 规则的分组, 同组内为 && 条件, 组之间为 || 条件, 适用于复杂条件配置
|
||||||
|
RuleSimple GenerateRuleExpressConfig `json:"rule_simple,omitempty"` // 简单条件配置, 与 RuleGroup 至少配置一个
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateRuleExpressConfig 生成规则验证表达式的配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:27 2025/1/24
|
||||||
|
type GenerateRuleExpressConfig struct {
|
||||||
|
Rule consts.ValidatorRule `json:"rule,omitempty"` // 条件配置
|
||||||
|
ParamList []any `json:"param_list,omitempty"` // 规则验证的参数列表
|
||||||
|
}
|
46
v10/init.go
Normal file
46
v10/init.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Package v10 ...
|
||||||
|
//
|
||||||
|
// Description : v10 ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 11:09
|
||||||
|
package v10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/abstract"
|
||||||
|
openValidator "github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
// validatorRuleExpressGenerateFunc 验证规则表达式生成方法
|
||||||
|
var validatorRuleExpressGenerateFunc abstract.IValidateRuleGenerateFunc = DefaultValidateRuleGenerateFunc
|
||||||
|
|
||||||
|
// validatorRuleExpressGenerateFunc 字段验证规则生成默认表达式
|
||||||
|
var fieldValidatorRuleExpressGenerateFunc abstract.IFieldValidateRuleGenerateFunc = DefaultFieldValidateRuleGenerateFunc
|
||||||
|
|
||||||
|
// 验证器实例
|
||||||
|
var validateInstance = openValidator.New()
|
||||||
|
|
||||||
|
// SetValidatorRuleExpressGenerateFunc 使用自定义的验证规则表达式函数覆盖默认的函数
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:11 2025/1/24
|
||||||
|
func SetValidatorRuleExpressGenerateFunc(generateFunc abstract.IValidateRuleGenerateFunc) {
|
||||||
|
if nil == generateFunc {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
validatorRuleExpressGenerateFunc = generateFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFieldValidatorRuleExpressGenerateFunc 字段默认表达式生成规则
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 11:56 2025/1/24
|
||||||
|
func SetFieldValidatorRuleExpressGenerateFunc(generateFunc abstract.IFieldValidateRuleGenerateFunc) {
|
||||||
|
if nil == generateFunc {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fieldValidatorRuleExpressGenerateFunc = generateFunc
|
||||||
|
}
|
90
v10/validate_value.go
Normal file
90
v10/validate_value.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Package v10 ...
|
||||||
|
//
|
||||||
|
// Description : v10 ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 16:42
|
||||||
|
package v10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateVar 验证任意变量值
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:44 2025/1/24
|
||||||
|
func ValidateVar(inputVal any, ruleConfig define.FieldValidateGenerateConfig) error {
|
||||||
|
validateRuleExpress, err := fieldValidatorRuleExpressGenerateFunc(ruleConfig)
|
||||||
|
if nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = validateInstance.Var(inputVal, validateRuleExpress); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateMap 验证Map数据
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:56 2025/1/24
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - inputMap: 输入的map数据
|
||||||
|
// - ruleConfigMap: map数据每一项的验证规则
|
||||||
|
//
|
||||||
|
// 返回值:
|
||||||
|
// - 验证结果表, key为验证的字段, val为验证的错误信息, 返回异常表长度为 0, 说明验证通过
|
||||||
|
func ValidateMap(inputMap map[string]any, ruleConfigMap map[string]define.FieldValidateGenerateConfig) map[string]error {
|
||||||
|
errTable := map[string]error{}
|
||||||
|
lock := &sync.RWMutex{}
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(len(inputMap))
|
||||||
|
for mapKey, mapVal := range inputMap {
|
||||||
|
go func(key string, val any) {
|
||||||
|
defer wg.Done()
|
||||||
|
if _, exist := ruleConfigMap[mapKey]; !exist {
|
||||||
|
// 未传入验证规则, 不验证
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := ValidateVar(val, ruleConfigMap[key]); nil != err {
|
||||||
|
// 验证失败
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
errTable[key] = err
|
||||||
|
}
|
||||||
|
}(mapKey, mapVal)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return errTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateDynamicStruct 验证动态结构体
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:28 2025/1/24
|
||||||
|
func ValidateDynamicStruct(inputMap map[string]any, ruleConfigMap map[string]define.FieldValidateGenerateConfig) error {
|
||||||
|
realMapData := make(map[string]any)
|
||||||
|
tagMap := make(map[string]string)
|
||||||
|
for mapKey, mapVal := range inputMap {
|
||||||
|
if _, exist := ruleConfigMap[mapKey]; !exist {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
realMapData[mapKey] = mapVal
|
||||||
|
express, err := fieldValidatorRuleExpressGenerateFunc(ruleConfigMap[mapKey])
|
||||||
|
if nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tagMap[mapKey] = "validate:\"" + express + "\""
|
||||||
|
}
|
||||||
|
dynamicStruct := wrapper.NewMap2DynamicStruct(realMapData, tagMap)
|
||||||
|
structVal := dynamicStruct.ToStructDefaultValue()
|
||||||
|
return validateInstance.Struct(structVal)
|
||||||
|
}
|
39
v10/validate_value_test.go
Normal file
39
v10/validate_value_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Package v10 ...
|
||||||
|
//
|
||||||
|
// Description : v10 ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-24 17:29
|
||||||
|
package v10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/v10/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidateDynamicStruct(t *testing.T) {
|
||||||
|
err := ValidateDynamicStruct(map[string]any{
|
||||||
|
"name": "zhang",
|
||||||
|
"age": 15,
|
||||||
|
}, map[string]define.FieldValidateGenerateConfig{
|
||||||
|
"name": {
|
||||||
|
Field: "name",
|
||||||
|
RuleGroup: nil,
|
||||||
|
RuleSimple: define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonRequired,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"age": {
|
||||||
|
Field: "age",
|
||||||
|
RuleGroup: nil,
|
||||||
|
RuleSimple: define.GenerateRuleExpressConfig{
|
||||||
|
Rule: consts.ValidatorRuleCommonMax,
|
||||||
|
ParamList: []any{17},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
Reference in New Issue
Block a user