package api import ( "box-cost/log" "crypto/md5" "encoding/json" "fmt" "net/http" "runtime" "strconv" "strings" jwt "github.com/appleboy/gin-jwt/v2" "github.com/gin-gonic/gin" ) // Handler 包装http处理函数 type Handler func(c *gin.Context, apictx *ApiSession) (interface{}, error) // JWTHander JWT授权的http处理函数 type JWTHander func(c *gin.Context, apictx *ApiSession) (interface{}, error) // ResultWrapper 统一返回结果处理 func ResultWrapper(handle Handler, svc *Service) gin.HandlerFunc { return func(c *gin.Context) { defer func() { if r := recover(); r != nil { fmt.Println("recover success.") fmt.Println(r) buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Println("buf", string(buf)) c.JSON(http.StatusOK, NewFailResultWithData("系统异常", r)) } }() data, err := handle(c, &ApiSession{Svc: svc, User: nil}) if err != nil { httpErr, ok := err.(HTTPError) if ok { c.JSON(http.StatusOK, NewFailResultWithCode(httpErr.Error(), httpErr.Code)) return } c.JSON(http.StatusOK, NewFailResult(err.Error())) return } if data != nil { c.JSON(http.StatusOK, NewOkResult(data)) } } } // ResultJWTWrapper JWT授权处理handler func ResultJWTWrapper(handle JWTHander, svc *Service) gin.HandlerFunc { return func(c *gin.Context) { defer func() { if r := recover(); r != nil { fmt.Println("recover success.") fmt.Println(r) buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Println("buf", string(buf)) c.JSON(http.StatusOK, NewFailResultWithData("系统异常", r)) } }() claims := jwt.ExtractClaims(c) var usr *JWTUser if claims["id"] != nil { id := claims["id"].(string) name := claims["phone"].(string) role := claims["role"].(string) parent := claims["parent"].(string) state := int32(claims["state"].(float64)) usr = &JWTUser{ID: id, Phone: name, Parent: parent, Role: role, State: state} } var apis = &ApiSession{ Svc: svc, User: usr, } data, err := handle(c, apis) if err != nil { fmt.Println(err) httpErr, ok := err.(HTTPError) if ok { c.JSON(http.StatusOK, NewFailResultWithCode(httpErr.Error(), httpErr.Code)) return } c.JSON(http.StatusOK, NewFailResult(err.Error())) return } if data != nil { c.JSON(http.StatusOK, NewOkResult(data)) } } } // ResultJWTTestWrapper test 默认一个测试用户 JWT授权处理handler func ResultJWTTestWrapper(handle JWTHander, svc *Service) gin.HandlerFunc { return func(c *gin.Context) { defer func() { if r := recover(); r != nil { fmt.Println("recover success.") fmt.Println(r) buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Println("buf", string(buf)) c.JSON(http.StatusOK, NewFailResultWithData("error", r)) } }() var usr *JWTUser = &JWTUser{ID: svc.DebugUserId, Phone: svc.DebugUserPhone, Parent: svc.DebugUserId, Role: svc.DebugUserRole} data, err := handle(c, &ApiSession{Svc: svc, User: usr}) if err != nil { fmt.Println(err) httpErr, ok := err.(HTTPError) if ok { c.JSON(http.StatusOK, NewFailResultWithCode(httpErr.Error(), httpErr.Code)) return } c.JSON(http.StatusOK, NewFailResult(err.Error())) return } c.JSON(http.StatusOK, NewOkResult(data)) } } // ResultSuc 成功 func ResultSuc(c *gin.Context, data interface{}) { c.JSON(http.StatusOK, NewOkResult(data)) } // ResultFail 失败 func ResultFail(c *gin.Context, msg string) { c.JSON(http.StatusOK, NewFailResult(msg)) } // ResultFail401 失败2 func ResultFail401(c *gin.Context, msg string, data interface{}) { c.JSON(http.StatusOK, &HTTPResult{ErrorNo: 401, Result: data, ErrorDesc: msg}) } // UtilMd5 结算md5的值 func UtilMd5(s string) string { data := []byte(s) has := md5.Sum(data) return fmt.Sprintf("%x", has) } // UtilQueryPageSize 分页数据 func UtilQueryPageSize(c *gin.Context) (page int64, size int64, query map[string]interface{}) { p := c.Query("page") s := c.Query("size") q := c.Query("query") var _page = 1 if len(p) > 0 { _page, _ = strconv.Atoi(p) } page = int64(_page) var _size = 10 if len(s) > 0 { _size, _ = strconv.Atoi(s) } size = int64(_size) if len(q) > 0 { json.Unmarshal([]byte(q), &query) } else { query = map[string]interface{}{} } return } func UtilQueryPageSize2(c *gin.Context) (page int64, size int64, query map[string]interface{}, fields []string) { p := c.Query("page") s := c.Query("size") q := c.Query("query") f := c.Query("fields") var _page = 1 if len(p) > 0 { _page, _ = strconv.Atoi(p) } page = int64(_page) var _size = 10 if len(s) > 0 { _size, _ = strconv.Atoi(s) } size = int64(_size) if len(q) > 0 { json.Unmarshal([]byte(q), &query) } else { query = map[string]interface{}{} } if len(f) > 0 { fields = strings.Split(f, ",") } else { fields = []string{} } return } // HTTPResult 客户端统一返回结构体 type HTTPResult struct { ErrorNo int32 `json:"errorNo"` Result interface{} `json:"result"` ErrorDesc string `json:"errorDesc"` } func (err HTTPResult) Error() string { return err.ErrorDesc } // HTTPError 统一错误处理 type HTTPError struct { Code int32 `json:"code"` Message string `json:"message"` } func (err HTTPError) Error() string { return err.Message } // NewOkResult 创建正确结果 func NewOkResult(obj interface{}) *HTTPResult { return &HTTPResult{ErrorNo: 200, Result: obj} } // NewFailResult 创建错误结构 func NewFailResult(desc string) *HTTPResult { return &HTTPResult{ErrorNo: 500, Result: nil, ErrorDesc: desc} } // NewFailResultWithData 创建错误返回结果 func NewFailResultWithData(desc string, data interface{}) *HTTPResult { return &HTTPResult{ErrorNo: 500, Result: data, ErrorDesc: desc} } // NewFailResultWithCode 创建错误结构 func NewFailResultWithCode(desc string, code int32) *HTTPResult { return &HTTPResult{ErrorNo: code, Result: nil, ErrorDesc: desc} } // NewError NewError func NewError(desc string) HTTPError { return HTTPError{Code: 500, Message: desc} } func NewLogError(desc string) HTTPError { pc, file, line, _ := runtime.Caller(1) log.Errorf("%s:%d=>%s %v", file, line, runtime.FuncForPC(pc).Name(), desc) return HTTPError{Code: 500, Message: desc} } func NewLogWithError(err error) HTTPError { pc, file, line, _ := runtime.Caller(1) log.Errorf("%s:%d=>%s %s", file, line, runtime.FuncForPC(pc).Name(), err.Error()) return HTTPError{Code: 500, Message: err.Error()} } // NewErrorWithCode NewErrorWithCode func NewErrorWithCode(desc string, code int32) HTTPError { return HTTPError{Code: code, Message: desc} } // JWTUser jwt登录用户 type JWTUser struct { ID string `json:"id"` Parent string `json:"parent"` Phone string `json:"phone"` Role string `json:"role"` Perms string `json:"perms"` State int32 `json:"state"` } func UtilQueryMap(c *gin.Context) map[string]interface{} { query := map[string]interface{}{} q := c.Query("query") if len(q) > 0 { json.Unmarshal([]byte(q), &query) } return query } func BoolValue(value bool) *bool { return &value } func Int32Value(value int32) *int32 { return &value } func Float32Value(value float32) *float32 { return &value } func Float64Value(value float64) *float64 { return &value }