haibei/pkg/util/gin.go
2025-06-19 10:33:58 +08:00

137 lines
2.9 KiB
Go

package util
import (
"fmt"
"net/http"
"reflect"
"strings"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.guxuan/haibei/pkg/encoding/json"
"github.guxuan/haibei/pkg/errors"
"github.guxuan/haibei/pkg/logging"
"go.uber.org/zap"
)
// Get access token from header or query parameter
func GetToken(c *gin.Context) string {
var token string
auth := c.GetHeader("Authorization")
prefix := "Bearer "
if auth != "" && strings.HasPrefix(auth, prefix) {
token = auth[len(prefix):]
} else {
token = auth
}
if token == "" {
token = c.Query("accessToken")
}
return token
}
// Get body data from context
func GetBodyData(c *gin.Context) []byte {
if v, ok := c.Get(ReqBodyKey); ok {
if b, ok := v.([]byte); ok {
return b
}
}
return nil
}
// Parse body json data to struct
func ParseJSON(c *gin.Context, obj interface{}) error {
if err := c.ShouldBindJSON(obj); err != nil {
return errors.BadRequest("", "Failed to parse json: %s", err.Error())
}
return nil
}
// Parse query parameter to struct
func ParseQuery(c *gin.Context, obj interface{}) error {
if err := c.ShouldBindQuery(obj); err != nil {
return errors.BadRequest("", "Failed to parse query: %s", err.Error())
}
return nil
}
// Parse body form data to struct
func ParseForm(c *gin.Context, obj interface{}) error {
if err := c.ShouldBindWith(obj, binding.Form); err != nil {
return errors.BadRequest("", "Failed to parse form: %s", err.Error())
}
return nil
}
// Response json data with status code
func ResJSON(c *gin.Context, status int, v interface{}) {
buf, err := json.Marshal(v)
if err != nil {
panic(err)
}
c.Set(ResBodyKey, buf)
c.Data(status, "application/json; charset=utf-8", buf)
c.Abort()
}
func ResSuccess(c *gin.Context, v interface{}) {
ResJSON(c, http.StatusOK, ResponseResult{
Success: true,
Data: v,
})
}
func ResOK(c *gin.Context) {
ResJSON(c, http.StatusOK, ResponseResult{
Success: true,
})
}
func ResPage(c *gin.Context, v interface{}, pr *PaginationResult) {
var total int64
if pr != nil {
total = pr.Total
}
reflectValue := reflect.Indirect(reflect.ValueOf(v))
if reflectValue.IsNil() {
v = make([]interface{}, 0)
}
ResJSON(c, http.StatusOK, ResponseResult{
Success: true,
Data: v,
Total: total,
})
}
func ResError(c *gin.Context, err error, status ...int) {
var ierr *errors.Error
if e, ok := errors.As(err); ok {
ierr = e
} else {
ierr = errors.FromError(errors.InternalServerError("", err.Error()))
}
code := int(ierr.Code)
if len(status) > 0 {
code = status[0]
}
if code >= 500 {
ctx := c.Request.Context()
ctx = logging.NewTag(ctx, logging.TagKeySystem)
ctx = logging.NewStack(ctx, fmt.Sprintf("%+v", err))
logging.Context(ctx).Error("Internal server error", zap.Error(err))
ierr.Detail = http.StatusText(http.StatusInternalServerError)
}
ierr.Code = int32(code)
ResJSON(c, code, ResponseResult{Error: ierr})
}