数据源不存在指定数据,生成目标结构体也需要生成对应的结构体,否则会丢失相关参数验证

This commit is contained in:
白茶清欢 2025-03-21 16:48:16 +08:00
parent 0754f879e8
commit be6b8e644f
3 changed files with 74 additions and 14 deletions

2
go.mod
View File

@ -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

View File

@ -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 获取源数据值

View File

@ -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))