package service import ( "context" "gitea.com/red-future/common/utils" "github.com/gogf/gf/v2/frame/g" ) // asyncCtx 固化异步执行所需的 token/user,避免请求结束后丢失(仅在“同请求内起 goroutine”有用)。 // 本项目当前是“落库 + 后台 worker”模式,因此还会把必要信息持久化到任务表的 request_payload 中。 func asyncCtx(ctx context.Context) context.Context { asyncCtx := context.WithoutCancel(ctx) if r := g.RequestFromCtx(ctx); r != nil { if token := r.Header.Get("Authorization"); token != "" { asyncCtx = context.WithValue(asyncCtx, "token", token) } if userInfo := r.Header.Get("X-User-Info"); userInfo != "" { asyncCtx = context.WithValue(asyncCtx, "xUserInfo", userInfo) } } if user, err := utils.GetUserInfo(ctx); err == nil && user != nil { asyncCtx = context.WithValue(asyncCtx, "user", user) } return asyncCtx } // forwardHeaders 透传调用链路中必须的头信息(优先使用 ctx 里固化的 token / xUserInfo)。 func forwardHeaders(ctx context.Context) map[string]string { headers := make(map[string]string) if token, ok := ctx.Value("token").(string); ok && token != "" { headers["Authorization"] = token } if x, ok := ctx.Value("xUserInfo").(string); ok && x != "" { headers["X-User-Info"] = x } // 兜底:从请求头拿 if r := g.RequestFromCtx(ctx); r != nil { if headers["Authorization"] == "" { if token := r.Header.Get("Authorization"); token != "" { headers["Authorization"] = token } } if headers["X-User-Info"] == "" { if userInfo := r.Header.Get("X-User-Info"); userInfo != "" { headers["X-User-Info"] = userInfo } } } return headers }