gin 多结构体嵌套 效验范例

作者工作中遇到需求,需要多级别效验 结构体,但是范例很少,特意留下范例,写得不好,请轻喷
版本: github.com/go-playground/validator/v10

主结构体

type SceneProcessUpdateRequest struct {
	Chat       *Chat       `json:"chat" form:"chat" binding:"required_without=Name"`                                // 流程json
	UpdateNote *NodeList   `json:"update_note" form:"update_note" binding:"required_without_all=Name DeleteNote"`   // 需要更新的节点 ,Name DeleteNote 不存在时必传
	DeleteNote *DeleteNote `json:"delete_note" form:"delete_note" binding:"required_without_all=Name UpdateNote"`   // 需要删除的节点
	ID         string      `json:"id" form:"id" binding:"required"`                                                 // 流程ID
	SceneID    string      `json:"scene_id" form:"scene_id" binding:"required"`                                     // 场景ID
	Name       string      `json:"name" form:"name" binding:"required_without=Chat"`                                // 名称
	IsComplete int32       `json:"is_complete" form:"is_complete" binding:"required_with=Chat,omitempty,oneof=1 2"` // "是否完整,1是 2否" Chat存在时必须存在,不存在时,可为空
}

type Chat struct {
	NodeList []NodeList `json:"node_list" form:"node_list" binding:"required,gte=1,dive,required"` // 节点 数组
	LineList []LineList `json:"line_list" form:"line_list" binding:"required,gte=1,dive,required"` // 前端定义
	ID       string     `json:"id" form:"id" binding:"required"`                                   // 流程ID
}
type LineList struct {
	From string `json:"from" form:"from" binding:"required"` // 来源 ID
	To   string `json:"to" form:"to" binding:"required"`     // 跳转 ID
}

type NodeList struct {
	TalkData       *ai_scene_node_repo.TalkData       `json:"talk_data" form:"talk_data" binding:"required_if=Type talk"`                                // 对话节点 数据
	KeyData        *ai_scene_node_repo.KeyData        `json:"key_data" form:"key_data" binding:"required_if=Type key"`                                   // 按键节点 数据
	ArtificialData *ai_scene_node_repo.ArtificialData `json:"artificial_data" form:"artificial_data" binding:"required_if=Type artificial"`              // 人工节点 数据
	NoteData       *ai_scene_node_repo.NoteData       `json:"note_data" form:"note_data" binding:"required_if=Type note"`                                // 短信节点 数据
	StartData      *ai_scene_node_repo.StartData      `json:"start_data" form:"start_data" binding:"required_if=Type start"`                             // 开始节点 数据
	JumpData       *ai_scene_node_repo.JumpData       `json:"jump_data" form:"jump_data" binding:"required_if=Type jump"`                                // 跳转节点 数据
	EndData        *ai_scene_node_repo.EndData        `json:"end_data" form:"end_data" binding:"required_if=Type end"`                                   // 结束节点 数据
	Type           string                             `json:"type" form:"type" binding:"required,eq=talk|eq=artificial|eq=note|eq=start|eq=jump|eq=end"` // 节点类型 start:开始 talk:对话   artificial:人工  note:短信  key:按键  jump:跳转 end:结束
	Tag            string                             `json:"tag" form:"tag" binding:"required"`                                                         // 节点标记(标签)
	Name           string                             `json:"name" form:"name" binding:"required"`                                                       // 节点名称
	ID             string                             `json:"id" form:"id" binding:"required"`                                                           // 节点ID
	Left           string                             `json:"left" form:"left"`                                                                          // 前端自定义
	Top            string                             `json:"top" form:"top"`                                                                            // 前端自定义
	Ico            string                             `json:"ico" form:"ico"`                                                                            // 前端自定义
	State          string                             `json:"state" form:"state"`                                                                        // 前端自定义
}

type DeleteNote struct {
	ID  string `json:"id" form:"id" binding:"required"`   // 节点ID
	Tag string `json:"tag" form:"tag" binding:"required"` // 节点标签
}
package ai_scene_node_repo

// 开始
type StartData struct {
	JumpNodeID string `json:"jump_node_id" form:"jump_node_id" binding:"required"` // 跳转至
}

