package response import ( "encoding/json" "github.com/gin-gonic/gin" "github.com/go-playground/form" "net/http" "unicode" ) type result struct { ctx *gin.Context } func New(ctx *gin.Context) *result { return &result{ctx: ctx} } func (s *result) BindQuery(v any) error { decoder := form.NewDecoder() decoder.SetTagName("json") err := decoder.Decode(v, s.ctx.Request.URL.Query()) if err != nil { return err } return s.Validate(v) } func (s *result) Validate(v any) error { if vv, ok := v.(interface { Validate() error }); ok { return vv.Validate() } return nil } func (s *result) BindJSON(v any) error { body := s.ctx.Request.Body decoder := json.NewDecoder(body) if err := decoder.Decode(v); err != nil { return err } return s.Validate(v) } func (s *result) Error(err error) { if err == nil { return } //参数错误 if vv, ok := err.(ValidateError); ok { s.Result(http.StatusBadRequest, "InvalidArgument", vv.ErrorName(), map[string]string{ lcfirst(vv.Field()): vv.Reason(), }) return } gs := errorx.FromError(err) s.Result(int(gs.Code), gs.Reason, gs.Message, gs.Metadata) } func lcfirst(str string) string { for i, v := range str { return string(unicode.ToLower(v)) + str[i+1:] } return "" } type ValidateError interface { Field() string Reason() string ErrorName() string } func (s *result) Success(data any) { s.ctx.JSON(http.StatusOK, data) } func (s *result) Result(httpCode int, reason string, message string, metadata map[string]string) { s.ctx.JSON(httpCode, gin.H{ "status": httpCode, "reason": reason, "message": message, "metadata": metadata, }) } func (s *result) ServerResult(res any, err error) { if err != nil { s.Error(err) } else { s.Success(res) } }