package utils import ( "errors" "reflect" "regexp" "strconv" "strings" ) // Rules 验证规则类型 type Rules map[string][]string // RulesMap 规则映射类型 type RulesMap map[string]Rules // CustomizeMap 自定义规则映射 var CustomizeMap = make(map[string]Rules) // 预定义验证规则 var ( IdVerify = Rules{"ID": []string{NotEmpty()}} ApiVerify = Rules{"Path": {NotEmpty()}, "Description": {NotEmpty()}, "ApiGroup": {NotEmpty()}, "Method": {NotEmpty()}} MenuVerify = Rules{"Path": {NotEmpty()}, "Name": {NotEmpty()}, "Component": {NotEmpty()}, "Sort": {Ge("0")}} MenuMetaVerify = Rules{"Title": {NotEmpty()}} LoginVerify = Rules{"Username": {NotEmpty()}, "Password": {NotEmpty()}} RegisterVerify = Rules{"Username": {NotEmpty()}, "NickName": {NotEmpty()}, "Password": {NotEmpty()}, "AuthorityId": {NotEmpty()}} PageInfoVerify = Rules{"Page": {NotEmpty()}, "PageSize": {NotEmpty()}} CustomerVerify = Rules{"CustomerName": {NotEmpty()}, "CustomerPhoneData": {NotEmpty()}} AutoCodeVerify = Rules{"Abbreviation": {NotEmpty()}, "StructName": {NotEmpty()}, "PackageName": {NotEmpty()}} AutoPackageVerify = Rules{"PackageName": {NotEmpty()}} AuthorityVerify = Rules{"AuthorityId": {NotEmpty()}, "AuthorityName": {NotEmpty()}} AuthorityIdVerify = Rules{"AuthorityId": {NotEmpty()}} OldAuthorityVerify = Rules{"OldAuthorityId": {NotEmpty()}} ChangePasswordVerify = Rules{"Password": {NotEmpty()}, "NewPassword": {NotEmpty()}} SetUserAuthorityVerify = Rules{"AuthorityId": {NotEmpty()}} ) // RegisterRule 注册自定义规则方案建议在路由初始化层即注册 func RegisterRule(key string, rule Rules) (err error) { if CustomizeMap[key] != nil { return errors.New(key + "已注册,无法重复注册") } CustomizeMap[key] = rule return nil } // NotEmpty 非空验证 func NotEmpty() string { return "notEmpty" } // Ge 大于等于验证 func Ge(value string) string { return "ge=" + value } // Le 小于等于验证 func Le(value string) string { return "le=" + value } // Gt 大于验证 func Gt(value string) string { return "gt=" + value } // Lt 小于验证 func Lt(value string) string { return "lt=" + value } // Eq 等于验证 func Eq(value string) string { return "eq=" + value } // Ne 不等于验证 func Ne(value string) string { return "ne=" + value } // Len 长度验证 func Len(value string) string { return "len=" + value } // MinLen 最小长度验证 func MinLen(value string) string { return "minLen=" + value } // MaxLen 最大长度验证 func MaxLen(value string) string { return "maxLen=" + value } // Regexp 正则验证 func Regexp(value string) string { return "regexp=" + value } // RegexpMatch 正则校验 校验输入项是否满足正则表达式 func RegexpMatch(rule string) string { return "regexp=" + rule } // Verify 验证结构体字段 func Verify(st interface{}, rules Rules) error { compareMap := map[string]bool{ "lt": true, "le": true, "eq": true, "ne": true, "ge": true, "gt": true, } typ := reflect.TypeOf(st) val := reflect.ValueOf(st) // 处理指针类型 if typ.Kind() == reflect.Ptr { typ = typ.Elem() val = val.Elem() } kd := val.Kind() if kd != reflect.Struct { return errors.New("expect struct") } num := val.NumField() for i := 0; i < num; i++ { tagVal := typ.Field(i) fieldVal := val.Field(i) fieldName := tagVal.Name // 递归处理嵌套结构体 if tagVal.Type.Kind() == reflect.Struct { if err := Verify(fieldVal.Interface(), rules); err != nil { return err } } // 检查是否有验证规则 if ruleList, ok := rules[fieldName]; ok { for _, rule := range ruleList { switch { case rule == "notEmpty": if isBlank(fieldVal) { return errors.New(fieldName + "值不能为空") } case strings.HasPrefix(rule, "regexp="): if !regexpMatch(strings.Split(rule, "=")[1], fieldVal.String()) { return errors.New(fieldName + "格式校验不通过") } case compareMap[strings.Split(rule, "=")[0]]: if !compareVerify(fieldVal, rule) { return errors.New(fieldName + "长度或值不在合法范围," + rule) } } } } } return nil } // isBlank 非空校验 func isBlank(value reflect.Value) bool { switch value.Kind() { case reflect.String, reflect.Slice: return value.Len() == 0 case reflect.Bool: return !value.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return value.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return value.Uint() == 0 case reflect.Float32, reflect.Float64: return value.Float() == 0 case reflect.Interface, reflect.Ptr: return value.IsNil() } return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface()) } // compareVerify 长度和数字的校验方法 根据类型自动校验 func compareVerify(value reflect.Value, VerifyStr string) bool { switch value.Kind() { case reflect.String: return compareInt(len([]rune(value.String())), VerifyStr) case reflect.Slice, reflect.Array: return compareInt(value.Len(), VerifyStr) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return compareUint(value.Uint(), VerifyStr) case reflect.Float32, reflect.Float64: return compareFloat64(value.Float(), VerifyStr) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return compareInt64(value.Int(), VerifyStr) default: return false } } // compareInt 整数比较 func compareInt(value int, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") VInt, VErr := strconv.Atoi(VerifyStrArr[1]) if VErr != nil { return false } switch VerifyStrArr[0] { case "lt": return value < VInt case "le": return value <= VInt case "eq": return value == VInt case "ne": return value != VInt case "ge": return value >= VInt case "gt": return value > VInt default: return false } } // compareInt64 int64比较 func compareInt64(value int64, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") VInt, VErr := strconv.ParseInt(VerifyStrArr[1], 10, 64) if VErr != nil { return false } switch VerifyStrArr[0] { case "lt": return value < VInt case "le": return value <= VInt case "eq": return value == VInt case "ne": return value != VInt case "ge": return value >= VInt case "gt": return value > VInt default: return false } } // compareUint uint64比较 func compareUint(value uint64, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") VInt, VErr := strconv.ParseUint(VerifyStrArr[1], 10, 64) if VErr != nil { return false } switch VerifyStrArr[0] { case "lt": return value < VInt case "le": return value <= VInt case "eq": return value == VInt case "ne": return value != VInt case "ge": return value >= VInt case "gt": return value > VInt default: return false } } // compareFloat64 float64比较 func compareFloat64(value float64, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") VFloat, VErr := strconv.ParseFloat(VerifyStrArr[1], 64) if VErr != nil { return false } switch VerifyStrArr[0] { case "lt": return value < VFloat case "le": return value <= VFloat case "eq": return value == VFloat case "ne": return value != VFloat case "ge": return value >= VFloat case "gt": return value > VFloat default: return false } } // regexpMatch 正则匹配 func regexpMatch(rule, matchStr string) bool { return regexp.MustCompile(rule).MatchString(matchStr) }