package utils import ( "errors" "reflect" "regexp" "strconv" "strings" ) type Rules map[string][]string type RulesMap map[string]Rules var CustomizeMap = make(map[string]Rules) var ( LANG_CN = "cn" //中文 LANG_EN = "english" //英文 ) var ( VERIFY_NOT_EMPTY = "notEmpty" //不为空,必填 VERIFY_LENGTH_NOT_LEGA = "lengthNotLega" //长度不合规 ) func RegisterRule(key string, rule Rules) (err error) { if CustomizeMap[key] != nil { return errors.New(key + "已注册,无法重复注册") } else { CustomizeMap[key] = rule return nil } } func NotEmpty() string { return "notEmpty" } func Lt(mark string) string { return "lt=" + mark } func Le(mark string) string { return "le=" + mark } func Eq(mark string) string { return "eq=" + mark } func Ne(mark string) string { return "ne=" + mark } func Ge(mark string) string { return "ge=" + mark } func Gt(mark string) string { return "gt=" + mark } func Verify(st interface{}, roleMap Rules,lang string) (err 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) // 获取reflect.Type类型 kd := val.Kind() // 获取到st对应的类别 if kd != reflect.Struct { return errors.New("expect struct") } num := val.NumField() for i := 0; i < num; i++ { tagVal := typ.Field(i) val := val.Field(i) tagName := tagVal.Tag.Get("form") if tagName == ""{ tagName = tagVal.Name } if len(roleMap[tagVal.Name]) > 0 { for _, v := range roleMap[tagVal.Name] { switch { case v == "notEmpty": if isBlank(val) { return errors.New(tagName + getVerifyErrInfo(VERIFY_NOT_EMPTY,lang)) } case compareMap[strings.Split(v, "=")[0]]: if !compareVerify(val, v) { return errors.New(tagName + getVerifyErrInfo(VERIFY_LENGTH_NOT_LEGA,lang) + v) } } } } } return nil } func compareVerify(value reflect.Value, VerifyStr string) bool { switch value.Kind() { case reflect.String, reflect.Slice, reflect.Array: return compare(value.Len(), VerifyStr) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return compare(value.Uint(), VerifyStr) case reflect.Float32, reflect.Float64: return compare(value.Float(), VerifyStr) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return compare(value.Int(), VerifyStr) default: return false } } func isBlank(value reflect.Value) bool { switch value.Kind() { case reflect.String: 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()) } func compare(value interface{}, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") val := reflect.ValueOf(value) switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: VInt, VErr := strconv.ParseInt(VerifyStrArr[1], 10, 64) if VErr != nil { return false } switch { case VerifyStrArr[0] == "lt": return val.Int() < VInt case VerifyStrArr[0] == "le": return val.Int() <= VInt case VerifyStrArr[0] == "eq": return val.Int() == VInt case VerifyStrArr[0] == "ne": return val.Int() != VInt case VerifyStrArr[0] == "ge": return val.Int() >= VInt case VerifyStrArr[0] == "gt": return val.Int() > VInt default: return false } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: VInt, VErr := strconv.Atoi(VerifyStrArr[1]) if VErr != nil { return false } switch { case VerifyStrArr[0] == "lt": return val.Uint() < uint64(VInt) case VerifyStrArr[0] == "le": return val.Uint() <= uint64(VInt) case VerifyStrArr[0] == "eq": return val.Uint() == uint64(VInt) case VerifyStrArr[0] == "ne": return val.Uint() != uint64(VInt) case VerifyStrArr[0] == "ge": return val.Uint() >= uint64(VInt) case VerifyStrArr[0] == "gt": return val.Uint() > uint64(VInt) default: return false } case reflect.Float32, reflect.Float64: VFloat, VErr := strconv.ParseFloat(VerifyStrArr[1], 64) if VErr != nil { return false } switch { case VerifyStrArr[0] == "lt": return val.Float() < VFloat case VerifyStrArr[0] == "le": return val.Float() <= VFloat case VerifyStrArr[0] == "eq": return val.Float() == VFloat case VerifyStrArr[0] == "ne": return val.Float() != VFloat case VerifyStrArr[0] == "ge": return val.Float() >= VFloat case VerifyStrArr[0] == "gt": return val.Float() > VFloat default: return false } default: return false } } func getVerifyErrInfo(errType string,lang string) (errInfo string) { if lang == LANG_EN{ switch errType { case VERIFY_NOT_EMPTY: errInfo = " Cannot be empty" case VERIFY_LENGTH_NOT_LEGA: errInfo = " Length or value is not in legal range," } }else{ switch errType { case VERIFY_NOT_EMPTY: errInfo = " 值不能为空" case VERIFY_LENGTH_NOT_LEGA: errInfo = " 长度或值不在合法范围," } } return } func ContainsChinese(str string) bool { var reg = regexp.MustCompile("^[\u4e00-\u9fa5]$") for _, v := range str { if reg.MatchString(string(v)) { return true } } return false }