|
@@ -0,0 +1,156 @@
|
|
|
|
+package utils
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "errors"
|
|
|
|
+ "reflect"
|
|
|
|
+ "strconv"
|
|
|
|
+ "strings"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// 校验方法 接收两个参数 入参实例,规则map
|
|
|
|
+func Verify(st interface{}, roleMap map[string][]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)
|
|
|
|
+ if len(roleMap[tagVal.Name]) > 0 {
|
|
|
|
+ for _, v := range roleMap[tagVal.Name] {
|
|
|
|
+ switch {
|
|
|
|
+ case strings.Index(v, "isBlank") > -1:
|
|
|
|
+ if isBlank(val) {
|
|
|
|
+ return errors.New(tagVal.Name + "值不能为空")
|
|
|
|
+ }
|
|
|
|
+ case compareMap[strings.Split(v, "=")[0]]:
|
|
|
|
+ if !compareVerify(val, v) {
|
|
|
|
+ return errors.New(tagVal.Name + "不在范围内")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ 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
|
|
|
|
+ }
|
|
|
|
+}
|