kra/pkg/utils/verify.go

305 lines
7.6 KiB
Go

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)
}