You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.1 KiB
109 lines
2.1 KiB
package response |
|
|
|
import ( |
|
"encoding/json" |
|
"git.echinacities.com/mogfee/protoc-gen-kit/xerrors" |
|
"github.com/gin-gonic/gin" |
|
"github.com/go-playground/form" |
|
"net/http" |
|
) |
|
|
|
var ( |
|
code codec |
|
) |
|
|
|
type result struct { |
|
ctx *gin.Context |
|
} |
|
|
|
func New(ctx *gin.Context) *result { |
|
return &result{ctx: ctx} |
|
} |
|
|
|
func (s *result) BindJSON(v any) error { |
|
err := s.ShouldBindJson(v) |
|
if err != nil { |
|
return err |
|
} |
|
if r, ok := v.(interface { |
|
Validate() error |
|
}); ok { |
|
return r.Validate() |
|
} |
|
return nil |
|
} |
|
func (s *result) BindQuery(v any) error { |
|
err := s.ShouldBindQuery(v) |
|
if err != nil { |
|
return err |
|
} |
|
if r, ok := v.(interface { |
|
Validate() error |
|
}); ok { |
|
return r.Validate() |
|
} |
|
return nil |
|
} |
|
|
|
func (s *result) ShouldBindQuery(v any) error { |
|
decoder := form.NewDecoder() |
|
decoder.SetTagName("json") |
|
return decoder.Decode(v, s.ctx.Request.URL.Query()) |
|
} |
|
func (s *result) ShouldBindJson(v any) error { |
|
body := s.ctx.Request.Body |
|
decoder := json.NewDecoder(body) |
|
return decoder.Decode(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{ |
|
vv.Field(): vv.Reason(), |
|
}) |
|
return |
|
} |
|
gs := xerrors.FromError(err) |
|
|
|
s.Result(gs.Status, gs.Reason, gs.Message, gs.Metadata) |
|
} |
|
|
|
type ValidateError interface { |
|
Field() string |
|
Reason() string |
|
ErrorName() string |
|
} |
|
type MyRender struct { |
|
Data any |
|
} |
|
|
|
func (m *MyRender) Render(writer http.ResponseWriter) error { |
|
jsonBytes, err := code.Marshal(m.Data) |
|
if err != nil { |
|
return err |
|
} |
|
_, err = writer.Write(jsonBytes) |
|
return err |
|
} |
|
|
|
func (m *MyRender) WriteContentType(w http.ResponseWriter) { |
|
header := w.Header() |
|
if val := header["Content-Type"]; len(val) == 0 { |
|
header["Content-Type"] = []string{"application/json; charset=utf-8"} |
|
} |
|
} |
|
|
|
func (s *result) Success(data any) { |
|
s.ctx.Render(http.StatusOK, &MyRender{Data: 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, |
|
}) |
|
}
|
|
|