|
|
|
package response
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"git.diulo.com/mogfee/kit/errors"
|
|
|
|
"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 := errors.FromError(err)
|
|
|
|
|
|
|
|
s.Result(gs.Status, 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)
|
|
|
|
}
|
|
|
|
}
|