feat: Router.Call 拆分出 CallWithUser,支持指定内部调用身份

新增 CallWithUser(r, u, code, params, opts...),内部转发请求时可以冒充成指定用户身份,而不是沿用外部传入 request 自带的身份,用于类似"查自己的信息不该受字段级角色权限限制"这种需要以系统用户身份发起内部调用的场景。Call 本身签名不变,不影响现有调用方。
This commit is contained in:
2026-07-21 18:01:28 +08:00
parent 7f74caead4
commit 6d0c01c21f
+32 -25
View File
@@ -7,7 +7,6 @@ import (
) )
type RouteMethod string type RouteMethod string
type RouteCategory string
type RouteService string type RouteService string
type RouteParamType string type RouteParamType string
type RouteParamCategory string type RouteParamCategory string
@@ -17,25 +16,25 @@ type RouteCtx struct {
} }
const ( const (
GET RouteMethod = "GET" GET RouteMethod = "GET"
POST RouteMethod = "POST" POST RouteMethod = "POST"
PUT RouteMethod = "PUT" PUT RouteMethod = "PUT"
DELETE RouteMethod = "DELETE" DELETE RouteMethod = "DELETE"
WS RouteMethod = "WS"
SSE RouteMethod = "SSE"
GRPC RouteMethod = "GRPC"
MCP RouteMethod = "MCP"
STRUCTURE RouteMethod = "STRUCTURE"
) )
const ( const (
WS RouteCategory = "ws" // resource_apis
GRPC RouteCategory = "grpc" FUNC RouteService = "func"
FUNC RouteCategory = "func" SHOW RouteService = "show"
SHOW RouteCategory = "show" QUERY RouteService = "query"
QUERY RouteCategory = "query" STORE RouteService = "store"
STORE RouteCategory = "store" DESTROY RouteService = "destroy"
DESTROY RouteCategory = "destroy" // system
STRUCTURE RouteCategory = "structure"
)
const (
API RouteService = "api"
FSM RouteService = "fsm" FSM RouteService = "fsm"
LIST RouteService = "list" LIST RouteService = "list"
XLSX RouteService = "xlsx" XLSX RouteService = "xlsx"
@@ -81,12 +80,19 @@ type RouteMiddleware interface {
type Router interface { type Router interface {
Call(r *http.Request, code string, params map[string]any, opts ...RouteMatchOption) (HttpResponse, error) Call(r *http.Request, code string, params map[string]any, opts ...RouteMatchOption) (HttpResponse, error)
// CallWithUser 与 Call 相同,但内部转发请求时冒充成 u 的身份,而不是沿用 r 自带的身份
// (比如需要以系统用户身份发起内部调用)。
CallWithUser(r *http.Request, u User, code string, params map[string]any, opts ...RouteMatchOption) (HttpResponse, error)
Get(uuid string, opts ...RouteMatchOption) (Route, bool) Get(uuid string, opts ...RouteMatchOption) (Route, bool)
Register(cr chi.Router) Register(cr chi.Router)
RefreshRoutes() error RefreshRoutes() error
// Shutdown 关闭路由层管理的所有长连接(如 MCP SSE),
// 应通过 http.Server.RegisterOnShutdown 注册,在 HTTP 服务关闭时调用。
Shutdown()
} }
type Route interface { type Route interface {
Method() RouteMethod
GetUuid() string GetUuid() string
GetCode() string GetCode() string
GetPrimaryKey() string GetPrimaryKey() string
@@ -94,10 +100,10 @@ type Route interface {
GetUris() []string GetUris() []string
GetParamValues(*http.Request, ...RouteParam) (GlobalParams, error) GetParamValues(*http.Request, ...RouteParam) (GlobalParams, error)
GetResource() Resource GetResource() Resource
GetCategory() RouteCategory
GetService() RouteService GetService() RouteService
GetRoles() []string GetRoles() []string
MakeRequest(r *http.Request, params map[string]any) (*http.Request, error) MakeRequest(r *http.Request, params map[string]any) (*http.Request, error)
Version() string
} }
type RouteParam interface { type RouteParam interface {
@@ -110,25 +116,26 @@ type RouteParam interface {
type RouteMatchOption func(opts *RouteMatches) type RouteMatchOption func(opts *RouteMatches)
type RouteMatches struct { type RouteMatches struct {
categories []RouteCategory methods []RouteMethod
services []RouteService services []RouteService
} }
func (this RouteMatches) RouteCategories() []RouteCategory { func (this RouteMatches) RouteMethods() []RouteMethod {
return this.categories return this.methods
} }
func (this RouteMatches) RouteServices() []RouteService { func (this RouteMatches) RouteServices() []RouteService {
return this.services return this.services
} }
func RouteMatch[T RouteCategory | RouteService](v T) RouteMatchOption { func RouteMatch[T RouteMethod | RouteService](v T) RouteMatchOption {
return func(opt *RouteMatches) { return func(opt *RouteMatches) {
switch value := any(v).(type) { switch value := any(v).(type) {
case RouteCategory: case RouteMethod:
opt.categories = append(opt.categories, value) opt.methods = append(opt.methods, value)
case RouteService: case RouteService:
opt.services = append(opt.services, value) opt.services = append(opt.services, value)
} }
} }
} }