108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
|
package validate
|
||
|
|
||
|
import (
|
||
|
"git.nobla.cn/golang/rest/types"
|
||
|
"gorm.io/gorm"
|
||
|
"reflect"
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
SkipValidations = "validations:skip_validations"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
scopeCtxKey = &validateScope{}
|
||
|
telephoneRegex = regexp.MustCompile("^\\d{5,20}$")
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
validateScope struct {
|
||
|
DB *gorm.DB
|
||
|
Column string
|
||
|
Domain string
|
||
|
MultiDomain bool
|
||
|
Model interface{}
|
||
|
}
|
||
|
|
||
|
StructError struct {
|
||
|
Tag string `json:"tag"`
|
||
|
Column string `json:"column"`
|
||
|
Message string `json:"message"`
|
||
|
}
|
||
|
|
||
|
validateRule struct {
|
||
|
Rule string
|
||
|
Value string
|
||
|
Valid bool
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func (err *StructError) Error() string {
|
||
|
return err.Message
|
||
|
}
|
||
|
|
||
|
func newRule(ss ...string) *validateRule {
|
||
|
v := &validateRule{
|
||
|
Valid: true,
|
||
|
}
|
||
|
if len(ss) == 1 {
|
||
|
v.Rule = ss[0]
|
||
|
} else if len(ss) >= 2 {
|
||
|
v.Rule = ss[0]
|
||
|
v.Value = ss[1]
|
||
|
}
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
// formatError 格式化错误消息
|
||
|
func formatError(rule types.Rule, scm *types.Schema, tag string) string {
|
||
|
var s string
|
||
|
switch tag {
|
||
|
case "db_unique":
|
||
|
s = scm.Label + "值已经存在."
|
||
|
break
|
||
|
case "required":
|
||
|
s = scm.Label + "值不能为空."
|
||
|
case "max":
|
||
|
if scm.Type == "string" {
|
||
|
s = scm.Label + "长度不能大于" + strconv.Itoa(rule.Max)
|
||
|
} else {
|
||
|
s = scm.Label + "值不能大于" + strconv.Itoa(rule.Max)
|
||
|
}
|
||
|
case "min":
|
||
|
if scm.Type == "string" {
|
||
|
s = scm.Label + "长度不能小于" + strconv.Itoa(rule.Max)
|
||
|
} else {
|
||
|
s = scm.Label + "值不能小于" + strconv.Itoa(rule.Max)
|
||
|
}
|
||
|
}
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
// isEmpty 判断值是否为空
|
||
|
func isEmpty(val any) bool {
|
||
|
if val == nil {
|
||
|
return true
|
||
|
}
|
||
|
v := reflect.ValueOf(val)
|
||
|
switch v.Kind() {
|
||
|
case reflect.String, reflect.Array:
|
||
|
return v.Len() == 0
|
||
|
case reflect.Map, reflect.Slice:
|
||
|
return v.IsNil() || v.Len() == 0
|
||
|
case reflect.Bool:
|
||
|
return !v.Bool()
|
||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||
|
return v.Int() == 0
|
||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||
|
return v.Uint() == 0
|
||
|
case reflect.Float32, reflect.Float64:
|
||
|
return v.Float() == 0
|
||
|
case reflect.Interface, reflect.Ptr:
|
||
|
return v.IsNil()
|
||
|
}
|
||
|
return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())
|
||
|
}
|