66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
package validate
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// ValidationError 用于收集多个字段错误,同时实现 error 接口
|
|
type ValidationError struct {
|
|
Errors map[string]string
|
|
}
|
|
|
|
// Error 实现 error 接口
|
|
func (v *ValidationError) Error() string {
|
|
msgs := make([]string, 0, len(v.Errors))
|
|
for field, err := range v.Errors {
|
|
msgs = append(msgs, fmt.Sprintf("%s: %s", field, err))
|
|
}
|
|
return strings.Join(msgs, "; ")
|
|
}
|
|
|
|
// NotEmpty 校验 map[string]interface{} 中指定字段不能为空
|
|
func NotEmpty(data map[string]interface{}, fields ...string) error {
|
|
errs := make(map[string]string)
|
|
|
|
for _, field := range fields {
|
|
collectErrors(data[field], field, errs)
|
|
}
|
|
|
|
if len(errs) > 0 {
|
|
return &ValidationError{Errors: errs}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// collectErrors 递归收集字段错误
|
|
func collectErrors(v interface{}, path string, errs map[string]string) {
|
|
if v == nil {
|
|
errs[path] = fmt.Sprintf("字段 %s 不能为空", path)
|
|
return
|
|
}
|
|
|
|
switch val := v.(type) {
|
|
case string:
|
|
if strings.TrimSpace(val) == "" {
|
|
errs[path] = fmt.Sprintf("字段 %s 不能为空", path)
|
|
}
|
|
case []interface{}:
|
|
if len(val) == 0 {
|
|
errs[path] = fmt.Sprintf("字段 %s 不能为空", path)
|
|
}
|
|
for i, elem := range val {
|
|
collectErrors(elem, fmt.Sprintf("%s[%d]", path, i), errs)
|
|
}
|
|
case map[string]interface{}:
|
|
if len(val) == 0 {
|
|
errs[path] = fmt.Sprintf("字段 %s 不能为空", path)
|
|
}
|
|
for k, elem := range val {
|
|
collectErrors(elem, fmt.Sprintf("%s.%s", path, k), errs)
|
|
}
|
|
default:
|
|
// 其他类型暂不校验
|
|
}
|
|
}
|