Files
PandaX/kit/ginx/req_ctx.go
lixxxww 6488dfe4aa 提交kit/ginx
Signed-off-by: lixxxww <941403820@qq.com>
2024-01-23 11:36:11 +00:00

125 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ginx
import (
"pandax/kit/biz"
"pandax/kit/token"
"time"
"github.com/gin-gonic/gin"
)
// 处理函数
type HandlerFunc func(*ReqCtx)
type ReqCtx struct {
GinCtx *gin.Context // gin context
// NeedToken bool // 是否需要token
RequiredPermission *Permission // 需要的权限信息默认为nil需要校验token
LoginAccount *token.Claims // 登录账号信息只有校验token后才会有值
LogInfo *LogInfo // 日志相关信息
ReqParam any // 请求参数,主要用于记录日志
ResData any // 响应结果
Err any // 请求错误
Timed int64 // 执行时间
noRes bool // 无需返回结果,即文件下载等
}
func (rc *ReqCtx) Handle(handler HandlerFunc) {
ginCtx := rc.GinCtx
defer func() {
var err any
err = recover()
if err != nil {
rc.Err = err
ErrorRes(ginCtx, err)
}
// 应用所有请求后置处理器
ApplyHandlerInterceptor(afterHandlers, rc)
}()
biz.IsTrue(ginCtx != nil, "ginContext == nil")
// 默认为不记录请求参数可在handler回调函数中覆盖赋值
rc.ReqParam = 0
// 默认响应结果为nil可在handler中赋值
rc.ResData = nil
// 调用请求前所有处理器
err := ApplyHandlerInterceptor(beforeHandlers, rc)
if err != nil {
panic(err)
}
begin := time.Now()
handler(rc)
rc.Timed = time.Now().Sub(begin).Milliseconds()
if !rc.noRes {
SuccessRes(ginCtx, rc.ResData)
}
}
func (rc *ReqCtx) Download(filename string) {
rc.noRes = true
Download(rc.GinCtx, filename)
}
// 新建请求上下文默认需要校验token
func NewReqCtx(g *gin.Context) *ReqCtx {
return &ReqCtx{GinCtx: g, LogInfo: NewLogInfo("默认日志信息"), RequiredPermission: &Permission{NeedToken: true, NeedCasbin: true}}
}
// 调用该方法设置请求描述,则默认记录日志,并不记录响应结果
func (r *ReqCtx) WithLog(model string) *ReqCtx {
r.LogInfo.Description = model
return r
}
// 设置请求上下文需要的权限信息
func (r *ReqCtx) WithRequiredPermission(permission *Permission) *ReqCtx {
r.RequiredPermission = permission
return r
}
// 是否需要token
func (r *ReqCtx) WithNeedToken(needToken bool) *ReqCtx {
r.RequiredPermission.NeedToken = needToken
return r
}
// 是否需要Casbin
func (r *ReqCtx) WithNeedCasbin(needCasbin bool) *ReqCtx {
r.RequiredPermission.NeedCasbin = needCasbin
return r
}
// 处理器拦截器函数
type HandlerInterceptorFunc func(*ReqCtx) error
type HandlerInterceptors []HandlerInterceptorFunc
var (
beforeHandlers HandlerInterceptors
afterHandlers HandlerInterceptors
)
// 使用前置处理器函数
func UseBeforeHandlerInterceptor(b HandlerInterceptorFunc) {
beforeHandlers = append(beforeHandlers, b)
}
// 使用后置处理器函数
func UseAfterHandlerInterceptor(b HandlerInterceptorFunc) {
afterHandlers = append(afterHandlers, b)
}
// 应用指定处理器拦截器,如果有一个错误则直接返回错误
func ApplyHandlerInterceptor(his HandlerInterceptors, rc *ReqCtx) any {
for _, handler := range his {
if err := handler(rc); err != nil {
return err
}
}
return nil
}