Files
workspace/code/base-project/base-go-v2/internal/utils/validate/validate.go
T
2025-11-05 22:25:09 +08:00

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:
// 其他类型暂不校验
}
}