From be6b8e644fc8442cc3e8e21635887f5cb4f942bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 21 Mar 2025 16:48:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=BA=90=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=8C=87=E5=AE=9A=E6=95=B0=E6=8D=AE,=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9B=AE=E6=A0=87=E7=BB=93=E6=9E=84=E4=BD=93=E4=B9=9F?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E7=94=9F=E6=88=90=E5=AF=B9=E5=BA=94=E7=9A=84?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E4=BD=93,=E5=90=A6=E5=88=99=E4=BC=9A?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1=E7=9B=B8=E5=85=B3=E5=8F=82=E6=95=B0=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- validate.go | 53 ++++++++++++++++++++++++++++++++++++------------ validate_test.go | 33 ++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index d9b83bf..778c81f 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250319072714-eab2a7abde63 git.zhangdeman.cn/zhangdeman/json_filter v0.0.0-20241205105007-b8c8c9d4338c git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd - git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250302133417-c1588abcb436 github.com/go-playground/validator/v10 v10.25.0 github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 @@ -16,6 +15,7 @@ require ( require ( git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect + git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250302133417-c1588abcb436 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect diff --git a/validate.go b/validate.go index 4649e16..d4de74a 100644 --- a/validate.go +++ b/validate.go @@ -35,23 +35,45 @@ func init() { // Date : 15:12 2025/3/18 func Run(sourceData []byte, fieldList []StructField) ([]byte, error) { handleInstance := &handle{ - sourceData: sourceData, - fieldList: fieldList, - dynamicStruct: dynamicStructGenerate.NewStruct(), + sourceData: sourceData, + fieldList: fieldList, + parentFieldTable: map[string]bool{}, } + tagTable := map[string]string{} + for _, item := range fieldList { + tagTable[item.TargetPath] = handleInstance.generateTag(item) + // 检测当前字段是否是某一个字段的父级字段 + for _, field := range fieldList { + if field.TargetPath == item.TargetPath { + continue + } + // 当前字段以itemTarget开头 + if strings.HasPrefix(field.TargetPath, item.TargetPath) { + // item.TargetPath是父级字段 + handleInstance.parentFieldTable[item.TargetPath] = true + } + } + } + handleInstance.dynamicStruct = dynamicStructGenerate.NewStruct(tagTable) + return handleInstance.Run() } type handle struct { - sourceData []byte - fieldList []StructField - dynamicStruct dynamicStructGenerate.Builder - formatVal string + sourceData []byte + fieldList []StructField + dynamicStruct dynamicStructGenerate.Builder + formatVal string + parentFieldTable map[string]bool // 父级字段路径表 } // Run 执行验证 func (h *handle) Run() ([]byte, error) { for _, field := range h.fieldList { + if h.parentFieldTable[field.TargetPath] { + // 中间层级字段, 无需额外处理 + continue + } if len(field.Errmsg) == 0 { field.Errmsg = field.JsonTag + " : 参数校验不通过" } @@ -70,12 +92,14 @@ func (h *handle) Run() ([]byte, error) { if nil != err { return nil, err } + // 支持嵌套结构体 + fieldTag := h.generateTag(field) if nil == sourceValue { // 没出现异常, 但是value为nil, 视作参数不存在处理 + // TODO: 这里需要设置为对应类型的零值 + h.dynamicStruct.AddField(field.JsonTag, "", "", fieldTag, false) continue } - // TODO : 支持嵌套结构体 - fieldTag := h.generateTag(field) h.dynamicStruct.AddField(field.JsonTag, "", sourceValue, fieldTag, false) } val := h.dynamicStruct.Build().New() @@ -104,11 +128,14 @@ func (h *handle) checkRequired(field StructField) (bool, bool) { if isHasRequiredRule { required = true } - if required && !isHasRequiredRule { - // 必传, 但是没有必传校验规则 - return true, true + if required { + if !isHasRequiredRule { + // 必传, 但是没有必传校验规则 + return true, true + } + return true, false } - return true, false + return false, false } // getSourceDataValue 获取源数据值 diff --git a/validate_test.go b/validate_test.go index 708e070..6e57a99 100644 --- a/validate_test.go +++ b/validate_test.go @@ -50,6 +50,39 @@ func TestRun_Simple_Data(t *testing.T) { TargetPath: "user_age", Errmsg: "年龄必须在[1,2000]之间", }, + { + JsonTag: "company_name", + Type: consts.DataTypeString, + Required: false, + RuleList: []Rule{ + { + Tag: "min", + Args: []string{"1"}, + }, + { + Tag: "max", + Args: []string{"20"}, + }, + }, + DefaultValue: "", + SourcePath: "company.name", + TargetPath: "company.cname", + Errmsg: "公司名称必须在[1,20]之间", + }, + { + JsonTag: "company", + Type: consts.DataTypeString, + Required: false, + RuleList: []Rule{ + { + Tag: "required", + }, + }, + DefaultValue: "", + SourcePath: "company", + TargetPath: "company", + Errmsg: "公司信息必传", + }, } res, err := Run(sourceByteData, fieldList) fmt.Println(err, string(res))