backend/app/brahma/api/murder/internal/handler/check.go

147 lines
3.8 KiB
Go
Raw Permalink Normal View History

2022-01-12 14:34:31 +08:00
package handler
import (
"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/error_process"
"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/model"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/spf13/cast"
"reflect"
"strings"
)
type pluginFunc func(interface{}) error
func checkParam(body interface{}, ctx *fiber.Ctx, plugins ...pluginFunc) error {
//第一次执行解析body并且调用插件方法
if ctx != nil {
err := ctx.BodyParser(body)
if err != nil {
return error_process.CommonErr(err)
}
for _, plugin := range plugins {
if err = plugin(body); err != nil {
return err
}
}
}
//step1 校验是否是指针
typ := reflect.TypeOf(body)
val := reflect.ValueOf(body)
if val.Kind().String() != reflect.Ptr.String() {
return errors.New(error_process.NoPointError)
}
if val.IsNil() {
return errors.New(error_process.NilPointError)
}
num := val.Elem().NumField()
for i := 0; i < num; i++ {
kind := val.Elem().Field(i).Kind().String()
switch kind {
case reflect.Ptr.String():
//显示指定某些指针跳过校验
if tag := typ.Elem().Field(i).Tag.Get("valid"); tag == "omitempty" {
continue
}
//递归调用
if err := checkParam(val.Elem().Field(i).Interface(), nil); err != nil {
return err
}
default:
//非空值验证
if tag := typ.Elem().Field(i).Tag.Get("valid"); tag == "no_empty" {
switch kind {
case reflect.Ptr.String():
if val.Elem().Field(i).IsNil() == true {
return error_process.EmptyValueErr(typ.Elem().Field(i).Tag.Get("json"))
}
case reflect.Slice.String():
if val.Elem().Field(i).IsNil() == true || val.Elem().Field(i).Len() == 0 {
return error_process.EmptyValueErr(typ.Elem().Field(i).Tag.Get("json"))
}
default:
if val.Elem().Field(i).IsZero() {
return error_process.EmptyValueErr(typ.Elem().Field(i).Tag.Get("json"))
}
}
}
}
//指定制验证
if values := typ.Elem().Field(i).Tag.Get("value"); values != "" {
eles := make([]string, 0)
if eles = strings.Split(values, "|"); len(eles) == 0 {
continue
}
switch kind {
case reflect.Int.String():
for _, v := range eles {
if b := val.Elem().Field(i).Int(); b == cast.ToInt64(v) {
//匹配到值定制跳出此次tag处理方法
goto LOOP
}
}
return errors.New(error_process.IllegalValueError)
default:
return errors.New(error_process.BodyParserErr)
}
}
LOOP:
}
return nil
}
//tag uuid 覆盖写
func tagUuidPlugin(body interface{}) error {
if req, ok := body.(*TagReq); ok {
if req.Tag == nil {
return errors.New(error_process.BodyParserErr)
}
//if req.Tag.Uuid == "" {
// req.Tag.Uuid = xid.New().String()
//}
return nil
}
return errors.New(error_process.BodyParserErr)
}
//category uuid 覆盖写
func categoryUuidPlugin(body interface{}) error {
if req, ok := body.(*CategoryReq); ok {
if req.Category == nil {
return errors.New(error_process.BodyParserErr)
}
if req.Category.Uuid == "" {
req.Category.Uuid = uuid.New().String()
}
return nil
}
return errors.New(error_process.BodyParserErr)
}
//script uuid 覆盖写
func scriptUuidPlugin(body interface{}) error {
if req, ok := body.(*model.Scripts); ok {
if req == nil {
return errors.New(error_process.BodyParserErr)
}
if req.Uuid == "" {
req.Uuid = uuid.New().String()
}
return nil
}
return errors.New(error_process.BodyParserErr)
}
func createTagParamCheck(body interface{}, ctx *fiber.Ctx) error {
return checkParam(body, ctx, tagUuidPlugin)
}
func createCategoryParamCheck(body interface{}, ctx *fiber.Ctx) error {
return checkParam(body, ctx, categoryUuidPlugin)
}
func createScriptParamCheck(body interface{}, ctx *fiber.Ctx) error {
return checkParam(body, ctx, scriptUuidPlugin)
}