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

147 lines
3.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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