// 对话
type TalkData struct {
	Rule            []NodeRule `json:"rule" form:"rule" binding:"required,dive,required"`           // 跳转规则
	ExceptionTag    []string   `json:"exception_tag" form:"exception_tag"`                          // 异常标签
	Words           string     `json:"words" form:"words" binding:"required"`                       // 节点话术
	RepeatWords     string     `json:"repeat_words" form:"repeat_words"`                            // 重新播报话术
	ExceptionAnswer string     `json:"exception_answer" form:"exception_answer" binding:"required"` // 发生异常时,机器人回答
	ExceptionNum    int16      `json:"exception_num" form:"exception_num" binding:"required"`       // 异常会话次数
	ExceptionHand   int8       `json:"exception_hand" form:"exception_hand" binding:"required"`     // 异常处理方式 1、人工 2、挂机
	IsInterrupt     int8       `json:"is_interrupt" form:"is_interrupt" binding:"required"`         // 是否打断 1、是 2、否
}

// 人工
type ArtificialData struct {
	Words          string `json:"words" form:"words" binding:"required"`                             // 机器人回答
	Phone          int32  `json:"phone" form:"phone" binding:"required_if=ArtificialType 1"`         // 呼叫转移
	Extension      int32  `json:"extension" form:"extension" binding:"required_if=ArtificialType 2"` // 分机号
	ArtificialType int8   `json:"artificial_type" form:"artificial_type" binding:"required"`         // 1、呼叫转移 2、转接分机
}

// 短信
type NoteData struct {
	Words    string `json:"words" form:"words" binding:"required"`         // 机器人回答
	NoteWord string `json:"note_word" form:"note_word" binding:"required"` //短信内容
}

// 按键
type KeyData struct {
	Rule            []KeyRule `json:"rule" form:"rule" binding:"required,dive,required"`           // 跳转规则
	ExceptionTag    []string  `json:"exception_tag" form:"exception_tag"`                          // 异常标签
	Words           string    `json:"words" form:"words" binding:"required"`                       // 节点话术
	RepeatWords     string    `json:"repeat_words" form:"repeat_words" binding:"required"`         // 重新播报话术
	ExceptionAnswer string    `json:"exception_answer" form:"exception_answer" binding:"required"` // 发生异常时,机器人回答
	ExceptionNum    int16     `json:"exception_num" form:"exception_num" binding:"required"`       // 异常会话次数
	ExceptionHand   int8      `json:"exception_hand" form:"exception_hand" binding:"required"`     // 异常处理方式 1、人工 2、挂机
	IsInterrupt     int8      `json:"is_interrupt" form:"is_interrupt" binding:"required"`         // 是否打断 1、是 2、否
}

// 跳转子流程
type JumpData struct {
	JumpNodeID string `json:"jump_node_id" form:"jump_node_id" binding:"required"` // 跳转至
}

// 结束
type EndData struct {
	Words string `json:"words" form:"words" binding:"required"` // 机器人回答
}

// 节点规则
type NodeRule struct {
	Conditions []Conditions `json:"conditions" form:"conditions" binding:"required,dive,required"` // 以下条件跳转
	Tag        []string     `json:"tag" form:"tag" `                                               // 标签
	JumpNodeID string       `json:"jump_node_id" form:"jump_node_id" binding:"required"`           // 跳转至
	JumpName   string       `json:"jump_name" form:"jump_name" binding:"required"`                 // 跳转名称
	Conform    int8         `json:"conform" form:"conform" binding:"required"`                     // 符合 1、任意 2、全部

}

// 条件
type Conditions struct {
	IntentionID string `json:"intention_id" form:"intention_id" binding:"required"` // 意图ID -1 全部异常意图
	If          int8   `json:"if" form:"if" binding:"required"`                     // 如果 1、意图
	Compare     int8   `json:"compare" form:"compare" binding:"required"`           // 比较方式 1、等于
	Content     int8   `json:"content" form:"content" binding:"required"`           // 内容 1、自定义意图 2、异常意图
}

// 按键规则
type KeyRule struct {
	Conditions []KeyConditions `json:"conditions" form:"conditions" binding:"required,dive,required"` // 以下条件跳转
	Tag        []string        `json:"tag" form:"tag"`                                                // 标签
	JumpNodeID string          `json:"jump_node_id" form:"jump_node_id" binding:"required"`           // 跳转至
	JumpName   string          `json:"jump_name" form:"jump_name" binding:"required"`                 // 跳转名称
	Conform    int8            `json:"conform" form:"conform" binding:"required"`                     // 符合 1、任意 2、全部

}

type KeyConditions struct {
	Key     string `json:"key" form:"key" binding:"required"`         // 内容
	If      int8   `json:"if" form:"if" binding:"required"`           // 如果 1、按键
	Compare int8   `json:"compare" form:"compare" binding:"required"` // 比较方式 1、等于
}