Beacon/pkg/validator/validator.go

106 lines
2.9 KiB
Go
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package validator
import (
"encoding/json"
"errors"
"fmt"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
enTranslations "github.com/go-playground/validator/v10/translations/en"
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
"go.uber.org/zap"
"reflect"
"strings"
)
// Trans 定义一个全局翻译器T
var Trans ut.Translator
// InitTrans 初始化翻译器
func InitTrans(locale string) (err error) {
// 修改gin框架中的Validator引擎属性实现自定制
v, ok := binding.Validator.Engine().(*validator.Validate)
if ok {
// 注册一个获取json tag的自定义方法
v.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
zhT := zh.New() // 中文翻译器
enT := en.New() // 英文翻译器
// 第一个参数是备用fallback的语言环境
// 后面的参数是应该支持的语言环境(支持多个)
// uni := ut.New(zhT, zhT) 也是可以的
uni := ut.New(enT, zhT, enT)
// locale 通常取决于 http 请求头的 'Accept-Language'
var ok bool
// 也可以使用 uni.FindTranslator(...) 传入多个locale进行查找
Trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
}
// 注册翻译器
switch locale {
case "en":
err = enTranslations.RegisterDefaultTranslations(v, Trans)
case "zh":
err = zhTranslations.RegisterDefaultTranslations(v, Trans)
default:
err = enTranslations.RegisterDefaultTranslations(v, Trans)
}
return
}
return
}
func RemoveTopStruct(fields map[string]string) map[string]string {
zap.L().Debug("RemoveTopStruct", zap.Any("fields", fields))
message := map[string]string{}
for field, err := range fields {
dotIndex := strings.Index(field, ".")
if dotIndex != -1 {
message[field[dotIndex+1:]] = err
} else {
message[field] = err
}
}
if len(message) == 0 {
message = map[string]string{"body": "请求的参数有误"}
}
return message
}
func TranslateErr(err error) map[string]string {
zap.L().Debug("TranslateErr", zap.Any("err", err))
var errs validator.ValidationErrors
if errors.As(err, &errs) {
return RemoveTopStruct(errs.Translate(Trans))
}
// 处理 JSON unmarshal 错误,提取字段名
var unmarshalErr *json.UnmarshalTypeError
if errors.As(err, &unmarshalErr) {
fieldName := unmarshalErr.Field
if fieldName != "" {
// 获取目标类型
targetType := unmarshalErr.Type.String()
if strings.Contains(fieldName, ".") {
fieldName = strings.Split(fieldName, ".")[len(strings.Split(fieldName, "."))-1]
}
return map[string]string{fieldName: fmt.Sprintf("类型错误,期望类型为 %s", targetType)}
}
}
return map[string]string{"body": err.Error()}
}